From 0f7dbb94a855c82dac5a95ab71f1d38e3097cc4a Mon Sep 17 00:00:00 2001 From: benedetta davico <46782255+benedettadavico@users.noreply.github.com> Date: Mon, 11 May 2026 16:50:14 +0200 Subject: [PATCH 01/94] fix for crates (#6745) * version fix * try to publish core crates first * bump version ci * fix to yaml * Slight modifications to ordering, remove core-crates and rely on ordering as test + sed tweak * crates release: bump version to 1.21.0 (#6744) Co-authored-by: Nym bot Co-authored-by: mfahampshire * Remove unnecessary verification step becase of dryrun (doubled) * Revert some changes to develop * Add preflight to its own workflow * Clippy * Update crate publishing file * Clippy --------- Co-authored-by: benedettadavico Co-authored-by: mfahampshire Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Nym bot --- .github/workflows/ci-crates-preflight.yml | 19 ++ .../workflows/ci-crates-publish-dry-run.yml | 3 +- .github/workflows/ci-crates-publish.yml | 6 +- .github/workflows/ci-crates-version-bump.yml | 31 ++- Cargo.lock | 238 +++++++++--------- Cargo.toml | 209 +++++++-------- common/ip-packet-requests/src/lib.rs | 2 +- common/nym-kkt/Cargo.toml | 2 +- crate-publishing.md | 49 +++- nym-registration-client/Cargo.toml | 2 +- .../ip-packet-router/src/messages/response.rs | 3 +- smolmix/core/Cargo.toml | 2 +- 12 files changed, 325 insertions(+), 241 deletions(-) create mode 100644 .github/workflows/ci-crates-preflight.yml diff --git a/.github/workflows/ci-crates-preflight.yml b/.github/workflows/ci-crates-preflight.yml new file mode 100644 index 0000000000..28948a1572 --- /dev/null +++ b/.github/workflows/ci-crates-preflight.yml @@ -0,0 +1,19 @@ +name: ci-crates-preflight +on: + workflow_dispatch: + pull_request: + paths: + - 'Cargo.toml' + - '**/Cargo.toml' + - 'tools/internal/check_publish_preflight.py' + - '.github/workflows/ci-crates-preflight.yml' + +jobs: + preflight: + runs-on: ubuntu-latest + steps: + - name: Checkout repo + uses: actions/checkout@v6 + + - name: Preflight publish checks + run: python3 tools/internal/check_publish_preflight.py diff --git a/.github/workflows/ci-crates-publish-dry-run.yml b/.github/workflows/ci-crates-publish-dry-run.yml index fa2714e7bb..8c3af47db6 100644 --- a/.github/workflows/ci-crates-publish-dry-run.yml +++ b/.github/workflows/ci-crates-publish-dry-run.yml @@ -57,7 +57,8 @@ jobs: - name: Update workspace dependencies run: | - sed -i '/path = /s/version = "${{ steps.current_version.outputs.version }}"/version = "${{ inputs.version }}"/g' Cargo.toml + # Match any semver version on lines with `path = `, not just the current workspace version. + sed -i '/path = /s/version = "[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*"/version = "${{ inputs.version }}"/g' Cargo.toml - name: Bump versions (local only) run: | diff --git a/.github/workflows/ci-crates-publish.yml b/.github/workflows/ci-crates-publish.yml index 94290c8a2d..57f744e7f2 100644 --- a/.github/workflows/ci-crates-publish.yml +++ b/.github/workflows/ci-crates-publish.yml @@ -33,7 +33,11 @@ jobs: - name: Install cargo-workspaces run: cargo install cargo-workspaces - # `--publish-as-is` skips version bumping since that's done in a separate CI job. + - name: Preflight publish checks + run: | + python3 tools/internal/check_publish_preflight.py + + # --publish-as-is skips version bumping since that's done in a separate CI job. - name: Publish env: CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }} diff --git a/.github/workflows/ci-crates-version-bump.yml b/.github/workflows/ci-crates-version-bump.yml index eebc0d64ac..0539d6b9f4 100644 --- a/.github/workflows/ci-crates-version-bump.yml +++ b/.github/workflows/ci-crates-version-bump.yml @@ -19,6 +19,7 @@ jobs: RUSTUP_PERMIT_COPY_RENAME: 1 permissions: contents: write + pull-requests: write steps: - name: Checkout repo uses: actions/checkout@v6 @@ -58,7 +59,9 @@ jobs: - name: Update workspace dependencies run: | - sed -i '/path = /s/version = "${{ steps.current_version.outputs.version }}"/version = "${{ inputs.version }}"/g' Cargo.toml + # Match any semver version on lines with `path = `, not just the current workspace version. + # This catches entries whose version has drifted (e.g. nym-sqlx-pool-guard at 1.2.0). + sed -i '/path = /s/version = "[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*"/version = "${{ inputs.version }}"/g' Cargo.toml - name: Bump versions run: | @@ -68,9 +71,33 @@ jobs: - name: Commit and push version bump run: | + set -euo pipefail + BASE_BRANCH="${GITHUB_REF_NAME}" + PR_BRANCH="ci/crates-version-bump-${{ inputs.version }}-${GITHUB_RUN_ID}" + + git checkout -b "$PR_BRANCH" git add -A git commit -m "crates release: bump version to ${{ inputs.version }}" - git push + git push -u origin "$PR_BRANCH" + + cat > /tmp/crates-version-bump-pr-body.md <<'EOF' + This PR was created by CI because direct pushes to the release branch are blocked by branch protection rules. + + ## Summary + - Bump workspace crate versions to the requested release version. + - Update workspace dependency versions accordingly. + + ## Notes + - Merge this PR to proceed with crates.io publishing. + EOF + + gh pr create \ + --base "$BASE_BRANCH" \ + --head "$PR_BRANCH" \ + --title "crates release: bump version to ${{ inputs.version }}" \ + --body-file /tmp/crates-version-bump-pr-body.md + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Show package versions run: cargo workspaces list --long diff --git a/Cargo.lock b/Cargo.lock index 2fc4083844..8c8df62b24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2642,7 +2642,7 @@ checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005" [[package]] name = "easy-addr" -version = "1.20.4" +version = "1.21.0" dependencies = [ "cosmwasm-std", "quote", @@ -5718,7 +5718,7 @@ dependencies = [ [[package]] name = "nym-api-requests" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bs58", "celes", @@ -5760,7 +5760,7 @@ dependencies = [ [[package]] name = "nym-async-file-watcher" -version = "1.20.4" +version = "1.21.0" dependencies = [ "futures", "log", @@ -5770,7 +5770,7 @@ dependencies = [ [[package]] name = "nym-authenticator-client" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bincode", "futures", @@ -5792,7 +5792,7 @@ dependencies = [ [[package]] name = "nym-authenticator-requests" -version = "1.20.4" +version = "1.21.0" dependencies = [ "base64 0.22.1", "bincode", @@ -5816,7 +5816,7 @@ dependencies = [ [[package]] name = "nym-bandwidth-controller" -version = "1.20.4" +version = "1.21.0" dependencies = [ "async-trait", "log", @@ -5833,7 +5833,7 @@ dependencies = [ [[package]] name = "nym-bin-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "clap", "clap_complete", @@ -5873,7 +5873,7 @@ dependencies = [ [[package]] name = "nym-cache" -version = "1.20.4" +version = "1.21.0" dependencies = [ "tokio", ] @@ -5904,7 +5904,7 @@ dependencies = [ [[package]] name = "nym-cli-commands" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "base64 0.22.1", @@ -6000,7 +6000,7 @@ dependencies = [ [[package]] name = "nym-client-core" -version = "1.20.4" +version = "1.21.0" dependencies = [ "async-trait", "base64 0.22.1", @@ -6062,7 +6062,7 @@ dependencies = [ [[package]] name = "nym-client-core-config-types" -version = "1.20.4" +version = "1.21.0" dependencies = [ "humantime-serde", "nym-config", @@ -6077,7 +6077,7 @@ dependencies = [ [[package]] name = "nym-client-core-gateways-storage" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "async-trait", @@ -6096,7 +6096,7 @@ dependencies = [ [[package]] name = "nym-client-core-surb-storage" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "async-trait", @@ -6142,7 +6142,7 @@ dependencies = [ [[package]] name = "nym-client-websocket-requests" -version = "1.20.4" +version = "1.21.0" dependencies = [ "nym-sphinx", "serde", @@ -6151,7 +6151,7 @@ dependencies = [ [[package]] name = "nym-coconut-dkg-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -6164,7 +6164,7 @@ dependencies = [ [[package]] name = "nym-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "tracing", "tracing-test", @@ -6172,7 +6172,7 @@ dependencies = [ [[package]] name = "nym-compact-ecash" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bincode", "bs58", @@ -6196,7 +6196,7 @@ dependencies = [ [[package]] name = "nym-config" -version = "1.20.4" +version = "1.21.0" dependencies = [ "dirs", "handlebars", @@ -6228,7 +6228,7 @@ dependencies = [ [[package]] name = "nym-contracts-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "bs58", @@ -6245,7 +6245,7 @@ dependencies = [ [[package]] name = "nym-contracts-common-testing" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "cosmwasm-std", @@ -6259,7 +6259,7 @@ dependencies = [ [[package]] name = "nym-cpp-ffi" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "bs58", @@ -6322,7 +6322,7 @@ dependencies = [ [[package]] name = "nym-credential-proxy-lib" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "axum 0.7.9", @@ -6360,7 +6360,7 @@ dependencies = [ [[package]] name = "nym-credential-proxy-requests" -version = "1.20.4" +version = "1.21.0" dependencies = [ "async-trait", "nym-credentials", @@ -6384,7 +6384,7 @@ dependencies = [ [[package]] name = "nym-credential-storage" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "async-trait", @@ -6407,7 +6407,7 @@ dependencies = [ [[package]] name = "nym-credential-utils" -version = "1.20.4" +version = "1.21.0" dependencies = [ "log", "nym-bandwidth-controller", @@ -6425,7 +6425,7 @@ dependencies = [ [[package]] name = "nym-credential-verification" -version = "1.20.4" +version = "1.21.0" dependencies = [ "async-trait", "bs58", @@ -6453,7 +6453,7 @@ dependencies = [ [[package]] name = "nym-credentials" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bincode", "cosmrs", @@ -6477,7 +6477,7 @@ dependencies = [ [[package]] name = "nym-credentials-interface" -version = "1.20.4" +version = "1.21.0" dependencies = [ "nym-bls12_381-fork", "nym-compact-ecash", @@ -6495,7 +6495,7 @@ dependencies = [ [[package]] name = "nym-crypto" -version = "1.20.4" +version = "1.21.0" dependencies = [ "aead", "aes", @@ -6570,7 +6570,7 @@ dependencies = [ [[package]] name = "nym-dkg" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bitvec", "bs58", @@ -6592,7 +6592,7 @@ dependencies = [ [[package]] name = "nym-ecash-contract-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bs58", "cosmwasm-schema", @@ -6606,7 +6606,7 @@ dependencies = [ [[package]] name = "nym-ecash-signer-check" -version = "1.20.4" +version = "1.21.0" dependencies = [ "futures", "nym-ecash-signer-check-types", @@ -6623,7 +6623,7 @@ dependencies = [ [[package]] name = "nym-ecash-signer-check-types" -version = "1.20.4" +version = "1.21.0" dependencies = [ "nym-coconut-dkg-common", "nym-crypto", @@ -6638,7 +6638,7 @@ dependencies = [ [[package]] name = "nym-ecash-time" -version = "1.20.4" +version = "1.21.0" dependencies = [ "nym-compact-ecash", "time", @@ -6646,7 +6646,7 @@ dependencies = [ [[package]] name = "nym-exit-policy" -version = "1.20.4" +version = "1.21.0" dependencies = [ "reqwest 0.13.1", "serde", @@ -6658,7 +6658,7 @@ dependencies = [ [[package]] name = "nym-ffi-shared" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "bs58", @@ -6733,7 +6733,7 @@ dependencies = [ [[package]] name = "nym-gateway-client" -version = "1.20.4" +version = "1.21.0" dependencies = [ "futures", "getrandom 0.2.16", @@ -6771,7 +6771,7 @@ dependencies = [ [[package]] name = "nym-gateway-probe" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "base64 0.22.1", @@ -6824,7 +6824,7 @@ dependencies = [ [[package]] name = "nym-gateway-requests" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "bs58", @@ -6856,7 +6856,7 @@ dependencies = [ [[package]] name = "nym-gateway-stats-storage" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "nym-node-metrics", @@ -6872,7 +6872,7 @@ dependencies = [ [[package]] name = "nym-gateway-storage" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "async-trait", @@ -6891,7 +6891,7 @@ dependencies = [ [[package]] name = "nym-go-ffi" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "lazy_static", @@ -6908,7 +6908,7 @@ dependencies = [ [[package]] name = "nym-group-contract-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "cosmwasm-schema", "cw-controllers", @@ -6919,7 +6919,7 @@ dependencies = [ [[package]] name = "nym-http-api-client" -version = "1.20.4" +version = "1.21.0" dependencies = [ "async-trait", "bincode", @@ -6952,7 +6952,7 @@ dependencies = [ [[package]] name = "nym-http-api-client-macro" -version = "1.20.4" +version = "1.21.0" dependencies = [ "nym-http-api-client", "proc-macro-crate", @@ -6965,7 +6965,7 @@ dependencies = [ [[package]] name = "nym-http-api-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "axum 0.7.9", "axum-client-ip", @@ -6987,7 +6987,7 @@ dependencies = [ [[package]] name = "nym-id" -version = "1.20.4" +version = "1.21.0" dependencies = [ "nym-credential-storage", "nym-credentials", @@ -7013,7 +7013,7 @@ dependencies = [ [[package]] name = "nym-inclusion-probability" -version = "1.20.4" +version = "1.21.0" dependencies = [ "log", "rand 0.8.5", @@ -7022,7 +7022,7 @@ dependencies = [ [[package]] name = "nym-ip-packet-client" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bincode", "bytes", @@ -7038,7 +7038,7 @@ dependencies = [ [[package]] name = "nym-ip-packet-requests" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bincode", "bytes", @@ -7059,7 +7059,7 @@ dependencies = [ [[package]] name = "nym-ip-packet-router" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "async-trait", @@ -7115,7 +7115,7 @@ dependencies = [ [[package]] name = "nym-kkt" -version = "0.1.0" +version = "1.21.0" dependencies = [ "anyhow", "libcrux-chacha20poly1305", @@ -7138,7 +7138,7 @@ dependencies = [ [[package]] name = "nym-kkt-ciphersuite" -version = "1.20.4" +version = "1.21.0" dependencies = [ "blake3", "libcrux-sha3", @@ -7151,7 +7151,7 @@ dependencies = [ [[package]] name = "nym-kkt-context" -version = "1.20.4" +version = "1.21.0" dependencies = [ "num_enum", "nym-kkt-ciphersuite", @@ -7160,7 +7160,7 @@ dependencies = [ [[package]] name = "nym-ledger" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bip32", "k256", @@ -7171,7 +7171,7 @@ dependencies = [ [[package]] name = "nym-lp" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "bs58", @@ -7230,7 +7230,7 @@ dependencies = [ [[package]] name = "nym-metrics" -version = "1.20.4" +version = "1.21.0" dependencies = [ "dashmap", "lazy_static", @@ -7240,7 +7240,7 @@ dependencies = [ [[package]] name = "nym-mixnet-client" -version = "1.20.4" +version = "1.21.0" dependencies = [ "dashmap", "futures", @@ -7257,7 +7257,7 @@ dependencies = [ [[package]] name = "nym-mixnet-contract-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bs58", "cosmwasm-schema", @@ -7280,7 +7280,7 @@ dependencies = [ [[package]] name = "nym-mixnode-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bytes", "futures", @@ -7307,7 +7307,7 @@ dependencies = [ [[package]] name = "nym-multisig-contract-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -7322,7 +7322,7 @@ dependencies = [ [[package]] name = "nym-network-defaults" -version = "1.20.4" +version = "1.21.0" dependencies = [ "cargo_metadata 0.19.2", "dotenvy", @@ -7518,7 +7518,7 @@ dependencies = [ [[package]] name = "nym-node-metrics" -version = "1.20.4" +version = "1.21.0" dependencies = [ "dashmap", "futures", @@ -7532,7 +7532,7 @@ dependencies = [ [[package]] name = "nym-node-requests" -version = "1.20.4" +version = "1.21.0" dependencies = [ "async-trait", "celes", @@ -7658,7 +7658,7 @@ dependencies = [ [[package]] name = "nym-node-tester-utils" -version = "1.20.4" +version = "1.21.0" dependencies = [ "futures", "log", @@ -7698,7 +7698,7 @@ dependencies = [ [[package]] name = "nym-noise" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "arc-swap", @@ -7721,7 +7721,7 @@ dependencies = [ [[package]] name = "nym-noise-keys" -version = "1.20.4" +version = "1.21.0" dependencies = [ "nym-crypto", "schemars 0.8.22", @@ -7731,7 +7731,7 @@ dependencies = [ [[package]] name = "nym-nonexhaustive-delayqueue" -version = "1.20.4" +version = "1.21.0" dependencies = [ "tokio", "tokio-stream", @@ -7757,7 +7757,7 @@ dependencies = [ [[package]] name = "nym-ordered-buffer" -version = "1.20.4" +version = "1.21.0" dependencies = [ "log", "thiserror 2.0.12", @@ -7765,7 +7765,7 @@ dependencies = [ [[package]] name = "nym-outfox" -version = "1.20.4" +version = "1.21.0" dependencies = [ "blake3", "chacha20", @@ -7779,7 +7779,7 @@ dependencies = [ [[package]] name = "nym-pemstore" -version = "1.20.4" +version = "1.21.0" dependencies = [ "pem", "tracing", @@ -7788,7 +7788,7 @@ dependencies = [ [[package]] name = "nym-performance-contract-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -7801,7 +7801,7 @@ dependencies = [ [[package]] name = "nym-pool-contract-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -7814,7 +7814,7 @@ dependencies = [ [[package]] name = "nym-registration-client" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bincode", "bytes", @@ -7842,7 +7842,7 @@ dependencies = [ [[package]] name = "nym-registration-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bincode", "nym-authenticator-requests", @@ -7859,7 +7859,7 @@ dependencies = [ [[package]] name = "nym-sdk" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "async-trait", @@ -7922,7 +7922,7 @@ dependencies = [ [[package]] name = "nym-serde-helpers" -version = "1.20.4" +version = "1.21.0" dependencies = [ "base64 0.22.1", "bs58", @@ -7933,7 +7933,7 @@ dependencies = [ [[package]] name = "nym-service-provider-requests-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bincode", "serde", @@ -7942,7 +7942,7 @@ dependencies = [ [[package]] name = "nym-service-providers-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "async-trait", "log", @@ -8008,7 +8008,7 @@ dependencies = [ [[package]] name = "nym-socks5-client-core" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "dirs", @@ -8040,7 +8040,7 @@ dependencies = [ [[package]] name = "nym-socks5-proxy-helpers" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bytes", "futures", @@ -8055,7 +8055,7 @@ dependencies = [ [[package]] name = "nym-socks5-requests" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bincode", "log", @@ -8070,7 +8070,7 @@ dependencies = [ [[package]] name = "nym-sphinx" -version = "1.20.4" +version = "1.21.0" dependencies = [ "nym-crypto", "nym-metrics", @@ -8096,7 +8096,7 @@ dependencies = [ [[package]] name = "nym-sphinx-acknowledgements" -version = "1.20.4" +version = "1.21.0" dependencies = [ "generic-array 0.14.7", "nym-crypto", @@ -8114,7 +8114,7 @@ dependencies = [ [[package]] name = "nym-sphinx-addressing" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bincode", "nym-crypto", @@ -8127,7 +8127,7 @@ dependencies = [ [[package]] name = "nym-sphinx-anonymous-replies" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bs58", "nym-crypto", @@ -8145,7 +8145,7 @@ dependencies = [ [[package]] name = "nym-sphinx-chunking" -version = "1.20.4" +version = "1.21.0" dependencies = [ "dashmap", "log", @@ -8163,7 +8163,7 @@ dependencies = [ [[package]] name = "nym-sphinx-cover" -version = "1.20.4" +version = "1.21.0" dependencies = [ "nym-crypto", "nym-sphinx-acknowledgements", @@ -8180,7 +8180,7 @@ dependencies = [ [[package]] name = "nym-sphinx-forwarding" -version = "1.20.4" +version = "1.21.0" dependencies = [ "nym-sphinx-addressing", "nym-sphinx-anonymous-replies", @@ -8191,7 +8191,7 @@ dependencies = [ [[package]] name = "nym-sphinx-framing" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bytes", "cfg-if", @@ -8208,7 +8208,7 @@ dependencies = [ [[package]] name = "nym-sphinx-params" -version = "1.20.4" +version = "1.21.0" dependencies = [ "nym-crypto", "nym-sphinx-types", @@ -8218,7 +8218,7 @@ dependencies = [ [[package]] name = "nym-sphinx-routing" -version = "1.20.4" +version = "1.21.0" dependencies = [ "nym-sphinx-addressing", "nym-sphinx-types", @@ -8227,7 +8227,7 @@ dependencies = [ [[package]] name = "nym-sphinx-types" -version = "1.20.4" +version = "1.21.0" dependencies = [ "nym-outfox", "sphinx-packet", @@ -8236,7 +8236,7 @@ dependencies = [ [[package]] name = "nym-sqlx-pool-guard" -version = "1.20.4" +version = "1.21.0" dependencies = [ "proc_pidinfo", "sqlx", @@ -8279,7 +8279,7 @@ dependencies = [ [[package]] name = "nym-statistics-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "futures", "log", @@ -8304,7 +8304,7 @@ dependencies = [ [[package]] name = "nym-store-cipher" -version = "1.20.4" +version = "1.21.0" dependencies = [ "aes-gcm", "argon2", @@ -8319,7 +8319,7 @@ dependencies = [ [[package]] name = "nym-task" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "cfg-if", @@ -8337,7 +8337,7 @@ dependencies = [ [[package]] name = "nym-test-utils" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "futures", @@ -8350,7 +8350,7 @@ dependencies = [ [[package]] name = "nym-ticketbooks-merkle" -version = "1.20.4" +version = "1.21.0" dependencies = [ "nym-credentials-interface", "nym-serde-helpers", @@ -8367,7 +8367,7 @@ dependencies = [ [[package]] name = "nym-topology" -version = "1.20.4" +version = "1.21.0" dependencies = [ "async-trait", "nym-api-requests", @@ -8389,7 +8389,7 @@ dependencies = [ [[package]] name = "nym-tun" -version = "1.20.4" +version = "1.21.0" dependencies = [ "etherparse", "log", @@ -8401,7 +8401,7 @@ dependencies = [ [[package]] name = "nym-types" -version = "1.20.4" +version = "1.21.0" dependencies = [ "base64 0.22.1", "cosmrs", @@ -8432,7 +8432,7 @@ dependencies = [ [[package]] name = "nym-upgrade-mode-check" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "jwt-simple", @@ -8450,7 +8450,7 @@ dependencies = [ [[package]] name = "nym-validator-client" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "async-trait", @@ -8544,7 +8544,7 @@ dependencies = [ [[package]] name = "nym-verloc" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bytes", "futures", @@ -8565,7 +8565,7 @@ dependencies = [ [[package]] name = "nym-vesting-contract-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -8599,7 +8599,7 @@ dependencies = [ [[package]] name = "nym-wasm-client-core" -version = "1.20.4" +version = "1.21.0" dependencies = [ "async-trait", "console_error_panic_hook", @@ -8633,7 +8633,7 @@ dependencies = [ [[package]] name = "nym-wasm-storage" -version = "1.20.4" +version = "1.21.0" dependencies = [ "async-trait", "indexed_db_futures", @@ -8647,7 +8647,7 @@ dependencies = [ [[package]] name = "nym-wasm-utils" -version = "1.20.4" +version = "1.21.0" dependencies = [ "console_error_panic_hook", "futures", @@ -8663,7 +8663,7 @@ dependencies = [ [[package]] name = "nym-wireguard" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "base64 0.22.1", @@ -8693,7 +8693,7 @@ dependencies = [ [[package]] name = "nym-wireguard-private-metadata-client" -version = "1.20.4" +version = "1.21.0" dependencies = [ "async-trait", "nym-http-api-client", @@ -8703,7 +8703,7 @@ dependencies = [ [[package]] name = "nym-wireguard-private-metadata-server" -version = "1.20.4" +version = "1.21.0" dependencies = [ "anyhow", "async-trait", @@ -8723,7 +8723,7 @@ dependencies = [ [[package]] name = "nym-wireguard-private-metadata-shared" -version = "1.20.4" +version = "1.21.0" dependencies = [ "axum 0.7.9", "bincode", @@ -8736,7 +8736,7 @@ dependencies = [ [[package]] name = "nym-wireguard-private-metadata-tests" -version = "1.20.4" +version = "1.21.0" dependencies = [ "async-trait", "axum 0.7.9", @@ -8760,7 +8760,7 @@ dependencies = [ [[package]] name = "nym-wireguard-types" -version = "1.20.4" +version = "1.21.0" dependencies = [ "base64 0.22.1", "nym-crypto", @@ -8851,7 +8851,7 @@ dependencies = [ [[package]] name = "nyxd-scraper-shared" -version = "1.20.4" +version = "1.21.0" dependencies = [ "async-trait", "base64 0.22.1", @@ -11165,7 +11165,7 @@ dependencies = [ [[package]] name = "smolmix" -version = "0.0.1" +version = "1.21.0" dependencies = [ "futures", "hickory-proto", @@ -14624,7 +14624,7 @@ dependencies = [ [[package]] name = "zknym-lib" -version = "1.20.4" +version = "1.21.0" dependencies = [ "async-trait", "js-sys", @@ -14683,7 +14683,7 @@ dependencies = [ [[package]] name = "zulip-client" -version = "1.20.4" +version = "1.21.0" dependencies = [ "itertools 0.14.0", "nym-bin-common", diff --git a/Cargo.toml b/Cargo.toml index 1d1db9f1da..00c5e6d273 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -206,7 +206,7 @@ edition = "2024" license = "Apache-2.0" rust-version = "1.87.0" readme = "README.md" -version = "1.20.4" +version = "1.21.0" [workspace.dependencies] addr = "0.15.6" @@ -349,7 +349,6 @@ serde_yaml = "0.9.25" serde_plain = "1.0.2" sha2 = "0.10.3" si-scale = "0.2.3" -smolmix = { version = "0.0.1", path = "smolmix/core" } smoltcp = "0.12" snow = "0.9.6" sphinx-packet = "=0.6.0" @@ -414,110 +413,112 @@ libcrux-sha3 = "0.0.8" libcrux-traits = "0.0.8" # Workspace dep definitions required by crates.io publication - we need a workspace version since `cargo workspaces` doesn't work with path imports from crate manifests -nym-api-requests = { version = "1.20.4", path = "nym-api/nym-api-requests" } -nym-authenticator-requests = { version = "1.20.4", path = "common/authenticator-requests" } -nym-async-file-watcher = { version = "1.20.4", path = "common/async-file-watcher" } -nym-authenticator-client = { version = "1.20.4", path = "nym-authenticator-client" } -nym-bandwidth-controller = { version = "1.20.4", path = "common/bandwidth-controller" } -nym-bin-common = { version = "1.20.4", path = "common/bin-common" } -nym-cache = { version = "1.20.4", path = "common/nym-cache" } -nym-client-core = { version = "1.20.4", path = "common/client-core", default-features = false } -nym-client-core-config-types = { version = "1.20.4", path = "common/client-core/config-types" } -nym-client-core-gateways-storage = { version = "1.20.4", path = "common/client-core/gateways-storage" } -nym-client-core-surb-storage = { version = "1.20.4", path = "common/client-core/surb-storage" } -nym-client-websocket-requests = { version = "1.20.4", path = "clients/native/websocket-requests" } -nym-common = { version = "1.20.4", path = "common/nym-common" } -nym-compact-ecash = { version = "1.20.4", path = "common/nym_offline_compact_ecash" } -nym-config = { version = "1.20.4", path = "common/config" } -nym-contracts-common = { version = "1.20.4", path = "common/cosmwasm-smart-contracts/contracts-common" } -nym-coconut-dkg-common = { version = "1.20.4", path = "common/cosmwasm-smart-contracts/coconut-dkg" } -nym-credential-storage = { version = "1.20.4", path = "common/credential-storage" } -nym-credential-utils = { version = "1.20.4", path = "common/credential-utils" } -nym-credential-proxy-lib = { version = "1.20.4", path = "common/credential-proxy" } -nym-credentials = { version = "1.20.4", path = "common/credentials", default-features = false } -nym-credentials-interface = { version = "1.20.4", path = "common/credentials-interface" } -nym-credential-proxy-requests = { version = "1.20.4", path = "nym-credential-proxy/nym-credential-proxy-requests", default-features = false } -nym-credential-verification = { version = "1.20.4", path = "common/credential-verification" } -nym-crypto = { version = "1.20.4", path = "common/crypto", default-features = false } -nym-dkg = { version = "1.20.4", path = "common/dkg" } -nym-ecash-contract-common = { version = "1.20.4", path = "common/cosmwasm-smart-contracts/ecash-contract" } -nym-ecash-signer-check = { version = "1.20.4", path = "common/ecash-signer-check" } -nym-ecash-signer-check-types = { version = "1.20.4", path = "common/ecash-signer-check-types" } -nym-ecash-time = { version = "1.20.4", path = "common/ecash-time" } -nym-exit-policy = { version = "1.20.4", path = "common/exit-policy" } -nym-ffi-shared = { version = "1.20.4", path = "sdk/ffi/shared" } -nym-gateway-client = { version = "1.20.4", path = "common/client-libs/gateway-client", default-features = false } +nym-api-requests = { version = "1.21.0", path = "nym-api/nym-api-requests" } +nym-authenticator-requests = { version = "1.21.0", path = "common/authenticator-requests" } +nym-async-file-watcher = { version = "1.21.0", path = "common/async-file-watcher" } +nym-authenticator-client = { version = "1.21.0", path = "nym-authenticator-client" } +nym-bandwidth-controller = { version = "1.21.0", path = "common/bandwidth-controller" } +nym-bin-common = { version = "1.21.0", path = "common/bin-common" } +nym-cache = { version = "1.21.0", path = "common/nym-cache" } +nym-client-core = { version = "1.21.0", path = "common/client-core", default-features = false } +nym-client-core-config-types = { version = "1.21.0", path = "common/client-core/config-types" } +nym-client-core-gateways-storage = { version = "1.21.0", path = "common/client-core/gateways-storage" } +nym-client-core-surb-storage = { version = "1.21.0", path = "common/client-core/surb-storage" } +nym-client-websocket-requests = { version = "1.21.0", path = "clients/native/websocket-requests" } +nym-common = { version = "1.21.0", path = "common/nym-common" } +nym-compact-ecash = { version = "1.21.0", path = "common/nym_offline_compact_ecash" } +nym-config = { version = "1.21.0", path = "common/config" } +nym-contracts-common = { version = "1.21.0", path = "common/cosmwasm-smart-contracts/contracts-common" } +nym-coconut-dkg-common = { version = "1.21.0", path = "common/cosmwasm-smart-contracts/coconut-dkg" } +nym-credential-storage = { version = "1.21.0", path = "common/credential-storage" } +nym-credential-utils = { version = "1.21.0", path = "common/credential-utils" } +nym-credential-proxy-lib = { version = "1.21.0", path = "common/credential-proxy" } +nym-credentials = { version = "1.21.0", path = "common/credentials", default-features = false } +nym-credentials-interface = { version = "1.21.0", path = "common/credentials-interface" } +nym-credential-proxy-requests = { version = "1.21.0", path = "nym-credential-proxy/nym-credential-proxy-requests", default-features = false } +nym-credential-verification = { version = "1.21.0", path = "common/credential-verification" } +nym-crypto = { version = "1.21.0", path = "common/crypto", default-features = false } +nym-dkg = { version = "1.21.0", path = "common/dkg" } +nym-ecash-contract-common = { version = "1.21.0", path = "common/cosmwasm-smart-contracts/ecash-contract" } +nym-ecash-signer-check = { version = "1.21.0", path = "common/ecash-signer-check" } +nym-ecash-signer-check-types = { version = "1.21.0", path = "common/ecash-signer-check-types" } +nym-ecash-time = { version = "1.21.0", path = "common/ecash-time" } +nym-exit-policy = { version = "1.21.0", path = "common/exit-policy" } +nym-ffi-shared = { version = "1.21.0", path = "sdk/ffi/shared" } +nym-gateway-client = { version = "1.21.0", path = "common/client-libs/gateway-client", default-features = false } nym-gateway-probe = { version = "1.18.0", path = "nym-gateway-probe" } -nym-gateway-requests = { version = "1.20.4", path = "common/gateway-requests" } -nym-gateway-storage = { version = "1.20.4", path = "common/gateway-storage" } -nym-gateway-stats-storage = { version = "1.20.4", path = "common/gateway-stats-storage" } -nym-group-contract-common = { version = "1.20.4", path = "common/cosmwasm-smart-contracts/group-contract" } -nym-http-api-client = { version = "1.20.4", path = "common/http-api-client" } -nym-http-api-client-macro = { version = "1.20.4", path = "common/http-api-client-macro" } -nym-http-api-common = { version = "1.20.4", path = "common/http-api-common", default-features = false } -nym-id = { version = "1.20.4", path = "common/nym-id" } -nym-ip-packet-client = { version = "1.20.4", path = "nym-ip-packet-client" } -nym-ip-packet-requests = { version = "1.20.4", path = "common/ip-packet-requests" } -nym-lp = { version = "1.20.4", path = "common/nym-lp" } -nym-kkt = { version = "0.1.0", path = "common/nym-kkt" } -nym-kkt-ciphersuite = { version = "1.20.4", path = "common/nym-kkt-ciphersuite" } -nym-kkt-context = { version = "1.20.4", path = "common/nym-kkt-context" } -nym-metrics = { version = "1.20.4", path = "common/nym-metrics" } -nym-mixnet-client = { version = "1.20.4", path = "common/client-libs/mixnet-client" } -nym-mixnet-contract-common = { version = "1.20.4", path = "common/cosmwasm-smart-contracts/mixnet-contract" } -nym-multisig-contract-common = { version = "1.20.4", path = "common/cosmwasm-smart-contracts/multisig-contract" } -nym-network-defaults = { version = "1.20.4", path = "common/network-defaults" } -nym-node-tester-utils = { version = "1.20.4", path = "common/node-tester-utils" } -nym-noise = { version = "1.20.4", path = "common/nymnoise" } -nym-noise-keys = { version = "1.20.4", path = "common/nymnoise/keys" } -nym-nonexhaustive-delayqueue = { version = "1.20.4", path = "common/nonexhaustive-delayqueue" } -nym-node-requests = { version = "1.20.4", path = "nym-node/nym-node-requests", default-features = false } -nym-node-metrics = { version = "1.20.4", path = "nym-node/nym-node-metrics" } -nym-ordered-buffer = { version = "1.20.4", path = "common/socks5/ordered-buffer" } -nym-outfox = { version = "1.20.4", path = "nym-outfox" } -nym-registration-common = { version = "1.20.4", path = "common/registration" } -nym-pemstore = { version = "1.20.4", path = "common/pemstore" } -nym-performance-contract-common = { version = "1.20.4", path = "common/cosmwasm-smart-contracts/nym-performance-contract" } -nym-sdk = { version = "1.20.4", path = "sdk/rust/nym-sdk" } -nym-serde-helpers = { version = "1.20.4", path = "common/serde-helpers" } -nym-service-providers-common = { version = "1.20.4", path = "service-providers/common" } -nym-service-provider-requests-common = { version = "1.20.4", path = "common/service-provider-requests-common" } -nym-socks5-client-core = { version = "1.20.4", path = "common/socks5-client-core" } -nym-socks5-proxy-helpers = { version = "1.20.4", path = "common/socks5/proxy-helpers" } -nym-socks5-requests = { version = "1.20.4", path = "common/socks5/requests" } -nym-sphinx = { version = "1.20.4", path = "common/nymsphinx" } -nym-sphinx-acknowledgements = { version = "1.20.4", path = "common/nymsphinx/acknowledgements" } -nym-sphinx-addressing = { version = "1.20.4", path = "common/nymsphinx/addressing" } -nym-sphinx-anonymous-replies = { version = "1.20.4", path = "common/nymsphinx/anonymous-replies" } -nym-sphinx-chunking = { version = "1.20.4", path = "common/nymsphinx/chunking" } -nym-sphinx-cover = { version = "1.20.4", path = "common/nymsphinx/cover" } -nym-sphinx-forwarding = { version = "1.20.4", path = "common/nymsphinx/forwarding" } -nym-sphinx-framing = { version = "1.20.4", path = "common/nymsphinx/framing" } -nym-sphinx-params = { version = "1.20.4", path = "common/nymsphinx/params" } -nym-sphinx-routing = { version = "1.20.4", path = "common/nymsphinx/routing" } -nym-sphinx-types = { version = "1.20.4", path = "common/nymsphinx/types" } -nym-statistics-common = { version = "1.20.4", path = "common/statistics" } -nym-store-cipher = { version = "1.20.4", path = "common/store-cipher" } -nym-task = { version = "1.20.4", path = "common/task" } -nym-tun = { version = "1.20.4", path = "common/tun" } -nym-test-utils = { version = "1.20.4", path = "common/test-utils" } -nym-ticketbooks-merkle = { version = "1.20.4", path = "common/ticketbooks-merkle" } -nym-topology = { version = "1.20.4", path = "common/topology" } -nym-types = { version = "1.20.4", path = "common/types" } -nym-upgrade-mode-check = { version = "1.20.4", path = "common/upgrade-mode-check" } -nym-validator-client = { version = "1.20.4", path = "common/client-libs/validator-client", default-features = false } -nym-vesting-contract-common = { version = "1.20.4", path = "common/cosmwasm-smart-contracts/vesting-contract" } -nym-verloc = { version = "1.20.4", path = "common/verloc" } -nym-wireguard = { version = "1.20.4", path = "common/wireguard" } -nym-wireguard-types = { version = "1.20.4", path = "common/wireguard-types" } -nym-wireguard-private-metadata-shared = { version = "1.20.4", path = "common/wireguard-private-metadata/shared" } -nym-wireguard-private-metadata-client = { version = "1.20.4", path = "common/wireguard-private-metadata/client" } -nym-wireguard-private-metadata-server = { version = "1.20.4", path = "common/wireguard-private-metadata/server" } +nym-gateway-requests = { version = "1.21.0", path = "common/gateway-requests" } +nym-gateway-storage = { version = "1.21.0", path = "common/gateway-storage" } +nym-gateway-stats-storage = { version = "1.21.0", path = "common/gateway-stats-storage" } +nym-group-contract-common = { version = "1.21.0", path = "common/cosmwasm-smart-contracts/group-contract" } +nym-http-api-client = { version = "1.21.0", path = "common/http-api-client" } +nym-http-api-client-macro = { version = "1.21.0", path = "common/http-api-client-macro" } +nym-http-api-common = { version = "1.21.0", path = "common/http-api-common", default-features = false } +nym-id = { version = "1.21.0", path = "common/nym-id" } +nym-ip-packet-client = { version = "1.21.0", path = "nym-ip-packet-client" } +nym-ip-packet-requests = { version = "1.21.0", path = "common/ip-packet-requests" } +nym-lp = { version = "1.21.0", path = "common/nym-lp" } +nym-kkt = { version = "1.21.0", path = "common/nym-kkt" } +nym-kkt-ciphersuite = { version = "1.21.0", path = "common/nym-kkt-ciphersuite" } +nym-kkt-context = { version = "1.21.0", path = "common/nym-kkt-context" } +nym-metrics = { version = "1.21.0", path = "common/nym-metrics" } +nym-mixnet-client = { version = "1.21.0", path = "common/client-libs/mixnet-client" } +nym-mixnet-contract-common = { version = "1.21.0", path = "common/cosmwasm-smart-contracts/mixnet-contract" } +nym-multisig-contract-common = { version = "1.21.0", path = "common/cosmwasm-smart-contracts/multisig-contract" } +nym-network-defaults = { version = "1.21.0", path = "common/network-defaults" } +nym-node-tester-utils = { version = "1.21.0", path = "common/node-tester-utils" } +nym-noise = { version = "1.21.0", path = "common/nymnoise" } +nym-noise-keys = { version = "1.21.0", path = "common/nymnoise/keys" } +nym-nonexhaustive-delayqueue = { version = "1.21.0", path = "common/nonexhaustive-delayqueue" } +nym-node-requests = { version = "1.21.0", path = "nym-node/nym-node-requests", default-features = false } +nym-node-metrics = { version = "1.21.0", path = "nym-node/nym-node-metrics" } +nym-ordered-buffer = { version = "1.21.0", path = "common/socks5/ordered-buffer" } +nym-outfox = { version = "1.21.0", path = "nym-outfox" } +nym-registration-common = { version = "1.21.0", path = "common/registration" } +nym-pemstore = { version = "1.21.0", path = "common/pemstore" } +nym-performance-contract-common = { version = "1.21.0", path = "common/cosmwasm-smart-contracts/nym-performance-contract" } +nym-sdk = { version = "1.21.0", path = "sdk/rust/nym-sdk" } +nym-serde-helpers = { version = "1.21.0", path = "common/serde-helpers" } +nym-service-providers-common = { version = "1.21.0", path = "service-providers/common" } +nym-service-provider-requests-common = { version = "1.21.0", path = "common/service-provider-requests-common" } +nym-socks5-client-core = { version = "1.21.0", path = "common/socks5-client-core" } +nym-socks5-proxy-helpers = { version = "1.21.0", path = "common/socks5/proxy-helpers" } +nym-socks5-requests = { version = "1.21.0", path = "common/socks5/requests" } +nym-sphinx = { version = "1.21.0", path = "common/nymsphinx" } +nym-sphinx-acknowledgements = { version = "1.21.0", path = "common/nymsphinx/acknowledgements" } +nym-sphinx-addressing = { version = "1.21.0", path = "common/nymsphinx/addressing" } +nym-sphinx-anonymous-replies = { version = "1.21.0", path = "common/nymsphinx/anonymous-replies" } +nym-sphinx-chunking = { version = "1.21.0", path = "common/nymsphinx/chunking" } +nym-sphinx-cover = { version = "1.21.0", path = "common/nymsphinx/cover" } +nym-sphinx-forwarding = { version = "1.21.0", path = "common/nymsphinx/forwarding" } +nym-sphinx-framing = { version = "1.21.0", path = "common/nymsphinx/framing" } +nym-sphinx-params = { version = "1.21.0", path = "common/nymsphinx/params" } +nym-sphinx-routing = { version = "1.21.0", path = "common/nymsphinx/routing" } +nym-sphinx-types = { version = "1.21.0", path = "common/nymsphinx/types" } +nym-statistics-common = { version = "1.21.0", path = "common/statistics" } +nym-store-cipher = { version = "1.21.0", path = "common/store-cipher" } +nym-task = { version = "1.21.0", path = "common/task" } +nym-tun = { version = "1.21.0", path = "common/tun" } +nym-test-utils = { version = "1.21.0", path = "common/test-utils" } +nym-ticketbooks-merkle = { version = "1.21.0", path = "common/ticketbooks-merkle" } +nym-topology = { version = "1.21.0", path = "common/topology" } +nym-types = { version = "1.21.0", path = "common/types" } +nym-upgrade-mode-check = { version = "1.21.0", path = "common/upgrade-mode-check" } +nym-validator-client = { version = "1.21.0", path = "common/client-libs/validator-client", default-features = false } +nym-vesting-contract-common = { version = "1.21.0", path = "common/cosmwasm-smart-contracts/vesting-contract" } +nym-verloc = { version = "1.21.0", path = "common/verloc" } +nym-wireguard = { version = "1.21.0", path = "common/wireguard" } +nym-wireguard-types = { version = "1.21.0", path = "common/wireguard-types" } +nym-wireguard-private-metadata-shared = { version = "1.21.0", path = "common/wireguard-private-metadata/shared" } +nym-wireguard-private-metadata-client = { version = "1.21.0", path = "common/wireguard-private-metadata/client" } +nym-wireguard-private-metadata-server = { version = "1.21.0", path = "common/wireguard-private-metadata/server" } nym-sqlx-pool-guard = { version = "1.2.0", path = "nym-sqlx-pool-guard" } -nym-wasm-client-core = { version = "1.20.4", path = "common/wasm/client-core" } -nym-wasm-storage = { version = "1.20.4", path = "common/wasm/storage" } -nym-wasm-utils = { version = "1.20.4", path = "common/wasm/utils", default-features = false } -nyxd-scraper-shared = { version = "1.20.4", path = "common/nyxd-scraper-shared" } +nym-wasm-client-core = { version = "1.21.0", path = "common/wasm/client-core" } +nym-wasm-storage = { version = "1.21.0", path = "common/wasm/storage" } +nym-wasm-utils = { version = "1.21.0", path = "common/wasm/utils", default-features = false } +nyxd-scraper-shared = { version = "1.21.0", path = "common/nyxd-scraper-shared" } + +smolmix = { version = "1.21.0", path = "smolmix/core" } # coconut/DKG related # unfortunately until https://github.com/zkcrypto/nym-bls12_381-fork/issues/10 is resolved, we have to rely on the fork diff --git a/common/ip-packet-requests/src/lib.rs b/common/ip-packet-requests/src/lib.rs index eb1ef05086..5c93dad297 100644 --- a/common/ip-packet-requests/src/lib.rs +++ b/common/ip-packet-requests/src/lib.rs @@ -28,7 +28,7 @@ mod tests { fn stream_transport_threshold_is_consistent() { assert_eq!(MAX_NON_STREAM_VERSION, 8); assert_eq!(SPHINX_STREAM_VERSION_THRESHOLD, 9); - assert!(SPHINX_STREAM_VERSION_THRESHOLD > MAX_NON_STREAM_VERSION); + const _: () = assert!(SPHINX_STREAM_VERSION_THRESHOLD > MAX_NON_STREAM_VERSION); } } diff --git a/common/nym-kkt/Cargo.toml b/common/nym-kkt/Cargo.toml index e278e33887..1157ee3869 100644 --- a/common/nym-kkt/Cargo.toml +++ b/common/nym-kkt/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "nym-kkt" description = "Key transport protocol for the Nym network" -version = "0.1.0" +version = "1.21.0" authors = ["Georgio Nicolas "] edition = { workspace = true } license.workspace = true diff --git a/crate-publishing.md b/crate-publishing.md index 86dc0988d2..037143712d 100644 --- a/crate-publishing.md +++ b/crate-publishing.md @@ -1,34 +1,67 @@ # Publishing workspace dependencies + ## Rationale re: versioning + We publish the majority of our workspace dependencies (essentially everything in the repo aside from binaries, smart contracts, and some internal tooling) to [crates.io](https://crates.io). -In order to make this easy to maintain, the versions of these workspace dependencies and the `nym-sdk` crate are kept in sync. +In order to make this easy to maintain, the versions of these workspace dependencies and the `nym-sdk` crate are kept in sync. The same is done to newer crates such as `smolmix`. This version is defined in the `[workspace.package]` section of the root monorepo `Cargo.toml` file. Each of the workspace dependencies have their paths and versions (this has to be individually defined at the moment per-dependency, **this version needs to stay the same as the `workspace.package` version**) defined in the `[workspace.dependencies]` section of the root monorepo `Cargo.toml` file. +The `contracts/` directory has its own separate `[workspace]`. Those crates are CosmWasm smart contracts deployed as WASM to chain, not published to crates.io. The shared types between the two workspaces (e.g. `nym-contracts-common`) live in `common/cosmwasm-smart-contracts/` within the root workspace and are published. The contracts workspace depends on them from crates.io. + ## When Developing + If you add a workspace dependency to the SDK when developing, make sure to add this to the workspace dependencies in the root monorepo `Cargo.toml`. +Crates that should not be published to crates.io must have `publish = false` in their `Cargo.toml`. The preflight check (`tools/internal/check_publish_preflight.py`) will flag publishable crates with missing metadata. + ## Check local publication + ``` # List crates to publish cargo workspaces list +# Check publishability (metadata, deps, non-publishable chains) +python3 tools/internal/check_publish_preflight.py + # Dry run locally - check for compilation or other problems cargo workspaces publish --no-git-commit --dry-run ``` ## CI -There are several workflows that should be run in the following order: -- `ci-crates-publish-dry-run`: **run this first!** This is a remote dry-run on a runner. This greps for any errors that would be a problem when we're not dry-running. It doesn't catch all errors, as `dry-run` has a known issue where, assuming that 2 new crates are being uploaded, and crate B relies on crate A, if crate A isn't on crates.io (which it won't be, since you're dry-running publication), then since `cargo workspaces publish` only checks for available versions on crates.io, it will error. We don't want the CI to fail in that case. -- `ci-crates-version-bump`: this bumps the versions of the workspace + dependencies to the passed version, and then commits the change. This is its own CI job so that we don't get into sticky situations whereby the version bump + commit happens, but the publication step fails. -- `ci-crates-publish`: this publishes the crates. So long as you're not uploading more than 5 new crates, pass `60` as the `publish_interval`. This is to get around [crates.io rate limiting](https://github.com/rust-lang/crates.io/blob/ad7e58e1afd65b9137e58a7bca3e1fb7f5546682/src/rate_limiter.rs#L24). Pass the Github handle of whoever should be the backup author of the crate for security redundency (see the section below) as the second arg. -> There is also `ci-crates-publish-resume` which is there in case a publication run fails and needs to be restarted part way through the list of unbumped/unpublished crates. Pass the previously bumped/published crate in the list output of `cargo workspaces list` +There are several workflows that should be run in the following order: + +1. **`ci-crates-publish-dry-run`**: Run this first. This is a remote dry-run on a runner that greps for real packaging errors (manifest issues, missing metadata). It ignores cascading dependency errors, which are expected in dry-run mode because upstream crates aren't actually uploaded to crates.io. + +2. **`ci-crates-version-bump`**: Bumps the versions of the workspace + dependencies to the passed version. This is a separate job so that if the version bump succeeds but publication fails, the versions aren't left in a bad state. **This creates a PR that must be merged into the branch you're publishing from before running publish.** + +3. **`ci-crates-publish`**: Publishes the crates using `cargo workspaces publish --publish-as-is`. The `--publish-as-is` flag tells cargo-workspaces to publish with the current versions in the repo (already bumped by step 2) without doing any version changes itself. + + - `publish_interval`: seconds to wait between publishes for crates.io indexing. Use `600` for first-time publication of many new crates, `60` after that. This is to get around [crates.io rate limiting](https://github.com/rust-lang/crates.io/blob/ad7e58e1afd65b9137e58a7bca3e1fb7f5546682/src/rate_limiter.rs#L24). + - `backup_author`: Github handle of who should be added as backup crate owner (defaults to `jstuczyn`). + +> There is also `ci-crates-publish-resume` which is there in case a publication run fails and needs to be restarted part way through the list of unpublished crates. + +### Important: workflow sequencing + +The version-bump workflow creates a PR due to branch protection rules. **You must merge that PR before running the publish workflow**, otherwise publish will run against the unbumped branch and fail with "already exists" errors for the old version. + +## How cargo-workspaces publish works + +`cargo workspaces publish` handles several things that raw `cargo publish` does not: + +- **Topological ordering**: publishes crates in dependency order. +- **Dev-dep removal**: by default, dev-dependencies are stripped from each crate's `Cargo.toml` before publishing. This avoids packaging failures where a dev-dep on a workspace sibling hasn't been uploaded yet. +- **Cargo.toml rewriting**: replaces `workspace = true` references with concrete values before calling `cargo publish`. + +Do not replace this with a manual `cargo publish -p` loop -- it will fail during packaging because `cargo publish` tries to resolve all deps (including dev-deps) against the crates.io index, and workspace siblings at the new version won't exist yet. ## Crates.io Authors -Since Github teams have [limited ownership / mod rights](https://doc.rust-lang.org/cargo/reference/publishing.html#cargo-owner) of crates, and we cannot create a `CARGO_REGISTRY_TOKEN` on behalf of the Nym Github org. As such, we are currently using personal cargo tokens generated by team members (currently Max), and adding the Nym Github org as an owner in the CI job. -However, since the Github org cannot add or modify owners, are also adding a second user author as a redundency, on the offchance that Max loses access to his Crates.io / Github account, gets struck by lightning, etc. This is the author passed as the second argument to the `ci-crates-publish` CI, and if none is passed, defaults to [https://github.com/jstuczyn](https://github.com/jstuczyn) since he is the Github org owner. +Since Github teams have [limited ownership / mod rights](https://doc.rust-lang.org/cargo/reference/publishing.html#cargo-owner) of crates, and we cannot create a `CARGO_REGISTRY_TOKEN` on behalf of the Nym Github org, we are currently using personal cargo tokens generated by team members (currently Max), and adding the Nym Github org as an owner in the CI job. + +However, since the Github org cannot add or modify owners, we are also adding a second user as a redundancy, on the offchance that Max loses access to his Crates.io / Github account, gets struck by lightning, etc. This is the author passed as the second argument to the `ci-crates-publish` CI, and if none is passed, defaults to [jstuczyn](https://github.com/jstuczyn) since he is the Github org owner. Authors can also be changed by running `scripts/add-crates-owners.sh`. diff --git a/nym-registration-client/Cargo.toml b/nym-registration-client/Cargo.toml index 0a7e845864..9e5082689f 100644 --- a/nym-registration-client/Cargo.toml +++ b/nym-registration-client/Cargo.toml @@ -38,4 +38,4 @@ nym-wireguard-types = { path = "../common/wireguard-types" } [dev-dependencies] nym-kkt.workspace = true -nym-test-utils.workspace = true \ No newline at end of file +nym-test-utils.workspace = true diff --git a/service-providers/ip-packet-router/src/messages/response.rs b/service-providers/ip-packet-router/src/messages/response.rs index e928487a26..deefccc146 100644 --- a/service-providers/ip-packet-router/src/messages/response.rs +++ b/service-providers/ip-packet-router/src/messages/response.rs @@ -133,8 +133,7 @@ impl VersionedResponse { ClientVersion::V9 => { let mut resp = IpPacketResponseV8::try_from(self)?; resp.version = nym_ip_packet_requests::v9::VERSION; - let bytes = resp.to_bytes(); - bytes + resp.to_bytes() } } .map_err(|err| IpPacketRouterError::FailedToSerializeResponsePacket { source: err }) diff --git a/smolmix/core/Cargo.toml b/smolmix/core/Cargo.toml index 9ef598b42d..2fe8ac0fca 100644 --- a/smolmix/core/Cargo.toml +++ b/smolmix/core/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "smolmix" description = "Tunnel for TCP and UDP traffic to be sent over Nym mixnet to clearnet remote hosts" -version = "0.0.1" +version.workspace = true authors.workspace = true edition = "2021" license.workspace = true From 87c236a9276d33433d585a32009223202bb3df4e Mon Sep 17 00:00:00 2001 From: Simon Wicky Date: Fri, 15 May 2026 09:42:30 +0200 Subject: [PATCH 02/94] ipr version revert on develop (#6772) --- Cargo.lock | 4 +- common/ip-packet-requests/src/lib.rs | 15 --- nym-gateway-probe/src/common/helpers.rs | 8 +- nym-gateway-probe/src/common/icmp.rs | 29 +---- nym-gateway-probe/src/common/probe_tests.rs | 23 +--- nym-ip-packet-client/src/connect.rs | 81 +++----------- nym-ip-packet-client/src/helpers.rs | 26 ++--- nym-ip-packet-client/src/lib.rs | 3 +- nym-ip-packet-client/src/lp_stream.rs | 100 ------------------ .../nym-sdk/src/ipr_wrapper/ip_mix_stream.rs | 10 +- .../src/clients/connected_client_handler.rs | 5 +- .../ip-packet-router/src/messages/request.rs | 5 +- .../ip-packet-router/src/messages/response.rs | 6 +- 13 files changed, 55 insertions(+), 260 deletions(-) delete mode 100644 nym-ip-packet-client/src/lp_stream.rs diff --git a/Cargo.lock b/Cargo.lock index 99019e079c..4568c69bb9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9635,9 +9635,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "prefix-trie" -version = "0.8.3" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f561214012d3fc240a1f9c817cc4d57f5310910d066069c1b093f766bb5966" +checksum = "4cf6e3177f0684016a5c209b00882e15f8bdd3f3bb48f0491df10cd102d0c6e7" dependencies = [ "either", "ipnet", diff --git a/common/ip-packet-requests/src/lib.rs b/common/ip-packet-requests/src/lib.rs index 7468c3580a..1a1c6f197d 100644 --- a/common/ip-packet-requests/src/lib.rs +++ b/common/ip-packet-requests/src/lib.rs @@ -20,21 +20,6 @@ pub const MAX_NON_STREAM_VERSION: u8 = v8::VERSION; /// mixnet sends, matching the node-side enforcement in `ip-packet-router`. pub const SPHINX_STREAM_VERSION_THRESHOLD: u8 = v9::VERSION; -#[cfg(test)] -mod tests { - use super::*; - - const _: () = { - assert!(SPHINX_STREAM_VERSION_THRESHOLD > MAX_NON_STREAM_VERSION); - }; - - #[test] - fn stream_transport_threshold_is_consistent() { - assert_eq!(MAX_NON_STREAM_VERSION, 8); - assert_eq!(SPHINX_STREAM_VERSION_THRESHOLD, 9); - } -} - // version 3: initial version // version 4: IPv6 support // version 5: Add severity level to info response diff --git a/nym-gateway-probe/src/common/helpers.rs b/nym-gateway-probe/src/common/helpers.rs index 54822c3987..5dc330e9cc 100644 --- a/nym-gateway-probe/src/common/helpers.rs +++ b/nym-gateway-probe/src/common/helpers.rs @@ -1,10 +1,9 @@ // Copyright 2026 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use nym_ip_packet_client::current::response::{ +use nym_ip_packet_requests::v8::response::{ ControlResponse, DataResponse, InfoLevel, IpPacketResponse, IpPacketResponseData, }; -use nym_ip_packet_client::lp_stream; use nym_sdk::{ DebugConfig, NymApiTopologyProvider, NymApiTopologyProviderConfig, NymNetworkDetails, TopologyProvider, mixnet::ReconstructedMessage, @@ -33,10 +32,7 @@ pub fn mixnet_debug_config( } pub fn unpack_data_response(reconstructed_message: &ReconstructedMessage) -> Option { - let payload = - lp_stream::maybe_unwrap_lp_stream_payload_from_reconstructed(reconstructed_message); - - match IpPacketResponse::from_bytes(payload) { + match IpPacketResponse::from_reconstructed_message(reconstructed_message) { Ok(response) => match response.data { IpPacketResponseData::Data(data_response) => Some(data_response), IpPacketResponseData::Control(control) => match *control { diff --git a/nym-gateway-probe/src/common/icmp.rs b/nym-gateway-probe/src/common/icmp.rs index 2d96a27da5..ec757623f1 100644 --- a/nym-gateway-probe/src/common/icmp.rs +++ b/nym-gateway-probe/src/common/icmp.rs @@ -9,7 +9,7 @@ use nym_connection_monitor::{ wrap_icmp_in_ipv6, }, }; -use nym_ip_packet_requests::{IpPair, codec::MultiIpPacketCodec}; +use nym_ip_packet_requests::{IpPair, codec::MultiIpPacketCodec, v8::request::IpPacketRequest}; use nym_sdk::mixnet::{ InputMessage, MixnetClient, MixnetMessageSender, Recipient, TransmissionLane, }; @@ -25,7 +25,6 @@ pub async fn send_ping_v4( sequence_number: u16, destination: Ipv4Addr, exit_router_address: Recipient, - stream_id: u64, ) -> anyhow::Result<()> { let icmp_identifier = icmp_identifier(); let icmp_echo_request = create_icmpv4_echo_request(sequence_number, icmp_identifier)?; @@ -36,12 +35,7 @@ pub async fn send_ping_v4( MultiIpPacketCodec::bundle_one_packet(ipv4_packet.packet().to_vec().into()); // Wrap into a mixnet input message addressed to the IPR - let mixnet_message = create_input_message( - exit_router_address, - bundled_packet, - stream_id, - sequence_number, - )?; + let mixnet_message = create_input_message(exit_router_address, bundled_packet)?; mixnet_client.send(mixnet_message).await?; Ok(()) @@ -53,7 +47,6 @@ pub async fn send_ping_v6( sequence_number: u16, destination: Ipv6Addr, exit_router_address: Recipient, - stream_id: u64, ) -> anyhow::Result<()> { let icmp_identifier = icmp_identifier(); let icmp_echo_request = create_icmpv6_echo_request( @@ -69,12 +62,7 @@ pub async fn send_ping_v6( MultiIpPacketCodec::bundle_one_packet(ipv6_packet.packet().to_vec().into()); // Wrap into a mixnet input message addressed to the IPR - let mixnet_message = create_input_message( - exit_router_address, - bundled_packet, - stream_id, - sequence_number, - )?; + let mixnet_message = create_input_message(exit_router_address, bundled_packet)?; // Send across the mixnet mixnet_client.send(mixnet_message).await?; @@ -84,22 +72,15 @@ pub async fn send_ping_v6( fn create_input_message( recipient: impl Into, bundled_packets: Bytes, - stream_id: u64, - sequence_number: u16, ) -> anyhow::Result { - let packet = nym_ip_packet_client::current::new_data_request(bundled_packets).to_bytes()?; - let framed_packet = nym_ip_packet_client::lp_stream::encode_stream_frame( - stream_id, - sequence_number as u32, - packet, - ); + let packet = IpPacketRequest::new_data_request(bundled_packets).to_bytes()?; let lane = TransmissionLane::General; let packet_type = None; let surbs = 0; Ok(InputMessage::new_anonymous( recipient.into(), - framed_packet, + packet, surbs, lane, packet_type, diff --git a/nym-gateway-probe/src/common/probe_tests.rs b/nym-gateway-probe/src/common/probe_tests.rs index 7f6bee2d01..d37a1042d2 100644 --- a/nym-gateway-probe/src/common/probe_tests.rs +++ b/nym-gateway-probe/src/common/probe_tests.rs @@ -256,8 +256,8 @@ pub async fn do_ping( let (maybe_ip_pair, mut mixnet_client) = connect_exit(mixnet_client, exit_router_address).await; match maybe_ip_pair { - Some((ip_pair, stream_id)) => ( - do_ping_exit(&mut mixnet_client, ip_pair, stream_id, exit_router_address).await, + Some(ip_pair) => ( + do_ping_exit(&mut mixnet_client, ip_pair, exit_router_address).await, mixnet_client, ), None => (Ok(Some(Exit::fail_to_connect())), mixnet_client), @@ -304,7 +304,7 @@ async fn do_ping_entry( async fn connect_exit( mixnet_client: MixnetClient, exit_router_address: Recipient, -) -> (Option<(IpPair, u64)>, MixnetClient) { +) -> (Option, MixnetClient) { // Step 2: connect to the exit gateway info!( "Connecting to exit gateway: {}", @@ -315,19 +315,12 @@ async fn connect_exit( let mut ipr_client = IprClientConnect::new(mixnet_client, cancel_token); let maybe_ip_pair = ipr_client.connect(exit_router_address).await; - let stream_id = ipr_client.stream_id(); let mixnet_client = ipr_client.into_mixnet_client(); if let Ok(our_ips) = maybe_ip_pair { info!("Successfully connected to exit gateway"); info!("Using mixnet VPN IP addresses: {our_ips}"); - let Some(stream_id) = stream_id else { - tracing::warn!( - "No active IPR stream id set after connect; cannot run IPR data-plane tests" - ); - return (None, mixnet_client); - }; - (Some((our_ips, stream_id)), mixnet_client) + (Some(our_ips), mixnet_client) } else { (None, mixnet_client) } @@ -336,11 +329,10 @@ async fn connect_exit( pub async fn do_ping_exit( mixnet_client: &mut MixnetClient, our_ips: IpPair, - stream_id: u64, exit_router_address: Recipient, ) -> anyhow::Result> { // Step 3: perform ICMP connectivity checks for the exit gateway - send_icmp_pings(mixnet_client, our_ips, exit_router_address, stream_id).await?; + send_icmp_pings(mixnet_client, our_ips, exit_router_address).await?; listen_for_icmp_ping_replies(mixnet_client, our_ips).await } @@ -348,7 +340,6 @@ async fn send_icmp_pings( mixnet_client: &MixnetClient, our_ips: IpPair, exit_router_address: Recipient, - stream_id: u64, ) -> anyhow::Result<()> { // ipv4 addresses for testing let ipr_tun_ip_v4 = NYM_TUN_DEVICE_ADDRESS_V4; @@ -370,7 +361,6 @@ async fn send_icmp_pings( ii, ipr_tun_ip_v4, exit_router_address, - stream_id, ) .await?; icmp::send_ping_v4( @@ -379,7 +369,6 @@ async fn send_icmp_pings( ii, external_ip_v4, exit_router_address, - stream_id, ) .await?; } @@ -392,7 +381,6 @@ async fn send_icmp_pings( ii, ipr_tun_ip_v6, exit_router_address, - stream_id, ) .await?; icmp::send_ping_v6( @@ -401,7 +389,6 @@ async fn send_icmp_pings( ii, external_ip_v6, exit_router_address, - stream_id, ) .await?; } diff --git a/nym-ip-packet-client/src/connect.rs b/nym-ip-packet-client/src/connect.rs index b49d87daa5..0448c0cf40 100644 --- a/nym-ip-packet-client/src/connect.rs +++ b/nym-ip-packet-client/src/connect.rs @@ -14,7 +14,7 @@ use tracing::{debug, error}; use nym_ip_packet_requests::response_helpers::{self, IprResponseError}; use crate::{ - current::{self, response::IpPacketResponse}, + current::{request::IpPacketRequest, response::IpPacketResponse}, error::{Error, Result}, helpers::check_ipr_message_version, }; @@ -24,12 +24,8 @@ const IPR_CONNECT_TIMEOUT: Duration = Duration::from_secs(10); #[derive(Clone, Debug, PartialEq, Eq)] enum ConnectionState { Disconnected, - Connecting { - stream_id: u64, - }, - Connected { - stream_id: u64, - }, + Connecting, + Connected, #[allow(unused)] Disconnecting, } @@ -55,27 +51,17 @@ impl IprClientConnect { self.mixnet_client } - pub fn stream_id(&self) -> Option { - match self.connected { - ConnectionState::Connecting { stream_id } - | ConnectionState::Connected { stream_id } => Some(stream_id), - ConnectionState::Disconnected | ConnectionState::Disconnecting => None, - } - } - pub async fn connect(&mut self, ip_packet_router_address: Recipient) -> Result { if self.connected != ConnectionState::Disconnected { return Err(Error::AlreadyConnected); } tracing::info!("Connecting to exit gateway"); + self.connected = ConnectionState::Connecting; match self.connect_inner(ip_packet_router_address).await { Ok(ips) => { debug!("Successfully connected to the ip-packet-router"); - let Some(stream_id) = self.stream_id() else { - return Err(Error::UnexpectedConnectResponse); - }; - self.connected = ConnectionState::Connected { stream_id }; + self.connected = ConnectionState::Connected; Ok(ips) } Err(err) => { @@ -88,37 +74,21 @@ impl IprClientConnect { async fn connect_inner(&mut self, ip_packet_router_address: Recipient) -> Result { let request_id = self.send_connect_request(ip_packet_router_address).await?; - self.connected = ConnectionState::Connecting { - stream_id: request_id, - }; debug!("Waiting for reply..."); self.listen_for_connect_response(request_id).await } - async fn send_connect_request(&mut self, ip_packet_router_address: Recipient) -> Result { - let (request, request_id) = current::new_connect_request(None); - tracing::info!( - request_id = request_id, - protocol_version = request.protocol.version, - current_version = crate::current::VERSION, - "Sending IPR connect request" - ); - if let Ok(bytes) = request.to_bytes() { - let prefix = bytes.get(0..2).unwrap_or(&bytes); - let prefix_hex = format!("{:02x?}", prefix); - tracing::info!(request_id = request_id, prefix = %prefix_hex, "IPR connect bytes prefix"); - } + async fn send_connect_request(&self, ip_packet_router_address: Recipient) -> Result { + let (request, request_id) = IpPacketRequest::new_connect_request(None); // We use 20 surbs for the connect request because typically the IPR is configured to have // a min threshold of 10 surbs that it reserves for itself to request additional surbs. let surbs = 20; - let request_bytes = request.to_bytes()?; - let framed_bytes = maybe_wrap_stream_frame(request_id, 0, request_bytes); self.mixnet_client .send(create_input_message( ip_packet_router_address, - framed_bytes, + request, surbs, )?) .await @@ -159,19 +129,13 @@ impl IprClientConnect { for msg in msgs { // Confirm that the version is correct if let Err(err) = check_ipr_message_version(&msg) { - let raw: &[u8] = msg.message.as_ref(); - tracing::warn!( - first_byte = raw.first().copied(), - expected = crate::current::VERSION, - len = raw.len(), - "Mixnet message version mismatch: {err}" - ); + tracing::info!("Mixnet message version mismatch: {err}"); continue; } // Then we deserialize the message tracing::debug!("IprClient: got message while waiting for connect response"); - let Ok(response) = ipr_response_from_reconstructed_message(&msg) else { + let Ok(response) = IpPacketResponse::from_reconstructed_message(&msg) else { // This is ok, it's likely just one of our self-pings tracing::debug!("Failed to deserialize mixnet message"); continue; @@ -196,27 +160,14 @@ impl IprClientConnect { } } -fn maybe_wrap_stream_frame(stream_id: u64, sequence_num: u32, payload: Vec) -> Vec { - if !crate::lp_stream::current_requires_sphinx_stream_transport() { - return payload; - } - - crate::lp_stream::encode_stream_frame(stream_id, sequence_num, payload) -} - -fn ipr_response_from_reconstructed_message( - msg: &nym_sdk::mixnet::ReconstructedMessage, -) -> std::result::Result { - let warn_on_unexpected = crate::lp_stream::current_requires_sphinx_stream_transport(); - let payload = - crate::lp_stream::maybe_unwrap_lp_stream_payload(&msg.message, warn_on_unexpected); - IpPacketResponse::from_bytes(payload) -} - -fn create_input_message(recipient: Recipient, bytes: Vec, surbs: u32) -> Result { +fn create_input_message( + recipient: Recipient, + request: IpPacketRequest, + surbs: u32, +) -> Result { Ok(InputMessage::new_anonymous( recipient, - bytes, + request.to_bytes()?, surbs, TransmissionLane::General, None, diff --git a/nym-ip-packet-client/src/helpers.rs b/nym-ip-packet-client/src/helpers.rs index cfa0957aec..1b31870ff8 100644 --- a/nym-ip-packet-client/src/helpers.rs +++ b/nym-ip-packet-client/src/helpers.rs @@ -7,16 +7,18 @@ use nym_sdk::mixnet::ReconstructedMessage; use crate::{current::VERSION as CURRENT_VERSION, error::Result}; pub(crate) fn check_ipr_message_version(message: &ReconstructedMessage) -> Result<()> { - let payload = crate::lp_stream::maybe_unwrap_lp_stream_payload_from_reconstructed(message); - nym_ip_packet_requests::response_helpers::check_ipr_message_version(payload, CURRENT_VERSION) - .map_err(|e| match e { - IprResponseError::NoVersionByte => crate::Error::NoVersionInMessage, - IprResponseError::VersionMismatch { expected, received } if received < expected => { - crate::Error::ReceivedResponseWithOldVersion { expected, received } - } - IprResponseError::VersionMismatch { expected, received } => { - crate::Error::ReceivedResponseWithNewVersion { expected, received } - } - _ => crate::Error::NoVersionInMessage, - }) + nym_ip_packet_requests::response_helpers::check_ipr_message_version( + &message.message, + CURRENT_VERSION, + ) + .map_err(|e| match e { + IprResponseError::NoVersionByte => crate::Error::NoVersionInMessage, + IprResponseError::VersionMismatch { expected, received } if received < expected => { + crate::Error::ReceivedResponseWithOldVersion { expected, received } + } + IprResponseError::VersionMismatch { expected, received } => { + crate::Error::ReceivedResponseWithNewVersion { expected, received } + } + _ => crate::Error::NoVersionInMessage, + }) } diff --git a/nym-ip-packet-client/src/lib.rs b/nym-ip-packet-client/src/lib.rs index 40478fc650..8aa5ffdf42 100644 --- a/nym-ip-packet-client/src/lib.rs +++ b/nym-ip-packet-client/src/lib.rs @@ -5,11 +5,10 @@ mod connect; mod error; mod helpers; mod listener; -pub mod lp_stream; pub use connect::IprClientConnect; pub use error::Error; pub use listener::{IprListener, MixnetMessageOutcome}; // Re-export the currently used version -pub use nym_ip_packet_requests::v9 as current; +pub use nym_ip_packet_requests::v8 as current; diff --git a/nym-ip-packet-client/src/lp_stream.rs b/nym-ip-packet-client/src/lp_stream.rs deleted file mode 100644 index 736d55f378..0000000000 --- a/nym-ip-packet-client/src/lp_stream.rs +++ /dev/null @@ -1,100 +0,0 @@ -use bytes::BytesMut; -use nym_ip_packet_requests::SPHINX_STREAM_VERSION_THRESHOLD; -use nym_lp::packet::frame::{ - LpFrame, LpFrameHeader, LpFrameKind, SphinxStreamFrameAttributes, SphinxStreamMsgType, -}; -use nym_sdk::mixnet::ReconstructedMessage; -use tracing::warn; - -/// Whether the "current" IPR client is operating at a version where the node expects -/// non-stream mixnet IPR messages to be LP Stream framed (see `SPHINX_STREAM_VERSION_THRESHOLD`). -pub(crate) fn current_requires_sphinx_stream_transport() -> bool { - crate::current::VERSION >= SPHINX_STREAM_VERSION_THRESHOLD -} - -pub fn maybe_unwrap_lp_stream_payload(data: &[u8], warn_on_unexpected: bool) -> &[u8] { - if data.len() < LpFrameHeader::SIZE { - if warn_on_unexpected { - warn!( - len = data.len(), - header_size = LpFrameHeader::SIZE, - "expected LP SphinxStream frame for IPR payload, but message is shorter than LP header; treating as raw payload" - ); - } - return data; - } - - let Ok(header) = LpFrameHeader::parse(data) else { - if warn_on_unexpected { - warn!( - "expected LP SphinxStream frame for IPR payload, but failed to parse LP header; treating as raw payload" - ); - } - return data; - }; - - if header.kind == LpFrameKind::SphinxStream { - &data[LpFrameHeader::SIZE..] - } else { - if warn_on_unexpected { - warn!( - kind = ?header.kind, - "expected LP SphinxStream frame for IPR payload, but got different LP frame kind; treating as raw payload" - ); - } - data - } -} - -pub fn maybe_unwrap_lp_stream_payload_from_reconstructed(message: &ReconstructedMessage) -> &[u8] { - maybe_unwrap_lp_stream_payload(&message.message, false) -} - -pub fn encode_stream_frame(stream_id: u64, sequence_num: u32, payload: Vec) -> Vec { - let attrs = SphinxStreamFrameAttributes { - stream_id, - msg_type: SphinxStreamMsgType::Data, - sequence_num, - }; - let frame = LpFrame::new_stream(attrs, payload); - let mut buf = BytesMut::with_capacity(LpFrameHeader::SIZE + frame.content.len()); - frame.encode(&mut buf); - buf.to_vec() -} - -#[cfg(test)] -mod tests { - use super::*; - use nym_lp::packet::frame::SphinxStreamFrameAttributes; - - #[test] - fn stream_frame_roundtrip_unwraps_payload() { - let stream_id = 0x0123_4567_89ab_cdef; - let seq = 42u32; - let payload = b"hello-ipr".to_vec(); - - let framed = encode_stream_frame(stream_id, seq, payload.clone()); - - let header = LpFrameHeader::parse(&framed).expect("valid lp header"); - assert_eq!(header.kind, LpFrameKind::SphinxStream); - - let attrs = - SphinxStreamFrameAttributes::parse(&header.frame_attributes).expect("valid attrs"); - assert_eq!(attrs.stream_id, stream_id); - assert_eq!(attrs.sequence_num, seq); - assert_eq!(attrs.msg_type, SphinxStreamMsgType::Data); - - let unwrapped = maybe_unwrap_lp_stream_payload(&framed, false); - assert_eq!(unwrapped, payload.as_slice()); - } - - #[test] - fn unwrap_noops_on_non_stream_or_malformed_data() { - let raw = b"\x09\x00\x01\x02\x03"; - assert_eq!(maybe_unwrap_lp_stream_payload(raw, false), raw); - - // malformed header: not enough bytes for LP header - let short = b"\x00\x01"; - assert_eq!(maybe_unwrap_lp_stream_payload(short, false), short); - } -} diff --git a/sdk/rust/nym-sdk/src/ipr_wrapper/ip_mix_stream.rs b/sdk/rust/nym-sdk/src/ipr_wrapper/ip_mix_stream.rs index b4e75746e0..13cfb56e23 100644 --- a/sdk/rust/nym-sdk/src/ipr_wrapper/ip_mix_stream.rs +++ b/sdk/rust/nym-sdk/src/ipr_wrapper/ip_mix_stream.rs @@ -9,9 +9,11 @@ use crate::ip_packet_client::{ use crate::mixnet::{MixnetClient, MixnetStream, Recipient}; use crate::Error; use bytes::Bytes; -use current_ipr::response::IpPacketResponse; use nym_ip_packet_requests::response_helpers; -use nym_ip_packet_requests::{v9 as current_ipr, IpPair}; +use nym_ip_packet_requests::{ + v9::{self, response::IpPacketResponse}, + IpPair, +}; use nym_network_defaults::NymNetworkDetails; use std::time::Duration; use tokio::io::AsyncWriteExt; @@ -105,7 +107,7 @@ impl IpMixStream { } async fn connect_tunnel(stream: &mut MixnetStream) -> Result { - let (request, request_id) = current_ipr::new_connect_request(None); + let (request, request_id) = v9::new_connect_request(None); debug!("Sending connect request with ID: {}", request_id); let request_bytes = request.to_bytes()?; @@ -144,7 +146,7 @@ impl IpMixStream { /// Send an IP packet through the tunnel. pub async fn send_ip_packet(&mut self, packet: &[u8]) -> Result<(), Error> { self.check_connected()?; - let request = current_ipr::new_data_request(packet.to_vec().into()); + let request = v9::new_data_request(packet.to_vec().into()); let request_bytes = request.to_bytes()?; self.stream .write_all(&request_bytes) diff --git a/service-providers/ip-packet-router/src/clients/connected_client_handler.rs b/service-providers/ip-packet-router/src/clients/connected_client_handler.rs index ff0e8e4924..e44b543276 100644 --- a/service-providers/ip-packet-router/src/clients/connected_client_handler.rs +++ b/service-providers/ip-packet-router/src/clients/connected_client_handler.rs @@ -218,10 +218,7 @@ fn create_ip_packet_response( ClientVersion::V6 => IpPacketResponseV6::new_ip_packet(packets).to_bytes(), ClientVersion::V7 => IpPacketResponseV7::new_ip_packet(packets).to_bytes(), ClientVersion::V8 => IpPacketResponseV8::new_ip_packet(packets).to_bytes(), - ClientVersion::V9 => { - let resp = v9::new_ip_packet_response(packets); - resp.to_bytes() - } + ClientVersion::V9 => v9::new_ip_packet_response(packets).to_bytes(), } } diff --git a/service-providers/ip-packet-router/src/messages/request.rs b/service-providers/ip-packet-router/src/messages/request.rs index 0c613a2fd4..0f8419e5e1 100644 --- a/service-providers/ip-packet-router/src/messages/request.rs +++ b/service-providers/ip-packet-router/src/messages/request.rs @@ -10,7 +10,6 @@ use nym_ip_packet_requests::{ IpPair, v6::request::IpPacketRequest as IpPacketRequestV6, v7::request::IpPacketRequest as IpPacketRequestV7, v8::request::IpPacketRequest as IpPacketRequestV8, - v9::request::IpPacketRequest as IpPacketRequestV9, }; use nym_sdk::mixnet::ReconstructedMessage; use nym_service_provider_requests_common::{Protocol, ServiceProviderType}; @@ -132,14 +131,14 @@ impl TryFrom<&ReconstructedMessage> for IpPacketRequest { Ok(IpPacketRequest::from((request_v8, sender_tag))) } 9 => { - let request_v9 = IpPacketRequestV9::from_reconstructed_message(reconstructed) + let request_v8 = IpPacketRequestV8::from_reconstructed_message(reconstructed) .map_err( |source| IpPacketRouterError::FailedToDeserializeTaggedPacket { source }, )?; let sender_tag = reconstructed .sender_tag .ok_or(IpPacketRouterError::MissingSenderTag)?; - Ok(v9::convert(request_v9, sender_tag)) + Ok(v9::convert(request_v8, sender_tag)) } _ => { log::info!("Received packet with invalid version: v{request_version}"); diff --git a/service-providers/ip-packet-router/src/messages/response.rs b/service-providers/ip-packet-router/src/messages/response.rs index deefccc146..4801983f48 100644 --- a/service-providers/ip-packet-router/src/messages/response.rs +++ b/service-providers/ip-packet-router/src/messages/response.rs @@ -130,11 +130,7 @@ impl VersionedResponse { ClientVersion::V6 => IpPacketResponseV6::try_from(self)?.to_bytes(), ClientVersion::V7 => IpPacketResponseV7::try_from(self)?.to_bytes(), ClientVersion::V8 => IpPacketResponseV8::try_from(self)?.to_bytes(), - ClientVersion::V9 => { - let mut resp = IpPacketResponseV8::try_from(self)?; - resp.version = nym_ip_packet_requests::v9::VERSION; - resp.to_bytes() - } + ClientVersion::V9 => IpPacketResponseV8::try_from(self)?.to_bytes(), } .map_err(|err| IpPacketRouterError::FailedToSerializeResponsePacket { source: err }) } From a53ca71bd2844489132add613ee97c355b7eaef7 Mon Sep 17 00:00:00 2001 From: Jack Wampler Date: Fri, 15 May 2026 09:46:33 -0600 Subject: [PATCH 03/94] Re-order default API urls for network details (#6767) --- common/network-defaults/src/mainnet.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/common/network-defaults/src/mainnet.rs b/common/network-defaults/src/mainnet.rs index e2c33def93..3c07beefc3 100644 --- a/common/network-defaults/src/mainnet.rs +++ b/common/network-defaults/src/mainnet.rs @@ -43,10 +43,6 @@ pub const NYM_APIS: &[ApiUrlConst] = &[ url: NYM_API, front_hosts: None, }, - ApiUrlConst { - url: "https://nym-frontdoor.vercel.app/api/", - front_hosts: Some(&["vercel.app", "vercel.com"]), - }, ApiUrlConst { url: "https://nym-frontdoor.global.ssl.fastly.net/api/", front_hosts: Some(&["yelp.global.ssl.fastly.net"]), @@ -68,7 +64,7 @@ pub const UPGRADE_MODE_ATTESTER_ED25519_BS58_PUBKEY: &str = pub const NYM_VPN_APIS: &[ApiUrlConst] = &[ ApiUrlConst { url: NYM_VPN_API, - front_hosts: Some(&["vercel.app", "vercel.com"]), + front_hosts: None, }, ApiUrlConst { url: "https://nymvpn-frontdoor.global.ssl.fastly.net/api/", From 362f84b5f667b4b3585972dde734ce99d1aba61c Mon Sep 17 00:00:00 2001 From: Jack Wampler Date: Mon, 18 May 2026 08:47:41 -0600 Subject: [PATCH 04/94] Handle Rate Limit Challenge Response (#6786) rotate urls on HTTP response error indicating API rate limiting --- common/http-api-client/src/lib.rs | 54 ++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/common/http-api-client/src/lib.rs b/common/http-api-client/src/lib.rs index b0a5a3d30a..b5d067bbca 100644 --- a/common/http-api-client/src/lib.rs +++ b/common/http-api-client/src/lib.rs @@ -1173,7 +1173,16 @@ impl ApiClientCore for Client { }; match response { - Ok(resp) => return Ok(resp), + Ok(resp) => { + // Check if the response includes a rate limit error from the vercel API + if is_http_rate_limit_err(&resp) { + warn!("encountered vercel rate limit error for {}", url.as_str()); + // if we have multiple urls, update to the next + self.maybe_rotate_hosts(Some(url.clone())); + } + + return Ok(resp); + } Err(err) => { #[cfg(target_arch = "wasm32")] let is_network_err = err.is_timeout(); @@ -1226,17 +1235,39 @@ impl ApiClientCore for Client { } } +const VERCEL_CHALLENGE_HEADER: &str = "x-vercel-mitigated"; +const VERCEL_CHALLENGE_VALUE: &[u8] = b"challenge"; + +/// Check for Rate Limit challenge response from the vercel API +pub(crate) fn is_http_rate_limit_err(resp: &Response) -> bool { + let status = resp.status() == StatusCode::FORBIDDEN; + let header = resp + .headers() + .get(VERCEL_CHALLENGE_HEADER) + .is_some_and(|v| v.as_bytes() == VERCEL_CHALLENGE_VALUE); + let content_type = resp + .headers() + .get(CONTENT_TYPE) + .and_then(|value| value.to_str().ok()) + .and_then(|value| value.parse::().ok()) + .is_some_and(|mime_type| { + mime_type.type_() == mime::TEXT && mime_type.subtype() == mime::HTML + }); + + status && header && content_type +} + #[cfg(not(target_arch = "wasm32"))] const MAX_ERR_SOURCE_ITERATIONS: usize = 4; -/// This functions attempts to check the error returned by reqwest to see if -/// rotating host informtion (for clients with mutliple hosts defined) could be -/// helpful. This looks for situations where the error could plausibly be caused -/// by a network adversary, or where rotating to an equival hostname might help. +/// This functions attempts to check the error returned by reqwest to see if rotating host +/// information (for clients with multiple hosts defined) could be helpful. This looks for +/// situations where the error could plausibly be caused by a network adversary, or where rotating +/// to an equivalent hostname might help. /// -/// For example --> NetworkUnreachable will not be helped by rotating domains, -/// but ConnectionReset might be caused by a network adversary blocking by SNI -/// which could possibly benefit from rotating domains. +/// For example --> NetworkUnreachable will not be helped by rotating domains, but ConnectionReset +/// might be caused by a network adversary blocking by SNI which could possibly benefit from +/// rotating domains. #[cfg(not(target_arch = "wasm32"))] pub(crate) fn might_be_network_interference(err: &reqwest::Error) -> bool { if err.is_timeout() { @@ -1697,6 +1728,13 @@ where decode_raw_response(&headers, full) } else if res.status() == StatusCode::NOT_FOUND { Err(HttpClientError::NotFound { url: Box::new(url) }) + } else if is_http_rate_limit_err(&res) { + Err(HttpClientError::EndpointFailure { + url: Box::new(url), + status, + headers: Box::new(headers), + error: String::from("received vercel rate limit challenge response"), + }) } else { let Ok(plaintext) = res.text().await else { return Err(HttpClientError::RequestFailure { From a21a01cf1a6941414da7be88a3f8d58c874b04a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 19 May 2026 10:36:20 +0100 Subject: [PATCH 05/94] node families (#6715) * start node families topic branch * start node families topic branch * initialise node families contract * define contract storage * registering new family in storage * accepting family invitation * add_pending_invitation * revoke_pending_invitation * remove_family_member * reject_pending_invitation * disband_family * added unit tests for the storage methods * added restriction on uniquness of family names * update rustc version for node families contract common * clippy * basic queries by id * query_families_paged * change family membership storage and expose query for all members of a family * queries for pending invitations * queries for past invitations * queries for past data per node * queries for past family members * query_past_members_for_node_paged * queries for family by name and by owner * fixup family name normalisation * fixed incorrect lower bound for queries for past data * implement contract and storage initialisation * stubbing tx messages that are to be exposed by the contract * handler for updating config * removed partial fee return * wip: create family * move mixnet contract interaction traits to shared location * store original family name alongside the normalised variant * prevent family creation if owner has a node in another family * try_disband_family * try_invite_to_family + shared helpers * try_revoke_family_invitation * accept_family_invitation * stub method for node unbonding * try_reject_family_invitation * unit tests for family name normalisation * try_leave_family * try_kick_from_family * fix outdated comments and add paid fee event attribute * feat: NMv3: leave family upon node unbonding * NF contract handling of unbonding * lints * init node families contract when creating performance contract tester * clippy * avoid self-dep in the contract dev deps * introduced client traits for interacting with the node families contract * add node families contract to cache refresher * added query for all node family members (globally) and started scaffolding nym-api caches * docs and cache -> api conversion * calculating average node age based on individual timestamps * wire up node families cache * http stubs * filled in the implementation * route tests + extracting shared code * review fixes * feat: expose family information for all dvpn gateway endpoints within NS API * expose family information for explorer v3 route * clippy * review comments and optimise db family update * feat: Node Families: expose stake information inside DVpnGateway * chore: update lock files after rebase * chore: sort workspace members * explicitly require providing node families contract address for mixnet contract migration * fix missing node families contract address env export * dont swallow cache overwrite failures in fixture * pin network-defaults rustc version due to contracts dep * further version pinning * chore: update mixnet contract schema --- Cargo.lock | 18 + Cargo.toml | 31 +- .../client-libs/validator-client/Cargo.toml | 1 + .../validator-client/src/nym_api/mod.rs | 40 + .../validator-client/src/nym_api/routes.rs | 1 + .../src/nyxd/contract_traits/mod.rs | 10 + .../node_families_query_client.rs | 441 +++ .../node_families_signing_client.rs | 254 ++ .../validator-client/src/nyxd/mod.rs | 11 + .../validator/cosmwasm/generators/mixnet.rs | 12 + .../src/tester/basic_traits.rs | 8 + .../mixnet-contract/src/helpers.rs | 115 +- .../mixnet-contract/src/lib.rs | 1 + .../mixnet-contract/src/mixnode.rs | 4 + .../mixnet-contract/src/msg.rs | 2 + .../mixnet-contract/src/types.rs | 4 + .../node-families-contract/Cargo.toml | 32 + .../node-families-contract/src/constants.rs | 104 + .../node-families-contract/src/error.rs | 161 + .../node-families-contract/src/lib.rs | 22 + .../node-families-contract/src/msg.rs | 211 ++ .../node-families-contract/src/types.rs | 403 +++ common/crypto/Cargo.toml | 4 +- common/http-api-common/src/response/mod.rs | 35 + common/network-defaults/Cargo.toml | 4 +- common/network-defaults/src/mainnet.rs | 4 + common/network-defaults/src/network.rs | 15 + common/network-defaults/src/var_names.rs | 1 + common/pemstore/Cargo.toml | 4 +- contracts/Cargo.lock | 340 +- contracts/Cargo.toml | 47 +- contracts/mixnet/Cargo.toml | 5 +- .../mixnet/schema/nym-mixnet-contract.json | 19 + contracts/mixnet/schema/raw/instantiate.json | 4 + contracts/mixnet/schema/raw/migrate.json | 6 + .../schema/raw/response_to_get_state.json | 9 + contracts/mixnet/src/contract.rs | 15 +- .../src/mixnet_contract_settings/queries.rs | 9 +- .../src/mixnet_contract_settings/storage.rs | 8 + contracts/mixnet/src/nodes/transactions.rs | 22 +- contracts/mixnet/src/queued_migrations.rs | 46 +- .../mixnet/src/testable_mixnet_contract.rs | 220 +- contracts/node-families/.cargo/config | 4 + contracts/node-families/Cargo.toml | 62 + contracts/node-families/Makefile | 5 + .../node-families/schema/node-families.json | 2844 +++++++++++++++++ .../node-families/schema/raw/execute.json | 318 ++ .../node-families/schema/raw/instantiate.json | 80 + .../node-families/schema/raw/migrate.json | 7 + contracts/node-families/schema/raw/query.json | 620 ++++ ...ponse_to_get_all_family_members_paged.json | 78 + ...nse_to_get_all_past_invitations_paged.json | 212 ++ ..._to_get_all_pending_invitations_paged.json | 95 + .../raw/response_to_get_families_paged.json | 117 + .../raw/response_to_get_family_by_id.json | 118 + .../raw/response_to_get_family_by_name.json | 116 + .../raw/response_to_get_family_by_owner.json | 120 + .../response_to_get_family_members_paged.json | 85 + .../response_to_get_family_membership.json | 27 + ...get_past_invitations_for_family_paged.json | 207 ++ ...o_get_past_invitations_for_node_paged.json | 207 ++ ..._to_get_past_members_for_family_paged.json | 79 + ...se_to_get_past_members_for_node_paged.json | 79 + .../response_to_get_pending_invitation.json | 91 + ..._pending_invitations_for_family_paged.json | 90 + ...et_pending_invitations_for_node_paged.json | 90 + contracts/node-families/src/bin/schema.rs | 14 + contracts/node-families/src/contract.rs | 355 ++ contracts/node-families/src/helpers.rs | 178 ++ contracts/node-families/src/lib.rs | 28 + contracts/node-families/src/queries.rs | 2501 +++++++++++++++ .../node-families/src/queued_migrations.rs | 2 + contracts/node-families/src/storage/mod.rs | 1386 ++++++++ .../src/storage/retrieval_limits.rs | 34 + .../src/storage/storage_indexes.rs | 174 + contracts/node-families/src/testing.rs | 219 ++ contracts/node-families/src/transactions.rs | 2165 +++++++++++++ contracts/performance/Cargo.toml | 7 + contracts/performance/src/helpers.rs | 97 - contracts/performance/src/lib.rs | 1 - contracts/performance/src/queries.rs | 1 + contracts/performance/src/storage.rs | 4 +- contracts/performance/src/testing/mod.rs | 258 +- contracts/performance/src/transactions.rs | 1 + nym-api/Cargo.toml | 1 + nym-api/nym-api-requests/src/models/mod.rs | 1 + .../src/models/node_families.rs | 130 + nym-api/src/ecash/tests/mod.rs | 240 +- nym-api/src/main.rs | 1 + nym-api/src/node_families/cache/mod.rs | 238 ++ nym-api/src/node_families/cache/refresher.rs | 213 ++ nym-api/src/node_families/handlers/mod.rs | 139 + nym-api/src/node_families/mod.rs | 37 + nym-api/src/node_families/tests.rs | 254 ++ nym-api/src/support/cli/run.rs | 19 +- nym-api/src/support/config/mod.rs | 43 + nym-api/src/support/http/helpers.rs | 10 +- nym-api/src/support/http/router.rs | 2 + .../support/http/state/contract_details.rs | 2 + nym-api/src/support/http/state/mod.rs | 6 + .../src/support/http/state/test_helpers.rs | 67 + nym-api/src/support/nyxd/mod.rs | 24 +- nym-api/src/support/storage/mod.rs | 33 +- ...56cdae6d3fe6b53a8ed5c37fdc4d9e3b7f7c.json} | 4 +- ...61d2afb1b37720f5756b9c6fb3aef55a3027.json} | 4 +- ...47c8d9e063f183c6da77295529b06495f6a5c.json | 56 + ...40572c15063457bac682e938bee632bd0260f.json | 26 + ...fce8994aa1d0b4ef4078a98f5a3efa4c70493.json | 21 + ...b565b2e258f66f4981ace2cfb36bd8b89991.json} | 4 +- ...3419b43304c3c93389abfc4c1d53955b15dd0.json | 16 + ...e62b0d2cfa2f7404f4afb8c3d393f0927f04.json} | 4 +- ...d0122403d252c369ebbee7b64cba8eacc4e05.json | 12 + ...be0cb679568a751c1b7e604a098a824b2a7c.json} | 4 +- ...47ee2ca1d3830ee0cc2237238f119ac50480.json} | 4 +- .../nym-node-status-api/Cargo.toml | 1 + .../20260514120000_node_families.sql | 24 + .../nym-node-status-api/src/db/mod.rs | 17 + .../nym-node-status-api/src/db/models.rs | 45 + .../src/db/queries/gateways.rs | 125 +- .../src/db/queries/misc.rs | 130 +- .../nym-node-status-api/src/db/queries/mod.rs | 11 +- .../src/db/queries/node_families.rs | 135 + .../src/db/queries/nym_nodes.rs | 442 ++- .../src/db/queries/scraper.rs | 3 +- .../src/http/api/dvpn/country.rs | 4 +- .../src/http/api/dvpn/entry.rs | 6 +- .../src/http/api/dvpn/exit.rs | 6 +- .../src/http/api/dvpn/mod.rs | 6 +- .../src/http/api/gateways.rs | 12 +- .../src/http/api/nym_nodes.rs | 4 +- .../src/http/api/services/mod.rs | 4 +- .../src/http/models/mod.rs | 285 +- .../nym-node-status-api/src/http/server.rs | 6 +- .../nym-node-status-api/src/http/state.rs | 391 ++- .../nym-node-status-api/src/main.rs | 4 +- .../nym-node-status-api/src/monitor/mod.rs | 108 +- nym-wallet/Cargo.lock | 80 +- .../nym-wallet-types/src/network/sandbox.rs | 5 + .../orchestrator/setup/cosmwasm_contracts.rs | 16 +- 139 files changed, 17916 insertions(+), 1448 deletions(-) create mode 100644 common/client-libs/validator-client/src/nyxd/contract_traits/node_families_query_client.rs create mode 100644 common/client-libs/validator-client/src/nyxd/contract_traits/node_families_signing_client.rs create mode 100644 common/cosmwasm-smart-contracts/node-families-contract/Cargo.toml create mode 100644 common/cosmwasm-smart-contracts/node-families-contract/src/constants.rs create mode 100644 common/cosmwasm-smart-contracts/node-families-contract/src/error.rs create mode 100644 common/cosmwasm-smart-contracts/node-families-contract/src/lib.rs create mode 100644 common/cosmwasm-smart-contracts/node-families-contract/src/msg.rs create mode 100644 common/cosmwasm-smart-contracts/node-families-contract/src/types.rs create mode 100644 contracts/node-families/.cargo/config create mode 100644 contracts/node-families/Cargo.toml create mode 100644 contracts/node-families/Makefile create mode 100644 contracts/node-families/schema/node-families.json create mode 100644 contracts/node-families/schema/raw/execute.json create mode 100644 contracts/node-families/schema/raw/instantiate.json create mode 100644 contracts/node-families/schema/raw/migrate.json create mode 100644 contracts/node-families/schema/raw/query.json create mode 100644 contracts/node-families/schema/raw/response_to_get_all_family_members_paged.json create mode 100644 contracts/node-families/schema/raw/response_to_get_all_past_invitations_paged.json create mode 100644 contracts/node-families/schema/raw/response_to_get_all_pending_invitations_paged.json create mode 100644 contracts/node-families/schema/raw/response_to_get_families_paged.json create mode 100644 contracts/node-families/schema/raw/response_to_get_family_by_id.json create mode 100644 contracts/node-families/schema/raw/response_to_get_family_by_name.json create mode 100644 contracts/node-families/schema/raw/response_to_get_family_by_owner.json create mode 100644 contracts/node-families/schema/raw/response_to_get_family_members_paged.json create mode 100644 contracts/node-families/schema/raw/response_to_get_family_membership.json create mode 100644 contracts/node-families/schema/raw/response_to_get_past_invitations_for_family_paged.json create mode 100644 contracts/node-families/schema/raw/response_to_get_past_invitations_for_node_paged.json create mode 100644 contracts/node-families/schema/raw/response_to_get_past_members_for_family_paged.json create mode 100644 contracts/node-families/schema/raw/response_to_get_past_members_for_node_paged.json create mode 100644 contracts/node-families/schema/raw/response_to_get_pending_invitation.json create mode 100644 contracts/node-families/schema/raw/response_to_get_pending_invitations_for_family_paged.json create mode 100644 contracts/node-families/schema/raw/response_to_get_pending_invitations_for_node_paged.json create mode 100644 contracts/node-families/src/bin/schema.rs create mode 100644 contracts/node-families/src/contract.rs create mode 100644 contracts/node-families/src/helpers.rs create mode 100644 contracts/node-families/src/lib.rs create mode 100644 contracts/node-families/src/queries.rs create mode 100644 contracts/node-families/src/queued_migrations.rs create mode 100644 contracts/node-families/src/storage/mod.rs create mode 100644 contracts/node-families/src/storage/retrieval_limits.rs create mode 100644 contracts/node-families/src/storage/storage_indexes.rs create mode 100644 contracts/node-families/src/testing.rs create mode 100644 contracts/node-families/src/transactions.rs delete mode 100644 contracts/performance/src/helpers.rs create mode 100644 nym-api/nym-api-requests/src/models/node_families.rs create mode 100644 nym-api/src/node_families/cache/mod.rs create mode 100644 nym-api/src/node_families/cache/refresher.rs create mode 100644 nym-api/src/node_families/handlers/mod.rs create mode 100644 nym-api/src/node_families/mod.rs create mode 100644 nym-api/src/node_families/tests.rs create mode 100644 nym-api/src/support/http/state/test_helpers.rs rename nym-node-status-api/nym-node-status-api/.sqlx/{query-56854f703321ff8d8f30628c7e5322024ea01b778ab55efa9c7c6b219ef36308.json => query-0d183e6ad37527d0f624580f702b56cdae6d3fe6b53a8ed5c37fdc4d9e3b7f7c.json} (60%) rename nym-node-status-api/nym-node-status-api/.sqlx/{query-f25a4eb90c11957669cfad4800d7a0a384b672077abb123c3437962def194e8a.json => query-1668f5a5a0abc8a73454953c3f5b61d2afb1b37720f5756b9c6fb3aef55a3027.json} (60%) create mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-3120dc00831742e0981bdcf486a47c8d9e063f183c6da77295529b06495f6a5c.json create mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-33e2ca569a31fd03fdc0b2cbf7840572c15063457bac682e938bee632bd0260f.json create mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-486bbf89adfd9343549263e84a1fce8994aa1d0b4ef4078a98f5a3efa4c70493.json rename nym-node-status-api/nym-node-status-api/.sqlx/{query-227539374e7473f6f9642289c5b5d1bcd636315ab23537cb5f6d2f82a2bcb7bf.json => query-5834dcc61f5409f568bad0484395b565b2e258f66f4981ace2cfb36bd8b89991.json} (50%) create mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-8c94f3c3bf7b9c3b135dc4b12303419b43304c3c93389abfc4c1d53955b15dd0.json rename nym-node-status-api/nym-node-status-api/.sqlx/{query-c7656b2b1b4328415772ce69d0568bd5438d6c8496ca9cbdcfb70bb5375b345e.json => query-a1bb7a40d073335db7d9061771dfe62b0d2cfa2f7404f4afb8c3d393f0927f04.json} (51%) create mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-a470feaded5ceee869202ab3a8bd0122403d252c369ebbee7b64cba8eacc4e05.json rename nym-node-status-api/nym-node-status-api/.sqlx/{query-3ddc12cc4e1796b787a50c40560d2bd71d1cfe5f5265e6f161b3122d1317a421.json => query-e5c75bbade89f9b1b7ddaad50f48be0cb679568a751c1b7e604a098a824b2a7c.json} (65%) rename nym-node-status-api/nym-node-status-api/.sqlx/{query-0b51df277ed66c6553f66af9b135342dee177abc1c92e4a89147de3c22d3d1a5.json => query-f2d5127e36621cb4dd3a7870e95447ee2ca1d3830ee0cc2237238f119ac50480.json} (67%) create mode 100644 nym-node-status-api/nym-node-status-api/migrations_pg/20260514120000_node_families.sql create mode 100644 nym-node-status-api/nym-node-status-api/src/db/queries/node_families.rs diff --git a/Cargo.lock b/Cargo.lock index a7d2736783..0eadd13981 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5768,6 +5768,7 @@ dependencies = [ "nym-http-api-client", "nym-http-api-common", "nym-mixnet-contract-common", + "nym-node-families-contract-common", "nym-node-requests", "nym-node-tester-utils", "nym-pemstore", @@ -7608,6 +7609,21 @@ dependencies = [ "zeroize", ] +[[package]] +name = "nym-node-families-contract-common" +version = "1.21.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers", + "cw-utils", + "nym-contracts-common", + "nym-mixnet-contract-common", + "schemars 0.8.22", + "serde", + "thiserror 2.0.12", +] + [[package]] name = "nym-node-metrics" version = "1.21.0" @@ -7688,6 +7704,7 @@ dependencies = [ "humantime", "itertools 0.14.0", "moka", + "nym-api-requests", "nym-bin-common", "nym-contracts-common", "nym-credential-proxy-lib", @@ -8572,6 +8589,7 @@ dependencies = [ "nym-mixnet-contract-common", "nym-multisig-contract-common", "nym-network-defaults", + "nym-node-families-contract-common", "nym-performance-contract-common", "nym-serde-helpers", "nym-vesting-contract-common", diff --git a/Cargo.toml b/Cargo.toml index db10a4b7ec..5d7ea433b9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,7 +31,6 @@ members = [ "common/client-libs/mixnet-client", "common/client-libs/validator-client", "common/commands", - "common/nym-common", "common/config", "common/cosmwasm-smart-contracts/coconut-dkg", "common/cosmwasm-smart-contracts/contracts-common", @@ -41,6 +40,7 @@ members = [ "common/cosmwasm-smart-contracts/group-contract", "common/cosmwasm-smart-contracts/mixnet-contract", "common/cosmwasm-smart-contracts/multisig-contract", + "common/cosmwasm-smart-contracts/node-families-contract", "common/cosmwasm-smart-contracts/nym-performance-contract", "common/cosmwasm-smart-contracts/nym-pool-contract", "common/cosmwasm-smart-contracts/vesting-contract", @@ -70,11 +70,14 @@ members = [ "common/node-tester-utils", "common/nonexhaustive-delayqueue", "common/nym-cache", + "common/nym-common", "common/nym-connection-monitor", "common/nym-id", "common/nym-kcp", - "common/nym-lp", "common/nym-kkt", + "common/nym-kkt-ciphersuite", + "common/nym-kkt-context", + "common/nym-lp", "common/nym-metrics", "common/nym_offline_compact_ecash", "common/nymnoise", @@ -90,9 +93,9 @@ members = [ "common/nymsphinx/params", "common/nymsphinx/routing", "common/nymsphinx/types", - "common/nyxd-scraper-sqlite", "common/nyxd-scraper-psql", "common/nyxd-scraper-shared", + "common/nyxd-scraper-sqlite", "common/pemstore", "common/registration", "common/serde-helpers", @@ -122,6 +125,7 @@ members = [ "common/zulip-client", "documentation/autodoc", "gateway", + "integration-tests", "nym-api", "nym-api/nym-api-requests", "nym-authenticator-client", @@ -129,6 +133,7 @@ members = [ "nym-credential-proxy/nym-credential-proxy", "nym-credential-proxy/nym-credential-proxy-requests", "nym-data-observatory", + "nym-gateway-probe", "nym-ip-packet-client", "nym-network-monitor", "nym-node", @@ -140,6 +145,7 @@ members = [ "nym-outfox", "nym-registration-client", "nym-signers-monitor", + "nym-sqlx-pool-guard", "nym-statistics-api", "nym-validator-rewarder", "nyx-chain-watcher", @@ -147,19 +153,18 @@ members = [ "sdk/ffi/go", "sdk/ffi/shared", "sdk/rust/nym-sdk", - "smolmix/core", "service-providers/common", "service-providers/ip-packet-router", "service-providers/network-requester", - "nym-sqlx-pool-guard", + "smolmix/core", "tools/echo-server", "tools/internal/contract-state-importer/importer-cli", "tools/internal/contract-state-importer/importer-contract", + "tools/internal/localnet-orchestrator", + "tools/internal/localnet-orchestrator/dkg-bypass-contract", "tools/internal/mixnet-connectivity-check", # "tools/internal/sdk-version-bump", "tools/internal/ssl-inject", - "tools/internal/localnet-orchestrator", - "tools/internal/localnet-orchestrator/dkg-bypass-contract", "tools/internal/validator-status-check", "tools/nym-cli", "tools/nym-id-cli", @@ -172,27 +177,23 @@ members = [ "wasm/mix-fetch", "wasm/node-tester", "wasm/zknym-lib", - "nym-gateway-probe", - "integration-tests", - "common/nym-kkt-ciphersuite", - "common/nym-kkt-context", ] default-members = [ "clients/native", "clients/socks5", - "nym-authenticator-client", "nym-api", + "nym-authenticator-client", "nym-credential-proxy/nym-credential-proxy", "nym-node", + "nym-registration-client", "nym-statistics-api", "nym-validator-rewarder", "nyx-chain-watcher", "service-providers/ip-packet-router", "service-providers/network-requester", + "tools/internal/localnet-orchestrator", "tools/nymvisor", - "nym-registration-client", - "tools/internal/localnet-orchestrator" ] exclude = ["contracts", "nym-wallet", "cpu-cycles"] @@ -472,6 +473,7 @@ nym-noise-keys = { version = "1.21.0", path = "common/nymnoise/keys" } nym-nonexhaustive-delayqueue = { version = "1.21.0", path = "common/nonexhaustive-delayqueue" } nym-node-requests = { version = "1.21.0", path = "nym-node/nym-node-requests", default-features = false } nym-node-metrics = { version = "1.21.0", path = "nym-node/nym-node-metrics" } +nym-node-families-contract-common = { version = "1.21.0", path = "common/cosmwasm-smart-contracts/node-families-contract" } nym-ordered-buffer = { version = "1.21.0", path = "common/socks5/ordered-buffer" } nym-outfox = { version = "1.21.0", path = "nym-outfox" } nym-registration-common = { version = "1.21.0", path = "common/registration" } @@ -617,3 +619,4 @@ exit = "deny" panic = "deny" unimplemented = "deny" unreachable = "deny" + diff --git a/common/client-libs/validator-client/Cargo.toml b/common/client-libs/validator-client/Cargo.toml index ea1de63563..ca5424537f 100644 --- a/common/client-libs/validator-client/Cargo.toml +++ b/common/client-libs/validator-client/Cargo.toml @@ -26,6 +26,7 @@ nym-ecash-contract-common = { workspace = true } nym-multisig-contract-common = { workspace = true } nym-group-contract-common = { workspace = true } nym-performance-contract-common = { workspace = true } +nym-node-families-contract-common = { workspace = true } nym-serde-helpers = { workspace = true, features = ["hex", "base64"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } diff --git a/common/client-libs/validator-client/src/nym_api/mod.rs b/common/client-libs/validator-client/src/nym_api/mod.rs index e2dffe496e..db6daad7a9 100644 --- a/common/client-libs/validator-client/src/nym_api/mod.rs +++ b/common/client-libs/validator-client/src/nym_api/mod.rs @@ -15,6 +15,7 @@ use nym_api_requests::ecash::models::{ VerifyEcashTicketBody, }; use nym_api_requests::ecash::VerificationKeyResponse; +use nym_api_requests::models::node_families::NodeFamily; use nym_api_requests::models::{ AnnotationResponse, ApiHealthResponse, BinaryBuildInformationOwned, ChainBlocksStatusResponse, ChainStatusResponse, KeyRotationInfoResponse, NodePerformanceResponse, NodeRefreshBody, @@ -389,6 +390,45 @@ pub trait NymApiClientExt: ApiClient { Ok(bonds) } + #[tracing::instrument(level = "debug", skip_all)] + async fn get_node_families( + &self, + page: Option, + per_page: Option, + ) -> Result, NymAPIError> { + let mut params = Vec::new(); + if let Some(page) = page { + params.push(("page", page.to_string())) + } + if let Some(per_page) = per_page { + params.push(("per_page", per_page.to_string())) + } + self.get_json( + &[routes::V1_API_VERSION, routes::NODE_FAMILIES_ROUTES], + ¶ms, + ) + .await + } + + async fn get_all_node_families(&self) -> Result, NymAPIError> { + // TODO: deal with paging in macro or some helper function or something, because it's the same pattern everywhere + let mut page = 0; + let mut families = Vec::new(); + + loop { + let mut res = self.get_node_families(Some(page), None).await?; + + families.append(&mut res.data); + if families.len() < res.pagination.total { + page += 1 + } else { + break; + } + } + + Ok(families) + } + #[deprecated] #[tracing::instrument(level = "debug", skip_all)] async fn get_basic_mixnodes(&self) -> Result, NymAPIError> { diff --git a/common/client-libs/validator-client/src/nym_api/routes.rs b/common/client-libs/validator-client/src/nym_api/routes.rs index 755b1282ef..1181a9d959 100644 --- a/common/client-libs/validator-client/src/nym_api/routes.rs +++ b/common/client-libs/validator-client/src/nym_api/routes.rs @@ -38,6 +38,7 @@ pub mod ecash { } pub const NYM_NODES_ROUTES: &str = "nym-nodes"; +pub const NODE_FAMILIES_ROUTES: &str = "node-families"; pub use nym_nodes::*; pub mod nym_nodes { diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs index ad7db0991b..ffc08e89c7 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs @@ -13,6 +13,7 @@ pub mod ecash_query_client; pub mod group_query_client; pub mod mixnet_query_client; pub mod multisig_query_client; +pub mod node_families_query_client; pub mod performance_query_client; pub mod vesting_query_client; @@ -22,6 +23,7 @@ pub mod ecash_signing_client; pub mod group_signing_client; pub mod mixnet_signing_client; pub mod multisig_signing_client; +pub mod node_families_signing_client; pub mod performance_signing_client; pub mod vesting_signing_client; @@ -31,6 +33,7 @@ pub use ecash_query_client::{EcashQueryClient, PagedEcashQueryClient}; pub use group_query_client::{GroupQueryClient, PagedGroupQueryClient}; pub use mixnet_query_client::{MixnetQueryClient, PagedMixnetQueryClient}; pub use multisig_query_client::{MultisigQueryClient, PagedMultisigQueryClient}; +pub use node_families_query_client::{NodeFamiliesQueryClient, PagedNodeFamiliesQueryClient}; pub use performance_query_client::{PagedPerformanceQueryClient, PerformanceQueryClient}; pub use vesting_query_client::{PagedVestingQueryClient, VestingQueryClient}; @@ -40,6 +43,7 @@ pub use ecash_signing_client::EcashSigningClient; pub use group_signing_client::GroupSigningClient; pub use mixnet_signing_client::MixnetSigningClient; pub use multisig_signing_client::MultisigSigningClient; +pub use node_families_signing_client::NodeFamiliesSigningClient; pub use performance_signing_client::PerformanceSigningClient; pub use vesting_signing_client::VestingSigningClient; @@ -49,6 +53,7 @@ pub trait NymContractsProvider { fn mixnet_contract_address(&self) -> Option<&AccountId>; fn vesting_contract_address(&self) -> Option<&AccountId>; fn performance_contract_address(&self) -> Option<&AccountId>; + fn node_families_contract_address(&self) -> Option<&AccountId>; // coconut-related fn ecash_contract_address(&self) -> Option<&AccountId>; @@ -62,6 +67,7 @@ pub struct TypedNymContracts { pub mixnet_contract_address: Option, pub vesting_contract_address: Option, pub performance_contract_address: Option, + pub node_families_contract_address: Option, pub ecash_contract_address: Option, pub group_contract_address: Option, @@ -86,6 +92,10 @@ impl TryFrom for TypedNymContracts { .performance_contract_address .map(|addr| addr.parse()) .transpose()?, + node_families_contract_address: value + .node_families_contract_address + .map(|addr| addr.parse()) + .transpose()?, ecash_contract_address: value .ecash_contract_address .map(|addr| addr.parse()) diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/node_families_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/node_families_query_client.rs new file mode 100644 index 0000000000..dd62bb7dc6 --- /dev/null +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/node_families_query_client.rs @@ -0,0 +1,441 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::collect_paged; +use crate::nyxd::contract_traits::NymContractsProvider; +use crate::nyxd::error::NyxdError; +use crate::nyxd::CosmWasmClient; +use async_trait::async_trait; +use cosmrs::AccountId; +use serde::Deserialize; + +use nym_mixnet_contract_common::NodeId; +pub use nym_node_families_contract_common::{ + msg::QueryMsg as NodeFamiliesQueryMsg, AllFamilyMembersPagedResponse, + AllPastFamilyInvitationsPagedResponse, FamiliesPagedResponse, FamilyMemberRecord, + FamilyMembersPagedResponse, GlobalPastFamilyInvitationCursor, NodeFamily, + NodeFamilyByNameResponse, NodeFamilyByOwnerResponse, NodeFamilyId, + NodeFamilyMembershipResponse, NodeFamilyResponse, PastFamilyInvitation, + PastFamilyInvitationCursor, PastFamilyInvitationForNodeCursor, + PastFamilyInvitationsForNodePagedResponse, PastFamilyInvitationsPagedResponse, + PastFamilyMember, PastFamilyMemberCursor, PastFamilyMemberForNodeCursor, + PastFamilyMembersForNodePagedResponse, PastFamilyMembersPagedResponse, + PendingFamilyInvitationDetails, PendingFamilyInvitationResponse, + PendingFamilyInvitationsPagedResponse, PendingInvitationsForNodePagedResponse, + PendingInvitationsPagedResponse, +}; + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +pub trait NodeFamiliesQueryClient { + async fn query_node_families_contract( + &self, + query: NodeFamiliesQueryMsg, + ) -> Result + where + for<'a> T: Deserialize<'a>; + + async fn get_family_by_id( + &self, + family_id: NodeFamilyId, + ) -> Result { + self.query_node_families_contract(NodeFamiliesQueryMsg::GetFamilyById { family_id }) + .await + } + + async fn get_family_by_owner( + &self, + owner: &AccountId, + ) -> Result { + self.query_node_families_contract(NodeFamiliesQueryMsg::GetFamilyByOwner { + owner: owner.to_string(), + }) + .await + } + + async fn get_family_by_name( + &self, + name: String, + ) -> Result { + self.query_node_families_contract(NodeFamiliesQueryMsg::GetFamilyByName { name }) + .await + } + + async fn get_families_paged( + &self, + start_after: Option, + limit: Option, + ) -> Result { + self.query_node_families_contract(NodeFamiliesQueryMsg::GetFamiliesPaged { + start_after, + limit, + }) + .await + } + + async fn get_family_membership( + &self, + node_id: NodeId, + ) -> Result { + self.query_node_families_contract(NodeFamiliesQueryMsg::GetFamilyMembership { node_id }) + .await + } + + async fn get_family_members_paged( + &self, + family_id: NodeFamilyId, + start_after: Option, + limit: Option, + ) -> Result { + self.query_node_families_contract(NodeFamiliesQueryMsg::GetFamilyMembersPaged { + family_id, + start_after, + limit, + }) + .await + } + + async fn get_all_family_members_paged( + &self, + start_after: Option, + limit: Option, + ) -> Result { + self.query_node_families_contract(NodeFamiliesQueryMsg::GetAllFamilyMembersPaged { + start_after, + limit, + }) + .await + } + + async fn get_pending_invitation( + &self, + family_id: NodeFamilyId, + node_id: NodeId, + ) -> Result { + self.query_node_families_contract(NodeFamiliesQueryMsg::GetPendingInvitation { + family_id, + node_id, + }) + .await + } + + async fn get_pending_invitations_for_family_paged( + &self, + family_id: NodeFamilyId, + start_after: Option, + limit: Option, + ) -> Result { + self.query_node_families_contract( + NodeFamiliesQueryMsg::GetPendingInvitationsForFamilyPaged { + family_id, + start_after, + limit, + }, + ) + .await + } + + async fn get_pending_invitations_for_node_paged( + &self, + node_id: NodeId, + start_after: Option, + limit: Option, + ) -> Result { + self.query_node_families_contract(NodeFamiliesQueryMsg::GetPendingInvitationsForNodePaged { + node_id, + start_after, + limit, + }) + .await + } + + async fn get_all_pending_invitations_paged( + &self, + start_after: Option<(NodeFamilyId, NodeId)>, + limit: Option, + ) -> Result { + self.query_node_families_contract(NodeFamiliesQueryMsg::GetAllPendingInvitationsPaged { + start_after, + limit, + }) + .await + } + + async fn get_past_invitations_for_family_paged( + &self, + family_id: NodeFamilyId, + start_after: Option, + limit: Option, + ) -> Result { + self.query_node_families_contract(NodeFamiliesQueryMsg::GetPastInvitationsForFamilyPaged { + family_id, + start_after, + limit, + }) + .await + } + + async fn get_past_invitations_for_node_paged( + &self, + node_id: NodeId, + start_after: Option, + limit: Option, + ) -> Result { + self.query_node_families_contract(NodeFamiliesQueryMsg::GetPastInvitationsForNodePaged { + node_id, + start_after, + limit, + }) + .await + } + + async fn get_all_past_invitations_paged( + &self, + start_after: Option, + limit: Option, + ) -> Result { + self.query_node_families_contract(NodeFamiliesQueryMsg::GetAllPastInvitationsPaged { + start_after, + limit, + }) + .await + } + + async fn get_past_members_for_family_paged( + &self, + family_id: NodeFamilyId, + start_after: Option, + limit: Option, + ) -> Result { + self.query_node_families_contract(NodeFamiliesQueryMsg::GetPastMembersForFamilyPaged { + family_id, + start_after, + limit, + }) + .await + } + + async fn get_past_members_for_node_paged( + &self, + node_id: NodeId, + start_after: Option, + limit: Option, + ) -> Result { + self.query_node_families_contract(NodeFamiliesQueryMsg::GetPastMembersForNodePaged { + node_id, + start_after, + limit, + }) + .await + } +} + +// extension trait to the query client to deal with the paged queries +// (it didn't feel appropriate to combine it with the existing trait) +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +pub trait PagedNodeFamiliesQueryClient: NodeFamiliesQueryClient { + async fn get_all_families(&self) -> Result, NyxdError> { + collect_paged!(self, get_families_paged, families) + } + + async fn get_all_family_members_for_family( + &self, + family_id: NodeFamilyId, + ) -> Result, NyxdError> { + collect_paged!(self, get_family_members_paged, members, family_id) + } + + async fn get_all_family_members(&self) -> Result, NyxdError> { + collect_paged!(self, get_all_family_members_paged, members) + } + + async fn get_all_pending_invitations_for_family( + &self, + family_id: NodeFamilyId, + ) -> Result, NyxdError> { + collect_paged!( + self, + get_pending_invitations_for_family_paged, + invitations, + family_id + ) + } + + async fn get_all_pending_invitations_for_node( + &self, + node_id: NodeId, + ) -> Result, NyxdError> { + collect_paged!( + self, + get_pending_invitations_for_node_paged, + invitations, + node_id + ) + } + + async fn get_all_pending_invitations( + &self, + ) -> Result, NyxdError> { + collect_paged!(self, get_all_pending_invitations_paged, invitations) + } + + async fn get_all_past_invitations_for_family( + &self, + family_id: NodeFamilyId, + ) -> Result, NyxdError> { + collect_paged!( + self, + get_past_invitations_for_family_paged, + invitations, + family_id + ) + } + + async fn get_all_past_invitations_for_node( + &self, + node_id: NodeId, + ) -> Result, NyxdError> { + collect_paged!( + self, + get_past_invitations_for_node_paged, + invitations, + node_id + ) + } + + async fn get_all_past_invitations(&self) -> Result, NyxdError> { + collect_paged!(self, get_all_past_invitations_paged, invitations) + } + + async fn get_all_past_members_for_family( + &self, + family_id: NodeFamilyId, + ) -> Result, NyxdError> { + collect_paged!(self, get_past_members_for_family_paged, members, family_id) + } + + async fn get_all_past_members_for_node( + &self, + node_id: NodeId, + ) -> Result, NyxdError> { + collect_paged!(self, get_past_members_for_node_paged, members, node_id) + } +} + +#[async_trait] +impl PagedNodeFamiliesQueryClient for T where T: NodeFamiliesQueryClient {} + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +impl NodeFamiliesQueryClient for C +where + C: CosmWasmClient + NymContractsProvider + Send + Sync, +{ + async fn query_node_families_contract( + &self, + query: NodeFamiliesQueryMsg, + ) -> Result + where + for<'a> T: Deserialize<'a>, + { + let node_families_contract_address = &self + .node_families_contract_address() + .ok_or_else(|| NyxdError::unavailable_contract_address("node families contract"))?; + self.query_contract_smart(node_families_contract_address, &query) + .await + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::nyxd::contract_traits::tests::IgnoreValue; + use nym_node_families_contract_common::QueryMsg; + + // it's enough that this compiles and clippy is happy about it + #[allow(dead_code)] + fn all_query_variants_are_covered( + client: C, + msg: NodeFamiliesQueryMsg, + ) { + match msg { + NodeFamiliesQueryMsg::GetFamilyById { family_id } => { + client.get_family_by_id(family_id).ignore() + } + NodeFamiliesQueryMsg::GetFamilyByOwner { owner } => { + client.get_family_by_owner(&owner.parse().unwrap()).ignore() + } + NodeFamiliesQueryMsg::GetFamilyByName { name } => { + client.get_family_by_name(name).ignore() + } + NodeFamiliesQueryMsg::GetFamiliesPaged { start_after, limit } => { + client.get_families_paged(start_after, limit).ignore() + } + NodeFamiliesQueryMsg::GetFamilyMembership { node_id } => { + client.get_family_membership(node_id).ignore() + } + NodeFamiliesQueryMsg::GetFamilyMembersPaged { + family_id, + start_after, + limit, + } => client + .get_family_members_paged(family_id, start_after, limit) + .ignore(), + NodeFamiliesQueryMsg::GetAllFamilyMembersPaged { start_after, limit } => client + .get_all_family_members_paged(start_after, limit) + .ignore(), + NodeFamiliesQueryMsg::GetPendingInvitation { family_id, node_id } => { + client.get_pending_invitation(family_id, node_id).ignore() + } + NodeFamiliesQueryMsg::GetPendingInvitationsForFamilyPaged { + family_id, + start_after, + limit, + } => client + .get_pending_invitations_for_family_paged(family_id, start_after, limit) + .ignore(), + NodeFamiliesQueryMsg::GetPendingInvitationsForNodePaged { + node_id, + start_after, + limit, + } => client + .get_pending_invitations_for_node_paged(node_id, start_after, limit) + .ignore(), + NodeFamiliesQueryMsg::GetAllPendingInvitationsPaged { start_after, limit } => client + .get_all_pending_invitations_paged(start_after, limit) + .ignore(), + NodeFamiliesQueryMsg::GetPastInvitationsForFamilyPaged { + family_id, + start_after, + limit, + } => client + .get_past_invitations_for_family_paged(family_id, start_after, limit) + .ignore(), + NodeFamiliesQueryMsg::GetPastInvitationsForNodePaged { + node_id, + start_after, + limit, + } => client + .get_past_invitations_for_node_paged(node_id, start_after, limit) + .ignore(), + NodeFamiliesQueryMsg::GetAllPastInvitationsPaged { start_after, limit } => client + .get_all_past_invitations_paged(start_after, limit) + .ignore(), + NodeFamiliesQueryMsg::GetPastMembersForFamilyPaged { + family_id, + start_after, + limit, + } => client + .get_past_members_for_family_paged(family_id, start_after, limit) + .ignore(), + QueryMsg::GetPastMembersForNodePaged { + node_id, + start_after, + limit, + } => client + .get_past_members_for_node_paged(node_id, start_after, limit) + .ignore(), + }; + } +} diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/node_families_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/node_families_signing_client.rs new file mode 100644 index 0000000000..34690c8be5 --- /dev/null +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/node_families_signing_client.rs @@ -0,0 +1,254 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::nyxd::coin::Coin; +use crate::nyxd::contract_traits::NymContractsProvider; +use crate::nyxd::cosmwasm_client::types::ExecuteResult; +use crate::nyxd::error::NyxdError; +use crate::nyxd::{Fee, SigningCosmWasmClient}; +use crate::signing::signer::OfflineSigner; +use async_trait::async_trait; +use nym_mixnet_contract_common::NodeId; +use nym_node_families_contract_common::{ + Config, ExecuteMsg as NodeFamiliesExecuteMsg, NodeFamilyId, +}; + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +pub trait NodeFamiliesSigningClient { + async fn execute_node_families_contract( + &self, + fee: Option, + msg: NodeFamiliesExecuteMsg, + memo: String, + funds: Vec, + ) -> Result; + + async fn update_node_families_config( + &self, + config: Config, + fee: Option, + ) -> Result { + self.execute_node_families_contract( + fee, + NodeFamiliesExecuteMsg::UpdateConfig { config }, + "NodeFamiliesContract::UpdateConfig".to_string(), + vec![], + ) + .await + } + + async fn create_family( + &self, + name: String, + description: String, + fee: Option, + creation_fee: Vec, + ) -> Result { + self.execute_node_families_contract( + fee, + NodeFamiliesExecuteMsg::CreateFamily { name, description }, + "NodeFamiliesContract::CreateFamily".to_string(), + creation_fee, + ) + .await + } + + async fn disband_family(&self, fee: Option) -> Result { + self.execute_node_families_contract( + fee, + NodeFamiliesExecuteMsg::DisbandFamily {}, + "NodeFamiliesContract::DisbandFamily".to_string(), + vec![], + ) + .await + } + + async fn invite_to_family( + &self, + node_id: NodeId, + validity_secs: Option, + fee: Option, + ) -> Result { + self.execute_node_families_contract( + fee, + NodeFamiliesExecuteMsg::InviteToFamily { + node_id, + validity_secs, + }, + "NodeFamiliesContract::InviteToFamily".to_string(), + vec![], + ) + .await + } + + async fn revoke_family_invitation( + &self, + node_id: NodeId, + fee: Option, + ) -> Result { + self.execute_node_families_contract( + fee, + NodeFamiliesExecuteMsg::RevokeFamilyInvitation { node_id }, + "NodeFamiliesContract::RevokeFamilyInvitation".to_string(), + vec![], + ) + .await + } + + async fn accept_family_invitation( + &self, + family_id: NodeFamilyId, + node_id: NodeId, + fee: Option, + ) -> Result { + self.execute_node_families_contract( + fee, + NodeFamiliesExecuteMsg::AcceptFamilyInvitation { family_id, node_id }, + "NodeFamiliesContract::AcceptFamilyInvitation".to_string(), + vec![], + ) + .await + } + + async fn reject_family_invitation( + &self, + family_id: NodeFamilyId, + node_id: NodeId, + fee: Option, + ) -> Result { + self.execute_node_families_contract( + fee, + NodeFamiliesExecuteMsg::RejectFamilyInvitation { family_id, node_id }, + "NodeFamiliesContract::RejectFamilyInvitation".to_string(), + vec![], + ) + .await + } + + async fn leave_family( + &self, + node_id: NodeId, + fee: Option, + ) -> Result { + self.execute_node_families_contract( + fee, + NodeFamiliesExecuteMsg::LeaveFamily { node_id }, + "NodeFamiliesContract::LeaveFamily".to_string(), + vec![], + ) + .await + } + + async fn kick_from_family( + &self, + node_id: NodeId, + fee: Option, + ) -> Result { + self.execute_node_families_contract( + fee, + NodeFamiliesExecuteMsg::KickFromFamily { node_id }, + "NodeFamiliesContract::KickFromFamily".to_string(), + vec![], + ) + .await + } + + /// Cross-contract callback fired by the mixnet contract on node unbonding. + /// Exposed for completeness; the families contract rejects this call from + /// any sender other than the configured mixnet contract address. + async fn on_nym_node_unbond( + &self, + node_id: NodeId, + fee: Option, + ) -> Result { + self.execute_node_families_contract( + fee, + NodeFamiliesExecuteMsg::OnNymNodeUnbond { node_id }, + "NodeFamiliesContract::OnNymNodeUnbond".to_string(), + vec![], + ) + .await + } +} + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +impl NodeFamiliesSigningClient for C +where + C: SigningCosmWasmClient + NymContractsProvider + Sync, + NyxdError: From<::Error>, +{ + async fn execute_node_families_contract( + &self, + fee: Option, + msg: NodeFamiliesExecuteMsg, + memo: String, + funds: Vec, + ) -> Result { + let node_families_contract_address = &self + .node_families_contract_address() + .ok_or_else(|| NyxdError::unavailable_contract_address("node families contract"))?; + + let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier()))); + + let signer_address = &self.signer_addresses()[0]; + self.execute( + signer_address, + node_families_contract_address, + &msg, + fee, + memo, + funds, + ) + .await + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::nyxd::contract_traits::tests::IgnoreValue; + use nym_node_families_contract_common::ExecuteMsg; + + // it's enough that this compiles and clippy is happy about it + #[allow(dead_code)] + fn all_execute_variants_are_covered( + client: C, + msg: NodeFamiliesExecuteMsg, + ) { + match msg { + NodeFamiliesExecuteMsg::UpdateConfig { config } => { + client.update_node_families_config(config, None).ignore() + } + NodeFamiliesExecuteMsg::CreateFamily { name, description } => client + .create_family(name, description, None, vec![]) + .ignore(), + NodeFamiliesExecuteMsg::DisbandFamily {} => client.disband_family(None).ignore(), + NodeFamiliesExecuteMsg::InviteToFamily { + node_id, + validity_secs, + } => client + .invite_to_family(node_id, validity_secs, None) + .ignore(), + NodeFamiliesExecuteMsg::RevokeFamilyInvitation { node_id } => { + client.revoke_family_invitation(node_id, None).ignore() + } + NodeFamiliesExecuteMsg::AcceptFamilyInvitation { family_id, node_id } => client + .accept_family_invitation(family_id, node_id, None) + .ignore(), + NodeFamiliesExecuteMsg::RejectFamilyInvitation { family_id, node_id } => client + .reject_family_invitation(family_id, node_id, None) + .ignore(), + NodeFamiliesExecuteMsg::LeaveFamily { node_id } => { + client.leave_family(node_id, None).ignore() + } + NodeFamiliesExecuteMsg::KickFromFamily { node_id } => { + client.kick_from_family(node_id, None).ignore() + } + ExecuteMsg::OnNymNodeUnbond { node_id } => { + client.on_nym_node_unbond(node_id, None).ignore() + } + }; + } +} diff --git a/common/client-libs/validator-client/src/nyxd/mod.rs b/common/client-libs/validator-client/src/nyxd/mod.rs index 0c931c2bd5..bb55c52bcb 100644 --- a/common/client-libs/validator-client/src/nyxd/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/mod.rs @@ -286,6 +286,10 @@ impl NyxdClient { self.config.contracts.multisig_contract_address = Some(address); } + pub fn set_node_families_contract_address(&mut self, address: AccountId) { + self.config.contracts.node_families_contract_address = Some(address); + } + pub fn set_simulated_gas_multiplier(&mut self, multiplier: f32) { self.config.simulated_gas_multiplier = multiplier; } @@ -304,6 +308,13 @@ impl NymContractsProvider for NyxdClient { self.config.contracts.performance_contract_address.as_ref() } + fn node_families_contract_address(&self) -> Option<&AccountId> { + self.config + .contracts + .node_families_contract_address + .as_ref() + } + fn ecash_contract_address(&self) -> Option<&AccountId> { self.config.contracts.ecash_contract_address.as_ref() } diff --git a/common/commands/src/validator/cosmwasm/generators/mixnet.rs b/common/commands/src/validator/cosmwasm/generators/mixnet.rs index 9226a02653..b8e561f5ed 100644 --- a/common/commands/src/validator/cosmwasm/generators/mixnet.rs +++ b/common/commands/src/validator/cosmwasm/generators/mixnet.rs @@ -30,6 +30,9 @@ pub struct Args { #[clap(long)] pub vesting_contract_address: Option, + #[clap(long)] + pub node_families_contract_address: Option, + #[clap(long)] pub rewarding_denom: Option, @@ -130,6 +133,14 @@ pub async fn generate(args: Args) { .expect("Failed converting vesting contract address to AccountId") }); + let node_families_contract_address = args.node_families_contract_address.unwrap_or_else(|| { + let address = + std::env::var(nym_network_defaults::var_names::NODE_FAMILIES_CONTRACT_ADDRESS) + .expect("node families contract address has to be set"); + AccountId::from_str(address.as_str()) + .expect("Failed converting node families contract address to AccountId") + }); + let rewarding_denom = args.rewarding_denom.unwrap_or_else(|| { std::env::var(nym_network_defaults::var_names::MIX_DENOM) .expect("Rewarding (mix) denom has to be set") @@ -142,6 +153,7 @@ pub async fn generate(args: Args) { let instantiate_msg = InstantiateMsg { rewarding_validator_address: rewarding_validator_address.to_string(), vesting_contract_address: vesting_contract_address.to_string(), + node_families_contract_address: node_families_contract_address.to_string(), rewarding_denom, epochs_in_interval: args.epochs_in_interval, epoch_duration: Duration::from_secs(args.epoch_duration), diff --git a/common/cosmwasm-smart-contracts/contracts-common-testing/src/tester/basic_traits.rs b/common/cosmwasm-smart-contracts/contracts-common-testing/src/tester/basic_traits.rs index facc2983de..f543f019be 100644 --- a/common/cosmwasm-smart-contracts/contracts-common-testing/src/tester/basic_traits.rs +++ b/common/cosmwasm-smart-contracts/contracts-common-testing/src/tester/basic_traits.rs @@ -26,6 +26,14 @@ pub trait ContractOpts { fn addr_make(&self, input: &str) -> Addr; + fn make_sender_with_funds(&self, input: &str, funds: &[Coin]) -> MessageInfo { + message_info(&self.addr_make(input), funds) + } + + fn make_sender(&self, input: &str) -> MessageInfo { + self.make_sender_with_funds(input, &[]) + } + fn deps_mut_env(&mut self) -> (DepsMut<'_>, Env) { let env = self.env().clone(); (self.deps_mut(), env) diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/helpers.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/helpers.rs index dc56386238..43dc8eb6be 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/helpers.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/helpers.rs @@ -3,12 +3,121 @@ use crate::error::MixnetContractError; use crate::mixnode::PendingMixNodeChanges; +use crate::nym_node::NodeOwnershipResponse; use crate::{ - EpochEventId, IntervalEventId, MixNodeBond, MixNodeDetails, NodeId, NodeRewarding, NymNodeBond, - NymNodeDetails, PendingNodeChanges, + EpochEventId, EpochId, Interval, IntervalEventId, MixNodeBond, MixNodeDetails, NodeId, + NodeRewarding, NymNodeBond, NymNodeDetails, PendingNodeChanges, QueryMsg, }; -use cosmwasm_std::{Coin, Decimal, StdError, StdResult, Uint128}; +use cosmwasm_std::{ + Addr, Binary, Coin, CustomQuery, Decimal, QuerierWrapper, StdError, StdResult, Uint128, + from_json, +}; +use cw_storage_plus::{Key, Namespace, Path, PrimaryKey}; use nym_contracts_common::IdentityKeyRef; +use serde::de::DeserializeOwned; +use std::ops::Deref; + +pub trait MixnetContractQuerier { + #[allow(dead_code)] + fn query_mixnet_contract( + &self, + address: impl Into, + msg: &QueryMsg, + ) -> StdResult; + + fn query_mixnet_contract_storage( + &self, + address: impl Into, + key: impl Into, + ) -> StdResult>>; + + fn query_mixnet_contract_storage_value( + &self, + address: impl Into, + key: impl Into, + ) -> StdResult> { + match self.query_mixnet_contract_storage(address, key)? { + None => Ok(None), + Some(value) => Ok(Some(from_json(&value)?)), + } + } + + fn query_current_mixnet_interval(&self, address: impl Into) -> StdResult { + self.query_mixnet_contract_storage_value(address, b"ci")? + .ok_or(StdError::not_found( + "unable to retrieve interval information from the mixnet contract storage", + )) + } + + fn query_current_absolute_mixnet_epoch_id( + &self, + address: impl Into, + ) -> StdResult { + self.query_current_mixnet_interval(address) + .map(|interval| interval.current_epoch_absolute_id()) + } + + fn check_node_existence(&self, address: impl Into, node_id: NodeId) -> StdResult { + let mixnet_contract_address = address.into(); + + if let Some(nym_node) = self.query_nymnode_bond(mixnet_contract_address.clone(), node_id)? { + return Ok(!nym_node.is_unbonding); + } + + Ok(false) + } + + fn query_nymnode_bond( + &self, + address: impl Into, + node_id: NodeId, + ) -> StdResult> { + // construct proper map key + let pk_namespace = "nn"; + let path: Path = Path::new( + Namespace::from_static_str(pk_namespace).as_slice(), + &node_id.key().iter().map(Key::as_ref).collect::>(), + ); + let storage_key = path.deref(); + + self.query_mixnet_contract_storage_value(address, storage_key) + } + + fn query_nymnode_ownership( + &self, + address: impl Into, + owner: &Addr, + ) -> StdResult> { + let resp: NodeOwnershipResponse = self.query_mixnet_contract( + address, + &QueryMsg::GetOwnedNymNode { + address: owner.to_string(), + }, + )?; + Ok(resp.details.map(|d| d.bond_information)) + } +} + +impl MixnetContractQuerier for QuerierWrapper<'_, C> +where + C: CustomQuery, +{ + fn query_mixnet_contract( + &self, + address: impl Into, + msg: &QueryMsg, + ) -> StdResult { + self.query_wasm_smart(address, msg) + } + + fn query_mixnet_contract_storage( + &self, + address: impl Into, + key: impl Into, + ) -> StdResult>> { + self.query_wasm_raw(address, key) + } +} #[track_caller] pub fn compare_decimals(a: Decimal, b: Decimal, epsilon: Option) { diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/lib.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/lib.rs index 3c6f4b6b08..ac084abb6c 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/lib.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/lib.rs @@ -30,6 +30,7 @@ pub use gateway::{ Gateway, GatewayBond, GatewayBondResponse, GatewayConfigUpdate, GatewayOwnershipResponse, PagedGatewayResponse, }; +pub use helpers::MixnetContractQuerier; pub use interval::{ CurrentIntervalResponse, EpochId, EpochState, EpochStatus, Interval, IntervalId, }; diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs index 66f7d05113..a0f55f108c 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/mixnode.rs @@ -190,6 +190,10 @@ impl NodeRewarding { truncate_reward(self.operator, denom) } + pub fn delegations_with_reward(&self, denom: impl Into) -> Coin { + truncate_reward(self.delegates, denom) + } + pub fn pending_delegator_reward(&self, delegation: &Delegation) -> StdResult { let delegator_reward = self.determine_delegation_reward(delegation)?; Ok(truncate_reward(delegator_reward, &delegation.amount.denom)) diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/msg.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/msg.rs index 4b0d31016d..f8b34b2898 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/msg.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/msg.rs @@ -63,6 +63,7 @@ use nym_contracts_common::{ContractBuildInformation, signing::Nonce}; pub struct InstantiateMsg { pub rewarding_validator_address: String, pub vesting_contract_address: String, + pub node_families_contract_address: String, pub rewarding_denom: String, pub epochs_in_interval: u32, @@ -885,4 +886,5 @@ pub enum QueryMsg { pub struct MigrateMsg { pub unsafe_skip_state_updates: Option, pub vesting_contract_address: Option, + pub node_families_contract_address: String, } diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/types.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/types.rs index 1b0590df1f..0cb427e201 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/types.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/types.rs @@ -212,6 +212,10 @@ pub struct ContractState { /// track-related messages. pub vesting_contract_address: Addr, + /// Address of the node families contract. It is called whenever nym-node unbonds + /// so that it could be removed from any family it belongs to. + pub node_families_contract_address: Addr, + /// The expected denom used for rewarding (and realistically any other operation). /// Default: `unym` pub rewarding_denom: String, diff --git a/common/cosmwasm-smart-contracts/node-families-contract/Cargo.toml b/common/cosmwasm-smart-contracts/node-families-contract/Cargo.toml new file mode 100644 index 0000000000..6a1fc4c1dc --- /dev/null +++ b/common/cosmwasm-smart-contracts/node-families-contract/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "nym-node-families-contract-common" +description = "Common crate for Nym's node families contract" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +homepage.workspace = true +documentation.workspace = true +rust-version = "1.85" +readme.workspace = true +publish = true + +[dependencies] +thiserror = { workspace = true } +serde = { workspace = true } +schemars = { workspace = true } + +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cw-controllers = { workspace = true } +cw-utils = { workspace = true } + +nym-contracts-common = { workspace = true } +nym-mixnet-contract-common = { workspace = true } + +[features] +schema = [] + +[lints] +workspace = true diff --git a/common/cosmwasm-smart-contracts/node-families-contract/src/constants.rs b/common/cosmwasm-smart-contracts/node-families-contract/src/constants.rs new file mode 100644 index 0000000000..372b2b9d9e --- /dev/null +++ b/common/cosmwasm-smart-contracts/node-families-contract/src/constants.rs @@ -0,0 +1,104 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +/// Storage key constants used by the node families contract. +/// +/// They are kept in the common crate so that off-chain tooling (indexers, migration +/// scripts) can reference them without depending on the contract crate itself. +/// Changing any of these values is a breaking change for already-deployed contracts. +pub mod storage_keys { + /// `Item`: address of the mixnet contract used to validate node existence. + pub const MIXNET_CONTRACT_ADDRESS: &str = "mixnet-contract-address"; + + /// `Item`: runtime configuration (fees, length limits) set at instantiation. + pub const CONFIG: &str = "config"; + + /// `Admin` (cw-controllers): admin allowed to perform privileged operations. + pub const CONTRACT_ADMIN: &str = "contract-admin"; + /// `Item`: monotonically increasing id counter for new families. + pub const NODE_FAMILY_ID_COUNTER: &str = "node-family-id-counter"; + /// Primary namespace for the current family-members `IndexedMap`, + /// keyed by `NodeId` with value [`crate::FamilyMembership`]. + pub const NODE_FAMILY_MEMBERS: &str = "node-family-members"; + /// Multi-index over current family members keyed by family id — + /// enables paginated listing of all nodes in a given family. + pub const NODE_FAMILY_MEMBERS_FAMILY_IDX_NAMESPACE: &str = "node-family-members__family"; + + /// Primary namespace for the families `IndexedMap`. + pub const FAMILIES_NAMESPACE: &str = "families"; + /// Secondary unique index keyed by `owner` (one family per owner). + pub const FAMILIES_OWNER_IDX_NAMESPACE: &str = "families__owner"; + /// Secondary unique index keyed by `name` (family names are globally unique). + pub const FAMILIES_NAME_IDX_NAMESPACE: &str = "families__name"; + + /// Primary namespace for the pending invitations `IndexedMap`. + pub const INVITATIONS_NAMESPACE: &str = "invitations"; + /// Multi-index over pending invitations keyed by family id. + pub const INVITATIONS_FAMILY_IDX_NAMESPACE: &str = "invitations__family"; + /// Multi-index over pending invitations keyed by node id + /// (a node can be invited to multiple families simultaneously). + pub const INVITATIONS_NODE_IDX_NAMESPACE: &str = "invitations__node"; + + /// Primary namespace for the archived (accepted/rejected/revoked) invitations `IndexedMap`. + pub const PAST_INVITATIONS_NAMESPACE: &str = "past-invitations"; + /// Multi-index over past invitations keyed by family id. + pub const PAST_INVITATIONS_FAMILY_IDX_NAMESPACE: &str = "past-invitations__family"; + /// Multi-index over past invitations keyed by node id. + pub const PAST_INVITATIONS_NODE_IDX_NAMESPACE: &str = "past-invitations__node"; + /// `Map<(NodeFamilyId, NodeId), u64>`: per-`(family, node)` counter used to + /// disambiguate repeat archive entries (a node can be invited and have the + /// invitation reach a terminal state more than once). + pub const PAST_INVITATIONS_COUNTER_NAMESPACE: &str = "past-invitations-counter"; + + /// Primary namespace for the past-members `IndexedMap`. + pub const PAST_FAMILY_MEMBER_NAMESPACE: &str = "past-family-member"; + /// Multi-index over past members keyed by family id. + pub const PAST_FAMILY_MEMBER_FAMILY_IDX_NAMESPACE: &str = "past-family-member__family"; + /// Multi-index over past members keyed by node id. + pub const PAST_FAMILY_MEMBER_NODE_IDX_NAMESPACE: &str = "past-family-member__node"; + /// `Map<(NodeFamilyId, NodeId), u64>`: per-`(family, node)` counter used to + /// disambiguate repeat past-membership entries (a node can join and leave + /// the same family more than once). + pub const PAST_FAMILY_MEMBER_COUNTER_NAMESPACE: &str = "past-family-member-counter"; +} + +pub mod events { + pub const FAMILY_CREATION_EVENT_NAME: &str = "family_creation"; + pub const FAMILY_CREATION_EVENT_FAMILY_NAME: &str = "family_name"; + pub const FAMILY_CREATION_EVENT_OWNER_ADDRESS: &str = "owner_address"; + pub const FAMILY_CREATION_EVENT_FAMILY_ID: &str = "family_id"; + pub const FAMILY_CREATION_EVENT_PAID_FEE: &str = "paid_fee"; + + pub const FAMILY_DISBAND_EVENT_NAME: &str = "family_disband"; + pub const FAMILY_DISBAND_EVENT_FAMILY_ID: &str = "family_id"; + pub const FAMILY_DISBAND_EVENT_OWNER_ADDRESS: &str = "owner_address"; + pub const FAMILY_DISBAND_EVENT_REFUNDED_FEE: &str = "refunded_fee"; + + pub const FAMILY_INVITATION_EVENT_NAME: &str = "family_invitation"; + pub const FAMILY_INVITATION_EVENT_FAMILY_ID: &str = "family_id"; + pub const FAMILY_INVITATION_EVENT_NODE_ID: &str = "node_id"; + pub const FAMILY_INVITATION_EVENT_EXPIRES_AT: &str = "expires_at"; + + pub const FAMILY_INVITATION_REVOKED_EVENT_NAME: &str = "family_invitation_revoked"; + pub const FAMILY_INVITATION_REVOKED_EVENT_FAMILY_ID: &str = "family_id"; + pub const FAMILY_INVITATION_REVOKED_EVENT_NODE_ID: &str = "node_id"; + + pub const FAMILY_INVITATION_ACCEPTED_EVENT_NAME: &str = "family_invitation_accepted"; + pub const FAMILY_INVITATION_ACCEPTED_EVENT_FAMILY_ID: &str = "family_id"; + pub const FAMILY_INVITATION_ACCEPTED_EVENT_NODE_ID: &str = "node_id"; + + pub const FAMILY_INVITATION_REJECTED_EVENT_NAME: &str = "family_invitation_rejected"; + pub const FAMILY_INVITATION_REJECTED_EVENT_FAMILY_ID: &str = "family_id"; + pub const FAMILY_INVITATION_REJECTED_EVENT_NODE_ID: &str = "node_id"; + + pub const FAMILY_MEMBER_LEFT_EVENT_NAME: &str = "family_member_left"; + pub const FAMILY_MEMBER_LEFT_EVENT_FAMILY_ID: &str = "family_id"; + pub const FAMILY_MEMBER_LEFT_EVENT_NODE_ID: &str = "node_id"; + + pub const FAMILY_MEMBER_KICKED_EVENT_NAME: &str = "family_member_kicked"; + pub const FAMILY_MEMBER_KICKED_EVENT_FAMILY_ID: &str = "family_id"; + pub const FAMILY_MEMBER_KICKED_EVENT_NODE_ID: &str = "node_id"; + + pub const NODE_UNBOND_CLEANUP_EVENT_NAME: &str = "family_node_unbond_cleanup"; + pub const NODE_UNBOND_CLEANUP_EVENT_NODE_ID: &str = "node_id"; +} diff --git a/common/cosmwasm-smart-contracts/node-families-contract/src/error.rs b/common/cosmwasm-smart-contracts/node-families-contract/src/error.rs new file mode 100644 index 0000000000..404fa09c28 --- /dev/null +++ b/common/cosmwasm-smart-contracts/node-families-contract/src/error.rs @@ -0,0 +1,161 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::NodeFamilyId; +use cosmwasm_std::{Addr, Coin}; +use cw_controllers::AdminError; +use cw_utils::PaymentError; +use nym_mixnet_contract_common::NodeId; +use thiserror::Error; + +/// Errors returned from any entry point of the node families contract. +#[derive(Error, Debug, PartialEq)] +pub enum NodeFamiliesContractError { + /// Returned from `migrate` when the on-chain state cannot be brought forward + /// to the current contract version (e.g. unsupported source version, malformed + /// stored data). + #[error("could not perform contract migration: {comment}")] + FailedMigration { comment: String }, + + /// The referenced family does not exist (or no longer exists). + #[error("family with id {family_id} does not exist")] + FamilyNotFound { family_id: NodeFamilyId }, + + /// Disbanding was requested on a family that still has members. + #[error("family {family_id} cannot be disbanded: it still has {members} member(s)")] + FamilyNotEmpty { + family_id: NodeFamilyId, + members: u64, + }, + + /// The given node is not currently a member of any family. + #[error("node {node_id} is not currently a member of any family")] + NodeNotInFamily { node_id: NodeId }, + + /// The given node is a member of a different family than the one the + /// caller is acting on. Distinct from [`NodeNotInFamily`] (which means the + /// node has no membership at all) — surfaces when, e.g., a family owner + /// tries to kick a node that belongs to someone else's family. + #[error("node {node_id} is not a member of family {family_id}")] + NodeNotMemberOfFamily { + node_id: NodeId, + family_id: NodeFamilyId, + }, + + /// A cross-contract callback (e.g. `OnNymNodeUnbond`) was received from a + /// sender that is not the configured mixnet contract address. + #[error("address {sender} is not authorised to invoke the mixnet-contract callback")] + UnauthorisedMixnetCallback { sender: Addr }, + + /// No pending invitation exists for the given `(family, node)` pair. + #[error("no pending invitation for node {node_id} from family {family_id}")] + InvitationNotFound { + family_id: NodeFamilyId, + node_id: NodeId, + }, + + /// A pending invitation for the given `(family, node)` pair already exists; + /// issuing a new one would silently overwrite it. + #[error("a pending invitation for node {node_id} from family {family_id} already exists")] + PendingInvitationAlreadyExists { + family_id: NodeFamilyId, + node_id: NodeId, + }, + + /// The invitation exists but its `expires_at` is at or before the current + /// block time, so it can no longer be acted on. + #[error( + "invitation for node {node_id} from family {family_id} expired at {expires_at} (now: {now})" + )] + InvitationExpired { + family_id: NodeFamilyId, + node_id: NodeId, + expires_at: u64, + now: u64, + }, + + /// The funds attached to a paid execution failed `cw_utils` payment + /// validation (no funds, wrong/extra denom). + #[error("invalid fee provided: {0}")] + InvalidDeposit(#[from] PaymentError), + + /// The funds attached to a `CreateFamily` execution don't match the + /// configured `create_family_fee`. + #[error("expected exactly {expected} as family creation fee; received {received:?}")] + InvalidFamilyCreationFee { expected: Coin, received: Vec }, + + /// The submitted family name normalised to the empty string (i.e. it + /// contained no ASCII alphanumeric characters). + #[error("family name cannot be empty after normalisation")] + EmptyFamilyName, + + /// The submitted family name exceeds the configured length limit. + #[error("family name length {length} exceeds the configured limit of {limit}")] + FamilyNameTooLong { length: usize, limit: usize }, + + /// The submitted family description exceeds the configured length limit. + #[error("family description length {length} exceeds the configured limit of {limit}")] + FamilyDescriptionTooLong { length: usize, limit: usize }, + + /// The transaction sender already owns a family. + #[error("address {address} already owns family {family_id}")] + SenderAlreadyOwnsAFamily { + address: Addr, + family_id: NodeFamilyId, + }, + + /// The transaction sender does not currently own any family - emitted by + /// owner-gated operations like `disband_family` when the sender has + /// nothing to act on. + #[error("address {address} does not currently own any family")] + SenderDoesntOwnAFamily { address: Addr }, + + /// The transaction sender is not the controller of the bonded node + /// referenced by the message. Covers all of: sender controls no bonded + /// node, sender controls a different node id, and sender's node has + /// entered the unbonding state. + #[error("address {address} is not the controller of bonded node {node_id}")] + SenderDoesntControlNode { address: Addr, node_id: NodeId }, + + /// A family with the requested (normalised) name already exists. + #[error("a family with name {name:?} already exists (id {family_id})")] + FamilyNameAlreadyTaken { + name: String, + family_id: NodeFamilyId, + }, + + /// A node controlled by the address is currently a member of a family, + /// so the address cannot also become a family owner or join another family. + #[error("address {address} controls node {node_id} which is currently in family {family_id}")] + AlreadyInFamily { + address: Addr, + node_id: NodeId, + family_id: NodeFamilyId, + }, + + /// The node referenced by an invitation does not exist as a bonded node + /// in the mixnet contract (or has already unbonded). + #[error("node {node_id} is not a bonded node in the mixnet contract")] + NodeDoesntExist { node_id: NodeId }, + + /// The node referenced by an invitation is already a member of a family, + /// so it cannot be invited to another one until it leaves / is removed. + #[error("node {node_id} is already a member of family {family_id}")] + NodeAlreadyInFamily { + node_id: NodeId, + family_id: NodeFamilyId, + }, + + /// The sender supplied a `validity_secs` of `0` for an invitation, which + /// would create one that is already expired at the moment it is stored. + #[error("invitation validity must be strictly positive")] + ZeroInvitationValidity, + + /// Wraps errors raised by `cw-controllers::Admin` (e.g. caller is not admin). + #[error(transparent)] + Admin(#[from] AdminError), + + /// Wraps any underlying `cosmwasm_std::StdError` (storage, serialization, etc.). + #[error(transparent)] + StdErr(#[from] cosmwasm_std::StdError), +} diff --git a/common/cosmwasm-smart-contracts/node-families-contract/src/lib.rs b/common/cosmwasm-smart-contracts/node-families-contract/src/lib.rs new file mode 100644 index 0000000000..265794d3e8 --- /dev/null +++ b/common/cosmwasm-smart-contracts/node-families-contract/src/lib.rs @@ -0,0 +1,22 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +//! Common types, messages, errors and storage-key constants shared between the +//! node families contract and any off-chain client. +//! +//! Keeping these in a separate crate allows clients to depend on the contract's +//! public surface without pulling in `cw-storage-plus` and other on-chain-only +//! dependencies. + +/// Storage-key string constants. See [`constants::storage_keys`]. +pub mod constants; +/// Contract-level error type. +pub mod error; +/// `InstantiateMsg`, `ExecuteMsg`, `QueryMsg`, `MigrateMsg` definitions. +pub mod msg; +/// Domain types stored in / returned by the contract. +pub mod types; + +pub use error::*; +pub use msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; +pub use types::*; diff --git a/common/cosmwasm-smart-contracts/node-families-contract/src/msg.rs b/common/cosmwasm-smart-contracts/node-families-contract/src/msg.rs new file mode 100644 index 0000000000..b5a509edcf --- /dev/null +++ b/common/cosmwasm-smart-contracts/node-families-contract/src/msg.rs @@ -0,0 +1,211 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::{ + Config, GlobalPastFamilyInvitationCursor, NodeFamilyId, PastFamilyInvitationCursor, + PastFamilyInvitationForNodeCursor, PastFamilyMemberCursor, PastFamilyMemberForNodeCursor, +}; +use cosmwasm_schema::cw_serde; +use nym_mixnet_contract_common::NodeId; + +#[cfg(feature = "schema")] +use crate::{ + AllFamilyMembersPagedResponse, AllPastFamilyInvitationsPagedResponse, FamiliesPagedResponse, + FamilyMembersPagedResponse, NodeFamilyByNameResponse, NodeFamilyByOwnerResponse, + NodeFamilyMembershipResponse, NodeFamilyResponse, PastFamilyInvitationsForNodePagedResponse, + PastFamilyInvitationsPagedResponse, PastFamilyMembersForNodePagedResponse, + PastFamilyMembersPagedResponse, PendingFamilyInvitationResponse, + PendingFamilyInvitationsPagedResponse, PendingInvitationsForNodePagedResponse, + PendingInvitationsPagedResponse, +}; + +/// Message used to instantiate the node families contract. +#[cw_serde] +pub struct InstantiateMsg { + pub config: Config, + + pub mixnet_contract_address: String, +} + +/// Execute messages accepted by the contract. +#[cw_serde] +pub enum ExecuteMsg { + /// Replace the contract's runtime [`Config`]. Restricted to the contract + /// admin. + UpdateConfig { config: Config }, + + /// Create a new family owned by the message sender. The configured + /// `create_family_fee` must be attached as funds. + CreateFamily { name: String, description: String }, + + /// Disband the family owned by the message sender. The family must have + /// no current members; any still-pending invitations are revoked. + DisbandFamily {}, + + /// Invite a node to the family owned by the message sender. If + /// `validity_secs` is omitted the invitation expires + /// `default_invitation_validity_secs` seconds (from [`Config`]) after the + /// current block time. + InviteToFamily { + node_id: NodeId, + validity_secs: Option, + }, + + /// Revoke a still-pending invitation previously issued by the sender's + /// family. + RevokeFamilyInvitation { node_id: NodeId }, + + /// Accept a pending invitation. The sender must control `node_id`. + AcceptFamilyInvitation { + family_id: NodeFamilyId, + node_id: NodeId, + }, + + /// Reject a pending invitation. The sender must control `node_id`. + RejectFamilyInvitation { + family_id: NodeFamilyId, + node_id: NodeId, + }, + + /// Leave the family `node_id` currently belongs to. The sender must + /// control `node_id`. + LeaveFamily { node_id: NodeId }, + + /// Remove `node_id` from the family owned by the message sender. + KickFromFamily { node_id: NodeId }, + + /// Cross-contract callback fired by the mixnet contract the moment + /// node with `node_id` initiates unbonding. + /// Removes the node from any family it currently + /// belongs to and rejects every pending invitation issued to it. + /// Sender must be the configured mixnet contract address. + OnNymNodeUnbond { node_id: NodeId }, +} + +/// Query messages accepted by the contract. +#[cw_serde] +#[cfg_attr(feature = "schema", derive(cosmwasm_schema::QueryResponses))] +pub enum QueryMsg { + /// Look up a single family by its id. + #[cfg_attr(feature = "schema", returns(NodeFamilyResponse))] + GetFamilyById { family_id: NodeFamilyId }, + + /// Look up the (at most one) family owned by a given address. + #[cfg_attr(feature = "schema", returns(NodeFamilyByOwnerResponse))] + GetFamilyByOwner { owner: String }, + + /// Look up a single family by its name. The lookup is normalised + /// contract-side (lowercased, non-alphanumerics stripped), so equivalent + /// inputs resolve to the same family. + #[cfg_attr(feature = "schema", returns(NodeFamilyByNameResponse))] + GetFamilyByName { name: String }, + + #[cfg_attr(feature = "schema", returns(FamiliesPagedResponse))] + GetFamiliesPaged { + start_after: Option, + limit: Option, + }, + + /// Look up which family — if any — a node currently belongs to. + #[cfg_attr(feature = "schema", returns(NodeFamilyMembershipResponse))] + GetFamilyMembership { node_id: NodeId }, + + /// Page through every node currently in a given family. + #[cfg_attr(feature = "schema", returns(FamilyMembersPagedResponse))] + GetFamilyMembersPaged { + family_id: NodeFamilyId, + start_after: Option, + limit: Option, + }, + + /// Page through every current family member across all families, in + /// ascending [`NodeId`] order. Each entry carries the membership record + /// (which in turn names the family the node belongs to). + #[cfg_attr(feature = "schema", returns(AllFamilyMembersPagedResponse))] + GetAllFamilyMembersPaged { + start_after: Option, + limit: Option, + }, + + /// Look up the pending invitation for a specific `(family_id, node_id)` + /// pair. + #[cfg_attr(feature = "schema", returns(PendingFamilyInvitationResponse))] + GetPendingInvitation { + family_id: NodeFamilyId, + node_id: NodeId, + }, + + /// Page through every pending invitation issued by a given family. + #[cfg_attr(feature = "schema", returns(PendingFamilyInvitationsPagedResponse))] + GetPendingInvitationsForFamilyPaged { + family_id: NodeFamilyId, + start_after: Option, + limit: Option, + }, + + /// Page through every pending invitation issued for a given node. + #[cfg_attr(feature = "schema", returns(PendingInvitationsForNodePagedResponse))] + GetPendingInvitationsForNodePaged { + node_id: NodeId, + start_after: Option, + limit: Option, + }, + + /// Page through every pending invitation across all families. + #[cfg_attr(feature = "schema", returns(PendingInvitationsPagedResponse))] + GetAllPendingInvitationsPaged { + start_after: Option<(NodeFamilyId, NodeId)>, + limit: Option, + }, + + /// Page through every archived (terminal-state) invitation issued by a + /// given family. + #[cfg_attr(feature = "schema", returns(PastFamilyInvitationsPagedResponse))] + GetPastInvitationsForFamilyPaged { + family_id: NodeFamilyId, + start_after: Option, + limit: Option, + }, + + /// Page through every archived (terminal-state) invitation issued to a + /// given node. + #[cfg_attr(feature = "schema", returns(PastFamilyInvitationsForNodePagedResponse))] + GetPastInvitationsForNodePaged { + node_id: NodeId, + start_after: Option, + limit: Option, + }, + + /// Page through every archived (terminal-state) invitation across all + /// families. + #[cfg_attr(feature = "schema", returns(AllPastFamilyInvitationsPagedResponse))] + GetAllPastInvitationsPaged { + start_after: Option, + limit: Option, + }, + + /// Page through every archived membership record for a given family + /// (nodes that used to belong to it but have since been removed). + #[cfg_attr(feature = "schema", returns(PastFamilyMembersPagedResponse))] + GetPastMembersForFamilyPaged { + family_id: NodeFamilyId, + start_after: Option, + limit: Option, + }, + + /// Page through every archived membership record for a given node + /// (every family the node used to belong to but has since been removed + /// from), across all families. + #[cfg_attr(feature = "schema", returns(PastFamilyMembersForNodePagedResponse))] + GetPastMembersForNodePaged { + node_id: NodeId, + start_after: Option, + limit: Option, + }, +} + +/// Message passed to the contract's `migrate` entry point. +#[cw_serde] +pub struct MigrateMsg { + // +} diff --git a/common/cosmwasm-smart-contracts/node-families-contract/src/types.rs b/common/cosmwasm-smart-contracts/node-families-contract/src/types.rs new file mode 100644 index 0000000000..6fefaae4ba --- /dev/null +++ b/common/cosmwasm-smart-contracts/node-families-contract/src/types.rs @@ -0,0 +1,403 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, Coin}; +use nym_mixnet_contract_common::NodeId; + +/// Identifier of a node family. +/// +/// Issued sequentially by the contract on family creation; never reused even if the +/// family is later disbanded. +pub type NodeFamilyId = u32; + +/// Runtime configuration of the node families contract. +#[cw_serde] +pub struct Config { + /// Fee charged on each successful `create_family` execution. + pub create_family_fee: Coin, + + /// Maximum allowed length, in characters, of a family name. + pub family_name_length_limit: usize, + + /// Maximum allowed length, in characters, of a family description. + pub family_description_length_limit: usize, + + /// Default lifetime, in seconds, used by `invite_to_family` when the + /// sender doesn't supply an explicit value. Senders may override this + /// per-invitation via the optional `validity_secs` argument. + pub default_invitation_validity_secs: u64, +} + +/// On-chain representation of a node family. +#[cw_serde] +pub struct NodeFamily { + /// The id of the node family + pub id: NodeFamilyId, + + /// The name of the node family + pub name: String, + + /// Normalised name of the node family used for uniqueness checks + pub normalised_name: String, + + /// The optional description of the node family + pub description: String, + + /// The owner of the node family + pub owner: Addr, + + /// Records the fee paid when the family was created, + /// so that the appropriate amount could be returned upon it getting disbanded. + pub paid_fee: Coin, + + /// Memoized value of the current number of members in the node family + /// Used to detect if the family is empty + pub members: u64, + + /// Timestamp of the creation of the node family + pub created_at: u64, +} + +/// A pending invitation for a node to join a particular family. +/// +/// Invitations are stored until they are accepted, rejected, revoked, or until the +/// chain advances past `expires_at` (in which case they remain in storage but are +/// treated as inert — there is no background process clearing expired invitations). +#[cw_serde] +pub struct FamilyInvitation { + /// The family that issued the invitation. + pub family_id: NodeFamilyId, + + /// The node being invited. + pub node_id: NodeId, + + /// Block timestamp (unix seconds) after which the invitation is no longer valid. + pub expires_at: u64, +} + +/// On-chain record of a node's current family membership. +/// +/// A node belongs to at most one family at a time, so this is keyed by +/// `NodeId` alone — `family_id` is carried in the value to support reverse +/// lookups (all nodes in a given family) via a secondary index. +#[cw_serde] +pub struct FamilyMembership { + /// The family the node is currently a member of. + pub family_id: NodeFamilyId, + + /// Block timestamp (unix seconds) at which the node accepted its + /// invitation and joined the family. + pub joined_at: u64, +} + +/// Historical record of a node that used to be part of a family but has since been +/// removed (kicked, left voluntarily, or because the family was disbanded). +#[cw_serde] +pub struct PastFamilyMember { + /// The family the node used to belong to. + pub family_id: NodeFamilyId, + + /// The node that was removed. + pub node_id: NodeId, + + /// Block timestamp (unix seconds) at which the membership was terminated. + pub removed_at: u64, +} + +/// Terminal status for an invitation that has been moved out of the pending set. +/// +/// Note: timed-out invitations are not represented here — they are simply left in +/// the pending set (see `FamilyInvitation::expires_at`). +#[cw_serde] +pub enum FamilyInvitationStatus { + /// Still awaiting a response. Recorded with a timestamp for completeness even + /// though pending invitations live in a separate map. + Pending { at: u64 }, + /// The invitee accepted and joined the family at the given timestamp. + Accepted { at: u64 }, + /// The invitee explicitly rejected the invitation at the given timestamp. + Rejected { at: u64 }, + /// The family revoked the invitation at the given timestamp before it could + /// be accepted or rejected. + Revoked { at: u64 }, +} + +/// Historical record of an invitation that has reached a terminal state +/// (`Accepted`, `Rejected`, or `Revoked`). Timed-out invitations are **not** +/// archived here — they remain in the pending map until explicitly cleared. +#[cw_serde] +pub struct PastFamilyInvitation { + /// The original invitation as it was issued. + pub invitation: FamilyInvitation, + + /// What ultimately happened to it. + pub status: FamilyInvitationStatus, +} + +/// Response to [`QueryMsg::GetFamilyById`](crate::QueryMsg::GetFamilyById). +#[cw_serde] +pub struct NodeFamilyResponse { + /// The id that was queried, echoed back so paginated callers can correlate. + pub family_id: NodeFamilyId, + + /// The matching family, or `None` if no family with `family_id` exists. + pub family: Option, +} + +/// Response to [`QueryMsg::GetFamilyByOwner`](crate::QueryMsg::GetFamilyByOwner). +#[cw_serde] +pub struct NodeFamilyByOwnerResponse { + /// The (validated) owner address that was queried, echoed back so callers + /// can correlate. + pub owner: Addr, + + /// The matching family, or `None` if `owner` does not currently own one. + pub family: Option, +} + +/// Response to [`QueryMsg::GetFamilyByName`](crate::QueryMsg::GetFamilyByName). +#[cw_serde] +pub struct NodeFamilyByNameResponse { + /// The name that was queried, echoed back so callers can correlate. + pub name: String, + + /// The matching family, or `None` if no family with that name exists. + pub family: Option, +} + +/// Response to [`QueryMsg::GetFamilyMembership`](crate::QueryMsg::GetFamilyMembership). +#[cw_serde] +pub struct NodeFamilyMembershipResponse { + /// The node that was queried. + pub node_id: NodeId, + + /// The id of the family the node currently belongs to, or `None` if the + /// node is not currently a member of any family. + pub family_id: Option, +} + +/// A pending [`FamilyInvitation`] paired with whether it has already timed +/// out at the time the query was served. +#[cw_serde] +pub struct PendingFamilyInvitationDetails { + /// The stored invitation as it was issued. + pub invitation: FamilyInvitation, + + /// `true` iff `now >= invitation.expires_at` at query time, i.e. the + /// invitation is still in the pending map but can no longer be acted on. + pub expired: bool, +} + +/// Response to [`QueryMsg::GetPendingInvitation`](crate::QueryMsg::GetPendingInvitation). +#[cw_serde] +pub struct PendingFamilyInvitationResponse { + /// The family component of the queried `(family_id, node_id)` key. + pub family_id: NodeFamilyId, + + /// The node component of the queried `(family_id, node_id)` key. + pub node_id: NodeId, + + /// The matching pending invitation along with an explicit expiry flag, + /// or `None` if no such invitation exists. + pub invitation: Option, +} + +/// One entry in a [`FamilyMembersPagedResponse`] page — pairs a node id with +/// its [`FamilyMembership`] record (notably its `joined_at` timestamp). +#[cw_serde] +pub struct FamilyMemberRecord { + /// The node currently in the family. + pub node_id: NodeId, + + /// The membership record (carries `family_id` and `joined_at`). + pub membership: FamilyMembership, +} + +/// Response to [`QueryMsg::GetFamilyMembersPaged`](crate::QueryMsg::GetFamilyMembersPaged). +#[cw_serde] +pub struct FamilyMembersPagedResponse { + /// The family whose members were queried, echoed back so paginated + /// callers can correlate. + pub family_id: NodeFamilyId, + + /// The members on this page, in ascending [`NodeId`] order. + pub members: Vec, + + /// Cursor to pass as `start_after` on the next call, or `None` if this + /// page is empty (which the caller should treat as end-of-list). + pub start_next_after: Option, +} + +/// Response to [`QueryMsg::GetAllFamilyMembersPaged`](crate::QueryMsg::GetAllFamilyMembersPaged). +#[cw_serde] +pub struct AllFamilyMembersPagedResponse { + /// The members on this page, in ascending [`NodeId`] order across every + /// family. + pub members: Vec, + + /// Cursor (last `node_id`) to pass as `start_after` on the next call, + /// or `None` if this page is empty (treat as end-of-list). + pub start_next_after: Option, +} + +/// Response to [`QueryMsg::GetPendingInvitationsForFamilyPaged`](crate::QueryMsg::GetPendingInvitationsForFamilyPaged). +#[cw_serde] +pub struct PendingFamilyInvitationsPagedResponse { + /// The family whose pending invitations were queried, echoed back so + /// paginated callers can correlate. + pub family_id: NodeFamilyId, + + /// The pending invitations on this page, in ascending invitee + /// [`NodeId`] order, each stamped with whether it had already timed out + /// at the time the query was served. + pub invitations: Vec, + + /// Cursor (last invitee node id) to pass as `start_after` on the next + /// call, or `None` if this page is empty (treat as end-of-list). + pub start_next_after: Option, +} + +/// Response to [`QueryMsg::GetPendingInvitationsForNodePaged`](crate::QueryMsg::GetPendingInvitationsForNodePaged). +#[cw_serde] +pub struct PendingInvitationsForNodePagedResponse { + /// The node whose pending invitations were queried, echoed back so + /// paginated callers can correlate. + pub node_id: NodeId, + + /// The pending invitations addressed to this node on this page, in + /// ascending [`NodeFamilyId`] order, each stamped with whether it had + /// already timed out at the time the query was served. + pub invitations: Vec, + + /// Cursor (last issuing family id) to pass as `start_after` on the + /// next call, or `None` if this page is empty (treat as end-of-list). + pub start_next_after: Option, +} + +/// Response to [`QueryMsg::GetAllPendingInvitationsPaged`](crate::QueryMsg::GetAllPendingInvitationsPaged). +#[cw_serde] +pub struct PendingInvitationsPagedResponse { + /// The pending invitations on this page, in ascending + /// `(family_id, node_id)` order, each stamped with whether it had + /// already timed out at the time the query was served. + pub invitations: Vec, + + /// Cursor (last `(family_id, node_id)` pair) to pass as `start_after` + /// on the next call, or `None` if this page is empty (treat as + /// end-of-list). + pub start_next_after: Option<(NodeFamilyId, NodeId)>, +} + +/// Cursor for paginating per-family past-invitation listings: identifies a +/// single archive entry within a family by `(node_id, counter)`. The +/// `counter` is the per-`(family, node)` archive slot — multiple archived +/// invitations can exist for the same `(family, node)` pair (a node may be +/// invited and have the invitation reach a terminal state more than once). +pub type PastFamilyInvitationCursor = (NodeId, u64); + +/// Cursor for paginating per-node past-invitation listings: identifies a +/// single archive entry addressed to a fixed node by `(family_id, counter)`. +pub type PastFamilyInvitationForNodeCursor = (NodeFamilyId, u64); + +/// Cursor for paginating global past-invitation listings: identifies a +/// single archive entry across all families by `((family_id, node_id), counter)`. +pub type GlobalPastFamilyInvitationCursor = ((NodeFamilyId, NodeId), u64); + +/// Response to [`QueryMsg::GetPastInvitationsForFamilyPaged`](crate::QueryMsg::GetPastInvitationsForFamilyPaged). +#[cw_serde] +pub struct PastFamilyInvitationsPagedResponse { + /// The family whose archived invitations were queried, echoed back so + /// paginated callers can correlate. + pub family_id: NodeFamilyId, + + /// The archived invitations on this page, in ascending + /// `(node_id, counter)` order across all terminal statuses. + pub invitations: Vec, + + /// Cursor to pass as `start_after` on the next call, or `None` if this + /// page is empty (treat as end-of-list). + pub start_next_after: Option, +} + +/// Response to [`QueryMsg::GetPastInvitationsForNodePaged`](crate::QueryMsg::GetPastInvitationsForNodePaged). +#[cw_serde] +pub struct PastFamilyInvitationsForNodePagedResponse { + /// The node whose past invitations were queried, echoed back so + /// paginated callers can correlate. + pub node_id: NodeId, + + /// The archived invitations addressed to this node on this page, in + /// ascending `(family_id, counter)` order across all terminal statuses. + pub invitations: Vec, + + /// Cursor to pass as `start_after` on the next call, or `None` if this + /// page is empty (treat as end-of-list). + pub start_next_after: Option, +} + +/// Response to [`QueryMsg::GetAllPastInvitationsPaged`](crate::QueryMsg::GetAllPastInvitationsPaged). +#[cw_serde] +pub struct AllPastFamilyInvitationsPagedResponse { + /// The archived invitations on this page, in ascending + /// `((family_id, node_id), counter)` order across all terminal statuses. + pub invitations: Vec, + + /// Cursor to pass as `start_after` on the next call, or `None` if this + /// page is empty (treat as end-of-list). + pub start_next_after: Option, +} + +/// Cursor for paginating per-family past-member listings: identifies a single +/// archive entry within a family by `(node_id, counter)`. The `counter` is the +/// per-`(family, node)` archive slot — multiple archived membership entries +/// can exist for the same `(family, node)` pair (a node may join, leave, and +/// re-join the same family more than once). +pub type PastFamilyMemberCursor = (NodeId, u64); + +/// Cursor for paginating per-node past-member listings: identifies a single +/// archive entry for a fixed node by `(family_id, counter)`. +pub type PastFamilyMemberForNodeCursor = (NodeFamilyId, u64); + +/// Response to [`QueryMsg::GetPastMembersForFamilyPaged`](crate::QueryMsg::GetPastMembersForFamilyPaged). +#[cw_serde] +pub struct PastFamilyMembersPagedResponse { + /// The family whose archived memberships were queried, echoed back so + /// paginated callers can correlate. + pub family_id: NodeFamilyId, + + /// The archived membership records on this page, in ascending + /// `(node_id, counter)` order. + pub members: Vec, + + /// Cursor to pass as `start_after` on the next call, or `None` if this + /// page is empty (treat as end-of-list). + pub start_next_after: Option, +} + +/// Response to [`QueryMsg::GetPastMembersForNodePaged`](crate::QueryMsg::GetPastMembersForNodePaged). +#[cw_serde] +pub struct PastFamilyMembersForNodePagedResponse { + /// The node whose archived memberships were queried, echoed back so + /// paginated callers can correlate. + pub node_id: NodeId, + + /// The archived membership records for this node on this page, in + /// ascending `(family_id, counter)` order. + pub members: Vec, + + /// Cursor to pass as `start_after` on the next call, or `None` if this + /// page is empty (treat as end-of-list). + pub start_next_after: Option, +} + +/// Response to [`QueryMsg::GetFamiliesPaged`](crate::QueryMsg::GetFamiliesPaged). +#[cw_serde] +pub struct FamiliesPagedResponse { + /// The families on this page, in ascending [`NodeFamilyId`] order. + pub families: Vec, + + /// Cursor to pass as `start_after` on the next call, or `None` if this + /// page is empty (which the caller should treat as end-of-list). + pub start_next_after: Option, +} diff --git a/common/crypto/Cargo.toml b/common/crypto/Cargo.toml index 1cc48788b6..ac426b25e5 100644 --- a/common/crypto/Cargo.toml +++ b/common/crypto/Cargo.toml @@ -8,7 +8,9 @@ license = { workspace = true } repository = { workspace = true } homepage.workspace = true documentation.workspace = true -rust-version.workspace = true +# pinned (not inherited from workspace) because this crate is imported by the ecash contract, +# and the contracts workspace cannot be built with rustc more recent than 1.86 +rust-version = "1.86.0" readme.workspace = true publish = true diff --git a/common/http-api-common/src/response/mod.rs b/common/http-api-common/src/response/mod.rs index 95e8cb5533..fcffebe052 100644 --- a/common/http-api-common/src/response/mod.rs +++ b/common/http-api-common/src/response/mod.rs @@ -129,6 +129,41 @@ where } } +#[derive(Default, Debug, Serialize, Deserialize, Copy, Clone)] +#[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] +#[serde(rename_all = "lowercase")] +pub enum OutputV2 { + #[default] + Json, + Yaml, +} + +#[derive(Default, Debug, Serialize, Deserialize, Copy, Clone)] +#[cfg_attr(feature = "utoipa", derive(utoipa::IntoParams, utoipa::ToSchema))] +#[serde(default)] +pub struct OutputParamsV2 { + pub output: Option, +} + +impl OutputParamsV2 { + pub fn get_output(&self) -> OutputV2 { + self.output.unwrap_or_default() + } + + pub fn to_response(self, data: T) -> FormattedResponse { + self.get_output().to_response(data) + } +} + +impl OutputV2 { + pub fn to_response(self, data: T) -> FormattedResponse { + match self { + OutputV2::Json => FormattedResponse::Json(Json::from(data)), + OutputV2::Yaml => FormattedResponse::Yaml(Yaml::from(data)), + } + } +} + #[derive(Default, Debug, Serialize, Deserialize, Copy, Clone)] #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] #[serde(rename_all = "lowercase")] diff --git a/common/network-defaults/Cargo.toml b/common/network-defaults/Cargo.toml index 238503673d..d83abccbc7 100644 --- a/common/network-defaults/Cargo.toml +++ b/common/network-defaults/Cargo.toml @@ -8,7 +8,9 @@ license.workspace = true repository.workspace = true homepage.workspace = true documentation.workspace = true -rust-version.workspace = true +# pinned (not inherited from workspace) because this crate is imported by the ecash contract, +# and the contracts workspace cannot be built with rustc more recent than 1.86 +rust-version = "1.86.0" readme.workspace = true publish = true # Exclude build.rs from published crate - it's only used for dev-time sync diff --git a/common/network-defaults/src/mainnet.rs b/common/network-defaults/src/mainnet.rs index 3c07beefc3..1cd1a40895 100644 --- a/common/network-defaults/src/mainnet.rs +++ b/common/network-defaults/src/mainnet.rs @@ -22,6 +22,10 @@ pub const VESTING_CONTRACT_ADDRESS: &str = pub const PERFORMANCE_CONTRACT_ADDRESS: &str = ""; // /\ TODO: this has to be updated once the contract is deployed +// \/ TODO: this has to be updated once the contract is deployed +pub const NODE_FAMILIES_CONTRACT_ADDRESS: &str = ""; +// /\ TODO: this has to be updated once the contract is deployed + pub const ECASH_CONTRACT_ADDRESS: &str = "n1r7s6aksyc6pqardx88k3rkgfagwvj4z4zum9mmz2sfk3zm2mha0sd4dnun"; pub const GROUP_CONTRACT_ADDRESS: &str = diff --git a/common/network-defaults/src/network.rs b/common/network-defaults/src/network.rs index ccba4af768..03bc65f416 100644 --- a/common/network-defaults/src/network.rs +++ b/common/network-defaults/src/network.rs @@ -39,6 +39,8 @@ pub struct NymContracts { pub vesting_contract_address: Option, #[serde(default)] pub performance_contract_address: Option, + #[serde(default)] + pub node_families_contract_address: Option, pub ecash_contract_address: Option, pub group_contract_address: Option, pub multisig_contract_address: Option, @@ -174,6 +176,9 @@ impl NymNetworkDetails { )) .with_mixnet_contract(get_optional_env(var_names::MIXNET_CONTRACT_ADDRESS)) .with_vesting_contract(get_optional_env(var_names::VESTING_CONTRACT_ADDRESS)) + .with_node_families_contract(get_optional_env( + var_names::NODE_FAMILIES_CONTRACT_ADDRESS, + )) .with_ecash_contract(get_optional_env(var_names::ECASH_CONTRACT_ADDRESS)) .with_group_contract(get_optional_env(var_names::GROUP_CONTRACT_ADDRESS)) .with_multisig_contract(get_optional_env(var_names::MULTISIG_CONTRACT_ADDRESS)) @@ -199,6 +204,9 @@ impl NymNetworkDetails { performance_contract_address: parse_optional_str( mainnet::PERFORMANCE_CONTRACT_ADDRESS, ), + node_families_contract_address: parse_optional_str( + mainnet::NODE_FAMILIES_CONTRACT_ADDRESS, + ), ecash_contract_address: parse_optional_str(mainnet::ECASH_CONTRACT_ADDRESS), group_contract_address: parse_optional_str(mainnet::GROUP_CONTRACT_ADDRESS), multisig_contract_address: parse_optional_str(mainnet::MULTISIG_CONTRACT_ADDRESS), @@ -252,6 +260,7 @@ impl NymNetworkDetails { set_optional_var(var_names::MIXNET_CONTRACT_ADDRESS, self.contracts.mixnet_contract_address); set_optional_var(var_names::VESTING_CONTRACT_ADDRESS, self.contracts.vesting_contract_address); + set_optional_var(var_names::NODE_FAMILIES_CONTRACT_ADDRESS, self.contracts.node_families_contract_address); set_optional_var(var_names::ECASH_CONTRACT_ADDRESS, self.contracts.ecash_contract_address); set_optional_var(var_names::GROUP_CONTRACT_ADDRESS, self.contracts.group_contract_address); set_optional_var(var_names::MULTISIG_CONTRACT_ADDRESS, self.contracts.multisig_contract_address); @@ -340,6 +349,12 @@ impl NymNetworkDetails { self } + #[must_use] + pub fn with_node_families_contract>(mut self, contract: Option) -> Self { + self.contracts.node_families_contract_address = contract.map(Into::into); + self + } + #[must_use] pub fn with_ecash_contract>(mut self, contract: Option) -> Self { self.contracts.ecash_contract_address = contract.map(Into::into); diff --git a/common/network-defaults/src/var_names.rs b/common/network-defaults/src/var_names.rs index 4bfb1d5877..d92de0fd16 100644 --- a/common/network-defaults/src/var_names.rs +++ b/common/network-defaults/src/var_names.rs @@ -17,6 +17,7 @@ pub const VESTING_CONTRACT_ADDRESS: &str = "VESTING_CONTRACT_ADDRESS"; pub const ECASH_CONTRACT_ADDRESS: &str = "ECASH_CONTRACT_ADDRESS"; pub const GROUP_CONTRACT_ADDRESS: &str = "GROUP_CONTRACT_ADDRESS"; pub const MULTISIG_CONTRACT_ADDRESS: &str = "MULTISIG_CONTRACT_ADDRESS"; +pub const NODE_FAMILIES_CONTRACT_ADDRESS: &str = "NODE_FAMILIES_CONTRACT_ADDRESS"; pub const COCONUT_DKG_CONTRACT_ADDRESS: &str = "COCONUT_DKG_CONTRACT_ADDRESS"; pub const REWARDING_VALIDATOR_ADDRESS: &str = "REWARDING_VALIDATOR_ADDRESS"; pub const NYXD: &str = "NYXD"; diff --git a/common/pemstore/Cargo.toml b/common/pemstore/Cargo.toml index ff2d78250e..4019c56770 100644 --- a/common/pemstore/Cargo.toml +++ b/common/pemstore/Cargo.toml @@ -8,7 +8,9 @@ license = { workspace = true } repository = { workspace = true } homepage.workspace = true documentation.workspace = true -rust-version.workspace = true +# pinned (not inherited from workspace) because this crate is imported by the ecash contract, +# and the contracts workspace cannot be built with rustc more recent than 1.86 +rust-version = "1.86.0" readme.workspace = true publish = true diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index f71026cddb..dc14cdffcb 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -2,17 +2,6 @@ # It is not intended for manual editing. version = 4 -[[package]] -name = "aes" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" -dependencies = [ - "cfg-if", - "cipher", - "cpufeatures", -] - [[package]] name = "ahash" version = "0.8.11" @@ -87,7 +76,7 @@ dependencies = [ "ark-serialize", "ark-std", "derivative", - "digest 0.10.7", + "digest", "itertools 0.10.5", "num-bigint", "num-traits", @@ -141,7 +130,7 @@ checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" dependencies = [ "ark-serialize-derive", "ark-std", - "digest 0.10.7", + "digest", "num-bigint", ] @@ -167,12 +156,6 @@ dependencies = [ "rayon", ] -[[package]] -name = "arrayref" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" - [[package]] name = "autocfg" version = "1.2.0" @@ -215,25 +198,13 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" -[[package]] -name = "blake2" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" -dependencies = [ - "byte-tools", - "crypto-mac", - "digest 0.8.1", - "opaque-debug", -] - [[package]] name = "block-buffer" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" dependencies = [ - "generic-array 0.14.7", + "generic-array", ] [[package]] @@ -251,12 +222,6 @@ dependencies = [ "tinyvec", ] -[[package]] -name = "byte-tools" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" - [[package]] name = "byteorder" version = "1.5.0" @@ -321,26 +286,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "chacha" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddf3c081b5fba1e5615640aae998e0fbd10c24cbd897ee39ed754a77601a4862" -dependencies = [ - "byteorder", - "keystream", -] - -[[package]] -name = "cipher" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" -dependencies = [ - "crypto-common", - "inout", -] - [[package]] name = "const-oid" version = "0.9.6" @@ -380,7 +325,7 @@ dependencies = [ "ark-serialize", "cosmwasm-core", "curve25519-dalek", - "digest 0.10.7", + "digest", "ecdsa", "ed25519-zebra", "k256", @@ -491,9 +436,9 @@ version = "0.5.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ - "generic-array 0.14.7", + "generic-array", "rand_core", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -503,29 +448,10 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ - "generic-array 0.14.7", + "generic-array", "typenum", ] -[[package]] -name = "crypto-mac" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" -dependencies = [ - "generic-array 0.12.4", - "subtle 1.0.0", -] - -[[package]] -name = "ctr" -version = "0.9.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" -dependencies = [ - "cipher", -] - [[package]] name = "curve25519-dalek" version = "4.1.3" @@ -535,10 +461,10 @@ dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", - "digest 0.10.7", + "digest", "fiat-crypto", "rustc_version", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -709,7 +635,7 @@ dependencies = [ "nym-contracts-common", "nym-contracts-common-testing", "nym-group-contract-common", - "nym-multisig-contract-common 1.20.4 (registry+https://github.com/rust-lang/crates.io-index)", + "nym-multisig-contract-common 1.21.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -796,15 +722,6 @@ dependencies = [ "unicode-xid", ] -[[package]] -name = "digest" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" -dependencies = [ - "generic-array 0.12.4", -] - [[package]] name = "digest" version = "0.10.7" @@ -814,7 +731,7 @@ dependencies = [ "block-buffer", "const-oid", "crypto-common", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -825,7 +742,7 @@ checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" [[package]] name = "easy-addr" -version = "1.20.4" +version = "1.21.0" dependencies = [ "cosmwasm-std", "quote", @@ -839,7 +756,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ "der", - "digest 0.10.7", + "digest", "elliptic-curve", "rfc6979", "signature", @@ -866,7 +783,7 @@ dependencies = [ "rand_core", "serde", "sha2", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -899,13 +816,13 @@ checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" dependencies = [ "base16ct", "crypto-bigint", - "digest 0.10.7", + "digest", "ff", - "generic-array 0.14.7", + "generic-array", "group", "rand_core", "sec1", - "subtle 2.4.1", + "subtle", "zeroize", ] @@ -922,7 +839,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ "rand_core", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -931,15 +848,6 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c007b1ae3abe1cb6f85a16305acd418b7ca6343b953633fee2b76d8f108b830f" -[[package]] -name = "generic-array" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" -dependencies = [ - "typenum", -] - [[package]] name = "generic-array" version = "0.14.7" @@ -970,7 +878,7 @@ checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", "rand_core", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -1004,22 +912,13 @@ version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -[[package]] -name = "hkdf" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" -dependencies = [ - "hmac", -] - [[package]] name = "hmac" version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest 0.10.7", + "digest", ] [[package]] @@ -1048,15 +947,6 @@ dependencies = [ "hashbrown 0.15.2", ] -[[package]] -name = "inout" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f10e63c20629ecabbb64a8010319738c66a5cd0c29b02d63d272b03751d01" -dependencies = [ - "generic-array 0.14.7", -] - [[package]] name = "itertools" version = "0.10.5" @@ -1102,12 +992,6 @@ dependencies = [ "sha2", ] -[[package]] -name = "keystream" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33070833c9ee02266356de0c43f723152bd38bd96ddf52c82b3af10c9138b28" - [[package]] name = "konst" version = "0.3.16" @@ -1141,30 +1025,32 @@ version = "0.2.180" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" -[[package]] -name = "libm" -version = "0.2.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de" - -[[package]] -name = "lioness" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae926706ba42c425c9457121178330d75e273df2e82e28b758faf3de3a9acb9" -dependencies = [ - "arrayref", - "blake2", - "chacha", - "keystream", -] - [[package]] name = "memchr" version = "2.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" +[[package]] +name = "node-families" +version = "0.1.0" +dependencies = [ + "anyhow", + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers", + "cw-storage-plus", + "cw-utils", + "cw2", + "nym-contracts-common", + "nym-contracts-common-testing", + "nym-crypto", + "nym-mixnet-contract", + "nym-mixnet-contract-common", + "nym-node-families-contract-common", + "serde", +] + [[package]] name = "num-bigint" version = "0.4.6" @@ -1197,7 +1083,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" dependencies = [ "autocfg", - "libm", ] [[package]] @@ -1233,9 +1118,9 @@ dependencies = [ [[package]] name = "nym-coconut-dkg-common" -version = "1.20.4" +version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a95dc43ef8954a4f79846e3224434cf389d4a9c14b77f526dae3cfd2221c6141" +checksum = "fcdfaf17c8b2a73bd6d14a3b9432118d66cc2335a371f185791099d32c25feb0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1243,14 +1128,12 @@ dependencies = [ "cw2", "cw4", "nym-contracts-common", - "nym-multisig-contract-common 1.20.4 (registry+https://github.com/rust-lang/crates.io-index)", + "nym-multisig-contract-common 1.21.0 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] name = "nym-contracts-common" -version = "1.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47bb3e8427c193cd500c802274b11879086863c3643525b6ece3e9ab1c77bddc" +version = "1.21.0" dependencies = [ "bs58", "cosmwasm-schema", @@ -1264,9 +1147,7 @@ dependencies = [ [[package]] name = "nym-contracts-common-testing" -version = "1.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3628aac6715e844f3ab20e3b8ae8c4684f144ccb78e205f002c1c3ae375e956" +version = "1.21.0" dependencies = [ "anyhow", "cosmwasm-std", @@ -1280,16 +1161,13 @@ dependencies = [ [[package]] name = "nym-crypto" -version = "1.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b710addc28c9950dd961e7dd3837ef3b479492d2b21b5f2437eb7d2899403027" +version = "1.21.0" dependencies = [ "base64 0.22.1", "bs58", "curve25519-dalek", "ed25519-dalek", "nym-pemstore", - "nym-sphinx-types", "rand", "sha2", "subtle-encoding", @@ -1317,7 +1195,7 @@ dependencies = [ "nym-contracts-common-testing", "nym-crypto", "nym-ecash-contract-common", - "nym-multisig-contract-common 1.20.4 (registry+https://github.com/rust-lang/crates.io-index)", + "nym-multisig-contract-common 1.21.0 (registry+https://github.com/rust-lang/crates.io-index)", "nym-network-defaults", "schemars", "semver", @@ -1328,7 +1206,7 @@ dependencies = [ [[package]] name = "nym-ecash-contract-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bs58", "cosmwasm-schema", @@ -1336,15 +1214,15 @@ dependencies = [ "cw-controllers", "cw-utils", "cw2", - "nym-multisig-contract-common 1.20.4", + "nym-multisig-contract-common 1.21.0", "thiserror 2.0.12", ] [[package]] name = "nym-group-contract-common" -version = "1.20.4" +version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb13102740426a4a2b683f54bbd6614fe9ecd745f5117bcf197c49c300b15edf" +checksum = "f6f9773b3adc4b979c4e0f86d8932a78d10149df36e136f770653ad5405ce41a" dependencies = [ "cosmwasm-schema", "cw-controllers", @@ -1370,6 +1248,7 @@ dependencies = [ "nym-crypto", "nym-mixnet-contract", "nym-mixnet-contract-common", + "nym-node-families-contract-common", "nym-vesting-contract-common", "rand", "rand_chacha", @@ -1379,9 +1258,7 @@ dependencies = [ [[package]] name = "nym-mixnet-contract-common" -version = "1.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41c21bceb3bb8ee2789851b3f381fc035485af825bf7290b7c99a5af4e8f6ba1" +version = "1.21.0" dependencies = [ "bs58", "cosmwasm-schema", @@ -1401,7 +1278,7 @@ dependencies = [ [[package]] name = "nym-multisig-contract-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1416,9 +1293,9 @@ dependencies = [ [[package]] name = "nym-multisig-contract-common" -version = "1.20.4" +version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4a20b931ee849f6179ce2b387accd058720017f644ffbc8c2422f3e9ac3ff54" +checksum = "7681c7b43201d45a4958eab012a93e285ce47f7bba405e1ba1808edd195f3347" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1433,19 +1310,30 @@ dependencies = [ [[package]] name = "nym-network-defaults" -version = "1.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9834193b4641acdf9f360aea684a6bd841cad287930bc0d7c3241a133756464" +version = "1.21.0" dependencies = [ "cargo_metadata 0.19.2", "regex", ] +[[package]] +name = "nym-node-families-contract-common" +version = "1.21.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers", + "cw-utils", + "nym-contracts-common", + "nym-mixnet-contract-common", + "schemars", + "serde", + "thiserror 2.0.12", +] + [[package]] name = "nym-pemstore" -version = "1.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03077f9ebeb40caf8aa8e6f7bf8728449f73733e7a246986e492fa34ad3e70ab" +version = "1.21.0" dependencies = [ "pem", "tracing", @@ -1462,20 +1350,22 @@ dependencies = [ "cw-controllers", "cw-storage-plus", "cw2", + "node-families", "nym-contracts-common", "nym-contracts-common-testing", "nym-crypto", "nym-mixnet-contract", "nym-mixnet-contract-common", + "nym-node-families-contract-common", "nym-performance-contract-common", "serde", ] [[package]] name = "nym-performance-contract-common" -version = "1.20.4" +version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42129a72f4b0dc0304a48b0ca1769b27694d913687ace5692d4c6924ca9f2a13" +checksum = "c6e47f2a04d8b0e1c492cdd7dcfc98face5efc2a4cb999c03887a5b77e4cf055" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1503,9 +1393,9 @@ dependencies = [ [[package]] name = "nym-pool-contract-common" -version = "1.20.4" +version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70239cc26beda3ad19289188c50d554522af29646d7d3f855bda6fc8ed332fe7" +checksum = "9965dce8aaee8e9943b342695ff3fda45c8a4f1daab943ed752a8a0b47aa04c7" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1515,16 +1405,6 @@ dependencies = [ "thiserror 2.0.12", ] -[[package]] -name = "nym-sphinx-types" -version = "1.20.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ba662d39fd6da9e13166fa1162ff41c2cfaed78a77c70df72fbda6fef5eb4f5" -dependencies = [ - "sphinx-packet", - "thiserror 2.0.12", -] - [[package]] name = "nym-vesting-contract" version = "1.4.1" @@ -1548,9 +1428,9 @@ dependencies = [ [[package]] name = "nym-vesting-contract-common" -version = "1.20.4" +version = "1.21.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "676c2793efbf9ccdf86bb788c903f778a2d5993a5174729303f9511a297f4ca8" +checksum = "af0179bfbb30551414277ca7bed631d48f3321df7b18e3032f23f2f111a577d7" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1567,12 +1447,6 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[package]] -name = "opaque-debug" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" - [[package]] name = "p256" version = "0.13.2" @@ -1743,16 +1617,6 @@ dependencies = [ "getrandom", ] -[[package]] -name = "rand_distr" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" -dependencies = [ - "num-traits", - "rand", -] - [[package]] name = "rayon" version = "1.10.0" @@ -1809,7 +1673,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" dependencies = [ "hmac", - "subtle 2.4.1", + "subtle", ] [[package]] @@ -1887,8 +1751,8 @@ checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", "der", - "generic-array 0.14.7", - "subtle 2.4.1", + "generic-array", + "subtle", "zeroize", ] @@ -1981,7 +1845,7 @@ checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", - "digest 0.10.7", + "digest", ] [[package]] @@ -1990,36 +1854,10 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest 0.10.7", + "digest", "rand_core", ] -[[package]] -name = "sphinx-packet" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c26f0c20d909fdda1c5d0ece3973127ca421984d55b000215df365e93722fc6e" -dependencies = [ - "aes", - "arrayref", - "blake2", - "bs58", - "byteorder", - "chacha", - "ctr", - "curve25519-dalek", - "digest 0.10.7", - "hkdf", - "hmac", - "lioness", - "rand", - "rand_distr", - "sha2", - "subtle 2.4.1", - "x25519-dalek", - "zeroize", -] - [[package]] name = "spki" version = "0.7.3" @@ -2036,12 +1874,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" -[[package]] -name = "subtle" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" - [[package]] name = "subtle" version = "2.4.1" diff --git a/contracts/Cargo.toml b/contracts/Cargo.toml index fbd31e1a55..9fc98b76ea 100644 --- a/contracts/Cargo.toml +++ b/contracts/Cargo.toml @@ -4,11 +4,12 @@ members = [ "coconut-dkg", "ecash", "mixnet", - "nym-pool", "multisig/cw3-flex-multisig", "multisig/cw4-group", - "vesting", + "node-families", + "nym-pool", "performance", + "vesting", ] [workspace.package] @@ -18,6 +19,8 @@ homepage = "https://nymtech.net" documentation = "https://nymtech.net" edition = "2021" license = "Apache-2.0" +rust-version = "1.86.0" +readme = "../README.md" [profile.release] opt-level = 3 @@ -56,31 +59,33 @@ schemars = "0.8.16" thiserror = "2.0.11" -easy-addr = { version = "1.20.1", path = "../common/cosmwasm-smart-contracts/easy_addr" } +easy-addr = { version = "1.21.0", path = "../common/cosmwasm-smart-contracts/easy_addr" } # For local development with modifications, add a [patch.crates-io] section (see bottom of file) -nym-coconut-dkg-common = "1.20.4" -nym-contracts-common = "1.20.4" -nym-contracts-common-testing = "1.20.4" -nym-crypto = { version = "1.20.4", default-features = false } -nym-ecash-contract-common = "1.20.4" -nym-group-contract-common = "1.20.4" -nym-mixnet-contract-common = "1.20.4" -nym-multisig-contract-common = "1.20.4" -nym-network-defaults = { version = "1.20.4", default-features = false } -nym-performance-contract-common = "1.20.4" -nym-pool-contract-common = "1.20.4" -nym-vesting-contract-common = "1.20.4" +nym-coconut-dkg-common = "1.21.0" +nym-contracts-common = "1.21.0" +nym-contracts-common-testing = "1.21.0" +nym-crypto = { version = "1.21.0", default-features = false } +nym-ecash-contract-common = "1.21.0" +nym-group-contract-common = "1.21.0" +nym-mixnet-contract-common = "1.21.0" +nym-multisig-contract-common = "1.21.0" +nym-network-defaults = { version = "1.21.0", default-features = false } +nym-performance-contract-common = "1.21.0" +nym-pool-contract-common = "1.21.0" +nym-vesting-contract-common = "1.21.0" # Aliases for crates that some contracts import under different names -contracts-common = { version = "1.20.4", package = "nym-contracts-common" } -mixnet-contract-common = { version = "1.20.4", package = "nym-mixnet-contract-common" } -vesting-contract-common = { version = "1.20.4", package = "nym-vesting-contract-common" } +contracts-common = { version = "1.21.0", package = "nym-contracts-common" } +mixnet-contract-common = { version = "1.21.0", package = "nym-mixnet-contract-common" } +vesting-contract-common = { version = "1.21.0", package = "nym-vesting-contract-common" } +nym-node-families-contract-common = { version = "1.21.0", package = "nym-node-families-contract-common" } # Internal contract workspace members (for cross-contract testing) cw3-flex-multisig = { version = "2.0.0", path = "multisig/cw3-flex-multisig" } cw4-group = { version = "2.0.0", path = "multisig/cw4-group" } nym-mixnet-contract = { version = "1.5.1", path = "mixnet" } nym-vesting-contract = { version = "1.4.1", path = "vesting" } +node-families = { version = "0.1.0", path = "node-families" } [workspace.lints.clippy] unwrap_used = "deny" @@ -97,4 +102,10 @@ unreachable = "deny" # nym-coconut-dkg-common = { path = "../common/cosmwasm-smart-contracts/coconut-dkg" } [patch.crates-io] +nym-network-defaults = { path = "../common/network-defaults" } +nym-crypto = { path = "../common/crypto" } +nym-contracts-common-testing = { path = "../common/cosmwasm-smart-contracts/contracts-common-testing" } +nym-contracts-common = { path = "../common/cosmwasm-smart-contracts/contracts-common" } nym-ecash-contract-common = { path = "../common/cosmwasm-smart-contracts/ecash-contract" } +nym-mixnet-contract-common = { path = "../common/cosmwasm-smart-contracts/mixnet-contract" } +nym-node-families-contract-common = { path = "../common/cosmwasm-smart-contracts/node-families-contract" } diff --git a/contracts/mixnet/Cargo.toml b/contracts/mixnet/Cargo.toml index 20222063f6..88212ffa27 100644 --- a/contracts/mixnet/Cargo.toml +++ b/contracts/mixnet/Cargo.toml @@ -28,6 +28,7 @@ crate-type = ["cdylib", "rlib"] [dependencies] mixnet-contract-common = { workspace = true } vesting-contract-common = { workspace = true } +nym-node-families-contract-common = { workspace = true } nym-contracts-common = { workspace = true } nym-contracts-common-testing = { workspace = true, optional = true } @@ -41,6 +42,8 @@ bs58 = { workspace = true } serde = { workspace = true, default-features = false, features = ["derive"] } semver = { workspace = true } +nym-crypto = { workspace = true, optional = true } + [dev-dependencies] anyhow.workspace = true @@ -56,7 +59,7 @@ nym-contracts-common-testing = { workspace = true } [features] default = [] contract-testing = ["mixnet-contract-common/contract-testing"] -testable-mixnet-contract = ["nym-contracts-common-testing"] +testable-mixnet-contract = ["nym-contracts-common-testing", "nym-crypto", "nym-crypto/asymmetric", "nym-crypto/rand"] schema-gen = ["mixnet-contract-common/schema", "cosmwasm-schema"] [lints] diff --git a/contracts/mixnet/schema/nym-mixnet-contract.json b/contracts/mixnet/schema/nym-mixnet-contract.json index cf36563949..a479011c28 100644 --- a/contracts/mixnet/schema/nym-mixnet-contract.json +++ b/contracts/mixnet/schema/nym-mixnet-contract.json @@ -11,6 +11,7 @@ "epoch_duration", "epochs_in_interval", "initial_rewarding_params", + "node_families_contract_address", "rewarding_denom", "rewarding_validator_address", "vesting_contract_address" @@ -50,6 +51,9 @@ "format": "uint32", "minimum": 0.0 }, + "node_families_contract_address": { + "type": "string" + }, "profit_margin": { "default": { "maximum": "1", @@ -3509,7 +3513,13 @@ "$schema": "http://json-schema.org/draft-07/schema#", "title": "MigrateMsg", "type": "object", + "required": [ + "node_families_contract_address" + ], "properties": { + "node_families_contract_address": { + "type": "string" + }, "unsafe_skip_state_updates": { "type": [ "boolean", @@ -10774,12 +10784,21 @@ "description": "The current state of the mixnet contract.", "type": "object", "required": [ + "node_families_contract_address", "params", "rewarding_denom", "rewarding_validator_address", "vesting_contract_address" ], "properties": { + "node_families_contract_address": { + "description": "Address of the node families contract. It is called whenever nym-node unbonds so that it could be removed from any family it belongs to.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, "owner": { "description": "Address of the contract owner.", "default": null, diff --git a/contracts/mixnet/schema/raw/instantiate.json b/contracts/mixnet/schema/raw/instantiate.json index b17e1ae6bf..52caa8a639 100644 --- a/contracts/mixnet/schema/raw/instantiate.json +++ b/contracts/mixnet/schema/raw/instantiate.json @@ -7,6 +7,7 @@ "epoch_duration", "epochs_in_interval", "initial_rewarding_params", + "node_families_contract_address", "rewarding_denom", "rewarding_validator_address", "vesting_contract_address" @@ -46,6 +47,9 @@ "format": "uint32", "minimum": 0.0 }, + "node_families_contract_address": { + "type": "string" + }, "profit_margin": { "default": { "maximum": "1", diff --git a/contracts/mixnet/schema/raw/migrate.json b/contracts/mixnet/schema/raw/migrate.json index 57f0d2acdb..757f74d146 100644 --- a/contracts/mixnet/schema/raw/migrate.json +++ b/contracts/mixnet/schema/raw/migrate.json @@ -2,7 +2,13 @@ "$schema": "http://json-schema.org/draft-07/schema#", "title": "MigrateMsg", "type": "object", + "required": [ + "node_families_contract_address" + ], "properties": { + "node_families_contract_address": { + "type": "string" + }, "unsafe_skip_state_updates": { "type": [ "boolean", diff --git a/contracts/mixnet/schema/raw/response_to_get_state.json b/contracts/mixnet/schema/raw/response_to_get_state.json index c4a10bdb80..35501057aa 100644 --- a/contracts/mixnet/schema/raw/response_to_get_state.json +++ b/contracts/mixnet/schema/raw/response_to_get_state.json @@ -4,12 +4,21 @@ "description": "The current state of the mixnet contract.", "type": "object", "required": [ + "node_families_contract_address", "params", "rewarding_denom", "rewarding_validator_address", "vesting_contract_address" ], "properties": { + "node_families_contract_address": { + "description": "Address of the node families contract. It is called whenever nym-node unbonds so that it could be removed from any family it belongs to.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, "owner": { "description": "Address of the contract owner.", "default": null, diff --git a/contracts/mixnet/src/contract.rs b/contracts/mixnet/src/contract.rs index 0703e6dc23..23dfa000b7 100644 --- a/contracts/mixnet/src/contract.rs +++ b/contracts/mixnet/src/contract.rs @@ -5,7 +5,7 @@ use crate::constants::INITIAL_PLEDGE_AMOUNT; use crate::interval::storage as interval_storage; use crate::mixnet_contract_settings::storage as mixnet_params_storage; use crate::nodes::storage as nymnodes_storage; -use crate::queued_migrations::introduce_key_rotation_id; +use crate::queued_migrations::introduce_node_families_contract; use crate::rewards::storage::RewardingStorage; use cosmwasm_std::{ entry_point, to_json_binary, Addr, Coin, Deps, DepsMut, Env, MessageInfo, QueryResponse, @@ -28,6 +28,7 @@ fn default_initial_state( owner: Addr, rewarding_validator_address: Addr, vesting_contract_address: Addr, + node_families_contract_address: Addr, ) -> ContractState { // we have to temporarily preserve this functionalities until it can be removed #[allow(deprecated)] @@ -35,6 +36,7 @@ fn default_initial_state( owner: Some(owner), rewarding_validator_address, vesting_contract_address, + node_families_contract_address, rewarding_denom: msg.rewarding_denom.clone(), params: ContractStateParams { delegations_params: DelegationsParams { @@ -90,11 +92,15 @@ pub fn instantiate( let rewarding_validator_address = deps.api.addr_validate(&msg.rewarding_validator_address)?; let vesting_contract_address = deps.api.addr_validate(&msg.vesting_contract_address)?; + let node_families_contract_address = deps + .api + .addr_validate(&msg.node_families_contract_address)?; let state = default_initial_state( &msg, info.sender.clone(), rewarding_validator_address.clone(), vesting_contract_address, + node_families_contract_address, ); let starting_interval = Interval::init_interval(msg.epochs_in_interval, msg.epoch_duration, &env); @@ -629,7 +635,10 @@ pub fn migrate( let skip_state_updates = msg.unsafe_skip_state_updates.unwrap_or(false); if !skip_state_updates { - introduce_key_rotation_id(deps.branch())?; + let addr = deps + .api + .addr_validate(&msg.node_families_contract_address)?; + introduce_node_families_contract(deps.branch(), addr)?; } // due to circular dependency on contract addresses (i.e. mixnet contract requiring vesting contract address @@ -668,6 +677,7 @@ mod tests { let init_msg = InstantiateMsg { rewarding_validator_address: deps.api.addr_make("foomp123").to_string(), vesting_contract_address: deps.api.addr_make("bar456").to_string(), + node_families_contract_address: deps.api.addr_make("baz789").to_string(), rewarding_denom: "uatom".to_string(), epochs_in_interval: 1234, epoch_duration: Duration::from_secs(4321), @@ -708,6 +718,7 @@ mod tests { owner: Some(deps.api.addr_make("sender")), rewarding_validator_address: deps.api.addr_make("foomp123"), vesting_contract_address: deps.api.addr_make("bar456"), + node_families_contract_address: deps.api.addr_make("baz789"), rewarding_denom: "uatom".into(), params: ContractStateParams { delegations_params: DelegationsParams { diff --git a/contracts/mixnet/src/mixnet_contract_settings/queries.rs b/contracts/mixnet/src/mixnet_contract_settings/queries.rs index 5963dbf0a2..5ea711a1d0 100644 --- a/contracts/mixnet/src/mixnet_contract_settings/queries.rs +++ b/contracts/mixnet/src/mixnet_contract_settings/queries.rs @@ -71,7 +71,7 @@ pub(crate) fn query_current_nym_node_version( pub(crate) mod tests { use super::*; use crate::support::tests::test_helpers; - use cosmwasm_std::{coin, Addr}; + use cosmwasm_std::coin; use mixnet_contract_common::{ConfigScoreParams, DelegationsParams, OperatorsParams}; #[test] @@ -80,9 +80,10 @@ pub(crate) mod tests { #[allow(deprecated)] let dummy_state = ContractState { - owner: Some(Addr::unchecked("foomp")), - rewarding_validator_address: Addr::unchecked("monitor"), - vesting_contract_address: Addr::unchecked("foomp"), + owner: Some(deps.api.addr_make("foomp")), + rewarding_validator_address: deps.api.addr_make("monitor"), + vesting_contract_address: deps.api.addr_make("foomp"), + node_families_contract_address: deps.api.addr_make("bar"), rewarding_denom: "unym".to_string(), params: ContractStateParams { delegations_params: DelegationsParams { diff --git a/contracts/mixnet/src/mixnet_contract_settings/storage.rs b/contracts/mixnet/src/mixnet_contract_settings/storage.rs index edf511e3cd..98fb47c68b 100644 --- a/contracts/mixnet/src/mixnet_contract_settings/storage.rs +++ b/contracts/mixnet/src/mixnet_contract_settings/storage.rs @@ -156,6 +156,14 @@ pub(crate) fn vesting_contract_address(storage: &dyn Storage) -> Result Result { + Ok(CONTRACT_STATE + .load(storage) + .map(|state| state.node_families_contract_address)?) +} + pub(crate) fn state_params( storage: &dyn Storage, ) -> Result { diff --git a/contracts/mixnet/src/nodes/transactions.rs b/contracts/mixnet/src/nodes/transactions.rs index 646bd48dd9..96b043935f 100644 --- a/contracts/mixnet/src/nodes/transactions.rs +++ b/contracts/mixnet/src/nodes/transactions.rs @@ -16,7 +16,7 @@ use crate::support::helpers::{ ensure_epoch_in_progress_state, ensure_no_existing_bond, ensure_operating_cost_within_range, ensure_profit_margin_within_range, validate_pledge, }; -use cosmwasm_std::{coin, Coin, DepsMut, Env, MessageInfo, Response}; +use cosmwasm_std::{coin, wasm_execute, Coin, DepsMut, Env, MessageInfo, Response}; use mixnet_contract_common::error::MixnetContractError; use mixnet_contract_common::events::{ new_nym_node_bonding_event, new_pending_cost_params_update_event, @@ -29,6 +29,7 @@ use mixnet_contract_common::{ PendingIntervalEventKind, }; use nym_contracts_common::signing::{MessageSignature, SigningPurpose}; +use nym_node_families_contract_common::msg::ExecuteMsg as NodeFamiliesExecuteMsg; use serde::Serialize; pub fn try_add_nym_node( @@ -147,13 +148,24 @@ pub(crate) fn try_remove_nym_node( }; interval_storage::push_new_epoch_event(deps.storage, &env, epoch_event)?; - Ok( - Response::new().add_event(new_pending_nym_node_unbonding_event( + // send message to the node families contract to remove this node from any family it might be a member of + let node_families_contract_addr = + mixnet_params_storage::node_families_contract_address(deps.storage)?; + let remove_from_family_exec = wasm_execute( + node_families_contract_addr, + &NodeFamiliesExecuteMsg::OnNymNodeUnbond { + node_id: existing_bond.node_id, + }, + vec![], + )?; + + Ok(Response::new() + .add_message(remove_from_family_exec) + .add_event(new_pending_nym_node_unbonding_event( &existing_bond.owner, existing_bond.identity(), existing_bond.node_id, - )), - ) + ))) } pub(crate) fn try_update_node_config( diff --git a/contracts/mixnet/src/queued_migrations.rs b/contracts/mixnet/src/queued_migrations.rs index 4f9690a87e..32d87c1ab7 100644 --- a/contracts/mixnet/src/queued_migrations.rs +++ b/contracts/mixnet/src/queued_migrations.rs @@ -1,21 +1,39 @@ // Copyright 2022-2025 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::interval::storage as interval_storage; -use crate::nodes::storage as nymnodes_storage; -use cosmwasm_std::DepsMut; +use crate::constants::CONTRACT_STATE_KEY; +use crate::mixnet_contract_settings::storage as mixnet_params_storage; +use cosmwasm_std::{Addr, DepsMut}; +use cw_storage_plus::Item; use mixnet_contract_common::error::MixnetContractError; -use mixnet_contract_common::KeyRotationState; +use mixnet_contract_common::{ContractState, ContractStateParams}; + +pub fn introduce_node_families_contract( + deps: DepsMut, + node_families_contract_address: Addr, +) -> Result<(), MixnetContractError> { + #[derive(serde::Serialize, serde::Deserialize)] + struct OldContractState { + owner: Option, + rewarding_validator_address: Addr, + vesting_contract_address: Addr, + rewarding_denom: String, + params: ContractStateParams, + } + + const OLD_CONTRACT_STATE: Item = Item::new(CONTRACT_STATE_KEY); + let old = OLD_CONTRACT_STATE.load(deps.storage)?; + + #[allow(deprecated)] + let updated = ContractState { + owner: old.owner, + rewarding_validator_address: old.rewarding_validator_address, + vesting_contract_address: old.vesting_contract_address, + rewarding_denom: old.rewarding_denom, + params: old.params, + node_families_contract_address, + }; + mixnet_params_storage::CONTRACT_STATE.save(deps.storage, &updated)?; -pub fn introduce_key_rotation_id(deps: DepsMut) -> Result<(), MixnetContractError> { - let current_epoch_id = - interval_storage::current_interval(deps.storage)?.current_epoch_absolute_id(); - nymnodes_storage::KEY_ROTATION_STATE.save( - deps.storage, - &KeyRotationState { - validity_epochs: 24, - initial_epoch_id: current_epoch_id, - }, - )?; Ok(()) } diff --git a/contracts/mixnet/src/testable_mixnet_contract.rs b/contracts/mixnet/src/testable_mixnet_contract.rs index 498e121222..d829105f0c 100644 --- a/contracts/mixnet/src/testable_mixnet_contract.rs +++ b/contracts/mixnet/src/testable_mixnet_contract.rs @@ -5,16 +5,26 @@ #![allow(clippy::unwrap_used)] use crate::contract::{execute, instantiate, migrate, query}; -use cosmwasm_std::Decimal; +use cosmwasm_std::testing::{message_info, mock_env}; +use cosmwasm_std::{coin, coins, Addr, Decimal, MessageInfo, StdError, StdResult}; use mixnet_contract_common::error::MixnetContractError; +use mixnet_contract_common::nym_node::{NodeDetailsResponse, NodeOwnershipResponse, Role}; use mixnet_contract_common::reward_params::RewardedSetParams; use mixnet_contract_common::{ - ExecuteMsg, InitialRewardingParams, InstantiateMsg, MigrateMsg, QueryMsg, + CurrentIntervalResponse, EpochId, ExecuteMsg, InitialRewardingParams, InstantiateMsg, Interval, + MigrateMsg, MixnetContractQuerier, NodeCostParams, NodeId, NymNode, NymNodeBondingPayload, + QueryMsg, RoleAssignment, SignableNymNodeBondingMsg, DEFAULT_INTERVAL_OPERATING_COST_AMOUNT, + DEFAULT_PROFIT_MARGIN_PERCENT, }; +use nym_contracts_common::signing::{ContractMessageContent, MessageSignature}; use nym_contracts_common::Percent; use nym_contracts_common_testing::{ - mock_dependencies, ContractFn, PermissionedFn, QueryFn, TEST_DENOM, + mock_dependencies, ArbitraryContractStorageReader, ArbitraryContractStorageWriter, BankExt, + ChainOpts, ContractFn, ContractTester, PermissionedFn, QueryFn, RandExt, TEST_DENOM, }; +use nym_crypto::asymmetric::ed25519; +use serde::de::DeserializeOwned; +use serde::Serialize; use std::time::Duration; pub use nym_contracts_common_testing::TestableNymContract; @@ -74,6 +84,10 @@ impl TestableNymContract for MixnetContract { InstantiateMsg { rewarding_validator_address: deps.api.addr_make("rewarder").to_string(), vesting_contract_address: deps.api.addr_make("vesting-contract").to_string(), + node_families_contract_address: deps + .api + .addr_make("node-families-contract") + .to_string(), rewarding_denom: TEST_DENOM.to_string(), epochs_in_interval: 720, epoch_duration: Duration::from_secs(60 * 60), @@ -87,3 +101,203 @@ impl TestableNymContract for MixnetContract { } } } + +pub trait EmbeddedMixnetContractExt: + ChainOpts + ArbitraryContractStorageWriter + ArbitraryContractStorageReader + RandExt + BankExt +{ + fn mixnet_contract_address(&self) -> StdResult; + + fn execute_mixnet_contract(&mut self, sender: MessageInfo, msg: &ExecuteMsg) -> StdResult<()> { + let address = self.mixnet_contract_address()?; + + self.execute_arbitrary_contract(address, sender, msg) + .map_err(|err| { + StdError::generic_err(format!("mixnet contract execution failure: {err}")) + })?; + Ok(()) + } + + fn read_from_mixnet_contract_storage( + &self, + key: impl AsRef<[u8]>, + ) -> StdResult { + let address = self.mixnet_contract_address()?; + + self.must_read_value_from_contract_storage(address, key) + } + + fn write_to_mixnet_contract_storage( + &mut self, + key: impl AsRef<[u8]>, + value: impl AsRef<[u8]>, + ) -> StdResult<()> { + let address = self.mixnet_contract_address()?; + + ::set_contract_storage(self, address, key, value); + Ok(()) + } + + fn write_to_mixnet_contract_storage_value( + &mut self, + key: impl AsRef<[u8]>, + value: &T, + ) -> StdResult<()> { + let address = self.mixnet_contract_address()?; + + self.set_contract_storage_value(address, key, value) + } + + fn current_mixnet_epoch(&self) -> StdResult { + let address = self.mixnet_contract_address()?; + + Ok(self + .deps() + .querier + .query_current_mixnet_interval(address.clone())? + .current_epoch_absolute_id()) + } + + fn advance_mixnet_epoch(&mut self) -> StdResult<()> { + let interval_details: CurrentIntervalResponse = self.query_arbitrary_contract( + self.mixnet_contract_address()?, + &QueryMsg::GetCurrentIntervalDetails {}, + )?; + let until_end = interval_details.time_until_current_epoch_end().as_secs(); + let timestamp = self.env().block.time.plus_seconds(until_end + 1); + self.set_block_time(timestamp); + self.next_block(); + + // this was hardcoded in mixnet init + let mixnet_rewarder = self.addr_make("rewarder"); + let rewarder = message_info(&mixnet_rewarder, &[]); + self.execute_mixnet_contract(rewarder.clone(), &ExecuteMsg::BeginEpochTransition {})?; + self.execute_mixnet_contract( + rewarder.clone(), + &ExecuteMsg::ReconcileEpochEvents { limit: None }, + )?; + + for role in [ + Role::ExitGateway, + Role::EntryGateway, + Role::Layer1, + Role::Layer2, + Role::Layer3, + Role::Standby, + ] { + self.execute_mixnet_contract( + rewarder.clone(), + &ExecuteMsg::AssignRoles { + assignment: RoleAssignment { + role, + nodes: vec![], + }, + }, + )?; + } + Ok(()) + } + + fn set_mixnet_epoch(&mut self, epoch_id: EpochId) -> StdResult<()> { + let address = self.mixnet_contract_address()?; + + let interval = self + .deps() + .querier + .query_current_mixnet_interval(address.clone())?; + + let mut to_update = if interval.current_epoch_absolute_id() <= epoch_id { + interval + } else { + Interval::init_interval( + interval.epochs_in_interval(), + interval.epoch_length(), + &mock_env(), + ) + }; + + let current = to_update.current_epoch_absolute_id(); + let diff = epoch_id - current; + for _ in 0..diff { + to_update = to_update.advance_epoch(); + } + self.set_contract_storage_value(&address, b"ci", &to_update) + } + + fn bond_dummy_nymnode_for(&mut self, node_owner: &Addr) -> Result { + let pledge = coins(100_000000, TEST_DENOM); + let keypair = ed25519::KeyPair::new(self.raw_rng()); + let identity_key = keypair.public_key().to_base58_string(); + + let node = NymNode { + host: "1.2.3.4".to_string(), + custom_http_port: None, + identity_key, + }; + let cost_params = NodeCostParams { + profit_margin_percent: Percent::from_percentage_value(DEFAULT_PROFIT_MARGIN_PERCENT) + .unwrap(), + interval_operating_cost: coin(DEFAULT_INTERVAL_OPERATING_COST_AMOUNT, TEST_DENOM), + }; + // initial signing nonce is 0 for a new address + let signing_nonce = 0; + + let payload = NymNodeBondingPayload::new(node.clone(), cost_params.clone()); + let content = ContractMessageContent::new(node_owner.clone(), pledge.clone(), payload); + let msg = SignableNymNodeBondingMsg::new(signing_nonce, content); + + let owner_signature = keypair.private_key().sign(msg.to_plaintext()?); + let owner_signature = MessageSignature::from(owner_signature.to_bytes().as_ref()); + + self.execute_mixnet_contract( + message_info(node_owner, &pledge), + &ExecuteMsg::BondNymNode { + node, + cost_params, + owner_signature, + }, + )?; + + let bond: NodeOwnershipResponse = self.query_arbitrary_contract( + self.mixnet_contract_address()?, + &QueryMsg::GetOwnedNymNode { + address: node_owner.to_string(), + }, + )?; + + Ok(bond.details.unwrap().bond_information.node_id) + } + + fn bond_dummy_nymnode(&mut self) -> Result { + let node_owner = self.generate_account_with_balance(); + self.bond_dummy_nymnode_for(&node_owner) + } + + fn unbond_nymnode(&mut self, node_id: NodeId) -> Result<(), StdError> { + let bond: NodeDetailsResponse = self.query_arbitrary_contract( + self.mixnet_contract_address()?, + &QueryMsg::GetNymNodeDetails { node_id }, + )?; + + let node_owner = bond.details.unwrap().bond_information.owner; + + self.execute_mixnet_contract( + message_info(&node_owner, &[]), + &ExecuteMsg::UnbondNymNode {}, + )?; + + self.advance_mixnet_epoch()?; + Ok(()) + } +} + +impl EmbeddedMixnetContractExt for ContractTester +where + C: TestableNymContract, +{ + fn mixnet_contract_address(&self) -> StdResult { + self.well_known_contracts + .get(MixnetContract::NAME) + .ok_or_else(|| StdError::generic_err("mixnet contract not part of the tester")) + .cloned() + } +} diff --git a/contracts/node-families/.cargo/config b/contracts/node-families/.cargo/config new file mode 100644 index 0000000000..2fb2c1afdb --- /dev/null +++ b/contracts/node-families/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --bin schema --features=schema-gen" \ No newline at end of file diff --git a/contracts/node-families/Cargo.toml b/contracts/node-families/Cargo.toml new file mode 100644 index 0000000000..289db1eae2 --- /dev/null +++ b/contracts/node-families/Cargo.toml @@ -0,0 +1,62 @@ +[package] +name = "node-families" +description = "Nym Node Families contract" +version = "0.1.0" +authors.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +homepage.workspace = true +documentation.workspace = true +rust-version.workspace = true +readme.workspace = true +publish = false + +[[bin]] +name = "schema" +required-features = ["schema-gen"] + +[lib] +name = "node_families_contract" +crate-type = ["cdylib", "rlib"] + +[dependencies] +cosmwasm-std = { workspace = true } +cw2 = { workspace = true } +cw-storage-plus = { workspace = true } +cw-controllers = { workspace = true } +serde = { workspace = true } +cosmwasm-schema = { workspace = true, optional = true } +cw-utils = { workspace = true } + +nym-contracts-common = { workspace = true } +nym-node-families-contract-common = { workspace = true } +nym-mixnet-contract-common = { workspace = true } + +# Optional deps activated by the `testable-node-families-contract` feature so +# downstream crates can pull in `crate::testing` for their own test harnesses. +nym-contracts-common-testing = { workspace = true, optional = true } +nym-mixnet-contract = { workspace = true, optional = true, features = ["testable-mixnet-contract"] } +nym-crypto = { workspace = true, optional = true } + +[dev-dependencies] +anyhow = { workspace = true } +# make the testing helpers available for this crate's own unit tests via +# `cfg(test)`; downstream crates instead pull these in through the +# `testable-node-families-contract` feature. +nym-contracts-common-testing = { workspace = true } +nym-mixnet-contract = { workspace = true, features = ["testable-mixnet-contract"] } +nym-crypto = { workspace = true, features = ["asymmetric"] } + +[features] +schema-gen = ["nym-node-families-contract-common/schema", "cosmwasm-schema"] +testable-node-families-contract = [ + "nym-contracts-common-testing", + "nym-mixnet-contract", + "nym-crypto", + "nym-crypto/asymmetric", +] + + +[lints] +workspace = true diff --git a/contracts/node-families/Makefile b/contracts/node-families/Makefile new file mode 100644 index 0000000000..086fa71ad3 --- /dev/null +++ b/contracts/node-families/Makefile @@ -0,0 +1,5 @@ +wasm: + RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown + +generate-schema: + cargo schema diff --git a/contracts/node-families/schema/node-families.json b/contracts/node-families/schema/node-families.json new file mode 100644 index 0000000000..b9165c7546 --- /dev/null +++ b/contracts/node-families/schema/node-families.json @@ -0,0 +1,2844 @@ +{ + "contract_name": "node-families", + "contract_version": "0.1.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "description": "Message used to instantiate the node families contract.", + "type": "object", + "required": [ + "config", + "mixnet_contract_address" + ], + "properties": { + "config": { + "$ref": "#/definitions/Config" + }, + "mixnet_contract_address": { + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "additionalProperties": false + }, + "Config": { + "description": "Runtime configuration of the node families contract.", + "type": "object", + "required": [ + "create_family_fee", + "default_invitation_validity_secs", + "family_description_length_limit", + "family_name_length_limit" + ], + "properties": { + "create_family_fee": { + "description": "Fee charged on each successful `create_family` execution.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "default_invitation_validity_secs": { + "description": "Default lifetime, in seconds, used by `invite_to_family` when the sender doesn't supply an explicit value. Senders may override this per-invitation via the optional `validity_secs` argument.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "family_description_length_limit": { + "description": "Maximum allowed length, in characters, of a family description.", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "family_name_length_limit": { + "description": "Maximum allowed length, in characters, of a family name.", + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "description": "Execute messages accepted by the contract.", + "oneOf": [ + { + "description": "Replace the contract's runtime [`Config`]. Restricted to the contract admin.", + "type": "object", + "required": [ + "update_config" + ], + "properties": { + "update_config": { + "type": "object", + "required": [ + "config" + ], + "properties": { + "config": { + "$ref": "#/definitions/Config" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Create a new family owned by the message sender. The configured `create_family_fee` must be attached as funds.", + "type": "object", + "required": [ + "create_family" + ], + "properties": { + "create_family": { + "type": "object", + "required": [ + "description", + "name" + ], + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Disband the family owned by the message sender. The family must have no current members; any still-pending invitations are revoked.", + "type": "object", + "required": [ + "disband_family" + ], + "properties": { + "disband_family": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Invite a node to the family owned by the message sender. If `validity_secs` is omitted the invitation expires `default_invitation_validity_secs` seconds (from [`Config`]) after the current block time.", + "type": "object", + "required": [ + "invite_to_family" + ], + "properties": { + "invite_to_family": { + "type": "object", + "required": [ + "node_id" + ], + "properties": { + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "validity_secs": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Revoke a still-pending invitation previously issued by the sender's family.", + "type": "object", + "required": [ + "revoke_family_invitation" + ], + "properties": { + "revoke_family_invitation": { + "type": "object", + "required": [ + "node_id" + ], + "properties": { + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Accept a pending invitation. The sender must control `node_id`.", + "type": "object", + "required": [ + "accept_family_invitation" + ], + "properties": { + "accept_family_invitation": { + "type": "object", + "required": [ + "family_id", + "node_id" + ], + "properties": { + "family_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Reject a pending invitation. The sender must control `node_id`.", + "type": "object", + "required": [ + "reject_family_invitation" + ], + "properties": { + "reject_family_invitation": { + "type": "object", + "required": [ + "family_id", + "node_id" + ], + "properties": { + "family_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Leave the family `node_id` currently belongs to. The sender must control `node_id`.", + "type": "object", + "required": [ + "leave_family" + ], + "properties": { + "leave_family": { + "type": "object", + "required": [ + "node_id" + ], + "properties": { + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Remove `node_id` from the family owned by the message sender.", + "type": "object", + "required": [ + "kick_from_family" + ], + "properties": { + "kick_from_family": { + "type": "object", + "required": [ + "node_id" + ], + "properties": { + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Cross-contract callback fired by the mixnet contract the moment node with `node_id` initiates unbonding. Removes the node from any family it currently belongs to and rejects every pending invitation issued to it. Sender must be the configured mixnet contract address.", + "type": "object", + "required": [ + "on_nym_node_unbond" + ], + "properties": { + "on_nym_node_unbond": { + "type": "object", + "required": [ + "node_id" + ], + "properties": { + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "additionalProperties": false + }, + "Config": { + "description": "Runtime configuration of the node families contract.", + "type": "object", + "required": [ + "create_family_fee", + "default_invitation_validity_secs", + "family_description_length_limit", + "family_name_length_limit" + ], + "properties": { + "create_family_fee": { + "description": "Fee charged on each successful `create_family` execution.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "default_invitation_validity_secs": { + "description": "Default lifetime, in seconds, used by `invite_to_family` when the sender doesn't supply an explicit value. Senders may override this per-invitation via the optional `validity_secs` argument.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "family_description_length_limit": { + "description": "Maximum allowed length, in characters, of a family description.", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "family_name_length_limit": { + "description": "Maximum allowed length, in characters, of a family name.", + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "description": "Query messages accepted by the contract.", + "oneOf": [ + { + "description": "Look up a single family by its id.", + "type": "object", + "required": [ + "get_family_by_id" + ], + "properties": { + "get_family_by_id": { + "type": "object", + "required": [ + "family_id" + ], + "properties": { + "family_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Look up the (at most one) family owned by a given address.", + "type": "object", + "required": [ + "get_family_by_owner" + ], + "properties": { + "get_family_by_owner": { + "type": "object", + "required": [ + "owner" + ], + "properties": { + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Look up a single family by its name. The lookup is normalised contract-side (lowercased, non-alphanumerics stripped), so equivalent inputs resolve to the same family.", + "type": "object", + "required": [ + "get_family_by_name" + ], + "properties": { + "get_family_by_name": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "get_families_paged" + ], + "properties": { + "get_families_paged": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Look up which family — if any — a node currently belongs to.", + "type": "object", + "required": [ + "get_family_membership" + ], + "properties": { + "get_family_membership": { + "type": "object", + "required": [ + "node_id" + ], + "properties": { + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Page through every node currently in a given family.", + "type": "object", + "required": [ + "get_family_members_paged" + ], + "properties": { + "get_family_members_paged": { + "type": "object", + "required": [ + "family_id" + ], + "properties": { + "family_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Page through every current family member across all families, in ascending [`NodeId`] order. Each entry carries the membership record (which in turn names the family the node belongs to).", + "type": "object", + "required": [ + "get_all_family_members_paged" + ], + "properties": { + "get_all_family_members_paged": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Look up the pending invitation for a specific `(family_id, node_id)` pair.", + "type": "object", + "required": [ + "get_pending_invitation" + ], + "properties": { + "get_pending_invitation": { + "type": "object", + "required": [ + "family_id", + "node_id" + ], + "properties": { + "family_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Page through every pending invitation issued by a given family.", + "type": "object", + "required": [ + "get_pending_invitations_for_family_paged" + ], + "properties": { + "get_pending_invitations_for_family_paged": { + "type": "object", + "required": [ + "family_id" + ], + "properties": { + "family_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Page through every pending invitation issued for a given node.", + "type": "object", + "required": [ + "get_pending_invitations_for_node_paged" + ], + "properties": { + "get_pending_invitations_for_node_paged": { + "type": "object", + "required": [ + "node_id" + ], + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Page through every pending invitation across all families.", + "type": "object", + "required": [ + "get_all_pending_invitations_paged" + ], + "properties": { + "get_all_pending_invitations_paged": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Page through every archived (terminal-state) invitation issued by a given family.", + "type": "object", + "required": [ + "get_past_invitations_for_family_paged" + ], + "properties": { + "get_past_invitations_for_family_paged": { + "type": "object", + "required": [ + "family_id" + ], + "properties": { + "family_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Page through every archived (terminal-state) invitation issued to a given node.", + "type": "object", + "required": [ + "get_past_invitations_for_node_paged" + ], + "properties": { + "get_past_invitations_for_node_paged": { + "type": "object", + "required": [ + "node_id" + ], + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Page through every archived (terminal-state) invitation across all families.", + "type": "object", + "required": [ + "get_all_past_invitations_paged" + ], + "properties": { + "get_all_past_invitations_paged": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Page through every archived membership record for a given family (nodes that used to belong to it but have since been removed).", + "type": "object", + "required": [ + "get_past_members_for_family_paged" + ], + "properties": { + "get_past_members_for_family_paged": { + "type": "object", + "required": [ + "family_id" + ], + "properties": { + "family_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Page through every archived membership record for a given node (every family the node used to belong to but has since been removed from), across all families.", + "type": "object", + "required": [ + "get_past_members_for_node_paged" + ], + "properties": { + "get_past_members_for_node_paged": { + "type": "object", + "required": [ + "node_id" + ], + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "description": "Message passed to the contract's `migrate` entry point.", + "type": "object", + "additionalProperties": false + }, + "sudo": null, + "responses": { + "get_all_family_members_paged": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AllFamilyMembersPagedResponse", + "description": "Response to [`QueryMsg::GetAllFamilyMembersPaged`](crate::QueryMsg::GetAllFamilyMembersPaged).", + "type": "object", + "required": [ + "members" + ], + "properties": { + "members": { + "description": "The members on this page, in ascending [`NodeId`] order across every family.", + "type": "array", + "items": { + "$ref": "#/definitions/FamilyMemberRecord" + } + }, + "start_next_after": { + "description": "Cursor (last `node_id`) to pass as `start_after` on the next call, or `None` if this page is empty (treat as end-of-list).", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "FamilyMemberRecord": { + "description": "One entry in a [`FamilyMembersPagedResponse`] page — pairs a node id with its [`FamilyMembership`] record (notably its `joined_at` timestamp).", + "type": "object", + "required": [ + "membership", + "node_id" + ], + "properties": { + "membership": { + "description": "The membership record (carries `family_id` and `joined_at`).", + "allOf": [ + { + "$ref": "#/definitions/FamilyMembership" + } + ] + }, + "node_id": { + "description": "The node currently in the family.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "FamilyMembership": { + "description": "On-chain record of a node's current family membership.\n\nA node belongs to at most one family at a time, so this is keyed by `NodeId` alone — `family_id` is carried in the value to support reverse lookups (all nodes in a given family) via a secondary index.", + "type": "object", + "required": [ + "family_id", + "joined_at" + ], + "properties": { + "family_id": { + "description": "The family the node is currently a member of.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "joined_at": { + "description": "Block timestamp (unix seconds) at which the node accepted its invitation and joined the family.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + }, + "get_all_past_invitations_paged": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AllPastFamilyInvitationsPagedResponse", + "description": "Response to [`QueryMsg::GetAllPastInvitationsPaged`](crate::QueryMsg::GetAllPastInvitationsPaged).", + "type": "object", + "required": [ + "invitations" + ], + "properties": { + "invitations": { + "description": "The archived invitations on this page, in ascending `((family_id, node_id), counter)` order across all terminal statuses.", + "type": "array", + "items": { + "$ref": "#/definitions/PastFamilyInvitation" + } + }, + "start_next_after": { + "description": "Cursor to pass as `start_after` on the next call, or `None` if this page is empty (treat as end-of-list).", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false, + "definitions": { + "FamilyInvitation": { + "description": "A pending invitation for a node to join a particular family.\n\nInvitations are stored until they are accepted, rejected, revoked, or until the chain advances past `expires_at` (in which case they remain in storage but are treated as inert — there is no background process clearing expired invitations).", + "type": "object", + "required": [ + "expires_at", + "family_id", + "node_id" + ], + "properties": { + "expires_at": { + "description": "Block timestamp (unix seconds) after which the invitation is no longer valid.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "family_id": { + "description": "The family that issued the invitation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "description": "The node being invited.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "FamilyInvitationStatus": { + "description": "Terminal status for an invitation that has been moved out of the pending set.\n\nNote: timed-out invitations are not represented here — they are simply left in the pending set (see `FamilyInvitation::expires_at`).", + "oneOf": [ + { + "description": "Still awaiting a response. Recorded with a timestamp for completeness even though pending invitations live in a separate map.", + "type": "object", + "required": [ + "pending" + ], + "properties": { + "pending": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "The invitee accepted and joined the family at the given timestamp.", + "type": "object", + "required": [ + "accepted" + ], + "properties": { + "accepted": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "The invitee explicitly rejected the invitation at the given timestamp.", + "type": "object", + "required": [ + "rejected" + ], + "properties": { + "rejected": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "The family revoked the invitation at the given timestamp before it could be accepted or rejected.", + "type": "object", + "required": [ + "revoked" + ], + "properties": { + "revoked": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "PastFamilyInvitation": { + "description": "Historical record of an invitation that has reached a terminal state (`Accepted`, `Rejected`, or `Revoked`). Timed-out invitations are **not** archived here — they remain in the pending map until explicitly cleared.", + "type": "object", + "required": [ + "invitation", + "status" + ], + "properties": { + "invitation": { + "description": "The original invitation as it was issued.", + "allOf": [ + { + "$ref": "#/definitions/FamilyInvitation" + } + ] + }, + "status": { + "description": "What ultimately happened to it.", + "allOf": [ + { + "$ref": "#/definitions/FamilyInvitationStatus" + } + ] + } + }, + "additionalProperties": false + } + } + }, + "get_all_pending_invitations_paged": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingInvitationsPagedResponse", + "description": "Response to [`QueryMsg::GetAllPendingInvitationsPaged`](crate::QueryMsg::GetAllPendingInvitationsPaged).", + "type": "object", + "required": [ + "invitations" + ], + "properties": { + "invitations": { + "description": "The pending invitations on this page, in ascending `(family_id, node_id)` order, each stamped with whether it had already timed out at the time the query was served.", + "type": "array", + "items": { + "$ref": "#/definitions/PendingFamilyInvitationDetails" + } + }, + "start_next_after": { + "description": "Cursor (last `(family_id, node_id)` pair) to pass as `start_after` on the next call, or `None` if this page is empty (treat as end-of-list).", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false, + "definitions": { + "FamilyInvitation": { + "description": "A pending invitation for a node to join a particular family.\n\nInvitations are stored until they are accepted, rejected, revoked, or until the chain advances past `expires_at` (in which case they remain in storage but are treated as inert — there is no background process clearing expired invitations).", + "type": "object", + "required": [ + "expires_at", + "family_id", + "node_id" + ], + "properties": { + "expires_at": { + "description": "Block timestamp (unix seconds) after which the invitation is no longer valid.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "family_id": { + "description": "The family that issued the invitation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "description": "The node being invited.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "PendingFamilyInvitationDetails": { + "description": "A pending [`FamilyInvitation`] paired with whether it has already timed out at the time the query was served.", + "type": "object", + "required": [ + "expired", + "invitation" + ], + "properties": { + "expired": { + "description": "`true` iff `now >= invitation.expires_at` at query time, i.e. the invitation is still in the pending map but can no longer be acted on.", + "type": "boolean" + }, + "invitation": { + "description": "The stored invitation as it was issued.", + "allOf": [ + { + "$ref": "#/definitions/FamilyInvitation" + } + ] + } + }, + "additionalProperties": false + } + } + }, + "get_families_paged": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "FamiliesPagedResponse", + "description": "Response to [`QueryMsg::GetFamiliesPaged`](crate::QueryMsg::GetFamiliesPaged).", + "type": "object", + "required": [ + "families" + ], + "properties": { + "families": { + "description": "The families on this page, in ascending [`NodeFamilyId`] order.", + "type": "array", + "items": { + "$ref": "#/definitions/NodeFamily" + } + }, + "start_next_after": { + "description": "Cursor to pass as `start_after` on the next call, or `None` if this page is empty (which the caller should treat as end-of-list).", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "additionalProperties": false + }, + "NodeFamily": { + "description": "On-chain representation of a node family.", + "type": "object", + "required": [ + "created_at", + "description", + "id", + "members", + "name", + "normalised_name", + "owner", + "paid_fee" + ], + "properties": { + "created_at": { + "description": "Timestamp of the creation of the node family", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "description": { + "description": "The optional description of the node family", + "type": "string" + }, + "id": { + "description": "The id of the node family", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "members": { + "description": "Memoized value of the current number of members in the node family Used to detect if the family is empty", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "name": { + "description": "The name of the node family", + "type": "string" + }, + "normalised_name": { + "description": "Normalised name of the node family used for uniqueness checks", + "type": "string" + }, + "owner": { + "description": "The owner of the node family", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "paid_fee": { + "description": "Records the fee paid when the family was created, so that the appropriate amount could be returned upon it getting disbanded.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_family_by_id": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "NodeFamilyResponse", + "description": "Response to [`QueryMsg::GetFamilyById`](crate::QueryMsg::GetFamilyById).", + "type": "object", + "required": [ + "family_id" + ], + "properties": { + "family": { + "description": "The matching family, or `None` if no family with `family_id` exists.", + "anyOf": [ + { + "$ref": "#/definitions/NodeFamily" + }, + { + "type": "null" + } + ] + }, + "family_id": { + "description": "The id that was queried, echoed back so paginated callers can correlate.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "additionalProperties": false + }, + "NodeFamily": { + "description": "On-chain representation of a node family.", + "type": "object", + "required": [ + "created_at", + "description", + "id", + "members", + "name", + "normalised_name", + "owner", + "paid_fee" + ], + "properties": { + "created_at": { + "description": "Timestamp of the creation of the node family", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "description": { + "description": "The optional description of the node family", + "type": "string" + }, + "id": { + "description": "The id of the node family", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "members": { + "description": "Memoized value of the current number of members in the node family Used to detect if the family is empty", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "name": { + "description": "The name of the node family", + "type": "string" + }, + "normalised_name": { + "description": "Normalised name of the node family used for uniqueness checks", + "type": "string" + }, + "owner": { + "description": "The owner of the node family", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "paid_fee": { + "description": "Records the fee paid when the family was created, so that the appropriate amount could be returned upon it getting disbanded.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_family_by_name": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "NodeFamilyByNameResponse", + "description": "Response to [`QueryMsg::GetFamilyByName`](crate::QueryMsg::GetFamilyByName).", + "type": "object", + "required": [ + "name" + ], + "properties": { + "family": { + "description": "The matching family, or `None` if no family with that name exists.", + "anyOf": [ + { + "$ref": "#/definitions/NodeFamily" + }, + { + "type": "null" + } + ] + }, + "name": { + "description": "The name that was queried, echoed back so callers can correlate.", + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "additionalProperties": false + }, + "NodeFamily": { + "description": "On-chain representation of a node family.", + "type": "object", + "required": [ + "created_at", + "description", + "id", + "members", + "name", + "normalised_name", + "owner", + "paid_fee" + ], + "properties": { + "created_at": { + "description": "Timestamp of the creation of the node family", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "description": { + "description": "The optional description of the node family", + "type": "string" + }, + "id": { + "description": "The id of the node family", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "members": { + "description": "Memoized value of the current number of members in the node family Used to detect if the family is empty", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "name": { + "description": "The name of the node family", + "type": "string" + }, + "normalised_name": { + "description": "Normalised name of the node family used for uniqueness checks", + "type": "string" + }, + "owner": { + "description": "The owner of the node family", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "paid_fee": { + "description": "Records the fee paid when the family was created, so that the appropriate amount could be returned upon it getting disbanded.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_family_by_owner": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "NodeFamilyByOwnerResponse", + "description": "Response to [`QueryMsg::GetFamilyByOwner`](crate::QueryMsg::GetFamilyByOwner).", + "type": "object", + "required": [ + "owner" + ], + "properties": { + "family": { + "description": "The matching family, or `None` if `owner` does not currently own one.", + "anyOf": [ + { + "$ref": "#/definitions/NodeFamily" + }, + { + "type": "null" + } + ] + }, + "owner": { + "description": "The (validated) owner address that was queried, echoed back so callers can correlate.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "additionalProperties": false + }, + "NodeFamily": { + "description": "On-chain representation of a node family.", + "type": "object", + "required": [ + "created_at", + "description", + "id", + "members", + "name", + "normalised_name", + "owner", + "paid_fee" + ], + "properties": { + "created_at": { + "description": "Timestamp of the creation of the node family", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "description": { + "description": "The optional description of the node family", + "type": "string" + }, + "id": { + "description": "The id of the node family", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "members": { + "description": "Memoized value of the current number of members in the node family Used to detect if the family is empty", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "name": { + "description": "The name of the node family", + "type": "string" + }, + "normalised_name": { + "description": "Normalised name of the node family used for uniqueness checks", + "type": "string" + }, + "owner": { + "description": "The owner of the node family", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "paid_fee": { + "description": "Records the fee paid when the family was created, so that the appropriate amount could be returned upon it getting disbanded.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } + }, + "get_family_members_paged": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "FamilyMembersPagedResponse", + "description": "Response to [`QueryMsg::GetFamilyMembersPaged`](crate::QueryMsg::GetFamilyMembersPaged).", + "type": "object", + "required": [ + "family_id", + "members" + ], + "properties": { + "family_id": { + "description": "The family whose members were queried, echoed back so paginated callers can correlate.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "members": { + "description": "The members on this page, in ascending [`NodeId`] order.", + "type": "array", + "items": { + "$ref": "#/definitions/FamilyMemberRecord" + } + }, + "start_next_after": { + "description": "Cursor to pass as `start_after` on the next call, or `None` if this page is empty (which the caller should treat as end-of-list).", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "FamilyMemberRecord": { + "description": "One entry in a [`FamilyMembersPagedResponse`] page — pairs a node id with its [`FamilyMembership`] record (notably its `joined_at` timestamp).", + "type": "object", + "required": [ + "membership", + "node_id" + ], + "properties": { + "membership": { + "description": "The membership record (carries `family_id` and `joined_at`).", + "allOf": [ + { + "$ref": "#/definitions/FamilyMembership" + } + ] + }, + "node_id": { + "description": "The node currently in the family.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "FamilyMembership": { + "description": "On-chain record of a node's current family membership.\n\nA node belongs to at most one family at a time, so this is keyed by `NodeId` alone — `family_id` is carried in the value to support reverse lookups (all nodes in a given family) via a secondary index.", + "type": "object", + "required": [ + "family_id", + "joined_at" + ], + "properties": { + "family_id": { + "description": "The family the node is currently a member of.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "joined_at": { + "description": "Block timestamp (unix seconds) at which the node accepted its invitation and joined the family.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + }, + "get_family_membership": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "NodeFamilyMembershipResponse", + "description": "Response to [`QueryMsg::GetFamilyMembership`](crate::QueryMsg::GetFamilyMembership).", + "type": "object", + "required": [ + "node_id" + ], + "properties": { + "family_id": { + "description": "The id of the family the node currently belongs to, or `None` if the node is not currently a member of any family.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "description": "The node that was queried.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "get_past_invitations_for_family_paged": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PastFamilyInvitationsPagedResponse", + "description": "Response to [`QueryMsg::GetPastInvitationsForFamilyPaged`](crate::QueryMsg::GetPastInvitationsForFamilyPaged).", + "type": "object", + "required": [ + "family_id", + "invitations" + ], + "properties": { + "family_id": { + "description": "The family whose archived invitations were queried, echoed back so paginated callers can correlate.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "invitations": { + "description": "The archived invitations on this page, in ascending `(node_id, counter)` order across all terminal statuses.", + "type": "array", + "items": { + "$ref": "#/definitions/PastFamilyInvitation" + } + }, + "start_next_after": { + "description": "Cursor to pass as `start_after` on the next call, or `None` if this page is empty (treat as end-of-list).", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false, + "definitions": { + "FamilyInvitation": { + "description": "A pending invitation for a node to join a particular family.\n\nInvitations are stored until they are accepted, rejected, revoked, or until the chain advances past `expires_at` (in which case they remain in storage but are treated as inert — there is no background process clearing expired invitations).", + "type": "object", + "required": [ + "expires_at", + "family_id", + "node_id" + ], + "properties": { + "expires_at": { + "description": "Block timestamp (unix seconds) after which the invitation is no longer valid.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "family_id": { + "description": "The family that issued the invitation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "description": "The node being invited.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "FamilyInvitationStatus": { + "description": "Terminal status for an invitation that has been moved out of the pending set.\n\nNote: timed-out invitations are not represented here — they are simply left in the pending set (see `FamilyInvitation::expires_at`).", + "oneOf": [ + { + "description": "Still awaiting a response. Recorded with a timestamp for completeness even though pending invitations live in a separate map.", + "type": "object", + "required": [ + "pending" + ], + "properties": { + "pending": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "The invitee accepted and joined the family at the given timestamp.", + "type": "object", + "required": [ + "accepted" + ], + "properties": { + "accepted": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "The invitee explicitly rejected the invitation at the given timestamp.", + "type": "object", + "required": [ + "rejected" + ], + "properties": { + "rejected": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "The family revoked the invitation at the given timestamp before it could be accepted or rejected.", + "type": "object", + "required": [ + "revoked" + ], + "properties": { + "revoked": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "PastFamilyInvitation": { + "description": "Historical record of an invitation that has reached a terminal state (`Accepted`, `Rejected`, or `Revoked`). Timed-out invitations are **not** archived here — they remain in the pending map until explicitly cleared.", + "type": "object", + "required": [ + "invitation", + "status" + ], + "properties": { + "invitation": { + "description": "The original invitation as it was issued.", + "allOf": [ + { + "$ref": "#/definitions/FamilyInvitation" + } + ] + }, + "status": { + "description": "What ultimately happened to it.", + "allOf": [ + { + "$ref": "#/definitions/FamilyInvitationStatus" + } + ] + } + }, + "additionalProperties": false + } + } + }, + "get_past_invitations_for_node_paged": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PastFamilyInvitationsForNodePagedResponse", + "description": "Response to [`QueryMsg::GetPastInvitationsForNodePaged`](crate::QueryMsg::GetPastInvitationsForNodePaged).", + "type": "object", + "required": [ + "invitations", + "node_id" + ], + "properties": { + "invitations": { + "description": "The archived invitations addressed to this node on this page, in ascending `(family_id, counter)` order across all terminal statuses.", + "type": "array", + "items": { + "$ref": "#/definitions/PastFamilyInvitation" + } + }, + "node_id": { + "description": "The node whose past invitations were queried, echoed back so paginated callers can correlate.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Cursor to pass as `start_after` on the next call, or `None` if this page is empty (treat as end-of-list).", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false, + "definitions": { + "FamilyInvitation": { + "description": "A pending invitation for a node to join a particular family.\n\nInvitations are stored until they are accepted, rejected, revoked, or until the chain advances past `expires_at` (in which case they remain in storage but are treated as inert — there is no background process clearing expired invitations).", + "type": "object", + "required": [ + "expires_at", + "family_id", + "node_id" + ], + "properties": { + "expires_at": { + "description": "Block timestamp (unix seconds) after which the invitation is no longer valid.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "family_id": { + "description": "The family that issued the invitation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "description": "The node being invited.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "FamilyInvitationStatus": { + "description": "Terminal status for an invitation that has been moved out of the pending set.\n\nNote: timed-out invitations are not represented here — they are simply left in the pending set (see `FamilyInvitation::expires_at`).", + "oneOf": [ + { + "description": "Still awaiting a response. Recorded with a timestamp for completeness even though pending invitations live in a separate map.", + "type": "object", + "required": [ + "pending" + ], + "properties": { + "pending": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "The invitee accepted and joined the family at the given timestamp.", + "type": "object", + "required": [ + "accepted" + ], + "properties": { + "accepted": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "The invitee explicitly rejected the invitation at the given timestamp.", + "type": "object", + "required": [ + "rejected" + ], + "properties": { + "rejected": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "The family revoked the invitation at the given timestamp before it could be accepted or rejected.", + "type": "object", + "required": [ + "revoked" + ], + "properties": { + "revoked": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "PastFamilyInvitation": { + "description": "Historical record of an invitation that has reached a terminal state (`Accepted`, `Rejected`, or `Revoked`). Timed-out invitations are **not** archived here — they remain in the pending map until explicitly cleared.", + "type": "object", + "required": [ + "invitation", + "status" + ], + "properties": { + "invitation": { + "description": "The original invitation as it was issued.", + "allOf": [ + { + "$ref": "#/definitions/FamilyInvitation" + } + ] + }, + "status": { + "description": "What ultimately happened to it.", + "allOf": [ + { + "$ref": "#/definitions/FamilyInvitationStatus" + } + ] + } + }, + "additionalProperties": false + } + } + }, + "get_past_members_for_family_paged": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PastFamilyMembersPagedResponse", + "description": "Response to [`QueryMsg::GetPastMembersForFamilyPaged`](crate::QueryMsg::GetPastMembersForFamilyPaged).", + "type": "object", + "required": [ + "family_id", + "members" + ], + "properties": { + "family_id": { + "description": "The family whose archived memberships were queried, echoed back so paginated callers can correlate.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "members": { + "description": "The archived membership records on this page, in ascending `(node_id, counter)` order.", + "type": "array", + "items": { + "$ref": "#/definitions/PastFamilyMember" + } + }, + "start_next_after": { + "description": "Cursor to pass as `start_after` on the next call, or `None` if this page is empty (treat as end-of-list).", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false, + "definitions": { + "PastFamilyMember": { + "description": "Historical record of a node that used to be part of a family but has since been removed (kicked, left voluntarily, or because the family was disbanded).", + "type": "object", + "required": [ + "family_id", + "node_id", + "removed_at" + ], + "properties": { + "family_id": { + "description": "The family the node used to belong to.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "description": "The node that was removed.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "removed_at": { + "description": "Block timestamp (unix seconds) at which the membership was terminated.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + }, + "get_past_members_for_node_paged": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PastFamilyMembersForNodePagedResponse", + "description": "Response to [`QueryMsg::GetPastMembersForNodePaged`](crate::QueryMsg::GetPastMembersForNodePaged).", + "type": "object", + "required": [ + "members", + "node_id" + ], + "properties": { + "members": { + "description": "The archived membership records for this node on this page, in ascending `(family_id, counter)` order.", + "type": "array", + "items": { + "$ref": "#/definitions/PastFamilyMember" + } + }, + "node_id": { + "description": "The node whose archived memberships were queried, echoed back so paginated callers can correlate.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Cursor to pass as `start_after` on the next call, or `None` if this page is empty (treat as end-of-list).", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false, + "definitions": { + "PastFamilyMember": { + "description": "Historical record of a node that used to be part of a family but has since been removed (kicked, left voluntarily, or because the family was disbanded).", + "type": "object", + "required": [ + "family_id", + "node_id", + "removed_at" + ], + "properties": { + "family_id": { + "description": "The family the node used to belong to.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "description": "The node that was removed.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "removed_at": { + "description": "Block timestamp (unix seconds) at which the membership was terminated.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } + }, + "get_pending_invitation": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingFamilyInvitationResponse", + "description": "Response to [`QueryMsg::GetPendingInvitation`](crate::QueryMsg::GetPendingInvitation).", + "type": "object", + "required": [ + "family_id", + "node_id" + ], + "properties": { + "family_id": { + "description": "The family component of the queried `(family_id, node_id)` key.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "invitation": { + "description": "The matching pending invitation along with an explicit expiry flag, or `None` if no such invitation exists.", + "anyOf": [ + { + "$ref": "#/definitions/PendingFamilyInvitationDetails" + }, + { + "type": "null" + } + ] + }, + "node_id": { + "description": "The node component of the queried `(family_id, node_id)` key.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "FamilyInvitation": { + "description": "A pending invitation for a node to join a particular family.\n\nInvitations are stored until they are accepted, rejected, revoked, or until the chain advances past `expires_at` (in which case they remain in storage but are treated as inert — there is no background process clearing expired invitations).", + "type": "object", + "required": [ + "expires_at", + "family_id", + "node_id" + ], + "properties": { + "expires_at": { + "description": "Block timestamp (unix seconds) after which the invitation is no longer valid.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "family_id": { + "description": "The family that issued the invitation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "description": "The node being invited.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "PendingFamilyInvitationDetails": { + "description": "A pending [`FamilyInvitation`] paired with whether it has already timed out at the time the query was served.", + "type": "object", + "required": [ + "expired", + "invitation" + ], + "properties": { + "expired": { + "description": "`true` iff `now >= invitation.expires_at` at query time, i.e. the invitation is still in the pending map but can no longer be acted on.", + "type": "boolean" + }, + "invitation": { + "description": "The stored invitation as it was issued.", + "allOf": [ + { + "$ref": "#/definitions/FamilyInvitation" + } + ] + } + }, + "additionalProperties": false + } + } + }, + "get_pending_invitations_for_family_paged": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingFamilyInvitationsPagedResponse", + "description": "Response to [`QueryMsg::GetPendingInvitationsForFamilyPaged`](crate::QueryMsg::GetPendingInvitationsForFamilyPaged).", + "type": "object", + "required": [ + "family_id", + "invitations" + ], + "properties": { + "family_id": { + "description": "The family whose pending invitations were queried, echoed back so paginated callers can correlate.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "invitations": { + "description": "The pending invitations on this page, in ascending invitee [`NodeId`] order, each stamped with whether it had already timed out at the time the query was served.", + "type": "array", + "items": { + "$ref": "#/definitions/PendingFamilyInvitationDetails" + } + }, + "start_next_after": { + "description": "Cursor (last invitee node id) to pass as `start_after` on the next call, or `None` if this page is empty (treat as end-of-list).", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "FamilyInvitation": { + "description": "A pending invitation for a node to join a particular family.\n\nInvitations are stored until they are accepted, rejected, revoked, or until the chain advances past `expires_at` (in which case they remain in storage but are treated as inert — there is no background process clearing expired invitations).", + "type": "object", + "required": [ + "expires_at", + "family_id", + "node_id" + ], + "properties": { + "expires_at": { + "description": "Block timestamp (unix seconds) after which the invitation is no longer valid.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "family_id": { + "description": "The family that issued the invitation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "description": "The node being invited.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "PendingFamilyInvitationDetails": { + "description": "A pending [`FamilyInvitation`] paired with whether it has already timed out at the time the query was served.", + "type": "object", + "required": [ + "expired", + "invitation" + ], + "properties": { + "expired": { + "description": "`true` iff `now >= invitation.expires_at` at query time, i.e. the invitation is still in the pending map but can no longer be acted on.", + "type": "boolean" + }, + "invitation": { + "description": "The stored invitation as it was issued.", + "allOf": [ + { + "$ref": "#/definitions/FamilyInvitation" + } + ] + } + }, + "additionalProperties": false + } + } + }, + "get_pending_invitations_for_node_paged": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingInvitationsForNodePagedResponse", + "description": "Response to [`QueryMsg::GetPendingInvitationsForNodePaged`](crate::QueryMsg::GetPendingInvitationsForNodePaged).", + "type": "object", + "required": [ + "invitations", + "node_id" + ], + "properties": { + "invitations": { + "description": "The pending invitations addressed to this node on this page, in ascending [`NodeFamilyId`] order, each stamped with whether it had already timed out at the time the query was served.", + "type": "array", + "items": { + "$ref": "#/definitions/PendingFamilyInvitationDetails" + } + }, + "node_id": { + "description": "The node whose pending invitations were queried, echoed back so paginated callers can correlate.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Cursor (last issuing family id) to pass as `start_after` on the next call, or `None` if this page is empty (treat as end-of-list).", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "FamilyInvitation": { + "description": "A pending invitation for a node to join a particular family.\n\nInvitations are stored until they are accepted, rejected, revoked, or until the chain advances past `expires_at` (in which case they remain in storage but are treated as inert — there is no background process clearing expired invitations).", + "type": "object", + "required": [ + "expires_at", + "family_id", + "node_id" + ], + "properties": { + "expires_at": { + "description": "Block timestamp (unix seconds) after which the invitation is no longer valid.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "family_id": { + "description": "The family that issued the invitation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "description": "The node being invited.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "PendingFamilyInvitationDetails": { + "description": "A pending [`FamilyInvitation`] paired with whether it has already timed out at the time the query was served.", + "type": "object", + "required": [ + "expired", + "invitation" + ], + "properties": { + "expired": { + "description": "`true` iff `now >= invitation.expires_at` at query time, i.e. the invitation is still in the pending map but can no longer be acted on.", + "type": "boolean" + }, + "invitation": { + "description": "The stored invitation as it was issued.", + "allOf": [ + { + "$ref": "#/definitions/FamilyInvitation" + } + ] + } + }, + "additionalProperties": false + } + } + } + } +} diff --git a/contracts/node-families/schema/raw/execute.json b/contracts/node-families/schema/raw/execute.json new file mode 100644 index 0000000000..7b06d071f0 --- /dev/null +++ b/contracts/node-families/schema/raw/execute.json @@ -0,0 +1,318 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "description": "Execute messages accepted by the contract.", + "oneOf": [ + { + "description": "Replace the contract's runtime [`Config`]. Restricted to the contract admin.", + "type": "object", + "required": [ + "update_config" + ], + "properties": { + "update_config": { + "type": "object", + "required": [ + "config" + ], + "properties": { + "config": { + "$ref": "#/definitions/Config" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Create a new family owned by the message sender. The configured `create_family_fee` must be attached as funds.", + "type": "object", + "required": [ + "create_family" + ], + "properties": { + "create_family": { + "type": "object", + "required": [ + "description", + "name" + ], + "properties": { + "description": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Disband the family owned by the message sender. The family must have no current members; any still-pending invitations are revoked.", + "type": "object", + "required": [ + "disband_family" + ], + "properties": { + "disband_family": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Invite a node to the family owned by the message sender. If `validity_secs` is omitted the invitation expires `default_invitation_validity_secs` seconds (from [`Config`]) after the current block time.", + "type": "object", + "required": [ + "invite_to_family" + ], + "properties": { + "invite_to_family": { + "type": "object", + "required": [ + "node_id" + ], + "properties": { + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "validity_secs": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Revoke a still-pending invitation previously issued by the sender's family.", + "type": "object", + "required": [ + "revoke_family_invitation" + ], + "properties": { + "revoke_family_invitation": { + "type": "object", + "required": [ + "node_id" + ], + "properties": { + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Accept a pending invitation. The sender must control `node_id`.", + "type": "object", + "required": [ + "accept_family_invitation" + ], + "properties": { + "accept_family_invitation": { + "type": "object", + "required": [ + "family_id", + "node_id" + ], + "properties": { + "family_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Reject a pending invitation. The sender must control `node_id`.", + "type": "object", + "required": [ + "reject_family_invitation" + ], + "properties": { + "reject_family_invitation": { + "type": "object", + "required": [ + "family_id", + "node_id" + ], + "properties": { + "family_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Leave the family `node_id` currently belongs to. The sender must control `node_id`.", + "type": "object", + "required": [ + "leave_family" + ], + "properties": { + "leave_family": { + "type": "object", + "required": [ + "node_id" + ], + "properties": { + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Remove `node_id` from the family owned by the message sender.", + "type": "object", + "required": [ + "kick_from_family" + ], + "properties": { + "kick_from_family": { + "type": "object", + "required": [ + "node_id" + ], + "properties": { + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Cross-contract callback fired by the mixnet contract the moment node with `node_id` initiates unbonding. Removes the node from any family it currently belongs to and rejects every pending invitation issued to it. Sender must be the configured mixnet contract address.", + "type": "object", + "required": [ + "on_nym_node_unbond" + ], + "properties": { + "on_nym_node_unbond": { + "type": "object", + "required": [ + "node_id" + ], + "properties": { + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ], + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "additionalProperties": false + }, + "Config": { + "description": "Runtime configuration of the node families contract.", + "type": "object", + "required": [ + "create_family_fee", + "default_invitation_validity_secs", + "family_description_length_limit", + "family_name_length_limit" + ], + "properties": { + "create_family_fee": { + "description": "Fee charged on each successful `create_family` execution.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "default_invitation_validity_secs": { + "description": "Default lifetime, in seconds, used by `invite_to_family` when the sender doesn't supply an explicit value. Senders may override this per-invitation via the optional `validity_secs` argument.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "family_description_length_limit": { + "description": "Maximum allowed length, in characters, of a family description.", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "family_name_length_limit": { + "description": "Maximum allowed length, in characters, of a family name.", + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/node-families/schema/raw/instantiate.json b/contracts/node-families/schema/raw/instantiate.json new file mode 100644 index 0000000000..596ec07212 --- /dev/null +++ b/contracts/node-families/schema/raw/instantiate.json @@ -0,0 +1,80 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "description": "Message used to instantiate the node families contract.", + "type": "object", + "required": [ + "config", + "mixnet_contract_address" + ], + "properties": { + "config": { + "$ref": "#/definitions/Config" + }, + "mixnet_contract_address": { + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "additionalProperties": false + }, + "Config": { + "description": "Runtime configuration of the node families contract.", + "type": "object", + "required": [ + "create_family_fee", + "default_invitation_validity_secs", + "family_description_length_limit", + "family_name_length_limit" + ], + "properties": { + "create_family_fee": { + "description": "Fee charged on each successful `create_family` execution.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + }, + "default_invitation_validity_secs": { + "description": "Default lifetime, in seconds, used by `invite_to_family` when the sender doesn't supply an explicit value. Senders may override this per-invitation via the optional `validity_secs` argument.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "family_description_length_limit": { + "description": "Maximum allowed length, in characters, of a family description.", + "type": "integer", + "format": "uint", + "minimum": 0.0 + }, + "family_name_length_limit": { + "description": "Maximum allowed length, in characters, of a family name.", + "type": "integer", + "format": "uint", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/node-families/schema/raw/migrate.json b/contracts/node-families/schema/raw/migrate.json new file mode 100644 index 0000000000..a02787c6a5 --- /dev/null +++ b/contracts/node-families/schema/raw/migrate.json @@ -0,0 +1,7 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "description": "Message passed to the contract's `migrate` entry point.", + "type": "object", + "additionalProperties": false +} diff --git a/contracts/node-families/schema/raw/query.json b/contracts/node-families/schema/raw/query.json new file mode 100644 index 0000000000..f03b673f0d --- /dev/null +++ b/contracts/node-families/schema/raw/query.json @@ -0,0 +1,620 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "description": "Query messages accepted by the contract.", + "oneOf": [ + { + "description": "Look up a single family by its id.", + "type": "object", + "required": [ + "get_family_by_id" + ], + "properties": { + "get_family_by_id": { + "type": "object", + "required": [ + "family_id" + ], + "properties": { + "family_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Look up the (at most one) family owned by a given address.", + "type": "object", + "required": [ + "get_family_by_owner" + ], + "properties": { + "get_family_by_owner": { + "type": "object", + "required": [ + "owner" + ], + "properties": { + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Look up a single family by its name. The lookup is normalised contract-side (lowercased, non-alphanumerics stripped), so equivalent inputs resolve to the same family.", + "type": "object", + "required": [ + "get_family_by_name" + ], + "properties": { + "get_family_by_name": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "get_families_paged" + ], + "properties": { + "get_families_paged": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Look up which family — if any — a node currently belongs to.", + "type": "object", + "required": [ + "get_family_membership" + ], + "properties": { + "get_family_membership": { + "type": "object", + "required": [ + "node_id" + ], + "properties": { + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Page through every node currently in a given family.", + "type": "object", + "required": [ + "get_family_members_paged" + ], + "properties": { + "get_family_members_paged": { + "type": "object", + "required": [ + "family_id" + ], + "properties": { + "family_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Page through every current family member across all families, in ascending [`NodeId`] order. Each entry carries the membership record (which in turn names the family the node belongs to).", + "type": "object", + "required": [ + "get_all_family_members_paged" + ], + "properties": { + "get_all_family_members_paged": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Look up the pending invitation for a specific `(family_id, node_id)` pair.", + "type": "object", + "required": [ + "get_pending_invitation" + ], + "properties": { + "get_pending_invitation": { + "type": "object", + "required": [ + "family_id", + "node_id" + ], + "properties": { + "family_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Page through every pending invitation issued by a given family.", + "type": "object", + "required": [ + "get_pending_invitations_for_family_paged" + ], + "properties": { + "get_pending_invitations_for_family_paged": { + "type": "object", + "required": [ + "family_id" + ], + "properties": { + "family_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Page through every pending invitation issued for a given node.", + "type": "object", + "required": [ + "get_pending_invitations_for_node_paged" + ], + "properties": { + "get_pending_invitations_for_node_paged": { + "type": "object", + "required": [ + "node_id" + ], + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Page through every pending invitation across all families.", + "type": "object", + "required": [ + "get_all_pending_invitations_paged" + ], + "properties": { + "get_all_pending_invitations_paged": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Page through every archived (terminal-state) invitation issued by a given family.", + "type": "object", + "required": [ + "get_past_invitations_for_family_paged" + ], + "properties": { + "get_past_invitations_for_family_paged": { + "type": "object", + "required": [ + "family_id" + ], + "properties": { + "family_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Page through every archived (terminal-state) invitation issued to a given node.", + "type": "object", + "required": [ + "get_past_invitations_for_node_paged" + ], + "properties": { + "get_past_invitations_for_node_paged": { + "type": "object", + "required": [ + "node_id" + ], + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Page through every archived (terminal-state) invitation across all families.", + "type": "object", + "required": [ + "get_all_past_invitations_paged" + ], + "properties": { + "get_all_past_invitations_paged": { + "type": "object", + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Page through every archived membership record for a given family (nodes that used to belong to it but have since been removed).", + "type": "object", + "required": [ + "get_past_members_for_family_paged" + ], + "properties": { + "get_past_members_for_family_paged": { + "type": "object", + "required": [ + "family_id" + ], + "properties": { + "family_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Page through every archived membership record for a given node (every family the node used to belong to but has since been removed from), across all families.", + "type": "object", + "required": [ + "get_past_members_for_node_paged" + ], + "properties": { + "get_past_members_for_node_paged": { + "type": "object", + "required": [ + "node_id" + ], + "properties": { + "limit": { + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "start_after": { + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/node-families/schema/raw/response_to_get_all_family_members_paged.json b/contracts/node-families/schema/raw/response_to_get_all_family_members_paged.json new file mode 100644 index 0000000000..d6d4baaf5c --- /dev/null +++ b/contracts/node-families/schema/raw/response_to_get_all_family_members_paged.json @@ -0,0 +1,78 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AllFamilyMembersPagedResponse", + "description": "Response to [`QueryMsg::GetAllFamilyMembersPaged`](crate::QueryMsg::GetAllFamilyMembersPaged).", + "type": "object", + "required": [ + "members" + ], + "properties": { + "members": { + "description": "The members on this page, in ascending [`NodeId`] order across every family.", + "type": "array", + "items": { + "$ref": "#/definitions/FamilyMemberRecord" + } + }, + "start_next_after": { + "description": "Cursor (last `node_id`) to pass as `start_after` on the next call, or `None` if this page is empty (treat as end-of-list).", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "FamilyMemberRecord": { + "description": "One entry in a [`FamilyMembersPagedResponse`] page — pairs a node id with its [`FamilyMembership`] record (notably its `joined_at` timestamp).", + "type": "object", + "required": [ + "membership", + "node_id" + ], + "properties": { + "membership": { + "description": "The membership record (carries `family_id` and `joined_at`).", + "allOf": [ + { + "$ref": "#/definitions/FamilyMembership" + } + ] + }, + "node_id": { + "description": "The node currently in the family.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "FamilyMembership": { + "description": "On-chain record of a node's current family membership.\n\nA node belongs to at most one family at a time, so this is keyed by `NodeId` alone — `family_id` is carried in the value to support reverse lookups (all nodes in a given family) via a secondary index.", + "type": "object", + "required": [ + "family_id", + "joined_at" + ], + "properties": { + "family_id": { + "description": "The family the node is currently a member of.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "joined_at": { + "description": "Block timestamp (unix seconds) at which the node accepted its invitation and joined the family.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/node-families/schema/raw/response_to_get_all_past_invitations_paged.json b/contracts/node-families/schema/raw/response_to_get_all_past_invitations_paged.json new file mode 100644 index 0000000000..dcbb67974b --- /dev/null +++ b/contracts/node-families/schema/raw/response_to_get_all_past_invitations_paged.json @@ -0,0 +1,212 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AllPastFamilyInvitationsPagedResponse", + "description": "Response to [`QueryMsg::GetAllPastInvitationsPaged`](crate::QueryMsg::GetAllPastInvitationsPaged).", + "type": "object", + "required": [ + "invitations" + ], + "properties": { + "invitations": { + "description": "The archived invitations on this page, in ascending `((family_id, node_id), counter)` order across all terminal statuses.", + "type": "array", + "items": { + "$ref": "#/definitions/PastFamilyInvitation" + } + }, + "start_next_after": { + "description": "Cursor to pass as `start_after` on the next call, or `None` if this page is empty (treat as end-of-list).", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "array", + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false, + "definitions": { + "FamilyInvitation": { + "description": "A pending invitation for a node to join a particular family.\n\nInvitations are stored until they are accepted, rejected, revoked, or until the chain advances past `expires_at` (in which case they remain in storage but are treated as inert — there is no background process clearing expired invitations).", + "type": "object", + "required": [ + "expires_at", + "family_id", + "node_id" + ], + "properties": { + "expires_at": { + "description": "Block timestamp (unix seconds) after which the invitation is no longer valid.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "family_id": { + "description": "The family that issued the invitation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "description": "The node being invited.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "FamilyInvitationStatus": { + "description": "Terminal status for an invitation that has been moved out of the pending set.\n\nNote: timed-out invitations are not represented here — they are simply left in the pending set (see `FamilyInvitation::expires_at`).", + "oneOf": [ + { + "description": "Still awaiting a response. Recorded with a timestamp for completeness even though pending invitations live in a separate map.", + "type": "object", + "required": [ + "pending" + ], + "properties": { + "pending": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "The invitee accepted and joined the family at the given timestamp.", + "type": "object", + "required": [ + "accepted" + ], + "properties": { + "accepted": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "The invitee explicitly rejected the invitation at the given timestamp.", + "type": "object", + "required": [ + "rejected" + ], + "properties": { + "rejected": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "The family revoked the invitation at the given timestamp before it could be accepted or rejected.", + "type": "object", + "required": [ + "revoked" + ], + "properties": { + "revoked": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "PastFamilyInvitation": { + "description": "Historical record of an invitation that has reached a terminal state (`Accepted`, `Rejected`, or `Revoked`). Timed-out invitations are **not** archived here — they remain in the pending map until explicitly cleared.", + "type": "object", + "required": [ + "invitation", + "status" + ], + "properties": { + "invitation": { + "description": "The original invitation as it was issued.", + "allOf": [ + { + "$ref": "#/definitions/FamilyInvitation" + } + ] + }, + "status": { + "description": "What ultimately happened to it.", + "allOf": [ + { + "$ref": "#/definitions/FamilyInvitationStatus" + } + ] + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/node-families/schema/raw/response_to_get_all_pending_invitations_paged.json b/contracts/node-families/schema/raw/response_to_get_all_pending_invitations_paged.json new file mode 100644 index 0000000000..90bffdabc9 --- /dev/null +++ b/contracts/node-families/schema/raw/response_to_get_all_pending_invitations_paged.json @@ -0,0 +1,95 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingInvitationsPagedResponse", + "description": "Response to [`QueryMsg::GetAllPendingInvitationsPaged`](crate::QueryMsg::GetAllPendingInvitationsPaged).", + "type": "object", + "required": [ + "invitations" + ], + "properties": { + "invitations": { + "description": "The pending invitations on this page, in ascending `(family_id, node_id)` order, each stamped with whether it had already timed out at the time the query was served.", + "type": "array", + "items": { + "$ref": "#/definitions/PendingFamilyInvitationDetails" + } + }, + "start_next_after": { + "description": "Cursor (last `(family_id, node_id)` pair) to pass as `start_after` on the next call, or `None` if this page is empty (treat as end-of-list).", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false, + "definitions": { + "FamilyInvitation": { + "description": "A pending invitation for a node to join a particular family.\n\nInvitations are stored until they are accepted, rejected, revoked, or until the chain advances past `expires_at` (in which case they remain in storage but are treated as inert — there is no background process clearing expired invitations).", + "type": "object", + "required": [ + "expires_at", + "family_id", + "node_id" + ], + "properties": { + "expires_at": { + "description": "Block timestamp (unix seconds) after which the invitation is no longer valid.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "family_id": { + "description": "The family that issued the invitation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "description": "The node being invited.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "PendingFamilyInvitationDetails": { + "description": "A pending [`FamilyInvitation`] paired with whether it has already timed out at the time the query was served.", + "type": "object", + "required": [ + "expired", + "invitation" + ], + "properties": { + "expired": { + "description": "`true` iff `now >= invitation.expires_at` at query time, i.e. the invitation is still in the pending map but can no longer be acted on.", + "type": "boolean" + }, + "invitation": { + "description": "The stored invitation as it was issued.", + "allOf": [ + { + "$ref": "#/definitions/FamilyInvitation" + } + ] + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/node-families/schema/raw/response_to_get_families_paged.json b/contracts/node-families/schema/raw/response_to_get_families_paged.json new file mode 100644 index 0000000000..459247a149 --- /dev/null +++ b/contracts/node-families/schema/raw/response_to_get_families_paged.json @@ -0,0 +1,117 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "FamiliesPagedResponse", + "description": "Response to [`QueryMsg::GetFamiliesPaged`](crate::QueryMsg::GetFamiliesPaged).", + "type": "object", + "required": [ + "families" + ], + "properties": { + "families": { + "description": "The families on this page, in ascending [`NodeFamilyId`] order.", + "type": "array", + "items": { + "$ref": "#/definitions/NodeFamily" + } + }, + "start_next_after": { + "description": "Cursor to pass as `start_after` on the next call, or `None` if this page is empty (which the caller should treat as end-of-list).", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "additionalProperties": false + }, + "NodeFamily": { + "description": "On-chain representation of a node family.", + "type": "object", + "required": [ + "created_at", + "description", + "id", + "members", + "name", + "normalised_name", + "owner", + "paid_fee" + ], + "properties": { + "created_at": { + "description": "Timestamp of the creation of the node family", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "description": { + "description": "The optional description of the node family", + "type": "string" + }, + "id": { + "description": "The id of the node family", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "members": { + "description": "Memoized value of the current number of members in the node family Used to detect if the family is empty", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "name": { + "description": "The name of the node family", + "type": "string" + }, + "normalised_name": { + "description": "Normalised name of the node family used for uniqueness checks", + "type": "string" + }, + "owner": { + "description": "The owner of the node family", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "paid_fee": { + "description": "Records the fee paid when the family was created, so that the appropriate amount could be returned upon it getting disbanded.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/node-families/schema/raw/response_to_get_family_by_id.json b/contracts/node-families/schema/raw/response_to_get_family_by_id.json new file mode 100644 index 0000000000..072a160145 --- /dev/null +++ b/contracts/node-families/schema/raw/response_to_get_family_by_id.json @@ -0,0 +1,118 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "NodeFamilyResponse", + "description": "Response to [`QueryMsg::GetFamilyById`](crate::QueryMsg::GetFamilyById).", + "type": "object", + "required": [ + "family_id" + ], + "properties": { + "family": { + "description": "The matching family, or `None` if no family with `family_id` exists.", + "anyOf": [ + { + "$ref": "#/definitions/NodeFamily" + }, + { + "type": "null" + } + ] + }, + "family_id": { + "description": "The id that was queried, echoed back so paginated callers can correlate.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "additionalProperties": false + }, + "NodeFamily": { + "description": "On-chain representation of a node family.", + "type": "object", + "required": [ + "created_at", + "description", + "id", + "members", + "name", + "normalised_name", + "owner", + "paid_fee" + ], + "properties": { + "created_at": { + "description": "Timestamp of the creation of the node family", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "description": { + "description": "The optional description of the node family", + "type": "string" + }, + "id": { + "description": "The id of the node family", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "members": { + "description": "Memoized value of the current number of members in the node family Used to detect if the family is empty", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "name": { + "description": "The name of the node family", + "type": "string" + }, + "normalised_name": { + "description": "Normalised name of the node family used for uniqueness checks", + "type": "string" + }, + "owner": { + "description": "The owner of the node family", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "paid_fee": { + "description": "Records the fee paid when the family was created, so that the appropriate amount could be returned upon it getting disbanded.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/node-families/schema/raw/response_to_get_family_by_name.json b/contracts/node-families/schema/raw/response_to_get_family_by_name.json new file mode 100644 index 0000000000..dec7aea652 --- /dev/null +++ b/contracts/node-families/schema/raw/response_to_get_family_by_name.json @@ -0,0 +1,116 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "NodeFamilyByNameResponse", + "description": "Response to [`QueryMsg::GetFamilyByName`](crate::QueryMsg::GetFamilyByName).", + "type": "object", + "required": [ + "name" + ], + "properties": { + "family": { + "description": "The matching family, or `None` if no family with that name exists.", + "anyOf": [ + { + "$ref": "#/definitions/NodeFamily" + }, + { + "type": "null" + } + ] + }, + "name": { + "description": "The name that was queried, echoed back so callers can correlate.", + "type": "string" + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "additionalProperties": false + }, + "NodeFamily": { + "description": "On-chain representation of a node family.", + "type": "object", + "required": [ + "created_at", + "description", + "id", + "members", + "name", + "normalised_name", + "owner", + "paid_fee" + ], + "properties": { + "created_at": { + "description": "Timestamp of the creation of the node family", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "description": { + "description": "The optional description of the node family", + "type": "string" + }, + "id": { + "description": "The id of the node family", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "members": { + "description": "Memoized value of the current number of members in the node family Used to detect if the family is empty", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "name": { + "description": "The name of the node family", + "type": "string" + }, + "normalised_name": { + "description": "Normalised name of the node family used for uniqueness checks", + "type": "string" + }, + "owner": { + "description": "The owner of the node family", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "paid_fee": { + "description": "Records the fee paid when the family was created, so that the appropriate amount could be returned upon it getting disbanded.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/node-families/schema/raw/response_to_get_family_by_owner.json b/contracts/node-families/schema/raw/response_to_get_family_by_owner.json new file mode 100644 index 0000000000..74b0412a9d --- /dev/null +++ b/contracts/node-families/schema/raw/response_to_get_family_by_owner.json @@ -0,0 +1,120 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "NodeFamilyByOwnerResponse", + "description": "Response to [`QueryMsg::GetFamilyByOwner`](crate::QueryMsg::GetFamilyByOwner).", + "type": "object", + "required": [ + "owner" + ], + "properties": { + "family": { + "description": "The matching family, or `None` if `owner` does not currently own one.", + "anyOf": [ + { + "$ref": "#/definitions/NodeFamily" + }, + { + "type": "null" + } + ] + }, + "owner": { + "description": "The (validated) owner address that was queried, echoed back so callers can correlate.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "Coin": { + "type": "object", + "required": [ + "amount", + "denom" + ], + "properties": { + "amount": { + "$ref": "#/definitions/Uint128" + }, + "denom": { + "type": "string" + } + }, + "additionalProperties": false + }, + "NodeFamily": { + "description": "On-chain representation of a node family.", + "type": "object", + "required": [ + "created_at", + "description", + "id", + "members", + "name", + "normalised_name", + "owner", + "paid_fee" + ], + "properties": { + "created_at": { + "description": "Timestamp of the creation of the node family", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "description": { + "description": "The optional description of the node family", + "type": "string" + }, + "id": { + "description": "The id of the node family", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "members": { + "description": "Memoized value of the current number of members in the node family Used to detect if the family is empty", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "name": { + "description": "The name of the node family", + "type": "string" + }, + "normalised_name": { + "description": "Normalised name of the node family used for uniqueness checks", + "type": "string" + }, + "owner": { + "description": "The owner of the node family", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "paid_fee": { + "description": "Records the fee paid when the family was created, so that the appropriate amount could be returned upon it getting disbanded.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] + } + }, + "additionalProperties": false + }, + "Uint128": { + "description": "A thin wrapper around u128 that is using strings for JSON encoding/decoding, such that the full u128 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u128` to get the value out:\n\n``` # use cosmwasm_std::Uint128; let a = Uint128::from(123u128); assert_eq!(a.u128(), 123);\n\nlet b = Uint128::from(42u64); assert_eq!(b.u128(), 42);\n\nlet c = Uint128::from(70u32); assert_eq!(c.u128(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/node-families/schema/raw/response_to_get_family_members_paged.json b/contracts/node-families/schema/raw/response_to_get_family_members_paged.json new file mode 100644 index 0000000000..7dbb1c64a4 --- /dev/null +++ b/contracts/node-families/schema/raw/response_to_get_family_members_paged.json @@ -0,0 +1,85 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "FamilyMembersPagedResponse", + "description": "Response to [`QueryMsg::GetFamilyMembersPaged`](crate::QueryMsg::GetFamilyMembersPaged).", + "type": "object", + "required": [ + "family_id", + "members" + ], + "properties": { + "family_id": { + "description": "The family whose members were queried, echoed back so paginated callers can correlate.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "members": { + "description": "The members on this page, in ascending [`NodeId`] order.", + "type": "array", + "items": { + "$ref": "#/definitions/FamilyMemberRecord" + } + }, + "start_next_after": { + "description": "Cursor to pass as `start_after` on the next call, or `None` if this page is empty (which the caller should treat as end-of-list).", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "FamilyMemberRecord": { + "description": "One entry in a [`FamilyMembersPagedResponse`] page — pairs a node id with its [`FamilyMembership`] record (notably its `joined_at` timestamp).", + "type": "object", + "required": [ + "membership", + "node_id" + ], + "properties": { + "membership": { + "description": "The membership record (carries `family_id` and `joined_at`).", + "allOf": [ + { + "$ref": "#/definitions/FamilyMembership" + } + ] + }, + "node_id": { + "description": "The node currently in the family.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "FamilyMembership": { + "description": "On-chain record of a node's current family membership.\n\nA node belongs to at most one family at a time, so this is keyed by `NodeId` alone — `family_id` is carried in the value to support reverse lookups (all nodes in a given family) via a secondary index.", + "type": "object", + "required": [ + "family_id", + "joined_at" + ], + "properties": { + "family_id": { + "description": "The family the node is currently a member of.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "joined_at": { + "description": "Block timestamp (unix seconds) at which the node accepted its invitation and joined the family.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/node-families/schema/raw/response_to_get_family_membership.json b/contracts/node-families/schema/raw/response_to_get_family_membership.json new file mode 100644 index 0000000000..838d916547 --- /dev/null +++ b/contracts/node-families/schema/raw/response_to_get_family_membership.json @@ -0,0 +1,27 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "NodeFamilyMembershipResponse", + "description": "Response to [`QueryMsg::GetFamilyMembership`](crate::QueryMsg::GetFamilyMembership).", + "type": "object", + "required": [ + "node_id" + ], + "properties": { + "family_id": { + "description": "The id of the family the node currently belongs to, or `None` if the node is not currently a member of any family.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "description": "The node that was queried.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false +} diff --git a/contracts/node-families/schema/raw/response_to_get_past_invitations_for_family_paged.json b/contracts/node-families/schema/raw/response_to_get_past_invitations_for_family_paged.json new file mode 100644 index 0000000000..15e2271e61 --- /dev/null +++ b/contracts/node-families/schema/raw/response_to_get_past_invitations_for_family_paged.json @@ -0,0 +1,207 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PastFamilyInvitationsPagedResponse", + "description": "Response to [`QueryMsg::GetPastInvitationsForFamilyPaged`](crate::QueryMsg::GetPastInvitationsForFamilyPaged).", + "type": "object", + "required": [ + "family_id", + "invitations" + ], + "properties": { + "family_id": { + "description": "The family whose archived invitations were queried, echoed back so paginated callers can correlate.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "invitations": { + "description": "The archived invitations on this page, in ascending `(node_id, counter)` order across all terminal statuses.", + "type": "array", + "items": { + "$ref": "#/definitions/PastFamilyInvitation" + } + }, + "start_next_after": { + "description": "Cursor to pass as `start_after` on the next call, or `None` if this page is empty (treat as end-of-list).", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false, + "definitions": { + "FamilyInvitation": { + "description": "A pending invitation for a node to join a particular family.\n\nInvitations are stored until they are accepted, rejected, revoked, or until the chain advances past `expires_at` (in which case they remain in storage but are treated as inert — there is no background process clearing expired invitations).", + "type": "object", + "required": [ + "expires_at", + "family_id", + "node_id" + ], + "properties": { + "expires_at": { + "description": "Block timestamp (unix seconds) after which the invitation is no longer valid.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "family_id": { + "description": "The family that issued the invitation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "description": "The node being invited.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "FamilyInvitationStatus": { + "description": "Terminal status for an invitation that has been moved out of the pending set.\n\nNote: timed-out invitations are not represented here — they are simply left in the pending set (see `FamilyInvitation::expires_at`).", + "oneOf": [ + { + "description": "Still awaiting a response. Recorded with a timestamp for completeness even though pending invitations live in a separate map.", + "type": "object", + "required": [ + "pending" + ], + "properties": { + "pending": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "The invitee accepted and joined the family at the given timestamp.", + "type": "object", + "required": [ + "accepted" + ], + "properties": { + "accepted": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "The invitee explicitly rejected the invitation at the given timestamp.", + "type": "object", + "required": [ + "rejected" + ], + "properties": { + "rejected": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "The family revoked the invitation at the given timestamp before it could be accepted or rejected.", + "type": "object", + "required": [ + "revoked" + ], + "properties": { + "revoked": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "PastFamilyInvitation": { + "description": "Historical record of an invitation that has reached a terminal state (`Accepted`, `Rejected`, or `Revoked`). Timed-out invitations are **not** archived here — they remain in the pending map until explicitly cleared.", + "type": "object", + "required": [ + "invitation", + "status" + ], + "properties": { + "invitation": { + "description": "The original invitation as it was issued.", + "allOf": [ + { + "$ref": "#/definitions/FamilyInvitation" + } + ] + }, + "status": { + "description": "What ultimately happened to it.", + "allOf": [ + { + "$ref": "#/definitions/FamilyInvitationStatus" + } + ] + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/node-families/schema/raw/response_to_get_past_invitations_for_node_paged.json b/contracts/node-families/schema/raw/response_to_get_past_invitations_for_node_paged.json new file mode 100644 index 0000000000..b438371287 --- /dev/null +++ b/contracts/node-families/schema/raw/response_to_get_past_invitations_for_node_paged.json @@ -0,0 +1,207 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PastFamilyInvitationsForNodePagedResponse", + "description": "Response to [`QueryMsg::GetPastInvitationsForNodePaged`](crate::QueryMsg::GetPastInvitationsForNodePaged).", + "type": "object", + "required": [ + "invitations", + "node_id" + ], + "properties": { + "invitations": { + "description": "The archived invitations addressed to this node on this page, in ascending `(family_id, counter)` order across all terminal statuses.", + "type": "array", + "items": { + "$ref": "#/definitions/PastFamilyInvitation" + } + }, + "node_id": { + "description": "The node whose past invitations were queried, echoed back so paginated callers can correlate.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Cursor to pass as `start_after` on the next call, or `None` if this page is empty (treat as end-of-list).", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false, + "definitions": { + "FamilyInvitation": { + "description": "A pending invitation for a node to join a particular family.\n\nInvitations are stored until they are accepted, rejected, revoked, or until the chain advances past `expires_at` (in which case they remain in storage but are treated as inert — there is no background process clearing expired invitations).", + "type": "object", + "required": [ + "expires_at", + "family_id", + "node_id" + ], + "properties": { + "expires_at": { + "description": "Block timestamp (unix seconds) after which the invitation is no longer valid.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "family_id": { + "description": "The family that issued the invitation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "description": "The node being invited.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "FamilyInvitationStatus": { + "description": "Terminal status for an invitation that has been moved out of the pending set.\n\nNote: timed-out invitations are not represented here — they are simply left in the pending set (see `FamilyInvitation::expires_at`).", + "oneOf": [ + { + "description": "Still awaiting a response. Recorded with a timestamp for completeness even though pending invitations live in a separate map.", + "type": "object", + "required": [ + "pending" + ], + "properties": { + "pending": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "The invitee accepted and joined the family at the given timestamp.", + "type": "object", + "required": [ + "accepted" + ], + "properties": { + "accepted": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "The invitee explicitly rejected the invitation at the given timestamp.", + "type": "object", + "required": [ + "rejected" + ], + "properties": { + "rejected": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "The family revoked the invitation at the given timestamp before it could be accepted or rejected.", + "type": "object", + "required": [ + "revoked" + ], + "properties": { + "revoked": { + "type": "object", + "required": [ + "at" + ], + "properties": { + "at": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "PastFamilyInvitation": { + "description": "Historical record of an invitation that has reached a terminal state (`Accepted`, `Rejected`, or `Revoked`). Timed-out invitations are **not** archived here — they remain in the pending map until explicitly cleared.", + "type": "object", + "required": [ + "invitation", + "status" + ], + "properties": { + "invitation": { + "description": "The original invitation as it was issued.", + "allOf": [ + { + "$ref": "#/definitions/FamilyInvitation" + } + ] + }, + "status": { + "description": "What ultimately happened to it.", + "allOf": [ + { + "$ref": "#/definitions/FamilyInvitationStatus" + } + ] + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/node-families/schema/raw/response_to_get_past_members_for_family_paged.json b/contracts/node-families/schema/raw/response_to_get_past_members_for_family_paged.json new file mode 100644 index 0000000000..2ad75d8dda --- /dev/null +++ b/contracts/node-families/schema/raw/response_to_get_past_members_for_family_paged.json @@ -0,0 +1,79 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PastFamilyMembersPagedResponse", + "description": "Response to [`QueryMsg::GetPastMembersForFamilyPaged`](crate::QueryMsg::GetPastMembersForFamilyPaged).", + "type": "object", + "required": [ + "family_id", + "members" + ], + "properties": { + "family_id": { + "description": "The family whose archived memberships were queried, echoed back so paginated callers can correlate.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "members": { + "description": "The archived membership records on this page, in ascending `(node_id, counter)` order.", + "type": "array", + "items": { + "$ref": "#/definitions/PastFamilyMember" + } + }, + "start_next_after": { + "description": "Cursor to pass as `start_after` on the next call, or `None` if this page is empty (treat as end-of-list).", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false, + "definitions": { + "PastFamilyMember": { + "description": "Historical record of a node that used to be part of a family but has since been removed (kicked, left voluntarily, or because the family was disbanded).", + "type": "object", + "required": [ + "family_id", + "node_id", + "removed_at" + ], + "properties": { + "family_id": { + "description": "The family the node used to belong to.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "description": "The node that was removed.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "removed_at": { + "description": "Block timestamp (unix seconds) at which the membership was terminated.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/node-families/schema/raw/response_to_get_past_members_for_node_paged.json b/contracts/node-families/schema/raw/response_to_get_past_members_for_node_paged.json new file mode 100644 index 0000000000..379b9df988 --- /dev/null +++ b/contracts/node-families/schema/raw/response_to_get_past_members_for_node_paged.json @@ -0,0 +1,79 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PastFamilyMembersForNodePagedResponse", + "description": "Response to [`QueryMsg::GetPastMembersForNodePaged`](crate::QueryMsg::GetPastMembersForNodePaged).", + "type": "object", + "required": [ + "members", + "node_id" + ], + "properties": { + "members": { + "description": "The archived membership records for this node on this page, in ascending `(family_id, counter)` order.", + "type": "array", + "items": { + "$ref": "#/definitions/PastFamilyMember" + } + }, + "node_id": { + "description": "The node whose archived memberships were queried, echoed back so paginated callers can correlate.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Cursor to pass as `start_after` on the next call, or `None` if this page is empty (treat as end-of-list).", + "type": [ + "array", + "null" + ], + "items": [ + { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "additionalProperties": false, + "definitions": { + "PastFamilyMember": { + "description": "Historical record of a node that used to be part of a family but has since been removed (kicked, left voluntarily, or because the family was disbanded).", + "type": "object", + "required": [ + "family_id", + "node_id", + "removed_at" + ], + "properties": { + "family_id": { + "description": "The family the node used to belong to.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "description": "The node that was removed.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "removed_at": { + "description": "Block timestamp (unix seconds) at which the membership was terminated.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/node-families/schema/raw/response_to_get_pending_invitation.json b/contracts/node-families/schema/raw/response_to_get_pending_invitation.json new file mode 100644 index 0000000000..c9ab63d67a --- /dev/null +++ b/contracts/node-families/schema/raw/response_to_get_pending_invitation.json @@ -0,0 +1,91 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingFamilyInvitationResponse", + "description": "Response to [`QueryMsg::GetPendingInvitation`](crate::QueryMsg::GetPendingInvitation).", + "type": "object", + "required": [ + "family_id", + "node_id" + ], + "properties": { + "family_id": { + "description": "The family component of the queried `(family_id, node_id)` key.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "invitation": { + "description": "The matching pending invitation along with an explicit expiry flag, or `None` if no such invitation exists.", + "anyOf": [ + { + "$ref": "#/definitions/PendingFamilyInvitationDetails" + }, + { + "type": "null" + } + ] + }, + "node_id": { + "description": "The node component of the queried `(family_id, node_id)` key.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "FamilyInvitation": { + "description": "A pending invitation for a node to join a particular family.\n\nInvitations are stored until they are accepted, rejected, revoked, or until the chain advances past `expires_at` (in which case they remain in storage but are treated as inert — there is no background process clearing expired invitations).", + "type": "object", + "required": [ + "expires_at", + "family_id", + "node_id" + ], + "properties": { + "expires_at": { + "description": "Block timestamp (unix seconds) after which the invitation is no longer valid.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "family_id": { + "description": "The family that issued the invitation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "description": "The node being invited.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "PendingFamilyInvitationDetails": { + "description": "A pending [`FamilyInvitation`] paired with whether it has already timed out at the time the query was served.", + "type": "object", + "required": [ + "expired", + "invitation" + ], + "properties": { + "expired": { + "description": "`true` iff `now >= invitation.expires_at` at query time, i.e. the invitation is still in the pending map but can no longer be acted on.", + "type": "boolean" + }, + "invitation": { + "description": "The stored invitation as it was issued.", + "allOf": [ + { + "$ref": "#/definitions/FamilyInvitation" + } + ] + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/node-families/schema/raw/response_to_get_pending_invitations_for_family_paged.json b/contracts/node-families/schema/raw/response_to_get_pending_invitations_for_family_paged.json new file mode 100644 index 0000000000..9dc1b084d0 --- /dev/null +++ b/contracts/node-families/schema/raw/response_to_get_pending_invitations_for_family_paged.json @@ -0,0 +1,90 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingFamilyInvitationsPagedResponse", + "description": "Response to [`QueryMsg::GetPendingInvitationsForFamilyPaged`](crate::QueryMsg::GetPendingInvitationsForFamilyPaged).", + "type": "object", + "required": [ + "family_id", + "invitations" + ], + "properties": { + "family_id": { + "description": "The family whose pending invitations were queried, echoed back so paginated callers can correlate.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "invitations": { + "description": "The pending invitations on this page, in ascending invitee [`NodeId`] order, each stamped with whether it had already timed out at the time the query was served.", + "type": "array", + "items": { + "$ref": "#/definitions/PendingFamilyInvitationDetails" + } + }, + "start_next_after": { + "description": "Cursor (last invitee node id) to pass as `start_after` on the next call, or `None` if this page is empty (treat as end-of-list).", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "FamilyInvitation": { + "description": "A pending invitation for a node to join a particular family.\n\nInvitations are stored until they are accepted, rejected, revoked, or until the chain advances past `expires_at` (in which case they remain in storage but are treated as inert — there is no background process clearing expired invitations).", + "type": "object", + "required": [ + "expires_at", + "family_id", + "node_id" + ], + "properties": { + "expires_at": { + "description": "Block timestamp (unix seconds) after which the invitation is no longer valid.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "family_id": { + "description": "The family that issued the invitation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "description": "The node being invited.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "PendingFamilyInvitationDetails": { + "description": "A pending [`FamilyInvitation`] paired with whether it has already timed out at the time the query was served.", + "type": "object", + "required": [ + "expired", + "invitation" + ], + "properties": { + "expired": { + "description": "`true` iff `now >= invitation.expires_at` at query time, i.e. the invitation is still in the pending map but can no longer be acted on.", + "type": "boolean" + }, + "invitation": { + "description": "The stored invitation as it was issued.", + "allOf": [ + { + "$ref": "#/definitions/FamilyInvitation" + } + ] + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/node-families/schema/raw/response_to_get_pending_invitations_for_node_paged.json b/contracts/node-families/schema/raw/response_to_get_pending_invitations_for_node_paged.json new file mode 100644 index 0000000000..6d59be893b --- /dev/null +++ b/contracts/node-families/schema/raw/response_to_get_pending_invitations_for_node_paged.json @@ -0,0 +1,90 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PendingInvitationsForNodePagedResponse", + "description": "Response to [`QueryMsg::GetPendingInvitationsForNodePaged`](crate::QueryMsg::GetPendingInvitationsForNodePaged).", + "type": "object", + "required": [ + "invitations", + "node_id" + ], + "properties": { + "invitations": { + "description": "The pending invitations addressed to this node on this page, in ascending [`NodeFamilyId`] order, each stamped with whether it had already timed out at the time the query was served.", + "type": "array", + "items": { + "$ref": "#/definitions/PendingFamilyInvitationDetails" + } + }, + "node_id": { + "description": "The node whose pending invitations were queried, echoed back so paginated callers can correlate.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Cursor (last issuing family id) to pass as `start_after` on the next call, or `None` if this page is empty (treat as end-of-list).", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false, + "definitions": { + "FamilyInvitation": { + "description": "A pending invitation for a node to join a particular family.\n\nInvitations are stored until they are accepted, rejected, revoked, or until the chain advances past `expires_at` (in which case they remain in storage but are treated as inert — there is no background process clearing expired invitations).", + "type": "object", + "required": [ + "expires_at", + "family_id", + "node_id" + ], + "properties": { + "expires_at": { + "description": "Block timestamp (unix seconds) after which the invitation is no longer valid.", + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, + "family_id": { + "description": "The family that issued the invitation.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "node_id": { + "description": "The node being invited.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "PendingFamilyInvitationDetails": { + "description": "A pending [`FamilyInvitation`] paired with whether it has already timed out at the time the query was served.", + "type": "object", + "required": [ + "expired", + "invitation" + ], + "properties": { + "expired": { + "description": "`true` iff `now >= invitation.expires_at` at query time, i.e. the invitation is still in the pending map but can no longer be acted on.", + "type": "boolean" + }, + "invitation": { + "description": "The stored invitation as it was issued.", + "allOf": [ + { + "$ref": "#/definitions/FamilyInvitation" + } + ] + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/node-families/src/bin/schema.rs b/contracts/node-families/src/bin/schema.rs new file mode 100644 index 0000000000..9be22a0984 --- /dev/null +++ b/contracts/node-families/src/bin/schema.rs @@ -0,0 +1,14 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use cosmwasm_schema::write_api; +use nym_node_families_contract_common::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + migrate: MigrateMsg, + } +} diff --git a/contracts/node-families/src/contract.rs b/contracts/node-families/src/contract.rs new file mode 100644 index 0000000000..64d37f6df8 --- /dev/null +++ b/contracts/node-families/src/contract.rs @@ -0,0 +1,355 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +//! CosmWasm entry points for the node families contract. + +use crate::queries::{ + query_all_family_members_paged, query_all_past_invitations_paged, + query_all_pending_invitations_paged, query_families_paged, query_family_by_id, + query_family_by_name, query_family_by_owner, query_family_members_paged, + query_family_membership, query_past_invitations_for_family_paged, + query_past_invitations_for_node_paged, query_past_members_for_family_paged, + query_past_members_for_node_paged, query_pending_invitation, + query_pending_invitations_for_family_paged, query_pending_invitations_for_node_paged, +}; +use crate::storage::NodeFamiliesStorage; +use crate::transactions::{ + try_accept_family_invitation, try_create_family, try_disband_family, try_handle_node_unbonding, + try_invite_to_family, try_kick_from_family, try_leave_family, try_reject_family_invitation, + try_revoke_family_invitation, try_update_config, +}; +use cosmwasm_std::{ + entry_point, to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, +}; +use nym_contracts_common::set_build_information; +use nym_node_families_contract_common::{ + ExecuteMsg, InstantiateMsg, MigrateMsg, NodeFamiliesContractError, QueryMsg, +}; + +const CONTRACT_NAME: &str = "crate:nym-node-families-contract"; + +/// Contract semver, taken from `Cargo.toml` at build time. Bumped on every +/// release; recorded in cw2 storage so migrations can detect the source version. +const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); + +/// One-time initialisation of contract storage on code instantiation. +#[entry_point] +pub fn instantiate( + deps: DepsMut, + _env: Env, + info: MessageInfo, + msg: InstantiateMsg, +) -> Result { + cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + set_build_information!(deps.storage)?; + + let mixnet_contract_address = deps.api.addr_validate(&msg.mixnet_contract_address)?; + + NodeFamiliesStorage::new().initialise( + deps, + info.sender, + mixnet_contract_address, + msg.config, + )?; + + Ok(Response::default()) +} + +/// State-mutating dispatcher. Concrete handlers live in [`crate::transactions`] +/// and are wired up here as variants are added to [`ExecuteMsg`]. +#[entry_point] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + match msg { + ExecuteMsg::UpdateConfig { config } => try_update_config(deps, env, info, config), + ExecuteMsg::CreateFamily { name, description } => { + try_create_family(deps, env, info, name, description) + } + ExecuteMsg::DisbandFamily {} => try_disband_family(deps, env, info), + ExecuteMsg::InviteToFamily { + node_id, + validity_secs, + } => try_invite_to_family(deps, env, info, node_id, validity_secs), + ExecuteMsg::RevokeFamilyInvitation { node_id } => { + try_revoke_family_invitation(deps, env, info, node_id) + } + ExecuteMsg::AcceptFamilyInvitation { family_id, node_id } => { + try_accept_family_invitation(deps, env, info, family_id, node_id) + } + ExecuteMsg::RejectFamilyInvitation { family_id, node_id } => { + try_reject_family_invitation(deps, env, info, family_id, node_id) + } + ExecuteMsg::LeaveFamily { node_id } => try_leave_family(deps, env, info, node_id), + ExecuteMsg::KickFromFamily { node_id } => try_kick_from_family(deps, env, info, node_id), + ExecuteMsg::OnNymNodeUnbond { node_id } => { + try_handle_node_unbonding(deps, env, info, node_id) + } + } +} + +/// Read-only dispatcher. Concrete handlers live in [`crate::queries`] and are +/// wired up here as variants are added to [`QueryMsg`]. +#[entry_point] +pub fn query(deps: Deps, env: Env, msg: QueryMsg) -> Result { + match msg { + QueryMsg::GetFamilyById { family_id } => { + Ok(to_json_binary(&query_family_by_id(deps, family_id)?)?) + } + QueryMsg::GetFamilyByOwner { owner } => { + Ok(to_json_binary(&query_family_by_owner(deps, owner)?)?) + } + QueryMsg::GetFamilyByName { name } => { + Ok(to_json_binary(&query_family_by_name(deps, name)?)?) + } + QueryMsg::GetFamilyMembership { node_id } => { + Ok(to_json_binary(&query_family_membership(deps, node_id)?)?) + } + QueryMsg::GetFamilyMembersPaged { + family_id, + start_after, + limit, + } => Ok(to_json_binary(&query_family_members_paged( + deps, + family_id, + start_after, + limit, + )?)?), + QueryMsg::GetAllFamilyMembersPaged { start_after, limit } => Ok(to_json_binary( + &query_all_family_members_paged(deps, start_after, limit)?, + )?), + QueryMsg::GetPendingInvitation { family_id, node_id } => Ok(to_json_binary( + &query_pending_invitation(deps, env, family_id, node_id)?, + )?), + QueryMsg::GetPendingInvitationsForFamilyPaged { + family_id, + start_after, + limit, + } => Ok(to_json_binary( + &query_pending_invitations_for_family_paged(deps, env, family_id, start_after, limit)?, + )?), + QueryMsg::GetPendingInvitationsForNodePaged { + node_id, + start_after, + limit, + } => Ok(to_json_binary(&query_pending_invitations_for_node_paged( + deps, + env, + node_id, + start_after, + limit, + )?)?), + QueryMsg::GetAllPendingInvitationsPaged { start_after, limit } => Ok(to_json_binary( + &query_all_pending_invitations_paged(deps, env, start_after, limit)?, + )?), + QueryMsg::GetPastInvitationsForFamilyPaged { + family_id, + start_after, + limit, + } => Ok(to_json_binary(&query_past_invitations_for_family_paged( + deps, + family_id, + start_after, + limit, + )?)?), + QueryMsg::GetPastInvitationsForNodePaged { + node_id, + start_after, + limit, + } => Ok(to_json_binary(&query_past_invitations_for_node_paged( + deps, + node_id, + start_after, + limit, + )?)?), + QueryMsg::GetAllPastInvitationsPaged { start_after, limit } => Ok(to_json_binary( + &query_all_past_invitations_paged(deps, start_after, limit)?, + )?), + QueryMsg::GetPastMembersForFamilyPaged { + family_id, + start_after, + limit, + } => Ok(to_json_binary(&query_past_members_for_family_paged( + deps, + family_id, + start_after, + limit, + )?)?), + QueryMsg::GetPastMembersForNodePaged { + node_id, + start_after, + limit, + } => Ok(to_json_binary(&query_past_members_for_node_paged( + deps, + node_id, + start_after, + limit, + )?)?), + QueryMsg::GetFamiliesPaged { start_after, limit } => Ok(to_json_binary( + &query_families_paged(deps, start_after, limit)?, + )?), + } +} + +/// Migration entry point. +/// +/// Refreshes recorded build information and ensures the existing on-chain +/// contract version is at most the current `CONTRACT_VERSION` (i.e. forbids +/// downgrades). Any data migrations are dispatched via +/// [`crate::queued_migrations`]. +#[entry_point] +pub fn migrate( + deps: DepsMut, + _env: Env, + _msg: MigrateMsg, +) -> Result { + set_build_information!(deps.storage)?; + cw2::ensure_from_older_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + + Ok(Default::default()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[cfg(test)] + mod contract_instantiation { + use super::*; + use cosmwasm_std::coin; + use cosmwasm_std::testing::{message_info, mock_dependencies, mock_env}; + use nym_node_families_contract_common::Config; + + fn mock_config() -> Config { + Config { + create_family_fee: coin(123, "unym"), + family_name_length_limit: 20, + family_description_length_limit: 100, + default_invitation_validity_secs: 24 * 60 * 60, + } + } + + #[test] + fn sets_contract_admin_to_the_message_sender() -> anyhow::Result<()> { + let mut deps = mock_dependencies(); + let env = mock_env(); + let mixnet_contract_address = deps.api.addr_make("mixnet-contract"); + let some_sender = deps.api.addr_make("some_sender"); + + instantiate( + deps.as_mut(), + env, + message_info(&some_sender, &[]), + InstantiateMsg { + config: mock_config(), + mixnet_contract_address: mixnet_contract_address.to_string(), + }, + )?; + + let deps = deps.as_ref(); + + NodeFamiliesStorage::new() + .contract_admin + .assert_admin(deps, &some_sender)?; + + Ok(()) + } + + #[test] + fn persists_the_provided_config() -> anyhow::Result<()> { + let mut deps = mock_dependencies(); + let env = mock_env(); + let mixnet_contract_address = deps.api.addr_make("mixnet-contract"); + let sender = deps.api.addr_make("some_sender"); + let config = mock_config(); + + instantiate( + deps.as_mut(), + env, + message_info(&sender, &[]), + InstantiateMsg { + config: config.clone(), + mixnet_contract_address: mixnet_contract_address.to_string(), + }, + )?; + + let stored = NodeFamiliesStorage::new() + .config + .load(deps.as_ref().storage)?; + assert_eq!(stored, config); + + Ok(()) + } + + #[test] + fn persists_the_validated_mixnet_contract_address() -> anyhow::Result<()> { + let mut deps = mock_dependencies(); + let env = mock_env(); + let mixnet_contract_address = deps.api.addr_make("mixnet-contract"); + let sender = deps.api.addr_make("some_sender"); + + instantiate( + deps.as_mut(), + env, + message_info(&sender, &[]), + InstantiateMsg { + config: mock_config(), + mixnet_contract_address: mixnet_contract_address.to_string(), + }, + )?; + + let stored = NodeFamiliesStorage::new() + .mixnet_contract_address + .load(deps.as_ref().storage)?; + assert_eq!(stored, mixnet_contract_address); + + Ok(()) + } + + #[test] + fn errors_on_invalid_mixnet_contract_address() { + let mut deps = mock_dependencies(); + let env = mock_env(); + let sender = deps.api.addr_make("some_sender"); + + let res = instantiate( + deps.as_mut(), + env, + message_info(&sender, &[]), + InstantiateMsg { + config: mock_config(), + mixnet_contract_address: "not-a-valid-bech32-address".to_string(), + }, + ); + + assert!(res.is_err()); + } + + #[test] + fn records_the_cw2_contract_version() -> anyhow::Result<()> { + let mut deps = mock_dependencies(); + let env = mock_env(); + let mixnet_contract_address = deps.api.addr_make("mixnet-contract"); + let sender = deps.api.addr_make("some_sender"); + + instantiate( + deps.as_mut(), + env, + message_info(&sender, &[]), + InstantiateMsg { + config: mock_config(), + mixnet_contract_address: mixnet_contract_address.to_string(), + }, + )?; + + let version = cw2::get_contract_version(deps.as_ref().storage)?; + assert_eq!(version.contract, CONTRACT_NAME); + assert_eq!(version.version, CONTRACT_VERSION); + + Ok(()) + } + } +} diff --git a/contracts/node-families/src/helpers.rs b/contracts/node-families/src/helpers.rs new file mode 100644 index 0000000000..03ba312779 --- /dev/null +++ b/contracts/node-families/src/helpers.rs @@ -0,0 +1,178 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::storage::NodeFamiliesStorage; +use cosmwasm_std::{Addr, Deps}; +use nym_mixnet_contract_common::{MixnetContractQuerier, NodeId}; +use nym_node_families_contract_common::NodeFamiliesContractError; + +/// Normalise a family name into the canonical form used as the unique-index key. +/// +/// Drops every character that isn't an ASCII letter or digit and lowercases +/// the rest, so `" Foo-Bar! "`, `"foobar"` and `"FOO BAR"` all collide on +/// the storage layer's unique-name index. +pub fn normalise_family_name(name: &str) -> String { + name.chars() + .filter(|c| c.is_ascii_alphanumeric()) + .map(|c| c.to_ascii_lowercase()) + .collect() +} + +/// Ensure no node controlled by `address` is currently a member of any family. +pub(crate) fn ensure_address_holds_no_family_membership( + storage: &NodeFamiliesStorage, + deps: Deps, + address: &Addr, +) -> Result<(), NodeFamiliesContractError> { + let mixnet_contract = storage.mixnet_contract_address.load(deps.storage)?; + let Some(nym_node) = deps + .querier + .query_nymnode_ownership(&mixnet_contract, address)? + else { + // if the owner has no nym-node, it can't possibly be in a family + return Ok(()); + }; + + // check if that node is in a family + if let Some(family) = storage + .family_members + .may_load(deps.storage, nym_node.node_id)? + { + return Err(NodeFamiliesContractError::AlreadyInFamily { + address: address.clone(), + node_id: nym_node.node_id, + family_id: family.family_id, + }); + } + + Ok(()) +} + +/// Cross-contract query: ensure `node_id` is a currently-bonded node in the +/// mixnet contract. Returns [`NodeDoesntExist`] otherwise. +/// +/// [`NodeDoesntExist`]: NodeFamiliesContractError::NodeDoesntExist +pub(crate) fn ensure_node_is_bonded( + storage: &NodeFamiliesStorage, + deps: Deps, + node_id: NodeId, +) -> Result<(), NodeFamiliesContractError> { + let mixnet_contract = storage.mixnet_contract_address.load(deps.storage)?; + if !deps + .querier + .check_node_existence(&mixnet_contract, node_id)? + { + return Err(NodeFamiliesContractError::NodeDoesntExist { node_id }); + } + Ok(()) +} + +/// Ensure `address` is the controller of the bonded node `node_id` per the +/// mixnet contract. Errors with [`SenderDoesntControlNode`] when `address` +/// owns no bonded node, owns a node with a different id, or owns it but it +/// has entered the unbonding state. +/// +/// [`SenderDoesntControlNode`]: NodeFamiliesContractError::SenderDoesntControlNode +pub(crate) fn ensure_has_bonded_node( + storage: &NodeFamiliesStorage, + deps: Deps, + address: &Addr, + node_id: NodeId, +) -> Result<(), NodeFamiliesContractError> { + let mixnet_contract = storage.mixnet_contract_address.load(deps.storage)?; + match deps + .querier + .query_nymnode_ownership(&mixnet_contract, address)? + { + Some(bond) if bond.node_id == node_id && !bond.is_unbonding => Ok(()), + _ => Err(NodeFamiliesContractError::SenderDoesntControlNode { + address: address.clone(), + node_id, + }), + } +} + +/// Ensure `node_id` is not currently a member of any family. Returns +/// [`NodeAlreadyInFamily`] if it is. +/// +/// [`NodeAlreadyInFamily`]: NodeFamiliesContractError::NodeAlreadyInFamily +pub(crate) fn ensure_node_not_in_family( + storage: &NodeFamiliesStorage, + deps: Deps, + node_id: NodeId, +) -> Result<(), NodeFamiliesContractError> { + if let Some(membership) = storage.family_members.may_load(deps.storage, node_id)? { + return Err(NodeFamiliesContractError::NodeAlreadyInFamily { + node_id, + family_id: membership.family_id, + }); + } + Ok(()) +} + +#[cfg(test)] +mod tests { + use super::*; + + mod normalise_family_name { + use super::*; + + #[test] + fn empty_input_yields_empty() { + assert_eq!(normalise_family_name(""), ""); + } + + #[test] + fn already_canonical_is_unchanged() { + assert_eq!(normalise_family_name("foobar42"), "foobar42"); + } + + #[test] + fn lowercases_uppercase_letters() { + assert_eq!(normalise_family_name("FOOBAR"), "foobar"); + assert_eq!(normalise_family_name("FooBar"), "foobar"); + } + + #[test] + fn strips_whitespace() { + assert_eq!(normalise_family_name(" foo bar "), "foobar"); + assert_eq!(normalise_family_name("foo\tbar\nbaz"), "foobarbaz"); + } + + #[test] + fn strips_punctuation_and_symbols() { + assert_eq!(normalise_family_name("foo-bar!"), "foobar"); + assert_eq!(normalise_family_name("a.b_c@d"), "abcd"); + } + + #[test] + fn preserves_digits() { + assert_eq!(normalise_family_name("squad-2026"), "squad2026"); + assert_eq!(normalise_family_name("0123456789"), "0123456789"); + } + + #[test] + fn drops_non_ascii_letters() { + // is_ascii_alphanumeric is strict — accented and non-Latin chars are dropped. + assert_eq!(normalise_family_name("café"), "caf"); + assert_eq!(normalise_family_name("Ω-team"), "team"); + assert_eq!(normalise_family_name("名前"), ""); + } + + #[test] + fn all_symbols_input_normalises_to_empty() { + // try_create_family relies on this to surface EmptyFamilyName. + assert_eq!(normalise_family_name(" "), ""); + assert_eq!(normalise_family_name("!!!---"), ""); + } + + #[test] + fn distinct_inputs_collide_under_normalisation() { + // The collision behaviour the unique-name index depends on. + let canonical = normalise_family_name("Foo Bar"); + assert_eq!(canonical, normalise_family_name("foobar")); + assert_eq!(canonical, normalise_family_name("FOO-BAR")); + assert_eq!(canonical, normalise_family_name(" f.o.o.b.a.r ")); + } + } +} diff --git a/contracts/node-families/src/lib.rs b/contracts/node-families/src/lib.rs new file mode 100644 index 0000000000..3325c5b687 --- /dev/null +++ b/contracts/node-families/src/lib.rs @@ -0,0 +1,28 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +//! CosmWasm contract that manages "node families" — owner-led groupings of +//! Nym nodes — including their members, pending invitations, and historical +//! records of past members and rejected/revoked invitations. +//! +//! The shared message and type surface lives in +//! [`node_families_contract_common`]; this crate contains only the on-chain logic +//! and storage layout. + +/// CosmWasm entry points (`instantiate`, `execute`, `query`, `migrate`). +pub mod contract; +/// One-shot data migrations executed by the `migrate` entry point. +pub mod queued_migrations; +/// `cw-storage-plus` definitions: typed maps, items and secondary indexes. +pub mod storage; + +mod helpers; +/// Read-only query handlers backing [`contract::query`]. +mod queries; +/// Test-only helpers — always compiled for this crate's own unit tests via +/// `cfg(test)`; downstream crates can pull them in for their own test +/// harnesses by enabling the `testable-node-families-contract` feature. +#[cfg(any(test, feature = "testable-node-families-contract"))] +pub mod testing; +/// State-mutating execute handlers backing [`contract::execute`]. +mod transactions; diff --git a/contracts/node-families/src/queries.rs b/contracts/node-families/src/queries.rs new file mode 100644 index 0000000000..9b75201fb5 --- /dev/null +++ b/contracts/node-families/src/queries.rs @@ -0,0 +1,2501 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::helpers::normalise_family_name; +use crate::storage::{retrieval_limits, NodeFamiliesStorage}; +use cosmwasm_std::{Deps, Env, Order, StdResult}; +use cw_storage_plus::Bound; +use nym_mixnet_contract_common::NodeId; +use nym_node_families_contract_common::{ + AllFamilyMembersPagedResponse, AllPastFamilyInvitationsPagedResponse, FamiliesPagedResponse, + FamilyMemberRecord, FamilyMembersPagedResponse, GlobalPastFamilyInvitationCursor, + NodeFamiliesContractError, NodeFamilyByNameResponse, NodeFamilyByOwnerResponse, NodeFamilyId, + NodeFamilyMembershipResponse, NodeFamilyResponse, PastFamilyInvitationCursor, + PastFamilyInvitationForNodeCursor, PastFamilyInvitationsForNodePagedResponse, + PastFamilyInvitationsPagedResponse, PastFamilyMemberCursor, PastFamilyMemberForNodeCursor, + PastFamilyMembersForNodePagedResponse, PastFamilyMembersPagedResponse, + PendingFamilyInvitationDetails, PendingFamilyInvitationResponse, + PendingFamilyInvitationsPagedResponse, PendingInvitationsForNodePagedResponse, + PendingInvitationsPagedResponse, +}; + +/// Resolve a single family by its id. Returns `family: None` if no family +/// with that id exists. +pub fn query_family_by_id( + deps: Deps, + family_id: NodeFamilyId, +) -> Result { + let family = NodeFamiliesStorage::new() + .families + .may_load(deps.storage, family_id)?; + Ok(NodeFamilyResponse { family_id, family }) +} + +/// Resolve the (at most one) family owned by `owner`. Returns `family: None` +/// if `owner` does not currently own a family. Backed by the `owner` +/// `UniqueIndex`, so cost is O(1). +pub fn query_family_by_owner( + deps: Deps, + owner: String, +) -> Result { + let owner = deps.api.addr_validate(&owner)?; + let family = NodeFamiliesStorage::new() + .families + .idx + .owner + .item(deps.storage, owner.clone())? + .map(|(_, family)| family); + Ok(NodeFamilyByOwnerResponse { owner, family }) +} + +/// Resolve a single family by its name. The lookup runs the input through +/// [`normalise_family_name`] before hitting the `name` `UniqueIndex`, so +/// e.g. `"foo"`, `"FoO"` and `" foo! "` all resolve to the same family. +/// Returns `family: None` if no family with that (normalised) name exists. +/// Backed by the `name` `UniqueIndex`, so cost is O(1). +pub fn query_family_by_name( + deps: Deps, + name: String, +) -> Result { + let normalised_name = normalise_family_name(&name); + let family = NodeFamiliesStorage::new() + .families + .idx + .normalised_name + .item(deps.storage, normalised_name)? + .map(|(_, family)| family); + Ok(NodeFamilyByNameResponse { name, family }) +} + +/// Report which family — if any — a node currently belongs to. +pub fn query_family_membership( + deps: Deps, + node_id: NodeId, +) -> Result { + let family_id = NodeFamiliesStorage::new() + .family_members + .may_load(deps.storage, node_id)? + .map(|m| m.family_id); + Ok(NodeFamilyMembershipResponse { node_id, family_id }) +} + +/// Resolve a pending invitation by its composite `(family_id, node_id)` key, +/// stamping it with whether it has already timed out at the current block +/// time so the caller doesn't have to do the comparison itself. +pub fn query_pending_invitation( + deps: Deps, + env: Env, + family_id: NodeFamilyId, + node_id: NodeId, +) -> Result { + let now = env.block.time.seconds(); + let invitation = NodeFamiliesStorage::new() + .pending_family_invitations + .may_load(deps.storage, (family_id, node_id))? + .map(|invitation| PendingFamilyInvitationDetails { + expired: now >= invitation.expires_at, + invitation, + }); + Ok(PendingFamilyInvitationResponse { + family_id, + node_id, + invitation, + }) +} + +/// Page through every node currently in `family_id`, in ascending +/// [`NodeId`] order. +/// +/// Backed by the `family` multi-index over [`crate::storage::NodeFamiliesStorage::family_members`], +/// so the cost is O(page size) regardless of how many other families exist. +/// Does not verify that `family_id` refers to an existing family — an +/// unknown id simply yields an empty page. +/// +/// `start_after` is exclusive — pass the previous page's `start_next_after` +/// to fetch the next page; pass `None` to start from the lowest-id member. +/// `limit` defaults to [`retrieval_limits::FAMILY_MEMBERS_DEFAULT_LIMIT`] +/// and is clamped to [`retrieval_limits::FAMILY_MEMBERS_MAX_LIMIT`]. +pub fn query_family_members_paged( + deps: Deps, + family_id: NodeFamilyId, + start_after: Option, + limit: Option, +) -> Result { + let limit = limit + .unwrap_or(retrieval_limits::FAMILY_MEMBERS_DEFAULT_LIMIT) + .min(retrieval_limits::FAMILY_MEMBERS_MAX_LIMIT) as usize; + + let start = start_after.map(Bound::exclusive); + + let storage = NodeFamiliesStorage::new(); + let members = storage + .family_members + .idx + .family + .prefix(family_id) + .range(deps.storage, start, None, Order::Ascending) + .take(limit) + .map(|res| { + res.map(|(node_id, membership)| FamilyMemberRecord { + node_id, + membership, + }) + }) + .collect::>>()?; + + let start_next_after = members.last().map(|record| record.node_id); + + Ok(FamilyMembersPagedResponse { + family_id, + members, + start_next_after, + }) +} + +/// Page through every current family member across all families, in ascending +/// [`NodeId`] order. Each entry carries the [`FamilyMembership`](node_families_contract_common::FamilyMembership) +/// record, which names the family the node belongs to. +/// +/// Cost is O(page size) — full range scan over the primary `family_members` +/// map without any prefix filter. Since each node belongs to at most one +/// family, [`NodeId`] alone is sufficient as a pagination cursor. +/// +/// `start_after` is exclusive — pass the previous page's `start_next_after` +/// to fetch the next page; pass `None` to start from the lowest-id member. +/// `limit` defaults to [`retrieval_limits::FAMILY_MEMBERS_DEFAULT_LIMIT`] +/// and is clamped to [`retrieval_limits::FAMILY_MEMBERS_MAX_LIMIT`]. +pub fn query_all_family_members_paged( + deps: Deps, + start_after: Option, + limit: Option, +) -> Result { + let limit = limit + .unwrap_or(retrieval_limits::FAMILY_MEMBERS_DEFAULT_LIMIT) + .min(retrieval_limits::FAMILY_MEMBERS_MAX_LIMIT) as usize; + + let start = start_after.map(Bound::exclusive); + + let storage = NodeFamiliesStorage::new(); + let members = storage + .family_members + .range(deps.storage, start, None, Order::Ascending) + .take(limit) + .map(|res| { + res.map(|(node_id, membership)| FamilyMemberRecord { + node_id, + membership, + }) + }) + .collect::>>()?; + + let start_next_after = members.last().map(|record| record.node_id); + + Ok(AllFamilyMembersPagedResponse { + members, + start_next_after, + }) +} + +/// Page through every pending invitation issued by `family_id`, in ascending +/// invitee [`NodeId`] order. Each entry is stamped with `expired` based on +/// the current block time, so callers don't have to compare it themselves. +/// +/// Backed by a prefix scan on the composite primary key +/// `(family_id, node_id)` of `pending_family_invitations`, so cost is +/// O(page size). Does not verify that `family_id` refers to an existing +/// family — an unknown id simply yields an empty page. +/// +/// `start_after` is exclusive — pass the previous page's `start_next_after` +/// to fetch the next page; pass `None` to start from the lowest-id invitee. +/// `limit` defaults to [`retrieval_limits::PENDING_INVITATIONS_DEFAULT_LIMIT`] +/// and is clamped to [`retrieval_limits::PENDING_INVITATIONS_MAX_LIMIT`]. +pub fn query_pending_invitations_for_family_paged( + deps: Deps, + env: Env, + family_id: NodeFamilyId, + start_after: Option, + limit: Option, +) -> Result { + let limit = limit + .unwrap_or(retrieval_limits::PENDING_INVITATIONS_DEFAULT_LIMIT) + .min(retrieval_limits::PENDING_INVITATIONS_MAX_LIMIT) as usize; + + let now = env.block.time.seconds(); + let start = start_after.map(Bound::exclusive); + + let storage = NodeFamiliesStorage::new(); + let invitations = storage + .pending_family_invitations + .prefix(family_id) + .range(deps.storage, start, None, Order::Ascending) + .take(limit) + .map(|res| { + res.map(|(_node_id, invitation)| PendingFamilyInvitationDetails { + expired: now >= invitation.expires_at, + invitation, + }) + }) + .collect::>>()?; + + let start_next_after = invitations.last().map(|d| d.invitation.node_id); + + Ok(PendingFamilyInvitationsPagedResponse { + family_id, + invitations, + start_next_after, + }) +} + +/// Page through every pending invitation addressed to `node_id`, in ascending +/// issuing [`NodeFamilyId`] order. Each entry is stamped with `expired` based +/// on the current block time. +/// +/// Backed by the `node` multi-index over `pending_family_invitations`, so +/// cost is O(page size). `start_after` is exclusive — pass the previous +/// page's `start_next_after` to fetch the next page. `limit` defaults to +/// [`retrieval_limits::PENDING_INVITATIONS_DEFAULT_LIMIT`] and is clamped to +/// [`retrieval_limits::PENDING_INVITATIONS_MAX_LIMIT`]. +pub fn query_pending_invitations_for_node_paged( + deps: Deps, + env: Env, + node_id: NodeId, + start_after: Option, + limit: Option, +) -> Result { + let limit = limit + .unwrap_or(retrieval_limits::PENDING_INVITATIONS_DEFAULT_LIMIT) + .min(retrieval_limits::PENDING_INVITATIONS_MAX_LIMIT) as usize; + + let now = env.block.time.seconds(); + let start = start_after.map(|family_id| Bound::exclusive((family_id, node_id))); + + let storage = NodeFamiliesStorage::new(); + let invitations = storage + .pending_family_invitations + .idx + .node + .prefix(node_id) + .range(deps.storage, start, None, Order::Ascending) + .take(limit) + .map(|res| { + res.map(|(_pk, invitation)| PendingFamilyInvitationDetails { + expired: now >= invitation.expires_at, + invitation, + }) + }) + .collect::>>()?; + + let start_next_after = invitations.last().map(|d| d.invitation.family_id); + + Ok(PendingInvitationsForNodePagedResponse { + node_id, + invitations, + start_next_after, + }) +} + +/// Page through every pending invitation across all families, in ascending +/// `(family_id, node_id)` order. Each entry is stamped with `expired` based +/// on the current block time. +/// +/// Cost is O(page size) — full range scan over the +/// `pending_family_invitations` map without any prefix filter. +/// +/// `start_after` is exclusive — pass the previous page's `start_next_after` +/// to fetch the next page; pass `None` to start from the first entry. +/// `limit` defaults to [`retrieval_limits::PENDING_INVITATIONS_DEFAULT_LIMIT`] +/// and is clamped to [`retrieval_limits::PENDING_INVITATIONS_MAX_LIMIT`]. +pub fn query_all_pending_invitations_paged( + deps: Deps, + env: Env, + start_after: Option<(NodeFamilyId, NodeId)>, + limit: Option, +) -> Result { + let limit = limit + .unwrap_or(retrieval_limits::PENDING_INVITATIONS_DEFAULT_LIMIT) + .min(retrieval_limits::PENDING_INVITATIONS_MAX_LIMIT) as usize; + + let now = env.block.time.seconds(); + let start = start_after.map(Bound::exclusive); + + let storage = NodeFamiliesStorage::new(); + let invitations = storage + .pending_family_invitations + .range(deps.storage, start, None, Order::Ascending) + .take(limit) + .map(|res| { + res.map(|(_key, invitation)| PendingFamilyInvitationDetails { + expired: now >= invitation.expires_at, + invitation, + }) + }) + .collect::>>()?; + + let start_next_after = invitations + .last() + .map(|d| (d.invitation.family_id, d.invitation.node_id)); + + Ok(PendingInvitationsPagedResponse { + invitations, + start_next_after, + }) +} + +/// Page through every archived (terminal-state) invitation issued by +/// `family_id`, in ascending `(node_id, counter)` order across all +/// `Accepted` / `Rejected` / `Revoked` statuses. +/// +/// Uses a direct bounds-based range scan on the primary map keyed by +/// `((family_id, node_id), counter)` — `family_id` is already the leftmost +/// key component, so this avoids the extra storage read per entry that +/// going through the `family` multi-index would incur. Cost is O(page +/// size). Does not verify that `family_id` refers to an existing +/// family — an unknown id simply yields an empty page. +/// +/// `start_after` is exclusive — pass the previous page's `start_next_after` +/// to fetch the next page; pass `None` to start from the first archived +/// entry. `limit` defaults to [`retrieval_limits::PAST_INVITATIONS_DEFAULT_LIMIT`] +/// and is clamped to [`retrieval_limits::PAST_INVITATIONS_MAX_LIMIT`]. +pub fn query_past_invitations_for_family_paged( + deps: Deps, + family_id: NodeFamilyId, + start_after: Option, + limit: Option, +) -> Result { + let limit = limit + .unwrap_or(retrieval_limits::PAST_INVITATIONS_DEFAULT_LIMIT) + .min(retrieval_limits::PAST_INVITATIONS_MAX_LIMIT) as usize; + + let lower = Some(match start_after { + Some((node_id, counter)) => Bound::exclusive(((family_id, node_id), counter)), + None => Bound::inclusive(((family_id, 0), 0)), + }); + + // upper bound = first key of next family; + let upper = Some(Bound::exclusive(((family_id + 1, 0), 0))); + + let storage = NodeFamiliesStorage::new(); + let entries = storage + .past_family_invitations + .range(deps.storage, lower, upper, Order::Ascending) + .take(limit) + .collect::>>()?; + + let start_next_after = entries + .last() + .map(|(((_, node_id), counter), _)| (*node_id, *counter)); + + let invitations = entries.into_iter().map(|(_, v)| v).collect(); + + Ok(PastFamilyInvitationsPagedResponse { + family_id, + invitations, + start_next_after, + }) +} + +/// Page through every archived (terminal-state) invitation addressed to +/// `node_id`, in ascending `(family_id, counter)` order across all +/// `Accepted` / `Rejected` / `Revoked` statuses. +/// +/// Backed by the `node` multi-index over `past_family_invitations`, so +/// cost is O(page size). `start_after` is exclusive — pass the previous +/// page's `start_next_after` to fetch the next page. `limit` defaults to +/// [`retrieval_limits::PAST_INVITATIONS_DEFAULT_LIMIT`] and is clamped to +/// [`retrieval_limits::PAST_INVITATIONS_MAX_LIMIT`]. +pub fn query_past_invitations_for_node_paged( + deps: Deps, + node_id: NodeId, + start_after: Option, + limit: Option, +) -> Result { + let limit = limit + .unwrap_or(retrieval_limits::PAST_INVITATIONS_DEFAULT_LIMIT) + .min(retrieval_limits::PAST_INVITATIONS_MAX_LIMIT) as usize; + + let start = + start_after.map(|(family_id, counter)| Bound::exclusive(((family_id, node_id), counter))); + + let storage = NodeFamiliesStorage::new(); + let entries = storage + .past_family_invitations + .idx + .node + .prefix(node_id) + .range(deps.storage, start, None, Order::Ascending) + .take(limit) + .collect::>>()?; + + let start_next_after = entries + .last() + .map(|(((family_id, _), counter), _)| (*family_id, *counter)); + + let invitations = entries.into_iter().map(|(_, v)| v).collect(); + + Ok(PastFamilyInvitationsForNodePagedResponse { + node_id, + invitations, + start_next_after, + }) +} + +/// Page through every archived (terminal-state) invitation across all +/// families, in ascending `((family_id, node_id), counter)` order. +/// +/// Cost is O(page size) — full range scan over the +/// `past_family_invitations` map without any prefix filter. +/// +/// `start_after` is exclusive — pass the previous page's `start_next_after` +/// to fetch the next page; pass `None` to start from the first entry. +/// `limit` defaults to [`retrieval_limits::PAST_INVITATIONS_DEFAULT_LIMIT`] +/// and is clamped to [`retrieval_limits::PAST_INVITATIONS_MAX_LIMIT`]. +pub fn query_all_past_invitations_paged( + deps: Deps, + start_after: Option, + limit: Option, +) -> Result { + let limit = limit + .unwrap_or(retrieval_limits::PAST_INVITATIONS_DEFAULT_LIMIT) + .min(retrieval_limits::PAST_INVITATIONS_MAX_LIMIT) as usize; + + let start = start_after.map(Bound::exclusive); + + let storage = NodeFamiliesStorage::new(); + let entries = storage + .past_family_invitations + .range(deps.storage, start, None, Order::Ascending) + .take(limit) + .collect::>>()?; + + let start_next_after = entries.last().map(|(key, _)| *key); + + let invitations = entries.into_iter().map(|(_, v)| v).collect(); + + Ok(AllPastFamilyInvitationsPagedResponse { + invitations, + start_next_after, + }) +} + +/// Page through every archived membership record for `family_id` (nodes that +/// used to belong to it but have since been removed), in ascending +/// `(node_id, counter)` order. +/// +/// Uses a direct bounds-based range scan on the primary map keyed by +/// `((family_id, node_id), counter)` — `family_id` is already the leftmost +/// key component, so this avoids the extra storage read per entry that +/// going through the `family` multi-index would incur. Cost is O(page +/// size). Does not verify that `family_id` refers to an existing +/// family — an unknown id simply yields an empty page. +/// +/// `start_after` is exclusive — pass the previous page's `start_next_after` +/// to fetch the next page; pass `None` to start from the first archived +/// entry. `limit` defaults to [`retrieval_limits::PAST_MEMBERS_DEFAULT_LIMIT`] +/// and is clamped to [`retrieval_limits::PAST_MEMBERS_MAX_LIMIT`]. +pub fn query_past_members_for_family_paged( + deps: Deps, + family_id: NodeFamilyId, + start_after: Option, + limit: Option, +) -> Result { + let limit = limit + .unwrap_or(retrieval_limits::PAST_MEMBERS_DEFAULT_LIMIT) + .min(retrieval_limits::PAST_MEMBERS_MAX_LIMIT) as usize; + + let lower = Some(match start_after { + Some((node_id, counter)) => Bound::exclusive(((family_id, node_id), counter)), + None => Bound::inclusive(((family_id, 0), 0)), + }); + + // upper bound = first key of next family; + let upper = Some(Bound::exclusive(((family_id + 1, 0), 0))); + + let storage = NodeFamiliesStorage::new(); + let entries = storage + .past_family_members + .range(deps.storage, lower, upper, Order::Ascending) + .take(limit) + .collect::>>()?; + + let start_next_after = entries + .last() + .map(|(((_, node_id), counter), _)| (*node_id, *counter)); + + let members = entries.into_iter().map(|(_, v)| v).collect(); + + Ok(PastFamilyMembersPagedResponse { + family_id, + members, + start_next_after, + }) +} + +/// Page through every archived membership record for `node_id` (every family +/// the node used to belong to but has since been removed from), in ascending +/// `(family_id, counter)` order. +/// +/// Backed by the `node` multi-index over `past_family_members`, so cost is +/// O(page size). `start_after` is exclusive — pass the previous page's +/// `start_next_after` to fetch the next page. `limit` defaults to +/// [`retrieval_limits::PAST_MEMBERS_DEFAULT_LIMIT`] and is clamped to +/// [`retrieval_limits::PAST_MEMBERS_MAX_LIMIT`]. +pub fn query_past_members_for_node_paged( + deps: Deps, + node_id: NodeId, + start_after: Option, + limit: Option, +) -> Result { + let limit = limit + .unwrap_or(retrieval_limits::PAST_MEMBERS_DEFAULT_LIMIT) + .min(retrieval_limits::PAST_MEMBERS_MAX_LIMIT) as usize; + + let start = + start_after.map(|(family_id, counter)| Bound::exclusive(((family_id, node_id), counter))); + + let storage = NodeFamiliesStorage::new(); + let entries = storage + .past_family_members + .idx + .node + .prefix(node_id) + .range(deps.storage, start, None, Order::Ascending) + .take(limit) + .collect::>>()?; + + let start_next_after = entries + .last() + .map(|(((family_id, _), counter), _)| (*family_id, *counter)); + + let members = entries.into_iter().map(|(_, v)| v).collect(); + + Ok(PastFamilyMembersForNodePagedResponse { + node_id, + members, + start_next_after, + }) +} + +/// Page through every existing family in ascending [`NodeFamilyId`] order. +/// +/// `start_after` is exclusive — pass the previous page's `start_next_after` +/// to fetch the next page; pass `None` to start from the first family. +/// `limit` defaults to [`retrieval_limits::FAMILIES_DEFAULT_LIMIT`] and is +/// clamped to [`retrieval_limits::FAMILIES_MAX_LIMIT`]. +pub fn query_families_paged( + deps: Deps, + start_after: Option, + limit: Option, +) -> Result { + let limit = limit + .unwrap_or(retrieval_limits::FAMILIES_DEFAULT_LIMIT) + .min(retrieval_limits::FAMILIES_MAX_LIMIT) as usize; + + let start = start_after.map(Bound::exclusive); + + let storage = NodeFamiliesStorage::new(); + let families = storage + .families + .range(deps.storage, start, None, Order::Ascending) + .take(limit) + .map(|res| res.map(|item| item.1)) + .collect::>>()?; + + let start_next_after = families.last().map(|family| family.id); + + Ok(FamiliesPagedResponse { + families, + start_next_after, + }) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::testing::{init_contract_tester, NodeFamiliesContractTesterExt}; + use nym_contracts_common_testing::{ChainOpts, ContractOpts}; + + #[cfg(test)] + mod family_by_id { + use super::*; + + #[test] + fn family_by_id_returns_none_when_missing() { + let tester = init_contract_tester(); + + let res = query_family_by_id(tester.deps(), 99).unwrap(); + assert_eq!(res.family_id, 99); + assert!(res.family.is_none()); + } + + #[test] + fn family_by_id_returns_persisted_family() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + + let res = query_family_by_id(tester.deps(), f.id).unwrap(); + assert_eq!(res.family_id, f.id); + assert_eq!(res.family, Some(f)); + } + } + + #[cfg(test)] + mod family_by_owner { + use super::*; + + #[test] + fn returns_none_when_owner_owns_no_family() { + let tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + + let res = query_family_by_owner(tester.deps(), alice.to_string()).unwrap(); + assert_eq!(res.owner, alice); + assert!(res.family.is_none()); + } + + #[test] + fn returns_persisted_family_for_owner() { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let f = tester.make_family(&alice); + + let res = query_family_by_owner(tester.deps(), alice.to_string()).unwrap(); + assert_eq!(res.owner, alice); + assert_eq!(res.family, Some(f)); + } + + #[test] + fn distinguishes_owners() { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let bob = tester.addr_make("bob"); + let f_alice = tester.make_family(&alice); + let f_bob = tester.make_family(&bob); + + let res = query_family_by_owner(tester.deps(), alice.to_string()).unwrap(); + assert_eq!(res.family, Some(f_alice)); + let res = query_family_by_owner(tester.deps(), bob.to_string()).unwrap(); + assert_eq!(res.family, Some(f_bob)); + } + + #[test] + fn errors_on_invalid_address() { + let tester = init_contract_tester(); + + let res = query_family_by_owner(tester.deps(), "not a valid addr".to_string()); + assert!(res.is_err()); + } + } + + #[cfg(test)] + mod family_by_name { + use super::*; + use nym_contracts_common_testing::RandExt; + + #[test] + fn returns_none_when_name_does_not_exist() { + let tester = init_contract_tester(); + + let res = query_family_by_name(tester.deps(), "missing".to_string()).unwrap(); + assert_eq!(res.name, "missing"); + assert!(res.family.is_none()); + } + + #[test] + fn returns_persisted_family_by_exact_name() { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let f = tester.make_named_family(&alice, "foo"); + + let res = query_family_by_name(tester.deps(), "foo".to_string()).unwrap(); + assert_eq!(res.name, "foo"); + assert_eq!(res.family, Some(f)); + } + + #[test] + fn lookup_normalises_name() { + let variants = ["foo", "FOO", "FoO", "fOo", "foo🚀", "🚀Foo", " foo-!"]; + + for family_name in variants { + let mut tester = init_contract_tester(); + let owner = tester.generate_account(); + let f = tester.make_named_family(&owner, family_name); + + for query_name in variants { + let res = query_family_by_name(tester.deps(), query_name.to_string()).unwrap(); + assert_eq!(res.name, query_name); + assert_eq!(res.family, Some(f.clone())); + let stored = res.family.unwrap(); + // user-submitted formatting is preserved on the record; + // the normalised form is what enforces uniqueness. + assert_eq!(stored.name, family_name); + assert_eq!(stored.normalised_name, normalise_family_name(family_name)); + } + } + } + } + + #[cfg(test)] + mod family_membership { + use super::*; + + #[test] + fn family_membership_returns_none_for_unaffiliated_node() { + let tester = init_contract_tester(); + + let res = query_family_membership(tester.deps(), 999).unwrap(); + assert_eq!(res.node_id, 999); + assert!(res.family_id.is_none()); + } + + #[test] + fn family_membership_returns_family_id_for_member() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + + tester.add_to_family(f.id, 42); + + let res = query_family_membership(tester.deps(), 42).unwrap(); + assert_eq!(res.node_id, 42); + assert_eq!(res.family_id, Some(f.id)); + } + + #[test] + fn family_membership_returns_none_after_node_is_removed() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + + tester.add_to_family(f.id, 42); + tester.remove_from_family(42); + + let res = query_family_membership(tester.deps(), 42).unwrap(); + assert!(res.family_id.is_none()); + } + } + + #[cfg(test)] + mod pending_invitation { + use super::*; + + #[test] + fn pending_invitation_returns_none_when_missing() { + let tester = init_contract_tester(); + let env = tester.env(); + + let res = query_pending_invitation(tester.deps(), env, 1, 42).unwrap(); + assert_eq!(res.family_id, 1); + assert_eq!(res.node_id, 42); + assert!(res.invitation.is_none()); + } + + #[test] + fn pending_invitation_returns_unexpired_when_in_future() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + + let inv = tester.invite_to_family(f.id, 42); + let env = tester.env(); + + let res = query_pending_invitation(tester.deps(), env, f.id, 42).unwrap(); + let details = res.invitation.unwrap(); + assert_eq!(details.invitation, inv); + assert!(!details.expired); + } + + #[test] + fn pending_invitation_flagged_as_expired_after_block_time() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + + let expires_at = tester.env().block.time.seconds() + 5; + tester.invite_to_family_with_expiration(f.id, 42, expires_at); + + // advance block time well past the expiry + tester.advance_time_by(60); + + let env = tester.env(); + assert!(env.block.time.seconds() >= expires_at); + + let res = query_pending_invitation(tester.deps(), env, f.id, 42).unwrap(); + let details = res.invitation.unwrap(); + assert_eq!(details.invitation.expires_at, expires_at); + assert!(details.expired); + } + } + + #[cfg(test)] + mod families_paged { + use super::*; + + #[test] + fn empty_when_no_families_exist() { + let tester = init_contract_tester(); + + let res = query_families_paged(tester.deps(), None, None).unwrap(); + assert!(res.families.is_empty()); + assert!(res.start_next_after.is_none()); + } + + #[test] + fn returns_all_families_within_default_limit() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + let f3 = tester.add_dummy_family(); + + let res = query_families_paged(tester.deps(), None, None).unwrap(); + assert_eq!(res.families, vec![f1, f2, f3.clone()]); + assert_eq!(res.start_next_after, Some(f3.id)); + } + + #[test] + fn returns_families_in_ascending_id_order() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + let f3 = tester.add_dummy_family(); + + let res = query_families_paged(tester.deps(), None, None).unwrap(); + let ids: Vec<_> = res.families.iter().map(|f| f.id).collect(); + assert_eq!(ids, vec![f1.id, f2.id, f3.id]); + } + + #[test] + fn limit_caps_page_size() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + let _f3 = tester.add_dummy_family(); + + let res = query_families_paged(tester.deps(), None, Some(2)).unwrap(); + assert_eq!(res.families, vec![f1, f2.clone()]); + assert_eq!(res.start_next_after, Some(f2.id)); + } + + #[test] + fn start_after_is_exclusive() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + let f3 = tester.add_dummy_family(); + + let res = query_families_paged(tester.deps(), Some(f1.id), None).unwrap(); + assert_eq!(res.families, vec![f2, f3.clone()]); + assert_eq!(res.start_next_after, Some(f3.id)); + } + + #[test] + fn paginates_through_all_families() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + let f3 = tester.add_dummy_family(); + let f4 = tester.add_dummy_family(); + let f5 = tester.add_dummy_family(); + + let page1 = query_families_paged(tester.deps(), None, Some(2)).unwrap(); + assert_eq!(page1.families, vec![f1, f2.clone()]); + assert_eq!(page1.start_next_after, Some(f2.id)); + + let page2 = + query_families_paged(tester.deps(), page1.start_next_after, Some(2)).unwrap(); + assert_eq!(page2.families, vec![f3, f4.clone()]); + assert_eq!(page2.start_next_after, Some(f4.id)); + + let page3 = + query_families_paged(tester.deps(), page2.start_next_after, Some(2)).unwrap(); + assert_eq!(page3.families, vec![f5.clone()]); + assert_eq!(page3.start_next_after, Some(f5.id)); + + let page4 = + query_families_paged(tester.deps(), page3.start_next_after, Some(2)).unwrap(); + assert!(page4.families.is_empty()); + assert!(page4.start_next_after.is_none()); + } + + #[test] + fn limit_is_clamped_to_max() { + let mut tester = init_contract_tester(); + let total = retrieval_limits::FAMILIES_MAX_LIMIT as usize + 5; + for _ in 0..total { + tester.add_dummy_family(); + } + + let res = query_families_paged(tester.deps(), None, Some(u32::MAX)).unwrap(); + assert_eq!( + res.families.len(), + retrieval_limits::FAMILIES_MAX_LIMIT as usize + ); + } + + #[test] + fn default_limit_applied_when_unspecified() { + let mut tester = init_contract_tester(); + let total = retrieval_limits::FAMILIES_DEFAULT_LIMIT as usize + 5; + for _ in 0..total { + tester.add_dummy_family(); + } + + let res = query_families_paged(tester.deps(), None, None).unwrap(); + assert_eq!( + res.families.len(), + retrieval_limits::FAMILIES_DEFAULT_LIMIT as usize + ); + } + + #[test] + fn start_after_past_end_returns_empty() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + + let res = query_families_paged(tester.deps(), Some(f.id), None).unwrap(); + assert!(res.families.is_empty()); + assert!(res.start_next_after.is_none()); + } + } + + #[cfg(test)] + mod family_members_paged { + use super::*; + + #[test] + fn empty_when_family_has_no_members() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + + let res = query_family_members_paged(tester.deps(), f.id, None, None).unwrap(); + assert_eq!(res.family_id, f.id); + assert!(res.members.is_empty()); + assert!(res.start_next_after.is_none()); + } + + #[test] + fn empty_for_unknown_family_id() { + let tester = init_contract_tester(); + + let res = query_family_members_paged(tester.deps(), 99, None, None).unwrap(); + assert_eq!(res.family_id, 99); + assert!(res.members.is_empty()); + assert!(res.start_next_after.is_none()); + } + + #[test] + fn returns_only_members_of_requested_family() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + + tester.add_to_family(f1.id, 10); + tester.add_to_family(f1.id, 11); + tester.add_to_family(f2.id, 20); + + let res = query_family_members_paged(tester.deps(), f1.id, None, None).unwrap(); + let ids: Vec<_> = res.members.iter().map(|m| m.node_id).collect(); + assert_eq!(ids, vec![10, 11]); + for record in &res.members { + assert_eq!(record.membership.family_id, f1.id); + } + } + + #[test] + fn member_record_carries_joined_at_timestamp() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + tester.add_to_family(f.id, 42); + + let expected = tester.env().block.time.seconds(); + let res = query_family_members_paged(tester.deps(), f.id, None, None).unwrap(); + let record = res.members.into_iter().next().unwrap(); + assert_eq!(record.node_id, 42); + assert_eq!(record.membership.family_id, f.id); + assert_eq!(record.membership.joined_at, expected); + } + + #[test] + fn members_returned_in_ascending_node_id_order() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + // insert out of order to confirm ordering isn't insertion order + tester.add_to_family(f.id, 30); + tester.add_to_family(f.id, 10); + tester.add_to_family(f.id, 20); + + let res = query_family_members_paged(tester.deps(), f.id, None, None).unwrap(); + let ids: Vec<_> = res.members.iter().map(|m| m.node_id).collect(); + assert_eq!(ids, vec![10, 20, 30]); + } + + #[test] + fn limit_caps_page_size() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + for n in [10, 11, 12] { + tester.add_to_family(f.id, n); + } + + let res = query_family_members_paged(tester.deps(), f.id, None, Some(2)).unwrap(); + let ids: Vec<_> = res.members.iter().map(|m| m.node_id).collect(); + assert_eq!(ids, vec![10, 11]); + assert_eq!(res.start_next_after, Some(11)); + } + + #[test] + fn start_after_is_exclusive() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + for n in [10, 11, 12] { + tester.add_to_family(f.id, n); + } + + let res = query_family_members_paged(tester.deps(), f.id, Some(10), None).unwrap(); + let ids: Vec<_> = res.members.iter().map(|m| m.node_id).collect(); + assert_eq!(ids, vec![11, 12]); + assert_eq!(res.start_next_after, Some(12)); + } + + #[test] + fn paginates_through_all_members() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + for n in [10, 11, 12, 13, 14] { + tester.add_to_family(f.id, n); + } + + let p1 = query_family_members_paged(tester.deps(), f.id, None, Some(2)).unwrap(); + assert_eq!( + p1.members.iter().map(|m| m.node_id).collect::>(), + vec![10, 11] + ); + assert_eq!(p1.start_next_after, Some(11)); + + let p2 = query_family_members_paged(tester.deps(), f.id, p1.start_next_after, Some(2)) + .unwrap(); + assert_eq!( + p2.members.iter().map(|m| m.node_id).collect::>(), + vec![12, 13] + ); + assert_eq!(p2.start_next_after, Some(13)); + + let p3 = query_family_members_paged(tester.deps(), f.id, p2.start_next_after, Some(2)) + .unwrap(); + assert_eq!( + p3.members.iter().map(|m| m.node_id).collect::>(), + vec![14] + ); + assert_eq!(p3.start_next_after, Some(14)); + + let p4 = query_family_members_paged(tester.deps(), f.id, p3.start_next_after, Some(2)) + .unwrap(); + assert!(p4.members.is_empty()); + assert!(p4.start_next_after.is_none()); + } + + #[test] + fn limit_is_clamped_to_max() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + let total = retrieval_limits::FAMILY_MEMBERS_MAX_LIMIT + 5; + tester.add_n_family_members(f.id, total); + + let res = + query_family_members_paged(tester.deps(), f.id, None, Some(u32::MAX)).unwrap(); + assert_eq!( + res.members.len(), + retrieval_limits::FAMILY_MEMBERS_MAX_LIMIT as usize + ); + } + + #[test] + fn excludes_node_after_it_leaves_family() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + tester.add_to_family(f.id, 10); + tester.add_to_family(f.id, 11); + + tester.remove_from_family(10); + + let res = query_family_members_paged(tester.deps(), f.id, None, None).unwrap(); + let ids: Vec<_> = res.members.iter().map(|m| m.node_id).collect(); + assert_eq!(ids, vec![11]); + } + } + + #[cfg(test)] + mod all_family_members_paged { + use super::*; + + #[test] + fn empty_when_no_families_exist() { + let tester = init_contract_tester(); + + let res = query_all_family_members_paged(tester.deps(), None, None).unwrap(); + assert!(res.members.is_empty()); + assert!(res.start_next_after.is_none()); + } + + #[test] + fn empty_when_families_have_no_members() { + let mut tester = init_contract_tester(); + tester.add_dummy_family(); + tester.add_dummy_family(); + + let res = query_all_family_members_paged(tester.deps(), None, None).unwrap(); + assert!(res.members.is_empty()); + assert!(res.start_next_after.is_none()); + } + + #[test] + fn returns_members_from_every_family() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + let f3 = tester.add_dummy_family(); + + tester.add_to_family(f1.id, 10); + tester.add_to_family(f2.id, 20); + tester.add_to_family(f3.id, 30); + + let res = query_all_family_members_paged(tester.deps(), None, None).unwrap(); + let pairs: Vec<_> = res + .members + .iter() + .map(|m| (m.node_id, m.membership.family_id)) + .collect(); + assert_eq!(pairs, vec![(10, f1.id), (20, f2.id), (30, f3.id)]); + } + + #[test] + fn members_returned_in_ascending_node_id_order_across_families() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + + // interleaved so insertion order does not match the requested ordering + tester.add_to_family(f2.id, 30); + tester.add_to_family(f1.id, 10); + tester.add_to_family(f2.id, 20); + tester.add_to_family(f1.id, 40); + + let res = query_all_family_members_paged(tester.deps(), None, None).unwrap(); + let ids: Vec<_> = res.members.iter().map(|m| m.node_id).collect(); + assert_eq!(ids, vec![10, 20, 30, 40]); + } + + #[test] + fn member_record_carries_correct_family_and_joined_at() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + + tester.add_to_family(f1.id, 7); + tester.add_to_family(f2.id, 99); + let expected_joined_at = tester.env().block.time.seconds(); + + let res = query_all_family_members_paged(tester.deps(), None, None).unwrap(); + let by_node: std::collections::HashMap<_, _> = res + .members + .into_iter() + .map(|m| (m.node_id, m.membership)) + .collect(); + + let m7 = &by_node[&7]; + assert_eq!(m7.family_id, f1.id); + assert_eq!(m7.joined_at, expected_joined_at); + + let m99 = &by_node[&99]; + assert_eq!(m99.family_id, f2.id); + assert_eq!(m99.joined_at, expected_joined_at); + } + + #[test] + fn limit_caps_page_size() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + for n in [10, 11, 12] { + tester.add_to_family(f.id, n); + } + + let res = query_all_family_members_paged(tester.deps(), None, Some(2)).unwrap(); + let ids: Vec<_> = res.members.iter().map(|m| m.node_id).collect(); + assert_eq!(ids, vec![10, 11]); + assert_eq!(res.start_next_after, Some(11)); + } + + #[test] + fn start_after_is_exclusive() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + for n in [10, 11, 12] { + tester.add_to_family(f.id, n); + } + + let res = query_all_family_members_paged(tester.deps(), Some(10), None).unwrap(); + let ids: Vec<_> = res.members.iter().map(|m| m.node_id).collect(); + assert_eq!(ids, vec![11, 12]); + assert_eq!(res.start_next_after, Some(12)); + } + + #[test] + fn paginates_through_all_members_across_families() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + + tester.add_to_family(f1.id, 10); + tester.add_to_family(f2.id, 11); + tester.add_to_family(f1.id, 12); + tester.add_to_family(f2.id, 13); + tester.add_to_family(f1.id, 14); + + let p1 = query_all_family_members_paged(tester.deps(), None, Some(2)).unwrap(); + assert_eq!( + p1.members.iter().map(|m| m.node_id).collect::>(), + vec![10, 11] + ); + assert_eq!(p1.start_next_after, Some(11)); + + let p2 = query_all_family_members_paged(tester.deps(), p1.start_next_after, Some(2)) + .unwrap(); + assert_eq!( + p2.members.iter().map(|m| m.node_id).collect::>(), + vec![12, 13] + ); + assert_eq!(p2.start_next_after, Some(13)); + + let p3 = query_all_family_members_paged(tester.deps(), p2.start_next_after, Some(2)) + .unwrap(); + assert_eq!( + p3.members.iter().map(|m| m.node_id).collect::>(), + vec![14] + ); + assert_eq!(p3.start_next_after, Some(14)); + + let p4 = query_all_family_members_paged(tester.deps(), p3.start_next_after, Some(2)) + .unwrap(); + assert!(p4.members.is_empty()); + assert!(p4.start_next_after.is_none()); + } + + #[test] + fn limit_is_clamped_to_max() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + let total = retrieval_limits::FAMILY_MEMBERS_MAX_LIMIT + 5; + tester.add_n_family_members(f.id, total); + + let res = query_all_family_members_paged(tester.deps(), None, Some(u32::MAX)).unwrap(); + assert_eq!( + res.members.len(), + retrieval_limits::FAMILY_MEMBERS_MAX_LIMIT as usize + ); + } + + #[test] + fn default_limit_applied_when_unspecified() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + let total = retrieval_limits::FAMILY_MEMBERS_DEFAULT_LIMIT + 5; + tester.add_n_family_members(f.id, total); + + let res = query_all_family_members_paged(tester.deps(), None, None).unwrap(); + assert_eq!( + res.members.len(), + retrieval_limits::FAMILY_MEMBERS_DEFAULT_LIMIT as usize + ); + } + + #[test] + fn excludes_node_after_it_leaves_family() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + tester.add_to_family(f1.id, 10); + tester.add_to_family(f2.id, 11); + + tester.remove_from_family(10); + + let res = query_all_family_members_paged(tester.deps(), None, None).unwrap(); + let ids: Vec<_> = res.members.iter().map(|m| m.node_id).collect(); + assert_eq!(ids, vec![11]); + } + } + + #[cfg(test)] + mod pending_invitations_for_family_paged { + use super::*; + + #[test] + fn empty_when_family_has_no_pending_invitations() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + let env = tester.env(); + + let res = + query_pending_invitations_for_family_paged(tester.deps(), env, f.id, None, None) + .unwrap(); + assert_eq!(res.family_id, f.id); + assert!(res.invitations.is_empty()); + assert!(res.start_next_after.is_none()); + } + + #[test] + fn empty_for_unknown_family_id() { + let tester = init_contract_tester(); + let env = tester.env(); + + let res = + query_pending_invitations_for_family_paged(tester.deps(), env, 99, None, None) + .unwrap(); + assert_eq!(res.family_id, 99); + assert!(res.invitations.is_empty()); + } + + #[test] + fn returns_only_invitations_from_requested_family() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + tester.invite_to_family(f1.id, 10); + tester.invite_to_family(f1.id, 11); + tester.invite_to_family(f2.id, 20); + + let env = tester.env(); + let res = + query_pending_invitations_for_family_paged(tester.deps(), env, f1.id, None, None) + .unwrap(); + let ids: Vec<_> = res + .invitations + .iter() + .map(|d| d.invitation.node_id) + .collect(); + assert_eq!(ids, vec![10, 11]); + for d in &res.invitations { + assert_eq!(d.invitation.family_id, f1.id); + } + } + + #[test] + fn returned_in_ascending_node_id_order() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + // out-of-order inserts + tester.invite_to_family(f.id, 30); + tester.invite_to_family(f.id, 10); + tester.invite_to_family(f.id, 20); + + let env = tester.env(); + let res = + query_pending_invitations_for_family_paged(tester.deps(), env, f.id, None, None) + .unwrap(); + let ids: Vec<_> = res + .invitations + .iter() + .map(|d| d.invitation.node_id) + .collect(); + assert_eq!(ids, vec![10, 20, 30]); + } + + #[test] + fn flags_expired_against_current_block_time() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + let now = tester.env().block.time.seconds(); + + tester.invite_to_family_with_expiration(f.id, 10, now + 5); + tester.invite_to_family_with_expiration(f.id, 11, now + 1000); + + tester.advance_time_by(60); + let env = tester.env(); + let res = + query_pending_invitations_for_family_paged(tester.deps(), env, f.id, None, None) + .unwrap(); + + assert_eq!(res.invitations[0].invitation.node_id, 10); + assert!(res.invitations[0].expired); + assert_eq!(res.invitations[1].invitation.node_id, 11); + assert!(!res.invitations[1].expired); + } + + #[test] + fn limit_caps_page_size_and_start_after_is_exclusive() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + for n in [10, 11, 12] { + tester.invite_to_family(f.id, n); + } + + let env = tester.env(); + let p1 = query_pending_invitations_for_family_paged( + tester.deps(), + env.clone(), + f.id, + None, + Some(2), + ) + .unwrap(); + let ids: Vec<_> = p1 + .invitations + .iter() + .map(|d| d.invitation.node_id) + .collect(); + assert_eq!(ids, vec![10, 11]); + assert_eq!(p1.start_next_after, Some(11)); + + let p2 = query_pending_invitations_for_family_paged( + tester.deps(), + env, + f.id, + p1.start_next_after, + Some(2), + ) + .unwrap(); + let ids: Vec<_> = p2 + .invitations + .iter() + .map(|d| d.invitation.node_id) + .collect(); + assert_eq!(ids, vec![12]); + } + + #[test] + fn limit_is_clamped_to_max() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + let total = retrieval_limits::PENDING_INVITATIONS_MAX_LIMIT + 5; + for n in 1..=total { + tester.invite_to_family(f.id, n); + } + + let env = tester.env(); + let res = query_pending_invitations_for_family_paged( + tester.deps(), + env, + f.id, + None, + Some(u32::MAX), + ) + .unwrap(); + assert_eq!( + res.invitations.len(), + retrieval_limits::PENDING_INVITATIONS_MAX_LIMIT as usize + ); + } + + #[test] + fn excludes_invitation_after_it_is_revoked() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + tester.invite_to_family(f.id, 10); + tester.invite_to_family(f.id, 11); + + // accepting moves the invitation out of the pending map + tester.accept_invitation(f.id, 10); + + let env = tester.env(); + let res = + query_pending_invitations_for_family_paged(tester.deps(), env, f.id, None, None) + .unwrap(); + let ids: Vec<_> = res + .invitations + .iter() + .map(|d| d.invitation.node_id) + .collect(); + assert_eq!(ids, vec![11]); + } + } + + #[cfg(test)] + mod all_pending_invitations_paged { + use super::*; + + #[test] + fn empty_when_no_pending_invitations() { + let tester = init_contract_tester(); + let env = tester.env(); + + let res = query_all_pending_invitations_paged(tester.deps(), env, None, None).unwrap(); + assert!(res.invitations.is_empty()); + assert!(res.start_next_after.is_none()); + } + + #[test] + fn returns_invitations_across_all_families() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + tester.invite_to_family(f1.id, 10); + tester.invite_to_family(f1.id, 20); + tester.invite_to_family(f2.id, 5); + + let env = tester.env(); + let res = query_all_pending_invitations_paged(tester.deps(), env, None, None).unwrap(); + + let pairs: Vec<_> = res + .invitations + .iter() + .map(|d| (d.invitation.family_id, d.invitation.node_id)) + .collect(); + // ordered by (family_id asc, node_id asc) + assert_eq!(pairs, vec![(f1.id, 10), (f1.id, 20), (f2.id, 5)]); + assert_eq!(res.start_next_after, Some((f2.id, 5))); + } + + #[test] + fn flags_expired_against_current_block_time() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + let now = tester.env().block.time.seconds(); + tester.invite_to_family_with_expiration(f.id, 10, now + 5); + tester.invite_to_family_with_expiration(f.id, 11, now + 1000); + + tester.advance_time_by(60); + let env = tester.env(); + let res = query_all_pending_invitations_paged(tester.deps(), env, None, None).unwrap(); + + let by_node: std::collections::HashMap<_, _> = res + .invitations + .iter() + .map(|d| (d.invitation.node_id, d.expired)) + .collect(); + assert!(by_node[&10]); + assert!(!by_node[&11]); + } + + #[test] + fn paginates_with_composite_cursor() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + tester.invite_to_family(f1.id, 10); + tester.invite_to_family(f1.id, 20); + tester.invite_to_family(f2.id, 5); + tester.invite_to_family(f2.id, 15); + + let env = tester.env(); + let p1 = query_all_pending_invitations_paged(tester.deps(), env.clone(), None, Some(2)) + .unwrap(); + let pairs: Vec<_> = p1 + .invitations + .iter() + .map(|d| (d.invitation.family_id, d.invitation.node_id)) + .collect(); + assert_eq!(pairs, vec![(f1.id, 10), (f1.id, 20)]); + assert_eq!(p1.start_next_after, Some((f1.id, 20))); + + let p2 = query_all_pending_invitations_paged( + tester.deps(), + env.clone(), + p1.start_next_after, + Some(2), + ) + .unwrap(); + let pairs: Vec<_> = p2 + .invitations + .iter() + .map(|d| (d.invitation.family_id, d.invitation.node_id)) + .collect(); + assert_eq!(pairs, vec![(f2.id, 5), (f2.id, 15)]); + + let p3 = query_all_pending_invitations_paged( + tester.deps(), + env, + p2.start_next_after, + Some(2), + ) + .unwrap(); + assert!(p3.invitations.is_empty()); + assert!(p3.start_next_after.is_none()); + } + + #[test] + fn limit_is_clamped_to_max() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + let total = retrieval_limits::PENDING_INVITATIONS_MAX_LIMIT + 5; + for n in 1..=total { + tester.invite_to_family(f.id, n); + } + + let env = tester.env(); + let res = query_all_pending_invitations_paged(tester.deps(), env, None, Some(u32::MAX)) + .unwrap(); + assert_eq!( + res.invitations.len(), + retrieval_limits::PENDING_INVITATIONS_MAX_LIMIT as usize + ); + } + } + + #[cfg(test)] + mod past_invitations_for_family_paged { + use super::*; + use nym_node_families_contract_common::FamilyInvitationStatus; + + #[test] + fn empty_when_family_has_no_archive_entries() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + + let res = + query_past_invitations_for_family_paged(tester.deps(), f.id, None, None).unwrap(); + assert_eq!(res.family_id, f.id); + assert!(res.invitations.is_empty()); + assert!(res.start_next_after.is_none()); + } + + #[test] + fn empty_for_unknown_family_id() { + let tester = init_contract_tester(); + + let res = + query_past_invitations_for_family_paged(tester.deps(), 99, None, None).unwrap(); + assert_eq!(res.family_id, 99); + assert!(res.invitations.is_empty()); + } + + #[test] + fn returns_only_archived_invitations_from_requested_family() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + // produce one Accepted in each family, plus one Rejected in f1 + tester.add_to_family(f1.id, 10); + tester.invite_to_family(f1.id, 11); + tester.reject_invitation(f1.id, 11); + tester.add_to_family(f2.id, 20); + + let res = + query_past_invitations_for_family_paged(tester.deps(), f1.id, None, None).unwrap(); + assert_eq!(res.invitations.len(), 2); + for entry in &res.invitations { + assert_eq!(entry.invitation.family_id, f1.id); + } + } + + #[test] + fn covers_all_terminal_statuses() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + + // Accepted + tester.add_to_family(f.id, 10); + // Rejected + tester.invite_to_family(f.id, 11); + tester.reject_invitation(f.id, 11); + // Revoked + tester.invite_to_family(f.id, 12); + tester.revoke_invitation(f.id, 12); + + let res = + query_past_invitations_for_family_paged(tester.deps(), f.id, None, None).unwrap(); + let by_node: std::collections::HashMap<_, _> = res + .invitations + .iter() + .map(|p| (p.invitation.node_id, p.status.clone())) + .collect(); + assert!(matches!( + by_node[&10], + FamilyInvitationStatus::Accepted { .. } + )); + assert!(matches!( + by_node[&11], + FamilyInvitationStatus::Rejected { .. } + )); + assert!(matches!( + by_node[&12], + FamilyInvitationStatus::Revoked { .. } + )); + } + + #[test] + fn ordered_by_node_id_then_counter() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + + // node 42 joins and leaves twice — produces two Accepted entries with counters 0 and 1 + for _ in 0..2 { + tester.add_to_family(f.id, 42); + tester.remove_from_family(42); + } + // node 7 has one Accepted entry + tester.add_to_family(f.id, 7); + + let res = + query_past_invitations_for_family_paged(tester.deps(), f.id, None, None).unwrap(); + let pairs: Vec<_> = res + .invitations + .iter() + .map(|p| p.invitation.node_id) + .collect(); + // 7 comes before 42; 42's two entries come together (both with counter 0 and 1) + assert_eq!(pairs, vec![7, 42, 42]); + } + + #[test] + fn paginates_with_node_counter_cursor() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + for n in [10, 11, 12] { + tester.add_to_family(f.id, n); + } + + let p1 = query_past_invitations_for_family_paged(tester.deps(), f.id, None, Some(2)) + .unwrap(); + let ids: Vec<_> = p1 + .invitations + .iter() + .map(|p| p.invitation.node_id) + .collect(); + assert_eq!(ids, vec![10, 11]); + assert_eq!(p1.start_next_after, Some((11, 0))); + + let p2 = query_past_invitations_for_family_paged( + tester.deps(), + f.id, + p1.start_next_after, + Some(2), + ) + .unwrap(); + let ids: Vec<_> = p2 + .invitations + .iter() + .map(|p| p.invitation.node_id) + .collect(); + assert_eq!(ids, vec![12]); + assert_eq!(p2.start_next_after, Some((12, 0))); + + let p3 = query_past_invitations_for_family_paged( + tester.deps(), + f.id, + p2.start_next_after, + Some(2), + ) + .unwrap(); + assert!(p3.invitations.is_empty()); + assert!(p3.start_next_after.is_none()); + } + + #[test] + fn limit_is_clamped_to_max() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + let total = retrieval_limits::PAST_INVITATIONS_MAX_LIMIT + 5; + tester.add_n_family_members(f.id, total); + + let res = + query_past_invitations_for_family_paged(tester.deps(), f.id, None, Some(u32::MAX)) + .unwrap(); + assert_eq!( + res.invitations.len(), + retrieval_limits::PAST_INVITATIONS_MAX_LIMIT as usize + ); + } + + #[test] + fn start_after_none_does_not_leak_earlier_families() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + tester.add_to_family(f1.id, 10); + tester.add_to_family(f1.id, 11); + + let res = + query_past_invitations_for_family_paged(tester.deps(), f2.id, None, None).unwrap(); + + assert_eq!(res.family_id, f2.id); + assert!( + res.invitations.is_empty(), + "expected no entries for f2 but got: {:?}", + res.invitations + .iter() + .map(|e| (e.invitation.family_id, e.invitation.node_id)) + .collect::>() + ); + assert!(res.start_next_after.is_none()); + } + } + + #[cfg(test)] + mod all_past_invitations_paged { + use super::*; + + #[test] + fn empty_when_no_archive_entries() { + let tester = init_contract_tester(); + + let res = query_all_past_invitations_paged(tester.deps(), None, None).unwrap(); + assert!(res.invitations.is_empty()); + assert!(res.start_next_after.is_none()); + } + + #[test] + fn returns_archives_across_all_families() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + tester.add_to_family(f1.id, 10); + tester.add_to_family(f1.id, 20); + tester.add_to_family(f2.id, 5); + + let res = query_all_past_invitations_paged(tester.deps(), None, None).unwrap(); + let pairs: Vec<_> = res + .invitations + .iter() + .map(|p| (p.invitation.family_id, p.invitation.node_id)) + .collect(); + assert_eq!(pairs, vec![(f1.id, 10), (f1.id, 20), (f2.id, 5)]); + assert_eq!(res.start_next_after, Some(((f2.id, 5), 0))); + } + + #[test] + fn paginates_with_composite_cursor() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + tester.add_to_family(f1.id, 10); + tester.add_to_family(f1.id, 20); + tester.add_to_family(f2.id, 5); + tester.add_to_family(f2.id, 15); + + let p1 = query_all_past_invitations_paged(tester.deps(), None, Some(2)).unwrap(); + let pairs: Vec<_> = p1 + .invitations + .iter() + .map(|p| (p.invitation.family_id, p.invitation.node_id)) + .collect(); + assert_eq!(pairs, vec![(f1.id, 10), (f1.id, 20)]); + assert_eq!(p1.start_next_after, Some(((f1.id, 20), 0))); + + let p2 = query_all_past_invitations_paged(tester.deps(), p1.start_next_after, Some(2)) + .unwrap(); + let pairs: Vec<_> = p2 + .invitations + .iter() + .map(|p| (p.invitation.family_id, p.invitation.node_id)) + .collect(); + assert_eq!(pairs, vec![(f2.id, 5), (f2.id, 15)]); + + let p3 = query_all_past_invitations_paged(tester.deps(), p2.start_next_after, Some(2)) + .unwrap(); + assert!(p3.invitations.is_empty()); + assert!(p3.start_next_after.is_none()); + } + + #[test] + fn per_pair_counter_disambiguates_repeat_archive_entries() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + // node 42 joins and leaves twice — two Accepted entries for (f, 42) with counters 0 and 1 + for _ in 0..2 { + tester.add_to_family(f.id, 42); + tester.remove_from_family(42); + } + + let res = query_all_past_invitations_paged(tester.deps(), None, None).unwrap(); + assert_eq!(res.invitations.len(), 2); + assert_eq!(res.start_next_after, Some(((f.id, 42), 1))); + } + + #[test] + fn limit_is_clamped_to_max() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + let total = retrieval_limits::PAST_INVITATIONS_MAX_LIMIT + 5; + tester.add_n_family_members(f.id, total); + + let res = + query_all_past_invitations_paged(tester.deps(), None, Some(u32::MAX)).unwrap(); + assert_eq!( + res.invitations.len(), + retrieval_limits::PAST_INVITATIONS_MAX_LIMIT as usize + ); + } + } + + #[cfg(test)] + mod pending_invitations_for_node_paged { + use super::*; + + #[test] + fn empty_when_node_has_no_pending_invitations() { + let tester = init_contract_tester(); + let env = tester.env(); + + let res = query_pending_invitations_for_node_paged(tester.deps(), env, 42, None, None) + .unwrap(); + assert_eq!(res.node_id, 42); + assert!(res.invitations.is_empty()); + assert!(res.start_next_after.is_none()); + } + + #[test] + fn returns_only_invitations_for_requested_node() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + tester.invite_to_family(f1.id, 10); + tester.invite_to_family(f1.id, 11); + tester.invite_to_family(f2.id, 10); + + let env = tester.env(); + let res = query_pending_invitations_for_node_paged(tester.deps(), env, 10, None, None) + .unwrap(); + let pairs: Vec<_> = res + .invitations + .iter() + .map(|d| (d.invitation.family_id, d.invitation.node_id)) + .collect(); + assert_eq!(pairs, vec![(f1.id, 10), (f2.id, 10)]); + } + + #[test] + fn ordered_by_ascending_family_id() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + let f3 = tester.add_dummy_family(); + // out-of-order inserts + tester.invite_to_family(f3.id, 7); + tester.invite_to_family(f1.id, 7); + tester.invite_to_family(f2.id, 7); + + let env = tester.env(); + let res = query_pending_invitations_for_node_paged(tester.deps(), env, 7, None, None) + .unwrap(); + let ids: Vec<_> = res + .invitations + .iter() + .map(|d| d.invitation.family_id) + .collect(); + assert_eq!(ids, vec![f1.id, f2.id, f3.id]); + } + + #[test] + fn paginates_with_family_id_cursor() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + let f3 = tester.add_dummy_family(); + tester.invite_to_family(f1.id, 7); + tester.invite_to_family(f2.id, 7); + tester.invite_to_family(f3.id, 7); + + let env = tester.env(); + let p1 = query_pending_invitations_for_node_paged( + tester.deps(), + env.clone(), + 7, + None, + Some(2), + ) + .unwrap(); + let ids: Vec<_> = p1 + .invitations + .iter() + .map(|d| d.invitation.family_id) + .collect(); + assert_eq!(ids, vec![f1.id, f2.id]); + assert_eq!(p1.start_next_after, Some(f2.id)); + + let p2 = query_pending_invitations_for_node_paged( + tester.deps(), + env.clone(), + 7, + p1.start_next_after, + Some(2), + ) + .unwrap(); + let ids: Vec<_> = p2 + .invitations + .iter() + .map(|d| d.invitation.family_id) + .collect(); + assert_eq!(ids, vec![f3.id]); + assert_eq!(p2.start_next_after, Some(f3.id)); + + let p3 = query_pending_invitations_for_node_paged( + tester.deps(), + env, + 7, + p2.start_next_after, + Some(2), + ) + .unwrap(); + assert!(p3.invitations.is_empty()); + assert!(p3.start_next_after.is_none()); + } + + #[test] + fn flags_expired_against_current_block_time() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + let now = tester.env().block.time.seconds(); + tester.invite_to_family_with_expiration(f1.id, 7, now + 5); + tester.invite_to_family_with_expiration(f2.id, 7, now + 1000); + + tester.advance_time_by(60); + let env = tester.env(); + let res = query_pending_invitations_for_node_paged(tester.deps(), env, 7, None, None) + .unwrap(); + let by_family: std::collections::HashMap<_, _> = res + .invitations + .iter() + .map(|d| (d.invitation.family_id, d.expired)) + .collect(); + assert!(by_family[&f1.id]); + assert!(!by_family[&f2.id]); + } + + #[test] + fn limit_is_clamped_to_max() { + let mut tester = init_contract_tester(); + let total = retrieval_limits::PENDING_INVITATIONS_MAX_LIMIT + 5; + for _ in 0..total { + let f = tester.add_dummy_family(); + tester.invite_to_family(f.id, 7); + } + + let env = tester.env(); + let res = query_pending_invitations_for_node_paged( + tester.deps(), + env, + 7, + None, + Some(u32::MAX), + ) + .unwrap(); + assert_eq!( + res.invitations.len(), + retrieval_limits::PENDING_INVITATIONS_MAX_LIMIT as usize + ); + } + } + + #[cfg(test)] + mod past_invitations_for_node_paged { + use super::*; + use nym_node_families_contract_common::FamilyInvitationStatus; + + #[test] + fn empty_when_node_has_no_archive_entries() { + let tester = init_contract_tester(); + + let res = query_past_invitations_for_node_paged(tester.deps(), 42, None, None).unwrap(); + assert_eq!(res.node_id, 42); + assert!(res.invitations.is_empty()); + assert!(res.start_next_after.is_none()); + } + + #[test] + fn returns_only_archives_for_requested_node() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + tester.add_to_family(f1.id, 7); + tester.add_to_family(f1.id, 8); + tester.add_to_family(f2.id, 7); + + let res = query_past_invitations_for_node_paged(tester.deps(), 7, None, None).unwrap(); + assert_eq!(res.invitations.len(), 2); + for entry in &res.invitations { + assert_eq!(entry.invitation.node_id, 7); + } + } + + #[test] + fn covers_all_terminal_statuses() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + let f3 = tester.add_dummy_family(); + // Accepted in f1 + tester.add_to_family(f1.id, 7); + // Rejected in f2 + tester.invite_to_family(f2.id, 7); + tester.reject_invitation(f2.id, 7); + // Revoked in f3 + tester.invite_to_family(f3.id, 7); + tester.revoke_invitation(f3.id, 7); + + let res = query_past_invitations_for_node_paged(tester.deps(), 7, None, None).unwrap(); + let by_family: std::collections::HashMap<_, _> = res + .invitations + .iter() + .map(|p| (p.invitation.family_id, p.status.clone())) + .collect(); + assert!(matches!( + by_family[&f1.id], + FamilyInvitationStatus::Accepted { .. } + )); + assert!(matches!( + by_family[&f2.id], + FamilyInvitationStatus::Rejected { .. } + )); + assert!(matches!( + by_family[&f3.id], + FamilyInvitationStatus::Revoked { .. } + )); + } + + #[test] + fn ordered_by_family_id_then_counter() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + // node 7 joins and leaves f1 twice — counters 0 and 1 in f1 + for _ in 0..2 { + tester.add_to_family(f1.id, 7); + tester.remove_from_family(7); + } + // one Accepted in f2 + tester.add_to_family(f2.id, 7); + + let res = query_past_invitations_for_node_paged(tester.deps(), 7, None, None).unwrap(); + let pairs: Vec<_> = res + .invitations + .iter() + .map(|p| p.invitation.family_id) + .collect(); + assert_eq!(pairs, vec![f1.id, f1.id, f2.id]); + } + + #[test] + fn paginates_with_family_counter_cursor() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + let f3 = tester.add_dummy_family(); + tester.add_to_family(f1.id, 7); + tester.add_to_family(f2.id, 7); + tester.add_to_family(f3.id, 7); + + let p1 = + query_past_invitations_for_node_paged(tester.deps(), 7, None, Some(2)).unwrap(); + let ids: Vec<_> = p1 + .invitations + .iter() + .map(|p| p.invitation.family_id) + .collect(); + assert_eq!(ids, vec![f1.id, f2.id]); + assert_eq!(p1.start_next_after, Some((f2.id, 0))); + + let p2 = query_past_invitations_for_node_paged( + tester.deps(), + 7, + p1.start_next_after, + Some(2), + ) + .unwrap(); + let ids: Vec<_> = p2 + .invitations + .iter() + .map(|p| p.invitation.family_id) + .collect(); + assert_eq!(ids, vec![f3.id]); + assert_eq!(p2.start_next_after, Some((f3.id, 0))); + + let p3 = query_past_invitations_for_node_paged( + tester.deps(), + 7, + p2.start_next_after, + Some(2), + ) + .unwrap(); + assert!(p3.invitations.is_empty()); + assert!(p3.start_next_after.is_none()); + } + + #[test] + fn limit_is_clamped_to_max() { + let mut tester = init_contract_tester(); + let total = retrieval_limits::PAST_INVITATIONS_MAX_LIMIT + 5; + for _ in 0..total { + let f = tester.add_dummy_family(); + tester.add_to_family(f.id, 7); + tester.remove_from_family(7); + } + + let res = query_past_invitations_for_node_paged(tester.deps(), 7, None, Some(u32::MAX)) + .unwrap(); + assert_eq!( + res.invitations.len(), + retrieval_limits::PAST_INVITATIONS_MAX_LIMIT as usize + ); + } + } + + #[cfg(test)] + mod past_members_for_family_paged { + use super::*; + + #[test] + fn empty_when_no_archive_entries() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + + let res = query_past_members_for_family_paged(tester.deps(), f.id, None, None).unwrap(); + assert_eq!(res.family_id, f.id); + assert!(res.members.is_empty()); + assert!(res.start_next_after.is_none()); + } + + #[test] + fn empty_for_unknown_family_id() { + let tester = init_contract_tester(); + + let res = query_past_members_for_family_paged(tester.deps(), 99, None, None).unwrap(); + assert_eq!(res.family_id, 99); + assert!(res.members.is_empty()); + assert!(res.start_next_after.is_none()); + } + + #[test] + fn returns_only_archives_from_requested_family() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + tester.add_to_family(f1.id, 10); + tester.remove_from_family(10); + tester.add_to_family(f2.id, 20); + tester.remove_from_family(20); + + let res = + query_past_members_for_family_paged(tester.deps(), f1.id, None, None).unwrap(); + assert_eq!(res.members.len(), 1); + assert_eq!(res.members[0].family_id, f1.id); + assert_eq!(res.members[0].node_id, 10); + } + + #[test] + fn record_carries_removed_at_timestamp() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + tester.add_to_family(f.id, 42); + let removed_at = tester.env().block.time.seconds(); + tester.remove_from_family(42); + + let res = query_past_members_for_family_paged(tester.deps(), f.id, None, None).unwrap(); + let entry = res.members.into_iter().next().unwrap(); + assert_eq!(entry.family_id, f.id); + assert_eq!(entry.node_id, 42); + assert_eq!(entry.removed_at, removed_at); + } + + #[test] + fn ordered_by_node_id_then_counter() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + // node 42 joins/leaves twice — counters 0 and 1 + for _ in 0..2 { + tester.add_to_family(f.id, 42); + tester.remove_from_family(42); + } + // node 7 once + tester.add_to_family(f.id, 7); + tester.remove_from_family(7); + + let res = query_past_members_for_family_paged(tester.deps(), f.id, None, None).unwrap(); + let ids: Vec<_> = res.members.iter().map(|m| m.node_id).collect(); + // 7 comes before 42; 42 appears twice + assert_eq!(ids, vec![7, 42, 42]); + } + + #[test] + fn paginates_with_node_counter_cursor() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + for n in [10, 11, 12] { + tester.add_to_family(f.id, n); + tester.remove_from_family(n); + } + + let p1 = + query_past_members_for_family_paged(tester.deps(), f.id, None, Some(2)).unwrap(); + let ids: Vec<_> = p1.members.iter().map(|m| m.node_id).collect(); + assert_eq!(ids, vec![10, 11]); + assert_eq!(p1.start_next_after, Some((11, 0))); + + let p2 = query_past_members_for_family_paged( + tester.deps(), + f.id, + p1.start_next_after, + Some(2), + ) + .unwrap(); + let ids: Vec<_> = p2.members.iter().map(|m| m.node_id).collect(); + assert_eq!(ids, vec![12]); + assert_eq!(p2.start_next_after, Some((12, 0))); + + let p3 = query_past_members_for_family_paged( + tester.deps(), + f.id, + p2.start_next_after, + Some(2), + ) + .unwrap(); + assert!(p3.members.is_empty()); + assert!(p3.start_next_after.is_none()); + } + + #[test] + fn limit_is_clamped_to_max() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + let total = retrieval_limits::PAST_MEMBERS_MAX_LIMIT + 5; + for n in 1..=total { + tester.add_to_family(f.id, n); + tester.remove_from_family(n); + } + + let res = + query_past_members_for_family_paged(tester.deps(), f.id, None, Some(u32::MAX)) + .unwrap(); + assert_eq!( + res.members.len(), + retrieval_limits::PAST_MEMBERS_MAX_LIMIT as usize + ); + } + + #[test] + fn start_after_none_does_not_leak_earlier_families() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + tester.add_to_family(f1.id, 10); + tester.add_to_family(f1.id, 11); + tester.remove_from_family(10); + tester.remove_from_family(11); + + let res = + query_past_members_for_family_paged(tester.deps(), f2.id, None, None).unwrap(); + + assert_eq!(res.family_id, f2.id); + assert!( + res.members.is_empty(), + "expected no entries for f2 but got: {:?}", + res.members + .iter() + .map(|m| (m.family_id, m.node_id)) + .collect::>() + ); + assert!(res.start_next_after.is_none()); + } + } + + #[cfg(test)] + mod past_members_for_node_paged { + use super::*; + + #[test] + fn empty_when_node_has_no_archive_entries() { + let tester = init_contract_tester(); + + let res = query_past_members_for_node_paged(tester.deps(), 42, None, None).unwrap(); + assert_eq!(res.node_id, 42); + assert!(res.members.is_empty()); + assert!(res.start_next_after.is_none()); + } + + #[test] + fn returns_only_archives_for_requested_node() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + tester.add_to_family(f1.id, 7); + tester.add_to_family(f1.id, 8); + tester.add_to_family(f2.id, 7); + tester.remove_from_family(7); + tester.remove_from_family(8); + + let res = query_past_members_for_node_paged(tester.deps(), 7, None, None).unwrap(); + assert_eq!(res.members.len(), 1); + for entry in &res.members { + assert_eq!(entry.node_id, 7); + } + } + + #[test] + fn record_carries_removed_at_timestamp() { + let mut tester = init_contract_tester(); + let f = tester.add_dummy_family(); + tester.add_to_family(f.id, 42); + let removed_at = tester.env().block.time.seconds(); + tester.remove_from_family(42); + + let res = query_past_members_for_node_paged(tester.deps(), 42, None, None).unwrap(); + let entry = res.members.into_iter().next().unwrap(); + assert_eq!(entry.family_id, f.id); + assert_eq!(entry.node_id, 42); + assert_eq!(entry.removed_at, removed_at); + } + + #[test] + fn ordered_by_family_id_then_counter() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + // node 7 joins/leaves f1 twice — counters 0 and 1 in f1 + for _ in 0..2 { + tester.add_to_family(f1.id, 7); + tester.remove_from_family(7); + } + // one record in f2 + tester.add_to_family(f2.id, 7); + tester.remove_from_family(7); + + let res = query_past_members_for_node_paged(tester.deps(), 7, None, None).unwrap(); + let ids: Vec<_> = res.members.iter().map(|m| m.family_id).collect(); + assert_eq!(ids, vec![f1.id, f1.id, f2.id]); + } + + #[test] + fn paginates_with_family_counter_cursor() { + let mut tester = init_contract_tester(); + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + let f3 = tester.add_dummy_family(); + tester.add_to_family(f1.id, 7); + tester.remove_from_family(7); + tester.add_to_family(f2.id, 7); + tester.remove_from_family(7); + tester.add_to_family(f3.id, 7); + tester.remove_from_family(7); + + let p1 = query_past_members_for_node_paged(tester.deps(), 7, None, Some(2)).unwrap(); + let ids: Vec<_> = p1.members.iter().map(|m| m.family_id).collect(); + assert_eq!(ids, vec![f1.id, f2.id]); + assert_eq!(p1.start_next_after, Some((f2.id, 0))); + + let p2 = + query_past_members_for_node_paged(tester.deps(), 7, p1.start_next_after, Some(2)) + .unwrap(); + let ids: Vec<_> = p2.members.iter().map(|m| m.family_id).collect(); + assert_eq!(ids, vec![f3.id]); + assert_eq!(p2.start_next_after, Some((f3.id, 0))); + + let p3 = + query_past_members_for_node_paged(tester.deps(), 7, p2.start_next_after, Some(2)) + .unwrap(); + assert!(p3.members.is_empty()); + assert!(p3.start_next_after.is_none()); + } + + #[test] + fn limit_is_clamped_to_max() { + let mut tester = init_contract_tester(); + let total = retrieval_limits::PAST_MEMBERS_MAX_LIMIT + 5; + for _ in 0..total { + let f = tester.add_dummy_family(); + tester.add_to_family(f.id, 7); + tester.remove_from_family(7); + } + + let res = + query_past_members_for_node_paged(tester.deps(), 7, None, Some(u32::MAX)).unwrap(); + assert_eq!( + res.members.len(), + retrieval_limits::PAST_MEMBERS_MAX_LIMIT as usize + ); + } + } +} diff --git a/contracts/node-families/src/queued_migrations.rs b/contracts/node-families/src/queued_migrations.rs new file mode 100644 index 0000000000..bdc05451cb --- /dev/null +++ b/contracts/node-families/src/queued_migrations.rs @@ -0,0 +1,2 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only diff --git a/contracts/node-families/src/storage/mod.rs b/contracts/node-families/src/storage/mod.rs new file mode 100644 index 0000000000..62ae93c82d --- /dev/null +++ b/contracts/node-families/src/storage/mod.rs @@ -0,0 +1,1386 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +// storage will be used in subsequent PRs/tickets +#![allow(dead_code)] + +use crate::storage::storage_indexes::{ + FamilyMembersIndex, NodeFamiliesIndex, NodeFamilyInvitationIndex, PastFamilyInvitationsIndex, + PastFamilyMembersIndex, +}; +use cosmwasm_std::{Addr, Coin, DepsMut, Env, Order, StdResult, Storage}; +use cw_controllers::Admin; +use cw_storage_plus::{IndexedMap, Item, Map}; +use nym_mixnet_contract_common::NodeId; +use nym_node_families_contract_common::constants::storage_keys; +use nym_node_families_contract_common::{ + Config, FamilyInvitation, FamilyInvitationStatus, FamilyMembership, NodeFamiliesContractError, + NodeFamily, NodeFamilyId, PastFamilyInvitation, PastFamilyMember, +}; + +pub(crate) mod retrieval_limits; +mod storage_indexes; + +/// Composite primary key for the invitation / past-member maps: +/// `(family id, node id)`. Only one pending invitation can exist for a given +/// `(family, node)` pair at a time. +pub(crate) type FamilyMember = (NodeFamilyId, NodeId); + +/// Container for every storage handle used by the contract. +/// +/// Constructed once via [`NodeFamiliesStorage::new`] and accessed through a +/// `lazy_static`-style singleton in the entry point modules. +pub struct NodeFamiliesStorage<'a> { + /// Admin of the contract; gates privileged operations. + pub(crate) contract_admin: Admin, + + /// Runtime configuration (fees, length limits) persisted at instantiation + /// and consulted by transaction handlers. + pub(crate) config: Item, + + /// Address of the mixnet contract; used to verify a node id refers to a + /// real, registered node. + pub(crate) mixnet_contract_address: Item, + + /// Monotonically increasing id assigned to every newly created family. + /// Ids start at `1` (see [`NodeFamiliesStorage::next_family_id`]); `0` is + /// reserved as a "no family" sentinel. + pub(crate) node_family_id_counter: Item, + + /// All existing families, keyed by id, with unique secondary indexes on + /// `owner` (one-family-per-owner-address) and on `normalised_name` + /// (family names are globally unique under their normalised form, so + /// `"MyFamily"` and `"myfamily"` collide while the original `name` field + /// preserves the user-submitted formatting). + pub(crate) families: IndexedMap>, + + /// Current family membership records, keyed by [`NodeId`]. A node + /// belongs to at most one family at a time, so the PK is the node id. + /// A `family` multi-index enables paginated listing of all nodes + /// belonging to a given family. + pub(crate) family_members: IndexedMap>, + + /// Currently outstanding family invitations, indexed by both family id + /// and node id (a single node can simultaneously hold invitations from + /// multiple families). + pub(crate) pending_family_invitations: + IndexedMap>, + + // ##### historical data ##### + // + // The two maps below archive terminal events. The trailing `u64` in the + // composite key is a per-`(family, node)` counter — a node can be removed + // from (or rejected by) the same family more than once, and we cannot use + // the block timestamp to disambiguate because multiple txs may share a + // block. + /// Archive of family memberships that have ended (kicked, left, or family + /// disbanded). Key: `((family_id, node_id), counter)`. + pub(crate) past_family_members: + IndexedMap<(FamilyMember, u64), PastFamilyMember, PastFamilyMembersIndex<'a>>, + + /// Per-`(family, node)` counter for the [`Self::past_family_members`] + /// archive — yields the next free `counter` slot when archiving a new + /// past-membership record. Stored explicitly (rather than derived via + /// range scan) to keep archival writes O(1). + pub(crate) past_family_member_counter: Map, + + /// Archive of invitations that reached a terminal `Accepted` / `Rejected` + /// / `Revoked` state. Timed-out invitations are **not** archived here — + /// there is no background process that sweeps expired entries out of + /// [`Self::pending_family_invitations`]. + pub(crate) past_family_invitations: + IndexedMap<(FamilyMember, u64), PastFamilyInvitation, PastFamilyInvitationsIndex<'a>>, + + /// Per-`(family, node)` counter for the [`Self::past_family_invitations`] + /// archive — yields the next free `counter` slot when archiving a + /// terminal invitation event. + pub(crate) past_family_invitation_counter: Map, +} + +impl NodeFamiliesStorage<'_> { + #[allow(clippy::new_without_default)] + pub fn new() -> Self { + NodeFamiliesStorage { + contract_admin: Admin::new(storage_keys::CONTRACT_ADMIN), + config: Item::new(storage_keys::CONFIG), + mixnet_contract_address: Item::new(storage_keys::MIXNET_CONTRACT_ADDRESS), + node_family_id_counter: Item::new(storage_keys::NODE_FAMILY_ID_COUNTER), + families: IndexedMap::new(storage_keys::FAMILIES_NAMESPACE, NodeFamiliesIndex::new()), + family_members: IndexedMap::new( + storage_keys::NODE_FAMILY_MEMBERS, + FamilyMembersIndex::new(), + ), + pending_family_invitations: IndexedMap::new( + storage_keys::INVITATIONS_NAMESPACE, + NodeFamilyInvitationIndex::new(), + ), + past_family_members: IndexedMap::new( + storage_keys::PAST_FAMILY_MEMBER_NAMESPACE, + PastFamilyMembersIndex::new(), + ), + past_family_member_counter: Map::new( + storage_keys::PAST_FAMILY_MEMBER_COUNTER_NAMESPACE, + ), + past_family_invitations: IndexedMap::new( + storage_keys::PAST_INVITATIONS_NAMESPACE, + PastFamilyInvitationsIndex::new(), + ), + past_family_invitation_counter: Map::new( + storage_keys::PAST_INVITATIONS_COUNTER_NAMESPACE, + ), + } + } + + /// One-time storage initialisation called from the contract's `instantiate` + /// entry point. Persists the runtime [`Config`] and mixnet contract + /// address, and sets `sender` as the contract admin. + pub(crate) fn initialise( + &self, + deps: DepsMut, + sender: Addr, + mixnet_contract_address: Addr, + config: Config, + ) -> Result<(), NodeFamiliesContractError> { + self.config.save(deps.storage, &config)?; + self.mixnet_contract_address + .save(deps.storage, &mixnet_contract_address)?; + + self.contract_admin.set(deps, Some(sender))?; + Ok(()) + } + + /// Allocate the next [`NodeFamilyId`] and persist the bumped counter. + /// + /// Ids are issued starting from `1`; `0` is reserved as a "no family" + /// sentinel value and must never be assigned to a real family. + pub(crate) fn next_family_id( + &self, + store: &mut dyn Storage, + ) -> Result { + let next_id = self + .node_family_id_counter + .may_load(store)? + .unwrap_or_default() + + 1; + self.node_family_id_counter.save(store, &next_id)?; + Ok(next_id) + } + + /// Allocate the next free archive slot for the [`Self::past_family_invitations`] + /// map under the given `(family, node)` key, and persist the bumped counter. + /// + /// Slots are issued starting from `0` and increase by 1 on every call. + pub(crate) fn next_past_invitation_counter( + &self, + store: &mut dyn Storage, + key: FamilyMember, + ) -> Result { + let counter = self + .past_family_invitation_counter + .may_load(store, key)? + .unwrap_or_default(); + self.past_family_invitation_counter + .save(store, key, &(counter + 1))?; + Ok(counter) + } + + /// Allocate the next free archive slot for the [`Self::past_family_members`] + /// map under the given `(family, node)` key, and persist the bumped counter. + /// + /// Slots are issued starting from `0` and increase by 1 on every call. + pub(crate) fn next_past_member_counter( + &self, + store: &mut dyn Storage, + key: FamilyMember, + ) -> Result { + let counter = self + .past_family_member_counter + .may_load(store, key)? + .unwrap_or_default(); + self.past_family_member_counter + .save(store, key, &(counter + 1))?; + Ok(counter) + } + + /// Persist a brand-new family in storage. + /// + /// Assigns a fresh [`NodeFamilyId`], stamps `created_at` from `env` + /// (unix seconds) and starts the membership counter at `0` — the owner + /// is **not** counted as a member. + /// + /// The caller (a transaction handler) is responsible for: + /// - validating `name`, `description` and `owner`; + /// - computing `normalised_name` from `name` (e.g. via + /// [`crate::helpers::normalise_family_name`]) — the unique-name index + /// keys on this field, so it is what enforces global uniqueness; + /// - ensuring `owner` does not already own a family **and** is not + /// currently a member of one. + /// + /// Returns the freshly persisted [`NodeFamily`]. The underlying + /// `IndexedMap` enforces the one-family-per-owner and unique-name + /// invariants via unique indexes on `owner` and `normalised_name` as a + /// defence-in-depth check, so this call will fail if either is already + /// taken — but the caller must not rely on it for the membership check. + #[allow(clippy::too_many_arguments)] + pub(crate) fn register_new_family( + &self, + store: &mut dyn Storage, + env: &Env, + fee: Coin, + owner: Addr, + name: String, + normalised_name: String, + description: String, + ) -> Result { + let id = self.next_family_id(store)?; + let family = NodeFamily { + id, + name, + normalised_name, + description, + owner, + paid_fee: fee, + members: 0, + created_at: env.block.time.seconds(), + }; + self.families.save(store, id, &family)?; + Ok(family) + } + + /// Persist a new pending invitation for `node_id` to join `family_id`. + /// + /// `expires_at` is taken as a unix-seconds absolute deadline (the caller + /// is expected to compute it from the current block time plus the + /// configured invitation duration). + /// + /// The caller (a transaction handler) is responsible for: + /// - verifying that `family_id` exists and that the transaction sender + /// is its owner; + /// - verifying that `node_id` refers to a real, registered node; + /// - ensuring `node_id` is not already a member of any family; + /// - ensuring `expires_at` is strictly in the future. + /// + /// As defence-in-depth, this method errors with [`FamilyNotFound`] if + /// `family_id` is unknown and with [`PendingInvitationAlreadyExists`] if + /// a pending invitation for the same `(family, node)` pair is already + /// stored — the underlying `IndexedMap` would otherwise silently + /// overwrite it. + /// + /// Returns the freshly persisted [`FamilyInvitation`]. + /// + /// [`FamilyNotFound`]: NodeFamiliesContractError::FamilyNotFound + /// [`PendingInvitationAlreadyExists`]: NodeFamiliesContractError::PendingInvitationAlreadyExists + pub(crate) fn add_pending_invitation( + &self, + store: &mut dyn Storage, + family_id: NodeFamilyId, + node_id: NodeId, + expires_at: u64, + ) -> Result { + let key: FamilyMember = (family_id, node_id); + + if !self.families.has(store, family_id) { + return Err(NodeFamiliesContractError::FamilyNotFound { family_id }); + } + + if self + .pending_family_invitations + .may_load(store, key)? + .is_some() + { + return Err(NodeFamiliesContractError::PendingInvitationAlreadyExists { + family_id, + node_id, + }); + } + + let invitation = FamilyInvitation { + family_id, + node_id, + expires_at, + }; + self.pending_family_invitations + .save(store, key, &invitation)?; + Ok(invitation) + } + + /// Accept a pending invitation for `node_id` to join `family_id`. + /// + /// Performs the full storage transition atomically: + /// 1. loads the pending invitation (errors with [`InvitationNotFound`] if + /// none exists for the given pair); + /// 2. verifies it has not expired (`now < expires_at`, errors with + /// [`InvitationExpired`] otherwise); + /// 3. removes it from the pending map; + /// 4. records `node_id -> family_id` in [`Self::family_members`]; + /// 5. increments the family's `members` counter (errors with + /// [`FamilyNotFound`] if the family has somehow been removed); + /// 6. archives the invitation in [`Self::past_family_invitations`] with + /// status [`FamilyInvitationStatus::Accepted`], using the next free + /// per-`(family, node)` counter. + /// + /// The caller is responsible for verifying that `node_id` is owned by + /// the transaction sender and is not already a member of any family. + /// + /// Returns the updated [`NodeFamily`] (with the bumped `members` count). + /// + /// [`InvitationNotFound`]: NodeFamiliesContractError::InvitationNotFound + /// [`InvitationExpired`]: NodeFamiliesContractError::InvitationExpired + /// [`FamilyNotFound`]: NodeFamiliesContractError::FamilyNotFound + pub(crate) fn accept_invitation( + &self, + store: &mut dyn Storage, + env: &Env, + family_id: NodeFamilyId, + node_id: NodeId, + ) -> Result { + let now = env.block.time.seconds(); + let key: FamilyMember = (family_id, node_id); + + let invitation = self + .pending_family_invitations + .may_load(store, key)? + .ok_or(NodeFamiliesContractError::InvitationNotFound { family_id, node_id })?; + + if now >= invitation.expires_at { + return Err(NodeFamiliesContractError::InvitationExpired { + family_id, + node_id, + expires_at: invitation.expires_at, + now, + }); + } + + self.pending_family_invitations.remove(store, key)?; + + self.family_members.save( + store, + node_id, + &FamilyMembership { + family_id, + joined_at: now, + }, + )?; + + let mut family = self + .families + .may_load(store, family_id)? + .ok_or(NodeFamiliesContractError::FamilyNotFound { family_id })?; + family.members += 1; + self.families.save(store, family_id, &family)?; + + let counter = self.next_past_invitation_counter(store, key)?; + self.past_family_invitations.save( + store, + (key, counter), + &PastFamilyInvitation { + invitation, + status: FamilyInvitationStatus::Accepted { at: now }, + }, + )?; + + Ok(family) + } + + /// Reject a pending invitation for `node_id` from `family_id`. + /// + /// Invitee-side counterpart to [`Self::revoke_pending_invitation`]: + /// removes the invitation from [`Self::pending_family_invitations`] and + /// archives it in [`Self::past_family_invitations`] with status + /// [`FamilyInvitationStatus::Rejected`], using the next free + /// per-`(family, node)` counter. Errors with [`InvitationNotFound`] if + /// no pending invitation exists for the given pair. + /// + /// Works regardless of whether the invitation has expired. + /// + /// The caller is responsible for verifying that the transaction sender + /// is the controller of `node_id`. + /// + /// Returns the rejected [`FamilyInvitation`]. + /// + /// [`InvitationNotFound`]: NodeFamiliesContractError::InvitationNotFound + pub(crate) fn reject_pending_invitation( + &self, + store: &mut dyn Storage, + env: &Env, + family_id: NodeFamilyId, + node_id: NodeId, + ) -> Result { + let now = env.block.time.seconds(); + let key: FamilyMember = (family_id, node_id); + + let invitation = self + .pending_family_invitations + .may_load(store, key)? + .ok_or(NodeFamiliesContractError::InvitationNotFound { family_id, node_id })?; + + self.pending_family_invitations.remove(store, key)?; + + let counter = self.next_past_invitation_counter(store, key)?; + self.past_family_invitations.save( + store, + (key, counter), + &PastFamilyInvitation { + invitation: invitation.clone(), + status: FamilyInvitationStatus::Rejected { at: now }, + }, + )?; + + Ok(invitation) + } + + /// Revoke a pending invitation for `node_id` from `family_id`. + /// + /// Removes the invitation from [`Self::pending_family_invitations`] and + /// archives it in [`Self::past_family_invitations`] with status + /// [`FamilyInvitationStatus::Revoked`], using the next free + /// per-`(family, node)` counter. Errors with [`InvitationNotFound`] if + /// no pending invitation exists for the given pair. + /// + /// Works regardless of whether the invitation has expired — this is the + /// only path that can clean expired entries out of the pending map, since + /// no background sweeper exists. + /// + /// The caller is responsible for verifying that the transaction sender + /// is the owner of `family_id`. + /// + /// Returns the revoked [`FamilyInvitation`]. + /// + /// [`InvitationNotFound`]: NodeFamiliesContractError::InvitationNotFound + pub(crate) fn revoke_pending_invitation( + &self, + store: &mut dyn Storage, + env: &Env, + family_id: NodeFamilyId, + node_id: NodeId, + ) -> Result { + let now = env.block.time.seconds(); + let key: FamilyMember = (family_id, node_id); + + let invitation = self + .pending_family_invitations + .may_load(store, key)? + .ok_or(NodeFamiliesContractError::InvitationNotFound { family_id, node_id })?; + + self.pending_family_invitations.remove(store, key)?; + + let counter = self.next_past_invitation_counter(store, key)?; + self.past_family_invitations.save( + store, + (key, counter), + &PastFamilyInvitation { + invitation: invitation.clone(), + status: FamilyInvitationStatus::Revoked { at: now }, + }, + )?; + + Ok(invitation) + } + + /// Remove `node_id` from whichever family it currently belongs to. + /// + /// Shared storage path for both routes that drop a member: + /// - **kick** — invoked by the family owner against another node; + /// - **leave** — invoked by the node's own controller. + /// + /// Looks up the node's family via [`Self::family_members`] (errors with + /// [`NodeNotInFamily`] if the node has no membership record), removes + /// the membership entry, decrements the family's `members` counter + /// (saturating at `0` as defence-in-depth — a underflow would indicate + /// an invariant break elsewhere), and archives a [`PastFamilyMember`] + /// record stamped with `removed_at = env.block.time.seconds()` using + /// the next per-`(family, node)` archive slot. + /// + /// The caller is responsible for verifying that the transaction sender + /// is authorised to remove this node — either as the family owner + /// (kick) or as the node's controller (leave). + /// + /// Returns the updated [`NodeFamily`] (with the decremented `members` + /// count). Errors with [`FamilyNotFound`] if the node's family has + /// somehow been removed. + /// + /// [`NodeNotInFamily`]: NodeFamiliesContractError::NodeNotInFamily + /// [`FamilyNotFound`]: NodeFamiliesContractError::FamilyNotFound + pub(crate) fn remove_family_member( + &self, + store: &mut dyn Storage, + env: &Env, + node_id: NodeId, + ) -> Result { + let now = env.block.time.seconds(); + + let family_id = self + .family_members + .may_load(store, node_id)? + .ok_or(NodeFamiliesContractError::NodeNotInFamily { node_id })? + .family_id; + + self.family_members.remove(store, node_id)?; + + let mut family = self + .families + .may_load(store, family_id)? + .ok_or(NodeFamiliesContractError::FamilyNotFound { family_id })?; + family.members = family.members.saturating_sub(1); + self.families.save(store, family_id, &family)?; + + let key: FamilyMember = (family_id, node_id); + let counter = self.next_past_member_counter(store, key)?; + self.past_family_members.save( + store, + (key, counter), + &PastFamilyMember { + family_id, + node_id, + removed_at: now, + }, + )?; + + Ok(family) + } + + /// Apply the family-side cleanup triggered when `node_id` initiates + /// unbonding from the mixnet contract. + /// + /// Idempotent over the membership half: drops the node's [`FamilyMembership`] + /// record (decrementing the family's `members` count and archiving a + /// [`PastFamilyMember`]) iff such a record exists, otherwise leaves the + /// state untouched. Then sweeps every pending invitation addressed to + /// `node_id` (iterating via [`NodeFamilyInvitationIndex::node`]), + /// removing each from the pending map and archiving it as + /// [`FamilyInvitationStatus::Rejected`] at `env.block.time` — the + /// auto-cleared invitations share the `Rejected` terminal state with + /// invitations the node controller would have explicitly declined. + /// + /// The caller is responsible for verifying that the transaction sender + /// is the configured mixnet contract address — there is no node-side + /// authority for this path and storage cannot tell the difference between + /// the legitimate callback and an arbitrary execute call. + /// + /// Returns the number of pending invitations that were swept (useful for + /// event attributes / telemetry); the membership half is observable via + /// the archived `PastFamilyMember`. + pub(crate) fn handle_node_unbonding( + &self, + store: &mut dyn Storage, + env: &Env, + node_id: NodeId, + ) -> Result { + if self.family_members.may_load(store, node_id)?.is_some() { + self.remove_family_member(store, env, node_id)?; + } + + let now = env.block.time.seconds(); + let pending: Vec<(FamilyMember, FamilyInvitation)> = self + .pending_family_invitations + .idx + .node + .prefix(node_id) + .range(store, None, None, Order::Ascending) + .collect::>>()?; + + let swept = pending.len() as u64; + for (key, invitation) in pending { + self.pending_family_invitations.remove(store, key)?; + let counter = self.next_past_invitation_counter(store, key)?; + self.past_family_invitations.save( + store, + (key, counter), + &PastFamilyInvitation { + invitation, + status: FamilyInvitationStatus::Rejected { at: now }, + }, + )?; + } + + Ok(swept) + } + + /// Disband (delete) `family_id`. + /// + /// Sweeps every still-pending invitation issued by the family + /// (iterating via the `family` multi-index over + /// [`Self::pending_family_invitations`]), removing each from the + /// pending map and archiving it as + /// [`FamilyInvitationStatus::Revoked`] at `env.block.time` — disbanding + /// the family is treated as the family withdrawing all of its + /// outstanding invitations. Gas cost therefore scales with the number + /// of leftover invitations; if that becomes a concern, the owner can + /// revoke them manually before disbanding. + /// + /// The caller (a transaction handler) is responsible for: + /// - verifying that the transaction sender is the owner of `family_id`; + /// - verifying that the family has zero current members (errors with + /// [`FamilyNotEmpty`] are raised at the transaction layer, not here) + /// — disbanding a family with members would otherwise leak orphaned + /// `FamilyMembership` records pointing at a removed family. + /// + /// Errors with [`FamilyNotFound`] if `family_id` does not exist. + /// Returns the disbanded [`NodeFamily`] (final snapshot) for use in + /// event attributes. + /// + /// [`FamilyNotEmpty`]: NodeFamiliesContractError::FamilyNotEmpty + /// [`FamilyNotFound`]: NodeFamiliesContractError::FamilyNotFound + pub(crate) fn disband_family( + &self, + store: &mut dyn Storage, + env: &Env, + family_id: NodeFamilyId, + ) -> Result { + let now = env.block.time.seconds(); + + let family = self + .families + .may_load(store, family_id)? + .ok_or(NodeFamiliesContractError::FamilyNotFound { family_id })?; + + // collect first, then mutate — iterating an IndexedMap while modifying it is unsafe + let pending: Vec<(FamilyMember, FamilyInvitation)> = self + .pending_family_invitations + .idx + .family + .prefix(family_id) + .range(store, None, None, Order::Ascending) + .collect::>>()?; + + for (key, invitation) in pending { + self.pending_family_invitations.remove(store, key)?; + let counter = self.next_past_invitation_counter(store, key)?; + self.past_family_invitations.save( + store, + (key, counter), + &PastFamilyInvitation { + invitation, + status: FamilyInvitationStatus::Revoked { at: now }, + }, + )?; + } + + self.families.remove(store, family_id)?; + + Ok(family) + } + + // helpers + + /// Look up the family owned by `owner` via the unique `owner` index. + /// + /// Returns `Ok(None)` if the address owns no family. The unique index + /// guarantees the lookup is `O(log n)` and that at most one family can + /// ever match. + pub(crate) fn may_get_owned_family( + &self, + storage: &dyn Storage, + owner: &Addr, + ) -> Result, NodeFamiliesContractError> { + Ok(self + .families + .idx + .owner + .item(storage, owner.clone())? + .map(|(_, owned)| owned)) + } + + /// Like [`Self::may_get_owned_family`] but errors with + /// [`SenderDoesntOwnAFamily`] when the address doesn't own one — meant + /// for owner-gated execute paths (`disband`, `invite`, …) where the + /// absence of a family is itself an error. + /// + /// [`SenderDoesntOwnAFamily`]: NodeFamiliesContractError::SenderDoesntOwnAFamily + pub(crate) fn must_get_owned_family( + &self, + storage: &dyn Storage, + owner: &Addr, + ) -> Result { + self.may_get_owned_family(storage, owner)?.ok_or_else(|| { + NodeFamiliesContractError::SenderDoesntOwnAFamily { + address: owner.clone(), + } + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::testing::{init_contract_tester, NodeFamiliesContractTesterExt}; + use nym_contracts_common_testing::ContractOpts; + + // ---- counters ---- + + #[test] + fn next_family_id_starts_at_1_and_increments() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + + assert_eq!(s.next_family_id(tester.storage_mut()).unwrap(), 1); + assert_eq!(s.next_family_id(tester.storage_mut()).unwrap(), 2); + assert_eq!(s.next_family_id(tester.storage_mut()).unwrap(), 3); + } + + #[test] + fn past_invitation_counter_starts_at_0_per_key() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let k1: FamilyMember = (1, 100); + let k2: FamilyMember = (2, 100); + + assert_eq!( + s.next_past_invitation_counter(tester.storage_mut(), k1) + .unwrap(), + 0 + ); + assert_eq!( + s.next_past_invitation_counter(tester.storage_mut(), k1) + .unwrap(), + 1 + ); + // independent counter for a different key + assert_eq!( + s.next_past_invitation_counter(tester.storage_mut(), k2) + .unwrap(), + 0 + ); + assert_eq!( + s.next_past_invitation_counter(tester.storage_mut(), k1) + .unwrap(), + 2 + ); + } + + #[test] + fn past_member_counter_starts_at_0_per_key() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let k: FamilyMember = (1, 100); + + assert_eq!( + s.next_past_member_counter(tester.storage_mut(), k).unwrap(), + 0 + ); + assert_eq!( + s.next_past_member_counter(tester.storage_mut(), k).unwrap(), + 1 + ); + } + + // ---- register_new_family ---- + + #[test] + fn register_new_family_persists_with_expected_fields() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let fee = tester.family_fee(); + let env = tester.env(); + let owner = tester.addr_make("alice"); + + let family = s + .register_new_family( + tester.storage_mut(), + &env, + fee, + owner.clone(), + "Fam!".into(), + "fam".into(), + "desc".into(), + ) + .unwrap(); + + assert_eq!(family.id, 1); + assert_eq!(family.owner, owner); + assert_eq!(family.name, "Fam!"); + assert_eq!(family.normalised_name, "fam"); + assert_eq!(family.description, "desc"); + assert_eq!(family.members, 0); + assert_eq!(family.created_at, tester.env().block.time.seconds()); + + let stored = s.families.load(tester.storage(), 1).unwrap(); + assert_eq!(stored, family); + } + + #[test] + fn register_new_family_assigns_sequential_ids() { + let mut tester = init_contract_tester(); + + let f1 = tester.add_dummy_family(); + let f2 = tester.add_dummy_family(); + + assert_eq!(f1.id, 1); + assert_eq!(f2.id, 2); + } + + #[test] + fn register_new_family_rejects_duplicate_name() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let env = tester.env(); + let alice = tester.addr_make("alice"); + let bob = tester.addr_make("bob"); + let fee = tester.family_fee(); + + s.register_new_family( + tester.storage_mut(), + &env, + fee.clone(), + alice, + "Shared".into(), + "shared".into(), + "".into(), + ) + .unwrap(); + + // unique-index defence-in-depth check: same normalised_name even though + // the user-submitted `name` differs in casing/punctuation. + let res = s.register_new_family( + tester.storage_mut(), + &env, + fee, + bob, + "$$shared$$".into(), + "shared".into(), + "".into(), + ); + assert!(res.is_err()); + } + + #[test] + fn register_new_family_rejects_duplicate_owner() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let env = tester.env(); + let alice = tester.addr_make("alice"); + let fee = tester.family_fee(); + + tester.make_family(&alice); + + // unique-index defence-in-depth check + let res = s.register_new_family( + tester.storage_mut(), + &env, + fee, + alice, + "second".into(), + "second".into(), + "".into(), + ); + assert!(res.is_err()); + } + + // ---- add_pending_invitation ---- + + #[test] + fn add_pending_invitation_persists() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let alice = tester.addr_make("alice"); + let f = tester.make_family(&alice); + let expires_at = tester.env().block.time.seconds() + 100; + + let inv = s + .add_pending_invitation(tester.storage_mut(), f.id, 42, expires_at) + .unwrap(); + + assert_eq!(inv.family_id, f.id); + assert_eq!(inv.node_id, 42); + assert_eq!(inv.expires_at, expires_at); + let stored = s + .pending_family_invitations + .load(tester.storage(), (f.id, 42)) + .unwrap(); + assert_eq!(stored, inv); + } + + #[test] + fn add_pending_invitation_errors_on_unknown_family() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let env = tester.env(); + let expires_at = env.block.time.seconds() + 100; + + let res = s.add_pending_invitation(tester.storage_mut(), 99, 42, expires_at); + assert_eq!( + res.unwrap_err(), + NodeFamiliesContractError::FamilyNotFound { family_id: 99 } + ); + } + + #[test] + fn add_pending_invitation_errors_on_duplicate() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let env = tester.env(); + let alice = tester.addr_make("alice"); + let f = tester.make_family(&alice); + + tester.invite_to_family(f.id, 42); + + let expires_at = env.block.time.seconds() + 200; + let res = s.add_pending_invitation(tester.storage_mut(), f.id, 42, expires_at); + assert_eq!( + res.unwrap_err(), + NodeFamiliesContractError::PendingInvitationAlreadyExists { + family_id: f.id, + node_id: 42, + } + ); + } + + // ---- accept_invitation ---- + + #[test] + fn accept_invitation_happy_path() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let env = tester.env(); + let alice = tester.addr_make("alice"); + let f = tester.make_family(&alice); + let expires_at = env.block.time.seconds() + 100; + s.add_pending_invitation(tester.storage_mut(), f.id, 42, expires_at) + .unwrap(); + + let updated = s + .accept_invitation(tester.storage_mut(), &env, f.id, 42) + .unwrap(); + + assert_eq!(updated.members, 1); + assert!(s + .pending_family_invitations + .may_load(tester.storage(), (f.id, 42)) + .unwrap() + .is_none()); + let membership = s.family_members.load(tester.storage(), 42).unwrap(); + assert_eq!(membership.family_id, f.id); + assert_eq!(membership.joined_at, tester.env().block.time.seconds()); + assert_eq!(s.families.load(tester.storage(), f.id).unwrap().members, 1); + + let past = s + .past_family_invitations + .load(tester.storage(), ((f.id, 42), 0)) + .unwrap(); + assert_eq!( + past.status, + FamilyInvitationStatus::Accepted { + at: tester.env().block.time.seconds() + } + ); + assert_eq!(past.invitation.family_id, f.id); + assert_eq!(past.invitation.node_id, 42); + } + + #[test] + fn accept_invitation_errors_when_no_pending() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let env = tester.env(); + + let res = s.accept_invitation(tester.storage_mut(), &env, 1, 42); + assert_eq!( + res.unwrap_err(), + NodeFamiliesContractError::InvitationNotFound { + family_id: 1, + node_id: 42, + } + ); + } + + #[test] + fn accept_invitation_errors_when_expired() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let env = tester.env(); + let alice = tester.addr_make("alice"); + let f = tester.make_family(&alice); + // expires at exactly `now` — `now >= expires_at` triggers + let expires_at = tester.env().block.time.seconds(); + s.add_pending_invitation(tester.storage_mut(), f.id, 42, expires_at) + .unwrap(); + + let res = s.accept_invitation(tester.storage_mut(), &env, f.id, 42); + assert_eq!( + res.unwrap_err(), + NodeFamiliesContractError::InvitationExpired { + family_id: f.id, + node_id: 42, + expires_at, + now: tester.env().block.time.seconds(), + } + ); + } + + // ---- reject_pending_invitation ---- + + #[test] + fn reject_invitation_happy_path() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let env = tester.env(); + let alice = tester.addr_make("alice"); + let f = tester.make_family(&alice); + tester.invite_to_family(f.id, 42); + + let inv = s + .reject_pending_invitation(tester.storage_mut(), &env, f.id, 42) + .unwrap(); + assert_eq!(inv.node_id, 42); + assert!(s + .pending_family_invitations + .may_load(tester.storage(), (f.id, 42)) + .unwrap() + .is_none()); + let past = s + .past_family_invitations + .load(tester.storage(), ((f.id, 42), 0)) + .unwrap(); + assert_eq!( + past.status, + FamilyInvitationStatus::Rejected { + at: tester.env().block.time.seconds() + } + ); + } + + #[test] + fn reject_invitation_works_on_expired() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let env = tester.env(); + let alice = tester.addr_make("alice"); + let f = tester.make_family(&alice); + let expires_at = env.block.time.seconds(); + s.add_pending_invitation(tester.storage_mut(), f.id, 42, expires_at) + .unwrap(); + + s.reject_pending_invitation(tester.storage_mut(), &env, f.id, 42) + .unwrap(); + } + + #[test] + fn reject_invitation_errors_when_no_pending() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let env = tester.env(); + + let res = s.reject_pending_invitation(tester.storage_mut(), &env, 1, 42); + assert_eq!( + res.unwrap_err(), + NodeFamiliesContractError::InvitationNotFound { + family_id: 1, + node_id: 42, + } + ); + } + + // ---- revoke_pending_invitation ---- + + #[test] + fn revoke_invitation_happy_path() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let env = tester.env(); + let alice = tester.addr_make("alice"); + let f = tester.make_family(&alice); + tester.invite_to_family(f.id, 42); + + s.revoke_pending_invitation(tester.storage_mut(), &env, f.id, 42) + .unwrap(); + let past = s + .past_family_invitations + .load(tester.storage(), ((f.id, 42), 0)) + .unwrap(); + assert_eq!( + past.status, + FamilyInvitationStatus::Revoked { + at: tester.env().block.time.seconds() + } + ); + } + + #[test] + fn revoke_invitation_errors_when_no_pending() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let env = tester.env(); + + let res = s.revoke_pending_invitation(tester.storage_mut(), &env, 1, 42); + assert_eq!( + res.unwrap_err(), + NodeFamiliesContractError::InvitationNotFound { + family_id: 1, + node_id: 42, + } + ); + } + + // ---- remove_family_member ---- + + #[test] + fn remove_family_member_happy_path() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let env = tester.env(); + let alice = tester.addr_make("alice"); + let f = tester.make_family(&alice); + tester.add_to_family(f.id, 42); + + let updated = s + .remove_family_member(tester.storage_mut(), &env, 42) + .unwrap(); + + assert_eq!(updated.members, 0); + assert!(s + .family_members + .may_load(tester.storage(), 42) + .unwrap() + .is_none()); + let past = s + .past_family_members + .load(tester.storage(), ((f.id, 42), 0)) + .unwrap(); + assert_eq!(past.family_id, f.id); + assert_eq!(past.node_id, 42); + assert_eq!(past.removed_at, tester.env().block.time.seconds()); + } + + #[test] + fn remove_family_member_errors_when_node_not_in_any_family() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let env = tester.env(); + + let res = s.remove_family_member(tester.storage_mut(), &env, 999); + assert_eq!( + res.unwrap_err(), + NodeFamiliesContractError::NodeNotInFamily { node_id: 999 } + ); + } + + #[test] + fn remove_family_member_uses_per_pair_archive_counter() { + // joining and leaving the same family twice must not collide on the archive key + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let env = tester.env(); + let alice = tester.addr_make("alice"); + let f = tester.make_family(&alice); + + let expires_at = env.block.time.seconds() + 100; + for _ in 0..2 { + s.add_pending_invitation(tester.storage_mut(), f.id, 42, expires_at) + .unwrap(); + s.accept_invitation(tester.storage_mut(), &env, f.id, 42) + .unwrap(); + s.remove_family_member(tester.storage_mut(), &env, 42) + .unwrap(); + } + + // both archive slots present + s.past_family_members + .load(tester.storage(), ((f.id, 42), 0)) + .unwrap(); + s.past_family_members + .load(tester.storage(), ((f.id, 42), 1)) + .unwrap(); + } + + // ---- disband_family ---- + + #[test] + fn disband_family_happy_path_no_pending() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let env = tester.env(); + let alice = tester.addr_make("alice"); + let f = tester.make_family(&alice); + + let snap = s.disband_family(tester.storage_mut(), &env, f.id).unwrap(); + assert_eq!(snap.id, f.id); + assert!(s + .families + .may_load(tester.storage(), f.id) + .unwrap() + .is_none()); + } + + #[test] + fn disband_family_sweeps_all_pending_invitations_as_revoked() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let env = tester.env(); + let alice = tester.addr_make("alice"); + let f = tester.make_family(&alice); + tester.invite_to_family(f.id, 42); + tester.invite_to_family(f.id, 43); + + s.disband_family(tester.storage_mut(), &env, f.id).unwrap(); + + assert!(s + .pending_family_invitations + .may_load(tester.storage(), (f.id, 42)) + .unwrap() + .is_none()); + assert!(s + .pending_family_invitations + .may_load(tester.storage(), (f.id, 43)) + .unwrap() + .is_none()); + assert_eq!( + s.past_family_invitations + .load(tester.storage(), ((f.id, 42), 0)) + .unwrap() + .status, + FamilyInvitationStatus::Revoked { + at: tester.env().block.time.seconds() + } + ); + assert_eq!( + s.past_family_invitations + .load(tester.storage(), ((f.id, 43), 0)) + .unwrap() + .status, + FamilyInvitationStatus::Revoked { + at: tester.env().block.time.seconds() + } + ); + } + + #[test] + fn disband_family_errors_on_unknown_family() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let env = tester.env(); + + let res = s.disband_family(tester.storage_mut(), &env, 99); + assert_eq!( + res.unwrap_err(), + NodeFamiliesContractError::FamilyNotFound { family_id: 99 } + ); + } + + #[test] + fn after_disband_owner_can_register_again_with_new_id() { + let mut tester = init_contract_tester(); + let fee = tester.family_fee(); + let s = NodeFamiliesStorage::new(); + let env = tester.env(); + let alice = tester.addr_make("alice"); + + let f1 = tester.make_family(&alice); + s.disband_family(tester.storage_mut(), &env, f1.id).unwrap(); + let f2 = s + .register_new_family( + tester.storage_mut(), + &env, + fee, + alice, + "2".into(), + "2".into(), + "".into(), + ) + .unwrap(); + + // ids monotonically increase, never recycled + assert_eq!(f1.id, 1); + assert_eq!(f2.id, 2); + } + + // ---- may_get_owned_family ---- + + #[test] + fn may_get_owned_family_returns_none_when_address_owns_nothing() { + let tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let alice = tester.addr_make("alice"); + + let res = s.may_get_owned_family(tester.storage(), &alice).unwrap(); + assert!(res.is_none()); + } + + #[test] + fn may_get_owned_family_returns_the_family_for_its_owner() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + + let res = s + .may_get_owned_family(tester.storage(), &alice) + .unwrap() + .unwrap(); + assert_eq!(res, family); + } + + #[test] + fn may_get_owned_family_does_not_leak_other_owners_family() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let alice = tester.addr_make("alice"); + let bob = tester.addr_make("bob"); + tester.make_family(&alice); + + let res = s.may_get_owned_family(tester.storage(), &bob).unwrap(); + assert!(res.is_none()); + } + + #[test] + fn may_get_owned_family_returns_none_after_disband() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + + let env = tester.env(); + s.disband_family(tester.storage_mut(), &env, family.id) + .unwrap(); + + let res = s.may_get_owned_family(tester.storage(), &alice).unwrap(); + assert!(res.is_none()); + } + + // ---- must_get_owned_family ---- + + #[test] + fn must_get_owned_family_returns_the_family_for_its_owner() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + + let res = s.must_get_owned_family(tester.storage(), &alice).unwrap(); + assert_eq!(res, family); + } + + #[test] + fn must_get_owned_family_errors_when_address_owns_nothing() { + let tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let alice = tester.addr_make("alice"); + + let err = s + .must_get_owned_family(tester.storage(), &alice) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::SenderDoesntOwnAFamily { address: alice } + ); + } + + #[test] + fn must_get_owned_family_errors_after_disband() { + let mut tester = init_contract_tester(); + let s = NodeFamiliesStorage::new(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + + let env = tester.env(); + s.disband_family(tester.storage_mut(), &env, family.id) + .unwrap(); + + let err = s + .must_get_owned_family(tester.storage(), &alice) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::SenderDoesntOwnAFamily { address: alice } + ); + } +} diff --git a/contracts/node-families/src/storage/retrieval_limits.rs b/contracts/node-families/src/storage/retrieval_limits.rs new file mode 100644 index 0000000000..bb993fe289 --- /dev/null +++ b/contracts/node-families/src/storage/retrieval_limits.rs @@ -0,0 +1,34 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +/// Default page size for paginated family listings when the caller omits `limit`. +pub const FAMILIES_DEFAULT_LIMIT: u32 = 50; + +/// Hard cap on the page size for paginated family listings; larger values are clamped. +pub const FAMILIES_MAX_LIMIT: u32 = 100; + +/// Default page size for paginated family-member listings when the caller omits `limit`. +pub const FAMILY_MEMBERS_DEFAULT_LIMIT: u32 = 50; + +/// Hard cap on the page size for paginated family-member listings; larger values are clamped. +pub const FAMILY_MEMBERS_MAX_LIMIT: u32 = 100; + +/// Default page size for paginated pending-invitation listings (both per-family +/// and global) when the caller omits `limit`. +pub const PENDING_INVITATIONS_DEFAULT_LIMIT: u32 = 50; + +/// Hard cap on the page size for paginated pending-invitation listings; larger values are clamped. +pub const PENDING_INVITATIONS_MAX_LIMIT: u32 = 100; + +/// Default page size for paginated past-invitation (archive) listings (both +/// per-family and global) when the caller omits `limit`. +pub const PAST_INVITATIONS_DEFAULT_LIMIT: u32 = 50; + +/// Hard cap on the page size for paginated past-invitation listings; larger values are clamped. +pub const PAST_INVITATIONS_MAX_LIMIT: u32 = 100; + +/// Default page size for paginated past-member (archive) listings when the caller omits `limit`. +pub const PAST_MEMBERS_DEFAULT_LIMIT: u32 = 50; + +/// Hard cap on the page size for paginated past-member listings; larger values are clamped. +pub const PAST_MEMBERS_MAX_LIMIT: u32 = 100; diff --git a/contracts/node-families/src/storage/storage_indexes.rs b/contracts/node-families/src/storage/storage_indexes.rs new file mode 100644 index 0000000000..0bae76f32a --- /dev/null +++ b/contracts/node-families/src/storage/storage_indexes.rs @@ -0,0 +1,174 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::storage::FamilyMember; +use cosmwasm_std::Addr; +use cw_storage_plus::{Index, IndexList, MultiIndex, UniqueIndex}; +use nym_mixnet_contract_common::NodeId; +use nym_node_families_contract_common::constants::storage_keys; +use nym_node_families_contract_common::{ + FamilyInvitation, FamilyMembership, NodeFamily, NodeFamilyId, PastFamilyInvitation, + PastFamilyMember, +}; + +/// Secondary indexes over [`NodeFamily`]. Enforces one-family-per-owner and +/// globally-unique family names via `UniqueIndex`es on `owner` and `name`. +pub(crate) struct NodeFamiliesIndex<'a> { + /// Unique index: at most one family per owner [`Addr`]. + pub(crate) owner: UniqueIndex<'a, Addr, NodeFamily, NodeFamilyId>, + /// Unique index keyed on [`NodeFamily::normalised_name`]: enforces global + /// uniqueness on the normalised form, so families with the same + /// canonical name but different user-submitted formatting collide. + pub(crate) normalised_name: UniqueIndex<'a, String, NodeFamily, NodeFamilyId>, +} + +impl NodeFamiliesIndex<'_> { + #[allow(clippy::new_without_default)] + pub(crate) fn new() -> Self { + NodeFamiliesIndex { + owner: UniqueIndex::new( + |family| family.owner.clone(), + storage_keys::FAMILIES_OWNER_IDX_NAMESPACE, + ), + normalised_name: UniqueIndex::new( + |family| family.normalised_name.clone(), + storage_keys::FAMILIES_NAME_IDX_NAMESPACE, + ), + } + } +} + +impl IndexList for NodeFamiliesIndex<'_> { + fn get_indexes(&'_ self) -> Box> + '_> { + let v: Vec<&dyn Index> = vec![&self.owner, &self.normalised_name]; + Box::new(v.into_iter()) + } +} + +/// Secondary indexes over current [`FamilyMembership`] records. The PK is +/// `NodeId` (one family per node), and the family-id multi-index enables +/// paginated listing of all nodes belonging to a given family. +pub(crate) struct FamilyMembersIndex<'a> { + /// Multi-index: every node currently in a given family. + pub(crate) family: MultiIndex<'a, NodeFamilyId, FamilyMembership, NodeId>, +} + +impl FamilyMembersIndex<'_> { + #[allow(clippy::new_without_default)] + pub(crate) fn new() -> Self { + FamilyMembersIndex { + family: MultiIndex::new( + |_pk, m| m.family_id, + storage_keys::NODE_FAMILY_MEMBERS, + storage_keys::NODE_FAMILY_MEMBERS_FAMILY_IDX_NAMESPACE, + ), + } + } +} + +impl IndexList for FamilyMembersIndex<'_> { + fn get_indexes(&'_ self) -> Box> + '_> { + let v: Vec<&dyn Index> = vec![&self.family]; + Box::new(v.into_iter()) + } +} + +/// Secondary indexes over pending [`FamilyInvitation`]s, allowing lookup by +/// either family id or node id. +pub(crate) struct NodeFamilyInvitationIndex<'a> { + /// Multi-index: all pending invitations issued by a given family. + pub(crate) family: MultiIndex<'a, NodeFamilyId, FamilyInvitation, FamilyMember>, + /// Multi-index: all pending invitations addressed to a given node. + pub(crate) node: MultiIndex<'a, NodeId, FamilyInvitation, FamilyMember>, +} + +impl NodeFamilyInvitationIndex<'_> { + pub(crate) fn new() -> Self { + NodeFamilyInvitationIndex { + family: MultiIndex::new( + |_pk, inv| inv.family_id, + storage_keys::INVITATIONS_NAMESPACE, + storage_keys::INVITATIONS_FAMILY_IDX_NAMESPACE, + ), + node: MultiIndex::new( + |_pk, inv| inv.node_id, + storage_keys::INVITATIONS_NAMESPACE, + storage_keys::INVITATIONS_NODE_IDX_NAMESPACE, + ), + } + } +} + +impl IndexList for NodeFamilyInvitationIndex<'_> { + fn get_indexes(&'_ self) -> Box> + '_> { + let v: Vec<&dyn Index> = vec![&self.family, &self.node]; + Box::new(v.into_iter()) + } +} + +/// Secondary indexes over the [`PastFamilyMember`] archive. +pub(crate) struct PastFamilyMembersIndex<'a> { + /// Multi-index: every past membership record for a given family. + pub(crate) family: MultiIndex<'a, NodeFamilyId, PastFamilyMember, (FamilyMember, u64)>, + /// Multi-index: every past membership record for a given node. + pub(crate) node: MultiIndex<'a, NodeId, PastFamilyMember, (FamilyMember, u64)>, +} + +impl PastFamilyMembersIndex<'_> { + #[allow(clippy::new_without_default)] + pub(crate) fn new() -> Self { + PastFamilyMembersIndex { + family: MultiIndex::new( + |_pk, mem| mem.family_id, + storage_keys::PAST_FAMILY_MEMBER_NAMESPACE, + storage_keys::PAST_FAMILY_MEMBER_FAMILY_IDX_NAMESPACE, + ), + node: MultiIndex::new( + |_pk, mem| mem.node_id, + storage_keys::PAST_FAMILY_MEMBER_NAMESPACE, + storage_keys::PAST_FAMILY_MEMBER_NODE_IDX_NAMESPACE, + ), + } + } +} + +impl IndexList for PastFamilyMembersIndex<'_> { + fn get_indexes(&'_ self) -> Box> + '_> { + let v: Vec<&dyn Index> = vec![&self.family, &self.node]; + Box::new(v.into_iter()) + } +} + +/// Secondary indexes over the [`PastFamilyInvitation`] archive +/// (rejected / revoked invitations). +pub(crate) struct PastFamilyInvitationsIndex<'a> { + /// Multi-index: every archived invitation issued by a given family. + pub(crate) family: MultiIndex<'a, NodeFamilyId, PastFamilyInvitation, (FamilyMember, u64)>, + /// Multi-index: every archived invitation addressed to a given node. + pub(crate) node: MultiIndex<'a, NodeId, PastFamilyInvitation, (FamilyMember, u64)>, +} + +impl PastFamilyInvitationsIndex<'_> { + #[allow(clippy::new_without_default)] + pub(crate) fn new() -> Self { + PastFamilyInvitationsIndex { + family: MultiIndex::new( + |_pk, inv| inv.invitation.family_id, + storage_keys::PAST_INVITATIONS_NAMESPACE, + storage_keys::PAST_INVITATIONS_FAMILY_IDX_NAMESPACE, + ), + node: MultiIndex::new( + |_pk, inv| inv.invitation.node_id, + storage_keys::PAST_INVITATIONS_NAMESPACE, + storage_keys::PAST_INVITATIONS_NODE_IDX_NAMESPACE, + ), + } + } +} + +impl IndexList for PastFamilyInvitationsIndex<'_> { + fn get_indexes(&'_ self) -> Box> + '_> { + let v: Vec<&dyn Index> = vec![&self.family, &self.node]; + Box::new(v.into_iter()) + } +} diff --git a/contracts/node-families/src/testing.rs b/contracts/node-families/src/testing.rs new file mode 100644 index 0000000000..f76bbacf26 --- /dev/null +++ b/contracts/node-families/src/testing.rs @@ -0,0 +1,219 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +// fine in test code +#![allow(clippy::unwrap_used)] +#![allow(clippy::expect_used)] + +use crate::contract::{execute, instantiate, migrate, query}; +use crate::helpers::normalise_family_name; +use crate::storage::NodeFamiliesStorage; +use cosmwasm_std::{coin, Addr, Coin, Storage}; +use mixnet_contract::testable_mixnet_contract::{EmbeddedMixnetContractExt, MixnetContract}; +use nym_contracts_common_testing::{ + AdminExt, ArbitraryContractStorageReader, ArbitraryContractStorageWriter, BankExt, ChainOpts, + CommonStorageKeys, ContractFn, ContractOpts, ContractTester, ContractTesterBuilder, DenomExt, + PermissionedFn, QueryFn, RandExt, TestableNymContract, TEST_DENOM, +}; +use nym_mixnet_contract_common::ContractState; +use nym_mixnet_contract_common::NodeId; +use nym_node_families_contract_common::constants::storage_keys; +use nym_node_families_contract_common::{ + Config, ExecuteMsg, FamilyInvitation, InstantiateMsg, MigrateMsg, NodeFamiliesContractError, + NodeFamily, NodeFamilyId, QueryMsg, +}; + +pub struct NodeFamiliesContract; + +impl TestableNymContract for NodeFamiliesContract { + const NAME: &'static str = "node-families-contract"; + type InitMsg = InstantiateMsg; + type ExecuteMsg = ExecuteMsg; + type QueryMsg = QueryMsg; + type MigrateMsg = MigrateMsg; + type ContractError = NodeFamiliesContractError; + + fn instantiate() -> ContractFn { + instantiate + } + + fn execute() -> ContractFn { + execute + } + + fn query() -> QueryFn { + query + } + + fn migrate() -> PermissionedFn { + migrate + } + + fn init() -> ContractTester + where + Self: Sized, + { + let builder = ContractTesterBuilder::new().instantiate::(None); + + // we just instantiated it + let mixnet_address = builder + .well_known_contracts + .get(MixnetContract::NAME) + .unwrap() + .clone(); + + builder + .instantiate::(Some(InstantiateMsg { + config: Config { + create_family_fee: coin(100_000000, TEST_DENOM), + family_name_length_limit: 20, + family_description_length_limit: 200, + default_invitation_validity_secs: 24 * 60 * 60, + }, + mixnet_contract_address: mixnet_address.to_string(), + })) + .build() + } +} + +/// Storage key the mixnet contract uses for its `ContractState` `Item` +/// (mirrors `mixnet/src/constants.rs::CONTRACT_STATE_KEY`). +const MIXNET_CONTRACT_STATE_STORAGE_KEY: &str = "state"; + +pub fn init_contract_tester() -> ContractTester { + let mut tester = NodeFamiliesContract::init() + .with_common_storage_key(CommonStorageKeys::Admin, storage_keys::CONTRACT_ADMIN); + + // Chicken-and-egg: the mixnet contract is instantiated first and is given + // a placeholder `node_families_contract_address` because the families + // contract doesn't exist yet. Once the families contract has been + // instantiated we patch the mixnet's stored `ContractState` so that the + // unbond callback (`OnNymNodeUnbond`) actually dispatches to the right + // contract. In production this fixup happens via a contract migration; + // here we go straight to storage to avoid jumping through cw2 version + // checks that don't apply on a fresh tester. + let families_address = tester.contract_address.clone(); + let mut mixnet_state: ContractState = tester + .read_from_mixnet_contract_storage(MIXNET_CONTRACT_STATE_STORAGE_KEY) + .expect("mixnet contract state should be loadable"); + mixnet_state.node_families_contract_address = families_address; + tester + .write_to_mixnet_contract_storage_value(MIXNET_CONTRACT_STATE_STORAGE_KEY, &mixnet_state) + .expect("should be able to patch mixnet contract state"); + + tester +} + +pub trait NodeFamiliesContractTesterExt: + ContractOpts< + ExecuteMsg = ExecuteMsg, + QueryMsg = QueryMsg, + ContractError = NodeFamiliesContractError, + > + ChainOpts + + AdminExt + + DenomExt + + BankExt + + RandExt + + Storage + + ArbitraryContractStorageReader + + ArbitraryContractStorageWriter + + EmbeddedMixnetContractExt + + Sized +{ + fn family_fee(&self) -> Coin { + let s = NodeFamiliesStorage::new(); + s.config.load(self).unwrap().create_family_fee + } + + fn make_named_family(&mut self, owner: &Addr, name: &str) -> NodeFamily { + let normalised = normalise_family_name(name); + let env = self.env(); + let fee = self.family_fee(); + NodeFamiliesStorage::new() + .register_new_family( + self, + &env, + fee, + owner.clone(), + name.to_string(), + normalised, + "dummy".to_string(), + ) + .unwrap() + } + + fn make_family(&mut self, owner: &Addr) -> NodeFamily { + // names must be globally unique; derive from owner addr (also unique) + let name = format!("family-{owner}"); + self.make_named_family(owner, &name) + } + + fn disband_family(&mut self, family: NodeFamilyId) { + let env = self.env(); + NodeFamiliesStorage::new() + .disband_family(self, &env, family) + .unwrap(); + } + + fn add_dummy_family(&mut self) -> NodeFamily { + let owner = self.generate_account(); + self.make_family(&owner) + } + + fn invite_to_family_with_expiration( + &mut self, + family: NodeFamilyId, + node: NodeId, + expiration: u64, + ) -> FamilyInvitation { + NodeFamiliesStorage::new() + .add_pending_invitation(self, family, node, expiration) + .unwrap() + } + + fn invite_to_family(&mut self, family: NodeFamilyId, node: NodeId) -> FamilyInvitation { + let exp = self.env().block.time.seconds() + 100; + self.invite_to_family_with_expiration(family, node, exp) + } + + fn accept_invitation(&mut self, family: NodeFamilyId, node: NodeId) { + let env = self.env(); + NodeFamiliesStorage::new() + .accept_invitation(self, &env, family, node) + .unwrap(); + } + + fn reject_invitation(&mut self, family: NodeFamilyId, node: NodeId) { + let env = self.env(); + NodeFamiliesStorage::new() + .reject_pending_invitation(self, &env, family, node) + .unwrap(); + } + + fn revoke_invitation(&mut self, family: NodeFamilyId, node: NodeId) { + let env = self.env(); + NodeFamiliesStorage::new() + .revoke_pending_invitation(self, &env, family, node) + .unwrap(); + } + + fn add_to_family(&mut self, family: NodeFamilyId, node: NodeId) { + self.invite_to_family(family, node); + self.accept_invitation(family, node); + } + + fn remove_from_family(&mut self, node: NodeId) { + let env = self.env(); + NodeFamiliesStorage::new() + .remove_family_member(self, &env, node) + .unwrap(); + } + + fn add_n_family_members(&mut self, family: NodeFamilyId, count: u32) { + for n in 1..=count { + self.add_to_family(family, n); + } + } +} + +impl NodeFamiliesContractTesterExt for ContractTester {} diff --git a/contracts/node-families/src/transactions.rs b/contracts/node-families/src/transactions.rs new file mode 100644 index 0000000000..0237dcf3ab --- /dev/null +++ b/contracts/node-families/src/transactions.rs @@ -0,0 +1,2165 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +//! State-mutating execute handlers + +use crate::helpers::{ + ensure_address_holds_no_family_membership, ensure_has_bonded_node, ensure_node_is_bonded, + ensure_node_not_in_family, normalise_family_name, +}; +use crate::storage::NodeFamiliesStorage; +use cosmwasm_std::{BankMsg, DepsMut, Env, Event, MessageInfo, Response}; +use nym_mixnet_contract_common::NodeId; +use nym_node_families_contract_common::constants::events; +use nym_node_families_contract_common::{Config, NodeFamiliesContractError, NodeFamilyId}; + +/// Replace the contract's runtime [`Config`]. Restricted to the contract admin. +pub(crate) fn try_update_config( + deps: DepsMut, + _env: Env, + info: MessageInfo, + config: Config, +) -> Result { + let storage = NodeFamiliesStorage::new(); + storage + .contract_admin + .assert_admin(deps.as_ref(), &info.sender)?; + storage.config.save(deps.storage, &config)?; + Ok(Response::default()) +} + +/// Create a new family owned by `info.sender`. +/// +/// Performs the caller-side checks specified on +/// [`NodeFamiliesStorage::register_new_family`]: validates the attached fee +/// matches the configured `create_family_fee`, that name and description +/// are within their configured length limits, that the name normalises to a +/// non-empty string, that the sender doesn't already own a family or +/// collide with an existing family's normalised name, and that the sender's +/// bonded node (if any) isn't already in a family. The unique indexes on +/// `owner` and `normalised_name` provide defence-in-depth, but pre-checking +/// yields typed errors with useful context. +pub(crate) fn try_create_family( + deps: DepsMut, + env: Env, + info: MessageInfo, + name: String, + description: String, +) -> Result { + let storage = NodeFamiliesStorage::new(); + let config = storage.config.load(deps.storage)?; + + // check for the correct number of coins and denom + let submitted = cw_utils::must_pay(&info, &config.create_family_fee.denom)?; + + // verify the amount + if submitted != config.create_family_fee.amount { + return Err(NodeFamiliesContractError::InvalidFamilyCreationFee { + expected: config.create_family_fee, + received: info.funds, + }); + } + + // validate family name + if name.len() > config.family_name_length_limit { + return Err(NodeFamiliesContractError::FamilyNameTooLong { + length: name.len(), + limit: config.family_name_length_limit, + }); + } + let normalised = normalise_family_name(&name); + if normalised.is_empty() { + return Err(NodeFamiliesContractError::EmptyFamilyName); + } + + // validate family description + if description.len() > config.family_description_length_limit { + return Err(NodeFamiliesContractError::FamilyDescriptionTooLong { + length: description.len(), + limit: config.family_description_length_limit, + }); + } + + // check if the sender already owns a family + if let Some(existing) = storage.may_get_owned_family(deps.storage, &info.sender)? { + return Err(NodeFamiliesContractError::SenderAlreadyOwnsAFamily { + address: info.sender, + family_id: existing.id, + }); + } + + // explicitly verify duplicate family name for a better error message + if let Some((_, existing)) = storage + .families + .idx + .normalised_name + .item(deps.storage, normalised.clone())? + { + return Err(NodeFamiliesContractError::FamilyNameAlreadyTaken { + name: normalised, + family_id: existing.id, + }); + } + + // check whether this owner has a bonded node which belongs to a family + ensure_address_holds_no_family_membership(&storage, deps.as_ref(), &info.sender)?; + + let family = storage.register_new_family( + deps.storage, + &env, + config.create_family_fee, + info.sender, + name, + normalised, + description, + )?; + + Ok(Response::new().add_event( + Event::new(events::FAMILY_CREATION_EVENT_NAME) + .add_attribute(events::FAMILY_CREATION_EVENT_FAMILY_NAME, family.name) + .add_attribute(events::FAMILY_CREATION_EVENT_OWNER_ADDRESS, family.owner) + .add_attribute( + events::FAMILY_CREATION_EVENT_FAMILY_ID, + family.id.to_string(), + ) + .add_attribute( + events::FAMILY_CREATION_EVENT_PAID_FEE, + family.paid_fee.to_string(), + ), + )) +} + +/// Disband the family owned by `info.sender` and refund the original +/// creation fee. +/// +/// Looks up the sender's family via the `owner` unique index (errors with +/// [`SenderDoesntOwnAFamily`] if none). The storage layer enforces the +/// "family must have zero current members" precondition and sweeps any +/// still-pending invitations as `Revoked`. The originally paid creation fee +/// is returned to the sender via a [`BankMsg::Send`] attached to the +/// response. +/// +/// [`SenderDoesntOwnAFamily`]: NodeFamiliesContractError::SenderDoesntOwnAFamily +pub(crate) fn try_disband_family( + deps: DepsMut, + env: Env, + info: MessageInfo, +) -> Result { + let storage = NodeFamiliesStorage::new(); + + let owned = storage.must_get_owned_family(deps.storage, &info.sender)?; + + if owned.members != 0 { + return Err(NodeFamiliesContractError::FamilyNotEmpty { + family_id: owned.id, + members: owned.members, + }); + } + + let family = storage.disband_family(deps.storage, &env, owned.id)?; + + let refund = BankMsg::Send { + to_address: family.owner.to_string(), + amount: vec![family.paid_fee.clone()], + }; + + Ok(Response::new().add_message(refund).add_event( + Event::new(events::FAMILY_DISBAND_EVENT_NAME) + .add_attribute( + events::FAMILY_DISBAND_EVENT_FAMILY_ID, + family.id.to_string(), + ) + .add_attribute(events::FAMILY_DISBAND_EVENT_OWNER_ADDRESS, &family.owner) + .add_attribute( + events::FAMILY_DISBAND_EVENT_REFUNDED_FEE, + family.paid_fee.to_string(), + ), + )) +} + +/// Issue a pending invitation for `node_id` to join the family owned by +/// `info.sender`. +/// +/// `validity_secs` overrides the configured `default_invitation_validity_secs` +/// when supplied; a value of `Some(0)` is rejected with +/// [`ZeroInvitationValidity`] since the invitation would already be expired +/// the moment it landed in storage. +/// +/// [`ZeroInvitationValidity`]: NodeFamiliesContractError::ZeroInvitationValidity +pub(crate) fn try_invite_to_family( + deps: DepsMut, + env: Env, + info: MessageInfo, + node_id: NodeId, + validity_secs: Option, +) -> Result { + let storage = NodeFamiliesStorage::new(); + let config = storage.config.load(deps.storage)?; + + let validity = validity_secs.unwrap_or(config.default_invitation_validity_secs); + if validity == 0 { + return Err(NodeFamiliesContractError::ZeroInvitationValidity); + } + + let owned = storage.must_get_owned_family(deps.storage, &info.sender)?; + ensure_node_is_bonded(&storage, deps.as_ref(), node_id)?; + ensure_node_not_in_family(&storage, deps.as_ref(), node_id)?; + + let expires_at = env.block.time.seconds() + validity; + let invitation = storage.add_pending_invitation(deps.storage, owned.id, node_id, expires_at)?; + + Ok(Response::new().add_event( + Event::new(events::FAMILY_INVITATION_EVENT_NAME) + .add_attribute( + events::FAMILY_INVITATION_EVENT_FAMILY_ID, + owned.id.to_string(), + ) + .add_attribute(events::FAMILY_INVITATION_EVENT_NODE_ID, node_id.to_string()) + .add_attribute( + events::FAMILY_INVITATION_EVENT_EXPIRES_AT, + invitation.expires_at.to_string(), + ), + )) +} + +/// Revoke a still-pending invitation previously issued by the sender's +/// family. +/// +/// The sender must currently own a family — the `(family, node)` pair +/// targeted for revocation is derived from that ownership rather than passed +/// explicitly, so a sender cannot revoke another family's invitations. +/// Errors with [`SenderDoesntOwnAFamily`] if the sender owns no family, or +/// [`InvitationNotFound`] if no pending invitation for `node_id` exists in +/// the sender's family. Expired invitations *can* be revoked — this is the +/// only path that cleans them out of the pending map. +/// +/// [`SenderDoesntOwnAFamily`]: NodeFamiliesContractError::SenderDoesntOwnAFamily +/// [`InvitationNotFound`]: NodeFamiliesContractError::InvitationNotFound +pub(crate) fn try_revoke_family_invitation( + deps: DepsMut, + env: Env, + info: MessageInfo, + node_id: NodeId, +) -> Result { + let storage = NodeFamiliesStorage::new(); + let owned = storage.must_get_owned_family(deps.storage, &info.sender)?; + + storage.revoke_pending_invitation(deps.storage, &env, owned.id, node_id)?; + + Ok(Response::new().add_event( + Event::new(events::FAMILY_INVITATION_REVOKED_EVENT_NAME) + .add_attribute( + events::FAMILY_INVITATION_REVOKED_EVENT_FAMILY_ID, + owned.id.to_string(), + ) + .add_attribute( + events::FAMILY_INVITATION_REVOKED_EVENT_NODE_ID, + node_id.to_string(), + ), + )) +} + +/// Accept the pending invitation for `node_id` to join `family_id`. +/// +/// `info.sender` must be the bond controller of `node_id` per the mixnet +/// contract; the storage layer's `family_members` write would otherwise +/// silently overwrite the membership of an unrelated node, so the controller +/// check (and the defence-in-depth `ensure_node_not_in_family`) live here +/// rather than down in storage. Errors with [`SenderDoesntControlNode`] if +/// the sender's bonded node id doesn't match (or the node is unbonding), +/// [`NodeAlreadyInFamily`] if the node has somehow joined another family +/// since the invitation was issued, [`InvitationNotFound`] if no pending +/// invitation exists for the pair, and [`InvitationExpired`] if it has. +/// +/// [`SenderDoesntControlNode`]: NodeFamiliesContractError::SenderDoesntControlNode +/// [`NodeAlreadyInFamily`]: NodeFamiliesContractError::NodeAlreadyInFamily +/// [`InvitationNotFound`]: NodeFamiliesContractError::InvitationNotFound +/// [`InvitationExpired`]: NodeFamiliesContractError::InvitationExpired +pub(crate) fn try_accept_family_invitation( + deps: DepsMut, + env: Env, + info: MessageInfo, + family_id: NodeFamilyId, + node_id: NodeId, +) -> Result { + let storage = NodeFamiliesStorage::new(); + + ensure_has_bonded_node(&storage, deps.as_ref(), &info.sender, node_id)?; + ensure_node_not_in_family(&storage, deps.as_ref(), node_id)?; + + storage.accept_invitation(deps.storage, &env, family_id, node_id)?; + + Ok(Response::new().add_event( + Event::new(events::FAMILY_INVITATION_ACCEPTED_EVENT_NAME) + .add_attribute( + events::FAMILY_INVITATION_ACCEPTED_EVENT_FAMILY_ID, + family_id.to_string(), + ) + .add_attribute( + events::FAMILY_INVITATION_ACCEPTED_EVENT_NODE_ID, + node_id.to_string(), + ), + )) +} + +/// Reject the pending invitation for `node_id` to join `family_id`. +/// +/// `info.sender` must be the bond controller of `node_id` per the mixnet +/// contract — rejection is the invitee's choice. Errors with +/// [`SenderDoesntControlNode`] if the sender doesn't control `node_id` (or +/// the node is unbonding) and [`InvitationNotFound`] if no pending invitation +/// exists for the pair. Expired invitations *can* be rejected — symmetric +/// with revocation, this is also a path that cleans them out of the pending +/// map. +/// +/// [`SenderDoesntControlNode`]: NodeFamiliesContractError::SenderDoesntControlNode +/// [`InvitationNotFound`]: NodeFamiliesContractError::InvitationNotFound +pub(crate) fn try_reject_family_invitation( + deps: DepsMut, + env: Env, + info: MessageInfo, + family_id: NodeFamilyId, + node_id: NodeId, +) -> Result { + let storage = NodeFamiliesStorage::new(); + + ensure_has_bonded_node(&storage, deps.as_ref(), &info.sender, node_id)?; + + storage.reject_pending_invitation(deps.storage, &env, family_id, node_id)?; + + Ok(Response::new().add_event( + Event::new(events::FAMILY_INVITATION_REJECTED_EVENT_NAME) + .add_attribute( + events::FAMILY_INVITATION_REJECTED_EVENT_FAMILY_ID, + family_id.to_string(), + ) + .add_attribute( + events::FAMILY_INVITATION_REJECTED_EVENT_NODE_ID, + node_id.to_string(), + ), + )) +} + +/// Remove `node_id` from whichever family it currently belongs to, at the +/// request of the node's controller. +/// +/// `info.sender` must be the bond controller of `node_id` per the mixnet +/// contract — a node only leaves of its own accord. Errors with +/// [`SenderDoesntControlNode`] if the sender doesn't control `node_id` (or +/// the node is unbonding) and [`NodeNotInFamily`] if the node isn't currently +/// a member of any family. +/// +/// The mixnet-contract unbonding callback drops a node from its family +/// independently (see [`try_handle_node_unbonding`]); this handler is the +/// voluntary-leave path and is not the one fired on unbond. +/// +/// [`SenderDoesntControlNode`]: NodeFamiliesContractError::SenderDoesntControlNode +/// [`NodeNotInFamily`]: NodeFamiliesContractError::NodeNotInFamily +pub(crate) fn try_leave_family( + deps: DepsMut, + env: Env, + info: MessageInfo, + node_id: NodeId, +) -> Result { + let storage = NodeFamiliesStorage::new(); + + ensure_has_bonded_node(&storage, deps.as_ref(), &info.sender, node_id)?; + + let family = storage.remove_family_member(deps.storage, &env, node_id)?; + + Ok(Response::new().add_event( + Event::new(events::FAMILY_MEMBER_LEFT_EVENT_NAME) + .add_attribute( + events::FAMILY_MEMBER_LEFT_EVENT_FAMILY_ID, + family.id.to_string(), + ) + .add_attribute( + events::FAMILY_MEMBER_LEFT_EVENT_NODE_ID, + node_id.to_string(), + ), + )) +} + +/// Kick `node_id` out of the family owned by `info.sender`. +/// +/// Owner-gated: the family acted on is derived from `info.sender`'s ownership +/// rather than passed as an argument, so a sender cannot kick from another +/// family. Errors with [`SenderDoesntOwnAFamily`] if the sender owns no +/// family, [`NodeNotInFamily`] if the node has no membership at all, and +/// [`NodeNotMemberOfFamily`] if the node is in a different family — the +/// scope check happens at the tx layer because `family_members` is keyed by +/// node only and `remove_family_member` would otherwise silently strip a +/// node from someone else's family. +/// +/// [`SenderDoesntOwnAFamily`]: NodeFamiliesContractError::SenderDoesntOwnAFamily +/// [`NodeNotInFamily`]: NodeFamiliesContractError::NodeNotInFamily +/// [`NodeNotMemberOfFamily`]: NodeFamiliesContractError::NodeNotMemberOfFamily +pub(crate) fn try_kick_from_family( + deps: DepsMut, + env: Env, + info: MessageInfo, + node_id: NodeId, +) -> Result { + let storage = NodeFamiliesStorage::new(); + + let owned = storage.must_get_owned_family(deps.storage, &info.sender)?; + + let membership = storage + .family_members + .may_load(deps.storage, node_id)? + .ok_or(NodeFamiliesContractError::NodeNotInFamily { node_id })?; + if membership.family_id != owned.id { + return Err(NodeFamiliesContractError::NodeNotMemberOfFamily { + node_id, + family_id: owned.id, + }); + } + + storage.remove_family_member(deps.storage, &env, node_id)?; + + Ok(Response::new().add_event( + Event::new(events::FAMILY_MEMBER_KICKED_EVENT_NAME) + .add_attribute( + events::FAMILY_MEMBER_KICKED_EVENT_FAMILY_ID, + owned.id.to_string(), + ) + .add_attribute( + events::FAMILY_MEMBER_KICKED_EVENT_NODE_ID, + node_id.to_string(), + ), + )) +} + +/// Cross-contract callback fired by the mixnet contract the moment `node_id` +/// initiates unbonding. Unbonding is irreversible, so from the families +/// contract's perspective the node is already effectively gone — drop it +/// from any family it currently belongs to and clear every pending +/// invitation issued to it. +/// +/// Auth: `info.sender` must equal the configured `mixnet_contract_address`, +/// since the mixnet contract is the only authority that can attest a node +/// has unbonded. Errors with [`UnauthorisedMixnetCallback`] otherwise. +/// +/// The membership half is idempotent — a node that initiates unbonding +/// without ever joining a family is the common case and is not an error. +/// Swept invitations are archived as +/// [`FamilyInvitationStatus::Rejected`]: the auto-cleanup shares the +/// `Rejected` terminal state with invitations that would have been +/// explicitly declined by the node controller. +/// +/// [`UnauthorisedMixnetCallback`]: NodeFamiliesContractError::UnauthorisedMixnetCallback +pub(crate) fn try_handle_node_unbonding( + deps: DepsMut, + env: Env, + info: MessageInfo, + node_id: NodeId, +) -> Result { + let storage = NodeFamiliesStorage::new(); + + let mixnet_contract = storage.mixnet_contract_address.load(deps.storage)?; + if info.sender != mixnet_contract { + return Err(NodeFamiliesContractError::UnauthorisedMixnetCallback { + sender: info.sender, + }); + } + + storage.handle_node_unbonding(deps.storage, &env, node_id)?; + + Ok(Response::new().add_event( + Event::new(events::NODE_UNBOND_CLEANUP_EVENT_NAME).add_attribute( + events::NODE_UNBOND_CLEANUP_EVENT_NODE_ID, + node_id.to_string(), + ), + )) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::testing::init_contract_tester; + use cosmwasm_std::coin; + use cosmwasm_std::testing::message_info; + use cw_controllers::AdminError; + use nym_contracts_common_testing::{AdminExt, ContractOpts, RandExt}; + + fn updated_config() -> Config { + Config { + create_family_fee: coin(999, "unym"), + family_name_length_limit: 1, + family_description_length_limit: 2, + default_invitation_validity_secs: 60, + } + } + + #[test] + fn admin_can_replace_the_config() { + let mut tester = init_contract_tester(); + let admin = tester.admin_msg(); + let new_config = updated_config(); + let env = tester.env(); + let res = try_update_config(tester.deps_mut(), env, admin, new_config.clone()); + assert!(res.is_ok()); + + let stored = NodeFamiliesStorage::new() + .config + .load(tester.deps().storage) + .unwrap(); + assert_eq!(stored, new_config); + } + + #[test] + fn non_admin_cannot_update_the_config() { + let mut tester = init_contract_tester(); + let not_admin = tester.generate_account(); + let not_admin = message_info(¬_admin, &[]); + + let original = NodeFamiliesStorage::new() + .config + .load(tester.deps().storage) + .unwrap(); + + let env = tester.env(); + let err = + try_update_config(tester.deps_mut(), env, not_admin, updated_config()).unwrap_err(); + + assert_eq!( + err, + NodeFamiliesContractError::Admin(AdminError::NotAdmin {}) + ); + + // config left untouched + let stored = NodeFamiliesStorage::new() + .config + .load(tester.deps().storage) + .unwrap(); + assert_eq!(stored, original); + } + + mod create_family { + use super::*; + use crate::testing::NodeFamiliesContractTesterExt; + use cosmwasm_std::coins; + use cw_utils::PaymentError; + use mixnet_contract::testable_mixnet_contract::EmbeddedMixnetContractExt; + use nym_contracts_common_testing::TEST_DENOM; + + #[test] + fn happy_path_persists_family_preserving_submitted_name() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let fee = tester.family_fee(); + let alice = tester.make_sender_with_funds("alice", &[fee]); + let env = tester.env(); + let deps = tester.deps_mut(); + + // user-submitted formatting includes punctuation + casing that + // the normaliser strips; both forms should end up on the stored + // record. + try_create_family( + deps, + env, + alice.clone(), + "My Family!".to_string(), + "description".to_string(), + )?; + + let storage = NodeFamiliesStorage::new(); + let family = storage.families.load(tester.deps().storage, 1)?; + assert_eq!(family.id, 1); + assert_eq!(family.name, "My Family!"); + assert_eq!(family.normalised_name, "myfamily"); + assert_eq!(family.owner, alice.sender); + assert_eq!(family.description, "description"); + assert_eq!(family.paid_fee, alice.funds[0]); + assert_eq!(family.members, 0); + + Ok(()) + } + + #[test] + fn rejects_when_no_funds_attached() { + let mut tester = init_contract_tester(); + let alice = tester.make_sender_with_funds("alice", &[]); + let env = tester.env(); + let deps = tester.deps_mut(); + + let err = try_create_family( + deps, + env, + alice.clone(), + "name".to_string(), + "description".to_string(), + ) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::InvalidDeposit(PaymentError::NoFunds {}) + ); + } + + #[test] + fn rejects_when_fee_amount_mismatched() { + let mut tester = init_contract_tester(); + let fee = tester.family_fee(); + let too_little = coins(fee.amount.u128() - 1, fee.denom.clone()); + let alice = tester.make_sender_with_funds("alice", &too_little); + let env = tester.env(); + let deps = tester.deps_mut(); + + let err = try_create_family( + deps, + env, + alice.clone(), + "name".to_string(), + "description".to_string(), + ) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::InvalidFamilyCreationFee { + expected: fee, + received: too_little, + } + ); + } + + #[test] + fn rejects_when_fee_denom_mismatched() { + let mut tester = init_contract_tester(); + + let fee = tester.family_fee(); + let wrong_denom = coins(fee.amount.u128(), "uatom"); + let alice = tester.make_sender_with_funds("alice", &wrong_denom); + let env = tester.env(); + let deps = tester.deps_mut(); + + let err = try_create_family( + deps, + env, + alice.clone(), + "name".to_string(), + "description".to_string(), + ) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::InvalidDeposit(PaymentError::MissingDenom( + TEST_DENOM.to_string() + )) + ); + } + + #[test] + fn rejects_name_exceeding_length_limit() { + let mut tester = init_contract_tester(); + + let fee = tester.family_fee(); + let alice = tester.make_sender_with_funds("alice", &[fee]); + + let limit = NodeFamiliesStorage::new() + .config + .load(tester.deps().storage) + .unwrap() + .family_name_length_limit; + let too_long: String = "a".repeat(limit + 1); + let env = tester.env(); + let deps = tester.deps_mut(); + + let err = try_create_family( + deps, + env, + alice, + too_long.to_string(), + "description".to_string(), + ) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::FamilyNameTooLong { + length: limit + 1, + limit, + } + ); + } + + #[test] + fn rejects_description_exceeding_length_limit() { + let mut tester = init_contract_tester(); + + let fee = tester.family_fee(); + let alice = tester.make_sender_with_funds("alice", &[fee]); + + let limit = NodeFamiliesStorage::new() + .config + .load(tester.deps().storage) + .unwrap() + .family_description_length_limit; + let too_long: String = "a".repeat(limit + 1); + let env = tester.env(); + let deps = tester.deps_mut(); + + let err = try_create_family(deps, env, alice, "name".to_string(), too_long.to_string()) + .unwrap_err(); + + assert_eq!( + err, + NodeFamiliesContractError::FamilyDescriptionTooLong { + length: limit + 1, + limit, + } + ); + } + + #[test] + fn rejects_name_that_normalises_to_empty() { + let mut tester = init_contract_tester(); + let env = tester.env(); + let alice = tester.make_sender_with_funds("alice", &[tester.family_fee()]); + let deps = tester.deps_mut(); + + let err = try_create_family( + deps, + env, + alice.clone(), + "!!! ---".to_string(), + "".to_string(), + ) + .unwrap_err(); + + assert_eq!(err, NodeFamiliesContractError::EmptyFamilyName); + } + + #[test] + fn rejects_when_sender_already_owns_a_family() { + let mut tester = init_contract_tester(); + let env = tester.env(); + let alice = tester.make_sender_with_funds("alice", &[tester.family_fee()]); + + tester.make_family(&alice.sender); + let deps = tester.deps_mut(); + + let err = try_create_family( + deps, + env, + alice.clone(), + "name".to_string(), + "description".to_string(), + ) + .unwrap_err(); + + assert_eq!( + err, + NodeFamiliesContractError::SenderAlreadyOwnsAFamily { + address: alice.sender, + family_id: 1, + } + ); + } + + #[test] + fn rejects_when_normalised_name_is_already_taken() { + let mut tester = init_contract_tester(); + let fee = vec![tester.family_fee()]; + let alice = tester.make_sender_with_funds("alice", &fee); + let bob = tester.make_sender_with_funds("bob", &fee); + let env = tester.env(); + + tester.make_named_family(&alice.sender, "MyFamily"); + let deps = tester.deps_mut(); + + // different casing / punctuation, same normalised form + let err = try_create_family( + deps, + env, + bob.clone(), + "$$myFaMiLy$$".to_string(), + "description".to_string(), + ) + .unwrap_err(); + + assert_eq!( + err, + NodeFamiliesContractError::FamilyNameAlreadyTaken { + name: "myfamily".to_string(), + family_id: 1, + } + ); + } + + #[test] + fn rejects_when_owner_owns_node_in_different_family() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let fee = tester.family_fee(); + let alice = tester.generate_account_with_balance(); + let env = tester.env(); + + let other_family = tester.make_family(&tester.addr_make("bob")); + let node_id = tester.bond_dummy_nymnode_for(&alice)?; + + let alice = message_info(&alice, &[fee]); + + // has node which is not in a family - that's still allowed! + let deps = tester.deps_mut(); + try_create_family( + deps, + env.clone(), + alice.clone(), + "My Family!".to_string(), + "description".to_string(), + )?; + tester.disband_family(2); + + // after joining family we error out + tester.add_to_family(other_family.id, node_id); + + let deps = tester.deps_mut(); + let err = try_create_family( + deps, + env.clone(), + alice.clone(), + "My Family!".to_string(), + "description".to_string(), + ) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::AlreadyInFamily { + address: alice.sender.clone(), + node_id, + family_id: other_family.id, + } + ); + + // after unbonding it is fine again + tester.unbond_nymnode(node_id)?; + let deps = tester.deps_mut(); + try_create_family( + deps, + env.clone(), + alice.clone(), + "My Family!".to_string(), + "description".to_string(), + )?; + + Ok(()) + } + } + + mod disband_family { + use super::*; + use crate::testing::NodeFamiliesContractTesterExt; + use cosmwasm_std::{BankMsg, CosmosMsg, SubMsg}; + + #[test] + fn happy_path_removes_family_and_refunds_fee() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + let info = message_info(&alice, &[]); + let env = tester.env(); + + let res = try_disband_family(tester.deps_mut(), env, info)?; + + // family is gone from storage + let storage = NodeFamiliesStorage::new(); + assert!(storage + .families + .may_load(tester.deps().storage, family.id)? + .is_none()); + + // single bank refund attached, going to the original owner with the + // exact paid fee + assert_eq!(res.messages.len(), 1); + assert_eq!( + res.messages[0], + SubMsg::new(CosmosMsg::Bank(BankMsg::Send { + to_address: alice.to_string(), + amount: vec![family.paid_fee.clone()], + })) + ); + + Ok(()) + } + + #[test] + fn rejects_when_sender_owns_no_family() { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let info = message_info(&alice, &[]); + let env = tester.env(); + + let err = try_disband_family(tester.deps_mut(), env, info).unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::SenderDoesntOwnAFamily { address: alice } + ); + } + + #[test] + fn rejects_when_family_still_has_members() { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + tester.add_to_family(family.id, 42); + + let info = message_info(&alice, &[]); + let env = tester.env(); + let err = try_disband_family(tester.deps_mut(), env, info).unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::FamilyNotEmpty { + family_id: family.id, + members: 1, + } + ); + } + + #[test] + fn after_disband_owner_can_create_a_new_family() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + tester.make_family(&alice); + + let env = tester.env(); + try_disband_family(tester.deps_mut(), env.clone(), message_info(&alice, &[]))?; + + // owner-index slot freed → a fresh create_family should succeed + let fee = tester.family_fee(); + let alice_with_fee = message_info(&alice, &[fee]); + try_create_family( + tester.deps_mut(), + env, + alice_with_fee, + "second".to_string(), + "".to_string(), + )?; + Ok(()) + } + } + + mod invite_to_family { + use super::*; + use crate::testing::NodeFamiliesContractTesterExt; + use mixnet_contract::testable_mixnet_contract::EmbeddedMixnetContractExt; + + #[test] + fn happy_path_persists_pending_invitation() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + let node_id = tester.bond_dummy_nymnode()?; + + let env = tester.env(); + let info = message_info(&alice, &[]); + try_invite_to_family(tester.deps_mut(), env.clone(), info, node_id, None)?; + + let storage = NodeFamiliesStorage::new(); + let invitation = storage + .pending_family_invitations + .load(tester.deps().storage, (family.id, node_id))?; + assert_eq!(invitation.family_id, family.id); + assert_eq!(invitation.node_id, node_id); + + let default_validity = storage + .config + .load(tester.deps().storage)? + .default_invitation_validity_secs; + assert_eq!( + invitation.expires_at, + env.block.time.seconds() + default_validity + ); + Ok(()) + } + + #[test] + fn custom_validity_overrides_default() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + let node_id = tester.bond_dummy_nymnode()?; + + let env = tester.env(); + let info = message_info(&alice, &[]); + try_invite_to_family(tester.deps_mut(), env.clone(), info, node_id, Some(5))?; + + let invitation = NodeFamiliesStorage::new() + .pending_family_invitations + .load(tester.deps().storage, (family.id, node_id))?; + assert_eq!(invitation.expires_at, env.block.time.seconds() + 5); + Ok(()) + } + + #[test] + fn rejects_zero_validity() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + tester.make_family(&alice); + let node_id = tester.bond_dummy_nymnode()?; + + let env = tester.env(); + let info = message_info(&alice, &[]); + let err = + try_invite_to_family(tester.deps_mut(), env, info, node_id, Some(0)).unwrap_err(); + assert_eq!(err, NodeFamiliesContractError::ZeroInvitationValidity); + Ok(()) + } + + #[test] + fn rejects_when_sender_owns_no_family() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let node_id = tester.bond_dummy_nymnode()?; + + let env = tester.env(); + let info = message_info(&alice, &[]); + let err = + try_invite_to_family(tester.deps_mut(), env, info, node_id, None).unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::SenderDoesntOwnAFamily { address: alice } + ); + Ok(()) + } + + #[test] + fn rejects_when_node_is_not_bonded() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + tester.make_family(&alice); + + let env = tester.env(); + let info = message_info(&alice, &[]); + let err = try_invite_to_family(tester.deps_mut(), env, info, 999, None).unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::NodeDoesntExist { node_id: 999 } + ); + Ok(()) + } + + #[test] + fn rejects_when_node_is_already_in_a_family() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let alice_family = tester.make_family(&alice); + let bob = tester.addr_make("bob"); + let bob_family = tester.make_family(&bob); + + let node_id = tester.bond_dummy_nymnode()?; + tester.add_to_family(bob_family.id, node_id); + + let env = tester.env(); + let info = message_info(&alice, &[]); + let err = + try_invite_to_family(tester.deps_mut(), env, info, node_id, None).unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::NodeAlreadyInFamily { + node_id, + family_id: bob_family.id, + } + ); + // alice's family is unchanged + assert!(NodeFamiliesStorage::new() + .pending_family_invitations + .may_load(tester.deps().storage, (alice_family.id, node_id))? + .is_none()); + Ok(()) + } + + #[test] + fn rejects_duplicate_pending_invitation() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + let node_id = tester.bond_dummy_nymnode()?; + + let env = tester.env(); + try_invite_to_family( + tester.deps_mut(), + env.clone(), + message_info(&alice, &[]), + node_id, + None, + )?; + let err = try_invite_to_family( + tester.deps_mut(), + env, + message_info(&alice, &[]), + node_id, + None, + ) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::PendingInvitationAlreadyExists { + family_id: family.id, + node_id, + } + ); + Ok(()) + } + } + + mod revoke_family_invitation { + use super::*; + use crate::testing::NodeFamiliesContractTesterExt; + use nym_node_families_contract_common::FamilyInvitationStatus; + + #[test] + fn happy_path_removes_pending_and_archives_revoked() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + let node_id = 7; + tester.invite_to_family(family.id, node_id); + + let env = tester.env(); + try_revoke_family_invitation( + tester.deps_mut(), + env.clone(), + message_info(&alice, &[]), + node_id, + )?; + + let storage = NodeFamiliesStorage::new(); + assert!(storage + .pending_family_invitations + .may_load(tester.deps().storage, (family.id, node_id))? + .is_none()); + + let archived = storage + .past_family_invitations + .load(tester.deps().storage, ((family.id, node_id), 0))?; + assert!(matches!( + archived.status, + FamilyInvitationStatus::Revoked { at } if at == env.block.time.seconds() + )); + Ok(()) + } + + #[test] + fn rejects_when_sender_owns_no_family() { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let env = tester.env(); + + let err = + try_revoke_family_invitation(tester.deps_mut(), env, message_info(&alice, &[]), 42) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::SenderDoesntOwnAFamily { address: alice } + ); + } + + #[test] + fn rejects_when_no_pending_invitation_for_node() { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + let env = tester.env(); + + let err = + try_revoke_family_invitation(tester.deps_mut(), env, message_info(&alice, &[]), 42) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::InvitationNotFound { + family_id: family.id, + node_id: 42, + } + ); + } + + #[test] + fn cannot_revoke_another_familys_invitation() { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let bob = tester.addr_make("bob"); + tester.make_family(&alice); + let bob_family = tester.make_family(&bob); + let node_id = 7; + tester.invite_to_family(bob_family.id, node_id); + + // alice is targeting node 7 — but there is no pending invitation + // in *her* family for it, so the lookup misses against alice's id + let env = tester.env(); + let err = try_revoke_family_invitation( + tester.deps_mut(), + env, + message_info(&alice, &[]), + node_id, + ) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::InvitationNotFound { + family_id: 1, + node_id, + } + ); + + // bob's invitation is still pending and untouched + let still_pending = NodeFamiliesStorage::new() + .pending_family_invitations + .may_load(tester.deps().storage, (bob_family.id, node_id)) + .unwrap(); + assert!(still_pending.is_some()); + } + + #[test] + fn revoking_expired_invitation_is_allowed() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + let node_id = 7; + // already-expired (expires_at = 1, well before block.time) + tester.invite_to_family_with_expiration(family.id, node_id, 1); + + let env = tester.env(); + try_revoke_family_invitation( + tester.deps_mut(), + env, + message_info(&alice, &[]), + node_id, + )?; + + // pending entry is gone + assert!(NodeFamiliesStorage::new() + .pending_family_invitations + .may_load(tester.deps().storage, (family.id, node_id))? + .is_none()); + Ok(()) + } + } + + mod accept_family_invitation { + use super::*; + use crate::testing::NodeFamiliesContractTesterExt; + use mixnet_contract::testable_mixnet_contract::EmbeddedMixnetContractExt; + use nym_node_families_contract_common::FamilyInvitationStatus; + + #[test] + fn happy_path_records_membership_and_archives_accepted() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + + let bob = tester.generate_account_with_balance(); + let node_id = tester.bond_dummy_nymnode_for(&bob)?; + tester.invite_to_family(family.id, node_id); + + let env = tester.env(); + try_accept_family_invitation( + tester.deps_mut(), + env.clone(), + message_info(&bob, &[]), + family.id, + node_id, + )?; + + let storage = NodeFamiliesStorage::new(); + assert!(storage + .pending_family_invitations + .may_load(tester.deps().storage, (family.id, node_id))? + .is_none()); + + let membership = storage + .family_members + .load(tester.deps().storage, node_id)?; + assert_eq!(membership.family_id, family.id); + assert_eq!(membership.joined_at, env.block.time.seconds()); + + let updated = storage.families.load(tester.deps().storage, family.id)?; + assert_eq!(updated.members, 1); + + let archived = storage + .past_family_invitations + .load(tester.deps().storage, ((family.id, node_id), 0))?; + assert!(matches!( + archived.status, + FamilyInvitationStatus::Accepted { at } if at == env.block.time.seconds() + )); + Ok(()) + } + + #[test] + fn rejects_when_sender_controls_no_bonded_node() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + let node_id = tester.bond_dummy_nymnode()?; + tester.invite_to_family(family.id, node_id); + + // mallory doesn't control any bonded node + let mallory = tester.addr_make("mallory"); + let env = tester.env(); + let err = try_accept_family_invitation( + tester.deps_mut(), + env, + message_info(&mallory, &[]), + family.id, + node_id, + ) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::SenderDoesntControlNode { + address: mallory, + node_id, + } + ); + Ok(()) + } + + #[test] + fn rejects_when_sender_controls_a_different_node() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + + let bob = tester.generate_account_with_balance(); + let bob_node = tester.bond_dummy_nymnode_for(&bob)?; + // invitation targets a different (also-bonded) node + let other_node = tester.bond_dummy_nymnode()?; + tester.invite_to_family(family.id, other_node); + + let env = tester.env(); + let err = try_accept_family_invitation( + tester.deps_mut(), + env, + message_info(&bob, &[]), + family.id, + other_node, + ) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::SenderDoesntControlNode { + address: bob, + node_id: other_node, + } + ); + // sanity: bob really does control bob_node + assert_ne!(bob_node, other_node); + Ok(()) + } + + #[test] + fn rejects_when_sender_node_is_unbonding() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + let bob = tester.generate_account_with_balance(); + let node_id = tester.bond_dummy_nymnode_for(&bob)?; + tester.invite_to_family(family.id, node_id); + + // unbond_nymnode advances the epoch, fully removing the bond from + // the mixnet store — the ownership query then returns None, which + // surfaces as the same SenderDoesntControlNode error as + // "no bonded node at all". + tester.unbond_nymnode(node_id)?; + + let env = tester.env(); + let err = try_accept_family_invitation( + tester.deps_mut(), + env, + message_info(&bob, &[]), + family.id, + node_id, + ) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::SenderDoesntControlNode { + address: bob, + node_id, + } + ); + Ok(()) + } + + #[test] + fn rejects_when_no_pending_invitation_exists() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + let bob = tester.generate_account_with_balance(); + let node_id = tester.bond_dummy_nymnode_for(&bob)?; + + let env = tester.env(); + let err = try_accept_family_invitation( + tester.deps_mut(), + env, + message_info(&bob, &[]), + family.id, + node_id, + ) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::InvitationNotFound { + family_id: family.id, + node_id, + } + ); + Ok(()) + } + + #[test] + fn rejects_when_invitation_is_expired() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + let bob = tester.generate_account_with_balance(); + let node_id = tester.bond_dummy_nymnode_for(&bob)?; + + let env = tester.env(); + // expires_at == now triggers the `now >= expires_at` branch + tester.invite_to_family_with_expiration(family.id, node_id, env.block.time.seconds()); + + let err = try_accept_family_invitation( + tester.deps_mut(), + env.clone(), + message_info(&bob, &[]), + family.id, + node_id, + ) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::InvitationExpired { + family_id: family.id, + node_id, + expires_at: env.block.time.seconds(), + now: env.block.time.seconds(), + } + ); + Ok(()) + } + + #[test] + fn rejects_when_node_already_in_another_family() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let alice_family = tester.make_family(&alice); + let bob = tester.addr_make("bob"); + let bob_family = tester.make_family(&bob); + + let bob = tester.generate_account_with_balance(); + let node_id = tester.bond_dummy_nymnode_for(&bob)?; + + // bob's node joins bob's family first, then tries to accept + // alice's still-pending invitation + tester.invite_to_family(alice_family.id, node_id); + tester.add_to_family(bob_family.id, node_id); + + let env = tester.env(); + let err = try_accept_family_invitation( + tester.deps_mut(), + env, + message_info(&bob, &[]), + alice_family.id, + node_id, + ) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::NodeAlreadyInFamily { + node_id, + family_id: bob_family.id, + } + ); + + // membership is unchanged — still in bob's family + let membership = NodeFamiliesStorage::new() + .family_members + .load(tester.deps().storage, node_id)?; + assert_eq!(membership.family_id, bob_family.id); + Ok(()) + } + } + + mod reject_family_invitation { + use super::*; + use crate::testing::NodeFamiliesContractTesterExt; + use mixnet_contract::testable_mixnet_contract::EmbeddedMixnetContractExt; + use nym_node_families_contract_common::FamilyInvitationStatus; + + #[test] + fn happy_path_removes_pending_and_archives_rejected() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + + let bob = tester.generate_account_with_balance(); + let node_id = tester.bond_dummy_nymnode_for(&bob)?; + tester.invite_to_family(family.id, node_id); + + let env = tester.env(); + try_reject_family_invitation( + tester.deps_mut(), + env.clone(), + message_info(&bob, &[]), + family.id, + node_id, + )?; + + let storage = NodeFamiliesStorage::new(); + assert!(storage + .pending_family_invitations + .may_load(tester.deps().storage, (family.id, node_id))? + .is_none()); + + let archived = storage + .past_family_invitations + .load(tester.deps().storage, ((family.id, node_id), 0))?; + assert!(matches!( + archived.status, + FamilyInvitationStatus::Rejected { at } if at == env.block.time.seconds() + )); + + // membership was never recorded + assert!(storage + .family_members + .may_load(tester.deps().storage, node_id)? + .is_none()); + Ok(()) + } + + #[test] + fn rejects_when_sender_controls_no_bonded_node() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + let node_id = tester.bond_dummy_nymnode()?; + tester.invite_to_family(family.id, node_id); + + let mallory = tester.addr_make("mallory"); + let env = tester.env(); + let err = try_reject_family_invitation( + tester.deps_mut(), + env, + message_info(&mallory, &[]), + family.id, + node_id, + ) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::SenderDoesntControlNode { + address: mallory, + node_id, + } + ); + Ok(()) + } + + #[test] + fn rejects_when_sender_controls_a_different_node() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + + let bob = tester.generate_account_with_balance(); + let bob_node = tester.bond_dummy_nymnode_for(&bob)?; + let other_node = tester.bond_dummy_nymnode()?; + tester.invite_to_family(family.id, other_node); + + let env = tester.env(); + let err = try_reject_family_invitation( + tester.deps_mut(), + env, + message_info(&bob, &[]), + family.id, + other_node, + ) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::SenderDoesntControlNode { + address: bob, + node_id: other_node, + } + ); + assert_ne!(bob_node, other_node); + Ok(()) + } + + #[test] + fn rejects_when_sender_node_is_unbonding() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + let bob = tester.generate_account_with_balance(); + let node_id = tester.bond_dummy_nymnode_for(&bob)?; + tester.invite_to_family(family.id, node_id); + + tester.unbond_nymnode(node_id)?; + + let env = tester.env(); + let err = try_reject_family_invitation( + tester.deps_mut(), + env, + message_info(&bob, &[]), + family.id, + node_id, + ) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::SenderDoesntControlNode { + address: bob, + node_id, + } + ); + Ok(()) + } + + #[test] + fn rejects_when_no_pending_invitation_exists() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + let bob = tester.generate_account_with_balance(); + let node_id = tester.bond_dummy_nymnode_for(&bob)?; + + let env = tester.env(); + let err = try_reject_family_invitation( + tester.deps_mut(), + env, + message_info(&bob, &[]), + family.id, + node_id, + ) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::InvitationNotFound { + family_id: family.id, + node_id, + } + ); + Ok(()) + } + + #[test] + fn rejecting_expired_invitation_is_allowed() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + let bob = tester.generate_account_with_balance(); + let node_id = tester.bond_dummy_nymnode_for(&bob)?; + + let env = tester.env(); + // already-expired (expires_at == now) + tester.invite_to_family_with_expiration(family.id, node_id, env.block.time.seconds()); + + try_reject_family_invitation( + tester.deps_mut(), + env.clone(), + message_info(&bob, &[]), + family.id, + node_id, + )?; + + let storage = NodeFamiliesStorage::new(); + assert!(storage + .pending_family_invitations + .may_load(tester.deps().storage, (family.id, node_id))? + .is_none()); + let archived = storage + .past_family_invitations + .load(tester.deps().storage, ((family.id, node_id), 0))?; + assert!(matches!( + archived.status, + FamilyInvitationStatus::Rejected { at } if at == env.block.time.seconds() + )); + Ok(()) + } + } + + mod leave_family { + use super::*; + use crate::testing::NodeFamiliesContractTesterExt; + use mixnet_contract::testable_mixnet_contract::EmbeddedMixnetContractExt; + + #[test] + fn happy_path_drops_membership_and_archives_past_member() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + + let bob = tester.generate_account_with_balance(); + let node_id = tester.bond_dummy_nymnode_for(&bob)?; + tester.add_to_family(family.id, node_id); + + // sanity: family has the member, count is 1 + let storage = NodeFamiliesStorage::new(); + assert_eq!( + storage + .families + .load(tester.deps().storage, family.id)? + .members, + 1 + ); + + let env = tester.env(); + try_leave_family( + tester.deps_mut(), + env.clone(), + message_info(&bob, &[]), + node_id, + )?; + + // membership gone + assert!(storage + .family_members + .may_load(tester.deps().storage, node_id)? + .is_none()); + + // family count decremented + let updated = storage.families.load(tester.deps().storage, family.id)?; + assert_eq!(updated.members, 0); + + // archived as past member + let past = storage + .past_family_members + .load(tester.deps().storage, ((family.id, node_id), 0))?; + assert_eq!(past.family_id, family.id); + assert_eq!(past.node_id, node_id); + assert_eq!(past.removed_at, env.block.time.seconds()); + Ok(()) + } + + #[test] + fn rejects_when_sender_controls_no_bonded_node() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + let node_id = tester.bond_dummy_nymnode()?; + tester.add_to_family(family.id, node_id); + + let mallory = tester.addr_make("mallory"); + let env = tester.env(); + let err = + try_leave_family(tester.deps_mut(), env, message_info(&mallory, &[]), node_id) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::SenderDoesntControlNode { + address: mallory, + node_id, + } + ); + Ok(()) + } + + #[test] + fn rejects_when_sender_controls_a_different_node() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + + let bob = tester.generate_account_with_balance(); + let bob_node = tester.bond_dummy_nymnode_for(&bob)?; + let other_node = tester.bond_dummy_nymnode()?; + tester.add_to_family(family.id, other_node); + + let env = tester.env(); + let err = try_leave_family(tester.deps_mut(), env, message_info(&bob, &[]), other_node) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::SenderDoesntControlNode { + address: bob, + node_id: other_node, + } + ); + assert_ne!(bob_node, other_node); + Ok(()) + } + + #[test] + fn rejects_when_sender_node_is_unbonding() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + let bob = tester.generate_account_with_balance(); + let node_id = tester.bond_dummy_nymnode_for(&bob)?; + tester.add_to_family(family.id, node_id); + + tester.unbond_nymnode(node_id)?; + + let env = tester.env(); + let err = try_leave_family(tester.deps_mut(), env, message_info(&bob, &[]), node_id) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::SenderDoesntControlNode { + address: bob, + node_id, + } + ); + Ok(()) + } + + #[test] + fn rejects_when_node_is_not_in_any_family() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let bob = tester.generate_account_with_balance(); + let node_id = tester.bond_dummy_nymnode_for(&bob)?; + + let env = tester.env(); + let err = try_leave_family(tester.deps_mut(), env, message_info(&bob, &[]), node_id) + .unwrap_err(); + assert_eq!(err, NodeFamiliesContractError::NodeNotInFamily { node_id }); + Ok(()) + } + } + + mod kick_from_family { + use super::*; + use crate::testing::NodeFamiliesContractTesterExt; + use mixnet_contract::testable_mixnet_contract::EmbeddedMixnetContractExt; + + #[test] + fn happy_path_drops_membership_and_archives_past_member() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + let node_id = tester.bond_dummy_nymnode()?; + tester.add_to_family(family.id, node_id); + + let env = tester.env(); + try_kick_from_family( + tester.deps_mut(), + env.clone(), + message_info(&alice, &[]), + node_id, + )?; + + let storage = NodeFamiliesStorage::new(); + assert!(storage + .family_members + .may_load(tester.deps().storage, node_id)? + .is_none()); + + let updated = storage.families.load(tester.deps().storage, family.id)?; + assert_eq!(updated.members, 0); + + let past = storage + .past_family_members + .load(tester.deps().storage, ((family.id, node_id), 0))?; + assert_eq!(past.family_id, family.id); + assert_eq!(past.node_id, node_id); + assert_eq!(past.removed_at, env.block.time.seconds()); + Ok(()) + } + + #[test] + fn rejects_when_sender_owns_no_family() { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let env = tester.env(); + + let err = try_kick_from_family(tester.deps_mut(), env, message_info(&alice, &[]), 42) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::SenderDoesntOwnAFamily { address: alice } + ); + } + + #[test] + fn rejects_when_node_is_not_in_any_family() { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + tester.make_family(&alice); + let env = tester.env(); + + let err = try_kick_from_family(tester.deps_mut(), env, message_info(&alice, &[]), 42) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::NodeNotInFamily { node_id: 42 } + ); + } + + #[test] + fn cannot_kick_member_of_another_family() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let bob = tester.addr_make("bob"); + let alice_family = tester.make_family(&alice); + let bob_family = tester.make_family(&bob); + + let node_id = tester.bond_dummy_nymnode()?; + tester.add_to_family(bob_family.id, node_id); + + // alice is targeting a node in bob's family — must error rather + // than silently strip the membership + let env = tester.env(); + let err = + try_kick_from_family(tester.deps_mut(), env, message_info(&alice, &[]), node_id) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::NodeNotMemberOfFamily { + node_id, + family_id: alice_family.id, + } + ); + + // bob's membership and family count are untouched + let storage = NodeFamiliesStorage::new(); + let mem = storage + .family_members + .load(tester.deps().storage, node_id)?; + assert_eq!(mem.family_id, bob_family.id); + let bob_fam = storage + .families + .load(tester.deps().storage, bob_family.id)?; + assert_eq!(bob_fam.members, 1); + Ok(()) + } + + #[test] + fn cannot_kick_member_already_cleared_by_unbond_callback() -> anyhow::Result<()> { + // The mixnet contract dispatches `OnNymNodeUnbond` to the families + // contract synchronously when a node initiates unbonding, so by + // the time `unbond_nymnode` returns the membership is already gone. + // A subsequent manual kick from the owner has nothing left to act + // on and surfaces `NodeNotInFamily`. + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + + let bob = tester.generate_account_with_balance(); + let node_id = tester.bond_dummy_nymnode_for(&bob)?; + tester.add_to_family(family.id, node_id); + tester.unbond_nymnode(node_id)?; + + // sanity: the unbond callback already cleaned up the membership + let storage = NodeFamiliesStorage::new(); + assert!(storage + .family_members + .may_load(tester.deps().storage, node_id)? + .is_none()); + + let env = tester.env(); + let err = + try_kick_from_family(tester.deps_mut(), env, message_info(&alice, &[]), node_id) + .unwrap_err(); + assert_eq!(err, NodeFamiliesContractError::NodeNotInFamily { node_id }); + Ok(()) + } + } + + mod handle_node_unbonding { + use super::*; + use crate::testing::NodeFamiliesContractTesterExt; + use cosmwasm_std::Addr; + use mixnet_contract::testable_mixnet_contract::EmbeddedMixnetContractExt; + use nym_node_families_contract_common::FamilyInvitationStatus; + + fn mixnet_addr(tester: &impl NodeFamiliesContractTesterExt) -> Addr { + NodeFamiliesStorage::new() + .mixnet_contract_address + .load(tester.deps().storage) + .unwrap() + } + + #[test] + fn rejects_when_sender_is_not_the_mixnet_contract() { + let mut tester = init_contract_tester(); + let mallory = tester.addr_make("mallory"); + let env = tester.env(); + + let err = + try_handle_node_unbonding(tester.deps_mut(), env, message_info(&mallory, &[]), 42) + .unwrap_err(); + assert_eq!( + err, + NodeFamiliesContractError::UnauthorisedMixnetCallback { sender: mallory } + ); + } + + #[test] + fn no_op_when_node_has_no_membership_and_no_invitations() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let env = tester.env(); + let mixnet = mixnet_addr(&tester); + + // node 42 has nothing in the contract — callback succeeds anyway + try_handle_node_unbonding(tester.deps_mut(), env, message_info(&mixnet, &[]), 42)?; + Ok(()) + } + + #[test] + fn drops_membership_when_node_is_a_member() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let family = tester.make_family(&alice); + let node_id = tester.bond_dummy_nymnode()?; + tester.add_to_family(family.id, node_id); + + let env = tester.env(); + let mixnet = mixnet_addr(&tester); + try_handle_node_unbonding( + tester.deps_mut(), + env.clone(), + message_info(&mixnet, &[]), + node_id, + )?; + + let storage = NodeFamiliesStorage::new(); + assert!(storage + .family_members + .may_load(tester.deps().storage, node_id)? + .is_none()); + let updated = storage.families.load(tester.deps().storage, family.id)?; + assert_eq!(updated.members, 0); + let past = storage + .past_family_members + .load(tester.deps().storage, ((family.id, node_id), 0))?; + assert_eq!(past.removed_at, env.block.time.seconds()); + Ok(()) + } + + #[test] + fn sweeps_pending_invitations_addressed_to_node() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let bob = tester.addr_make("bob"); + let alice_family = tester.make_family(&alice); + let bob_family = tester.make_family(&bob); + + let node_id = tester.bond_dummy_nymnode()?; + tester.invite_to_family(alice_family.id, node_id); + tester.invite_to_family(bob_family.id, node_id); + + let env = tester.env(); + let mixnet = mixnet_addr(&tester); + try_handle_node_unbonding( + tester.deps_mut(), + env.clone(), + message_info(&mixnet, &[]), + node_id, + )?; + + let storage = NodeFamiliesStorage::new(); + // both pending invitations are gone + assert!(storage + .pending_family_invitations + .may_load(tester.deps().storage, (alice_family.id, node_id))? + .is_none()); + assert!(storage + .pending_family_invitations + .may_load(tester.deps().storage, (bob_family.id, node_id))? + .is_none()); + + // both archived as Rejected + for fam_id in [alice_family.id, bob_family.id] { + let past = storage + .past_family_invitations + .load(tester.deps().storage, ((fam_id, node_id), 0))?; + assert!(matches!( + past.status, + FamilyInvitationStatus::Rejected { at } if at == env.block.time.seconds() + )); + } + Ok(()) + } + + #[test] + fn handles_membership_and_invitation_sweep_together() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let bob = tester.addr_make("bob"); + let alice_family = tester.make_family(&alice); + let bob_family = tester.make_family(&bob); + + let node_id = tester.bond_dummy_nymnode()?; + // node is a member of alice's family AND has a pending invite from bob's + tester.add_to_family(alice_family.id, node_id); + tester.invite_to_family(bob_family.id, node_id); + + let env = tester.env(); + let mixnet = mixnet_addr(&tester); + try_handle_node_unbonding( + tester.deps_mut(), + env.clone(), + message_info(&mixnet, &[]), + node_id, + )?; + + let storage = NodeFamiliesStorage::new(); + // membership gone + assert!(storage + .family_members + .may_load(tester.deps().storage, node_id)? + .is_none()); + assert_eq!( + storage + .families + .load(tester.deps().storage, alice_family.id)? + .members, + 0 + ); + // past member record stamped + let past_member = storage + .past_family_members + .load(tester.deps().storage, ((alice_family.id, node_id), 0))?; + assert_eq!(past_member.removed_at, env.block.time.seconds()); + + // pending invitation from bob's family is swept + assert!(storage + .pending_family_invitations + .may_load(tester.deps().storage, (bob_family.id, node_id))? + .is_none()); + let archived = storage + .past_family_invitations + .load(tester.deps().storage, ((bob_family.id, node_id), 0))?; + assert!(matches!( + archived.status, + FamilyInvitationStatus::Rejected { at } if at == env.block.time.seconds() + )); + Ok(()) + } + + #[test] + fn unrelated_invitations_are_left_untouched() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let alice_family = tester.make_family(&alice); + + let unbonding_node = tester.bond_dummy_nymnode()?; + let other_node = tester.bond_dummy_nymnode()?; + tester.invite_to_family(alice_family.id, unbonding_node); + tester.invite_to_family(alice_family.id, other_node); + + let env = tester.env(); + let mixnet = mixnet_addr(&tester); + try_handle_node_unbonding( + tester.deps_mut(), + env, + message_info(&mixnet, &[]), + unbonding_node, + )?; + + let storage = NodeFamiliesStorage::new(); + // unbonding node's invitation is gone + assert!(storage + .pending_family_invitations + .may_load(tester.deps().storage, (alice_family.id, unbonding_node))? + .is_none()); + // the unrelated invitation is still pending + assert!(storage + .pending_family_invitations + .may_load(tester.deps().storage, (alice_family.id, other_node))? + .is_some()); + Ok(()) + } + } +} diff --git a/contracts/performance/Cargo.toml b/contracts/performance/Cargo.toml index 78069a02de..18d434f578 100644 --- a/contracts/performance/Cargo.toml +++ b/contracts/performance/Cargo.toml @@ -36,6 +36,13 @@ nym-contracts-common-testing = { workspace = true } nym-mixnet-contract = { workspace = true, features = ["testable-mixnet-contract"] } nym-crypto = { workspace = true, features = ["asymmetric", "rand"] } +# Needed only by the test harness: the embedded mixnet contract dispatches an +# `OnNymNodeUnbond` WasmMsg on `try_remove_nym_node` and the target must be a +# real contract. We instantiate the families contract alongside so the call +# lands somewhere that knows how to handle it. +node-families = { workspace = true, features = ["testable-node-families-contract"] } +nym-node-families-contract-common = { workspace = true } + [features] schema-gen = ["nym-performance-contract-common/schema", "cosmwasm-schema"] diff --git a/contracts/performance/src/helpers.rs b/contracts/performance/src/helpers.rs deleted file mode 100644 index 8219910787..0000000000 --- a/contracts/performance/src/helpers.rs +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2025 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use cosmwasm_std::{from_json, Binary, CustomQuery, QuerierWrapper, StdError, StdResult}; -use cw_storage_plus::{Key, Namespace, Path, PrimaryKey}; -use nym_mixnet_contract_common::{Interval, NymNodeBond}; -use nym_performance_contract_common::{EpochId, NodeId}; -use serde::de::DeserializeOwned; -use std::ops::Deref; - -pub(crate) trait MixnetContractQuerier { - #[allow(dead_code)] - fn query_mixnet_contract( - &self, - address: impl Into, - msg: &nym_mixnet_contract_common::QueryMsg, - ) -> StdResult; - - fn query_mixnet_contract_storage( - &self, - address: impl Into, - key: impl Into, - ) -> StdResult>>; - - fn query_mixnet_contract_storage_value( - &self, - address: impl Into, - key: impl Into, - ) -> StdResult> { - match self.query_mixnet_contract_storage(address, key)? { - None => Ok(None), - Some(value) => Ok(Some(from_json(&value)?)), - } - } - - fn query_current_mixnet_interval(&self, address: impl Into) -> StdResult { - self.query_mixnet_contract_storage_value(address, b"ci")? - .ok_or(StdError::not_found( - "unable to retrieve interval information from the mixnet contract storage", - )) - } - - fn query_current_absolute_mixnet_epoch_id( - &self, - address: impl Into, - ) -> StdResult { - self.query_current_mixnet_interval(address) - .map(|interval| interval.current_epoch_absolute_id()) - } - - fn check_node_existence(&self, address: impl Into, node_id: NodeId) -> StdResult { - let mixnet_contract_address = address.into(); - - if let Some(nym_node) = self.query_nymnode_bond(mixnet_contract_address.clone(), node_id)? { - return Ok(!nym_node.is_unbonding); - } - - Ok(false) - } - - fn query_nymnode_bond( - &self, - address: impl Into, - node_id: NodeId, - ) -> StdResult> { - // construct proper map key - let pk_namespace = "nn"; - let path: Path = Path::new( - Namespace::from_static_str(pk_namespace).as_slice(), - &node_id.key().iter().map(Key::as_ref).collect::>(), - ); - let storage_key = path.deref(); - - self.query_mixnet_contract_storage_value(address, storage_key) - } -} - -impl MixnetContractQuerier for QuerierWrapper<'_, C> -where - C: CustomQuery, -{ - fn query_mixnet_contract( - &self, - address: impl Into, - msg: &nym_mixnet_contract_common::QueryMsg, - ) -> StdResult { - self.query_wasm_smart(address, msg) - } - - fn query_mixnet_contract_storage( - &self, - address: impl Into, - key: impl Into, - ) -> StdResult>> { - self.query_wasm_raw(address, key) - } -} diff --git a/contracts/performance/src/lib.rs b/contracts/performance/src/lib.rs index 08a2b9651d..d97317410b 100644 --- a/contracts/performance/src/lib.rs +++ b/contracts/performance/src/lib.rs @@ -5,7 +5,6 @@ pub mod contract; pub mod queued_migrations; pub mod storage; -mod helpers; mod queries; mod transactions; diff --git a/contracts/performance/src/queries.rs b/contracts/performance/src/queries.rs index 5fe2c3ed91..c32cbd6a4c 100644 --- a/contracts/performance/src/queries.rs +++ b/contracts/performance/src/queries.rs @@ -316,6 +316,7 @@ pub fn query_last_submission(deps: Deps) -> Result // SPDX-License-Identifier: Apache-2.0 -use crate::helpers::MixnetContractQuerier; use cosmwasm_std::{Addr, Deps, DepsMut, Env, StdError, Storage}; use cw_controllers::Admin; use cw_storage_plus::{Item, Map}; use nym_contracts_common::Percent; +use nym_mixnet_contract_common::MixnetContractQuerier; use nym_performance_contract_common::constants::storage_keys; use nym_performance_contract_common::{ BatchSubmissionResult, EpochId, LastSubmission, LastSubmittedData, NetworkMonitorDetails, @@ -580,6 +580,7 @@ mod tests { mod performance_contract_storage { use super::*; use crate::testing::{init_contract_tester, PerformanceContractTesterExt, PreInitContract}; + use mixnet_contract::testable_mixnet_contract::EmbeddedMixnetContractExt; use nym_contracts_common_testing::{AdminExt, ContractOpts}; #[cfg(test)] @@ -2856,6 +2857,7 @@ mod tests { mod performance_storage { use super::*; use crate::testing::{init_contract_tester, PerformanceContractTesterExt}; + use mixnet_contract::testable_mixnet_contract::EmbeddedMixnetContractExt; use nym_contracts_common_testing::ContractOpts; use std::str::FromStr; diff --git a/contracts/performance/src/testing/mod.rs b/contracts/performance/src/testing/mod.rs index 33e90beaf3..bdf0df09f0 100644 --- a/contracts/performance/src/testing/mod.rs +++ b/contracts/performance/src/testing/mod.rs @@ -2,15 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 use crate::contract::{execute, instantiate, migrate, query}; -use crate::helpers::MixnetContractQuerier; use crate::storage::NYM_PERFORMANCE_CONTRACT_STORAGE; -use cosmwasm_std::testing::{message_info, mock_env, MockApi}; +use cosmwasm_std::testing::{mock_env, MockApi}; use cosmwasm_std::{ - coin, coins, Addr, ContractInfo, Deps, DepsMut, Env, MessageInfo, QuerierWrapper, StdError, - StdResult, + coin, Addr, ContractInfo, Deps, DepsMut, Env, QuerierWrapper, StdError, StdResult, }; -use mixnet_contract::testable_mixnet_contract::MixnetContract; -use nym_contracts_common::signing::{ContractMessageContent, MessageSignature}; +use mixnet_contract::testable_mixnet_contract::{EmbeddedMixnetContractExt, MixnetContract}; +use node_families_contract::testing::NodeFamiliesContract; use nym_contracts_common::Percent; use nym_contracts_common_testing::{ addr, AdminExt, ArbitraryContractStorageReader, ArbitraryContractStorageWriter, BankExt, @@ -18,19 +16,15 @@ use nym_contracts_common_testing::{ ContractTesterBuilder, DenomExt, PermissionedFn, QueryFn, RandExt, TestableNymContract, TEST_DENOM, }; -use nym_crypto::asymmetric::ed25519; -use nym_mixnet_contract_common::nym_node::{NodeDetailsResponse, NodeOwnershipResponse, Role}; -use nym_mixnet_contract_common::{ - CurrentIntervalResponse, EpochId, Interval, NodeCostParams, NymNode, NymNodeBondingPayload, - RoleAssignment, SignableNymNodeBondingMsg, DEFAULT_INTERVAL_OPERATING_COST_AMOUNT, - DEFAULT_PROFIT_MARGIN_PERCENT, +use nym_mixnet_contract_common::{ContractState, EpochId}; +use nym_node_families_contract_common::{ + Config as NodeFamiliesConfig, InstantiateMsg as NodeFamiliesInstantiateMsg, }; use nym_performance_contract_common::constants::storage_keys; use nym_performance_contract_common::{ ExecuteMsg, InstantiateMsg, MigrateMsg, NodeId, NodePerformance, NodeResults, NymPerformanceContractError, QueryMsg, }; -use serde::de::DeserializeOwned; use serde::Serialize; use std::str::FromStr; @@ -80,6 +74,22 @@ impl TestableNymContract for PerformanceContract { .unwrap() .clone(); + // The embedded mixnet's `try_remove_nym_node` always emits an + // `OnNymNodeUnbond` WasmMsg to the configured families contract; + // instantiate one alongside so that target exists and accepts the call. + // `init_contract_tester` patches the mixnet's stored families address + // to point at this instance after the build completes. + let builder = + builder.instantiate::(Some(NodeFamiliesInstantiateMsg { + config: NodeFamiliesConfig { + create_family_fee: coin(100_000000, TEST_DENOM), + family_name_length_limit: 20, + family_description_length_limit: 200, + default_invitation_validity_secs: 24 * 60 * 60, + }, + mixnet_contract_address: mixnet_address.to_string(), + })); + builder .instantiate::(Some(InstantiateMsg { mixnet_contract_address: mixnet_address.to_string(), @@ -89,9 +99,35 @@ impl TestableNymContract for PerformanceContract { } } +/// Storage key the mixnet contract uses for its `ContractState` `Item` +/// (mirrors `mixnet/src/constants.rs::CONTRACT_STATE_KEY`). +const MIXNET_CONTRACT_STATE_STORAGE_KEY: &str = "state"; + pub fn init_contract_tester() -> ContractTester { - PerformanceContract::init() - .with_common_storage_key(CommonStorageKeys::Admin, storage_keys::CONTRACT_ADMIN) + let mut tester = PerformanceContract::init() + .with_common_storage_key(CommonStorageKeys::Admin, storage_keys::CONTRACT_ADMIN); + + // Chicken-and-egg: the mixnet contract was instantiated first with a + // placeholder `node_families_contract_address`. Now that the families + // contract exists, patch the mixnet's `ContractState` so its + // `OnNymNodeUnbond` dispatch lands on the real contract instead of the + // placeholder. In production this fixup happens via a contract migration; + // here we go straight to storage to avoid the cw2 version check that + // blocks migrating a freshly-instantiated contract. + let families_address = tester + .well_known_contracts + .get(NodeFamiliesContract::NAME) + .expect("families contract should have been instantiated") + .clone(); + let mut mixnet_state: ContractState = tester + .read_from_mixnet_contract_storage(MIXNET_CONTRACT_STATE_STORAGE_KEY) + .expect("mixnet contract state should be loadable"); + mixnet_state.node_families_contract_address = families_address; + tester + .write_to_mixnet_contract_storage_value(MIXNET_CONTRACT_STATE_STORAGE_KEY, &mixnet_state) + .expect("should be able to patch mixnet contract state"); + + tester } // we need to be able to test instantiation, but for that we require @@ -214,136 +250,8 @@ pub(crate) trait PerformanceContractTesterExt: + BankExt + ArbitraryContractStorageReader + ArbitraryContractStorageWriter + + EmbeddedMixnetContractExt { - fn mixnet_contract_address(&self) -> StdResult { - NYM_PERFORMANCE_CONTRACT_STORAGE - .mixnet_contract_address - .load(self.deps().storage) - } - - fn execute_mixnet_contract( - &mut self, - sender: MessageInfo, - msg: &nym_mixnet_contract_common::ExecuteMsg, - ) -> StdResult<()> { - let address = self.mixnet_contract_address()?; - - self.execute_arbitrary_contract(address, sender, msg) - .map_err(|err| { - StdError::generic_err(format!("mixnet contract execution failure: {err}")) - })?; - Ok(()) - } - - fn read_from_mixnet_contract_storage( - &self, - key: impl AsRef<[u8]>, - ) -> StdResult { - let address = self.mixnet_contract_address()?; - - self.must_read_value_from_contract_storage(address, key) - } - - fn write_to_mixnet_contract_storage( - &mut self, - key: impl AsRef<[u8]>, - value: impl AsRef<[u8]>, - ) -> StdResult<()> { - let address = self.mixnet_contract_address()?; - - ::set_contract_storage(self, address, key, value); - Ok(()) - } - - fn write_to_mixnet_contract_storage_value( - &mut self, - key: impl AsRef<[u8]>, - value: &T, - ) -> StdResult<()> { - let address = self.mixnet_contract_address()?; - - self.set_contract_storage_value(address, key, value) - } - - fn current_mixnet_epoch(&self) -> StdResult { - let address = self.mixnet_contract_address()?; - - Ok(self - .deps() - .querier - .query_current_mixnet_interval(address.clone())? - .current_epoch_absolute_id()) - } - - fn advance_mixnet_epoch(&mut self) -> StdResult<()> { - let interval_details: CurrentIntervalResponse = self.query_arbitrary_contract( - self.mixnet_contract_address()?, - &nym_mixnet_contract_common::QueryMsg::GetCurrentIntervalDetails {}, - )?; - let until_end = interval_details.time_until_current_epoch_end().as_secs(); - let timestamp = self.env().block.time.plus_seconds(until_end + 1); - self.set_block_time(timestamp); - self.next_block(); - - // this was hardcoded in mixnet init - let mixnet_rewarder = self.addr_make("rewarder"); - let rewarder = message_info(&mixnet_rewarder, &[]); - self.execute_mixnet_contract( - rewarder.clone(), - &nym_mixnet_contract_common::ExecuteMsg::BeginEpochTransition {}, - )?; - self.execute_mixnet_contract( - rewarder.clone(), - &nym_mixnet_contract_common::ExecuteMsg::ReconcileEpochEvents { limit: None }, - )?; - - for role in [ - Role::ExitGateway, - Role::EntryGateway, - Role::Layer1, - Role::Layer2, - Role::Layer3, - Role::Standby, - ] { - self.execute_mixnet_contract( - rewarder.clone(), - &nym_mixnet_contract_common::ExecuteMsg::AssignRoles { - assignment: RoleAssignment { - role, - nodes: vec![], - }, - }, - )?; - } - Ok(()) - } - - fn set_mixnet_epoch(&mut self, epoch_id: EpochId) -> StdResult<()> { - let address = self.mixnet_contract_address()?; - - let interval = self - .deps() - .querier - .query_current_mixnet_interval(address.clone())?; - - let mut to_update = if interval.current_epoch_absolute_id() <= epoch_id { - interval - } else { - Interval::init_interval( - interval.epochs_in_interval(), - interval.epoch_length(), - &mock_env(), - ) - }; - - let current = to_update.current_epoch_absolute_id(); - let diff = epoch_id - current; - for _ in 0..diff { - to_update = to_update.advance_epoch(); - } - self.set_contract_storage_value(&address, b"ci", &to_update) - } - fn authorise_network_monitor( &mut self, addr: &Addr, @@ -435,68 +343,6 @@ pub(crate) trait PerformanceContractTesterExt: .load(self.deps().storage, (epoch_id, node_id))?; Ok(scores) } - - fn bond_dummy_nymnode(&mut self) -> Result { - let node_owner = self.generate_account_with_balance(); - let pledge = coins(100_000000, TEST_DENOM); - let keypair = ed25519::KeyPair::new(self.raw_rng()); - let identity_key = keypair.public_key().to_base58_string(); - - let node = NymNode { - host: "1.2.3.4".to_string(), - custom_http_port: None, - identity_key, - }; - let cost_params = NodeCostParams { - profit_margin_percent: Percent::from_percentage_value(DEFAULT_PROFIT_MARGIN_PERCENT) - .unwrap(), - interval_operating_cost: coin(DEFAULT_INTERVAL_OPERATING_COST_AMOUNT, TEST_DENOM), - }; - // initial signing nonce is 0 for a new address - let signing_nonce = 0; - - let payload = NymNodeBondingPayload::new(node.clone(), cost_params.clone()); - let content = ContractMessageContent::new(node_owner.clone(), pledge.clone(), payload); - let msg = SignableNymNodeBondingMsg::new(signing_nonce, content); - - let owner_signature = keypair.private_key().sign(msg.to_plaintext()?); - let owner_signature = MessageSignature::from(owner_signature.to_bytes().as_ref()); - - self.execute_mixnet_contract( - message_info(&node_owner, &pledge), - &nym_mixnet_contract_common::ExecuteMsg::BondNymNode { - node, - cost_params, - owner_signature, - }, - )?; - - let bond: NodeOwnershipResponse = self.query_arbitrary_contract( - self.mixnet_contract_address()?, - &nym_mixnet_contract_common::QueryMsg::GetOwnedNymNode { - address: node_owner.to_string(), - }, - )?; - - Ok(bond.details.unwrap().bond_information.node_id) - } - - fn unbond_nymnode(&mut self, node_id: NodeId) -> Result<(), NymPerformanceContractError> { - let bond: NodeDetailsResponse = self.query_arbitrary_contract( - self.mixnet_contract_address()?, - &nym_mixnet_contract_common::QueryMsg::GetNymNodeDetails { node_id }, - )?; - - let node_owner = bond.details.unwrap().bond_information.owner; - - self.execute_mixnet_contract( - message_info(&node_owner, &[]), - &nym_mixnet_contract_common::ExecuteMsg::UnbondNymNode {}, - )?; - - self.advance_mixnet_epoch()?; - Ok(()) - } } impl PerformanceContractTesterExt for ContractTester {} diff --git a/contracts/performance/src/transactions.rs b/contracts/performance/src/transactions.rs index 86a2d99772..3f9fe4aaed 100644 --- a/contracts/performance/src/transactions.rs +++ b/contracts/performance/src/transactions.rs @@ -132,6 +132,7 @@ mod tests { use crate::storage::retrieval_limits; use crate::testing::{init_contract_tester, PerformanceContractTesterExt}; use cosmwasm_std::from_json; + use mixnet_contract::testable_mixnet_contract::EmbeddedMixnetContractExt; use nym_contracts_common_testing::{AdminExt, ContractOpts}; use nym_performance_contract_common::RemoveEpochMeasurementsResponse; diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index 93f2e44db4..0435652210 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -104,6 +104,7 @@ nym-serde-helpers = { workspace = true, features = ["date"] } nym-ticketbooks-merkle = { workspace = true } nym-statistics-common = { workspace = true } nym-ecash-signer-check = { workspace = true } +nym-node-families-contract-common = { workspace = true } [features] diff --git a/nym-api/nym-api-requests/src/models/mod.rs b/nym-api/nym-api-requests/src/models/mod.rs index 6a0c523a52..46c1fc0820 100644 --- a/nym-api/nym-api-requests/src/models/mod.rs +++ b/nym-api/nym-api-requests/src/models/mod.rs @@ -15,6 +15,7 @@ pub mod legacy; pub mod mixnet; pub mod network; pub mod network_monitor; +pub mod node_families; pub mod node_status; pub mod schema_helpers; pub mod utility; diff --git a/nym-api/nym-api-requests/src/models/node_families.rs b/nym-api/nym-api-requests/src/models/node_families.rs new file mode 100644 index 0000000000..0cad61c59a --- /dev/null +++ b/nym-api/nym-api-requests/src/models/node_families.rs @@ -0,0 +1,130 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use super::CoinSchema; +use cosmwasm_std::Coin; +use nym_mixnet_contract_common::{NodeId, NodeRewarding}; +use serde::{Deserialize, Serialize}; +use std::time::Duration; +use time::OffsetDateTime; +use utoipa::ToSchema; + +/// Pending family invitation as exposed by the nym-api node-families endpoints. +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +pub struct PendingFamilyInvitation { + /// Node the invitation is addressed to. + pub node_id: NodeId, + + /// Block-time after which the invitation can no longer be accepted. + #[serde(with = "time::serde::rfc3339")] + #[schema(value_type = String)] + pub expires_at: OffsetDateTime, +} + +/// Per-node stake snapshot derived from the mixnet contract's rewarding state. +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +pub struct NodeStakeInformation { + /// Operator bond + all delegations, with accrued rewards applied. + #[schema(value_type = CoinSchema)] + pub stake: Coin, + + /// Operator pledge component of `stake`. + #[schema(value_type = CoinSchema)] + pub bond: Coin, + + /// Delegations component of `stake`. + #[schema(value_type = CoinSchema)] + pub delegations: Coin, + + /// Number of unique delegators backing this node. + pub delegators: usize, +} + +impl From<&NodeRewarding> for NodeStakeInformation { + fn from(rewarding: &NodeRewarding) -> Self { + let denom = &rewarding.cost_params.interval_operating_cost.denom; + + let bond = rewarding.operator_pledge_with_reward(denom); + let delegations = rewarding.delegations_with_reward(denom); + let mut stake = bond.clone(); + stake.amount += delegations.amount; + + NodeStakeInformation { + stake, + bond, + delegations, + delegators: rewarding.unique_delegations as usize, + } + } +} + +/// Family member view as exposed by the nym-api node-families endpoints. +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +pub struct NodeFamilyMember { + pub node_id: NodeId, + + /// Block-time at which the node joined the family. + #[serde(with = "time::serde::rfc3339")] + #[schema(value_type = String)] + pub joined_at: OffsetDateTime, + + /// Stake/bond/delegation snapshot; `None` if the node was not in the + /// mixnet-contract cache at refresh time. + pub stake_information: Option, +} + +/// Family view as exposed by the nym-api node-families endpoints, carrying +/// current members, pending invitations and aggregated stats. +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +pub struct NodeFamily { + /// Unique family identifier assigned by the contract. + pub id: u32, + + /// Display name (canonical form — see `normalise_family_name`). + pub name: String, + + /// Free-form family description. + pub description: String, + + /// Owner address (cosmos `Addr` rendered as a string). + pub owner: String, + + /// Average age of members. + #[serde(with = "humantime_serde")] + #[schema(value_type = String)] + pub average_node_age: Duration, + + /// Sum of member stakes; `None` when no member has reportable stake. + #[schema(value_type = Option)] + pub total_stake: Option, + + /// Block-time the family was created. + #[serde(with = "time::serde::rfc3339")] + #[schema(value_type = String)] + pub created_at: OffsetDateTime, + + /// Current members of the family. + pub members: Vec, + + /// Outstanding invitations issued by the family owner. + pub pending_invitations: Vec, +} + +/// Response wrapper for endpoints that look up a single family. `family` is +/// `None` when the lookup did not match (rather than returning a 404). +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +pub struct NodeFamilyResponse { + pub family: Option, +} + +/// Response wrapper for endpoints that look up the family a given node +/// belongs to. `family` is `None` when the node is not currently a member of +/// any cached family. +#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)] +pub struct NodeFamilyForNodeResponse { + /// The node the lookup was performed for. + pub node_id: NodeId, + + /// The family this node belongs to, if any. + pub family: Option, +} diff --git a/nym-api/src/ecash/tests/mod.rs b/nym-api/src/ecash/tests/mod.rs index 2640a25009..20781ccbaf 100644 --- a/nym-api/src/ecash/tests/mod.rs +++ b/nym-api/src/ecash/tests/mod.rs @@ -5,24 +5,11 @@ use crate::ecash::api_routes::handlers::ecash_routes; use crate::ecash::error::{EcashError, Result}; use crate::ecash::keys::KeyPairWithEpoch; use crate::ecash::state::EcashState; -use crate::mixnet_contract_cache::cache::MixnetContractCache; -use crate::network::models::NetworkDetails; -use crate::node_describe_cache::cache::DescribedNodes; -use crate::node_status_api::handlers::unstable; -use crate::node_status_api::NodeStatusCache; -use crate::status::ApiStatusState; +use crate::node_families::cache::NodeFamiliesCacheData; use crate::support::caching::cache::SharedCache; -use crate::support::caching::refresher::RefreshRequester; use crate::support::config; -use crate::support::http::state::chain_status::ChainStatusCache; -use crate::support::http::state::contract_details::ContractDetailsCache; -use crate::support::http::state::force_refresh::ForcedRefresh; -use crate::support::http::state::mixnet_contract_cache::MixnetContractCacheState; -use crate::support::http::state::node_annotations_cache::NodeAnnotationsCache; -use crate::support::http::state::AppState; use crate::support::nyxd::Client; use crate::support::storage::NymApiStorage; -use crate::unstable_routes::v1::account::cache::AddressInfoCache; use async_trait::async_trait; use axum::Router; use axum_test::http::StatusCode; @@ -78,8 +65,6 @@ use std::ops::Deref; use std::str::FromStr; use std::sync::atomic::{AtomicU64, Ordering}; use std::sync::{Arc, Mutex}; -use std::time::Duration; -use tempfile::{tempdir, TempDir}; use time::Date; use tokio::sync::RwLock; @@ -88,7 +73,8 @@ pub(crate) mod helpers; mod issued_ticketbooks; const TEST_COIN_DENOM: &str = "unym"; -const TEST_REWARDING_VALIDATOR_ADDRESS: &str = "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0"; +pub(crate) const TEST_REWARDING_VALIDATOR_ADDRESS: &str = + "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0"; #[derive(Default, Debug)] struct InternalCounters { @@ -1271,133 +1257,124 @@ struct TestFixture { chain_state: SharedFakeChain, epoch: Arc, ecash_clients: Arc>>>, +} - _tmp_dir: TempDir, +/// Test-only bundle returned by [`build_dummy_ecash_state`]. Carries the +/// constructed [`EcashState`] plus the test handles the caller may want to +/// poke at directly (chain state, registered ecash clients, epoch counter). +pub(crate) struct DummyEcashBundle { + pub ecash_state: EcashState, + pub chain_state: SharedFakeChain, + pub ecash_clients: Arc>>>, + /// A real [`Client`] (not the [`DummyClient`]) suitable for the + /// `nyxd_client` field on [`AppState`]. Built from a global env-var dance + /// (see body), which is required because `AppState` is not generic. + pub real_client: Client, + pub epoch: Arc, +} + +/// Build a self-contained [`EcashState`] suitable for handler tests. Pulls +/// every dependency it needs (coconut keypair, identity, fake chain, dummy +/// comm channel, etc.) from a deterministic RNG seed so callers get +/// reproducible setups. +pub(crate) async fn build_dummy_ecash_state( + config: &config::Config, + storage: NymApiStorage, + rng_seed: [u8; 32], +) -> DummyEcashBundle { + let mut rng = crate::ecash::tests::fixtures::test_rng(rng_seed); + let coconut_keypair = ttp_keygen(1, 1).unwrap().remove(0); + let identity = ed25519::KeyPair::new(&mut rng); + let epoch = Arc::new(AtomicU64::new(1)); + let address = AccountId::from_str(TEST_REWARDING_VALIDATOR_ADDRESS).unwrap(); + let comm_channel = DummyCommunicationChannel::new_single_dummy( + coconut_keypair.verification_key().clone(), + address.clone(), + ) + .with_epoch(epoch.clone()); + let ecash_clients = comm_channel.clients_arc(); + + let staged_key_pair = crate::ecash::keys::KeyPair::new(); + staged_key_pair + .set(KeyPairWithEpoch { + keys: coconut_keypair, + issued_for_epoch: 1, + }) + .await; + staged_key_pair.validate(); + + let chain_state = SharedFakeChain::default(); + let nyxd_client = DummyClient::new(address, chain_state.clone()); + + let ecash_contract = chain_state + .lock() + .unwrap() + .ecash_contract + .address + .clone() + .as_str() + .parse() + .unwrap(); + + let ecash_state = EcashState::new( + config, + ecash_contract, + nyxd_client, + identity, + staged_key_pair, + comm_channel, + storage, + &ShutdownManager::empty_mock(), + ); + + // ideally this would have been generic, but that's way too much work + // since then `AppState` would have had to be made generic + // also, this is such a disgusting workaround to make it 'work'. yuck + let mut dummy = NymNetworkDetails::new_empty(); + dummy.endpoints = vec![ValidatorDetails::new( + "http://127.0.0.1:26657", + Some("http://why-do-we-even-need-api-url-set-here.wtf"), + None, + )]; + dummy.export_to_env(); + let real_client = Client::new(config).unwrap(); + + DummyEcashBundle { + ecash_state, + chain_state, + ecash_clients, + real_client, + epoch, + } } impl TestFixture { - fn build_app_state( - storage: NymApiStorage, - ecash_state: EcashState, - nyxd_client: Client, - tmp_dir: &TempDir, - ) -> AppState { - let mixnet_contract_paths = tmp_dir.path().join("mixnet_contract"); - let node_annotations_paths = tmp_dir.path().join("node_annotations"); - - let mixnet_contract_cache_state = - MixnetContractCache::new(&mixnet_contract_paths, Duration::from_secs(42)); - let mixnet_contract_cache = - MixnetContractCacheState::new(mixnet_contract_cache_state, RefreshRequester::default()); - - let node_status_cache_state = - NodeStatusCache::new(&node_annotations_paths, Duration::from_secs(42)); - let node_annotations_cache = - NodeAnnotationsCache::new(node_status_cache_state, RefreshRequester::default()); - - AppState { - nyxd_client, - chain_status_cache: ChainStatusCache::new(Duration::from_secs(42)), - ecash_signers_cache: Default::default(), - address_info_cache: AddressInfoCache::new(Duration::from_secs(42), 1000), - forced_refresh: ForcedRefresh::new(true), - mixnet_contract_cache, - node_annotations_cache, - storage, - described_nodes_cache: SharedCache::::new(), - network_details: NetworkDetails::new( - "localhost".to_string(), - NymNetworkDetails::new_empty(), - ), - node_info_cache: unstable::NodeInfoCache::default(), - contract_info_cache: ContractDetailsCache::new(Duration::from_secs(42)), - api_status: ApiStatusState::new(None), - ecash_state: Arc::new(ecash_state), - } - } - async fn new() -> Self { - let mut rng = crate::ecash::tests::fixtures::test_rng([69u8; 32]); - let coconut_keypair = ttp_keygen(1, 1).unwrap().remove(0); - let identity = ed25519::KeyPair::new(&mut rng); - let epoch = Arc::new(AtomicU64::new(1)); - let address = AccountId::from_str(TEST_REWARDING_VALIDATOR_ADDRESS).unwrap(); - let comm_channel = DummyCommunicationChannel::new_single_dummy( - coconut_keypair.verification_key().clone(), - address.clone(), - ) - .with_epoch(epoch.clone()); - let ecash_clients = comm_channel.clients_arc(); - - // TODO: it's AWFUL to test with actual storage, we should somehow abstract it away - let tmp_dir = tempdir().unwrap(); - let storage = NymApiStorage::init(tmp_dir.path().join("TESTING_STORAGE.db")) - .await - .unwrap(); - - let staged_key_pair = crate::ecash::keys::KeyPair::new(); - staged_key_pair - .set(KeyPairWithEpoch { - keys: coconut_keypair, - issued_for_epoch: 1, - }) - .await; - staged_key_pair.validate(); - - let chain_state = SharedFakeChain::default(); - let nyxd_client = DummyClient::new(address, chain_state.clone()); - - let ecash_contract = chain_state - .lock() - .unwrap() - .ecash_contract - .address - .clone() - .as_str() - .parse() - .unwrap(); + let storage = NymApiStorage::init_in_memory().await.unwrap(); let mut config = config::Config::new("test"); config.ecash_signer.enabled = true; - let ecash_state = EcashState::new( - &config, - ecash_contract, - nyxd_client, - identity, - staged_key_pair, - comm_channel, + let bundle = build_dummy_ecash_state(&config, storage.clone(), [69u8; 32]).await; + + let app_state = crate::support::http::state::test_helpers::build_app_state( storage.clone(), - &ShutdownManager::empty_mock(), + bundle.ecash_state, + bundle.real_client, + SharedCache::::new(), ); - // ideally this would have been generic, but that's way too much work - // since then `AppState` would have had to be made generic - // also, this is such a disgusting workaround to make it 'work'. yuck - let mut dummy = NymNetworkDetails::new_empty(); - dummy.endpoints = vec![ValidatorDetails::new( - "http://127.0.0.1:26657", - Some("http://why-do-we-even-need-api-url-set-here.wtf"), - None, - )]; - dummy.export_to_env(); - let another_fake_nyxd_client = Client::new(&config).unwrap(); - TestFixture { - axum: TestServer::new(Router::new().nest("/v1/ecash", ecash_routes()).with_state( - Self::build_app_state( - storage.clone(), - ecash_state, - another_fake_nyxd_client, - &tmp_dir, - ), - )) + axum: TestServer::new( + Router::new() + .nest("/v1/ecash", ecash_routes()) + .with_state(app_state), + ) .unwrap(), storage, - chain_state, - epoch, - ecash_clients, - _tmp_dir: tmp_dir, + chain_state: bundle.chain_state, + epoch: bundle.epoch, + ecash_clients: bundle.ecash_clients, } } @@ -1573,11 +1550,8 @@ mod credential_tests { let nyxd_client = DummyClient::new(address.clone(), Default::default()); let key_pair = ttp_keygen(1, 1).unwrap().remove(0); - let tmp_dir = tempdir().unwrap(); - let storage = NymApiStorage::init(tmp_dir.path().join("storage.db")) - .await - .unwrap(); + let storage = NymApiStorage::init_in_memory().await.unwrap(); let comm_channel = DummyCommunicationChannel::new_single_dummy( key_pair.verification_key().clone(), address, diff --git a/nym-api/src/main.rs b/nym-api/src/main.rs index b2f52320e0..5089edd2a3 100644 --- a/nym-api/src/main.rs +++ b/nym-api/src/main.rs @@ -17,6 +17,7 @@ pub(crate) mod mixnet_contract_cache; pub(crate) mod network; mod network_monitor; pub(crate) mod node_describe_cache; +mod node_families; mod node_performance; pub(crate) mod node_status_api; pub(crate) mod nym_nodes; diff --git a/nym-api/src/node_families/cache/mod.rs b/nym-api/src/node_families/cache/mod.rs new file mode 100644 index 0000000000..3d3e771eab --- /dev/null +++ b/nym-api/src/node_families/cache/mod.rs @@ -0,0 +1,238 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use cosmwasm_std::Coin; +use nym_api_requests::models::node_families::{ + NodeFamily, NodeFamilyMember, NodeStakeInformation, PendingFamilyInvitation, +}; +use nym_mixnet_contract_common::{NodeId, NymNodeDetails}; +use nym_node_families_contract_common::{FamilyMemberRecord, NodeFamilyId}; +use serde::{Deserialize, Serialize}; +use std::collections::{BTreeMap, HashMap}; +use std::time::Duration; +use time::OffsetDateTime; + +pub(crate) mod refresher; + +/// Cached view of a single family member, joining the contract membership +/// record with mixnet-contract node details (bond height + stake). +#[derive(Serialize, Deserialize, Debug)] +pub(crate) struct CachedFamilyMember { + pub(crate) node_id: NodeId, + + /// Block-time at which the node joined the family. + #[serde(with = "time::serde::rfc3339")] + pub(crate) joined_at: OffsetDateTime, + + /// Bonding height from the mixnet contract; `None` if the node is no + /// longer in the mixnet cache snapshot. + pub(crate) bonding_height: Option, + + /// Stake/bond/delegation snapshot; `None` if the node is no longer in the + /// mixnet cache snapshot. + pub(crate) node_stake_information: Option, +} + +impl CachedFamilyMember { + pub(crate) fn new( + record: FamilyMemberRecord, + node_information: Option<&NymNodeDetails>, + ) -> Self { + CachedFamilyMember { + node_id: record.node_id, + joined_at: OffsetDateTime::from_unix_timestamp(record.membership.joined_at as i64) + .unwrap_or(OffsetDateTime::UNIX_EPOCH), + bonding_height: node_information.map(|n| n.bond_information.bonding_height), + node_stake_information: node_information.map(|n| (&n.rewarding_details).into()), + } + } +} + +/// Cached pending invitation entry for a family. +#[derive(Serialize, Deserialize, Debug)] +pub(crate) struct CachedFamilyInvitation { + /// Node the invitation is addressed to. + pub(crate) node_id: NodeId, + + /// Block-time after which the invitation can no longer be accepted. + #[serde(with = "time::serde::rfc3339")] + pub(crate) expires_at: OffsetDateTime, +} + +impl From + for CachedFamilyInvitation +{ + fn from(invitation: nym_node_families_contract_common::PendingFamilyInvitationDetails) -> Self { + CachedFamilyInvitation { + node_id: invitation.invitation.node_id, + expires_at: OffsetDateTime::from_unix_timestamp( + invitation.invitation.expires_at as i64, + ) + .unwrap_or(OffsetDateTime::UNIX_EPOCH), + } + } +} + +/// Cached family record with its current members, pending invitations and +/// aggregated stats (`average_node_age`, `total_stake`). +#[derive(Serialize, Deserialize, Debug)] +pub(crate) struct CachedFamily { + /// Unique family identifier assigned by the contract. + pub(crate) id: NodeFamilyId, + + /// Display name (canonical form — see `normalise_family_name`). + pub(crate) name: String, + + /// Free-form family description. + pub(crate) description: String, + + /// Owner address (cosmos `Addr` rendered as a string). + pub(crate) owner: String, + + /// Average age of members, computed from cached per-height + /// block timestamps. + #[serde(with = "humantime_serde")] + pub(crate) average_node_age: Duration, + + /// Sum of member stakes; `None` when no member has reportable stake (e.g. + /// all bonds unbonding). + pub(crate) total_stake: Option, + + /// Block-time the family was created. + #[serde(with = "time::serde::rfc3339")] + pub(crate) created_at: OffsetDateTime, + + /// Current members of the family. + pub(crate) members: Vec, + + /// Outstanding invitations issued by the family owner. + pub(crate) pending_invitations: Vec, +} + +/// Full nym-api node-families cache snapshot — combined families-contract +/// state plus mixnet-contract stake/bond information. +#[derive(Default, Debug, Serialize, Deserialize)] +pub(crate) struct NodeFamiliesCacheData { + /// Every family known to the contract, keyed by family id. `BTreeMap` so + /// iteration order is deterministic across refreshes (stable list + /// endpoint output, deterministic on-disk bincode). + pub(crate) families: BTreeMap, + + /// Secondary index: member node id → family id. Built alongside + /// `families` during refresh; lets `by-node` lookups avoid an O(families + /// × members) scan. + pub(crate) family_by_member: HashMap, + + /// Persistent block-height → block-time cache used by the refresher when + /// computing per-member age. Survives restarts via the on-disk cache file. + pub(crate) block_timestamps: HashMap, +} + +/// Intermediate accumulator used while folding contract data into a +/// [`CachedFamily`]; finalised via [`Self::build`] once `average_node_age` is +/// known. +pub(crate) struct CachedFamilyBuilder { + /// Unique family identifier assigned by the contract. + pub(crate) id: NodeFamilyId, + + /// Display name (canonical form — see `normalise_family_name`). + pub(crate) name: String, + + /// Free-form family description. + pub(crate) description: String, + + /// Owner address (cosmos `Addr` rendered as a string). + pub(crate) owner: String, + + /// Block-time the family was created. + pub(crate) created_at: OffsetDateTime, + + /// Members accumulated as the refresher iterates the contract response. + pub(crate) members: Vec, + + /// Pending invitations accumulated as the refresher iterates the contract + /// response. + pub(crate) pending_invitations: Vec, +} + +impl CachedFamilyBuilder { + pub(crate) fn build(self, average_node_age: Duration) -> CachedFamily { + let total_stake = self.total_family_stake(); + + CachedFamily { + id: self.id, + name: self.name, + description: self.description, + owner: self.owner, + created_at: self.created_at, + members: self.members, + pending_invitations: self.pending_invitations, + total_stake, + average_node_age, + } + } + + /// Sum the per-member stake into a single family total. Returns `None` if + /// no member has a known stake. + pub(crate) fn total_family_stake(&self) -> Option { + self.members + .iter() + .filter_map(|m| m.node_stake_information.as_ref().map(|s| s.stake.clone())) + .reduce(|acc, e| { + let mut updated = acc; + updated.amount += e.amount; + updated + }) + } +} + +impl From<&CachedFamilyInvitation> for PendingFamilyInvitation { + fn from(value: &CachedFamilyInvitation) -> Self { + PendingFamilyInvitation { + node_id: value.node_id, + expires_at: value.expires_at, + } + } +} + +impl From<&CachedFamilyMember> for NodeFamilyMember { + fn from(value: &CachedFamilyMember) -> Self { + NodeFamilyMember { + node_id: value.node_id, + joined_at: value.joined_at, + stake_information: value.node_stake_information.clone(), + } + } +} + +impl From<&CachedFamily> for NodeFamily { + fn from(value: &CachedFamily) -> Self { + NodeFamily { + id: value.id, + name: value.name.clone(), + description: value.description.clone(), + owner: value.owner.clone(), + average_node_age: value.average_node_age, + total_stake: value.total_stake.clone(), + created_at: value.created_at, + members: value.members.iter().map(Into::into).collect(), + pending_invitations: value.pending_invitations.iter().map(Into::into).collect(), + } + } +} + +// initial conversion with empty details +impl From for CachedFamilyBuilder { + fn from(value: nym_node_families_contract_common::NodeFamily) -> Self { + CachedFamilyBuilder { + id: value.id, + name: value.name, + description: value.description, + owner: value.owner.to_string(), + created_at: OffsetDateTime::from_unix_timestamp(value.created_at as i64) + .unwrap_or(OffsetDateTime::UNIX_EPOCH), + members: Vec::new(), + pending_invitations: Vec::new(), + } + } +} diff --git a/nym-api/src/node_families/cache/refresher.rs b/nym-api/src/node_families/cache/refresher.rs new file mode 100644 index 0000000000..12b40cc119 --- /dev/null +++ b/nym-api/src/node_families/cache/refresher.rs @@ -0,0 +1,213 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::mixnet_contract_cache::cache::MixnetContractCache; +use crate::node_families::cache::{CachedFamilyBuilder, CachedFamilyMember, NodeFamiliesCacheData}; +use crate::support::caching::cache::SharedCache; +use crate::support::caching::refresher::CacheItemProvider; +use crate::support::nyxd::Client; +use async_trait::async_trait; +use futures::{stream, StreamExt}; +use nym_mixnet_contract_common::NodeId; +use nym_validator_client::nyxd::contract_traits::PagedNodeFamiliesQueryClient; +use nym_validator_client::nyxd::error::NyxdError; +use std::collections::{BTreeMap, HashMap, HashSet}; +use std::time::Duration; +use time::OffsetDateTime; +use tracing::error; + +/// Periodic refresher feeding the [`NodeFamiliesCacheData`] cache from the +/// node-families contract, joined with mixnet-contract stake snapshots. +pub struct NodeFamiliesDataProvider { + /// Nyxd client used for contract queries and block timestamp lookups. + nyxd_client: Client, + + /// Source of per-node stake/delegation information. + mixnet_contract_cache: MixnetContractCache, + + /// Read-only handle to the cache this provider feeds. Used to recover the + /// previously-known block-height → block-time map (rehydrated from disk on + /// startup) so we only RPC heights we haven't already seen. + shared_cache: SharedCache, + + /// Maximum number of `block_timestamp` lookups in flight in parallel during a + /// single refresh tick. + block_timestamp_fetch_concurrency: usize, +} + +#[async_trait] +impl CacheItemProvider for NodeFamiliesDataProvider { + type Item = NodeFamiliesCacheData; + type Error = NyxdError; + + async fn wait_until_ready(&self) { + self.mixnet_contract_cache + .naive_wait_for_initial_values() + .await + } + + async fn try_refresh(&mut self) -> Result, Self::Error> { + self.refresh().await.map(Some) + } +} + +impl NodeFamiliesDataProvider { + pub(crate) fn new( + block_timestamp_fetch_concurrency: usize, + nyxd_client: Client, + mixnet_contract_cache: MixnetContractCache, + shared_cache: SharedCache, + ) -> Self { + NodeFamiliesDataProvider { + nyxd_client, + mixnet_contract_cache, + shared_cache, + block_timestamp_fetch_concurrency, + } + } + + /// Snapshot of the previously-cached block timestamps (rehydrated from + /// disk on startup). Empty if the cache hasn't been initialised yet. + async fn previous_block_timestamps(&self) -> HashMap { + let Ok(prev) = self.shared_cache.get().await else { + return HashMap::new(); + }; + prev.block_timestamps.clone() + } + + /// Pull the full families/members/pending-invitations snapshot from the + /// node-families contract and join it with the latest mixnet-contract node + /// information for stake/bonding data. + async fn refresh(&self) -> Result { + // retrieve the base data from the contract + let raw_families = self.nyxd_client.get_all_families().await?; + let raw_members = self.nyxd_client.get_all_family_members().await?; + let pending_invites = self.nyxd_client.get_all_pending_invitations().await?; + + let nym_nodes = self + .mixnet_contract_cache + .nym_nodes() + .await + .into_iter() + .map(|node| (node.node_id(), node)) + .collect::>(); + + let mut families: HashMap<_, CachedFamilyBuilder> = raw_families + .into_iter() + .map(|family| (family.id, family.into())) + .collect(); + let mut family_by_member: HashMap = HashMap::new(); + + // insert all member information into appropriate families + for member_record in raw_members { + let family_id = member_record.membership.family_id; + let node_id = member_record.node_id; + let Some(family) = families.get_mut(&family_id) else { + error!( + "node {node_id} belongs to family {family_id}, but this family does not exist!", + ); + continue; + }; + let node_info = nym_nodes.get(&node_id); + family + .members + .push(CachedFamilyMember::new(member_record, node_info)); + family_by_member.insert(node_id, family_id); + } + + // insert all invitations into appropriate families + for invitation in pending_invites { + let family_id = invitation.invitation.family_id; + let node_id = invitation.invitation.node_id; + let Some(family) = families.get_mut(&family_id) else { + error!( + "node {node_id} has been invited to family {family_id}, but this family does not exist!", + ); + continue; + }; + family.pending_invitations.push(invitation.into()); + } + + let referenced_heights: HashSet = families + .values() + .flat_map(|f| f.members.iter().filter_map(|m| m.bonding_height)) + .collect(); + + let block_timestamps = self.resolve_block_timestamps(&referenced_heights).await; + + let family_details: BTreeMap<_, _> = families + .into_values() + .map(|family| { + let average_node_age = average_node_age(&family.members, &block_timestamps); + let built = family.build(average_node_age); + (built.id, built) + }) + .collect(); + + Ok(NodeFamiliesCacheData { + families: family_details, + family_by_member, + block_timestamps, + }) + } + + /// Build the block-height → block-time map for this refresh: keep entries + /// from the previous cache that we still need, parallel-fetch the rest. + async fn resolve_block_timestamps( + &self, + referenced_heights: &HashSet, + ) -> HashMap { + let mut block_timestamps = self.previous_block_timestamps().await; + + let to_fetch: Vec = referenced_heights + .iter() + .filter(|h| !block_timestamps.contains_key(h)) + .copied() + .collect(); + + let fetched: Vec<(u64, OffsetDateTime)> = stream::iter(to_fetch) + .map(|h| async move { + match self.nyxd_client.block_timestamp(h as u32).await { + Ok(t) => Some((h, OffsetDateTime::from(t))), + Err(err) => { + error!("failed to retrieve block timestamp for height {h}: {err}"); + None + } + } + }) + .buffer_unordered(self.block_timestamp_fetch_concurrency) + .filter_map(|x| async move { x }) + .collect() + .await; + + block_timestamps.extend(fetched); + block_timestamps + } +} + +/// Average member age: for each member with a known bonding +/// height we have a cached block-time, take `now - t` and average. Heights we +/// failed to resolve are skipped rather than poisoning the average. +fn average_node_age( + members: &[CachedFamilyMember], + block_timestamps: &HashMap, +) -> Duration { + let now = OffsetDateTime::now_utc(); + let mut total_secs: i64 = 0; + let mut count: i64 = 0; + for height in members.iter().filter_map(|m| m.bonding_height) { + let Some(ts) = block_timestamps.get(&height) else { + continue; + }; + let age = (now - *ts).whole_seconds(); + if age < 0 { + continue; + } + total_secs += age; + count += 1; + } + if count == 0 { + return Duration::ZERO; + } + Duration::from_secs((total_secs / count) as u64) +} diff --git a/nym-api/src/node_families/handlers/mod.rs b/nym-api/src/node_families/handlers/mod.rs new file mode 100644 index 0000000000..f0a587c783 --- /dev/null +++ b/nym-api/src/node_families/handlers/mod.rs @@ -0,0 +1,139 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::node_status_api::models::AxumResult; +use crate::support::http::helpers::PaginationRequestV2; +use crate::support::http::state::AppState; +use axum::extract::{Path, Query, State}; +use axum::routing::get; +use axum::Router; +use nym_api_requests::models::node_families::{ + NodeFamily, NodeFamilyForNodeResponse, NodeFamilyResponse, +}; +use nym_api_requests::pagination::{PaginatedResponse, Pagination}; +use nym_http_api_common::{FormattedResponse, OutputParamsV2}; +use nym_mixnet_contract_common::NodeId; +use nym_node_families_contract_common::NodeFamilyId; +use std::cmp::min; + +const DEFAULT_FAMILIES_PAGE_SIZE: u32 = 50; +const MAX_FAMILIES_PAGE_SIZE: u32 = 200; + +// /v1/node-families +pub(crate) fn routes() -> Router { + Router::new() + .route("/", get(get_families)) + .route("/:family_id", get(get_family_by_id)) + .route("/by-node/:node_id", get(get_family_for_node)) +} + +#[utoipa::path( + tag = "Node Families", + get, + path = "", + context_path = "/v1/node-families", + responses( + (status = 200, content( + (PaginatedResponse = "application/json"), + (PaginatedResponse = "application/yaml"), + )) + ), + params(PaginationRequestV2) +)] +async fn get_families( + Query(pagination): Query, + State(state): State, +) -> AxumResult>> { + let page = pagination.page.unwrap_or_default(); + let per_page = min( + pagination.per_page.unwrap_or(DEFAULT_FAMILIES_PAGE_SIZE), + MAX_FAMILIES_PAGE_SIZE, + ); + let output = pagination.output.unwrap_or_default(); + + let cache = state.node_families_cache.get().await?; + let total = cache.families.len(); + let offset = (page as usize).saturating_mul(per_page as usize); + + // BTreeMap ascending-id iteration is stable across refreshes, so paging + // by offset is well-defined: page N is the same window of ids on every + // call (until the underlying set changes). + let data: Vec = cache + .families + .values() + .skip(offset) + .take(per_page as usize) + .map(Into::into) + .collect(); + + Ok(output.to_response(PaginatedResponse { + pagination: Pagination { + total, + page, + size: data.len(), + }, + data, + })) +} + +#[utoipa::path( + tag = "Node Families", + get, + path = "/{family_id}", + context_path = "/v1/node-families", + responses( + (status = 200, content( + (NodeFamilyResponse = "application/json"), + (NodeFamilyResponse = "application/yaml"), + )) + ), + params( + ("family_id" = u32, Path, description = "Identifier of the family"), + OutputParamsV2, + ) +)] +async fn get_family_by_id( + Path(family_id): Path, + Query(output): Query, + State(state): State, +) -> AxumResult> { + let output = output.get_output(); + + let cache = state.node_families_cache.get().await?; + let family = cache.families.get(&family_id).map(NodeFamily::from); + + Ok(output.to_response(NodeFamilyResponse { family })) +} + +#[utoipa::path( + tag = "Node Families", + get, + path = "/by-node/{node_id}", + context_path = "/v1/node-families", + responses( + (status = 200, content( + (NodeFamilyForNodeResponse = "application/json"), + (NodeFamilyForNodeResponse = "application/yaml"), + )) + ), + params( + ("node_id" = u32, Path, description = "Identifier of the member node"), + OutputParamsV2, + ) +)] +async fn get_family_for_node( + Path(node_id): Path, + Query(output): Query, + State(state): State, +) -> AxumResult> { + let output = output.get_output(); + + let cache = state.node_families_cache.get().await?; + let family = cache + .family_by_member + .get(&node_id) + .and_then(|family_id| cache.families.get(family_id)) + .map(NodeFamily::from); + + Ok(output.to_response(NodeFamilyForNodeResponse { node_id, family })) +} diff --git a/nym-api/src/node_families/mod.rs b/nym-api/src/node_families/mod.rs new file mode 100644 index 0000000000..c86c9dda3e --- /dev/null +++ b/nym-api/src/node_families/mod.rs @@ -0,0 +1,37 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::mixnet_contract_cache::cache::MixnetContractCache; +use crate::node_families::cache::refresher::NodeFamiliesDataProvider; +use crate::node_families::cache::NodeFamiliesCacheData; +use crate::support::caching::cache::SharedCache; +use crate::support::caching::refresher::CacheRefresher; +use crate::support::{config, nyxd}; +use nym_validator_client::nyxd::error::NyxdError; +use std::path::PathBuf; + +pub(crate) mod cache; +pub(crate) mod handlers; +#[cfg(test)] +mod tests; + +pub(crate) fn build_refresher( + config: &config::NodeFamiliesCache, + mixnet_contract_cache: &MixnetContractCache, + node_families_cache: &SharedCache, + nyxd_client: nyxd::Client, + on_disk_file: PathBuf, +) -> CacheRefresher { + CacheRefresher::new_with_initial_value( + Box::new(NodeFamiliesDataProvider::new( + config.debug.node_families_block_timestamp_fetch_concurrency, + nyxd_client, + mixnet_contract_cache.clone(), + node_families_cache.clone(), + )), + config.debug.caching_interval, + node_families_cache.clone(), + ) + .named("node-families-cache-refresher") + .with_persistent_cache(on_disk_file) +} diff --git a/nym-api/src/node_families/tests.rs b/nym-api/src/node_families/tests.rs new file mode 100644 index 0000000000..9db626acc8 --- /dev/null +++ b/nym-api/src/node_families/tests.rs @@ -0,0 +1,254 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::ecash::tests::build_dummy_ecash_state; +use crate::node_families::cache::{CachedFamily, CachedFamilyMember, NodeFamiliesCacheData}; +use crate::node_families::handlers; +use crate::support::caching::cache::SharedCache; +use crate::support::config; +use crate::support::http::state::test_helpers::build_app_state; +use crate::support::storage::NymApiStorage; +use axum::Router; +use axum_test::http::StatusCode; +use axum_test::TestServer; +use cosmwasm_std::Coin; +use nym_api_requests::models::node_families::{ + NodeFamily, NodeFamilyForNodeResponse, NodeFamilyResponse, NodeStakeInformation, +}; +use nym_api_requests::pagination::PaginatedResponse; +use nym_mixnet_contract_common::NodeId; +use nym_node_families_contract_common::NodeFamilyId; +use std::collections::{BTreeMap, HashMap}; +use std::time::Duration; +use time::OffsetDateTime; + +struct NodeFamiliesTestFixture { + axum: TestServer, + cache: SharedCache, +} + +impl NodeFamiliesTestFixture { + /// Build a test server with the node-families router mounted and an empty + /// (but initialised) shared cache. Use [`seed`] to populate it. + async fn new() -> Self { + let storage = NymApiStorage::init_in_memory().await.unwrap(); + + let cache = SharedCache::::new_with_value(Default::default()); + + // node-families handlers don't read `AppState.ecash_state`, but + // `AppState` requires one; we just need a valid construction. + let mut cfg = config::Config::new("test"); + cfg.ecash_signer.enabled = false; + let bundle = build_dummy_ecash_state(&cfg, storage.clone(), [7u8; 32]).await; + + let app_state = build_app_state( + storage, + bundle.ecash_state, + bundle.real_client, + cache.clone(), + ); + + let server = TestServer::new( + Router::new() + .nest("/v1/node-families", handlers::routes()) + .with_state(app_state), + ) + .unwrap(); + + NodeFamiliesTestFixture { + axum: server, + cache, + } + } + + /// Replace the cached data with the provided snapshot. + async fn seed(&self, data: NodeFamiliesCacheData) { + // try_overwrite_old_value swaps the entire cached value + let res = self + .cache + .try_overwrite_old_value(data, "node-families-test") + .await; + assert!(res.is_ok(), "failed to seed node-families cache: {res:?}"); + } +} + +// ---------- fixtures ---------- + +fn stake_coin(amount: u128) -> Coin { + Coin::new(amount, "unym") +} + +fn member(node_id: NodeId, with_stake: Option) -> CachedFamilyMember { + CachedFamilyMember { + node_id, + joined_at: OffsetDateTime::UNIX_EPOCH, + bonding_height: Some(1), + node_stake_information: with_stake.map(|amt| NodeStakeInformation { + stake: stake_coin(amt), + bond: stake_coin(amt), + delegations: stake_coin(0), + delegators: 0, + }), + } +} + +fn family(id: NodeFamilyId, name: &str, members: Vec) -> CachedFamily { + CachedFamily { + id, + name: name.to_string(), + description: format!("{name} description"), + owner: format!("n1owner{id}"), + average_node_age: Duration::ZERO, + total_stake: None, + created_at: OffsetDateTime::UNIX_EPOCH, + members, + pending_invitations: Vec::new(), + } +} + +fn snapshot(families: Vec) -> NodeFamiliesCacheData { + let mut family_by_member: HashMap = HashMap::new(); + let mut families_map: BTreeMap = BTreeMap::new(); + for family in families { + for m in &family.members { + family_by_member.insert(m.node_id, family.id); + } + families_map.insert(family.id, family); + } + NodeFamiliesCacheData { + families: families_map, + family_by_member, + block_timestamps: HashMap::new(), + } +} + +// ---------- /v1/node-families (list) ---------- + +#[tokio::test] +async fn list_returns_empty_when_cache_has_no_families() { + let fx = NodeFamiliesTestFixture::new().await; + + let res = fx.axum.get("/v1/node-families").await; + assert_eq!(res.status_code(), StatusCode::OK); + let body: PaginatedResponse = res.json(); + assert_eq!(body.pagination.total, 0); + assert_eq!(body.pagination.size, 0); + assert_eq!(body.pagination.page, 0); + assert!(body.data.is_empty()); +} + +#[tokio::test] +async fn list_returns_every_seeded_family() { + let fx = NodeFamiliesTestFixture::new().await; + fx.seed(snapshot(vec![ + family(1, "alpha", vec![member(10, Some(100))]), + family(2, "beta", vec![member(20, None)]), + ])) + .await; + + let res = fx.axum.get("/v1/node-families").await; + let body: PaginatedResponse = res.json(); + assert_eq!(body.pagination.total, 2); + let ids: Vec<_> = body.data.iter().map(|f| f.id).collect(); + assert_eq!(ids, vec![1, 2]); +} + +#[tokio::test] +async fn list_paginates_by_offset_in_ascending_id_order() { + let fx = NodeFamiliesTestFixture::new().await; + let families: Vec<_> = (1u32..=5) + .map(|i| family(i, &format!("f{i}"), vec![])) + .collect(); + fx.seed(snapshot(families)).await; + + // page 0 / per_page 2 → ids [1, 2] + let res = fx.axum.get("/v1/node-families?page=0&per_page=2").await; + let page0: PaginatedResponse = res.json(); + assert_eq!(page0.pagination.total, 5); + assert_eq!(page0.pagination.page, 0); + assert_eq!(page0.pagination.size, 2); + assert_eq!( + page0.data.iter().map(|f| f.id).collect::>(), + vec![1, 2] + ); + + // page 1 / per_page 2 → ids [3, 4] + let res = fx.axum.get("/v1/node-families?page=1&per_page=2").await; + let page1: PaginatedResponse = res.json(); + assert_eq!( + page1.data.iter().map(|f| f.id).collect::>(), + vec![3, 4] + ); + + // page 2 / per_page 2 → just id 5 on the last page + let res = fx.axum.get("/v1/node-families?page=2&per_page=2").await; + let page2: PaginatedResponse = res.json(); + assert_eq!(page2.pagination.size, 1); + assert_eq!(page2.data.iter().map(|f| f.id).collect::>(), vec![5]); + + // page 3 / per_page 2 → past the end; data empty but total still reported + let res = fx.axum.get("/v1/node-families?page=3&per_page=2").await; + let page3: PaginatedResponse = res.json(); + assert_eq!(page3.pagination.total, 5); + assert_eq!(page3.pagination.size, 0); + assert!(page3.data.is_empty()); +} + +// ---------- /v1/node-families/{family_id} ---------- + +#[tokio::test] +async fn get_family_by_id_returns_some_on_hit() { + let fx = NodeFamiliesTestFixture::new().await; + fx.seed(snapshot(vec![family(7, "seven", vec![])])).await; + + let res = fx.axum.get("/v1/node-families/7").await; + assert_eq!(res.status_code(), StatusCode::OK); + let body: NodeFamilyResponse = res.json(); + let family = body.family.expect("family should be present"); + assert_eq!(family.id, 7); + assert_eq!(family.name, "seven"); +} + +#[tokio::test] +async fn get_family_by_id_returns_none_on_miss() { + let fx = NodeFamiliesTestFixture::new().await; + fx.seed(snapshot(vec![family(1, "alpha", vec![])])).await; + + let res = fx.axum.get("/v1/node-families/999").await; + // still 200 — `family: None` signals absence + assert_eq!(res.status_code(), StatusCode::OK); + let body: NodeFamilyResponse = res.json(); + assert!(body.family.is_none()); +} + +// ---------- /v1/node-families/by-node/{node_id} ---------- + +#[tokio::test] +async fn get_family_for_node_returns_some_on_hit() { + let fx = NodeFamiliesTestFixture::new().await; + fx.seed(snapshot(vec![family( + 3, + "gamma", + vec![member(42, None), member(43, None)], + )])) + .await; + + let res = fx.axum.get("/v1/node-families/by-node/42").await; + let body: NodeFamilyForNodeResponse = res.json(); + assert_eq!(body.node_id, 42); + let family = body.family.expect("expected to find the family"); + assert_eq!(family.id, 3); +} + +#[tokio::test] +async fn get_family_for_node_returns_none_on_miss() { + let fx = NodeFamiliesTestFixture::new().await; + fx.seed(snapshot(vec![family(1, "alpha", vec![member(10, None)])])) + .await; + + let res = fx.axum.get("/v1/node-families/by-node/9999").await; + assert_eq!(res.status_code(), StatusCode::OK); + let body: NodeFamilyForNodeResponse = res.json(); + assert_eq!(body.node_id, 9999); + assert!(body.family.is_none()); +} diff --git a/nym-api/src/support/cli/run.rs b/nym-api/src/support/cli/run.rs index 2a120cc6fd..85574a4bde 100644 --- a/nym-api/src/support/cli/run.rs +++ b/nym-api/src/support/cli/run.rs @@ -13,6 +13,7 @@ use crate::key_rotation::KeyRotationController; use crate::mixnet_contract_cache::cache::MixnetContractCache; use crate::network::models::NetworkDetails; use crate::node_describe_cache::cache::DescribedNodes; +use crate::node_families::cache::NodeFamiliesCacheData; use crate::node_performance::provider::contract_provider::ContractPerformanceProvider; use crate::node_performance::provider::legacy_storage_provider::LegacyStoragePerformanceProvider; use crate::node_performance::provider::NodePerformanceProvider; @@ -36,7 +37,7 @@ use crate::support::storage::NymApiStorage; use crate::unstable_routes::v1::account::cache::AddressInfoCache; use crate::{ ecash, epoch_operations, mixnet_contract_cache, network_monitor, node_describe_cache, - node_performance, node_status_api, signers_cache, + node_families, node_performance, node_status_api, signers_cache, }; use anyhow::{bail, Context}; use nym_config::defaults::NymNetworkDetails; @@ -188,6 +189,19 @@ async fn start_nym_api_tasks(mut config: Config) -> anyhow::Result::new_with_persistent(&node_families_path, ttl, None); + let node_families_cache_refresher = node_families::build_refresher( + &config.node_families_cache, + &mixnet_contract_cache_state.clone(), + &node_families_cache, + nyxd_client.clone(), + node_families_path, + ); + // NODES ANNOTATIONS let annotations_path = storage_cfg.cache_file("node_annotations"); let ttl = config.node_status_api.debug.caching_interval; @@ -316,6 +330,8 @@ async fn start_nym_api_tasks(mut config: Config) -> anyhow::Result anyhow::Result Self { + NodeFamiliesCache { + debug: Default::default(), + } + } +} + +#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(default)] +pub struct NodeFamiliesCacheDebug { + #[serde(with = "humantime_serde")] + pub caching_interval: Duration, + + pub node_families_block_timestamp_fetch_concurrency: usize, +} + +impl Default for NodeFamiliesCacheDebug { + fn default() -> Self { + NodeFamiliesCacheDebug { + caching_interval: DEFAULT_NODE_FAMILIES_CACHE_REFRESH_INTERVAL, + node_families_block_timestamp_fetch_concurrency: + DEFAULT_NODE_FAMILIES_BLOCK_TIMESTAMP_FETCH_CONCURRENCY, + } + } +} + #[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] pub struct PerformanceProvider { /// Specifies whether this nym-api should attempt to retrieve node performance diff --git a/nym-api/src/support/http/helpers.rs b/nym-api/src/support/http/helpers.rs index ed11746900..b73d5eb0a3 100644 --- a/nym-api/src/support/http/helpers.rs +++ b/nym-api/src/support/http/helpers.rs @@ -1,7 +1,7 @@ // Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use nym_http_api_common::Output; +use nym_http_api_common::{Output, OutputV2}; use nym_mixnet_contract_common::NodeId; use serde::{Deserialize, Serialize}; use utoipa::{IntoParams, ToSchema}; @@ -14,6 +14,14 @@ pub struct PaginationRequest { pub per_page: Option, } +#[derive(Serialize, Deserialize, Debug, ToSchema, IntoParams)] +#[into_params(parameter_in = Query)] +pub struct PaginationRequestV2 { + pub output: Option, + pub page: Option, + pub per_page: Option, +} + #[derive(Deserialize, IntoParams, ToSchema)] #[schema(title = "NodeId")] #[schema(as = NodeId)] diff --git a/nym-api/src/support/http/router.rs b/nym-api/src/support/http/router.rs index 00ab46c8af..a66ee02c72 100644 --- a/nym-api/src/support/http/router.rs +++ b/nym-api/src/support/http/router.rs @@ -5,6 +5,7 @@ use crate::circulating_supply_api::handlers::circulating_supply_routes; use crate::ecash::api_routes::handlers::ecash_routes; use crate::mixnet_contract_cache::handlers::{epoch_routes, legacy_nodes_routes}; use crate::network::handlers::nym_network_routes; +use crate::node_families::handlers as node_families_handlers; use crate::node_status_api::handlers::status_routes; use crate::support::http::openapi::ApiDoc; use crate::support::http::state::AppState; @@ -49,6 +50,7 @@ impl RouterBuilder { .nest("/network", nym_network_routes()) .nest("/api-status", status::handlers::api_status_routes()) .nest("/nym-nodes", nym_nodes::handlers::v1::routes()) + .nest("/node-families", node_families_handlers::routes()) .nest("/ecash", ecash_routes()) .nest("/unstable", unstable_routes_v1()) .nest("/legacy", legacy_nodes_routes()); // CORS layer needs to be "outside" of routes diff --git a/nym-api/src/support/http/state/contract_details.rs b/nym-api/src/support/http/state/contract_details.rs index 5ea1079993..8eac98acd3 100644 --- a/nym-api/src/support/http/state/contract_details.rs +++ b/nym-api/src/support/http/state/contract_details.rs @@ -55,6 +55,7 @@ async fn refresh(nyxd_client: &Client) -> Result let multisig = query_guard!(client_guard, multisig_contract_address()); let ecash = query_guard!(client_guard, ecash_contract_address()); let performance = query_guard!(client_guard, performance_contract_address()); + let node_families = query_guard!(client_guard, node_families_contract_address()); for (address, name) in [ (mixnet, "nym-mixnet-contract"), @@ -64,6 +65,7 @@ async fn refresh(nyxd_client: &Client) -> Result (multisig, "nym-cw3-multisig-contract"), (ecash, "nym-ecash-contract"), (performance, "nym-performance-contract"), + (node_families, "nym-node-families-contract"), ] { let (cw2, build_info) = if let Some(address) = address { let cw2 = query_guard!(client_guard, try_get_cw2_contract_version(address).await); diff --git a/nym-api/src/support/http/state/mod.rs b/nym-api/src/support/http/state/mod.rs index 35c2416f85..36ac22da6f 100644 --- a/nym-api/src/support/http/state/mod.rs +++ b/nym-api/src/support/http/state/mod.rs @@ -5,6 +5,7 @@ use crate::ecash::state::EcashState; use crate::mixnet_contract_cache::cache::MixnetContractCache; use crate::network::models::NetworkDetails; use crate::node_describe_cache::cache::DescribedNodes; +use crate::node_families::cache::NodeFamiliesCacheData; use crate::node_status_api::handlers::unstable; use crate::node_status_api::models::AxumErrorResponse; use crate::node_status_api::NodeStatusCache; @@ -33,6 +34,8 @@ pub(crate) mod force_refresh; pub(crate) mod helpers; pub(crate) mod mixnet_contract_cache; pub(crate) mod node_annotations_cache; +#[cfg(test)] +pub(crate) mod test_helpers; #[derive(Clone)] pub(crate) struct AppState { @@ -59,6 +62,9 @@ pub(crate) struct AppState { /// Holds cached state of the Nym Mixnet contract, e.g. bonded nym-nodes, rewarded set, current interval. pub(crate) mixnet_contract_cache: MixnetContractCacheState, + /// Hold cached state of node families, e.g. membership, invitations, age, etc. + pub(crate) node_families_cache: SharedCache, + /// Holds processed information on network nodes, i.e. performance, config scores, etc. // TODO: also perhaps redundant? pub(crate) node_annotations_cache: NodeAnnotationsCache, diff --git a/nym-api/src/support/http/state/test_helpers.rs b/nym-api/src/support/http/state/test_helpers.rs new file mode 100644 index 0000000000..5c693a293c --- /dev/null +++ b/nym-api/src/support/http/state/test_helpers.rs @@ -0,0 +1,67 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +//! Shared test-only helpers for assembling an [`AppState`] without going +//! through the full nym-api startup path. + +use crate::ecash::state::EcashState; +use crate::mixnet_contract_cache::cache::MixnetContractCache; +use crate::network::models::NetworkDetails; +use crate::node_describe_cache::cache::DescribedNodes; +use crate::node_families::cache::NodeFamiliesCacheData; +use crate::node_status_api::handlers::unstable; +use crate::node_status_api::NodeStatusCache; +use crate::status::ApiStatusState; +use crate::support::caching::cache::SharedCache; +use crate::support::caching::refresher::RefreshRequester; +use crate::support::http::state::chain_status::ChainStatusCache; +use crate::support::http::state::contract_details::ContractDetailsCache; +use crate::support::http::state::force_refresh::ForcedRefresh; +use crate::support::http::state::mixnet_contract_cache::MixnetContractCacheState; +use crate::support::http::state::node_annotations_cache::NodeAnnotationsCache; +use crate::support::http::state::AppState; +use crate::support::nyxd::Client; +use crate::support::storage::NymApiStorage; +use crate::unstable_routes::v1::account::cache::AddressInfoCache; +use nym_config::defaults::NymNetworkDetails; +use std::sync::Arc; +use std::time::Duration; + +/// Construct a default test [`AppState`]. All caches start empty +/// (in-memory `SharedCache::new()` for the disk-backed ones); seed +/// `node_families_cache` upstream of this call if the test needs data. +pub(crate) fn build_app_state( + storage: NymApiStorage, + ecash_state: EcashState, + nyxd_client: Client, + node_families_cache: SharedCache, +) -> AppState { + let mixnet_contract_cache: MixnetContractCache = SharedCache::new().into(); + let mixnet_contract_cache = + MixnetContractCacheState::new(mixnet_contract_cache, RefreshRequester::default()); + + let node_status_cache: NodeStatusCache = SharedCache::new().into(); + let node_annotations_cache = + NodeAnnotationsCache::new(node_status_cache, RefreshRequester::default()); + + AppState { + nyxd_client, + chain_status_cache: ChainStatusCache::new(Duration::from_secs(42)), + ecash_signers_cache: Default::default(), + address_info_cache: AddressInfoCache::new(Duration::from_secs(42), 1000), + forced_refresh: ForcedRefresh::new(true), + mixnet_contract_cache, + node_families_cache, + node_annotations_cache, + storage, + described_nodes_cache: SharedCache::::new(), + network_details: NetworkDetails::new( + "localhost".to_string(), + NymNetworkDetails::new_empty(), + ), + node_info_cache: unstable::NodeInfoCache::default(), + contract_info_cache: ContractDetailsCache::new(Duration::from_secs(42)), + api_status: ApiStatusState::new(None), + ecash_state: Arc::new(ecash_state), + } +} diff --git a/nym-api/src/support/nyxd/mod.rs b/nym-api/src/support/nyxd/mod.rs index 6de33c4738..59995ecd75 100644 --- a/nym-api/src/support/nyxd/mod.rs +++ b/nym-api/src/support/nyxd/mod.rs @@ -33,13 +33,15 @@ use nym_mixnet_contract_common::{ ExecuteMsg, GatewayBond, HistoricalNymNodeVersionEntry, IdentityKey, KeyRotationState, NymNodeDetails, RewardedSet, RoleAssignment, }; +use nym_node_families_contract_common::msg::QueryMsg as NodeFamiliesQueryMsg; use nym_validator_client::coconut::EcashApiError; use nym_validator_client::nyxd::contract_traits::mixnet_query_client::MixnetQueryClientExt; use nym_validator_client::nyxd::contract_traits::performance_query_client::{ LastSubmission, NodePerformance, }; use nym_validator_client::nyxd::contract_traits::{ - PagedDkgQueryClient, PagedPerformanceQueryClient, PerformanceQueryClient, + NodeFamiliesQueryClient, PagedDkgQueryClient, PagedPerformanceQueryClient, + PerformanceQueryClient, }; use nym_validator_client::nyxd::error::NyxdError; use nym_validator_client::nyxd::Coin; @@ -204,6 +206,13 @@ impl Client { Ok(time) } + /// Tendermint block timestamp at the given height. + pub(crate) async fn block_timestamp(&self, height: u32) -> Result { + let time = nyxd_query!(self, get_block_timestamp(Some(height)).await?); + + Ok(time) + } + /// Obtains the hash of a block specified by the provided height. /// If the resulting digest is empty, a `None` is returned instead. /// @@ -695,3 +704,16 @@ impl DkgQueryClient for Client { nyxd_query!(self, query_dkg_contract(query).await) } } + +#[async_trait] +impl NodeFamiliesQueryClient for Client { + async fn query_node_families_contract( + &self, + query: NodeFamiliesQueryMsg, + ) -> std::result::Result + where + for<'a> T: Deserialize<'a>, + { + nyxd_query!(self, query_node_families_contract(query).await) + } +} diff --git a/nym-api/src/support/storage/mod.rs b/nym-api/src/support/storage/mod.rs index 8bb14a697d..457b3dcd98 100644 --- a/nym-api/src/support/storage/mod.rs +++ b/nym-api/src/support/storage/mod.rs @@ -82,6 +82,33 @@ impl NymApiStorage { .max_connections(25) .acquire_timeout(Duration::from_secs(60)); + Self::from_options(connect_opts, pool_opts).await + } + + /// Build a [`NymApiStorage`] backed by an in-memory SQLite database. The + /// pool is pinned to a single connection so every query sees the same DB + /// (the standard "private :memory:" gotcha — multiple connections to + /// `:memory:` produce independent DBs unless shared-cache is used). + /// + /// Intended for tests; migrations run identically to the file-backed + /// constructor. + #[cfg(test)] + pub async fn init_in_memory() -> Result { + let connect_opts = sqlx::sqlite::SqliteConnectOptions::new() + .filename(":memory:") + .create_if_missing(true); + + let pool_opts = sqlx::sqlite::SqlitePoolOptions::new() + .min_connections(1) + .max_connections(1); + + Self::from_options(connect_opts, pool_opts).await + } + + async fn from_options( + connect_opts: sqlx::sqlite::SqliteConnectOptions, + pool_opts: sqlx::sqlite::SqlitePoolOptions, + ) -> Result { let connection_pool = match pool_opts.connect_with(connect_opts).await { Ok(db) => db, Err(err) => { @@ -97,12 +124,10 @@ impl NymApiStorage { info!("Database migration finished!"); - let storage = NymApiStorage { + Ok(NymApiStorage { manager: StorageManager { connection_pool }, db_id_cache: Arc::new(Default::default()), - }; - - Ok(storage) + }) } pub(crate) async fn get_mixnode_database_id( diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-56854f703321ff8d8f30628c7e5322024ea01b778ab55efa9c7c6b219ef36308.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-0d183e6ad37527d0f624580f702b56cdae6d3fe6b53a8ed5c37fdc4d9e3b7f7c.json similarity index 60% rename from nym-node-status-api/nym-node-status-api/.sqlx/query-56854f703321ff8d8f30628c7e5322024ea01b778ab55efa9c7c6b219ef36308.json rename to nym-node-status-api/nym-node-status-api/.sqlx/query-0d183e6ad37527d0f624580f702b56cdae6d3fe6b53a8ed5c37fdc4d9e3b7f7c.json index 4525f5cd77..7fcbfc7607 100644 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-56854f703321ff8d8f30628c7e5322024ea01b778ab55efa9c7c6b219ef36308.json +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-0d183e6ad37527d0f624580f702b56cdae6d3fe6b53a8ed5c37fdc4d9e3b7f7c.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT\n nd.node_id,\n moniker,\n website,\n security_contact,\n details\n FROM\n nym_node_descriptions nd\n INNER JOIN\n nym_nodes nn on nd.node_id = nn.node_id\n WHERE\n bond_info IS NOT NULL\n ", + "query": "SELECT\n nd.node_id,\n moniker,\n website,\n security_contact,\n details\n FROM\n nym_node_descriptions nd\n INNER JOIN\n nym_nodes nn on nd.node_id = nn.node_id\n WHERE\n bond_info IS NOT NULL\n ", "describe": { "columns": [ { @@ -40,5 +40,5 @@ true ] }, - "hash": "56854f703321ff8d8f30628c7e5322024ea01b778ab55efa9c7c6b219ef36308" + "hash": "0d183e6ad37527d0f624580f702b56cdae6d3fe6b53a8ed5c37fdc4d9e3b7f7c" } diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-f25a4eb90c11957669cfad4800d7a0a384b672077abb123c3437962def194e8a.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-1668f5a5a0abc8a73454953c3f5b61d2afb1b37720f5756b9c6fb3aef55a3027.json similarity index 60% rename from nym-node-status-api/nym-node-status-api/.sqlx/query-f25a4eb90c11957669cfad4800d7a0a384b672077abb123c3437962def194e8a.json rename to nym-node-status-api/nym-node-status-api/.sqlx/query-1668f5a5a0abc8a73454953c3f5b61d2afb1b37720f5756b9c6fb3aef55a3027.json index 32c3613a08..1fee9eb103 100644 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-f25a4eb90c11957669cfad4800d7a0a384b672077abb123c3437962def194e8a.json +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-1668f5a5a0abc8a73454953c3f5b61d2afb1b37720f5756b9c6fb3aef55a3027.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT\n gw.gateway_identity_key as \"gateway_identity_key!\",\n gw.bonded as \"bonded: bool\",\n gw.performance as \"performance!\",\n gw.self_described as \"self_described?\",\n gw.explorer_pretty_bond as \"explorer_pretty_bond?\",\n gw.last_probe_result as \"last_probe_result?\",\n gw.last_probe_log as \"last_probe_log?\",\n gw.last_testrun_utc as \"last_testrun_utc?\",\n gw.last_updated_utc as \"last_updated_utc!\",\n gw.bridges as \"bridges?: serde_json::Value\",\n COALESCE(gd.moniker, 'NA') as \"moniker!\",\n COALESCE(gd.website, 'NA') as \"website!\",\n COALESCE(gd.security_contact, 'NA') as \"security_contact!\",\n COALESCE(gd.details, 'NA') as \"details!\"\n FROM gateways gw\n LEFT JOIN gateway_description gd\n ON gw.gateway_identity_key = gd.gateway_identity_key\n ORDER BY gw.gateway_identity_key", + "query": "SELECT\n gw.gateway_identity_key as \"gateway_identity_key!\",\n gw.bonded as \"bonded: bool\",\n gw.performance as \"performance!\",\n gw.self_described as \"self_described?\",\n gw.explorer_pretty_bond as \"explorer_pretty_bond?\",\n gw.last_probe_result as \"last_probe_result?\",\n gw.last_probe_log as \"last_probe_log?\",\n gw.last_testrun_utc as \"last_testrun_utc?\",\n gw.last_updated_utc as \"last_updated_utc!\",\n gw.bridges as \"bridges?: serde_json::Value\",\n COALESCE(gd.moniker, 'NA') as \"moniker!\",\n COALESCE(gd.website, 'NA') as \"website!\",\n COALESCE(gd.security_contact, 'NA') as \"security_contact!\",\n COALESCE(gd.details, 'NA') as \"details!\"\n FROM gateways gw\n LEFT JOIN gateway_description gd\n ON gw.gateway_identity_key = gd.gateway_identity_key\n ORDER BY gw.gateway_identity_key", "describe": { "columns": [ { @@ -94,5 +94,5 @@ null ] }, - "hash": "f25a4eb90c11957669cfad4800d7a0a384b672077abb123c3437962def194e8a" + "hash": "1668f5a5a0abc8a73454953c3f5b61d2afb1b37720f5756b9c6fb3aef55a3027" } diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-3120dc00831742e0981bdcf486a47c8d9e063f183c6da77295529b06495f6a5c.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-3120dc00831742e0981bdcf486a47c8d9e063f183c6da77295529b06495f6a5c.json new file mode 100644 index 0000000000..11a37364e8 --- /dev/null +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-3120dc00831742e0981bdcf486a47c8d9e063f183c6da77295529b06495f6a5c.json @@ -0,0 +1,56 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT\n family_id,\n name,\n description,\n owner,\n family_stake_unym,\n members_count,\n created_at\n FROM node_families\n ORDER BY family_id", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "family_id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "name", + "type_info": "Text" + }, + { + "ordinal": 2, + "name": "description", + "type_info": "Text" + }, + { + "ordinal": 3, + "name": "owner", + "type_info": "Text" + }, + { + "ordinal": 4, + "name": "family_stake_unym", + "type_info": "Int8" + }, + { + "ordinal": 5, + "name": "members_count", + "type_info": "Int4" + }, + { + "ordinal": 6, + "name": "created_at", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + false, + false, + false, + false, + true, + false, + false + ] + }, + "hash": "3120dc00831742e0981bdcf486a47c8d9e063f183c6da77295529b06495f6a5c" +} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-33e2ca569a31fd03fdc0b2cbf7840572c15063457bac682e938bee632bd0260f.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-33e2ca569a31fd03fdc0b2cbf7840572c15063457bac682e938bee632bd0260f.json new file mode 100644 index 0000000000..1f7d697eed --- /dev/null +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-33e2ca569a31fd03fdc0b2cbf7840572c15063457bac682e938bee632bd0260f.json @@ -0,0 +1,26 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT node_id, family_id\n FROM node_family_members", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "node_id", + "type_info": "Int8" + }, + { + "ordinal": 1, + "name": "family_id", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [] + }, + "nullable": [ + false, + false + ] + }, + "hash": "33e2ca569a31fd03fdc0b2cbf7840572c15063457bac682e938bee632bd0260f" +} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-486bbf89adfd9343549263e84a1fce8994aa1d0b4ef4078a98f5a3efa4c70493.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-486bbf89adfd9343549263e84a1fce8994aa1d0b4ef4078a98f5a3efa4c70493.json new file mode 100644 index 0000000000..244026dc3c --- /dev/null +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-486bbf89adfd9343549263e84a1fce8994aa1d0b4ef4078a98f5a3efa4c70493.json @@ -0,0 +1,21 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO node_families\n (family_id, name, description, owner, family_stake_unym, members_count, created_at, last_updated_utc)\n SELECT * FROM UNNEST(\n $1::BIGINT[], $2::TEXT[], $3::TEXT[], $4::TEXT[],\n $5::BIGINT[], $6::INTEGER[], $7::BIGINT[], $8::BIGINT[]\n )", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int8Array", + "TextArray", + "TextArray", + "TextArray", + "Int8Array", + "Int4Array", + "Int8Array", + "Int8Array" + ] + }, + "nullable": [] + }, + "hash": "486bbf89adfd9343549263e84a1fce8994aa1d0b4ef4078a98f5a3efa4c70493" +} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-227539374e7473f6f9642289c5b5d1bcd636315ab23537cb5f6d2f82a2bcb7bf.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-5834dcc61f5409f568bad0484395b565b2e258f66f4981ace2cfb36bd8b89991.json similarity index 50% rename from nym-node-status-api/nym-node-status-api/.sqlx/query-227539374e7473f6f9642289c5b5d1bcd636315ab23537cb5f6d2f82a2bcb7bf.json rename to nym-node-status-api/nym-node-status-api/.sqlx/query-5834dcc61f5409f568bad0484395b565b2e258f66f4981ace2cfb36bd8b89991.json index 63d48b0826..d06e186dd8 100644 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-227539374e7473f6f9642289c5b5d1bcd636315ab23537cb5f6d2f82a2bcb7bf.json +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-5834dcc61f5409f568bad0484395b565b2e258f66f4981ace2cfb36bd8b89991.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT\n node_id,\n bond_info as \"bond_info: serde_json::Value\"\n FROM\n nym_nodes\n WHERE\n bond_info IS NOT NULL\n AND\n self_described IS NOT NULL\n ", + "query": "SELECT\n node_id,\n bond_info as \"bond_info: serde_json::Value\"\n FROM\n nym_nodes\n WHERE\n bond_info IS NOT NULL\n AND\n self_described IS NOT NULL\n ", "describe": { "columns": [ { @@ -22,5 +22,5 @@ true ] }, - "hash": "227539374e7473f6f9642289c5b5d1bcd636315ab23537cb5f6d2f82a2bcb7bf" + "hash": "5834dcc61f5409f568bad0484395b565b2e258f66f4981ace2cfb36bd8b89991" } diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-8c94f3c3bf7b9c3b135dc4b12303419b43304c3c93389abfc4c1d53955b15dd0.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-8c94f3c3bf7b9c3b135dc4b12303419b43304c3c93389abfc4c1d53955b15dd0.json new file mode 100644 index 0000000000..31cdba1d44 --- /dev/null +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-8c94f3c3bf7b9c3b135dc4b12303419b43304c3c93389abfc4c1d53955b15dd0.json @@ -0,0 +1,16 @@ +{ + "db_name": "PostgreSQL", + "query": "INSERT INTO node_family_members (node_id, family_id, joined_at)\n SELECT * FROM UNNEST($1::BIGINT[], $2::BIGINT[], $3::BIGINT[])", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int8Array", + "Int8Array", + "Int8Array" + ] + }, + "nullable": [] + }, + "hash": "8c94f3c3bf7b9c3b135dc4b12303419b43304c3c93389abfc4c1d53955b15dd0" +} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-c7656b2b1b4328415772ce69d0568bd5438d6c8496ca9cbdcfb70bb5375b345e.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-a1bb7a40d073335db7d9061771dfe62b0d2cfa2f7404f4afb8c3d393f0927f04.json similarity index 51% rename from nym-node-status-api/nym-node-status-api/.sqlx/query-c7656b2b1b4328415772ce69d0568bd5438d6c8496ca9cbdcfb70bb5375b345e.json rename to nym-node-status-api/nym-node-status-api/.sqlx/query-a1bb7a40d073335db7d9061771dfe62b0d2cfa2f7404f4afb8c3d393f0927f04.json index 5cf589c5d7..d9cc36f899 100644 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-c7656b2b1b4328415772ce69d0568bd5438d6c8496ca9cbdcfb70bb5375b345e.json +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-a1bb7a40d073335db7d9061771dfe62b0d2cfa2f7404f4afb8c3d393f0927f04.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT\n node_id,\n self_described as \"self_described: serde_json::Value\"\n FROM\n nym_nodes\n WHERE\n self_described IS NOT NULL\n ORDER BY\n node_id\n ", + "query": "SELECT\n node_id,\n self_described as \"self_described: serde_json::Value\"\n FROM\n nym_nodes\n WHERE\n self_described IS NOT NULL\n ORDER BY\n node_id\n ", "describe": { "columns": [ { @@ -22,5 +22,5 @@ true ] }, - "hash": "c7656b2b1b4328415772ce69d0568bd5438d6c8496ca9cbdcfb70bb5375b345e" + "hash": "a1bb7a40d073335db7d9061771dfe62b0d2cfa2f7404f4afb8c3d393f0927f04" } diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-a470feaded5ceee869202ab3a8bd0122403d252c369ebbee7b64cba8eacc4e05.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-a470feaded5ceee869202ab3a8bd0122403d252c369ebbee7b64cba8eacc4e05.json new file mode 100644 index 0000000000..44af265514 --- /dev/null +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-a470feaded5ceee869202ab3a8bd0122403d252c369ebbee7b64cba8eacc4e05.json @@ -0,0 +1,12 @@ +{ + "db_name": "PostgreSQL", + "query": "DELETE FROM node_families", + "describe": { + "columns": [], + "parameters": { + "Left": [] + }, + "nullable": [] + }, + "hash": "a470feaded5ceee869202ab3a8bd0122403d252c369ebbee7b64cba8eacc4e05" +} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-3ddc12cc4e1796b787a50c40560d2bd71d1cfe5f5265e6f161b3122d1317a421.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-e5c75bbade89f9b1b7ddaad50f48be0cb679568a751c1b7e604a098a824b2a7c.json similarity index 65% rename from nym-node-status-api/nym-node-status-api/.sqlx/query-3ddc12cc4e1796b787a50c40560d2bd71d1cfe5f5265e6f161b3122d1317a421.json rename to nym-node-status-api/nym-node-status-api/.sqlx/query-e5c75bbade89f9b1b7ddaad50f48be0cb679568a751c1b7e604a098a824b2a7c.json index 2e19afef0d..977c28feb8 100644 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-3ddc12cc4e1796b787a50c40560d2bd71d1cfe5f5265e6f161b3122d1317a421.json +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-e5c75bbade89f9b1b7ddaad50f48be0cb679568a751c1b7e604a098a824b2a7c.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT\n node_id,\n ed25519_identity_pubkey,\n total_stake,\n ip_addresses as \"ip_addresses!: serde_json::Value\",\n mix_port,\n x25519_sphinx_pubkey,\n node_role as \"node_role: serde_json::Value\",\n supported_roles as \"supported_roles: serde_json::Value\",\n entry as \"entry: serde_json::Value\",\n performance,\n self_described as \"self_described: serde_json::Value\",\n bond_info as \"bond_info: serde_json::Value\",\n http_api_port\n FROM\n nym_nodes\n ORDER BY\n node_id\n ", + "query": "SELECT\n node_id,\n ed25519_identity_pubkey,\n total_stake,\n ip_addresses as \"ip_addresses!: serde_json::Value\",\n mix_port,\n x25519_sphinx_pubkey,\n node_role as \"node_role: serde_json::Value\",\n supported_roles as \"supported_roles: serde_json::Value\",\n entry as \"entry: serde_json::Value\",\n performance,\n self_described as \"self_described: serde_json::Value\",\n bond_info as \"bond_info: serde_json::Value\",\n http_api_port\n FROM\n nym_nodes\n WHERE\n self_described IS NOT NULL\n AND\n bond_info IS NOT NULL\n ", "describe": { "columns": [ { @@ -88,5 +88,5 @@ true ] }, - "hash": "3ddc12cc4e1796b787a50c40560d2bd71d1cfe5f5265e6f161b3122d1317a421" + "hash": "e5c75bbade89f9b1b7ddaad50f48be0cb679568a751c1b7e604a098a824b2a7c" } diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-0b51df277ed66c6553f66af9b135342dee177abc1c92e4a89147de3c22d3d1a5.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-f2d5127e36621cb4dd3a7870e95447ee2ca1d3830ee0cc2237238f119ac50480.json similarity index 67% rename from nym-node-status-api/nym-node-status-api/.sqlx/query-0b51df277ed66c6553f66af9b135342dee177abc1c92e4a89147de3c22d3d1a5.json rename to nym-node-status-api/nym-node-status-api/.sqlx/query-f2d5127e36621cb4dd3a7870e95447ee2ca1d3830ee0cc2237238f119ac50480.json index a5cc377447..12b754855f 100644 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-0b51df277ed66c6553f66af9b135342dee177abc1c92e4a89147de3c22d3d1a5.json +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-f2d5127e36621cb4dd3a7870e95447ee2ca1d3830ee0cc2237238f119ac50480.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT\n node_id,\n ed25519_identity_pubkey,\n total_stake,\n ip_addresses as \"ip_addresses!: serde_json::Value\",\n mix_port,\n x25519_sphinx_pubkey,\n node_role as \"node_role: serde_json::Value\",\n supported_roles as \"supported_roles: serde_json::Value\",\n entry as \"entry: serde_json::Value\",\n performance,\n self_described as \"self_described: serde_json::Value\",\n bond_info as \"bond_info: serde_json::Value\",\n http_api_port\n FROM\n nym_nodes\n WHERE\n self_described IS NOT NULL\n AND\n bond_info IS NOT NULL\n ", + "query": "SELECT\n node_id,\n ed25519_identity_pubkey,\n total_stake,\n ip_addresses as \"ip_addresses!: serde_json::Value\",\n mix_port,\n x25519_sphinx_pubkey,\n node_role as \"node_role: serde_json::Value\",\n supported_roles as \"supported_roles: serde_json::Value\",\n entry as \"entry: serde_json::Value\",\n performance,\n self_described as \"self_described: serde_json::Value\",\n bond_info as \"bond_info: serde_json::Value\",\n http_api_port\n FROM\n nym_nodes\n ORDER BY\n node_id\n ", "describe": { "columns": [ { @@ -88,5 +88,5 @@ true ] }, - "hash": "0b51df277ed66c6553f66af9b135342dee177abc1c92e4a89147de3c22d3d1a5" + "hash": "f2d5127e36621cb4dd3a7870e95447ee2ca1d3830ee0cc2237238f119ac50480" } diff --git a/nym-node-status-api/nym-node-status-api/Cargo.toml b/nym-node-status-api/nym-node-status-api/Cargo.toml index 729404d8b6..94fd77efe1 100644 --- a/nym-node-status-api/nym-node-status-api/Cargo.toml +++ b/nym-node-status-api/nym-node-status-api/Cargo.toml @@ -40,6 +40,7 @@ nym-http-api-common = { workspace = true, features = ["middleware"] } nym-network-defaults = { workspace = true } nym-serde-helpers = { workspace = true } nym-statistics-common = { workspace = true } +nym-api-requests = { workspace = true } nym-validator-client = { workspace = true } nym-task = { workspace = true } nym-node-requests = { workspace = true, features = ["openapi", "client"] } diff --git a/nym-node-status-api/nym-node-status-api/migrations_pg/20260514120000_node_families.sql b/nym-node-status-api/nym-node-status-api/migrations_pg/20260514120000_node_families.sql new file mode 100644 index 0000000000..95f3f9bd41 --- /dev/null +++ b/nym-node-status-api/nym-node-status-api/migrations_pg/20260514120000_node_families.sql @@ -0,0 +1,24 @@ +/* + * Copyright 2026 - Nym Technologies SA + * SPDX-License-Identifier: GPL-3.0-only + */ + +CREATE TABLE IF NOT EXISTS node_families ( + family_id BIGINT PRIMARY KEY, + name TEXT NOT NULL, + description TEXT NOT NULL, + owner TEXT NOT NULL, + family_stake_unym BIGINT, + members_count INTEGER NOT NULL, + created_at BIGINT NOT NULL, + last_updated_utc BIGINT NOT NULL +); + +CREATE TABLE IF NOT EXISTS node_family_members ( + node_id BIGINT PRIMARY KEY, + family_id BIGINT NOT NULL REFERENCES node_families (family_id) ON DELETE CASCADE, + joined_at BIGINT NOT NULL +); + +CREATE INDEX IF NOT EXISTS idx_node_family_members_family_id + ON node_family_members (family_id); diff --git a/nym-node-status-api/nym-node-status-api/src/db/mod.rs b/nym-node-status-api/nym-node-status-api/src/db/mod.rs index 03fe202e3a..14f5281b63 100644 --- a/nym-node-status-api/nym-node-status-api/src/db/mod.rs +++ b/nym-node-status-api/nym-node-status-api/src/db/mod.rs @@ -71,4 +71,21 @@ impl Storage { pub fn pool_owned(&self) -> DbPool { self.pool.clone() } + + pub fn pool(&self) -> &DbPool { + &self.pool + } + + /// Build a `Storage` view from an existing pool. The wrapped pool is + /// `Clone`-cheap (shares the same underlying connection set), so this is + /// effectively free. + pub(crate) fn from_pool(pool: DbPool) -> Self { + pool.into() + } +} + +impl From for Storage { + fn from(pool: DbPool) -> Self { + Storage { pool } + } } diff --git a/nym-node-status-api/nym-node-status-api/src/db/models.rs b/nym-node-status-api/nym-node-status-api/src/db/models.rs index 809c9651e3..d9291462af 100644 --- a/nym-node-status-api/nym-node-status-api/src/db/models.rs +++ b/nym-node-status-api/nym-node-status-api/src/db/models.rs @@ -672,3 +672,48 @@ pub struct HostKeysDeHelper { #[serde(default)] pub x25519_versioned_noise: Option, } + +// ---- node families ---- + +// it's not dead code but clippy doesn't detect usage in sqlx macros +#[allow(dead_code)] +#[derive(Debug, Clone)] +pub(crate) struct NodeFamilyInsertRecord { + pub family_id: i64, + pub name: String, + pub description: String, + pub owner: String, + pub family_stake_unym: Option, + /// Member count as reported by nym-api; stored denormalised so callers + /// don't have to aggregate over `node_family_members`. + pub members_count: i32, + pub created_at: i64, + pub last_updated_utc: i64, + pub members: Vec, +} + +#[allow(dead_code)] +#[derive(Debug, Clone)] +pub(crate) struct NodeFamilyMemberInsertRecord { + pub node_id: i64, + pub joined_at: i64, +} + +#[allow(dead_code)] +#[derive(Debug, Clone, FromRow)] +pub(crate) struct NodeFamilyDto { + pub family_id: i64, + pub name: String, + pub description: String, + pub owner: String, + pub family_stake_unym: Option, + pub members_count: i32, + pub created_at: i64, +} + +#[allow(dead_code)] +#[derive(Debug, Clone, FromRow)] +pub(crate) struct NodeFamilyMemberDto { + pub node_id: i64, + pub family_id: i64, +} diff --git a/nym-node-status-api/nym-node-status-api/src/db/queries/gateways.rs b/nym-node-status-api/nym-node-status-api/src/db/queries/gateways.rs index 196d8623a5..99e178086a 100644 --- a/nym-node-status-api/nym-node-status-api/src/db/queries/gateways.rs +++ b/nym-node-status-api/nym-node-status-api/src/db/queries/gateways.rs @@ -2,7 +2,7 @@ use std::collections::HashSet; use crate::{ db::{ - DbConnection, DbPool, + DbConnection, DbPool, Storage, models::{GatewayDto, GatewayInsertRecord}, }, http::models::Gateway, @@ -30,25 +30,26 @@ pub(crate) async fn select_gateway_identity( Ok(record.gateway_identity_key) } -pub(crate) async fn update_bonded_gateways( - pool: &DbPool, - gateways: Vec, -) -> anyhow::Result<()> { - let mut tx = pool.begin().await?; +impl Storage { + pub(crate) async fn update_bonded_gateways( + &self, + gateways: Vec, + ) -> anyhow::Result<()> { + let mut tx = self.pool.begin().await?; - sqlx::query!( - r#"UPDATE + sqlx::query!( + r#"UPDATE gateways SET bonded = false "#, - ) - .execute(&mut *tx) - .await?; + ) + .execute(&mut *tx) + .await?; - for record in gateways { - sqlx::query!( - "INSERT INTO gateways + for record in gateways { + sqlx::query!( + "INSERT INTO gateways (gateway_identity_key, bonded, self_described, explorer_pretty_bond, last_updated_utc, performance) @@ -59,57 +60,57 @@ pub(crate) async fn update_bonded_gateways( explorer_pretty_bond=excluded.explorer_pretty_bond, last_updated_utc=excluded.last_updated_utc, performance = excluded.performance;", - record.identity_key, - record.bonded, - record.self_described, - record.explorer_pretty_bond, - record.last_updated_utc, - record.performance as i32 - ) - .execute(&mut *tx) - .await?; + record.identity_key, + record.bonded, + record.self_described, + record.explorer_pretty_bond, + record.last_updated_utc, + record.performance as i32 + ) + .execute(&mut *tx) + .await?; + } + + tx.commit().await?; + + Ok(()) } - tx.commit().await?; + pub(crate) async fn get_all_gateways(&self) -> anyhow::Result> { + let items = sqlx::query_as!( + GatewayDto, + r#"SELECT + gw.gateway_identity_key as "gateway_identity_key!", + gw.bonded as "bonded: bool", + gw.performance as "performance!", + gw.self_described as "self_described?", + gw.explorer_pretty_bond as "explorer_pretty_bond?", + gw.last_probe_result as "last_probe_result?", + gw.last_probe_log as "last_probe_log?", + gw.last_testrun_utc as "last_testrun_utc?", + gw.last_updated_utc as "last_updated_utc!", + gw.bridges as "bridges?: serde_json::Value", + COALESCE(gd.moniker, 'NA') as "moniker!", + COALESCE(gd.website, 'NA') as "website!", + COALESCE(gd.security_contact, 'NA') as "security_contact!", + COALESCE(gd.details, 'NA') as "details!" + FROM gateways gw + LEFT JOIN gateway_description gd + ON gw.gateway_identity_key = gd.gateway_identity_key + ORDER BY gw.gateway_identity_key"#, + ) + .fetch(&self.pool) + .try_collect::>() + .await?; - Ok(()) -} - -pub(crate) async fn get_all_gateways(pool: &DbPool) -> anyhow::Result> { - let mut conn = pool.acquire().await?; - let items = sqlx::query_as!( - GatewayDto, - r#"SELECT - gw.gateway_identity_key as "gateway_identity_key!", - gw.bonded as "bonded: bool", - gw.performance as "performance!", - gw.self_described as "self_described?", - gw.explorer_pretty_bond as "explorer_pretty_bond?", - gw.last_probe_result as "last_probe_result?", - gw.last_probe_log as "last_probe_log?", - gw.last_testrun_utc as "last_testrun_utc?", - gw.last_updated_utc as "last_updated_utc!", - gw.bridges as "bridges?: serde_json::Value", - COALESCE(gd.moniker, 'NA') as "moniker!", - COALESCE(gd.website, 'NA') as "website!", - COALESCE(gd.security_contact, 'NA') as "security_contact!", - COALESCE(gd.details, 'NA') as "details!" - FROM gateways gw - LEFT JOIN gateway_description gd - ON gw.gateway_identity_key = gd.gateway_identity_key - ORDER BY gw.gateway_identity_key"#, - ) - .fetch(&mut *conn) - .try_collect::>() - .await?; - - let items: Vec = items - .into_iter() - .map(|item| item.try_into()) - .collect::>>() - .inspect_err(|e| error!("Conversion from DTO failed: {e}. Invalidly stored data?"))?; - tracing::trace!("Fetched {} gateways from DB", items.len()); - Ok(items) + let items: Vec = items + .into_iter() + .map(|item| item.try_into()) + .collect::>>() + .inspect_err(|e| error!("Conversion from DTO failed: {e}. Invalidly stored data?"))?; + tracing::trace!("Fetched {} gateways from DB", items.len()); + Ok(items) + } } pub(crate) async fn get_bonded_gateway_id_keys(pool: &DbPool) -> anyhow::Result> { diff --git a/nym-node-status-api/nym-node-status-api/src/db/queries/misc.rs b/nym-node-status-api/nym-node-status-api/src/db/queries/misc.rs index 0dcc6130b3..5240424060 100644 --- a/nym-node-status-api/nym-node-status-api/src/db/queries/misc.rs +++ b/nym-node-status-api/nym-node-status-api/src/db/queries/misc.rs @@ -1,90 +1,92 @@ use time::UtcDateTime; -use crate::db::{DbPool, models::NetworkSummary}; +use crate::db::{Storage, models::NetworkSummary}; -/// take `last_updated` instead of calculating it so that `summary` matches -/// `daily_summary` -pub(crate) async fn insert_summaries( - pool: &DbPool, - summaries: &Vec<(&str, usize)>, - summary: &NetworkSummary, - last_updated: UtcDateTime, -) -> anyhow::Result<()> { - insert_summary(pool, summaries, last_updated).await?; +impl Storage { + /// take `last_updated` instead of calculating it so that `summary` matches + /// `daily_summary` + pub(crate) async fn insert_summaries( + &self, + summaries: &Vec<(&str, usize)>, + summary: &NetworkSummary, + last_updated: UtcDateTime, + ) -> anyhow::Result<()> { + self.insert_summary(summaries, last_updated).await?; - insert_summary_history(pool, summary, last_updated).await?; + self.insert_summary_history(summary, last_updated).await?; - Ok(()) -} + Ok(()) + } -async fn insert_summary( - pool: &DbPool, - summaries: &Vec<(&str, usize)>, - last_updated: UtcDateTime, -) -> anyhow::Result<()> { - let timestamp = last_updated.unix_timestamp(); - let mut tx = pool.begin().await?; + async fn insert_summary( + &self, + summaries: &Vec<(&str, usize)>, + last_updated: UtcDateTime, + ) -> anyhow::Result<()> { + let timestamp = last_updated.unix_timestamp(); + let mut tx = self.pool.begin().await?; - for (kind, value) in summaries { - let value = value.to_string(); - sqlx::query!( - "INSERT INTO summary + for (kind, value) in summaries { + let value = value.to_string(); + sqlx::query!( + "INSERT INTO summary (key, value_json, last_updated_utc) VALUES ($1, $2, $3) ON CONFLICT(key) DO UPDATE SET value_json=excluded.value_json, last_updated_utc=excluded.last_updated_utc;", - kind, - value, - timestamp - ) - .execute(&mut *tx) - .await - .map_err(|err| { - tracing::error!("Failed to insert data for {kind}: {err}, aborting transaction",); - err - })?; + kind, + value, + timestamp + ) + .execute(&mut *tx) + .await + .map_err(|err| { + tracing::error!("Failed to insert data for {kind}: {err}, aborting transaction",); + err + })?; + } + + tx.commit().await?; + + Ok(()) } - tx.commit().await?; + /// For ``, `summary_history` is updated with fresh data on every + /// iteration. + /// + /// After UTC midnight, summary is inserted for `` and last entry for + /// `` stays there forever. + /// + /// This is not aggregate data, it's a set of latest data points + async fn insert_summary_history( + &self, + summary: &NetworkSummary, + last_updated: UtcDateTime, + ) -> anyhow::Result<()> { + let mut conn = self.pool.acquire().await?; - Ok(()) -} + let value_json = serde_json::to_string(&summary)?; + let timestamp = last_updated.unix_timestamp(); -/// For ``, `summary_history` is updated with fresh data on every -/// iteration. -/// -/// After UTC midnight, summary is inserted for `` and last entry for -/// `` stays there forever. -/// -/// This is not aggregate data, it's a set of latest data points -async fn insert_summary_history( - pool: &DbPool, - summary: &NetworkSummary, - last_updated: UtcDateTime, -) -> anyhow::Result<()> { - let mut conn = pool.acquire().await?; + let date = datetime_to_only_date_str(last_updated); - let value_json = serde_json::to_string(&summary)?; - let timestamp = last_updated.unix_timestamp(); - - let date = datetime_to_only_date_str(last_updated); - - sqlx::query!( - "INSERT INTO summary_history + sqlx::query!( + "INSERT INTO summary_history (date, timestamp_utc, value_json) VALUES ($1, $2, $3) ON CONFLICT(date) DO UPDATE SET timestamp_utc=excluded.timestamp_utc, value_json=excluded.value_json;", - date, - timestamp, - value_json - ) - .execute(&mut *conn) - .await?; + date, + timestamp, + value_json + ) + .execute(&mut *conn) + .await?; - Ok(()) + Ok(()) + } } /// YYYY-MM-DD, without time diff --git a/nym-node-status-api/nym-node-status-api/src/db/queries/mod.rs b/nym-node-status-api/nym-node-status-api/src/db/queries/mod.rs index cb0e79b549..cac16a6d89 100644 --- a/nym-node-status-api/nym-node-status-api/src/db/queries/mod.rs +++ b/nym-node-status-api/nym-node-status-api/src/db/queries/mod.rs @@ -2,6 +2,7 @@ pub(crate) mod ecash_data; mod gateways; mod gateways_stats; mod misc; +mod node_families; mod nym_nodes; mod packet_stats; pub(crate) mod scraper; @@ -9,16 +10,10 @@ mod summary; pub(crate) mod testruns; pub(crate) use gateways::{ - get_all_gateways, get_bonded_gateway_id_keys, get_or_create_gateway, select_gateway_identity, - update_bonded_gateways, + get_bonded_gateway_id_keys, get_or_create_gateway, select_gateway_identity, }; pub(crate) use gateways_stats::{delete_old_records, get_sessions_stats, insert_session_records}; -pub(crate) use misc::insert_summaries; -pub(crate) use nym_nodes::{ - get_all_nym_nodes, get_bonded_node_description, get_daily_stats, - get_described_bonded_nym_nodes, get_described_node_bond_info, get_node_self_description, - update_nym_nodes, -}; +pub(crate) use nym_nodes::get_daily_stats; pub(crate) use packet_stats::{ batch_store_node_scraper_results, get_raw_node_stats, insert_daily_node_stats_uncommitted, }; diff --git a/nym-node-status-api/nym-node-status-api/src/db/queries/node_families.rs b/nym-node-status-api/nym-node-status-api/src/db/queries/node_families.rs new file mode 100644 index 0000000000..491a90408d --- /dev/null +++ b/nym-node-status-api/nym-node-status-api/src/db/queries/node_families.rs @@ -0,0 +1,135 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::db::Storage; +use crate::db::models::{NodeFamilyDto, NodeFamilyInsertRecord, NodeFamilyMemberDto}; +use futures_util::TryStreamExt; +use tracing::instrument; + +impl Storage { + /// Replace the node-families snapshot atomically. Wipes both + /// `node_families` and `node_family_members` (cascade) and re-inserts + /// the provided records inside a single transaction so reads never + /// observe a partial state. + /// + /// Both inserts are batched via `UNNEST(..)`, so the whole refresh is a + /// constant number of round trips regardless of how many families/members + /// the snapshot contains. + #[instrument(level = "debug", skip_all, fields(family_records = family_records.len()))] + pub(crate) async fn update_node_families( + &self, + family_records: Vec, + ) -> anyhow::Result { + let inserted = family_records.len(); + + // Reshape the row-major records into column-major vectors so we can + // bind each column as a Postgres array and let `UNNEST` expand them + // back into rows. + let mut family_ids: Vec = Vec::with_capacity(inserted); + let mut names: Vec = Vec::with_capacity(inserted); + let mut descriptions: Vec = Vec::with_capacity(inserted); + let mut owners: Vec = Vec::with_capacity(inserted); + let mut family_stakes: Vec> = Vec::with_capacity(inserted); + let mut members_counts: Vec = Vec::with_capacity(inserted); + let mut created_ats: Vec = Vec::with_capacity(inserted); + let mut last_updated_utcs: Vec = Vec::with_capacity(inserted); + + let total_members: usize = family_records.iter().map(|f| f.members.len()).sum(); + let mut member_node_ids: Vec = Vec::with_capacity(total_members); + let mut member_family_ids: Vec = Vec::with_capacity(total_members); + let mut member_joined_ats: Vec = Vec::with_capacity(total_members); + + for record in family_records { + let family_id = record.family_id; + family_ids.push(family_id); + names.push(record.name); + descriptions.push(record.description); + owners.push(record.owner); + family_stakes.push(record.family_stake_unym); + members_counts.push(record.members_count); + created_ats.push(record.created_at); + last_updated_utcs.push(record.last_updated_utc); + + for member in record.members { + member_node_ids.push(member.node_id); + member_family_ids.push(family_id); + member_joined_ats.push(member.joined_at); + } + } + + let mut tx = self.pool.begin().await?; + + // ON DELETE CASCADE on the members table wipes both sides + sqlx::query!("DELETE FROM node_families") + .execute(&mut *tx) + .await?; + + sqlx::query!( + "INSERT INTO node_families + (family_id, name, description, owner, family_stake_unym, members_count, created_at, last_updated_utc) + SELECT * FROM UNNEST( + $1::BIGINT[], $2::TEXT[], $3::TEXT[], $4::TEXT[], + $5::BIGINT[], $6::INTEGER[], $7::BIGINT[], $8::BIGINT[] + )", + &family_ids[..], + &names[..], + &descriptions[..], + &owners[..], + &family_stakes[..] as &[Option], + &members_counts[..], + &created_ats[..], + &last_updated_utcs[..], + ) + .execute(&mut *tx) + .await?; + + sqlx::query!( + "INSERT INTO node_family_members (node_id, family_id, joined_at) + SELECT * FROM UNNEST($1::BIGINT[], $2::BIGINT[], $3::BIGINT[])", + &member_node_ids[..], + &member_family_ids[..], + &member_joined_ats[..], + ) + .execute(&mut *tx) + .await?; + + tx.commit().await?; + Ok(inserted) + } + + /// Read every cached family. + pub(crate) async fn get_all_node_families(&self) -> anyhow::Result> { + sqlx::query_as!( + NodeFamilyDto, + r#"SELECT + family_id, + name, + description, + owner, + family_stake_unym, + members_count, + created_at + FROM node_families + ORDER BY family_id"#, + ) + .fetch(&self.pool) + .try_collect::>() + .await + .map_err(From::from) + } + + /// Read every cached `(node_id, family_id)` membership pair. + pub(crate) async fn get_all_node_family_members( + &self, + ) -> anyhow::Result> { + sqlx::query_as!( + NodeFamilyMemberDto, + r#"SELECT node_id, family_id + FROM node_family_members"#, + ) + .fetch(&self.pool) + .try_collect::>() + .await + .map_err(From::from) + } +} diff --git a/nym-node-status-api/nym-node-status-api/src/db/queries/nym_nodes.rs b/nym-node-status-api/nym-node-status-api/src/db/queries/nym_nodes.rs index 969fd087f6..a6cd26223c 100644 --- a/nym-node-status-api/nym-node-status-api/src/db/queries/nym_nodes.rs +++ b/nym-node-status-api/nym-node-status-api/src/db/queries/nym_nodes.rs @@ -1,4 +1,5 @@ use crate::db::DbConnection; +use crate::db::Storage; use crate::db::models::NymNodeDescriptionDeHelper; use crate::http::models::DailyStats; use crate::{ @@ -13,100 +14,95 @@ use nym_node_requests::api::v1::node::models::NodeDescription; use nym_validator_client::client::{NodeId, NymNodeDetails}; use nym_validator_client::models::NymNodeDescriptionV2; use std::collections::HashMap; -use tracing::{instrument, warn}; +use tracing::{error, instrument, warn}; -pub(crate) async fn get_all_nym_nodes(pool: &DbPool) -> anyhow::Result> { - let mut conn = pool.acquire().await?; +impl Storage { + pub(crate) async fn get_all_nym_nodes(&self) -> anyhow::Result> { + sqlx::query_as!( + NymNodeDto, + r#"SELECT + node_id, + ed25519_identity_pubkey, + total_stake, + ip_addresses as "ip_addresses!: serde_json::Value", + mix_port, + x25519_sphinx_pubkey, + node_role as "node_role: serde_json::Value", + supported_roles as "supported_roles: serde_json::Value", + entry as "entry: serde_json::Value", + performance, + self_described as "self_described: serde_json::Value", + bond_info as "bond_info: serde_json::Value", + http_api_port + FROM + nym_nodes + ORDER BY + node_id + "#, + ) + .fetch(&self.pool) + .try_collect::>() + .await + .map_err(From::from) + } - sqlx::query_as!( - NymNodeDto, - r#"SELECT - node_id, - ed25519_identity_pubkey, - total_stake, - ip_addresses as "ip_addresses!: serde_json::Value", - mix_port, - x25519_sphinx_pubkey, - node_role as "node_role: serde_json::Value", - supported_roles as "supported_roles: serde_json::Value", - entry as "entry: serde_json::Value", - performance, - self_described as "self_described: serde_json::Value", - bond_info as "bond_info: serde_json::Value", - http_api_port - FROM - nym_nodes - ORDER BY - node_id - "#, - ) - .fetch(&mut *conn) - .try_collect::>() - .await - .map_err(From::from) -} + /// if a node doesn't expose its self-described endpoint, it can't route traffic + /// - https://nym.com/docs/operators/nodes/nym-node/bonding + /// + /// same if it's not bonded in the mixnet smart contract + /// - https://nym.com/docs/operators/tokenomics/mixnet-rewards#rewarded-set-selection + pub(crate) async fn get_described_bonded_nym_nodes(&self) -> anyhow::Result> { + sqlx::query_as!( + NymNodeDto, + r#"SELECT + node_id, + ed25519_identity_pubkey, + total_stake, + ip_addresses as "ip_addresses!: serde_json::Value", + mix_port, + x25519_sphinx_pubkey, + node_role as "node_role: serde_json::Value", + supported_roles as "supported_roles: serde_json::Value", + entry as "entry: serde_json::Value", + performance, + self_described as "self_described: serde_json::Value", + bond_info as "bond_info: serde_json::Value", + http_api_port + FROM + nym_nodes + WHERE + self_described IS NOT NULL + AND + bond_info IS NOT NULL + "#, + ) + .fetch(&self.pool) + .try_collect::>() + .await + .map_err(From::from) + } -/// if a node doesn't expose its self-described endpoint, it can't route traffic -/// - https://nym.com/docs/operators/nodes/nym-node/bonding -/// -/// same if it's not bonded in the mixnet smart contract -/// - https://nym.com/docs/operators/tokenomics/mixnet-rewards#rewarded-set-selection -pub(crate) async fn get_described_bonded_nym_nodes( - pool: &DbPool, -) -> anyhow::Result> { - let mut conn = pool.acquire().await?; + #[instrument(level = "debug", skip_all, fields(node_records=node_records.len()))] + pub(crate) async fn update_nym_nodes( + &self, + node_records: Vec, + ) -> anyhow::Result { + let mut tx = self.pool.begin().await?; - sqlx::query_as!( - NymNodeDto, - r#"SELECT - node_id, - ed25519_identity_pubkey, - total_stake, - ip_addresses as "ip_addresses!: serde_json::Value", - mix_port, - x25519_sphinx_pubkey, - node_role as "node_role: serde_json::Value", - supported_roles as "supported_roles: serde_json::Value", - entry as "entry: serde_json::Value", - performance, - self_described as "self_described: serde_json::Value", - bond_info as "bond_info: serde_json::Value", - http_api_port - FROM - nym_nodes - WHERE - self_described IS NOT NULL - AND - bond_info IS NOT NULL - "#, - ) - .fetch(&mut *conn) - .try_collect::>() - .await - .map_err(From::from) -} - -#[instrument(level = "debug", skip_all, fields(node_records=node_records.len()))] -pub(crate) async fn update_nym_nodes( - pool: &DbPool, - node_records: Vec, -) -> anyhow::Result { - let mut tx = pool.begin().await?; - - sqlx::query!( - "UPDATE nym_nodes + sqlx::query!( + "UPDATE nym_nodes SET self_described = NULL, bond_info = NULL", - ) - .execute(&mut *tx) - .await?; + ) + .execute(&mut *tx) + .await?; - let inserted = node_records.len(); - for record in node_records { - // https://www.sqlite.org/lang_upsert.html - sqlx::query!( - "INSERT INTO nym_nodes + let inserted = node_records.len(); + for record in node_records { + // https://www.sqlite.org/lang_upsert.html + sqlx::query!( + "INSERT INTO nym_nodes (node_id, ed25519_identity_pubkey, total_stake, ip_addresses, mix_port, @@ -131,146 +127,148 @@ pub(crate) async fn update_nym_nodes( last_updated_utc=excluded.last_updated_utc, http_api_port=excluded.http_api_port ;", - record.node_id, - record.ed25519_identity_pubkey, - record.total_stake, - record.ip_addresses, - record.mix_port, - record.x25519_sphinx_pubkey, - record.node_role, - record.supported_roles, - record.entry, - record.self_described, - record.bond_info, - record.performance, - record.last_updated_utc as i32, - record.http_api_port, - ) - .execute(&mut *tx) - .await - .map_err(|e| anyhow::anyhow!("Failed to INSERT node_id={}: {}", record.node_id, e))?; + record.node_id, + record.ed25519_identity_pubkey, + record.total_stake, + record.ip_addresses, + record.mix_port, + record.x25519_sphinx_pubkey, + record.node_role, + record.supported_roles, + record.entry, + record.self_described, + record.bond_info, + record.performance, + record.last_updated_utc as i32, + record.http_api_port, + ) + .execute(&mut *tx) + .await + .map_err(|e| anyhow::anyhow!("Failed to INSERT node_id={}: {}", record.node_id, e))?; + } + + tx.commit().await?; + + Ok(inserted) } - tx.commit().await?; + pub(crate) async fn get_described_node_bond_info( + &self, + ) -> anyhow::Result> { + sqlx::query!( + r#"SELECT + node_id, + bond_info as "bond_info: serde_json::Value" + FROM + nym_nodes + WHERE + bond_info IS NOT NULL + AND + self_described IS NOT NULL + "#, + ) + .fetch_all(&self.pool) + .await + .map(|records| { + records + .into_iter() + .filter_map(|record| { + let node_id = record.node_id; + record + .bond_info + // only return details for nodes which have details stored + .and_then(|bond_info| { + serde_json::from_value::(bond_info) + .inspect_err(|err| { + error!("malformed bond_info for node {node_id}: {err}") + }) + .ok() + }) + .map(|res| (node_id as NodeId, res)) + }) + .collect::>() + }) + .map_err(From::from) + } - Ok(inserted) -} + pub(crate) async fn get_node_self_description( + &self, + ) -> anyhow::Result> { + sqlx::query!( + r#"SELECT + node_id, + self_described as "self_described: serde_json::Value" + FROM + nym_nodes + WHERE + self_described IS NOT NULL + ORDER BY + node_id + "#, + ) + .fetch_all(&self.pool) + .await + .map(|records| { + records + .into_iter() + .filter_map(|record| { + let node_id = record.node_id; + record + .self_described + // only return details for nodes which have details stored + .and_then(|description| { + serde_json::from_value::(description) + .inspect_err(|err| { + warn!("malformed description data for node {node_id}: {err}") + }) + .ok() + }) + .map(|res| (record.node_id as NodeId, res.into())) + }) + .collect::>() + }) + .map_err(From::from) + } -pub(crate) async fn get_described_node_bond_info( - pool: &DbPool, -) -> anyhow::Result> { - let mut conn = pool.acquire().await?; - - sqlx::query!( - r#"SELECT - node_id, - bond_info as "bond_info: serde_json::Value" - FROM - nym_nodes - WHERE - bond_info IS NOT NULL - AND - self_described IS NOT NULL - "#, - ) - .fetch_all(&mut *conn) - .await - .map(|records| { - records - .into_iter() - .filter_map(|record| { - record - .bond_info - // only return details for nodes which have details stored - .and_then(|bond_info| serde_json::from_value::(bond_info).ok()) - .map(|res| (record.node_id as NodeId, res)) - }) - .collect::>() - }) - .map_err(From::from) -} - -pub(crate) async fn get_node_self_description( - pool: &DbPool, -) -> anyhow::Result> { - let mut conn = pool.acquire().await?; - - sqlx::query!( - r#"SELECT - node_id, - self_described as "self_described: serde_json::Value" - FROM - nym_nodes - WHERE - self_described IS NOT NULL - ORDER BY - node_id - "#, - ) - .fetch_all(&mut *conn) - .await - .map(|records| { - records - .into_iter() - .filter_map(|record| { - let node_id = record.node_id; - record - .self_described - // only return details for nodes which have details stored - .and_then(|description| { - serde_json::from_value::(description) - .inspect_err(|err| { - warn!("malformed description data for node {node_id}: {err}") - }) - .ok() - }) - .map(|res| (record.node_id as NodeId, res.into())) - }) - .collect::>() - }) - .map_err(From::from) -} - -pub(crate) async fn get_bonded_node_description( - pool: &DbPool, -) -> anyhow::Result> { - let mut conn = pool.acquire().await?; - - sqlx::query!( - r#"SELECT - nd.node_id, - moniker, - website, - security_contact, - details - FROM - nym_node_descriptions nd - INNER JOIN - nym_nodes nn on nd.node_id = nn.node_id - WHERE - bond_info IS NOT NULL - "#, - ) - .fetch_all(&mut *conn) - .await - .map(|records| { - records - .into_iter() - .map(|elem| { - let node_id: NodeId = elem.node_id.try_into().unwrap_or_default(); - ( - node_id, - NodeDescription { - moniker: elem.moniker.unwrap_or_default(), - website: elem.website.unwrap_or_default(), - security_contact: elem.security_contact.unwrap_or_default(), - details: elem.details.unwrap_or_default(), - }, - ) - }) - .collect::>() - }) - .map_err(From::from) + pub(crate) async fn get_bonded_node_description( + &self, + ) -> anyhow::Result> { + sqlx::query!( + r#"SELECT + nd.node_id, + moniker, + website, + security_contact, + details + FROM + nym_node_descriptions nd + INNER JOIN + nym_nodes nn on nd.node_id = nn.node_id + WHERE + bond_info IS NOT NULL + "#, + ) + .fetch_all(&self.pool) + .await + .map(|records| { + records + .into_iter() + .map(|elem| { + let node_id: NodeId = elem.node_id.try_into().unwrap_or_default(); + ( + node_id, + NodeDescription { + moniker: elem.moniker.unwrap_or_default(), + website: elem.website.unwrap_or_default(), + security_contact: elem.security_contact.unwrap_or_default(), + details: elem.details.unwrap_or_default(), + }, + ) + }) + .collect::>() + }) + .map_err(From::from) + } } pub(crate) async fn insert_nym_node_description( diff --git a/nym-node-status-api/nym-node-status-api/src/db/queries/scraper.rs b/nym-node-status-api/nym-node-status-api/src/db/queries/scraper.rs index 8b962067e3..6e0aa76a24 100644 --- a/nym-node-status-api/nym-node-status-api/src/db/queries/scraper.rs +++ b/nym-node-status-api/nym-node-status-api/src/db/queries/scraper.rs @@ -18,7 +18,8 @@ pub(crate) async fn get_nodes_for_scraping(pool: &DbPool) -> Result) -> HttpResult) -> HttpResult) -> HttpResult) -> HttpResult) -> HttpResult MIN_SUPPORTED_VERSION.clone(), }; + let storage = state.storage(); Ok(Json( state .cache() - .get_dvpn_gateway_list(state.db_pool(), &min_node_version) + .get_dvpn_gateway_list(storage, &min_node_version) .await, )) } #[instrument(level = tracing::Level::INFO, skip(state))] pub async fn dvpn_gateway_ips(state: State) -> HttpResult>> { + let storage = state.storage(); Ok(Json( state .cache() - .get_gateway_ips(state.db_pool(), &MIN_SUPPORTED_VERSION) + .get_gateway_ips(storage, &MIN_SUPPORTED_VERSION) .await, )) } diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/gateways.rs b/nym-node-status-api/nym-node-status-api/src/http/api/gateways.rs index 687e02ad34..ac24be2351 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/gateways.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/gateways.rs @@ -34,8 +34,8 @@ async fn gateways( Query(pagination): Query, State(state): State, ) -> HttpResult>> { - let db = state.db_pool(); - let res = state.cache().get_gateway_list(db).await; + let storage = state.storage(); + let res = state.cache().get_gateway_list(storage).await; Ok(Json(PagedResult::paginate(pagination, res))) } @@ -55,8 +55,8 @@ async fn gateways_skinny( Query(pagination): Query, State(state): State, ) -> HttpResult>> { - let db = state.db_pool(); - let res = state.cache().get_gateway_list(db).await; + let storage = state.storage(); + let res = state.cache().get_gateway_list(storage).await; let res: Vec = filter_bonded_gateways_to_skinny(res); Ok(Json(PagedResult::paginate(pagination, res))) @@ -83,8 +83,8 @@ async fn get_gateway( Path(IdentityKeyParam { identity_key }): Path, State(state): State, ) -> HttpResult> { - let db = state.db_pool(); - let res = state.cache().get_gateway_list(db).await; + let storage = state.storage(); + let res = state.cache().get_gateway_list(storage).await; match res .iter() diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/nym_nodes.rs b/nym-node-status-api/nym-node-status-api/src/http/api/nym_nodes.rs index ae551685a4..ab8e4539c0 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/nym_nodes.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/nym_nodes.rs @@ -40,12 +40,12 @@ async fn nym_nodes( Query(pagination): Query, State(state): State, ) -> HttpResult>> { - let db = state.db_pool(); + let storage = state.storage(); let node_geocache = state.node_geocache(); let nodes = state .cache() - .get_nym_nodes_list(db, node_geocache) + .get_nym_nodes_list(storage, node_geocache) .await .map_err(|e| { tracing::error!("{e}"); diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/services/mod.rs b/nym-node-status-api/nym-node-status-api/src/http/api/services/mod.rs index 9658ab3614..a1615289a0 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/services/mod.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/services/mod.rs @@ -43,14 +43,14 @@ async fn mixnodes( Query(params): Query, State(state): State, ) -> HttpResult>> { - let db = state.db_pool(); + let storage = state.storage(); let cache = state.cache(); let paths = ParseJsonPaths::new().map_err(|e| { tracing::error!("Invalidly configured ParseJsonPaths: {e}"); HttpError::internal() })?; - let res = cache.get_gateway_list(db).await; + let res = cache.get_gateway_list(storage).await; let services = gateway_list_to_services(&paths, res, params.clone()); Ok(Json(PagedResult::paginate( diff --git a/nym-node-status-api/nym-node-status-api/src/http/models/mod.rs b/nym-node-status-api/nym-node-status-api/src/http/models/mod.rs index e070a85ec3..dfb93f9c52 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/models/mod.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/models/mod.rs @@ -9,7 +9,7 @@ use crate::{ monitor::ExplorerPrettyBond, }; use cosmwasm_std::{Addr, Coin, Decimal}; -use nym_mixnet_contract_common::CoinSchema; +use nym_mixnet_contract_common::{CoinSchema, NodeRewarding}; use nym_node_requests::api::v1::node::models::NodeDescription; use nym_validator_client::{ client::NodeId, @@ -29,6 +29,7 @@ use utoipa::ToSchema; use crate::db::models::NymNodeDataDeHelper; use crate::node_scraper::models::BridgeInformation; +use crate::monitor::geodata; pub(crate) use nym_node_status_client::models::TestrunAssignment; pub(crate) mod gw_probe; @@ -50,6 +51,128 @@ pub struct Gateway { pub bridges: Option, } +impl Gateway { + fn geo_location(&self) -> anyhow::Result { + self.explorer_pretty_bond + .clone() + .ok_or_else(|| anyhow::anyhow!("Missing explorer_pretty_bond")) + .and_then(|value| { + serde_json::from_value::(value).map_err(From::from) + }) + .map(|bond| bond.location) + } + + pub(crate) fn location(&self) -> anyhow::Result { + let geolocation = self.geo_location()?; + Ok(Location { + latitude: geolocation.location.latitude, + longitude: geolocation.location.longitude, + two_letter_iso_country_code: geolocation.two_letter_iso_country_code, + org: geolocation.org, + city: geolocation.city, + region: geolocation.region, + postal: geolocation.postal, + timezone: geolocation.timezone, + asn: geolocation.asn.map(|a| { + let kind = if a.kind.eq_ignore_ascii_case("isp") { + // we consider anything that is "ISP" from ipinfo to be residential + AsnKind::Residential + } else { + // everything else is considered "other" + AsnKind::Other + }; + Asn { + asn: a.asn, + domain: a.domain, + kind, + name: a.name, + route: a.route, + } + }), + }) + } + + pub(crate) fn self_described(&self) -> anyhow::Result { + self.self_described + .clone() + .ok_or_else(|| anyhow::anyhow!("Missing self_described")) + .and_then(|value| { + serde_json::from_value::(value).map_err(From::from) + }) + } + + pub(crate) fn bridges(&self) -> Option { + self.bridges.clone().and_then(|v| { + serde_json::from_value::(v) + .inspect_err(|err| { + error!( + "Failed to deserialize bridges for gateway identity {}: {err}", + self.gateway_identity_key + ); + }) + .ok() + }) + } + + fn last_probe_result(&self) -> anyhow::Result> { + let Some(last_probe) = &self.last_probe_result else { + return Ok(None); + }; + let probe = + LastProbeResult::deserialize_with_fallback(last_probe.clone()).inspect_err(|err| { + error!("Failed to deserialize probe result: {err}"); + })?; + + tracing::trace!("🌈 gateway probe parsed: {probe:?}"); + Ok(Some(probe)) + } + + pub(crate) fn last_dvpn_probe_result( + &self, + socks5_score: Option<&ScoreValue>, + ) -> anyhow::Result> { + let Some(last_probe) = self.last_probe_result()? else { + return Ok(None); + }; + + let socks5_score = socks5_score.unwrap_or(&ScoreValue::Offline).to_owned(); + let dvpn_probe_result = + DvpnProbeOutcome::from_raw_probe_outcome(last_probe.outcome(), socks5_score); + + Ok(Some(dvpn_probe_result)) + } + + pub(crate) fn performance_v2(&self) -> anyhow::Result> { + let Some(last_probe) = self.last_probe_result()? else { + return Ok(None); + }; + + let last_updated_utc = self.last_testrun_utc.clone().unwrap_or_default(); + + let network_monitor_performance_mixnet_mode = self.performance as f32 / 100f32; + let mixnet_score = calculate_mixnet_score(self); + let score = calc_gateway_visual_score(self, &last_probe); + let mut load = calculate_load(&last_probe); + + // clamp the load value to offline, when the score is offline + if score == ScoreValue::Offline { + load = ScoreValue::Offline; + } + + let performance_v2 = DVpnGatewayPerformance { + last_updated_utc: last_updated_utc.to_string(), + load, + score, + mixnet_score, + + // the network monitor's measure is a good proxy for node uptime, it can be improved in the future + uptime_percentage_last_24_hours: network_monitor_performance_mixnet_mode, + }; + + Ok(Some(performance_v2)) + } +} + #[derive(Debug, Clone, Deserialize, Serialize, ToSchema)] pub struct BuildInformation { pub build_version: String, @@ -157,6 +280,66 @@ impl From<&LewesProtocolDetailsDataV1Validator> for LewesProtocolDetailsDataV1 { } } +#[derive(Debug, Clone, Deserialize, Serialize, ToSchema)] +pub struct NodeFamilyInformation { + // family id + id: u32, + + // family name + name: String, + + // description + description: String, + + // amount in unym + family_stake: u128, + + // number of members + members: usize, +} + +impl NodeFamilyInformation { + pub(crate) fn new( + id: u32, + name: String, + description: String, + family_stake: u128, + members: usize, + ) -> Self { + Self { + id, + name, + description, + family_stake, + members, + } + } +} + +#[derive(Debug, Clone, Deserialize, Serialize, ToSchema)] +pub struct NodeStakeInformation { + // delegations + bond + total_stake: u128, + total_delegations: u128, + total_bond: u128, + // number of delegations + delegations: usize, +} + +impl From<&NodeRewarding> for NodeStakeInformation { + fn from(rewarding: &NodeRewarding) -> Self { + let denom = &rewarding.cost_params.interval_operating_cost.denom; + let total_bond = rewarding.operator_pledge_with_reward(denom).amount.u128(); + let total_delegations = rewarding.delegations_with_reward(denom).amount.u128(); + NodeStakeInformation { + total_stake: total_bond + total_delegations, + total_bond, + total_delegations, + delegations: rewarding.unique_delegations as usize, + } + } +} + #[derive(Debug, Clone, Deserialize, Serialize, ToSchema)] pub struct DVpnGateway { pub identity_key: String, @@ -183,6 +366,9 @@ pub struct DVpnGateway { pub lewes_protocol_details: Option, + pub family_data: Option, + pub staking_data: Option, + pub build_information: BinaryBuildInformationOwned, } @@ -208,73 +394,20 @@ impl DVpnGateway { gateway: Gateway, skimmed_node: &SkimmedNodeV1, socks5_score: Option<&ScoreValue>, + family_details: Option, + staking_details: Option, ) -> anyhow::Result { - let location = gateway - .explorer_pretty_bond - .clone() - .ok_or_else(|| anyhow::anyhow!("Missing explorer_pretty_bond")) - .and_then(|value| { - serde_json::from_value::(value).map_err(From::from) - }) - .map(|bond| bond.location)?; - - let self_described: NymNodeDataDeHelper = gateway - .self_described - .clone() - .ok_or_else(|| anyhow::anyhow!("Missing self_described")) - .and_then(|value| { - serde_json::from_value::(value).map_err(From::from) - })?; + let location = gateway.location()?; + let self_described = gateway.self_described()?; let last_updated_utc = gateway.last_testrun_utc.clone().unwrap_or_default(); let performance = to_percent(gateway.performance); - let network_monitor_performance_mixnet_mode = gateway.performance as f32 / 100f32; - let bridges = gateway.bridges.clone().and_then(|v| { - serde_json::from_value(v) - .inspect_err(|err| { - error!( - "Failed to deserialize bridges for gateway identity {}: {err}", - gateway.gateway_identity_key - ); - }) - .ok() - }); + let bridges = gateway.bridges(); tracing::debug!("🌈 gateway probe result: {:?}", gateway.last_probe_result); - let (last_probe_result, performance_v2) = match gateway.last_probe_result { - Some(ref value) => { - let parsed = LastProbeResult::deserialize_with_fallback(value.clone()) - .inspect_err(|err| { - error!("Failed to deserialize probe result: {err}"); - })?; - - tracing::trace!("🌈 gateway probe parsed: {:?}", parsed); - let mixnet_score = calculate_mixnet_score(&gateway); - let score = calc_gateway_visual_score(&gateway, &parsed); - let mut load = calculate_load(&parsed); - let socks5_score = socks5_score.unwrap_or(&ScoreValue::Offline).to_owned(); - let dvpn_probe_result = - DvpnProbeOutcome::from_raw_probe_outcome(parsed.outcome(), socks5_score); - - // clamp the load value to offline, when the score is offline - if score == ScoreValue::Offline { - load = ScoreValue::Offline; - } - - let performance_v2 = DVpnGatewayPerformance { - last_updated_utc: last_updated_utc.to_string(), - load, - score, - mixnet_score, - - // the network monitor's measure is a good proxy for node uptime, it can be improved in the future - uptime_percentage_last_24_hours: network_monitor_performance_mixnet_mode, - }; - (Some(dvpn_probe_result), Some(performance_v2)) - } - None => (None, None), - }; + let last_probe_result = gateway.last_dvpn_probe_result(socks5_score)?; + let performance_v2 = gateway.performance_v2()?; Ok(Self { identity_key: gateway.gateway_identity_key, @@ -282,32 +415,7 @@ impl DVpnGateway { description: Some(gateway.description.details), ip_packet_router: self_described.ip_packet_router, authenticator: self_described.authenticator, - location: Location { - latitude: location.location.latitude, - longitude: location.location.longitude, - two_letter_iso_country_code: location.two_letter_iso_country_code, - org: location.org, - city: location.city, - region: location.region, - postal: location.postal, - timezone: location.timezone, - asn: location.asn.map(|a| { - let kind = if a.kind.eq_ignore_ascii_case("isp") { - // we consider anything that is "ISP" from ipinfo to be residential - AsnKind::Residential - } else { - // everything else is considered "other" - AsnKind::Other - }; - Asn { - asn: a.asn, - domain: a.domain, - kind, - name: a.name, - route: a.route, - } - }), - }, + location, last_probe: last_probe_result .map(|res| DvpnGwProbe::from_outcome(res, last_updated_utc)), ip_addresses: skimmed_node.ip_addresses.clone(), @@ -321,6 +429,8 @@ impl DVpnGateway { .lewes_protocol .as_ref() .map(LewesProtocolDetailsV1::from), + family_data: family_details, + staking_data: staking_details, build_information: self_described.build_information, }) } @@ -664,6 +774,7 @@ pub(crate) struct ExtendedNymNode { pub(crate) rewarding_details: Option, pub(crate) description: NodeDescription, pub(crate) geoip: Option, + pub family_data: Option, } #[derive(Clone, Debug, utoipa::ToSchema, Deserialize, Serialize)] diff --git a/nym-node-status-api/nym-node-status-api/src/http/server.rs b/nym-node-status-api/nym-node-status-api/src/http/server.rs index 26106f3ba6..0127cc0fc1 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/server.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/server.rs @@ -1,6 +1,6 @@ use crate::ticketbook_manager::state::TicketbookManagerState; use crate::{ - db::DbPool, + db, http::{api::RouterBuilder, state::AppState}, monitor::{DelegationsCache, NodeGeoCache}, }; @@ -15,7 +15,7 @@ use tokio::{net::TcpListener, sync::RwLock}; /// background tokio task #[allow(clippy::too_many_arguments)] pub(crate) async fn start_http_api( - db_pool: DbPool, + storage: db::Storage, http_port: u16, nym_http_cache_ttl: u64, agent_key_list: Vec, @@ -29,7 +29,7 @@ pub(crate) async fn start_http_api( let router_builder = RouterBuilder::with_default_routes(); let state = AppState::new( - db_pool, + storage, nym_http_cache_ttl, agent_key_list, agent_max_count, diff --git a/nym-node-status-api/nym-node-status-api/src/http/state.rs b/nym-node-status-api/nym-node-status-api/src/http/state.rs index b630c17d40..4819c4ab80 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/state.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/state.rs @@ -15,9 +15,10 @@ use tokio::sync::RwLock; use tracing::{error, instrument, trace, warn}; use utoipa::ToSchema; -use super::models::SessionStats; +use super::models::{NodeFamilyInformation, NodeStakeInformation, SessionStats}; use crate::{ - db::{DbPool, queries}, + db, + db::DbPool, http::{ error::{HttpError, HttpResult}, models::{ @@ -30,10 +31,11 @@ use crate::{ use crate::ticketbook_manager::state::TicketbookManagerState; pub(crate) use nym_validator_client::models::BinaryBuildInformationOwned; +use nym_validator_client::nyxd::contract_traits::node_families_query_client::NodeFamilyId; #[derive(Clone)] pub(crate) struct AppState { - db_pool: DbPool, + storage: db::Storage, cache: HttpCache, agent_key_list: Vec, agent_max_count: i64, @@ -47,7 +49,7 @@ pub(crate) struct AppState { impl AppState { #[allow(clippy::too_many_arguments)] pub(crate) async fn new( - db_pool: DbPool, + storage: db::Storage, cache_ttl: u64, agent_key_list: Vec, agent_max_count: i64, @@ -57,7 +59,7 @@ impl AppState { ticketbook_manager_state: TicketbookManagerState, ) -> Self { Self { - db_pool, + storage, cache: HttpCache::new(cache_ttl).await, agent_key_list, agent_max_count, @@ -70,7 +72,11 @@ impl AppState { } pub(crate) fn db_pool(&self) -> &DbPool { - &self.db_pool + self.storage.pool() + } + + pub(crate) fn storage(&self) -> &db::Storage { + &self.storage } pub(crate) fn cache(&self) -> &HttpCache { @@ -225,7 +231,7 @@ impl HttpCache { .await } - pub async fn get_gateway_list(&self, db: &DbPool) -> Vec { + pub async fn get_gateway_list(&self, storage: &db::Storage) -> Vec { match self.gateways.get(GATEWAYS_LIST_KEY).await { Some(guard) => { tracing::trace!("Fetching from cache..."); @@ -236,7 +242,7 @@ impl HttpCache { // the key is missing so populate it tracing::trace!("No gateways in cache, refreshing cache from DB..."); - let gateways = match crate::db::queries::get_all_gateways(db).await { + let gateways = match storage.get_all_gateways().await { Ok(gws) => { tracing::info!("Successfully fetched {} gateways from database", gws.len()); if !gws.is_empty() { @@ -282,148 +288,185 @@ impl HttpCache { pub async fn get_dvpn_gateway_list( &self, - db: &DbPool, + storage: &db::Storage, min_node_version: &Version, ) -> Vec { - match self.dvpn_gateways.get(DVPN_GATEWAYS_LIST_KEY).await { + let gateways = match self.dvpn_gateways.get(DVPN_GATEWAYS_LIST_KEY).await { Some(guard) => { tracing::trace!("Fetching from cache..."); - let read_lock = guard.read().await; - read_lock.clone() + guard.read().await.clone() } None => { tracing::info!("No gateways (dVPN) in cache, refreshing from DB..."); - - let gateways = self.get_gateway_list(db).await; - tracing::info!("Found {} gateways in database", gateways.len()); - - let started_with = gateways.len(); - let skimmed_nodes = match crate::db::queries::get_described_bonded_nym_nodes(db) - .await - { - Ok(records) => { - let mut nodes = HashMap::new(); - for dto in records { - match SkimmedNodeV1::try_from(dto) { - Ok(skimmed_node) => { - let key = - skimmed_node.ed25519_identity_pubkey.to_base58_string(); - nodes.insert(key, skimmed_node); - } - Err(err) => { - error!( - "CRITICAL: Failed to convert NymNodeDto to SkimmedNode: {err}" - ); - panic!( - "Cannot convert database record to SkimmedNode - this should never happen! Error: {err}" - ); - } - } - } - nodes - } - Err(err) => { - error!("CRITICAL: Failed to query nym_nodes from database: {err}"); - panic!( - "Cannot read nym_nodes table - database connection issue? Error: {err}" - ); - } - }; - - let socks5_scores = calculate_socks5_percentiles(&gateways); - - let res_gws = gateways - .iter() - .filter(|gw| gw.bonded) - .filter_map(|gw| match skimmed_nodes.get(&gw.gateway_identity_key) { - Some(skimmed_node) => Some((gw, skimmed_node)), - None => { - error!( - "CRITICAL: Gateway {} exists in gateways table but not in nym_nodes table! This should not happen.", - gw.gateway_identity_key - ); - None - } - }) - .filter_map( - |(gw, skimmed_node)| match DVpnGateway::new(gw.clone(), skimmed_node, socks5_scores.get(&gw.gateway_identity_key)) { - Ok(gw) => Some(gw), - Err(err) => { - error!( - "CRITICAL: Failed to create DVpnGateway for node_id={}, identity_key={}: {}", - skimmed_node.node_id, - skimmed_node.ed25519_identity_pubkey.to_base58_string(), - err - ); - // Don't panic here as this might be due to missing fields, but log it loudly - None - } - }, - ) - .filter(|gw| { - let gw_version = &gw.build_information.build_version; - if let Ok(gw_version) = Version::parse(gw_version) { - &gw_version >= min_node_version - } else { - warn!("Failed to parse GW version {}", gw_version); - false - } - }) - .filter(|gw| { - // gateways must have a country - if gw.location.two_letter_iso_country_code.len() == 2 { - true - } else { - warn!( - "Invalid country code: {}", - gw.location.two_letter_iso_country_code - ); - false - } - }) - // sort by country, then by identity key - .sorted_by_key(|item| { - ( - item.location.two_letter_iso_country_code.clone(), - item.identity_key.clone(), - ) - }) - .collect::>(); - - let bonded_count = gateways.iter().filter(|gw| gw.bonded).count(); - tracing::info!( - "DVpn gateway filtering: {} total gateways, {} bonded, {} nym_nodes, {} final DVpn gateways", - started_with, - bonded_count, - skimmed_nodes.len(), - res_gws.len() - ); - - if res_gws.is_empty() && started_with > 0 { - tracing::error!( - "CRITICAL: Started with {} gateways but got 0 DVpn gateways! Min version: {}", - started_with, - min_node_version - ); - } else { - tracing::info!( - "Successfully loaded {} DVpn gateways into cache", - res_gws.len() - ); - self.upsert_dvpn_gateway_list(res_gws.clone()).await; + let built = self.build_dvpn_gateway_list(storage).await; + if !built.is_empty() { + self.upsert_dvpn_gateway_list(built.clone()).await; } + built + } + }; - res_gws + // version filter is applied at read time, not at cache-fill time, so + // requests with different `min_node_version` values do not poison each + // other's results. + gateways + .into_iter() + .filter(|gw| { + let gw_version = &gw.build_information.build_version; + match Version::parse(gw_version) { + Ok(parsed) => &parsed >= min_node_version, + Err(_) => { + warn!("Failed to parse GW version {gw_version}"); + false + } + } + }) + .collect() + } + + /// Rebuild the dVPN gateway list from DB. Does **not** apply any version + /// filter — that's done at read time. + async fn build_dvpn_gateway_list(&self, storage: &db::Storage) -> Vec { + let gateways = self.get_gateway_list(storage).await; + tracing::info!("Found {} gateways in database", gateways.len()); + + let started_with = gateways.len(); + + let records = match storage.get_described_bonded_nym_nodes().await { + Ok(records) => records, + Err(err) => { + error!("CRITICAL: Failed to query nym_nodes from database: {err}"); + panic!("Cannot read nym_nodes table - database connection issue? Error: {err}"); + } + }; + + let mut skimmed_nodes = HashMap::new(); + for dto in records { + match SkimmedNodeV1::try_from(dto) { + Ok(skimmed_node) => { + let key = skimmed_node.ed25519_identity_pubkey.to_base58_string(); + skimmed_nodes.insert(key, skimmed_node); + } + Err(err) => { + error!("CRITICAL: Failed to convert NymNodeDto to SkimmedNode: {err}"); + panic!( + "Cannot convert database record to SkimmedNode - this should never happen! Error: {err}" + ); + } } } + + let family_lookup = match load_family_lookup(storage).await { + Ok(lookup) => lookup, + Err(err) => { + error!("CRITICAL: Failed to load node-families lookup from database: {err}"); + panic!( + "Cannot read node_families tables - database connection issue? Error: {err}" + ); + } + }; + + let bond_info = match storage.get_described_node_bond_info().await { + Ok(map) => map, + Err(err) => { + error!("CRITICAL: Failed to load node bond info from database: {err}"); + panic!( + "Cannot read nym_nodes.bond_info column - database connection issue? Error: {err}" + ); + } + }; + + let socks5_scores = calculate_socks5_percentiles(&gateways); + + let res_gws = gateways + .iter() + .filter(|gw| gw.bonded) + .filter_map(|gw| match skimmed_nodes.get(&gw.gateway_identity_key) { + Some(skimmed_node) => Some((gw, skimmed_node)), + None => { + error!( + "CRITICAL: Gateway {} exists in gateways table but not in nym_nodes table! This should not happen.", + gw.gateway_identity_key + ); + None + } + }) + .filter_map(|(gw, skimmed_node)| { + let family = family_lookup.family_for_node(skimmed_node.node_id).cloned(); + let staking = bond_info + .get(&skimmed_node.node_id) + .map(|details| NodeStakeInformation::from(&details.rewarding_details)); + match DVpnGateway::new( + gw.clone(), + skimmed_node, + socks5_scores.get(&gw.gateway_identity_key), + family, + staking, + ) { + Ok(gw) => Some(gw), + Err(err) => { + error!( + "CRITICAL: Failed to create DVpnGateway for node_id={}, identity_key={}: {}", + skimmed_node.node_id, + skimmed_node.ed25519_identity_pubkey.to_base58_string(), + err + ); + // Don't panic here as this might be due to missing fields, but log it loudly + None + } + } + }) + .filter(|gw| { + // gateways must have a country + if gw.location.two_letter_iso_country_code.len() == 2 { + true + } else { + warn!( + "Invalid country code: {}", + gw.location.two_letter_iso_country_code + ); + false + } + }) + // sort by country, then by identity key + .sorted_by_key(|item| { + ( + item.location.two_letter_iso_country_code.clone(), + item.identity_key.clone(), + ) + }) + .collect::>(); + + let bonded_count = gateways.iter().filter(|gw| gw.bonded).count(); + tracing::info!( + "DVpn gateway filtering: {} total gateways, {} bonded, {} nym_nodes, {} final DVpn gateways", + started_with, + bonded_count, + skimmed_nodes.len(), + res_gws.len() + ); + + if res_gws.is_empty() && started_with > 0 { + tracing::error!( + "CRITICAL: Started with {} gateways but got 0 DVpn gateways!", + started_with + ); + } else { + tracing::info!( + "Successfully loaded {} DVpn gateways into cache", + res_gws.len() + ); + } + + res_gws } pub async fn get_entry_dvpn_gateways( &self, - db: &DbPool, + storage: &db::Storage, min_node_version: &Version, ) -> Vec { - self.get_dvpn_gateway_list(db, min_node_version) + self.get_dvpn_gateway_list(storage, min_node_version) .await .into_iter() .filter(DVpnGateway::can_route_entry) @@ -432,17 +475,21 @@ impl HttpCache { pub async fn get_exit_dvpn_gateways( &self, - db: &DbPool, + storage: &db::Storage, min_node_version: &Version, ) -> Vec { - self.get_dvpn_gateway_list(db, min_node_version) + self.get_dvpn_gateway_list(storage, min_node_version) .await .into_iter() .filter(DVpnGateway::can_route_exit) .collect() } - pub async fn get_gateway_ips(&self, db: &DbPool, min_node_version: &Version) -> Vec { + pub async fn get_gateway_ips( + &self, + storage: &db::Storage, + min_node_version: &Version, + ) -> Vec { match self.gateway_ips.get(DVPN_GATEWAY_IPS).await { Some(guard) => { let read_lock = guard.read().await; @@ -452,7 +499,7 @@ impl HttpCache { trace!("No exit gateway IPs in cache, refreshing..."); let ips: Vec = self - .get_dvpn_gateway_list(db, min_node_version) + .get_dvpn_gateway_list(storage, min_node_version) .await .into_iter() .flat_map(|gw| gw.ip_addresses) @@ -508,7 +555,7 @@ impl HttpCache { pub async fn get_nym_nodes_list( &self, - db: &DbPool, + storage: &db::Storage, node_geocache: NodeGeoCache, ) -> anyhow::Result> { match self.nym_nodes.get(NYM_NODES_LIST_KEY).await { @@ -520,7 +567,7 @@ impl HttpCache { None => { tracing::trace!("No nym nodes in cache, refreshing cache from DB..."); - let nym_nodes = aggregate_node_info_from_db(db, node_geocache).await?; + let nym_nodes = aggregate_node_info_from_db(storage, node_geocache).await?; if nym_nodes.is_empty() { tracing::warn!("Database contains 0 nym nodes"); @@ -650,13 +697,13 @@ impl HttpCache { #[instrument(level = "info", skip_all)] async fn aggregate_node_info_from_db( - pool: &DbPool, + storage: &db::Storage, node_geocache: NodeGeoCache, ) -> anyhow::Result> { - let node_bond_info = queries::get_described_node_bond_info(pool).await?; + let node_bond_info = storage.get_described_node_bond_info().await?; tracing::debug!("Described nodes with bond info: {}", node_bond_info.len()); - let skimmed_nodes = queries::get_all_nym_nodes(pool).await.map(|records| { + let skimmed_nodes = storage.get_all_nym_nodes().await.map(|records| { records .into_iter() .filter_map(|dto| SkimmedNodeV1::try_from(dto).ok()) @@ -665,10 +712,12 @@ async fn aggregate_node_info_from_db( })?; tracing::debug!("Skimmed nodes: {}", skimmed_nodes.len()); - let described_nodes = queries::get_node_self_description(pool).await?; + let described_nodes = storage.get_node_self_description().await?; tracing::debug!("Described nodes: {}", described_nodes.len()); - let node_descriptions = queries::get_bonded_node_description(pool).await?; + let node_descriptions = storage.get_bonded_node_description().await?; + + let families = load_family_lookup(storage).await?; let mut parsed_nym_nodes = Vec::new(); for (node_id, described_node) in described_nodes { @@ -722,6 +771,8 @@ async fn aggregate_node_info_from_db( }) }; + let family_data = families.family_for_node(node_id).cloned(); + parsed_nym_nodes.push(ExtendedNymNode { node_id, identity_key, @@ -737,6 +788,7 @@ async fn aggregate_node_info_from_db( rewarding_details: rewarding_details.to_owned(), description: node_description, geoip, + family_data, }); } @@ -762,3 +814,54 @@ impl BinaryInfo { pub(crate) struct HealthInfo { pub(crate) uptime: i64, } + +struct LoadedNodeFamilies { + member_lookup: HashMap, + family_lookup: HashMap, +} + +impl LoadedNodeFamilies { + /// Resolve the family `node_id` belongs to (if any) in one step. + fn family_for_node(&self, node_id: NodeId) -> Option<&NodeFamilyInformation> { + self.member_lookup + .get(&node_id) + .and_then(|fid| self.family_lookup.get(fid)) + } +} + +/// Load the families snapshot from DB and build two lookup maps: +/// `node_id → family_id` for member→family resolution, and +/// `family_id → NodeFamilyInformation` for hydrating gateway responses. +async fn load_family_lookup(storage: &db::Storage) -> anyhow::Result { + let families = storage.get_all_node_families().await?; + let members = storage.get_all_node_family_members().await?; + + let mut family_by_node = HashMap::new(); + for m in &members { + let node_id = m.node_id as NodeId; + let family_id = m.family_id as NodeFamilyId; + family_by_node.insert(node_id, family_id); + } + + let mut family_by_id: HashMap = HashMap::new(); + for f in families { + let family_id = f.family_id as u32; + let family_stake = f.family_stake_unym.unwrap_or_default() as u128; + let members_count = f.members_count as usize; + family_by_id.insert( + family_id, + NodeFamilyInformation::new( + family_id, + f.name, + f.description, + family_stake, + members_count, + ), + ); + } + + Ok(LoadedNodeFamilies { + member_lookup: family_by_node, + family_lookup: family_by_id, + }) +} diff --git a/nym-node-status-api/nym-node-status-api/src/main.rs b/nym-node-status-api/nym-node-status-api/src/main.rs index 352f310c01..0d504638a1 100644 --- a/nym-node-status-api/nym-node-status-api/src/main.rs +++ b/nym-node-status-api/nym-node-status-api/src/main.rs @@ -17,7 +17,7 @@ mod db; mod http; mod logging; mod metrics_scraper; -mod monitor; +pub(crate) mod monitor; mod node_scraper; mod testruns; mod ticketbook_manager; @@ -182,7 +182,7 @@ async fn main() -> anyhow::Result<()> { let shutdown_tracker = shutdown_manager.shutdown_tracker(); http::server::start_http_api( - storage.pool_owned(), + storage, args.http_port, args.nym_http_cache_ttl, agent_key_list.to_owned(), diff --git a/nym-node-status-api/nym-node-status-api/src/monitor/mod.rs b/nym-node-status-api/nym-node-status-api/src/monitor/mod.rs index ea95ae6cbb..7be4ea6368 100644 --- a/nym-node-status-api/nym-node-status-api/src/monitor/mod.rs +++ b/nym-node-status-api/nym-node-status-api/src/monitor/mod.rs @@ -3,9 +3,10 @@ use crate::db::models::{ ASSIGNED_ENTRY_COUNT, ASSIGNED_EXIT_COUNT, ASSIGNED_MIXING_COUNT, GATEWAYS_BONDED_COUNT, GATEWAYS_HISTORICAL_COUNT, GatewayInsertRecord, MIXNODES_HISTORICAL_COUNT, NYMNODE_COUNT, - NYMNODES_DESCRIBED_COUNT, NetworkSummary, NymNodeInsertRecord, gateway, mixnode, + NYMNODES_DESCRIBED_COUNT, NetworkSummary, NodeFamilyInsertRecord, NodeFamilyMemberInsertRecord, + NymNodeInsertRecord, gateway, mixnode, }; -use crate::db::{DbPool, queries}; +use crate::db::{DbPool, Storage}; use crate::utils::now_utc; use crate::utils::{LogError, NumericalCheckedCast}; use moka::future::Cache; @@ -23,14 +24,14 @@ use tracing::instrument; pub(crate) use geodata::{ExplorerPrettyBond, IpInfoClient, Location}; pub(crate) use node_delegations::DelegationsCache; -mod geodata; +pub(crate) mod geodata; mod node_delegations; const MONITOR_FAILURE_RETRY_DELAY: Duration = Duration::from_secs(60); pub(crate) type NodeGeoCache = Cache; struct Monitor { - db_pool: DbPool, + storage: Storage, network_details: NymNetworkDetails, nym_api_client_timeout: Duration, nyxd_client: QueryHttpRpcNyxdClient, @@ -54,7 +55,7 @@ pub(crate) async fn run_in_background( let ipinfo = IpInfoClient::new(ipinfo_api_token.clone()); let mut monitor = Monitor { - db_pool, + storage: Storage::from_pool(db_pool), network_details: nym_network_defaults::NymNetworkDetails::new_from_env(), nym_api_client_timeout, nyxd_client, @@ -94,7 +95,7 @@ pub(crate) async fn run_once( let ipinfo = IpInfoClient::new(ipinfo_api_token.clone()); let mut monitor = Monitor { - db_pool, + storage: Storage::from_pool(db_pool), network_details: nym_network_defaults::NymNetworkDetails::new_from_env(), nym_api_client_timeout, nyxd_client, @@ -170,12 +171,26 @@ impl Monitor { let nym_node_records = self.prepare_nym_node_data(nym_nodes.clone(), &bonded_nym_nodes, &described_nodes); - queries::update_nym_nodes(&self.db_pool, nym_node_records) + self.storage + .update_nym_nodes(nym_node_records) .await .map(|inserted| { tracing::debug!("{} nym nodes written to DB!", inserted); })?; + let node_families = nym_api + .get_all_node_families() + .await + .log_error("get_all_node_families")?; + tracing::info!("🟣 node families: {}", node_families.len()); + let family_records = prepare_node_family_data(node_families); + self.storage + .update_node_families(family_records) + .await + .map(|inserted| { + tracing::debug!("{inserted} node families written to DB!"); + })?; + // stop here if running once if exit_early { return Ok(()); @@ -209,9 +224,9 @@ impl Monitor { .prepare_gateway_data(&gateways, &nym_nodes, &bonded_nym_nodes) .await?; - let pool = self.db_pool.clone(); let gateways_count = gateway_records.len(); - queries::update_bonded_gateways(&pool, gateway_records) + self.storage + .update_bonded_gateways(gateway_records) .await .map(|_| { tracing::debug!("{} gateway records written to DB!", gateways_count); @@ -219,7 +234,7 @@ impl Monitor { self.refresh_node_delegations(&bonded_nym_nodes).await; - let (all_historical_gateways, all_historical_mixnodes) = historical_count(&pool).await?; + let (all_historical_gateways, all_historical_mixnodes) = self.historical_count().await?; // // write summary keys and values to table @@ -267,7 +282,9 @@ impl Monitor { }, }; - queries::insert_summaries(&pool, &nodes_summary, &network_summary, last_updated).await?; + self.storage + .insert_summaries(&nodes_summary, &network_summary, last_updated) + .await?; let mut log_lines: Vec = vec![]; for (key, value) in nodes_summary.iter() { @@ -402,22 +419,65 @@ impl Monitor { // update after refreshing all to avoid holding write lock for too long *self.node_delegations.write().await = delegations_per_node; } + + async fn historical_count(&self) -> anyhow::Result<(usize, usize)> { + let mut conn = self.storage.pool().acquire().await?; + + let all_historical_gateways = sqlx::query_scalar!(r#"SELECT count(id) FROM gateways"#) + .fetch_one(&mut *conn) + .await? + .unwrap_or(0) + .cast_checked()?; + + let all_historical_mixnodes = sqlx::query_scalar!(r#"SELECT count(id) FROM mixnodes"#) + .fetch_one(&mut *conn) + .await? + .unwrap_or(0) + .cast_checked()?; + + Ok((all_historical_gateways, all_historical_mixnodes)) + } } -async fn historical_count(pool: &DbPool) -> anyhow::Result<(usize, usize)> { - let mut conn = pool.acquire().await?; +/// Project a nym-api families snapshot into the shape stored in the +/// `node_families` / `node_family_members` tables. Members with stake info +/// missing on the nym-api side are still recorded — only the per-family +/// stake total drops to `NULL`. +fn prepare_node_family_data( + families: Vec, +) -> Vec { + let last_updated_utc = now_utc().unix_timestamp(); - let all_historical_gateways = sqlx::query_scalar!(r#"SELECT count(id) FROM gateways"#) - .fetch_one(&mut *conn) - .await? - .unwrap_or(0) - .cast_checked()?; + families + .into_iter() + .map(|family| { + let family_stake_unym = family + .total_stake + .as_ref() + .and_then(|coin| i64::try_from(coin.amount.u128()).ok()); - let all_historical_mixnodes = sqlx::query_scalar!(r#"SELECT count(id) FROM mixnodes"#) - .fetch_one(&mut *conn) - .await? - .unwrap_or(0) - .cast_checked()?; + let members_count = family.members.len() as i32; - Ok((all_historical_gateways, all_historical_mixnodes)) + let members: Vec<_> = family + .members + .into_iter() + .map(|m| NodeFamilyMemberInsertRecord { + node_id: m.node_id as i64, + joined_at: m.joined_at.unix_timestamp(), + }) + .collect(); + + NodeFamilyInsertRecord { + family_id: family.id as i64, + name: family.name, + description: family.description, + owner: family.owner, + family_stake_unym, + members_count, + created_at: family.created_at.unix_timestamp(), + last_updated_utc, + members, + } + }) + .collect() } diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 1f2c0eddb3..fa332f465b 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -4615,7 +4615,7 @@ dependencies = [ [[package]] name = "nym-api-requests" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bs58", "celes", @@ -4655,7 +4655,7 @@ dependencies = [ [[package]] name = "nym-bin-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "const-str", "log", @@ -4686,7 +4686,7 @@ dependencies = [ [[package]] name = "nym-coconut-dkg-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -4699,7 +4699,7 @@ dependencies = [ [[package]] name = "nym-compact-ecash" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bincode", "bs58", @@ -4721,7 +4721,7 @@ dependencies = [ [[package]] name = "nym-config" -version = "1.20.4" +version = "1.21.0" dependencies = [ "dirs 6.0.0", "handlebars", @@ -4735,7 +4735,7 @@ dependencies = [ [[package]] name = "nym-contracts-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bs58", "cosmwasm-schema", @@ -4749,7 +4749,7 @@ dependencies = [ [[package]] name = "nym-credentials-interface" -version = "1.20.4" +version = "1.21.0" dependencies = [ "nym-bls12_381-fork", "nym-compact-ecash", @@ -4767,7 +4767,7 @@ dependencies = [ [[package]] name = "nym-crypto" -version = "1.20.4" +version = "1.21.0" dependencies = [ "base64 0.22.1", "bs58", @@ -4789,7 +4789,7 @@ dependencies = [ [[package]] name = "nym-ecash-contract-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bs58", "cosmwasm-schema", @@ -4802,7 +4802,7 @@ dependencies = [ [[package]] name = "nym-ecash-signer-check-types" -version = "1.20.4" +version = "1.21.0" dependencies = [ "nym-coconut-dkg-common", "nym-crypto", @@ -4817,14 +4817,14 @@ dependencies = [ [[package]] name = "nym-ecash-time" -version = "1.20.4" +version = "1.21.0" dependencies = [ "time", ] [[package]] name = "nym-exit-policy" -version = "1.20.4" +version = "1.21.0" dependencies = [ "serde", "serde_json", @@ -4835,7 +4835,7 @@ dependencies = [ [[package]] name = "nym-group-contract-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "cosmwasm-schema", "cw-controllers", @@ -4846,7 +4846,7 @@ dependencies = [ [[package]] name = "nym-http-api-client" -version = "1.20.4" +version = "1.21.0" dependencies = [ "async-trait", "bincode", @@ -4878,7 +4878,7 @@ dependencies = [ [[package]] name = "nym-http-api-client-macro" -version = "1.20.4" +version = "1.21.0" dependencies = [ "proc-macro-crate 3.3.0", "proc-macro2", @@ -4889,7 +4889,7 @@ dependencies = [ [[package]] name = "nym-http-api-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bincode", "serde", @@ -4899,7 +4899,7 @@ dependencies = [ [[package]] name = "nym-kkt-ciphersuite" -version = "1.20.4" +version = "1.21.0" dependencies = [ "num_enum", "semver", @@ -4910,7 +4910,7 @@ dependencies = [ [[package]] name = "nym-mixnet-contract-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "bs58", "cosmwasm-schema", @@ -4931,7 +4931,7 @@ dependencies = [ [[package]] name = "nym-multisig-contract-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -4946,7 +4946,7 @@ dependencies = [ [[package]] name = "nym-network-defaults" -version = "1.20.4" +version = "1.21.0" dependencies = [ "cargo_metadata 0.19.2", "dotenvy", @@ -4960,9 +4960,24 @@ dependencies = [ "utoipa", ] +[[package]] +name = "nym-node-families-contract-common" +version = "1.21.0" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers", + "cw-utils", + "nym-contracts-common", + "nym-mixnet-contract-common", + "schemars", + "serde", + "thiserror 2.0.12", +] + [[package]] name = "nym-node-requests" -version = "1.20.4" +version = "1.21.0" dependencies = [ "async-trait", "celes", @@ -4988,7 +5003,7 @@ dependencies = [ [[package]] name = "nym-noise-keys" -version = "1.20.4" +version = "1.21.0" dependencies = [ "nym-crypto", "schemars", @@ -4998,7 +5013,7 @@ dependencies = [ [[package]] name = "nym-pemstore" -version = "1.20.4" +version = "1.21.0" dependencies = [ "pem", "tracing", @@ -5007,7 +5022,7 @@ dependencies = [ [[package]] name = "nym-performance-contract-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -5020,7 +5035,7 @@ dependencies = [ [[package]] name = "nym-serde-helpers" -version = "1.20.4" +version = "1.21.0" dependencies = [ "base64 0.22.1", "bs58", @@ -5031,7 +5046,7 @@ dependencies = [ [[package]] name = "nym-store-cipher" -version = "1.20.4" +version = "1.21.0" dependencies = [ "aes-gcm", "argon2", @@ -5046,7 +5061,7 @@ dependencies = [ [[package]] name = "nym-ticketbooks-merkle" -version = "1.20.4" +version = "1.21.0" dependencies = [ "nym-credentials-interface", "nym-serde-helpers", @@ -5060,7 +5075,7 @@ dependencies = [ [[package]] name = "nym-types" -version = "1.20.4" +version = "1.21.0" dependencies = [ "base64 0.22.1", "cosmrs", @@ -5090,7 +5105,7 @@ dependencies = [ [[package]] name = "nym-upgrade-mode-check" -version = "1.20.4" +version = "1.21.0" dependencies = [ "jwt-simple", "nym-crypto", @@ -5106,7 +5121,7 @@ dependencies = [ [[package]] name = "nym-validator-client" -version = "1.20.4" +version = "1.21.0" dependencies = [ "async-trait", "base64 0.22.1", @@ -5135,6 +5150,7 @@ dependencies = [ "nym-mixnet-contract-common", "nym-multisig-contract-common", "nym-network-defaults", + "nym-node-families-contract-common", "nym-performance-contract-common", "nym-serde-helpers", "nym-vesting-contract-common", @@ -5155,7 +5171,7 @@ dependencies = [ [[package]] name = "nym-vesting-contract-common" -version = "1.20.4" +version = "1.21.0" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -5201,7 +5217,7 @@ dependencies = [ [[package]] name = "nym-wireguard-types" -version = "1.20.4" +version = "1.21.0" dependencies = [ "base64 0.22.1", "nym-crypto", diff --git a/nym-wallet/nym-wallet-types/src/network/sandbox.rs b/nym-wallet/nym-wallet-types/src/network/sandbox.rs index f8e66ebe3e..6b82c30932 100644 --- a/nym-wallet/nym-wallet-types/src/network/sandbox.rs +++ b/nym-wallet/nym-wallet-types/src/network/sandbox.rs @@ -28,6 +28,10 @@ pub(crate) const COCONUT_DKG_CONTRACT_ADDRESS: &str = pub(crate) const PERFORMANCE_CONTRACT_ADDRESS: &str = ""; // /\ TODO: this has to be updated once the contract is deployed +// \/ TODO: this has to be updated once the contract is deployed +pub(crate) const NODE_FAMILIES_CONTRACT_ADDRESS: &str = ""; +// /\ TODO: this has to be updated once the contract is deployed + // -- Constructor functions -- pub(crate) fn validators() -> Vec { @@ -51,6 +55,7 @@ pub(crate) fn network_details() -> nym_network_defaults::NymNetworkDetails { mixnet_contract_address: parse_optional_str(MIXNET_CONTRACT_ADDRESS), vesting_contract_address: parse_optional_str(VESTING_CONTRACT_ADDRESS), performance_contract_address: parse_optional_str(PERFORMANCE_CONTRACT_ADDRESS), + node_families_contract_address: parse_optional_str(NODE_FAMILIES_CONTRACT_ADDRESS), ecash_contract_address: parse_optional_str(ECASH_CONTRACT_ADDRESS), group_contract_address: parse_optional_str(GROUP_CONTRACT_ADDRESS), multisig_contract_address: parse_optional_str(MULTISIG_CONTRACT_ADDRESS), diff --git a/tools/internal/localnet-orchestrator/src/orchestrator/setup/cosmwasm_contracts.rs b/tools/internal/localnet-orchestrator/src/orchestrator/setup/cosmwasm_contracts.rs index 5962a36b7c..d43fa3b53c 100644 --- a/tools/internal/localnet-orchestrator/src/orchestrator/setup/cosmwasm_contracts.rs +++ b/tools/internal/localnet-orchestrator/src/orchestrator/setup/cosmwasm_contracts.rs @@ -28,7 +28,7 @@ use std::path::PathBuf; use std::time::Duration; use time::OffsetDateTime; use time::format_description::well_known::Rfc3339; -use tracing::{debug, info}; +use tracing::{debug, error, info}; pub(crate) struct Config { pub(crate) reproducible_builds: bool, @@ -92,6 +92,10 @@ impl LocalnetOrchestrator { Ok(nym_mixnet_contract_common::MigrateMsg { vesting_contract_address: Some(ctx.data.contracts.vesting.address()?.to_string()), unsafe_skip_state_updates: Some(true), + // currently the orchestrator is NOT instantiating the node families contract, + // however, because we have set `unsafe_skip_state_updates to true, + // the address will not actually be used, so we can put any placeholder value here + node_families_contract_address: ctx.data.contracts.vesting.address()?.to_string(), }) } @@ -109,6 +113,7 @@ impl LocalnetOrchestrator { &self, ctx: &LocalnetContext, ) -> anyhow::Result { + error!("unimplemented node families contract instantiation"); Ok(nym_mixnet_contract_common::InstantiateMsg { rewarding_validator_address: ctx .data @@ -124,6 +129,15 @@ impl LocalnetOrchestrator { .address() .to_string(), // PLACEHOLDER /\ + + // PLACEHOLDER \/ + node_families_contract_address: ctx + .data + .auxiliary_accounts + .mixnet_rewarder + .address() + .to_string(), + // PLACEHOLDER /\ rewarding_denom: "unym".to_string(), epochs_in_interval: 720, epoch_duration: Duration::from_secs(60 * 60), From 71d50d79c236bf766dc42bb02e88c103c006a9b6 Mon Sep 17 00:00:00 2001 From: Simon Wicky Date: Tue, 19 May 2026 14:21:12 +0200 Subject: [PATCH 06/94] fix clippy 1.95 lints (#6794) --- clients/native/src/websocket/handler.rs | 2 ++ .../src/client/real_messages_control/message_handler.rs | 4 ++-- common/nym_offline_compact_ecash/src/proofs/mod.rs | 4 +--- common/verloc/src/measurements/sender.rs | 5 ++--- nym-api/src/network_monitor/monitor/sender.rs | 2 +- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/clients/native/src/websocket/handler.rs b/clients/native/src/websocket/handler.rs index 2ea7cac609..e9ade8d046 100644 --- a/clients/native/src/websocket/handler.rs +++ b/clients/native/src/websocket/handler.rs @@ -472,6 +472,7 @@ impl Handler { fn prepare_reconstructed_binary( reconstructed_messages: Vec, ) -> Vec> { + #[allow(clippy::result_large_err)] // TODO : remove this once tungstenite is updated reconstructed_messages .into_iter() .map(ServerResponse::Received) @@ -484,6 +485,7 @@ fn prepare_reconstructed_binary( fn prepare_reconstructed_text( reconstructed_messages: Vec, ) -> Vec> { + #[allow(clippy::result_large_err)] // TODO : remove this once tungstenite is updated reconstructed_messages .into_iter() .map(ServerResponse::Received) diff --git a/common/client-core/src/client/real_messages_control/message_handler.rs b/common/client-core/src/client/real_messages_control/message_handler.rs index 77677b749e..c4aca70c9b 100644 --- a/common/client-core/src/client/real_messages_control/message_handler.rs +++ b/common/client-core/src/client/real_messages_control/message_handler.rs @@ -439,7 +439,7 @@ where let mut pending_acks = Vec::with_capacity(fragments.len()); let mut to_forward: HashMap<_, Vec<_>> = HashMap::new(); - for (raw, prepared) in fragments.into_iter().zip(prepared_fragments.into_iter()) { + for (raw, prepared) in fragments.into_iter().zip(prepared_fragments) { let lane = raw.0; let FragmentWithMaxRetransmissions { fragment, @@ -670,7 +670,7 @@ where Ok(fragments .into_iter() - .zip(reply_surbs.into_iter()) + .zip(reply_surbs) .map(|(fragment, reply_surb)| { // unwrap here is fine as we know we have a valid topology #[allow(clippy::unwrap_used)] diff --git a/common/nym_offline_compact_ecash/src/proofs/mod.rs b/common/nym_offline_compact_ecash/src/proofs/mod.rs index c1a19acc8c..bd3cc63e89 100644 --- a/common/nym_offline_compact_ecash/src/proofs/mod.rs +++ b/common/nym_offline_compact_ecash/src/proofs/mod.rs @@ -31,9 +31,7 @@ where // instead we could maybe use the `from_bytes` variant and adding some suffix // when computing the digest until we produce a valid scalar. let mut bytes = [0u8; 64]; - let pad_size = 64usize - .checked_sub(D::OutputSize::to_usize()) - .unwrap_or_default(); + let pad_size = 64usize.saturating_sub(D::OutputSize::to_usize()); bytes[pad_size..].copy_from_slice(&digest); diff --git a/common/verloc/src/measurements/sender.rs b/common/verloc/src/measurements/sender.rs index f27c531603..86fab92f47 100644 --- a/common/verloc/src/measurements/sender.rs +++ b/common/verloc/src/measurements/sender.rs @@ -109,8 +109,8 @@ impl PacketSender { let mut results = Vec::with_capacity(self.packets_per_node); - let mut seq = self.random_sequence_number(); - for _ in 0..self.packets_per_node { + let start_seq = self.random_sequence_number(); + for seq in start_seq..start_seq + self.packets_per_node as u64 { let packet = EchoPacket::new(seq, &self.identity); let start = Instant::now(); // TODO: should we get the start time after or before actually sending the data? @@ -210,7 +210,6 @@ impl PacketSender { let time_taken = Instant::now().duration_since(start); results.push(time_taken); - seq += 1; sleep(self.delay_between_packets).await; } diff --git a/nym-api/src/network_monitor/monitor/sender.rs b/nym-api/src/network_monitor/monitor/sender.rs index 1e87c9e433..3f53dcfd08 100644 --- a/nym-api/src/network_monitor/monitor/sender.rs +++ b/nym-api/src/network_monitor/monitor/sender.rs @@ -448,7 +448,7 @@ impl PacketSender { // // we need to keep clients alive until the test finishes so that we could keep receiving ForEachConcurrentClientUse::new( - stream::iter(stream_data.into_iter()), + stream::iter(stream_data), max_concurrent_clients, |(packets, fresh_data)| async move { Self::send_gateway_packets( From e12ada0105f5019478e76b521688f90e4b652bbe Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Tue, 19 May 2026 13:00:51 +0000 Subject: [PATCH 07/94] Point mobile reference section at nymvpn setup (#6776) --- documentation/docs/pages/developers/integrations.mdx | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/documentation/docs/pages/developers/integrations.mdx b/documentation/docs/pages/developers/integrations.mdx index 64aea1ed93..83174c554e 100644 --- a/documentation/docs/pages/developers/integrations.mdx +++ b/documentation/docs/pages/developers/integrations.mdx @@ -18,7 +18,7 @@ Any application that integrates with Nym sends its traffic through the Mixnet vi |---|---|---| | **Rust** (native / desktop / CLI) | [`nym-sdk`](/developers/rust) (Stream, Mixnet, Client Pool) | [`smolmix`](/developers/smolmix) (TCP / UDP) · [`nym-sdk`](/developers/rust) SOCKS client | | **TypeScript** (browser) | [TypeScript SDK](/developers/typescript) (WASM Mixnet Client, messaging only) | [`mix-fetch`](/developers/mix-fetch) (HTTP) | -| **Mobile** (iOS / Android) | _untested; see [Mobile note](#mobile-untested-ground) below_ | _untested; see [Mobile note](#mobile-untested-ground) below_ | +| **Mobile** (iOS / Android) | via [`nym-vpn-client`](#mobile) (uniffi + cargo-swift / cargo-ndk) | via [`nym-vpn-client`](#mobile) (uniffi + cargo-swift / cargo-ndk) | ## Environment @@ -27,16 +27,12 @@ Different runtimes have different transport constraints: a browser cannot open r - **Native / Desktop / CLI**: full access to system networking and persistent storage. Use [`nym-sdk`](/developers/rust) (the Rust SDK) for E2E messaging or byte streams, or [`smolmix`](/developers/smolmix) for TCP/UDP socket-shaped access in proxy mode. - **Browser**: restricted to WebSockets, Web Transport, and `fetch`; HTTPS-only mixed-content rules; no filesystem access. Use [`mix-fetch`](/developers/mix-fetch) for HTTP(S) requests, or the [TypeScript SDK](/developers/typescript)'s WASM Mixnet Client for raw message passing. -### Mobile (untested ground) +### Mobile -There is no first-party mobile SDK, and we have not yet shipped tested mobile builds. The Rust crates *should* cross-compile to mobile targets. This is the path we'd take if starting today: +There is no first-party mobile SDK, but [`nym-vpn-client`](https://github.com/nymtech/nym-vpn-client) ships production iOS and Android apps built around the Nym stack and is the reference we'd point you at. The relevant pieces are `nym-vpn-core/crates/nym-vpn-lib-uniffi` ([`uniffi`](https://mozilla.github.io/uniffi-rs/) FFI wrapper), `nym-vpn-core/iOS.mk` ([`cargo-swift`](https://github.com/antoniusnaumann/cargo-swift) → XCFramework + SwiftPM), and `nym-vpn-core/Android.mk` ([`cargo-ndk`](https://github.com/bbqsrc/cargo-ndk) → `jniLibs/`, driven from Gradle). -- Build [`nym-sdk`](/developers/rust) or [`smolmix`](/developers/smolmix) for the target triple (`aarch64-apple-ios`, `aarch64-linux-android`, etc.). -- Generate FFI bindings with [`uniffi`](https://mozilla.github.io/uniffi-rs/) and call them from Swift or Kotlin. The existing [Rust SDK FFI](/developers/rust/ffi) (Go, C/C++) is a useful reference for the binding shape. -- Run the tokio reactor on a dedicated background thread. iOS in particular has strong opinions about backgrounding and `libdispatch` interaction. -- Plan for TLS / cert-store integration up front. On mobile you'll typically want to call out to platform TLS (`SecTrust` on iOS, Android `NetworkSecurityConfig`) rather than embed a CA bundle. -If you try this and hit (or solve) blockers, we'd like to hear about it. Drop a note in the [Nym chat](https://nymtech.net/community) or open an issue on [GitHub](https://github.com/nymtech/nym). +If you try this and hit (or solve) blockers, drop a note in the [Nym dev channel on Matrix](https://matrix.to/#/#dev:nymtech.chat) or open an issue on [GitHub](https://github.com/nymtech/nym). ## Architecture From d3b6a270de708f197f2e825f8b6b44709ebcb345 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 19 May 2026 15:13:03 +0100 Subject: [PATCH 08/94] chore: expose admin method for migrating vesting delegations/mixnodes (#6795) * chore: expose admin method for migrating vesting delegations/mixnodes * don't error out on vested delegation no longer existing - perform a noop instead * cargo fmt * add message for batch migration --- .../contract_traits/mixnet_signing_client.rs | 4 + .../mixnet-contract/src/msg.rs | 31 ++ .../mixnet/schema/nym-mixnet-contract.json | 93 ++++ contracts/mixnet/schema/raw/execute.json | 93 ++++ contracts/mixnet/src/contract.rs | 13 + contracts/mixnet/src/vesting_migration.rs | 422 +++++++++++++++++- contracts/vesting/src/transactions.rs | 8 +- 7 files changed, 643 insertions(+), 21 deletions(-) diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs index 69aaac59d5..e18e387977 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mixnet_signing_client.rs @@ -867,6 +867,10 @@ mod tests { MixnetExecuteMsg::TestingResolveAllPendingEvents { .. } => { client.testing_resolve_all_pending_events(None).ignore() } + // not expected to be exposed by the client + ExecuteMsg::AdminMigrateVestedMixNode { .. } + | ExecuteMsg::AdminMigrateVestedDelegation { .. } + | ExecuteMsg::AdminBatchMigrateVestedDelegations { .. } => ().ignore(), }; } } diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/msg.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/msg.rs index f8b34b2898..a6cc8a8c77 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/msg.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/msg.rs @@ -306,6 +306,22 @@ pub enum ExecuteMsg { MigrateVestedDelegation { mix_id: NodeId, }, + /// Admin-only: forcibly migrate the vested mixnode owned by `owner`. + /// Used to drain the last vested entries so the mixnet contract can drop its dependency on the vesting contract. + AdminMigrateVestedMixNode { + owner: String, + }, + /// Admin-only: forcibly migrate the vested delegation `(mix_id, owner)`. + /// Used to drain the last vested entries so the mixnet contract can drop its dependency on the vesting contract. + AdminMigrateVestedDelegation { + mix_id: NodeId, + owner: String, + }, + /// Admin-only: batch variant of [`ExecuteMsg::AdminMigrateVestedDelegation`]. + /// Reverts the entire batch on the first error, so callers should treat it as all-or-nothing. + AdminBatchMigrateVestedDelegations { + entries: Vec, + }, // testing-only #[cfg(feature = "contract-testing")] @@ -395,6 +411,15 @@ impl ExecuteMsg { } ExecuteMsg::MigrateVestedMixNode { .. } => "migrate vested mixnode".into(), ExecuteMsg::MigrateVestedDelegation { .. } => "migrate vested delegation".to_string(), + ExecuteMsg::AdminMigrateVestedMixNode { owner } => { + format!("admin migrating vested mixnode of {owner}") + } + ExecuteMsg::AdminMigrateVestedDelegation { mix_id, owner } => { + format!("admin migrating vested delegation of {owner} on mixnode {mix_id}") + } + ExecuteMsg::AdminBatchMigrateVestedDelegations { entries } => { + format!("admin batch migrating {} vested delegations", entries.len()) + } ExecuteMsg::AssignRoles { .. } => "assigning epoch roles".into(), ExecuteMsg::MigrateMixnode { .. } => "migrating legacy mixnode".into(), ExecuteMsg::MigrateGateway { .. } => "migrating legacy gateway".into(), @@ -882,6 +907,12 @@ pub enum QueryMsg { GetKeyRotationId {}, } +#[cw_serde] +pub struct VestedDelegationMigrationEntry { + pub mix_id: NodeId, + pub owner: String, +} + #[cw_serde] pub struct MigrateMsg { pub unsafe_skip_state_updates: Option, diff --git a/contracts/mixnet/schema/nym-mixnet-contract.json b/contracts/mixnet/schema/nym-mixnet-contract.json index a479011c28..1c41e08746 100644 --- a/contracts/mixnet/schema/nym-mixnet-contract.json +++ b/contracts/mixnet/schema/nym-mixnet-contract.json @@ -1271,6 +1271,81 @@ } }, "additionalProperties": false + }, + { + "description": "Admin-only: forcibly migrate the vested mixnode owned by `owner`. Used to drain the last vested entries so the mixnet contract can drop its dependency on the vesting contract.", + "type": "object", + "required": [ + "admin_migrate_vested_mix_node" + ], + "properties": { + "admin_migrate_vested_mix_node": { + "type": "object", + "required": [ + "owner" + ], + "properties": { + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Admin-only: forcibly migrate the vested delegation `(mix_id, owner)`. Used to drain the last vested entries so the mixnet contract can drop its dependency on the vesting contract.", + "type": "object", + "required": [ + "admin_migrate_vested_delegation" + ], + "properties": { + "admin_migrate_vested_delegation": { + "type": "object", + "required": [ + "mix_id", + "owner" + ], + "properties": { + "mix_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Admin-only: batch variant of [`ExecuteMsg::AdminMigrateVestedDelegation`]. Reverts the entire batch on the first error, so callers should treat it as all-or-nothing.", + "type": "object", + "required": [ + "admin_batch_migrate_vested_delegations" + ], + "properties": { + "admin_batch_migrate_vested_delegations": { + "type": "object", + "required": [ + "entries" + ], + "properties": { + "entries": { + "type": "array", + "items": { + "$ref": "#/definitions/VestedDelegationMigrationEntry" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false } ], "definitions": { @@ -1962,6 +2037,24 @@ } }, "additionalProperties": false + }, + "VestedDelegationMigrationEntry": { + "type": "object", + "required": [ + "mix_id", + "owner" + ], + "properties": { + "mix_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "type": "string" + } + }, + "additionalProperties": false } } }, diff --git a/contracts/mixnet/schema/raw/execute.json b/contracts/mixnet/schema/raw/execute.json index 8884a73158..8e4daa0564 100644 --- a/contracts/mixnet/schema/raw/execute.json +++ b/contracts/mixnet/schema/raw/execute.json @@ -976,6 +976,81 @@ } }, "additionalProperties": false + }, + { + "description": "Admin-only: forcibly migrate the vested mixnode owned by `owner`. Used to drain the last vested entries so the mixnet contract can drop its dependency on the vesting contract.", + "type": "object", + "required": [ + "admin_migrate_vested_mix_node" + ], + "properties": { + "admin_migrate_vested_mix_node": { + "type": "object", + "required": [ + "owner" + ], + "properties": { + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Admin-only: forcibly migrate the vested delegation `(mix_id, owner)`. Used to drain the last vested entries so the mixnet contract can drop its dependency on the vesting contract.", + "type": "object", + "required": [ + "admin_migrate_vested_delegation" + ], + "properties": { + "admin_migrate_vested_delegation": { + "type": "object", + "required": [ + "mix_id", + "owner" + ], + "properties": { + "mix_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Admin-only: batch variant of [`ExecuteMsg::AdminMigrateVestedDelegation`]. Reverts the entire batch on the first error, so callers should treat it as all-or-nothing.", + "type": "object", + "required": [ + "admin_batch_migrate_vested_delegations" + ], + "properties": { + "admin_batch_migrate_vested_delegations": { + "type": "object", + "required": [ + "entries" + ], + "properties": { + "entries": { + "type": "array", + "items": { + "$ref": "#/definitions/VestedDelegationMigrationEntry" + } + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false } ], "definitions": { @@ -1667,6 +1742,24 @@ } }, "additionalProperties": false + }, + "VestedDelegationMigrationEntry": { + "type": "object", + "required": [ + "mix_id", + "owner" + ], + "properties": { + "mix_id": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "owner": { + "type": "string" + } + }, + "additionalProperties": false } } } diff --git a/contracts/mixnet/src/contract.rs b/contracts/mixnet/src/contract.rs index 23dfa000b7..f86b9a49f8 100644 --- a/contracts/mixnet/src/contract.rs +++ b/contracts/mixnet/src/contract.rs @@ -307,6 +307,19 @@ pub fn execute( ExecuteMsg::MigrateVestedDelegation { mix_id } => { crate::vesting_migration::try_migrate_vested_delegation(deps, env, info, mix_id) } + ExecuteMsg::AdminMigrateVestedMixNode { owner } => { + crate::vesting_migration::try_admin_migrate_vested_mixnode(deps, info, owner) + } + ExecuteMsg::AdminMigrateVestedDelegation { mix_id, owner } => { + crate::vesting_migration::try_admin_migrate_vested_delegation( + deps, env, info, mix_id, owner, + ) + } + ExecuteMsg::AdminBatchMigrateVestedDelegations { entries } => { + crate::vesting_migration::try_admin_batch_migrate_vested_delegations( + deps, env, info, entries, + ) + } // legacy vesting ExecuteMsg::BondMixnodeOnBehalf { .. } diff --git a/contracts/mixnet/src/vesting_migration.rs b/contracts/mixnet/src/vesting_migration.rs index 683b7a6102..89c0274e65 100644 --- a/contracts/mixnet/src/vesting_migration.rs +++ b/contracts/mixnet/src/vesting_migration.rs @@ -3,24 +3,42 @@ use crate::delegations::storage as delegations_storage; use crate::mixnet_contract_settings::storage as mixnet_params_storage; +use crate::mixnet_contract_settings::storage::ADMIN; use crate::mixnodes::helpers::get_mixnode_details_by_owner; use crate::mixnodes::storage as mixnodes_storage; use crate::rewards::storage as rewards_storage; use crate::support::helpers::{ ensure_bonded, ensure_epoch_in_progress_state, ensure_no_pending_pledge_changes, }; -use cosmwasm_std::{wasm_execute, DepsMut, Env, Event, MessageInfo, Response}; +use cosmwasm_std::{wasm_execute, Addr, DepsMut, Env, Event, MessageInfo, Response}; use mixnet_contract_common::error::MixnetContractError; -use mixnet_contract_common::{Delegation, NodeId}; +use mixnet_contract_common::{Delegation, NodeId, VestedDelegationMigrationEntry}; use vesting_contract_common::messages::ExecuteMsg as VestingExecuteMsg; pub(crate) fn try_migrate_vested_mixnode( deps: DepsMut<'_>, info: MessageInfo, ) -> Result { - let mix_details = get_mixnode_details_by_owner(deps.storage, info.sender.clone())?.ok_or( + migrate_vested_mixnode_for_owner(deps, info.sender) +} + +pub(crate) fn try_admin_migrate_vested_mixnode( + deps: DepsMut<'_>, + info: MessageInfo, + owner: String, +) -> Result { + ADMIN.assert_admin(deps.as_ref(), &info.sender)?; + let owner = deps.api.addr_validate(&owner)?; + migrate_vested_mixnode_for_owner(deps, owner) +} + +fn migrate_vested_mixnode_for_owner( + deps: DepsMut<'_>, + owner: Addr, +) -> Result { + let mix_details = get_mixnode_details_by_owner(deps.storage, owner.clone())?.ok_or( MixnetContractError::NoAssociatedMixNodeBond { - owner: info.sender.clone(), + owner: owner.clone(), }, )?; let mix_id = mix_details.mix_id(); @@ -55,7 +73,7 @@ pub(crate) fn try_migrate_vested_mixnode( .add_message(wasm_execute( vesting_contract, &VestingExecuteMsg::TrackMigratedMixnode { - owner: info.sender.into_string(), + owner: owner.into_string(), }, vec![], )?)) @@ -66,6 +84,46 @@ pub(crate) fn try_migrate_vested_delegation( env: Env, info: MessageInfo, mix_id: NodeId, +) -> Result { + migrate_vested_delegation_for_owner(deps, env, info.sender, mix_id) +} + +pub(crate) fn try_admin_migrate_vested_delegation( + deps: DepsMut<'_>, + env: Env, + info: MessageInfo, + mix_id: NodeId, + owner: String, +) -> Result { + ADMIN.assert_admin(deps.as_ref(), &info.sender)?; + let owner = deps.api.addr_validate(&owner)?; + migrate_vested_delegation_for_owner(deps, env, owner, mix_id) +} + +pub(crate) fn try_admin_batch_migrate_vested_delegations( + mut deps: DepsMut<'_>, + env: Env, + info: MessageInfo, + entries: Vec, +) -> Result { + ADMIN.assert_admin(deps.as_ref(), &info.sender)?; + + let mut response = Response::new(); + for VestedDelegationMigrationEntry { mix_id, owner } in entries { + let owner = deps.api.addr_validate(&owner)?; + let sub = migrate_vested_delegation_for_owner(deps.branch(), env.clone(), owner, mix_id)?; + response = response + .add_submessages(sub.messages) + .add_events(sub.events); + } + Ok(response) +} + +fn migrate_vested_delegation_for_owner( + deps: DepsMut<'_>, + env: Env, + owner: Addr, + mix_id: NodeId, ) -> Result { let mut response = Response::new(); @@ -73,12 +131,16 @@ pub(crate) fn try_migrate_vested_delegation( let vesting_contract = mixnet_params_storage::vesting_contract_address(deps.storage)?; - let storage_key = - Delegation::generate_storage_key(mix_id, &info.sender, Some(&vesting_contract)); + let storage_key = Delegation::generate_storage_key(mix_id, &owner, Some(&vesting_contract)); let Some(vested_delegation) = delegations_storage::delegations().may_load(deps.storage, storage_key.clone())? else { - return Err(MixnetContractError::NotAVestingDelegation); + return Ok(Response::new().add_event( + Event::new("migrate-vested-delegation-noop") + .add_attribute("owner", owner.as_str()) + .add_attribute("mix_id", mix_id.to_string()) + .add_attribute("reason", "no_vested_delegation"), + )); }; // sanity check that's meant to blow up the contract @@ -88,7 +150,7 @@ pub(crate) fn try_migrate_vested_delegation( let mut updated_delegation = vested_delegation.clone(); updated_delegation.proxy = None; - let new_storage_key = Delegation::generate_storage_key(mix_id, &info.sender, None); + let new_storage_key = Delegation::generate_storage_key(mix_id, &owner, None); // remove the old (vested) delegation delegations_storage::delegations().remove(deps.storage, storage_key)?; @@ -205,7 +267,7 @@ pub(crate) fn try_migrate_vested_delegation( Ok(response.add_message(wasm_execute( vesting_contract, &VestingExecuteMsg::TrackMigratedDelegation { - owner: info.sender.into_string(), + owner: owner.into_string(), mix_id, }, vec![], @@ -307,9 +369,10 @@ mod tests { let sender = test.make_sender("owner-without-any-delegations"); - // it simply fails for there is nothing to migrate - let res = try_migrate_vested_delegation(test.deps_mut(), env, sender, 42).unwrap_err(); - assert_eq!(res, MixnetContractError::NotAVestingDelegation); + // nothing to migrate -> idempotent no-op (so admin batches don't fail on stale entries) + let res = try_migrate_vested_delegation(test.deps_mut(), env, sender, 42).unwrap(); + assert!(res.messages.is_empty()); + assert_eq!(res.events[0].ty, "migrate-vested-delegation-noop"); } #[test] @@ -333,10 +396,10 @@ mod tests { let sender = message_info(&delegation.owner, &[]); let mix_id = delegation.node_id; - // it also fails because the method is only allowed for vested delegations - let res = - try_migrate_vested_delegation(test.deps_mut(), env, sender, mix_id).unwrap_err(); - assert_eq!(res, MixnetContractError::NotAVestingDelegation); + // liquid-only delegations are no-ops (nothing vested to migrate) + let res = try_migrate_vested_delegation(test.deps_mut(), env, sender, mix_id).unwrap(); + assert!(res.messages.is_empty()); + assert_eq!(res.events[0].ty, "migrate-vested-delegation-noop"); } #[test] @@ -566,4 +629,329 @@ mod tests { compare_decimals(rewards, new_rewards_twin, Some("0.01".parse().unwrap())) } } + + #[cfg(test)] + mod admin_migrating_vested_mixnode { + use super::*; + use crate::mixnodes::helpers::get_mixnode_details_by_id; + use crate::support::tests::test_helpers::TestSetup; + use cosmwasm_std::testing::message_info; + use cosmwasm_std::{from_json, CosmosMsg, WasmMsg}; + + #[test] + fn rejects_non_admin_caller() { + let mut test = TestSetup::new(); + let owner = test.make_addr("owner"); + let mix_id = test.add_legacy_mixnode_with_legal_proxy(&owner, None); + + let intruder = message_info(&test.make_addr("not-admin"), &[]); + let owner_str = owner.to_string(); + let res = + try_admin_migrate_vested_mixnode(test.deps_mut(), intruder, owner_str).unwrap_err(); + assert!(matches!(res, MixnetContractError::Admin(_))); + + // bond is untouched + let existing = get_mixnode_details_by_id(test.deps().storage, mix_id) + .unwrap() + .unwrap(); + assert!(existing.bond_information.proxy.is_some()); + } + + #[test] + fn admin_can_migrate_someone_elses_vested_node() { + let mut test = TestSetup::new(); + let owner = test.make_addr("owner"); + let mix_id = test.add_legacy_mixnode_with_legal_proxy(&owner, None); + let admin = test.admin(); + + let info = message_info(&admin, &[]); + let owner_str = owner.to_string(); + let res = + try_admin_migrate_vested_mixnode(test.deps_mut(), info, owner_str.clone()).unwrap(); + + let CosmosMsg::Wasm(WasmMsg::Execute { msg, .. }) = &res.messages[0].msg else { + panic!("no track message present") + }; + assert_eq!( + from_json::(msg).unwrap(), + VestingExecuteMsg::TrackMigratedMixnode { owner: owner_str } + ); + + // proxy was cleared on the bond owned by `owner` (not by the admin) + let migrated = get_mixnode_details_by_id(test.deps().storage, mix_id) + .unwrap() + .unwrap(); + assert!(migrated.bond_information.proxy.is_none()); + } + + #[test] + fn rejects_invalid_owner_address() { + let mut test = TestSetup::new(); + let admin = test.admin(); + + let info = message_info(&admin, &[]); + let res = + try_admin_migrate_vested_mixnode(test.deps_mut(), info, "not a bech32".to_string()) + .unwrap_err(); + assert!(matches!(res, MixnetContractError::StdErr { .. })); + } + } + + #[cfg(test)] + mod admin_migrating_vested_delegation { + use super::*; + use crate::delegations::storage::delegations; + use crate::support::tests::test_helpers::TestSetup; + use cosmwasm_std::testing::message_info; + use cosmwasm_std::{from_json, CosmosMsg, Order, WasmMsg}; + + #[test] + fn rejects_non_admin_caller() { + let mut test = TestSetup::new_complex(); + let env = test.env(); + + let vested = delegations() + .range(test.deps().storage, None, None, Order::Ascending) + .filter_map(|d| d.map(|(_, del)| del).ok()) + .find(|d| d.proxy.is_some()) + .unwrap(); + + let intruder = message_info(&test.make_addr("not-admin"), &[]); + let res = try_admin_migrate_vested_delegation( + test.deps_mut(), + env, + intruder, + vested.node_id, + vested.owner.to_string(), + ) + .unwrap_err(); + assert!(matches!(res, MixnetContractError::Admin(_))); + + // delegation is untouched + assert!(delegations() + .may_load(test.deps().storage, vested.storage_key()) + .unwrap() + .is_some()); + } + + #[test] + fn admin_can_migrate_someone_elses_vested_delegation() { + let mut test = TestSetup::new_complex(); + let env = test.env(); + let admin = test.admin(); + + let vested = delegations() + .range(test.deps().storage, None, None, Order::Ascending) + .filter_map(|d| d.map(|(_, del)| del).ok()) + .find(|d| d.proxy.is_some()) + .unwrap(); + + // pick an owner that has no liquid twin so we exercise the simple branch + let has_liquid_twin = delegations() + .range(test.deps().storage, None, None, Order::Ascending) + .filter_map(|d| d.map(|(_, del)| del).ok()) + .any(|d| { + d.proxy.is_none() + && d.owner.as_str() == vested.owner.as_str() + && d.node_id == vested.node_id + }); + assert!(!has_liquid_twin); + + let old_key = vested.storage_key(); + let mut expected_liquid = vested.clone(); + expected_liquid.proxy = None; + let new_key = expected_liquid.storage_key(); + + let info = message_info(&admin, &[]); + let res = try_admin_migrate_vested_delegation( + test.deps_mut(), + env, + info, + vested.node_id, + vested.owner.to_string(), + ) + .unwrap(); + + let CosmosMsg::Wasm(WasmMsg::Execute { msg, .. }) = &res.messages[0].msg else { + panic!("no track message present") + }; + assert_eq!( + from_json::(msg).unwrap(), + VestingExecuteMsg::TrackMigratedDelegation { + owner: vested.owner.to_string(), + mix_id: vested.node_id, + } + ); + + assert!(delegations() + .may_load(test.deps().storage, old_key) + .unwrap() + .is_none()); + assert_eq!( + expected_liquid, + delegations().load(test.deps().storage, new_key).unwrap() + ); + } + } + + #[cfg(test)] + mod admin_batch_migrating_vested_delegations { + use super::*; + use crate::delegations::storage::delegations; + use crate::support::tests::test_helpers::TestSetup; + use cosmwasm_std::testing::message_info; + use cosmwasm_std::{CosmosMsg, Order, WasmMsg}; + + fn collect_vested(test: &TestSetup, n: usize) -> Vec { + delegations() + .range(test.deps().storage, None, None, Order::Ascending) + .filter_map(|d| d.map(|(_, del)| del).ok()) + .filter(|d| d.proxy.is_some()) + .take(n) + .collect() + } + + #[test] + fn rejects_non_admin_caller() { + let mut test = TestSetup::new_complex(); + let env = test.env(); + let vested = collect_vested(&test, 2); + let entries = vested + .iter() + .map(|d| VestedDelegationMigrationEntry { + mix_id: d.node_id, + owner: d.owner.to_string(), + }) + .collect(); + + let intruder = message_info(&test.make_addr("not-admin"), &[]); + let res = + try_admin_batch_migrate_vested_delegations(test.deps_mut(), env, intruder, entries) + .unwrap_err(); + assert!(matches!(res, MixnetContractError::Admin(_))); + + // nothing was touched + for d in &vested { + assert!(delegations() + .may_load(test.deps().storage, d.storage_key()) + .unwrap() + .is_some()); + } + } + + #[test] + fn admin_can_migrate_multiple_entries_in_one_call() { + let mut test = TestSetup::new_complex(); + let env = test.env(); + let admin = test.admin(); + let vested = collect_vested(&test, 3); + assert_eq!(vested.len(), 3, "fixture must have ≥3 vested delegations"); + + let entries: Vec<_> = vested + .iter() + .map(|d| VestedDelegationMigrationEntry { + mix_id: d.node_id, + owner: d.owner.to_string(), + }) + .collect(); + + let info = message_info(&admin, &[]); + let res = + try_admin_batch_migrate_vested_delegations(test.deps_mut(), env, info, entries) + .unwrap(); + + // one TrackMigratedDelegation WasmMsg per entry + let track_msgs: Vec<_> = res + .messages + .iter() + .filter(|sub| matches!(sub.msg, CosmosMsg::Wasm(WasmMsg::Execute { .. }))) + .collect(); + assert_eq!(track_msgs.len(), 3); + + // each vested entry was removed and re-saved under the liquid key + for d in &vested { + assert!(delegations() + .may_load(test.deps().storage, d.storage_key()) + .unwrap() + .is_none()); + let liquid_key = Delegation::generate_storage_key(d.node_id, &d.owner, None); + let liquid = delegations().load(test.deps().storage, liquid_key).unwrap(); + assert!(liquid.proxy.is_none()); + } + } + + #[test] + fn batch_with_noop_entries_still_succeeds() { + // batch contains: 1 valid vested, 1 stale (non-existent) — the stale one is a noop + let mut test = TestSetup::new_complex(); + let env = test.env(); + let admin = test.admin(); + let vested = collect_vested(&test, 1); + let real = &vested[0]; + + let entries = vec![ + VestedDelegationMigrationEntry { + mix_id: real.node_id, + owner: real.owner.to_string(), + }, + VestedDelegationMigrationEntry { + mix_id: 999_999, + owner: test.make_addr("ghost").to_string(), + }, + ]; + + let info = message_info(&admin, &[]); + let res = + try_admin_batch_migrate_vested_delegations(test.deps_mut(), env, info, entries) + .unwrap(); + + // only the real entry dispatched a track message; the ghost was a noop + let track_msgs: Vec<_> = res + .messages + .iter() + .filter(|sub| matches!(sub.msg, CosmosMsg::Wasm(WasmMsg::Execute { .. }))) + .collect(); + assert_eq!(track_msgs.len(), 1); + assert!(res + .events + .iter() + .any(|e| e.ty == "migrate-vested-delegation-noop")); + } + + #[test] + fn bad_owner_address_propagates_as_error() { + // a malformed entry causes the handler to return Err; on-chain this reverts + // the entire batch atomically. (Unit tests use a raw `DepsMut` that does not + // simulate chain-level rollback, so we only assert the error and ensure no + // entry after the bad one was processed.) + let mut test = TestSetup::new_complex(); + let env = test.env(); + let admin = test.admin(); + let vested = collect_vested(&test, 1); + + let entries = vec![ + VestedDelegationMigrationEntry { + mix_id: vested[0].node_id, + owner: "not-a-bech32".to_string(), + }, + VestedDelegationMigrationEntry { + mix_id: vested[0].node_id, + owner: vested[0].owner.to_string(), + }, + ]; + + let info = message_info(&admin, &[]); + let err = + try_admin_batch_migrate_vested_delegations(test.deps_mut(), env, info, entries) + .unwrap_err(); + assert!(matches!(err, MixnetContractError::StdErr { .. })); + + // bailed out before reaching the second (valid) entry, so the vested record + // is still in storage + assert!(delegations() + .may_load(test.deps().storage, vested[0].storage_key()) + .unwrap() + .is_some()); + } + } } diff --git a/contracts/vesting/src/transactions.rs b/contracts/vesting/src/transactions.rs index 09e3ac9a8a..9c37cd8884 100644 --- a/contracts/vesting/src/transactions.rs +++ b/contracts/vesting/src/transactions.rs @@ -17,9 +17,9 @@ use mixnet_contract_common::{ use vesting_contract_common::events::{ new_ownership_transfer_event, new_periodic_vesting_account_event, new_staking_address_update_event, new_track_gateway_unbond_event, - new_track_migrate_mixnode_event, new_track_mixnode_pledge_decrease_event, - new_track_mixnode_unbond_event, new_track_reward_event, new_track_undelegation_event, - new_vested_coins_withdraw_event, + new_track_migrate_delegation_event, new_track_migrate_mixnode_event, + new_track_mixnode_pledge_decrease_event, new_track_mixnode_unbond_event, + new_track_reward_event, new_track_undelegation_event, new_vested_coins_withdraw_event, }; use vesting_contract_common::{Account, PledgeCap, VestingContractError, VestingSpecification}; @@ -247,7 +247,7 @@ pub fn try_track_migrate_delegation( } let account = account_from_address(owner, deps.storage, deps.api)?; account.track_migrated_delegation(mix_id, deps.storage)?; - Ok(Response::new().add_event(new_track_migrate_mixnode_event())) + Ok(Response::new().add_event(new_track_migrate_delegation_event())) } /// Bond a mixnode, sends [mixnet_contract_common::ExecuteMsg::BondMixnodeOnBehalf] to [crate::storage::MIXNET_CONTRACT_ADDRESS]. From 227e6a10e1682e1304e5917ad05c404f3b90845f Mon Sep 17 00:00:00 2001 From: ZM <153792750+code-zm@users.noreply.github.com> Date: Tue, 19 May 2026 09:17:24 -0500 Subject: [PATCH 09/94] fix(ecash): cast usize to u64 in to_bytes() for 32-bit platform compatibility (#6528) VerificationKeyAuth::to_bytes() and SecretKeyAuth::to_bytes() used usize::to_le_bytes() to serialize vector lengths, producing 4 bytes on 32-bit and 8 bytes on 64-bit. Since from_bytes() always reads 8 bytes (u64), this caused ZK proof challenge hash mismatches when a 32-bit client's proof was verified by a 64-bit gateway, resulting in "the provided ticket failed to get verified" on all 32-bit platforms. --- common/nym_offline_compact_ecash/src/scheme/keygen.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/nym_offline_compact_ecash/src/scheme/keygen.rs b/common/nym_offline_compact_ecash/src/scheme/keygen.rs index c771b6658f..4164a3723f 100644 --- a/common/nym_offline_compact_ecash/src/scheme/keygen.rs +++ b/common/nym_offline_compact_ecash/src/scheme/keygen.rs @@ -112,7 +112,7 @@ impl SecretKeyAuth { let ys_len = self.ys.len(); let mut bytes = Vec::with_capacity(8 + (ys_len + 1) * 32); bytes.extend_from_slice(&self.x.to_bytes()); - bytes.extend_from_slice(&ys_len.to_le_bytes()); + bytes.extend_from_slice(&(ys_len as u64).to_le_bytes()); for y in self.ys.iter() { bytes.extend_from_slice(&y.to_bytes()) } @@ -337,7 +337,7 @@ impl VerificationKeyAuth { bytes.extend_from_slice(&self.alpha.to_affine().to_compressed()); - bytes.extend_from_slice(&beta_g1_len.to_le_bytes()); + bytes.extend_from_slice(&(beta_g1_len as u64).to_le_bytes()); for beta_g1 in self.beta_g1.iter() { bytes.extend_from_slice(&beta_g1.to_affine().to_compressed()) From e0de0d8835096d15eef58602240623f33583d9be Mon Sep 17 00:00:00 2001 From: Andy Duplain Date: Fri, 15 May 2026 13:42:25 +0100 Subject: [PATCH 10/94] NYM-583: Avoid corrupted database on Windows. On Windows, the database can become corrupted if the client is killed while it is running. This is fixed by ensuring the database file is properly closed. --- .../client/base_client/non_wasm_helpers.rs | 62 ++++++++++++++++--- nym-sqlx-pool-guard/src/lib.rs | 18 ++++++ 2 files changed, 72 insertions(+), 8 deletions(-) diff --git a/common/client-core/src/client/base_client/non_wasm_helpers.rs b/common/client-core/src/client/base_client/non_wasm_helpers.rs index 335ca8c522..cd61760d3c 100644 --- a/common/client-core/src/client/base_client/non_wasm_helpers.rs +++ b/common/client-core/src/client/base_client/non_wasm_helpers.rs @@ -11,11 +11,17 @@ use nym_bandwidth_controller::BandwidthController; use nym_client_core_gateways_storage::OnDiskGatewaysDetails; use nym_credential_storage::storage::Storage as CredentialStorage; use nym_validator_client::{QueryHttpRpcNyxdClient, nyxd}; -use std::{io, path::Path}; +use std::{io, path::Path, time::Duration}; use time::OffsetDateTime; use tracing::{error, info, trace}; use url::Url; +/// Maximum rename retry attempts when the database file is temporarily locked. +const ARCHIVE_MAX_RETRY_ATTEMPTS: u8 = 15; + +/// Delay between archive rename retry attempts. +const ARCHIVE_RETRY_DELAY: Duration = Duration::from_millis(200); + async fn setup_fresh_backend>( db_path: P, surb_config: &config::ReplySurbs, @@ -74,13 +80,53 @@ async fn archive_corrupted_database>(db_path: P) -> io::Result<() }; let renamed = db_path.with_extension(new_extension); - tokio::fs::rename(db_path, &renamed).await.inspect_err(|_| { - error!( - "Failed to rename corrupt database file: {} to {}", - db_path.display(), - renamed.display() - ); - }) + // On Windows, a previously cancelled connection may still hold a file handle open + // (ERROR_SHARING_VIOLATION, os error 32), temporarily preventing the rename. The + // SqlitePoolGuard::drop() spawns an async close task for exactly this situation, so + // we retry with a short delay to give that task time to complete. + let mut last_err = None; + for attempt in 0..ARCHIVE_MAX_RETRY_ATTEMPTS { + match tokio::fs::rename(db_path, &renamed).await { + Ok(()) => return Ok(()), + Err(e) if is_file_locked_error(&e) && (attempt + 1) < ARCHIVE_MAX_RETRY_ATTEMPTS => { + trace!( + "Database file is temporarily locked, retrying archive \ + (attempt {}/{}): {e}", + attempt + 1, + ARCHIVE_MAX_RETRY_ATTEMPTS + ); + tokio::time::sleep(ARCHIVE_RETRY_DELAY).await; + last_err = Some(e); + } + Err(e) => { + last_err = Some(e); + break; + } + } + } + + let err = last_err.unwrap(); + error!( + "Failed to rename corrupt database file: {} to {}", + db_path.display(), + renamed.display() + ); + Err(err) +} + +/// Returns `true` when the IO error indicates a temporary file lock held by another handle +/// within the same process. Only meaningful on Windows; always `false` elsewhere. +fn is_file_locked_error(e: &io::Error) -> bool { + #[cfg(windows)] + { + // ERROR_SHARING_VIOLATION = 32, ERROR_LOCK_VIOLATION = 33 + matches!(e.raw_os_error(), Some(32) | Some(33)) + } + #[cfg(not(windows))] + { + let _ = e; + false + } } pub async fn setup_fs_reply_surb_backend>( diff --git a/nym-sqlx-pool-guard/src/lib.rs b/nym-sqlx-pool-guard/src/lib.rs index 3e16683de3..6eb9b82387 100644 --- a/nym-sqlx-pool-guard/src/lib.rs +++ b/nym-sqlx-pool-guard/src/lib.rs @@ -120,6 +120,24 @@ impl SqlitePoolGuard { } } +impl Drop for SqlitePoolGuard { + fn drop(&mut self) { + if !self.connection_pool.is_closed() { + // When the guard is dropped without an explicit call to close() — for example, + // due to async task cancellation — the underlying pool must still be closed to + // promptly release OS file handles. On Windows, an open file handle prevents + // rename/delete operations on the same file (ERROR_SHARING_VIOLATION, os error + // 32), which would break the next connection attempt's database recovery logic. + let pool = self.connection_pool.clone(); + if let Ok(handle) = tokio::runtime::Handle::try_current() { + handle.spawn(async move { + pool.close().await; + }); + } + } + } +} + impl Deref for SqlitePoolGuard { type Target = sqlx::SqlitePool; From bafed70f51d012140697d397c4f0f732bfbc135d Mon Sep 17 00:00:00 2001 From: Andy Duplain Date: Fri, 15 May 2026 13:52:41 +0100 Subject: [PATCH 11/94] Use `unwrap_or_default()`. --- common/client-core/src/client/base_client/non_wasm_helpers.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/client-core/src/client/base_client/non_wasm_helpers.rs b/common/client-core/src/client/base_client/non_wasm_helpers.rs index cd61760d3c..b9b08e6001 100644 --- a/common/client-core/src/client/base_client/non_wasm_helpers.rs +++ b/common/client-core/src/client/base_client/non_wasm_helpers.rs @@ -105,7 +105,7 @@ async fn archive_corrupted_database>(db_path: P) -> io::Result<() } } - let err = last_err.unwrap(); + let err = last_err.unwrap_or_default(); error!( "Failed to rename corrupt database file: {} to {}", db_path.display(), From c7e425509501576042ce5874dfd24c6887ae90c8 Mon Sep 17 00:00:00 2001 From: Andy Duplain Date: Fri, 15 May 2026 13:58:36 +0100 Subject: [PATCH 12/94] Avoid use of `unwrap()`. --- .../client/base_client/non_wasm_helpers.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/common/client-core/src/client/base_client/non_wasm_helpers.rs b/common/client-core/src/client/base_client/non_wasm_helpers.rs index b9b08e6001..11b711cedd 100644 --- a/common/client-core/src/client/base_client/non_wasm_helpers.rs +++ b/common/client-core/src/client/base_client/non_wasm_helpers.rs @@ -84,7 +84,6 @@ async fn archive_corrupted_database>(db_path: P) -> io::Result<() // (ERROR_SHARING_VIOLATION, os error 32), temporarily preventing the rename. The // SqlitePoolGuard::drop() spawns an async close task for exactly this situation, so // we retry with a short delay to give that task time to complete. - let mut last_err = None; for attempt in 0..ARCHIVE_MAX_RETRY_ATTEMPTS { match tokio::fs::rename(db_path, &renamed).await { Ok(()) => return Ok(()), @@ -96,22 +95,28 @@ async fn archive_corrupted_database>(db_path: P) -> io::Result<() ARCHIVE_MAX_RETRY_ATTEMPTS ); tokio::time::sleep(ARCHIVE_RETRY_DELAY).await; - last_err = Some(e); } Err(e) => { - last_err = Some(e); - break; + error!( + "Failed to rename corrupt database file: {} to {}", + db_path.display(), + renamed.display() + ); + return Err(e); } } } - let err = last_err.unwrap_or_default(); + // Reached only when every attempt was blocked by a file lock. error!( - "Failed to rename corrupt database file: {} to {}", + "Failed to rename corrupt database file after {} attempts: {} to {}", + ARCHIVE_MAX_RETRY_ATTEMPTS, db_path.display(), renamed.display() ); - Err(err) + Err(io::Error::other( + "corrupt database archive blocked by persistent file lock", + )) } /// Returns `true` when the IO error indicates a temporary file lock held by another handle From b45351bb0c47a69cd19741607f629a614a037977 Mon Sep 17 00:00:00 2001 From: Andy Duplain Date: Fri, 15 May 2026 14:11:21 +0100 Subject: [PATCH 13/94] Avoid async calls in Drop. --- .../client/base_client/non_wasm_helpers.rs | 8 +++--- nym-sqlx-pool-guard/src/lib.rs | 26 ++++++++++--------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/common/client-core/src/client/base_client/non_wasm_helpers.rs b/common/client-core/src/client/base_client/non_wasm_helpers.rs index 11b711cedd..ab57caf0cf 100644 --- a/common/client-core/src/client/base_client/non_wasm_helpers.rs +++ b/common/client-core/src/client/base_client/non_wasm_helpers.rs @@ -80,10 +80,10 @@ async fn archive_corrupted_database>(db_path: P) -> io::Result<() }; let renamed = db_path.with_extension(new_extension); - // On Windows, a previously cancelled connection may still hold a file handle open - // (ERROR_SHARING_VIOLATION, os error 32), temporarily preventing the rename. The - // SqlitePoolGuard::drop() spawns an async close task for exactly this situation, so - // we retry with a short delay to give that task time to complete. + // On Windows, sqlx may release its OS file handles asynchronously after + // pool.close() returns, briefly keeping the file locked + // (ERROR_SHARING_VIOLATION, os error 32). Retry with a short delay to + // give the OS time to flush the remaining handles. for attempt in 0..ARCHIVE_MAX_RETRY_ATTEMPTS { match tokio::fs::rename(db_path, &renamed).await { Ok(()) => return Ok(()), diff --git a/nym-sqlx-pool-guard/src/lib.rs b/nym-sqlx-pool-guard/src/lib.rs index 6eb9b82387..f58398f942 100644 --- a/nym-sqlx-pool-guard/src/lib.rs +++ b/nym-sqlx-pool-guard/src/lib.rs @@ -56,7 +56,11 @@ impl SqlitePoolGuard { &self.database_path } - /// Close udnerlying sqlite pool and wait for files to be closed before returning. + /// Close the underlying sqlite pool and wait for OS file handles to be released. + /// + /// **Callers must invoke this method before dropping the guard.** The `Drop` impl does + /// not perform async cleanup; it only logs a warning when the pool was not closed + /// beforehand. pub async fn close(&self) { // Avoid waiting for db files once the pool is marked closed to ensure that we don't wait on some other sqlite pool to close the database. if !self.connection_pool.is_closed() { @@ -122,18 +126,16 @@ impl SqlitePoolGuard { impl Drop for SqlitePoolGuard { fn drop(&mut self) { + // Spawning async tasks from Drop is an anti-pattern: tasks may not execute during + // runtime shutdown, and there may be no runtime at all. Callers are responsible + // for calling `close()` before dropping this guard. Log a warning here so that + // missed explicit-close call sites are visible during development. if !self.connection_pool.is_closed() { - // When the guard is dropped without an explicit call to close() — for example, - // due to async task cancellation — the underlying pool must still be closed to - // promptly release OS file handles. On Windows, an open file handle prevents - // rename/delete operations on the same file (ERROR_SHARING_VIOLATION, os error - // 32), which would break the next connection attempt's database recovery logic. - let pool = self.connection_pool.clone(); - if let Ok(handle) = tokio::runtime::Handle::try_current() { - handle.spawn(async move { - pool.close().await; - }); - } + tracing::warn!( + path = %self.database_path.display(), + "SqlitePoolGuard dropped without explicit close(); \ + OS file handles may not be released promptly" + ); } } } From 657aa9f86f98da83cd713ad8455795bc834fc9bf Mon Sep 17 00:00:00 2001 From: Andy Duplain Date: Fri, 15 May 2026 14:43:18 +0100 Subject: [PATCH 14/94] Ensure storage is shutdown. --- common/client-core/surb-storage/src/backend/fs_backend/mod.rs | 4 +++- common/client-core/surb-storage/src/lib.rs | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/common/client-core/surb-storage/src/backend/fs_backend/mod.rs b/common/client-core/surb-storage/src/backend/fs_backend/mod.rs index 625913e174..9c0c465433 100644 --- a/common/client-core/surb-storage/src/backend/fs_backend/mod.rs +++ b/common/client-core/surb-storage/src/backend/fs_backend/mod.rs @@ -337,6 +337,8 @@ impl ReplyStorageBackend for Backend { } async fn stop_storage_session(self) -> Result<(), Self::StorageError> { - self.stop_client_use().await + let result = self.stop_client_use().await; + self.shutdown().await; + result } } diff --git a/common/client-core/surb-storage/src/lib.rs b/common/client-core/surb-storage/src/lib.rs index ffd7ad85f6..f88a746ad2 100644 --- a/common/client-core/surb-storage/src/lib.rs +++ b/common/client-core/surb-storage/src/lib.rs @@ -48,6 +48,7 @@ where debug!("Started PersistentReplyStorage"); if let Err(err) = self.backend.start_storage_session().await { error!("failed to start the storage session - {err}"); + self.backend.stop_storage_session().await.ok(); return; } From ad9d66ef3a50a266b6015810d4269adc858e9a79 Mon Sep 17 00:00:00 2001 From: Andy Duplain Date: Tue, 19 May 2026 15:39:15 +0100 Subject: [PATCH 15/94] Use an `Arc` in order to detect if this is the last instance before warning. --- nym-sqlx-pool-guard/src/lib.rs | 84 +++++++++++++++++++++++----------- 1 file changed, 57 insertions(+), 27 deletions(-) diff --git a/nym-sqlx-pool-guard/src/lib.rs b/nym-sqlx-pool-guard/src/lib.rs index f58398f942..3e0a64e6ee 100644 --- a/nym-sqlx-pool-guard/src/lib.rs +++ b/nym-sqlx-pool-guard/src/lib.rs @@ -3,8 +3,9 @@ use std::{ io, - ops::{Deref, DerefMut}, + ops::Deref, path::{Path, PathBuf}, + sync::Arc, time::Duration, }; @@ -26,10 +27,8 @@ const CHECK_FILES_CLOSED_MAX_ATTEMPTS: u8 = 20; /// Delay between file checks const CHECK_FILES_CLOSED_RETRY_DELAY: Duration = Duration::from_millis(100); -/// `sqlx::SqlitePool` wrapper providing a workaround for the [known bug](https://github.com/launchbadge/sqlx/issues/3217). -/// In principle after requesting to close the sqlite pool, the wrapper monitors open file descriptor and polls periodically until all database files are closed. -#[derive(Debug, Clone)] -pub struct SqlitePoolGuard { +#[derive(Debug)] +struct SqlitePoolGuardInner { /// Path to sqlite database file. database_path: PathBuf, @@ -37,6 +36,18 @@ pub struct SqlitePoolGuard { connection_pool: sqlx::SqlitePool, } +/// `sqlx::SqlitePool` wrapper providing a workaround for the [known bug](https://github.com/launchbadge/sqlx/issues/3217). +/// In principle after requesting to close the sqlite pool, the wrapper monitors open file descriptor and polls periodically until all database files are closed. +/// +/// This type is cheaply [`Clone`]-able: all clones share the same underlying pool and the same +/// reference count. The `Drop` impl only emits a warning when the **last** reference is dropped +/// without an explicit [`close`](Self::close) call, so it is safe to clone this guard temporarily +/// (e.g. to pass into a spawned task) without triggering spurious warnings. +#[derive(Debug, Clone)] +pub struct SqlitePoolGuard { + inner: Arc, +} + impl SqlitePoolGuard { /// Create new instance providing path to database and connection pool pub fn new(connection_pool: sqlx::SqlitePool) -> Self { @@ -46,14 +57,16 @@ impl SqlitePoolGuard { .to_path_buf(); Self { - database_path, - connection_pool, + inner: Arc::new(SqlitePoolGuardInner { + database_path, + connection_pool, + }), } } /// Returns database path pub fn database_path(&self) -> &Path { - &self.database_path + &self.inner.database_path } /// Close the underlying sqlite pool and wait for OS file handles to be released. @@ -63,14 +76,14 @@ impl SqlitePoolGuard { /// beforehand. pub async fn close(&self) { // Avoid waiting for db files once the pool is marked closed to ensure that we don't wait on some other sqlite pool to close the database. - if !self.connection_pool.is_closed() { - tracing::info!("Closing sqlite pool: {}", self.database_path.display()); + if !self.inner.connection_pool.is_closed() { + tracing::info!("Closing sqlite pool: {}", self.inner.database_path.display()); self.close_pool_inner().await.ok(); } } async fn close_pool_inner(&self) -> std::io::Result<()> { - self.connection_pool.close().await; + self.inner.connection_pool.close().await; self.wait_for_db_files_close().await.inspect_err(|e| { tracing::error!("Failed to wait for file to close: {e}"); @@ -81,15 +94,16 @@ impl SqlitePoolGuard { fn all_database_files(&self) -> Vec { let mut database_files = vec![]; let canonical_path = self + .inner .database_path .canonicalize() .inspect_err(|e| { tracing::error!( "Failed to canonicalize path: {}. Cause: {e}", - self.database_path.display() + self.inner.database_path.display() ); }) - .unwrap_or(self.database_path.clone()); + .unwrap_or(self.inner.database_path.clone()); if let Some(ext) = canonical_path.extension() { for added_ext in ["-shm", "-wal"] { @@ -126,15 +140,9 @@ impl SqlitePoolGuard { impl Drop for SqlitePoolGuard { fn drop(&mut self) { - // Spawning async tasks from Drop is an anti-pattern: tasks may not execute during - // runtime shutdown, and there may be no runtime at all. Callers are responsible - // for calling `close()` before dropping this guard. Log a warning here so that - // missed explicit-close call sites are visible during development. - if !self.connection_pool.is_closed() { + if Arc::strong_count(&self.inner) == 1 && !self.inner.connection_pool.is_closed() { tracing::warn!( - path = %self.database_path.display(), - "SqlitePoolGuard dropped without explicit close(); \ - OS file handles may not be released promptly" + "SqlitePoolGuard dropped without explicit close(); path={}", self.inner.database_path.display() ); } } @@ -144,15 +152,10 @@ impl Deref for SqlitePoolGuard { type Target = sqlx::SqlitePool; fn deref(&self) -> &Self::Target { - &self.connection_pool + &self.inner.connection_pool } } -impl DerefMut for SqlitePoolGuard { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.connection_pool - } -} #[cfg(test)] mod tests { use sqlx::{ @@ -197,4 +200,31 @@ mod tests { assert!(guard.close_pool_inner().await.is_ok()); tokio::fs::remove_file(database_path).await.unwrap(); } + + #[tokio::test] + async fn test_clone_drop_no_warning() { + // Cloning the guard and dropping the clone should not warn because the original is still alive. + let temp_dir = tempfile::tempdir().unwrap(); + let database_path = temp_dir.path().join("storage2.db"); + + let opts = sqlx::sqlite::SqliteConnectOptions::new() + .journal_mode(sqlx::sqlite::SqliteJournalMode::Wal) + .synchronous(SqliteSynchronous::Normal) + .auto_vacuum(SqliteAutoVacuum::Incremental) + .filename(database_path.clone()) + .create_if_missing(true) + .disable_statement_logging(); + let connection_pool = sqlx::SqlitePool::connect_with(opts).await.unwrap(); + let guard = SqlitePoolGuard::new(connection_pool); + + { + let _clone = guard.clone(); + assert_eq!(Arc::strong_count(&guard.inner), 2); + // _clone drops here - should NOT warn since guard still holds a reference + } + assert_eq!(Arc::strong_count(&guard.inner), 1); + + guard.close().await; + tokio::fs::remove_file(database_path).await.unwrap(); + } } From 0215ad9294e60546dc23e838e51368161b44a234 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 15:47:26 +0100 Subject: [PATCH 16/94] build(deps): bump actions/upload-artifact from 6 to 7 (#6496) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v6...v7) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-version: '7' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/build-deb-meta.yml | 4 ++-- .github/workflows/ci-build-upload-binaries.yml | 2 +- .github/workflows/nightly-security-audit.yml | 2 +- .github/workflows/publish-nym-binaries.yml | 2 +- .github/workflows/publish-nym-contracts.yml | 4 ++-- .github/workflows/publish-nym-wallet-macos.yml | 2 +- .github/workflows/publish-nym-wallet-ubuntu.yml | 2 +- .github/workflows/publish-nym-wallet-win11.yml | 2 +- .github/workflows/publish-nyms5-android-apk.yml | 2 +- .github/workflows/release-calculate-hash.yml | 2 +- 10 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.github/workflows/build-deb-meta.yml b/.github/workflows/build-deb-meta.yml index be9da77868..bb87aff2ef 100644 --- a/.github/workflows/build-deb-meta.yml +++ b/.github/workflows/build-deb-meta.yml @@ -25,14 +25,14 @@ jobs: echo "file2=$(ls nym-vpn*.deb)" >> $GITHUB_ENV - name: Upload nym-repo-setup - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: ${{ env.file1 }} path: ppa/packages/nym-repo-setup*.deb retention-days: 10 - name: Upload nym-vpn - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: ${{ env.file2 }} path: ppa/packages/nym-vpn*.deb diff --git a/.github/workflows/ci-build-upload-binaries.yml b/.github/workflows/ci-build-upload-binaries.yml index 03ac19b7f2..0ddd5afe7f 100644 --- a/.github/workflows/ci-build-upload-binaries.yml +++ b/.github/workflows/ci-build-upload-binaries.yml @@ -110,7 +110,7 @@ jobs: - name: Upload Artifact if: github.event_name == 'workflow_dispatch' - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: nym-binaries-artifacts path: | diff --git a/.github/workflows/nightly-security-audit.yml b/.github/workflows/nightly-security-audit.yml index 8d03483a9c..624e050a28 100644 --- a/.github/workflows/nightly-security-audit.yml +++ b/.github/workflows/nightly-security-audit.yml @@ -20,7 +20,7 @@ jobs: find . -name Cargo.toml -exec cargo deny --manifest-path {} check \ advisories -A advisory-not-detected --hide-inclusion-graph \; &> \ >(uniq &> .github/workflows/support-files/notifications/deny.message ) - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7 with: name: report path: .github/workflows/support-files/notifications/deny.message diff --git a/.github/workflows/publish-nym-binaries.yml b/.github/workflows/publish-nym-binaries.yml index 0a15eb2717..03f56d573e 100644 --- a/.github/workflows/publish-nym-binaries.yml +++ b/.github/workflows/publish-nym-binaries.yml @@ -66,7 +66,7 @@ jobs: args: --workspace --release ${{ env.CARGO_FEATURES }} - name: Upload Artifact - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: my-artifact path: | diff --git a/.github/workflows/publish-nym-contracts.yml b/.github/workflows/publish-nym-contracts.yml index a93b0d5c93..63687caeca 100644 --- a/.github/workflows/publish-nym-contracts.yml +++ b/.github/workflows/publish-nym-contracts.yml @@ -27,14 +27,14 @@ jobs: run: make contracts - name: Upload Mixnet Contract Artifact - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: mixnet_contract.wasm path: contracts/target/wasm32-unknown-unknown/release/mixnet_contract.wasm retention-days: 5 - name: Upload Vesting Contract Artifact - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: vesting_contract.wasm path: contracts/target/wasm32-unknown-unknown/release/vesting_contract.wasm diff --git a/.github/workflows/publish-nym-wallet-macos.yml b/.github/workflows/publish-nym-wallet-macos.yml index 1cd4887570..fad6f3ef0b 100644 --- a/.github/workflows/publish-nym-wallet-macos.yml +++ b/.github/workflows/publish-nym-wallet-macos.yml @@ -108,7 +108,7 @@ jobs: cd - - name: Upload Artifact - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: nym-wallet.app.tar.gz path: nym-wallet/target/x86_64-apple-darwin/release/bundle/macos/nym-wallet.app.tar.gz diff --git a/.github/workflows/publish-nym-wallet-ubuntu.yml b/.github/workflows/publish-nym-wallet-ubuntu.yml index 3fdc95939e..18cebe43bc 100644 --- a/.github/workflows/publish-nym-wallet-ubuntu.yml +++ b/.github/workflows/publish-nym-wallet-ubuntu.yml @@ -132,7 +132,7 @@ jobs: fi - name: Upload Artifact - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: nym-wallet-appimage.tar.gz path: | diff --git a/.github/workflows/publish-nym-wallet-win11.yml b/.github/workflows/publish-nym-wallet-win11.yml index e05940fd96..1a2e1315e2 100644 --- a/.github/workflows/publish-nym-wallet-win11.yml +++ b/.github/workflows/publish-nym-wallet-win11.yml @@ -165,7 +165,7 @@ jobs: find . -name "*.msi" -type f - name: Upload Artifact - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: nym-wallet.msi path: | diff --git a/.github/workflows/publish-nyms5-android-apk.yml b/.github/workflows/publish-nyms5-android-apk.yml index 6241452068..5979fcd7a5 100644 --- a/.github/workflows/publish-nyms5-android-apk.yml +++ b/.github/workflows/publish-nyms5-android-apk.yml @@ -76,7 +76,7 @@ jobs: apk/nyms5-arch64-release.apk - name: Upload APKs - uses: actions/upload-artifact@v6 + uses: actions/upload-artifact@v7 with: name: nyms5-apk-arch64 path: | diff --git a/.github/workflows/release-calculate-hash.yml b/.github/workflows/release-calculate-hash.yml index 23b772bb24..4e927f9bdb 100644 --- a/.github/workflows/release-calculate-hash.yml +++ b/.github/workflows/release-calculate-hash.yml @@ -30,7 +30,7 @@ jobs: with: release-tag-or-name-or-id: ${{ inputs.release_tag }} - - uses: actions/upload-artifact@v6 + - uses: actions/upload-artifact@v7 with: name: Asset Hashes path: hashes.json From 5aa576b5963420eb284abe886a15bf2119151e54 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 15:47:59 +0100 Subject: [PATCH 17/94] build(deps): bump actions/download-artifact from 7 to 8 (#6497) Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 7 to 8. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v7...v8) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-version: '8' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish-nyms5-android-apk.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-nyms5-android-apk.yml b/.github/workflows/publish-nyms5-android-apk.yml index 5979fcd7a5..f38ff56df3 100644 --- a/.github/workflows/publish-nyms5-android-apk.yml +++ b/.github/workflows/publish-nyms5-android-apk.yml @@ -91,7 +91,7 @@ jobs: - name: Checkout uses: actions/checkout@v6 - name: Download binary artifact - uses: actions/download-artifact@v7 + uses: actions/download-artifact@v8 with: name: nyms5-apk-arch64 path: apk From 42807890af3986c65fa908b19c1b3486777226af Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 15:48:09 +0100 Subject: [PATCH 18/94] build(deps): bump docker/login-action from 3 to 4 (#6518) Bumps [docker/login-action](https://github.com/docker/login-action) from 3 to 4. - [Release notes](https://github.com/docker/login-action/releases) - [Commits](https://github.com/docker/login-action/compare/v3...v4) --- updated-dependencies: - dependency-name: docker/login-action dependency-version: '4' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/push-credential-proxy.yaml | 2 +- .github/workflows/push-data-observatory.yaml | 2 +- .github/workflows/push-network-monitor.yaml | 2 +- .github/workflows/push-node-status-agent.yaml | 2 +- .github/workflows/push-node-status-api.yaml | 2 +- .github/workflows/push-nym-api.yaml | 2 +- .github/workflows/push-nym-node.yaml | 2 +- .github/workflows/push-nym-statistics-api.yaml | 2 +- .github/workflows/push-nyx-chain-watcher.yaml | 2 +- .github/workflows/push-validator-rewarder.yaml | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/push-credential-proxy.yaml b/.github/workflows/push-credential-proxy.yaml index a45e8be309..7c54250358 100644 --- a/.github/workflows/push-credential-proxy.yaml +++ b/.github/workflows/push-credential-proxy.yaml @@ -11,7 +11,7 @@ jobs: runs-on: arc-linux-latest-dind steps: - name: Login to Harbor - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: harbor.nymte.ch username: ${{ secrets.HARBOR_ROBOT_USERNAME }} diff --git a/.github/workflows/push-data-observatory.yaml b/.github/workflows/push-data-observatory.yaml index 4af505b9a5..9b6d4e1ae4 100644 --- a/.github/workflows/push-data-observatory.yaml +++ b/.github/workflows/push-data-observatory.yaml @@ -11,7 +11,7 @@ jobs: runs-on: arc-linux-latest-dind steps: - name: Login to Harbor - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: harbor.nymte.ch username: ${{ secrets.HARBOR_ROBOT_USERNAME }} diff --git a/.github/workflows/push-network-monitor.yaml b/.github/workflows/push-network-monitor.yaml index a277d6431e..14a90c4ea1 100644 --- a/.github/workflows/push-network-monitor.yaml +++ b/.github/workflows/push-network-monitor.yaml @@ -11,7 +11,7 @@ jobs: runs-on: arc-ubuntu-22.04-dind steps: - name: Login to Harbor - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: harbor.nymte.ch username: ${{ secrets.HARBOR_ROBOT_USERNAME }} diff --git a/.github/workflows/push-node-status-agent.yaml b/.github/workflows/push-node-status-agent.yaml index 7140d16253..a371d1009b 100644 --- a/.github/workflows/push-node-status-agent.yaml +++ b/.github/workflows/push-node-status-agent.yaml @@ -18,7 +18,7 @@ jobs: runs-on: arc-linux-latest-dind steps: - name: Login to Harbor - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: harbor.nymte.ch username: ${{ secrets.HARBOR_ROBOT_USERNAME }} diff --git a/.github/workflows/push-node-status-api.yaml b/.github/workflows/push-node-status-api.yaml index 380be82338..a966c3f292 100644 --- a/.github/workflows/push-node-status-api.yaml +++ b/.github/workflows/push-node-status-api.yaml @@ -17,7 +17,7 @@ jobs: runs-on: arc-linux-latest-dind steps: - name: Login to Harbor - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: harbor.nymte.ch username: ${{ secrets.HARBOR_ROBOT_USERNAME }} diff --git a/.github/workflows/push-nym-api.yaml b/.github/workflows/push-nym-api.yaml index 86477f6da0..25863f34e4 100644 --- a/.github/workflows/push-nym-api.yaml +++ b/.github/workflows/push-nym-api.yaml @@ -11,7 +11,7 @@ jobs: runs-on: arc-ubuntu-22.04-dind steps: - name: Login to Harbor - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: harbor.nymte.ch username: ${{ secrets.HARBOR_ROBOT_USERNAME }} diff --git a/.github/workflows/push-nym-node.yaml b/.github/workflows/push-nym-node.yaml index 9081795a5a..a349c95e05 100644 --- a/.github/workflows/push-nym-node.yaml +++ b/.github/workflows/push-nym-node.yaml @@ -11,7 +11,7 @@ jobs: runs-on: arc-ubuntu-22.04-dind steps: - name: Login to Harbor - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: harbor.nymte.ch username: ${{ secrets.HARBOR_ROBOT_USERNAME }} diff --git a/.github/workflows/push-nym-statistics-api.yaml b/.github/workflows/push-nym-statistics-api.yaml index 505fc87cd0..fa75cbe470 100644 --- a/.github/workflows/push-nym-statistics-api.yaml +++ b/.github/workflows/push-nym-statistics-api.yaml @@ -11,7 +11,7 @@ jobs: runs-on: arc-linux-latest-dind steps: - name: Login to Harbor - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: harbor.nymte.ch username: ${{ secrets.HARBOR_ROBOT_USERNAME }} diff --git a/.github/workflows/push-nyx-chain-watcher.yaml b/.github/workflows/push-nyx-chain-watcher.yaml index 7db8161813..f73f14adb4 100644 --- a/.github/workflows/push-nyx-chain-watcher.yaml +++ b/.github/workflows/push-nyx-chain-watcher.yaml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Login to Harbor - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: harbor.nymte.ch username: ${{ secrets.HARBOR_ROBOT_USERNAME }} diff --git a/.github/workflows/push-validator-rewarder.yaml b/.github/workflows/push-validator-rewarder.yaml index c8ba6415a8..5be692caaa 100644 --- a/.github/workflows/push-validator-rewarder.yaml +++ b/.github/workflows/push-validator-rewarder.yaml @@ -11,7 +11,7 @@ jobs: runs-on: arc-ubuntu-22.04-dind steps: - name: Login to Harbor - uses: docker/login-action@v3 + uses: docker/login-action@v4 with: registry: harbor.nymte.ch username: ${{ secrets.HARBOR_ROBOT_USERNAME }} From f8a4d5f1ff66a4d9b8008cec29feb0200c121ddf Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 15:48:20 +0100 Subject: [PATCH 19/94] build(deps): bump quinn-proto from 0.11.10 to 0.11.14 in /nym-wallet (#6548) Bumps [quinn-proto](https://github.com/quinn-rs/quinn) from 0.11.10 to 0.11.14. - [Release notes](https://github.com/quinn-rs/quinn/releases) - [Commits](https://github.com/quinn-rs/quinn/compare/quinn-proto-0.11.10...quinn-proto-0.11.14) --- updated-dependencies: - dependency-name: quinn-proto dependency-version: 0.11.14 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- nym-wallet/Cargo.lock | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index fa332f465b..11d5886d82 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -4301,6 +4301,12 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "lru-slab" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" + [[package]] name = "mac" version = "0.1.1" @@ -6241,13 +6247,14 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.10" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc" +checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" dependencies = [ "aws-lc-rs", "bytes", "getrandom 0.3.3", + "lru-slab", "rand 0.9.2", "ring", "rustc-hash", From 1c40499829d27d8e5a0b1bf1bfe0b5eb6bf54c5d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 15:48:31 +0100 Subject: [PATCH 20/94] build(deps): bump quinn-proto from 0.11.12 to 0.11.14 (#6549) Bumps [quinn-proto](https://github.com/quinn-rs/quinn) from 0.11.12 to 0.11.14. - [Release notes](https://github.com/quinn-rs/quinn/releases) - [Commits](https://github.com/quinn-rs/quinn/compare/quinn-proto-0.11.12...quinn-proto-0.11.14) --- updated-dependencies: - dependency-name: quinn-proto dependency-version: 0.11.14 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0eadd13981..aa464dfc75 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9883,9 +9883,9 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.12" +version = "0.11.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e" +checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098" dependencies = [ "aws-lc-rs", "bytes", From f94589c2d1d908d55df3b30ece2b835b2d1e5a0c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 15:49:14 +0100 Subject: [PATCH 21/94] build(deps): bump tar from 0.4.44 to 0.4.45 (#6595) Bumps [tar](https://github.com/alexcrichton/tar-rs) from 0.4.44 to 0.4.45. - [Commits](https://github.com/alexcrichton/tar-rs/compare/0.4.44...0.4.45) --- updated-dependencies: - dependency-name: tar dependency-version: 0.4.45 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aa464dfc75..f7152bdfdd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11950,9 +11950,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.44" +version = "0.4.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" +checksum = "22692a6476a21fa75fdfc11d452fda482af402c008cdbaf3476414e122040973" dependencies = [ "filetime", "libc", diff --git a/Cargo.toml b/Cargo.toml index 5d7ea433b9..7bf905d45f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -360,7 +360,7 @@ subtle-encoding = "0.5" syn = "2" sysinfo = "0.37.0" tap = "1.0.1" -tar = "0.4.44" +tar = "0.4.45" test-with = { version = "0.15.4", default-features = false } tempfile = "3.20" thiserror = "2.0" From fd76c5ca4da6295531655470f2af0d0f0788ce10 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 15:49:24 +0100 Subject: [PATCH 22/94] build(deps): bump microsoft/setup-msbuild from 2 to 3 (#6602) Bumps [microsoft/setup-msbuild](https://github.com/microsoft/setup-msbuild) from 2 to 3. - [Release notes](https://github.com/microsoft/setup-msbuild/releases) - [Commits](https://github.com/microsoft/setup-msbuild/compare/v2...v3) --- updated-dependencies: - dependency-name: microsoft/setup-msbuild dependency-version: '3' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/publish-nym-wallet-win11.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish-nym-wallet-win11.yml b/.github/workflows/publish-nym-wallet-win11.yml index 1a2e1315e2..dc692cda36 100644 --- a/.github/workflows/publish-nym-wallet-win11.yml +++ b/.github/workflows/publish-nym-wallet-win11.yml @@ -38,7 +38,7 @@ jobs: toolchain: ${{ vars.REQUIRED_RUSTC_VERSION }} - name: Setup MSBuild.exe - uses: microsoft/setup-msbuild@v2 + uses: microsoft/setup-msbuild@v3 # No cache:yarn here: setup-node needs yarn on PATH to populate the cache, but this runner # only gets yarn from the step below. From 1572d8e5c287283bf64ace154ca98f7e73a8af86 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 15:49:54 +0100 Subject: [PATCH 23/94] Bump rand from 0.8.5 to 0.8.6 in /contracts (#6702) Bumps [rand](https://github.com/rust-random/rand) from 0.8.5 to 0.8.6. - [Release notes](https://github.com/rust-random/rand/releases) - [Changelog](https://github.com/rust-random/rand/blob/0.8.6/CHANGELOG.md) - [Commits](https://github.com/rust-random/rand/compare/0.8.5...0.8.6) --- updated-dependencies: - dependency-name: rand dependency-version: 0.8.6 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Cargo.toml | 2 +- contracts/Cargo.lock | 4 ++-- contracts/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 7bf905d45f..b6fbaeacf7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -326,7 +326,7 @@ pnet_packet = "0.35.0" publicsuffix = "2.3.0" proc_pidinfo = "0.1.3" quote = "1" -rand = "0.8.5" +rand = "0.8.6" rand09 = { package = "rand", version = "=0.9.2" } rand_chacha = "0.3" rand_chacha09 = { package = "rand_chacha", version = "=0.9.0" } diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index dc14cdffcb..febb1d256f 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -1589,9 +1589,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" dependencies = [ "libc", "rand_chacha", diff --git a/contracts/Cargo.toml b/contracts/Cargo.toml index 9fc98b76ea..df045e70a3 100644 --- a/contracts/Cargo.toml +++ b/contracts/Cargo.toml @@ -50,7 +50,7 @@ cw3-fixed-multisig = "=2.0.0" cw4 = "=2.0.0" cw20 = "=2.0.0" cw20-base = "2.0.0" -rand = "0.8.5" +rand = "0.8.6" rand_chacha = "0.3.1" semver = "1.0.21" serde = "1.0.196" From 3c6d88397ece7b966fe1145e91ebe1153687001a Mon Sep 17 00:00:00 2001 From: Andy Duplain Date: Tue, 19 May 2026 15:51:34 +0100 Subject: [PATCH 24/94] Formatting. --- nym-sqlx-pool-guard/src/lib.rs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/nym-sqlx-pool-guard/src/lib.rs b/nym-sqlx-pool-guard/src/lib.rs index 3e0a64e6ee..a66a0b9167 100644 --- a/nym-sqlx-pool-guard/src/lib.rs +++ b/nym-sqlx-pool-guard/src/lib.rs @@ -77,7 +77,10 @@ impl SqlitePoolGuard { pub async fn close(&self) { // Avoid waiting for db files once the pool is marked closed to ensure that we don't wait on some other sqlite pool to close the database. if !self.inner.connection_pool.is_closed() { - tracing::info!("Closing sqlite pool: {}", self.inner.database_path.display()); + tracing::info!( + "Closing sqlite pool: {}", + self.inner.database_path.display() + ); self.close_pool_inner().await.ok(); } } @@ -142,7 +145,8 @@ impl Drop for SqlitePoolGuard { fn drop(&mut self) { if Arc::strong_count(&self.inner) == 1 && !self.inner.connection_pool.is_closed() { tracing::warn!( - "SqlitePoolGuard dropped without explicit close(); path={}", self.inner.database_path.display() + "SqlitePoolGuard dropped without explicit close(); path={}", + self.inner.database_path.display() ); } } From a68355a75a3d40d74417db9114923b03bad0b108 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 16:36:30 +0100 Subject: [PATCH 25/94] Bump tauri from 2.10.3 to 2.11.1 in /nym-wallet (#6742) Bumps [tauri](https://github.com/tauri-apps/tauri) from 2.10.3 to 2.11.1. - [Release notes](https://github.com/tauri-apps/tauri/releases) - [Commits](https://github.com/tauri-apps/tauri/compare/tauri-v2.10.3...tauri-v2.11.1) --- updated-dependencies: - dependency-name: tauri dependency-version: 2.11.1 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- nym-wallet/Cargo.lock | 1033 ++++++++++++++++++++++++------- nym-wallet/src-tauri/Cargo.toml | 2 +- 2 files changed, 806 insertions(+), 229 deletions(-) diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 11d5886d82..31ea2e2eae 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -78,7 +78,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ - "crypto-common", + "crypto-common 0.1.6", "generic-array", ] @@ -89,10 +89,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", - "cipher", + "cipher 0.4.4", "cpufeatures 0.2.17", ] +[[package]] +name = "aes" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66bd29a732b644c0431c6140f370d097879203d79b80c94a6747ba0872adaef8" +dependencies = [ + "cipher 0.5.1", + "cpubits", + "cpufeatures 0.3.0", +] + [[package]] name = "aes-gcm" version = "0.10.3" @@ -100,13 +111,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" dependencies = [ "aead", - "aes", - "cipher", + "aes 0.8.4", + "cipher 0.4.4", "ctr", "ghash", "subtle", ] +[[package]] +name = "aes-keywrap" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10b6f24a1f796bc46415a1d0d18dc0a8203ccba088acf5def3291c4f61225522" +dependencies = [ + "aes 0.9.0", + "byteorder", +] + [[package]] name = "ahash" version = "0.8.11" @@ -216,9 +237,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.97" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "arbitrary" @@ -238,7 +259,7 @@ dependencies = [ "clipboard-win", "image", "log", - "objc2 0.6.0", + "objc2 0.6.4", "objc2-app-kit", "objc2-core-foundation", "objc2-core-graphics", @@ -379,7 +400,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ "num-traits", - "rand 0.8.5", + "rand 0.8.6", "rayon", ] @@ -701,13 +722,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33415e24172c1b7d6066f6d999545375ab8e1d95421d6784bdfff9496f292387" dependencies = [ "bitcoin_hashes", - "rand 0.8.5", + "rand 0.7.3", "rand_core 0.6.4", "serde", "unicode-normalization", "zeroize", ] +[[package]] +name = "bit-set" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7" + [[package]] name = "bitcoin-internals" version = "0.2.0" @@ -750,9 +786,9 @@ dependencies = [ [[package]] name = "blake2b_simd" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e903a20b159e944f91ec8499fe1e55651480c541ea0a584f5d967c49ad9d99" +checksum = "b79834656f71332577234b50bfc009996f7449e0c056884e6a02492ded0ca2f3" dependencies = [ "arrayref", "arrayvec", @@ -777,6 +813,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" +dependencies = [ + "hybrid-array", +] + [[package]] name = "block2" version = "0.5.1" @@ -788,11 +833,11 @@ dependencies = [ [[package]] name = "block2" -version = "0.6.0" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d59b4c170e16f0405a2e95aff44432a0d41aa97675f3d52623effe95792a037" +checksum = "cdeb9d870516001442e364c5220d3574d2da8dc765554b4a617230d33fa58ef5" dependencies = [ - "objc2 0.6.0", + "objc2 0.6.4", ] [[package]] @@ -967,7 +1012,7 @@ dependencies = [ "semver", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -1071,8 +1116,18 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "crypto-common", - "inout", + "crypto-common 0.1.6", + "inout 0.1.4", +] + +[[package]] +name = "cipher" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e34d8227fe1ba289043aeb13792056ff80fd6de1a9f49137a5f499de8e8c78ea" +dependencies = [ + "crypto-common 0.2.1", + "inout 0.2.2", ] [[package]] @@ -1134,10 +1189,16 @@ dependencies = [ ] [[package]] -name = "coarsetime" -version = "0.1.36" +name = "cmov" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91849686042de1b41cd81490edc83afbcb0abe5a9b6f2c4114f23ce8cca1bcf4" +checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746" + +[[package]] +name = "coarsetime" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e58eb270476aa4fc7843849f8a35063e8743b4dbcdf6dd0f8ea0886980c204c2" dependencies = [ "libc", "wasix", @@ -1196,6 +1257,12 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + [[package]] name = "const-str" version = "0.5.7" @@ -1204,9 +1271,9 @@ checksum = "3618cccc083bb987a415d85c02ca6c9994ea5b44731ec28b9ecf09658655fba9" [[package]] name = "constant_time_eq" -version = "0.3.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" +checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" [[package]] name = "convert_case" @@ -1263,6 +1330,19 @@ dependencies = [ "libc", ] +[[package]] +name = "core-graphics" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "064badf302c3194842cf2c5d61f56cc88e54a759313879cdf03abdd27d0c3b97" +dependencies = [ + "bitflags 2.9.0", + "core-foundation 0.10.0", + "core-graphics-types", + "foreign-types 0.5.0", + "libc", +] + [[package]] name = "core-graphics-types" version = "0.2.0" @@ -1309,7 +1389,7 @@ dependencies = [ "rand_core 0.6.4", "serde", "serde_json", - "signature", + "signature 2.2.0", "subtle-encoding", "tendermint", "tendermint-rpc", @@ -1405,6 +1485,12 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "cpubits" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -1495,6 +1581,17 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77727bb15fa921304124b128af125e7e3b968275d1b108b379190264f4423710" +dependencies = [ + "getrandom 0.4.2", + "hybrid-array", + "rand_core 0.10.1", +] + [[package]] name = "cssparser" version = "0.29.6" @@ -1512,6 +1609,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "cssparser" +version = "0.36.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dae61cf9c0abb83bd659dab65b7e4e38d8236824c85f0f804f173567bda257d2" +dependencies = [ + "cssparser-macros", + "dtoa-short", + "itoa", + "phf 0.13.1", + "smallvec", +] + [[package]] name = "cssparser-macros" version = "0.6.1" @@ -1530,21 +1640,36 @@ checksum = "9b10589d1a5e400d61f9f38f12f884cfd080ff345de8f17efda36fe0e4a02aa8" [[package]] name = "ctor" -version = "0.2.9" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" +checksum = "352d39c2f7bef1d6ad73db6f5160efcaed66d94ef8c6c573a8410c00bf909a98" dependencies = [ - "quote", - "syn 2.0.117", + "ctor-proc-macro", + "dtor", ] +[[package]] +name = "ctor-proc-macro" +version = "0.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52560adf09603e58c9a7ee1fe1dcb95a16927b17c127f0ac02d6e768a0e25bc1" + [[package]] name = "ctr" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ - "cipher", + "cipher 0.4.4", +] + +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", ] [[package]] @@ -1724,17 +1849,38 @@ version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010" +[[package]] +name = "dbus" +version = "0.9.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b942602992bb7acfd1f51c49811c58a610ef9181b6e66f3e519d79b540a3bf73" +dependencies = [ + "libc", + "libdbus-sys", + "windows-sys 0.61.2", +] + [[package]] name = "der" version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" dependencies = [ - "const-oid", + "const-oid 0.9.6", "pem-rfc7468", "zeroize", ] +[[package]] +name = "der" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71fd89660b2dc699704064e59e9dba0147b903e85319429e131620d022be411b" +dependencies = [ + "const-oid 0.10.2", + "zeroize", +] + [[package]] name = "deranged" version = "0.4.1" @@ -1786,7 +1932,16 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" dependencies = [ - "derive_more-impl", + "derive_more-impl 1.0.0", +] + +[[package]] +name = "derive_more" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134" +dependencies = [ + "derive_more-impl 2.1.1", ] [[package]] @@ -1801,6 +1956,18 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "derive_more-impl" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "syn 2.0.117", +] + [[package]] name = "digest" version = "0.9.0" @@ -1817,11 +1984,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", - "const-oid", - "crypto-common", + "const-oid 0.9.6", + "crypto-common 0.1.6", "subtle", ] +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.0", + "crypto-common 0.2.1", +] + [[package]] name = "dirs" version = "4.0.0" @@ -1864,10 +2041,16 @@ dependencies = [ ] [[package]] -name = "dispatch" -version = "0.2.0" +name = "dispatch2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +checksum = "1e0e367e4e7da84520dedcac1901e4da967309406d1e51017ae1abfb97adbd38" +dependencies = [ + "bitflags 2.9.0", + "block2 0.6.2", + "libc", + "objc2 0.6.4", +] [[package]] name = "displaydoc" @@ -1903,6 +2086,21 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "dom_query" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "521e380c0c8afb8d9a1e83a1822ee03556fc3e3e7dbc1fd30be14e37f9cb3f89" +dependencies = [ + "bit-set", + "cssparser 0.36.0", + "foldhash 0.2.0", + "html5ever 0.38.0", + "precomputed-hash", + "selectors 0.36.1", + "tendril 0.5.0", +] + [[package]] name = "dotenvy" version = "0.15.7" @@ -1939,6 +2137,21 @@ dependencies = [ "dtoa", ] +[[package]] +name = "dtor" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1057d6c64987086ff8ed0fd3fbf377a6b7d205cc7715868cd401705f715cbe4" +dependencies = [ + "dtor-proc-macro", +] + +[[package]] +name = "dtor-proc-macro" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f678cf4a922c215c63e0de95eb1ff08a958a81d47e485cf9da1e27bf6305cfa5" + [[package]] name = "dunce" version = "1.0.5" @@ -1957,13 +2170,13 @@ version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "der", + "der 0.7.9", "digest 0.10.7", "elliptic-curve", "rfc6979", "serdect 0.2.0", - "signature", - "spki", + "signature 2.2.0", + "spki 0.7.3", ] [[package]] @@ -1972,19 +2185,19 @@ version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ - "pkcs8", + "pkcs8 0.10.2", "serde", - "signature", + "signature 2.2.0", ] [[package]] name = "ed25519-compact" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9b3460f44bea8cd47f45a0c70892f1eff856d97cd55358b2f73f663789f6190" +checksum = "f5c0284a5d4b1a2fae017a9fe55fd7d01699711f1b572493f16593e173ea2801" dependencies = [ "ct-codecs", - "getrandom 0.2.15", + "getrandom 0.4.2", ] [[package]] @@ -2050,7 +2263,7 @@ dependencies = [ "group", "hkdf", "pem-rfc7468", - "pkcs8", + "pkcs8 0.10.2", "rand_core 0.6.4", "sec1", "serdect 0.2.0", @@ -2297,6 +2510,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" +[[package]] +name = "foldhash" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb" + [[package]] name = "foreign-types" version = "0.3.2" @@ -2653,11 +2872,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi 6.0.0", "rand_core 0.10.1", "wasip2", "wasip3", + "wasm-bindgen", ] [[package]] @@ -2918,7 +3139,7 @@ version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" dependencies = [ - "foldhash", + "foldhash 0.1.5", ] [[package]] @@ -3030,7 +3251,7 @@ dependencies = [ "jni 0.22.4", "rand 0.10.1", "rustls 0.23.37", - "thiserror 2.0.12", + "thiserror 2.0.18", "tinyvec", "tokio", "tokio-rustls 0.26.2", @@ -3053,7 +3274,7 @@ dependencies = [ "prefix-trie", "rand 0.10.1", "ring", - "thiserror 2.0.12", + "thiserror 2.0.18", "tinyvec", "tracing", "url", @@ -3081,7 +3302,7 @@ dependencies = [ "rustls 0.23.37", "smallvec", "system-configuration 0.7.0", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tokio-rustls 0.26.2", "tracing", @@ -3108,24 +3329,24 @@ dependencies = [ [[package]] name = "hmac-sha1-compact" -version = "1.1.5" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18492c9f6f9a560e0d346369b665ad2bdbc89fa9bceca75796584e79042694c3" +checksum = "b0b3ba31f6dc772cc8221ce81dbbbd64fa1e668255a6737d95eeace59b5a8823" [[package]] name = "hmac-sha256" -version = "1.1.12" +version = "1.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad6880c8d4a9ebf39c6e8b77007ce223f646a4d21ce29d99f70cb16420545425" +checksum = "ec9d92d097f4749b64e8cc33d924d9f40a2d4eb91402b458014b781f5733d60f" dependencies = [ "digest 0.10.7", ] [[package]] name = "hmac-sha512" -version = "1.1.7" +version = "1.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89e8d20b3799fa526152a5301a771eaaad80857f83e01b23216ceaafb2d9280" +checksum = "019ece39bbefc17f13f677a690328cb978dbf6790e141a3c24e66372cb38588b" dependencies = [ "digest 0.10.7", ] @@ -3149,10 +3370,20 @@ checksum = "3b7410cae13cbc75623c98ac4cbfd1f0bedddf3227afc24f370cf0f50a44a11c" dependencies = [ "log", "mac", - "markup5ever", + "markup5ever 0.14.1", "match_token", ] +[[package]] +name = "html5ever" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1054432bae2f14e0061e33d23402fbaa67a921d319d56adc6bcf887ddad1cbc2" +dependencies = [ + "log", + "markup5ever 0.38.0", +] + [[package]] name = "http" version = "0.2.12" @@ -3246,6 +3477,16 @@ dependencies = [ "serde", ] +[[package]] +name = "hybrid-array" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" +dependencies = [ + "ctutils", + "typenum", +] + [[package]] name = "hyper" version = "0.14.32" @@ -3393,7 +3634,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e795dff5605e0f04bff85ca41b51a96b83e80b281e96231bcaaf1ac35103371" dependencies = [ "byteorder", - "png", + "png 0.17.16", ] [[package]] @@ -3556,7 +3797,7 @@ dependencies = [ "bytemuck", "byteorder-lite", "num-traits", - "png", + "png 0.17.16", "tiff", ] @@ -3606,6 +3847,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "inout" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" +dependencies = [ + "hybrid-array", +] + [[package]] name = "inventory" version = "0.3.21" @@ -3768,7 +4018,7 @@ dependencies = [ "jni-sys 0.4.1", "log", "simd_cesu8", - "thiserror 2.0.12", + "thiserror 2.0.18", "walkdir", "windows-link 0.2.1", ] @@ -3863,9 +4113,9 @@ dependencies = [ [[package]] name = "jwt-simple" -version = "0.12.12" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "731011e9647a71ff4f8474176ff6ce6e0d2de87a0173f15613af3a84c3e3401a" +checksum = "f45048cd18221c81d27dd4621d51df25b33f11b68655d79f67a9f9d3eb48fecc" dependencies = [ "anyhow", "binstring", @@ -3879,11 +4129,11 @@ dependencies = [ "k256", "p256", "p384", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde_json", "superboring", - "thiserror 2.0.12", + "thiserror 2.0.18", "zeroize", ] @@ -3898,7 +4148,17 @@ dependencies = [ "elliptic-curve", "once_cell", "sha2 0.10.9", - "signature", + "signature 2.2.0", +] + +[[package]] +name = "keccak" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e24a010dd405bd7ed803e5253182815b41bf2e6a80cc3bfc066658e03a198aa" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", ] [[package]] @@ -3918,10 +4178,10 @@ version = "0.8.8-speedreader" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "02cb977175687f33fa4afa0c95c112b987ea1443e5a51c8f8ff27dc618270cc2" dependencies = [ - "cssparser", - "html5ever", + "cssparser 0.29.6", + "html5ever 0.29.1", "indexmap 2.8.0", - "selectors", + "selectors 0.24.0", ] [[package]] @@ -4224,6 +4484,15 @@ dependencies = [ "rand 0.9.2", ] +[[package]] +name = "libdbus-sys" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "328c4789d42200f1eeec05bd86c9c13c7f091d2ba9a6ea35acdf51f31bc0f043" +dependencies = [ + "pkg-config", +] + [[package]] name = "libloading" version = "0.7.4" @@ -4322,9 +4591,20 @@ dependencies = [ "log", "phf 0.11.3", "phf_codegen 0.11.3", - "string_cache", - "string_cache_codegen", - "tendril", + "string_cache 0.8.9", + "string_cache_codegen 0.5.4", + "tendril 0.4.3", +] + +[[package]] +name = "markup5ever" +version = "0.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8983d30f2915feeaaab2d6babdd6bc7e9ed1a00b66b5e6d74df19aa9c0e91862" +dependencies = [ + "log", + "tendril 0.5.0", + "web_atoms", ] [[package]] @@ -4407,6 +4687,33 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "ml-dsa" +version = "0.1.0-rc.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "163f15320f3fba11760c373af52d7f69d638482c2c350d877fb06513b1c3137c" +dependencies = [ + "const-oid 0.10.2", + "crypto-common 0.2.1", + "ctutils", + "hybrid-array", + "module-lattice", + "pkcs8 0.11.0", + "sha3", + "signature 3.0.0", +] + +[[package]] +name = "module-lattice" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c61b87c9683ab7cb1c6871d261ad5479b6b10ceb52c4352aaca3b5d35a8febe" +dependencies = [ + "ctutils", + "hybrid-array", + "num-traits", +] + [[package]] name = "moka" version = "0.12.10" @@ -4428,23 +4735,23 @@ dependencies = [ [[package]] name = "muda" -version = "0.17.1" +version = "0.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c1738382f66ed56b3b9c8119e794a2e23148ac8ea214eda86622d4cb9d415a" +checksum = "0ae8844f63b5b118e334e205585b8c5c17b984121dbdb179d44aeb087ffad3cb" dependencies = [ "crossbeam-channel", "dpi", "gtk", "keyboard-types", - "objc2 0.6.0", + "objc2 0.6.4", "objc2-app-kit", "objc2-core-foundation", "objc2-foundation 0.3.0", "once_cell", - "png", + "png 0.18.1", "serde", - "thiserror 2.0.12", - "windows-sys 0.60.2", + "thiserror 2.0.18", + "windows-sys 0.61.2", ] [[package]] @@ -4537,17 +4844,16 @@ dependencies = [ [[package]] name = "num-bigint-dig" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" dependencies = [ - "byteorder", "lazy_static", "libm", "num-integer", "num-iter", "num-traits", - "rand 0.8.5", + "rand 0.8.6", "smallvec", "zeroize", ] @@ -4653,7 +4959,7 @@ dependencies = [ "strum_macros 0.28.0", "tendermint", "tendermint-rpc", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tracing", "utoipa", @@ -4717,11 +5023,11 @@ dependencies = [ "nym-bls12_381-fork", "nym-network-defaults", "nym-pemstore", - "rand 0.8.5", + "rand 0.8.6", "serde", "sha2 0.10.9", "subtle", - "thiserror 2.0.12", + "thiserror 2.0.18", "zeroize", ] @@ -4734,7 +5040,7 @@ dependencies = [ "log", "nym-network-defaults", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", "toml 0.8.22", "url", ] @@ -4749,7 +5055,7 @@ dependencies = [ "cw-storage-plus", "schemars", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", "vergen", ] @@ -4762,11 +5068,11 @@ dependencies = [ "nym-ecash-time", "nym-network-defaults", "nym-upgrade-mode-check", - "rand 0.8.5", + "rand 0.8.6", "serde", "strum 0.28.0", "strum_macros 0.28.0", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "utoipa", ] @@ -4783,12 +5089,12 @@ dependencies = [ "libcrux-curve25519", "libcrux-psq", "nym-pemstore", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde_bytes", "sha2 0.10.9", "subtle-encoding", - "thiserror 2.0.12", + "thiserror 2.0.18", "x25519-dalek", "zeroize", ] @@ -4803,7 +5109,7 @@ dependencies = [ "cw-controllers", "cw-utils", "nym-multisig-contract-common", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -4814,7 +5120,7 @@ dependencies = [ "nym-crypto", "semver", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tracing", "url", @@ -4834,7 +5140,7 @@ version = "1.21.0" dependencies = [ "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.18", "tracing", "utoipa", ] @@ -4875,7 +5181,7 @@ dependencies = [ "serde_json", "serde_plain", "serde_yaml", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tracing", "url", @@ -4911,7 +5217,7 @@ dependencies = [ "semver", "strum 0.28.0", "strum_macros 0.28.0", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -4929,7 +5235,7 @@ dependencies = [ "semver", "serde", "serde_repr", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "ts-rs", "utoipa", @@ -4947,7 +5253,7 @@ dependencies = [ "cw4", "schemars", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -4978,7 +5284,7 @@ dependencies = [ "nym-mixnet-contract-common", "schemars", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -5001,7 +5307,7 @@ dependencies = [ "serde_json", "strum 0.28.0", "strum_macros 0.28.0", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "url", "utoipa", @@ -5036,7 +5342,7 @@ dependencies = [ "nym-contracts-common", "schemars", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -5058,10 +5364,10 @@ dependencies = [ "argon2", "generic-array", "getrandom 0.2.15", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.18", "zeroize", ] @@ -5102,7 +5408,7 @@ dependencies = [ "sha2 0.10.9", "strum 0.28.0", "strum_macros 0.28.0", - "thiserror 2.0.12", + "thiserror 2.0.18", "ts-rs", "url", "utoipa", @@ -5119,7 +5425,7 @@ dependencies = [ "reqwest 0.13.2", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tracing", "utoipa", @@ -5166,7 +5472,7 @@ dependencies = [ "serde_json", "sha2 0.10.9", "tendermint-rpc", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tracing", @@ -5184,7 +5490,7 @@ dependencies = [ "nym-contracts-common", "nym-mixnet-contract-common", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -5228,7 +5534,7 @@ dependencies = [ "base64 0.22.1", "nym-crypto", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", "x25519-dalek", "zeroize", ] @@ -5251,9 +5557,9 @@ dependencies = [ [[package]] name = "objc2" -version = "0.6.0" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3531f65190d9cff863b77a99857e74c314dd16bf56c538c4b57c7cbc3f3a6e59" +checksum = "3a12a8ed07aefc768292f076dc3ac8c48f3781c8f2d5851dd3d98950e8c5a89f" dependencies = [ "objc2-encode", "objc2-exception-helper", @@ -5266,13 +5572,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5906f93257178e2f7ae069efb89fbd6ee94f0592740b5f8a1512ca498814d0fb" dependencies = [ "bitflags 2.9.0", - "block2 0.6.0", - "objc2 0.6.0", + "block2 0.6.2", + "objc2 0.6.4", "objc2-core-foundation", "objc2-core-graphics", "objc2-foundation 0.3.0", ] +[[package]] +name = "objc2-cloud-kit" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c1948a9be5f469deadbd6bcb86ad7ff9e47b4f632380139722f7d9840c0d42c" +dependencies = [ + "bitflags 2.9.0", + "objc2 0.6.4", + "objc2-foundation 0.3.0", +] + +[[package]] +name = "objc2-core-data" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f860f8e841f6d32f754836f51e6bc7777cd7e7053cf18528233f6811d3eceb4" +dependencies = [ + "objc2 0.6.4", + "objc2-foundation 0.3.0", +] + [[package]] name = "objc2-core-foundation" version = "0.3.0" @@ -5280,7 +5607,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daeaf60f25471d26948a1c2f840e3f7d86f4109e3af4e8e4b5cd70c39690d925" dependencies = [ "bitflags 2.9.0", - "objc2 0.6.0", + "objc2 0.6.4", ] [[package]] @@ -5290,11 +5617,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dca602628b65356b6513290a21a6405b4d4027b8b250f0b98dddbb28b7de02" dependencies = [ "bitflags 2.9.0", - "objc2 0.6.0", + "objc2 0.6.4", "objc2-core-foundation", "objc2-io-surface", ] +[[package]] +name = "objc2-core-image" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ffa6bea72bf42c78b0b34e89c0bafac877d5f80bf91e159a5d96ea7f693ca56" +dependencies = [ + "objc2 0.6.4", + "objc2-foundation 0.3.0", +] + +[[package]] +name = "objc2-core-location" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d31f4c5b5192304996badc466aeadffe1411d73a9bbd3b18b6b2ee9d048b07bd" +dependencies = [ + "objc2 0.6.4", + "objc2-foundation 0.3.0", +] + [[package]] name = "objc2-encode" version = "4.1.0" @@ -5329,9 +5676,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a21c6c9014b82c39515db5b396f91645182611c97d24637cf56ac01e5f8d998" dependencies = [ "bitflags 2.9.0", - "block2 0.6.0", + "block2 0.6.2", "libc", - "objc2 0.6.0", + "objc2 0.6.4", "objc2-core-foundation", ] @@ -5342,7 +5689,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "161a8b87e32610086e1a7a9e9ec39f84459db7b3a0881c1f16ca5a2605581c19" dependencies = [ "bitflags 2.9.0", - "objc2 0.6.0", + "objc2 0.6.4", "objc2-core-foundation", ] @@ -5365,7 +5712,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a1ac59da3ceebc4a82179b35dc550431ad9458f9cc326e053f49ba371ce76c5a" dependencies = [ "bitflags 2.9.0", - "objc2 0.6.0", + "objc2 0.6.4", "objc2-app-kit", "objc2-foundation 0.3.0", ] @@ -5383,6 +5730,18 @@ dependencies = [ "objc2-metal", ] +[[package]] +name = "objc2-quartz-core" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fb3794501bb1bee12f08dcad8c61f2a5875791ad1c6f47faa71a0f033f20071" +dependencies = [ + "bitflags 2.9.0", + "objc2 0.6.4", + "objc2-core-foundation", + "objc2-foundation 0.3.0", +] + [[package]] name = "objc2-ui-kit" version = "0.3.0" @@ -5390,8 +5749,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "777a571be14a42a3990d4ebedaeb8b54cd17377ec21b92e8200ac03797b3bee1" dependencies = [ "bitflags 2.9.0", - "objc2 0.6.0", + "block2 0.6.2", + "objc2 0.6.4", + "objc2-cloud-kit", + "objc2-core-data", "objc2-core-foundation", + "objc2-core-graphics", + "objc2-core-image", + "objc2-core-location", + "objc2-foundation 0.3.0", + "objc2-quartz-core 0.3.0", + "objc2-user-notifications", +] + +[[package]] +name = "objc2-user-notifications" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670fe793adbf3b5e93686d48a05a7ed7ee53dfa65d106ced4805fae8969059b2" +dependencies = [ + "objc2 0.6.4", "objc2-foundation 0.3.0", ] @@ -5402,8 +5779,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b717127e4014b0f9f3e8bba3d3f2acec81f1bde01f656823036e823ed2c94dce" dependencies = [ "bitflags 2.9.0", - "block2 0.6.0", - "objc2 0.6.0", + "block2 0.6.2", + "objc2 0.6.4", "objc2-app-kit", "objc2-core-foundation", "objc2-foundation 0.3.0", @@ -5527,12 +5904,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "732c71caeaa72c065bb69d7ea08717bd3f4863a4f451402fc9513e29dbd5261b" dependencies = [ - "objc2 0.6.0", + "objc2 0.6.4", "objc2-foundation 0.3.0", "objc2-osa-kit", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -5711,7 +6088,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "198db74531d58c70a361c42201efde7e2591e976d518caf7662a47dc5720e7b6" dependencies = [ "memchr", - "thiserror 2.0.12", + "thiserror 2.0.18", "ucd-trie", ] @@ -5789,6 +6166,17 @@ dependencies = [ "phf_shared 0.11.3", ] +[[package]] +name = "phf" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1562dc717473dbaa4c1f85a36410e03c047b2e7df7f45ee938fbef64ae7fadf" +dependencies = [ + "phf_macros 0.13.1", + "phf_shared 0.13.1", + "serde", +] + [[package]] name = "phf_codegen" version = "0.8.0" @@ -5809,6 +6197,16 @@ dependencies = [ "phf_shared 0.11.3", ] +[[package]] +name = "phf_codegen" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49aa7f9d80421bca176ca8dbfebe668cc7a2684708594ec9f3c0db0805d5d6e1" +dependencies = [ + "phf_generator 0.13.1", + "phf_shared 0.13.1", +] + [[package]] name = "phf_generator" version = "0.8.0" @@ -5826,7 +6224,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d5285893bb5eb82e6aaf5d59ee909a06a16737a8970984dd7746ba9283498d6" dependencies = [ "phf_shared 0.10.0", - "rand 0.8.5", + "rand 0.8.6", ] [[package]] @@ -5836,7 +6234,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared 0.11.3", - "rand 0.8.5", + "rand 0.8.6", +] + +[[package]] +name = "phf_generator" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "135ace3a761e564ec88c03a77317a7c6b80bb7f7135ef2544dbe054243b89737" +dependencies = [ + "fastrand", + "phf_shared 0.13.1", ] [[package]] @@ -5866,6 +6274,19 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "phf_macros" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "812f032b54b1e759ccd5f8b6677695d5268c588701effba24601f6932f8269ef" +dependencies = [ + "phf_generator 0.13.1", + "phf_shared 0.13.1", + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "phf_shared" version = "0.8.0" @@ -5893,6 +6314,15 @@ dependencies = [ "siphasher 1.0.1", ] +[[package]] +name = "phf_shared" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e57fef6bc5981e38c2ce2d63bfa546861309f875b8a75f092d1d54ae2d64f266" +dependencies = [ + "siphasher 1.0.1", +] + [[package]] name = "pin-project" version = "1.1.10" @@ -5942,9 +6372,9 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" dependencies = [ - "der", - "pkcs8", - "spki", + "der 0.7.9", + "pkcs8 0.10.2", + "spki 0.7.3", ] [[package]] @@ -5953,8 +6383,18 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der", - "spki", + "der 0.7.9", + "spki 0.7.3", +] + +[[package]] +name = "pkcs8" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" +dependencies = [ + "der 0.8.0", + "spki 0.8.0", ] [[package]] @@ -5989,6 +6429,19 @@ dependencies = [ "miniz_oxide", ] +[[package]] +name = "png" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60769b8b31b2a9f263dae2776c37b1b28ae246943cf719eb6946a1db05128a61" +dependencies = [ + "bitflags 2.9.0", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + [[package]] name = "polling" version = "3.7.4" @@ -6165,9 +6618,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] @@ -6239,7 +6692,7 @@ dependencies = [ "rustc-hash", "rustls 0.23.37", "socket2 0.5.9", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tracing", "web-time", @@ -6261,7 +6714,7 @@ dependencies = [ "rustls 0.23.37", "rustls-pki-types", "slab", - "thiserror 2.0.12", + "thiserror 2.0.18", "tinyvec", "tracing", "web-time", @@ -6318,9 +6771,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" dependencies = [ "libc", "rand_chacha 0.3.1", @@ -6483,7 +6936,7 @@ checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" dependencies = [ "getrandom 0.2.15", "libredox", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -6715,21 +7168,21 @@ dependencies = [ [[package]] name = "rsa" -version = "0.9.8" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b" +checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" dependencies = [ - "const-oid", + "const-oid 0.9.6", "digest 0.10.7", "num-bigint-dig", "num-integer", "num-traits", "pkcs1", - "pkcs8", + "pkcs8 0.10.2", "rand_core 0.6.4", "sha2 0.10.9", - "signature", - "spki", + "signature 2.2.0", + "spki 0.7.3", "subtle", "zeroize", ] @@ -6996,9 +7449,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", - "der", + "der 0.7.9", "generic-array", - "pkcs8", + "pkcs8 0.10.2", "serdect 0.2.0", "subtle", "zeroize", @@ -7065,14 +7518,33 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c37578180969d00692904465fb7f6b3d50b9a2b952b87c23d0e2e5cb5013416" dependencies = [ "bitflags 1.3.2", - "cssparser", + "cssparser 0.29.6", "derive_more 0.99.19", "fxhash", "log", "phf 0.8.0", "phf_codegen 0.8.0", "precomputed-hash", - "servo_arc", + "servo_arc 0.2.0", + "smallvec", +] + +[[package]] +name = "selectors" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5d9c0c92a92d33f08817311cf3f2c29a3538a8240e94a6a3c622ce652d7e00c" +dependencies = [ + "bitflags 2.9.0", + "cssparser 0.36.0", + "derive_more 2.1.1", + "log", + "new_debug_unreachable", + "phf 0.13.1", + "phf_codegen 0.13.1", + "precomputed-hash", + "rustc-hash", + "servo_arc 0.4.3", "smallvec", ] @@ -7087,10 +7559,11 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" dependencies = [ + "serde_core", "serde_derive", ] @@ -7124,10 +7597,19 @@ dependencies = [ ] [[package]] -name = "serde_derive" -version = "1.0.219" +name = "serde_core" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", @@ -7147,14 +7629,15 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.140" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "itoa", "memchr", - "ryu", "serde", + "serde_core", + "zmij", ] [[package]] @@ -7302,6 +7785,15 @@ dependencies = [ "stable_deref_trait", ] +[[package]] +name = "servo_arc" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "170fb83ab34de17dc69aa7c67482b22218ddb85da56546f9bd6b929e32a05930" +dependencies = [ + "stable_deref_trait", +] + [[package]] name = "sha2" version = "0.9.9" @@ -7326,6 +7818,16 @@ dependencies = [ "digest 0.10.7", ] +[[package]] +name = "sha3" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be176f1a57ce4e3d31c1a166222d9768de5954f811601fb7ca06fc8203905ce1" +dependencies = [ + "digest 0.11.3", + "keccak", +] + [[package]] name = "sharded-slab" version = "0.1.7" @@ -7360,6 +7862,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "signature" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" +dependencies = [ + "digest 0.11.3", + "rand_core 0.10.1", +] + [[package]] name = "simd-adler32" version = "0.3.7" @@ -7437,13 +7949,13 @@ checksum = "18051cdd562e792cad055119e0cdb2cfc137e44e3987532e0f9659a77931bb08" dependencies = [ "bytemuck", "cfg_aliases", - "core-graphics", + "core-graphics 0.24.0", "foreign-types 0.5.0", "js-sys", "log", "objc2 0.5.2", "objc2-foundation 0.2.2", - "objc2-quartz-core", + "objc2-quartz-core 0.2.2", "raw-window-handle", "redox_syscall", "wasm-bindgen", @@ -7490,7 +8002,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der", + "der 0.7.9", +] + +[[package]] +name = "spki" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" +dependencies = [ + "base64ct", + "der 0.8.0", ] [[package]] @@ -7518,6 +8040,18 @@ dependencies = [ "serde", ] +[[package]] +name = "string_cache" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18596f8c785a729f2819c0f6a7eae6ebeebdfffbfe4214ae6b087f690e31901" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared 0.13.1", + "precomputed-hash", +] + [[package]] name = "string_cache_codegen" version = "0.5.4" @@ -7530,6 +8064,18 @@ dependencies = [ "quote", ] +[[package]] +name = "string_cache_codegen" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585635e46db231059f76c5849798146164652513eb9e8ab2685939dd90f29b69" +dependencies = [ + "phf_generator 0.13.1", + "phf_shared 0.13.1", + "proc-macro2", + "quote", +] + [[package]] name = "strsim" version = "0.11.1" @@ -7601,14 +8147,17 @@ checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" [[package]] name = "superboring" -version = "0.1.4" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "515cce34a781d7250b8a65706e0f2a5b99236ea605cb235d4baed6685820478f" +checksum = "efc6310a69b44420f3bf53d518077615b7d466cc57df7a80e404e7feb8c510f7" dependencies = [ + "aes-gcm", + "aes-keywrap", "getrandom 0.2.15", "hmac-sha256", "hmac-sha512", - "rand 0.8.5", + "ml-dsa", + "rand 0.8.6", "rsa", ] @@ -7745,35 +8294,35 @@ checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" [[package]] name = "tao" -version = "0.34.5" +version = "0.35.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3a753bdc39c07b192151523a3f77cd0394aa75413802c883a0f6f6a0e5ee2e7" +checksum = "a33f7f9e486ade65fcf1e45c440f9236c904f5c1002cdc7fc6ae582777345ce4" dependencies = [ "bitflags 2.9.0", - "block2 0.6.0", + "block2 0.6.2", "core-foundation 0.10.0", - "core-graphics", + "core-graphics 0.25.0", "crossbeam-channel", - "dispatch", + "dbus", + "dispatch2", "dlopen2", "dpi", "gdkwayland-sys", "gdkx11-sys", "gtk", "jni 0.21.1", - "lazy_static", "libc", "log", "ndk", - "ndk-context", "ndk-sys", - "objc2 0.6.0", + "objc2 0.6.4", "objc2-app-kit", "objc2-foundation 0.3.0", + "objc2-ui-kit", "once_cell", "parking_lot", + "percent-encoding", "raw-window-handle", - "scopeguard", "tao-macros", "unicode-segmentation", "url", @@ -7819,9 +8368,9 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tauri" -version = "2.10.3" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da77cc00fb9028caf5b5d4650f75e31f1ef3693459dfca7f7e506d1ecef0ba2d" +checksum = "b93bd86d231f0a8138f11a02a584769fe4b703dc36ae133d783228dbc4801405" dependencies = [ "anyhow", "bytes", @@ -7839,7 +8388,7 @@ dependencies = [ "log", "mime", "muda", - "objc2 0.6.0", + "objc2 0.6.4", "objc2-app-kit", "objc2-foundation 0.3.0", "objc2-ui-kit", @@ -7858,7 +8407,7 @@ dependencies = [ "tauri-runtime", "tauri-runtime-wry", "tauri-utils", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tray-icon", "url", @@ -7870,9 +8419,9 @@ dependencies = [ [[package]] name = "tauri-build" -version = "2.5.6" +version = "2.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bbc990d1dbf57a8e1c7fa2327f2a614d8b757805603c1b9ba5c81bade09fd4d" +checksum = "4aa1f9055fc23919a54e4e125052bed16ed04aef0487086e758fe01a67b451c7" dependencies = [ "anyhow", "cargo_toml", @@ -7886,22 +8435,21 @@ dependencies = [ "serde_json", "tauri-utils", "tauri-winres", - "toml 0.9.5", "walkdir", ] [[package]] name = "tauri-codegen" -version = "2.5.5" +version = "2.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4a24476afd977c5d5d169f72425868613d82747916dd29e0a357c84c4bd6d29" +checksum = "e4a0319528a025a38c4078e7dae2c446f4e63620ddb0659a643ede1cb38f90e9" dependencies = [ "base64 0.22.1", "brotli 8.0.2", "ico", "json-patch", "plist", - "png", + "png 0.17.16", "proc-macro2", "quote", "semver", @@ -7910,7 +8458,7 @@ dependencies = [ "sha2 0.10.9", "syn 2.0.117", "tauri-utils", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "url", "uuid", @@ -7919,9 +8467,9 @@ dependencies = [ [[package]] name = "tauri-macros" -version = "2.5.5" +version = "2.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d39b349a98dadaffebb73f0a40dcd1f23c999211e5a2e744403db384d0c33de7" +checksum = "ae6cb4e3896c21d2f6da5b31251d2faea0153bba56ed0e970f918115dbee4924" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -7960,7 +8508,7 @@ dependencies = [ "serde_json", "tauri", "tauri-plugin", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -7979,7 +8527,7 @@ dependencies = [ "serde_json", "tauri", "tauri-plugin", - "thiserror 2.0.12", + "thiserror 2.0.18", "url", "windows 0.61.3", "zbus", @@ -8020,7 +8568,7 @@ dependencies = [ "tauri", "tauri-plugin", "tempfile", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "url", @@ -8030,23 +8578,23 @@ dependencies = [ [[package]] name = "tauri-runtime" -version = "2.10.1" +version = "2.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2826d79a3297ed08cd6ea7f412644ef58e32969504bc4fbd8d7dbeabc4445ea2" +checksum = "48222d7116c8807eaa6fe2f372e023fae125084e61e6eca6d70b7961cdf129ef" dependencies = [ "cookie", "dpi", "gtk", "http 1.3.1", "jni 0.21.1", - "objc2 0.6.0", + "objc2 0.6.4", "objc2-ui-kit", "objc2-web-kit", "raw-window-handle", "serde", "serde_json", "tauri-utils", - "thiserror 2.0.12", + "thiserror 2.0.18", "url", "webkit2gtk", "webview2-com", @@ -8055,15 +8603,15 @@ dependencies = [ [[package]] name = "tauri-runtime-wry" -version = "2.10.1" +version = "2.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e11ea2e6f801d275fdd890d6c9603736012742a1c33b96d0db788c9cdebf7f9e" +checksum = "b83849ee63ecb27a8e8d0fe51915ca215076914aca43f96db1179f0f415f6cd9" dependencies = [ "gtk", "http 1.3.1", "jni 0.21.1", "log", - "objc2 0.6.0", + "objc2 0.6.4", "objc2-app-kit", "once_cell", "percent-encoding", @@ -8081,24 +8629,26 @@ dependencies = [ [[package]] name = "tauri-utils" -version = "2.8.3" +version = "2.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "219a1f983a2af3653f75b5747f76733b0da7ff03069c7a41901a5eb3ace4557d" +checksum = "092379df9a707631978e6c56b1bc2401d387f01e2d4a3c123360d167bbb9aa95" dependencies = [ "anyhow", "brotli 8.0.2", "cargo_metadata 0.19.2", "ctor", + "dom_query", "dunce", "glob", - "html5ever", + "html5ever 0.29.1", "http 1.3.1", "infer", "json-patch", "kuchikiki", "log", "memchr", - "phf 0.11.3", + "phf 0.13.1", + "plist", "proc-macro2", "quote", "regex", @@ -8109,7 +8659,7 @@ dependencies = [ "serde_json", "serde_with", "swift-rs", - "thiserror 2.0.12", + "thiserror 2.0.18", "toml 0.9.5", "url", "urlpattern", @@ -8134,7 +8684,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" dependencies = [ "fastrand", - "getrandom 0.3.3", + "getrandom 0.4.2", "once_cell", "rustix 1.1.4", "windows-sys 0.61.2", @@ -8162,7 +8712,7 @@ dependencies = [ "serde_json", "serde_repr", "sha2 0.10.9", - "signature", + "signature 2.2.0", "subtle", "subtle-encoding", "tendermint-proto", @@ -8212,7 +8762,7 @@ dependencies = [ "getrandom 0.2.15", "peg", "pin-project", - "rand 0.8.5", + "rand 0.8.6", "reqwest 0.11.27", "semver", "serde", @@ -8243,6 +8793,16 @@ dependencies = [ "utf-8", ] +[[package]] +name = "tendril" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4790fc369d5a530f4b544b094e31388b9b3a37c0f4652ade4505945f5660d24" +dependencies = [ + "new_debug_unreachable", + "utf-8", +] + [[package]] name = "termcolor" version = "1.4.1" @@ -8263,11 +8823,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.12", + "thiserror-impl 2.0.18", ] [[package]] @@ -8283,9 +8843,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", @@ -8690,24 +9250,24 @@ dependencies = [ [[package]] name = "tray-icon" -version = "0.21.3" +version = "0.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e85aa143ceb072062fc4d6356c1b520a51d636e7bc8e77ec94be3608e5e80c" +checksum = "15edbb0d80583e85ee8df283410038e17314df5cba30da2087a54a85216c0773" dependencies = [ "crossbeam-channel", "dirs 6.0.0", "libappindicator", "muda", - "objc2 0.6.0", + "objc2 0.6.4", "objc2-app-kit", "objc2-core-foundation", "objc2-core-graphics", "objc2-foundation 0.3.0", "once_cell", - "png", + "png 0.18.1", "serde", - "thiserror 2.0.12", - "windows-sys 0.60.2", + "thiserror 2.0.18", + "windows-sys 0.61.2", ] [[package]] @@ -8735,7 +9295,7 @@ version = "12.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "756050066659291d47a554a9f558125db17428b073c5ffce1daf5dcb0f7231d8" dependencies = [ - "thiserror 2.0.12", + "thiserror 2.0.18", "ts-rs-macros", ] @@ -8759,9 +9319,9 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typenum" -version = "1.18.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" [[package]] name = "ucd-trie" @@ -8854,7 +9414,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ - "crypto-common", + "crypto-common 0.1.6", "subtle", ] @@ -9070,9 +9630,9 @@ dependencies = [ [[package]] name = "wasix" -version = "0.12.21" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1fbb4ef9bbca0c1170e0b00dd28abc9e3b68669821600cad1caaed606583c6d" +checksum = "1757e0d1f8456693c7e5c6c629bdb54884e032aa0bb53c155f6a39f94440d332" dependencies = [ "wasi 0.11.0+wasi-snapshot-preview1", ] @@ -9283,6 +9843,18 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "web_atoms" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7cff6eef815df1834fd250e3a2ff436044d82a9f1bc1980ca1dbdf07effc538" +dependencies = [ + "phf 0.13.1", + "phf_codegen 0.13.1", + "string_cache 0.9.0", + "string_cache_codegen 0.6.1", +] + [[package]] name = "webkit2gtk" version = "2.0.2" @@ -9376,7 +9948,7 @@ version = "0.38.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "381336cfffd772377d291702245447a5251a2ffa5bad679c99e61bc48bacbf9c" dependencies = [ - "thiserror 2.0.12", + "thiserror 2.0.18", "windows 0.61.3", "windows-core 0.61.2", ] @@ -9430,7 +10002,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9bec5a31f3f9362f2258fd0e9c9dd61a9ca432e7306cc78c444258f0dce9a9c" dependencies = [ - "objc2 0.6.0", + "objc2 0.6.4", "objc2-app-kit", "objc2-core-foundation", "objc2-foundation 0.3.0", @@ -10108,7 +10680,7 @@ dependencies = [ "os_pipe", "rustix 0.38.44", "tempfile", - "thiserror 2.0.12", + "thiserror 2.0.18", "tree_magic_mini", "wayland-backend", "wayland-client", @@ -10130,27 +10702,26 @@ checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" [[package]] name = "wry" -version = "0.54.2" +version = "0.55.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb26159b420aa77684589a744ae9a9461a95395b848764ad12290a14d960a11a" +checksum = "186f9871daa55fd9c016578b810d149de58367113db7fb72b462d2323ce19514" dependencies = [ "base64 0.22.1", - "block2 0.6.0", + "block2 0.6.2", "cookie", "crossbeam-channel", "dirs 6.0.0", + "dom_query", "dpi", "dunce", "gdkx11", "gtk", - "html5ever", "http 1.3.1", "javascriptcore-rs", "jni 0.21.1", - "kuchikiki", "libc", "ndk", - "objc2 0.6.0", + "objc2 0.6.4", "objc2-app-kit", "objc2-core-foundation", "objc2-foundation 0.3.0", @@ -10162,7 +10733,7 @@ dependencies = [ "sha2 0.10.9", "soup3", "tao-macros", - "thiserror 2.0.12", + "thiserror 2.0.18", "url", "webkit2gtk", "webkit2gtk-sys", @@ -10381,9 +10952,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" dependencies = [ "serde", "zeroize_derive", @@ -10434,6 +11005,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" + [[package]] name = "zstd" version = "0.13.3" diff --git a/nym-wallet/src-tauri/Cargo.toml b/nym-wallet/src-tauri/Cargo.toml index c4a1215ecf..178e6e4ea3 100644 --- a/nym-wallet/src-tauri/Cargo.toml +++ b/nym-wallet/src-tauri/Cargo.toml @@ -40,7 +40,7 @@ serde_json = "1.0" serde_repr = "0.1" strum = { version = "0.27.2", features = ["derive"] } tap = "1" -tauri = { version = "2.10.3", features = ["devtools"] } +tauri = { version = "2.11.1", features = ["devtools"] } #tendermint-rpc = "0.23.0" time = { version = "0.3.30", features = ["local-offset"] } thiserror = "1.0" From 483bb6f47724cf5577b89f2915268be165c2470f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 19 May 2026 16:37:52 +0100 Subject: [PATCH 26/94] build(deps): bump pnpm/action-setup from 4.2.0 to 5.0.0 (#6571) Bumps [pnpm/action-setup](https://github.com/pnpm/action-setup) from 4.2.0 to 5.0.0. - [Release notes](https://github.com/pnpm/action-setup/releases) - [Commits](https://github.com/pnpm/action-setup/compare/v4.2.0...v5.0.0) --- updated-dependencies: - dependency-name: pnpm/action-setup dependency-version: 5.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/cd-docs.yml | 2 +- .github/workflows/ci-docs.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cd-docs.yml b/.github/workflows/cd-docs.yml index bdc3724563..507fe18b70 100644 --- a/.github/workflows/cd-docs.yml +++ b/.github/workflows/cd-docs.yml @@ -21,7 +21,7 @@ jobs: run: sudo apt-get install -y rsync - uses: rlespinasse/github-slug-action@v3.x - name: Setup pnpm - uses: pnpm/action-setup@v4.2.0 + uses: pnpm/action-setup@v5.0.0 with: version: 9 - uses: actions/setup-node@v4 diff --git a/.github/workflows/ci-docs.yml b/.github/workflows/ci-docs.yml index 07660f5578..dd4a2ff1f7 100644 --- a/.github/workflows/ci-docs.yml +++ b/.github/workflows/ci-docs.yml @@ -28,7 +28,7 @@ jobs: run: sudo apt-get install -y rsync - uses: rlespinasse/github-slug-action@v3.x - name: Setup pnpm - uses: pnpm/action-setup@v4.2.0 + uses: pnpm/action-setup@v5.0.0 with: version: 9 - uses: actions/setup-node@v4 From 4a266a73482c31f3f30e77df71ab37cf1e651118 Mon Sep 17 00:00:00 2001 From: Andy Duplain Date: Tue, 19 May 2026 16:43:03 +0100 Subject: [PATCH 27/94] More explicit closing of the database before drop. --- common/bandwidth-controller/src/traits.rs | 10 ++++++++++ common/client-core/src/client/base_client/mod.rs | 10 ++++++++++ 2 files changed, 20 insertions(+) diff --git a/common/bandwidth-controller/src/traits.rs b/common/bandwidth-controller/src/traits.rs index bb958f482b..1ff14027ef 100644 --- a/common/bandwidth-controller/src/traits.rs +++ b/common/bandwidth-controller/src/traits.rs @@ -25,6 +25,8 @@ pub trait BandwidthTicketProvider: Send + Sync { ) -> Result; async fn get_upgrade_mode_token(&self) -> Result, BandwidthControllerError>; + + async fn close(&self) {} } #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] @@ -56,6 +58,10 @@ where .map_err(|_| BandwidthControllerError::MalformedUpgradeModeToken)?; Ok(Some(token)) } + + async fn close(&self) { + self.storage.close().await; + } } #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] @@ -75,4 +81,8 @@ impl BandwidthTicketProvider for Box async fn get_upgrade_mode_token(&self) -> Result, BandwidthControllerError> { (**self).get_upgrade_mode_token().await } + + async fn close(&self) { + (**self).close().await; + } } diff --git a/common/client-core/src/client/base_client/mod.rs b/common/client-core/src/client/base_client/mod.rs index 7b27d7b1b1..253da7d6c6 100644 --- a/common/client-core/src/client/base_client/mod.rs +++ b/common/client-core/src/client/base_client/mod.rs @@ -1023,6 +1023,16 @@ where let encryption_keys = init_res.client_keys.encryption_keypair(); let identity_keys = init_res.client_keys.identity_keypair(); + let credential_store_for_close = credential_store.clone(); + let close_credential_token = shutdown_tracker.clone_shutdown_token(); + shutdown_tracker.try_spawn_named( + async move { + close_credential_token.cancelled().await; + credential_store_for_close.close().await; + }, + "CredentialStorage::close_on_shutdown", + ); + // the components are started in very specific order. Unless you know what you are doing, // do not change that. let bandwidth_controller = self From 26538f5a40abe9d7fbb6d69339e9222d92b22ae9 Mon Sep 17 00:00:00 2001 From: import this <97586125+serinko@users.noreply.github.com> Date: Wed, 20 May 2026 09:17:36 +0200 Subject: [PATCH 28/94] Patch: Linux kernel vulnerability patch (#6773) * add guide component * add mitigate kernel playbook * add to troubleshooting * remove redundant * remove redundant * FIX ISSUES * fix * fix url to raw * update docs and add new playbook * update and simplify docs and ansible * create ntm explanation component and import it * rm mistaken empty file * rm crap * rm crap * rm all crap * try to fix nextra screaming seagul * try to fix nextra screaming seagul * try to fix nextra screaming seagul * UX improvement by logic refactoring * UX improvement by logic refactoring * UX improvement by logic refactoring * UX improvement by logic refactoring * fix header urls * fix command syntax * fix indentation * update auto-stats * resolve review comments * resolve review comments in docs * fix remove kernel book * soften warning * address comments * address comments * update stats --- .../playbooks/mitigate_kernel_CVE.yml | 42 +++ .../remove_kernel_CVE_mitigations.yml | 111 +++++++ .../snippets/ntm-accordion-explanation.mdx | 18 ++ .../troubleshooting-linux-vulnerability.mdx | 292 ++++++++++++++++++ .../api-scraping-outputs/nodes-count.json | 8 +- .../outputs/api-scraping-outputs/time-now.md | 2 +- .../node-api-check-query-help.md | 2 +- .../outputs/command-outputs/nym-api-help.md | 6 +- .../nym-node-cli-install-help.md | 17 +- .../outputs/command-outputs/nym-node-help.md | 6 +- .../command-outputs/nym-node-run-help.md | 217 +++++-------- .../outputs/command-outputs/nymvisor-help.md | 3 +- .../operators/troubleshooting/vps-isp.mdx | 2 + 13 files changed, 572 insertions(+), 154 deletions(-) create mode 100644 ansible/nym-node/playbooks/mitigate_kernel_CVE.yml create mode 100644 ansible/nym-node/playbooks/remove_kernel_CVE_mitigations.yml create mode 100644 documentation/docs/components/operators/snippets/ntm-accordion-explanation.mdx create mode 100644 documentation/docs/components/operators/snippets/troubleshooting-linux-vulnerability.mdx diff --git a/ansible/nym-node/playbooks/mitigate_kernel_CVE.yml b/ansible/nym-node/playbooks/mitigate_kernel_CVE.yml new file mode 100644 index 0000000000..228f538dc6 --- /dev/null +++ b/ansible/nym-node/playbooks/mitigate_kernel_CVE.yml @@ -0,0 +1,42 @@ +# Mitigation playbook for CopyFail (CVE-2026-31431) and DirtyFrag (CVE-2026-43284 / CVE-2026-43500) +# This playbook applies interim module blacklists only +# Kernel patches are not yet available (May 2026) +# Once patched kernels ship, use remove_kernel_CVE_mitigations.yml to reverse everything +# This playbook is idempotent - safe to re-run if mitigations were already applied + +- name: Mitigate Copy Fail + Dirty Frag + hosts: all + become: true + tasks: + - name: Blacklist algif_aead (Copy Fail) + copy: + dest: /etc/modprobe.d/disable-algif_aead.conf + content: "install algif_aead /bin/false\n" + owner: root + group: root + mode: "0644" + + - name: Blacklist esp4, esp6, rxrpc (Dirty Frag) + copy: + dest: /etc/modprobe.d/dirtyfrag.conf + content: | + install esp4 /bin/false + install esp6 /bin/false + install rxrpc /bin/false + owner: root + group: root + mode: "0644" + + - name: Unload all affected modules + modprobe: + name: "{{ item }}" + state: absent + loop: + - algif_aead + - esp4 + - esp6 + - rxrpc + ignore_errors: true + + - name: Drop page cache to clear any contamination + shell: echo 3 > /proc/sys/vm/drop_caches \ No newline at end of file diff --git a/ansible/nym-node/playbooks/remove_kernel_CVE_mitigations.yml b/ansible/nym-node/playbooks/remove_kernel_CVE_mitigations.yml new file mode 100644 index 0000000000..d966d75444 --- /dev/null +++ b/ansible/nym-node/playbooks/remove_kernel_CVE_mitigations.yml @@ -0,0 +1,111 @@ +############################################################################################ +############################################################################################ +############################################################################################ +#### THIS PLAYBOOK IS NOT MEANT TO BE RUN YET, IT IS NOT REFERRED IN ANY DOCUMENTATION! #### +############################################################################################ +############################################################################################ +############################################################################################ +# +# Reversal playbook for mitigate_kernel_CVE.yml (CopyFail CVE-2026-31431 / DirtyFrag CVE-2026-43284 / CVE-2026-43500). +# +# Run this AFTER your distro has shipped the patched kernel. +# This playbook: +# 1. Updates the kernel via apt +# 2. Reboots and waits for reconnect +# 3. Verifies the running kernel is newer than the pre-patch version +# 4. Removes the interim module blacklists +# 5. Re-enables the affected modules live (no second reboot needed) +# +# Debian family only (Debian, Ubuntu). Tested on Debian 11, Debian 12, Ubuntu 20.04, 22.04, 24.04. +# +# For exit-gateway nodes with --wireguard-enabled true: +# After this playbook completes, run the networking restore step on each node via: +# ansible-playbook deploy.yml -t ntm +# See the CVE patch documentation for details. + +- name: Remove CVE mitigations and apply patched kernel + hosts: all + become: true + + tasks: + - name: Verify OS is Debian family + assert: + that: + - ansible_os_family == "Debian" + fail_msg: "This playbook supports Debian-family distros only (Debian, Ubuntu). For other distros, apply the kernel update and mitigation removal manually." + + - name: Update apt cache + apt: + update_cache: true + cache_valid_time: 0 + + - name: Upgrade kernel packages + apt: + upgrade: full + only_upgrade: false + register: apt_upgrade_result + + - name: Record pre-reboot kernel version + command: uname -r + register: kernel_before + changed_when: false + + - name: Reboot to load patched kernel + reboot: + msg: "Rebooting to apply patched kernel (CVE-2026-31431 / CVE-2026-43284 / CVE-2026-43500)" + reboot_timeout: 300 + pre_reboot_delay: 5 + post_reboot_delay: 15 + + - name: Record post-reboot kernel version + command: uname -r + register: kernel_after + changed_when: false + + - name: Show kernel versions before and after reboot + debug: + msg: + - "Kernel before reboot: {{ kernel_before.stdout }}" + - "Kernel after reboot: {{ kernel_after.stdout }}" + + - name: Warn if kernel did not change after reboot + debug: + msg: > + WARNING: kernel version did not change after reboot ({{ kernel_after.stdout }}). + The patched kernel may not have been selected by GRUB, or no kernel update was available. + Do NOT remove the interim mitigations until you have confirmed the running kernel is patched. + Check: apt-cache policy linux-image-amd64 # Debian + Check: apt-cache policy linux-image-generic # Ubuntu + when: kernel_before.stdout == kernel_after.stdout + + - name: Remove algif_aead blacklist + file: + path: /etc/modprobe.d/disable-algif_aead.conf + state: absent + + - name: Remove DirtyFrag blacklist (esp4, esp6, rxrpc) + file: + path: /etc/modprobe.d/dirtyfrag.conf + state: absent + + - name: Re-enable affected modules live + modprobe: + name: "{{ item }}" + state: present + loop: + - esp4 + - esp6 + - rxrpc + - algif_aead + ignore_errors: true + + - name: Confirm nym-node service is still running + systemd: + name: nym-node + state: started + register: nym_node_status + failed_when: false + + - name: Show nym-node status + debug: + msg: "nym-node service state: {{ nym_node_status.state | default('unknown - service may not exist on this node') }}" \ No newline at end of file diff --git a/documentation/docs/components/operators/snippets/ntm-accordion-explanation.mdx b/documentation/docs/components/operators/snippets/ntm-accordion-explanation.mdx new file mode 100644 index 0000000000..ec5c54d173 --- /dev/null +++ b/documentation/docs/components/operators/snippets/ntm-accordion-explanation.mdx @@ -0,0 +1,18 @@ +import { AccordionTemplate } from 'components/accordion-template.tsx'; + + + +[Nym network tunnel manager](https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/nym-node-setup/network-tunnel-manager.sh) (NTM) `complete_networking_configuration` runs four phases: + +1. **Tunnel setup** - deduplicates existing iptables rules, enables IPv4/IPv6 forwarding persistently via `/etc/sysctl.d/99-nym-forwarding.conf`, applies NAT MASQUERADE and FORWARD rules for both `nymtun0` and `nymwg` + +2. **Host firewall** - opens the required INPUT ports for all Nym services: TCP `22, 80, 443, 1789, 1790, 8080, 9000, 9001, 41264` and UDP `4443, 51822, 51264` + +3. **Exit policy** - creates the `NYM-EXIT` iptables chain, applies the full port allowlist, rate-limits SMTPS (TCP/465), applies the Spamhaus blocklist, adds a default REJECT at the end of the chain + +4. **Verification** - runs automated tests against all firewall rules and reports any issues + +All rules are saved to `/etc/iptables/rules.v4` and `/etc/iptables/rules.v6` via `iptables-persistent`, so they survive future reboots. + +The script is idempotent - safe to re-run multiple times. + \ No newline at end of file diff --git a/documentation/docs/components/operators/snippets/troubleshooting-linux-vulnerability.mdx b/documentation/docs/components/operators/snippets/troubleshooting-linux-vulnerability.mdx new file mode 100644 index 0000000000..d4ef71ab1e --- /dev/null +++ b/documentation/docs/components/operators/snippets/troubleshooting-linux-vulnerability.mdx @@ -0,0 +1,292 @@ +import { Callout } from 'nextra/components'; +import { Steps } from 'nextra/components'; +import { Tabs } from 'nextra/components'; +import { MyTab } from 'components/generic-tabs.tsx'; +import { AccordionTemplate } from 'components/accordion-template.tsx'; +import NTMExplanation from 'components/operators/snippets/ntm-accordion-explanation.mdx'; + +## Security Patch: `CopyFail` & `DirtyFrag` + +In spring 2026 two critical Linux kernel vulnerabilities had been disclosed. Both allow any local user or process to gain root access on the machine - no special permissions needed. + + +**What is exposed?** An attacker (or any compromised process) can take full control of the machine: read or exfiltrate everything, modify files, install backdoors, or escape containers onto the host. + + +**Security patch required! Follow these steps to patch the vulnerability as soon as possible!** + +**CVEs covered** + +| CVE | Name | Affected module | +|---|---|---| +| `CVE-2026-31431` | `CopyFail` | `algif_aead` | +| `CVE-2026-43284` | `DirtyFrag` | `esp4`, `esp6` | +| `CVE-2026-43500` | `DirtyFrag` | `rxrpc` | + +
+ Directly on the hosting server, + Using Ansible, + ]} defaultIndex="0"> + + + + +**This guide is written from root perspective, please add `sudo` to your commands if you are non-root user.** + + +###### 1. Check if mitigations are already applied + +Many hosting providers already applied these mitigations automatically via `unattended-upgrades`. Run these checks first: + +```sh +cat /etc/modprobe.d/disable-algif_aead.conf 2>/dev/null && echo "Already mitigated" || echo "Not yet mitigated" +cat /etc/modprobe.d/dirtyfrag.conf 2>/dev/null && echo "Already mitigated" || echo "Not yet mitigated" +``` + +Compare your output to this table: + +| Check | Safe output | Action if not safe | +|---|---|---| +| `disable-algif_aead.conf` | `Already mitigated` | Go to [Step 2](#2-apply-the-interim-mitigation---disable-algif_aead) | +| `dirtyfrag.conf` | `Already mitigated` | Go to [Step 3](#3-apply-the-interim-mitigation---disable-esp4-esp6-and-rxrpc) | + +If both checks are `Already mitigated` - **you are done, no further action needed.** + + +###### 2. Apply the interim mitigation - disable `algif_aead` + +The fastest fix on Debian/Ubuntu is to update the `kmod` package - this is how [providers applied it](https://ubuntu.com/blog/copy-fail-vulnerability-fixes-available) automatically and avoids a reboot: + +```sh +apt update && apt install --only-upgrade kmod +rmmod algif_aead 2>/dev/null || true +``` + +- Alternatively, apply manually: + +```sh +echo "install algif_aead /bin/false" | tee /etc/modprobe.d/disable-algif_aead.conf +rmmod algif_aead 2>/dev/null || true +``` + +- Drop page cache to clear any contamination: + +```sh +echo 3 > /proc/sys/vm/drop_caches +``` + + +No reboot is required unless the module was already in active use by a running process. The `rmmod` command above unloads it live. + + + +**RHEL, AlmaLinux, Rocky, CentOS** only: this module is baked into the kernel on these distros - the command above does nothing. You must wait for a patched kernel from your distro and apply it when available. + + +Continue to [Step 4](#4-restore-gateway-egress-routing--wireguard-functionality). + +###### 3. Apply the interim mitigation - disable `esp4`, `esp6`, and `rxrpc` + +```sh +sh -c "printf 'install esp4 /bin/false\ninstall esp6 /bin/false\ninstall rxrpc /bin/false\n' > /etc/modprobe.d/dirtyfrag.conf" +rmmod esp4 esp6 rxrpc 2>/dev/null || true +``` + +- Drop page cache to clear any contamination: + +```sh +echo 3 > /proc/sys/vm/drop_caches +``` + +Continue to [Step 4](#4-restore-gateway-egress-routing--wireguard-functionality). + +###### 4. Restore Gateway egress routing & WireGuard functionality + + +This step applies only to Gateway nodes. Skip this step for Mixnodes. + + +If your server was rebooted for any reason, all iptables rules including NAT, forwarding rules, and the `NYM-EXIT` chain are dropped. Unless `iptables-persistent` was already configured, these rules are gone. + +- Run the [Nym network tunnel manager](https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/nym-node-setup/network-tunnel-manager.sh) (NTM) to restore and persist everything. NTM will also install `iptables-persistent` if not already present, ensuring rules survive future reboots: + +```sh +curl -L "https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/nym-node-setup/network-tunnel-manager.sh" -o network-tunnel-manager.sh +``` + +- Run NTM (Standard SSH on port 22 (default)): +```sh +chmod +x ./network-tunnel-manager.sh && +./network-tunnel-manager.sh complete_networking_configuration +``` + +- NTM on non-standart SSH port (replace `2222` with your actual port): +```sh +chmod +x ./network-tunnel-manager.sh && +HOST_SSH_PORT=2222 ./network-tunnel-manager.sh complete_networking_configuration +``` + + + +###### 5. Verify egress routing & WireGuard functionality + +There are a few ways to check that your WireGuard is working correctly: + +- Connect to your node in NymVPN as an exit node in the *Fast* mode, if you rebooted it may take up to one hour for the node to be working properly again + +- Verify WireGuard handshakes are resuming inside the node: + +```sh +watch -n 5 'wg show all | grep -E "peer|latest handshake|transfer"' +``` + +Within 60–90 seconds you should see `latest handshake: X seconds ago` timestamps appearing next to active peers and transfer bytes incrementing. Press `Ctrl+C` to exit the watch loop. + + + + +If you are using Ansible you can use this playbook [mitigate_kernel_CVE.yml](https://github.com/nymtech/nym/tree/develop/ansible/nym-node/playbooks/mitigate_kernel_CVE.yml). + + +###### 1. Create new playbook + +- Navigate to your Nym node Ansible directory with all playbooks (`/playbooks`) + +- You can double check that you are in the right place, running `ls` command and checking this output: + + +``` +ansible.cfg bond.yml deploy.yml group_vars inventory system-maintenance.yml upgrade.yml +``` + +- Download the playbook +```sh +curl -o mitigate_kernel_CVE.yml -L https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/ansible/nym-node/playbooks/mitigate_kernel_CVE.yml +``` +- To control, run `ls` again + +``` +ansible.cfg bond.yml deploy.yml group_vars inventory mitigate_kernel_CVE.yml system-maintenance.yml upgrade.yml +``` + + +###### 2. Run playbook `mitigate_kernel_CVE.yml` + +- For safety start only with one node: +```sh +ansible-playbook mitigate_kernel_CVE.yml -l node1 +``` + +- Check if everything worked smooth on the node machine + +- Run on all machines in your inventory +```sh +ansible-playbook mitigate_kernel_CVE.yml +``` + +###### 3. Ensure routing & WireGuard functionality + + +This step applies only to Gateway nodes. Skip this step for Mixnodes. + + +In case your hosting servers rebooted all iptables rules including NAT, forwarding rules, and the `NYM-EXIT` chain, are dropped. Unless `iptables-persistent` was already configured before the reboot, these rules are gone. + +- Run the [Nym network tunnel manager](https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/nym-node-setup/network-tunnel-manager.sh) (NTM) to restore and persist everything, using Ansible playbook `deploy.yml` pointing to the correct role: + +- For safety start only with one node: +```sh +ansible-playbook deploy.yml -t ntm -l node1 +``` + +- Check if everything worked smooth on the node machine + +- Run on all machines in your inventory +```sh +ansible-playbook deploy.yml -t ntm +``` + +###### 4. Verify egress routing & WireGuard functionality + +- Connect to your node in NymVPN as an exit node in the *Fast* mode, it may take up to one hour for the node to be working properly again + +In case something doesn't work fine, please check the manual steps and [troubleshooting steps](#troubleshooting-wireguard-handshake-fails-after-patching) below + + + + +
+ +### Troubleshooting: WireGuard handshake fails after patching + +If after completing all steps above WireGuard peers are still not handshaking and you can't connect to your node via NymVPN, work through this checklist: + + + +###### 1. Confirm blacklists are in place + +```sh +cat /etc/modprobe.d/disable-algif_aead.conf 2>/dev/null && echo "algif_aead: mitigated" || echo "algif_aead: NOT mitigated" +cat /etc/modprobe.d/dirtyfrag.conf 2>/dev/null && echo "dirtyfrag: mitigated" || echo "dirtyfrag: NOT mitigated" +``` + +- Both files must exist - these are what prevent the modules from loading on demand or after reboot + +- If either is missing, return to [Step 2](#2-apply-the-interim-mitigation---disable-algif_aead) or [Step 3](#3-apply-the-interim-mitigation---disable-esp4-esp6-and-rxrpc) and apply the missing mitigation + +###### 2. Check for stale xfrm state + +```sh +ip xfrm policy list && ip xfrm state list +``` + +- If either returns entries, flush them — WireGuard does not use xfrm and stale entries can intercept handshake packets: + +```sh +ip xfrm state flush && ip xfrm policy flush +``` + +###### 3. Confirm the `nymwg` interface is up + +```sh +ip addr show type wireguard +``` +- If absent, restart the `nym-node service`: + +```sh +systemctl restart nym-node +``` + +###### 4. Check iptables forwarding rules are present + +```sh +iptables -L FORWARD -n -v | grep -E 'nymwg|nymtun' +iptables -L NYM-EXIT -n | head -10 +``` + +- If the `NYM-EXIT` chain is missing or `FORWARD` has no entries for `nymwg`, re-run [Step 4](#4-restore-gateway-egress-routing--wireguard-functionality). + +###### 5. Confirm IP forwarding is enabled + +```sh +sysctl net.ipv4.ip_forward net.ipv6.conf.all.forwarding +``` + +- Both should return `= 1`. If not: `sysctl -w net.ipv4.ip_forward=1 && sysctl -w net.ipv6.conf.all.forwarding=1` + +###### 6. Watch for live handshake packets + +- Install tcpdump if missing + +```sh +apt install tcpdump -y # Debian/Ubuntu +dnf install tcpdump -y # RHEL family + +# replace with your actual WG port from: ss -ulnp | grep nym-node +tcpdump -ni any udp port 51264 +``` + +Trigger a connection attempt from a client. If you see packets arriving but WireGuard is not responding, check `journalctl -u nym-node -n 100` for errors from the binary itself. + + \ No newline at end of file diff --git a/documentation/docs/components/outputs/api-scraping-outputs/nodes-count.json b/documentation/docs/components/outputs/api-scraping-outputs/nodes-count.json index cc5266cf38..afc2a063f8 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/nodes-count.json +++ b/documentation/docs/components/outputs/api-scraping-outputs/nodes-count.json @@ -1,6 +1,6 @@ { - "nodes": 743, - "locations": 77, - "mixnodes": 258, - "exit_gateways": 477 + "nodes": 723, + "locations": 76, + "mixnodes": 249, + "exit_gateways": 466 } diff --git a/documentation/docs/components/outputs/api-scraping-outputs/time-now.md b/documentation/docs/components/outputs/api-scraping-outputs/time-now.md index dd38066ac5..5ecc447407 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/time-now.md +++ b/documentation/docs/components/outputs/api-scraping-outputs/time-now.md @@ -1 +1 @@ -Wednesday, May 13th 2026, 10:37:10 UTC +Wednesday, May 20th 2026, 06:27:43 UTC diff --git a/documentation/docs/components/outputs/command-outputs/node-api-check-query-help.md b/documentation/docs/components/outputs/command-outputs/node-api-check-query-help.md index 999f3d4a6f..bfa068ddb0 100644 --- a/documentation/docs/components/outputs/command-outputs/node-api-check-query-help.md +++ b/documentation/docs/components/outputs/command-outputs/node-api-check-query-help.md @@ -11,7 +11,7 @@ options: --no_routing_history Display node stats without routing history --no_verloc_metrics Display node stats without verloc metrics -m, --markdown Display results in markdown format - -o, --output [OUTPUT] + -o [OUTPUT], --output [OUTPUT] Save results to file (in current dir or supply with path without filename) ``` diff --git a/documentation/docs/components/outputs/command-outputs/nym-api-help.md b/documentation/docs/components/outputs/command-outputs/nym-api-help.md index a00d8c810a..da2cedcfe5 100644 --- a/documentation/docs/components/outputs/command-outputs/nym-api-help.md +++ b/documentation/docs/components/outputs/command-outputs/nym-api-help.md @@ -8,10 +8,8 @@ Commands: help Print this message or the help of the given subcommand(s) Options: - -c, --config-env-file Path pointing to an env file that configures the Nym API [env: - NYMAPI_CONFIG_ENV_FILE_ARG=] - --no-banner A no-op flag included for consistency with other binaries (and compatibility with - nymvisor, oops) [env: NYMAPI_NO_BANNER_ARG=] + -c, --config-env-file Path pointing to an env file that configures the Nym API [env: NYMAPI_CONFIG_ENV_FILE_ARG=] + --no-banner A no-op flag included for consistency with other binaries (and compatibility with nymvisor, oops) [env: NYMAPI_NO_BANNER_ARG=] -h, --help Print help -V, --version Print version ``` diff --git a/documentation/docs/components/outputs/command-outputs/nym-node-cli-install-help.md b/documentation/docs/components/outputs/command-outputs/nym-node-cli-install-help.md index d6fb736bed..c4bddbd0d7 100644 --- a/documentation/docs/components/outputs/command-outputs/nym-node-cli-install-help.md +++ b/documentation/docs/components/outputs/command-outputs/nym-node-cli-install-help.md @@ -8,12 +8,15 @@ usage: nym-node-cli install [-h] [-V] [-d BRANCH] [-v] [--public-ip PUBLIC_IP] [--host-ssh-port HOST_SSH_PORT] [--nym-node-binary NYM_NODE_BINARY] - [--uplink-dev UPLINK_DEV] [--env KEY=VALUE] + [--uplink-dev UPLINK_DEV] + [--uplink-dev-v4 UPLINK_DEV_V4] + [--uplink-dev-v6 UPLINK_DEV_V6] [--env KEY=VALUE] options: -h, --help show this help message and exit -V, --version show program's version number and exit - -d, --dev BRANCH Define github branch (default: develop) + -d BRANCH, --dev BRANCH + Define github branch (default: develop) -v, --verbose Show full error tracebacks --mode {mixnode,entry-gateway,exit-gateway} Node mode: 'mixnode', 'entry-gateway', or 'exit- @@ -33,7 +36,13 @@ options: --nym-node-binary NYM_NODE_BINARY URL for nym-node binary (autodetected if omitted) --uplink-dev UPLINK_DEV - Override uplink interface used for NAT/FORWARD (e.g., - 'eth0'; autodetected if omitted) + Backward-compatible override for both IPv4 and IPv6 + uplinks, e.g. 'eth0' + --uplink-dev-v4 UPLINK_DEV_V4 + Override IPv4 uplink interface used for NAT/FORWARD, + e.g. 'eth0' + --uplink-dev-v6 UPLINK_DEV_V6 + Override IPv6 uplink interface used for NAT/FORWARD, + e.g. 'eth1' --env KEY=VALUE (Optional) Extra ENV VARS, e.g. --env CUSTOM_KEY=value ``` diff --git a/documentation/docs/components/outputs/command-outputs/nym-node-help.md b/documentation/docs/components/outputs/command-outputs/nym-node-help.md index 6f47c76202..7eaa0fdaa3 100644 --- a/documentation/docs/components/outputs/command-outputs/nym-node-help.md +++ b/documentation/docs/components/outputs/command-outputs/nym-node-help.md @@ -8,13 +8,11 @@ Commands: migrate Attempt to migrate an existing mixnode or gateway into a nym-node run Start this nym-node sign Use identity key of this node to sign provided message - unsafe-reset-sphinx-keys UNSAFE: reset existing sphinx keys and attempt to generate fresh one for the current network - state + unsafe-reset-sphinx-keys UNSAFE: reset existing sphinx keys and attempt to generate fresh one for the current network state help Print this message or the help of the given subcommand(s) Options: - -c, --config-env-file Path pointing to an env file that configures the nym-node and overrides any - preconfigured values [env: NYMNODE_CONFIG_ENV_FILE_ARG=] + -c, --config-env-file Path pointing to an env file that configures the nym-node and overrides any preconfigured values [env: NYMNODE_CONFIG_ENV_FILE_ARG=] --no-banner Flag used for disabling the printed banner in tty [env: NYMNODE_NO_BANNER=] -h, --help Print help -V, --version Print version diff --git a/documentation/docs/components/outputs/command-outputs/nym-node-run-help.md b/documentation/docs/components/outputs/command-outputs/nym-node-run-help.md index 298c919400..67799f0690 100644 --- a/documentation/docs/components/outputs/command-outputs/nym-node-run-help.md +++ b/documentation/docs/components/outputs/command-outputs/nym-node-run-help.md @@ -4,138 +4,87 @@ Start this nym-node Usage: nym-node run [OPTIONS] Options: - --id - Id of the nym-node to use [env: NYMNODE_ID=] [default: default-nym-node] - --config-file - Path to a configuration file of this node [env: NYMNODE_CONFIG=] - --accept-operator-terms-and-conditions - Explicitly specify whether you agree with the terms and conditions of a nym node operator as defined at - [env: NYMNODE_ACCEPT_OPERATOR_TERMS=] - --deny-init - Forbid a new node from being initialised if configuration file for the provided specification doesn't already - exist [env: NYMNODE_DENY_INIT=] - --init-only - If this is a brand new nym-node, specify whether it should only be initialised without actually running the - subprocesses [env: NYMNODE_INIT_ONLY=] - --local - Flag specifying this node will be running in a local setting [env: NYMNODE_LOCAL=] - --mode [...] - Specifies the current mode(s) of this nym-node [env: NYMNODE_MODE=] [possible values: mixnode, entry-gateway, - exit-gateway, exit-providers-only] - --modes - Specifies the current mode(s) of this nym-node as a single flag [env: NYMNODE_MODES=] [possible values: mixnode, - entry-gateway, exit-gateway, exit-providers-only] - -w, --write-changes - If this node has been initialised before, specify whether to write any new changes to the config file [env: - NYMNODE_WRITE_CONFIG_CHANGES=] - --bonding-information-output - Specify output file for bonding information of this nym-node, i.e. its encoded keys. NOTE: the required bonding - information is still a subject to change and this argument should be treated only as a preview of future features - [env: NYMNODE_BONDING_INFORMATION_OUTPUT=] - -o, --output - Specify the output format of the bonding information (`text` or `json`) [env: NYMNODE_OUTPUT=] [default: text] - [possible values: text, json] - --public-ips - Comma separated list of public ip addresses that will be announced to the nym-api and subsequently to the clients. - In nearly all circumstances, it's going to be identical to the address you're going to use for bonding [env: - NYMNODE_PUBLIC_IPS=] - --hostname - Optional hostname associated with this gateway that will be announced to the nym-api and subsequently to the - clients [env: NYMNODE_HOSTNAME=] - --location - Optional **physical** location of this node's server. Either full country name (e.g. 'Poland'), two-letter alpha2 - (e.g. 'PL'), three-letter alpha3 (e.g. 'POL') or three-digit numeric-3 (e.g. '616') can be provided [env: - NYMNODE_LOCATION=] - --http-bind-address - Socket address this node will use for binding its http API. default: `[::]:8080` [env: NYMNODE_HTTP_BIND_ADDRESS=] - --landing-page-assets-path - Path to assets directory of custom landing page of this node [env: NYMNODE_HTTP_LANDING_ASSETS=] - --http-access-token - An optional bearer token for accessing certain http endpoints. Currently only used for prometheus metrics [env: - NYMNODE_HTTP_ACCESS_TOKEN=] - --expose-system-info - Specify whether basic system information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_SYSTEM_INFO=] - [possible values: true, false] - --expose-system-hardware - Specify whether basic system hardware information should be exposed. default: true [env: - NYMNODE_HTTP_EXPOSE_SYSTEM_HARDWARE=] [possible values: true, false] - --expose-crypto-hardware - Specify whether detailed system crypto hardware information should be exposed. default: true [env: - NYMNODE_HTTP_EXPOSE_CRYPTO_HARDWARE=] [possible values: true, false] - --mixnet-bind-address - Address this node will bind to for listening for mixnet packets default: `[::]:1789` [env: - NYMNODE_MIXNET_BIND_ADDRESS=] - --mixnet-announce-port - If applicable, custom port announced in the self-described API that other clients and nodes will use. Useful when - the node is behind a proxy [env: NYMNODE_MIXNET_ANNOUNCE_PORT=] - --nym-api-urls - Addresses to nym APIs from which the node gets the view of the network [env: NYMNODE_NYM_APIS=] - --nyxd-urls - Addresses to nyxd chain endpoint which the node will use for chain interactions [env: NYMNODE_NYXD=] - --enable-console-logging - Specify whether running statistics of this node should be logged to the console [env: - NYMNODE_ENABLE_CONSOLE_LOGGING=] [possible values: true, false] - --wireguard-enabled - Specifies whether the wireguard service is enabled on this node [env: NYMNODE_WG_ENABLED=] [possible values: true, - false] - --wireguard-bind-address - Socket address this node will use for binding its wireguard interface. default: `[::]:51822` [env: - NYMNODE_WG_BIND_ADDRESS=] - --wireguard-tunnel-announced-port - Tunnel port announced to external clients wishing to connect to the wireguard interface. Useful in the instances - where the node is behind a proxy [env: NYMNODE_WG_ANNOUNCED_PORT=] - --wireguard-private-network-prefix - The prefix denoting the maximum number of the clients that can be connected via Wireguard. The maximum value for - IPv4 is 32 and for IPv6 is 128 [env: NYMNODE_WG_PRIVATE_NETWORK_PREFIX=] - --wireguard-userspace - Use userspace implementation of WireGuard (wireguard-go) instead of kernel module. Useful in containerized - environments without kernel WireGuard support [env: NYMNODE_WG_USERSPACE=] [possible values: true, false] - --verloc-bind-address - Socket address this node will use for binding its verloc API. default: `[::]:1790` [env: - NYMNODE_VERLOC_BIND_ADDRESS=] - --verloc-announce-port - If applicable, custom port announced in the self-described API that other clients and nodes will use. Useful when - the node is behind a proxy [env: NYMNODE_VERLOC_ANNOUNCE_PORT=] - --entry-bind-address - Socket address this node will use for binding its client websocket API. default: `[::]:9000` [env: - NYMNODE_ENTRY_BIND_ADDRESS=] - --announce-ws-port - Custom announced port for listening for websocket client traffic. If unspecified, the value from the - `bind_address` will be used instead [env: NYMNODE_ENTRY_ANNOUNCE_WS_PORT=] - --announce-wss-port - If applicable, announced port for listening for secure websocket client traffic [env: - NYMNODE_ENTRY_ANNOUNCE_WSS_PORT=] - --enforce-zk-nyms - Indicates whether this gateway is accepting only coconut credentials for accessing the mixnet or if it also - accepts non-paying clients [env: NYMNODE_ENFORCE_ZK_NYMS=] [possible values: true, false] - --mnemonic - Custom cosmos wallet mnemonic used for zk-nym redemption. If no value is provided, a fresh mnemonic is going to be - generated [env: NYMNODE_MNEMONIC=] - --upgrade-mode-attestation-url - Endpoint to query to retrieve current upgrade mode attestation. This argument should never be set outside testnets - and local networks [env: NYMNODE_UPGRADE_MODE_ATTESTATION_URL=] - --upgrade-mode-attester-public-key - Expected public key of the entity signing the published attestation. This argument should never be set outside - testnets and local networks [env: NYMNODE_UPGRADE_MODE_ATTESTER_PUBKEY=] - --upstream-exit-policy-url - Specifies the url for an upstream source of the exit policy used by this node [env: NYMNODE_UPSTREAM_EXIT_POLICY=] - --open-proxy - Specifies whether this exit node should run in 'open-proxy' mode and thus would attempt to resolve **ANY** request - it receives [env: NYMNODE_OPEN_PROXY=] [possible values: true, false] - --lp-control-bind-address - Bind address for the TCP LP control traffic. default: `[::]:41264` [env: NYMNODE_LP_CONTROL_BIND_ADDRESS=] - --lp-control-announce-port - Custom announced port for listening for the TCP LP control traffic. If unspecified, the value from the - `lp_control_bind_address` will be used instead [env: NYMNODE_LP_CONTROL_ANNOUNCE_PORT=] - --lp-data-bind-address - Bind address for the UDP LP data traffic. default: `[::]:51264` [env: NYMNODE_LP_DATA_BIND_ADDRESS=] - --lp-data-announce-port - Custom announced port for listening for the UDP LP data traffic. If unspecified, the value from the - `lp_data_bind_address` will be used instead [env: NYMNODE_LP_DATA_ANNOUNCE_PORT=] - --lp-use-mock-ecash - Use mock ecash manager for LP testing. WARNING: Only use this for local testing! Never enable in production. When - enabled, the LP listener will accept any credential without blockchain verification [env: - NYMNODE_LP_USE_MOCK_ECASH=] [possible values: true, false] - -h, --help - Print help + --id Id of the nym-node to use [env: NYMNODE_ID=] [default: default-nym-node] + --config-file Path to a configuration file of this node [env: NYMNODE_CONFIG=] + --accept-operator-terms-and-conditions Explicitly specify whether you agree with the terms and conditions of a nym node operator as defined at + [env: NYMNODE_ACCEPT_OPERATOR_TERMS=] + --deny-init Forbid a new node from being initialised if configuration file for the provided specification doesn't already exist [env: + NYMNODE_DENY_INIT=] + --init-only If this is a brand new nym-node, specify whether it should only be initialised without actually running the subprocesses [env: + NYMNODE_INIT_ONLY=] + --local Flag specifying this node will be running in a local setting [env: NYMNODE_LOCAL=] + --mode [...] Specifies the current mode(s) of this nym-node [env: NYMNODE_MODE=] [possible values: mixnode, entry-gateway, exit-gateway, + exit-providers-only] + --modes Specifies the current mode(s) of this nym-node as a single flag [env: NYMNODE_MODES=] [possible values: mixnode, entry-gateway, + exit-gateway, exit-providers-only] + -w, --write-changes If this node has been initialised before, specify whether to write any new changes to the config file [env: + NYMNODE_WRITE_CONFIG_CHANGES=] + --bonding-information-output Specify output file for bonding information of this nym-node, i.e. its encoded keys. NOTE: the required bonding information is still a + subject to change and this argument should be treated only as a preview of future features [env: NYMNODE_BONDING_INFORMATION_OUTPUT=] + -o, --output Specify the output format of the bonding information (`text` or `json`) [env: NYMNODE_OUTPUT=] [default: text] [possible values: text, + json] + --public-ips Comma separated list of public ip addresses that will be announced to the nym-api and subsequently to the clients. In nearly all + circumstances, it's going to be identical to the address you're going to use for bonding [env: NYMNODE_PUBLIC_IPS=] + --hostname Optional hostname associated with this gateway that will be announced to the nym-api and subsequently to the clients [env: + NYMNODE_HOSTNAME=] + --location Optional **physical** location of this node's server. Either full country name (e.g. 'Poland'), two-letter alpha2 (e.g. 'PL'), + three-letter alpha3 (e.g. 'POL') or three-digit numeric-3 (e.g. '616') can be provided [env: NYMNODE_LOCATION=] + --http-bind-address Socket address this node will use for binding its http API. default: `[::]:8080` [env: NYMNODE_HTTP_BIND_ADDRESS=] + --landing-page-assets-path Path to assets directory of custom landing page of this node [env: NYMNODE_HTTP_LANDING_ASSETS=] + --http-access-token An optional bearer token for accessing certain http endpoints. Currently only used for prometheus metrics [env: + NYMNODE_HTTP_ACCESS_TOKEN=] + --expose-system-info Specify whether basic system information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_SYSTEM_INFO=] [possible values: + true, false] + --expose-system-hardware Specify whether basic system hardware information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_SYSTEM_HARDWARE=] + [possible values: true, false] + --expose-crypto-hardware Specify whether detailed system crypto hardware information should be exposed. default: true [env: + NYMNODE_HTTP_EXPOSE_CRYPTO_HARDWARE=] [possible values: true, false] + --mixnet-bind-address Address this node will bind to for listening for mixnet packets default: `[::]:1789` [env: NYMNODE_MIXNET_BIND_ADDRESS=] + --mixnet-announce-port If applicable, custom port announced in the self-described API that other clients and nodes will use. Useful when the node is behind a + proxy [env: NYMNODE_MIXNET_ANNOUNCE_PORT=] + --nym-api-urls Addresses to nym APIs from which the node gets the view of the network [env: NYMNODE_NYM_APIS=] + --nyxd-urls Addresses to nyxd chain endpoint which the node will use for chain interactions [env: NYMNODE_NYXD=] + --enable-console-logging Specify whether running statistics of this node should be logged to the console [env: NYMNODE_ENABLE_CONSOLE_LOGGING=] [possible + values: true, false] + --wireguard-enabled Specifies whether the wireguard service is enabled on this node [env: NYMNODE_WG_ENABLED=] [possible values: true, false] + --wireguard-bind-address Socket address this node will use for binding its wireguard interface. default: `[::]:51822` [env: NYMNODE_WG_BIND_ADDRESS=] + --wireguard-tunnel-announced-port Tunnel port announced to external clients wishing to connect to the wireguard interface. Useful in the instances where the node is + behind a proxy [env: NYMNODE_WG_ANNOUNCED_PORT=] + --wireguard-private-network-prefix The prefix denoting the maximum number of the clients that can be connected via Wireguard. The maximum value for IPv4 is 32 and for + IPv6 is 128 [env: NYMNODE_WG_PRIVATE_NETWORK_PREFIX=] + --wireguard-userspace Use userspace implementation of WireGuard (wireguard-go) instead of kernel module. Useful in containerized environments without kernel + WireGuard support [env: NYMNODE_WG_USERSPACE=] [possible values: true, false] + --verloc-bind-address Socket address this node will use for binding its verloc API. default: `[::]:1790` [env: NYMNODE_VERLOC_BIND_ADDRESS=] + --verloc-announce-port If applicable, custom port announced in the self-described API that other clients and nodes will use. Useful when the node is behind a + proxy [env: NYMNODE_VERLOC_ANNOUNCE_PORT=] + --entry-bind-address Socket address this node will use for binding its client websocket API. default: `[::]:9000` [env: NYMNODE_ENTRY_BIND_ADDRESS=] + --announce-ws-port Custom announced port for listening for websocket client traffic. If unspecified, the value from the `bind_address` will be used + instead [env: NYMNODE_ENTRY_ANNOUNCE_WS_PORT=] + --announce-wss-port If applicable, announced port for listening for secure websocket client traffic [env: NYMNODE_ENTRY_ANNOUNCE_WSS_PORT=] + --enforce-zk-nyms Indicates whether this gateway is accepting only coconut credentials for accessing the mixnet or if it also accepts non-paying clients + [env: NYMNODE_ENFORCE_ZK_NYMS=] [possible values: true, false] + --mnemonic Custom cosmos wallet mnemonic used for zk-nym redemption. If no value is provided, a fresh mnemonic is going to be generated [env: + NYMNODE_MNEMONIC=] + --upgrade-mode-attestation-url Endpoint to query to retrieve current upgrade mode attestation. This argument should never be set outside testnets and local networks + [env: NYMNODE_UPGRADE_MODE_ATTESTATION_URL=] + --upgrade-mode-attester-public-key Expected public key of the entity signing the published attestation. This argument should never be set outside testnets and local + networks [env: NYMNODE_UPGRADE_MODE_ATTESTER_PUBKEY=] + --upstream-exit-policy-url Specifies the url for an upstream source of the exit policy used by this node [env: NYMNODE_UPSTREAM_EXIT_POLICY=] + --open-proxy Specifies whether this exit node should run in 'open-proxy' mode and thus would attempt to resolve **ANY** request it receives [env: + NYMNODE_OPEN_PROXY=] [possible values: true, false] + --nr-allow-local-ips Allow the network requester to forward traffic to non-globally-routable addresses. Intended for local development, private-network + deployments, and testnet scenarios. Not recommended on production exit gateway unless you know what you're doing [env: + NYMNODE_NR_ALLOW_LOCAL_IPS=] [possible values: true, false] + --ipr-allow-local-ips Allow the IP packet router to forward traffic to non-globally-routable addresses. Intended for local development, private-network + deployments, and testnet scenarios. Not recommended on production exit gateway unless you know what you're doing [env: + NYMNODE_IPR_ALLOW_LOCAL_IPS=] [possible values: true, false] + --lp-control-bind-address Bind address for the TCP LP control traffic. default: `[::]:41264` [env: NYMNODE_LP_CONTROL_BIND_ADDRESS=] + --lp-control-announce-port Custom announced port for listening for the TCP LP control traffic. If unspecified, the value from the `lp_control_bind_address` will + be used instead [env: NYMNODE_LP_CONTROL_ANNOUNCE_PORT=] + --lp-data-bind-address Bind address for the UDP LP data traffic. default: `[::]:51264` [env: NYMNODE_LP_DATA_BIND_ADDRESS=] + --lp-data-announce-port Custom announced port for listening for the UDP LP data traffic. If unspecified, the value from the `lp_data_bind_address` will be + used instead [env: NYMNODE_LP_DATA_ANNOUNCE_PORT=] + --lp-use-mock-ecash Use mock ecash manager for LP testing. WARNING: Only use this for local testing! Never enable in production. When enabled, the LP + listener will accept any credential without blockchain verification [env: NYMNODE_LP_USE_MOCK_ECASH=] [possible values: true, false] + -h, --help Print help ``` diff --git a/documentation/docs/components/outputs/command-outputs/nymvisor-help.md b/documentation/docs/components/outputs/command-outputs/nymvisor-help.md index ce0399ac28..e3c23ff77d 100644 --- a/documentation/docs/components/outputs/command-outputs/nymvisor-help.md +++ b/documentation/docs/components/outputs/command-outputs/nymvisor-help.md @@ -11,8 +11,7 @@ Commands: help Print this message or the help of the given subcommand(s) Options: - -c, --config-env-file Path pointing to an env file that configures the nymvisor and overrides any - preconfigured values + -c, --config-env-file Path pointing to an env file that configures the nymvisor and overrides any preconfigured values -h, --help Print help -V, --version Print version ``` diff --git a/documentation/docs/pages/operators/troubleshooting/vps-isp.mdx b/documentation/docs/pages/operators/troubleshooting/vps-isp.mdx index 2a0ed2cedc..b47dad33f8 100644 --- a/documentation/docs/pages/operators/troubleshooting/vps-isp.mdx +++ b/documentation/docs/pages/operators/troubleshooting/vps-isp.mdx @@ -5,11 +5,13 @@ import { Steps } from 'nextra/components'; import { MyTab } from 'components/generic-tabs.tsx'; import PruneLogsVM from 'components/operators/snippets/prune-logs-vm.mdx'; import PruneLogsVPS from 'components/operators/snippets/prune-logs-vps.mdx'; +import PatchLinuxVulnerability from 'components/operators/snippets/troubleshooting-linux-vulnerability.mdx'; # Troubleshooting VPS Setup + ## System Hygiene From 21c14c0df074b103fad1f66c438a45b475c82209 Mon Sep 17 00:00:00 2001 From: Jack Wampler Date: Wed, 20 May 2026 01:48:07 -0600 Subject: [PATCH 29/94] Re-order default API urls for network details - waterloo (#6799) --- common/network-defaults/src/mainnet.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/common/network-defaults/src/mainnet.rs b/common/network-defaults/src/mainnet.rs index e2c33def93..3c07beefc3 100644 --- a/common/network-defaults/src/mainnet.rs +++ b/common/network-defaults/src/mainnet.rs @@ -43,10 +43,6 @@ pub const NYM_APIS: &[ApiUrlConst] = &[ url: NYM_API, front_hosts: None, }, - ApiUrlConst { - url: "https://nym-frontdoor.vercel.app/api/", - front_hosts: Some(&["vercel.app", "vercel.com"]), - }, ApiUrlConst { url: "https://nym-frontdoor.global.ssl.fastly.net/api/", front_hosts: Some(&["yelp.global.ssl.fastly.net"]), @@ -68,7 +64,7 @@ pub const UPGRADE_MODE_ATTESTER_ED25519_BS58_PUBKEY: &str = pub const NYM_VPN_APIS: &[ApiUrlConst] = &[ ApiUrlConst { url: NYM_VPN_API, - front_hosts: Some(&["vercel.app", "vercel.com"]), + front_hosts: None, }, ApiUrlConst { url: "https://nymvpn-frontdoor.global.ssl.fastly.net/api/", From 8795cbe407fb40c525985d88779bbd4081e6d9ca Mon Sep 17 00:00:00 2001 From: Andy Duplain Date: Wed, 20 May 2026 09:28:38 +0100 Subject: [PATCH 30/94] It's not an error if we cannot close the database files. --- nym-sqlx-pool-guard/src/lib.rs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/nym-sqlx-pool-guard/src/lib.rs b/nym-sqlx-pool-guard/src/lib.rs index a66a0b9167..d1b3808bd9 100644 --- a/nym-sqlx-pool-guard/src/lib.rs +++ b/nym-sqlx-pool-guard/src/lib.rs @@ -88,9 +88,23 @@ impl SqlitePoolGuard { async fn close_pool_inner(&self) -> std::io::Result<()> { self.inner.connection_pool.close().await; - self.wait_for_db_files_close().await.inspect_err(|e| { - tracing::error!("Failed to wait for file to close: {e}"); - }) + if let Err(e) = self.wait_for_db_files_close().await { + if e.kind() == std::io::ErrorKind::TimedOut { + tracing::warn!( + "Timed out waiting for OS file handles for sqlite database to be released; \ + another connection to the same file may still be open. Path = {}", + self.inner.database_path.display() + ); + } else { + tracing::warn!( + "Failed to wait for sqlite database file handles to be released: Path = {}. Error = {}", + self.inner.database_path.display(), + e + ); + } + } + + Ok(()) } /// Returns all database files, including shm and wal files. From bde2b07d0dd0000853a67fdbf20da9fb1622f335 Mon Sep 17 00:00:00 2001 From: import this <97586125+serinko@users.noreply.github.com> Date: Wed, 20 May 2026 10:30:49 +0200 Subject: [PATCH 31/94] NTM: NIP-11 exit policy update (#6807) --- scripts/nym-node-setup/network-tunnel-manager.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/nym-node-setup/network-tunnel-manager.sh b/scripts/nym-node-setup/network-tunnel-manager.sh index 581f9ec0e5..e2bea6e9f1 100644 --- a/scripts/nym-node-setup/network-tunnel-manager.sh +++ b/scripts/nym-node-setup/network-tunnel-manager.sh @@ -871,6 +871,7 @@ apply_port_allowlist() { ["RTSP"]="554" ["UseNet2"]="563" ["SMTPSubmission"]="587" + ["TelegramVoiceVideo"]="596-599" ["LDAPS"]="636" ["SILC"]="706" ["KerberosAdmin"]="749" @@ -888,6 +889,7 @@ apply_port_allowlist() { ["WireGuardPeer"]="51820-51822" ["QTServerAdmin"]="1220" ["PKTKRB"]="1293" + ["TelegramMTProto"]="1400" ["MSSQL"]="1433" ["VLSILicenseManager"]="1500" ["OracleDB"]="1521" @@ -896,6 +898,7 @@ apply_port_allowlist() { ["PPTP"]="1723" ["RTSPAlt"]="1755" ["MSNP"]="1863" + ["Gemini"]="1965" ["NFS"]="2049" ["DiscordVoiceChat2"]="2053" ["CPanel"]="2082-2083" From bad438b5ad43778a8231c2d52ce09391d8d36fd7 Mon Sep 17 00:00:00 2001 From: Andy Duplain Date: Wed, 20 May 2026 12:24:20 +0100 Subject: [PATCH 32/94] Address review comments. --- Cargo.lock | 1 + common/client-core/surb-storage/src/lib.rs | 7 ++++--- nym-sqlx-pool-guard/Cargo.toml | 1 + nym-sqlx-pool-guard/src/lib.rs | 6 +++++- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0eadd13981..dbdc7f892d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8353,6 +8353,7 @@ dependencies = [ "tokio", "tracing", "tracing-subscriber", + "tracing-test", "windows 0.61.3", ] diff --git a/common/client-core/surb-storage/src/lib.rs b/common/client-core/surb-storage/src/lib.rs index f88a746ad2..f79127b422 100644 --- a/common/client-core/surb-storage/src/lib.rs +++ b/common/client-core/surb-storage/src/lib.rs @@ -56,10 +56,11 @@ where info!("PersistentReplyStorage is flushing all reply-related data to underlying storage"); if let Err(err) = self.backend.flush_surb_storage(&mem_state).await { - error!("failed to flush our reply-related data to the persistent storage: {err}") - } else { - info!("Data flush is complete") + error!("failed to flush our reply-related data to the persistent storage: {err}"); + self.backend.stop_storage_session().await.ok(); + return; } + info!("Data flush is complete"); if let Err(err) = self.backend.stop_storage_session().await { error!("failed to properly stop the storage session - {err}. We might not be able to smoothly restore it") diff --git a/nym-sqlx-pool-guard/Cargo.toml b/nym-sqlx-pool-guard/Cargo.toml index 85622863ad..e4b86ad2c5 100644 --- a/nym-sqlx-pool-guard/Cargo.toml +++ b/nym-sqlx-pool-guard/Cargo.toml @@ -42,3 +42,4 @@ windows = { version = "0.61", features = [ [dev-dependencies] tempfile.workspace = true tracing-subscriber.workspace = true +tracing-test.workspace = true diff --git a/nym-sqlx-pool-guard/src/lib.rs b/nym-sqlx-pool-guard/src/lib.rs index d1b3808bd9..8ded2cfb61 100644 --- a/nym-sqlx-pool-guard/src/lib.rs +++ b/nym-sqlx-pool-guard/src/lib.rs @@ -180,6 +180,7 @@ mod tests { ConnectOptions, Executor, sqlite::{SqliteAutoVacuum, SqliteSynchronous}, }; + use tracing_test::traced_test; use super::*; @@ -219,6 +220,7 @@ mod tests { tokio::fs::remove_file(database_path).await.unwrap(); } + #[traced_test] #[tokio::test] async fn test_clone_drop_no_warning() { // Cloning the guard and dropping the clone should not warn because the original is still alive. @@ -238,9 +240,11 @@ mod tests { { let _clone = guard.clone(); assert_eq!(Arc::strong_count(&guard.inner), 2); - // _clone drops here - should NOT warn since guard still holds a reference } assert_eq!(Arc::strong_count(&guard.inner), 1); + assert!(!logs_contain( + "SqlitePoolGuard dropped without explicit close" + )); guard.close().await; tokio::fs::remove_file(database_path).await.unwrap(); From b3e37ce13cc21ec2f0181339b56cac664dfeaff4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 20 May 2026 13:29:33 +0100 Subject: [PATCH 33/94] Bump tar from 0.4.44 to 0.4.46 in /nym-wallet (#6594) Bumps [tar](https://github.com/composefs/tar-rs) from 0.4.44 to 0.4.46. - [Release notes](https://github.com/composefs/tar-rs/releases) - [Commits](https://github.com/composefs/tar-rs/compare/0.4.44...0.4.46) --- updated-dependencies: - dependency-name: tar dependency-version: 0.4.45 dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- nym-wallet/Cargo.lock | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 31ea2e2eae..85c59aac11 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -266,7 +266,7 @@ dependencies = [ "objc2-foundation 0.3.0", "parking_lot", "percent-encoding", - "windows-sys 0.59.0", + "windows-sys 0.52.0", "wl-clipboard-rs", "x11rb", ] @@ -1229,7 +1229,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "117725a109d387c937a1533ce01b450cbde6b88abceea8473c4d7a85853cda3c" dependencies = [ "lazy_static", - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] @@ -2037,7 +2037,7 @@ dependencies = [ "libc", "option-ext", "redox_users 0.5.0", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -2363,7 +2363,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -3924,7 +3924,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9" dependencies = [ "hermit-abi 0.5.0", "libc", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -6731,7 +6731,7 @@ dependencies = [ "once_cell", "socket2 0.5.9", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -7218,7 +7218,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", + "windows-sys 0.52.0", ] [[package]] @@ -7231,7 +7231,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -7332,7 +7332,7 @@ dependencies = [ "security-framework 3.5.1", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -8351,9 +8351,9 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tar" -version = "0.4.44" +version = "0.4.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d863878d212c87a19c1a610eb53bb01fe12951c0501cf5a0d65f724914a667a" +checksum = "3f6221d9a6003c78398e3b239969f352578258df48c8eb051caadae0015bc840" dependencies = [ "filetime", "libc", @@ -8687,7 +8687,7 @@ dependencies = [ "getrandom 0.4.2", "once_cell", "rustix 1.1.4", - "windows-sys 0.61.2", + "windows-sys 0.52.0", ] [[package]] @@ -9987,7 +9987,7 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "windows-sys 0.59.0", + "windows-sys 0.48.0", ] [[package]] From 71d4b5b3ead0eb2706fa4a240a1dc901d94373ca Mon Sep 17 00:00:00 2001 From: Simon Wicky Date: Wed, 20 May 2026 14:32:01 +0200 Subject: [PATCH 34/94] moving lp packets in lp-data crate (#6810) * moving lp packets in lp-data crate * one more bit * fmt * crate description --- Cargo.lock | 817 +++++++++++------- Cargo.toml | 2 + common/nym-lp-data/Cargo.toml | 25 + common/nym-lp-data/src/lib.rs | 4 + .../src/packet/error.rs | 0 .../src/packet/frame.rs | 8 +- .../src/packet/header.rs | 4 +- .../{nym-lp => nym-lp-data}/src/packet/mod.rs | 1 - common/nym-lp/Cargo.toml | 5 +- common/nym-lp/benches/replay_protection.rs | 2 + common/nym-lp/src/codec.rs | 4 +- common/nym-lp/src/error.rs | 4 +- common/nym-lp/src/lib.rs | 7 +- common/nym-lp/src/packet/replay.rs | 33 - common/nym-lp/src/peer_config.rs | 3 +- common/nym-lp/src/psq/mod.rs | 2 +- common/nym-lp/src/replay/mod.rs | 35 + common/nym-lp/src/session.rs | 6 +- common/nym-lp/src/session_integration/mod.rs | 2 +- common/nym-lp/src/session_manager.rs | 4 +- common/nym-lp/src/transport/traits.rs | 2 +- gateway/Cargo.toml | 2 +- .../wireguard/new_peer_registration/lp.rs | 2 +- .../wireguard/new_peer_registration/mod.rs | 2 +- .../new_peer_registration/pending.rs | 2 +- nym-gateway-probe/Cargo.toml | 1 + nym-gateway-probe/src/common/nodes.rs | 2 +- nym-ip-packet-client/Cargo.toml | 2 +- nym-ip-packet-client/src/lp_stream.rs | 4 +- nym-node/Cargo.toml | 1 + nym-node/src/node/lp/control/control_tests.rs | 2 +- .../node/lp/control/ingress/client_handler.rs | 10 +- nym-node/src/node/lp/data/handler.rs | 2 +- nym-node/src/node/lp/error.rs | 5 +- nym-node/src/node/lp/registration.rs | 2 +- nym-node/src/node/lp/state.rs | 2 +- nym-registration-client/Cargo.toml | 1 + .../src/lp_client/client.rs | 6 +- .../src/lp_client/error.rs | 4 +- .../src/lp_client/helpers.rs | 4 +- .../lp_client/nested_session/connection.rs | 2 +- .../src/lp_client/nested_session/mod.rs | 4 +- .../src/lp_client/session_helpers.rs | 4 +- sdk/rust/nym-sdk/Cargo.toml | 2 +- .../src/mixnet/stream/mixnet_stream.rs | 2 +- sdk/rust/nym-sdk/src/mixnet/stream/mod.rs | 2 +- .../nym-sdk/src/mixnet/stream/protocol.rs | 2 +- service-providers/ip-packet-router/Cargo.toml | 2 +- .../src/clients/connected_client_handler.rs | 2 +- .../ip-packet-router/src/mixnet_listener.rs | 6 +- tools/nym-lp-client/Cargo.toml | 1 + tools/nym-lp-client/src/client.rs | 2 +- 52 files changed, 668 insertions(+), 389 deletions(-) create mode 100644 common/nym-lp-data/Cargo.toml create mode 100644 common/nym-lp-data/src/lib.rs rename common/{nym-lp => nym-lp-data}/src/packet/error.rs (100%) rename common/{nym-lp => nym-lp-data}/src/packet/frame.rs (96%) rename common/{nym-lp => nym-lp-data}/src/packet/header.rs (98%) rename common/{nym-lp => nym-lp-data}/src/packet/mod.rs (99%) delete mode 100644 common/nym-lp/src/packet/replay.rs diff --git a/Cargo.lock b/Cargo.lock index f7152bdfdd..5718dab961 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -45,7 +45,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ - "crypto-common", + "crypto-common 0.1.6", "generic-array 0.14.7", ] @@ -56,10 +56,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", - "cipher", + "cipher 0.4.4", "cpufeatures 0.2.17", ] +[[package]] +name = "aes" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66bd29a732b644c0431c6140f370d097879203d79b80c94a6747ba0872adaef8" +dependencies = [ + "cipher 0.5.2", + "cpubits", + "cpufeatures 0.3.0", +] + [[package]] name = "aes-gcm" version = "0.10.3" @@ -67,8 +78,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" dependencies = [ "aead", - "aes", - "cipher", + "aes 0.8.4", + "cipher 0.4.4", "ctr", "ghash", "subtle 2.6.1", @@ -81,14 +92,24 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae0784134ba9375416d469ec31e7c5f9fa94405049cf08c5ce5b4698be673e0d" dependencies = [ "aead", - "aes", - "cipher", + "aes 0.8.4", + "cipher 0.4.4", "ctr", "polyval", "subtle 2.6.1", "zeroize", ] +[[package]] +name = "aes-keywrap" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10b6f24a1f796bc46415a1d0d18dc0a8203ccba088acf5def3291c4f61225522" +dependencies = [ + "aes 0.9.0", + "byteorder", +] + [[package]] name = "ahash" version = "0.8.12" @@ -226,9 +247,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.98" +version = "1.0.102" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" [[package]] name = "arbitrary" @@ -374,7 +395,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" dependencies = [ "num-traits", - "rand 0.8.5", + "rand 0.8.6", "rayon", ] @@ -909,7 +930,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43d193de1f7487df1914d3a568b772458861d33f9c54249612cc2893d6915054" dependencies = [ "bitcoin_hashes", - "rand 0.8.5", + "rand 0.8.6", "rand_core 0.6.4", "serde", "unicode-normalization", @@ -982,13 +1003,13 @@ dependencies = [ [[package]] name = "blake2b_simd" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e903a20b159e944f91ec8499fe1e55651480c541ea0a584f5d967c49ad9d99" +checksum = "b79834656f71332577234b50bfc009996f7449e0c056884e6a02492ded0ca2f3" dependencies = [ "arrayref", "arrayvec", - "constant_time_eq", + "constant_time_eq 0.4.2", ] [[package]] @@ -1001,7 +1022,7 @@ dependencies = [ "arrayvec", "cc", "cfg-if", - "constant_time_eq", + "constant_time_eq 0.3.1", "digest 0.10.7", ] @@ -1023,6 +1044,15 @@ dependencies = [ "generic-array 0.14.7", ] +[[package]] +name = "block-buffer" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdd35008169921d80bc60d3d0ab416eecb028c4cd653352907921d95084790be" +dependencies = [ + "hybrid-array", +] + [[package]] name = "block-padding" version = "0.3.3" @@ -1196,7 +1226,7 @@ dependencies = [ "serde", "serde-untagged", "serde-value", - "thiserror 2.0.12", + "thiserror 2.0.18", "toml 0.8.23", "unicode-xid", "url", @@ -1227,7 +1257,7 @@ dependencies = [ "semver 1.0.27", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -1242,7 +1272,7 @@ dependencies = [ "semver 1.0.27", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -1308,7 +1338,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" dependencies = [ "cfg-if", - "cipher", + "cipher 0.4.4", "cpufeatures 0.2.17", ] @@ -1331,7 +1361,7 @@ checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" dependencies = [ "aead", "chacha20 0.9.1", - "cipher", + "cipher 0.4.4", "poly1305", "zeroize", ] @@ -1384,11 +1414,21 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "crypto-common", - "inout", + "crypto-common 0.1.6", + "inout 0.1.4", "zeroize", ] +[[package]] +name = "cipher" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8cf2a2c93cd704877c0858356ed03480ff301ee950b43f1cbe4573b088bfa6c" +dependencies = [ + "crypto-common 0.2.2", + "inout 0.2.2", +] + [[package]] name = "clap" version = "4.5.60" @@ -1475,8 +1515,8 @@ version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62a9b6d27e553269a76625911aa8cf6afaa8659f1b0c85b410cb5f51a87183d9" dependencies = [ - "rand 0.8.5", - "sha3", + "rand 0.8.6", + "sha3 0.10.8", "zeroize", ] @@ -1490,10 +1530,16 @@ dependencies = [ ] [[package]] -name = "coarsetime" -version = "0.1.36" +name = "cmov" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91849686042de1b41cd81490edc83afbcb0abe5a9b6f2c4114f23ce8cca1bcf4" +checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746" + +[[package]] +name = "coarsetime" +version = "0.1.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e58eb270476aa4fc7843849f8a35063e8743b4dbcdf6dd0f8ea0886980c204c2" dependencies = [ "libc", "wasix", @@ -1631,6 +1677,12 @@ version = "0.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + [[package]] name = "const-str" version = "0.5.7" @@ -1663,6 +1715,12 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" +[[package]] +name = "constant_time_eq" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d52eff69cd5e647efe296129160853a42795992097e8af39800e1060caeea9b" + [[package]] name = "cookie" version = "0.18.1" @@ -1737,7 +1795,7 @@ dependencies = [ "rand_core 0.6.4", "serde", "serde_json", - "signature", + "signature 2.2.0", "subtle-encoding", "tendermint", "tendermint-rpc", @@ -1833,6 +1891,12 @@ dependencies = [ "thiserror 1.0.69", ] +[[package]] +name = "cpubits" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" + [[package]] name = "cpufeatures" version = "0.2.17" @@ -2029,6 +2093,17 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "getrandom 0.4.1", + "hybrid-array", + "rand_core 0.10.1", +] + [[package]] name = "crypto-mac" version = "0.7.0" @@ -2095,7 +2170,16 @@ version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" dependencies = [ - "cipher", + "cipher 0.4.4", +] + +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", ] [[package]] @@ -2181,7 +2265,7 @@ dependencies = [ "schemars 0.8.22", "serde", "sha2 0.10.9", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -2338,7 +2422,7 @@ dependencies = [ "parking_lot", "ring", "socket2 0.6.0", - "thiserror 2.0.12", + "thiserror 2.0.18", "tracing", "uniffi 0.31.0", "untrusted", @@ -2365,7 +2449,7 @@ dependencies = [ "nix 0.30.1", "regex", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", "windows 0.62.2", "wireguard-nt", "x25519-dalek", @@ -2409,7 +2493,7 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "10d60334b3b2e7c9d91ef8150abfb6fa4c1c39ebbcf4a81c2e346aad939fee3e" dependencies = [ - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -2432,11 +2516,21 @@ version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" dependencies = [ - "const-oid", + "const-oid 0.9.6", "pem-rfc7468", "zeroize", ] +[[package]] +name = "der" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71fd89660b2dc699704064e59e9dba0147b903e85319429e131620d022be411b" +dependencies = [ + "const-oid 0.10.2", + "zeroize", +] + [[package]] name = "deranged" version = "0.4.0" @@ -2573,11 +2667,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", - "const-oid", - "crypto-common", + "const-oid 0.9.6", + "crypto-common 0.1.6", "subtle 2.6.1", ] +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.0", + "crypto-common 0.2.2", +] + [[package]] name = "dirs" version = "6.0.0" @@ -2675,13 +2779,13 @@ version = "0.16.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" dependencies = [ - "der", + "der 0.7.10", "digest 0.10.7", "elliptic-curve", "rfc6979", "serdect 0.2.0", - "signature", - "spki", + "signature 2.2.0", + "spki 0.7.3", ] [[package]] @@ -2715,19 +2819,19 @@ version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" dependencies = [ - "pkcs8", + "pkcs8 0.10.2", "serde", - "signature", + "signature 2.2.0", ] [[package]] name = "ed25519-compact" -version = "2.1.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9b3460f44bea8cd47f45a0c70892f1eff856d97cd55358b2f73f663789f6190" +checksum = "f5c0284a5d4b1a2fae017a9fe55fd7d01699711f1b572493f16593e173ea2801" dependencies = [ "ct-codecs", - "getrandom 0.2.16", + "getrandom 0.4.1", ] [[package]] @@ -2796,7 +2900,7 @@ dependencies = [ "group", "hkdf", "pem-rfc7468", - "pkcs8", + "pkcs8 0.10.2", "rand_core 0.6.4", "sec1", "serdect 0.2.0", @@ -2920,7 +3024,7 @@ dependencies = [ "nym-wasm-storage", "nym-wasm-utils", "serde-wasm-bindgen 0.6.5", - "thiserror 2.0.12", + "thiserror 2.0.18", "wasm-bindgen", "wasm-bindgen-futures", "zeroize", @@ -3277,11 +3381,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "139ef39800118c7683f2fd3c98c1b23c09ae076556b435f8e9064ae108aaeeec" dependencies = [ "cfg-if", + "js-sys", "libc", "r-efi", "rand_core 0.10.1", "wasip2", "wasip3", + "wasm-bindgen", ] [[package]] @@ -3659,7 +3765,7 @@ dependencies = [ "jni 0.22.4", "rand 0.10.1", "rustls 0.23.37", - "thiserror 2.0.12", + "thiserror 2.0.18", "tinyvec", "tokio", "tokio-rustls 0.26.2", @@ -3682,7 +3788,7 @@ dependencies = [ "prefix-trie", "rand 0.10.1", "ring", - "thiserror 2.0.12", + "thiserror 2.0.18", "tinyvec", "tracing", "url", @@ -3710,7 +3816,7 @@ dependencies = [ "rustls 0.23.37", "smallvec", "system-configuration 0.7.0", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tokio-rustls 0.26.2", "tracing", @@ -3749,24 +3855,24 @@ dependencies = [ [[package]] name = "hmac-sha1-compact" -version = "1.1.5" +version = "1.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18492c9f6f9a560e0d346369b665ad2bdbc89fa9bceca75796584e79042694c3" +checksum = "b0b3ba31f6dc772cc8221ce81dbbbd64fa1e668255a6737d95eeace59b5a8823" [[package]] name = "hmac-sha256" -version = "1.1.12" +version = "1.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad6880c8d4a9ebf39c6e8b77007ce223f646a4d21ce29d99f70cb16420545425" +checksum = "ec9d92d097f4749b64e8cc33d924d9f40a2d4eb91402b458014b781f5733d60f" dependencies = [ "digest 0.10.7", ] [[package]] name = "hmac-sha512" -version = "1.1.7" +version = "1.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89e8d20b3799fa526152a5301a771eaaad80857f83e01b23216ceaafb2d9280" +checksum = "019ece39bbefc17f13f677a690328cb978dbf6790e141a3c24e66372cb38588b" dependencies = [ "digest 0.10.7", ] @@ -3897,6 +4003,16 @@ dependencies = [ "serde", ] +[[package]] +name = "hybrid-array" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9155a582abd142abc056962c29e3ce5ff2ad5469f4246b537ed42c5deba857da" +dependencies = [ + "ctutils", + "typenum", +] + [[package]] name = "hyper" version = "0.14.32" @@ -4248,7 +4364,7 @@ dependencies = [ "js-sys", "sealed", "smallvec", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "wasm-bindgen", "wasm-bindgen-futures", @@ -4344,6 +4460,15 @@ dependencies = [ "generic-array 0.14.7", ] +[[package]] +name = "inout" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4250ce6452e92010fdf7268ccc5d14faa80bb12fc741938534c58f16804e03c7" +dependencies = [ + "hybrid-array", +] + [[package]] name = "inquire" version = "0.6.2" @@ -4558,7 +4683,7 @@ dependencies = [ "jni-sys 0.4.1", "log", "simd_cesu8", - "thiserror 2.0.12", + "thiserror 2.0.18", "walkdir", "windows-link 0.2.1", ] @@ -4623,9 +4748,9 @@ dependencies = [ [[package]] name = "jwt-simple" -version = "0.12.12" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "731011e9647a71ff4f8474176ff6ce6e0d2de87a0173f15613af3a84c3e3401a" +checksum = "f45048cd18221c81d27dd4621d51df25b33f11b68655d79f67a9f9d3eb48fecc" dependencies = [ "anyhow", "binstring", @@ -4639,11 +4764,11 @@ dependencies = [ "k256", "p256", "p384", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde_json", "superboring", - "thiserror 2.0.12", + "thiserror 2.0.18", "zeroize", ] @@ -4658,7 +4783,7 @@ dependencies = [ "elliptic-curve", "once_cell", "sha2 0.10.9", - "signature", + "signature 2.2.0", ] [[package]] @@ -4670,6 +4795,16 @@ dependencies = [ "cpufeatures 0.2.17", ] +[[package]] +name = "keccak" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e24a010dd405bd7ed803e5253182815b41bf2e6a80cc3bfc066658e03a198aa" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", +] + [[package]] name = "keystream" version = "1.0.0" @@ -4964,7 +5099,7 @@ dependencies = [ "libcrux-ml-kem", "libcrux-sha2", "libcrux-traits", - "rand 0.8.5", + "rand 0.8.6", "rand 0.9.2", "tls_codec", ] @@ -5110,7 +5245,7 @@ dependencies = [ "nym-performance-contract-common", "nym-validator-client", "nym-vesting-contract-common", - "rand 0.8.5", + "rand 0.8.6", "reqwest 0.13.1", "serde", "serde_json", @@ -5373,10 +5508,10 @@ dependencies = [ "nym-validator-client", "nym-wasm-client-core", "nym-wasm-utils", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde-wasm-bindgen 0.6.5", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tsify", "url", @@ -5399,12 +5534,39 @@ dependencies = [ "tracing", ] +[[package]] +name = "ml-dsa" +version = "0.1.0-rc.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "163f15320f3fba11760c373af52d7f69d638482c2c350d877fb06513b1c3137c" +dependencies = [ + "const-oid 0.10.2", + "crypto-common 0.2.2", + "ctutils", + "hybrid-array", + "module-lattice", + "pkcs8 0.11.0", + "sha3 0.11.0", + "signature 3.0.0", +] + [[package]] name = "mock_instant" version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dce6dd36094cac388f119d2e9dc82dc730ef91c32a6222170d630e5414b956e6" +[[package]] +name = "module-lattice" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c61b87c9683ab7cb1c6871d261ad5479b6b10ceb52c4352aaca3b5d35a8febe" +dependencies = [ + "ctutils", + "hybrid-array", + "num-traits", +] + [[package]] name = "moka" version = "0.12.10" @@ -5488,7 +5650,7 @@ checksum = "3176f18d11a1ae46053e59ec89d46ba318ae1343615bd3f8c908bfc84edae35c" dependencies = [ "byteorder", "pastey 0.1.1", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -5642,17 +5804,16 @@ dependencies = [ [[package]] name = "num-bigint-dig" -version = "0.8.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" dependencies = [ - "byteorder", "lazy_static", "libm", "num-integer", "num-iter", "num-traits", - "rand 0.8.5", + "rand 0.8.6", "smallvec", "zeroize", ] @@ -5781,7 +5942,7 @@ dependencies = [ "nym-types", "nym-validator-client", "pin-project", - "rand 0.8.5", + "rand 0.8.6", "rand_chacha 0.3.1", "reqwest 0.13.1", "schemars 0.8.22", @@ -5793,7 +5954,7 @@ dependencies = [ "tempfile", "tendermint", "test-with", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tokio-stream", @@ -5843,7 +6004,7 @@ dependencies = [ "strum_macros 0.28.0", "tendermint", "tendermint-rpc", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tracing", "ts-rs", @@ -5876,7 +6037,7 @@ dependencies = [ "nym-validator-client", "nym-wireguard-types", "semver 1.0.27", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tokio-util", "tracing", @@ -5896,12 +6057,12 @@ dependencies = [ "nym-sphinx", "nym-test-utils", "nym-wireguard-types", - "rand 0.8.5", + "rand 0.8.6", "semver 1.0.27", "serde", "sha2 0.10.9", "strum_macros 0.28.0", - "thiserror 2.0.12", + "thiserror 2.0.18", "tracing", "x25519-dalek", ] @@ -5919,8 +6080,8 @@ dependencies = [ "nym-ecash-time", "nym-task", "nym-validator-client", - "rand 0.8.5", - "thiserror 2.0.12", + "rand 0.8.6", + "thiserror 2.0.18", ] [[package]] @@ -6040,12 +6201,12 @@ dependencies = [ "nym-types", "nym-validator-client", "nym-vesting-contract-common", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde_json", "tap", "tempfile", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "toml 0.8.23", @@ -6078,11 +6239,11 @@ dependencies = [ "nym-task", "nym-topology", "nym-validator-client", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde_json", "tap", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tokio-tungstenite", @@ -6130,14 +6291,14 @@ dependencies = [ "nym-topology", "nym-validator-client", "nym-wasm-utils", - "rand 0.8.5", + "rand 0.8.6", "rand_chacha 0.3.1", "serde", "serde_json", "sha2 0.10.9", "si-scale", "tempfile", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tokio-stream", @@ -6163,7 +6324,7 @@ dependencies = [ "nym-sphinx-params", "nym-statistics-common", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", "url", ] @@ -6178,7 +6339,7 @@ dependencies = [ "nym-gateway-requests", "serde", "sqlx", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tracing", @@ -6198,7 +6359,7 @@ dependencies = [ "nym-sqlx-pool-guard", "nym-task", "sqlx", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tracing", @@ -6219,11 +6380,11 @@ dependencies = [ "nym-wasm-client-core", "nym-wasm-utils", "once_cell", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde-wasm-bindgen 0.6.5", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio_with_wasm", "tsify", "wasm-bindgen", @@ -6277,12 +6438,12 @@ dependencies = [ "nym-bls12_381-fork", "nym-network-defaults", "nym-pemstore", - "rand 0.8.5", + "rand 0.8.6", "rayon", "serde", "sha2 0.10.9", "subtle 2.6.1", - "thiserror 2.0.12", + "thiserror 2.0.18", "zeroize", ] @@ -6295,7 +6456,7 @@ dependencies = [ "log", "nym-network-defaults", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", "toml 0.8.23", "url", ] @@ -6312,7 +6473,7 @@ dependencies = [ "nym-ip-packet-requests", "nym-sdk", "pnet_packet", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tokio-util", "tracing", @@ -6330,7 +6491,7 @@ dependencies = [ "schemars 0.8.22", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.18", "utoipa", "vergen 8.3.1", ] @@ -6344,7 +6505,7 @@ dependencies = [ "cw-multi-test", "cw-storage-plus", "nym-contracts-common", - "rand 0.8.5", + "rand 0.8.6", "rand_chacha 0.3.1", "serde", ] @@ -6391,7 +6552,7 @@ dependencies = [ "nym-pemstore", "nym-upgrade-mode-check", "nym-validator-client", - "rand 0.8.5", + "rand 0.8.6", "reqwest 0.13.1", "serde", "serde_json", @@ -6399,7 +6560,7 @@ dependencies = [ "strum 0.28.0", "strum_macros 0.28.0", "tempfile", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tokio-util", @@ -6432,7 +6593,7 @@ dependencies = [ "nym-ecash-signer-check", "nym-network-defaults", "nym-validator-client", - "rand 0.8.5", + "rand 0.8.6", "reqwest 0.13.1", "serde", "serde_json", @@ -6440,7 +6601,7 @@ dependencies = [ "strum 0.28.0", "strum_macros 0.28.0", "tempfile", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tokio-util", @@ -6491,7 +6652,7 @@ dependencies = [ "nym-test-utils", "serde", "sqlx", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "zeroize", @@ -6510,7 +6671,7 @@ dependencies = [ "nym-credentials-interface", "nym-ecash-time", "nym-validator-client", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", ] @@ -6537,7 +6698,7 @@ dependencies = [ "nym-upgrade-mode-check", "nym-validator-client", "si-scale", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tracing", @@ -6560,9 +6721,9 @@ dependencies = [ "nym-network-defaults", "nym-serde-helpers", "nym-validator-client", - "rand 0.8.5", + "rand 0.8.6", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "zeroize", ] @@ -6576,11 +6737,11 @@ dependencies = [ "nym-ecash-time", "nym-network-defaults", "nym-upgrade-mode-check", - "rand 0.8.5", + "rand 0.8.6", "serde", "strum 0.28.0", "strum_macros 0.28.0", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "utoipa", ] @@ -6590,13 +6751,13 @@ name = "nym-crypto" version = "1.21.0" dependencies = [ "aead", - "aes", + "aes 0.8.4", "aes-gcm-siv", "anyhow", "base64 0.22.1", "blake3", "bs58", - "cipher", + "cipher 0.4.4", "ctr", "curve25519-dalek", "digest 0.10.7", @@ -6610,7 +6771,7 @@ dependencies = [ "nym-pemstore", "nym-sphinx-types", "nym-test-utils", - "rand 0.8.5", + "rand 0.8.6", "rand 0.9.2", "rand_chacha 0.3.1", "serde", @@ -6618,7 +6779,7 @@ dependencies = [ "serde_json", "sha2 0.10.9", "subtle-encoding", - "thiserror 2.0.12", + "thiserror 2.0.18", "x25519-dalek", "zeroize", ] @@ -6647,7 +6808,7 @@ dependencies = [ "serde", "serde_json", "sqlx", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tokio-util", @@ -6672,13 +6833,13 @@ dependencies = [ "nym-bls12_381-fork", "nym-contracts-common", "nym-pemstore", - "rand 0.8.5", + "rand 0.8.6", "rand_chacha 0.3.1", "rand_core 0.6.4", "serde", "serde_derive", "sha2 0.10.9", - "thiserror 2.0.12", + "thiserror 2.0.18", "zeroize", ] @@ -6693,7 +6854,7 @@ dependencies = [ "cw-utils", "cw2", "nym-multisig-contract-common", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -6707,7 +6868,7 @@ dependencies = [ "nym-validator-client", "semver 1.0.27", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tracing", "url", @@ -6721,7 +6882,7 @@ dependencies = [ "nym-crypto", "semver 1.0.27", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tracing", "url", @@ -6743,7 +6904,7 @@ dependencies = [ "reqwest 0.13.1", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.18", "tracing", "utoipa", ] @@ -6793,6 +6954,7 @@ dependencies = [ "nym-id", "nym-ip-packet-router", "nym-lp", + "nym-lp-data", "nym-metrics", "nym-mixnet-client", "nym-network-defaults", @@ -6811,9 +6973,9 @@ dependencies = [ "nym-wireguard", "nym-wireguard-private-metadata-server", "nym-wireguard-types", - "rand 0.8.5", + "rand 0.8.6", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tokio-stream", @@ -6844,10 +7006,10 @@ dependencies = [ "nym-task", "nym-validator-client", "nym-wasm-utils", - "rand 0.8.5", + "rand 0.8.6", "serde", "si-scale", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tokio-stream", @@ -6890,6 +7052,7 @@ dependencies = [ "nym-ip-packet-requests", "nym-kkt-ciphersuite", "nym-lp", + "nym-lp-data", "nym-network-defaults", "nym-node-requests", "nym-registration-client", @@ -6898,7 +7061,7 @@ dependencies = [ "nym-topology", "nym-validator-client", "pnet_packet", - "rand 0.8.5", + "rand 0.8.6", "rand 0.9.2", "reqwest 0.13.1", "semver 1.0.27", @@ -6932,12 +7095,12 @@ dependencies = [ "nym-statistics-common", "nym-task", "nym-test-utils", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde_json", "strum 0.28.0", "subtle 2.6.1", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tracing", @@ -6956,7 +7119,7 @@ dependencies = [ "nym-statistics-common", "sqlx", "strum 0.28.0", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tracing", @@ -6975,7 +7138,7 @@ dependencies = [ "nym-gateway-requests", "nym-sphinx", "sqlx", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tracing", @@ -6992,7 +7155,7 @@ dependencies = [ "nym-ffi-shared", "nym-sdk", "nym-sphinx-anonymous-replies", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "uniffi 0.29.3", "uniffi_build 0.29.3", @@ -7035,7 +7198,7 @@ dependencies = [ "serde_json", "serde_plain", "serde_yaml", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tracing", "tracing-subscriber", @@ -7084,7 +7247,7 @@ version = "1.21.0" dependencies = [ "nym-credential-storage", "nym-credentials", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tracing", "zeroize", @@ -7109,8 +7272,8 @@ name = "nym-inclusion-probability" version = "1.21.0" dependencies = [ "log", - "rand 0.8.5", - "thiserror 2.0.12", + "rand 0.8.6", + "thiserror 2.0.18", ] [[package]] @@ -7121,9 +7284,9 @@ dependencies = [ "bytes", "futures", "nym-ip-packet-requests", - "nym-lp", + "nym-lp-data", "nym-sdk", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tokio-util", "tracing", @@ -7140,10 +7303,10 @@ dependencies = [ "nym-service-provider-requests-common", "nym-sphinx", "pnet_packet", - "rand 0.8.5", + "rand 0.8.6", "semver 1.0.27", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tokio-util", @@ -7170,7 +7333,7 @@ dependencies = [ "nym-exit-policy", "nym-id", "nym-ip-packet-requests", - "nym-lp", + "nym-lp-data", "nym-network-defaults", "nym-network-requester", "nym-sdk", @@ -7182,11 +7345,11 @@ dependencies = [ "nym-types", "nym-wireguard", "nym-wireguard-types", - "rand 0.8.5", + "rand 0.8.6", "reqwest 0.13.1", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tokio-tun", @@ -7202,7 +7365,7 @@ dependencies = [ "bytes", "env_logger", "log", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio-util", ] @@ -7225,7 +7388,7 @@ dependencies = [ "rand 0.9.2", "rand_chacha 0.9.0", "strum 0.28.0", - "thiserror 2.0.12", + "thiserror 2.0.18", "zeroize", ] @@ -7239,7 +7402,7 @@ dependencies = [ "semver 1.0.27", "strum 0.28.0", "strum_macros 0.28.0", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -7248,7 +7411,7 @@ version = "1.21.0" dependencies = [ "num_enum", "nym-kkt-ciphersuite", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -7259,7 +7422,7 @@ dependencies = [ "k256", "ledger-transport", "ledger-transport-hid", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -7271,14 +7434,14 @@ dependencies = [ "bytes", "criterion", "libcrux-psq", - "num_enum", "nym-common", "nym-crypto", "nym-kkt", "nym-kkt-ciphersuite", + "nym-lp-data", "nym-test-utils", "rand 0.9.2", - "thiserror 2.0.12", + "thiserror 2.0.18", "tls_codec", "tokio", "tracing", @@ -7299,6 +7462,7 @@ dependencies = [ "nym-kcp", "nym-kkt-ciphersuite", "nym-lp", + "nym-lp-data", "nym-registration-client", "nym-sphinx", "nym-sphinx-addressing", @@ -7308,7 +7472,7 @@ dependencies = [ "nym-sphinx-types", "nym-topology", "nym-validator-client", - "rand 0.8.5", + "rand 0.8.6", "rand 0.9.2", "rand_chacha 0.3.1", "serde", @@ -7321,6 +7485,17 @@ dependencies = [ "url", ] +[[package]] +name = "nym-lp-data" +version = "1.21.0" +dependencies = [ + "bytes", + "num_enum", + "nym-common", + "thiserror 2.0.18", + "tracing", +] + [[package]] name = "nym-metrics" version = "1.21.0" @@ -7341,7 +7516,7 @@ dependencies = [ "nym-noise", "nym-sphinx", "nym-task", - "rand 0.8.5", + "rand 0.8.6", "tokio", "tokio-stream", "tokio-util", @@ -7365,7 +7540,7 @@ dependencies = [ "semver 1.0.27", "serde", "serde_repr", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "ts-rs", "utoipa", @@ -7389,9 +7564,9 @@ dependencies = [ "nym-sphinx-params", "nym-sphinx-types", "nym-task", - "rand 0.8.5", + "rand 0.8.6", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tokio-util", @@ -7410,7 +7585,7 @@ dependencies = [ "cw4", "schemars 0.8.22", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -7452,7 +7627,7 @@ dependencies = [ "nym-types", "nym-validator-client", "petgraph", - "rand 0.8.5", + "rand 0.8.6", "rand_chacha 0.3.1", "reqwest 0.13.1", "serde", @@ -7498,7 +7673,7 @@ dependencies = [ "nym-task", "nym-types", "publicsuffix", - "rand 0.8.5", + "rand 0.8.6", "regex", "reqwest 0.13.1", "serde", @@ -7506,7 +7681,7 @@ dependencies = [ "sqlx", "tap", "tempfile", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tokio-tungstenite", @@ -7559,6 +7734,7 @@ dependencies = [ "nym-ip-packet-router", "nym-kkt", "nym-lp", + "nym-lp-data", "nym-metrics", "nym-mixnet-client", "nym-network-requester", @@ -7587,13 +7763,13 @@ dependencies = [ "nym-wireguard-types", "opentelemetry", "opentelemetry_sdk", - "rand 0.8.5", + "rand 0.8.6", "rand 0.9.2", "serde", "serde_json", "sha2 0.10.9", "sysinfo", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tokio-stream", @@ -7621,7 +7797,7 @@ dependencies = [ "nym-mixnet-contract-common", "schemars 0.8.22", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -7659,7 +7835,7 @@ dependencies = [ "serde_json", "strum 0.28.0", "strum_macros 0.28.0", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "url", @@ -7678,7 +7854,7 @@ dependencies = [ "nym-gateway-probe", "nym-node-status-client", "nym-sdk", - "rand 0.8.5", + "rand 0.8.6", "regex", "serde_json", "tempfile", @@ -7723,7 +7899,7 @@ dependencies = [ "nym-statistics-common", "nym-task", "nym-validator-client", - "rand 0.8.5", + "rand 0.8.6", "rand_chacha 0.3.1", "regex", "reqwest 0.13.1", @@ -7734,7 +7910,7 @@ dependencies = [ "sqlx", "strum 0.28.0", "strum_macros 0.28.0", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tokio-stream", @@ -7777,11 +7953,11 @@ dependencies = [ "nym-task", "nym-topology", "nym-wasm-utils", - "rand 0.8.5", + "rand 0.8.6", "rand_chacha 0.3.1", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", ] @@ -7794,10 +7970,10 @@ dependencies = [ "nym-node-tester-utils", "nym-wasm-client-core", "nym-wasm-utils", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde-wasm-bindgen 0.6.5", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tsify", "wasm-bindgen", @@ -7822,7 +7998,7 @@ dependencies = [ "snow", "strum 0.28.0", "strum_macros 0.28.0", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tokio-util", "tracing", @@ -7869,7 +8045,7 @@ name = "nym-ordered-buffer" version = "1.21.0" dependencies = [ "log", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -7881,7 +8057,7 @@ dependencies = [ "chacha20poly1305", "fastrand", "sphinx-packet", - "thiserror 2.0.12", + "thiserror 2.0.18", "x25519-dalek", "zeroize", ] @@ -7905,7 +8081,7 @@ dependencies = [ "nym-contracts-common", "schemars 0.8.22", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -7917,7 +8093,7 @@ dependencies = [ "cw-controllers", "schemars 0.8.22", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", ] @@ -7936,13 +8112,14 @@ dependencies = [ "nym-ip-packet-client", "nym-kkt", "nym-lp", + "nym-lp-data", "nym-registration-common", "nym-sdk", "nym-test-utils", "nym-validator-client", "nym-wireguard-types", "rand 0.9.2", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tokio-util", "tracing", @@ -7996,7 +8173,7 @@ dependencies = [ "nym-gateway-requests", "nym-http-api-client", "nym-ip-packet-requests", - "nym-lp", + "nym-lp-data", "nym-network-defaults", "nym-ordered-buffer", "nym-service-providers-common", @@ -8010,13 +8187,13 @@ dependencies = [ "nym-validator-client", "parking_lot", "pnet_packet", - "rand 0.8.5", + "rand 0.8.6", "reqwest 0.13.1", "semver 1.0.27", "serde", "tap", "tempfile", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tokio-stream", @@ -8046,7 +8223,7 @@ version = "1.21.0" dependencies = [ "bincode", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -8059,7 +8236,7 @@ dependencies = [ "nym-sphinx-anonymous-replies", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -8104,11 +8281,11 @@ dependencies = [ "nym-sphinx", "nym-topology", "nym-validator-client", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde_json", "tap", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "url", @@ -8137,12 +8314,12 @@ dependencies = [ "nym-task", "nym-validator-client", "pin-project", - "rand 0.8.5", + "rand 0.8.6", "reqwest 0.13.1", "schemars 0.8.22", "serde", "tap", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "url", ] @@ -8174,7 +8351,7 @@ dependencies = [ "serde", "serde_json", "tap", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -8195,10 +8372,10 @@ dependencies = [ "nym-sphinx-routing", "nym-sphinx-types", "nym-topology", - "rand 0.8.5", + "rand 0.8.6", "rand_chacha 0.3.1", "rand_distr", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tracing", ] @@ -8215,9 +8392,9 @@ dependencies = [ "nym-sphinx-routing", "nym-sphinx-types", "nym-topology", - "rand 0.8.5", + "rand 0.8.6", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", "zeroize", ] @@ -8228,10 +8405,10 @@ dependencies = [ "bincode", "nym-crypto", "nym-sphinx-types", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -8245,9 +8422,9 @@ dependencies = [ "nym-sphinx-routing", "nym-sphinx-types", "nym-topology", - "rand 0.8.5", + "rand 0.8.6", "rand_chacha 0.3.1", - "thiserror 2.0.12", + "thiserror 2.0.18", "tracing", "wasm-bindgen", ] @@ -8263,9 +8440,9 @@ dependencies = [ "nym-sphinx-addressing", "nym-sphinx-params", "nym-sphinx-types", - "rand 0.8.5", + "rand 0.8.6", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", "utoipa", "wasmtimer", ] @@ -8283,8 +8460,8 @@ dependencies = [ "nym-sphinx-routing", "nym-sphinx-types", "nym-topology", - "rand 0.8.5", - "thiserror 2.0.12", + "rand 0.8.6", + "thiserror 2.0.18", ] [[package]] @@ -8295,7 +8472,7 @@ dependencies = [ "nym-sphinx-anonymous-replies", "nym-sphinx-params", "nym-sphinx-types", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -8309,7 +8486,7 @@ dependencies = [ "nym-sphinx-forwarding", "nym-sphinx-params", "nym-sphinx-types", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tokio-util", "tracing", @@ -8322,7 +8499,7 @@ dependencies = [ "nym-crypto", "nym-sphinx-types", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -8331,7 +8508,7 @@ version = "1.21.0" dependencies = [ "nym-sphinx-addressing", "nym-sphinx-types", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -8340,7 +8517,7 @@ version = "1.21.0" dependencies = [ "nym-outfox", "sphinx-packet", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -8404,7 +8581,7 @@ dependencies = [ "strum 0.28.0", "strum_macros 0.28.0", "sysinfo", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "utoipa", @@ -8419,10 +8596,10 @@ dependencies = [ "argon2", "generic-array 0.14.7", "getrandom 0.2.16", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.18", "zeroize", ] @@ -8435,7 +8612,7 @@ dependencies = [ "futures", "log", "nym-test-utils", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tokio-util", "tracing", @@ -8463,7 +8640,7 @@ version = "1.21.0" dependencies = [ "nym-credentials-interface", "nym-serde-helpers", - "rand 0.8.5", + "rand 0.8.6", "rand_chacha 0.3.1", "rs_merkle", "schemars 0.8.22", @@ -8485,11 +8662,11 @@ dependencies = [ "nym-sphinx-addressing", "nym-sphinx-types", "nym-wasm-utils", - "rand 0.8.5", + "rand 0.8.6", "reqwest 0.13.1", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tracing", "tsify", @@ -8503,7 +8680,7 @@ dependencies = [ "etherparse", "log", "nym-wireguard-types", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tokio-tun", ] @@ -8532,7 +8709,7 @@ dependencies = [ "strum 0.28.0", "strum_macros 0.28.0", "tempfile", - "thiserror 2.0.12", + "thiserror 2.0.18", "ts-rs", "url", "utoipa", @@ -8551,7 +8728,7 @@ dependencies = [ "reqwest 0.13.1", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tracing", "utoipa", @@ -8599,7 +8776,7 @@ dependencies = [ "serde_json", "sha2 0.10.9", "tendermint-rpc", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tracing", @@ -8637,14 +8814,14 @@ dependencies = [ "nym-ticketbooks-merkle", "nym-validator-client", "nyxd-scraper-sqlite", - "rand 0.8.5", + "rand 0.8.6", "rand_chacha 0.3.1", "serde", "serde_json", "serde_with", "sha2 0.10.9", "sqlx", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tracing", @@ -8664,8 +8841,8 @@ dependencies = [ "nym-http-api-client", "nym-task", "nym-validator-client", - "rand 0.8.5", - "thiserror 2.0.12", + "rand 0.8.6", + "thiserror 2.0.18", "time", "tokio", "tokio-util", @@ -8683,7 +8860,7 @@ dependencies = [ "nym-contracts-common", "nym-mixnet-contract-common", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", "ts-rs", ] @@ -8729,10 +8906,10 @@ dependencies = [ "nym-validator-client", "nym-wasm-storage", "nym-wasm-utils", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde-wasm-bindgen 0.6.5", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tsify", "url", @@ -8751,7 +8928,7 @@ dependencies = [ "nym-wasm-utils", "serde", "serde-wasm-bindgen 0.6.5", - "thiserror 2.0.12", + "thiserror 2.0.18", "wasm-bindgen", ] @@ -8794,8 +8971,8 @@ dependencies = [ "nym-task", "nym-test-utils", "nym-wireguard-types", - "rand 0.8.5", - "thiserror 2.0.12", + "rand 0.8.6", + "thiserror 2.0.18", "tokio", "tokio-stream", "tracing", @@ -8840,7 +9017,7 @@ dependencies = [ "nym-credentials-interface", "schemars 0.8.22", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", "utoipa", ] @@ -8874,9 +9051,9 @@ version = "1.21.0" dependencies = [ "base64 0.22.1", "nym-crypto", - "rand 0.8.5", + "rand 0.8.6", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", "x25519-dalek", "zeroize", ] @@ -8904,7 +9081,7 @@ dependencies = [ "serde_json", "sha2 0.10.9", "tar", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tracing", @@ -8930,7 +9107,7 @@ dependencies = [ "schemars 0.8.22", "serde", "sqlx", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tokio-util", @@ -8954,7 +9131,7 @@ dependencies = [ "serde", "serde_json", "sqlx", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tracing", ] @@ -8978,7 +9155,7 @@ dependencies = [ "sha2 0.10.9", "tendermint", "tendermint-rpc", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tokio-stream", @@ -8995,7 +9172,7 @@ dependencies = [ "async-trait", "nyxd-scraper-shared", "sqlx", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tracing", ] @@ -9084,7 +9261,7 @@ dependencies = [ "futures-sink", "js-sys", "pin-project-lite", - "thiserror 2.0.12", + "thiserror 2.0.18", "tracing", ] @@ -9114,7 +9291,7 @@ dependencies = [ "opentelemetry_sdk", "prost 0.14.3", "reqwest 0.12.22", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tonic 0.14.4", "tracing", @@ -9145,7 +9322,7 @@ dependencies = [ "opentelemetry", "percent-encoding", "rand 0.9.2", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -9320,7 +9497,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323" dependencies = [ "memchr", - "thiserror 2.0.12", + "thiserror 2.0.18", "ucd-trie", ] @@ -9394,7 +9571,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" dependencies = [ "phf_shared", - "rand 0.8.5", + "rand 0.8.6", ] [[package]] @@ -9457,9 +9634,9 @@ version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" dependencies = [ - "der", - "pkcs8", - "spki", + "der 0.7.10", + "pkcs8 0.10.2", + "spki 0.7.3", ] [[package]] @@ -9468,8 +9645,18 @@ version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der", - "spki", + "der 0.7.10", + "spki 0.7.3", +] + +[[package]] +name = "pkcs8" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" +dependencies = [ + "der 0.8.0", + "spki 0.8.0", ] [[package]] @@ -9752,7 +9939,7 @@ dependencies = [ "memchr", "parking_lot", "protobuf", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -9875,7 +10062,7 @@ dependencies = [ "rustc-hash", "rustls 0.23.37", "socket2 0.5.10", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tracing", "web-time", @@ -9897,7 +10084,7 @@ dependencies = [ "rustls 0.23.37", "rustls-pki-types", "slab", - "thiserror 2.0.12", + "thiserror 2.0.18", "tinyvec", "tracing", "web-time", @@ -9940,9 +10127,9 @@ checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" [[package]] name = "rand" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" dependencies = [ "libc", "rand_chacha 0.3.1", @@ -10021,7 +10208,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" dependencies = [ "num-traits", - "rand 0.8.5", + "rand 0.8.6", ] [[package]] @@ -10061,7 +10248,7 @@ checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.16", "libredox", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -10245,7 +10432,7 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "21918d6644020c6f6ef1993242989bf6d4952d2e025617744f184c02df51c356" dependencies = [ - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -10320,21 +10507,21 @@ dependencies = [ [[package]] name = "rsa" -version = "0.9.8" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b" +checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" dependencies = [ - "const-oid", + "const-oid 0.9.6", "digest 0.10.7", "num-bigint-dig", "num-integer", "num-traits", "pkcs1", - "pkcs8", + "pkcs8 0.10.2", "rand_core 0.6.4", "sha2 0.10.9", - "signature", - "spki", + "signature 2.2.0", + "spki 0.7.3", "subtle 2.6.1", "zeroize", ] @@ -10385,7 +10572,7 @@ dependencies = [ "http 0.2.12", "mime", "mime_guess", - "rand 0.8.5", + "rand 0.8.6", "thiserror 1.0.69", ] @@ -10758,9 +10945,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ "base16ct", - "der", + "der 0.7.10", "generic-array 0.14.7", - "pkcs8", + "pkcs8 0.10.2", "serdect 0.2.0", "subtle 2.6.1", "zeroize", @@ -10961,14 +11148,15 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.141" +version = "1.0.149" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3" +checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" dependencies = [ "itoa", "memchr", - "ryu", "serde", + "serde_core", + "zmij", ] [[package]] @@ -10984,7 +11172,7 @@ dependencies = [ "serde_json", "serde_json_path_core", "serde_json_path_macros", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -10996,7 +11184,7 @@ dependencies = [ "inventory", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.18", ] [[package]] @@ -11188,7 +11376,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" dependencies = [ "digest 0.10.7", - "keccak", + "keccak 0.1.6", +] + +[[package]] +name = "sha3" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be176f1a57ce4e3d31c1a166222d9768de5954f811601fb7ca06fc8203905ce1" +dependencies = [ + "digest 0.11.3", + "keccak 0.2.0", ] [[package]] @@ -11252,6 +11450,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "signature" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" +dependencies = [ + "digest 0.11.3", + "rand_core 0.10.1", +] + [[package]] name = "simd-adler32" version = "0.3.7" @@ -11333,7 +11541,7 @@ dependencies = [ "reqwest 0.13.1", "rustls 0.23.37", "smoltcp", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tokio-rustls 0.26.2", "tokio-smoltcp", @@ -11422,7 +11630,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c26f0c20d909fdda1c5d0ece3973127ca421984d55b000215df365e93722fc6e" dependencies = [ - "aes", + "aes 0.8.4", "arrayref", "blake2 0.8.1", "bs58", @@ -11434,7 +11642,7 @@ dependencies = [ "hkdf", "hmac", "lioness", - "rand 0.8.5", + "rand 0.8.6", "rand_distr", "sha2 0.10.9", "subtle 2.6.1", @@ -11458,7 +11666,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" dependencies = [ "base64ct", - "der", + "der 0.7.10", +] + +[[package]] +name = "spki" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" +dependencies = [ + "base64ct", + "der 0.8.0", ] [[package]] @@ -11503,7 +11721,7 @@ dependencies = [ "serde_json", "sha2 0.10.9", "smallvec", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tokio", "tokio-stream", @@ -11580,7 +11798,7 @@ dependencies = [ "memchr", "once_cell", "percent-encoding", - "rand 0.8.5", + "rand 0.8.6", "rsa", "serde", "sha1", @@ -11588,7 +11806,7 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tracing", "whoami", @@ -11620,14 +11838,14 @@ dependencies = [ "md-5", "memchr", "once_cell", - "rand 0.8.5", + "rand 0.8.6", "serde", "serde_json", "sha2 0.10.9", "smallvec", "sqlx-core", "stringprep", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tracing", "whoami", @@ -11653,7 +11871,7 @@ dependencies = [ "serde", "serde_urlencoded", "sqlx-core", - "thiserror 2.0.12", + "thiserror 2.0.18", "time", "tracing", "url", @@ -11794,14 +12012,17 @@ checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" [[package]] name = "superboring" -version = "0.1.4" +version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "515cce34a781d7250b8a65706e0f2a5b99236ea605cb235d4baed6685820478f" +checksum = "efc6310a69b44420f3bf53d518077615b7d466cc57df7a80e404e7feb8c510f7" dependencies = [ + "aes-gcm", + "aes-keywrap", "getrandom 0.2.16", "hmac-sha256", "hmac-sha512", - "rand 0.8.5", + "ml-dsa", + "rand 0.8.6", "rsa", ] @@ -11936,7 +12157,7 @@ dependencies = [ "serde_json", "sha2 0.10.9", "smol_str", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "toml-span", "twox-hash", @@ -11994,7 +12215,7 @@ dependencies = [ "serde_json", "serde_repr", "sha2 0.10.9", - "signature", + "signature 2.2.0", "subtle 2.6.1", "subtle-encoding", "tendermint-proto", @@ -12045,7 +12266,7 @@ dependencies = [ "getrandom 0.2.16", "peg", "pin-project", - "rand 0.8.5", + "rand 0.8.6", "reqwest 0.11.27", "semver 1.0.27", "serde", @@ -12128,11 +12349,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.12" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.12", + "thiserror-impl 2.0.18", ] [[package]] @@ -12148,9 +12369,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.12" +version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", @@ -12673,7 +12894,7 @@ dependencies = [ "indexmap 1.9.3", "pin-project", "pin-project-lite", - "rand 0.8.5", + "rand 0.8.6", "slab", "tokio", "tokio-util", @@ -12894,7 +13115,7 @@ version = "12.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "756050066659291d47a554a9f558125db17428b073c5ffce1daf5dcb0f7231d8" dependencies = [ - "thiserror 2.0.12", + "thiserror 2.0.18", "ts-rs-macros", ] @@ -12963,7 +13184,7 @@ dependencies = [ "http 0.2.12", "httparse", "log", - "rand 0.8.5", + "rand 0.8.6", "rustls 0.21.12", "sha1", "thiserror 1.0.69", @@ -12984,7 +13205,7 @@ dependencies = [ "http 1.3.1", "httparse", "log", - "rand 0.8.5", + "rand 0.8.6", "rustls 0.22.4", "rustls-pki-types", "sha1", @@ -13027,9 +13248,9 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" [[package]] name = "typenum" -version = "1.18.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" +checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" [[package]] name = "ucd-trie" @@ -13372,7 +13593,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ - "crypto-common", + "crypto-common 0.1.6", "subtle 2.6.1", ] @@ -13692,9 +13913,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasix" -version = "0.12.21" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1fbb4ef9bbca0c1170e0b00dd28abc9e3b68669821600cad1caaed606583c6d" +checksum = "1757e0d1f8456693c7e5c6c629bdb54884e032aa0bb53c155f6a39f94440d332" dependencies = [ "wasi 0.11.1+wasi-snapshot-preview1", ] @@ -14729,9 +14950,9 @@ dependencies = [ [[package]] name = "zeroize" -version = "1.8.1" +version = "1.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" dependencies = [ "zeroize_derive", ] @@ -14793,7 +15014,7 @@ dependencies = [ "flate2", "indexmap 2.13.0", "memchr", - "thiserror 2.0.12", + "thiserror 2.0.18", "zopfli", ] @@ -14808,7 +15029,7 @@ dependencies = [ "nym-http-api-client", "nym-wasm-utils", "serde", - "thiserror 2.0.12", + "thiserror 2.0.18", "tsify", "uuid", "wasm-bindgen", @@ -14816,6 +15037,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" + [[package]] name = "zopfli" version = "0.8.2" @@ -14866,7 +15093,7 @@ dependencies = [ "reqwest 0.13.1", "serde", "serde_json", - "thiserror 2.0.12", + "thiserror 2.0.18", "tokio", "tracing", "url", diff --git a/Cargo.toml b/Cargo.toml index b6fbaeacf7..95d08ed7be 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -78,6 +78,7 @@ members = [ "common/nym-kkt-ciphersuite", "common/nym-kkt-context", "common/nym-lp", + "common/nym-lp-data", "common/nym-metrics", "common/nym_offline_compact_ecash", "common/nymnoise", @@ -459,6 +460,7 @@ nym-id = { version = "1.21.0", path = "common/nym-id" } nym-ip-packet-client = { version = "1.21.0", path = "nym-ip-packet-client" } nym-ip-packet-requests = { version = "1.21.0", path = "common/ip-packet-requests" } nym-lp = { version = "1.21.0", path = "common/nym-lp" } +nym-lp-data = { version = "1.21.0", path = "common/nym-lp-data" } nym-kkt = { version = "1.21.0", path = "common/nym-kkt" } nym-kkt-ciphersuite = { version = "1.21.0", path = "common/nym-kkt-ciphersuite" } nym-kkt-context = { version = "1.21.0", path = "common/nym-kkt-context" } diff --git a/common/nym-lp-data/Cargo.toml b/common/nym-lp-data/Cargo.toml new file mode 100644 index 0000000000..5a4f47aafa --- /dev/null +++ b/common/nym-lp-data/Cargo.toml @@ -0,0 +1,25 @@ +[package] +name = "nym-lp-data" +description = "Lewes Protocol data structure for the Nym network" +version.workspace = true +authors.workspace = true +edition.workspace = true +rust-version.workspace = true +license.workspace = true +repository.workspace = true +homepage.workspace = true +documentation.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +bytes.workspace = true +num_enum.workspace = true +tracing.workspace = true +thiserror.workspace = true + +nym-common.workspace = true + + +[lints] +workspace = true diff --git a/common/nym-lp-data/src/lib.rs b/common/nym-lp-data/src/lib.rs new file mode 100644 index 0000000000..46f172a2fd --- /dev/null +++ b/common/nym-lp-data/src/lib.rs @@ -0,0 +1,4 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +pub mod packet; diff --git a/common/nym-lp/src/packet/error.rs b/common/nym-lp-data/src/packet/error.rs similarity index 100% rename from common/nym-lp/src/packet/error.rs rename to common/nym-lp-data/src/packet/error.rs diff --git a/common/nym-lp/src/packet/frame.rs b/common/nym-lp-data/src/packet/frame.rs similarity index 96% rename from common/nym-lp/src/packet/frame.rs rename to common/nym-lp-data/src/packet/frame.rs index 81b73de04f..c0bd7b265d 100644 --- a/common/nym-lp/src/packet/frame.rs +++ b/common/nym-lp-data/src/packet/frame.rs @@ -110,7 +110,9 @@ impl LpFrame { } } - pub(crate) fn len(&self) -> usize { + // is_empty in the sense len == 0 doesn't make sense in that case + #[allow(clippy::len_without_is_empty)] + pub fn len(&self) -> usize { LpFrameHeader::SIZE + self.content.len() } } @@ -165,6 +167,8 @@ impl SphinxStreamFrameAttributes { } pub fn parse(attrs: &LpFrameAttributes) -> Result { + // SAFETY : 8 bytes slice into 8 bytes array + #[allow(clippy::unwrap_used)] let stream_id = u64::from_be_bytes(attrs[0..8].try_into().unwrap()); let msg_type = match attrs[8] { 0 => SphinxStreamMsgType::Open, @@ -175,6 +179,8 @@ impl SphinxStreamFrameAttributes { ))); } }; + // SAFETY : 4 bytes slice into 4 bytes array + #[allow(clippy::unwrap_used)] let sequence_num = u32::from_be_bytes(attrs[9..13].try_into().unwrap()); Ok(Self { stream_id, diff --git a/common/nym-lp/src/packet/header.rs b/common/nym-lp-data/src/packet/header.rs similarity index 98% rename from common/nym-lp/src/packet/header.rs rename to common/nym-lp-data/src/packet/header.rs index 4055284f58..f6f573cecb 100644 --- a/common/nym-lp/src/packet/header.rs +++ b/common/nym-lp-data/src/packet/header.rs @@ -1,11 +1,13 @@ // Copyright 2026 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::packet::error::MalformedLpPacketError; use crate::packet::version; -use crate::{packet::error::MalformedLpPacketError, peer_config::LpReceiverIndex}; use bytes::{BufMut, BytesMut}; use tracing::warn; +pub type LpReceiverIndex = u32; + /// Outer header (12 bytes) - always cleartext, used for routing. /// /// This is the first 12 bytes of every LP packet, containing only the fields diff --git a/common/nym-lp/src/packet/mod.rs b/common/nym-lp-data/src/packet/mod.rs similarity index 99% rename from common/nym-lp/src/packet/mod.rs rename to common/nym-lp-data/src/packet/mod.rs index e5e8687c4b..b45dfc812e 100644 --- a/common/nym-lp/src/packet/mod.rs +++ b/common/nym-lp-data/src/packet/mod.rs @@ -13,7 +13,6 @@ pub use header::{InnerHeader, LpHeader, OuterHeader}; pub mod error; pub mod frame; pub mod header; -pub mod replay; pub mod version { /// The current version of the Lewes Protocol that is put into each new constructed header. diff --git a/common/nym-lp/Cargo.toml b/common/nym-lp/Cargo.toml index 24f78711a0..03767d06f6 100644 --- a/common/nym-lp/Cargo.toml +++ b/common/nym-lp/Cargo.toml @@ -25,10 +25,10 @@ nym-crypto = { workspace = true, features = ["hashing"] } nym-common.workspace = true nym-kkt = { workspace = true } nym-kkt-ciphersuite = { workspace = true } +nym-lp-data.workspace = true # libcrux dependencies for PSQ (Post-Quantum PSK derivation) libcrux-psq = { workspace = true, features = ["test-utils"] } -num_enum = { workspace = true } zeroize = { workspace = true, features = ["zeroize_derive"] } @@ -48,3 +48,6 @@ mock = ["nym-test-utils"] [[bench]] name = "replay_protection" harness = false + +[lints] +workspace = true diff --git a/common/nym-lp/benches/replay_protection.rs b/common/nym-lp/benches/replay_protection.rs index 63c1b615d9..14e6237891 100644 --- a/common/nym-lp/benches/replay_protection.rs +++ b/common/nym-lp/benches/replay_protection.rs @@ -1,3 +1,5 @@ +#![allow(clippy::unwrap_used)] + use criterion::{BenchmarkId, Criterion, Throughput, black_box, criterion_group, criterion_main}; use nym_lp::replay::ReceivingKeyCounterValidator; use nym_test_utils::helpers::deterministic_rng_09; diff --git a/common/nym-lp/src/codec.rs b/common/nym-lp/src/codec.rs index b8a6b44cbf..dcd74fb0f0 100644 --- a/common/nym-lp/src/codec.rs +++ b/common/nym-lp/src/codec.rs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 use crate::LpError; -use crate::packet::{EncryptedLpPacket, InnerHeader, LpFrame, LpHeader, LpPacket}; use bytes::BytesMut; use libcrux_psq::Channel; +use nym_lp_data::packet::{EncryptedLpPacket, InnerHeader, LpFrame, LpHeader, LpPacket}; // needs to be equal or above to the actual overhead pub(crate) const SANE_ENC_OVERHEAD: usize = 32; @@ -82,12 +82,12 @@ pub(crate) fn decrypt_lp_packet( mod tests { use crate::LpError; use crate::codec::{decrypt_data, decrypt_lp_packet, encrypt_data, encrypt_lp_packet}; - use crate::packet::{EncryptedLpPacket, LpFrame, LpHeader, LpPacket}; use crate::peer::mock_peers; use crate::psq::initiator::{build_psq_ciphersuite, build_psq_principal}; use crate::psq::{PSQ_MSG2_SIZE, psq_msg1_size, responder}; use libcrux_psq::{Channel, IntoSession}; use nym_kkt_ciphersuite::KEM; + use nym_lp_data::packet::{EncryptedLpPacket, LpFrame, LpHeader, LpPacket}; use nym_test_utils::helpers::u64_seeded_rng_09; fn mock_transport() -> ( diff --git a/common/nym-lp/src/error.rs b/common/nym-lp/src/error.rs index d292a08952..ac1d5b7357 100644 --- a/common/nym-lp/src/error.rs +++ b/common/nym-lp/src/error.rs @@ -1,13 +1,13 @@ // Copyright 2025 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::packet::MalformedLpPacketError; -use crate::peer_config::LpReceiverIndex; use crate::replay::ReplayError; use crate::transport::LpTransportError; use libcrux_psq::handshake::HandshakeError; use libcrux_psq::handshake::builders::BuilderError; use libcrux_psq::session::SessionError; +use nym_lp_data::packet::MalformedLpPacketError; +use nym_lp_data::packet::header::LpReceiverIndex; // use nym_crypto::asymmetric::ed25519::Ed25519RecoveryError; use nym_kkt::error::KKTError; use nym_kkt_ciphersuite::{HashFunction, KEM}; diff --git a/common/nym-lp/src/lib.rs b/common/nym-lp/src/lib.rs index a1193bd153..e9bc674833 100644 --- a/common/nym-lp/src/lib.rs +++ b/common/nym-lp/src/lib.rs @@ -3,7 +3,6 @@ pub mod codec; pub mod error; -pub mod packet; pub mod peer; pub mod peer_config; pub mod psq; @@ -43,9 +42,13 @@ pub struct SessionsMock { #[cfg(any(feature = "mock", test))] impl SessionsMock { + // Unwrap in test is fine + #![allow(clippy::unwrap_used)] + #![allow(clippy::panic)] + pub fn mock_seeded_post_handshake(seed: u64, kem: KEM) -> SessionsMock { use crate::peer::mock_peers; - use crate::peer_config::LpReceiverIndex; + use nym_lp_data::packet::header::LpReceiverIndex; use rand09::Rng; let (init, resp) = mock_peers(); diff --git a/common/nym-lp/src/packet/replay.rs b/common/nym-lp/src/packet/replay.rs deleted file mode 100644 index 5cbdc3c0d2..0000000000 --- a/common/nym-lp/src/packet/replay.rs +++ /dev/null @@ -1,33 +0,0 @@ -use crate::{LpError, packet::LpPacket, replay::ReceivingKeyCounterValidator}; - -pub trait LpPacketReplayExt { - /// Validate packet counter against a replay protection validator - /// - /// This performs a quick check to see if the packet counter is valid before - /// any expensive processing is done. - fn validate_counter(&self, validator: &ReceivingKeyCounterValidator) -> Result<(), LpError>; - - /// Mark packet as received in the replay protection validator - /// - /// This should be called after a packet has been successfully processed. - fn mark_received(&self, validator: &mut ReceivingKeyCounterValidator) -> Result<(), LpError>; -} - -impl LpPacketReplayExt for LpPacket { - /// Validate packet counter against a replay protection validator - /// - /// This performs a quick check to see if the packet counter is valid before - /// any expensive processing is done. - fn validate_counter(&self, validator: &ReceivingKeyCounterValidator) -> Result<(), LpError> { - validator.will_accept_branchless(self.header().outer.counter)?; - Ok(()) - } - - /// Mark packet as received in the replay protection validator - /// - /// This should be called after a packet has been successfully processed. - fn mark_received(&self, validator: &mut ReceivingKeyCounterValidator) -> Result<(), LpError> { - validator.mark_did_receive_branchless(self.header().outer.counter)?; - Ok(()) - } -} diff --git a/common/nym-lp/src/peer_config.rs b/common/nym-lp/src/peer_config.rs index d28dd6bc23..ab57bdfcea 100644 --- a/common/nym-lp/src/peer_config.rs +++ b/common/nym-lp/src/peer_config.rs @@ -6,12 +6,11 @@ use libcrux_psq::handshake::types::Authenticator; use nym_crypto::hkdf::blake3::derive_key_blake3_multi_input; use nym_kkt::keys::EncapsulationKey; +use nym_lp_data::packet::header::LpReceiverIndex; use rand09::{self, CryptoRng, Rng}; use tls_codec::Serialize; use zeroize::Zeroize; -pub type LpReceiverIndex = u32; - pub const MAX_HOPS: u8 = 16; pub const LP_PEER_CONFIG_SIZE: usize = 20; diff --git a/common/nym-lp/src/psq/mod.rs b/common/nym-lp/src/psq/mod.rs index 0386e62880..f8afee6abf 100644 --- a/common/nym-lp/src/psq/mod.rs +++ b/common/nym-lp/src/psq/mod.rs @@ -1,10 +1,10 @@ // Copyright 2026 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::packet::version; use crate::peer::{LpLocalPeer, LpRemotePeer}; use crate::transport::traits::LpHandshakeChannel; use nym_kkt_ciphersuite::{HashFunction, IntoEnumIterator, KEM, KEMKeyDigests, SignatureScheme}; +use nym_lp_data::packet::version; use std::collections::BTreeMap; pub(crate) mod handshake_message; diff --git a/common/nym-lp/src/replay/mod.rs b/common/nym-lp/src/replay/mod.rs index 6363600b4c..e19911710a 100644 --- a/common/nym-lp/src/replay/mod.rs +++ b/common/nym-lp/src/replay/mod.rs @@ -7,9 +7,44 @@ //! replay attacks and ensure packet ordering. It uses a bitmap-based //! approach to track received packets and validate their sequence. +use crate::LpError; +use nym_lp_data::packet::LpPacket; + pub mod error; pub mod simd; pub mod validator; pub use error::ReplayError; pub use validator::ReceivingKeyCounterValidator; + +pub trait LpPacketReplayExt { + /// Validate packet counter against a replay protection validator + /// + /// This performs a quick check to see if the packet counter is valid before + /// any expensive processing is done. + fn validate_counter(&self, validator: &ReceivingKeyCounterValidator) -> Result<(), LpError>; + + /// Mark packet as received in the replay protection validator + /// + /// This should be called after a packet has been successfully processed. + fn mark_received(&self, validator: &mut ReceivingKeyCounterValidator) -> Result<(), LpError>; +} + +impl LpPacketReplayExt for LpPacket { + /// Validate packet counter against a replay protection validator + /// + /// This performs a quick check to see if the packet counter is valid before + /// any expensive processing is done. + fn validate_counter(&self, validator: &ReceivingKeyCounterValidator) -> Result<(), LpError> { + validator.will_accept_branchless(self.header().outer.counter)?; + Ok(()) + } + + /// Mark packet as received in the replay protection validator + /// + /// This should be called after a packet has been successfully processed. + fn mark_received(&self, validator: &mut ReceivingKeyCounterValidator) -> Result<(), LpError> { + validator.mark_did_receive_branchless(self.header().outer.counter)?; + Ok(()) + } +} diff --git a/common/nym-lp/src/session.rs b/common/nym-lp/src/session.rs index dc122d425a..ea2ff84375 100644 --- a/common/nym-lp/src/session.rs +++ b/common/nym-lp/src/session.rs @@ -6,9 +6,7 @@ //! This module implements session management functionality, including replay protection use crate::codec::{decrypt_lp_packet, encrypt_lp_packet}; -use crate::packet::{EncryptedLpPacket, LpFrame, LpHeader, LpPacket}; use crate::peer::{LpLocalPeer, LpRemotePeer}; -use crate::peer_config::LpReceiverIndex; use crate::psq::initiator::HandshakeMode; use crate::psq::{ InitiatorData, PSQHandshakeState, PSQHandshakeStateInitiator, PSQHandshakeStateResponder, @@ -21,6 +19,8 @@ use libcrux_psq::handshake::types::{Authenticator, DHPublicKey}; use libcrux_psq::session::{Session, SessionBinding}; use nym_kkt::keys::EncapsulationKey; use nym_kkt_ciphersuite::{KEM, KEMKeyDigests}; +use nym_lp_data::packet::header::LpReceiverIndex; +use nym_lp_data::packet::{EncryptedLpPacket, LpFrame, LpHeader, LpPacket}; use std::collections::BTreeMap; use std::fmt::{Debug, Formatter}; @@ -355,7 +355,7 @@ impl LpTransportSession { self.receiving_counter_mark(ctr)?; // 4. deliver the message - Ok(LpAction::DeliverFrame(packet.frame)) + Ok(LpAction::DeliverFrame(packet.into_frame())) } LpInput::SendFrame(data) => { // Encrypt and send application data diff --git a/common/nym-lp/src/session_integration/mod.rs b/common/nym-lp/src/session_integration/mod.rs index e07538f45b..fd35b2b94f 100644 --- a/common/nym-lp/src/session_integration/mod.rs +++ b/common/nym-lp/src/session_integration/mod.rs @@ -1,9 +1,9 @@ #[cfg(test)] mod tests { - use crate::packet::{EncryptedLpPacket, LpFrame}; use crate::session::{LpAction, LpInput}; use crate::{LpError, SessionManager, SessionsMock}; use nym_kkt_ciphersuite::{IntoEnumIterator, KEM}; + use nym_lp_data::packet::{EncryptedLpPacket, LpFrame}; // helpers to make tests smaller trait ActionExtract { diff --git a/common/nym-lp/src/session_manager.rs b/common/nym-lp/src/session_manager.rs index 6c54d67bbf..36d5ced5cb 100644 --- a/common/nym-lp/src/session_manager.rs +++ b/common/nym-lp/src/session_manager.rs @@ -6,9 +6,9 @@ //! This module implements session lifecycle management functionality, handling //! creation, retrieval, and storage of sessions. -use crate::packet::{EncryptedLpPacket, LpFrame}; -use crate::peer_config::LpReceiverIndex; use crate::{LpError, LpTransportSession}; +use nym_lp_data::packet::header::LpReceiverIndex; +use nym_lp_data::packet::{EncryptedLpPacket, LpFrame}; use std::collections::HashMap; pub use crate::replay::validator::PacketCount; diff --git a/common/nym-lp/src/transport/traits.rs b/common/nym-lp/src/transport/traits.rs index 0d71632cf5..49c90b40db 100644 --- a/common/nym-lp/src/transport/traits.rs +++ b/common/nym-lp/src/transport/traits.rs @@ -1,10 +1,10 @@ // Copyright 2026 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::packet::{EncryptedLpPacket, OuterHeader}; use crate::transport::error::LpTransportError; use nym_kkt::context::KKTMode; use nym_kkt_ciphersuite::KEM; +use nym_lp_data::packet::{EncryptedLpPacket, OuterHeader}; use std::net::SocketAddr; use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt}; use tokio::net::TcpStream; diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index d5c76b9b54..69a05d9288 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -80,7 +80,7 @@ nym-id = { workspace = true } nym-service-provider-requests-common = { workspace = true } nym-registration-common = { path = "../common/registration" } -nym-lp = { path = "../common/nym-lp" } +nym-lp-data.workspace = true defguard_wireguard_rs = { workspace = true } diff --git a/gateway/src/node/wireguard/new_peer_registration/lp.rs b/gateway/src/node/wireguard/new_peer_registration/lp.rs index 9e7a45d057..352e517ccf 100644 --- a/gateway/src/node/wireguard/new_peer_registration/lp.rs +++ b/gateway/src/node/wireguard/new_peer_registration/lp.rs @@ -7,7 +7,7 @@ use crate::node::wireguard::new_peer_registration::pending::{ use crate::node::wireguard::{GatewayWireguardError, PeerRegistrator}; use defguard_wireguard_rs::host::Peer; use defguard_wireguard_rs::key::Key; -use nym_lp::peer_config::LpReceiverIndex; +use nym_lp_data::packet::header::LpReceiverIndex; use nym_registration_common::{LpRegistrationResponse, WireguardRegistrationData}; use nym_wireguard::ip_pool::{allocated_ip_pair, IpPair}; use nym_wireguard_types::PeerPublicKey; diff --git a/gateway/src/node/wireguard/new_peer_registration/mod.rs b/gateway/src/node/wireguard/new_peer_registration/mod.rs index ddb53b5517..f21ee02096 100644 --- a/gateway/src/node/wireguard/new_peer_registration/mod.rs +++ b/gateway/src/node/wireguard/new_peer_registration/mod.rs @@ -31,7 +31,7 @@ use nym_credentials_interface::{BandwidthCredential, CredentialSpendingData}; use nym_crypto::asymmetric::x25519; use nym_gateway_requests::models::CredentialSpendingRequest; use nym_gateway_storage::models::PersistedBandwidth; -use nym_lp::peer_config::LpReceiverIndex; +use nym_lp_data::packet::header::LpReceiverIndex; use nym_node_metrics::prometheus_wrapper::{PrometheusMetric, PROMETHEUS_METRICS}; use nym_registration_common::dvpn::{ LpDvpnRegistrationFinalisation, LpDvpnRegistrationInitialRequest, diff --git a/gateway/src/node/wireguard/new_peer_registration/pending.rs b/gateway/src/node/wireguard/new_peer_registration/pending.rs index 1899ccf8c8..b8b9e4d7ef 100644 --- a/gateway/src/node/wireguard/new_peer_registration/pending.rs +++ b/gateway/src/node/wireguard/new_peer_registration/pending.rs @@ -8,7 +8,7 @@ use crate::node::wireguard::GatewayWireguardError; use defguard_wireguard_rs::key::Key; use nym_authenticator_requests::AuthenticatorVersion; use nym_crypto::asymmetric::x25519; -use nym_lp::peer_config::LpReceiverIndex; +use nym_lp_data::packet::header::LpReceiverIndex; use nym_registration_common::{LpRegistrationResponse, WireguardRegistrationData}; use nym_sdk::mixnet::Recipient; use nym_wireguard::ip_pool::IpPair; diff --git a/nym-gateway-probe/Cargo.toml b/nym-gateway-probe/Cargo.toml index 7cb0bf8575..18be3c9577 100644 --- a/nym-gateway-probe/Cargo.toml +++ b/nym-gateway-probe/Cargo.toml @@ -60,6 +60,7 @@ nym-ip-packet-client = { workspace = true } nym-ip-packet-requests = { workspace = true } nym-kkt-ciphersuite = { workspace = true } nym-lp = { path = "../common/nym-lp" } +nym-lp-data.workspace = true nym-network-defaults = { path = "../common/network-defaults" } nym-node-requests = { path = "../nym-node/nym-node-requests" } nym-registration-client = { path = "../nym-registration-client" } diff --git a/nym-gateway-probe/src/common/nodes.rs b/nym-gateway-probe/src/common/nodes.rs index c36daff81b..85c87614d0 100644 --- a/nym-gateway-probe/src/common/nodes.rs +++ b/nym-gateway-probe/src/common/nodes.rs @@ -12,8 +12,8 @@ use nym_bin_common::build_information::BinaryBuildInformationOwned; use nym_http_api_client::UserAgent; use nym_kkt_ciphersuite::Ciphersuite; use nym_kkt_ciphersuite::{KEM, KEMKeyDigests}; -use nym_lp::packet::version; use nym_lp::peer::{DHPublicKey, LpRemotePeer}; +use nym_lp_data::packet::version; use nym_network_defaults::DEFAULT_NYM_NODE_HTTP_PORT; use nym_node_requests::api::client::NymNodeApiClientExt; use nym_node_requests::api::v1::node::models::AuxiliaryDetails as NodeAuxiliaryDetails; diff --git a/nym-ip-packet-client/Cargo.toml b/nym-ip-packet-client/Cargo.toml index 4117d80350..837cab9fb2 100644 --- a/nym-ip-packet-client/Cargo.toml +++ b/nym-ip-packet-client/Cargo.toml @@ -26,4 +26,4 @@ tracing.workspace = true nym-sdk = { workspace = true } nym-ip-packet-requests = { workspace = true } -nym-lp = { workspace = true } +nym-lp-data = { workspace = true } diff --git a/nym-ip-packet-client/src/lp_stream.rs b/nym-ip-packet-client/src/lp_stream.rs index 736d55f378..e863fbafad 100644 --- a/nym-ip-packet-client/src/lp_stream.rs +++ b/nym-ip-packet-client/src/lp_stream.rs @@ -1,6 +1,6 @@ use bytes::BytesMut; use nym_ip_packet_requests::SPHINX_STREAM_VERSION_THRESHOLD; -use nym_lp::packet::frame::{ +use nym_lp_data::packet::frame::{ LpFrame, LpFrameHeader, LpFrameKind, SphinxStreamFrameAttributes, SphinxStreamMsgType, }; use nym_sdk::mixnet::ReconstructedMessage; @@ -65,7 +65,7 @@ pub fn encode_stream_frame(stream_id: u64, sequence_num: u32, payload: Vec) #[cfg(test)] mod tests { use super::*; - use nym_lp::packet::frame::SphinxStreamFrameAttributes; + use nym_lp_data::packet::frame::SphinxStreamFrameAttributes; #[test] fn stream_frame_roundtrip_unwraps_payload() { diff --git a/nym-node/Cargo.toml b/nym-node/Cargo.toml index 574d41d60a..a53c8dcc92 100644 --- a/nym-node/Cargo.toml +++ b/nym-node/Cargo.toml @@ -117,6 +117,7 @@ nym-ip-packet-router = { path = "../service-providers/ip-packet-router" } # LP dependencies nym-lp = { workspace = true } +nym-lp-data.workspace = true nym-registration-common = { path = "../common/registration" } bincode = { workspace = true } diff --git a/nym-node/src/node/lp/control/control_tests.rs b/nym-node/src/node/lp/control/control_tests.rs index f83e8c76e9..096d58e81b 100644 --- a/nym-node/src/node/lp/control/control_tests.rs +++ b/nym-node/src/node/lp/control/control_tests.rs @@ -9,8 +9,8 @@ mod tests { use crate::node::lp::directory::LpNodeDetails; use crate::node::lp::state::SharedLpNodeControlState; use anyhow::Context; - use nym_lp::packet::version; use nym_lp::peer::{LpLocalPeer, LpRemotePeer, mock_peers}; + use nym_lp_data::packet::version; use nym_test_utils::helpers::seeded_rng; use nym_test_utils::mocks::async_read_write::MockIOStream; use nym_test_utils::traits::TimeboxedSpawnable; diff --git a/nym-node/src/node/lp/control/ingress/client_handler.rs b/nym-node/src/node/lp/control/ingress/client_handler.rs index 6cd8a6c1b7..1613795601 100644 --- a/nym-node/src/node/lp/control/ingress/client_handler.rs +++ b/nym-node/src/node/lp/control/ingress/client_handler.rs @@ -6,13 +6,15 @@ use crate::node::lp::control::{LP_DURATION_BUCKETS, LpConnectionStats}; use crate::node::lp::error::LpHandlerError; use crate::node::lp::state::SharedLpClientControlState; use dashmap::mapref::one::RefMut; -use nym_lp::packet::frame::LpFrameKind; -use nym_lp::packet::{EncryptedLpPacket, ForwardPacketData, LpFrame}; -use nym_lp::peer_config::LpReceiverIndex; +use nym_lp::LpTransportSession; use nym_lp::session::{LpAction, LpInput}; use nym_lp::transport::LpHandshakeChannel; use nym_lp::transport::traits::LpTransportChannel; -use nym_lp::{LpTransportSession, packet::frame::ExpectedResponseSize}; +use nym_lp_data::packet::frame::LpFrameKind; +use nym_lp_data::packet::header::LpReceiverIndex; +use nym_lp_data::packet::{ + EncryptedLpPacket, ForwardPacketData, LpFrame, frame::ExpectedResponseSize, +}; use nym_metrics::{add_histogram_obs, inc}; use nym_node_metrics::NymNodeMetrics; use nym_registration_common::{LpRegistrationRequest, RegistrationStatus}; diff --git a/nym-node/src/node/lp/data/handler.rs b/nym-node/src/node/lp/data/handler.rs index 53e4af7ea1..d4961b3f12 100644 --- a/nym-node/src/node/lp/data/handler.rs +++ b/nym-node/src/node/lp/data/handler.rs @@ -17,7 +17,7 @@ use crate::node::lp::error::LpHandlerError; use crate::node::lp::state::SharedLpDataState; -use nym_lp::packet::OuterHeader; +use nym_lp_data::packet::OuterHeader; use nym_metrics::inc; use std::net::SocketAddr; use tracing::*; diff --git a/nym-node/src/node/lp/error.rs b/nym-node/src/node/lp/error.rs index c86b34b911..a0e84ccf60 100644 --- a/nym-node/src/node/lp/error.rs +++ b/nym-node/src/node/lp/error.rs @@ -1,11 +1,10 @@ // Copyright 2026 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use nym_lp::packet::frame::LpFrameKind; -use nym_lp::peer_config::LpReceiverIndex; +use nym_lp::LpError; use nym_lp::session::LpAction; use nym_lp::transport::LpTransportError; -use nym_lp::{LpError, packet::MalformedLpPacketError}; +use nym_lp_data::packet::{MalformedLpPacketError, frame::LpFrameKind, header::LpReceiverIndex}; use nym_topology::NodeId; use std::net::{IpAddr, SocketAddr}; use thiserror::Error; diff --git a/nym-node/src/node/lp/registration.rs b/nym-node/src/node/lp/registration.rs index fa51d49ac0..4fd2a29144 100644 --- a/nym-node/src/node/lp/registration.rs +++ b/nym-node/src/node/lp/registration.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::node::lp::state::SharedLpClientControlState; -use nym_lp::peer_config::LpReceiverIndex; +use nym_lp_data::packet::header::LpReceiverIndex; use nym_metrics::{add_histogram_obs, inc}; use nym_registration_common::dvpn::{ LpDvpnRegistrationFinalisation, LpDvpnRegistrationInitialRequest, diff --git a/nym-node/src/node/lp/state.rs b/nym-node/src/node/lp/state.rs index c16dcf50ca..0afac45b85 100644 --- a/nym-node/src/node/lp/state.rs +++ b/nym-node/src/node/lp/state.rs @@ -10,7 +10,7 @@ use dashmap::mapref::one::RefMut; use nym_gateway::node::wireguard::PeerRegistrator; use nym_lp::LpTransportSession; use nym_lp::peer::LpLocalPeer; -use nym_lp::peer_config::LpReceiverIndex; +use nym_lp_data::packet::header::LpReceiverIndex; use nym_mixnet_client::forwarder::MixForwardingSender; use nym_node_metrics::NymNodeMetrics; use std::sync::Arc; diff --git a/nym-registration-client/Cargo.toml b/nym-registration-client/Cargo.toml index 9e5082689f..84e2471372 100644 --- a/nym-registration-client/Cargo.toml +++ b/nym-registration-client/Cargo.toml @@ -31,6 +31,7 @@ nym-credentials-interface = { workspace = true } nym-crypto = { workspace = true, features = ["asymmetric", "libcrux_x25519"] } nym-ip-packet-client = { workspace = true } nym-lp = { path = "../common/nym-lp" } +nym-lp-data.workspace = true nym-registration-common = { workspace = true } nym-sdk = { workspace = true } nym-validator-client = { workspace = true } diff --git a/nym-registration-client/src/lp_client/client.rs b/nym-registration-client/src/lp_client/client.rs index 45527b4bb7..5fa37662bd 100644 --- a/nym-registration-client/src/lp_client/client.rs +++ b/nym-registration-client/src/lp_client/client.rs @@ -13,13 +13,13 @@ use crate::lp_client::session_helpers::{extract_forwarded_response, prepare_send use nym_bandwidth_controller::{BandwidthTicketProvider, DEFAULT_TICKETS_TO_SPEND}; use nym_credentials_interface::TicketType; use nym_crypto::asymmetric::{ed25519, x25519}; +use nym_lp::Ciphersuite; use nym_lp::LpTransportSession; use nym_lp::peer::{DHKeyPair, LpLocalPeer, LpRemotePeer}; -use nym_lp::peer_config::LpReceiverIndex; use nym_lp::psq::initiator::HandshakeMode; use nym_lp::transport::traits::LpTransportChannel; use nym_lp::transport::{LpHandshakeChannel, LpTransportError}; -use nym_lp::{Ciphersuite, packet::EncryptedLpPacket, packet::version}; +use nym_lp_data::packet::{EncryptedLpPacket, header::LpReceiverIndex, version}; use nym_registration_common::dvpn::LpDvpnRegistrationResponseMessageContent; use nym_registration_common::{ LpRegistrationRequest, LpRegistrationResponse, WireguardConfiguration, @@ -708,7 +708,7 @@ where mod tests { use super::*; use nym_kkt::key_utils::generate_lp_keypair_x25519; - use nym_lp::packet::version; + use nym_lp_data::packet::version; use nym_test_utils::helpers::deterministic_rng_09; #[test] diff --git a/nym-registration-client/src/lp_client/error.rs b/nym-registration-client/src/lp_client/error.rs index 168ee3836e..4b6fc15b1e 100644 --- a/nym-registration-client/src/lp_client/error.rs +++ b/nym-registration-client/src/lp_client/error.rs @@ -4,10 +4,10 @@ //! Error types for LP (Lewes Protocol) client operations. use nym_lp::LpError; -use nym_lp::packet::MalformedLpPacketError; -use nym_lp::packet::frame::LpFrameKind; use nym_lp::session::LpAction; use nym_lp::transport::LpTransportError; +use nym_lp_data::packet::MalformedLpPacketError; +use nym_lp_data::packet::frame::LpFrameKind; use thiserror::Error; /// Errors that can occur during LP client operations. diff --git a/nym-registration-client/src/lp_client/helpers.rs b/nym-registration-client/src/lp_client/helpers.rs index bda1a67a69..c0f5747222 100644 --- a/nym-registration-client/src/lp_client/helpers.rs +++ b/nym-registration-client/src/lp_client/helpers.rs @@ -4,10 +4,10 @@ #![allow(dead_code)] use crate::LpClientError; -use nym_lp::packet::frame::LpFrameKind; -use nym_lp::packet::{ForwardPacketData, LpFrame}; use nym_lp::peer::LpRemotePeer; use nym_lp::session::{LpAction, LpInput}; +use nym_lp_data::packet::frame::LpFrameKind; +use nym_lp_data::packet::{ForwardPacketData, LpFrame}; use nym_registration_common::{ LpRegistrationRequest, LpRegistrationResponse, NymNodeLPInformation, }; diff --git a/nym-registration-client/src/lp_client/nested_session/connection.rs b/nym-registration-client/src/lp_client/nested_session/connection.rs index c446998756..9ae7488193 100644 --- a/nym-registration-client/src/lp_client/nested_session/connection.rs +++ b/nym-registration-client/src/lp_client/nested_session/connection.rs @@ -5,10 +5,10 @@ use crate::lp_client::helpers::{convert_forward_data, try_convert_forward_respon use crate::{LpClientError, LpRegistrationClient}; use bytes::{BufMut, BytesMut}; use nym_lp::KEM; -use nym_lp::packet::{EncryptedLpPacket, ForwardPacketData, frame::ExpectedResponseSize}; use nym_lp::session::{LpAction, LpInput}; use nym_lp::transport::traits::{HandshakeMessage, LpTransportChannel}; use nym_lp::transport::{LpHandshakeChannel, LpTransportError}; +use nym_lp_data::packet::{EncryptedLpPacket, ForwardPacketData, frame::ExpectedResponseSize}; use std::io; use std::net::SocketAddr; diff --git a/nym-registration-client/src/lp_client/nested_session/mod.rs b/nym-registration-client/src/lp_client/nested_session/mod.rs index 08ba26ee4d..fcf1fa32b5 100644 --- a/nym-registration-client/src/lp_client/nested_session/mod.rs +++ b/nym-registration-client/src/lp_client/nested_session/mod.rs @@ -27,13 +27,13 @@ use crate::lp_client::session_helpers::{extract_forwarded_response, prepare_send use nym_bandwidth_controller::{BandwidthTicketProvider, DEFAULT_TICKETS_TO_SPEND}; use nym_credentials_interface::TicketType; use nym_crypto::asymmetric::{ed25519, x25519}; -use nym_lp::packet::version; -use nym_lp::packet::{EncryptedLpPacket, LpFrame}; use nym_lp::peer::{DHKeyPair, LpLocalPeer, LpRemotePeer}; use nym_lp::psq::initiator::HandshakeMode; use nym_lp::transport::LpHandshakeChannel; use nym_lp::transport::traits::LpTransportChannel; use nym_lp::{Ciphersuite, KEM, LpTransportSession}; +use nym_lp_data::packet::version; +use nym_lp_data::packet::{EncryptedLpPacket, LpFrame}; use nym_registration_common::dvpn::LpDvpnRegistrationResponseMessageContent; use nym_registration_common::{ LpRegistrationRequest, LpRegistrationResponse, WireguardConfiguration, diff --git a/nym-registration-client/src/lp_client/session_helpers.rs b/nym-registration-client/src/lp_client/session_helpers.rs index fa7d0c9ef6..d411281ab1 100644 --- a/nym-registration-client/src/lp_client/session_helpers.rs +++ b/nym-registration-client/src/lp_client/session_helpers.rs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 use crate::LpClientError; -use nym_lp::packet::LpFrame; +use nym_lp::LpTransportSession; use nym_lp::session::{LpAction, LpInput}; -use nym_lp::{LpTransportSession, packet::EncryptedLpPacket}; +use nym_lp_data::packet::{EncryptedLpPacket, LpFrame}; /// Attempt to prepare the provided data for sending by wrapping it in appropriate `LpAction`, /// and attempting to extract `EncryptedLpPacket` from the provided state machine. diff --git a/sdk/rust/nym-sdk/Cargo.toml b/sdk/rust/nym-sdk/Cargo.toml index 931c640edb..1391873b51 100644 --- a/sdk/rust/nym-sdk/Cargo.toml +++ b/sdk/rust/nym-sdk/Cargo.toml @@ -39,7 +39,7 @@ nym-credentials-interface = { workspace = true } nym-credential-storage = { workspace = true } nym-credential-utils = { workspace = true } nym-network-defaults = { workspace = true } -nym-lp = { workspace = true } +nym-lp-data = { workspace = true } nym-sphinx = { workspace = true } nym-statistics-common = { workspace = true } nym-task = { workspace = true } diff --git a/sdk/rust/nym-sdk/src/mixnet/stream/mixnet_stream.rs b/sdk/rust/nym-sdk/src/mixnet/stream/mixnet_stream.rs index c7de30e9ba..0b27bf2b79 100644 --- a/sdk/rust/nym-sdk/src/mixnet/stream/mixnet_stream.rs +++ b/sdk/rust/nym-sdk/src/mixnet/stream/mixnet_stream.rs @@ -19,7 +19,7 @@ use nym_sphinx::params::PacketType; use nym_task::connections::TransmissionLane; use tokio_util::sync::PollSender; -use nym_lp::packet::frame::SphinxStreamMsgType; +use nym_lp_data::packet::frame::SphinxStreamMsgType; use super::protocol::{encode_stream_message, StreamId}; use super::StreamMap; diff --git a/sdk/rust/nym-sdk/src/mixnet/stream/mod.rs b/sdk/rust/nym-sdk/src/mixnet/stream/mod.rs index 5f91536eab..9da2ce1701 100644 --- a/sdk/rust/nym-sdk/src/mixnet/stream/mod.rs +++ b/sdk/rust/nym-sdk/src/mixnet/stream/mod.rs @@ -40,7 +40,7 @@ use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag; use nym_task::connections::TransmissionLane; -use nym_lp::packet::frame::SphinxStreamMsgType; +use nym_lp_data::packet::frame::SphinxStreamMsgType; use protocol::{decode_stream_message, encode_stream_message}; use crate::mixnet::native_client::MixnetClient; diff --git a/sdk/rust/nym-sdk/src/mixnet/stream/protocol.rs b/sdk/rust/nym-sdk/src/mixnet/stream/protocol.rs index 058e6c445d..ddadcf11af 100644 --- a/sdk/rust/nym-sdk/src/mixnet/stream/protocol.rs +++ b/sdk/rust/nym-sdk/src/mixnet/stream/protocol.rs @@ -17,7 +17,7 @@ use std::fmt; use bytes::BytesMut; -use nym_lp::packet::frame::{ +use nym_lp_data::packet::frame::{ LpFrame, LpFrameHeader, LpFrameKind, SphinxStreamFrameAttributes, SphinxStreamMsgType, }; diff --git a/service-providers/ip-packet-router/Cargo.toml b/service-providers/ip-packet-router/Cargo.toml index 8c05b495e7..261fc676e9 100644 --- a/service-providers/ip-packet-router/Cargo.toml +++ b/service-providers/ip-packet-router/Cargo.toml @@ -26,7 +26,7 @@ nym-crypto = { workspace = true } nym-exit-policy = { workspace = true } nym-id = { workspace = true } nym-ip-packet-requests = { workspace = true } -nym-lp = { workspace = true } +nym-lp-data = { workspace = true } nym-network-defaults = { workspace = true } nym-network-requester = { path = "../network-requester" } nym-sdk = { workspace = true } diff --git a/service-providers/ip-packet-router/src/clients/connected_client_handler.rs b/service-providers/ip-packet-router/src/clients/connected_client_handler.rs index ff0e8e4924..da56306232 100644 --- a/service-providers/ip-packet-router/src/clients/connected_client_handler.rs +++ b/service-providers/ip-packet-router/src/clients/connected_client_handler.rs @@ -12,7 +12,7 @@ use nym_ip_packet_requests::{ v8::response::IpPacketResponse as IpPacketResponseV8, v9, }; -use nym_lp::packet::frame::{ +use nym_lp_data::packet::frame::{ LpFrame, LpFrameHeader, SphinxStreamFrameAttributes, SphinxStreamMsgType, }; use nym_sdk::mixnet::{ diff --git a/service-providers/ip-packet-router/src/mixnet_listener.rs b/service-providers/ip-packet-router/src/mixnet_listener.rs index 3295dfeeb1..6dd3613b7a 100644 --- a/service-providers/ip-packet-router/src/mixnet_listener.rs +++ b/service-providers/ip-packet-router/src/mixnet_listener.rs @@ -24,7 +24,7 @@ use crate::{ use futures::StreamExt; use nym_ip_packet_requests::codec::MultiIpPacketCodec; use nym_ip_packet_requests::{MAX_NON_STREAM_VERSION, SPHINX_STREAM_VERSION_THRESHOLD}; -use nym_lp::packet::frame::{LpFrameHeader, LpFrameKind, SphinxStreamFrameAttributes}; +use nym_lp_data::packet::frame::{LpFrameHeader, LpFrameKind, SphinxStreamFrameAttributes}; use nym_sdk::mixnet::MixnetMessageSender; use nym_sphinx::receiver::ReconstructedMessage; use nym_task::ShutdownToken; @@ -704,7 +704,7 @@ mod tests { #[test] fn test_lp_stream_frame_detected() { use bytes::BytesMut; - use nym_lp::packet::frame::{ + use nym_lp_data::packet::frame::{ LpFrameHeader, LpFrameKind, SphinxStreamFrameAttributes, SphinxStreamMsgType, }; @@ -713,7 +713,7 @@ mod tests { msg_type: SphinxStreamMsgType::Data, sequence_num: 42, }; - let frame = nym_lp::packet::frame::LpFrame::new_stream(attrs, vec![8, 1, 0]); // fake IPR payload + let frame = nym_lp_data::packet::frame::LpFrame::new_stream(attrs, vec![8, 1, 0]); // fake IPR payload let mut buf = BytesMut::new(); frame.encode(&mut buf); diff --git a/tools/nym-lp-client/Cargo.toml b/tools/nym-lp-client/Cargo.toml index c33b04f366..bbb576ebda 100644 --- a/tools/nym-lp-client/Cargo.toml +++ b/tools/nym-lp-client/Cargo.toml @@ -33,6 +33,7 @@ nym-kkt-ciphersuite = { workspace = true } nym-http-api-client = { path = "../../common/http-api-client" } nym-kcp = { path = "../../common/nym-kcp" } nym-lp = { path = "../../common/nym-lp" } +nym-lp-data.workspace = true nym-sphinx = { path = "../../common/nymsphinx" } nym-sphinx-framing = { path = "../../common/nymsphinx/framing", features = ["no-mix-acks"] } nym-sphinx-anonymous-replies = { path = "../../common/nymsphinx/anonymous-replies" } diff --git a/tools/nym-lp-client/src/client.rs b/tools/nym-lp-client/src/client.rs index 2d656b2334..e764eb74c2 100644 --- a/tools/nym-lp-client/src/client.rs +++ b/tools/nym-lp-client/src/client.rs @@ -33,8 +33,8 @@ use tracing::{debug, info, trace}; use crate::topology::{GatewayInfo, SpeedtestTopology}; use nym_ip_packet_requests::v8::request::IpPacketRequest; -use nym_lp::packet::version; use nym_lp::peer::{DHKeyPair, LpRemotePeer}; +use nym_lp_data::packet::version; use nym_sphinx::forwarding::packet::MixPacket; /// Conv ID for KCP - hash of source and destination addresses From 64c68d7b7686e8da07b10212d5367ea8e6b7da48 Mon Sep 17 00:00:00 2001 From: Andy Duplain Date: Thu, 21 May 2026 09:13:31 +0100 Subject: [PATCH 35/94] Fix tests. --- Cargo.lock | 1 - nym-sqlx-pool-guard/Cargo.toml | 1 - nym-sqlx-pool-guard/src/lib.rs | 5 +---- 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dbdc7f892d..8ddcc03d1b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8352,7 +8352,6 @@ dependencies = [ "tempfile", "tokio", "tracing", - "tracing-subscriber", "tracing-test", "windows 0.61.3", ] diff --git a/nym-sqlx-pool-guard/Cargo.toml b/nym-sqlx-pool-guard/Cargo.toml index e4b86ad2c5..ed980db3e1 100644 --- a/nym-sqlx-pool-guard/Cargo.toml +++ b/nym-sqlx-pool-guard/Cargo.toml @@ -41,5 +41,4 @@ windows = { version = "0.61", features = [ [dev-dependencies] tempfile.workspace = true -tracing-subscriber.workspace = true tracing-test.workspace = true diff --git a/nym-sqlx-pool-guard/src/lib.rs b/nym-sqlx-pool-guard/src/lib.rs index 8ded2cfb61..8e0d400c65 100644 --- a/nym-sqlx-pool-guard/src/lib.rs +++ b/nym-sqlx-pool-guard/src/lib.rs @@ -184,12 +184,9 @@ mod tests { use super::*; + #[traced_test] #[tokio::test] async fn test_wait_close() { - tracing_subscriber::fmt() - .with_max_level(tracing::Level::TRACE) - .init(); - let temp_dir = tempfile::tempdir().unwrap(); let database_path = temp_dir.path().join("storage.db"); From e5cd9fd69e5251986fda8414da680e807840e950 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Thu, 21 May 2026 17:24:08 +0200 Subject: [PATCH 36/94] bump versions --- Cargo.lock | 14 +++++++------- clients/native/Cargo.toml | 2 +- clients/socks5/Cargo.toml | 2 +- nym-api/Cargo.toml | 2 +- nym-node/Cargo.toml | 2 +- service-providers/network-requester/Cargo.toml | 2 +- tools/nym-cli/Cargo.toml | 2 +- tools/nymvisor/Cargo.toml | 2 +- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4568c69bb9..5dc706e4fc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5726,7 +5726,7 @@ dependencies = [ [[package]] name = "nym-api" -version = "1.1.79" +version = "1.1.80" dependencies = [ "anyhow", "async-trait", @@ -5971,7 +5971,7 @@ dependencies = [ [[package]] name = "nym-cli" -version = "1.1.76" +version = "1.1.77" dependencies = [ "anyhow", "base64 0.22.1", @@ -6054,7 +6054,7 @@ dependencies = [ [[package]] name = "nym-client" -version = "1.1.76" +version = "1.1.77" dependencies = [ "bs58", "clap", @@ -7465,7 +7465,7 @@ dependencies = [ [[package]] name = "nym-network-requester" -version = "1.1.77" +version = "1.1.78" dependencies = [ "addr", "anyhow", @@ -7515,7 +7515,7 @@ dependencies = [ [[package]] name = "nym-node" -version = "1.31.0" +version = "1.32.0" dependencies = [ "anyhow", "arc-swap", @@ -8067,7 +8067,7 @@ dependencies = [ [[package]] name = "nym-socks5-client" -version = "1.1.76" +version = "1.1.77" dependencies = [ "bs58", "clap", @@ -8865,7 +8865,7 @@ dependencies = [ [[package]] name = "nymvisor" -version = "0.1.41" +version = "0.1.42" dependencies = [ "anyhow", "bytes", diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index 83e9bd5d97..1535070585 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "nym-client" description = "Implementation of the Nym Client" -version = "1.1.76" +version = "1.1.77" authors = ["Dave Hrycyszyn ", "Jędrzej Stuczyński "] edition = "2021" license.workspace = true diff --git a/clients/socks5/Cargo.toml b/clients/socks5/Cargo.toml index a22ad47a08..47d259d342 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "nym-socks5-client" description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address" -version = "1.1.76" +version = "1.1.77" authors = ["Dave Hrycyszyn "] edition = "2021" license.workspace = true diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index 93f2e44db4..a9c34d69aa 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-api" -version = "1.1.79" +version = "1.1.80" authors.workspace = true edition = "2021" license = "GPL-3.0" diff --git a/nym-node/Cargo.toml b/nym-node/Cargo.toml index 574d41d60a..c3f8aa0489 100644 --- a/nym-node/Cargo.toml +++ b/nym-node/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node" -version = "1.31.0" +version = "1.32.0" authors.workspace = true edition.workspace = true license = "GPL-3.0" diff --git a/service-providers/network-requester/Cargo.toml b/service-providers/network-requester/Cargo.toml index c55c845e97..bc6719e1b3 100644 --- a/service-providers/network-requester/Cargo.toml +++ b/service-providers/network-requester/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-network-requester" -version = "1.1.77" +version = "1.1.78" authors.workspace = true edition.workspace = true license = "GPL-3.0" diff --git a/tools/nym-cli/Cargo.toml b/tools/nym-cli/Cargo.toml index f1f8836a30..54d942cc29 100644 --- a/tools/nym-cli/Cargo.toml +++ b/tools/nym-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-cli" -version = "1.1.76" +version = "1.1.77" authors.workspace = true edition = "2021" license.workspace = true diff --git a/tools/nymvisor/Cargo.toml b/tools/nymvisor/Cargo.toml index f8dc2249cd..ca520e5c35 100644 --- a/tools/nymvisor/Cargo.toml +++ b/tools/nymvisor/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nymvisor" -version = "0.1.41" +version = "0.1.42" authors.workspace = true edition.workspace = true license.workspace = true From 46c67440bb2c96308ec8352a423faa931b610d1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 22 May 2026 09:43:20 +0100 Subject: [PATCH 37/94] Mixnode stress testing (#6575) * Squashing the mix stress testing branch (#6575) reduced chain watcher per block log severity update network monitors contract semver to 1.0.0 fix build issues fix mixnet client dropping initial packet on egress reconnection adjusted logs for network monitor agent changed default testing interval to 2h refresh NM contract information explicit return type for batch submission for mixnet listener task to get scheduled before beginning connectivity test make sure to always use canonical ip for network monitor noise keys feat: NMv3: make agents decide egress port (#6746) add config v12->v13 config migration for nym nodes fix formatting in wallet types simplified client config creation remove other swagger redirect removed swagger redirect on /swagger/ route log version info on startup add workflows, contract address, and dockerfile bugfix: use correct endpoints when setting up orchestrator (#6733) clippy adjust DEFAULT_MIN_STRESS_TESTED_NODES ratio expose route with new performance metrics fixes and additional docs use stress testing scores stub for usage of stress testing scores stub traits added new fields to nym-api config controlling usage of stress test data guard against duplicate packets prevent usage of chain_authorisation_check_max_attempts with value of 0 make sure duplicate results cant be inserted into the db submit test results from orchestrator on an interval docs and fixes nym-api side of handling result submission stubs for submitting results NM orchestrator verifying nym-api result submission permissions NM orchestrator to update announced key on startup allow NM orchestrator to announce its identity key to the contract stubs within nym-api for accepting NMv3 results added additional metrics docs bugfixes + making sure to only assign mixnode testruns fixed node refresher to only retrieve mixnodes and add additional metrics topology metrics defined basic prometheus metrics authorised endpoint for returning prometheus data create initial stub for prometheus metrics post rebasing fixes adjusted routes missing implementation for storage getters a lot of new stubs and db accessors stubs for results endpoints update utoipa tags for agent rountes shared auth between metrics and results moved stale results eviction into the interval.tick branch refactor and comments create background process to evict stale data include sphinx packet delay as part of the stats fix mock construction add median to the calculated latency distribution remove unused imports cleanup performing testrun and submitting the results assigning testruns to requesting agents basic stub for http server for the NMv3 orchestrator chore: rename existing 'NetworkMonitorAgent' to 'NodeStressTester' make sure to use canonical ips within the noise config fixed contract tests cargo fmt additional comments and unit tests contract and nym-node support of NM agents being run on the same host basic unit tests refactoring make agents retrieve mix port assignment from the orchestrator provide sensible defaults to CLI arguments stub the initial structure for the agent chore: remove redundant import missed tick behaviour removed redundant mutex removed redundant try_get_client reuse existing constant for default nymnode port add node refresher for periodic scraping of bonded nym-node details - NodeRefresher periodically queries the mixnet contract for all bonded nodes and probes each node's HTTP API for host information, sphinx keys, noise keys, and key rotation IDs - Extract NymNodeApiClientRetriever into nym-node-requests with port probing, identity verification, and host information signature checking - Add clone_query_client on NyxdClient so the refresher can hold its own query client without locking the signing client - Batch upsert for nym_node rows (single transaction instead of per-row) - Reuse the new helpers in nym-api's node_describe_cache ensure assignment of testrun begins an IMMEDIATE tx construction of the orchestrator struct initial set of cli args make sure to not assign testable nodes too often very initial database structure and cli fixed construction of RoutableNetworkMonitors remove redundant constructor for NoiseNode forbid 0-nonsense config values add type safety for test route construction moved lioness and arrayref to workspace deps fixed dockerfile build always use canonical addresses in RoutableNetworkMonitors fixed old contract formatting issues removed redundant into() call network monitor agent fixes additional logs config unit tests more docs standalone stress testing invocation further refactoring and changes refactor testing loop and return valid test result upon completion initial sending/receiving test loop generating reusable sphinx headers additional structure for receiving ingress packets initial scaffolding for NMv3 agent added validation of x25519 noise key removed unstable call to 'is_multiple_of' remove calls to from_octets as they're unavailable in pre 1.91 additional docs/comments propagating noise information about NM for mixnet routing pass full socket address of the agent into the contract storage feat: store noise keys alongside ip addresses within the contract removed redundant comment ensure NM packets can only go to NM PR review comments added additional docs allow NM to replay packets + fix replay prometheus metrics propagate information about nm agent to connection handler updated nym-node config migration feat: introduced nym-node websocket subscription for keeping updated list of NM agents allow admin to also revoke monitor agents remove agents upon orchestrator removal fixed schema generation and regenerated the contract schema removed rustc restriction on contracts-common added client methods for interacting with the contract added unit tests for contract methods implemented logic of the network monitors contract create initial structure for network monitors contract start mix stress testing topic branch * make nym-node default to the new blockstream rpc/ws node cluster * reduced mixnet-client log severity * set network monitors contract address for mainnet --- Cargo.lock | 98 +- Cargo.toml | 10 + .../src/client/mix_traffic/transceiver.rs | 2 +- common/client-libs/mixnet-client/Cargo.toml | 1 + .../client-libs/mixnet-client/src/client.rs | 346 +++- .../mixnet-client/src/forwarder.rs | 38 +- .../client-libs/validator-client/Cargo.toml | 1 + .../validator-client/src/client.rs | 17 + .../validator-client/src/nym_api/mod.rs | 61 +- .../validator-client/src/nym_api/routes.rs | 3 + .../src/nyxd/contract_traits/mod.rs | 12 + .../network_monitors_query_client.rs | 107 ++ .../network_monitors_signing_client.rs | 205 +++ .../src/nyxd/cosmwasm_client/mod.rs | 13 +- .../validator-client/src/nyxd/mod.rs | 32 +- .../network-monitors-contract/Cargo.toml | 26 + .../src/constants.rs | 8 + .../network-monitors-contract/src/error.rs | 30 + .../network-monitors-contract/src/lib.rs | 11 + .../network-monitors-contract/src/msg.rs | 78 + .../network-monitors-contract/src/types.rs | 53 + common/crypto/src/lib.rs | 2 + common/http-api-client/src/path.rs | 2 + common/network-defaults/Cargo.toml | 9 +- common/network-defaults/src/env_setup.rs | 12 +- common/network-defaults/src/mainnet.rs | 23 + common/network-defaults/src/network.rs | 40 +- common/network-defaults/src/sandbox.rs | 0 common/network-defaults/src/var_names.rs | 4 + common/nymnoise/src/config.rs | 429 ++++- common/nymnoise/src/connection.rs | 6 + common/nymnoise/src/lib.rs | 4 +- common/nymsphinx/framing/src/processing.rs | 6 + common/nymsphinx/types/src/lib.rs | 2 +- common/nyxd-scraper-psql/src/lib.rs | 5 +- .../nyxd-scraper-psql/src/storage/helpers.rs | 2 +- .../src/storage/transaction.rs | 38 +- .../nyxd-scraper-shared/examples/watcher.rs | 6 +- .../src/block_processor/mod.rs | 28 +- .../src/block_processor/types.rs | 31 +- common/nyxd-scraper-shared/src/error.rs | 4 +- common/nyxd-scraper-shared/src/helpers.rs | 2 +- common/nyxd-scraper-shared/src/lib.rs | 6 +- common/nyxd-scraper-shared/src/modules/mod.rs | 2 +- .../src/modules/msg_module.rs | 41 +- common/nyxd-scraper-shared/src/rpc_client.rs | 36 +- common/nyxd-scraper-shared/src/watcher.rs | 12 +- common/nyxd-scraper-sqlite/src/lib.rs | 5 +- .../src/storage/transaction.rs | 24 +- contracts/Cargo.lock | 28 + contracts/Cargo.toml | 8 +- contracts/network-monitors/.cargo/config | 4 + contracts/network-monitors/Cargo.toml | 43 + contracts/network-monitors/Makefile | 5 + .../schema/network-monitors.json | 368 ++++ .../network-monitors/schema/raw/execute.json | 125 ++ .../schema/raw/instantiate.json | 15 + .../network-monitors/schema/raw/migrate.json | 6 + .../network-monitors/schema/raw/query.json | 64 + .../schema/raw/response_to_admin.json | 15 + .../response_to_network_monitor_agents.json | 74 + ...onse_to_network_monitor_orchestrators.json | 61 + contracts/network-monitors/src/bin/schema.rs | 14 + contracts/network-monitors/src/contract.rs | 179 ++ contracts/network-monitors/src/lib.rs | 11 + contracts/network-monitors/src/queries.rs | 345 ++++ .../network-monitors/src/queued_migrations.rs | 2 + contracts/network-monitors/src/storage.rs | 1626 +++++++++++++++++ contracts/network-monitors/src/testing/mod.rs | 188 ++ .../network-monitors/src/transactions.rs | 1096 +++++++++++ envs/sandbox.env | 1 + .../connection_handler/authenticated.rs | 2 +- gateway/src/node/mod.rs | 7 +- .../20260424120000_stress_testing.sql | 29 + .../src/models/network_monitor.rs | 110 ++ .../src/models/node_status.rs | 140 +- nym-api/nym-api-requests/src/signable.rs | 6 +- nym-api/src/ecash/tests/mod.rs | 3 + nym-api/src/epoch_operations/helpers.rs | 4 +- .../src/network_monitor/monitor/preparer.rs | 11 +- nym-api/src/node_describe_cache/mod.rs | 27 +- nym-api/src/node_describe_cache/refresh.rs | 101 +- .../provider/contract_provider.rs | 4 +- .../provider/legacy_storage_provider.rs | 87 +- nym-api/src/node_performance/provider/mod.rs | 120 +- nym-api/src/node_status_api/cache/data.rs | 8 +- nym-api/src/node_status_api/cache/mod.rs | 6 +- .../src/node_status_api/cache/refresher.rs | 108 +- .../handlers/without_monitor.rs | 3 + nym-api/src/node_status_api/mod.rs | 18 +- nym-api/src/nym_nodes/handlers/mod.rs | 1 + nym-api/src/nym_nodes/handlers/v1.rs | 16 +- nym-api/src/nym_nodes/handlers/v2.rs | 36 +- nym-api/src/nym_nodes/handlers/v3.rs | 178 ++ nym-api/src/status/mod.rs | 7 + nym-api/src/support/caching/mod.rs | 4 + nym-api/src/support/cli/run.rs | 8 +- nym-api/src/support/config/mod.rs | 74 +- nym-api/src/support/config/template.rs | 24 + nym-api/src/support/http/router.rs | 4 +- .../support/http/state/contract_details.rs | 199 +- nym-api/src/support/http/state/helpers.rs | 125 ++ nym-api/src/support/http/state/mod.rs | 21 + .../support/http/state/network_monitors.rs | 114 ++ nym-api/src/support/nyxd/mod.rs | 37 +- nym-api/src/support/storage/manager.rs | 73 +- nym-api/src/support/storage/mod.rs | 27 +- nym-api/src/support/storage/models.rs | 48 +- .../v2/nym_nodes/semi_skimmed/mod.rs | 10 +- .../v2/nym_nodes/skimmed/helpers.rs | 10 +- .../v3/nym_nodes/semi_skimmed/mod.rs | 10 +- .../src/chain_scraper/webhook.rs | 64 +- nym-data-observatory/src/modules/wasm.rs | 10 +- .../nym-network-monitor-agent/Cargo.toml | 56 + .../nym-network-monitor-agent/Dockerfile | 22 + .../nym-network-monitor-agent/README.md | 3 + .../build-push-node-status-agent.sh | 49 + .../nym-network-monitor-agent/entrypoint.sh | 20 + .../src/agent/config.rs | 110 ++ .../src/agent/helpers.rs | 19 + .../src/agent/mod.rs | 110 ++ .../src/agent/result.rs | 381 ++++ .../src/agent/tested_node.rs | 53 + .../src/agent/tester.rs | 521 ++++++ .../src/cli/build_info.rs | 15 + .../src/cli/common.rs | 88 + .../nym-network-monitor-agent/src/cli/env.rs | 48 + .../src/cli/keygen.rs | 24 + .../nym-network-monitor-agent/src/cli/mod.rs | 56 + .../src/cli/run_agent.rs | 63 + .../src/cli/test_node.rs | 77 + .../src/egress_connection.rs | 123 ++ .../src/listener/mod.rs | 167 ++ .../src/listener/received.rs | 32 + .../nym-network-monitor-agent/src/main.rs | 47 + .../src/processor.rs | 165 ++ .../src/sphinx_helpers.rs | 264 +++ .../src/test_packet.rs | 204 +++ .../Cargo.toml | 31 + .../src/api/mod.rs | 2 + .../src/client.rs | 81 + .../src/lib.rs | 91 + .../src/models.rs | 378 ++++ .../Cargo.toml | 64 + .../Dockerfile | 19 + .../nym-network-monitor-orchestrator/build.rs | 37 + .../migrations/01_initial_tables.sql | 139 ++ .../src/cli/build_info.rs | 15 + .../src/cli/env.rs | 40 + .../src/cli/mod.rs | 50 + .../src/cli/run_orchestrator.rs | 214 +++ .../src/http/api/api_docs.rs | 52 + .../src/http/api/mod.rs | 69 + .../src/http/api/v1/agent/mod.rs | 243 +++ .../src/http/api/v1/error.rs | 51 + .../src/http/api/v1/metrics/mod.rs | 30 + .../src/http/api/v1/mod.rs | 29 + .../src/http/api/v1/results/mod.rs | 230 +++ .../src/http/mod.rs | 5 + .../src/http/state.rs | 471 +++++ .../src/main.rs | 50 + .../src/orchestrator/config.rs | 123 ++ .../src/orchestrator/mod.rs | 336 ++++ .../src/orchestrator/node_refresher.rs | 243 +++ .../src/orchestrator/prometheus.rs | 437 +++++ .../src/orchestrator/result_submitter.rs | 141 ++ .../orchestrator/stale_results_eviction.rs | 146 ++ .../src/orchestrator/testruns.rs | 2 + .../src/storage/manager.rs | 1540 ++++++++++++++++ .../src/storage/mod.rs | 279 +++ .../src/storage/models.rs | 406 ++++ .../src/metrics_scraper/error.rs | 155 -- .../src/metrics_scraper/mod.rs | 60 +- nym-node/Cargo.toml | 5 +- nym-node/nym-node-metrics/src/mixnet.rs | 22 + .../src/prometheus_wrapper.rs | 8 +- nym-node/nym-node-requests/Cargo.toml | 6 +- nym-node/nym-node-requests/src/api/helpers.rs | 255 +++ nym-node/nym-node-requests/src/api/mod.rs | 1 + .../src/api/v1/metrics/models.rs | 3 + nym-node/nym-node-requests/src/error.rs | 41 + nym-node/nym-node-requests/src/lib.rs | 7 +- .../src/cli/commands/reset_sphinx_keys.rs | 2 +- nym-node/src/cli/commands/run/args.rs | 7 +- nym-node/src/cli/helpers.rs | 49 +- nym-node/src/config/helpers.rs | 4 +- nym-node/src/config/mod.rs | 116 +- nym-node/src/config/old_configs/mod.rs | 2 + .../src/config/old_configs/old_config_v12.rs | 456 +---- .../src/config/old_configs/old_config_v13.rs | 923 ++++++++++ nym-node/src/config/template.rs | 17 +- nym-node/src/config/upgrade_helpers.rs | 3 +- nym-node/src/env.rs | 5 +- nym-node/src/error.rs | 7 + .../router/api/v1/metrics/packets_stats.rs | 1 + .../handler/global_prometheus_updater/mod.rs | 4 + nym-node/src/node/mixnet/handler.rs | 106 +- .../src/node/mixnet/packet_forwarding/mod.rs | 5 +- nym-node/src/node/mixnet/shared/mod.rs | 42 +- nym-node/src/node/mod.rs | 176 +- nym-node/src/node/nym_apis_client.rs | 55 +- nym-node/src/node/nyxd_watcher/mod.rs | 4 + .../nyxd_watcher/network_monitor_agents.rs | 295 +++ nym-node/src/node/routing_filter/mod.rs | 4 +- .../src/node/routing_filter/network_filter.rs | 208 ++- nym-node/src/node/shared_network.rs | 446 ----- nym-node/src/node/shared_network/mod.rs | 56 + nym-node/src/node/shared_network/refresher.rs | 337 ++++ .../node/shared_network/topology_provider.rs | 79 + nym-wallet/Cargo.lock | 15 +- .../nym-wallet-types/src/network/sandbox.rs | 6 + .../src/operations/nym_api/status.rs | 4 +- nyx-chain-watcher/src/chain_scraper/mod.rs | 32 +- nyx-chain-watcher/src/http/state.rs | 6 +- tools/ts-rs-cli/src/main.rs | 16 +- 215 files changed, 19059 insertions(+), 1858 deletions(-) create mode 100644 common/client-libs/validator-client/src/nyxd/contract_traits/network_monitors_query_client.rs create mode 100644 common/client-libs/validator-client/src/nyxd/contract_traits/network_monitors_signing_client.rs create mode 100644 common/cosmwasm-smart-contracts/network-monitors-contract/Cargo.toml create mode 100644 common/cosmwasm-smart-contracts/network-monitors-contract/src/constants.rs create mode 100644 common/cosmwasm-smart-contracts/network-monitors-contract/src/error.rs create mode 100644 common/cosmwasm-smart-contracts/network-monitors-contract/src/lib.rs create mode 100644 common/cosmwasm-smart-contracts/network-monitors-contract/src/msg.rs create mode 100644 common/cosmwasm-smart-contracts/network-monitors-contract/src/types.rs delete mode 100644 common/network-defaults/src/sandbox.rs create mode 100644 contracts/network-monitors/.cargo/config create mode 100644 contracts/network-monitors/Cargo.toml create mode 100644 contracts/network-monitors/Makefile create mode 100644 contracts/network-monitors/schema/network-monitors.json create mode 100644 contracts/network-monitors/schema/raw/execute.json create mode 100644 contracts/network-monitors/schema/raw/instantiate.json create mode 100644 contracts/network-monitors/schema/raw/migrate.json create mode 100644 contracts/network-monitors/schema/raw/query.json create mode 100644 contracts/network-monitors/schema/raw/response_to_admin.json create mode 100644 contracts/network-monitors/schema/raw/response_to_network_monitor_agents.json create mode 100644 contracts/network-monitors/schema/raw/response_to_network_monitor_orchestrators.json create mode 100644 contracts/network-monitors/src/bin/schema.rs create mode 100644 contracts/network-monitors/src/contract.rs create mode 100644 contracts/network-monitors/src/lib.rs create mode 100644 contracts/network-monitors/src/queries.rs create mode 100644 contracts/network-monitors/src/queued_migrations.rs create mode 100644 contracts/network-monitors/src/storage.rs create mode 100644 contracts/network-monitors/src/testing/mod.rs create mode 100644 contracts/network-monitors/src/transactions.rs create mode 100644 nym-api/migrations/20260424120000_stress_testing.sql create mode 100644 nym-api/src/nym_nodes/handlers/v3.rs create mode 100644 nym-api/src/support/http/state/network_monitors.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/Cargo.toml create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/Dockerfile create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/README.md create mode 100755 nym-network-monitor-v3/nym-network-monitor-agent/build-push-node-status-agent.sh create mode 100755 nym-network-monitor-v3/nym-network-monitor-agent/entrypoint.sh create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/src/agent/config.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/src/agent/helpers.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/src/agent/mod.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/src/agent/result.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/src/agent/tested_node.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/src/agent/tester.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/src/cli/build_info.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/src/cli/common.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/src/cli/env.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/src/cli/keygen.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/src/cli/mod.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/src/cli/run_agent.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/src/cli/test_node.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/src/egress_connection.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/src/listener/mod.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/src/listener/received.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/src/main.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/src/processor.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/src/sphinx_helpers.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-agent/src/test_packet.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/Cargo.toml create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/src/api/mod.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/src/client.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/src/lib.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/src/models.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/Cargo.toml create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/Dockerfile create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/build.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/migrations/01_initial_tables.sql create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/build_info.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/env.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/mod.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/run_orchestrator.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/api_docs.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/mod.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/agent/mod.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/error.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/metrics/mod.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/mod.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/results/mod.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/mod.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/state.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/main.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/config.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/mod.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/node_refresher.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/prometheus.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/result_submitter.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/stale_results_eviction.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/testruns.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/storage/manager.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/storage/mod.rs create mode 100644 nym-network-monitor-v3/nym-network-monitor-orchestrator/src/storage/models.rs delete mode 100644 nym-node-status-api/nym-node-status-api/src/metrics_scraper/error.rs create mode 100644 nym-node/nym-node-requests/src/api/helpers.rs create mode 100644 nym-node/src/config/old_configs/old_config_v13.rs create mode 100644 nym-node/src/node/nyxd_watcher/mod.rs create mode 100644 nym-node/src/node/nyxd_watcher/network_monitor_agents.rs delete mode 100644 nym-node/src/node/shared_network.rs create mode 100644 nym-node/src/node/shared_network/mod.rs create mode 100644 nym-node/src/node/shared_network/refresher.rs create mode 100644 nym-node/src/node/shared_network/topology_provider.rs diff --git a/Cargo.lock b/Cargo.lock index 5dc706e4fc..62bab445e4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7418,7 +7418,6 @@ version = "1.20.4" dependencies = [ "cargo_metadata 0.19.2", "dotenvy", - "log", "regex", "schemars 0.8.22", "serde", @@ -7463,6 +7462,100 @@ dependencies = [ "utoipa-swagger-ui", ] +[[package]] +name = "nym-network-monitor-agent" +version = "1.0.2" +dependencies = [ + "anyhow", + "arrayref", + "clap", + "futures", + "hkdf", + "humantime", + "lioness", + "nym-bin-common", + "nym-crypto", + "nym-network-monitor-orchestrator-requests", + "nym-noise", + "nym-pemstore", + "nym-sphinx-addressing", + "nym-sphinx-framing", + "nym-sphinx-params", + "nym-sphinx-types", + "nym-task", + "nym-test-utils", + "rand 0.8.5", + "sha2 0.10.9", + "time", + "tokio", + "tokio-util", + "tracing", + "url", + "x25519-dalek", + "zeroize", +] + +[[package]] +name = "nym-network-monitor-orchestrator" +version = "1.0.2" +dependencies = [ + "anyhow", + "axum 0.7.9", + "clap", + "futures", + "humantime", + "nym-api-requests", + "nym-bin-common", + "nym-crypto", + "nym-http-api-common", + "nym-metrics", + "nym-network-defaults", + "nym-network-monitor-orchestrator-requests", + "nym-node-requests", + "nym-task", + "nym-test-utils", + "nym-validator-client", + "rand 0.8.5", + "sqlx", + "strum 0.28.0", + "thiserror 2.0.12", + "time", + "tokio", + "tracing", + "url", + "utoipa", + "utoipa-swagger-ui", + "utoipauto", + "zeroize", +] + +[[package]] +name = "nym-network-monitor-orchestrator-requests" +version = "1.20.4" +dependencies = [ + "anyhow", + "humantime-serde", + "nym-crypto", + "nym-http-api-client", + "serde", + "time", + "tracing", + "utoipa", + "zeroize", +] + +[[package]] +name = "nym-network-monitors-contract-common" +version = "1.20.4" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers", + "schemars 0.8.22", + "serde", + "thiserror 2.0.12", +] + [[package]] name = "nym-network-requester" version = "1.1.78" @@ -7584,6 +7677,7 @@ dependencies = [ "nym-verloc", "nym-wireguard", "nym-wireguard-types", + "nyxd-scraper-shared", "opentelemetry", "opentelemetry_sdk", "rand 0.8.5", @@ -7634,6 +7728,7 @@ dependencies = [ "nym-exit-policy", "nym-http-api-client", "nym-kkt-ciphersuite", + "nym-network-defaults", "nym-noise-keys", "nym-test-utils", "nym-upgrade-mode-check", @@ -8572,6 +8667,7 @@ dependencies = [ "nym-mixnet-contract-common", "nym-multisig-contract-common", "nym-network-defaults", + "nym-network-monitors-contract-common", "nym-performance-contract-common", "nym-serde-helpers", "nym-vesting-contract-common", diff --git a/Cargo.toml b/Cargo.toml index 14ab79e00a..7025c29062 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,7 @@ members = [ "common/cosmwasm-smart-contracts/nym-performance-contract", "common/cosmwasm-smart-contracts/nym-pool-contract", "common/cosmwasm-smart-contracts/vesting-contract", + "common/cosmwasm-smart-contracts/network-monitors-contract", "common/credential-proxy", "common/credential-storage", "common/credential-utils", @@ -176,6 +177,8 @@ members = [ "integration-tests", "common/nym-kkt-ciphersuite", "common/nym-kkt-context", + "nym-network-monitor-v3/nym-network-monitor-orchestrator", + "nym-network-monitor-v3/nym-network-monitor-agent", "nym-network-monitor-v3/nym-network-monitor-orchestrator-requests", ] default-members = [ @@ -192,6 +195,8 @@ default-members = [ "service-providers/network-requester", "tools/nymvisor", "nym-registration-client", + "nym-network-monitor-v3/nym-network-monitor-orchestrator", + "nym-network-monitor-v3/nym-network-monitor-agent", "tools/internal/localnet-orchestrator" ] @@ -402,6 +407,10 @@ zeroize = "1.7.0" prometheus = { version = "0.14.0" } +# recreating lioness +# we don't care about particular versions - just pull whatever is used by sphinx +lioness = "*" +arrayref = "*" # libcrux libcrux-kem = "0.0.7" @@ -507,6 +516,7 @@ nym-types = { version = "1.20.4", path = "common/types" } nym-upgrade-mode-check = { version = "1.20.4", path = "common/upgrade-mode-check" } nym-validator-client = { version = "1.20.4", path = "common/client-libs/validator-client", default-features = false } nym-vesting-contract-common = { version = "1.20.4", path = "common/cosmwasm-smart-contracts/vesting-contract" } +nym-network-monitors-contract-common = { version = "1.20.4", path = "common/cosmwasm-smart-contracts/network-monitors-contract" } nym-verloc = { version = "1.20.4", path = "common/verloc" } nym-wireguard = { version = "1.20.4", path = "common/wireguard" } nym-wireguard-types = { version = "1.20.4", path = "common/wireguard-types" } diff --git a/common/client-core/src/client/mix_traffic/transceiver.rs b/common/client-core/src/client/mix_traffic/transceiver.rs index 8edc17dbfb..3ec27c0488 100644 --- a/common/client-core/src/client/mix_traffic/transceiver.rs +++ b/common/client-core/src/client/mix_traffic/transceiver.rs @@ -240,7 +240,7 @@ mod nonwasm_sealed { impl GatewaySender for LocalGateway { async fn send_mix_packet(&mut self, packet: MixPacket) -> Result<(), ErasedGatewayError> { self.packet_forwarder - .forward_packet(packet) + .forward_client_packet_without_delay(packet) .map_err(erase_err) } } diff --git a/common/client-libs/mixnet-client/Cargo.toml b/common/client-libs/mixnet-client/Cargo.toml index 614e4e698e..353da725bd 100644 --- a/common/client-libs/mixnet-client/Cargo.toml +++ b/common/client-libs/mixnet-client/Cargo.toml @@ -34,3 +34,4 @@ client = ["tokio-util", "nym-task", "tokio/net", "tokio/rt"] [dev-dependencies] nym-crypto = { workspace = true } rand = { workspace = true } +tokio = { workspace = true, features = ["macros", "io-util", "rt", "rt-multi-thread"] } diff --git a/common/client-libs/mixnet-client/src/client.rs b/common/client-libs/mixnet-client/src/client.rs index 0bdb06a198..9cef37e2d2 100644 --- a/common/client-libs/mixnet-client/src/client.rs +++ b/common/client-libs/mixnet-client/src/client.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use dashmap::DashMap; -use futures::StreamExt; +use futures::{SinkExt, StreamExt}; use nym_noise::config::NoiseConfig; use nym_noise::upgrade_noise_initiator; use nym_sphinx::forwarding::packet::MixPacket; @@ -14,6 +14,7 @@ use std::ops::Deref; use std::sync::atomic::{AtomicU32, AtomicUsize, Ordering}; use std::sync::Arc; use std::time::Duration; +use tokio::io::{AsyncRead, AsyncWrite}; use tokio::net::TcpStream; use tokio::sync::mpsc; use tokio::sync::mpsc::error::TrySendError; @@ -90,13 +91,17 @@ impl Deref for ActiveConnections { pub struct ConnectionSender { channel: mpsc::Sender, current_reconnection_attempt: Arc, + // Identifies the `ManagedConnection` task currently owning this entry; used + // to ensure drop-time eviction only fires on the still-owning task. + handle_token: Arc<()>, } impl ConnectionSender { - fn new(channel: mpsc::Sender) -> Self { + fn new(channel: mpsc::Sender, handle_token: Arc<()>) -> Self { ConnectionSender { channel, current_reconnection_attempt: Arc::new(AtomicU32::new(0)), + handle_token, } } } @@ -107,6 +112,31 @@ struct ManagedConnection { message_receiver: ReceiverStream, connection_timeout: Duration, current_reconnection: Arc, + active_connections: ActiveConnections, + handle_token: Arc<()>, +} + +// Evicts the cache entry on task exit (only if still owned by this task). +// Without this, a stale `ConnectionSender` survives after the peer disconnects +// and the next outbound packet is silently swallowed by the dead TCP. +struct EvictOnDrop { + active_connections: ActiveConnections, + address: SocketAddr, + handle_token: Arc<()>, +} + +impl Drop for EvictOnDrop { + fn drop(&mut self) { + let address = self.address; + let handle_token = &self.handle_token; + self.active_connections.remove_if(&address, |_, sender| { + Arc::ptr_eq(&sender.handle_token, handle_token) + }); + trace!( + peer = %address, + "managed connection task exited; evicted owning cache entry" + ); + } } impl ManagedConnection { @@ -116,6 +146,8 @@ impl ManagedConnection { message_receiver: mpsc::Receiver, connection_timeout: Duration, current_reconnection: Arc, + active_connections: ActiveConnections, + handle_token: Arc<()>, ) -> Self { ManagedConnection { address, @@ -123,72 +155,30 @@ impl ManagedConnection { message_receiver: ReceiverStream::new(message_receiver), connection_timeout, current_reconnection, + active_connections, + handle_token, } } async fn run(self) { let address = self.address; + let _evict_guard = EvictOnDrop { + active_connections: self.active_connections, + address, + handle_token: self.handle_token, + }; + let reconnection_attempt = self.current_reconnection.load(Ordering::Acquire); let connect_start = tokio::time::Instant::now(); let connection_fut = TcpStream::connect(address); - let conn = match tokio::time::timeout(self.connection_timeout, connection_fut).await { - Ok(stream_res) => match stream_res { - Ok(stream) => { - let connect_ms = connect_start.elapsed().as_millis() as u64; - debug!( - peer = %address, - connect_ms, - "Managed to establish connection to {}", self.address - ); - - let noise_start = tokio::time::Instant::now(); - let noise_stream = - match upgrade_noise_initiator(stream, &self.noise_config).await { - Ok(noise_stream) => noise_stream, - Err(err) => { - let noise_handshake_ms = noise_start.elapsed().as_millis() as u64; - warn!( - event = "connection.failed.noise", - peer = %address, - error = %err, - connect_ms, - noise_handshake_ms, - reconnection_attempt, - exit_reason = "noise_error", - "Failed to perform Noise initiator handshake with {address}" - ); - self.current_reconnection.fetch_add(1, Ordering::SeqCst); - return; - } - }; - let noise_handshake_ms = noise_start.elapsed().as_millis() as u64; - self.current_reconnection.store(0, Ordering::Release); - debug!( - peer = %address, - connect_ms, - noise_handshake_ms, - "Noise initiator handshake completed for {:?}", address - ); - Framed::new(noise_stream, NymCodec) - } - Err(err) => { - let connect_ms = connect_start.elapsed().as_millis() as u64; - warn!( - event = "connection.failed.connect", - peer = %address, - error = %err, - connect_ms, - reconnection_attempt, - exit_reason = "connect_error", - "failed to establish connection to {address}" - ); - return; - } - }, + // 1. attempt to establish the connection with timeout + let maybe_stream = match tokio::time::timeout(self.connection_timeout, connection_fut).await + { + Ok(stream) => stream, Err(_) => { let connect_ms = connect_start.elapsed().as_millis() as u64; - warn!( + debug!( event = "connection.failed.timeout", peer = %address, timeout_ms = self.connection_timeout.as_millis() as u64, @@ -203,21 +193,133 @@ impl ManagedConnection { } }; - if let Err(err) = self.message_receiver.map(Ok).forward(conn).await { - warn!( - event = "connection.forward_error", - peer = %address, - error = %err, - exit_reason = "forward_error", - "Failed to forward packets to {address}: {err}" - ); - } + // 2. check if it actually succeeded + let stream = match maybe_stream { + Ok(stream) => stream, + Err(err) => { + let connect_ms = connect_start.elapsed().as_millis() as u64; + debug!( + event = "connection.failed.connect", + peer = %address, + error = %err, + connect_ms, + reconnection_attempt, + exit_reason = "connect_error", + "failed to establish connection to {address}" + ); + return; + } + }; + let connect_ms = connect_start.elapsed().as_millis() as u64; debug!( peer = %address, - exit_reason = "sender_dropped", - "connection manager to {address} finished" + connect_ms, + "Managed to establish connection to {}", self.address ); + + // 3. perform noise handshake (if applicable) + let noise_start = tokio::time::Instant::now(); + let noise_stream = match upgrade_noise_initiator(stream, &self.noise_config).await { + Ok(noise_stream) => noise_stream, + Err(err) => { + let noise_handshake_ms = noise_start.elapsed().as_millis() as u64; + debug!( + event = "connection.failed.noise", + peer = %address, + error = %err, + connect_ms, + noise_handshake_ms, + reconnection_attempt, + exit_reason = "noise_error", + "Failed to perform Noise initiator handshake with {address}" + ); + self.current_reconnection.fetch_add(1, Ordering::SeqCst); + return; + } + }; + let noise_handshake_ms = noise_start.elapsed().as_millis() as u64; + self.current_reconnection.store(0, Ordering::Release); + debug!( + peer = %address, + connect_ms, + noise_handshake_ms, + "Noise initiator handshake completed for {:?}", address + ); + let conn = Framed::new(noise_stream, NymCodec); + + // 4. start handling the framed stream + run_io_loop(conn, self.message_receiver, address).await; + } +} + +// The connection is unidirectional (send-only); we read from it solely to +// notice peer FIN/RST while idle so we can evict the cache entry before the +// next outbound send finds it stale. +async fn run_io_loop( + conn: Framed, + mut receiver: ReceiverStream, + address: SocketAddr, +) where + T: AsyncRead + AsyncWrite + Unpin, +{ + let (mut sink, mut stream) = conn.split(); + + loop { + tokio::select! { + msg = stream.next() => { + match msg { + None => { + debug!( + peer = %address, + exit_reason = "peer_closed", + "peer closed mixnet connection to {address}" + ); + break; + } + Some(Err(err)) => { + debug!( + event = "connection.read_error", + peer = %address, + error = %err, + exit_reason = "read_error", + "read error on mixnet connection to {address}: {err}" + ); + break; + } + Some(Ok(_)) => { + trace!( + peer = %address, + "unexpected inbound packet on mixnet connection to {address}; discarding" + ); + } + } + } + outgoing = receiver.next() => { + match outgoing { + None => { + debug!( + peer = %address, + exit_reason = "sender_dropped", + "connection manager to {address} finished" + ); + break; + } + Some(packet) => { + if let Err(err) = sink.send(packet).await { + debug!( + event = "connection.forward_error", + peer = %address, + error = %err, + exit_reason = "forward_error", + "Failed to forward packet to {address}: {err}" + ); + break; + } + } + } + } + } } } @@ -264,13 +366,18 @@ impl Client { sender.try_send(pending_packet).unwrap(); } + // Ownership token for the task we're about to spawn; lets it tell + // on exit whether the cache entry still names it. + let handle_token = Arc::new(()); + // if we already tried to connect to `address` before, grab the current attempt count let current_reconnection_attempt = if let Some(mut existing) = self.active_connections.get_mut(&address) { existing.channel = sender; + existing.handle_token = Arc::clone(&handle_token); Arc::clone(&existing.current_reconnection_attempt) } else { - let new_entry = ConnectionSender::new(sender); + let new_entry = ConnectionSender::new(sender, Arc::clone(&handle_token)); let current_attempt = Arc::clone(&new_entry.current_reconnection_attempt); self.active_connections.insert(address, new_entry); current_attempt @@ -285,6 +392,7 @@ impl Client { let connections_count = self.connections_count.clone(); let noise_config = self.noise_config.clone(); + let active_connections = self.active_connections.clone(); tokio::spawn(async move { // before executing the manager, wait for what was specified, if anything if let Some(backoff) = backoff { @@ -299,6 +407,8 @@ impl Client { receiver, initial_connection_timeout, current_reconnection_attempt, + active_connections, + handle_token, ) .run() .await; @@ -428,4 +538,102 @@ mod tests { client.config.maximum_reconnection_backoff ); } + + fn test_addr() -> SocketAddr { + "127.0.0.1:1".parse().unwrap() + } + + fn insert_with_token( + active: &ActiveConnections, + addr: SocketAddr, + token: Arc<()>, + ) -> mpsc::Receiver { + let (tx, rx) = mpsc::channel(1); + active.insert(addr, ConnectionSender::new(tx, token)); + rx + } + + #[test] + fn evict_on_drop_removes_entry_when_token_still_matches() { + let active = ActiveConnections::default(); + let addr = test_addr(); + let token = Arc::new(()); + let _rx = insert_with_token(&active, addr, Arc::clone(&token)); + + assert!(active.get(&addr).is_some()); + + { + let _guard = EvictOnDrop { + active_connections: active.clone(), + address: addr, + handle_token: token, + }; + } + + assert!( + active.get(&addr).is_none(), + "owning task's drop should evict the entry" + ); + } + + #[test] + fn evict_on_drop_preserves_entry_replaced_by_newer_make_connection() { + // Simulates the race: old task's run() has returned, but before its + // drop guard fires, a concurrent `make_connection` replaced the + // entry's channel + handle_token with a fresh task's token. + let active = ActiveConnections::default(); + let addr = test_addr(); + let old_token = Arc::new(()); + let new_token = Arc::new(()); + let _rx_new = insert_with_token(&active, addr, Arc::clone(&new_token)); + + { + let _guard = EvictOnDrop { + active_connections: active.clone(), + address: addr, + handle_token: old_token, + }; + } + + assert!( + active.get(&addr).is_some(), + "old task's drop must not clobber the newer entry" + ); + } + + #[tokio::test] + async fn io_loop_exits_when_peer_closes_idle_connection() { + // The fix's second half: while no packets are flowing, peer FIN/RST + // must still be observed so the cache entry can be evicted before the + // next send finds it stale. + let (a, b) = tokio::io::duplex(64); + let conn = Framed::new(a, NymCodec); + let (_tx, rx) = mpsc::channel(1); + + let task = tokio::spawn(run_io_loop(conn, ReceiverStream::new(rx), test_addr())); + + // Simulate peer closing both directions of the connection. + drop(b); + + tokio::time::timeout(Duration::from_secs(1), task) + .await + .expect("io_loop must notice peer close while idle") + .expect("io_loop task must not panic"); + } + + #[tokio::test] + async fn io_loop_exits_when_sender_dropped() { + let (a, _b) = tokio::io::duplex(64); + let conn = Framed::new(a, NymCodec); + let (tx, rx) = mpsc::channel(1); + + let task = tokio::spawn(run_io_loop(conn, ReceiverStream::new(rx), test_addr())); + + drop(tx); + + tokio::time::timeout(Duration::from_secs(1), task) + .await + .expect("io_loop must exit when the upstream sender is dropped") + .expect("io_loop task must not panic"); + } } diff --git a/common/client-libs/mixnet-client/src/forwarder.rs b/common/client-libs/mixnet-client/src/forwarder.rs index d7815be92f..402a3b056a 100644 --- a/common/client-libs/mixnet-client/src/forwarder.rs +++ b/common/client-libs/mixnet-client/src/forwarder.rs @@ -21,12 +21,16 @@ impl From> for MixForwardingSender { } impl MixForwardingSender { - pub fn forward_packet(&self, packet: impl Into) -> Result<(), SendError> { + pub fn forward_packet(&self, packet: PacketToForward) -> Result<(), SendError> { self.0 - .unbounded_send(packet.into()) + .unbounded_send(packet) .map_err(|err| err.into_send_error()) } + pub fn forward_client_packet_without_delay(&self, packet: MixPacket) -> Result<(), SendError> { + self.forward_packet(PacketToForward::client_packet_without_delay(packet)) + } + #[allow(clippy::len_without_is_empty)] pub fn len(&self) -> usize { self.0.len() @@ -38,35 +42,23 @@ pub type MixForwardingReceiver = mpsc::UnboundedReceiver; pub struct PacketToForward { pub packet: MixPacket, pub forward_delay_target: Option, -} - -impl From for PacketToForward { - fn from(packet: MixPacket) -> Self { - PacketToForward::new_no_delay(packet) - } -} - -impl From<(MixPacket, Option)> for PacketToForward { - fn from((packet, delay_until): (MixPacket, Option)) -> Self { - PacketToForward::new(packet, delay_until) - } -} - -impl From<(MixPacket, Instant)> for PacketToForward { - fn from((packet, delay_until): (MixPacket, Instant)) -> Self { - PacketToForward::new(packet, Some(delay_until)) - } + pub network_monitor_packet: bool, } impl PacketToForward { - pub fn new(packet: MixPacket, forward_delay_target: Option) -> Self { + pub fn new( + packet: MixPacket, + forward_delay_target: Option, + network_monitor_packet: bool, + ) -> Self { PacketToForward { packet, forward_delay_target, + network_monitor_packet, } } - pub fn new_no_delay(packet: MixPacket) -> Self { - Self::new(packet, None) + pub fn client_packet_without_delay(packet: MixPacket) -> Self { + Self::new(packet, None, false) } } diff --git a/common/client-libs/validator-client/Cargo.toml b/common/client-libs/validator-client/Cargo.toml index ea1de63563..61bfc64cf9 100644 --- a/common/client-libs/validator-client/Cargo.toml +++ b/common/client-libs/validator-client/Cargo.toml @@ -26,6 +26,7 @@ nym-ecash-contract-common = { workspace = true } nym-multisig-contract-common = { workspace = true } nym-group-contract-common = { workspace = true } nym-performance-contract-common = { workspace = true } +nym-network-monitors-contract-common = { workspace = true } nym-serde-helpers = { workspace = true, features = ["hex", "base64"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } diff --git a/common/client-libs/validator-client/src/client.rs b/common/client-libs/validator-client/src/client.rs index 19977987b8..8507b0fcb4 100644 --- a/common/client-libs/validator-client/src/client.rs +++ b/common/client-libs/validator-client/src/client.rs @@ -104,6 +104,14 @@ impl TryFrom for Config { } impl Config { + pub fn new(nyxd_url: Url, api_url: Url, nyxd_config: nyxd::Config) -> Self { + Config { + api_url, + nyxd_url, + nyxd_config, + } + } + pub fn try_from_nym_network_details( details: &NymNetworkDetails, ) -> Result { @@ -114,6 +122,15 @@ impl Config { .map(|url| Url::parse(url)) .collect::, _>>()?; + if let Some(nym_api_urls) = details.nym_api_urls.as_ref() { + api_url.extend( + nym_api_urls + .iter() + .map(|url| url.url.parse()) + .collect::, _>>()?, + ); + } + if api_url.is_empty() { return Err(ValidatorClientError::NoAPIUrlAvailable); } diff --git a/common/client-libs/validator-client/src/nym_api/mod.rs b/common/client-libs/validator-client/src/nym_api/mod.rs index e2dffe496e..dc2739ea48 100644 --- a/common/client-libs/validator-client/src/nym_api/mod.rs +++ b/common/client-libs/validator-client/src/nym_api/mod.rs @@ -15,11 +15,15 @@ use nym_api_requests::ecash::models::{ VerifyEcashTicketBody, }; use nym_api_requests::ecash::VerificationKeyResponse; +use nym_api_requests::models::network_monitor::{ + KnownNetworkMonitorResponse, StressTestBatchSubmission, +}; use nym_api_requests::models::{ - AnnotationResponse, ApiHealthResponse, BinaryBuildInformationOwned, ChainBlocksStatusResponse, - ChainStatusResponse, KeyRotationInfoResponse, NodePerformanceResponse, NodeRefreshBody, - NymNodeDescriptionV1, NymNodeDescriptionV2, PerformanceHistoryResponse, RewardedSetResponse, - SignerInformationResponse, + AnnotationResponseV1, ApiHealthResponse, BinaryBuildInformationOwned, + ChainBlocksStatusResponse, ChainStatusResponse, KeyRotationInfoResponse, + NodePerformanceResponse, NodeRefreshBody, NymNodeDescriptionV1, NymNodeDescriptionV2, + PerformanceHistoryResponse, RewardedSetResponse, SignerInformationResponse, + StressTestBatchSubmissionResponse, }; use nym_api_requests::pagination::PaginatedResponse; use nym_http_api_client::{ApiClient, NO_PARAMS}; @@ -976,7 +980,7 @@ pub trait NymApiClientExt: ApiClient { async fn get_node_annotation( &self, node_id: NodeId, - ) -> Result { + ) -> Result { self.get_json( &[ routes::V1_API_VERSION, @@ -1359,6 +1363,53 @@ pub trait NymApiClientExt: ApiClient { Ok(SemiSkimmedNodesWithMetadata::new(nodes, metadata)) } + + /// Queries the nym-api for whether a particular ed25519 identity key is currently recognised + /// as an authorised network monitor permitted to submit stress testing results. + /// + /// `identity_key` is expected to be the base58-encoded form of the ed25519 public key. + #[instrument(level = "debug", skip(self))] + async fn get_known_network_monitor( + &self, + identity_key: IdentityKeyRef<'_>, + ) -> Result { + self.get_json( + &[ + routes::V3_API_VERSION, + routes::NYM_NODES_ROUTES, + routes::STRESS_TESTING, + routes::STRESS_TESTING_KNOWN_MONITORS, + identity_key, + ], + NO_PARAMS, + ) + .await + } + + /// Submit a signed batch of stress-testing results to nym-api on behalf of a network monitor + /// orchestrator. + /// + /// The caller is expected to have produced `request` via + /// `StressTestBatchSubmissionContent::new(...)` and signed it with the orchestrator's ed25519 + /// key; nym-api will reject submissions that are stale, replayed, unauthorised, or whose + /// signature fails to verify. + #[instrument(level = "debug", skip(self, request))] + async fn submit_stress_testing_results( + &self, + request: &StressTestBatchSubmission, + ) -> Result { + self.post_json( + &[ + routes::V3_API_VERSION, + routes::NYM_NODES_ROUTES, + routes::STRESS_TESTING, + routes::STRESS_TESTING_BATCH_SUBMIT, + ], + NO_PARAMS, + request, + ) + .await + } } // Client is already nym_http_api_client::Client (re-exported above), so just one impl needed diff --git a/common/client-libs/validator-client/src/nym_api/routes.rs b/common/client-libs/validator-client/src/nym_api/routes.rs index 755b1282ef..8320944f2f 100644 --- a/common/client-libs/validator-client/src/nym_api/routes.rs +++ b/common/client-libs/validator-client/src/nym_api/routes.rs @@ -49,6 +49,9 @@ pub mod nym_nodes { pub const NYM_NODES_REWARDED_SET: &str = "rewarded-set"; pub const NYM_NODES_REFRESH_DESCRIBED: &str = "refresh-described"; pub const BY_ADDRESSES: &str = "by-addresses"; + pub const STRESS_TESTING: &str = "stress-testing"; + pub const STRESS_TESTING_KNOWN_MONITORS: &str = "known-monitors"; + pub const STRESS_TESTING_BATCH_SUBMIT: &str = "batch-submit"; } pub const STATUS_ROUTES: &str = "status"; diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs index ad7db0991b..3dd4bb70fe 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/mod.rs @@ -13,6 +13,7 @@ pub mod ecash_query_client; pub mod group_query_client; pub mod mixnet_query_client; pub mod multisig_query_client; +pub mod network_monitors_query_client; pub mod performance_query_client; pub mod vesting_query_client; @@ -22,6 +23,7 @@ pub mod ecash_signing_client; pub mod group_signing_client; pub mod mixnet_signing_client; pub mod multisig_signing_client; +pub mod network_monitors_signing_client; pub mod performance_signing_client; pub mod vesting_signing_client; @@ -31,6 +33,9 @@ pub use ecash_query_client::{EcashQueryClient, PagedEcashQueryClient}; pub use group_query_client::{GroupQueryClient, PagedGroupQueryClient}; pub use mixnet_query_client::{MixnetQueryClient, PagedMixnetQueryClient}; pub use multisig_query_client::{MultisigQueryClient, PagedMultisigQueryClient}; +pub use network_monitors_query_client::{ + NetworkMonitorsQueryClient, PagedNetworkMonitorsQueryClient, +}; pub use performance_query_client::{PagedPerformanceQueryClient, PerformanceQueryClient}; pub use vesting_query_client::{PagedVestingQueryClient, VestingQueryClient}; @@ -40,6 +45,7 @@ pub use ecash_signing_client::EcashSigningClient; pub use group_signing_client::GroupSigningClient; pub use mixnet_signing_client::MixnetSigningClient; pub use multisig_signing_client::MultisigSigningClient; +pub use network_monitors_signing_client::NetworkMonitorsSigningClient; pub use performance_signing_client::PerformanceSigningClient; pub use vesting_signing_client::VestingSigningClient; @@ -49,6 +55,7 @@ pub trait NymContractsProvider { fn mixnet_contract_address(&self) -> Option<&AccountId>; fn vesting_contract_address(&self) -> Option<&AccountId>; fn performance_contract_address(&self) -> Option<&AccountId>; + fn network_monitors_contract_address(&self) -> Option<&AccountId>; // coconut-related fn ecash_contract_address(&self) -> Option<&AccountId>; @@ -62,6 +69,7 @@ pub struct TypedNymContracts { pub mixnet_contract_address: Option, pub vesting_contract_address: Option, pub performance_contract_address: Option, + pub network_monitors_contract_address: Option, pub ecash_contract_address: Option, pub group_contract_address: Option, @@ -86,6 +94,10 @@ impl TryFrom for TypedNymContracts { .performance_contract_address .map(|addr| addr.parse()) .transpose()?, + network_monitors_contract_address: value + .network_monitors_contract_address + .map(|addr| addr.parse()) + .transpose()?, ecash_contract_address: value .ecash_contract_address .map(|addr| addr.parse()) diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/network_monitors_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/network_monitors_query_client.rs new file mode 100644 index 0000000000..86e7767b84 --- /dev/null +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/network_monitors_query_client.rs @@ -0,0 +1,107 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::collect_paged; +use crate::nyxd::contract_traits::NymContractsProvider; +use crate::nyxd::error::NyxdError; +use crate::nyxd::CosmWasmClient; +use async_trait::async_trait; +use nym_network_monitors_contract_common::{ + AuthorisedNetworkMonitor, AuthorisedNetworkMonitorOrchestratorsResponse, + AuthorisedNetworkMonitorsPagedResponse, QueryMsg as NetworkMonitorsQueryMsg, +}; +use serde::Deserialize; +use std::net::SocketAddr; + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +pub trait NetworkMonitorsQueryClient { + async fn query_network_monitors_contract( + &self, + query: NetworkMonitorsQueryMsg, + ) -> Result + where + for<'a> T: Deserialize<'a>; + + async fn get_admin(&self) -> Result { + self.query_network_monitors_contract(NetworkMonitorsQueryMsg::Admin {}) + .await + } + + async fn get_network_monitor_orchestrators( + &self, + ) -> Result { + self.query_network_monitors_contract( + NetworkMonitorsQueryMsg::NetworkMonitorOrchestrators {}, + ) + .await + } + + async fn get_network_monitor_agents_paged( + &self, + start_next_after: Option, + limit: Option, + ) -> Result { + self.query_network_monitors_contract(NetworkMonitorsQueryMsg::NetworkMonitorAgents { + start_next_after, + limit, + }) + .await + } +} + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +pub trait PagedNetworkMonitorsQueryClient: NetworkMonitorsQueryClient { + async fn get_all_network_monitor_agents( + &self, + ) -> Result, NyxdError> { + collect_paged!(self, get_network_monitor_agents_paged, authorised) + } +} + +#[async_trait] +impl PagedNetworkMonitorsQueryClient for T where T: NetworkMonitorsQueryClient {} + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +impl NetworkMonitorsQueryClient for C +where + C: CosmWasmClient + NymContractsProvider + Send + Sync, +{ + async fn query_network_monitors_contract( + &self, + query: NetworkMonitorsQueryMsg, + ) -> Result + where + for<'a> T: Deserialize<'a>, + { + let contract_address = &self + .network_monitors_contract_address() + .ok_or_else(|| NyxdError::unavailable_contract_address("network monitors contract"))?; + self.query_contract_smart(contract_address, &query).await + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::nyxd::contract_traits::tests::IgnoreValue; + + // it's enough that this compiles and clippy is happy about it + #[allow(dead_code)] + fn all_query_variants_are_covered( + client: C, + msg: NetworkMonitorsQueryMsg, + ) { + match msg { + NetworkMonitorsQueryMsg::Admin {} => client.get_admin().ignore(), + NetworkMonitorsQueryMsg::NetworkMonitorOrchestrators {} => { + client.get_network_monitor_orchestrators().ignore() + } + NetworkMonitorsQueryMsg::NetworkMonitorAgents { .. } => { + client.get_network_monitor_agents_paged(None, None).ignore() + } + }; + } +} diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/network_monitors_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/network_monitors_signing_client.rs new file mode 100644 index 0000000000..bfae9340a8 --- /dev/null +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/network_monitors_signing_client.rs @@ -0,0 +1,205 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::nyxd::contract_traits::NymContractsProvider; +use crate::nyxd::cosmwasm_client::types::ExecuteResult; +use crate::nyxd::error::NyxdError; +use crate::nyxd::{Coin, Fee, SigningCosmWasmClient}; +use crate::signing::signer::OfflineSigner; +use async_trait::async_trait; +use nym_network_monitors_contract_common::ExecuteMsg as NetworkMonitorsExecuteMsg; +use std::net::SocketAddr; + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +pub trait NetworkMonitorsSigningClient { + async fn execute_network_monitors_contract( + &self, + fee: Option, + msg: NetworkMonitorsExecuteMsg, + memo: String, + funds: Vec, + ) -> Result; + + async fn update_admin( + &self, + admin: String, + fee: Option, + ) -> Result { + let msg = NetworkMonitorsExecuteMsg::UpdateAdmin { admin }; + self.execute_network_monitors_contract( + fee, + msg, + "NetworkMonitorsExecuteMsg::UpdateAdmin".into(), + vec![], + ) + .await + } + + async fn authorise_network_monitor_orchestrator( + &self, + address: String, + fee: Option, + ) -> Result { + let msg = NetworkMonitorsExecuteMsg::AuthoriseNetworkMonitorOrchestrator { address }; + self.execute_network_monitors_contract( + fee, + msg, + "NetworkMonitorsExecuteMsg::AuthoriseNetworkMonitorOrchestrator".into(), + vec![], + ) + .await + } + + /// Announce (or rotate) the ed25519 identity key of the calling network monitor orchestrator. + /// + /// The caller must already be an authorised orchestrator; the contract validates that + /// `identity_key` is a well-formed base-58 encoding of a 32-byte ed25519 public key. + async fn update_orchestrator_identity_key( + &self, + identity_key: String, + fee: Option, + ) -> Result { + let msg = NetworkMonitorsExecuteMsg::UpdateOrchestratorIdentityKey { key: identity_key }; + self.execute_network_monitors_contract( + fee, + msg, + "NetworkMonitorsExecuteMsg::UpdateOrchestratorIdentityKey".into(), + vec![], + ) + .await + } + + async fn revoke_network_monitor_orchestrator( + &self, + address: String, + fee: Option, + ) -> Result { + let msg = NetworkMonitorsExecuteMsg::RevokeNetworkMonitorOrchestrator { address }; + self.execute_network_monitors_contract( + fee, + msg, + "NetworkMonitorsExecuteMsg::RevokeNetworkMonitorOrchestrator".into(), + vec![], + ) + .await + } + + async fn authorise_network_monitor( + &self, + mixnet_address: SocketAddr, + bs58_x25519_noise: String, + noise_version: u8, + fee: Option, + ) -> Result { + let msg = NetworkMonitorsExecuteMsg::AuthoriseNetworkMonitor { + mixnet_address, + bs58_x25519_noise, + noise_version, + }; + self.execute_network_monitors_contract( + fee, + msg, + "NetworkMonitorsExecuteMsg::AuthoriseNetworkMonitor".into(), + vec![], + ) + .await + } + + async fn revoke_network_monitor( + &self, + address: SocketAddr, + fee: Option, + ) -> Result { + let msg = NetworkMonitorsExecuteMsg::RevokeNetworkMonitor { address }; + self.execute_network_monitors_contract( + fee, + msg, + "NetworkMonitorsExecuteMsg::RevokeNetworkMonitor".into(), + vec![], + ) + .await + } + + async fn revoke_all_network_monitors( + &self, + fee: Option, + ) -> Result { + let msg = NetworkMonitorsExecuteMsg::RevokeAllNetworkMonitors; + self.execute_network_monitors_contract( + fee, + msg, + "NetworkMonitorsExecuteMsg::RevokeAllNetworkMonitors".into(), + vec![], + ) + .await + } +} + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +impl NetworkMonitorsSigningClient for C +where + C: SigningCosmWasmClient + NymContractsProvider + Sync, + NyxdError: From<::Error>, +{ + async fn execute_network_monitors_contract( + &self, + fee: Option, + msg: NetworkMonitorsExecuteMsg, + memo: String, + funds: Vec, + ) -> Result { + let contract_address = &self + .network_monitors_contract_address() + .ok_or_else(|| NyxdError::unavailable_contract_address("network monitors contract"))?; + + let fee = fee.unwrap_or(Fee::Auto(Some(self.simulated_gas_multiplier()))); + + let signer_address = &self.signer_addresses()[0]; + self.execute(signer_address, contract_address, &msg, fee, memo, funds) + .await + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::nyxd::contract_traits::tests::IgnoreValue; + use nym_network_monitors_contract_common::ExecuteMsg; + + // it's enough that this compiles and clippy is happy about it + #[allow(dead_code)] + fn all_execute_variants_are_covered( + client: C, + msg: NetworkMonitorsExecuteMsg, + ) { + match msg { + NetworkMonitorsExecuteMsg::UpdateAdmin { admin } => { + client.update_admin(admin, None).ignore() + } + ExecuteMsg::AuthoriseNetworkMonitorOrchestrator { address } => client + .authorise_network_monitor_orchestrator(address, None) + .ignore(), + ExecuteMsg::UpdateOrchestratorIdentityKey { key } => { + client.update_orchestrator_identity_key(key, None).ignore() + } + ExecuteMsg::RevokeNetworkMonitorOrchestrator { address } => client + .revoke_network_monitor_orchestrator(address, None) + .ignore(), + ExecuteMsg::AuthoriseNetworkMonitor { + mixnet_address: address, + bs58_x25519_noise, + noise_version, + } => client + .authorise_network_monitor(address, bs58_x25519_noise, noise_version, None) + .ignore(), + ExecuteMsg::RevokeNetworkMonitor { address } => { + client.revoke_network_monitor(address, None).ignore() + } + ExecuteMsg::RevokeAllNetworkMonitors => { + client.revoke_all_network_monitors(None).ignore() + } + }; + } +} diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/mod.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/mod.rs index df7f03dd34..793fb1bc13 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/mod.rs @@ -36,7 +36,7 @@ pub mod logs; pub mod module_traits; pub mod types; -#[derive(Debug)] +#[derive(Debug, Clone)] pub(crate) struct SigningClientOptions { gas_price: GasPrice, simulated_gas_multiplier: f32, @@ -80,6 +80,17 @@ impl MaybeSigningClient { opts, } } + + pub(crate) fn clone_query_client(&self) -> MaybeSigningClient + where + C: Clone, + { + MaybeSigningClient { + client: self.client.clone(), + signer: Default::default(), + opts: self.opts.clone(), + } + } } #[cfg(feature = "http-client")] diff --git a/common/client-libs/validator-client/src/nyxd/mod.rs b/common/client-libs/validator-client/src/nyxd/mod.rs index 0c931c2bd5..ed01097ee9 100644 --- a/common/client-libs/validator-client/src/nyxd/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/mod.rs @@ -24,6 +24,8 @@ use async_trait::async_trait; use cosmrs::tendermint::{abci, evidence::Evidence, Genesis}; use cosmrs::tx::{Raw, SignDoc}; use cosmwasm_std::Addr; +use nym_contracts_common::build_information::CONTRACT_BUILD_INFO_STORAGE_KEY; +use nym_contracts_common::ContractBuildInformation; use nym_network_defaults::{ChainDetails, NymNetworkDetails}; use serde::{de::DeserializeOwned, Serialize}; use std::fmt::Debug; @@ -40,6 +42,7 @@ pub use crate::nyxd::{ fee::Fee, }; pub use crate::rpc::TendermintRpcClient; +pub use bip39; pub use coin::Coin; pub use cosmrs::{ bank::MsgSend, @@ -70,14 +73,19 @@ pub use tendermint_rpc::{ Paging, Request, Response, SimpleRequest, }; +pub use nym_ecash_contract_common; +pub use nym_mixnet_contract_common; +pub use nym_multisig_contract_common; +pub use nym_network_monitors_contract_common; +pub use nym_performance_contract_common; +pub use nym_vesting_contract_common; + #[cfg(feature = "http-client")] use crate::http_client; #[cfg(feature = "http-client")] use crate::{DirectSigningHttpRpcNyxdClient, QueryHttpRpcNyxdClient}; #[cfg(feature = "http-client")] use cosmrs::rpc::{HttpClient, HttpClientUrl}; -use nym_contracts_common::build_information::CONTRACT_BUILD_INFO_STORAGE_KEY; -use nym_contracts_common::ContractBuildInformation; pub mod coin; pub mod contract_traits; @@ -262,6 +270,16 @@ impl NyxdClient { } } + pub fn clone_query_client(&self) -> NyxdClient + where + C: Clone, + { + NyxdClient { + client: self.client.clone_query_client(), + config: self.config.clone(), + } + } + pub fn current_config(&self) -> &Config { &self.config } @@ -289,6 +307,10 @@ impl NyxdClient { pub fn set_simulated_gas_multiplier(&mut self, multiplier: f32) { self.config.simulated_gas_multiplier = multiplier; } + + pub fn get_nym_contracts(&self) -> TypedNymContracts { + self.config.contracts.clone() + } } impl NymContractsProvider for NyxdClient { @@ -303,6 +325,12 @@ impl NymContractsProvider for NyxdClient { fn performance_contract_address(&self) -> Option<&AccountId> { self.config.contracts.performance_contract_address.as_ref() } + fn network_monitors_contract_address(&self) -> Option<&AccountId> { + self.config + .contracts + .network_monitors_contract_address + .as_ref() + } fn ecash_contract_address(&self) -> Option<&AccountId> { self.config.contracts.ecash_contract_address.as_ref() diff --git a/common/cosmwasm-smart-contracts/network-monitors-contract/Cargo.toml b/common/cosmwasm-smart-contracts/network-monitors-contract/Cargo.toml new file mode 100644 index 0000000000..47021f35e4 --- /dev/null +++ b/common/cosmwasm-smart-contracts/network-monitors-contract/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "nym-network-monitors-contract-common" +description = "Common library for the Nym Network Monitors contract" +authors.workspace = true +repository.workspace = true +homepage.workspace = true +documentation.workspace = true +edition.workspace = true +license.workspace = true +readme.workspace = true +version.workspace = true + +[dependencies] +thiserror = { workspace = true } +serde = { workspace = true } +schemars = { workspace = true } + +cosmwasm-std = { workspace = true } +cosmwasm-schema = { workspace = true } +cw-controllers = { workspace = true } + +[features] +schema = [] + +[lints] +workspace = true diff --git a/common/cosmwasm-smart-contracts/network-monitors-contract/src/constants.rs b/common/cosmwasm-smart-contracts/network-monitors-contract/src/constants.rs new file mode 100644 index 0000000000..f3bfb238d2 --- /dev/null +++ b/common/cosmwasm-smart-contracts/network-monitors-contract/src/constants.rs @@ -0,0 +1,8 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +pub mod storage_keys { + pub const CONTRACT_ADMIN: &str = "contract-admin"; + pub const AUTHORISED_ORCHESTRATORS: &str = "authorised-orchestrators"; + pub const AUTHORISED_NETWORK_MONITORS: &str = "authorised-network-monitors"; +} diff --git a/common/cosmwasm-smart-contracts/network-monitors-contract/src/error.rs b/common/cosmwasm-smart-contracts/network-monitors-contract/src/error.rs new file mode 100644 index 0000000000..a2e31d546b --- /dev/null +++ b/common/cosmwasm-smart-contracts/network-monitors-contract/src/error.rs @@ -0,0 +1,30 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use cosmwasm_std::Addr; +use cw_controllers::AdminError; +use thiserror::Error; + +#[derive(Error, Debug, PartialEq)] +pub enum NetworkMonitorsContractError { + #[error("could not perform contract migration: {comment}")] + FailedMigration { comment: String }, + + #[error(transparent)] + Admin(#[from] AdminError), + + #[error("unauthorised")] + Unauthorized, + + #[error("address {addr} is not an authorised orchestrator")] + NotAnOrchestrator { addr: Addr }, + + #[error("Failed to recover x25519 public key from its base58 representation: {0}")] + MalformedX25519AgentNoiseKey(String), + + #[error("Failed to recover ed25519 public key from its base58 representation: {0}")] + MalformedEd25519OrchestratorIdentityKey(String), + + #[error(transparent)] + StdErr(#[from] cosmwasm_std::StdError), +} diff --git a/common/cosmwasm-smart-contracts/network-monitors-contract/src/lib.rs b/common/cosmwasm-smart-contracts/network-monitors-contract/src/lib.rs new file mode 100644 index 0000000000..273ff38d15 --- /dev/null +++ b/common/cosmwasm-smart-contracts/network-monitors-contract/src/lib.rs @@ -0,0 +1,11 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +pub mod constants; +pub mod error; +pub mod msg; +pub mod types; + +pub use error::*; +pub use msg::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; +pub use types::*; diff --git a/common/cosmwasm-smart-contracts/network-monitors-contract/src/msg.rs b/common/cosmwasm-smart-contracts/network-monitors-contract/src/msg.rs new file mode 100644 index 0000000000..a5fbf4d101 --- /dev/null +++ b/common/cosmwasm-smart-contracts/network-monitors-contract/src/msg.rs @@ -0,0 +1,78 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use cosmwasm_schema::cw_serde; +use std::net::SocketAddr; + +#[cfg(feature = "schema")] +use crate::{ + AuthorisedNetworkMonitorOrchestratorsResponse, AuthorisedNetworkMonitorsPagedResponse, +}; + +#[cw_serde] +pub struct InstantiateMsg { + /// Address of the initial network monitor orchestrator. + pub orchestrator_address: String, +} + +#[cw_serde] +pub enum ExecuteMsg { + /// Change the admin + UpdateAdmin { admin: String }, + + /// Authorise new network monitor orchestrator + AuthoriseNetworkMonitorOrchestrator { address: String }, + + /// Attempt to update the announced identity key of this orchestrator + UpdateOrchestratorIdentityKey { key: String }, + + /// Revoke network monitor orchestrator authorisation. + RevokeNetworkMonitorOrchestrator { address: String }, + + /// Authorise new network monitor (or renew authorisation) + /// granting additional privileges when sending mixnet packets to Nym nodes. + AuthoriseNetworkMonitor { + /// Mixnet address of the agent. + /// The underlying ip address is going to be used as ingress to the nodes, + /// and the full socket address announces the egress and the association with the noise key + mixnet_address: SocketAddr, + + /// Base-58 encoded noise key of the agent. + bs58_x25519_noise: String, + + /// Version of the noise protocol used by the agent. + noise_version: u8, + }, + + /// Revoke network monitor authorisation. + RevokeNetworkMonitor { address: SocketAddr }, + + /// Revoke all network monitor authorisations. + RevokeAllNetworkMonitors, +} + +#[cw_serde] +#[cfg_attr(feature = "schema", derive(cosmwasm_schema::QueryResponses))] +pub enum QueryMsg { + #[cfg_attr(feature = "schema", returns(cw_controllers::AdminResponse))] + Admin {}, + + // no need for pagination as we don't expect even a double digit of those + #[cfg_attr( + feature = "schema", + returns(AuthorisedNetworkMonitorOrchestratorsResponse) + )] + NetworkMonitorOrchestrators {}, + + #[cfg_attr(feature = "schema", returns(AuthorisedNetworkMonitorsPagedResponse))] + NetworkMonitorAgents { + /// Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response. + start_next_after: Option, + + /// Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default. + limit: Option, + }, +} + +#[cw_serde] +pub struct MigrateMsg {} diff --git a/common/cosmwasm-smart-contracts/network-monitors-contract/src/types.rs b/common/cosmwasm-smart-contracts/network-monitors-contract/src/types.rs new file mode 100644 index 0000000000..b0f9a4a754 --- /dev/null +++ b/common/cosmwasm-smart-contracts/network-monitors-contract/src/types.rs @@ -0,0 +1,53 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use cosmwasm_schema::cw_serde; +use cosmwasm_std::{Addr, Timestamp}; +use std::net::SocketAddr; + +pub type OrchestratorAddress = Addr; + +#[cw_serde] +pub struct AuthorisedNetworkMonitorOrchestrator { + /// The address associated with the network monitor orchestrator. + pub address: Addr, + + /// Base-58 encoded identity key of the orchestrator, announced by the orchestrator itself + /// on startup. + pub identity_key: Option, + + /// Timestamp of when the network monitor was authorised. + pub authorised_at: Timestamp, +} + +#[cw_serde] +pub struct AuthorisedNetworkMonitor { + /// Mixnet address of the agent. + /// The underlying ip address is going to be used as ingress to the nodes, + /// and the full socket address announces the egress and the association with the noise key + pub mixnet_address: SocketAddr, + + /// The address of the orchestrator that authorised the network monitor agent. + pub authorised_by: OrchestratorAddress, + + /// Timestamp of when the network monitor was authorised. + pub authorised_at: Timestamp, + + /// Base-58 encoded noise key of the agent. + pub bs58_x25519_noise: String, + + /// Version of the noise protocol used by the agent. + pub noise_version: u8, +} + +#[cw_serde] +pub struct AuthorisedNetworkMonitorOrchestratorsResponse { + pub authorised: Vec, +} + +#[cw_serde] +pub struct AuthorisedNetworkMonitorsPagedResponse { + pub authorised: Vec, + + pub start_next_after: Option, +} diff --git a/common/crypto/src/lib.rs b/common/crypto/src/lib.rs index e8426bb085..7dc11fa0b4 100644 --- a/common/crypto/src/lib.rs +++ b/common/crypto/src/lib.rs @@ -31,3 +31,5 @@ pub use aes_gcm_siv::{Aes128GcmSiv, Aes256GcmSiv}; pub use blake3; #[cfg(feature = "stream_cipher")] pub use ctr; +#[cfg(feature = "hashing")] +pub use sha2; diff --git a/common/http-api-client/src/path.rs b/common/http-api-client/src/path.rs index b7aeea5e47..39ee964057 100644 --- a/common/http-api-client/src/path.rs +++ b/common/http-api-client/src/path.rs @@ -10,7 +10,9 @@ fn sanitize_fragment(segment: &str) -> &str { segment.trim_matches(|c: char| c.is_whitespace() || c == '/') } +/// Defines a path that can be used to make a request to an API. pub trait RequestPath: Debug { + /// Sanitise the request path by removing empty segments and trimming whitespace and slashes fn to_sanitized_segments(&self) -> Vec<&str>; } diff --git a/common/network-defaults/Cargo.toml b/common/network-defaults/Cargo.toml index 238503673d..823e9fc200 100644 --- a/common/network-defaults/Cargo.toml +++ b/common/network-defaults/Cargo.toml @@ -17,11 +17,10 @@ exclude = ["build.rs"] [dependencies] dotenvy = { workspace = true, optional = true } -log = { workspace = true, optional = true } schemars = { workspace = true, features = ["preserve_order"], optional = true } serde = { workspace = true, features = ["derive"], optional = true } -serde_json = {workspace = true, optional = true } -tracing = {workspace = true, optional = true } +serde_json = { workspace = true, optional = true } +tracing = { workspace = true, optional = true } url = { workspace = true, optional = true } utoipa = { workspace = true, optional = true } @@ -30,9 +29,9 @@ utoipa = { workspace = true, optional = true } [features] default = ["env", "network"] -env = ["dotenvy", "log", "serde_json", "tracing"] +env = ["dotenvy", "serde_json", "tracing"] network = ["schemars", "serde", "url"] -utoipa = [ "dep:utoipa" ] +utoipa = ["dep:utoipa"] [build-dependencies] regex = { workspace = true } diff --git a/common/network-defaults/src/env_setup.rs b/common/network-defaults/src/env_setup.rs index 66a8243d00..d7ba6f32c7 100644 --- a/common/network-defaults/src/env_setup.rs +++ b/common/network-defaults/src/env_setup.rs @@ -27,16 +27,20 @@ fn print_env_vars_with_keys_in_file + Copy>(config_env_file: P) { .expect("Invalid path to environment configuration file"); for item in items { let (key, val) = item.expect("Invalid item in environment configuration file"); - log::debug!("{key}: {val}"); + tracing::debug!("{key}: {val}"); } } +pub fn env_configured() -> bool { + std::env::var(var_names::CONFIGURED).is_ok() +} + pub fn setup_env>(config_env_file: Option

) { match std::env::var(var_names::CONFIGURED) { // if the configuration is not already set in the env vars Err(std::env::VarError::NotPresent) => { if let Some(config_env_file) = &config_env_file { - log::debug!( + tracing::debug!( "Loading environment variables from {:?}", config_env_file.as_ref() ); @@ -47,12 +51,12 @@ pub fn setup_env>(config_env_file: Option

) { // if nothing is set, the use mainnet defaults // if the user has not set `CONFIGURED`, then even if they set any of the env variables, // overwrite them - log::debug!("Loading mainnet defaults"); + tracing::debug!("Loading mainnet defaults"); crate::mainnet::export_to_env(); } } Err(_) => { - log::debug!("Environment variables already set. Using them"); + tracing::debug!("Environment variables already set. Using them"); crate::mainnet::export_to_env() } _ => { diff --git a/common/network-defaults/src/mainnet.rs b/common/network-defaults/src/mainnet.rs index 3c07beefc3..0ce8772863 100644 --- a/common/network-defaults/src/mainnet.rs +++ b/common/network-defaults/src/mainnet.rs @@ -22,6 +22,8 @@ pub const VESTING_CONTRACT_ADDRESS: &str = pub const PERFORMANCE_CONTRACT_ADDRESS: &str = ""; // /\ TODO: this has to be updated once the contract is deployed +pub const NETWORK_MONITORS_CONTRACT_ADDRESS: &str = + "n1m3a2ltkjqud8mkmrpqvgllrtv2p4r6js6qwl7p8cqkzrq8jg6e2qwqgl8z"; pub const ECASH_CONTRACT_ADDRESS: &str = "n1r7s6aksyc6pqardx88k3rkgfagwvj4z4zum9mmz2sfk3zm2mha0sd4dnun"; pub const GROUP_CONTRACT_ADDRESS: &str = @@ -36,6 +38,10 @@ pub const REWARDING_VALIDATOR_ADDRESS: &str = "n10yyd98e2tuwu0f7ypz9dy3hhjw7v772 pub const NYXD_URL: &str = "https://rpc.nymtech.net"; pub const NYXD_WS: &str = "wss://rpc.nymtech.net/websocket"; +// cluster of lite rpc nodes (not part of consensus, aggressive pruning, no archival state) +pub const NYXD_QUERY_LITE: &str = "https://blockstream.nymtech.net"; +pub const NYXD_WS_LITE: &str = "wss://blockstream.nymtech.net/websocket"; + pub const NYM_API: &str = "https://validator.nymtech.net/api/"; #[cfg(feature = "network")] pub const NYM_APIS: &[ApiUrlConst] = &[ @@ -133,6 +139,11 @@ pub fn read_parsed_var_if_not_default( .map(std::str::FromStr::from_str) } +#[cfg(feature = "env")] +pub fn read_parsed_var(var: &str) -> Result { + std::env::var(var).unwrap_or_default().parse() +} + #[cfg(all(feature = "env", feature = "network"))] pub fn export_to_env() { use crate::var_names; @@ -163,6 +174,14 @@ pub fn export_to_env() { var_names::COCONUT_DKG_CONTRACT_ADDRESS, COCONUT_DKG_CONTRACT_ADDRESS, ); + set_var_to_default( + var_names::PERFORMANCE_CONTRACT_ADDRESS, + PERFORMANCE_CONTRACT_ADDRESS, + ); + set_var_to_default( + var_names::NETWORK_MONITORS_CONTRACT_ADDRESS, + NETWORK_MONITORS_CONTRACT_ADDRESS, + ); set_var_to_default( var_names::REWARDING_VALIDATOR_ADDRESS, REWARDING_VALIDATOR_ADDRESS, @@ -182,6 +201,8 @@ pub fn export_to_env() { var_names::UPGRADE_MODE_ATTESTER_ED25519_BS58_PUBKEY, UPGRADE_MODE_ATTESTER_ED25519_BS58_PUBKEY, ); + set_var_to_default(var_names::NYXD_QUERY_LITE, NYXD_QUERY_LITE); + set_var_to_default(var_names::NYXD_WS_LITE, NYXD_WS_LITE); } #[cfg(all(feature = "env", feature = "network"))] @@ -233,4 +254,6 @@ pub fn export_to_env_if_not_set() { var_names::UPGRADE_MODE_ATTESTER_ED25519_BS58_PUBKEY, UPGRADE_MODE_ATTESTER_ED25519_BS58_PUBKEY, ); + set_var_conditionally_to_default(var_names::NYXD_QUERY_LITE, NYXD_QUERY_LITE); + set_var_conditionally_to_default(var_names::NYXD_WS_LITE, NYXD_WS_LITE); } diff --git a/common/network-defaults/src/network.rs b/common/network-defaults/src/network.rs index ccba4af768..868ef8bf81 100644 --- a/common/network-defaults/src/network.rs +++ b/common/network-defaults/src/network.rs @@ -39,6 +39,8 @@ pub struct NymContracts { pub vesting_contract_address: Option, #[serde(default)] pub performance_contract_address: Option, + #[serde(default)] + pub network_monitors_contract_address: Option, pub ecash_contract_address: Option, pub group_contract_address: Option, pub multisig_contract_address: Option, @@ -72,6 +74,15 @@ pub struct ApiUrl { pub front_hosts: Option>, } +impl From for ApiUrl { + fn from(value: Url) -> Self { + ApiUrl { + url: value.to_string(), + front_hosts: None, + } + } +} + #[derive(Copy, Clone, Debug, Serialize)] pub struct ApiUrlConst<'a> { pub url: &'a str, @@ -178,6 +189,10 @@ impl NymNetworkDetails { .with_group_contract(get_optional_env(var_names::GROUP_CONTRACT_ADDRESS)) .with_multisig_contract(get_optional_env(var_names::MULTISIG_CONTRACT_ADDRESS)) .with_coconut_dkg_contract(get_optional_env(var_names::COCONUT_DKG_CONTRACT_ADDRESS)) + .with_performance_contract(get_optional_env(var_names::PERFORMANCE_CONTRACT_ADDRESS)) + .with_network_monitors_contract(get_optional_env( + var_names::NETWORK_MONITORS_CONTRACT_ADDRESS, + )) .with_nym_vpn_api_url(get_optional_env(var_names::NYM_VPN_API)) .with_nym_vpn_api_urls(nym_vpn_api_urls) .with_nym_api_urls(nym_api_urls) @@ -199,6 +214,9 @@ impl NymNetworkDetails { performance_contract_address: parse_optional_str( mainnet::PERFORMANCE_CONTRACT_ADDRESS, ), + network_monitors_contract_address: parse_optional_str( + mainnet::NETWORK_MONITORS_CONTRACT_ADDRESS, + ), ecash_contract_address: parse_optional_str(mainnet::ECASH_CONTRACT_ADDRESS), group_contract_address: parse_optional_str(mainnet::GROUP_CONTRACT_ADDRESS), multisig_contract_address: parse_optional_str(mainnet::MULTISIG_CONTRACT_ADDRESS), @@ -226,7 +244,7 @@ impl NymNetworkDetails { fn set_optional_var(var_name: &str, value: Option) { if let Some(value) = value { - unsafe {set_var(var_name, value)} + unsafe { set_var(var_name, value) } } } unsafe { @@ -364,15 +382,31 @@ impl NymNetworkDetails { self } + #[must_use] + pub fn with_performance_contract>(mut self, contract: Option) -> Self { + self.contracts.performance_contract_address = contract.map(Into::into); + self + } + + #[must_use] + pub fn with_network_monitors_contract>(mut self, contract: Option) -> Self { + self.contracts.network_monitors_contract_address = contract.map(Into::into); + self + } + #[must_use] pub fn with_nym_vpn_api_url>(mut self, endpoint: Option) -> Self { self.nym_vpn_api_url = endpoint.map(Into::into); self } + pub fn set_nym_api_urls>(&mut self, urls: Vec) { + self.nym_api_urls = Some(urls.into_iter().map(Into::into).collect()); + } + #[must_use] - pub fn with_nym_api_urls(mut self, urls: Vec) -> Self { - self.nym_api_urls = Some(urls); + pub fn with_nym_api_urls>(mut self, urls: Vec) -> Self { + self.set_nym_api_urls(urls); self } diff --git a/common/network-defaults/src/sandbox.rs b/common/network-defaults/src/sandbox.rs deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/common/network-defaults/src/var_names.rs b/common/network-defaults/src/var_names.rs index 4bfb1d5877..96dd561650 100644 --- a/common/network-defaults/src/var_names.rs +++ b/common/network-defaults/src/var_names.rs @@ -18,11 +18,15 @@ pub const ECASH_CONTRACT_ADDRESS: &str = "ECASH_CONTRACT_ADDRESS"; pub const GROUP_CONTRACT_ADDRESS: &str = "GROUP_CONTRACT_ADDRESS"; pub const MULTISIG_CONTRACT_ADDRESS: &str = "MULTISIG_CONTRACT_ADDRESS"; pub const COCONUT_DKG_CONTRACT_ADDRESS: &str = "COCONUT_DKG_CONTRACT_ADDRESS"; +pub const PERFORMANCE_CONTRACT_ADDRESS: &str = "PERFORMANCE_CONTRACT_ADDRESS"; +pub const NETWORK_MONITORS_CONTRACT_ADDRESS: &str = "NETWORK_MONITORS_CONTRACT_ADDRESS"; pub const REWARDING_VALIDATOR_ADDRESS: &str = "REWARDING_VALIDATOR_ADDRESS"; pub const NYXD: &str = "NYXD"; pub const NYM_API: &str = "NYM_API"; pub const NYM_APIS: &str = "NYM_APIS"; pub const NYXD_WEBSOCKET: &str = "NYXD_WS"; +pub const NYXD_QUERY_LITE: &str = "NYXD_LITE"; +pub const NYXD_WS_LITE: &str = "NYXD_WS_LITE"; pub const EXIT_POLICY_URL: &str = "EXIT_POLICY"; pub const NYM_VPN_API: &str = "NYM_VPN_API"; pub const NYM_VPN_APIS: &str = "NYM_VPN_APIS"; diff --git a/common/nymnoise/src/config.rs b/common/nymnoise/src/config.rs index 1ef2235928..ab5f7afccd 100644 --- a/common/nymnoise/src/config.rs +++ b/common/nymnoise/src/config.rs @@ -1,19 +1,19 @@ // Copyright 2025 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use arc_swap::ArcSwap; +use nym_crypto::asymmetric::x25519; +use snow::params::NoiseParams; use std::{ collections::HashMap, net::{IpAddr, SocketAddr}, sync::Arc, time::Duration, }; - -use arc_swap::ArcSwap; -use nym_crypto::asymmetric::x25519; -use nym_noise_keys::{NoiseVersion, VersionedNoiseKeyV1}; -use snow::params::NoiseParams; - use strum_macros::{EnumIter, FromRepr}; +use tokio::sync::{Mutex, MutexGuard}; + +pub use nym_noise_keys::{NoiseVersion, VersionedNoiseKeyV1}; #[derive(Default, Debug, Clone, Copy, EnumIter, FromRepr, Eq, PartialEq)] #[repr(u8)] @@ -53,38 +53,125 @@ impl NoisePattern { } } -#[derive(Debug, Default)] -struct SocketAddrToKey { - inner: ArcSwap>, -} - -// SW NOTE : Only for phased upgrade. To remove once we decide all nodes have to support Noise -#[derive(Debug, Default)] -struct IpAddrToVersion { - inner: ArcSwap>, -} - -#[derive(Debug, Clone, Default)] +#[derive(Debug, Clone)] pub struct NoiseNetworkView { - keys: Arc, - support: Arc, + inner: Arc, } -impl NoiseNetworkView { - pub fn new_empty() -> Self { - NoiseNetworkView { - keys: Default::default(), - support: Default::default(), +/// Inner state of [`NoiseNetworkView`], shared behind an `Arc`. +/// +/// # Concurrency model +/// +/// Reads (on the packet-processing hot path) use `ArcSwap` and are fully lock-free. +/// Writers must first acquire `update_lock` to serialise concurrent updates, then call +/// `swap_view` to atomically publish the new map. The lock is intentionally *not* wrapping +/// the map itself so that readers are never blocked. +#[derive(Debug)] +struct NoiseNetworkViewInner { + update_lock: Mutex<()>, + nodes: ArcSwap>, +} + +/// A node in the noise network map, keyed by IP address. +/// +/// A single IP can correspond to either one nym-node (which has a single noise key) +/// or one-or-more network monitor agents (each with its own port and noise key). +/// The two variants have independent lifecycles: nym-node entries come from the +/// nym-api topology refresher, while agent entries come from blockchain events. +#[derive(Debug, Clone)] +pub enum NoiseNode { + NymNode { key: VersionedNoiseKeyV1 }, + // due to the structure of network monitor agents, + // it is possible to have multiple destinations with the same host ip address, + // but a different noise key. + // however, we are also guaranteed all of those are going to have a unique port. + // note: we're not storing it in a map, since at maximum we might have maybe 20 or so + // entries under a single ip address and linear look-up of a vec is faster than the overhead of a hashmap + NetworkMonitorAgent { nodes: Vec }, +} + +impl NoiseNode { + pub fn new_nym_node(key: VersionedNoiseKeyV1) -> Self { + NoiseNode::NymNode { key } + } + + pub fn new_agent(socket_addr: SocketAddr, key: VersionedNoiseKeyV1) -> Self { + NoiseNode::NetworkMonitorAgent { + nodes: vec![NetworkMonitorAgentNode { + port: socket_addr.port(), + key, + }], } } - pub fn swap_view(&self, new: HashMap) { - let noise_support = new - .iter() - .map(|(s_addr, key)| (s_addr.ip(), key.supported_version)) - .collect::>(); - self.keys.inner.store(Arc::new(new)); - self.support.inner.store(Arc::new(noise_support)); + pub fn is_nym_node(&self) -> bool { + matches!(self, NoiseNode::NymNode { .. }) + } +} + +/// A single network monitor agent identified by its port on a shared host. +/// +/// Multiple agents may share an IP address but are guaranteed to have unique ports. +#[derive(Debug, Clone)] +pub struct NetworkMonitorAgentNode { + pub port: u16, + pub key: VersionedNoiseKeyV1, +} + +impl NoiseNetworkView { + pub fn new(nodes: HashMap) -> Self { + // ensure we're always storing canonical IPs + NoiseNetworkView { + inner: Arc::new(NoiseNetworkViewInner { + update_lock: Mutex::new(()), + nodes: ArcSwap::from_pointee( + nodes + .into_iter() + .map(|(k, v)| (k.to_canonical(), v)) + .collect(), + ), + }), + } + } + + pub fn new_empty() -> Self { + Self::new(Default::default()) + } + + /// Build a noise view pre-populated with network monitor agents (used at startup). + pub fn new_with_agents(agents: HashMap>) -> Self { + let mut nodes = HashMap::new(); + for (ip, agent_nodes) in agents { + nodes.insert(ip, NoiseNode::NetworkMonitorAgent { nodes: agent_nodes }); + } + Self::new(nodes) + } + + pub async fn get_update_permit(&self) -> MutexGuard<'_, ()> { + self.inner.update_lock.lock().await + } + + /// Atomically replace the noise key map. + /// + /// # Precondition + /// + /// The caller **must** hold the permit returned by [`NoiseNetworkView::get_update_permit`]. + /// Passing the `MutexGuard` by value enforces this at the type level — the guard is dropped + /// (releasing the lock) only after the swap completes, preventing torn writes from concurrent + /// update calls. + pub fn swap_view(&self, _permit: MutexGuard<'_, ()>, new: HashMap) { + // defensive: ensure stored keys are always canonical so lookups (which canonicalise) + // always match. callers should still canonicalise before assembling `new` to keep + // collision resolution deterministic. + let canonical = new + .into_iter() + .map(|(k, v)| (k.to_canonical(), v)) + .collect(); + self.inner.nodes.store(Arc::new(canonical)); + } + + pub fn all_nodes(&self) -> HashMap { + self.inner.nodes.load().as_ref().clone() } } @@ -126,20 +213,38 @@ impl NoiseConfig { self } - pub(crate) fn get_noise_key(&self, s_address: &SocketAddr) -> Option { - self.network.keys.inner.load().get(s_address).copied() + /// Look up the noise key for a specific remote socket address. + /// + /// Used on the **initiator** path where we need the responder's public key + /// to start the handshake. For nym-nodes the port is ignored (one key per IP); + /// for network monitor agents, the port disambiguates which agent's key to use. + pub(crate) fn get_noise_key(&self, address: SocketAddr) -> Option { + let ip_to_check = address.ip().to_canonical(); + let nodes = self.network.inner.nodes.load(); + + // Resolve the noise key for `address` from a loaded snapshot of the node map. + // For [`NoiseNode::NymNode`] entries the port is irrelevant — only the IP is matched. + // For [`NoiseNode::NetworkMonitorAgent`] entries the port selects the specific agent. + match nodes.get(&ip_to_check)? { + NoiseNode::NymNode { key } => Some(*key), + NoiseNode::NetworkMonitorAgent { nodes } => { + let port = address.port(); + nodes.iter().find(|n| n.port == port).map(|n| n.key) + } + } } - // Only for phased update - //SW This can lead to some troubles if two nodes share the same IP and one support Noise but not the other. - // This in only for the progressive update though and there is no workaround - pub(crate) fn get_noise_support(&self, ip_addr: IpAddr) -> Option { - let plain_ip_support = self.network.support.inner.load().get(&ip_addr).copied(); - - // SW default bind address being [::]:1789, it can happen that a responder sees the ipv6-mapped address of the initiator, this check for that - let canonical_ip = &ip_addr.to_canonical(); - let canonical_ip_support = self.network.support.inner.load().get(canonical_ip).copied(); - plain_ip_support.or(canonical_ip_support) + /// Check whether a remote IP is known to support noise. + /// Used on the responder path where we don't need the remote's key + /// (the initiator sends it during the handshake). + // note: in the case of network monitor agents, it must hold + // that ALL agents on given host support it (or don't support it) + pub(crate) fn supports_noise(&self, ip_addr: IpAddr) -> bool { + self.network + .inner + .nodes + .load() + .contains_key(&ip_addr.to_canonical()) } } @@ -169,4 +274,240 @@ mod tests { } } } + + mod noise_key_lookup { + use super::super::*; + use nym_crypto::asymmetric::x25519; + use nym_noise_keys::NoiseVersion; + use nym_test_utils::helpers::deterministic_rng; + use std::net::{IpAddr, Ipv4Addr, SocketAddr}; + use std::sync::Arc; + use std::time::Duration; + + fn dummy_key(seed: u8) -> VersionedNoiseKeyV1 { + VersionedNoiseKeyV1 { + supported_version: NoiseVersion::V1, + x25519_pubkey: x25519::PublicKey::from([seed; 32]), + } + } + + fn make_config(nodes: HashMap) -> NoiseConfig { + NoiseConfig::new( + Arc::new(x25519::KeyPair::new(&mut deterministic_rng())), + NoiseNetworkView::new(nodes), + Duration::from_secs(5), + ) + } + + // -- get_noise_key tests -- + + #[test] + fn nym_node_key_returned_regardless_of_port() { + let ip = IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)); + let key = dummy_key(1); + let config = make_config(HashMap::from([(ip, NoiseNode::new_nym_node(key))])); + + // any port should resolve to the same key + assert_eq!(config.get_noise_key(SocketAddr::new(ip, 1000)), Some(key)); + assert_eq!(config.get_noise_key(SocketAddr::new(ip, 9999)), Some(key)); + } + + #[test] + fn agent_key_resolved_by_port() { + let ip = IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)); + let key_a = dummy_key(1); + let key_b = dummy_key(2); + + let node = NoiseNode::NetworkMonitorAgent { + nodes: vec![ + NetworkMonitorAgentNode { + port: 1000, + key: key_a, + }, + NetworkMonitorAgentNode { + port: 2000, + key: key_b, + }, + ], + }; + let config = make_config(HashMap::from([(ip, node)])); + + assert_eq!(config.get_noise_key(SocketAddr::new(ip, 1000)), Some(key_a)); + assert_eq!(config.get_noise_key(SocketAddr::new(ip, 2000)), Some(key_b)); + } + + #[test] + fn agent_unknown_port_returns_none() { + let ip = IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)); + let node = NoiseNode::NetworkMonitorAgent { + nodes: vec![NetworkMonitorAgentNode { + port: 1000, + key: dummy_key(1), + }], + }; + let config = make_config(HashMap::from([(ip, node)])); + + assert!(config.get_noise_key(SocketAddr::new(ip, 9999)).is_none()); + } + + #[test] + fn completely_unknown_address_returns_none() { + let config = make_config(HashMap::new()); + + assert!(config + .get_noise_key(SocketAddr::new(IpAddr::V4(Ipv4Addr::new(1, 2, 3, 4)), 80)) + .is_none()); + } + + #[test] + fn canonical_ipv6_fallback_for_nym_node() { + // register under the plain IPv4 address + let v4 = IpAddr::V4(Ipv4Addr::new(1, 2, 3, 4)); + let key = dummy_key(1); + let config = make_config(HashMap::from([(v4, NoiseNode::new_nym_node(key))])); + + // query with the IPv4-mapped IPv6 form (::ffff:1.2.3.4) + let v6_mapped = IpAddr::V6(Ipv4Addr::new(1, 2, 3, 4).to_ipv6_mapped()); + assert_eq!( + config.get_noise_key(SocketAddr::new(v6_mapped, 1789)), + Some(key) + ); + } + + #[test] + fn canonical_ipv6_fallback_for_agent() { + let v4 = IpAddr::V4(Ipv4Addr::new(1, 2, 3, 4)); + let key = dummy_key(1); + let node = NoiseNode::NetworkMonitorAgent { + nodes: vec![NetworkMonitorAgentNode { port: 1000, key }], + }; + let config = make_config(HashMap::from([(v4, node)])); + + let v6_mapped = IpAddr::V6(Ipv4Addr::new(1, 2, 3, 4).to_ipv6_mapped()); + assert_eq!( + config.get_noise_key(SocketAddr::new(v6_mapped, 1000)), + Some(key) + ); + // wrong port still returns None even with the fallback + assert!(config + .get_noise_key(SocketAddr::new(v6_mapped, 9999)) + .is_none()); + } + + // -- supports_noise tests -- + + #[test] + fn supports_noise_true_for_nym_node() { + let ip = IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)); + let config = make_config(HashMap::from([(ip, NoiseNode::new_nym_node(dummy_key(1)))])); + + assert!(config.supports_noise(ip)); + } + + #[test] + fn supports_noise_true_for_agent_ip() { + let ip = IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)); + let node = NoiseNode::NetworkMonitorAgent { + nodes: vec![NetworkMonitorAgentNode { + port: 1000, + key: dummy_key(1), + }], + }; + let config = make_config(HashMap::from([(ip, node)])); + + assert!(config.supports_noise(ip)); + } + + #[test] + fn supports_noise_false_for_unknown_ip() { + let config = make_config(HashMap::new()); + + assert!(!config.supports_noise(IpAddr::V4(Ipv4Addr::new(1, 2, 3, 4)))); + } + + #[test] + fn supports_noise_canonical_ipv6_fallback() { + let v4 = IpAddr::V4(Ipv4Addr::new(1, 2, 3, 4)); + let config = make_config(HashMap::from([(v4, NoiseNode::new_nym_node(dummy_key(1)))])); + + let v6_mapped = IpAddr::V6(Ipv4Addr::new(1, 2, 3, 4).to_ipv6_mapped()); + assert!(config.supports_noise(v6_mapped)); + } + + // -- new_with_agents test -- + + #[test] + fn new_with_agents_builds_correct_view() { + let ip = IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)); + let key_a = dummy_key(1); + let key_b = dummy_key(2); + + let agents = HashMap::from([( + ip, + vec![ + NetworkMonitorAgentNode { + port: 1000, + key: key_a, + }, + NetworkMonitorAgentNode { + port: 2000, + key: key_b, + }, + ], + )]); + + let config = NoiseConfig::new( + Arc::new(x25519::KeyPair::new(&mut deterministic_rng())), + NoiseNetworkView::new_with_agents(agents), + Duration::from_secs(5), + ); + + assert_eq!(config.get_noise_key(SocketAddr::new(ip, 1000)), Some(key_a)); + assert_eq!(config.get_noise_key(SocketAddr::new(ip, 2000)), Some(key_b)); + assert!(config.supports_noise(ip)); + } + + // -- swap_view canonicalisation test -- + + // Regression: an agent registered via blockchain events flows through `swap_view` (called + // from `NetworkMonitorAgentsModule::new_agent` and from the periodic network refresher). + // If a non-canonical (IPv4-mapped IPv6) key reaches `swap_view`, lookups via + // `supports_noise` (which canonicalises) used to miss, producing the + // "can't speak Noise yet, falling back to TCP" warning despite the agent being correctly + // authorised in the routing filter. + #[tokio::test] + async fn swap_view_canonicalises_non_canonical_keys() { + let view = NoiseNetworkView::new_empty(); + let v4 = IpAddr::V4(Ipv4Addr::new(1, 2, 3, 4)); + let v6_mapped = IpAddr::V6(Ipv4Addr::new(1, 2, 3, 4).to_ipv6_mapped()); + + let mut nodes = HashMap::new(); + // intentionally insert under the IPv4-mapped form — what a buggy caller might do + nodes.insert( + v6_mapped, + NoiseNode::NetworkMonitorAgent { + nodes: vec![NetworkMonitorAgentNode { + port: 1000, + key: dummy_key(1), + }], + }, + ); + + let permit = view.get_update_permit().await; + view.swap_view(permit, nodes); + + let config = NoiseConfig::new( + Arc::new(x25519::KeyPair::new(&mut deterministic_rng())), + view, + Duration::from_secs(5), + ); + + // lookup via either form must succeed + assert!(config.supports_noise(v4)); + assert!(config.supports_noise(v6_mapped)); + assert!(config + .get_noise_key(SocketAddr::new(v6_mapped, 1000)) + .is_some()); + } + } } diff --git a/common/nymnoise/src/connection.rs b/common/nymnoise/src/connection.rs index 81daa9bc98..0f09edd563 100644 --- a/common/nymnoise/src/connection.rs +++ b/common/nymnoise/src/connection.rs @@ -15,6 +15,12 @@ pub enum Connection { Noise(#[pin] Box>), } +impl Connection { + pub fn is_noise(&self) -> bool { + matches!(self, Connection::Noise(_)) + } +} + impl AsyncRead for Connection where C: AsyncRead + AsyncWrite + Unpin, diff --git a/common/nymnoise/src/lib.rs b/common/nymnoise/src/lib.rs index 5d3ff953cb..ed3cd09bd3 100644 --- a/common/nymnoise/src/lib.rs +++ b/common/nymnoise/src/lib.rs @@ -66,7 +66,7 @@ pub async fn upgrade_noise_initiator( Error::Prereq(Prerequisite::RemotePublicKey) })?; - let Some(key) = config.get_noise_key(&responder_addr) else { + let Some(key) = config.get_noise_key(responder_addr) else { warn!("{responder_addr} can't speak Noise yet, falling back to TCP"); return Ok(Connection::Raw(conn)); }; @@ -106,7 +106,7 @@ pub async fn upgrade_noise_responder( }; // if responder doesn't announce noise support, we fallback to tcp - if config.get_noise_support(initiator_addr.ip()).is_none() { + if !config.supports_noise(initiator_addr.ip()) { warn!("{initiator_addr} can't speak Noise yet, falling back to TCP",); return Ok(Connection::Raw(conn)); }; diff --git a/common/nymsphinx/framing/src/processing.rs b/common/nymsphinx/framing/src/processing.rs index afaba392dd..b5e81f6f51 100644 --- a/common/nymsphinx/framing/src/processing.rs +++ b/common/nymsphinx/framing/src/processing.rs @@ -110,6 +110,12 @@ pub enum PacketProcessingError { PacketReplay, } +impl PacketProcessingError { + pub fn is_replay(&self) -> bool { + matches!(self, PacketProcessingError::PacketReplay) + } +} + pub struct PartialyUnwrappedPacketWithKeyRotation { pub packet: PartiallyUnwrappedPacket, pub used_key_rotation: u32, diff --git a/common/nymsphinx/types/src/lib.rs b/common/nymsphinx/types/src/lib.rs index 1f3010b2f1..8f8b67296a 100644 --- a/common/nymsphinx/types/src/lib.rs +++ b/common/nymsphinx/types/src/lib.rs @@ -29,7 +29,7 @@ pub use sphinx_packet::{ packet::builder::DEFAULT_PAYLOAD_SIZE, payload::{ PAYLOAD_OVERHEAD_SIZE, Payload, - key::{PayloadKey, PayloadKeySeed}, + key::{PayloadKey, PayloadKeySeed, derive_payload_key}, }, route::{Destination, DestinationAddressBytes, Node, NodeAddressBytes, SURBIdentifier}, surb::{SURB, SURBMaterial}, diff --git a/common/nyxd-scraper-psql/src/lib.rs b/common/nyxd-scraper-psql/src/lib.rs index 85fcbb46ef..36ed11bee7 100644 --- a/common/nyxd-scraper-psql/src/lib.rs +++ b/common/nyxd-scraper-psql/src/lib.rs @@ -7,8 +7,9 @@ use nyxd_scraper_shared::NyxdScraper; pub use nyxd_scraper_shared::constants; pub use nyxd_scraper_shared::error::ScraperError; pub use nyxd_scraper_shared::{ - BlockModule, MsgModule, NyxdScraperTransaction, ParsedTransactionResponse, PruningOptions, - PruningStrategy, StartingBlockOpts, TxModule, + BlockModule, DecodedMessage, MsgModule, NyxdScraperTransaction, ParsedTransactionDetails, + ParsedTransactionResponse, PruningOptions, PruningStrategy, StartingBlockOpts, TxModule, + parse_msg, }; pub use storage::models; diff --git a/common/nyxd-scraper-psql/src/storage/helpers.rs b/common/nyxd-scraper-psql/src/storage/helpers.rs index 8d56ee72f7..ecbc06a8ec 100644 --- a/common/nyxd-scraper-psql/src/storage/helpers.rs +++ b/common/nyxd-scraper-psql/src/storage/helpers.rs @@ -9,7 +9,7 @@ use std::str::FromStr; // replicate behaviour of `CosmosMessageAddressesParser` from juno pub(crate) fn parse_addresses_from_events(tx: &ParsedTransactionResponse) -> Vec { let mut addresses: Vec = Vec::new(); - for event in &tx.tx_result.events { + for event in &tx.tx_details.tx_result.events { for attribute in &event.attributes { let Ok(value) = attribute.value_str() else { continue; diff --git a/common/nyxd-scraper-psql/src/storage/transaction.rs b/common/nyxd-scraper-psql/src/storage/transaction.rs index 5aad23dfe1..34923d1983 100644 --- a/common/nyxd-scraper-psql/src/storage/transaction.rs +++ b/common/nyxd-scraper-psql/src/storage/transaction.rs @@ -147,6 +147,7 @@ impl PostgresStorageTransaction { for chain_tx in txs { // bdjuno style, base64 encode them let signatures = chain_tx + .tx_details .tx .signatures .iter() @@ -154,12 +155,14 @@ impl PostgresStorageTransaction { .collect(); let messages = chain_tx - .parsed_messages + .decoded_messages .values() + .map(|msg| &msg.decoded_content) .cloned() .collect::>(); let signer_infos = chain_tx + .tx_details .tx .auth_info .signer_infos @@ -167,28 +170,28 @@ impl PostgresStorageTransaction { .map(|info| proto::cosmos::tx::v1beta1::SignerInfo::from(info.clone())) .collect::>(); - let hash = chain_tx.hash.to_string(); - let height = chain_tx.height.into(); - let index = chain_tx.index as i32; + let hash = chain_tx.tx_details.hash.to_string(); + let height = chain_tx.tx_details.height().into(); + let index = chain_tx.tx_details.index as i32; - let log = serde_json::to_value(chain_tx.tx_result.log.clone()) + let log = serde_json::to_value(chain_tx.tx_details.tx_result.log.clone()) .inspect_err(|e| error!(hash, height, index, "Failed to parse logs: {e}")) .unwrap_or_default(); - let events = &chain_tx.tx_result.events; + let events = &chain_tx.tx_details.tx_result.events; insert_transaction( hash, height, index, - chain_tx.tx_result.code.is_ok(), + chain_tx.tx_details.tx_result.code.is_ok(), serde_json::Value::Array(messages), - chain_tx.tx.body.memo.clone(), + chain_tx.tx_details.tx.body.memo.clone(), signatures, serde_json::to_value(signer_infos)?, - serde_json::to_value(&chain_tx.tx.auth_info.fee)?, - chain_tx.tx_result.gas_wanted, - chain_tx.tx_result.gas_used, - chain_tx.tx_result.log.clone(), + serde_json::to_value(&chain_tx.tx_details.tx.auth_info.fee)?, + chain_tx.tx_details.tx_result.gas_wanted, + chain_tx.tx_details.tx_result.gas_used, + chain_tx.tx_details.tx_result.log.clone(), json!(log), json!(events), self.inner.as_mut(), @@ -207,17 +210,20 @@ impl PostgresStorageTransaction { for chain_tx in txs { let involved_addresses = parse_addresses_from_events(chain_tx); - for (index, msg) in chain_tx.tx.body.messages.iter().enumerate() { - let parsed_message = chain_tx.parsed_messages.get(&index); + for (index, msg) in chain_tx.tx_details.tx.body.messages.iter().enumerate() { + let parsed_message = chain_tx + .decoded_messages + .get(&index) + .map(|msg| &msg.decoded_content); let value = serde_json::to_value(parsed_message)?; insert_message( - chain_tx.hash.to_string(), + chain_tx.tx_details.hash.to_string(), index as i64, msg.type_url.clone(), value, involved_addresses.clone(), - chain_tx.height.into(), + chain_tx.tx_details.height().into(), self.inner.as_mut(), ) .await? diff --git a/common/nyxd-scraper-shared/examples/watcher.rs b/common/nyxd-scraper-shared/examples/watcher.rs index 3d72c8bb5a..bbcbe6a3da 100644 --- a/common/nyxd-scraper-shared/examples/watcher.rs +++ b/common/nyxd-scraper-shared/examples/watcher.rs @@ -33,9 +33,9 @@ impl TxModule for FancyTxModule { async fn handle_tx(&mut self, tx: &ParsedTransactionResponse) -> Result<(), ScraperError> { println!( "✨ got new tx for height {}: {} ({} msgs)", - tx.block.header.height, - tx.hash, - tx.parsed_messages.len() + tx.tx_details.height(), + tx.tx_details.hash, + tx.tx_details.tx.body.messages.len() ); Ok(()) diff --git a/common/nyxd-scraper-shared/src/block_processor/mod.rs b/common/nyxd-scraper-shared/src/block_processor/mod.rs index d29129b790..86f1910a9a 100644 --- a/common/nyxd-scraper-shared/src/block_processor/mod.rs +++ b/common/nyxd-scraper-shared/src/block_processor/mod.rs @@ -281,7 +281,7 @@ where &mut self, block: BlockToProcess, ) -> Result<(), ScraperError> { - info!("processing block at height {}", block.height); + debug!("processing block at height {}", block.height); let full_info = self .rpc_client @@ -291,8 +291,13 @@ where if let Some(tx_info) = &full_info.transactions { debug!("this block has {} transaction(s)", tx_info.len()); for tx in tx_info { - debug!("{} has {} message(s)", tx.hash, tx.tx.body.messages.len()); - for (index, msg) in tx.tx.body.messages.iter().enumerate() { + let details = &tx.tx_details; + debug!( + "{} has {} message(s)", + details.hash, + details.tx.body.messages.len() + ); + for (index, msg) in details.tx.body.messages.iter().enumerate() { debug!("{index}: {:?}", msg.type_url) } } @@ -315,11 +320,24 @@ where for tx_module in &mut self.tx_modules { tx_module.handle_tx(block_tx).await?; } + let tx_details = &block_tx.tx_details; + // the ones concerned with individual messages - for (index, msg) in block_tx.tx.body.messages.iter().enumerate() { + for (index, msg) in tx_details.tx.body.messages.iter().enumerate() { + let Some(decoded) = block_tx.decoded_messages.get(&index) else { + warn!( + "height: {} tx: {} tx_index: {}, msg_index: {index}: message failed to get decoded", + tx_details.height(), + tx_details.hash, + tx_details.index, + ); + continue; + }; for msg_module in &mut self.msg_modules { if msg.type_url == msg_module.type_url() { - msg_module.handle_msg(index, msg, block_tx).await? + msg_module + .handle_msg(index, msg, decoded, tx_details) + .await? } } } diff --git a/common/nyxd-scraper-shared/src/block_processor/types.rs b/common/nyxd-scraper-shared/src/block_processor/types.rs index 044d9bcffc..b835dd69be 100644 --- a/common/nyxd-scraper-shared/src/block_processor/types.rs +++ b/common/nyxd-scraper-shared/src/block_processor/types.rs @@ -7,9 +7,16 @@ use tendermint::{Block, Hash, abci, block, tx}; use tendermint_rpc::endpoint::{block as block_endpoint, block_results, validators}; use tendermint_rpc::event::{Event, EventData}; -// just get all everything out of tx::Response, but parse raw `tx` bytes +/// Message decoded from the raw transaction and converted into json. +/// Note that it might have gone through additional processing as set by the `MessageRegistry` #[derive(Clone, Debug)] -pub struct ParsedTransactionResponse { +pub struct DecodedMessage { + pub type_url: String, + pub decoded_content: serde_json::Value, +} + +#[derive(Clone, Debug)] +pub struct ParsedTransactionDetails { /// The hash of the transaction. /// /// Deserialized from a hex-encoded string (there is a discrepancy between @@ -17,8 +24,6 @@ pub struct ParsedTransactionResponse { /// the Tendermint RPC). pub hash: Hash, - pub height: block::Height, - pub index: u32, pub tx_result: abci::types::ExecTxResult, @@ -27,13 +32,23 @@ pub struct ParsedTransactionResponse { pub proof: Option, - pub parsed_messages: BTreeMap, - - pub parsed_message_urls: BTreeMap, - pub block: Block, } +impl ParsedTransactionDetails { + pub fn height(&self) -> block::Height { + self.block.header.height + } +} + +// just get all everything out of tx::Response, but parse raw `tx` bytes +#[derive(Clone, Debug)] +pub struct ParsedTransactionResponse { + pub tx_details: ParsedTransactionDetails, + + pub decoded_messages: BTreeMap, +} + #[derive(Debug)] pub struct FullBlockInformation { /// Basic block information, including its signers. diff --git a/common/nyxd-scraper-shared/src/error.rs b/common/nyxd-scraper-shared/src/error.rs index 41264896ee..d35a449ca7 100644 --- a/common/nyxd-scraper-shared/src/error.rs +++ b/common/nyxd-scraper-shared/src/error.rs @@ -82,10 +82,8 @@ pub enum ScraperError { source: cosmrs::ErrorReport, }, - #[error("could not parse msg in tx {hash} at index {index} into {type_url}: {source}")] + #[error("could not parse msg of type {type_url}: {source}")] MsgParseFailure { - hash: Hash, - index: usize, type_url: String, #[source] source: cosmrs::ErrorReport, diff --git a/common/nyxd-scraper-shared/src/helpers.rs b/common/nyxd-scraper-shared/src/helpers.rs index 54c5a1cbc0..b519dddb3b 100644 --- a/common/nyxd-scraper-shared/src/helpers.rs +++ b/common/nyxd-scraper-shared/src/helpers.rs @@ -47,7 +47,7 @@ pub fn validator_consensus_address(id: account::Id) -> Result i64 { - txs.iter().map(|tx| tx.tx_result.gas_used).sum() + txs.iter().map(|tx| tx.tx_details.tx_result.gas_used).sum() } pub fn validator_info( diff --git a/common/nyxd-scraper-shared/src/lib.rs b/common/nyxd-scraper-shared/src/lib.rs index 43afe4f83d..e6f00b7609 100644 --- a/common/nyxd-scraper-shared/src/lib.rs +++ b/common/nyxd-scraper-shared/src/lib.rs @@ -15,12 +15,14 @@ pub(crate) mod subscriber; pub mod watcher; pub use block_processor::pruning::{PruningOptions, PruningStrategy}; -pub use block_processor::types::ParsedTransactionResponse; +pub use block_processor::types::{ + DecodedMessage, ParsedTransactionDetails, ParsedTransactionResponse, +}; pub use cosmos_module::{ CosmosModule, message_registry::{MessageRegistry, default_message_registry}, }; pub use cosmrs::Any; -pub use modules::{BlockModule, MsgModule, TxModule}; +pub use modules::{BlockModule, MsgModule, TxModule, parse_msg}; pub use scraper::{Config, NyxdScraper, StartingBlockOpts}; pub use storage::{NyxdScraperStorage, NyxdScraperTransaction}; diff --git a/common/nyxd-scraper-shared/src/modules/mod.rs b/common/nyxd-scraper-shared/src/modules/mod.rs index 1f37d149e0..7e131003ee 100644 --- a/common/nyxd-scraper-shared/src/modules/mod.rs +++ b/common/nyxd-scraper-shared/src/modules/mod.rs @@ -6,5 +6,5 @@ mod msg_module; mod tx_module; pub use block_module::BlockModule; -pub use msg_module::MsgModule; +pub use msg_module::{MsgModule, parse_msg}; pub use tx_module::TxModule; diff --git a/common/nyxd-scraper-shared/src/modules/msg_module.rs b/common/nyxd-scraper-shared/src/modules/msg_module.rs index 93b09bf427..0061e612af 100644 --- a/common/nyxd-scraper-shared/src/modules/msg_module.rs +++ b/common/nyxd-scraper-shared/src/modules/msg_module.rs @@ -1,11 +1,47 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::block_processor::types::ParsedTransactionResponse; +use crate::block_processor::types::{DecodedMessage, ParsedTransactionDetails}; use crate::error::ScraperError; use async_trait::async_trait; use cosmrs::Any; +use cosmrs::tx::Msg; +/// Parse a protobuf `Any` message into a strongly typed Cosmos message. +/// +/// # Example +/// +/// ```rust,ignore +/// let execute_msg: MsgExecuteContract = parse_msg(msg)?; +/// ``` +/// +/// # Errors +/// +/// Returns `ScraperError::MsgParseFailure` if: +/// - The type URL doesn't match the expected type +/// - The protobuf bytes are malformed +/// - The message schema is incompatible with this version of the code +pub fn parse_msg(msg: &Any) -> Result { + T::from_any(msg).map_err(|source| ScraperError::MsgParseFailure { + type_url: msg.type_url.clone(), + source, + }) +} + +/// Trait for modules that process specific message types from blockchain transactions. +/// +/// # Parameters +/// +/// - `index`: Position of this message within the transaction (0-based) +/// - `msg`: Raw protobuf message (use `parse_msg()` to decode) +/// - `decoded_msg`: Pre-decoded JSON representation (may be None for unsupported types) +/// - `tx`: Transaction details including block height, hash, and execution result +/// +/// # Error Handling +/// +/// - Return `Err` for critical failures that should stop block processing +/// - Return `Ok(())` for non-critical errors (e.g., unexpected contract schema) +/// - Log warnings for debugging without propagating errors #[async_trait] pub trait MsgModule { fn type_url(&self) -> String; @@ -14,6 +50,7 @@ pub trait MsgModule { &mut self, index: usize, msg: &Any, - tx: &ParsedTransactionResponse, + decoded_msg: &DecodedMessage, + tx: &ParsedTransactionDetails, ) -> Result<(), ScraperError>; } diff --git a/common/nyxd-scraper-shared/src/rpc_client.rs b/common/nyxd-scraper-shared/src/rpc_client.rs index 8d1df1890e..0d41e907e0 100644 --- a/common/nyxd-scraper-shared/src/rpc_client.rs +++ b/common/nyxd-scraper-shared/src/rpc_client.rs @@ -2,11 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 use crate::block_processor::types::{ - BlockToProcess, FullBlockInformation, ParsedTransactionResponse, + BlockToProcess, DecodedMessage, FullBlockInformation, ParsedTransactionResponse, }; use crate::error::ScraperError; use crate::helpers::tx_hash; -use crate::{Any, MessageRegistry, default_message_registry}; +use crate::{Any, MessageRegistry, ParsedTransactionDetails, default_message_registry}; use futures::StreamExt; use futures::future::join3; use std::collections::BTreeMap; @@ -77,8 +77,7 @@ impl RpcClient { ) -> Result, ScraperError> { let mut transactions = Vec::with_capacity(raw_transactions.len()); for raw_tx in raw_transactions { - let mut parsed_messages = BTreeMap::new(); - let mut parsed_message_urls = BTreeMap::new(); + let mut decoded_messages = BTreeMap::new(); let tx = cosmrs::Tx::from_bytes(&raw_tx.tx).map_err(|source| { ScraperError::TxParseFailure { hash: raw_tx.hash, @@ -87,22 +86,27 @@ impl RpcClient { })?; for (index, msg) in tx.body.messages.iter().enumerate() { - if let Some(value) = self.decode_or_skip(msg) { - parsed_messages.insert(index, value); - parsed_message_urls.insert(index, msg.type_url.clone()); + if let Some(decoded_content) = self.decode_or_skip(msg) { + decoded_messages.insert( + index, + DecodedMessage { + type_url: msg.type_url.clone(), + decoded_content, + }, + ); } } transactions.push(ParsedTransactionResponse { - hash: raw_tx.hash, - height: raw_tx.height, - index: raw_tx.index, - tx_result: raw_tx.tx_result, - tx, - proof: raw_tx.proof, - parsed_messages, - parsed_message_urls, - block: block.clone(), + tx_details: ParsedTransactionDetails { + hash: raw_tx.hash, + index: raw_tx.index, + tx_result: raw_tx.tx_result, + tx, + proof: raw_tx.proof, + block: block.clone(), + }, + decoded_messages, }) } Ok(transactions) diff --git a/common/nyxd-scraper-shared/src/watcher.rs b/common/nyxd-scraper-shared/src/watcher.rs index 3ba3ea5b4e..52633585cf 100644 --- a/common/nyxd-scraper-shared/src/watcher.rs +++ b/common/nyxd-scraper-shared/src/watcher.rs @@ -14,15 +14,16 @@ use tracing::info; use url::Url; pub struct WatcherConfig { - /// Url to the websocket endpoint of a validator, for example `wss://rpc.nymtech.net/websocket` + /// Url to the websocket endpoint of a validator, for example, `wss://rpc.nymtech.net/websocket` pub websocket_url: Url, - /// Url to the rpc endpoint of a validator, for example `https://rpc.nymtech.net/` + /// Url to the rpc endpoint of a validator, for example, `https://rpc.nymtech.net/` pub rpc_url: Url, } pub struct NyxdWatcherBuilder { config: WatcherConfig, + custom_shutdown: CancellationToken, block_modules: Vec>, tx_modules: Vec>, @@ -33,12 +34,19 @@ impl NyxdWatcherBuilder { pub fn new(config: WatcherConfig) -> Self { NyxdWatcherBuilder { config, + custom_shutdown: CancellationToken::new(), block_modules: vec![], tx_modules: vec![], msg_modules: vec![], } } + #[must_use] + pub fn with_custom_shutdown(mut self, token: CancellationToken) -> Self { + self.custom_shutdown = token; + self + } + #[must_use] pub fn with_block_module(mut self, module: M) -> Self { self.block_modules.push(Box::new(module)); diff --git a/common/nyxd-scraper-sqlite/src/lib.rs b/common/nyxd-scraper-sqlite/src/lib.rs index 56c202b63f..18eb916d43 100644 --- a/common/nyxd-scraper-sqlite/src/lib.rs +++ b/common/nyxd-scraper-sqlite/src/lib.rs @@ -7,8 +7,9 @@ use nyxd_scraper_shared::NyxdScraper; pub use nyxd_scraper_shared::constants; pub use nyxd_scraper_shared::error::ScraperError; pub use nyxd_scraper_shared::{ - BlockModule, MsgModule, NyxdScraperTransaction, ParsedTransactionResponse, PruningOptions, - PruningStrategy, StartingBlockOpts, TxModule, + BlockModule, DecodedMessage, MsgModule, NyxdScraperTransaction, ParsedTransactionDetails, + ParsedTransactionResponse, PruningOptions, PruningStrategy, StartingBlockOpts, TxModule, + parse_msg, }; pub use storage::models; diff --git a/common/nyxd-scraper-sqlite/src/storage/transaction.rs b/common/nyxd-scraper-sqlite/src/storage/transaction.rs index 0cd57b78c8..a1a8ef149b 100644 --- a/common/nyxd-scraper-sqlite/src/storage/transaction.rs +++ b/common/nyxd-scraper-sqlite/src/storage/transaction.rs @@ -132,15 +132,15 @@ impl SqliteStorageTransaction { for chain_tx in txs { insert_transaction( - chain_tx.hash.to_string(), - chain_tx.height.into(), - chain_tx.index as i64, - chain_tx.tx_result.code.is_ok(), - chain_tx.tx.body.messages.len() as i64, - chain_tx.tx.body.memo.clone(), - chain_tx.tx_result.gas_wanted, - chain_tx.tx_result.gas_used, - chain_tx.tx_result.log.clone(), + chain_tx.tx_details.hash.to_string(), + chain_tx.tx_details.height().into(), + chain_tx.tx_details.index as i64, + chain_tx.tx_details.tx_result.code.is_ok(), + chain_tx.tx_details.tx.body.messages.len() as i64, + chain_tx.tx_details.tx.body.memo.clone(), + chain_tx.tx_details.tx_result.gas_wanted, + chain_tx.tx_details.tx_result.gas_used, + chain_tx.tx_details.tx_result.log.clone(), self.0.as_mut(), ) .await?; @@ -156,12 +156,12 @@ impl SqliteStorageTransaction { debug!("persisting messages"); for chain_tx in txs { - for (index, msg) in chain_tx.tx.body.messages.iter().enumerate() { + for (index, msg) in chain_tx.tx_details.tx.body.messages.iter().enumerate() { insert_message( - chain_tx.hash.to_string(), + chain_tx.tx_details.hash.to_string(), index as i64, msg.type_url.clone(), - chain_tx.height.into(), + chain_tx.tx_details.height().into(), self.0.as_mut(), ) .await? diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index 1fb526afa4..10663f6bd1 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -1180,6 +1180,22 @@ dependencies = [ "rand_chacha", ] +[[package]] +name = "network-monitors" +version = "1.0.0" +dependencies = [ + "anyhow", + "bs58", + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers", + "cw-storage-plus", + "cw2", + "nym-contracts-common", + "nym-contracts-common-testing", + "nym-network-monitors-contract-common", +] + [[package]] name = "num-bigint" version = "0.4.6" @@ -1456,6 +1472,18 @@ dependencies = [ "regex", ] +[[package]] +name = "nym-network-monitors-contract-common" +version = "1.20.4" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers", + "schemars", + "serde", + "thiserror 2.0.12", +] + [[package]] name = "nym-pemstore" version = "1.20.4" diff --git a/contracts/Cargo.toml b/contracts/Cargo.toml index 0b23099771..342e9029bf 100644 --- a/contracts/Cargo.toml +++ b/contracts/Cargo.toml @@ -10,6 +10,7 @@ members = [ "multisig/cw4-group", "vesting", "performance", + "network-monitors", ] [workspace.package] @@ -19,6 +20,8 @@ homepage = "https://nymtech.net" documentation = "https://nymtech.net" edition = "2021" license = "Apache-2.0" +rust-version = "1.86.0" +readme = "../README.md" [profile.release] opt-level = 3 @@ -67,6 +70,7 @@ nym-ecash-contract-common = "1.20.4" nym-group-contract-common = "1.20.4" nym-mixnet-contract-common = "1.20.4" nym-multisig-contract-common = "1.20.4" +nym-network-monitors-contract-common = "1.20.4" nym-network-defaults = { version = "1.20.4", default-features = false } nym-performance-contract-common = "1.20.4" nym-pool-contract-common = "1.20.4" @@ -94,8 +98,6 @@ unimplemented = "deny" unreachable = "deny" # For local development, import via path instead of crates.io, e.g. -# [patch.crates-io] -# nym-coconut-dkg-common = { path = "../common/cosmwasm-smart-contracts/coconut-dkg" } - [patch.crates-io] +nym-network-monitors-contract-common = { path = "../common/cosmwasm-smart-contracts/network-monitors-contract" } nym-ecash-contract-common = { path = "../common/cosmwasm-smart-contracts/ecash-contract" } diff --git a/contracts/network-monitors/.cargo/config b/contracts/network-monitors/.cargo/config new file mode 100644 index 0000000000..2fb2c1afdb --- /dev/null +++ b/contracts/network-monitors/.cargo/config @@ -0,0 +1,4 @@ +[alias] +wasm = "build --release --lib --target wasm32-unknown-unknown" +unit-test = "test --lib" +schema = "run --bin schema --features=schema-gen" \ No newline at end of file diff --git a/contracts/network-monitors/Cargo.toml b/contracts/network-monitors/Cargo.toml new file mode 100644 index 0000000000..5a29cf154a --- /dev/null +++ b/contracts/network-monitors/Cargo.toml @@ -0,0 +1,43 @@ +[package] +name = "network-monitors" +description = "CosmWasm smart contract storing information on Nym network monitors" +version = "1.0.0" +authors.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +homepage.workspace = true +documentation.workspace = true +rust-version.workspace = true +readme.workspace = true +publish = false + +[[bin]] +name = "schema" +required-features = ["schema-gen"] + +[lib] +name = "network_monitors_contract" +crate-type = ["cdylib", "rlib"] + +[dependencies] +bs58 = { workspace = true } +cosmwasm-std = { workspace = true } +cw2 = { workspace = true } +cw-storage-plus = { workspace = true } +cw-controllers = { workspace = true } + +cosmwasm-schema = { workspace = true, optional = true } + +nym-network-monitors-contract-common = { workspace = true } +nym-contracts-common = { workspace = true } + +[dev-dependencies] +anyhow = { workspace = true } +nym-contracts-common-testing = { workspace = true } + +[features] +schema-gen = ["nym-network-monitors-contract-common/schema", "cosmwasm-schema"] + +[lints] +workspace = true diff --git a/contracts/network-monitors/Makefile b/contracts/network-monitors/Makefile new file mode 100644 index 0000000000..086fa71ad3 --- /dev/null +++ b/contracts/network-monitors/Makefile @@ -0,0 +1,5 @@ +wasm: + RUSTFLAGS='-C link-arg=-s' cargo build --release --target wasm32-unknown-unknown + +generate-schema: + cargo schema diff --git a/contracts/network-monitors/schema/network-monitors.json b/contracts/network-monitors/schema/network-monitors.json new file mode 100644 index 0000000000..1d4daa680d --- /dev/null +++ b/contracts/network-monitors/schema/network-monitors.json @@ -0,0 +1,368 @@ +{ + "contract_name": "network-monitors", + "contract_version": "0.1.0", + "idl_version": "1.0.0", + "instantiate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "orchestrator_address" + ], + "properties": { + "orchestrator_address": { + "description": "Address of the initial network monitor orchestrator.", + "type": "string" + } + }, + "additionalProperties": false + }, + "execute": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Change the admin", + "type": "object", + "required": [ + "update_admin" + ], + "properties": { + "update_admin": { + "type": "object", + "required": [ + "admin" + ], + "properties": { + "admin": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Authorise new network monitor orchestrator", + "type": "object", + "required": [ + "authorise_network_monitor_orchestrator" + ], + "properties": { + "authorise_network_monitor_orchestrator": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Revoke network monitor orchestrator authorisation.", + "type": "object", + "required": [ + "revoke_network_monitor_orchestrator" + ], + "properties": { + "revoke_network_monitor_orchestrator": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Authorise new network monitor (or renew authorisation) granting additional privileges when sending mixnet packets to Nym nodes.", + "type": "object", + "required": [ + "authorise_network_monitor" + ], + "properties": { + "authorise_network_monitor": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string", + "format": "ip" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Revoke network monitor authorisation.", + "type": "object", + "required": [ + "revoke_network_monitor" + ], + "properties": { + "revoke_network_monitor": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string", + "format": "ip" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Revoke all network monitor authorisations.", + "type": "string", + "enum": [ + "revoke_all_network_monitors" + ] + } + ] + }, + "query": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "admin" + ], + "properties": { + "admin": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "network_monitor_orchestrators" + ], + "properties": { + "network_monitor_orchestrators": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "network_monitor_agents" + ], + "properties": { + "network_monitor_agents": { + "type": "object", + "properties": { + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "string", + "null" + ], + "format": "ip" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "migrate": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "additionalProperties": false + }, + "sudo": null, + "responses": { + "admin": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AdminResponse", + "description": "Returned from Admin.query_admin()", + "type": "object", + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + }, + "network_monitor_agents": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AuthorisedNetworkMonitorsPagedResponse", + "type": "object", + "required": [ + "authorised" + ], + "properties": { + "authorised": { + "type": "array", + "items": { + "$ref": "#/definitions/AuthorisedNetworkMonitor" + } + }, + "start_next_after": { + "type": [ + "string", + "null" + ], + "format": "ip" + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "AuthorisedNetworkMonitor": { + "type": "object", + "required": [ + "address", + "authorised_at", + "authorised_by" + ], + "properties": { + "address": { + "description": "The Ip address associated with the network monitor agent.", + "type": "string", + "format": "ip" + }, + "authorised_at": { + "description": "Timestamp of when the network monitor was authorised.", + "allOf": [ + { + "$ref": "#/definitions/Timestamp" + } + ] + }, + "authorised_by": { + "description": "The address of the orchestrator that authorised the network monitor agent.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + }, + "additionalProperties": false + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } + }, + "network_monitor_orchestrators": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AuthorisedNetworkMonitorOrchestratorsResponse", + "type": "object", + "required": [ + "authorised" + ], + "properties": { + "authorised": { + "type": "array", + "items": { + "$ref": "#/definitions/AuthorisedNetworkMonitorOrchestrator" + } + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "AuthorisedNetworkMonitorOrchestrator": { + "type": "object", + "required": [ + "address", + "authorised_at" + ], + "properties": { + "address": { + "description": "The address associated with the network monitor orchestrator.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "authorised_at": { + "description": "Timestamp of when the network monitor was authorised.", + "allOf": [ + { + "$ref": "#/definitions/Timestamp" + } + ] + } + }, + "additionalProperties": false + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } + } + } +} diff --git a/contracts/network-monitors/schema/raw/execute.json b/contracts/network-monitors/schema/raw/execute.json new file mode 100644 index 0000000000..f1b73c039f --- /dev/null +++ b/contracts/network-monitors/schema/raw/execute.json @@ -0,0 +1,125 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "ExecuteMsg", + "oneOf": [ + { + "description": "Change the admin", + "type": "object", + "required": [ + "update_admin" + ], + "properties": { + "update_admin": { + "type": "object", + "required": [ + "admin" + ], + "properties": { + "admin": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Authorise new network monitor orchestrator", + "type": "object", + "required": [ + "authorise_network_monitor_orchestrator" + ], + "properties": { + "authorise_network_monitor_orchestrator": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Revoke network monitor orchestrator authorisation.", + "type": "object", + "required": [ + "revoke_network_monitor_orchestrator" + ], + "properties": { + "revoke_network_monitor_orchestrator": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Authorise new network monitor (or renew authorisation) granting additional privileges when sending mixnet packets to Nym nodes.", + "type": "object", + "required": [ + "authorise_network_monitor" + ], + "properties": { + "authorise_network_monitor": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string", + "format": "ip" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Revoke network monitor authorisation.", + "type": "object", + "required": [ + "revoke_network_monitor" + ], + "properties": { + "revoke_network_monitor": { + "type": "object", + "required": [ + "address" + ], + "properties": { + "address": { + "type": "string", + "format": "ip" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "description": "Revoke all network monitor authorisations.", + "type": "string", + "enum": [ + "revoke_all_network_monitors" + ] + } + ] +} diff --git a/contracts/network-monitors/schema/raw/instantiate.json b/contracts/network-monitors/schema/raw/instantiate.json new file mode 100644 index 0000000000..76e97a0950 --- /dev/null +++ b/contracts/network-monitors/schema/raw/instantiate.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "InstantiateMsg", + "type": "object", + "required": [ + "orchestrator_address" + ], + "properties": { + "orchestrator_address": { + "description": "Address of the initial network monitor orchestrator.", + "type": "string" + } + }, + "additionalProperties": false +} diff --git a/contracts/network-monitors/schema/raw/migrate.json b/contracts/network-monitors/schema/raw/migrate.json new file mode 100644 index 0000000000..7fbe8c5708 --- /dev/null +++ b/contracts/network-monitors/schema/raw/migrate.json @@ -0,0 +1,6 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "MigrateMsg", + "type": "object", + "additionalProperties": false +} diff --git a/contracts/network-monitors/schema/raw/query.json b/contracts/network-monitors/schema/raw/query.json new file mode 100644 index 0000000000..edffb9922f --- /dev/null +++ b/contracts/network-monitors/schema/raw/query.json @@ -0,0 +1,64 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "QueryMsg", + "oneOf": [ + { + "type": "object", + "required": [ + "admin" + ], + "properties": { + "admin": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "network_monitor_orchestrators" + ], + "properties": { + "network_monitor_orchestrators": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "network_monitor_agents" + ], + "properties": { + "network_monitor_agents": { + "type": "object", + "properties": { + "limit": { + "description": "Controls the maximum number of entries returned by the query. Note that too large values will be overwritten by a saner default.", + "type": [ + "integer", + "null" + ], + "format": "uint32", + "minimum": 0.0 + }, + "start_next_after": { + "description": "Pagination control for the values returned by the query. Note that the provided value itself will **not** be used for the response.", + "type": [ + "string", + "null" + ], + "format": "ip" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] +} diff --git a/contracts/network-monitors/schema/raw/response_to_admin.json b/contracts/network-monitors/schema/raw/response_to_admin.json new file mode 100644 index 0000000000..c73969ab04 --- /dev/null +++ b/contracts/network-monitors/schema/raw/response_to_admin.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AdminResponse", + "description": "Returned from Admin.query_admin()", + "type": "object", + "properties": { + "admin": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false +} diff --git a/contracts/network-monitors/schema/raw/response_to_network_monitor_agents.json b/contracts/network-monitors/schema/raw/response_to_network_monitor_agents.json new file mode 100644 index 0000000000..3ee1b74278 --- /dev/null +++ b/contracts/network-monitors/schema/raw/response_to_network_monitor_agents.json @@ -0,0 +1,74 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AuthorisedNetworkMonitorsPagedResponse", + "type": "object", + "required": [ + "authorised" + ], + "properties": { + "authorised": { + "type": "array", + "items": { + "$ref": "#/definitions/AuthorisedNetworkMonitor" + } + }, + "start_next_after": { + "type": [ + "string", + "null" + ], + "format": "ip" + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "AuthorisedNetworkMonitor": { + "type": "object", + "required": [ + "address", + "authorised_at", + "authorised_by" + ], + "properties": { + "address": { + "description": "The Ip address associated with the network monitor agent.", + "type": "string", + "format": "ip" + }, + "authorised_at": { + "description": "Timestamp of when the network monitor was authorised.", + "allOf": [ + { + "$ref": "#/definitions/Timestamp" + } + ] + }, + "authorised_by": { + "description": "The address of the orchestrator that authorised the network monitor agent.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + } + }, + "additionalProperties": false + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/network-monitors/schema/raw/response_to_network_monitor_orchestrators.json b/contracts/network-monitors/schema/raw/response_to_network_monitor_orchestrators.json new file mode 100644 index 0000000000..f08a35e9df --- /dev/null +++ b/contracts/network-monitors/schema/raw/response_to_network_monitor_orchestrators.json @@ -0,0 +1,61 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "AuthorisedNetworkMonitorOrchestratorsResponse", + "type": "object", + "required": [ + "authorised" + ], + "properties": { + "authorised": { + "type": "array", + "items": { + "$ref": "#/definitions/AuthorisedNetworkMonitorOrchestrator" + } + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + }, + "AuthorisedNetworkMonitorOrchestrator": { + "type": "object", + "required": [ + "address", + "authorised_at" + ], + "properties": { + "address": { + "description": "The address associated with the network monitor orchestrator.", + "allOf": [ + { + "$ref": "#/definitions/Addr" + } + ] + }, + "authorised_at": { + "description": "Timestamp of when the network monitor was authorised.", + "allOf": [ + { + "$ref": "#/definitions/Timestamp" + } + ] + } + }, + "additionalProperties": false + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/network-monitors/src/bin/schema.rs b/contracts/network-monitors/src/bin/schema.rs new file mode 100644 index 0000000000..734d1c3b2a --- /dev/null +++ b/contracts/network-monitors/src/bin/schema.rs @@ -0,0 +1,14 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use cosmwasm_schema::write_api; +use nym_network_monitors_contract_common::{ExecuteMsg, InstantiateMsg, MigrateMsg, QueryMsg}; + +fn main() { + write_api! { + instantiate: InstantiateMsg, + query: QueryMsg, + execute: ExecuteMsg, + migrate: MigrateMsg, + } +} diff --git a/contracts/network-monitors/src/contract.rs b/contracts/network-monitors/src/contract.rs new file mode 100644 index 0000000000..1dbd50b16a --- /dev/null +++ b/contracts/network-monitors/src/contract.rs @@ -0,0 +1,179 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::queries::{ + query_admin, query_network_monitor_agents, query_network_monitor_orchestrators, +}; +use crate::storage::NETWORK_MONITORS_CONTRACT_STORAGE; +use crate::transactions::{ + try_authorise_network_monitor, try_authorise_network_monitor_orchestrator, + try_revoke_all_network_monitors, try_revoke_network_monitor, + try_revoke_network_monitor_orchestrator, try_update_contract_admin, + try_update_orchestrator_identity_key, +}; +use cosmwasm_std::{ + entry_point, to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, +}; +use nym_contracts_common::set_build_information; +use nym_network_monitors_contract_common::{ + ExecuteMsg, InstantiateMsg, MigrateMsg, NetworkMonitorsContractError, QueryMsg, +}; + +const CONTRACT_NAME: &str = "crate:nym-network-monitors-contract"; +const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); + +#[entry_point] +pub fn instantiate( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: InstantiateMsg, +) -> Result { + cw2::set_contract_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + set_build_information!(deps.storage)?; + + let orchestrator = deps.api.addr_validate(&msg.orchestrator_address)?; + NETWORK_MONITORS_CONTRACT_STORAGE.initialise(deps, env, info.sender, orchestrator)?; + + Ok(Response::default()) +} + +#[entry_point] +pub fn execute( + deps: DepsMut, + env: Env, + info: MessageInfo, + msg: ExecuteMsg, +) -> Result { + match msg { + ExecuteMsg::UpdateAdmin { admin } => try_update_contract_admin(deps, info, admin), + ExecuteMsg::AuthoriseNetworkMonitorOrchestrator { address } => { + try_authorise_network_monitor_orchestrator(deps, env, info, address) + } + ExecuteMsg::UpdateOrchestratorIdentityKey { key } => { + try_update_orchestrator_identity_key(deps, info, key) + } + ExecuteMsg::RevokeNetworkMonitorOrchestrator { address } => { + try_revoke_network_monitor_orchestrator(deps, info, address) + } + ExecuteMsg::AuthoriseNetworkMonitor { + mixnet_address: address, + bs58_x25519_noise, + noise_version, + } => try_authorise_network_monitor( + deps, + env, + info, + address, + bs58_x25519_noise, + noise_version, + ), + ExecuteMsg::RevokeNetworkMonitor { address } => { + try_revoke_network_monitor(deps, info, address) + } + ExecuteMsg::RevokeAllNetworkMonitors => try_revoke_all_network_monitors(deps, info), + } +} + +#[entry_point] +pub fn query(deps: Deps, _: Env, msg: QueryMsg) -> Result { + match msg { + QueryMsg::Admin {} => Ok(to_json_binary(&query_admin(deps)?)?), + QueryMsg::NetworkMonitorOrchestrators {} => { + Ok(to_json_binary(&query_network_monitor_orchestrators(deps)?)?) + } + QueryMsg::NetworkMonitorAgents { + start_next_after, + limit, + } => Ok(to_json_binary(&query_network_monitor_agents( + deps, + start_next_after, + limit, + )?)?), + } +} + +#[entry_point] +pub fn migrate( + deps: DepsMut, + _env: Env, + _msg: MigrateMsg, +) -> Result { + set_build_information!(deps.storage)?; + cw2::ensure_from_older_version(deps.storage, CONTRACT_NAME, CONTRACT_VERSION)?; + + Ok(Default::default()) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[cfg(test)] + mod contract_instantiation { + use super::*; + use cosmwasm_std::testing::{message_info, mock_dependencies, mock_env}; + use cosmwasm_std::Addr; + + #[test] + fn sets_contract_admin_to_the_message_sender() -> anyhow::Result<()> { + let mut deps = mock_dependencies(); + let env = mock_env(); + let init_msg = InstantiateMsg { + orchestrator_address: deps.api.addr_make("foo").to_string(), + }; + + let some_sender = deps.api.addr_make("some_sender"); + instantiate( + deps.as_mut(), + env, + message_info(&some_sender, &[]), + init_msg, + )?; + + NETWORK_MONITORS_CONTRACT_STORAGE + .contract_admin + .assert_admin(deps.as_ref(), &some_sender)?; + + Ok(()) + } + + #[test] + fn sets_the_initial_orchestrator() -> anyhow::Result<()> { + let mut deps = mock_dependencies(); + let env = mock_env(); + let admin = deps.api.addr_make("some_sender"); + + let bad_addr = "foo".to_string(); + let good_addr = deps.api.addr_make("foo").to_string(); + + let bad_init_msg = InstantiateMsg { + orchestrator_address: bad_addr.clone(), + }; + + let good_init_msg = InstantiateMsg { + orchestrator_address: good_addr.clone(), + }; + + let res = instantiate( + deps.as_mut(), + env.clone(), + message_info(&admin, &[]), + bad_init_msg, + ); + assert!(res.is_err()); + + let is_orchestrator = NETWORK_MONITORS_CONTRACT_STORAGE + .is_orchestrator(deps.as_ref(), &Addr::unchecked(&good_addr))?; + assert!(!is_orchestrator); + + instantiate(deps.as_mut(), env, message_info(&admin, &[]), good_init_msg)?; + + let is_orchestrator = NETWORK_MONITORS_CONTRACT_STORAGE + .is_orchestrator(deps.as_ref(), &Addr::unchecked(&good_addr))?; + assert!(is_orchestrator); + + Ok(()) + } + } +} diff --git a/contracts/network-monitors/src/lib.rs b/contracts/network-monitors/src/lib.rs new file mode 100644 index 0000000000..8aff9760d1 --- /dev/null +++ b/contracts/network-monitors/src/lib.rs @@ -0,0 +1,11 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +pub mod contract; +pub mod queries; +pub mod queued_migrations; +pub mod storage; +pub mod transactions; + +#[cfg(test)] +pub mod testing; diff --git a/contracts/network-monitors/src/queries.rs b/contracts/network-monitors/src/queries.rs new file mode 100644 index 0000000000..27c8d98762 --- /dev/null +++ b/contracts/network-monitors/src/queries.rs @@ -0,0 +1,345 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::storage::{retrieval_limits, AgentStorageKey, NETWORK_MONITORS_CONTRACT_STORAGE}; +use cosmwasm_std::{Deps, StdResult}; +use cw_controllers::AdminResponse; +use cw_storage_plus::Bound; +use nym_network_monitors_contract_common::{ + AuthorisedNetworkMonitorOrchestratorsResponse, AuthorisedNetworkMonitorsPagedResponse, + NetworkMonitorsContractError, +}; +use std::net::SocketAddr; + +pub fn query_admin(deps: Deps) -> Result { + NETWORK_MONITORS_CONTRACT_STORAGE + .contract_admin + .query_admin(deps) + .map_err(Into::into) +} + +// no need for pagination as we don't expect even a double digit of those +pub fn query_network_monitor_orchestrators( + deps: Deps, +) -> Result { + let authorised = NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_orchestrators + .range(deps.storage, None, None, cosmwasm_std::Order::Ascending) + .map(|record| record.map(|(_, details)| details)) + .collect::>>()?; + + Ok(AuthorisedNetworkMonitorOrchestratorsResponse { authorised }) +} + +pub fn query_network_monitor_agents( + deps: Deps, + start_after: Option, + limit: Option, +) -> Result { + let limit = limit + .unwrap_or(retrieval_limits::AGENTS_DEFAULT_LIMIT) + .min(retrieval_limits::AGENTS_MAX_LIMIT) as usize; + + let start = start_after.map(|addr| Bound::exclusive(AgentStorageKey::from(addr))); + + let authorised = NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_agents + .range(deps.storage, start, None, cosmwasm_std::Order::Ascending) + .take(limit) + .map(|record| record.map(|(_, details)| details)) + .collect::>>()?; + + let start_next_after = authorised.last().map(|last| last.mixnet_address); + + Ok(AuthorisedNetworkMonitorsPagedResponse { + authorised, + start_next_after, + }) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[cfg(test)] + mod admin_query { + use crate::queries::query_admin; + use crate::testing::init_contract_tester; + use nym_contracts_common_testing::{AdminExt, ChainOpts, ContractOpts, RandExt}; + use nym_network_monitors_contract_common::ExecuteMsg; + + #[test] + fn returns_current_admin() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + + let initial_admin = test.admin_unchecked(); + + // initial + let res = query_admin(test.deps())?; + assert_eq!(res.admin, Some(initial_admin.to_string())); + + let new_admin = test.generate_account(); + + // sanity check + assert_ne!(initial_admin, new_admin); + + // after update + test.execute_msg( + initial_admin.clone(), + &ExecuteMsg::UpdateAdmin { + admin: new_admin.to_string(), + }, + )?; + + let updated_admin = query_admin(test.deps())?; + assert_eq!(updated_admin.admin, Some(new_admin.to_string())); + + Ok(()) + } + } + + #[cfg(test)] + mod network_monitor_orchestrators_query { + use super::*; + use crate::testing::{init_contract_tester, NetworkMonitorsContractTesterExt}; + use nym_contracts_common_testing::{AdminExt, ContractOpts}; + use nym_network_monitors_contract_common::ExecuteMsg; + + #[test] + fn returns_empty_list_when_there_are_no_extra_orchestrators() -> anyhow::Result<()> { + // make sure to start with an empty state + let mut test = init_contract_tester(); + test.remove_all_orchestrators(); + + let res = query_network_monitor_orchestrators(test.deps())?; + + assert!(res.authorised.is_empty()); + + Ok(()) + } + + #[test] + fn returns_all_authorised_orchestrators() -> anyhow::Result<()> { + // make sure to start with an empty state + let mut test = init_contract_tester(); + test.remove_all_orchestrators(); + + let orchestrator1 = test.add_orchestrator()?; + let orchestrator2 = test.add_orchestrator()?; + let orchestrator3 = test.add_orchestrator()?; + + let res = query_network_monitor_orchestrators(test.deps())?; + + assert_eq!(res.authorised.len(), 3); + assert!(res.authorised.iter().any(|o| o.address == orchestrator1)); + assert!(res.authorised.iter().any(|o| o.address == orchestrator2)); + assert!(res.authorised.iter().any(|o| o.address == orchestrator3)); + + Ok(()) + } + + #[test] + fn does_not_return_revoked_orchestrators() -> anyhow::Result<()> { + // make sure to start with an empty state + let mut test = init_contract_tester(); + test.remove_all_orchestrators(); + + let orchestrator1 = test.add_orchestrator()?; + let orchestrator2 = test.add_orchestrator()?; + + test.execute_raw( + test.admin_unchecked(), + ExecuteMsg::RevokeNetworkMonitorOrchestrator { + address: orchestrator1.to_string(), + }, + )?; + + let res = query_network_monitor_orchestrators(test.deps())?; + + assert!(!res.authorised.iter().any(|o| o.address == orchestrator1)); + assert!(res.authorised.iter().any(|o| o.address == orchestrator2)); + + Ok(()) + } + + #[test] + fn returns_entries_in_ascending_order() -> anyhow::Result<()> { + // make sure to start with an empty state + let mut test = init_contract_tester(); + test.remove_all_orchestrators(); + + test.add_orchestrator()?; + test.add_orchestrator()?; + test.add_orchestrator()?; + + let res = query_network_monitor_orchestrators(test.deps())?; + + assert!(res + .authorised + .windows(2) + .all(|window| window[0].address <= window[1].address)); + + Ok(()) + } + } + + #[cfg(test)] + mod network_monitor_agents_query { + use super::*; + use crate::testing::{ + init_contract_tester, storage_socket_comp, NetworkMonitorsContract, + NetworkMonitorsContractTesterExt, + }; + use nym_contracts_common_testing::{ContractOpts, ContractTester}; + use std::net::SocketAddr; + + fn storage_sorted_addresses( + test: &mut ContractTester, + n: usize, + ) -> Vec { + let mut ips = Vec::new(); + for _ in 0..n { + ips.push(test.random_socket()); + } + + ips.sort_by(|a, b| storage_socket_comp(*a, *b)); + ips + } + + #[test] + fn returns_empty_response_when_no_agents_are_authorised() -> anyhow::Result<()> { + let test = init_contract_tester(); + + let res = query_network_monitor_agents(test.deps(), None, None)?; + + assert!(res.authorised.is_empty()); + assert_eq!(res.start_next_after, None); + + Ok(()) + } + + #[test] + fn returns_all_authorised_agents_below_default_limit() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + let agents = storage_sorted_addresses(&mut test, 5); + + for agent in &agents { + test.add_dummy_agent(*agent) + } + + let res = query_network_monitor_agents(test.deps(), None, None)?; + + assert_eq!(res.authorised.len(), agents.len()); + assert_eq!(res.start_next_after, agents.last().copied()); + + for agent in &agents { + assert!(res.authorised.iter().any(|a| a.mixnet_address == *agent)); + } + + Ok(()) + } + + #[test] + fn respects_explicit_limit() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + let agents = storage_sorted_addresses(&mut test, 5); + + for agent in &agents { + test.add_dummy_agent(*agent) + } + + let res = query_network_monitor_agents(test.deps(), None, Some(2))?; + + assert_eq!(res.authorised.len(), 2); + assert_eq!(res.authorised[0].mixnet_address, agents[0]); + assert_eq!(res.authorised[1].mixnet_address, agents[1]); + assert_eq!(res.start_next_after, Some(agents[1])); + + Ok(()) + } + + #[test] + fn respects_start_after_for_pagination() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + let agents = storage_sorted_addresses(&mut test, 5); + + for agent in &agents { + test.add_dummy_agent(*agent) + } + + let res = query_network_monitor_agents(test.deps(), Some(agents[1]), Some(2))?; + + assert_eq!(res.authorised.len(), 2); + assert_eq!(res.authorised[0].mixnet_address, agents[2]); + assert_eq!(res.authorised[1].mixnet_address, agents[3]); + assert_eq!(res.start_next_after, Some(agents[3])); + + Ok(()) + } + + #[test] + fn caps_limit_at_maximum() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + let total = retrieval_limits::AGENTS_MAX_LIMIT as usize + 20; + let agents = storage_sorted_addresses(&mut test, total); + + for agent in &agents { + test.add_dummy_agent(*agent) + } + + let res = query_network_monitor_agents( + test.deps(), + None, + Some(retrieval_limits::AGENTS_MAX_LIMIT + 1), + )?; + + assert_eq!( + res.authorised.len(), + retrieval_limits::AGENTS_MAX_LIMIT as usize + ); + assert_eq!( + res.start_next_after, + Some(agents[retrieval_limits::AGENTS_MAX_LIMIT as usize - 1]) + ); + + Ok(()) + } + + #[test] + fn start_next_after_is_none_for_empty_page() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + let agents = storage_sorted_addresses(&mut test, 3); + + for agent in &agents { + test.add_dummy_agent(*agent) + } + + let res = query_network_monitor_agents(test.deps(), Some(agents[2]), Some(10))?; + + assert!(res.authorised.is_empty()); + assert_eq!(res.start_next_after, None); + + Ok(()) + } + + #[test] + fn returns_entries_in_ascending_order() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + let agents = storage_sorted_addresses(&mut test, 6); + + for agent in &agents { + test.add_dummy_agent(*agent) + } + + let res = query_network_monitor_agents(test.deps(), None, None)?; + + assert!(res.authorised.windows(2).all(|window| storage_socket_comp( + window[0].mixnet_address, + window[1].mixnet_address + ) + .is_le())); + + Ok(()) + } + } +} diff --git a/contracts/network-monitors/src/queued_migrations.rs b/contracts/network-monitors/src/queued_migrations.rs new file mode 100644 index 0000000000..9285ae3ffc --- /dev/null +++ b/contracts/network-monitors/src/queued_migrations.rs @@ -0,0 +1,2 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 diff --git a/contracts/network-monitors/src/storage.rs b/contracts/network-monitors/src/storage.rs new file mode 100644 index 0000000000..a5a400839b --- /dev/null +++ b/contracts/network-monitors/src/storage.rs @@ -0,0 +1,1626 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use cosmwasm_std::{Addr, Deps, DepsMut, Env, StdError, StdResult}; +use cw_controllers::Admin; +use cw_storage_plus::{Key, KeyDeserialize, Map, PrimaryKey}; +use nym_network_monitors_contract_common::constants::storage_keys; +use nym_network_monitors_contract_common::{ + AuthorisedNetworkMonitor, AuthorisedNetworkMonitorOrchestrator, NetworkMonitorsContractError, + OrchestratorAddress, +}; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; + +pub const NETWORK_MONITORS_CONTRACT_STORAGE: NetworkMonitorsStorage = NetworkMonitorsStorage::new(); + +/// The storage has an authorisation hierarchy: +/// - At the top there's the contract admin (controlled by Nymtech SA multisig, later by governance) +/// which has ultimate control over the contract and is permitted to authorise new network monitors orchestrators +/// - This is followed by network monitor orchestrators which are permitted to make changes to the set of allowed agents +/// - Finally, at the bottom, authorised network monitor agents which are permitted to send test mixnet packets to Nym nodes +pub struct NetworkMonitorsStorage { + pub(crate) contract_admin: Admin, + pub(crate) authorised_orchestrators: + Map<&'static OrchestratorAddress, AuthorisedNetworkMonitorOrchestrator>, + pub(crate) authorised_agents: Map, +} + +/// CosmWasm storage key encoding a [`SocketAddr`] as a composite primary key. +/// +/// ## On-disk layout +/// +/// The key is encoded as two elements (see [`PrimaryKey::key`]): +/// 1. IP octets — `Val32` (4 bytes) for IPv4, `Val128` (16 bytes) for IPv6 +/// 2. Port — `Val16` (2 bytes, big-endian) +/// +/// cw-storage-plus prepends each element with a 2-byte big-endian length prefix, +/// so the full byte sequence is `[0, ip_len][ip_octets...][0, 2][port_be]`. +/// This means IPv4 keys naturally sort before IPv6, and within the same IP +/// family keys sort by IP octets then by port. +#[derive(Clone, Copy, Debug)] +pub(crate) struct AgentStorageKey(SocketAddr); + +impl PrimaryKey<'_> for AgentStorageKey { + type Prefix = (); + type SubPrefix = (); + type Suffix = Self; + type SuperSuffix = Self; + + fn key(&'_ self) -> Vec> { + let port = self.0.port().to_be_bytes(); + match self.0.ip() { + IpAddr::V4(ipv4) => vec![Key::Val32(ipv4.octets()), Key::Val16(port)], + IpAddr::V6(ipv6) => vec![Key::Val128(ipv6.octets()), Key::Val16(port)], + } + } +} + +impl KeyDeserialize for AgentStorageKey { + type Output = AgentStorageKey; + const KEY_ELEMS: u16 = 2; + + fn from_vec(value: Vec) -> StdResult { + // format: 2-byte length prefix + IP bytes + 2-byte port + if value.len() < 4 { + return Err(StdError::generic_err("invalid socket address length")); + } + + // SAFETY: we're using the correct number of bytes for the conversion + #[allow(clippy::unwrap_used)] + let ip_len = u16::from_be_bytes([value[0], value[1]]) as usize; + let ip_bytes = &value[2..2 + ip_len]; + let port_bytes = &value[2 + ip_len..]; + + #[allow(clippy::unwrap_used)] + let ip = match ip_len { + 4 => IpAddr::V4(Ipv4Addr::from( + TryInto::<[u8; 4]>::try_into(ip_bytes).unwrap(), + )), + 16 => IpAddr::V6(Ipv6Addr::from( + TryInto::<[u8; 16]>::try_into(ip_bytes).unwrap(), + )), + _ => return Err(StdError::generic_err("invalid IP address length")), + }; + + let port = u16::from_be_bytes( + TryInto::<[u8; 2]>::try_into(port_bytes) + .map_err(|_| StdError::generic_err("invalid port length"))?, + ); + + Ok(AgentStorageKey(SocketAddr::new(ip, port))) + } +} + +impl From for AgentStorageKey { + fn from(addr: SocketAddr) -> Self { + Self(addr) + } +} + +impl NetworkMonitorsStorage { + #[allow(clippy::new_without_default)] + pub const fn new() -> Self { + NetworkMonitorsStorage { + contract_admin: Admin::new(storage_keys::CONTRACT_ADMIN), + authorised_orchestrators: Map::new(storage_keys::AUTHORISED_ORCHESTRATORS), + authorised_agents: Map::new(storage_keys::AUTHORISED_NETWORK_MONITORS), + } + } + + pub fn initialise( + &self, + mut deps: DepsMut, + env: Env, + admin: Addr, + orchestrator: Addr, + ) -> Result<(), NetworkMonitorsContractError> { + // set the contract admin + self.contract_admin + .set(deps.branch(), Some(admin.clone()))?; + + // set the initial orchestrator authorisation + self.authorised_orchestrators.save( + deps.storage, + &orchestrator, + &AuthorisedNetworkMonitorOrchestrator { + address: orchestrator.clone(), + identity_key: None, + authorised_at: env.block.time, + }, + )?; + + Ok(()) + } + + fn is_admin(&self, deps: Deps, addr: &Addr) -> Result { + self.contract_admin.is_admin(deps, addr).map_err(Into::into) + } + + fn ensure_is_admin(&self, deps: Deps, addr: &Addr) -> Result<(), NetworkMonitorsContractError> { + self.contract_admin + .assert_admin(deps, addr) + .map_err(Into::into) + } + + pub(crate) fn is_orchestrator( + &self, + deps: Deps, + addr: &Addr, + ) -> Result { + Ok(self + .authorised_orchestrators + .may_load(deps.storage, addr)? + .is_some()) + } + + fn ensure_is_orchestrator( + &self, + deps: Deps, + addr: &Addr, + ) -> Result<(), NetworkMonitorsContractError> { + if !self.is_orchestrator(deps, addr)? { + return Err(NetworkMonitorsContractError::NotAnOrchestrator { addr: addr.clone() }); + } + Ok(()) + } + + pub fn authorise_orchestrator( + &self, + deps: DepsMut, + env: &Env, + sender: &Addr, + orchestrator_address: OrchestratorAddress, + ) -> Result<(), NetworkMonitorsContractError> { + // only contract admin can authorise new orchestrators + self.ensure_is_admin(deps.as_ref(), sender)?; + + // if orchestrator is already authorised, it's a no-op + if self.is_orchestrator(deps.as_ref(), &orchestrator_address)? { + return Ok(()); + } + + self.authorised_orchestrators.save( + deps.storage, + &orchestrator_address, + &AuthorisedNetworkMonitorOrchestrator { + address: orchestrator_address.clone(), + identity_key: None, + authorised_at: env.block.time, + }, + )?; + Ok(()) + } + + /// Overwrite the announced identity key for the orchestrator at `sender`. + /// + /// The orchestrator must already be authorised - the existence of the storage entry is used as + /// the authorisation check itself, avoiding a second load. `identity_key` is stored verbatim + /// (callers are expected to have validated its shape beforehand). + pub fn update_orchestrator_identity_key( + &self, + deps: DepsMut, + sender: &Addr, + identity_key: String, + ) -> Result<(), NetworkMonitorsContractError> { + // ensure the sender is actually a valid orchestrator + // by checking if there is any data stored behind its address + let Some(mut orchestrator_info) = self + .authorised_orchestrators + .may_load(deps.storage, sender)? + else { + return Err(NetworkMonitorsContractError::NotAnOrchestrator { + addr: sender.clone(), + }); + }; + + orchestrator_info.identity_key = Some(identity_key); + self.authorised_orchestrators + .save(deps.storage, sender, &orchestrator_info)?; + + Ok(()) + } + + pub fn remove_orchestrator_authorisation( + &self, + deps: DepsMut, + sender: &Addr, + orchestrator_address: OrchestratorAddress, + ) -> Result<(), NetworkMonitorsContractError> { + self.ensure_is_admin(deps.as_ref(), sender)?; + + self.authorised_orchestrators + .remove(deps.storage, &orchestrator_address); + + // cascade-remove agents authorised by the removed orchestrator + // TODO: optimise it in the future in case there are more agents than could be handled in a single block + let agents_to_remove = self + .authorised_agents + .range(deps.storage, None, None, cosmwasm_std::Order::Ascending) + .filter(|r| { + r.as_ref() + .map(|(_, v)| v.authorised_by == orchestrator_address) + .unwrap_or(true) + }) + .map(|r| r.map(|(k, _)| k)) + .collect::>>()?; + for agent in agents_to_remove { + self.authorised_agents.remove(deps.storage, agent); + } + + Ok(()) + } + + pub fn authorise_monitor( + &self, + deps: DepsMut, + env: &Env, + sender: &Addr, + monitor_address: SocketAddr, + bs58_x25519_noise: String, + noise_version: u8, + ) -> Result<(), NetworkMonitorsContractError> { + // only orchestrators can authorise new monitors + self.ensure_is_orchestrator(deps.as_ref(), sender)?; + + self.authorised_agents.save( + deps.storage, + monitor_address.into(), + &AuthorisedNetworkMonitor { + mixnet_address: monitor_address, + authorised_by: sender.clone(), + authorised_at: env.block.time, + bs58_x25519_noise, + noise_version, + }, + )?; + Ok(()) + } + + pub fn remove_monitor_authorisation( + &self, + deps: DepsMut, + sender: &Addr, + monitor_address: SocketAddr, + ) -> Result<(), NetworkMonitorsContractError> { + // the contract admin or an authorised orchestrator may revoke a monitor + if !self.is_admin(deps.as_ref(), sender)? && !self.is_orchestrator(deps.as_ref(), sender)? { + return Err(NetworkMonitorsContractError::Unauthorized); + } + + self.authorised_agents + .remove(deps.storage, monitor_address.into()); + Ok(()) + } + + pub fn remove_all_monitors( + &self, + deps: DepsMut, + sender: &Addr, + ) -> Result<(), NetworkMonitorsContractError> { + // only the contract admin or an authorised orchestrator can remove all monitors + if !self.is_admin(deps.as_ref(), sender)? && !self.is_orchestrator(deps.as_ref(), sender)? { + return Err(NetworkMonitorsContractError::Unauthorized); + } + + self.authorised_agents.clear(deps.storage); + Ok(()) + } +} + +pub mod retrieval_limits { + pub const AGENTS_DEFAULT_LIMIT: u32 = 100; + pub const AGENTS_MAX_LIMIT: u32 = 200; +} + +#[cfg(test)] +mod tests { + + #[cfg(test)] + mod agent_storage_key { + use super::super::AgentStorageKey; + use cw_storage_plus::{KeyDeserialize, Map, PrimaryKey}; + use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; + + #[test] + fn ipv4_key_roundtrips_through_joined_key_and_from_vec() { + let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 42)), 8080); + let key = AgentStorageKey::from(addr); + let joined = key.joined_key(); + let recovered = AgentStorageKey::from_vec(joined).unwrap(); + assert_eq!(recovered.0, addr); + } + + #[test] + fn ipv6_key_roundtrips_through_joined_key_and_from_vec() { + let addr = SocketAddr::new( + IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)), + 443, + ); + let key = AgentStorageKey::from(addr); + let joined = key.joined_key(); + let recovered = AgentStorageKey::from_vec(joined).unwrap(); + assert_eq!(recovered.0, addr); + } + + #[test] + fn port_zero_roundtrips() { + let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 0); + let key = AgentStorageKey::from(addr); + let joined = key.joined_key(); + let recovered = AgentStorageKey::from_vec(joined).unwrap(); + assert_eq!(recovered.0, addr); + } + + #[test] + fn port_max_roundtrips() { + let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), u16::MAX); + let key = AgentStorageKey::from(addr); + let joined = key.joined_key(); + let recovered = AgentStorageKey::from_vec(joined).unwrap(); + assert_eq!(recovered.0, addr); + } + + #[test] + fn same_ip_different_ports_produce_different_keys() { + let ip = IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)); + let a = AgentStorageKey::from(SocketAddr::new(ip, 1000)); + let b = AgentStorageKey::from(SocketAddr::new(ip, 2000)); + assert_ne!(a.joined_key(), b.joined_key()); + } + + #[test] + fn ipv4_keys_sort_by_ip_then_port() { + let addrs = [ + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 2000), + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 1000), + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)), 500), + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(1, 2, 3, 4)), 9999), + ]; + + let mut keys: Vec<_> = addrs + .iter() + .map(|a| (AgentStorageKey::from(*a).joined_key(), *a)) + .collect(); + keys.sort_by(|a, b| a.0.cmp(&b.0)); + + let sorted_addrs: Vec<_> = keys.iter().map(|(_, a)| *a).collect(); + assert_eq!( + sorted_addrs, + vec![ + // 1.2.3.4 < 10.0.0.1 < 10.0.0.2 + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(1, 2, 3, 4)), 9999), + // same IP, port 1000 < 2000 + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 1000), + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 2000), + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)), 500), + ] + ); + } + + #[test] + fn ipv4_sorts_before_ipv6() { + let v4 = AgentStorageKey::from(SocketAddr::new( + IpAddr::V4(Ipv4Addr::new(255, 255, 255, 255)), + 65535, + )); + let v6 = AgentStorageKey::from(SocketAddr::new( + IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), + 1, + )); + assert!(v4.joined_key() < v6.joined_key()); + } + + #[test] + fn map_save_and_load_roundtrip_ipv4() { + use cosmwasm_std::testing::MockStorage; + + let map: Map = Map::new("test"); + let mut storage = MockStorage::new(); + + let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1)), 8080); + map.save(&mut storage, addr.into(), &"agent-v4".to_string()) + .unwrap(); + + let loaded = map.load(&storage, addr.into()).unwrap(); + assert_eq!(loaded, "agent-v4"); + } + + #[test] + fn map_save_and_load_roundtrip_ipv6() { + use cosmwasm_std::testing::MockStorage; + + let map: Map = Map::new("test"); + let mut storage = MockStorage::new(); + + let addr = SocketAddr::new( + IpAddr::V6(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1)), + 443, + ); + map.save(&mut storage, addr.into(), &"agent-v6".to_string()) + .unwrap(); + + let loaded = map.load(&storage, addr.into()).unwrap(); + assert_eq!(loaded, "agent-v6"); + } + + #[test] + fn map_stores_same_ip_different_ports_independently() { + use cosmwasm_std::testing::MockStorage; + + let map: Map = Map::new("test"); + let mut storage = MockStorage::new(); + + let ip = IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)); + let agent_a = SocketAddr::new(ip, 1000); + let agent_b = SocketAddr::new(ip, 2000); + + map.save(&mut storage, agent_a.into(), &"agent-a".to_string()) + .unwrap(); + map.save(&mut storage, agent_b.into(), &"agent-b".to_string()) + .unwrap(); + + assert_eq!(map.load(&storage, agent_a.into()).unwrap(), "agent-a"); + assert_eq!(map.load(&storage, agent_b.into()).unwrap(), "agent-b"); + } + + #[test] + fn map_remove_one_agent_preserves_other_on_same_ip() { + use cosmwasm_std::testing::MockStorage; + + let map: Map = Map::new("test"); + let mut storage = MockStorage::new(); + + let ip = IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)); + let agent_a = SocketAddr::new(ip, 1000); + let agent_b = SocketAddr::new(ip, 2000); + + map.save(&mut storage, agent_a.into(), &"agent-a".to_string()) + .unwrap(); + map.save(&mut storage, agent_b.into(), &"agent-b".to_string()) + .unwrap(); + + map.remove(&mut storage, agent_a.into()); + + assert!(map.may_load(&storage, agent_a.into()).unwrap().is_none()); + assert_eq!(map.load(&storage, agent_b.into()).unwrap(), "agent-b"); + } + + #[test] + fn map_range_returns_correct_order_with_mixed_ips_and_ports() { + use cosmwasm_std::testing::MockStorage; + use cosmwasm_std::{Order, StdResult}; + + let map: Map = Map::new("test"); + let mut storage = MockStorage::new(); + + let addrs = [ + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 2000), + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 1000), + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(1, 2, 3, 4)), 80), + SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), 443), + ]; + + for addr in &addrs { + map.save(&mut storage, (*addr).into(), &addr.to_string()) + .unwrap(); + } + + let all: Vec = map + .range(&storage, None, None, Order::Ascending) + .map(|r: StdResult<(AgentStorageKey, String)>| r.unwrap().0 .0) + .collect(); + + assert_eq!( + all, + vec![ + // IPv4 sorted by octets, then port + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(1, 2, 3, 4)), 80), + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 1000), + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 2000), + // IPv6 after all IPv4 + SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), 443), + ] + ); + } + + #[test] + fn map_range_with_exclusive_bound_skips_exact_match() { + use cosmwasm_std::testing::MockStorage; + use cosmwasm_std::{Order, StdResult}; + use cw_storage_plus::Bound; + + let map: Map = Map::new("test"); + let mut storage = MockStorage::new(); + + let addrs = [ + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 1000), + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 2000), + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 3000), + ]; + + for addr in &addrs { + map.save(&mut storage, (*addr).into(), &addr.to_string()) + .unwrap(); + } + + // paginate after the second entry + let start = Bound::exclusive(AgentStorageKey::from(addrs[1])); + let page: Vec = map + .range(&storage, Some(start), None, Order::Ascending) + .map(|r: StdResult<(AgentStorageKey, String)>| r.unwrap().0 .0) + .collect(); + + assert_eq!(page, vec![addrs[2]]); + } + } + + #[cfg(test)] + mod network_monitors_storage { + use crate::storage::NetworkMonitorsStorage; + use cosmwasm_std::testing::{mock_dependencies, mock_env}; + + #[cfg(test)] + mod initialisation { + use crate::storage::NetworkMonitorsStorage; + use cosmwasm_std::testing::{mock_dependencies, mock_env}; + + #[test] + fn sets_contract_admin() -> anyhow::Result<()> { + let storage = NetworkMonitorsStorage::new(); + let mut deps = mock_dependencies(); + let env = mock_env(); + let admin1 = deps.api.addr_make("first-admin"); + let admin2 = deps.api.addr_make("second-admin"); + let orchestrator = deps.api.addr_make("orchestrator"); + + storage.initialise( + deps.as_mut(), + env.clone(), + admin1.clone(), + orchestrator.clone(), + )?; + assert!(storage.ensure_is_admin(deps.as_ref(), &admin1).is_ok()); + + let mut deps = mock_dependencies(); + storage.initialise(deps.as_mut(), env.clone(), admin2.clone(), orchestrator)?; + assert!(storage.ensure_is_admin(deps.as_ref(), &admin2).is_ok()); + + Ok(()) + } + + #[test] + fn sets_the_initial_orchestrator() -> anyhow::Result<()> { + let storage = NetworkMonitorsStorage::new(); + let mut deps = mock_dependencies(); + let env = mock_env(); + let admin = deps.api.addr_make("admin"); + let orchestrator1 = deps.api.addr_make("orchestrator"); + let orchestrator2 = deps.api.addr_make("orchestrator"); + + storage.initialise( + deps.as_mut(), + env.clone(), + admin.clone(), + orchestrator1.clone(), + )?; + assert!(storage + .ensure_is_orchestrator(deps.as_ref(), &orchestrator1) + .is_ok()); + + let mut deps = mock_dependencies(); + storage.initialise( + deps.as_mut(), + env.clone(), + admin.clone(), + orchestrator2.clone(), + )?; + assert!(storage + .ensure_is_orchestrator(deps.as_ref(), &orchestrator2) + .is_ok()); + + Ok(()) + } + } + + #[test] + fn checking_for_admin() -> anyhow::Result<()> { + let storage = NetworkMonitorsStorage::new(); + let mut deps = mock_dependencies(); + let env = mock_env(); + let admin = deps.api.addr_make("admin"); + let non_admin = deps.api.addr_make("non-admin"); + let orchestrator = deps.api.addr_make("orchestrator"); + + storage.initialise(deps.as_mut(), env, admin.clone(), orchestrator)?; + assert!(storage.is_admin(deps.as_ref(), &admin)?); + assert!(!storage.is_admin(deps.as_ref(), &non_admin)?); + + Ok(()) + } + + #[test] + fn ensuring_admin_privileges() -> anyhow::Result<()> { + let storage = NetworkMonitorsStorage::new(); + let mut deps = mock_dependencies(); + let env = mock_env(); + let admin = deps.api.addr_make("admin"); + let non_admin = deps.api.addr_make("non-admin"); + let orchestrator = deps.api.addr_make("orchestrator"); + + storage.initialise(deps.as_mut(), env, admin.clone(), orchestrator)?; + assert!(storage.ensure_is_admin(deps.as_ref(), &admin).is_ok()); + assert!(storage.ensure_is_admin(deps.as_ref(), &non_admin).is_err()); + + Ok(()) + } + + #[test] + fn checking_for_orchestrator() -> anyhow::Result<()> { + let storage = NetworkMonitorsStorage::new(); + let mut deps = mock_dependencies(); + let env = mock_env(); + let admin = deps.api.addr_make("admin"); + let non_orchestrator = deps.api.addr_make("non-orchestrator"); + let orchestrator = deps.api.addr_make("orchestrator"); + + storage.initialise(deps.as_mut(), env, admin, orchestrator.clone())?; + assert!(storage.is_orchestrator(deps.as_ref(), &orchestrator)?); + assert!(!storage.is_orchestrator(deps.as_ref(), &non_orchestrator)?); + + Ok(()) + } + + #[test] + fn ensuring_orchestrator_privileges() -> anyhow::Result<()> { + let storage = NetworkMonitorsStorage::new(); + let mut deps = mock_dependencies(); + let env = mock_env(); + let admin = deps.api.addr_make("admin"); + let non_orchestrator = deps.api.addr_make("non-orchestrator"); + let orchestrator = deps.api.addr_make("orchestrator"); + + storage.initialise(deps.as_mut(), env, admin, orchestrator.clone())?; + assert!(storage + .ensure_is_orchestrator(deps.as_ref(), &orchestrator) + .is_ok()); + assert!(storage + .ensure_is_orchestrator(deps.as_ref(), &non_orchestrator) + .is_err()); + + Ok(()) + } + + #[cfg(test)] + mod authorising_orchestrator { + use super::*; + use crate::testing::init_contract_tester; + use cw_controllers::AdminError; + use nym_contracts_common_testing::{AdminExt, ChainOpts, ContractOpts, RandExt}; + use nym_network_monitors_contract_common::NetworkMonitorsContractError; + + #[test] + fn can_only_be_done_by_admin() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let storage = NetworkMonitorsStorage::new(); + + let admin = tester.admin_unchecked(); + let non_admin = tester.generate_account(); + let orchestrator = tester.generate_account(); + + let env = tester.env(); + let deps = tester.deps_mut(); + let res = storage + .authorise_orchestrator(deps, &env, &non_admin, orchestrator.clone()) + .unwrap_err(); + assert_eq!( + NetworkMonitorsContractError::Admin(AdminError::NotAdmin {}), + res + ); + + let env = tester.env(); + let deps = tester.deps_mut(); + let res2 = storage.authorise_orchestrator(deps, &env, &admin, orchestrator.clone()); + assert_eq!(res2, Ok(())); + + Ok(()) + } + + #[test] + fn inserts_new_entry_for_fresh_accounts() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let storage = NetworkMonitorsStorage::new(); + + let admin = tester.admin_unchecked(); + let orchestrator = tester.generate_account(); + + let env = tester.env(); + let deps = tester.deps_mut(); + + assert!(storage + .authorised_orchestrators + .may_load(deps.storage, &orchestrator)? + .is_none()); + storage.authorise_orchestrator(deps, &env, &admin, orchestrator.clone())?; + + let info = storage + .authorised_orchestrators + .load(&tester, &orchestrator)?; + + assert_eq!(info.address, orchestrator); + assert_eq!(info.authorised_at, env.block.time); + + Ok(()) + } + + #[test] + fn no_op_for_older_accounts() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let storage = NetworkMonitorsStorage::new(); + + let admin = tester.admin_unchecked(); + let orchestrator = tester.generate_account(); + + let env = tester.env(); + let deps = tester.deps_mut(); + + storage.authorise_orchestrator(deps, &env, &admin, orchestrator.clone())?; + let info = storage + .authorised_orchestrators + .load(&tester, &orchestrator)?; + + tester.advance_day_of_blocks(); + + let env = tester.env(); + let deps = tester.deps_mut(); + storage.authorise_orchestrator(deps, &env, &admin, orchestrator.clone())?; + + let updated_info = storage + .authorised_orchestrators + .load(&tester, &orchestrator)?; + + assert_eq!(info, updated_info); + + Ok(()) + } + } + + #[cfg(test)] + mod removing_orchestrator_authorisation { + use super::*; + use crate::testing::{init_contract_tester, NetworkMonitorsContractTesterExt}; + use cw_controllers::AdminError; + use nym_contracts_common_testing::{AdminExt, ContractOpts, RandExt}; + use nym_network_monitors_contract_common::NetworkMonitorsContractError; + + #[test] + fn can_only_be_done_by_admin() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let storage = NetworkMonitorsStorage::new(); + + let admin = tester.admin_unchecked(); + let non_admin = tester.generate_account(); + let orchestrator = tester.generate_account(); + + let env = tester.env(); + let deps = tester.deps_mut(); + storage.authorise_orchestrator(deps, &env, &admin, orchestrator.clone())?; + + let deps = tester.deps_mut(); + let res = storage + .remove_orchestrator_authorisation(deps, &non_admin, orchestrator.clone()) + .unwrap_err(); + assert_eq!( + NetworkMonitorsContractError::Admin(AdminError::NotAdmin {}), + res + ); + + let deps = tester.deps_mut(); + let res2 = storage.remove_orchestrator_authorisation(deps, &admin, orchestrator); + assert_eq!(res2, Ok(())); + + Ok(()) + } + + #[test] + fn deletes_entry_from_storage() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let storage = NetworkMonitorsStorage::new(); + + let admin = tester.admin_unchecked(); + let orchestrator = tester.generate_account(); + + let env = tester.env(); + let deps = tester.deps_mut(); + storage.authorise_orchestrator(deps, &env, &admin, orchestrator.clone())?; + + assert!(storage + .authorised_orchestrators + .may_load(&tester, &orchestrator)? + .is_some()); + + let deps = tester.deps_mut(); + storage.remove_orchestrator_authorisation(deps, &admin, orchestrator.clone())?; + + assert!(storage + .authorised_orchestrators + .may_load(&tester, &orchestrator)? + .is_none()); + + Ok(()) + } + + #[test] + fn no_op_for_non_existent_entries() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let storage = NetworkMonitorsStorage::new(); + + let admin = tester.admin_unchecked(); + let orchestrator = tester.generate_account(); + + assert!(storage + .authorised_orchestrators + .may_load(&tester, &orchestrator)? + .is_none()); + + let deps = tester.deps_mut(); + let res = + storage.remove_orchestrator_authorisation(deps, &admin, orchestrator.clone()); + assert_eq!(res, Ok(())); + + assert!(storage + .authorised_orchestrators + .may_load(&tester, &orchestrator)? + .is_none()); + + Ok(()) + } + + #[test] + fn removes_agents_authorised_by_the_removed_orchestrator() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let storage = NetworkMonitorsStorage::new(); + + let admin = tester.admin_unchecked(); + let orchestrator = tester.add_orchestrator()?; + + let agent1 = tester.random_socket(); + let agent2 = tester.random_socket(); + + let env = tester.env(); + let deps = tester.deps_mut(); + storage.authorise_monitor( + deps, + &env, + &orchestrator, + agent1, + "test_noise_key".to_string(), + 1, + )?; + + let env = tester.env(); + let deps = tester.deps_mut(); + storage.authorise_monitor( + deps, + &env, + &orchestrator, + agent2, + "test_noise_key".to_string(), + 1, + )?; + + // sanity: both agents present + assert!(storage + .authorised_agents + .may_load(&tester, agent1.into())? + .is_some()); + assert!(storage + .authorised_agents + .may_load(&tester, agent2.into())? + .is_some()); + + let deps = tester.deps_mut(); + storage.remove_orchestrator_authorisation(deps, &admin, orchestrator.clone())?; + + // orchestrator is gone + assert!(storage + .authorised_orchestrators + .may_load(&tester, &orchestrator)? + .is_none()); + + // its agents are cascade-removed + assert!(storage + .authorised_agents + .may_load(&tester, agent1.into())? + .is_none()); + assert!(storage + .authorised_agents + .may_load(&tester, agent2.into())? + .is_none()); + + Ok(()) + } + + #[test] + fn does_not_remove_agents_authorised_by_other_orchestrators() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let storage = NetworkMonitorsStorage::new(); + + let admin = tester.admin_unchecked(); + let orchestrator_a = tester.add_orchestrator()?; + let orchestrator_b = tester.add_orchestrator()?; + + let agent_a = tester.random_socket(); + let agent_b = tester.random_socket(); + + let env = tester.env(); + let deps = tester.deps_mut(); + storage.authorise_monitor( + deps, + &env, + &orchestrator_a, + agent_a, + "test_noise_key".to_string(), + 1, + )?; + + let env = tester.env(); + let deps = tester.deps_mut(); + storage.authorise_monitor( + deps, + &env, + &orchestrator_b, + agent_b, + "test_noise_key".to_string(), + 1, + )?; + + let deps = tester.deps_mut(); + storage.remove_orchestrator_authorisation(deps, &admin, orchestrator_a.clone())?; + + // orchestrator_a's agent is gone + assert!(storage + .authorised_agents + .may_load(&tester, agent_a.into())? + .is_none()); + + // orchestrator_b's agent is untouched + let remaining = storage.authorised_agents.load(&tester, agent_b.into())?; + assert_eq!(remaining.mixnet_address, agent_b); + assert_eq!(remaining.authorised_by, orchestrator_b); + + // orchestrator_b itself is untouched + assert!(storage + .authorised_orchestrators + .may_load(&tester, &orchestrator_b)? + .is_some()); + + Ok(()) + } + } + + #[cfg(test)] + mod authorising_monitors { + use super::*; + use crate::testing::{init_contract_tester, NetworkMonitorsContractTesterExt}; + use nym_contracts_common_testing::{ChainOpts, ContractOpts, RandExt}; + use nym_network_monitors_contract_common::NetworkMonitorsContractError; + + #[test] + fn can_only_be_done_by_an_orchestrator() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let storage = NetworkMonitorsStorage::new(); + + let orchestrator = tester.add_orchestrator()?; + let non_orchestrator = tester.generate_account(); + let agent = tester.random_socket(); + + let env = tester.env(); + let deps = tester.deps_mut(); + let res = storage + .authorise_monitor( + deps, + &env, + &non_orchestrator, + agent, + "test_noise_key".to_string(), + 1, + ) + .unwrap_err(); + assert_eq!( + NetworkMonitorsContractError::NotAnOrchestrator { + addr: non_orchestrator.clone() + }, + res + ); + + let env = tester.env(); + let deps = tester.deps_mut(); + let res2 = storage.authorise_monitor( + deps, + &env, + &orchestrator, + agent, + "test_noise_key".to_string(), + 1, + ); + assert_eq!(res2, Ok(())); + + Ok(()) + } + + #[test] + fn inserts_new_entry_for_fresh_accounts() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let storage = NetworkMonitorsStorage::new(); + + // IPV4: + let orchestrator = tester.add_orchestrator()?; + let agent = tester.random_socket_ipv4(); + + let env = tester.env(); + let deps = tester.deps_mut(); + + assert!(storage + .authorised_agents + .may_load(deps.storage, agent.into())? + .is_none()); + storage.authorise_monitor( + deps, + &env, + &orchestrator, + agent, + "test_noise_key".to_string(), + 1, + )?; + + let info = storage.authorised_agents.load(&tester, agent.into())?; + + assert_eq!(info.mixnet_address, agent); + assert_eq!(info.authorised_by, orchestrator); + assert_eq!(info.authorised_at, env.block.time); + + tester.advance_day_of_blocks(); + + // IPV6: + let agent = tester.random_socket_ipv6(); + + let env = tester.env(); + let deps = tester.deps_mut(); + + assert!(storage + .authorised_agents + .may_load(deps.storage, agent.into())? + .is_none()); + storage.authorise_monitor( + deps, + &env, + &orchestrator, + agent, + "test_noise_key".to_string(), + 1, + )?; + + let info = storage.authorised_agents.load(&tester, agent.into())?; + + assert_eq!(info.mixnet_address, agent); + assert_eq!(info.authorised_by, orchestrator); + assert_eq!(info.authorised_at, env.block.time); + + Ok(()) + } + + #[test] + fn updates_timestamp_for_older_accounts() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let storage = NetworkMonitorsStorage::new(); + + // IPV4: + let orchestrator = tester.add_orchestrator()?; + let agent = tester.random_socket_ipv4(); + + let env = tester.env(); + let deps = tester.deps_mut(); + + storage.authorise_monitor( + deps, + &env, + &orchestrator, + agent, + "test_noise_key".to_string(), + 1, + )?; + + let initial_time = env.block.time; + tester.advance_day_of_blocks(); + let new_expected_time = tester.env().block.time; + + let env = tester.env(); + let deps = tester.deps_mut(); + storage.authorise_monitor( + deps, + &env, + &orchestrator, + agent, + "test_noise_key".to_string(), + 1, + )?; + + let updated_info = storage.authorised_agents.load(&tester, agent.into())?; + + assert_eq!(updated_info.mixnet_address, agent); + assert_eq!(updated_info.authorised_by, orchestrator); + assert_ne!(updated_info.authorised_at, initial_time); + assert_eq!(updated_info.authorised_at, new_expected_time); + + tester.advance_day_of_blocks(); + + // IPV6: + let agent = tester.random_socket_ipv6(); + + let env = tester.env(); + let deps = tester.deps_mut(); + + storage.authorise_monitor( + deps, + &env, + &orchestrator, + agent, + "test_noise_key".to_string(), + 1, + )?; + + let initial_time = env.block.time; + tester.advance_day_of_blocks(); + let new_expected_time = tester.env().block.time; + + let env = tester.env(); + let deps = tester.deps_mut(); + storage.authorise_monitor( + deps, + &env, + &orchestrator, + agent, + "test_noise_key".to_string(), + 1, + )?; + + let updated_info = storage.authorised_agents.load(&tester, agent.into())?; + + assert_eq!(updated_info.mixnet_address, agent); + assert_eq!(updated_info.authorised_by, orchestrator); + assert_ne!(updated_info.authorised_at, initial_time); + assert_eq!(updated_info.authorised_at, new_expected_time); + + Ok(()) + } + } + + #[cfg(test)] + mod removing_monitor_authorisation { + use super::*; + use crate::testing::{init_contract_tester, NetworkMonitorsContractTesterExt}; + use nym_contracts_common_testing::{AdminExt, ChainOpts, ContractOpts, RandExt}; + use nym_network_monitors_contract_common::NetworkMonitorsContractError; + + #[test] + fn rejects_non_privileged_accounts() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let storage = NetworkMonitorsStorage::new(); + + let orchestrator = tester.add_orchestrator()?; + let non_privileged = tester.generate_account(); + let agent = tester.random_socket(); + + let env = tester.env(); + let deps = tester.deps_mut(); + storage.authorise_monitor( + deps, + &env, + &orchestrator, + agent, + "test_noise_key".to_string(), + 1, + )?; + + let deps = tester.deps_mut(); + let res = storage + .remove_monitor_authorisation(deps, &non_privileged, agent) + .unwrap_err(); + assert_eq!(NetworkMonitorsContractError::Unauthorized, res); + + let deps = tester.deps_mut(); + let res2 = storage.remove_monitor_authorisation(deps, &orchestrator, agent); + assert_eq!(res2, Ok(())); + + Ok(()) + } + + #[test] + fn can_be_done_by_admin() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let storage = NetworkMonitorsStorage::new(); + + let admin = tester.admin_unchecked(); + let orchestrator = tester.add_orchestrator()?; + let agent = tester.random_socket(); + + let env = tester.env(); + let deps = tester.deps_mut(); + storage.authorise_monitor( + deps, + &env, + &orchestrator, + agent, + "test_noise_key".to_string(), + 1, + )?; + + let deps = tester.deps_mut(); + storage.remove_monitor_authorisation(deps, &admin, agent)?; + + assert!(storage + .authorised_agents + .may_load(&tester, agent.into())? + .is_none()); + + Ok(()) + } + + #[test] + fn deletes_entry_from_storage() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let storage = NetworkMonitorsStorage::new(); + + // IPV4: + let orchestrator = tester.add_orchestrator()?; + let agent = tester.random_socket_ipv4(); + + let env = tester.env(); + let deps = tester.deps_mut(); + storage.authorise_monitor( + deps, + &env, + &orchestrator, + agent, + "test_noise_key".to_string(), + 1, + )?; + + assert!(storage + .authorised_agents + .may_load(&tester, agent.into())? + .is_some()); + + let deps = tester.deps_mut(); + storage.remove_monitor_authorisation(deps, &orchestrator, agent)?; + + assert!(storage + .authorised_agents + .may_load(&tester, agent.into())? + .is_none()); + + tester.advance_day_of_blocks(); + + // IPV6: + let agent = tester.random_socket_ipv6(); + + let env = tester.env(); + let deps = tester.deps_mut(); + storage.authorise_monitor( + deps, + &env, + &orchestrator, + agent, + "test_noise_key".to_string(), + 1, + )?; + + assert!(storage + .authorised_agents + .may_load(&tester, agent.into())? + .is_some()); + + let deps = tester.deps_mut(); + storage.remove_monitor_authorisation(deps, &orchestrator, agent)?; + + assert!(storage + .authorised_agents + .may_load(&tester, agent.into())? + .is_none()); + + Ok(()) + } + + #[test] + fn no_op_for_non_existent_entries() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let storage = NetworkMonitorsStorage::new(); + + let orchestrator = tester.add_orchestrator()?; + let agent = tester.random_socket(); + + assert!(storage + .authorised_agents + .may_load(&tester, agent.into())? + .is_none()); + + let deps = tester.deps_mut(); + let res = storage.remove_monitor_authorisation(deps, &orchestrator, agent); + assert_eq!(res, Ok(())); + + assert!(storage + .authorised_agents + .may_load(&tester, agent.into())? + .is_none()); + + Ok(()) + } + } + + #[cfg(test)] + mod removing_all_monitors { + use super::*; + use crate::testing::{ + init_contract_tester, NetworkMonitorsContract, NetworkMonitorsContractTesterExt, + }; + use cosmwasm_std::Addr; + use nym_contracts_common_testing::{AdminExt, ContractOpts, ContractTester, RandExt}; + use nym_network_monitors_contract_common::NetworkMonitorsContractError; + + fn setup_prepopulated_tester() -> (ContractTester, Addr) { + let mut tester = init_contract_tester(); + let storage = NetworkMonitorsStorage::new(); + let orchestrator = tester.add_orchestrator().unwrap(); + + // Prepopulate with several agents + let agent1 = tester.random_socket(); + let agent2 = tester.random_socket(); + let agent3 = tester.random_socket(); + + let env = tester.env(); + let deps = tester.deps_mut(); + storage + .authorise_monitor( + deps, + &env, + &orchestrator, + agent1, + "test_noise_key".to_string(), + 1, + ) + .unwrap(); + + let env = tester.env(); + let deps = tester.deps_mut(); + storage + .authorise_monitor( + deps, + &env, + &orchestrator, + agent2, + "test_noise_key".to_string(), + 1, + ) + .unwrap(); + + let env = tester.env(); + let deps = tester.deps_mut(); + storage + .authorise_monitor( + deps, + &env, + &orchestrator, + agent3, + "test_noise_key".to_string(), + 1, + ) + .unwrap(); + + // sanity check to make sure all agents got added + let all_agents = tester.all_agents(); + assert_eq!(all_agents.len(), 3); + assert!(all_agents.contains(&agent1)); + assert!(all_agents.contains(&agent2)); + assert!(all_agents.contains(&agent3)); + + (tester, orchestrator) + } + + #[test] + fn can_be_done_by_admin() -> anyhow::Result<()> { + let storage = NetworkMonitorsStorage::new(); + + let (mut tester, _) = setup_prepopulated_tester(); + let admin = tester.admin_unchecked(); + + let all_agents = tester.all_agents(); + + // Admin can call this method + let deps = tester.deps_mut(); + storage.remove_all_monitors(deps, &admin)?; + + // Verify all agents are cleared + for agent in all_agents { + assert!(storage + .authorised_agents + .may_load(&tester, agent.into())? + .is_none()); + } + + assert!(tester.all_agents().is_empty()); + + Ok(()) + } + + #[test] + fn can_be_done_by_orchestrator() -> anyhow::Result<()> { + let storage = NetworkMonitorsStorage::new(); + let (mut tester, orchestrator) = setup_prepopulated_tester(); + + let all_agents = tester.all_agents(); + + let deps = tester.deps_mut(); + storage.remove_all_monitors(deps, &orchestrator)?; + + // Verify all agents are cleared + for agent in all_agents { + assert!(storage + .authorised_agents + .may_load(&tester, agent.into())? + .is_none()); + } + + assert!(tester.all_agents().is_empty()); + + Ok(()) + } + + #[test] + fn cannot_be_done_by_non_privileged_account() -> anyhow::Result<()> { + let storage = NetworkMonitorsStorage::new(); + let (mut tester, _) = setup_prepopulated_tester(); + + let non_privileged = tester.generate_account(); + + // Non-privileged account cannot call this method + let deps = tester.deps_mut(); + let res = storage + .remove_all_monitors(deps, &non_privileged) + .unwrap_err(); + assert_eq!(NetworkMonitorsContractError::Unauthorized, res); + + Ok(()) + } + + #[test] + fn cannot_be_done_by_revoked_orchestrator() -> anyhow::Result<()> { + let storage = NetworkMonitorsStorage::new(); + let (mut tester, orchestrator) = setup_prepopulated_tester(); + + let admin = tester.admin_unchecked(); + + let deps = tester.deps_mut(); + + // Revoke orchestrator privileges (cascade-removes its agents) + storage.remove_orchestrator_authorisation(deps, &admin, orchestrator.clone())?; + + // snapshot the post-revocation agent set so we can assert the failed + // remove_all_monitors call below does not further mutate storage + let post_revoke_agents = tester.all_agents(); + + // Verify revoked orchestrator cannot call remove_all_monitors + let deps = tester.deps_mut(); + let res = storage + .remove_all_monitors(deps, &orchestrator) + .unwrap_err(); + assert_eq!(NetworkMonitorsContractError::Unauthorized, res); + + // Verify the failed attempt did not mutate the agent set + assert_eq!(tester.all_agents(), post_revoke_agents); + + Ok(()) + } + + #[test] + fn clears_all_agents() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let storage = NetworkMonitorsStorage::new(); + + let admin = tester.admin_unchecked(); + let orchestrator = tester.add_orchestrator()?; + + // Prepopulate with multiple agents + let agent1 = tester.random_socket(); + let agent2 = tester.random_socket(); + let agent3 = tester.random_socket(); + let agent4 = tester.random_socket(); + + let env = tester.env(); + let deps = tester.deps_mut(); + storage.authorise_monitor( + deps, + &env, + &orchestrator, + agent1, + "test_noise_key".to_string(), + 1, + )?; + + let env = tester.env(); + let deps = tester.deps_mut(); + storage.authorise_monitor( + deps, + &env, + &orchestrator, + agent2, + "test_noise_key".to_string(), + 1, + )?; + + let env = tester.env(); + let deps = tester.deps_mut(); + storage.authorise_monitor( + deps, + &env, + &orchestrator, + agent3, + "test_noise_key".to_string(), + 1, + )?; + + let env = tester.env(); + let deps = tester.deps_mut(); + storage.authorise_monitor( + deps, + &env, + &orchestrator, + agent4, + "test_noise_key".to_string(), + 1, + )?; + + // Verify agents are present + assert!(storage + .authorised_agents + .may_load(&tester, agent1.into())? + .is_some()); + assert!(storage + .authorised_agents + .may_load(&tester, agent2.into())? + .is_some()); + assert!(storage + .authorised_agents + .may_load(&tester, agent3.into())? + .is_some()); + assert!(storage + .authorised_agents + .may_load(&tester, agent4.into())? + .is_some()); + + // Remove all monitors + let deps = tester.deps_mut(); + storage.remove_all_monitors(deps, &admin)?; + + // Verify all agents are cleared + assert!(storage + .authorised_agents + .may_load(&tester, agent1.into())? + .is_none()); + assert!(storage + .authorised_agents + .may_load(&tester, agent2.into())? + .is_none()); + assert!(storage + .authorised_agents + .may_load(&tester, agent3.into())? + .is_none()); + assert!(storage + .authorised_agents + .may_load(&tester, agent4.into())? + .is_none()); + + Ok(()) + } + } + } +} diff --git a/contracts/network-monitors/src/testing/mod.rs b/contracts/network-monitors/src/testing/mod.rs new file mode 100644 index 0000000000..f2222627c4 --- /dev/null +++ b/contracts/network-monitors/src/testing/mod.rs @@ -0,0 +1,188 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::contract::{execute, instantiate, migrate, query}; +use cosmwasm_std::{Addr, Order}; +use nym_contracts_common_testing::{ + mock_dependencies, AdminExt, ChainOpts, CommonStorageKeys, ContractFn, ContractOpts, + ContractTester, DenomExt, PermissionedFn, QueryFn, RandExt, Rng, RngCore, TestableNymContract, +}; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; + +use crate::storage::NetworkMonitorsStorage; +use nym_network_monitors_contract_common::constants::storage_keys; +use nym_network_monitors_contract_common::{ + ExecuteMsg, InstantiateMsg, MigrateMsg, NetworkMonitorsContractError, QueryMsg, +}; + +pub struct NetworkMonitorsContract; + +impl TestableNymContract for NetworkMonitorsContract { + const NAME: &'static str = "nym-network-monitors-contract"; + type InitMsg = InstantiateMsg; + type ExecuteMsg = ExecuteMsg; + type QueryMsg = QueryMsg; + type MigrateMsg = MigrateMsg; + type ContractError = NetworkMonitorsContractError; + + fn instantiate() -> ContractFn { + instantiate + } + + fn execute() -> ContractFn { + execute + } + + fn query() -> QueryFn { + query + } + + fn migrate() -> PermissionedFn { + migrate + } + + fn base_init_msg() -> Self::InitMsg { + let deps = mock_dependencies(); + InstantiateMsg { + orchestrator_address: deps.api.addr_make("initial-dummy-orchestrator").to_string(), + } + } +} + +pub fn init_contract_tester() -> ContractTester { + NetworkMonitorsContract::init() + .with_common_storage_key(CommonStorageKeys::Admin, storage_keys::CONTRACT_ADMIN) +} + +pub trait NetworkMonitorsContractTesterExt: + ContractOpts< + ExecuteMsg = ExecuteMsg, + QueryMsg = QueryMsg, + ContractError = NetworkMonitorsContractError, + > + ChainOpts + + AdminExt + + DenomExt + + RandExt +{ + fn add_orchestrator(&mut self) -> Result { + let admin = self.admin_unchecked(); + let addr = self.generate_account(); + self.execute_raw( + admin, + ExecuteMsg::AuthoriseNetworkMonitorOrchestrator { + address: addr.to_string(), + }, + )?; + Ok(addr) + } + + fn remove_all_orchestrators(&mut self) { + let orchestrators = self.all_orchestrators(); + for orchestrator in orchestrators { + self.execute_raw( + self.admin_unchecked(), + ExecuteMsg::RevokeNetworkMonitorOrchestrator { + address: orchestrator.to_string(), + }, + ) + .unwrap(); + } + } + + fn add_dummy_agent(&mut self, agent: SocketAddr) { + let orchestrators = self.all_orchestrators(); + let orchestrator = match orchestrators.first() { + Some(orchestrator) => orchestrator.clone(), + None => self.add_orchestrator().unwrap().clone(), + }; + + self.execute_raw( + orchestrator, + ExecuteMsg::AuthoriseNetworkMonitor { + mixnet_address: agent, + bs58_x25519_noise: "11111111111111111111111111111111".to_string(), + noise_version: 1, + }, + ) + .unwrap(); + } + + fn random_ipv4(&mut self) -> IpAddr { + let rng = self.raw_rng(); + IpAddr::V4(Ipv4Addr::new(rng.gen(), rng.gen(), rng.gen(), rng.gen())) + } + + fn random_ipv6(&mut self) -> IpAddr { + let rng = self.raw_rng(); + IpAddr::V6(Ipv6Addr::new( + rng.gen(), + rng.gen(), + rng.gen(), + rng.gen(), + rng.gen(), + rng.gen(), + rng.gen(), + rng.gen(), + )) + } + + fn random_ip(&mut self) -> IpAddr { + let rng = self.raw_rng(); + + // toss a coin, if even => ipv4, if odd => ipv6 + if rng.next_u32() % 2 == 0 { + self.random_ipv4() + } else { + self.random_ipv6() + } + } + + fn random_socket_ipv4(&mut self) -> SocketAddr { + let port = self.raw_rng().gen(); + SocketAddr::new(self.random_ipv4(), port) + } + + fn random_socket_ipv6(&mut self) -> SocketAddr { + let port = self.raw_rng().gen(); + SocketAddr::new(self.random_ipv6(), port) + } + + fn random_socket(&mut self) -> SocketAddr { + let port = self.raw_rng().gen(); + SocketAddr::new(self.random_ip(), port) + } + + fn all_agents(&self) -> Vec { + NetworkMonitorsStorage::new() + .authorised_agents + .range(self.storage(), None, None, Order::Ascending) + .map(|record| record.unwrap().1.mixnet_address) + .collect() + } + + fn all_orchestrators(&self) -> Vec { + NetworkMonitorsStorage::new() + .authorised_orchestrators + .range(self.storage(), None, None, Order::Ascending) + .map(|record| record.unwrap().0) + .collect() + } +} + +impl NetworkMonitorsContractTesterExt for ContractTester {} + +/// Compare SocketAddrs in the same order as the storage key encoding. +/// +/// Storage keys are: `[0, ip_len] [ip_octets...] [port_be_bytes]` +/// This means IPv4 (len=4) always sorts before IPv6 (len=16), +/// within the same type keys sort by IP octets then by port. +pub(crate) fn storage_socket_comp(a: SocketAddr, b: SocketAddr) -> std::cmp::Ordering { + let ip_ord = match (a.ip(), b.ip()) { + (IpAddr::V4(a), IpAddr::V4(b)) => a.octets().cmp(&b.octets()), + (IpAddr::V6(a), IpAddr::V6(b)) => a.octets().cmp(&b.octets()), + // length prefix [0, 4] < [0, 16] so all IPv4 sorts before all IPv6 + (IpAddr::V4(_), IpAddr::V6(_)) => std::cmp::Ordering::Less, + (IpAddr::V6(_), IpAddr::V4(_)) => std::cmp::Ordering::Greater, + }; + ip_ord.then(a.port().cmp(&b.port())) +} diff --git a/contracts/network-monitors/src/transactions.rs b/contracts/network-monitors/src/transactions.rs new file mode 100644 index 0000000000..a2baafb78e --- /dev/null +++ b/contracts/network-monitors/src/transactions.rs @@ -0,0 +1,1096 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::storage::NETWORK_MONITORS_CONTRACT_STORAGE; +use cosmwasm_std::{DepsMut, Env, MessageInfo, Response}; +use nym_network_monitors_contract_common::NetworkMonitorsContractError; +use std::net::SocketAddr; + +pub fn try_update_contract_admin( + deps: DepsMut<'_>, + info: MessageInfo, + new_admin: String, +) -> Result { + let new_admin = deps.api.addr_validate(&new_admin)?; + + let res = NETWORK_MONITORS_CONTRACT_STORAGE + .contract_admin + .execute_update_admin(deps, info, Some(new_admin))?; + + Ok(res) +} + +pub fn try_authorise_network_monitor_orchestrator( + deps: DepsMut<'_>, + env: Env, + info: MessageInfo, + orchestrator_address: String, +) -> Result { + let orchestrator_address = deps.api.addr_validate(&orchestrator_address)?; + NETWORK_MONITORS_CONTRACT_STORAGE.authorise_orchestrator( + deps, + &env, + &info.sender, + orchestrator_address, + )?; + + Ok(Response::new()) +} + +/// Update the announced ed25519 identity key of the orchestrator submitting the transaction. +/// +/// The sender must already be an authorised orchestrator - this is enforced by +/// [`NetworkMonitorsStorage::update_orchestrator_identity_key`] via the `NotAnOrchestrator` error +/// when no entry exists for the sender. +/// +/// Only shape-level validation is performed on `identity_key` (valid base58 encoding a 32-byte +/// ed25519 public key). The key is not verified to be a valid curve point, as doing so on-chain +/// is disproportionately expensive relative to the downstream risk - a malformed key will simply +/// fail signature verification when used. +pub fn try_update_orchestrator_identity_key( + deps: DepsMut<'_>, + info: MessageInfo, + identity_key: String, +) -> Result { + // perform basic validation of the key, i.e. is it valid base58 and is it 32 bytes (i.e. ed25519)? + let mut public_key = [0u8; 32]; + let used = bs58::decode(&identity_key) + .onto(&mut public_key) + .map_err(|err| { + NetworkMonitorsContractError::MalformedEd25519OrchestratorIdentityKey(err.to_string()) + })?; + + if used != 32 { + return Err( + NetworkMonitorsContractError::MalformedEd25519OrchestratorIdentityKey( + "Too few bytes provided for the public key".into(), + ), + ); + } + + NETWORK_MONITORS_CONTRACT_STORAGE.update_orchestrator_identity_key( + deps, + &info.sender, + identity_key, + )?; + + Ok(Response::new()) +} + +pub fn try_revoke_network_monitor_orchestrator( + deps: DepsMut<'_>, + info: MessageInfo, + orchestrator_address: String, +) -> Result { + let orchestrator_address = deps.api.addr_validate(&orchestrator_address)?; + + NETWORK_MONITORS_CONTRACT_STORAGE.remove_orchestrator_authorisation( + deps, + &info.sender, + orchestrator_address, + )?; + + Ok(Response::new()) +} + +pub fn try_authorise_network_monitor( + deps: DepsMut<'_>, + env: Env, + info: MessageInfo, + network_monitor_address: SocketAddr, + bs58_x25519_noise: String, + noise_version: u8, +) -> Result { + // perform basic validation of the key, i.e. is it valid base58 and is it 32 bytes (i.e. x25519)? + let mut public_key = [0u8; 32]; + let used = bs58::decode(&bs58_x25519_noise) + .onto(&mut public_key) + .map_err(|err| { + NetworkMonitorsContractError::MalformedX25519AgentNoiseKey(err.to_string()) + })?; + + if used != 32 { + return Err(NetworkMonitorsContractError::MalformedX25519AgentNoiseKey( + "Too few bytes provided for the public key".into(), + )); + } + + NETWORK_MONITORS_CONTRACT_STORAGE.authorise_monitor( + deps, + &env, + &info.sender, + network_monitor_address, + bs58_x25519_noise, + noise_version, + )?; + + Ok(Response::new()) +} + +pub fn try_revoke_network_monitor( + deps: DepsMut<'_>, + info: MessageInfo, + network_monitor_address: SocketAddr, +) -> Result { + NETWORK_MONITORS_CONTRACT_STORAGE.remove_monitor_authorisation( + deps, + &info.sender, + network_monitor_address, + )?; + Ok(Response::new()) +} + +pub fn try_revoke_all_network_monitors( + deps: DepsMut<'_>, + info: MessageInfo, +) -> Result { + NETWORK_MONITORS_CONTRACT_STORAGE.remove_all_monitors(deps, &info.sender)?; + Ok(Response::new()) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::testing::{init_contract_tester, NetworkMonitorsContractTesterExt}; + use nym_contracts_common_testing::{AdminExt, ContractOpts, RandExt}; + use nym_network_monitors_contract_common::ExecuteMsg; + + // bs58 encoding of 32 zero bytes — a syntactically valid x25519 key for tests + const TEST_NOISE_KEY: &str = "11111111111111111111111111111111"; + + #[cfg(test)] + mod updating_contract_admin { + use super::*; + use crate::testing::init_contract_tester; + use cw_controllers::AdminError; + use nym_contracts_common_testing::{AdminExt, ContractOpts, RandExt}; + use nym_network_monitors_contract_common::ExecuteMsg; + + #[test] + fn can_only_be_performed_by_current_admin() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + + let random_acc = test.generate_account(); + let new_admin = test.generate_account(); + let res = test + .execute_raw( + random_acc, + ExecuteMsg::UpdateAdmin { + admin: new_admin.to_string(), + }, + ) + .unwrap_err(); + + assert_eq!( + res, + NetworkMonitorsContractError::Admin(AdminError::NotAdmin {}) + ); + + let actual_admin = test.admin_unchecked(); + let res = test.execute_raw( + actual_admin.clone(), + ExecuteMsg::UpdateAdmin { + admin: new_admin.to_string(), + }, + ); + assert!(res.is_ok()); + + let updated_admin = test.admin_unchecked(); + assert_eq!(new_admin, updated_admin); + + Ok(()) + } + + #[test] + fn requires_providing_valid_address() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + + let bad_account = "definitely-not-valid-account"; + let res = test.execute_raw( + test.admin_unchecked(), + ExecuteMsg::UpdateAdmin { + admin: bad_account.to_string(), + }, + ); + + assert!(res.is_err()); + + let empty_account = ""; + let res = test.execute_raw( + test.admin_unchecked(), + ExecuteMsg::UpdateAdmin { + admin: empty_account.to_string(), + }, + ); + + assert!(res.is_err()); + + Ok(()) + } + } + + #[cfg(test)] + mod authorising_network_monitor_orchestrator { + use super::*; + use cw_controllers::AdminError; + + #[test] + fn can_only_be_performed_by_contract_admin() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + + let non_admin = test.generate_account(); + let orchestrator = test.generate_account(); + + let res = test + .execute_raw( + non_admin.clone(), + ExecuteMsg::AuthoriseNetworkMonitorOrchestrator { + address: orchestrator.to_string(), + }, + ) + .unwrap_err(); + + assert_eq!( + res, + NetworkMonitorsContractError::Admin(AdminError::NotAdmin {}) + ); + + let admin = test.admin_unchecked(); + let res = test.execute_raw( + admin, + ExecuteMsg::AuthoriseNetworkMonitorOrchestrator { + address: orchestrator.to_string(), + }, + ); + assert!(res.is_ok()); + + Ok(()) + } + + #[test] + fn requires_providing_valid_orchestrator_address() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + + let bad_address = "definitely-not-valid-account"; + let res = test.execute_raw( + test.admin_unchecked(), + ExecuteMsg::AuthoriseNetworkMonitorOrchestrator { + address: bad_address.to_string(), + }, + ); + assert!(res.is_err()); + + let good_address = test.generate_account(); + let res = test.execute_raw( + test.admin_unchecked(), + ExecuteMsg::AuthoriseNetworkMonitorOrchestrator { + address: good_address.to_string(), + }, + ); + assert!(res.is_ok()); + + Ok(()) + } + + #[test] + fn inserts_new_entry_for_fresh_accounts() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + let orchestrator = test.generate_account(); + + assert!(NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_orchestrators + .may_load(test.storage(), &orchestrator)? + .is_none()); + + test.execute_raw( + test.admin_unchecked(), + ExecuteMsg::AuthoriseNetworkMonitorOrchestrator { + address: orchestrator.to_string(), + }, + )?; + + let info = NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_orchestrators + .load(test.storage(), &orchestrator)?; + + assert_eq!(info.address, orchestrator); + + Ok(()) + } + + #[test] + fn is_noop_for_already_authorised_accounts() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + let orchestrator = test.generate_account(); + let admin = test.admin_unchecked(); + + test.execute_raw( + admin.clone(), + ExecuteMsg::AuthoriseNetworkMonitorOrchestrator { + address: orchestrator.to_string(), + }, + )?; + + let info = NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_orchestrators + .load(test.storage(), &orchestrator)?; + + test.execute_raw( + admin, + ExecuteMsg::AuthoriseNetworkMonitorOrchestrator { + address: orchestrator.to_string(), + }, + )?; + + let updated = NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_orchestrators + .load(test.storage(), &orchestrator)?; + + assert_eq!(info, updated); + + Ok(()) + } + } + + #[cfg(test)] + mod updating_orchestrator_identity_key { + use super::*; + + /// Base58 encoding of 32 bytes - a valid ed25519 key shape. + fn valid_identity_key() -> String { + bs58::encode([7u8; 32]).into_string() + } + + #[test] + fn can_only_be_performed_by_authorised_orchestrator() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + + let non_orchestrator = test.generate_account(); + + let res = test + .execute_raw( + non_orchestrator.clone(), + ExecuteMsg::UpdateOrchestratorIdentityKey { + key: valid_identity_key(), + }, + ) + .unwrap_err(); + assert_eq!( + res, + NetworkMonitorsContractError::NotAnOrchestrator { + addr: non_orchestrator + } + ); + + let orchestrator = test.add_orchestrator()?; + let res = test.execute_raw( + orchestrator, + ExecuteMsg::UpdateOrchestratorIdentityKey { + key: valid_identity_key(), + }, + ); + assert!(res.is_ok()); + + Ok(()) + } + + #[test] + fn rejects_key_that_is_not_valid_base58() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + let orchestrator = test.add_orchestrator()?; + + // '0', 'O', 'I', 'l' are not in the bitcoin alphabet used by bs58 + let res = test + .execute_raw( + orchestrator, + ExecuteMsg::UpdateOrchestratorIdentityKey { + key: "not_valid_base58_0OIl".to_string(), + }, + ) + .unwrap_err(); + assert!(matches!( + res, + NetworkMonitorsContractError::MalformedEd25519OrchestratorIdentityKey(_) + )); + + Ok(()) + } + + #[test] + fn rejects_key_that_is_too_short() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + let orchestrator = test.add_orchestrator()?; + + // 16 bytes, not 32 + let too_short = bs58::encode([1u8; 16]).into_string(); + let res = test + .execute_raw( + orchestrator, + ExecuteMsg::UpdateOrchestratorIdentityKey { key: too_short }, + ) + .unwrap_err(); + assert!(matches!( + res, + NetworkMonitorsContractError::MalformedEd25519OrchestratorIdentityKey(_) + )); + + Ok(()) + } + + #[test] + fn rejects_key_that_is_too_long() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + let orchestrator = test.add_orchestrator()?; + + // 33 bytes, not 32 - decoder should bail out because the destination buffer is too small + let too_long = bs58::encode([1u8; 33]).into_string(); + let res = test + .execute_raw( + orchestrator, + ExecuteMsg::UpdateOrchestratorIdentityKey { key: too_long }, + ) + .unwrap_err(); + assert!(matches!( + res, + NetworkMonitorsContractError::MalformedEd25519OrchestratorIdentityKey(_) + )); + + Ok(()) + } + + #[test] + fn stores_provided_key_against_orchestrator_entry() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + let orchestrator = test.add_orchestrator()?; + + // freshly authorised orchestrator has no announced identity key + let info = NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_orchestrators + .load(test.storage(), &orchestrator)?; + assert!(info.identity_key.is_none()); + + let key = valid_identity_key(); + test.execute_raw( + orchestrator.clone(), + ExecuteMsg::UpdateOrchestratorIdentityKey { key: key.clone() }, + )?; + + let updated = NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_orchestrators + .load(test.storage(), &orchestrator)?; + assert_eq!(updated.identity_key.as_deref(), Some(key.as_str())); + + Ok(()) + } + + #[test] + fn overwrites_previously_announced_key() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + let orchestrator = test.add_orchestrator()?; + + let first_key = bs58::encode([1u8; 32]).into_string(); + let second_key = bs58::encode([2u8; 32]).into_string(); + + test.execute_raw( + orchestrator.clone(), + ExecuteMsg::UpdateOrchestratorIdentityKey { + key: first_key.clone(), + }, + )?; + test.execute_raw( + orchestrator.clone(), + ExecuteMsg::UpdateOrchestratorIdentityKey { + key: second_key.clone(), + }, + )?; + + let info = NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_orchestrators + .load(test.storage(), &orchestrator)?; + assert_eq!(info.identity_key.as_deref(), Some(second_key.as_str())); + + Ok(()) + } + + #[test] + fn updating_one_orchestrator_key_does_not_affect_others() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + let orchestrator_a = test.add_orchestrator()?; + let orchestrator_b = test.add_orchestrator()?; + + let key_a = bs58::encode([10u8; 32]).into_string(); + test.execute_raw( + orchestrator_a.clone(), + ExecuteMsg::UpdateOrchestratorIdentityKey { key: key_a.clone() }, + )?; + + let info_a = NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_orchestrators + .load(test.storage(), &orchestrator_a)?; + let info_b = NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_orchestrators + .load(test.storage(), &orchestrator_b)?; + + assert_eq!(info_a.identity_key.as_deref(), Some(key_a.as_str())); + assert!(info_b.identity_key.is_none()); + + Ok(()) + } + } + + #[cfg(test)] + mod revoking_network_monitor_orchestrator { + use super::*; + use cw_controllers::AdminError; + + #[test] + fn can_only_be_performed_by_contract_admin() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + + let orchestrator = test.add_orchestrator()?; + let non_admin = test.generate_account(); + + let res = test + .execute_raw( + non_admin.clone(), + ExecuteMsg::RevokeNetworkMonitorOrchestrator { + address: orchestrator.to_string(), + }, + ) + .unwrap_err(); + + assert_eq!( + res, + NetworkMonitorsContractError::Admin(AdminError::NotAdmin {}) + ); + + let res = test.execute_raw( + test.admin_unchecked(), + ExecuteMsg::RevokeNetworkMonitorOrchestrator { + address: orchestrator.to_string(), + }, + ); + assert!(res.is_ok()); + + Ok(()) + } + + #[test] + fn requires_providing_valid_orchestrator_address() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + + let res = test.execute_raw( + test.admin_unchecked(), + ExecuteMsg::RevokeNetworkMonitorOrchestrator { + address: "definitely-not-valid-account".to_string(), + }, + ); + assert!(res.is_err()); + + let valid_but_missing = test.generate_account(); + let res = test.execute_raw( + test.admin_unchecked(), + ExecuteMsg::RevokeNetworkMonitorOrchestrator { + address: valid_but_missing.to_string(), + }, + ); + assert!(res.is_ok()); + + Ok(()) + } + + #[test] + fn deletes_entry_from_storage() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + let orchestrator = test.add_orchestrator()?; + + assert!(NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_orchestrators + .may_load(test.storage(), &orchestrator)? + .is_some()); + + test.execute_raw( + test.admin_unchecked(), + ExecuteMsg::RevokeNetworkMonitorOrchestrator { + address: orchestrator.to_string(), + }, + )?; + + assert!(NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_orchestrators + .may_load(test.storage(), &orchestrator)? + .is_none()); + + Ok(()) + } + } + + #[cfg(test)] + mod authorising_network_monitor { + use super::*; + use nym_contracts_common_testing::ChainOpts; + + #[test] + fn can_only_be_performed_by_orchestrator() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + + let non_orchestrator = test.generate_account(); + let agent = test.random_socket(); + + let res = test + .execute_raw( + non_orchestrator.clone(), + ExecuteMsg::AuthoriseNetworkMonitor { + mixnet_address: agent, + bs58_x25519_noise: TEST_NOISE_KEY.to_string(), + noise_version: 1, + }, + ) + .unwrap_err(); + + assert_eq!( + res, + NetworkMonitorsContractError::NotAnOrchestrator { + addr: non_orchestrator + } + ); + + let orchestrator = test.add_orchestrator()?; + let res = test.execute_raw( + orchestrator, + ExecuteMsg::AuthoriseNetworkMonitor { + mixnet_address: agent, + bs58_x25519_noise: TEST_NOISE_KEY.to_string(), + noise_version: 1, + }, + ); + assert!(res.is_ok()); + + Ok(()) + } + + #[test] + fn inserts_new_entry_for_fresh_agents() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + let orchestrator = test.add_orchestrator()?; + let agent = test.random_socket(); + + assert!(NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_agents + .may_load(test.storage(), agent.into())? + .is_none()); + + test.execute_raw( + orchestrator.clone(), + ExecuteMsg::AuthoriseNetworkMonitor { + mixnet_address: agent, + bs58_x25519_noise: TEST_NOISE_KEY.to_string(), + noise_version: 1, + }, + )?; + + let info = NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_agents + .load(test.storage(), agent.into())?; + + assert_eq!(info.mixnet_address, agent); + assert_eq!(info.authorised_by, orchestrator); + + Ok(()) + } + + #[test] + fn renews_existing_agent_authorisation() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + let orchestrator = test.add_orchestrator()?; + let agent = test.random_socket(); + + test.execute_raw( + orchestrator.clone(), + ExecuteMsg::AuthoriseNetworkMonitor { + mixnet_address: agent, + bs58_x25519_noise: TEST_NOISE_KEY.to_string(), + noise_version: 1, + }, + )?; + + let initial = NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_agents + .load(test.storage(), agent.into())?; + + test.advance_day_of_blocks(); + + test.execute_raw( + orchestrator.clone(), + ExecuteMsg::AuthoriseNetworkMonitor { + mixnet_address: agent, + bs58_x25519_noise: TEST_NOISE_KEY.to_string(), + noise_version: 1, + }, + )?; + + let updated = NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_agents + .load(test.storage(), agent.into())?; + + assert_eq!(updated.mixnet_address, agent); + assert_eq!(updated.authorised_by, orchestrator); + assert!(updated.authorised_at > initial.authorised_at); + + Ok(()) + } + } + + #[cfg(test)] + mod revoking_network_monitor { + use super::*; + + #[test] + fn can_be_performed_by_orchestrator() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + + let orchestrator = test.add_orchestrator()?; + let agent = test.random_socket(); + + test.execute_raw( + orchestrator.clone(), + ExecuteMsg::AuthoriseNetworkMonitor { + mixnet_address: agent, + bs58_x25519_noise: TEST_NOISE_KEY.to_string(), + noise_version: 1, + }, + )?; + + let res = test.execute_raw( + orchestrator, + ExecuteMsg::RevokeNetworkMonitor { address: agent }, + ); + assert!(res.is_ok()); + + Ok(()) + } + + #[test] + fn can_be_performed_by_admin() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + + let admin = test.admin_unchecked(); + let orchestrator = test.add_orchestrator()?; + let agent = test.random_socket(); + + test.execute_raw( + orchestrator, + ExecuteMsg::AuthoriseNetworkMonitor { + mixnet_address: agent, + bs58_x25519_noise: TEST_NOISE_KEY.to_string(), + noise_version: 1, + }, + )?; + + let res = test.execute_raw(admin, ExecuteMsg::RevokeNetworkMonitor { address: agent }); + assert!(res.is_ok()); + + assert!(NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_agents + .may_load(test.storage(), agent.into())? + .is_none()); + + Ok(()) + } + + #[test] + fn rejects_non_privileged_accounts() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + + let orchestrator = test.add_orchestrator()?; + let non_privileged = test.generate_account(); + let agent = test.random_socket(); + + test.execute_raw( + orchestrator, + ExecuteMsg::AuthoriseNetworkMonitor { + mixnet_address: agent, + bs58_x25519_noise: TEST_NOISE_KEY.to_string(), + noise_version: 1, + }, + )?; + + let res = test + .execute_raw( + non_privileged, + ExecuteMsg::RevokeNetworkMonitor { address: agent }, + ) + .unwrap_err(); + + assert_eq!(res, NetworkMonitorsContractError::Unauthorized); + + Ok(()) + } + + #[test] + fn deletes_entry_from_storage() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + let orchestrator = test.add_orchestrator()?; + let agent = test.random_socket(); + + test.execute_raw( + orchestrator.clone(), + ExecuteMsg::AuthoriseNetworkMonitor { + mixnet_address: agent, + bs58_x25519_noise: TEST_NOISE_KEY.to_string(), + noise_version: 1, + }, + )?; + + assert!(NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_agents + .may_load(test.storage(), agent.into())? + .is_some()); + + test.execute_raw( + orchestrator, + ExecuteMsg::RevokeNetworkMonitor { address: agent }, + )?; + + assert!(NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_agents + .may_load(test.storage(), agent.into())? + .is_none()); + + Ok(()) + } + + #[test] + fn is_noop_for_non_existent_entries() -> anyhow::Result<()> { + let mut test = init_contract_tester(); + let orchestrator = test.add_orchestrator()?; + let agent = test.random_socket(); + + assert!(NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_agents + .may_load(test.storage(), agent.into())? + .is_none()); + + let res = test.execute_raw( + orchestrator, + ExecuteMsg::RevokeNetworkMonitor { address: agent }, + ); + assert!(res.is_ok()); + + assert!(NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_agents + .may_load(test.storage(), agent.into())? + .is_none()); + + Ok(()) + } + + #[test] + fn revoking_one_agent_preserves_other_on_same_host() -> anyhow::Result<()> { + use std::net::{IpAddr, Ipv4Addr, SocketAddr}; + + let mut test = init_contract_tester(); + let orchestrator = test.add_orchestrator()?; + + // two agents on the same IP but different ports + let ip = IpAddr::V4(Ipv4Addr::new(192, 168, 1, 1)); + let agent_a = SocketAddr::new(ip, 1000); + let agent_b = SocketAddr::new(ip, 2000); + + // two syntactically valid (32-byte) bs58 x25519 keys + let noise_key_a = TEST_NOISE_KEY.to_string(); + let noise_key_b = "4vJ9JU1bJJE96FWSJKvHsmmFADCg4gpZQff4P3bkLKi".to_string(); + + test.execute_raw( + orchestrator.clone(), + ExecuteMsg::AuthoriseNetworkMonitor { + mixnet_address: agent_a, + bs58_x25519_noise: noise_key_a, + noise_version: 1, + }, + )?; + test.execute_raw( + orchestrator.clone(), + ExecuteMsg::AuthoriseNetworkMonitor { + mixnet_address: agent_b, + bs58_x25519_noise: noise_key_b.clone(), + noise_version: 1, + }, + )?; + + // both exist + assert!(NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_agents + .may_load(test.storage(), agent_a.into())? + .is_some()); + assert!(NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_agents + .may_load(test.storage(), agent_b.into())? + .is_some()); + + // revoke agent_a + test.execute_raw( + orchestrator, + ExecuteMsg::RevokeNetworkMonitor { address: agent_a }, + )?; + + // agent_a gone, agent_b still present + assert!(NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_agents + .may_load(test.storage(), agent_a.into())? + .is_none()); + let remaining = NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_agents + .load(test.storage(), agent_b.into())?; + assert_eq!(remaining.mixnet_address, agent_b); + assert_eq!( + remaining.bs58_x25519_noise, + "4vJ9JU1bJJE96FWSJKvHsmmFADCg4gpZQff4P3bkLKi" + ); + + Ok(()) + } + } + + #[cfg(test)] + mod revoking_all_network_monitors { + use super::*; + + fn setup_prepopulated_tester() -> anyhow::Result<( + nym_contracts_common_testing::ContractTester, + cosmwasm_std::Addr, + )> { + let mut test = init_contract_tester(); + let orchestrator = test.add_orchestrator()?; + + let agent1 = test.random_socket(); + let agent2 = test.random_socket(); + let agent3 = test.random_socket(); + + test.execute_raw( + orchestrator.clone(), + ExecuteMsg::AuthoriseNetworkMonitor { + mixnet_address: agent1, + bs58_x25519_noise: TEST_NOISE_KEY.to_string(), + noise_version: 1, + }, + )?; + test.execute_raw( + orchestrator.clone(), + ExecuteMsg::AuthoriseNetworkMonitor { + mixnet_address: agent2, + bs58_x25519_noise: TEST_NOISE_KEY.to_string(), + noise_version: 1, + }, + )?; + test.execute_raw( + orchestrator.clone(), + ExecuteMsg::AuthoriseNetworkMonitor { + mixnet_address: agent3, + bs58_x25519_noise: TEST_NOISE_KEY.to_string(), + noise_version: 1, + }, + )?; + + Ok((test, orchestrator)) + } + + #[test] + fn can_be_performed_by_admin() -> anyhow::Result<()> { + let (mut test, _) = setup_prepopulated_tester()?; + let agents = test.all_agents(); + + test.execute_raw(test.admin_unchecked(), ExecuteMsg::RevokeAllNetworkMonitors)?; + + for agent in agents { + assert!(NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_agents + .may_load(test.storage(), agent.into())? + .is_none()); + } + + assert!(test.all_agents().is_empty()); + + Ok(()) + } + + #[test] + fn can_be_performed_by_orchestrator() -> anyhow::Result<()> { + let (mut test, orchestrator) = setup_prepopulated_tester()?; + let agents = test.all_agents(); + + test.execute_raw(orchestrator, ExecuteMsg::RevokeAllNetworkMonitors)?; + + for agent in agents { + assert!(NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_agents + .may_load(test.storage(), agent.into())? + .is_none()); + } + + assert!(test.all_agents().is_empty()); + + Ok(()) + } + + #[test] + fn cannot_be_performed_by_non_privileged_account() -> anyhow::Result<()> { + let (mut test, _) = setup_prepopulated_tester()?; + let agents = test.all_agents(); + let random_acc = test.generate_account(); + + let res = test + .execute_raw(random_acc, ExecuteMsg::RevokeAllNetworkMonitors) + .unwrap_err(); + + assert_eq!(res, NetworkMonitorsContractError::Unauthorized); + assert_eq!(test.all_agents(), agents); + + Ok(()) + } + + #[test] + fn cannot_be_performed_by_revoked_orchestrator() -> anyhow::Result<()> { + let (mut test, orchestrator) = setup_prepopulated_tester()?; + + test.execute_raw( + test.admin_unchecked(), + ExecuteMsg::RevokeNetworkMonitorOrchestrator { + address: orchestrator.to_string(), + }, + )?; + + // snapshot after revocation (cascade-delete has already run); the failed + // call below must not mutate this set + let post_revoke_agents = test.all_agents(); + + let res = test + .execute_raw(orchestrator, ExecuteMsg::RevokeAllNetworkMonitors) + .unwrap_err(); + + assert_eq!(res, NetworkMonitorsContractError::Unauthorized); + assert_eq!(test.all_agents(), post_revoke_agents); + + Ok(()) + } + + #[test] + fn clears_all_agents() -> anyhow::Result<()> { + let (mut test, _) = setup_prepopulated_tester()?; + let agents = test.all_agents(); + + test.execute_raw(test.admin_unchecked(), ExecuteMsg::RevokeAllNetworkMonitors)?; + + for agent in agents { + assert!(NETWORK_MONITORS_CONTRACT_STORAGE + .authorised_agents + .may_load(test.storage(), agent.into())? + .is_none()); + } + + assert!(test.all_agents().is_empty()); + + Ok(()) + } + } +} diff --git a/envs/sandbox.env b/envs/sandbox.env index 8495e73e18..cd929f8c4b 100644 --- a/envs/sandbox.env +++ b/envs/sandbox.env @@ -17,6 +17,7 @@ GROUP_CONTRACT_ADDRESS=n1ewmwz97xm0h8rdk8sw7h9mwn866qkx9hl9zlmagqfkhuzvwk5hhq844 MULTISIG_CONTRACT_ADDRESS=n1tz0setr8vkh9udp8xyxgpqc89ns27k4d0jx2h942hr0ax63yjhmqz6xct8 COCONUT_DKG_CONTRACT_ADDRESS=n1v3n2ly2dp3a9ng3ff6rh26yfkn0pc5hed7w2shc5u9ca5c865utqj5elvh ECASH_CONTRACT_ADDRESS=n1v3vydvs2ued84yv3khqwtgldmgwn0elljsdh08dr5s2j9x4rc5fs9jlwz9 +NETWORK_MONITORS_CONTRACT_ADDRESS=n1x5krtvyqklj360x38v62ze42g8s8trfsfqzlv8c9296chcpvqadssqnem5 STATISTICS_SERVICE_DOMAIN_ADDRESS="http://0.0.0.0" NYXD=https://rpc.sandbox.nymtech.net diff --git a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs index 189a5a4ca6..5dfcf036f5 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs @@ -241,7 +241,7 @@ impl AuthenticatedHandler { .inner .shared_state .outbound_mix_sender - .forward_packet(mix_packet) + .forward_client_packet_without_delay(mix_packet) { error!("We failed to forward requested mix packet - {err}. Presumably our mix forwarder has crashed. We cannot continue."); process::exit(1); diff --git a/gateway/src/node/mod.rs b/gateway/src/node/mod.rs index 89722e9f72..82de02979e 100644 --- a/gateway/src/node/mod.rs +++ b/gateway/src/node/mod.rs @@ -77,6 +77,8 @@ pub struct LocalAuthenticatorOpts { pub struct GatewayTasksBuilder { config: Config, + network: NymNetworkDetails, + network_requester_opts: Option, ip_packet_router_opts: Option, @@ -120,6 +122,7 @@ impl GatewayTasksBuilder { #[allow(clippy::too_many_arguments)] pub fn new( config: Config, + network: NymNetworkDetails, identity: Arc, storage: GatewayStorage, mix_packet_sender: MixForwardingSender, @@ -133,6 +136,7 @@ impl GatewayTasksBuilder { ) -> GatewayTasksBuilder { GatewayTasksBuilder { config, + network, network_requester_opts: None, ip_packet_router_opts: None, authenticator_opts: None, @@ -184,8 +188,7 @@ impl GatewayTasksBuilder { .choose(&mut thread_rng()) .ok_or(GatewayError::NoNyxdAvailable)?; - let network_details = NymNetworkDetails::new_from_env(); - let client_config = nyxd::Config::try_from_nym_network_details(&network_details)?; + let client_config = nyxd::Config::try_from_nym_network_details(&self.network)?; let nyxd_client = DirectSigningHttpRpcNyxdClient::connect_with_mnemonic( client_config, diff --git a/nym-api/migrations/20260424120000_stress_testing.sql b/nym-api/migrations/20260424120000_stress_testing.sql new file mode 100644 index 0000000000..c437f19a64 --- /dev/null +++ b/nym-api/migrations/20260424120000_stress_testing.sql @@ -0,0 +1,29 @@ +/* + * Copyright 2026 - Nym Technologies SA + * SPDX-License-Identifier: GPL-3.0-only + */ + +CREATE TABLE nym_node_stress_testing_result +( + -- Orchestrator-local testrun id that produced this result. Paired with `submitter_pubkey` + -- it uniquely identifies a measurement and lets us dedupe retried submissions (the + -- orchestrator uses at-least-once delivery and may re-POST the same row after a crash + -- between a successful POST and its watermark update). + testrun_id INTEGER NOT NULL, + + -- Base58-encoded ed25519 identity key of the submitting orchestrator. Part of the primary + -- key so distinct orchestrators can coincidentally share a `testrun_id` without colliding. + submitter_pubkey TEXT NOT NULL, + + -- unfortunately, due to legacy reasons we have separate tables for mixnodes and gateways + -- so that we can't put a reference constraint here + node_id INTEGER NOT NULL, + + result REAL NOT NULL, + + was_reachable BOOLEAN NOT NULL, + + test_timestamp TIMESTAMP WITHOUT TIME ZONE NOT NULL, + + PRIMARY KEY (testrun_id, submitter_pubkey) +); diff --git a/nym-api/nym-api-requests/src/models/network_monitor.rs b/nym-api/nym-api-requests/src/models/network_monitor.rs index c253bd28ca..3075a76e88 100644 --- a/nym-api/nym-api-requests/src/models/network_monitor.rs +++ b/nym-api/nym-api-requests/src/models/network_monitor.rs @@ -2,6 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 use crate::pagination::PaginatedResponse; +use nym_crypto::asymmetric::ed25519; +use nym_crypto::asymmetric::ed25519::serde_helpers::bs58_ed25519_pubkey; use nym_mixnet_contract_common::NodeId; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; @@ -72,3 +74,111 @@ pub struct GatewayCoreStatusResponse { pub identity: String, pub count: i64, } + +pub use v3::*; + +/// Request/response types for the v3 network-monitor flow, in which an orchestrator submits +/// stress testing results to nym-api via signed batches. +pub mod v3 { + use super::*; + use crate::signable::SignedMessage; + use std::time::Duration; + use time::OffsetDateTime; + + /// Signed envelope posted by a network monitor orchestrator to + /// `POST /v3/nym-nodes/stress-testing/batch-submit`. + /// + /// The signature is checked against the `signer` field of the inner + /// [`StressTestBatchSubmissionContent`], which must also match one of the orchestrators + /// registered in the network-monitors contract. + pub type StressTestBatchSubmission = SignedMessage; + + /// Confirmation returned to an orchestrator after a successful submission. + /// Currently empty — exists to give the response an explicit type rather than + /// relying on `Json(())`. + #[derive(Clone, Debug, Serialize, Deserialize, ToSchema)] + pub struct StressTestBatchSubmissionResponse {} + + /// Single stress-test measurement for one node, produced by a network monitor orchestrator. + #[derive(Clone, Debug, Serialize, Deserialize, ToSchema)] + pub struct StressTestResult { + /// Orchestrator-local id of the test run that produced this result. Combined with the + /// batch's `signer` it uniquely identifies the measurement, allowing nym-api to dedupe + /// retried submissions on the at-least-once delivery path. + pub testrun_id: i64, + + /// Contract-assigned id of the node that was tested. + pub node_id: NodeId, + + /// Whether the tested node was acting as a mixnode during the measurement. + /// + /// Included explicitly (rather than inferred from on-chain role) so the API can reject or + /// route entries that don't match the expected role without re-querying the contract. + pub is_mixnode: bool, + + #[schema(value_type = String)] + #[serde(with = "time::serde::rfc3339")] + pub test_timestamp: OffsetDateTime, + + /// Measured performance score in the `[0.0, 1.0]` range. + pub test_performance: f64, + + /// Whether the node responded at all during testing. + /// + /// Recorded alongside `test_performance` so that a genuine 0.0 score (node responded but + /// dropped everything) can be distinguished from the node being offline entirely. + pub was_reachable: bool, + } + + /// Body of a stress-test batch submission, signed by a network monitor orchestrator. + #[derive(Clone, Debug, Serialize, Deserialize, ToSchema)] + pub struct StressTestBatchSubmissionContent { + /// ed25519 identity key of the submitting orchestrator. Must match an entry in the + /// network-monitors contract for the batch to be accepted. + #[schema(value_type = String)] + #[serde(with = "ed25519::bs58_ed25519_pubkey")] + pub signer: ed25519::PublicKey, + + /// Time at which this batch was produced. Also used as a monotonic nonce for replay + /// protection: the API rejects submissions whose timestamp is not strictly greater than + /// the orchestrator's previous accepted submission. + #[schema(value_type = String)] + #[serde(with = "time::serde::rfc3339")] + pub timestamp: OffsetDateTime, + + pub results: Vec, + } + + impl StressTestBatchSubmissionContent { + /// Build a batch submission body stamped with the current UTC time. + pub fn new(signer: ed25519::PublicKey, results: Vec) -> Self { + StressTestBatchSubmissionContent { + signer, + timestamp: OffsetDateTime::now_utc(), + results, + } + } + + /// Whether this submission is older than `max_age` relative to the current UTC time. + /// + /// Used server-side to reject submissions that have been sitting around too long, even if + /// they are otherwise well-formed and correctly signed. + pub fn is_stale(&self, max_age: Duration) -> bool { + self.timestamp + max_age < OffsetDateTime::now_utc() + } + } + + /// Response body for `GET /v3/nym-nodes/stress-testing/known-monitors/{identity_key}`, + /// used by orchestrators to check whether this nym-api currently recognises their key. + #[derive(Clone, Debug, Serialize, Deserialize, ToSchema)] + pub struct KnownNetworkMonitorResponse { + /// The ed25519 identity key that was queried (base58-encoded on the wire). + #[serde(with = "bs58_ed25519_pubkey")] + #[schema(value_type = String)] + pub identity_key: ed25519::PublicKey, + + /// Whether the queried identity key is currently recognised by this nym-api + /// as an authorised network monitor permitted to submit stress testing results. + pub authorised: bool, + } +} diff --git a/nym-api/nym-api-requests/src/models/node_status.rs b/nym-api/nym-api-requests/src/models/node_status.rs index 6e432c250e..58e55a057c 100644 --- a/nym-api/nym-api-requests/src/models/node_status.rs +++ b/nym-api/nym-api-requests/src/models/node_status.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::helpers::PlaceholderJsonSchemaImpl; +use crate::models::DisplayRole; use crate::pagination::PaginatedResponse; use cosmwasm_std::Decimal; use nym_contracts_common::{IdentityKey, NaiveFloat}; @@ -15,7 +16,6 @@ use std::time::Duration; use time::{Date, OffsetDateTime}; use utoipa::ToSchema; -use crate::models::DisplayRole; pub use config_score::*; pub type StakeSaturation = Decimal; @@ -406,17 +406,17 @@ pub struct NodePerformance { feature = "generate-ts", ts( export, - export_to = "ts-packages/types/src/types/rust/NodeAnnotation.ts" + export_to = "ts-packages/types/src/types/rust/NodeAnnotationV1.ts" ) )] -pub struct NodeAnnotation { +pub struct NodeAnnotationV1 { #[cfg_attr(feature = "generate-ts", ts(type = "string"))] // legacy #[schema(value_type = String)] pub last_24h_performance: Performance, pub current_role: Option, - pub detailed_performance: DetailedNodePerformance, + pub detailed_performance: DetailedNodePerformanceV1, } #[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema, ToSchema)] @@ -425,11 +425,47 @@ pub struct NodeAnnotation { feature = "generate-ts", ts( export, - export_to = "ts-packages/types/src/types/rust/DetailedNodePerformance.ts" + export_to = "ts-packages/types/src/types/rust/NodeAnnotationV2.ts" + ) +)] +pub struct NodeAnnotationV2 { + pub current_role: Option, + + pub detailed_performance: DetailedNodePerformanceV2, +} + +impl From for NodeAnnotationV1 { + fn from(value: NodeAnnotationV2) -> Self { + // map it from 0-1 range into 0-100 + let scaled_performance = + value.detailed_performance.performance_score.clamp(0.0, 1.0) * 100.; + #[allow(clippy::unwrap_used)] + let legacy_performance = + Performance::from_percentage_value(scaled_performance as u64).unwrap(); + + NodeAnnotationV1 { + last_24h_performance: legacy_performance, + current_role: value.current_role, + detailed_performance: DetailedNodePerformanceV1 { + performance_score: value.detailed_performance.performance_score, + routing_score: value.detailed_performance.routing_score, + config_score: value.detailed_performance.config_score, + }, + } + } +} + +#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema, ToSchema)] +#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] +#[cfg_attr( + feature = "generate-ts", + ts( + export, + export_to = "ts-packages/types/src/types/rust/DetailedNodePerformanceV1.ts" ) )] #[non_exhaustive] -pub struct DetailedNodePerformance { +pub struct DetailedNodePerformanceV1 { /// routing_score * config_score pub performance_score: f64, @@ -437,12 +473,12 @@ pub struct DetailedNodePerformance { pub config_score: ConfigScore, } -impl DetailedNodePerformance { +impl DetailedNodePerformanceV1 { pub fn new( performance_score: f64, routing_score: RoutingScore, config_score: ConfigScore, - ) -> DetailedNodePerformance { + ) -> DetailedNodePerformanceV1 { Self { performance_score, routing_score, @@ -455,6 +491,47 @@ impl DetailedNodePerformance { } } +#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema, ToSchema)] +#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] +#[cfg_attr( + feature = "generate-ts", + ts( + export, + export_to = "ts-packages/types/src/types/rust/DetailedNodePerformanceV2.ts" + ) +)] +#[non_exhaustive] +pub struct DetailedNodePerformanceV2 { + /// routing_score * config_score + /// or + /// routing_score * config_score * stress_testing_score, if enabled + pub performance_score: f64, + + pub routing_score: RoutingScore, + pub config_score: ConfigScore, + pub stress_testing_score: StressTestingScore, +} + +impl DetailedNodePerformanceV2 { + pub fn new( + performance_score: f64, + routing_score: RoutingScore, + config_score: ConfigScore, + stress_testing_score: StressTestingScore, + ) -> DetailedNodePerformanceV2 { + Self { + performance_score, + routing_score, + config_score, + stress_testing_score, + } + } + + pub fn to_rewarding_performance(&self) -> Performance { + Performance::naive_try_from_f64(self.performance_score).unwrap_or_default() + } +} + #[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema, ToSchema)] #[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] #[cfg_attr( @@ -481,6 +558,32 @@ impl RoutingScore { } } +#[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema, ToSchema)] +#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] +#[cfg_attr( + feature = "generate-ts", + ts( + export, + export_to = "ts-packages/types/src/types/rust/StressTestingScore.ts" + ) +)] +pub struct StressTestingScore { + pub score: f64, + /// Distinguishes a genuine zero score (node was tested and scored 0) from + /// "node was unreachable" (no successful sample was collected). Consumers may use + /// this to decide whether to penalise the node or treat the score as missing. + pub was_reachable: bool, +} + +impl StressTestingScore { + pub fn unreachable() -> Self { + StressTestingScore { + score: 0.0, + was_reachable: false, + } + } +} + #[derive(Clone, Copy, Debug, Default, Serialize, Deserialize, JsonSchema, ToSchema)] #[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] #[cfg_attr( @@ -541,13 +644,28 @@ impl ConfigScore { feature = "generate-ts", ts( export, - export_to = "ts-packages/types/src/types/rust/AnnotationResponse.ts" + export_to = "ts-packages/types/src/types/rust/AnnotationResponseV1.ts" ) )] -pub struct AnnotationResponse { +pub struct AnnotationResponseV1 { #[schema(value_type = u32)] pub node_id: NodeId, - pub annotation: Option, + pub annotation: Option, +} + +#[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, ToSchema)] +#[cfg_attr(feature = "generate-ts", derive(ts_rs::TS))] +#[cfg_attr( + feature = "generate-ts", + ts( + export, + export_to = "ts-packages/types/src/types/rust/AnnotationResponseV2.ts" + ) +)] +pub struct AnnotationResponseV2 { + #[schema(value_type = u32)] + pub node_id: NodeId, + pub annotation: Option, } #[derive(Clone, Copy, Debug, Serialize, Deserialize, JsonSchema, ToSchema)] diff --git a/nym-api/nym-api-requests/src/signable.rs b/nym-api/nym-api-requests/src/signable.rs index 5b1bb90584..a404716a2b 100644 --- a/nym-api/nym-api-requests/src/signable.rs +++ b/nym-api/nym-api-requests/src/signable.rs @@ -55,7 +55,8 @@ impl SignedMessage { pub(crate) mod sealed { use crate::ecash::models::*; use crate::models::{ - ChainBlocksStatusResponseBody, DetailedSignersStatusResponseBody, SignersStatusResponseBody, + v3, ChainBlocksStatusResponseBody, DetailedSignersStatusResponseBody, + SignersStatusResponseBody, }; pub trait Sealed {} @@ -72,4 +73,7 @@ pub(crate) mod sealed { impl Sealed for ChainBlocksStatusResponseBody {} impl Sealed for SignersStatusResponseBody {} impl Sealed for DetailedSignersStatusResponseBody {} + + // v3 stress testing + impl Sealed for v3::StressTestBatchSubmissionContent {} } diff --git a/nym-api/src/ecash/tests/mod.rs b/nym-api/src/ecash/tests/mod.rs index 2640a25009..14e50cfbac 100644 --- a/nym-api/src/ecash/tests/mod.rs +++ b/nym-api/src/ecash/tests/mod.rs @@ -18,6 +18,7 @@ use crate::support::http::state::chain_status::ChainStatusCache; use crate::support::http::state::contract_details::ContractDetailsCache; use crate::support::http::state::force_refresh::ForcedRefresh; use crate::support::http::state::mixnet_contract_cache::MixnetContractCacheState; +use crate::support::http::state::network_monitors::{LastNMSubmissions, NetworkMonitorsCache}; use crate::support::http::state::node_annotations_cache::NodeAnnotationsCache; use crate::support::http::state::AppState; use crate::support::nyxd::Client; @@ -1301,7 +1302,9 @@ impl TestFixture { ecash_signers_cache: Default::default(), address_info_cache: AddressInfoCache::new(Duration::from_secs(42), 1000), forced_refresh: ForcedRefresh::new(true), + network_monitor_submissions: LastNMSubmissions::new(), mixnet_contract_cache, + network_monitors_cache: NetworkMonitorsCache::new(Duration::from_secs(42)), node_annotations_cache, storage, described_nodes_cache: SharedCache::::new(), diff --git a/nym-api/src/epoch_operations/helpers.rs b/nym-api/src/epoch_operations/helpers.rs index a353dc0d29..bd41a72ac8 100644 --- a/nym-api/src/epoch_operations/helpers.rs +++ b/nym-api/src/epoch_operations/helpers.rs @@ -4,7 +4,7 @@ use crate::epoch_operations::EpochAdvancer; use crate::support::caching::cache::UninitialisedCache; use cosmwasm_std::{Decimal, Fraction}; -use nym_api_requests::models::NodeAnnotation; +use nym_api_requests::models::NodeAnnotationV2; use nym_mixnet_contract_common::helpers::IntoBaseDecimal; use nym_mixnet_contract_common::reward_params::{NodeRewardingParameters, Performance, WorkFactor}; use nym_mixnet_contract_common::{ @@ -211,7 +211,7 @@ fn determine_per_node_work( impl EpochAdvancer { fn load_performance( status_cache: &Result< - RwLockReadGuard<'_, HashMap>, + RwLockReadGuard<'_, HashMap>, UninitialisedCache, >, node_id: NodeId, diff --git a/nym-api/src/network_monitor/monitor/preparer.rs b/nym-api/src/network_monitor/monitor/preparer.rs index 10e8f6a48d..cadb38c223 100644 --- a/nym-api/src/network_monitor/monitor/preparer.rs +++ b/nym-api/src/network_monitor/monitor/preparer.rs @@ -8,8 +8,7 @@ use crate::node_describe_cache::cache::DescribedNodes; use crate::node_describe_cache::NodeDescriptionTopologyExt; use crate::node_status_api::NodeStatusCache; use crate::support::caching::cache::SharedCache; -use nym_api_requests::models::{NodeAnnotation, NymNodeDescriptionV2}; -use nym_contracts_common::NaiveFloat; +use nym_api_requests::models::{NodeAnnotationV2, NymNodeDescriptionV2}; use nym_crypto::asymmetric::{ed25519, x25519}; use nym_mixnet_contract_common::{LegacyMixLayer, NodeId}; use nym_node_tester_utils::node::{NodeType, TestableNode}; @@ -205,7 +204,7 @@ impl PacketPreparer { &self, rng: &mut R, current_rotation_id: u32, - node_statuses: &HashMap, + node_statuses: &HashMap, mixing_nym_nodes: impl Iterator + 'a, ) -> HashMap> { let mut layered_mixes = HashMap::new(); @@ -219,7 +218,7 @@ impl PacketPreparer { // if the node is not present, default to 0.5 let weight = node_statuses .get(&mixing_nym_node.node_id) - .map(|node| node.last_24h_performance.naive_to_f64()) + .map(|node| node.detailed_performance.performance_score) .unwrap_or(0.5); let layer = self.random_legacy_layer(rng); let layer_mixes = layered_mixes.entry(layer).or_insert_with(Vec::new); @@ -245,7 +244,7 @@ impl PacketPreparer { fn to_legacy_gateway_nodes<'a>( &self, current_rotation_id: u32, - node_statuses: &HashMap, + node_statuses: &HashMap, gateway_capable_nym_nodes: impl Iterator + 'a, ) -> Vec<(RoutingNode, f64)> { let mut gateways = Vec::new(); @@ -259,7 +258,7 @@ impl PacketPreparer { // if the node is not present, default to 0.5 let weight = node_statuses .get(&gateway_capable_node.node_id) - .map(|node| node.last_24h_performance.naive_to_f64()) + .map(|node| node.detailed_performance.performance_score) .unwrap_or(0.5); gateways.push((parsed_node, weight)) } diff --git a/nym-api/src/node_describe_cache/mod.rs b/nym-api/src/node_describe_cache/mod.rs index 976904ce2c..512b4c5d9e 100644 --- a/nym-api/src/node_describe_cache/mod.rs +++ b/nym-api/src/node_describe_cache/mod.rs @@ -3,7 +3,6 @@ use crate::support::caching::cache::UninitialisedCache; use nym_api_requests::models::{NymNodeDescriptionV1, NymNodeDescriptionV2}; -use nym_config::defaults::DEFAULT_NYM_NODE_HTTP_PORT; use nym_mixnet_contract_common::NodeId; use nym_node_requests::api::client::NymNodeApiClientError; use nym_topology::node::RoutingNodeError; @@ -23,18 +22,11 @@ pub enum NodeDescribeCacheError { source: UninitialisedCache, }, - #[error("node {node_id} has provided malformed host information ({host}: {source}")] - MalformedHost { - host: String, + #[error(transparent)] + ClientRetrievalFailure(#[from] nym_node_requests::error::Error), - node_id: NodeId, - - #[source] - source: Box, - }, - - #[error("node {node_id} with host '{host}' doesn't seem to expose its declared http port nor any of the standard API ports, i.e.: 80, 443 or {}", DEFAULT_NYM_NODE_HTTP_PORT)] - NoHttpPortsAvailable { host: String, node_id: NodeId }, + #[error("failed to retrieve host information of node {node_id} - this is most likely a bug")] + NoHostInformationAvailable { node_id: NodeId, host: String }, #[error("failed to query node {node_id}: {source}")] ApiFailure { @@ -44,17 +36,6 @@ pub enum NodeDescribeCacheError { source: Box, }, - // TODO: perhaps include more details here like whether key/signature/payload was malformed - #[error("could not verify signed host information for node {node_id}")] - MissignedHostInformation { node_id: NodeId }, - - #[error("identity of node {node_id} does not match. expected {expected} but got {got}")] - MismatchedIdentity { - node_id: NodeId, - expected: String, - got: String, - }, - #[error("node {node_id} is announcing an illegal ip address")] IllegalIpAddress { node_id: NodeId }, } diff --git a/nym-api/src/node_describe_cache/refresh.rs b/nym-api/src/node_describe_cache/refresh.rs index 801aa5dc29..3a52e688a6 100644 --- a/nym-api/src/node_describe_cache/refresh.rs +++ b/nym-api/src/node_describe_cache/refresh.rs @@ -5,13 +5,10 @@ use crate::node_describe_cache::query_helpers::query_for_described_data; use crate::node_describe_cache::NodeDescribeCacheError; use nym_api_requests::models::{DescribedNodeTypeV2, NymNodeDescriptionV2}; use nym_bin_common::bin_info; -use nym_config::defaults::DEFAULT_NYM_NODE_HTTP_PORT; use nym_crypto::asymmetric::ed25519; use nym_mixnet_contract_common::{NodeId, NymNodeDetails}; -use nym_node_requests::api::client::NymNodeApiClientExt; -use nym_validator_client::UserAgent; -use std::time::Duration; -use tracing::debug; +use nym_node_requests::api::helpers::NymNodeApiClientRetriever; +use tracing::{debug, error}; #[derive(Debug)] pub(crate) struct RefreshData { @@ -69,93 +66,39 @@ impl RefreshData { } } -async fn try_get_client( - host: &str, - node_id: NodeId, - custom_port: Option, -) -> Result { - // first try the standard port in case the operator didn't put the node behind the proxy, - // then default https (443) - // finally default http (80) - let mut addresses_to_try = vec![ - format!("http://{host}:{DEFAULT_NYM_NODE_HTTP_PORT}"), // 'standard' nym-node - format!("https://{host}"), // node behind https proxy (443) - format!("http://{host}"), // node behind http proxy (80) - ]; - - // note: I removed 'standard' legacy mixnode port because it should now be automatically pulled via - // the 'custom_port' since it should have been present in the contract. - - if let Some(port) = custom_port { - addresses_to_try.insert(0, format!("http://{host}:{port}")); - } - - for address in addresses_to_try { - // if provided host was malformed, no point in continuing - let client = match nym_node_requests::api::Client::builder(address).and_then(|b| { - b.with_timeout(Duration::from_secs(5)) - .no_hickory_dns() - .with_user_agent(UserAgent::from(bin_info!())) - .build() - }) { - Ok(client) => client, - Err(err) => { - return Err(NodeDescribeCacheError::MalformedHost { - host: host.to_string(), - node_id, - source: Box::new(err), - }); - } - }; - - if let Ok(health) = client.get_health().await { - if health.status.is_up() { - return Ok(client); - } - } - } - - Err(NodeDescribeCacheError::NoHttpPortsAvailable { - host: host.to_string(), - node_id, - }) -} - async fn try_get_description( data: RefreshData, allow_all_ips: bool, ) -> Result { - let client = try_get_client(&data.host, data.node_id, data.port).await?; + let client = NymNodeApiClientRetriever::new(bin_info!()) + .with_expected_identity(Some(data.expected_identity.to_base58_string())) + .with_verify_host_information() + .with_custom_port(data.port) + .get_client(&data.host, data.node_id) + .await?; - let map_query_err = |err| NodeDescribeCacheError::ApiFailure { - node_id: data.node_id, - source: Box::new(err), + let host_info = match client.host_information { + Some(host_info) => host_info, + // this branch should be impossible unless unexpected code changes occurred + None => { + error!( + "failed to retrieve host information of node {} - this is most likely a bug", + data.node_id + ); + return Err(NodeDescribeCacheError::NoHostInformationAvailable { + node_id: data.node_id, + host: data.host.to_string(), + }); + } }; - let host_info = client.get_host_information().await.map_err(map_query_err)?; - - // check if the identity key matches the information provided during bonding - if data.expected_identity != host_info.keys.ed25519_identity { - return Err(NodeDescribeCacheError::MismatchedIdentity { - node_id: data.node_id, - expected: data.expected_identity.to_base58_string(), - got: host_info.keys.ed25519_identity.to_base58_string(), - }); - } - - if !host_info.verify_host_information() { - return Err(NodeDescribeCacheError::MissignedHostInformation { - node_id: data.node_id, - }); - } - if !allow_all_ips && !host_info.data.check_ips() { return Err(NodeDescribeCacheError::IllegalIpAddress { node_id: data.node_id, }); } - let node_info = query_for_described_data(&client, data.node_id).await?; + let node_info = query_for_described_data(&client.client, data.node_id).await?; let description = node_info.into_node_description(host_info.data); Ok(NymNodeDescriptionV2 { diff --git a/nym-api/src/node_performance/provider/contract_provider.rs b/nym-api/src/node_performance/provider/contract_provider.rs index 29923ccd20..ce9928df52 100644 --- a/nym-api/src/node_performance/provider/contract_provider.rs +++ b/nym-api/src/node_performance/provider/contract_provider.rs @@ -68,7 +68,7 @@ impl ContractPerformanceProvider { pub(crate) async fn node_routing_scores( &self, - node_ids: Vec, + node_ids: &[NodeId], epoch_id: EpochId, ) -> Result { let Some(first) = node_ids.first() else { @@ -84,7 +84,7 @@ impl ContractPerformanceProvider { })?; let mut scores = HashMap::new(); - for node_id in node_ids { + for &node_id in node_ids { let score = self.node_routing_score_with_fallback(&contract_cache, node_id, epoch_id); scores.insert(node_id, score); } diff --git a/nym-api/src/node_performance/provider/legacy_storage_provider.rs b/nym-api/src/node_performance/provider/legacy_storage_provider.rs index 99a886a19b..953421b0f6 100644 --- a/nym-api/src/node_performance/provider/legacy_storage_provider.rs +++ b/nym-api/src/node_performance/provider/legacy_storage_provider.rs @@ -2,55 +2,66 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::mixnet_contract_cache::cache::MixnetContractCache; -use crate::node_performance::provider::PerformanceRetrievalFailure; +use crate::node_performance::provider::{NodesStressTestingScores, PerformanceRetrievalFailure}; use crate::support::caching::cache::UninitialisedCache; use crate::support::storage::NymApiStorage; -use nym_api_requests::models::RoutingScore; +use nym_api_requests::models::{RoutingScore, StressTestingScore}; use nym_mixnet_contract_common::{EpochId, NodeId}; +use std::collections::HashMap; +use std::time::Duration; +use time::OffsetDateTime; pub(crate) struct LegacyStoragePerformanceProvider { + /// Specifies the duration of the rolling average used for stress testing score. + stress_testing_data_period: Duration, + storage: NymApiStorage, mixnet_contract_cache: MixnetContractCache, } impl LegacyStoragePerformanceProvider { - pub(crate) fn new(storage: NymApiStorage, mixnet_contract_cache: MixnetContractCache) -> Self { + pub(crate) fn new( + storage: NymApiStorage, + mixnet_contract_cache: MixnetContractCache, + stress_testing_data_period: Duration, + ) -> Self { LegacyStoragePerformanceProvider { + stress_testing_data_period, storage, mixnet_contract_cache, } } - async fn map_epoch_id_to_end_unix_timestamp( + async fn map_epoch_id_to_end_timestamp( &self, epoch_id: EpochId, - ) -> Result { + ) -> Result { let interval_details = self.mixnet_contract_cache.current_interval().await?; let duration = interval_details.epoch_length(); let current_end = interval_details.current_epoch_end(); let current_id = interval_details.current_epoch_absolute_id(); if current_id == epoch_id { - return Ok(current_end.unix_timestamp()); + return Ok(current_end); } if current_id < epoch_id { let diff = epoch_id - current_id; let end = current_end + diff * duration; - return Ok(end.unix_timestamp()); + return Ok(end); } // epoch_id > current_id let diff = current_id - epoch_id; let end = current_end - diff * duration; - Ok(end.unix_timestamp()) + Ok(end) } - pub(crate) async fn epoch_id_unix_timestamp( + pub(crate) async fn epoch_id_timestamp( &self, epoch_id: EpochId, - ) -> Result { - self.map_epoch_id_to_end_unix_timestamp(epoch_id) + ) -> Result { + self.map_epoch_id_to_end_timestamp(epoch_id) .await .map_err(|_| { PerformanceRetrievalFailure::new( @@ -66,7 +77,7 @@ impl LegacyStoragePerformanceProvider { node_id: NodeId, epoch_id: EpochId, ) -> Result { - let end_ts = self.epoch_id_unix_timestamp(epoch_id).await?; + let end_ts = self.epoch_id_timestamp(epoch_id).await?.unix_timestamp(); self.get_node_routing_score_with_unix_timestamp(node_id, epoch_id, end_ts) .await } @@ -88,4 +99,56 @@ impl LegacyStoragePerformanceProvider { let score = reliability / 100.; Ok(RoutingScore::new(score as f64)) } + + pub(crate) async fn node_stress_testing_score( + &self, + node_id: NodeId, + epoch_id: EpochId, + ) -> Result { + let end_ts = self.epoch_id_timestamp(epoch_id).await?; + let start_ts = end_ts - self.stress_testing_data_period; + + self.node_stress_testing_score_in_range(node_id, epoch_id, start_ts, end_ts) + .await + } + + pub(crate) async fn node_stress_testing_score_in_range( + &self, + node_id: NodeId, + epoch_id: EpochId, + start_ts: OffsetDateTime, + end_ts: OffsetDateTime, + ) -> Result { + let result = self + .storage + .get_average_node_stress_test_score(node_id, start_ts, end_ts) + .await + .map_err(|err| PerformanceRetrievalFailure::new(node_id, epoch_id, err.to_string()))?; + + match result { + None => Ok(StressTestingScore::unreachable()), + Some(result) => Ok(result.into()), + } + } + + pub(crate) async fn get_node_stress_testing_scores( + &self, + node_ids: &[NodeId], + epoch_id: EpochId, + ) -> Result { + let mut scores = HashMap::new(); + + let end_ts = self.epoch_id_timestamp(epoch_id).await?; + let start_ts = end_ts - self.stress_testing_data_period; + + for &node_id in node_ids { + scores.insert( + node_id, + self.node_stress_testing_score_in_range(node_id, epoch_id, start_ts, end_ts) + .await, + ); + } + + Ok(NodesStressTestingScores { inner: scores }) + } } diff --git a/nym-api/src/node_performance/provider/mod.rs b/nym-api/src/node_performance/provider/mod.rs index f8b1bf61a4..43446e446e 100644 --- a/nym-api/src/node_performance/provider/mod.rs +++ b/nym-api/src/node_performance/provider/mod.rs @@ -4,11 +4,11 @@ use crate::node_performance::provider::contract_provider::ContractPerformanceProvider; use async_trait::async_trait; use legacy_storage_provider::LegacyStoragePerformanceProvider; -use nym_api_requests::models::RoutingScore; +use nym_api_requests::models::{RoutingScore, StressTestingScore}; use nym_mixnet_contract_common::{EpochId, NodeId}; use std::collections::HashMap; use thiserror::Error; -use tracing::debug; +use tracing::{debug, error}; pub(crate) mod contract_provider; pub(crate) mod legacy_storage_provider; @@ -31,6 +31,41 @@ impl PerformanceRetrievalFailure { } } +pub(crate) struct NodesStressTestingScores { + inner: HashMap>, +} + +impl NodesStressTestingScores { + pub(crate) fn get_or_log(&self, node_id: NodeId) -> StressTestingScore { + match self.inner.get(&node_id) { + Some(Ok(score)) => *score, + Some(Err(err)) => { + debug!("{err}"); + StressTestingScore::unreachable() + } + None => StressTestingScore::unreachable(), + } + } + + /// Number of nodes for which the orchestrator has produced at least one reachable sample + /// in the configured window. Used by the refresher to gate whether stress-testing data is + /// applied at all: if the orchestrator is down or has not yet submitted anything, this + /// returns 0 and the refresher falls back to routing × config score only. + /// + /// Note: nodes that were tested but found unreachable (`was_reachable=false`) intentionally + /// do **not** count here. Counting them would let a single recently-rebooted orchestrator + /// pass the threshold while every node it touched still scored 0. + pub(crate) fn available_count(&self) -> usize { + self.inner + .iter() + .filter(|(_, v)| match v { + Ok(score) => score.was_reachable, + Err(_) => false, + }) + .count() + } +} + pub(crate) struct NodesRoutingScores { inner: HashMap>, } @@ -57,24 +92,39 @@ impl NodesRoutingScores { pub(crate) trait NodePerformanceProvider { /// Obtain a performance/routing score of a particular node for given epoch #[allow(unused)] - async fn get_node_score( + async fn get_node_routing_score( &self, node_id: NodeId, epoch_id: EpochId, ) -> Result; /// An optimisation for obtaining node scores of multiple nodes at once - async fn get_batch_node_scores( + async fn get_batch_node_routing_scores( &self, - node_ids: Vec, + node_ids: &[NodeId], epoch_id: EpochId, ) -> Result; + + /// Obtain a stress-testing score of a particular node for given epoch + #[allow(unused)] + async fn get_node_stress_testing_score( + &self, + node_id: NodeId, + epoch_id: EpochId, + ) -> Result; + + /// An optimisation for obtaining node scores of multiple nodes at once + async fn get_batch_node_stress_testing_scores( + &self, + node_ids: &[NodeId], + epoch_id: EpochId, + ) -> Result; } #[async_trait] impl NodePerformanceProvider for ContractPerformanceProvider { #[allow(unused)] - async fn get_node_score( + async fn get_node_routing_score( &self, node_id: NodeId, epoch_id: EpochId, @@ -82,19 +132,45 @@ impl NodePerformanceProvider for ContractPerformanceProvider { self.node_routing_score(node_id, epoch_id).await } - async fn get_batch_node_scores( + async fn get_batch_node_routing_scores( &self, - node_ids: Vec, + node_ids: &[NodeId], epoch_id: EpochId, ) -> Result { self.node_routing_scores(node_ids, epoch_id).await } + + async fn get_node_stress_testing_score( + &self, + node_id: NodeId, + epoch_id: EpochId, + ) -> Result { + error!("stress testing data not available in contract data"); + Err(PerformanceRetrievalFailure { + node_id, + epoch_id, + error: "stress testing data not available in contract data".to_string(), + }) + } + + async fn get_batch_node_stress_testing_scores( + &self, + _: &[NodeId], + epoch_id: EpochId, + ) -> Result { + error!("stress testing data not available in contract data"); + Err(PerformanceRetrievalFailure { + node_id: 0, + epoch_id, + error: "stress testing data not available in contract data".to_string(), + }) + } } #[async_trait] impl NodePerformanceProvider for LegacyStoragePerformanceProvider { #[allow(unused)] - async fn get_node_score( + async fn get_node_routing_score( &self, node_id: NodeId, epoch_id: EpochId, @@ -102,15 +178,15 @@ impl NodePerformanceProvider for LegacyStoragePerformanceProvider { self.node_routing_score(node_id, epoch_id).await } - async fn get_batch_node_scores( + async fn get_batch_node_routing_scores( &self, - node_ids: Vec, + node_ids: &[NodeId], epoch_id: EpochId, ) -> Result { let mut scores = HashMap::new(); - let epoch_timestamp = self.epoch_id_unix_timestamp(epoch_id).await?; - for node_id in node_ids { + let epoch_timestamp = self.epoch_id_timestamp(epoch_id).await?.unix_timestamp(); + for &node_id in node_ids { scores.insert( node_id, self.get_node_routing_score_with_unix_timestamp(node_id, epoch_id, epoch_timestamp) @@ -120,4 +196,22 @@ impl NodePerformanceProvider for LegacyStoragePerformanceProvider { Ok(NodesRoutingScores { inner: scores }) } + + #[allow(unused)] + async fn get_node_stress_testing_score( + &self, + node_id: NodeId, + epoch_id: EpochId, + ) -> Result { + self.node_stress_testing_score(node_id, epoch_id).await + } + + async fn get_batch_node_stress_testing_scores( + &self, + node_ids: &[NodeId], + epoch_id: EpochId, + ) -> Result { + self.get_node_stress_testing_scores(node_ids, epoch_id) + .await + } } diff --git a/nym-api/src/node_status_api/cache/data.rs b/nym-api/src/node_status_api/cache/data.rs index 0457d4c8c8..50a9deff97 100644 --- a/nym-api/src/node_status_api/cache/data.rs +++ b/nym-api/src/node_status_api/cache/data.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use nym_api_requests::models::NodeAnnotation; +use nym_api_requests::models::NodeAnnotationV2; use nym_mixnet_contract_common::NodeId; use serde::{Deserialize, Serialize}; use std::collections::HashMap; @@ -10,11 +10,11 @@ use std::collections::HashMap; #[allow(deprecated)] pub(crate) struct NodeStatusCacheData { /// Basic annotation for nym-nodes - pub(crate) node_annotations: HashMap, + pub(crate) node_annotations: HashMap, } -impl From> for NodeStatusCacheData { - fn from(node_annotations: HashMap) -> Self { +impl From> for NodeStatusCacheData { + fn from(node_annotations: HashMap) -> Self { NodeStatusCacheData { node_annotations } } } diff --git a/nym-api/src/node_status_api/cache/mod.rs b/nym-api/src/node_status_api/cache/mod.rs index 9a16762c32..9f41f176ef 100644 --- a/nym-api/src/node_status_api/cache/mod.rs +++ b/nym-api/src/node_status_api/cache/mod.rs @@ -5,7 +5,7 @@ use self::data::NodeStatusCacheData; use crate::node_performance::provider::PerformanceRetrievalFailure; use crate::support::caching::cache::{SharedCache, UninitialisedCache}; use crate::support::caching::Cache; -use nym_api_requests::models::NodeAnnotation; +use nym_api_requests::models::NodeAnnotationV2; use nym_mixnet_contract_common::NodeId; use std::collections::HashMap; use std::path::Path; @@ -73,7 +73,7 @@ impl NodeStatusCache { } /// Updates the cache with the latest data. - async fn update(&self, node_annotations: HashMap) { + async fn update(&self, node_annotations: HashMap) { if self .inner .try_overwrite_old_value(node_annotations, "node-status") @@ -100,7 +100,7 @@ impl NodeStatusCache { pub(crate) async fn node_annotations( &self, - ) -> Result>, UninitialisedCache> { + ) -> Result>, UninitialisedCache> { self.get(|c| &c.node_annotations).await } } diff --git a/nym-api/src/node_status_api/cache/refresher.rs b/nym-api/src/node_status_api/cache/refresher.rs index bf5d0033c5..8b56a9ffb1 100644 --- a/nym-api/src/node_status_api/cache/refresher.rs +++ b/nym-api/src/node_status_api/cache/refresher.rs @@ -4,32 +4,52 @@ use super::NodeStatusCache; use crate::mixnet_contract_cache::cache::data::ConfigScoreData; use crate::node_describe_cache::cache::DescribedNodes; -use crate::node_performance::provider::{NodePerformanceProvider, NodesRoutingScores}; +use crate::node_performance::provider::{ + NodePerformanceProvider, NodesRoutingScores, NodesStressTestingScores, +}; use crate::node_status_api::cache::config_score::calculate_config_score; -use crate::node_status_api::models::Uptime; use crate::support::caching::cache::SharedCache; use crate::support::caching::refresher::RefreshRequester; +use crate::support::caching::CacheNotificationWatcher; use crate::{ mixnet_contract_cache::cache::MixnetContractCache, node_status_api::cache::NodeStatusCacheError, support::caching::CacheNotification, }; use ::time::OffsetDateTime; -use nym_api_requests::models::{DetailedNodePerformance, NodeAnnotation}; +use nym_api_requests::models::{DetailedNodePerformanceV2, NodeAnnotationV2}; use nym_mixnet_contract_common::{NodeId, NymNodeDetails}; use nym_task::ShutdownToken; use nym_topology::CachedEpochRewardedSet; use std::collections::HashMap; use std::path::PathBuf; use std::time::Duration; -use tokio::sync::watch; use tokio::time; use tracing::{error, info, trace, warn}; +pub(crate) struct NodeStatusCacheConfig { + pub(crate) fallback_caching_interval: Duration, + + /// Specify whether external stress testing data should be used for calculating node performance + /// score used for rewarding and active set selection + /// note: this can only be enabled if use_performance_contract_data is set to false! + pub use_stress_testing_data: bool, + + /// If `use_stress_testing_data` is set to true, this specifies the minimum % of nodes, + /// that must have their stress data available in the `stress_testing_data_period`, + /// in order to include that metric in performance calculation. + /// This is done to protect against Network Monitor failures and not receiving any data. + pub minimum_available_stress_testing_results: f32, + + /// If use_stress_testing_data is enabled, specifies the weight of the stress testing score in the overall performance score. + pub stress_testing_score_weight: f64, +} + // Long running task responsible for keeping the node status cache up-to-date. pub struct NodeStatusCacheRefresher { + config: NodeStatusCacheConfig, + // Main stored data cache: NodeStatusCache, - fallback_caching_interval: Duration, // Sources for when refreshing data mixnet_contract_cache: MixnetContractCache, @@ -37,11 +57,11 @@ pub struct NodeStatusCacheRefresher { /// channel notifying us when mixnet cache has been refreshed, /// so that this cache could also be recreated - mixnet_contract_cache_listener: watch::Receiver, + mixnet_contract_cache_listener: CacheNotificationWatcher, /// channel notifying us when the describe cache has been refreshed, /// so that this cache could also be recreated - describe_cache_listener: watch::Receiver, + describe_cache_listener: CacheNotificationWatcher, /// channel explicitly requesting cache refresh. it does not follow the usual rate limiting refresh_requester: RefreshRequester, @@ -57,17 +77,17 @@ impl NodeStatusCacheRefresher { #[allow(clippy::too_many_arguments)] pub(crate) fn new( cache: NodeStatusCache, - fallback_caching_interval: Duration, + config: NodeStatusCacheConfig, contract_cache: MixnetContractCache, described_cache: SharedCache, - contract_cache_listener: watch::Receiver, - describe_cache_listener: watch::Receiver, + contract_cache_listener: CacheNotificationWatcher, + describe_cache_listener: CacheNotificationWatcher, performance_provider: Box, on_disk_file: PathBuf, ) -> Self { Self { cache, - fallback_caching_interval, + config, mixnet_contract_cache: contract_cache, described_cache, mixnet_contract_cache_listener: contract_cache_listener, @@ -85,7 +105,7 @@ impl NodeStatusCacheRefresher { /// Runs the node status cache refresher task. pub async fn run(&mut self, shutdown_token: ShutdownToken) { let mut last_update = OffsetDateTime::now_utc(); - let mut fallback_interval = time::interval(self.fallback_caching_interval); + let mut fallback_interval = time::interval(self.config.fallback_caching_interval); loop { tokio::select! { biased; @@ -171,7 +191,7 @@ impl NodeStatusCacheRefresher { return; } - if OffsetDateTime::now_utc() - *last_updated < self.fallback_caching_interval { + if OffsetDateTime::now_utc() - *last_updated < self.config.fallback_caching_interval { // don't update too often trace!("not updating the cache since they've been updated recently"); return; @@ -186,32 +206,65 @@ impl NodeStatusCacheRefresher { &self, config_score_data: &ConfigScoreData, routing_scores: &NodesRoutingScores, + stress_testing_scores: &NodesStressTestingScores, nym_nodes: &[NymNodeDetails], rewarded_set: &CachedEpochRewardedSet, described_nodes: &DescribedNodes, - ) -> HashMap { + ) -> HashMap { let mut annotations = HashMap::new(); + if nym_nodes.is_empty() { + return annotations; + } + + let use_stress_testing_scores = self.config.use_stress_testing_data; + let threshold = self.config.minimum_available_stress_testing_results; + let available_ratio = + stress_testing_scores.available_count() as f32 / nym_nodes.len() as f32; + + // Guard against an orchestrator outage silently slashing every node's performance: + // if too few nodes have a reachable stress-test sample for the configured window we + // assume the orchestrator (rather than the network) is at fault and fall back to the + // routing × config score alone. The threshold is a network-wide ratio, not per-node — + // once it is met, individual nodes without data still score 0 in the weighted formula + // by design, on the assumption that the orchestrator tried to test them and failed. + let include_stress_testing = use_stress_testing_scores && available_ratio >= threshold; + + if use_stress_testing_scores && !include_stress_testing { + info!( + "not using stress testing data for performance calculation: \ + available ratio {available_ratio:.3} is below threshold {threshold:.3}" + ); + } + + // stress testing + let sw = self.config.stress_testing_score_weight; + + // not stress testing + let nsw = 1.0 - sw; for nym_node in nym_nodes { let node_id = nym_node.node_id(); let routing_score = routing_scores.get_or_log(node_id); let config_score = calculate_config_score(config_score_data, described_nodes.get_node(&node_id)); + let stress_testing_score = stress_testing_scores.get_or_log(node_id); - let performance = routing_score.score * config_score.score; - // map it from 0-1 range into 0-100 - let scaled_performance = performance * 100.; - let legacy_performance = Uptime::new(scaled_performance as f32).into(); + let performance = if include_stress_testing { + // use weighted arithmetic mean (we don't want a single 0 to cause the whole thing to be 0) + sw * stress_testing_score.score + nsw * routing_score.score * config_score.score + } else { + routing_score.score * config_score.score + }; annotations.insert( nym_node.node_id(), - NodeAnnotation { - last_24h_performance: legacy_performance, + NodeAnnotationV2 { current_role: rewarded_set.role(nym_node.node_id()).map(|r| r.into()), - detailed_performance: DetailedNodePerformance::new( + detailed_performance: DetailedNodePerformanceV2::new( performance, routing_score, config_score, + stress_testing_score, ), }, ); @@ -238,12 +291,20 @@ impl NodeStatusCacheRefresher { let all_ids = nym_nodes .iter() .map(|n| n.bond_information.node_id) - .collect(); + .collect::>(); // note: any internal errors imply failures for that node in particular let routing_scores = self .performance_provider - .get_batch_node_scores(all_ids, current_interval.current_epoch_absolute_id()) + .get_batch_node_routing_scores(&all_ids, current_interval.current_epoch_absolute_id()) + .await?; + + let stress_testing_scores = self + .performance_provider + .get_batch_node_stress_testing_scores( + &all_ids, + current_interval.current_epoch_absolute_id(), + ) .await?; // Create annotated data @@ -251,6 +312,7 @@ impl NodeStatusCacheRefresher { .produce_node_annotations( &config_score_data, &routing_scores, + &stress_testing_scores, &nym_nodes, &rewarded_set, &described, diff --git a/nym-api/src/node_status_api/handlers/without_monitor.rs b/nym-api/src/node_status_api/handlers/without_monitor.rs index 08d8b7c9da..882be3b403 100644 --- a/nym-api/src/node_status_api/handlers/without_monitor.rs +++ b/nym-api/src/node_status_api/handlers/without_monitor.rs @@ -10,6 +10,7 @@ use axum::Router; use nym_types::monitoring::MonitorMessage; use tracing::error; +#[allow(deprecated)] pub(super) fn mandatory_routes() -> Router { Router::new() .route( @@ -33,6 +34,7 @@ pub(super) fn mandatory_routes() -> Router { (status = 500, body = String, description = "TBD"), ), )] +#[deprecated] pub(crate) async fn submit_gateway_monitoring_results( State(state): State, Json(message): Json, @@ -77,6 +79,7 @@ pub(crate) async fn submit_gateway_monitoring_results( (status = 500, body = String, description = "TBD"), ), )] +#[deprecated] pub(crate) async fn submit_node_monitoring_results( State(state): State, Json(message): Json, diff --git a/nym-api/src/node_status_api/mod.rs b/nym-api/src/node_status_api/mod.rs index afd8265e35..00bb136e8c 100644 --- a/nym-api/src/node_status_api/mod.rs +++ b/nym-api/src/node_status_api/mod.rs @@ -4,6 +4,7 @@ use self::cache::refresher::NodeStatusCacheRefresher; use crate::node_describe_cache::cache::DescribedNodes; use crate::node_performance::provider::NodePerformanceProvider; +use crate::node_status_api::cache::refresher::NodeStatusCacheConfig; use crate::support::caching::cache::SharedCache; use crate::support::caching::refresher::RefreshRequester; use crate::support::config; @@ -34,7 +35,7 @@ pub(crate) const ONE_DAY: Duration = Duration::from_secs(86400); /// caching interval that is twice the nym contract cache #[allow(clippy::too_many_arguments)] pub(crate) fn start_cache_refresh( - config: &config::NodeStatusAPI, + config: &config::Config, nym_contract_cache_state: &MixnetContractCache, described_cache: &SharedCache, node_status_cache_state: &NodeStatusCache, @@ -44,9 +45,22 @@ pub(crate) fn start_cache_refresh( on_disk_file: PathBuf, shutdown_manager: &ShutdownManager, ) -> RefreshRequester { + let config = NodeStatusCacheConfig { + fallback_caching_interval: config.node_status_api.debug.caching_interval, + use_stress_testing_data: config.performance_provider.debug.use_stress_testing_data, + minimum_available_stress_testing_results: config + .performance_provider + .debug + .minimum_available_stress_testing_results, + stress_testing_score_weight: config + .performance_provider + .debug + .stress_testing_score_weight, + }; + let mut nym_api_cache_refresher = NodeStatusCacheRefresher::new( node_status_cache_state.to_owned(), - config.debug.caching_interval, + config, nym_contract_cache_state.to_owned(), described_cache.clone(), nym_contract_cache_listener, diff --git a/nym-api/src/nym_nodes/handlers/mod.rs b/nym-api/src/nym_nodes/handlers/mod.rs index d242f328cf..38954f43e7 100644 --- a/nym-api/src/nym_nodes/handlers/mod.rs +++ b/nym-api/src/nym_nodes/handlers/mod.rs @@ -3,3 +3,4 @@ pub mod v1; pub mod v2; +pub mod v3; diff --git a/nym-api/src/nym_nodes/handlers/v1.rs b/nym-api/src/nym_nodes/handlers/v1.rs index ce004731ed..e1513eeb68 100644 --- a/nym-api/src/nym_nodes/handlers/v1.rs +++ b/nym-api/src/nym_nodes/handlers/v1.rs @@ -8,7 +8,7 @@ use axum::extract::{Path, Query, State}; use axum::routing::{get, post}; use axum::{Json, Router}; use nym_api_requests::models::{ - AnnotationResponse, NodeDatePerformanceResponse, NodePerformanceResponse, NodeRefreshBody, + AnnotationResponseV1, NodeDatePerformanceResponse, NodePerformanceResponse, NodeRefreshBody, NoiseDetails, NymNodeDescriptionV1, PerformanceHistoryResponse, RewardedSetResponse, StakeSaturationResponse, UptimeHistoryResponse, }; @@ -265,9 +265,9 @@ async fn get_described_nodes( context_path = "/v1/nym-nodes", responses( (status = 200, content( - (AnnotationResponse = "application/json"), - (AnnotationResponse = "application/yaml"), - (AnnotationResponse = "application/bincode") + (AnnotationResponseV1 = "application/json"), + (AnnotationResponseV1 = "application/yaml"), + (AnnotationResponseV1 = "application/bincode") )) ), params(NodeIdParam, OutputParams), @@ -276,14 +276,14 @@ async fn get_node_annotation( Path(NodeIdParam { node_id }): Path, Query(output): Query, State(state): State, -) -> AxumResult> { +) -> AxumResult> { let output = output.output.unwrap_or_default(); let annotations = state.node_status_cache().node_annotations().await?; - Ok(output.to_response(AnnotationResponse { + Ok(output.to_response(AnnotationResponseV1 { node_id, - annotation: annotations.get(&node_id).cloned(), + annotation: annotations.get(&node_id).cloned().map(Into::into), })) } @@ -314,7 +314,7 @@ async fn get_current_node_performance( node_id, performance: annotations .get(&node_id) - .map(|n| n.last_24h_performance.naive_to_f64()), + .map(|n| n.detailed_performance.performance_score), })) } diff --git a/nym-api/src/nym_nodes/handlers/v2.rs b/nym-api/src/nym_nodes/handlers/v2.rs index ee49e575fa..75f60d1316 100644 --- a/nym-api/src/nym_nodes/handlers/v2.rs +++ b/nym-api/src/nym_nodes/handlers/v2.rs @@ -2,19 +2,20 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::node_status_api::models::AxumResult; -use crate::support::http::helpers::PaginationRequest; +use crate::support::http::helpers::{NodeIdParam, PaginationRequest}; use crate::support::http::state::AppState; -use axum::extract::{Query, State}; +use axum::extract::{Path, Query, State}; use axum::routing::get; use axum::Router; -use nym_api_requests::models::NymNodeDescriptionV2; +use nym_api_requests::models::{AnnotationResponseV2, NymNodeDescriptionV2}; use nym_api_requests::pagination::{PaginatedResponse, Pagination}; -use nym_http_api_common::FormattedResponse; +use nym_http_api_common::{FormattedResponse, OutputParams}; use tower_http::compression::CompressionLayer; pub(crate) fn routes() -> Router { Router::new() .route("/described", get(get_described_nodes)) + .route("/annotation/:node_id", get(get_node_annotation)) .layer(CompressionLayer::new()) } @@ -52,3 +53,30 @@ async fn get_described_nodes( data: descriptions, })) } + +#[utoipa::path( + tag = "Nym Nodes", + get, + path = "/annotation/{node_id}", + context_path = "/v2/nym-nodes", + responses( + (status = 200, content( + (AnnotationResponseV2 = "application/json"), + (AnnotationResponseV2 = "application/yaml"), + (AnnotationResponseV2 = "application/bincode") + )) + ), + params(NodeIdParam, OutputParams), +)] +async fn get_node_annotation( + Path(NodeIdParam { node_id }): Path, + Query(output): Query, + State(state): State, +) -> AxumResult> { + let annotations = state.node_status_cache().node_annotations().await?; + + Ok(output.get_output().to_response(AnnotationResponseV2 { + node_id, + annotation: annotations.get(&node_id).cloned(), + })) +} diff --git a/nym-api/src/nym_nodes/handlers/v3.rs b/nym-api/src/nym_nodes/handlers/v3.rs new file mode 100644 index 0000000000..20dbfe9bdc --- /dev/null +++ b/nym-api/src/nym_nodes/handlers/v3.rs @@ -0,0 +1,178 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::node_status_api::models::{ApiResult, AxumErrorResponse}; +use crate::support::http::state::AppState; +use crate::support::storage::models::NymNodeStressTestingResult; +use axum::extract::{Path, State}; +use axum::routing::{get, post}; +use axum::{Json, Router}; +use nym_api_requests::models::network_monitor::KnownNetworkMonitorResponse; +use nym_api_requests::models::{StressTestBatchSubmission, StressTestBatchSubmissionResponse}; +use nym_crypto::asymmetric::ed25519; +use std::time::Duration; +use time::OffsetDateTime; +use tracing::error; + +/// Accept a batch of stress-test results from an authorised network monitor orchestrator. +/// +/// The batch is rejected unless all of the following hold: +/// - the submission timestamp is within a short staleness window of the current time, +/// - the signer's key is currently registered in the network-monitors contract, +/// - the submission timestamp is strictly greater than the signer's previous accepted submission +/// (timestamp-based replay protection, so orchestrators don't need to keep a nonce counter), +/// - the signature on the body verifies against the signer's key. +/// +/// Individual result entries that fail per-entry validation (non-mixnode role, performance score +/// outside `[0.0, 1.0]`) are logged as errors and dropped, but do not fail the batch. +#[utoipa::path( + tag = "Nym Nodes", + post, + path = "/stress-testing/batch-submit", + context_path = "/v3/nym-nodes", + responses( + (status = 200, description = "the submitted batch has been accepted and stored"), + (status = 400, description = "the submitted request is stale or replayed"), + (status = 401, description = "the submitted request was unauthorised or failed integrity check"), + ), +)] +async fn batch_submit_stress_testing_results( + State(state): State, + Json(body): Json, +) -> ApiResult> { + // 1. check if the request is not stale + // TODO: make the timeout configurable. currently we have an issue of no easy way of + // propagating config values, but hardcoding it to 30s is fine for now + if body.body.is_stale(Duration::from_secs(30)) { + return Err(AxumErrorResponse::bad_request( + "request is stale, please resubmit it with a fresh timestamp", + )); + } + + // 2. check if the sent public key is even in the authorised set + if !state + .network_monitors() + .is_authorised(&state.nyxd_client, &body.body.signer) + .await? + { + return Err(AxumErrorResponse::unauthorised( + "the provided public key does not correspond to any known network monitor", + )); + } + + // 3. check if the request is not replayed (i.e. timestamp is not smaller than the latest known submission) + let last_request = state + .network_monitor_submissions + .submitted(body.body.signer) + .await; + + // if we have no known requests, we might have just restarted + // so we use the time of when we came back online - it's impossible there were any other requests since then + let last_known = match last_request { + Some(last) => last, + None => { + let uptime = state.api_status.uptime(); + OffsetDateTime::now_utc() - uptime + } + }; + + if body.body.timestamp <= last_known { + return Err(AxumErrorResponse::bad_request( + "each request must have an explicitly greater timestamp than the previous one", + )); + } + + // 4. verify the signature on the request + if !body.verify_signature(&body.body.signer) { + return Err(AxumErrorResponse::unauthorised( + "the provided request failed integrity check", + )); + } + + // 5. update the latest submission timestamp + state + .network_monitor_submissions + .set_submitted(body.body.signer, body.body.timestamp) + .await; + + // 6. process received results + let signer = body.body.signer; + let mut mixnode_results = Vec::with_capacity(body.body.results.len()); + for result in body.body.results { + if !result.is_mixnode { + error!( + %signer, + node_id = result.node_id, + "received a stress testing result for a non-mixnode entry which should never happen - is the nym-api outdated?" + ); + continue; + } + if !(0.0..=1.0).contains(&result.test_performance) { + error!( + %signer, + node_id = result.node_id, + test_performance = result.test_performance, + "received a stress testing result with performance outside the [0, 1] range - is the monitor misconfigured?" + ); + continue; + } + mixnode_results.push(NymNodeStressTestingResult::from_submission(&signer, result)); + } + + state + .storage() + .insert_nym_node_stress_testing_results(mixnode_results) + .await?; + + Ok(Json(StressTestBatchSubmissionResponse {})) +} + +/// Report whether the given identity key is currently recognised by this nym-api as an +/// authorised network monitor orchestrator. +/// +/// Intended for orchestrators to self-check after (re)announcing their key on-chain - a +/// successful response with `authorised: true` means this nym-api has picked up the chain change +/// and is ready to accept stress-test submissions signed by that key. +#[utoipa::path( + tag = "Nym Nodes", + get, + path = "/stress-testing/known-monitors/{identity_key}", + context_path = "/v3/nym-nodes", + params( + ("identity_key" = String, Path, description = "base58-encoded ed25519 identity key of the queried network monitor"), + ), + responses( + (status = 200, body = KnownNetworkMonitorResponse), + (status = 400, description = "the provided identity key is not a valid base58-encoded ed25519 public key"), + ), +)] +async fn known_network_monitor( + Path(identity_key): Path, + State(state): State, +) -> ApiResult> { + let identity_key = ed25519::PublicKey::from_base58_string(&identity_key) + .map_err(|err| AxumErrorResponse::bad_request(format!("malformed identity key: {err}")))?; + + let known = state + .network_monitors() + .get_or_refresh(&state.nyxd_client) + .await?; + + let authorised = known.contains(&identity_key); + + Ok(Json(KnownNetworkMonitorResponse { + identity_key, + authorised, + })) +} + +fn stress_testing_routes() -> Router { + Router::new() + .route("/batch-submit", post(batch_submit_stress_testing_results)) + .route("/known-monitors/:identity_key", get(known_network_monitor)) +} + +/// Build the `/v3/nym-nodes` subtree hosting the v3 network-monitor endpoints. +pub(crate) fn routes() -> Router { + Router::new().nest("/stress-testing", stress_testing_routes()) +} diff --git a/nym-api/src/status/mod.rs b/nym-api/src/status/mod.rs index f7ff611d6d..2abb636267 100644 --- a/nym-api/src/status/mod.rs +++ b/nym-api/src/status/mod.rs @@ -6,6 +6,7 @@ use nym_bin_common::bin_info; use nym_bin_common::build_information::BinaryBuildInformation; use std::ops::Deref; use std::sync::Arc; +use std::time::Duration; use tokio::time::Instant; pub(crate) mod handlers; @@ -15,6 +16,12 @@ pub(crate) struct ApiStatusState { inner: Arc, } +impl ApiStatusState { + pub(crate) fn uptime(&self) -> Duration { + self.inner.startup_time.elapsed() + } +} + impl Deref for ApiStatusState { type Target = ApiStatusStateInner; fn deref(&self) -> &Self::Target { diff --git a/nym-api/src/support/caching/mod.rs b/nym-api/src/support/caching/mod.rs index babc6375d1..93682d3665 100644 --- a/nym-api/src/support/caching/mod.rs +++ b/nym-api/src/support/caching/mod.rs @@ -4,6 +4,8 @@ pub(crate) mod cache; pub(crate) mod refresher; +use tokio::sync::watch; + // don't break existing imports pub(crate) use cache::Cache; @@ -13,3 +15,5 @@ pub enum CacheNotification { Start, Updated, } + +pub type CacheNotificationWatcher = watch::Receiver; diff --git a/nym-api/src/support/cli/run.rs b/nym-api/src/support/cli/run.rs index 2a120cc6fd..250e6bc000 100644 --- a/nym-api/src/support/cli/run.rs +++ b/nym-api/src/support/cli/run.rs @@ -27,6 +27,7 @@ use crate::support::http::state::chain_status::ChainStatusCache; use crate::support::http::state::contract_details::ContractDetailsCache; use crate::support::http::state::force_refresh::ForcedRefresh; use crate::support::http::state::mixnet_contract_cache::MixnetContractCacheState; +use crate::support::http::state::network_monitors::{LastNMSubmissions, NetworkMonitorsCache}; use crate::support::http::state::node_annotations_cache::NodeAnnotationsCache; use crate::support::http::state::AppState; use crate::support::http::{RouterBuilder, TASK_MANAGER_TIMEOUT_S}; @@ -297,6 +298,7 @@ async fn start_nym_api_tasks(mut config: Config) -> anyhow::Result anyhow::Result anyhow::Result/config` @@ -104,7 +111,7 @@ pub fn default_data_directory>(id: P) -> PathBuf { .join(DEFAULT_DATA_DIR) } -#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] +#[derive(Debug, Deserialize, PartialEq, Serialize)] pub struct Config { // additional metadata holding on-disk location of this config file #[serde(skip)] @@ -130,6 +137,9 @@ pub struct Config { #[serde(default)] pub contracts_info_cache: ContractsInfoCache, + #[serde(default)] + pub network_monitors_cache: NetworkMonitorsCache, + pub rewarding: Rewarding, #[serde(default)] @@ -159,6 +169,7 @@ impl Config { node_status_api: NodeStatusAPI::new_default(id.as_ref()), describe_cache: Default::default(), contracts_info_cache: Default::default(), + network_monitors_cache: Default::default(), rewarding: Default::default(), signers_cache: Default::default(), ecash_signer: EcashSigner::new_default(id.as_ref()), @@ -183,6 +194,15 @@ impl Config { NymApiPaths::new_default(&self.base.id).persistent_cache_directory; } + if self.performance_provider.debug.use_stress_testing_data + && self.performance_provider.use_performance_contract_data + { + bail!( + "[performance_provider.debug].use_stress_testing_data cannot be enabled while \ + [performance_provider].use_performance_contract_data is also enabled" + ) + } + self.ecash_signer.validate()?; Ok(()) @@ -359,6 +379,24 @@ impl Default for ContractsInfoCache { } } +/// Configuration for the in-memory cache of authorised network-monitor orchestrators. +/// +/// Controls how often nym-api re-queries the network-monitors contract for the authorised set; +/// a new orchestrator registering on-chain will not be recognised for submissions until the next +/// refresh triggered by this TTL. +#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] +pub struct NetworkMonitorsCache { + pub time_to_live: Duration, +} + +impl Default for NetworkMonitorsCache { + fn default() -> Self { + NetworkMonitorsCache { + time_to_live: DEFAULT_NETWORK_MONITORS_CACHE_TTL, + } + } +} + #[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] pub struct MixnetContractCache { #[serde(default)] @@ -389,7 +427,7 @@ impl Default for MixnetContractCacheDebug { } } -#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] +#[derive(Debug, Deserialize, PartialEq, Serialize)] pub struct PerformanceProvider { /// Specifies whether this nym-api should attempt to retrieve node performance /// information from the performance contract. @@ -409,7 +447,7 @@ impl Default for PerformanceProvider { } } -#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] +#[derive(Debug, Deserialize, PartialEq, Serialize)] pub struct PerformanceProviderDebug { /// Specifies interval of polling the performance contract. Note it is only applicable /// if the contract data is being used. @@ -425,6 +463,26 @@ pub struct PerformanceProviderDebug { /// Specify the maximum number of epoch entries to be kept in the cache in case we needed non-current data // (currently we need an equivalent of full day worth of data for legacy endpoints) pub max_epoch_entries_to_retain: usize, + + // this is semi-temporary. in the long-run this information will be stored in a smart contract + // and the nym-api will have no influence over its usage + /// Specify whether external stress testing data should be used for calculating node performance + /// score used for rewarding and active set selection + /// note: this can only be enabled if use_performance_contract_data is set to false! + pub use_stress_testing_data: bool, + + /// If `use_stress_testing_data` is set to true, this specifies the minimum % of nodes, + /// that must have their stress data available in the `stress_testing_data_period`, + /// in order to include that metric in performance calculation. + /// This is done to protect against Network Monitor failures and not receiving any data. + pub minimum_available_stress_testing_results: f32, + + /// If use_stress_testing_data is enabled, specifies the weight of the stress testing score in the overall performance score. + pub stress_testing_score_weight: f64, + + /// Specifies the duration of the rolling average used for stress testing score. + #[serde(with = "humantime_serde")] + pub stress_testing_data_period: Duration, } #[allow(clippy::derivable_impls)] @@ -434,6 +492,12 @@ impl Default for PerformanceProviderDebug { contract_polling_interval: DEFAULT_PERFORMANCE_CONTRACT_POLLING_INTERVAL, max_performance_fallback_epochs: DEFAULT_PERFORMANCE_CONTRACT_FALLBACK_EPOCHS, max_epoch_entries_to_retain: DEFAULT_PERFORMANCE_CONTRACT_RETAINED_EPOCHS, + + // set this to true once sufficient number of nodes are being tested + use_stress_testing_data: false, + minimum_available_stress_testing_results: DEFAULT_MIN_STRESS_TESTED_NODES, + stress_testing_score_weight: DEFAULT_STRESS_TESTING_SCORE_WEIGHT, + stress_testing_data_period: DEFAULT_MIN_STRESS_TESTING_DATA_INTERVAL, } } } @@ -657,7 +721,7 @@ impl Default for DescribeCacheDebug { } } -#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] +#[derive(Debug, Deserialize, PartialEq, Serialize)] #[serde(default)] pub struct Rewarding { /// Specifies whether rewarding service is enabled in this process. @@ -679,7 +743,7 @@ impl Default for Rewarding { } } -#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] +#[derive(Debug, Deserialize, PartialEq, Serialize)] #[serde(default)] pub struct RewardingDebug { /// Specifies the minimum percentage of monitor test run data present in order to diff --git a/nym-api/src/support/config/template.rs b/nym-api/src/support/config/template.rs index 7b19567caa..7e038c1aa3 100644 --- a/nym-api/src/support/config/template.rs +++ b/nym-api/src/support/config/template.rs @@ -79,6 +79,29 @@ per_node_test_packets = {{ network_monitor.debug.per_node_test_packets }} # Path to the database file containing uptime statuses for all mixnodes and gateways. database_path = '{{ node_status_api.storage_paths.database_path }}' + +##### performance provider config options ##### +[performance_provider] + +# Specifies whether this nym-api should attempt to retrieve node performance +# information from the performance contract. +use_performance_contract_data = {{ performance_provider.use_performance_contract_data }} + +[performance_provider.debug] +# Specify whether external stress testing data should be used for calculating node performance +# score used for rewarding and active set selection +# note: this can only be enabled if use_performance_contract_data is set to false! +use_stress_testing_data = {{ performance_provider.debug.use_stress_testing_data }} + +# If `use_stress_testing_data` is set to true, this specifies the minimum % of nodes, +# that must have their stress data available in the `stress_testing_data_period`, +# in order to include that metric in performance calculation. +# This is done to protect against Network Monitor failures and not receiving any data. +minimum_available_stress_testing_results = {{ performance_provider.debug.minimum_available_stress_testing_results }} + +# Specifies the duration of the rolling average used for stress testing score. +stress_testing_data_period = '{{ performance_provider.debug.stress_testing_data_period }}' + ##### rewarding config options ##### [rewarding] @@ -93,6 +116,7 @@ enabled = {{ rewarding.enabled }} # Note, only values in range 0-100 are valid minimum_interval_monitor_threshold = {{ rewarding.debug.minimum_interval_monitor_threshold }} + [ecash_signer] # Specifies whether ecash signing protocol is enabled in this process. diff --git a/nym-api/src/support/http/router.rs b/nym-api/src/support/http/router.rs index 00ab46c8af..7053bc6200 100644 --- a/nym-api/src/support/http/router.rs +++ b/nym-api/src/support/http/router.rs @@ -68,7 +68,9 @@ impl RouterBuilder { } fn v3_routes() -> Router { - Router::new().nest("/unstable", unstable_routes_v3()) + Router::new() + .nest("/nym-nodes", nym_nodes::handlers::v3::routes()) + .nest("/unstable", unstable_routes_v3()) } /// All routes should be, if possible, added here. Exceptions are e.g. diff --git a/nym-api/src/support/http/state/contract_details.rs b/nym-api/src/support/http/state/contract_details.rs index 5380a92809..a776746120 100644 --- a/nym-api/src/support/http/state/contract_details.rs +++ b/nym-api/src/support/http/state/contract_details.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::node_status_api::models::AxumErrorResponse; +use crate::support::http::state::helpers::ChainSharedCacheWithTtl; use crate::support::nyxd::Client; use nym_contracts_common::ContractBuildInformation; use nym_validator_client::nyxd::contract_traits::{ @@ -10,10 +11,7 @@ use nym_validator_client::nyxd::contract_traits::{ use nym_validator_client::nyxd::error::NyxdError; use nym_validator_client::nyxd::AccountId; use std::collections::HashMap; -use std::sync::Arc; use std::time::Duration; -use time::OffsetDateTime; -use tokio::sync::RwLock; type ContractAddress = String; @@ -41,142 +39,83 @@ impl CachedContractInfo { } #[derive(Clone)] -pub(crate) struct ContractDetailsCache { - cache_ttl: Duration, - inner: Arc>, +pub(crate) struct ContractDetailsCache(ChainSharedCacheWithTtl); + +async fn refresh(nyxd_client: &Client) -> Result { + use crate::query_guard; + + let mut updated = HashMap::new(); + + let client_guard = nyxd_client.read().await; + + let mixnet = query_guard!(client_guard, mixnet_contract_address()); + let vesting = query_guard!(client_guard, vesting_contract_address()); + let coconut_dkg = query_guard!(client_guard, dkg_contract_address()); + let group = query_guard!(client_guard, group_contract_address()); + let multisig = query_guard!(client_guard, multisig_contract_address()); + let ecash = query_guard!(client_guard, ecash_contract_address()); + let performance = query_guard!(client_guard, performance_contract_address()); + let network_monitors = query_guard!(client_guard, network_monitors_contract_address()); + + for (address, name) in [ + (mixnet, "nym-mixnet-contract"), + (vesting, "nym-vesting-contract"), + (coconut_dkg, "nym-coconut-dkg-contract"), + (group, "nym-cw4-group-contract"), + (multisig, "nym-cw3-multisig-contract"), + (ecash, "nym-ecash-contract"), + (performance, "nym-performance-contract"), + (network_monitors, "nym-network-monitors-contract"), + ] { + let (cw2, build_info) = if let Some(address) = address { + let cw2 = query_guard!(client_guard, try_get_cw2_contract_version(address).await); + let mut build_info = query_guard!( + client_guard, + try_get_contract_build_information(address).await + ); + + // for backwards compatibility until we migrate the contracts + if build_info.is_none() { + match name { + "nym-mixnet-contract" => { + build_info = Some(query_guard!( + client_guard, + get_mixnet_contract_version().await + )?) + } + "nym-vesting-contract" => { + build_info = Some(query_guard!( + client_guard, + get_vesting_contract_version().await + )?) + } + _ => (), + } + } + + (cw2, build_info) + } else { + (None, None) + }; + + updated.insert( + name.to_string(), + CachedContractInfo::new(address, cw2, build_info), + ); + } + + Ok(updated) } impl ContractDetailsCache { pub(crate) fn new(cache_ttl: Duration) -> Self { - ContractDetailsCache { - cache_ttl, - inner: Arc::new(RwLock::new(ContractDetailsCacheInner::new())), - } - } -} - -struct ContractDetailsCacheInner { - last_refreshed_at: OffsetDateTime, - cache_value: CachedContractsInfo, -} - -impl ContractDetailsCacheInner { - pub(crate) fn new() -> Self { - ContractDetailsCacheInner { - last_refreshed_at: OffsetDateTime::UNIX_EPOCH, - cache_value: Default::default(), - } + ContractDetailsCache(ChainSharedCacheWithTtl::new(cache_ttl)) } - fn is_valid(&self, ttl: Duration) -> bool { - if self.last_refreshed_at + ttl > OffsetDateTime::now_utc() { - return true; - } - false - } - - async fn retrieve_nym_contracts_info( - &self, - nyxd_client: &Client, - ) -> Result { - use crate::query_guard; - - let mut updated = HashMap::new(); - - let client_guard = nyxd_client.read().await; - - let mixnet = query_guard!(client_guard, mixnet_contract_address()); - let vesting = query_guard!(client_guard, vesting_contract_address()); - let coconut_dkg = query_guard!(client_guard, dkg_contract_address()); - let group = query_guard!(client_guard, group_contract_address()); - let multisig = query_guard!(client_guard, multisig_contract_address()); - let ecash = query_guard!(client_guard, ecash_contract_address()); - let performance = query_guard!(client_guard, performance_contract_address()); - - for (address, name) in [ - (mixnet, "nym-mixnet-contract"), - (vesting, "nym-vesting-contract"), - (coconut_dkg, "nym-coconut-dkg-contract"), - (group, "nym-cw4-group-contract"), - (multisig, "nym-cw3-multisig-contract"), - (ecash, "nym-ecash-contract"), - (performance, "nym-performance-contract"), - ] { - let (cw2, build_info) = if let Some(address) = address { - let cw2 = query_guard!(client_guard, try_get_cw2_contract_version(address).await); - let mut build_info = query_guard!( - client_guard, - try_get_contract_build_information(address).await - ); - - // for backwards compatibility until we migrate the contracts - if build_info.is_none() { - match name { - "nym-mixnet-contract" => { - build_info = Some(query_guard!( - client_guard, - get_mixnet_contract_version().await - )?) - } - "nym-vesting-contract" => { - build_info = Some(query_guard!( - client_guard, - get_vesting_contract_version().await - )?) - } - _ => (), - } - } - - (cw2, build_info) - } else { - (None, None) - }; - - updated.insert( - name.to_string(), - CachedContractInfo::new(address, cw2, build_info), - ); - } - - Ok(updated) - } -} - -impl ContractDetailsCache { pub(crate) async fn get_or_refresh( &self, client: &Client, ) -> Result { - if let Some(cached) = self.check_cache().await { - return Ok(cached); - } - - self.refresh(client).await - } - - async fn check_cache(&self) -> Option { - let guard = self.inner.read().await; - if guard.is_valid(self.cache_ttl) { - return Some(guard.cache_value.clone()); - } - None - } - - async fn refresh(&self, client: &Client) -> Result { - // 1. attempt to get write lock permit - let mut guard = self.inner.write().await; - - // 2. check if another task hasn't already updated the cache whilst we were waiting for the permit - if guard.is_valid(self.cache_ttl) { - return Ok(guard.cache_value.clone()); - } - - // 3. attempt to query the chain for the contracts data - let updated_values = guard.retrieve_nym_contracts_info(client).await?; - guard.last_refreshed_at = OffsetDateTime::now_utc(); - guard.cache_value = updated_values.clone(); - - Ok(updated_values) + self.0.get_or_refresh(client, refresh).await } } diff --git a/nym-api/src/support/http/state/helpers.rs b/nym-api/src/support/http/state/helpers.rs index 07581ae53d..bea9ec8adf 100644 --- a/nym-api/src/support/http/state/helpers.rs +++ b/nym-api/src/support/http/state/helpers.rs @@ -1,10 +1,15 @@ // Copyright 2025 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only +use crate::node_status_api::models::AxumErrorResponse; use crate::support::caching::refresher::RefreshRequester; +use crate::support::nyxd::Client; +use nym_validator_client::nyxd::error::NyxdError; use std::sync::atomic::{AtomicI64, Ordering}; use std::sync::Arc; +use std::time::Duration; use time::OffsetDateTime; +use tokio::sync::RwLock; #[derive(Clone)] pub(crate) struct Refreshing { @@ -36,3 +41,123 @@ impl Refreshing { self.handle.request_cache_refresh(); } } + +/// Shared, TTL-gated cache for values that are (re)hydrated from the nyxd chain on demand. +/// +/// The cache collapses the common "check cache, otherwise refresh" pattern used across the various +/// chain-backed state caches (chain status, contract details, ...) into a single generic type. +/// Callers plug in a type-specific `refresh_fn` that knows how to fetch `T` from the chain; this +/// type handles the locking, TTL check, and single-flight behavior. +/// +/// Concurrency model: +/// - Reads happen under a read lock; if the cached value is present and within TTL it is returned +/// immediately. +/// - If the cached value is missing or stale, a single writer takes the write lock, re-checks the +/// TTL (so a refresh that completed while we were waiting isn't redundantly repeated) and then +/// invokes `refresh_fn`. Other concurrent callers will block on the write lock and observe the +/// freshly populated value instead of each running their own query against the chain. +#[derive(Clone)] +pub(crate) struct ChainSharedCacheWithTtl { + cache_ttl: Duration, + inner: Arc>>>, +} + +impl ChainSharedCacheWithTtl +where + T: Clone, +{ + pub(crate) fn new(cache_ttl: Duration) -> Self { + ChainSharedCacheWithTtl { + cache_ttl, + inner: Arc::new(RwLock::new(None)), + } + } + + /// Return the cached value if it is still fresh, otherwise refresh it via `refresh_fn`. + /// + /// Takes the read-only fast path when the cache is warm and only escalates to a write-locked + /// refresh when the value is missing or expired. + pub(crate) async fn get_or_refresh( + &self, + client: &Client, + refresh_fn: F, + ) -> Result + where + F: AsyncFn(&Client) -> Result, + { + if let Some(cached) = self.check_cache().await { + return Ok(cached); + } + + self.refresh(client, refresh_fn).await + } + + /// Return the cached value if present and within TTL without attempting a refresh. + async fn check_cache(&self) -> Option + where + T: Clone, + { + let guard = self.inner.read().await; + let inner = guard.as_ref()?; + if inner.is_valid(self.cache_ttl) { + return Some(inner.value.clone()); + } + None + } + + /// Forcibly re-query the chain via `refresh_fn` and replace the cached value. + /// + /// The double-checked TTL guard after acquiring the write lock prevents the common + /// thundering-herd case where many concurrent callers all observe a stale cache at once - only + /// the first one to acquire the write lock will actually hit the chain. + async fn refresh(&self, client: &Client, refresh_fn: F) -> Result + where + F: AsyncFn(&Client) -> Result, + T: Clone, + { + // 1. attempt to get write lock permit + let mut guard = self.inner.write().await; + + // 2. check if another task hasn't already updated the cache whilst we were waiting for the permit + if let Some(cached) = guard.as_ref() { + if cached.is_valid(self.cache_ttl) { + return Ok(cached.clone_value()); + } + } + + let refresh_res = refresh_fn(client).await?; + + *guard = Self::new_inner(refresh_res.clone()); + Ok(refresh_res) + } + + fn new_inner(value: T) -> Option> { + Some(ChainSharedCacheWithTtlInner::new(value)) + } +} + +/// Cached value alongside the timestamp at which it was fetched, used to evaluate the TTL. +struct ChainSharedCacheWithTtlInner { + last_refreshed_at: OffsetDateTime, + value: T, +} + +impl ChainSharedCacheWithTtlInner { + fn new(value: T) -> Self { + ChainSharedCacheWithTtlInner { + last_refreshed_at: OffsetDateTime::now_utc(), + value, + } + } + + fn is_valid(&self, ttl: Duration) -> bool { + self.last_refreshed_at + ttl > OffsetDateTime::now_utc() + } + + fn clone_value(&self) -> T + where + T: Clone, + { + self.value.clone() + } +} diff --git a/nym-api/src/support/http/state/mod.rs b/nym-api/src/support/http/state/mod.rs index 35c2416f85..b2b4ae1bac 100644 --- a/nym-api/src/support/http/state/mod.rs +++ b/nym-api/src/support/http/state/mod.rs @@ -16,6 +16,7 @@ use crate::support::http::state::chain_status::ChainStatusCache; use crate::support::http::state::contract_details::ContractDetailsCache; use crate::support::http::state::force_refresh::ForcedRefresh; use crate::support::http::state::mixnet_contract_cache::MixnetContractCacheState; +use crate::support::http::state::network_monitors::{LastNMSubmissions, NetworkMonitorsCache}; use crate::support::http::state::node_annotations_cache::NodeAnnotationsCache; use crate::support::nyxd::Client; use crate::support::storage; @@ -32,6 +33,7 @@ pub(crate) mod contract_details; pub(crate) mod force_refresh; pub(crate) mod helpers; pub(crate) mod mixnet_contract_cache; +pub(crate) mod network_monitors; pub(crate) mod node_annotations_cache; #[derive(Clone)] @@ -56,9 +58,17 @@ pub(crate) struct AppState { /// It is used to prevent DoS by nodes constantly requesting the refresh. pub(crate) forced_refresh: ForcedRefresh, + /// Holds information on when the last stress testing submission was made by a network monitor. + /// It is used to prevent replay attacks by attempting to re-use request timestamps + /// Timestamps are used instead of nonces to avoid NM having to keep state with the expected values. + pub(crate) network_monitor_submissions: LastNMSubmissions, + /// Holds cached state of the Nym Mixnet contract, e.g. bonded nym-nodes, rewarded set, current interval. pub(crate) mixnet_contract_cache: MixnetContractCacheState, + /// Holds information on known network monitors that are permitted to submit stress testing results. + pub(crate) network_monitors_cache: NetworkMonitorsCache, + /// Holds processed information on network nodes, i.e. performance, config scores, etc. // TODO: also perhaps redundant? pub(crate) node_annotations_cache: NodeAnnotationsCache, @@ -102,6 +112,12 @@ impl FromRef for Arc { } } +impl FromRef for NetworkMonitorsCache { + fn from_ref(app_state: &AppState) -> Self { + app_state.network_monitors_cache.clone() + } +} + impl FromRef for MixnetContractCache { fn from_ref(app_state: &AppState) -> Self { app_state.mixnet_contract_cache.inner_cache.clone() @@ -155,6 +171,11 @@ impl AppState { &self.described_nodes_cache } + /// Access the cache of authorised network-monitor orchestrators. + pub(crate) fn network_monitors(&self) -> &NetworkMonitorsCache { + &self.network_monitors_cache + } + pub(crate) fn storage(&self) -> &storage::NymApiStorage { &self.storage } diff --git a/nym-api/src/support/http/state/network_monitors.rs b/nym-api/src/support/http/state/network_monitors.rs new file mode 100644 index 0000000000..f8a7e1b1ca --- /dev/null +++ b/nym-api/src/support/http/state/network_monitors.rs @@ -0,0 +1,114 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::node_status_api::models::AxumErrorResponse; +use crate::support::http::state::helpers::ChainSharedCacheWithTtl; +use crate::support::nyxd::Client; +use nym_crypto::asymmetric::ed25519; +use nym_validator_client::nyxd::error::NyxdError; +use std::collections::{HashMap, HashSet}; +use std::sync::Arc; +use std::time::Duration; +use time::OffsetDateTime; +use tokio::sync::RwLock; +use tracing::{error, warn}; + +/// Per-orchestrator high-water mark of accepted submission timestamps, kept in-memory to provide +/// replay protection for the stress-test submission endpoint. +#[derive(Clone)] +pub(crate) struct LastNMSubmissions { + pub(crate) submissions: Arc>>, +} + +impl LastNMSubmissions { + pub(crate) fn new() -> LastNMSubmissions { + LastNMSubmissions { + submissions: Arc::new(Default::default()), + } + } + + /// Last accepted submission timestamp for particular network monitor + pub(crate) async fn submitted(&self, nm: ed25519::PublicKey) -> Option { + self.submissions.read().await.get(&nm).copied() + } + + /// Record `timestamp` as the most recent accepted submission for `nm`. + /// + /// Callers are responsible for ensuring `timestamp` passes the monotonicity check against + /// [`submitted`][Self::submitted] before calling this. + pub(crate) async fn set_submitted(&self, nm: ed25519::PublicKey, timestamp: OffsetDateTime) { + self.submissions.write().await.insert(nm, timestamp); + } +} + +/// Snapshot of identity keys for network monitor orchestrators currently registered in the +/// network-monitors contract. +#[derive(Clone)] +pub(crate) struct KnownNetworkMonitors { + known: HashSet, +} + +impl KnownNetworkMonitors { + pub(crate) fn contains(&self, key: &ed25519::PublicKey) -> bool { + self.known.contains(key) + } +} + +/// TTL-gated cache over [`KnownNetworkMonitors`] so that every submission doesn't re-query the +/// network-monitors contract; refresh happens lazily on the first request after the TTL expires. +#[derive(Clone)] +pub(crate) struct NetworkMonitorsCache(ChainSharedCacheWithTtl); + +impl NetworkMonitorsCache { + pub(crate) fn new(cache_ttl: Duration) -> Self { + NetworkMonitorsCache(ChainSharedCacheWithTtl::new(cache_ttl)) + } + + /// Return the currently-cached set of known orchestrators, refreshing from chain if stale. + pub(crate) async fn get_or_refresh( + &self, + client: &Client, + ) -> Result { + self.0.get_or_refresh(client, refresh).await + } + + /// Shortcut for "is this key in the current (possibly just-refreshed) orchestrator set?". + pub(crate) async fn is_authorised( + &self, + nyxd_client: &Client, + key: &ed25519::PublicKey, + ) -> Result { + Ok(self.get_or_refresh(nyxd_client).await?.known.contains(key)) + } +} + +/// Fetch the orchestrator set from the network-monitors contract and decode each entry's identity +/// key. Orchestrators without an announced key, or with an unparseable one, are logged and +/// skipped - the rest still populate the cache so one bad entry doesn't take down submissions for +/// everyone. +async fn refresh(client: &Client) -> Result { + if let Err(err) = client.get_network_monitors_contract_address().await { + warn!("network monitor contract address not set - can't accept any stress testing results"); + return Err(err); + } + + let known_monitors = client.get_all_network_monitor_orchestrators().await?; + let mut updated_monitors = HashSet::new(); + for monitor in known_monitors { + let Some(public_key) = monitor.identity_key else { + warn!("{} orchestrator is authorised but has not announced its public key - is the process running correctly?", monitor.address); + continue; + }; + let parsed = match ed25519::PublicKey::from_base58_string(&public_key) { + Ok(key) => key, + Err(err) => { + error!("failed to parse public key for {}: {err}", monitor.address); + continue; + } + }; + updated_monitors.insert(parsed); + } + Ok(KnownNetworkMonitors { + known: updated_monitors, + }) +} diff --git a/nym-api/src/support/nyxd/mod.rs b/nym-api/src/support/nyxd/mod.rs index 6de33c4738..e008cb4fe7 100644 --- a/nym-api/src/support/nyxd/mod.rs +++ b/nym-api/src/support/nyxd/mod.rs @@ -39,9 +39,11 @@ use nym_validator_client::nyxd::contract_traits::performance_query_client::{ LastSubmission, NodePerformance, }; use nym_validator_client::nyxd::contract_traits::{ - PagedDkgQueryClient, PagedPerformanceQueryClient, PerformanceQueryClient, + NetworkMonitorsQueryClient, PagedDkgQueryClient, PagedPerformanceQueryClient, + PerformanceQueryClient, TypedNymContracts, }; use nym_validator_client::nyxd::error::NyxdError; +use nym_validator_client::nyxd::nym_network_monitors_contract_common::AuthorisedNetworkMonitorOrchestrator; use nym_validator_client::nyxd::Coin; use nym_validator_client::nyxd::{ contract_traits::{ @@ -167,6 +169,12 @@ impl Client { } } + /// Return the full set of Nym contract addresses currently configured on this client. + #[allow(dead_code)] + pub(crate) async fn known_contracts(&self) -> TypedNymContracts { + nyxd_query!(self, get_nym_contracts()) + } + pub(crate) async fn get_ecash_contract_address(&self) -> Result { nyxd_query!( self, @@ -176,6 +184,22 @@ impl Client { ) } + /// Return the configured network-monitors contract address. + /// + /// Returns [`NyxdError::UnavailableContractAddress`] if the address is not configured - this + /// is the signal used upstream (e.g. in `NetworkMonitorsCache`) to warn that stress-test + /// submissions cannot be accepted. + pub(crate) async fn get_network_monitors_contract_address( + &self, + ) -> Result { + nyxd_query!( + self, + network_monitors_contract_address().cloned().ok_or_else(|| { + NyxdError::unavailable_contract_address("network monitors contract") + }) + ) + } + pub(crate) async fn get_rewarding_validator_address(&self) -> Result { let cosmwasm_addr = nyxd_query!( self, @@ -417,6 +441,17 @@ impl Client { ) -> Result, NyxdError> { nyxd_query!(self, get_all_epoch_performance(epoch_id).await) } + + /// Query the network-monitors contract for the full set of authorised orchestrators. + /// + /// This returns every orchestrator registered in the contract regardless of whether they + /// have announced an identity key yet - callers are responsible for filtering entries with + /// `identity_key == None`. + pub(crate) async fn get_all_network_monitor_orchestrators( + &self, + ) -> Result, NyxdError> { + Ok(nyxd_query!(self, get_network_monitor_orchestrators().await)?.authorised) + } } #[async_trait] diff --git a/nym-api/src/support/storage/manager.rs b/nym-api/src/support/storage/manager.rs index 710481d41e..fc24ccc757 100644 --- a/nym-api/src/support/storage/manager.rs +++ b/nym-api/src/support/storage/manager.rs @@ -5,8 +5,9 @@ use crate::node_status_api::models::{HistoricalUptime as ApiHistoricalUptime, Up use crate::node_status_api::utils::{ActiveGatewayStatuses, ActiveMixnodeStatuses}; use crate::support::storage::models::{ ActiveGateway, ActiveMixnode, GatewayDetails, HistoricalUptime, MixnodeDetails, - MonitorRunReport, MonitorRunScore, NodeStatus, RewardingReport, TestedGatewayStatus, - TestedMixnodeStatus, TestingRoute, + MonitorRunReport, MonitorRunScore, NodeStatus, NymNodeStressTestingResult, + RetrievedAverageStressTestResult, RewardingReport, TestedGatewayStatus, TestedMixnodeStatus, + TestingRoute, }; use crate::support::storage::DbIdCache; use nym_mixnet_contract_common::{EpochId, IdentityKey, NodeId}; @@ -308,6 +309,42 @@ impl StorageManager { Ok(result.reliability) } + /// Returns the rolling average stress-testing score for a single node over the given window. + /// + /// `was_reachable` is `MAX(was_reachable)` so it is `true` if **any** sample reported the + /// node reachable, and `false` only if every sample marked it unreachable — matching the + /// "false only when all entries are false" rule used by the consumers. + /// + /// `GROUP BY node_id` (rather than a bare aggregate) ensures that an empty selection yields + /// no row (so `fetch_optional` returns `None`) instead of a single all-NULL row that would + /// be indistinguishable from "node was never tested". + pub(super) async fn get_average_node_stress_test_score( + &self, + node_id: i64, + start_ts: OffsetDateTime, + end_ts: OffsetDateTime, + ) -> Result, sqlx::Error> { + sqlx::query_as!( + RetrievedAverageStressTestResult, + r#" + SELECT + node_id as "node_id!: NodeId", + AVG(result) as "result!: f64", + MAX(was_reachable) as "was_reachable!: bool" + FROM nym_node_stress_testing_result + WHERE node_id = ? + AND test_timestamp >= ? + AND test_timestamp <= ? + GROUP BY node_id + "#, + node_id, + start_ts, + end_ts, + ) + .fetch_optional(&self.connection_pool) + .await + } + /// Gets all reliability statuses for gateway with particular id that were inserted /// into the database within the specified time interval. /// @@ -779,6 +816,38 @@ impl StorageManager { .await } + /// Batch-insert the given stress-testing results into the `nym_node_stress_testing_result` + /// table. An empty input is a no-op rather than an invalid-SQL error, since an incoming + /// submission may legitimately contain no mixnode entries after filtering. + /// + /// Uses `INSERT OR IGNORE` so that a retried submission carrying the same + /// `(testrun_id, submitter_pubkey)` pair - expected under the orchestrator's at-least-once + /// delivery semantics - silently drops the duplicate rows rather than failing the batch. + pub(super) async fn insert_nym_node_stress_testing_results( + &self, + results: Vec, + ) -> Result<(), sqlx::Error> { + if results.is_empty() { + return Ok(()); + } + + let mut query_builder = sqlx::QueryBuilder::new( + "INSERT OR IGNORE INTO nym_node_stress_testing_result (testrun_id, submitter_pubkey, node_id, result, was_reachable, test_timestamp) ", + ); + + query_builder.push_values(results, |mut b, entry| { + b.push_bind(entry.testrun_id) + .push_bind(entry.submitter_pubkey) + .push_bind(entry.node_id) + .push_bind(entry.result) + .push_bind(entry.was_reachable) + .push_bind(entry.test_timestamp); + }); + + query_builder.build().execute(&self.connection_pool).await?; + Ok(()) + } + /// Obtains number of network monitor test runs that have occurred within the specified interval. /// /// # Arguments diff --git a/nym-api/src/support/storage/mod.rs b/nym-api/src/support/storage/mod.rs index 8bb14a697d..71e9fc3752 100644 --- a/nym-api/src/support/storage/mod.rs +++ b/nym-api/src/support/storage/mod.rs @@ -12,7 +12,8 @@ use crate::storage::manager::StorageManager; use crate::storage::models::TestingRoute; use crate::support::storage::models::{ GatewayDetails, HistoricalUptime, MixnodeDetails, MonitorRunReport, MonitorRunScore, - TestedGatewayStatus, TestedMixnodeStatus, + NymNodeStressTestingResult, RetrievedAverageStressTestResult, TestedGatewayStatus, + TestedMixnodeStatus, }; use dashmap::DashMap; use nym_mixnet_contract_common::NodeId; @@ -226,6 +227,18 @@ impl NymApiStorage { Ok(reliability) } + pub(crate) async fn get_average_node_stress_test_score( + &self, + node_id: NodeId, + start_ts: OffsetDateTime, + end_ts: OffsetDateTime, + ) -> Result, NymApiStorageError> { + Ok(self + .manager + .get_average_node_stress_test_score(node_id as i64, start_ts, end_ts) + .await?) + } + #[allow(unused)] pub(crate) async fn get_average_mixnode_uptime_in_the_last_24hrs( &self, @@ -692,6 +705,18 @@ impl NymApiStorage { Ok(()) } + /// Persist the given stress-testing results, produced by an authorised network monitor + /// orchestrator, into the database. + pub(crate) async fn insert_nym_node_stress_testing_results( + &self, + results: Vec, + ) -> Result<(), NymApiStorageError> { + self.manager + .insert_nym_node_stress_testing_results(results) + .await?; + Ok(()) + } + /// Obtains number of network monitor test runs that have occurred within the specified interval. /// /// # Arguments diff --git a/nym-api/src/support/storage/models.rs b/nym-api/src/support/storage/models.rs index e082961b01..c9fe22c440 100644 --- a/nym-api/src/support/storage/models.rs +++ b/nym-api/src/support/storage/models.rs @@ -1,7 +1,8 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use nym_api_requests::models::TestNode; +use nym_api_requests::models::{StressTestResult, StressTestingScore, TestNode}; +use nym_crypto::asymmetric::ed25519; use nym_mixnet_contract_common::NodeId; use sqlx::FromRow; use time::Date; @@ -146,3 +147,48 @@ pub struct HistoricalUptime { pub date: Date, pub uptime: i64, } + +/// Row model for the `nym_node_stress_testing_result` table. +/// +/// Produced from the wire-level [`StressTestResult`] via [`Self::from_submission`], which also +/// renames `test_performance` to `result` to match the on-disk column name and attaches the +/// submitting orchestrator's identity key so that `(testrun_id, submitter_pubkey)` dedupes +/// retried at-least-once submissions. +#[derive(FromRow)] +pub struct NymNodeStressTestingResult { + pub testrun_id: i64, + pub submitter_pubkey: String, + pub node_id: NodeId, + pub result: f64, + pub was_reachable: bool, + pub test_timestamp: time::OffsetDateTime, +} + +impl NymNodeStressTestingResult { + pub fn from_submission(signer: &ed25519::PublicKey, value: StressTestResult) -> Self { + NymNodeStressTestingResult { + testrun_id: value.testrun_id, + submitter_pubkey: signer.to_base58_string(), + node_id: value.node_id, + result: value.test_performance, + was_reachable: value.was_reachable, + test_timestamp: value.test_timestamp, + } + } +} + +#[derive(FromRow)] +pub struct RetrievedAverageStressTestResult { + pub node_id: NodeId, + pub result: f64, + pub was_reachable: bool, +} + +impl From for StressTestingScore { + fn from(value: RetrievedAverageStressTestResult) -> Self { + StressTestingScore { + score: value.result, + was_reachable: value.was_reachable, + } + } +} diff --git a/nym-api/src/unstable_routes/v2/nym_nodes/semi_skimmed/mod.rs b/nym-api/src/unstable_routes/v2/nym_nodes/semi_skimmed/mod.rs index 20a31c5f74..e3cca6a660 100644 --- a/nym-api/src/unstable_routes/v2/nym_nodes/semi_skimmed/mod.rs +++ b/nym-api/src/unstable_routes/v2/nym_nodes/semi_skimmed/mod.rs @@ -7,7 +7,7 @@ use crate::unstable_routes::helpers::refreshed_at; use crate::unstable_routes::v2::nym_nodes::helpers::NodesParamsWithRole; use axum::extract::{Query, State}; use nym_api_requests::models::{ - NodeAnnotation, NymNodeDescriptionV2, OffsetDateTimeJsonSchemaWrapper, + NodeAnnotationV1, NodeAnnotationV2, NymNodeDescriptionV2, OffsetDateTimeJsonSchemaWrapper, }; use nym_api_requests::nym_nodes::{NodeRole, PaginatedCachedNodesResponseV2, SemiSkimmedNodeV1}; use nym_api_requests::pagination::PaginatedResponse; @@ -24,7 +24,7 @@ pub type PaginatedSemiSkimmedNodes = fn build_nym_nodes_response<'a, NI>( rewarded_set: &CachedEpochRewardedSet, nym_nodes_subset: NI, - annotations: &HashMap, + annotations: &HashMap, current_key_rotation: u32, active_only: bool, ) -> Vec @@ -44,7 +44,11 @@ where // honestly, not sure under what exact circumstances this value could be missing, // but in that case just use 0 performance - let annotation = annotations.get(&node_id).copied().unwrap_or_default(); + let annotation: NodeAnnotationV1 = annotations + .get(&node_id) + .copied() + .unwrap_or_default() + .into(); nodes.push(nym_node.to_semi_skimmed_node( current_key_rotation, diff --git a/nym-api/src/unstable_routes/v2/nym_nodes/skimmed/helpers.rs b/nym-api/src/unstable_routes/v2/nym_nodes/skimmed/helpers.rs index 017c0e98ea..a82d4452dc 100644 --- a/nym-api/src/unstable_routes/v2/nym_nodes/skimmed/helpers.rs +++ b/nym-api/src/unstable_routes/v2/nym_nodes/skimmed/helpers.rs @@ -7,7 +7,7 @@ use crate::unstable_routes::v2::nym_nodes::helpers::NodesParams; use crate::unstable_routes::v2::nym_nodes::skimmed::PaginatedSkimmedNodes; use axum::extract::{Query, State}; use nym_api_requests::models::{ - NodeAnnotation, NymNodeDescriptionV2, OffsetDateTimeJsonSchemaWrapper, + NodeAnnotationV1, NodeAnnotationV2, NymNodeDescriptionV2, OffsetDateTimeJsonSchemaWrapper, }; use nym_api_requests::nym_nodes::{NodeRole, PaginatedCachedNodesResponseV2, SkimmedNodeV1}; use nym_http_api_common::Output; @@ -20,7 +20,7 @@ use std::time::Duration; fn build_nym_nodes_response<'a, NI>( rewarded_set: &CachedEpochRewardedSet, nym_nodes_subset: NI, - annotations: &HashMap, + annotations: &HashMap, current_key_rotation: u32, active_only: bool, ) -> Vec @@ -40,7 +40,11 @@ where // honestly, not sure under what exact circumstances this value could be missing, // but in that case just use 0 performance - let annotation = annotations.get(&node_id).copied().unwrap_or_default(); + let annotation: NodeAnnotationV1 = annotations + .get(&node_id) + .copied() + .unwrap_or_default() + .into(); nodes.push(nym_node.to_skimmed_node( current_key_rotation, diff --git a/nym-api/src/unstable_routes/v3/nym_nodes/semi_skimmed/mod.rs b/nym-api/src/unstable_routes/v3/nym_nodes/semi_skimmed/mod.rs index a189000077..b7b5ab8138 100644 --- a/nym-api/src/unstable_routes/v3/nym_nodes/semi_skimmed/mod.rs +++ b/nym-api/src/unstable_routes/v3/nym_nodes/semi_skimmed/mod.rs @@ -6,7 +6,7 @@ use crate::support::http::state::AppState; use crate::unstable_routes::helpers::refreshed_at; use axum::extract::{Query, State}; use nym_api_requests::models::{ - NodeAnnotation, NymNodeDescriptionV2, OffsetDateTimeJsonSchemaWrapper, + NodeAnnotationV1, NodeAnnotationV2, NymNodeDescriptionV2, OffsetDateTimeJsonSchemaWrapper, }; use nym_api_requests::nym_nodes::{NodeRole, PaginatedCachedNodesResponseV2, SemiSkimmedNodeV3}; use nym_api_requests::pagination::PaginatedResponse; @@ -22,7 +22,7 @@ pub type PaginatedSemiSkimmedNodes = fn build_response<'a>( rewarded_set: &CachedEpochRewardedSet, nym_nodes: impl Iterator, - annotations: &HashMap, + annotations: &HashMap, current_key_rotation: u32, ) -> Vec { let mut nodes = Vec::new(); @@ -33,7 +33,11 @@ fn build_response<'a>( // honestly, not sure under what exact circumstances this value could be missing, // but in that case just use 0 performance - let annotation = annotations.get(&node_id).copied().unwrap_or_default(); + let annotation: NodeAnnotationV1 = annotations + .get(&node_id) + .copied() + .unwrap_or_default() + .into(); nodes.push(nym_node.to_semi_skimmed_node_v3( current_key_rotation, diff --git a/nym-data-observatory/src/chain_scraper/webhook.rs b/nym-data-observatory/src/chain_scraper/webhook.rs index 240bcbdccf..dd03806fb7 100644 --- a/nym-data-observatory/src/chain_scraper/webhook.rs +++ b/nym-data-observatory/src/chain_scraper/webhook.rs @@ -28,42 +28,40 @@ impl WebhookModule { #[async_trait] impl TxModule for WebhookModule { async fn handle_tx(&mut self, tx: &ParsedTransactionResponse) -> Result<(), ScraperError> { - for (index, msg) in &tx.parsed_messages { - if let Some(parsed_message_type_url) = tx.parsed_message_urls.get(index) { - let payload = WebhookPayload { - height: tx.height.value(), - message_index: *index as u64, - transaction_hash: tx.hash.to_string(), - message: Some(msg.clone()), - }; + for (index, msg) in &tx.decoded_messages { + let payload = WebhookPayload { + height: tx.tx_details.height().value(), + message_index: *index as u64, + transaction_hash: tx.tx_details.hash.to_string(), + message: Some(msg.decoded_content.clone()), + }; - // println!( - // "->>>>>>>>>>>>>>>>>>>>>>>>> {}", - // serde_json::to_string(&payload).unwrap() - // ); + // println!( + // "->>>>>>>>>>>>>>>>>>>>>>>>> {}", + // serde_json::to_string(&payload).unwrap() + // ); - for webhook in self.webhooks.clone() { - // if the webhook requires a type and the parsed message type doesn't match, skip - if !webhook.config.watch_for_chain_message_types.is_empty() - && !webhook - .config - .watch_for_chain_message_types - .contains(parsed_message_type_url) - { - continue; - } - - let payload = payload.clone(); - - // TODO: some excellent advice from Andrew, for another day: - // - pass a cancellation token for shutdown - // - use TaskManager and limit number of webhooks to spawn at once - tokio::spawn(async move { - if let Err(e) = webhook.invoke_webhook(&payload).await { - error!("webhook error: {}", e); - } - }); + for webhook in self.webhooks.clone() { + // if the webhook requires a type and the parsed message type doesn't match, skip + if !webhook.config.watch_for_chain_message_types.is_empty() + && !webhook + .config + .watch_for_chain_message_types + .contains(&msg.type_url) + { + continue; } + + let payload = payload.clone(); + + // TODO: some excellent advice from Andrew, for another day: + // - pass a cancellation token for shutdown + // - use TaskManager and limit number of webhooks to spawn at once + tokio::spawn(async move { + if let Err(e) = webhook.invoke_webhook(&payload).await { + error!("webhook error: {}", e); + } + }); } } Ok(()) diff --git a/nym-data-observatory/src/modules/wasm.rs b/nym-data-observatory/src/modules/wasm.rs index bbe90e2c37..3fc39afac3 100644 --- a/nym-data-observatory/src/modules/wasm.rs +++ b/nym-data-observatory/src/modules/wasm.rs @@ -8,7 +8,8 @@ use cosmrs::proto::cosmwasm::wasm::v1::MsgExecuteContract; use cosmrs::proto::prost::Message; use nym_validator_client::nyxd::{Any, Name}; use nyxd_scraper_psql::models::DbCoin; -use nyxd_scraper_psql::{MsgModule, ParsedTransactionResponse, ScraperError}; +use nyxd_scraper_psql::{MsgModule, ScraperError}; +use nyxd_scraper_shared::{DecodedMessage, ParsedTransactionDetails}; use serde_json::Value; use time::{OffsetDateTime, PrimitiveDateTime}; use tracing::{error, trace}; @@ -34,9 +35,10 @@ impl MsgModule for WasmModule { &mut self, index: usize, msg: &Any, - tx: &ParsedTransactionResponse, + decoded_msg: &DecodedMessage, + tx: &ParsedTransactionDetails, ) -> Result<(), ScraperError> { - let message = serde_json::to_value(tx.parsed_messages.get(&index)).unwrap_or_default(); + let message = serde_json::to_value(&decoded_msg.decoded_content).unwrap_or_default(); let value = serde_json::to_value(message.clone()).unwrap_or_default(); let wasm_message_type = get_wasm_message_type(&value); let fee: Vec = tx @@ -55,7 +57,7 @@ impl MsgModule for WasmModule { let offset_datetime: OffsetDateTime = tx.block.header.time.into(); let executed_at = PrimitiveDateTime::new(offset_datetime.date(), offset_datetime.time()); - let height = tx.height.value() as i64; + let height = tx.height().value() as i64; let hash = tx.hash.to_string(); let memo = tx.tx.body.memo.clone(); diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/Cargo.toml b/nym-network-monitor-v3/nym-network-monitor-agent/Cargo.toml new file mode 100644 index 0000000000..97d0adccef --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/Cargo.toml @@ -0,0 +1,56 @@ +[package] +name = "nym-network-monitor-agent" +description = "Agent used for stress testing Nym mixnodes" +version = "1.0.2" +authors.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +homepage.workspace = true +documentation.workspace = true +rust-version.workspace = true +readme.workspace = true +publish = false + +[dependencies] +anyhow = { workspace = true } +clap = { workspace = true, features = ["cargo", "env"] } +futures = { workspace = true } +humantime = { workspace = true } +rand = { workspace = true } +nym-sphinx-types = { workspace = true } +nym-sphinx-params = { workspace = true } +nym-sphinx-framing = { workspace = true } +nym-sphinx-addressing = { workspace = true } +nym-noise = { workspace = true } +time = { workspace = true } +tokio = { workspace = true, features = ["macros", "sync", "rt-multi-thread"] } +tokio-util = { workspace = true } +tracing = { workspace = true } +url = { workspace = true } +zeroize = { workspace = true } + +# methods to recreate lioness +# we don't care about particular versions - just pull whatever is used by sphinx +lioness = { workspace = true } +arrayref = { workspace = true } +sha2 = { workspace = true } +hkdf = { workspace = true } +x25519-dalek = { workspace = true } + + +nym-bin-common = { workspace = true, features = [ + "basic_tracing", + "output_format", +] } +nym-crypto = { workspace = true, features = ["asymmetric", "rand", "hashing"] } +nym-pemstore = { workspace = true } +nym-task = { workspace = true } + +nym-network-monitor-orchestrator-requests = { path = "../nym-network-monitor-orchestrator-requests", features = ["client"] } + +[dev-dependencies] +nym-test-utils = { workspace = true } + +[lints] +workspace = true diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/Dockerfile b/nym-network-monitor-v3/nym-network-monitor-agent/Dockerfile new file mode 100644 index 0000000000..ac476573f0 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/Dockerfile @@ -0,0 +1,22 @@ +# this will only work with VPN, otherwise remove the harbor part +FROM harbor.nymte.ch/dockerhub/rust:latest AS builder + +RUN apt update && apt install -yy libdbus-1-dev pkg-config libclang-dev + +COPY ./ /usr/src/nym +WORKDIR /usr/src/nym + +RUN cargo build --bin nym-network-monitor-agent --release + +FROM harbor.nymte.ch/dockerhub/ubuntu:24.04 + +RUN apt-get update && apt-get install -y ca-certificates + +WORKDIR /nym + +COPY --from=builder /usr/src/nym/target/release/nym-network-monitor-agent ./ +COPY --from=builder /usr/src/nym/nym-network-monitor-v3/nym-network-monitor-agent/entrypoint.sh ./ +RUN chmod +x /nym/entrypoint.sh + +ENV SLEEP_TIME=5 +ENTRYPOINT [ "/nym/entrypoint.sh" ] diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/README.md b/nym-network-monitor-v3/nym-network-monitor-agent/README.md new file mode 100644 index 0000000000..e8df6d423d --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/README.md @@ -0,0 +1,3 @@ +# Network Monitor Agent + +An agent to run nym node stress tests and report results back to the Network Monitor orchestrator. diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/build-push-node-status-agent.sh b/nym-network-monitor-v3/nym-network-monitor-agent/build-push-node-status-agent.sh new file mode 100755 index 0000000000..721c996f94 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/build-push-node-status-agent.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +# Build and push Network Monitor Agent container to harbor.nymte.ch + +set -e + +# Configuration +SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +WORKING_DIRECTORY="${SCRIPT_DIR}" +CONTAINER_NAME="network-monitor-agent" +REGISTRY="harbor.nymte.ch" +NAMESPACE="nym" + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# Get version from Cargo.toml +VERSION=$(grep "^version = " "${WORKING_DIRECTORY}/Cargo.toml" | sed -E 's/version = "(.*)"/\1/') +if [ -z "$VERSION" ]; then + echo -e "${RED}Error: Could not extract version from Cargo.toml${NC}" + exit 1 +fi + +echo -e "${YELLOW}Building Network Monitor Agent${NC}" +echo -e "${YELLOW}Version: ${VERSION}${NC}" + +# Login to Harbor +echo -e "${GREEN}Logging into Harbor...${NC}" +docker login "${REGISTRY}" + +# Build the container +echo -e "${GREEN}Building the container...${NC}" +# Build from repository root (two levels up from script location) +docker build \ + --build-arg GIT_REF="${GATEWAY_PROBE_GIT_REF}" \ + -f "${WORKING_DIRECTORY}/Dockerfile" \ + "${SCRIPT_DIR}/../.." \ + -t "${REGISTRY}/${NAMESPACE}/${CONTAINER_NAME}:${VERSION}" \ + -t "${REGISTRY}/${NAMESPACE}/${CONTAINER_NAME}:latest" + +# Push to Harbor +echo -e "${GREEN}Pushing container to Harbor...${NC}" +docker push "${REGISTRY}/${NAMESPACE}/${CONTAINER_NAME}:${VERSION}" +docker push "${REGISTRY}/${NAMESPACE}/${CONTAINER_NAME}:latest" + +echo -e "${GREEN}Successfully built and pushed ${CONTAINER_NAME}:${VERSION}${NC}" \ No newline at end of file diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/entrypoint.sh b/nym-network-monitor-v3/nym-network-monitor-agent/entrypoint.sh new file mode 100755 index 0000000000..111e61ad0a --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/entrypoint.sh @@ -0,0 +1,20 @@ +#!/bin/sh + +echo "Starting agent loop with sleep interval: ${SLEEP_TIME}s" + +# Trap SIGTERM to allow graceful shutdown +trap "echo 'Stopping...'; exit 0" SIGTERM + +DEFAULT_ARGS="run-agent --orchestrator_address \"${NETWORK_MONITOR_AGENT_SERVER_ADDRESS}:${NETWORK_MONITOR_AGENT_SERVER_PORT}\" " +ARGS=${NETWORK_MONITOR_AGENT_ARGS:-${DEFAULT_ARGS}} +COMMAND="/nym/nym-network-monitor-agent ${ARGS}" + +echo "default_args = '${DEFAULT_ARGS}'" +echo "args = '${ARGS}'" +echo "command = '${COMMAND}'" + +# Run agent in an infinite loop +while true; do + eval "$COMMAND" + sleep "$SLEEP_TIME" +done diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/config.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/config.rs new file mode 100644 index 0000000000..4761b88c1f --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/config.rs @@ -0,0 +1,110 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use std::net::SocketAddr; +use std::time::Duration; + +/// Configuration for the [`NodeStressTester`], controlling packet sending behaviour during a test run. +#[derive(Debug, Clone, Copy)] +pub(crate) struct NodeTesterConfig { + /// How long the agent should be sending test packets with the specified rate. + pub(crate) sending_duration: Duration, + + /// How long the agent will wait to receive any leftover packets after finishing sending. + pub(crate) waiting_duration: Duration, + + /// How long the target node should delay the packet (i.e. the sphinx delay) + pub(crate) packet_delay: Duration, + + /// Timeout for establishing the egress connection to the node under test. + pub(crate) egress_connection_timeout: Duration, + + /// Timeout for the completing the noise handshake. + pub(crate) noise_handshake_timeout: Duration, + + /// Number of packets dispatched in a single batch. Together with `target_rate` this + /// determines the inter-batch interval: `sending_batch_size / target_rate` seconds. + pub(crate) sending_batch_size: usize, + + /// Target rate of packets (per second) to be sent. + pub(crate) target_rate: usize, + + /// Whether the agent should reuse the same header for all packets, and consequently replay them. + pub(crate) reuse_header: bool, + + /// Local socket address the agent binds its mixnet listener on to receive returning packets. + pub(crate) mixnet_bind_address: SocketAddr, + + /// The mixnet address announced in the contract, where the tested nodes will send their packets to. + pub(crate) external_mixnet_address: SocketAddr, +} + +impl NodeTesterConfig { + /// Total number of packets the agent intends to send: `floor(target_rate * sending_duration)`. + pub(crate) fn expected_packets(&self) -> usize { + (self.target_rate as f32 * self.sending_duration.as_secs_f32()).floor() as usize + } + + /// Time between consecutive batch dispatches needed to sustain `target_rate`: + /// `sending_batch_size / target_rate` seconds. + pub(crate) fn batch_interval(&self) -> Duration { + Duration::from_secs_f64(self.sending_batch_size as f64 / self.target_rate as f64) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use std::time::Duration; + + fn config( + target_rate: usize, + sending_duration: Duration, + batch_size: usize, + ) -> NodeTesterConfig { + NodeTesterConfig { + sending_duration, + waiting_duration: Duration::from_secs(5), + packet_delay: Duration::from_millis(50), + egress_connection_timeout: Duration::from_secs(5), + noise_handshake_timeout: Duration::from_secs(3), + sending_batch_size: batch_size, + target_rate, + reuse_header: true, + mixnet_bind_address: "127.0.0.1:1789".parse().unwrap(), + external_mixnet_address: "127.0.0.1:1789".parse().unwrap(), + } + } + + #[test] + fn expected_packets_floors_fractional_result() { + // 1000 * 0.5s = 500.0 — exact, no rounding needed + assert_eq!( + config(1000, Duration::from_millis(500), 50).expected_packets(), + 500 + ); + } + + #[test] + fn expected_packets_floors_not_rounds() { + // 1000 * 1.9s = 1900.0 exactly + assert_eq!( + config(1000, Duration::from_millis(1900), 50).expected_packets(), + 1900 + ); + } + + #[test] + fn batch_interval_is_batch_size_over_rate() { + // 100 packets / 1000 pps = 100ms + let interval = config(1000, Duration::from_secs(30), 100).batch_interval(); + assert_eq!(interval, Duration::from_millis(100)); + } + + #[test] + fn batch_interval_smaller_than_one_ms() { + // 1 packet / 1000 pps = 1ms + let interval = config(1000, Duration::from_secs(30), 1).batch_interval(); + assert_eq!(interval, Duration::from_millis(1)); + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/helpers.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/helpers.rs new file mode 100644 index 0000000000..6293361d6b --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/helpers.rs @@ -0,0 +1,19 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use anyhow::{Context, bail}; +use nym_crypto::asymmetric::x25519; +use nym_pemstore::load_key; +use std::path::Path; +use std::sync::Arc; + +/// Loads an x25519 Noise private key from a PEM file and returns the full key pair +/// wrapped in an [`Arc`] for shared ownership. +pub(crate) fn load_noise_key>(path: P) -> anyhow::Result> { + let path = path.as_ref(); + if !path.exists() { + bail!("noise key file does not exist at: {}", path.display()); + } + let noise_key: x25519::PrivateKey = load_key(path).context("failed to load noise key")?; + Ok(Arc::new(noise_key.into())) +} diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/mod.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/mod.rs new file mode 100644 index 0000000000..bc089f16f4 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/mod.rs @@ -0,0 +1,110 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::agent::config::NodeTesterConfig; +use crate::agent::tested_node::TestedNodeDetails; +use crate::agent::tester::NodeStressTester; +use anyhow::Context; +use nym_crypto::asymmetric::x25519; +use nym_network_monitor_orchestrator_requests::client::OrchestratorClient; +use nym_network_monitor_orchestrator_requests::models::{ + AgentAnnounceRequest, TestRunAssignmentRequest, TestRunResultSubmissionRequest, +}; +use nym_noise::LATEST_NOISE_VERSION; +use std::sync::Arc; +use tracing::info; + +pub(crate) mod config; +pub(crate) mod helpers; +pub(crate) mod result; +pub(crate) mod tested_node; +pub(crate) mod tester; + +/// A network monitor agent that receives test assignments from the orchestrator, +/// stress-tests individual nym-nodes, and reports results back. +pub(crate) struct NetworkMonitorAgent { + /// Tester configuration controlling rates, timeouts, and addressing. + tester_config: NodeTesterConfig, + + /// Client used to communicate with the orchestrator API (port requests, announcements, + /// work assignments, result submissions). + orchestrator_client: OrchestratorClient, + + /// The tester's own Noise key pair, used to authenticate the egress connection. + noise_key: Arc, +} + +impl NetworkMonitorAgent { + /// Creates a new agent with the given tester configuration, pre-loaded noise key, + /// and orchestrator client. + pub(crate) fn new( + tester_config: NodeTesterConfig, + noise_key: Arc, + orchestrator_client: OrchestratorClient, + ) -> Self { + NetworkMonitorAgent { + tester_config, + orchestrator_client, + noise_key, + } + } + + /// Announces this agent's details (mixnet address, noise key, protocol version) + /// to the orchestrator so they can be registered in the smart contract. + pub(crate) async fn announce_agent(&self) -> anyhow::Result<()> { + self.orchestrator_client + .announce_agent(&AgentAnnounceRequest { + agent_mix_socket_address: self.tester_config.external_mixnet_address, + x25519_noise_key: *self.noise_key.public_key(), + // we're always using the latest noise version available + noise_version: LATEST_NOISE_VERSION.into(), + }) + .await?; + Ok(()) + } + + /// Requests a work assignment from the orchestrator and, if one is available, + /// performs a stress test against the assigned node and submits the results. + pub(crate) async fn run_stress_test(&self) -> anyhow::Result<()> { + let request = TestRunAssignmentRequest { + agent_mix_socket_address: self.tester_config.external_mixnet_address, + x25519_noise_key: *self.noise_key.public_key(), + }; + + // 1. query the orchestrator for a work assignment + let Some(work_assignment) = self + .orchestrator_client + .request_work_assignment(&request) + .await? + .assignment + else { + // 2. if no work is available - exit immediately + info!("no work available, exiting..."); + return Ok(()); + }; + + info!("retrieved the following work assignment: {work_assignment:?}"); + let node_id = work_assignment.node_id; + + // 3. otherwise construct the tester and attempt to perform the measurements + let tested_node = TestedNodeDetails::from_testrun_assignment(work_assignment); + let mut stress_tester = + NodeStressTester::new(self.tester_config, self.noise_key.clone(), tested_node)?; + + // attempt to perform the measurements within the configured timeouts + // note: the only errors we're possibly exiting on are critical failures like + // theoretically impossible sphinx packet creations or failing to join on tasks. + // any sending/receiving errors are included as part of an `Ok(result)` response. + let result = stress_tester.run_stress_test().await?; + + // 4. after that has concluded - submit the results back to the orchestrator + self.orchestrator_client + .submit_test_run_result(&TestRunResultSubmissionRequest { + node_id, + result: result.into(), + }) + .await + .context("failed to submit test run result")?; + Ok(()) + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/result.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/result.rs new file mode 100644 index 0000000000..5799ba432a --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/result.rs @@ -0,0 +1,381 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::egress_connection::EgressConnectionStatistics; +use std::time::Duration; +use time::OffsetDateTime; + +// TODO: once created, move this struct to a shared models library +/// Captures the outcome of a single [`run_stress_test`](super::NodeStressTester::run_stress_test) run. +/// +/// Fields are populated incrementally as the test progresses; absent values (`None`) indicate +/// that the corresponding step was not reached or did not produce a result. +#[derive(Debug, Clone)] +pub(crate) struct TestRunResult { + /// The timestamp when the test run was initiated. + pub(crate) start_time: OffsetDateTime, + + /// Duration of the Noise handshake on the ingress (responder) side, if completed. + pub(crate) ingress_noise_handshake: Option, + + /// Duration of the Noise handshake on the egress (initiator) side, if completed. + pub(crate) egress_noise_handshake: Option, + + /// The (constant) delay of the sphinx packet set during the test run. + pub sphinx_packet_delay: Duration, + + /// Number of sphinx packets successfully sent to the node under test. + pub(crate) packets_sent: usize, + + /// Number of sphinx packets returned by the node and successfully received. + pub(crate) packets_received: usize, + + /// Round-trip time of the very first probe packet, sent in isolation before any load is applied. + /// Because the node is idle at this point, this value approximates the baseline network latency + /// to the node without any queuing or processing overhead from the stress test itself. + /// `None` if the initial probe did not complete successfully. + pub(crate) approximate_latency: Option, + + /// RTT statistics computed over all received packets, or `None` if no packets were received. + pub(crate) packets_statistics: Option, + + /// Latency distribution of individual batch send operations recorded during the load test. + /// Reflects how long each batch took to flush to the OS socket, giving a rough measure of + /// egress throughput. `None` if no batches were sent. + pub(crate) sending_statistics: Option, + + /// Whether any packet was received with an ID that had already been seen in this test run. + /// Duplicates should never occur under normal operation; their presence may indicate a + /// misbehaving or malicious node replaying packets. + pub(crate) received_duplicates: bool, + + /// Human-readable description of the first error that caused the test to abort if any. + pub(crate) error: Option, +} + +impl TestRunResult { + pub(crate) fn new(sphinx_packet_delay: Duration) -> Self { + TestRunResult { + start_time: OffsetDateTime::now_utc(), + ingress_noise_handshake: None, + egress_noise_handshake: None, + sphinx_packet_delay, + packets_sent: 0, + packets_received: 0, + approximate_latency: None, + packets_statistics: None, + sending_statistics: None, + received_duplicates: false, + error: None, + } + } + + /// Calculates the percentage of packets received out of the total sent. + pub(crate) fn received_percentage(&self) -> f64 { + if self.packets_sent > 0 { + (self.packets_received as f64 / self.packets_sent as f64) * 100.0 + } else { + 0.0 + } + } + + /// Records the duration of the ingress Noise handshake. + pub(crate) fn set_ingress_noise_handshake(&mut self, duration: Duration) { + self.ingress_noise_handshake = Some(duration); + } + + /// Records the duration of the egress Noise handshake. + pub(crate) fn set_egress_noise_handshake(&mut self, duration: Duration) { + self.egress_noise_handshake = Some(duration); + } + + /// Records the RTT of the initial probe packet as the baseline latency estimate. + pub(crate) fn set_approximate_latency(&mut self, rtt: Duration) { + self.approximate_latency = Some(rtt); + } + + /// Sets the number of packets that were sent during the stress test. + pub(crate) fn set_packets_sent(&mut self, count: usize) { + self.packets_sent = count; + } + + /// Sets the number of packets that were received back from the node under test. + pub(crate) fn set_packets_received(&mut self, count: usize) { + self.packets_received = count; + } + + /// Attaches pre-computed RTT statistics for the received packets. + pub(crate) fn set_packets_statistics(&mut self, stats: LatencyDistribution) { + self.packets_statistics = Some(stats); + } + + /// Marks that at least one duplicate packet ID was observed during the test run. + pub(crate) fn set_received_duplicates(&mut self) { + self.received_duplicates = true; + } + + /// Records an error message that caused the test run to abort. + pub(crate) fn set_error(&mut self, error: impl Into) { + self.error = Some(error.into()); + } + + /// Populates egress-side statistics from the finished [`EgressConnection`](crate::egress_connection::EgressConnection). + /// Sets the egress Noise handshake duration and, if any batches were sent, the batch send + /// latency distribution. + pub(crate) fn set_egress_connection_statistics(&mut self, stats: EgressConnectionStatistics) { + self.set_egress_noise_handshake(stats.noise_handshake_duration); + + if !stats.packet_batches_sending_duration.is_empty() { + self.sending_statistics = Some(LatencyDistribution::compute( + &stats.packet_batches_sending_duration, + )) + } + } +} + +/// Latency statistics computed over the set of test packets received or sent during a stress test. +#[derive(Debug, Copy, Clone, PartialEq, Eq)] +pub struct LatencyDistribution { + /// Minimum latency duration it took to send or receive a test packet. + pub minimum: Duration, + + /// Average latency duration it took to send or receive a test packet. + pub mean: Duration, + + /// Median latency duration it took to send or receive a test packet. + /// For an even number of samples, this is the arithmetic mean of the two middle values. + pub median: Duration, + + /// Maximum latency duration it took to send or receive a test packet. + pub maximum: Duration, + + /// The standard deviation of the latency duration it took to send or receive the test packets. + pub standard_deviation: Duration, +} + +impl LatencyDistribution { + /// Computes statistics from a slice of per-packet RTT durations. + /// Returns zeroed statistics if `raw_results` is empty. + pub fn compute(raw_results: &[Duration]) -> Self { + if raw_results.is_empty() { + return LatencyDistribution { + minimum: Duration::ZERO, + mean: Duration::ZERO, + median: Duration::ZERO, + maximum: Duration::ZERO, + standard_deviation: Duration::ZERO, + }; + } + + let mut sorted = raw_results.to_vec(); + sorted.sort(); + + let minimum = sorted[0]; + + // SAFETY: we have ensured our list is not empty + #[allow(clippy::unwrap_used)] + let maximum = *sorted.last().unwrap(); + let median = Self::duration_median(&sorted); + let mean = Self::duration_mean(&sorted); + let standard_deviation = Self::duration_standard_deviation(&sorted, mean); + + LatencyDistribution { + minimum, + mean, + median, + maximum, + standard_deviation, + } + } + + /// Computes the median of an already-sorted slice of durations. + /// For an even count, returns the arithmetic mean of the two middle elements. + /// Caller must ensure `sorted` is non-empty and ordered ascending. + fn duration_median(sorted: &[Duration]) -> Duration { + let len = sorted.len(); + let mid = len / 2; + if len % 2 == 1 { + sorted[mid] + } else { + (sorted[mid - 1] + sorted[mid]) / 2 + } + } + + /// Computes the arithmetic mean of a slice of durations. + /// Returns [`Duration::ZERO`] for an empty slice. + fn duration_mean(data: &[Duration]) -> Duration { + if data.is_empty() { + return Default::default(); + } + + let sum = data.iter().sum::(); + // packet counts realistically fit in a u32; a test sending 4 billion packets would + // have other problems first + let count = data.len() as u32; + + sum / count + } + + /// Computes the population standard deviation (divides by N, not N-1) of the RTT durations. + /// Precision is truncated to microseconds, which is sufficient for network latency. + fn duration_standard_deviation(data: &[Duration], mean: Duration) -> Duration { + if data.is_empty() { + return Default::default(); + } + + let variance_micros = data + .iter() + .map(|&value| { + let diff = mean.abs_diff(value); + // truncate to microseconds — nanosecond precision is noise for network RTTs + let diff_micros = diff.as_micros(); + diff_micros * diff_micros + }) + .sum::() + / data.len() as u128; + + // u128 easily holds squared microsecond values for any realistic RTT (< thousands of seconds) + let std_deviation_micros = (variance_micros as f64).sqrt() as u64; + Duration::from_micros(std_deviation_micros) + } +} + +impl From + for nym_network_monitor_orchestrator_requests::models::LatencyDistribution +{ + fn from(value: LatencyDistribution) -> Self { + Self { + minimum: value.minimum, + mean: value.mean, + median: value.median, + maximum: value.maximum, + standard_deviation: value.standard_deviation, + } + } +} + +impl From for nym_network_monitor_orchestrator_requests::models::TestRunResult { + fn from(value: TestRunResult) -> Self { + Self { + time_taken: (OffsetDateTime::now_utc() - value.start_time).unsigned_abs(), + ingress_noise_handshake: value.ingress_noise_handshake, + egress_noise_handshake: value.egress_noise_handshake, + sphinx_packet_delay: value.sphinx_packet_delay, + packets_sent: value.packets_sent, + packets_received: value.packets_received, + approximate_latency: value.approximate_latency, + packets_statistics: value.packets_statistics.map(Into::into), + sending_statistics: value.sending_statistics.map(Into::into), + received_duplicates: value.received_duplicates, + error: value.error, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + fn ms(n: u64) -> Duration { + Duration::from_millis(n) + } + + #[test] + fn empty_slice_gives_zero_stats() { + let stats = LatencyDistribution::compute(&[]); + assert_eq!(stats.minimum, Duration::ZERO); + assert_eq!(stats.maximum, Duration::ZERO); + assert_eq!(stats.mean, Duration::ZERO); + assert_eq!(stats.median, Duration::ZERO); + assert_eq!(stats.standard_deviation, Duration::ZERO); + } + + #[test] + fn single_value_has_zero_deviation() { + let stats = LatencyDistribution::compute(&[ms(42)]); + assert_eq!(stats.minimum, ms(42)); + assert_eq!(stats.maximum, ms(42)); + assert_eq!(stats.mean, ms(42)); + assert_eq!(stats.median, ms(42)); + assert_eq!(stats.standard_deviation, Duration::ZERO); + } + + #[test] + fn two_equal_values_have_zero_deviation() { + let stats = LatencyDistribution::compute(&[ms(10), ms(10)]); + assert_eq!(stats.mean, ms(10)); + assert_eq!(stats.median, ms(10)); + assert_eq!(stats.standard_deviation, Duration::ZERO); + } + + #[test] + fn median_odd_count_picks_middle() { + // sorted: 10, 20, 30, 40, 50 -> median = 30 + let data = [ms(40), ms(10), ms(50), ms(20), ms(30)]; + let stats = LatencyDistribution::compute(&data); + assert_eq!(stats.median, ms(30)); + } + + #[test] + fn median_even_count_averages_two_middle() { + // sorted: 10, 20, 30, 40 -> median = (20 + 30) / 2 = 25 + let data = [ms(30), ms(10), ms(40), ms(20)]; + let stats = LatencyDistribution::compute(&data); + assert_eq!(stats.median, ms(25)); + } + + #[test] + fn min_max_are_correct() { + let data = [ms(30), ms(10), ms(50), ms(20)]; + let stats = LatencyDistribution::compute(&data); + assert_eq!(stats.minimum, ms(10)); + assert_eq!(stats.maximum, ms(50)); + } + + #[test] + fn mean_is_correct() { + // mean of 10, 20, 30, 40 = 25 ms + let data = [ms(10), ms(20), ms(30), ms(40)]; + let stats = LatencyDistribution::compute(&data); + assert_eq!(stats.mean, ms(25)); + } + + #[test] + fn standard_deviation_known_values() { + // population std-dev of {10, 20, 30, 40} ms: + // mean = 25, deviations = {-15, -5, 5, 15} + // variance = (225 + 25 + 25 + 225) / 4 = 125 + // std-dev = sqrt(125) ≈ 11.180 ms → truncated to microseconds = 11180 µs + let data = [ms(10), ms(20), ms(30), ms(40)]; + let stats = LatencyDistribution::compute(&data); + let expected = Duration::from_micros(11180); + // allow ±1 µs for floating-point rounding + let diff = stats.standard_deviation.abs_diff(expected); + assert!( + diff <= Duration::from_micros(1), + "std-dev {:.3?} not within 1µs of expected {:.3?}", + stats.standard_deviation, + expected + ); + } + + #[test] + fn result_setters_populate_fields() { + let mut result = TestRunResult::new(ms(2)); + result.set_ingress_noise_handshake(ms(5)); + result.set_egress_noise_handshake(ms(7)); + result.set_packets_sent(100); + result.set_packets_received(95); + result.set_error("timeout"); + + let stats = LatencyDistribution::compute(&[ms(10), ms(20)]); + result.set_packets_statistics(stats); + + assert_eq!(result.ingress_noise_handshake, Some(ms(5))); + assert_eq!(result.egress_noise_handshake, Some(ms(7))); + assert_eq!(result.packets_sent, 100); + assert_eq!(result.packets_received, 95); + assert_eq!(result.packets_statistics, Some(stats)); + assert_eq!(result.error.as_deref(), Some("timeout")); + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/tested_node.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/tested_node.rs new file mode 100644 index 0000000000..5b4e16ed8a --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/tested_node.rs @@ -0,0 +1,53 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::sphinx_helpers::as_sphinx_node; +use nym_crypto::asymmetric::x25519; +use nym_network_monitor_orchestrator_requests::models::TestRunAssignment; +use nym_noise::config::{NoiseNode, NoiseVersion, VersionedNoiseKeyV1}; +use nym_sphinx_params::SphinxKeyRotation; +use std::net::SocketAddr; + +/// Identity and addressing information for the node being tested in a stress-test run. +#[derive(Debug)] +pub(crate) struct TestedNodeDetails { + pub(crate) node_id: Option, + + /// TCP socket address of the node's mixnet listener, used for the egress connection. + pub(crate) address: SocketAddr, + + /// Node's static Noise public key, used to authenticate and encrypt the egress connection. + pub(crate) noise_key: x25519::PublicKey, + + /// Key rotation associated with the current sphinx key of the node. + pub(crate) key_rotation: SphinxKeyRotation, + + /// Node's current sphinx public key, used to build the sphinx packet header. + pub(crate) sphinx_key: x25519::PublicKey, +} + +impl TestedNodeDetails { + pub(crate) fn from_testrun_assignment(assignment: TestRunAssignment) -> Self { + TestedNodeDetails { + node_id: Some(assignment.node_id), + address: assignment.node_address, + noise_key: assignment.noise_key, + key_rotation: SphinxKeyRotation::from_key_rotation_id(assignment.key_rotation_id), + sphinx_key: assignment.sphinx_key, + } + } + + /// Returns a sphinx [`Node`](nym_sphinx_types::Node) representation of this node, + /// suitable for use as a hop in a sphinx route. + pub(crate) fn as_sphinx_node(&self) -> nym_sphinx_types::Node { + as_sphinx_node(self.address, self.sphinx_key) + } + + /// Returns a [`NoiseNode`] representation of this node for use in the Noise network view. + pub(crate) fn as_noise_node(&self) -> NoiseNode { + NoiseNode::new_nym_node(VersionedNoiseKeyV1 { + supported_version: NoiseVersion::V1, + x25519_pubkey: self.noise_key, + }) + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/tester.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/tester.rs new file mode 100644 index 0000000000..f4277ce9d4 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/tester.rs @@ -0,0 +1,521 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::agent::config::NodeTesterConfig; +use crate::agent::result::{LatencyDistribution, TestRunResult}; +use crate::agent::tested_node::TestedNodeDetails; +use crate::egress_connection::EgressConnection; +use crate::listener::MixnetListener; +use crate::listener::received::MixnetPacketsSender; +use crate::processor::{MixnetPacketProcessor, ProcessedPacket}; +use crate::sphinx_helpers::{ + as_sphinx_node, build_test_sphinx_packet, create_test_sphinx_packet_header, +}; +use crate::test_packet::{TestPacketContent, TestPacketHeader}; +use anyhow::Context; +use humantime::format_duration; +use nym_crypto::asymmetric::x25519; +use nym_noise::config::{NoiseConfig, NoiseNetworkView}; +use nym_sphinx_types::SphinxPacket; +use nym_task::ShutdownToken; +use rand::rngs::OsRng; +use std::collections::HashMap; +use std::sync::Arc; +use std::time::Duration; +use tokio::pin; +use tokio::sync::Notify; +use tokio::time::{Instant, sleep}; +use tracing::{debug, error, info, warn}; + +/// The core component responsible for executing a stress-test run against a single node. +/// +/// A test run proceeds in five ordered steps (see [`run_stress_test`](Self::run_stress_test)): +/// +/// 1. Establish an outbound (egress) Noise-encrypted TCP connection to the node. +/// 2. Bind a local TCP listener (ingress) that receives sphinx packets the node sends back. +/// 3. Send a single probe packet to verify basic connectivity and record baseline latency. +/// 4. Replay the same packet (when `reuse_header` is enabled) to confirm the node's +/// bloomfilter bypass is correctly configured. +/// 5. Send packets at the configured rate for the configured duration, then collect and +/// summarise the results. +/// +/// Only critical failures (e.g. failing to bind a port) are returned as +/// `Err`; node-level failures (e.g. the node not responding) are captured inside the +/// returned [`TestRunResult`] so the caller can still inspect partial data. +pub(crate) struct NodeStressTester { + /// Tester configuration controlling rates, timeouts, and addressing. + config: NodeTesterConfig, + + /// Monotonically increasing counter embedded in each outgoing packet as its ID. + packet_counter: u64, + + /// Pre-built sphinx packet header reused across all packets when `config.reuse_header` + /// is set. Allows the node's bloomfilter bypass to be exercised. `None` means a fresh + /// header is built for every packet. + reusable_test_header: Option, + + /// The tester's own Noise key pair, used to authenticate the egress connection. + noise_key: Arc, + + /// An ephemeral sphinx key pair generated at construction time. Used both to build the + /// return-route sphinx header (so packets come back to this tester) and to decrypt + /// returning packets when `reuse_header` is disabled. + sphinx_key: Arc, + + /// Identity and addressing information for the node being tested. + tested_node: TestedNodeDetails, +} + +impl NodeStressTester { + /// Creates a new tester, loading the Noise private key from `noise_key_path` and + /// generating a fresh ephemeral sphinx key. If `config.reuse_header` is set, the + /// sphinx packet header is pre-built here so it can be reused across all test packets. + pub(crate) fn new( + config: NodeTesterConfig, + noise_key: Arc, + tested_node: TestedNodeDetails, + ) -> anyhow::Result { + debug!("using the following tester config"); + debug!("{config:#?}"); + + debug!("testing the following node"); + debug!("{tested_node:#?}"); + + let sphinx_key = x25519::PrivateKey::new(&mut OsRng); + + let reusable_test_header = if config.reuse_header { + debug!("reusing sphinx header for tests"); + // Route: tested node → this agent (so packets come back to us). + let route = [ + tested_node.as_sphinx_node(), + as_sphinx_node(config.external_mixnet_address, sphinx_key.public_key()), + ]; + let delay = config.packet_delay; + Some(create_test_sphinx_packet_header(route, delay)?) + } else { + debug!("new sphinx header will be generated for each new test packet"); + None + }; + + Ok(Self { + config, + packet_counter: 0, + reusable_test_header, + noise_key, + sphinx_key: Arc::new(sphinx_key.into()), + tested_node, + }) + } + + /// Opens the outbound Noise-encrypted TCP connection to the node under test. + async fn establish_egress_connection(&self) -> anyhow::Result { + EgressConnection::establish( + self.tested_node.address, + self.config.egress_connection_timeout, + self.tested_node.key_rotation, + &self.noise_config(), + ) + .await + } + + /// Constructs the [`MixnetPacketProcessor`] used to decode and time-stamp returning packets. + /// When a reusable header is available it is used for decryption; otherwise the tester's + /// sphinx private key is used directly. + fn build_packet_processor(&self) -> MixnetPacketProcessor { + let packet_recovery = match &self.reusable_test_header { + Some(header) => header.clone().into(), + None => self.sphinx_key.clone().into(), + }; + MixnetPacketProcessor::new(packet_recovery, self.config.waiting_duration) + } + + /// Binds the local TCP listener and wraps it in a [`MixnetListener`] that will forward + /// decoded packets to `received_sender`. + async fn build_mixnet_listener( + &self, + received_sender: MixnetPacketsSender, + shutdown_token: ShutdownToken, + ) -> anyhow::Result { + MixnetListener::new( + self.config.mixnet_bind_address, + self.tested_node.address, + self.noise_config(), + received_sender, + shutdown_token.clone(), + ) + .await + } + + /// Builds a [`NoiseConfig`] that contains the default configuration for the protocol + /// and the key associated with the tested node to accept its connection. + fn noise_config(&self) -> NoiseConfig { + let mut nodes = HashMap::new(); + nodes.insert( + self.tested_node.address.ip(), + self.tested_node.as_noise_node(), + ); + let network = NoiseNetworkView::new(nodes); + + NoiseConfig::new( + self.noise_key.clone(), + network, + self.config.noise_handshake_timeout, + ) + } + + /// Returns a sphinx node representation of this tester's own mixnet listener address, + /// used as the final hop in the packet route so packets are delivered back here. + fn as_sphinx_node(&self) -> nym_sphinx_types::Node { + as_sphinx_node( + self.config.external_mixnet_address, + *self.sphinx_key.public_key(), + ) + } + + /// Builds the next test sphinx packet, incrementing the internal packet counter. + /// Reuses the pre-built header when available; otherwise builds a fresh header and + /// encrypts it with a new sphinx key each time. + fn create_test_sphinx_packet(&mut self) -> anyhow::Result { + let content = TestPacketContent::new(self.packet_counter); + self.packet_counter += 1; + + match &self.reusable_test_header { + Some(header) => header.create_test_packet(content), + None => { + let route = [self.tested_node.as_sphinx_node(), self.as_sphinx_node()]; + build_test_sphinx_packet( + &route, + self.config.packet_delay, + None, + &content.to_bytes(), + ) + } + } + } + + /// Builds a batch of `batch_size` test sphinx packets with consecutive IDs. + fn create_packet_batch(&mut self, batch_size: usize) -> anyhow::Result> { + let mut packets = Vec::with_capacity(batch_size); + for _ in 0..batch_size { + let packet = self.create_test_sphinx_packet()?; + packets.push(packet); + } + Ok(packets) + } + + /// Computes the network latency for a received packet by subtracting the configured + /// sphinx delay from its measured round-trip time. + fn packet_latency(&self, received: ProcessedPacket) -> Duration { + received.rtt - self.config.packet_delay + } + + /// Creates and sends a single test sphinx packet over `egress`. + /// On send failure, records an error on `result` and returns `false`. + async fn send_test_packet( + &mut self, + egress: &mut EgressConnection, + result: &mut TestRunResult, + ) -> anyhow::Result { + let packet = self + .create_test_sphinx_packet() + .context("sphinx packet creation failure!")?; + if let Err(err) = egress.send_packet(packet).await { + result.set_error(format!("{:#}", err.context("failed to send test packet"))); + return Ok(false); + }; + Ok(true) + } + + /// Creates and sends a batch of `batch_size` test packets over `egress`. + /// On send failure, records an error on `result` and returns `false`. + async fn send_test_packet_batch( + &mut self, + batch_size: usize, + egress: &mut EgressConnection, + result: &mut TestRunResult, + ) -> anyhow::Result { + let batch = self + .create_packet_batch(batch_size) + .context("sphinx packet batch creation failure!")?; + + if let Err(err) = egress.send_packet_batch(batch).await { + result.set_error(format!("{:#}", err.context("failed to send test packet"))); + return Ok(false); + }; + Ok(true) + } + + /// Sends a single packet and waits for it to come back. + /// On success, sets `approximate_latency` on the result and returns `true`. + /// On failure, sets an error on the result and returns `false` (caller should abort). + async fn send_connectivity_probe( + &mut self, + egress: &mut EgressConnection, + processor: &mut MixnetPacketProcessor, + result: &mut TestRunResult, + ) -> anyhow::Result { + if !self.send_test_packet(egress, result).await? { + return Ok(false); + } + + match processor.next_packet().await { + Ok(res) => { + result.set_approximate_latency(self.packet_latency(res)); + Ok(true) + } + Err(err) => { + result.set_error(format!( + "{:#}", + err.context("failed to receive a valid initial packet back") + )); + Ok(false) + } + } + } + + /// Replays a packet to verify that the node's bloomfilter bypass is correctly configured. + /// Returns `true` if the packet was returned, `false` if the node failed the check (caller should abort). + /// Should only be called when `config.reuse_header` is set. + async fn send_bloomfilter_probe( + &mut self, + egress: &mut EgressConnection, + processor: &mut MixnetPacketProcessor, + result: &mut TestRunResult, + ) -> anyhow::Result { + info!("repeating the packet to check bloomfilter bypass configuration"); + if !self.send_test_packet(egress, result).await? { + return Ok(false); + } + + match processor.next_packet().await { + Ok(res) => { + info!("received {res}"); + Ok(true) + } + Err(err) => { + result.set_error(format!( + "{:#}", + err.context("failed to receive a valid secondary packet back - the node might not have a working chain subscriber (or the agent might be misconfigured)")) + ); + Ok(false) + } + } + } + + /// Sends packets at the configured rate for the configured duration. + /// Dispatches one batch every `batch_interval` seconds; if the egress falls behind, + /// ticks are delayed rather than bunched up to avoid unintended bursts. + /// Updates `result.packets_sent` after every batch and returns `false` on send failure. + async fn send_load_test( + &mut self, + egress: &mut EgressConnection, + result: &mut TestRunResult, + ) -> anyhow::Result { + // one batch every (sending_batch_size / target_rate) seconds keeps us at the target rate + let batch_interval = self.config.batch_interval(); + let mut interval = tokio::time::interval(batch_interval); + // if we fall behind, don't try to catch up with burst sends + interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay); + + let start = Instant::now(); + let mut sent = 0; + let total_packets = self.config.expected_packets(); + + loop { + if start.elapsed() >= self.config.sending_duration { + break; + } + if sent >= total_packets { + break; + } + interval.tick().await; + + // the last batch may be smaller than other batches + let remaining = total_packets - sent; + let batch_size = self.config.sending_batch_size.min(remaining); + if !self + .send_test_packet_batch(batch_size, egress, result) + .await? + { + return Ok(false); + } + + sent += batch_size; + // update send count after each batch so partial results are visible on early exit + result.set_packets_sent(sent); + } + + if sent < total_packets { + warn!( + "did not manage to send all required packets within the sending window. sent {sent}/{total_packets}" + ); + } + Ok(true) + } + + /// Drains all received packets from `processor` (waiting up to `waiting_duration` for + /// stragglers), deduplicates by ID, computes RTT statistics, and populates `result`. + async fn collect_test_results( + &self, + processor: &mut MixnetPacketProcessor, + result: &mut TestRunResult, + ) { + // drain whatever arrived immediately, then wait for stragglers + let mut received = processor.all_available(); + if received.len() < result.packets_sent { + let deadline = sleep(self.config.waiting_duration); + pin!(deadline); + loop { + tokio::select! { + _ = &mut deadline => break, + next = processor.next_packet() => { + received.push(next); + if received.len() >= result.packets_sent { + break; + } + } + } + } + } + + // deduplicate by packet ID; duplicates indicate possible node misbehaviour + let mut valid_received = HashMap::new(); + for packet in received { + let Ok(packet) = packet else { + debug!("received packet was malformed"); + continue; + }; + if valid_received.insert(packet.id, packet).is_some() { + error!( + "‼️ received duplicate packet for id {} - something nasty is going on!", + packet.id + ); + result.set_received_duplicates(); + } + } + + let latencies = valid_received + .values() + .map(|p| self.packet_latency(*p)) + .collect::>(); + + let received_count = valid_received.len(); + result.set_packets_received(received_count); + result.set_packets_statistics(LatencyDistribution::compute(&latencies)); + + debug!( + sent = result.packets_sent, + received = received_count, + recv_pct = format!("{:.1}%", result.received_percentage()), + "load test complete" + ); + } + + /// Runs a full stress-test against the configured node and returns the collected results. + /// + /// Only returns `Err` for critical failures (e.g. unable to bind the listener + /// port). Node-level failures (no response, bloomfilter misconfiguration, etc.) are + /// recorded inside the returned [`TestRunResult`] so the caller always gets partial data. + pub(crate) async fn run_stress_test(&mut self) -> anyhow::Result { + let node_address = self.tested_node.address; + if let Some(node_id) = self.tested_node.node_id { + info!("beginning stress test of node {node_id} ({node_address})",); + } else { + info!("beginning stress test of node {node_address}",); + } + + let mut result = TestRunResult::new(self.config.packet_delay); + + // 1. establish the egress connection — abort immediately if it fails + debug!("attempting to establish egress connection to the tested node"); + let mut egress = match self.establish_egress_connection().await { + Ok(conn) => conn, + Err(err) => { + result.set_error(format!( + "{:#}", + err.context("failed to establish egress node connection") + )); + return Ok(result); + } + }; + + // 2. spawn the mixnet packet listener that forwards received packets to the processor + debug!( + "creating mixnet listener on {}", + self.config.mixnet_bind_address + ); + let mut processor = self.build_packet_processor(); + let shutdown_token = ShutdownToken::new(); + let listener = self + .build_mixnet_listener(processor.sender(), shutdown_token.clone()) + .await?; + let listener_on_start = Arc::new(Notify::new()); + let listener_on_start_clone = listener_on_start.clone(); + + let listener_join = + tokio::spawn(async move { listener.run(listener_on_start_clone).await }); + + // wait for the listener task to properly begin + listener_on_start.notified().await; + + // 3. probe: send a single packet to confirm the node responds + debug!("sending initial node connectivity probe"); + if !self + .send_connectivity_probe(&mut egress, &mut processor, &mut result) + .await? + { + shutdown_token.cancel(); + let _ = listener_join.await?; + return Ok(result); + } + + // 4. probe: replay the packet to verify bloomfilter bypass is configured + debug!("sending bloomfilter probe"); + if self.config.reuse_header + && !self + .send_bloomfilter_probe(&mut egress, &mut processor, &mut result) + .await? + { + shutdown_token.cancel(); + let mixnet_listener = listener_join.await?; + let ingress_noise = mixnet_listener + .last_noise_handshake_duration + .context("missing ingress noise duration after completing entire test run!")?; + + result.set_ingress_noise_handshake(ingress_noise); + result.set_egress_connection_statistics(egress.connection_statistics); + return Ok(result); + } + + // 5. stress test: send packets at the target rate for the configured duration + debug!( + "beginning the proper load testing. going to send at rate {}/s for {}", + self.config.target_rate, + format_duration(self.config.sending_duration) + ); + self.send_load_test(&mut egress, &mut result).await?; + + // 6. collect and summarise results + debug!("waiting for final packets to arrive"); + self.collect_test_results(&mut processor, &mut result).await; + + // 7. shut down the listener and harvest its stats + debug!("shutting down the mixnet listener and finishing the test"); + shutdown_token.cancel(); + let mixnet_listener = listener_join.await?; + let ingress_noise = mixnet_listener + .last_noise_handshake_duration + .context("missing ingress noise duration after completing entire test run!")?; + + result.set_ingress_noise_handshake(ingress_noise); + result.set_egress_connection_statistics(egress.connection_statistics); + + if let Some(node_id) = self.tested_node.node_id { + info!("finished stress test of node {node_id} ({node_address})",); + } else { + info!("finished stress test of node {node_address}",); + } + + Ok(result) + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/cli/build_info.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/cli/build_info.rs new file mode 100644 index 0000000000..a5b80d67bf --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/cli/build_info.rs @@ -0,0 +1,15 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use nym_bin_common::bin_info_owned; +use nym_bin_common::output_format::OutputFormat; + +#[derive(clap::Args, Debug)] +pub(crate) struct Args { + #[clap(short, long, default_value_t = OutputFormat::default())] + output: OutputFormat, +} + +pub(crate) fn execute(args: Args) { + println!("{}", args.output.format(&bin_info_owned!())) +} diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/cli/common.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/cli/common.rs new file mode 100644 index 0000000000..94eed06d95 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/cli/common.rs @@ -0,0 +1,88 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use super::env::vars::*; +use crate::agent::config::NodeTesterConfig; +use anyhow::bail; +use std::net::SocketAddr; +use std::num::NonZeroUsize; +use std::time::Duration; + +#[derive(clap::Args, Debug)] +pub(crate) struct CommonArgs { + /// Specifies for how long the agent should be sending test packets with the specified rate. + #[arg(long, value_parser = humantime::parse_duration, default_value = "30s", env = NYM_NETWORK_MONITOR_AGENT_SENDING_DURATION_ARG)] + sending_duration: Duration, + + /// Specifies how long the agent will wait to receive any leftover packets after finishing sending. + #[arg(long, value_parser = humantime::parse_duration, default_value = "5s", env = NYM_NETWORK_MONITOR_AGENT_WAITING_DURATION_ARG)] + waiting_duration: Duration, + + /// How long the node itself should delay the packet + /// It shouldn't be set to zero as otherwise the node will not put the packet through + /// its delay queue and we would not test the entire pipeline + #[arg(long, value_parser = humantime::parse_duration, default_value = "50ms", env = NYM_NETWORK_MONITOR_AGENT_PACKET_DELAY_ARG)] + packet_delay: Duration, + + /// Specifies the target rate of packets (per second) to be sent. + #[arg(long, default_value = "1000", env = NYM_NETWORK_MONITOR_AGENT_TARGET_RATE_ARG)] + target_rate: NonZeroUsize, + + /// Specifies whether the agent should reuse the same header for all packets. + /// And consequently replay them + #[arg(long, short, default_value = "true", env = NYM_NETWORK_MONITOR_AGENT_REUSE_HEADER_ARG)] + reuse_header: bool, + + /// Timeout for establishing the TCP connection to the node under test. + #[arg(long, value_parser = humantime::parse_duration, default_value = "5s", env = NYM_NETWORK_MONITOR_AGENT_EGRESS_CONNECTION_TIMEOUT_ARG)] + egress_connection_timeout: Duration, + + /// Timeout for completing the Noise handshake with the node under test. + #[arg(long, value_parser = humantime::parse_duration, default_value = "3s", env = NYM_NETWORK_MONITOR_AGENT_NOISE_HANDSHAKE_TIMEOUT_ARG)] + noise_handshake_timeout: Duration, + + /// Number of packets sent in a single batch. Together with `target_rate` this controls + /// how frequently batches are dispatched: one batch every `sending_batch_size / target_rate` seconds. + #[arg(long, default_value = "50", env = NYM_NETWORK_MONITOR_AGENT_SENDING_BATCH_SIZE_ARG)] + sending_batch_size: NonZeroUsize, + + /// Specifies the path to the noise key file used for establishing tunnel with the node being tested + #[arg(long, env = NYM_NETWORK_MONITOR_AGENT_NOISE_KEY_PATH_ARG)] + pub(crate) noise_key_path: String, + + /// Specifies the socket address the agent will bind to for receiving mixnet traffic. + #[arg(long, env = NYM_NETWORK_MONITOR_AGENT_BIND_ADDRESS_ARG, default_value = "[::]:9000")] + bind_address: SocketAddr, +} + +impl CommonArgs { + /// Constructs a [`NodeTesterConfig`] from the common CLI arguments. + /// `mixnet_address` is provided separately as it is command-specific. + pub(crate) fn build_config( + &self, + external_address: SocketAddr, + ) -> anyhow::Result { + if self.sending_duration.is_zero() { + bail!("attempted to set sending duration to 0s") + } + if self.egress_connection_timeout.is_zero() { + bail!("attempted to set egress connection timeout to 0s") + } + if self.noise_handshake_timeout.is_zero() { + bail!("attempted to set noise handshake timeout to 0s") + } + + Ok(NodeTesterConfig { + sending_duration: self.sending_duration, + waiting_duration: self.waiting_duration, + packet_delay: self.packet_delay, + egress_connection_timeout: self.egress_connection_timeout, + noise_handshake_timeout: self.noise_handshake_timeout, + sending_batch_size: self.sending_batch_size.get(), + target_rate: self.target_rate.get(), + reuse_header: self.reuse_header, + mixnet_bind_address: self.bind_address, + external_mixnet_address: external_address, + }) + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/cli/env.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/cli/env.rs new file mode 100644 index 0000000000..2a12a6fe67 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/cli/env.rs @@ -0,0 +1,48 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +/// Environment variable names used as fallbacks for CLI arguments. +/// Each constant matches the `env = ...` attribute on the corresponding clap field. +pub mod vars { + // common args + pub const NYM_NETWORK_MONITOR_AGENT_SENDING_DURATION_ARG: &str = + "NYM_NETWORK_MONITOR_AGENT_SENDING_DURATION"; + pub const NYM_NETWORK_MONITOR_AGENT_WAITING_DURATION_ARG: &str = + "NYM_NETWORK_MONITOR_AGENT_WAITING_DURATION"; + pub const NYM_NETWORK_MONITOR_AGENT_TARGET_RATE_ARG: &str = + "NYM_NETWORK_MONITOR_AGENT_TARGET_RATE"; + pub const NYM_NETWORK_MONITOR_AGENT_REUSE_HEADER_ARG: &str = + "NYM_NETWORK_MONITOR_AGENT_REUSE_HEADER"; + pub const NYM_NETWORK_MONITOR_AGENT_NOISE_KEY_PATH_ARG: &str = + "NYM_NETWORK_MONITOR_AGENT_NOISE_KEY_PATH"; + pub const NYM_NETWORK_MONITOR_AGENT_PACKET_DELAY_ARG: &str = + "NYM_NETWORK_MONITOR_AGENT_PACKET_DELAY"; + pub const NYM_NETWORK_MONITOR_AGENT_EGRESS_CONNECTION_TIMEOUT_ARG: &str = + "NYM_NETWORK_MONITOR_AGENT_EGRESS_CONNECTION_TIMEOUT"; + pub const NYM_NETWORK_MONITOR_AGENT_NOISE_HANDSHAKE_TIMEOUT_ARG: &str = + "NYM_NETWORK_MONITOR_AGENT_NOISE_HANDSHAKE_TIMEOUT"; + pub const NYM_NETWORK_MONITOR_AGENT_SENDING_BATCH_SIZE_ARG: &str = + "NYM_NETWORK_MONITOR_AGENT_SENDING_BATCH_SIZE"; + pub const NYM_NETWORK_MONITOR_AGENT_BIND_ADDRESS_ARG: &str = + "NYM_NETWORK_MONITOR_AGENT_BIND_ADDRESS"; + + // run agent args + pub const NYM_NETWORK_MONITOR_AGENT_ORCHESTRATOR_ADDRESS_ARG: &str = + "NYM_NETWORK_MONITOR_AGENT_ORCHESTRATOR_ADDRESS"; + pub const NYM_NETWORK_MONITOR_AGENT_ORCHESTRATOR_TOKEN_ARG: &str = + "NYM_NETWORK_MONITOR_AGENT_ORCHESTRATOR_TOKEN"; + pub const NYM_NETWORK_MONITOR_AGENT_HOST_IP_ARG: &str = "NYM_NETWORK_MONITOR_AGENT_HOST_IP"; + pub const NYM_NETWORK_MONITOR_AGENT_HOST_PORT_ARG: &str = "NYM_NETWORK_MONITOR_AGENT_HOST_PORT"; + + // test node args + pub const NYM_NETWORK_MONITOR_AGENT_MIXNET_ADDRESS_ARG: &str = + "NYM_NETWORK_MONITOR_AGENT_MIXNET_ADDRESS"; + pub const NYM_NETWORK_MONITOR_AGENT_NODE_ADDRESS_ARG: &str = + "NYM_NETWORK_MONITOR_AGENT_NODE_ADDRESS"; + pub const NYM_NETWORK_MONITOR_AGENT_NODE_NOISE_KEY_ARG: &str = + "NYM_NETWORK_MONITOR_AGENT_NODE_NOISE_KEY"; + pub const NYM_NETWORK_MONITOR_AGENT_NODE_SPHINX_KEY_ARG: &str = + "NYM_NETWORK_MONITOR_AGENT_NODE_SPHINX_KEY"; + pub const NYM_NETWORK_MONITOR_AGENT_NODE_SPHINX_KEY_ROTATION_ARG: &str = + "NYM_NETWORK_MONITOR_AGENT_NODE_SPHINX_KEY_ROTATION"; +} diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/cli/keygen.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/cli/keygen.rs new file mode 100644 index 0000000000..a1771fc508 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/cli/keygen.rs @@ -0,0 +1,24 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use super::env::vars::*; +use nym_crypto::asymmetric::x25519; +use tracing::info; + +/// Arguments for the `keygen` subcommand. +#[derive(clap::Args, Debug)] +pub(crate) struct Args { + /// Specifies the path to the noise key file used for establishing tunnel with the node being tested + #[arg(long, env = NYM_NETWORK_MONITOR_AGENT_NOISE_KEY_PATH_ARG)] + noise_key_path: String, +} + +/// Generates a fresh x25519 Noise private key and writes it to the path specified in `args`. +pub(crate) fn execute(args: Args) -> anyhow::Result<()> { + let mut rng = rand::thread_rng(); + let noise_key = x25519::PrivateKey::new(&mut rng); + + nym_pemstore::store_key(&noise_key, &args.noise_key_path)?; + info!("noise key written to '{}'", args.noise_key_path); + Ok(()) +} diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/cli/mod.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/cli/mod.rs new file mode 100644 index 0000000000..d271f10b60 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/cli/mod.rs @@ -0,0 +1,56 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use clap::{Parser, Subcommand}; +use nym_bin_common::bin_info; +use std::sync::OnceLock; + +mod build_info; +mod common; +mod env; +mod keygen; +mod run_agent; +mod test_node; + +// Helper for passing LONG_VERSION to clap +fn pretty_build_info_static() -> &'static str { + static PRETTY_BUILD_INFORMATION: OnceLock = OnceLock::new(); + PRETTY_BUILD_INFORMATION.get_or_init(|| bin_info!().pretty_print()) +} + +/// Top-level CLI entry point for the network monitor agent. +#[derive(Parser, Debug)] +#[clap(author = "Nymtech", version, long_version = pretty_build_info_static(), about)] +pub(crate) struct Cli { + #[command(subcommand)] + pub(crate) command: Command, +} + +impl Cli { + /// Dispatches execution to the subcommand selected by the user. + pub(crate) async fn execute(self) -> anyhow::Result<()> { + match self.command { + Command::BuildInfo(args) => build_info::execute(args), + Command::TestNode(args) => test_node::execute(args).await?, + Command::RunAgent(args) => run_agent::execute(args).await?, + Command::Keygen(args) => keygen::execute(args)?, + } + Ok(()) + } +} + +#[derive(Subcommand, Debug)] +pub(crate) enum Command { + /// Show build information of this binary + BuildInfo(build_info::Args), + + /// One-shot manual testing of a specified node + /// without interacting with the orchestrator. + TestNode(test_node::Args), + + /// Test a node by contacting the orchestrator for the work assignment + RunAgent(run_agent::Args), + + /// Generate all required keys for the agent to work + Keygen(keygen::Args), +} diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/cli/run_agent.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/cli/run_agent.rs new file mode 100644 index 0000000000..eba620e58a --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/cli/run_agent.rs @@ -0,0 +1,63 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use super::env::vars::*; +use crate::agent::NetworkMonitorAgent; +use crate::agent::helpers::load_noise_key; +use crate::cli::common::CommonArgs; +use nym_network_monitor_orchestrator_requests::client::OrchestratorClient; +use std::net::{IpAddr, SocketAddr}; +use tracing::info; +use url::Url; + +#[derive(clap::Args, Debug)] +pub(crate) struct Args { + #[clap(flatten)] + common_args: CommonArgs, + + /// Address of the orchestrator for requesting work assignments + #[clap(long, env = NYM_NETWORK_MONITOR_AGENT_ORCHESTRATOR_ADDRESS_ARG)] + orchestrator_address: Url, + + /// Bearer token required for requesting work assignments + /// and submitting the results + #[clap(long, env = NYM_NETWORK_MONITOR_AGENT_ORCHESTRATOR_TOKEN_ARG)] + orchestrator_token: String, + + /// Egress IP address of this agent, retrieved from status.hostIP via the Downward API + #[clap(long, env = NYM_NETWORK_MONITOR_AGENT_HOST_IP_ARG)] + host_ip: IpAddr, + + /// Announced port of this agent, used alongside host_ip by nodes sending packets back to the agent + #[clap(long, env = NYM_NETWORK_MONITOR_AGENT_HOST_PORT_ARG)] + host_port: u16, +} + +pub(crate) async fn execute(args: Args) -> anyhow::Result<()> { + let orchestrator_client = + OrchestratorClient::new(args.orchestrator_address.into(), args.orchestrator_token)?; + + let noise_key = load_noise_key(&args.common_args.noise_key_path)?; + + let external_address = SocketAddr::new(args.host_ip, args.host_port); + + // 1. build instance of the agent (loads the noise keys) + let agent = NetworkMonitorAgent::new( + args.common_args.build_config(external_address)?, + noise_key, + orchestrator_client, + ); + + // 2. announce the agent to the orchestrator + // so that it would be registered in the smart contract + // (if it hasn't been announced before) + info!("announcing agent information to the orchestrator"); + agent.announce_agent().await?; + + // 3. query the orchestrator for work assignment and attempt to perform the stress test + // of the target node + info!("attempting to request test run assignment"); + agent.run_stress_test().await?; + + Ok(()) +} diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/cli/test_node.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/cli/test_node.rs new file mode 100644 index 0000000000..1e6c7542fa --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/cli/test_node.rs @@ -0,0 +1,77 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use super::env::vars::*; +use crate::agent::config::NodeTesterConfig; +use crate::agent::helpers::load_noise_key; +use crate::agent::tested_node::TestedNodeDetails; +use crate::agent::tester::NodeStressTester; +use crate::cli::common::CommonArgs; +use nym_crypto::asymmetric::x25519; +use nym_sphinx_params::SphinxKeyRotation; +use std::net::SocketAddr; +use tracing::info; + +/// Arguments for the `test-node` subcommand. +#[derive(clap::Args, Debug)] +pub(crate) struct Args { + #[clap(flatten)] + common_args: CommonArgs, + + /// The socket address of the agent to use for receiving test packets back + #[arg(long, env = NYM_NETWORK_MONITOR_AGENT_MIXNET_ADDRESS_ARG)] + agent_mixnet_listener: SocketAddr, + + /// The socket address of the node to test + #[arg(long, env = NYM_NETWORK_MONITOR_AGENT_NODE_ADDRESS_ARG)] + tested_node_address: SocketAddr, + + /// Noise key of the node to test + #[arg(long, env = NYM_NETWORK_MONITOR_AGENT_NODE_NOISE_KEY_ARG)] + tested_node_noise_key: x25519::PublicKey, + + /// Sphinx key of the node to test + #[arg(long, env = NYM_NETWORK_MONITOR_AGENT_NODE_SPHINX_KEY_ARG)] + tested_node_sphinx_key: x25519::PublicKey, + + /// Current sphinx key rotation of the node to test + #[arg(long, env = NYM_NETWORK_MONITOR_AGENT_NODE_SPHINX_KEY_ROTATION_ARG)] + tested_node_sphinx_key_rotation: u32, +} + +impl Args { + /// Builds the agent [`NodeTesterConfig`] from the flattened common args and the local mixnet listener address. + pub(crate) fn build_tester_config(&self) -> anyhow::Result { + self.common_args.build_config(self.agent_mixnet_listener) + } + + /// Builds the [`TestedNodeDetails`] from the node address and key arguments. + pub(crate) fn build_tested_node_details(&self) -> TestedNodeDetails { + TestedNodeDetails { + node_id: None, + address: self.tested_node_address, + noise_key: self.tested_node_noise_key, + sphinx_key: self.tested_node_sphinx_key, + key_rotation: SphinxKeyRotation::from_key_rotation_id( + self.tested_node_sphinx_key_rotation, + ), + } + } + + /// Constructs a fully initialised [`NodeStressTester`] from the parsed arguments. + pub(crate) fn build_stress_tester(&self) -> anyhow::Result { + NodeStressTester::new( + self.build_tester_config()?, + load_noise_key(&self.common_args.noise_key_path)?, + self.build_tested_node_details(), + ) + } +} + +/// Runs a one-shot stress test against the specified node and logs the result. +pub(crate) async fn execute(args: Args) -> anyhow::Result<()> { + let result = args.build_stress_tester()?.run_stress_test().await?; + + info!("{result:#?}"); + Ok(()) +} diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/egress_connection.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/egress_connection.rs new file mode 100644 index 0000000000..5eea7ceb15 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/egress_connection.rs @@ -0,0 +1,123 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use anyhow::bail; +use futures::{SinkExt, stream}; +use humantime::format_duration; +use nym_noise::config::NoiseConfig; +use nym_noise::connection::Connection; +use nym_noise::upgrade_noise_initiator; +use nym_sphinx_framing::codec::NymCodec; +use nym_sphinx_framing::packet::FramedNymPacket; +use nym_sphinx_params::{PacketType, SphinxKeyRotation}; +use nym_sphinx_types::{NymPacket, SphinxPacket}; +use std::net::SocketAddr; +use tokio::net::TcpStream; +use tokio::time::{Instant, timeout}; +use tokio_util::codec::Framed; +use tracing::{error, info, trace}; + +/// Timing statistics collected over the lifetime of an [`EgressConnection`]. +pub(crate) struct EgressConnectionStatistics { + /// Duration of the Noise handshake performed when the connection was established. + pub(crate) noise_handshake_duration: std::time::Duration, + + /// Per-batch send durations, one entry for each call to [`send_packet_batch`](EgressConnection::send_packet_batch). + pub(crate) packet_batches_sending_duration: Vec, +} + +/// An outbound, noise-encrypted TCP connection to the node under test used for sending sphinx packets. +pub(crate) struct EgressConnection { + /// Timing statistics accumulated while the connection is active. + pub(crate) connection_statistics: EgressConnectionStatistics, + + /// The key rotation at the time of starting the agent. + key_rotation: SphinxKeyRotation, + + /// The noise-encrypted, framed TCP stream used to send sphinx packets. + mixnet_connection: Framed, NymCodec>, +} + +impl EgressConnection { + /// Opens a TCP connection to `address`, performs the Noise handshake as the initiator, + /// and returns a ready-to-use [`EgressConnection`]. + /// Fails if the TCP connect or Noise upgrade exceeds timeout. + pub(crate) async fn establish( + address: SocketAddr, + timeout_duration: std::time::Duration, + key_rotation: SphinxKeyRotation, + noise_config: &NoiseConfig, + ) -> anyhow::Result { + info!("attempting to establish connection to {address}"); + let stream = timeout(timeout_duration, TcpStream::connect(address)).await??; + + info!("beginning the noise handshake (initiator)"); + + let noise_handshake_start = Instant::now(); + let noise_stream = upgrade_noise_initiator(stream, noise_config).await?; + + if !noise_stream.is_noise() { + error!( + "failed to upgrade the connection to noise with {address}. does the node support the protocol?" + ); + bail!("egress connection failure"); + } + + let noise_handshake_duration = noise_handshake_start.elapsed(); + info!( + "noise handshake with {address} completed in {}", + format_duration(noise_handshake_duration) + ); + + Ok(Self { + connection_statistics: EgressConnectionStatistics { + noise_handshake_duration, + packet_batches_sending_duration: vec![], + }, + key_rotation, + mixnet_connection: Framed::new(noise_stream, NymCodec), + }) + } + + /// Sends a single sphinx packet and records the send duration in [`EgressConnectionStatistics`]. + pub(crate) async fn send_packet(&mut self, packet: SphinxPacket) -> anyhow::Result<()> { + self.mixnet_connection + .send(FramedNymPacket::new( + NymPacket::Sphinx(packet), + PacketType::Mix, + self.key_rotation, + false, + )) + .await?; + + Ok(()) + } + + /// Sends a batch of sphinx packets in one flushed write and records the total batch send duration. + pub(crate) async fn send_packet_batch( + &mut self, + packets: Vec, + ) -> anyhow::Result<()> { + let count = packets.len(); + let send_start = Instant::now(); + self.mixnet_connection + .send_all(&mut stream::iter(packets.into_iter().map(|p| { + Ok(FramedNymPacket::new( + NymPacket::Sphinx(p), + PacketType::Mix, + self.key_rotation, + false, + )) + }))) + .await?; + let elapsed = send_start.elapsed(); + self.connection_statistics + .packet_batches_sending_duration + .push(elapsed); + trace!( + "sent batch of {count} packets in {}", + format_duration(elapsed) + ); + Ok(()) + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/listener/mod.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/listener/mod.rs new file mode 100644 index 0000000000..90817f277c --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/listener/mod.rs @@ -0,0 +1,167 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::listener::received::{MixnetPacketsSender, ReceivedPacket}; +use futures::StreamExt; +use nym_noise::config::NoiseConfig; +use nym_noise::connection::Connection; +use nym_noise::upgrade_noise_responder; +use nym_sphinx_framing::codec::NymCodec; +use nym_task::ShutdownToken; +use std::net::SocketAddr; +use std::sync::Arc; +use tokio::net::TcpStream; +use tokio::sync::Notify; +use tokio::time::Instant; +use tokio_util::codec::Framed; +use tracing::{error, info, warn}; + +pub(crate) mod received; + +/// Listens for inbound sphinx packets returned by the node under test. +/// +/// Binds a TCP listener on `bind_address`, accepts a single connection at a time, +/// performs a Noise handshake as the responder, then forwards every decoded +/// [`NymPacket`] to the [`receiver`](received) via `received_packets_sender`. +/// Connections from any address other than `tested_node_address` are rejected. +pub(crate) struct MixnetListener { + /// Local TCP listener. + tcp_listener: tokio::net::TcpListener, + + /// Address of the node being tested; connections from any other source are rejected. + tested_node_address: SocketAddr, + + /// Noise protocol configuration used when upgrading incoming TCP connections. + noise_config: NoiseConfig, + + /// Channel used to forward received packets to the [`PacketReceiver`](received). + received_packets_sender: MixnetPacketsSender, + + /// Duration it took to complete the last Noise handshake as the responder. + pub(crate) last_noise_handshake_duration: Option, + + /// Global shutdown token + shutdown: ShutdownToken, +} + +impl MixnetListener { + /// Creates a new [`MixnetListener`] ready to be started with [`run`](Self::run). + pub(crate) async fn new( + bind_address: SocketAddr, + tested_node_address: SocketAddr, + noise_config: NoiseConfig, + received_packets_sender: MixnetPacketsSender, + shutdown: ShutdownToken, + ) -> anyhow::Result { + info!("attempting to run mixnet listener on {bind_address}"); + + let tcp_listener = tokio::net::TcpListener::bind(bind_address) + .await + .inspect_err(|err| { + error!("Failed to the mixnet listener bind to {bind_address}: {err}") + })?; + + Ok(Self { + tcp_listener, + tested_node_address, + noise_config, + received_packets_sender, + last_noise_handshake_duration: None, + shutdown, + }) + } + + /// Reads sphinx packets from an established, noise-encrypted stream and forwards + /// each one to the receiver until the connection is closed or an error occurs. + async fn handle_stream(&self, mut mixnet_connection: Framed, NymCodec>) { + loop { + tokio::select! { + biased; + _ = self.shutdown.cancelled() => { + tracing::debug!("mixnet listener: received shutdown"); + return + } + next_packet = mixnet_connection.next() => { + let next_packet = match next_packet { + None => { + info!("mixnet connection closed"); + return; + } + Some(Ok(packet)) => packet, + Some(Err(err)) => { + error!("failed to read a packet from the mixnet connection: {err}"); + return; + } + }; + if self + .received_packets_sender + .unbounded_send(ReceivedPacket::new(next_packet)) + .is_err() + { + warn!("mixnet packet receiver has shut down - is the agent still running?"); + return; + } + } + } + } + } + + /// Validates the source address, performs the Noise handshake, then delegates to + /// [`handle_stream`](Self::handle_stream) for the lifetime of the connection. + async fn handle_connection(&mut self, (socket, source): (TcpStream, SocketAddr)) { + if source.ip() != self.tested_node_address.ip() { + warn!( + "received a connection from a source that's not the node being tested. Ignoring it. Source: {source}, tested node: {}", + self.tested_node_address + ); + return; + } + info!("accepted connection from {source}. beginning the noise handshake (responder)"); + + let noise_handshake_start = Instant::now(); + let noise_stream = match upgrade_noise_responder(socket, &self.noise_config).await { + Ok(noise_stream) => noise_stream, + Err(err) => { + error!("failed to upgrade the connection to noise with {source}: {err}"); + return; + } + }; + let noise_handshake_duration = noise_handshake_start.elapsed(); + + if !noise_stream.is_noise() { + error!( + "failed to upgrade the connection to noise with {source}. does the node support the protocol?" + ); + return; + } + self.last_noise_handshake_duration = Some(noise_handshake_duration); + + self.handle_stream(Framed::new(noise_stream, NymCodec)) + .await + } + + /// Processes one connection at a time until the shutdown token is cancelled. + /// Returns `self` so that the caller can inspect fields such as + /// [`last_noise_handshake_duration`](Self::last_noise_handshake_duration) after the run. + pub(crate) async fn run(mut self, on_start: Arc) -> Self { + on_start.notify_waiters(); + // only handle a single connection at once + // (we don't need more than that) + loop { + tokio::select! { + biased; + _ = self.shutdown.cancelled() => { + tracing::debug!("mixnet listener: received shutdown"); + return self + } + connection = self.tcp_listener.accept() => { + if let Ok(connection) = connection { + self.handle_connection(connection).await; + } else { + error!("failed to accept a TCP connection from the mixnet listener"); + } + } + } + } + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/listener/received.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/listener/received.rs new file mode 100644 index 0000000000..8a9371c3d4 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/listener/received.rs @@ -0,0 +1,32 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use futures::channel::mpsc::{UnboundedReceiver, UnboundedSender}; +use nym_sphinx_framing::packet::FramedNymPacket; +use time::OffsetDateTime; + +/// A sphinx packet received by the [`MixnetListener`](super::MixnetListener), bundled with its +/// wall-clock arrival time. +pub(crate) struct ReceivedPacket { + /// UTC timestamp at which the packet was pulled off the stream. + pub(crate) received_at: OffsetDateTime, + + /// The decoded sphinx packet as delivered by the framed codec. + pub(crate) received: FramedNymPacket, +} + +impl ReceivedPacket { + /// Wraps `received` and stamps it with the current UTC time. + pub(crate) fn new(received: FramedNymPacket) -> Self { + Self { + received_at: OffsetDateTime::now_utc(), + received, + } + } +} + +/// Sender half of the channel used to forward [`ReceivedPacket`]s from the listener to the processor. +pub(crate) type MixnetPacketsSender = UnboundedSender; + +/// Receiver half of the channel used to forward [`ReceivedPacket`]s from the listener to the processor. +pub(crate) type MixnetPacketsReceiver = UnboundedReceiver; diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/main.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/main.rs new file mode 100644 index 0000000000..bb002e0e48 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/main.rs @@ -0,0 +1,47 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::cli::Cli; +use clap::Parser; +use nym_bin_common::logging::tracing_subscriber::layer::SubscriberExt; +use nym_bin_common::logging::tracing_subscriber::util::SubscriberInitExt; +use nym_bin_common::logging::{ + default_tracing_env_filter, default_tracing_fmt_layer, tracing_subscriber, +}; +use tracing::info; + +mod agent; +pub(crate) mod cli; +mod egress_connection; +pub(crate) mod listener; +mod processor; +pub(crate) mod sphinx_helpers; +pub(crate) mod test_packet; + +fn setup_logger() -> anyhow::Result<()> { + // crates that are more granularly filtered, regardless of default `RUST_LOG` value + let filter_crates = ["reqwest", "hyper"]; + + let mut env_filter = default_tracing_env_filter(); + for crate_name in filter_crates { + env_filter = env_filter.add_directive(format!("{crate_name}=warn").parse()?); + } + + tracing_subscriber::registry() + .with(default_tracing_fmt_layer(std::io::stderr)) + .with(env_filter) + .init(); + + Ok(()) +} + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + setup_logger()?; + let cli = Cli::parse(); + + cli.execute().await?; + + info!("network monitor agent is done - quitting"); + Ok(()) +} diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/processor.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/processor.rs new file mode 100644 index 0000000000..8b3a6812e5 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/processor.rs @@ -0,0 +1,165 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::listener::received::{MixnetPacketsReceiver, MixnetPacketsSender, ReceivedPacket}; +use crate::test_packet::{TestPacketContent, TestPacketHeader}; +use anyhow::{Context, bail}; +use futures::StreamExt; +use futures::channel::mpsc::unbounded; +use nym_crypto::asymmetric::x25519; +use nym_sphinx_types::{ProcessedPacketData, SphinxPacket}; +use std::fmt::Display; +use std::sync::Arc; +use std::time::Duration; +use tokio::time::timeout; +use tracing::{debug, warn}; + +/// A decoded test packet together with its measured round-trip time. +#[derive(Debug, Clone, Copy)] +pub(crate) struct ProcessedPacket { + /// The packet ID copied from the embedded [`TestPacketContent`]. + pub(crate) id: u64, + + /// Round-trip time measured from when the packet was created to when it was received. + /// This includes both the sphinx delay and the network transit time; callers should + /// subtract `config.packet_delay` to obtain the network-only latency. + pub(crate) rtt: Duration, +} + +impl Display for ProcessedPacket { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "{}: {}", self.id, humantime::format_duration(self.rtt)) + } +} + +/// Strategy used to decrypt a returning sphinx packet and extract its [`TestPacketContent`]. +/// +/// When the agent operates with a reusable header it already holds the payload key, so +/// only the payload needs unwrapping. When it builds a fresh header per-packet the full +/// sphinx processing path (DH + decryption) must be performed using the agent's private key. +pub(crate) enum PayloadRecovery { + /// The agent holds a pre-built [`TestPacketHeader`] whose payload key can be used to + /// unwrap the payload directly, skipping the full sphinx processing step. + ReusableHeader(TestPacketHeader), + + /// The agent must perform full sphinx processing using its private key to decrypt + /// the payload, as no pre-built header is available. + FullProcessing(Arc), +} + +impl From for PayloadRecovery { + fn from(header: TestPacketHeader) -> Self { + PayloadRecovery::ReusableHeader(header) + } +} + +impl From> for PayloadRecovery { + fn from(private_key: Arc) -> Self { + PayloadRecovery::FullProcessing(private_key) + } +} + +impl PayloadRecovery { + /// Decrypts `received` and deserialises its payload into a [`TestPacketContent`]. + /// Returns an error if decryption fails or the packet is not addressed to the final hop. + pub(crate) fn recover_test_payload( + &self, + received: SphinxPacket, + ) -> anyhow::Result { + match self { + PayloadRecovery::ReusableHeader(header) => header.recover_payload(received.payload), + PayloadRecovery::FullProcessing(private_key) => { + let ProcessedPacketData::FinalHop { payload, .. } = + received.process(private_key.private_key().inner())?.data + else { + bail!("received non final hop data") + }; + TestPacketContent::from_bytes(&payload.recover_plaintext()?) + } + } + } +} + +/// Receives raw sphinx packets forwarded by the [`MixnetListener`](crate::listener::MixnetListener), +/// decrypts them, and exposes them as [`ProcessedPacket`]s with RTT measurements. +/// +/// The processor owns one half of an unbounded channel; the sender half is cloned and handed +/// to the listener via [`sender`](Self::sender). Packets can be consumed one at a time with +/// [`next_packet`](Self::next_packet) or drained in bulk with [`all_available`](Self::all_available). +pub(crate) struct MixnetPacketProcessor { + /// Decryption strategy: either reuse a pre-built header or perform full sphinx processing. + payload_recovery: PayloadRecovery, + + /// How long [`next_packet`](Self::next_packet) will wait before returning a timeout error. + receive_timeout: Duration, + + /// Sender half kept alive so the channel stays open as long as the processor exists. + sender: MixnetPacketsSender, + + /// Receiver half polled by [`next_packet`](Self::next_packet) and [`all_available`](Self::all_available). + receiver: MixnetPacketsReceiver, +} + +impl MixnetPacketProcessor { + /// Creates a new processor along with an internal channel for receiving packets. + pub(crate) fn new(payload_recovery: PayloadRecovery, receive_timeout: Duration) -> Self { + let (sender, receiver) = unbounded(); + + Self { + payload_recovery, + receive_timeout, + sender, + receiver, + } + } + + /// Returns a clone of the sender half so the listener can forward packets to this processor. + pub(crate) fn sender(&self) -> MixnetPacketsSender { + self.sender.clone() + } + + /// Decrypts a [`ReceivedPacket`] and computes its RTT from the embedded send timestamp. + fn process_received(&self, packet: ReceivedPacket) -> anyhow::Result { + let sphinx_packet = packet + .received + .into_inner() + .to_sphinx_packet() + .context("the received packet was not a sphinx packet!")?; + let received_content = self.payload_recovery.recover_test_payload(sphinx_packet)?; + let latency = packet.received_at - received_content.sending_timestamp; + + Ok(ProcessedPacket { + id: received_content.id, + rtt: latency.unsigned_abs(), + }) + } + + /// Drains all packets currently available in the channel without blocking. + /// Returns a vec of results — decryption failures are included as `Err` entries rather + /// than causing the entire drain to abort. + pub(crate) fn all_available(&mut self) -> Vec> { + let mut packets = Vec::new(); + while let Ok(Some(pending)) = self.receiver.try_next() { + packets.push(self.process_received(pending)); + } + + debug!("drained {} immediately available packets", packets.len()); + packets + } + + /// Waits for the next packet, up to `receive_timeout`. + /// Returns `Err` on timeout, channel exhaustion, or decryption failure. + pub(crate) async fn next_packet(&mut self) -> anyhow::Result { + let packet = timeout(self.receive_timeout, self.receiver.next()) + .await + .inspect_err(|_| { + warn!( + "timed out waiting for next packet after {}", + humantime::format_duration(self.receive_timeout) + ) + })? + .context("stream has been exhausted")?; + + self.process_received(packet) + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/sphinx_helpers.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/sphinx_helpers.rs new file mode 100644 index 0000000000..f1ba355097 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/sphinx_helpers.rs @@ -0,0 +1,264 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::test_packet::TestPacketHeader; +use arrayref::array_ref; +use hkdf::Hkdf; +use nym_crypto::aes::cipher::crypto_common::rand_core::OsRng; +use nym_crypto::asymmetric::x25519; +use nym_sphinx_addressing::nodes::NymNodeRoutingAddress; +use nym_sphinx_params::PacketSize; +use nym_sphinx_types::constants::{ + BLINDING_FACTOR_SIZE, EXPANDED_SHARED_SECRET_HKDF_INFO, EXPANDED_SHARED_SECRET_HKDF_SALT, + EXPANDED_SHARED_SECRET_LENGTH, INTEGRITY_MAC_KEY_SIZE, PAYLOAD_KEY_SEED_SIZE, +}; +use nym_sphinx_types::crypto::STREAM_CIPHER_KEY_SIZE; +use nym_sphinx_types::{ + DESTINATION_ADDRESS_LENGTH, Delay, Destination, DestinationAddressBytes, IDENTIFIER_LENGTH, + Node, PAYLOAD_KEY_SIZE, PayloadKey, SphinxPacket, SphinxPacketBuilder, derive_payload_key, +}; +use sha2::Sha256; +use std::net::SocketAddr; +use std::time::Duration; +use x25519_dalek::{PublicKey, StaticSecret}; + +/// Newtype wrapper around the HKDF-expanded shared secret used in the sphinx protocol +/// since the actual type within the sphinx library does not expose the required methods. +pub(crate) struct ExpandedSharedSecretWrapper(pub(crate) [u8; EXPANDED_SHARED_SECRET_LENGTH]); + +impl ExpandedSharedSecretWrapper { + /// Returns the blinding factor as an x25519 [`StaticSecret`], used to derive the + /// shared secret for the next hop when manually reconstructing payload keys. + pub(crate) fn blinding_factor(&self) -> StaticSecret { + StaticSecret::from(*self.blinding_factor_bytes()) + } + + /// Returns the raw blinding factor bytes. + pub(crate) fn blinding_factor_bytes(&self) -> &[u8; BLINDING_FACTOR_SIZE] { + array_ref!( + &self.0, + STREAM_CIPHER_KEY_SIZE + INTEGRITY_MAC_KEY_SIZE + PAYLOAD_KEY_SIZE, + BLINDING_FACTOR_SIZE + ) + } + + /// Returns the payload key seed, used as input to [`derive_payload_key`]. + pub(crate) fn payload_key_seed(&self) -> &[u8; PAYLOAD_KEY_SEED_SIZE] { + array_ref!( + &self.0, + STREAM_CIPHER_KEY_SIZE + INTEGRITY_MAC_KEY_SIZE, + PAYLOAD_KEY_SEED_SIZE + ) + } + + /// Derives the [`PayloadKey`] for this hop from the payload key seed. + pub(crate) fn derive_payload_key(&self) -> PayloadKey { + derive_payload_key(self.payload_key_seed()) + } +} + +/// Re-derives the expanded shared secret from a raw 32-byte DH shared secret using HKDF-SHA256 +/// with the sphinx protocol's standard salt and info strings. +/// +/// This mirrors the derivation performed inside the sphinx library, which is not publicly +/// exposed — hence the need to replicate it here when reconstructing payload keys for a +/// reusable header. +pub(crate) fn rederive_expanded_shared_secret( + shared_secret: &[u8; 32], +) -> ExpandedSharedSecretWrapper { + let hkdf = Hkdf::::new(Some(EXPANDED_SHARED_SECRET_HKDF_SALT), shared_secret); + + let mut output = [0u8; EXPANDED_SHARED_SECRET_LENGTH]; + // SAFETY: the length of the provided okm is within the allowed range + #[allow(clippy::unwrap_used)] + hkdf.expand(EXPANDED_SHARED_SECRET_HKDF_INFO, &mut output) + .unwrap(); + + ExpandedSharedSecretWrapper(output) +} + +/// Returns an all-zeroes [`Destination`] used as a placeholder for the final delivery address. +/// The sphinx protocol requires a destination, but for the agent's loopback packets the +/// address is irrelevant — the final hop (the agent itself) is already in the route. +fn dummy_destination() -> Destination { + Destination::new( + DestinationAddressBytes::from_bytes([0u8; DESTINATION_ADDRESS_LENGTH]), + [0u8; IDENTIFIER_LENGTH], + ) +} + +/// Builds a single test sphinx packet along `route` with the given per-hop `delay`. +/// +/// The packet uses [`PacketSize::AckPacket`] to keep its size as small as possible. If `initial_secret` +/// is provided it is used as the sender's ephemeral key, allowing the resulting header to +/// be deterministically reproduced (needed for `create_test_sphinx_packet_header`). +pub(crate) fn build_test_sphinx_packet( + route: &[Node; 2], + delay: Duration, + initial_secret: Option<&StaticSecret>, + message: &[u8], +) -> anyhow::Result { + let delays = [ + Delay::new_from_nanos(delay.as_nanos() as u64), + Delay::new_from_nanos(delay.as_nanos() as u64), + ]; + let destination = dummy_destination(); + let payload = PacketSize::AckPacket.payload_size(); + + let packet = match initial_secret { + None => SphinxPacketBuilder::new() + .with_payload_size(payload) + .build_packet(message, route, &destination, &delays), + Some(initial_secret) => SphinxPacketBuilder::new() + .with_payload_size(payload) + .with_initial_secret(initial_secret) + .build_packet(message, route, &destination, &delays), + }?; + + Ok(packet) +} + +/// Builds a [`TestPacketHeader`] that can be reused to send many packets with different +/// payloads but the same routing header. +/// +/// Internally this builds one full sphinx packet to capture the header, then manually +/// re-derives the per-hop payload keys by replaying the DH key-agreement steps along the +/// route. This is necessary because the sphinx library does not expose the payload keys +/// after packet construction. +/// +/// The derived `payload_key` vec has one entry per hop; the last entry (index 1) is the +/// key held by this agent as the final recipient and is used by [`TestPacketHeader::recover_payload`]. +pub(crate) fn create_test_sphinx_packet_header( + route: [Node; 2], + delay: Duration, +) -> anyhow::Result { + let initial_secret = StaticSecret::random_from_rng(OsRng); + + // Build a throwaway packet solely to capture the reusable header. + let packet = build_test_sphinx_packet(&route, delay, Some(&initial_secret), b"dummy-message")?; + + let header = packet.header; + + // Manually reconstruct the payload keys for each hop. + let mut expanded_shared_secrets = Vec::new(); + let mut blinding_factors = Vec::new(); + + // The sphinx library keeps these private, so we replicate the derivation: + // for each hop, apply all previous blinding factors to the node's public key + // via DH, then expand the result with HKDF to obtain the payload key. + for node in &route { + let mut acc = node.pub_key; + + for blinding_factor in std::iter::once(&initial_secret).chain(&blinding_factors) { + let shared_secret = blinding_factor.diffie_hellman(&acc); + acc = PublicKey::from(shared_secret.to_bytes()); + } + + let expanded_shared_secret = rederive_expanded_shared_secret(acc.as_bytes()); + blinding_factors.push(expanded_shared_secret.blinding_factor()); + expanded_shared_secrets.push(expanded_shared_secret); + } + + let payload_keys = expanded_shared_secrets + .iter() + .map(|s| s.derive_payload_key()) + .collect::>(); + assert_eq!(payload_keys.len(), 2); + + Ok(TestPacketHeader { + header, + payload_key: payload_keys, + }) +} + +/// Constructs a sphinx [`Node`](Node) from a socket address and public key. +/// Panics if the address cannot be converted to a routing address, which should never happen +/// for a valid `SocketAddr`. +pub(crate) fn as_sphinx_node(address: SocketAddr, pub_key: x25519::PublicKey) -> Node { + // SAFETY: we know that the address is valid, so we can safely unwrap it + #[allow(clippy::unwrap_used)] + Node::new( + NymNodeRoutingAddress::from(address).try_into().unwrap(), + pub_key.into(), + ) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::test_packet::TestPacketContent; + use nym_crypto::asymmetric::x25519; + use nym_sphinx_addressing::nodes::NymNodeRoutingAddress; + use nym_sphinx_types::ProcessedPacketData; + use nym_test_utils::helpers::deterministic_rng; + use std::net::SocketAddr; + + #[test] + fn creating_test_sphinx_packets() { + let mut rng = deterministic_rng(); + let remote_node_key = x25519::KeyPair::new(&mut rng); + let agent_key = x25519::KeyPair::new(&mut rng); + let node_addr: SocketAddr = "1.2.3.4:5677".parse().unwrap(); + let agent_addr: SocketAddr = "2.2.3.4:5678".parse().unwrap(); + + let remote_node = Node::new( + NymNodeRoutingAddress::from(node_addr).try_into().unwrap(), + (*remote_node_key.public_key()).into(), + ); + let agent_node = Node::new( + NymNodeRoutingAddress::from(agent_addr).try_into().unwrap(), + (*agent_key.public_key()).into(), + ); + + let delay = Duration::from_millis(1); + + let test_header = + create_test_sphinx_packet_header([remote_node, agent_node], delay).unwrap(); + + let payload1 = TestPacketContent::new(123); + let payload2 = TestPacketContent::new(456); + + let packet1 = test_header.create_test_packet(payload1).unwrap(); + let packet2 = test_header.create_test_packet(payload2).unwrap(); + + // simulate packet being received by remote node + let res1 = packet1 + .process(remote_node_key.private_key().inner()) + .unwrap(); + let ProcessedPacketData::ForwardHop { + next_hop_packet: res1_packet, + next_hop_address, + .. + } = res1.data + else { + panic!("bad data") + }; + assert_eq!( + next_hop_address, + NymNodeRoutingAddress::from(agent_addr).try_into().unwrap() + ); + + let res2 = packet2 + .process(remote_node_key.private_key().inner()) + .unwrap(); + let ProcessedPacketData::ForwardHop { + next_hop_packet: res2_packet, + next_hop_address, + .. + } = res2.data + else { + panic!("bad data") + }; + assert_eq!( + next_hop_address, + NymNodeRoutingAddress::from(agent_addr).try_into().unwrap() + ); + + // now getting back to us (no need for full unwrapping as we already have the payload key) + let received1 = test_header.recover_payload(res1_packet.payload).unwrap(); + assert_eq!(received1, payload1); + + let received2 = test_header.recover_payload(res2_packet.payload).unwrap(); + assert_eq!(received2, payload2); + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/test_packet.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/test_packet.rs new file mode 100644 index 0000000000..58603cfad3 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/test_packet.rs @@ -0,0 +1,204 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use anyhow::{Context, bail}; +use nym_sphinx_params::PacketSize; +use nym_sphinx_types::{Payload, PayloadKey, SphinxHeader, SphinxPacket}; +use time::OffsetDateTime; + +/// A pre-built sphinx packet header that can be reused across multiple test packets. +/// +/// When `config.reuse_header` is enabled the agent constructs one header for the entire +/// test run and stamps a fresh [`TestPacketContent`] (new ID + timestamp) into each +/// packet's payload. This lets the agent avoid performing expensive packet derivation +/// for each sent payload. +pub(crate) struct TestPacketHeader { + /// The immutable sphinx routing header shared across all replayed packets. + pub(crate) header: SphinxHeader, + + /// List of payload keys derived when the header was built + pub(crate) payload_key: Vec, +} + +impl Clone for TestPacketHeader { + fn clone(&self) -> Self { + TestPacketHeader { + header: SphinxHeader { + shared_secret: self.header.shared_secret, + routing_info: self.header.routing_info.clone(), + }, + payload_key: self.payload_key.clone(), + } + } +} + +impl TestPacketHeader { + /// Encapsulates `content` into a new [`SphinxPacket`] by reusing the pre-built header. + pub(crate) fn create_test_packet( + &self, + content: TestPacketContent, + ) -> anyhow::Result { + let payload = Payload::encapsulate_message( + &content.to_bytes(), + &self.payload_key, + PacketSize::AckPacket.payload_size(), + )?; + Ok(SphinxPacket { + header: SphinxHeader { + shared_secret: self.header.shared_secret, + routing_info: self.header.routing_info.clone(), + }, + payload, + }) + } + + /// Decrypts a received payload using the last payload key (the one belonging to this + /// agent as the final hop) and deserialises it into a [`TestPacketContent`]. + pub(crate) fn recover_payload(&self, received: Payload) -> anyhow::Result { + let key = self + .payload_key + .last() + .context("no payload keys generated")?; + + let payload = received.unwrap(key)?.recover_plaintext()?; + TestPacketContent::from_bytes(&payload) + } +} + +/// The payload embedded in every test sphinx packet. +/// +/// Serialises to exactly 16 bytes: 8 bytes for `id` (big-endian `u64`) followed by +/// 8 bytes for `sending_timestamp` (big-endian Unix timestamp in nanoseconds as `i64`). +/// Nanosecond precision is preserved for dates up to year 2262 (i64 max ≈ 9.2*10^18 ns). +/// The timestamp is used to compute the packet's round-trip time on receipt. +#[derive(Copy, Clone, PartialEq, Debug)] +pub(crate) struct TestPacketContent { + /// Monotonically increasing ID assigned by the agent; used to detect duplicates and + /// correlate sent packets with received ones. + pub(crate) id: u64, + + /// UTC wall-clock time at which the packet was created, used to compute RTT. + pub(crate) sending_timestamp: OffsetDateTime, +} + +impl TestPacketContent { + /// Creates a new content value with the given `id` and the current UTC time. + pub(crate) fn new(id: u64) -> Self { + Self { + id, + sending_timestamp: OffsetDateTime::now_utc(), + } + } + + /// Serialises the content to 16 bytes: `id` as big-endian u64, then + /// `sending_timestamp` as a big-endian i64 Unix timestamp in nanoseconds. + pub(crate) fn to_bytes(self) -> Vec { + let mut bytes = Vec::with_capacity(16); + bytes.extend_from_slice(&self.id.to_be_bytes()); + // unix_timestamp_nanos() returns i128, but the value fits in i64 for dates up to year 2262. + #[allow(clippy::cast_possible_truncation)] + bytes.extend_from_slice( + &(self.sending_timestamp.unix_timestamp_nanos() as i64).to_be_bytes(), + ); + bytes + } + + /// Deserialises content from a 16-byte slice produced by [`to_bytes`](Self::to_bytes). + /// Returns an error if the slice is not exactly 16 bytes or the timestamp is out of range. + pub(crate) fn from_bytes(bytes: &[u8]) -> anyhow::Result { + if bytes.len() != 16 { + bail!("malformed test packet received") + } + + let id = u64::from_be_bytes(bytes[0..8].try_into()?); + let nanos = i64::from_be_bytes(bytes[8..16].try_into()?); + Ok(Self { + id, + sending_timestamp: OffsetDateTime::from_unix_timestamp_nanos(nanos as i128)?, + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use time::macros::datetime; + + fn content_with_timestamp(id: u64, ts: OffsetDateTime) -> TestPacketContent { + TestPacketContent { + id, + sending_timestamp: ts, + } + } + + #[test] + fn serialised_length_is_always_16_bytes() { + let content = TestPacketContent::new(0); + assert_eq!(content.to_bytes().len(), 16); + } + + #[test] + fn roundtrip_preserves_all_fields() { + // Use a fixed timestamp to avoid sub-nanosecond clock jitter in the test. + let original = content_with_timestamp(42, datetime!(2025-06-01 12:00:00 UTC)); + let bytes = original.to_bytes(); + let recovered = TestPacketContent::from_bytes(&bytes).unwrap(); + assert_eq!(original, recovered); + } + + #[test] + fn roundtrip_preserves_nanosecond_precision() { + // Construct a timestamp with a sub-second component to verify nanos are not truncated. + let ts = datetime!(2025-06-01 12:00:00.123456789 UTC); + let original = content_with_timestamp(1, ts); + let recovered = TestPacketContent::from_bytes(&original.to_bytes()).unwrap(); + assert_eq!( + original.sending_timestamp.unix_timestamp_nanos(), + recovered.sending_timestamp.unix_timestamp_nanos() + ); + } + + #[test] + fn id_zero_and_max_roundtrip() { + for id in [0u64, u64::MAX] { + let original = content_with_timestamp(id, datetime!(2025-01-01 00:00:00 UTC)); + let recovered = TestPacketContent::from_bytes(&original.to_bytes()).unwrap(); + assert_eq!(recovered.id, id); + } + } + + #[test] + fn id_is_encoded_in_first_8_bytes_big_endian() { + let content = content_with_timestamp(1, datetime!(2025-01-01 00:00:00 UTC)); + let bytes = content.to_bytes(); + let id_bytes: [u8; 8] = bytes[0..8].try_into().unwrap(); + assert_eq!(u64::from_be_bytes(id_bytes), 1u64); + } + + #[test] + fn timestamp_is_encoded_in_last_8_bytes_big_endian() { + let ts = datetime!(2025-01-01 00:00:00 UTC); + let content = content_with_timestamp(0, ts); + let bytes = content.to_bytes(); + let ts_bytes: [u8; 8] = bytes[8..16].try_into().unwrap(); + assert_eq!( + i64::from_be_bytes(ts_bytes), + ts.unix_timestamp_nanos() as i64 + ); + } + + #[test] + fn from_bytes_rejects_too_short() { + assert!(TestPacketContent::from_bytes(&[0u8; 15]).is_err()); + } + + #[test] + fn from_bytes_rejects_too_long() { + assert!(TestPacketContent::from_bytes(&[0u8; 17]).is_err()); + } + + #[test] + fn from_bytes_rejects_empty() { + assert!(TestPacketContent::from_bytes(&[]).is_err()); + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/Cargo.toml b/nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/Cargo.toml new file mode 100644 index 0000000000..9a738326f2 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "nym-network-monitor-orchestrator-requests" +authors.workspace = true +repository.workspace = true +homepage.workspace = true +documentation.workspace = true +edition.workspace = true +license.workspace = true +rust-version.workspace = true +readme.workspace = true +version.workspace = true +publish = false + +[dependencies] +anyhow = { workspace = true } +humantime-serde = { workspace = true } +serde = { workspace = true, features = ["derive"] } +time = { workspace = true, features = ["serde-well-known"] } +tracing = { workspace = true } +utoipa = { workspace = true, optional = true } +zeroize = { workspace = true, optional = true } + +nym-crypto = { workspace = true, features = ["asymmetric", "serde"] } +nym-http-api-client = { workspace = true, optional = true } + +[features] +client = ["nym-http-api-client", "zeroize"] +openapi = ["utoipa"] + +[lints] +workspace = true diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/src/api/mod.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/src/api/mod.rs new file mode 100644 index 0000000000..bdc05451cb --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/src/api/mod.rs @@ -0,0 +1,2 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/src/client.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/src/client.rs new file mode 100644 index 0000000000..6d840dc68b --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/src/client.rs @@ -0,0 +1,81 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::models::{ + AgentAnnounceRequest, AgentAnnounceResponse, TestRunAssignmentRequest, + TestRunAssignmentResponse, TestRunResultSubmissionRequest, TestRunSubmissionResponse, +}; +use crate::routes::v1::agent::{ + announce_absolute, request_testrun_absolute, submit_testrun_absolute, +}; +pub use nym_http_api_client::Client; +use nym_http_api_client::{ApiClient, HttpClientError, NO_PARAMS, Url, parse_response}; +use serde::{Deserialize, Serialize}; +use std::sync::Arc; +use zeroize::Zeroizing; + +/// HTTP client for communicating with the network monitor orchestrator API. +/// All requests are authenticated with a bearer token. +pub struct OrchestratorClient { + inner: Client, + bearer_token: Arc>, +} + +impl OrchestratorClient { + /// Creates a new client targeting `base_url`, storing the bearer token in a + /// zeroizing container. + pub fn new(base_url: Url, bearer_token: String) -> Result { + Ok(OrchestratorClient { + inner: Client::builder(base_url)? + .no_hickory_dns() + .with_user_agent(format!( + "nym-network-monitor-orchestrator-requests/{}", + env!("CARGO_PKG_VERSION") + )) + .build()?, + bearer_token: Arc::new(Zeroizing::new(bearer_token)), + }) + } + + /// Sends an authenticated POST request with a JSON body and deserialises the response. + async fn post_with_auth(&self, path: &str, json_body: &B) -> Result + where + B: Serialize + ?Sized + Sync, + for<'a> T: Deserialize<'a>, + { + let res = self + .inner + .create_post_request(path, NO_PARAMS, json_body)? + .bearer_auth(self.bearer_token.as_str()) + .send() + .await?; + + parse_response(res, false).await + } + + /// Announces this agent's details to the orchestrator, which forwards them + /// to the smart contract so network nodes can whitelist the agent. + pub async fn announce_agent( + &self, + body: &AgentAnnounceRequest, + ) -> Result { + self.post_with_auth(&announce_absolute(), body).await + } + + /// Asks the orchestrator for the next test run to execute. Returns `None` + /// inside the assignment if no work is currently available. + pub async fn request_work_assignment( + &self, + body: &TestRunAssignmentRequest, + ) -> Result { + self.post_with_auth(&request_testrun_absolute(), body).await + } + + /// Submits the result of a completed test run back to the orchestrator for storage. + pub async fn submit_test_run_result( + &self, + body: &TestRunResultSubmissionRequest, + ) -> Result { + self.post_with_auth(&submit_testrun_absolute(), body).await + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/src/lib.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/src/lib.rs new file mode 100644 index 0000000000..34b32f9c01 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/src/lib.rs @@ -0,0 +1,91 @@ +// Copyright 2026 Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +pub mod api; +pub mod models; + +#[cfg(feature = "client")] +pub mod client; + +/// Generates a function that returns the full absolute path for a route +/// by concatenating a parent prefix with a suffix. +macro_rules! absolute_route { + ( $name:ident, $parent:expr, $suffix:expr ) => { + pub fn $name() -> String { + format!("{}{}", $parent, $suffix) + } + }; +} + +/// Route constants and absolute-path helpers for the orchestrator HTTP API. +/// Used by both the orchestrator server (for route registration) and the agent +/// client (for constructing request URLs). +pub mod routes { + pub const ROOT: &str = "/"; + pub const V1: &str = "/v1"; + pub const SWAGGER: &str = "/swagger"; + + pub mod v1 { + pub const AGENT: &str = "/agent"; + pub const METRICS: &str = "/metrics"; + pub const RESULTS: &str = "/results"; + + absolute_route!(agent_absolute, super::V1, AGENT); + absolute_route!(metrics_absolute, super::V1, METRICS); + absolute_route!(results_absolute, super::V1, RESULTS); + + pub mod agent { + use super::*; + + pub const ANNOUNCE: &str = "/announce"; + pub const REQUEST_TESTRUN: &str = "/request-testrun"; + pub const SUBMIT_TESTRUN_RESULT: &str = "/submit-testrun-result"; + + absolute_route!(announce_absolute, agent_absolute(), ANNOUNCE); + absolute_route!(request_testrun_absolute, agent_absolute(), REQUEST_TESTRUN); + absolute_route!( + submit_testrun_absolute, + agent_absolute(), + SUBMIT_TESTRUN_RESULT + ); + } + + pub mod metrics { + use super::*; + + pub const PROMETHEUS: &str = "/prometheus"; + + absolute_route!(prometheus_absolute, metrics_absolute(), PROMETHEUS); + } + + pub mod results { + use super::*; + + pub const TESTRUN_BY_ID: &str = "/testrun/:id"; + pub const NYM_NODE_BY_NODE_ID: &str = "/nym-node/:node_id"; + pub const NYM_NODE_TESTRUNS: &str = "/nym-node/:node_id/testruns"; + pub const TESTRUNS_IN_PROGRESS: &str = "/testruns-in-progress"; + pub const TESTRUNS: &str = "/testruns"; + pub const NYM_NODES: &str = "/nym-nodes"; + + absolute_route!(testrun_by_id_absolute, results_absolute(), TESTRUN_BY_ID); + absolute_route!( + nym_node_by_node_id_absolute, + results_absolute(), + NYM_NODE_BY_NODE_ID + ); + absolute_route!( + nym_node_testruns_absolute, + results_absolute(), + NYM_NODE_TESTRUNS + ); + absolute_route!( + testruns_in_progress_absolute, + results_absolute(), + TESTRUNS_IN_PROGRESS + ); + absolute_route!(testruns_absolute, results_absolute(), TESTRUNS); + absolute_route!(nym_nodes_absolute, results_absolute(), NYM_NODES); + } + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/src/models.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/src/models.rs new file mode 100644 index 0000000000..da1bc36ff0 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/src/models.rs @@ -0,0 +1,378 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use nym_crypto::asymmetric::ed25519; +use nym_crypto::asymmetric::ed25519::serde_helpers::bs58_ed25519_pubkey; +use nym_crypto::asymmetric::x25519; +use nym_crypto::asymmetric::x25519::serde_helpers::{ + bs58_x25519_pubkey, option_bs58_x25519_pubkey, +}; +use serde::{Deserialize, Serialize}; +use std::net::SocketAddr; +use std::time::Duration; +use time::OffsetDateTime; + +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +#[derive(Debug, Clone, Serialize, Deserialize)] +/// Body sent by an agent to announce its details to the orchestrator. +/// The orchestrator forwards this information to the smart contract so that +/// network nodes can whitelist connections from known agents. +pub struct AgentAnnounceRequest { + /// Egress address of the agent node combined with the previously + /// assigned mixnet socket address from the orchestrator + #[cfg_attr(feature = "openapi", schema(value_type = String))] + pub agent_mix_socket_address: SocketAddr, + + /// Base-58 encoded noise key of the agent. + #[serde(with = "bs58_x25519_pubkey")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] + pub x25519_noise_key: x25519::PublicKey, + + /// Version of the noise protocol used by the agent. + pub noise_version: u8, +} + +/// Confirmation returned to an agent after a successful announcement. +/// Currently empty — exists to give the response an explicit type rather than +/// relying on `Json(())`. +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AgentAnnounceResponse {} + +/// Request sent by an agent to ask the orchestrator for a node to test. +/// Identifies the agent so the orchestrator can verify it has been announced. +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct TestRunAssignmentRequest { + /// Egress address of the agent node combined with the previously + /// assigned mixnet socket address from the orchestrator + #[cfg_attr(feature = "openapi", schema(value_type = String))] + pub agent_mix_socket_address: SocketAddr, + + /// Base-58 encoded noise key of the agent. + #[serde(with = "bs58_x25519_pubkey")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] + pub x25519_noise_key: x25519::PublicKey, +} + +/// Response from the orchestrator when an agent requests work. +/// `assignment` is `None` when no nodes are due for testing. +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct TestRunAssignmentResponse { + pub assignment: Option, +} + +/// Details of a single node assigned to an agent for stress testing. +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct TestRunAssignment { + pub node_id: u32, + + /// The address of the node that should be tested. + #[cfg_attr(feature = "openapi", schema(value_type = String))] + pub node_address: SocketAddr, + + #[serde(with = "bs58_x25519_pubkey")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] + pub noise_key: x25519::PublicKey, + + #[serde(with = "bs58_x25519_pubkey")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] + pub sphinx_key: x25519::PublicKey, + + pub key_rotation_id: u32, +} + +/// Latency statistics computed over the set of test packets received or sent during a stress test. +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] +pub struct LatencyDistribution { + /// Minimum latency duration it took to send or receive a test packet. + #[serde(with = "humantime_serde")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] + pub minimum: Duration, + + /// Average latency duration it took to send or receive a test packet. + #[serde(with = "humantime_serde")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] + pub mean: Duration, + + /// Median latency duration it took to send or receive a test packet. + /// For an even number of samples, this is the arithmetic mean of the two middle values. + #[serde(with = "humantime_serde")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] + pub median: Duration, + + /// Maximum latency duration it took to send or receive a test packet. + #[serde(with = "humantime_serde")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] + pub maximum: Duration, + + /// The standard deviation of the latency duration it took to send or receive the test packets. + #[serde(with = "humantime_serde")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] + pub standard_deviation: Duration, +} + +/// Request sent by an agent to submit test results for a previously assigned node. +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +pub struct TestRunResultSubmissionRequest { + pub node_id: u32, + pub result: TestRunResult, +} + +/// Captures the outcome of a single test run against a nym node. +/// +/// Fields are populated incrementally as the test progresses; absent values (`None`) indicate +/// that the corresponding step was not reached or did not produce a result. +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +#[derive(Debug, Clone, Default, Serialize, Deserialize)] +pub struct TestRunResult { + /// Total duration of the test run, including the time it took to establish the connections. + #[serde(default, with = "humantime_serde")] + #[cfg_attr(feature = "openapi", schema(value_type = Option))] + pub time_taken: Duration, + + /// Duration of the Noise handshake on the ingress (responder) side, if completed. + #[serde(default, with = "humantime_serde")] + #[cfg_attr(feature = "openapi", schema(value_type = Option))] + pub ingress_noise_handshake: Option, + + /// Duration of the Noise handshake on the egress (initiator) side, if completed. + #[serde(default, with = "humantime_serde")] + #[cfg_attr(feature = "openapi", schema(value_type = Option))] + pub egress_noise_handshake: Option, + + /// The (constant) delay of the sphinx packet set during the test run. + #[serde(default, with = "humantime_serde")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] + pub sphinx_packet_delay: Duration, + + /// Number of sphinx packets successfully sent to the node under test. + pub packets_sent: usize, + + /// Number of sphinx packets returned by the node and successfully received. + pub packets_received: usize, + + /// Round-trip time of the very first probe packet, sent in isolation before any load is applied. + /// Because the node is idle at this point, this value approximates the baseline network latency + /// to the node without any queuing or processing overhead from the stress test itself. + /// `None` if the initial probe did not complete successfully. + #[serde(default, with = "humantime_serde")] + #[cfg_attr(feature = "openapi", schema(value_type = Option))] + pub approximate_latency: Option, + + /// RTT statistics computed over all received packets, or `None` if no packets were received. + pub packets_statistics: Option, + + /// Latency distribution of individual batch send operations recorded during the load test. + /// Reflects how long each batch took to flush to the OS socket, giving a rough measure of + /// egress throughput. `None` if no batches were sent. + pub sending_statistics: Option, + + /// Whether any packet was received with an ID that had already been seen in this test run. + /// Duplicates should never occur under normal operation; their presence may indicate a + /// misbehaving or malicious node replaying packets. + pub received_duplicates: bool, + + /// Human-readable description of the first error that caused the test to abort if any. + pub error: Option, +} + +impl TestRunResult { + pub fn received_ratio(&self) -> f64 { + if self.packets_sent == 0 { + return 0.0; + } + let received = self.packets_received.min(self.packets_sent); + received as f64 / self.packets_sent as f64 + } +} + +/// Confirmation returned to an agent after a successful result submission. +/// Currently empty — exists to give the response an explicit type rather than +/// relying on `Json(())`. +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct TestRunSubmissionResponse {} + +// ------------------------------------------------------------------------ +// Response shapes for the read-only results API (`/v1/results/*`). These are +// the public, serialisation-stable types returned to callers; conversion from +// the storage layer's sqlx rows happens in `orchestrator/storage/models.rs`. +// ------------------------------------------------------------------------ + +pub const PAGINATION_SIZE_DEFAULT: usize = 50; +pub const PAGINATION_SIZE_MAX: usize = 200; +pub const PAGINATION_PAGE_DEFAULT: usize = 0; + +/// Query parameters for paginated endpoints. `size` defaults to +/// [`PAGINATION_SIZE_DEFAULT`] and is capped at [`PAGINATION_SIZE_MAX`]; +/// `page` defaults to [`PAGINATION_PAGE_DEFAULT`]. +#[cfg_attr(feature = "openapi", derive(utoipa::IntoParams))] +#[cfg_attr(feature = "openapi", into_params(parameter_in = Query))] +#[derive(Debug, Copy, Clone, Serialize, Deserialize)] +pub struct Pagination { + pub per_page: Option, + pub page: Option, +} + +impl Default for Pagination { + fn default() -> Self { + Self { + per_page: Some(PAGINATION_SIZE_DEFAULT), + page: Some(PAGINATION_PAGE_DEFAULT), + } + } +} + +impl Pagination { + pub fn new(per_page: Option, page: Option) -> Self { + Self { per_page, page } + } + + /// Resolved page size — defaults to [`PAGINATION_SIZE_DEFAULT`] when absent + /// and is capped at [`PAGINATION_SIZE_MAX`]. + pub fn per_page(&self) -> usize { + self.per_page + .unwrap_or(PAGINATION_SIZE_DEFAULT) + .min(PAGINATION_SIZE_MAX) + } + + /// Resolved page index — defaults to [`PAGINATION_PAGE_DEFAULT`] when absent. + pub fn page(&self) -> usize { + self.page.unwrap_or(PAGINATION_PAGE_DEFAULT) + } + + /// Value to bind to a SQL `LIMIT ?` clause. Equivalent to + /// [`Self::per_page`] cast to the `i64` sqlx bind type. + pub fn limit(&self) -> i64 { + self.per_page() as i64 + } + + /// Value to bind to a SQL `OFFSET ?` clause, i.e. `page * per_page`. + /// Saturating to avoid overflow on absurdly large `page` values from a client. + pub fn offset(&self) -> i64 { + (self.page() as i64).saturating_mul(self.limit()) + } +} + +/// Generic wrapper for a single page of results. +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +#[derive(Debug, Default, Clone, Serialize, Deserialize)] +pub struct PagedResult { + pub page: usize, + pub per_page: usize, + pub total: usize, + pub items: Vec, +} + +/// Discriminator for the type of node targeted by a test run. +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] +#[serde(rename_all = "lowercase")] +pub enum TestType { + Mixnode, + Gateway, +} + +/// A completed test run as exposed by the results API. +/// +/// Unlike the agent-facing [`TestRunResult`], this carries the database id, +/// the node that was tested, and the timestamp at which the result was +/// recorded by the orchestrator. +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct TestRunData { + /// Database-assigned identifier of the test run. + pub id: i64, + + /// Node that was tested. + pub node_id: u32, + + /// Kind of node that was tested. + pub test_type: TestType, + + /// When the test run completed and was recorded. + /// Serialised as an RFC 3339 timestamp string. + #[serde(with = "time::serde::rfc3339")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] + pub test_timestamp: OffsetDateTime, + + /// The test run result itself. + pub result: TestRunResult, +} + +/// Public snapshot of a nym-node as tracked by the orchestrator. +/// +/// Built from the on-chain bond plus any details the orchestrator has managed +/// to retrieve directly from the node itself. The optional fields +/// (`mixnet_socket_address`, `noise_key`, `sphinx_key`, `key_rotation_id`) +/// are populated lazily by the node refresher and may be absent either because +/// the node is newly observed or because the refresher failed to reach it. +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct NymNodeData { + pub node_id: u32, + + /// Ed25519 identity key of the node, serialised as a base58 string. + #[serde(with = "bs58_ed25519_pubkey")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] + pub identity_key: ed25519::PublicKey, + + /// When this node was last observed as bonded in the contract. + #[serde(with = "time::serde::rfc3339")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] + pub last_seen_bonded: OffsetDateTime, + + /// Mixnet socket address (host:port) at which the node accepts sphinx packets. + #[cfg_attr(feature = "openapi", schema(value_type = String))] + pub mixnet_socket_address: Option, + + /// X25519 public key used for Noise handshakes. + /// `None` if retrieval from the node failed. + #[serde(with = "option_bs58_x25519_pubkey")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] + pub noise_key: Option, + + /// Sphinx public key used for packet encryption. + /// `None` if retrieval from the node failed. + /// Always `None`/`Some` together with `key_rotation_id`. + #[serde(with = "option_bs58_x25519_pubkey")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] + pub sphinx_key: Option, + + /// Key rotation epoch ID that `sphinx_key` belongs to. + /// `None` if retrieval from the node failed. + /// Always `None`/`Some` together with `sphinx_key`. + pub key_rotation_id: Option, +} + +/// Node snapshot paired with its most recent completed test run. +/// +/// `latest_test_run` is `None` when the node has never been tested or when its +/// most recent run has been evicted by the stale-result sweeper. +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct NymNodeWithTestRun { + pub node: NymNodeData, + + pub latest_test_run: Option, +} + +/// Marker for a test run that has been handed out to an agent but whose result +/// hasn't been submitted yet. Stripped of test-payload fields because by +/// definition none of them exist yet. +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct TestRunInProgressData { + pub node_id: u32, + + /// When the test run was handed out to an agent. Serialised as an + /// RFC 3339 timestamp string. + #[serde(with = "time::serde::rfc3339")] + #[cfg_attr(feature = "openapi", schema(value_type = String))] + pub started_at: OffsetDateTime, +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/Cargo.toml b/nym-network-monitor-v3/nym-network-monitor-orchestrator/Cargo.toml new file mode 100644 index 0000000000..a93df645e7 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/Cargo.toml @@ -0,0 +1,64 @@ +[package] +name = "nym-network-monitor-orchestrator" +description = "Orchestrator for performing Nym network stress testing" +version = "1.0.2" +authors.workspace = true +edition.workspace = true +license.workspace = true +repository.workspace = true +homepage.workspace = true +documentation.workspace = true +rust-version.workspace = true +readme.workspace = true +publish = false + +[dependencies] +anyhow = { workspace = true } +clap = { workspace = true, features = ["cargo", "env"] } +futures = { workspace = true } +humantime = { workspace = true } +rand = { workspace = true } +sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate", "time"] } +tokio = { workspace = true, features = ["macros", "sync", "rt-multi-thread"] } +strum = { workspace = true } +thiserror = { workspace = true } +tracing = { workspace = true } +time = { workspace = true } +url = { workspace = true } +zeroize = { workspace = true } + +# http +axum = { workspace = true, features = ["tokio", "macros"] } +utoipa = { workspace = true, features = ["axum_extras", "time"] } +utoipa-swagger-ui = { workspace = true, features = ["axum"] } +utoipauto = { workspace = true } + +nym-validator-client = { workspace = true, features = ["http-client"] } +nym-bin-common = { workspace = true, features = ["basic_tracing", "output_format"] } +nym-crypto = { workspace = true, features = ["asymmetric"] } +nym-network-defaults = { workspace = true } +nym-task = { workspace = true } +nym-node-requests = { workspace = true, features = ["client"] } +nym-metrics = { workspace = true } +nym-http-api-common = { workspace = true, features = ["utoipa", "middleware"] } +nym-api-requests = { workspace = true } + +nym-network-monitor-orchestrator-requests = { path = "../nym-network-monitor-orchestrator-requests", features = ["openapi"] } + +[dev-dependencies] +nym-crypto = { workspace = true, features = ["asymmetric", "rand"] } +nym-test-utils = { workspace = true } + +[build-dependencies] +anyhow = { workspace = true } +sqlx = { workspace = true, features = [ + "runtime-tokio-rustls", + "sqlite", + "macros", + "migrate", +] } +tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } + + +[lints] +workspace = true diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/Dockerfile b/nym-network-monitor-v3/nym-network-monitor-orchestrator/Dockerfile new file mode 100644 index 0000000000..d7592eafcf --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/Dockerfile @@ -0,0 +1,19 @@ +# this will only work with VPN, otherwise remove the harbor part +FROM harbor.nymte.ch/dockerhub/rust:latest AS builder + +RUN apt update && apt install -yy libdbus-1-dev pkg-config libclang-dev + +COPY ./ /usr/src/nym +WORKDIR /usr/src/nym + +RUN cargo build --bin nym-network-monitor-orchestrator --release + +FROM harbor.nymte.ch/dockerhub/ubuntu:24.04 + +RUN apt-get update && apt-get install -y ca-certificates && rm -rf /var/lib/apt/lists/* + +WORKDIR /nym + +COPY --from=builder /usr/src/nym/target/release/nym-network-monitor-orchestrator ./ + +ENTRYPOINT ["/nym/nym-network-monitor-orchestrator", "run-orchestrator"] diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/build.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/build.rs new file mode 100644 index 0000000000..f08f638b03 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/build.rs @@ -0,0 +1,37 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use anyhow::Context; +use sqlx::{Connection, SqliteConnection}; +use std::env; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + let out_dir = env::var("OUT_DIR")?; + let database_path = format!("{out_dir}/orchestrator.sqlite"); + + // remove the db file if it already existed from previous build + // in case it was from a different branch + if std::fs::exists(&database_path)? { + std::fs::remove_file(&database_path)?; + } + + let mut conn = SqliteConnection::connect(&format!("sqlite://{database_path}?mode=rwc")) + .await + .context("Failed to create SQLx database connection")?; + + sqlx::migrate!("./migrations") + .run(&mut conn) + .await + .context("Failed to perform SQLx migrations")?; + + #[cfg(target_family = "unix")] + println!("cargo:rustc-env=DATABASE_URL=sqlite://{}", &database_path); + + #[cfg(target_family = "windows")] + // for some strange reason we need to add a leading `/` to the windows path even though it's + // not a valid windows path... but hey, it works... + println!("cargo:rustc-env=DATABASE_URL=sqlite:///{}", &database_path); + + Ok(()) +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/migrations/01_initial_tables.sql b/nym-network-monitor-v3/nym-network-monitor-orchestrator/migrations/01_initial_tables.sql new file mode 100644 index 0000000000..499157a88a --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/migrations/01_initial_tables.sql @@ -0,0 +1,139 @@ +/* + * Copyright 2026 - Nym Technologies SA + * SPDX-License-Identifier: GPL-3.0-only + */ + +CREATE TABLE metadata +( + id INTEGER PRIMARY KEY CHECK (id = 0), + last_submitted_testrun_id INTEGER +); + +CREATE TABLE testrun +( + -- Surrogate primary key. + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + + -- The node under test. References nym_node(node_id); forward reference is allowed in + -- SQLite since foreign keys are validated at INSERT time, not at CREATE TABLE time. + -- Kept as a full column (rather than relying on nym_node.last_testrun) so that the + -- node→testrun link survives once the node gets a newer run. + node_id INTEGER NOT NULL REFERENCES nym_node (node_id), + + -- Discriminator for the type of node under test; future-proofs the table for when we start testing gateways. + test_type TEXT CHECK ( test_type IN ('mixnode', 'gateway') ) NOT NULL, + + -- When this testrun has been performed. + test_timestamp TIMESTAMP WITHOUT TIME ZONE NOT NULL, + + -- How long the test took to complete, in microseconds, from the point of view of an agent. + time_taken_us INTEGER NOT NULL, + + -- Duration of the Noise handshake on the ingress (responder) side, in microseconds. + -- NULL if the handshake did not complete. + ingress_noise_handshake_us INTEGER, + + -- Duration of the Noise handshake on the egress (initiator) side, in microseconds. + -- NULL if the handshake did not complete. + egress_noise_handshake_us INTEGER, + + -- The (constant) per-hop delay applied to sphinx packets during the test run, in microseconds. + sphinx_packet_delay_us INTEGER NOT NULL, + + -- Number of sphinx packets sent to the node under test. + packets_sent INTEGER NOT NULL DEFAULT 0, + + -- Number of sphinx packets received back from the node under test. + packets_received INTEGER NOT NULL DEFAULT 0, + + -- RTT of the initial probe packet in microseconds, approximating baseline latency. + -- NULL if the probe did not complete successfully. + approximate_latency_us INTEGER, + + -- RTT distribution (in microseconds) computed over all received packets. + -- All five columns are NULL together when no packets were received. + packets_rtt_min_us INTEGER, + packets_rtt_mean_us INTEGER, + packets_rtt_median_us INTEGER, + packets_rtt_max_us INTEGER, + packets_rtt_std_dev_us INTEGER, + + -- Batch send latency distribution (in microseconds) recorded during the load test. + -- All five columns are NULL together when no batches were sent. + sending_latency_min_us INTEGER, + sending_latency_mean_us INTEGER, + sending_latency_median_us INTEGER, + sending_latency_max_us INTEGER, + sending_latency_std_dev_us INTEGER, + + -- Whether any packet was received with a duplicate ID during this test run. + received_duplicates BOOLEAN NOT NULL, + + -- Human-readable description of the first error that caused the test to abort. + -- NULL if the test completed without error. + error TEXT + +); + +-- Supports efficient "all runs for node X, newest first" lookups. +CREATE INDEX idx_testrun_node_id_timestamp ON testrun (node_id, test_timestamp DESC); + +-- Supports efficient "all runs, newest first" lookups (the global testruns pagination endpoint). +-- The composite index above cannot serve this query because its leading column is node_id. +CREATE INDEX idx_testrun_test_timestamp ON testrun (test_timestamp DESC); + +CREATE TABLE nym_node +( + -- Node ID as assigned by the mixnet contract. + node_id INTEGER PRIMARY KEY NOT NULL, + + -- Ed25519 identity key of the node, base58-encoded. + -- A node_id always maps to exactly one identity_key and is never reassigned. + -- The inverse is not true: the same identity_key may appear under multiple node_ids + -- if the operator unbonds and rebonds, receiving a new contract-assigned node_id. + identity_key TEXT NOT NULL, + + -- When this node was last observed as bonded in the contract. + last_seen_bonded TIMESTAMP WITHOUT TIME ZONE NOT NULL, + + -- Mixnet socket address (host:port) at which the node accepts sphinx packets. + mixnet_socket_address TEXT, + + -- X25519 public key used for Noise handshakes, base58-encoded. + -- NULL if retrieval from the node failed. + noise_key TEXT, + + -- Sphinx public key used for packet encryption, base58-encoded. + -- NULL if retrieval from the node failed. + -- Always NULL/non-NULL together with key_rotation_id. + sphinx_key TEXT, + + -- Key rotation epoch ID that the sphinx_key belongs to. + -- NULL if retrieval from the node failed. + -- Always NULL/non-NULL together with sphinx_key. + key_rotation_id INTEGER, + + -- Classification of the node based on the roles reported via its self-described endpoint. + -- 'unknown' is used both before the node has been successfully queried and when a queried + -- node reports no roles. Only nodes with node_type in ('mixnode', 'mixnode_and_gateway') + -- are eligible for testruns today. + node_type TEXT CHECK ( node_type IN ('unknown', 'mixnode', 'gateway', 'mixnode_and_gateway') ) NOT NULL DEFAULT 'unknown', + + -- The most recent test run performed against this node. NULL if never tested. + -- Set to NULL automatically when the referenced testrun row is evicted. + last_testrun INTEGER REFERENCES testrun (id) ON DELETE SET NULL, + + CHECK ((sphinx_key IS NULL) = (key_rotation_id IS NULL)) +); + +-- Tracks nodes that currently have a test run in progress. +-- At most one row per node (enforced by the PRIMARY KEY on node_id). +-- A row is inserted when a run is dispatched and deleted when it completes or is abandoned. +CREATE TABLE testrun_in_progress +( + -- The node currently being tested. + node_id INTEGER PRIMARY KEY REFERENCES nym_node (node_id) NOT NULL, + + -- When the in-progress run was started; used to detect stale/hung runs. + started_at TIMESTAMP WITHOUT TIME ZONE NOT NULL +) \ No newline at end of file diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/build_info.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/build_info.rs new file mode 100644 index 0000000000..a5b80d67bf --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/build_info.rs @@ -0,0 +1,15 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use nym_bin_common::bin_info_owned; +use nym_bin_common::output_format::OutputFormat; + +#[derive(clap::Args, Debug)] +pub(crate) struct Args { + #[clap(short, long, default_value_t = OutputFormat::default())] + output: OutputFormat, +} + +pub(crate) fn execute(args: Args) { + println!("{}", args.output.format(&bin_info_owned!())) +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/env.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/env.rs new file mode 100644 index 0000000000..d37292bc8f --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/env.rs @@ -0,0 +1,40 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +/// Environment variable names used as fallbacks for CLI arguments. +/// Each constant matches the `env = ...` attribute on the corresponding clap field. +pub mod vars { + // run orchestrator args + pub const NYM_NETWORK_MONITOR_ORCHESTRATOR_AGENTS_TOKEN_ARG: &str = + "NYM_NETWORK_MONITOR_ORCHESTRATOR_AGENTS_TOKEN"; + pub const NYM_NETWORK_MONITOR_ORCHESTRATOR_METRICS_AND_RESULTS_TOKEN_ARG: &str = + "NYM_NETWORK_MONITOR_ORCHESTRATOR_METRICS_AND_RESULTS_TOKEN"; + pub const NYM_NETWORK_MONITOR_TEST_INTERVAL_ARG: &str = "NYM_NETWORK_MONITOR_TEST_INTERVAL"; + pub const NYM_NETWORK_MONITOR_TEST_TIMEOUT_ARG: &str = "NYM_NETWORK_MONITOR_TEST_TIMEOUT"; + pub const NYM_NETWORK_MONITOR_HTTP_SERVER_BIND_ADDRESS_ARG: &str = + "NYM_NETWORK_MONITOR_HTTP_SERVER_BIND_ADDRESS"; + pub const NYM_NETWORK_MONITOR_NYM_API_ENDPOINT_ARG: &str = + "NYM_NETWORK_MONITOR_NYM_API_ENDPOINT"; + pub const NYM_NETWORK_MONITOR_MNEMONIC_ARG: &str = "NYM_NETWORK_MONITOR_MNEMONIC"; + pub const NYM_NETWORK_MONITOR_RPC_URL_ARG: &str = "NYM_NETWORK_MONITOR_RPC_URL"; + pub const NYM_NETWORK_MONITOR_DATABASE_PATH_ARG: &str = "NYM_NETWORK_MONITOR_DATABASE_PATH"; + pub const NYM_NETWORK_MONITOR_PRIVATE_KEY_ARG: &str = "NYM_NETWORK_MONITOR_PRIVATE_KEY"; + pub const NYM_NETWORK_MONITOR_NODE_REFRESH_RATE_ARG: &str = + "NYM_NETWORK_MONITOR_NODE_REFRESH_RATE"; + pub const NYM_NETWORK_MONITOR_NODE_INFO_QUERY_TIMEOUT_ARG: &str = + "NYM_NETWORK_MONITOR_NODE_INFO_QUERY_TIMEOUT"; + pub const NYM_NETWORK_MONITOR_NETWORK_MONITORS_CONTRACT_ADDRESS_ARG: &str = + "NYM_NETWORK_MONITOR_NETWORK_MONITORS_CONTRACT_ADDRESS"; + pub const NYM_NETWORK_MONITOR_MIXNET_CONTRACT_ADDRESS_ARG: &str = + "NYM_NETWORK_MONITOR_MIXNET_CONTRACT_ADDRESS"; + pub const NYM_NETWORK_MONITOR_TESTRUN_EVICTION_AGE_ARG: &str = + "NYM_NETWORK_MONITOR_TESTRUN_EVICTION_AGE"; + pub const NYM_NETWORK_MONITOR_CONCURRENT_NODE_QUERIES_ARG: &str = + "NYM_NETWORK_MONITOR_CONCURRENT_NODE_QUERIES"; + pub const NYM_NETWORK_MONITOR_CHAIN_AUTH_CHECK_MAX_ATTEMPTS_ARG: &str = + "NYM_NETWORK_MONITOR_CHAIN_AUTH_CHECK_MAX_ATTEMPTS"; + pub const NYM_NETWORK_MONITOR_CHAIN_AUTH_CHECK_RETRY_DELAY_ARG: &str = + "NYM_NETWORK_MONITOR_CHAIN_AUTH_CHECK_RETRY_DELAY"; + pub const NYM_NETWORK_MONITOR_RESULT_SUBMISSION_INTERVAL_ARG: &str = + "NYM_NETWORK_MONITOR_RESULT_SUBMISSION_INTERVAL"; +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/mod.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/mod.rs new file mode 100644 index 0000000000..955d9f1cfe --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/mod.rs @@ -0,0 +1,50 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use clap::{Parser, Subcommand}; +use nym_bin_common::bin_info; +use std::sync::OnceLock; + +mod build_info; +mod env; +mod run_orchestrator; + +// Helper for passing LONG_VERSION to clap +fn pretty_build_info_static() -> &'static str { + static PRETTY_BUILD_INFORMATION: OnceLock = OnceLock::new(); + PRETTY_BUILD_INFORMATION.get_or_init(|| bin_info!().pretty_print()) +} + +/// Top-level CLI entry point for the network monitor agent. +#[derive(Parser, Debug)] +#[clap(author = "Nymtech", version, long_version = pretty_build_info_static(), about)] +pub(crate) struct Cli { + /// Path pointing to an env file that configures the binary. + /// Useful in local testing setups against networks different from mainnet + #[clap(short, long)] + pub(crate) config_env_file: Option, + + #[command(subcommand)] + pub(crate) command: Command, +} + +impl Cli { + /// Dispatches execution to the subcommand selected by the user. + pub(crate) async fn execute(self) -> anyhow::Result<()> { + match self.command { + Command::BuildInfo(args) => build_info::execute(args), + Command::RunOrchestrator(args) => run_orchestrator::execute(*args).await?, + } + Ok(()) + } +} + +#[derive(Subcommand, Debug)] +pub(crate) enum Command { + /// Show build information of this binary + BuildInfo(build_info::Args), + + /// Run the network monitor orchestrator which will periodically + /// issue work assignments for stress testing mixnodes + RunOrchestrator(Box), +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/run_orchestrator.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/run_orchestrator.rs new file mode 100644 index 0000000000..fa85d2aa62 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/run_orchestrator.rs @@ -0,0 +1,214 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use super::env::vars::*; +use crate::orchestrator::NetworkMonitorOrchestrator; +use crate::orchestrator::config::Config; +use anyhow::{Context, anyhow, bail}; +use nym_crypto::asymmetric::ed25519; +use nym_validator_client::nyxd::bip39; +use std::mem; +use std::net::SocketAddr; +use std::num::NonZeroU32; +use std::path::PathBuf; +use std::sync::Arc; +use std::time::Duration; +use tracing::info; +use url::Url; +use zeroize::Zeroizing; + +#[derive(clap::Args, Debug)] +pub(crate) struct Args { + /// Bearer token required by the agents requesting work assignments and submitting results. + #[clap(long, env = NYM_NETWORK_MONITOR_ORCHESTRATOR_AGENTS_TOKEN_ARG)] + agents_token: String, + + /// Bearer token used for accessing the metrics and results endpoints. + #[clap(long, env = NYM_NETWORK_MONITOR_ORCHESTRATOR_METRICS_AND_RESULTS_TOKEN_ARG)] + metrics_and_results_token: String, + + /// How often each node should be stress-tested (e.g. `30m`, `1h`). + #[clap(long, env = NYM_NETWORK_MONITOR_TEST_INTERVAL_ARG, value_parser = humantime::parse_duration, default_value = "2h")] + test_interval: Duration, + + /// Maximum time a single test run is allowed to run before being considered timed out + /// (e.g. `5m`). + #[clap(long, env = NYM_NETWORK_MONITOR_TEST_TIMEOUT_ARG, value_parser = humantime::parse_duration, default_value = "5m")] + test_timeout: Duration, + + /// HTTP address to bind the HTTP server to (e.g. `0.0.0.0:8080`). + #[clap(long, env = NYM_NETWORK_MONITOR_HTTP_SERVER_BIND_ADDRESS_ARG, default_value = "0.0.0.0:8080")] + http_server_bind_address: SocketAddr, + + /// HTTP endpoint of the nym-api to which test results are submitted. + #[clap(long, env = NYM_NETWORK_MONITOR_NYM_API_ENDPOINT_ARG)] + nym_api_endpoint: Url, + + /// Mnemonic of the account used to authorise network monitor agents in the + /// network monitors contract. + #[clap(long, env = NYM_NETWORK_MONITOR_MNEMONIC_ARG)] + mnemonic: bip39::Mnemonic, + + /// HTTPS RPC URL of a Nyx node (e.g. `https://rpc.nymtech.net`). + /// If not provided, the default value from the environment will be retrieved (if available). + #[clap(long, env = NYM_NETWORK_MONITOR_RPC_URL_ARG)] + rpc_url: Option, + + /// Path to the SQLite database file. + #[clap(long, env = NYM_NETWORK_MONITOR_DATABASE_PATH_ARG)] + database_path: PathBuf, + + /// Base58-encoded Ed25519 private key used to authorise result submissions to the nym-api. + #[clap(long, env = NYM_NETWORK_MONITOR_PRIVATE_KEY_ARG)] + private_key: String, + + /// How often the list of bonded nym-nodes is refreshed from the mixnet contract + /// (e.g. `10m`, `1h`). + #[clap(long, env = NYM_NETWORK_MONITOR_NODE_REFRESH_RATE_ARG, value_parser = humantime::parse_duration, default_value = "2h")] + node_refresh_rate: Duration, + + /// Timeout for querying a single node for its detailed information (sphinx key, noise key, + /// etc.). Queries that exceed this budget leave the corresponding fields as `NULL` + /// (e.g. `10s`). + #[clap(long, env = NYM_NETWORK_MONITOR_NODE_INFO_QUERY_TIMEOUT_ARG, value_parser = humantime::parse_duration, default_value = "10s")] + node_info_query_timeout: Duration, + + /// Bech32 address of the networks monitors contract used to authorise agents + /// If not provided, the default value from the environment will be retrieved (if available). + #[clap(long, env = NYM_NETWORK_MONITOR_NETWORK_MONITORS_CONTRACT_ADDRESS_ARG)] + network_monitors_contract_address: Option, + + /// Bech32 address of the mixnet contract used to retrieve the list of bonded nodes. + /// If not provided, the default value from the environment will be retrieved (if available). + #[clap(long, env = NYM_NETWORK_MONITOR_MIXNET_CONTRACT_ADDRESS_ARG)] + mixnet_contract_address: Option, + + /// Maximum age of a completed test run row before it is evicted from the local database. + /// Rows older than this are assumed to have already been submitted to the nym-api + /// (e.g. `7d`, `24h`). + #[clap(long, env = NYM_NETWORK_MONITOR_TESTRUN_EVICTION_AGE_ARG, value_parser = humantime::parse_duration, default_value = "7d",)] + testrun_eviction_age: Duration, + + /// Maximum number of nodes queried concurrently during a node refresh cycle. + #[clap(long, env = NYM_NETWORK_MONITOR_CONCURRENT_NODE_QUERIES_ARG, default_value_t = 32)] + number_of_concurrent_node_queries: usize, + + /// Maximum number of attempts (including the initial one) made to verify that this + /// orchestrator's account is authorised in the network monitors contract before start-up. + /// The process exits with an error once the budget is exhausted. + #[clap(long, env = NYM_NETWORK_MONITOR_CHAIN_AUTH_CHECK_MAX_ATTEMPTS_ARG, default_value = "10")] + chain_authorisation_check_max_attempts: NonZeroU32, + + /// Delay between consecutive chain authorisation checks during start-up (e.g. `1m`, `30s`). + /// Applied both when the query itself fails and when it succeeds but the orchestrator is not + /// (yet) listed. + #[clap(long, env = NYM_NETWORK_MONITOR_CHAIN_AUTH_CHECK_RETRY_DELAY_ARG, value_parser = humantime::parse_duration, default_value = "1m")] + chain_authorisation_check_retry_delay: Duration, + + /// How often the orchestrator flushes accumulated test results to the nym-api as a signed + /// batch submission (e.g. `15m`, `1h`). + #[clap(long, env = NYM_NETWORK_MONITOR_RESULT_SUBMISSION_INTERVAL_ARG, value_parser = humantime::parse_duration, default_value = "15m")] + result_submission_interval: Duration, +} + +impl Args { + /// Converts the parsed CLI arguments into a [`Config`]. + /// + /// Returns an error if `mixnet_contract_address` is not a valid bech32 account address. + /// + /// Note: `orchestrator_token`, `mnemonic`, and `private_key` are not part of [`Config`] + /// and must be handled separately by the caller. + pub(crate) fn build_orchestrator_config(&self) -> anyhow::Result { + Ok(Config { + nyxd_rpc_endpoint: self.rpc_url.clone(), + nym_api_endpoint: self.nym_api_endpoint.clone(), + http_server_bind_address: self.http_server_bind_address, + test_interval: self.test_interval, + test_timeout: self.test_timeout, + database_path: self.database_path.clone(), + node_refresh_rate: self.node_refresh_rate, + node_info_query_timeout: self.node_info_query_timeout, + network_monitors_contract_address: self + .network_monitors_contract_address + .as_ref() + .map(|addr| addr.parse()) + .transpose() + .map_err(|err| anyhow!("invalid network monitors contract address: {err}"))?, + mixnet_contract_address: self + .mixnet_contract_address + .as_ref() + .map(|addr| addr.parse()) + .transpose() + .map_err(|err| anyhow!("invalid mixnet contract address: {err}"))?, + testrun_eviction_age: self.testrun_eviction_age, + number_of_concurrent_node_queries: self.number_of_concurrent_node_queries, + chain_authorisation_check_max_attempts: self.chain_authorisation_check_max_attempts, + chain_authorisation_check_retry_delay: self.chain_authorisation_check_retry_delay, + result_submission_interval: self.result_submission_interval, + }) + } + + /// Moves the orchestrator agents token out of `self`, zeroizing the original. + /// + /// Returns an error if the token is empty. + pub(crate) fn take_agents_orchestrator_token(&mut self) -> anyhow::Result> { + // we must never accept empty tokens + if self.agents_token.is_empty() { + bail!("provided orchestrator token is empty, please provide a non-empty value") + } + let taken = mem::take(&mut self.agents_token); + Ok(Zeroizing::new(taken)) + } + + /// Moves the orchestrator metrics-and-results token out of `self`, zeroizing the original. + /// + /// Returns an error if the token is empty. + pub(crate) fn take_metrics_and_results_orchestrator_token( + &mut self, + ) -> anyhow::Result> { + // we must never accept empty tokens + if self.metrics_and_results_token.is_empty() { + bail!("provided orchestrator token is empty, please provide a non-empty value") + } + let taken = mem::take(&mut self.metrics_and_results_token); + Ok(Zeroizing::new(taken)) + } + + /// Moves the raw Base58-encoded private key out of `self`, parses it into an Ed25519 key pair, + /// and zeroizes the original string. + /// + /// Returns an error if the value is not a valid Base58-encoded Ed25519 private key. + pub(crate) fn take_identity_key(&mut self) -> anyhow::Result> { + // whatever happens, we'll zeroize the value + let taken = Zeroizing::new(mem::take(&mut self.private_key)); + + let private_key = ed25519::PrivateKey::from_base58_string(&taken) + .context("malformed identity key provided")?; + Ok(Arc::new(private_key.into())) + } + + /// Consumes `self` and returns the mnemonic. + pub(crate) fn into_mnemonic(self) -> bip39::Mnemonic { + self.mnemonic + } +} + +pub(crate) async fn execute(mut args: Args) -> anyhow::Result<()> { + info!("Starting network monitor orchestrator"); + let config = args.build_orchestrator_config()?; + let identity_keys = args.take_identity_key()?; + let agents_auth_token = args.take_agents_orchestrator_token()?; + let metrics_and_results_auth_token = args.take_metrics_and_results_orchestrator_token()?; + let mnemonic = args.into_mnemonic(); + + let mut orchestrator = NetworkMonitorOrchestrator::new( + config, + identity_keys, + agents_auth_token, + metrics_and_results_auth_token, + mnemonic, + ) + .await?; + orchestrator.run().await?; + Ok(()) +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/api_docs.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/api_docs.rs new file mode 100644 index 0000000000..92bd3db53a --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/api_docs.rs @@ -0,0 +1,52 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use axum::Router; +use nym_network_monitor_orchestrator_requests::routes; +use utoipa::openapi::security::{Http, HttpAuthScheme, SecurityScheme}; +use utoipa::{Modify, OpenApi}; +use utoipa_swagger_ui::SwaggerUi; +use utoipauto::utoipauto; + +// manually import external structs which are behind feature flags because they +// can't be automatically discovered +// https://github.com/ProbablyClem/utoipauto/issues/13#issuecomment-1974911829 +#[utoipauto( + paths = "./nym-network-monitor-v3/nym-network-monitor-orchestrator/src", + "./nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/src from nym-network-monitor-orchestrator-requests" +)] +#[derive(OpenApi)] +#[openapi( + info(title = "Nym Network Monitor Orchestrator API"), + tags(), + modifiers(&SecurityAddon), +)] +pub(crate) struct ApiDoc; + +/// OpenAPI modifier that registers bearer-token security schemes for the API docs. +struct SecurityAddon; + +impl Modify for SecurityAddon { + fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) { + if let Some(components) = openapi.components.as_mut() { + // token authorising access to prometheus metrics and test-run results + components.add_security_scheme( + "metrics_and_results_token", + SecurityScheme::Http(Http::new(HttpAuthScheme::Bearer)), + ); + + // token authorising monitor agents + components.add_security_scheme( + "agents_token", + SecurityScheme::Http(Http::new(HttpAuthScheme::Bearer)), + ); + } + } +} + +/// Returns a router that serves the Swagger UI and the generated OpenAPI JSON spec. +pub(crate) fn route() -> Router { + SwaggerUi::new(routes::SWAGGER) + .url("/api-docs/openapi.json", ApiDoc::openapi()) + .into() +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/mod.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/mod.rs new file mode 100644 index 0000000000..05ecd8d703 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/mod.rs @@ -0,0 +1,69 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::http::state::AppState; +use axum::Router; +use axum::response::Redirect; +use axum::routing::{MethodRouter, get}; +use nym_http_api_common::middleware::bearer_auth::AuthLayer; +use nym_http_api_common::middleware::logging::log_request_debug; +use nym_network_monitor_orchestrator_requests::routes; +use nym_task::ShutdownToken; +use std::net::SocketAddr; +use std::sync::Arc; +use tracing::{error, info}; +use zeroize::Zeroizing; + +pub(crate) mod api_docs; +pub(crate) mod v1; + +/// Returns a handler that issues a 303 redirect to the Swagger UI. +fn swagger_redirect() -> MethodRouter { + // redirects with 303 status code + get(|| async { Redirect::to(routes::SWAGGER) }) +} + +/// Assembles the full orchestrator HTTP router with Swagger UI, v1 API routes, +/// bearer-auth middleware, and request logging. +pub(crate) fn build_router( + state: AppState, + agents_auth_token: Arc>, + metrics_and_results_auth_token: Arc>, +) -> Router { + let agents_auth = AuthLayer::new(agents_auth_token); + let metrics_and_results_auth = AuthLayer::new(metrics_and_results_auth_token); + + Router::new() + .route(routes::ROOT, swagger_redirect()) + .merge(api_docs::route()) + .nest( + routes::V1, + v1::routes(agents_auth, metrics_and_results_auth), + ) + .layer(axum::middleware::from_fn(log_request_debug)) + .with_state(state) +} + +/// Binds to `bind_address` and serves the given router until the shutdown token is cancelled. +/// The listener is created with `into_make_service_with_connect_info` so handlers can +/// extract the peer [`SocketAddr`]. +pub(crate) async fn run_http_server( + router: Router, + bind_address: SocketAddr, + shutdown_token: ShutdownToken, +) -> anyhow::Result<()> { + let listener = tokio::net::TcpListener::bind(bind_address) + .await + .inspect_err(|err| error!("couldn't bind to address {bind_address}: {err}"))?; + + info!("starting http api server on {bind_address}"); + + axum::serve( + listener, + router.into_make_service_with_connect_info::(), + ) + .with_graceful_shutdown(async move { shutdown_token.cancelled().await }) + .await?; + + Ok(()) +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/agent/mod.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/agent/mod.rs new file mode 100644 index 0000000000..872ff05c1d --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/agent/mod.rs @@ -0,0 +1,243 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::http::api::v1::error::ApiError; +use crate::http::state::AppState; +use crate::orchestrator::prometheus::{PROMETHEUS_METRICS, PrometheusMetric}; +use axum::extract::{ConnectInfo, State}; +use axum::routing::post; +use axum::{Json, Router}; +use nym_http_api_common::middleware::bearer_auth::AuthLayer; +use nym_network_monitor_orchestrator_requests::models::{ + AgentAnnounceRequest, AgentAnnounceResponse, TestRunAssignmentRequest, + TestRunAssignmentResponse, TestRunResultSubmissionRequest, TestRunSubmissionResponse, +}; +use nym_network_monitor_orchestrator_requests::routes; +use nym_validator_client::nyxd::contract_traits::NetworkMonitorsSigningClient; +use std::net::SocketAddr; +use tracing::{error, info}; + +#[utoipa::path( + operation_id = "v1_agent_announce", + tag = "Network Monitor Agent", + post, + request_body = AgentAnnounceRequest, + path = "/announce", + context_path = "/v1/agent", + security(("agents_token" = [])), + responses( + (status = 200, content( + (AgentAnnounceResponse = "application/json"), + )), + (status = 500, description = "failed to announce agent to the network monitors contract"), + ) +)] +#[tracing::instrument( + level = "debug", + skip_all, + fields( + agent_pod = %addr + ) +)] +async fn announce_agent( + ConnectInfo(addr): ConnectInfo, + State(state): State, + Json(body): Json, +) -> Result, ApiError> { + let pod_ip = addr.ip(); + info!("received announce request from pod at {pod_ip}: {body:?}"); + + PROMETHEUS_METRICS.inc(PrometheusMetric::AgentAnnounceRequests); + + // 1. upsert the agent in the cache and learn whether it has already been announced + let already_announced = state + .agents + .try_announce_agent(body.agent_mix_socket_address, body.x25519_noise_key) + .await; + + // 2. if the agent was already announced, skip the contract tx + if already_announced { + info!("agent at {pod_ip} is already announced, skipping contract tx"); + PROMETHEUS_METRICS.inc(PrometheusMetric::AgentDuplicateAnnouncementRequests); + return Ok(Json(AgentAnnounceResponse {})); + } + + // 3. attempt to announce the agent to the network monitors contract + state + .validator_client + .write() + .await + .nyxd + .authorise_network_monitor( + body.agent_mix_socket_address, + body.x25519_noise_key.to_base58_string(), + body.noise_version, + None, + ) + .await + .inspect_err(|err| { + PROMETHEUS_METRICS.inc(PrometheusMetric::AgentContractAnnounceFailures); + + error!("failed to announce agent to the network monitors contract: {err}") + }) + .map_err(|_| ApiError::ContractFailure)?; + + PROMETHEUS_METRICS.inc(PrometheusMetric::AgentContractAnnounceSuccesses); + + // 4. mark the agent as announced so subsequent calls are no-ops + state + .agents + .mark_announced(body.agent_mix_socket_address) + .await; + + Ok(Json(AgentAnnounceResponse {})) +} + +#[utoipa::path( + operation_id = "v1_agent_request_testrun", + tag = "Network Monitor Agent", + post, + request_body = TestRunAssignmentRequest, + path = "/request-testrun", + context_path = "/v1/agent", + security(("agents_token" = [])), + responses( + (status = 200, content( + (TestRunAssignmentResponse = "application/json"), + )), + (status = 400, description = "agent not found in cache, or agent has not yet been announced to the contract"), + (status = 500, description = "failed to read from storage, or a stored field could not be decoded"), + ) +)] +#[tracing::instrument( + level = "debug", + skip_all, + fields( + agent_pod = %addr + ) +)] +async fn request_testrun( + ConnectInfo(addr): ConnectInfo, + State(state): State, + Json(body): Json, +) -> Result, ApiError> { + let pod_ip = addr.ip(); + info!("received testrun request from pod at {pod_ip}"); + PROMETHEUS_METRICS.inc(PrometheusMetric::AgentTestrunRequests); + + // 1. ensure the agent still exists in our announced cache + // in case there was a weird network failure between the calls + let Some(agent) = state.agents.get_agent(body.agent_mix_socket_address).await else { + PROMETHEUS_METRICS.inc(PrometheusMetric::AgentUnknownAgentTestrunRequests); + return Err(ApiError::AgentNotFound); + }; + + if !agent.announced { + PROMETHEUS_METRICS.inc(PrometheusMetric::AgentTestrunRequestsWithoutAnnouncement); + return Err(ApiError::AgentNotAnnounced); + } + + // 2. attempt to assign a testrun to the agent + let assignment = state.assign_next_mixnode_testrun().await?; + if assignment.is_none() { + PROMETHEUS_METRICS.inc(PrometheusMetric::EmptyTestrunAssignments); + } else { + PROMETHEUS_METRICS.inc(PrometheusMetric::NonEmptyTestrunAssignments); + } + + Ok(Json(TestRunAssignmentResponse { assignment })) +} + +fn emit_testrun_result_metrics(result: &TestRunResultSubmissionRequest) { + PROMETHEUS_METRICS.inc(PrometheusMetric::TestRunResultSubmissions); + + PROMETHEUS_METRICS.inc_by( + PrometheusMetric::TestPacketsSent, + result.result.packets_sent as i64, + ); + PROMETHEUS_METRICS.inc_by( + PrometheusMetric::TestPacketsReceived, + result.result.packets_received as i64, + ); + + PROMETHEUS_METRICS.observe_histogram( + PrometheusMetric::TestDurationSeconds, + result.result.time_taken.as_secs_f64(), + ); + if let Some(latency) = result.result.approximate_latency { + PROMETHEUS_METRICS.observe_histogram( + PrometheusMetric::ApproximateNodeLatencyMs, + latency.as_millis() as f64, + ); + } + PROMETHEUS_METRICS.observe_histogram( + PrometheusMetric::TestrunReceivedPacketsRatio, + result.result.received_ratio(), + ); + + if let Some(packets_stats) = result.result.packets_statistics { + PROMETHEUS_METRICS.observe_histogram( + PrometheusMetric::AverageTestPacketRTTMs, + packets_stats.mean.as_millis() as f64, + ); + } + + if result.result.error.is_some() { + PROMETHEUS_METRICS.inc(PrometheusMetric::TestrunsErrors) + } +} + +#[utoipa::path( + operation_id = "v1_agent_submit_testrun_result", + tag = "Network Monitor Agent", + post, + request_body = TestRunResultSubmissionRequest, + path = "/submit-testrun-result", + context_path = "/v1/agent", + security(("agents_token" = [])), + responses( + (status = 200, content( + (TestRunSubmissionResponse = "application/json"), + )), + (status = 500, description = "failed to persist the test run result to storage"), + ) +)] +#[tracing::instrument( + level = "debug", + skip_all, + fields( + agent_pod = %addr + ) +)] +async fn submit_testrun_result( + ConnectInfo(addr): ConnectInfo, + State(state): State, + Json(body): Json, +) -> Result, ApiError> { + let pod_ip = addr.ip(); + + emit_testrun_result_metrics(&body); + + info!( + "received testrun result for node {} from pod at {pod_ip}", + body.node_id + ); + + state + .submit_testrun_result(body.result, body.node_id) + .await?; + + Ok(Json(TestRunSubmissionResponse {})) +} + +/// Builds the agent sub-router with all agent endpoints behind bearer-token auth. +pub(super) fn routes(auth_layer: AuthLayer) -> Router { + Router::new() + .route(routes::v1::agent::ANNOUNCE, post(announce_agent)) + .route(routes::v1::agent::REQUEST_TESTRUN, post(request_testrun)) + .route( + routes::v1::agent::SUBMIT_TESTRUN_RESULT, + post(submit_testrun_result), + ) + .route_layer(auth_layer) +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/error.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/error.rs new file mode 100644 index 0000000000..16a4595681 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/error.rs @@ -0,0 +1,51 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use axum::http::StatusCode; +use axum::response::{IntoResponse, Response}; + +/// Unified error type for all v1 API endpoints. +/// The `Display` message from each variant is used as the HTTP response body. +#[derive(Debug, thiserror::Error)] +pub(crate) enum ApiError { + #[error("agent information not found")] + AgentNotFound, + + #[error("failed to announce agent to the network monitors contract")] + ContractFailure, + + #[error("failed to read or write data from the database")] + StorageFailure, + + #[error("some of the stored data is malformed and could not be parsed")] + MalformedStoredData, + + #[error("agent hasn't been announced to the contract - can't assign testruns")] + AgentNotAnnounced, + + #[error("no test run found with the requested id")] + TestRunNotFound, + + #[error("no nym-node found with the requested node id")] + NymNodeNotFound, +} + +impl ApiError { + fn status_code(&self) -> StatusCode { + use ApiError::*; + + match self { + AgentNotFound | AgentNotAnnounced => StatusCode::BAD_REQUEST, + TestRunNotFound | NymNodeNotFound => StatusCode::NOT_FOUND, + ContractFailure | StorageFailure | MalformedStoredData => { + StatusCode::INTERNAL_SERVER_ERROR + } + } + } +} + +impl IntoResponse for ApiError { + fn into_response(self) -> Response { + (self.status_code(), self.to_string()).into_response() + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/metrics/mod.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/metrics/mod.rs new file mode 100644 index 0000000000..984b0f0def --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/metrics/mod.rs @@ -0,0 +1,30 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::http::state::AppState; +use crate::orchestrator::prometheus::PROMETHEUS_METRICS; +use axum::Router; +use axum::routing::get; +use nym_network_monitor_orchestrator_requests::routes; + +/// Returns `prometheus` compatible metrics +#[utoipa::path( + get, + path = "/prometheus", + context_path = "/v1/metrics", + tag = "Metrics", + responses( + (status = 200, body = String), + (status = 400, description = "`Authorization` header was missing"), + (status = 401, description = "Access token is missing or invalid"), + ), + security(("metrics_and_results_token" = [])) +)] +// the AuthLayer is protecting access to this endpoint +pub(crate) async fn prometheus_metrics() -> String { + PROMETHEUS_METRICS.metrics() +} + +pub(super) fn routes() -> Router { + Router::new().route(routes::v1::metrics::PROMETHEUS, get(prometheus_metrics)) +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/mod.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/mod.rs new file mode 100644 index 0000000000..26b039adc3 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/mod.rs @@ -0,0 +1,29 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::http::state::AppState; +use axum::Router; +use nym_http_api_common::middleware::bearer_auth::AuthLayer; +use nym_network_monitor_orchestrator_requests::routes; + +pub(crate) mod agent; +pub(crate) mod error; +pub(crate) mod metrics; +pub(crate) mod results; + +/// Assembles the v1 API router, nesting agent, metrics, and results sub-routers +/// under their respective path prefixes. Metrics and results share the same +/// bearer-auth layer. +pub(crate) fn routes( + agents_auth: AuthLayer, + metrics_and_results_auth: AuthLayer, +) -> Router { + Router::new() + .nest(routes::v1::AGENT, agent::routes(agents_auth)) + .merge( + Router::new() + .nest(routes::v1::METRICS, metrics::routes()) + .nest(routes::v1::RESULTS, results::routes()) + .route_layer(metrics_and_results_auth), + ) +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/results/mod.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/results/mod.rs new file mode 100644 index 0000000000..bfbfd10d15 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/results/mod.rs @@ -0,0 +1,230 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +//! Read-only HTTP endpoints that expose the orchestrator's local database: +//! the set of nym-nodes it is tracking, the test runs it has recorded, and +//! the runs currently in flight. +//! +//! All handlers are thin wrappers that extract path/query parameters and +//! delegate the actual work to [`AppState`]; conversion from storage rows to +//! the public response shapes lives in [`crate::storage::models`]. Every +//! route in this module is protected by the shared `metrics_and_results` +//! bearer token applied one level up in [`crate::http::api::v1::routes`]. + +use crate::http::api::v1::error::ApiError; +use crate::http::state::AppState; +use axum::extract::{Path, Query, State}; +use axum::routing::get; +use axum::{Json, Router}; +use nym_network_monitor_orchestrator_requests::models::{ + NymNodeData, NymNodeWithTestRun, PagedResult, Pagination, TestRunData, TestRunInProgressData, +}; +use nym_network_monitor_orchestrator_requests::routes; +use nym_validator_client::client::NodeId; + +/// Fetches a single completed test run by its database-assigned id. +/// Returns `404` with [`ApiError::TestRunNotFound`] if no such row exists — for +/// example because the run has already been evicted by the stale-result sweeper. +#[utoipa::path( + operation_id = "v1_results_testrun_by_id", + tag = "Network Monitor Results", + get, + params(("id" = i64, Path, description = "Database-assigned test-run id")), + path = "/testrun/{id}", + context_path = "/v1/results", + security(("metrics_and_results_token" = [])), + responses( + (status = 200, content( + (TestRunData = "application/json"), + )), + (status = 404, description = "no test run found with the requested id"), + (status = 500, description = "failed to read the test run from storage"), + ) +)] +async fn get_testrun_by_id( + Path(id): Path, + State(state): State, +) -> Result, ApiError> { + state + .get_testrun_by_id(id) + .await? + .map(Json) + .ok_or(ApiError::TestRunNotFound) +} + +/// Fetches a single node along with its most recent completed test run. +/// +/// The `latest_test_run` field is `None` if the node has never been tested or +/// if its most recent run has been evicted. Returns `404` with +/// [`ApiError::NymNodeNotFound`] if the orchestrator has never observed a bond +/// for this `node_id`. +#[utoipa::path( + operation_id = "v1_results_nym_node_by_node_id", + tag = "Network Monitor Results", + get, + params(("node_id" = u32, Path, description = "Mixnet-contract node id")), + path = "/nym-node/{node_id}", + context_path = "/v1/results", + security(("metrics_and_results_token" = [])), + responses( + (status = 200, content( + (NymNodeWithTestRun = "application/json"), + )), + (status = 404, description = "no nym-node found with the requested node id"), + (status = 500, description = "failed to read the node from storage, or a stored field could not be decoded"), + ) +)] +async fn get_nym_node_by_id( + Path(node_id): Path, + State(state): State, +) -> Result, ApiError> { + state + .get_nym_node_by_id(node_id) + .await? + .map(Json) + .ok_or(ApiError::NymNodeNotFound) +} + +/// Paginated list of test runs currently dispatched to agents and awaiting results. +/// +/// Ordered oldest-started first, so stale or hung runs surface at the top. In +/// normal operation the underlying table holds roughly one entry per active +/// agent. See [`Pagination`] for the page-size/page-number contract and default +/// caps. +#[utoipa::path( + operation_id = "v1_results_testruns_in_progress", + tag = "Network Monitor Results", + get, + params(Pagination), + path = "/testruns-in-progress", + context_path = "/v1/results", + security(("metrics_and_results_token" = [])), + responses( + (status = 200, content( + (PagedResult = "application/json"), + )), + (status = 500, description = "failed to read in-progress test runs from storage"), + ) +)] +async fn get_testruns_in_progress( + Query(pagination): Query, + State(state): State, +) -> Result>, ApiError> { + state + .get_testruns_in_progress_paginated(pagination) + .await + .map(Json) +} + +/// Paginated list of all completed test runs, newest first. +/// +/// See [`Pagination`] for the page-size/page-number contract and default caps. +/// `total` reflects the row count at the moment the page was read; it is +/// fetched in the same transaction as the page itself to guarantee consistency. +#[utoipa::path( + operation_id = "v1_results_testruns", + tag = "Network Monitor Results", + get, + params(Pagination), + path = "/testruns", + context_path = "/v1/results", + security(("metrics_and_results_token" = [])), + responses( + (status = 200, content( + (PagedResult = "application/json"), + )), + (status = 500, description = "failed to read test runs from storage"), + ) +)] +async fn get_testruns( + Query(pagination): Query, + State(state): State, +) -> Result>, ApiError> { + state.get_testruns_paginated(pagination).await.map(Json) +} + +/// Paginated list of every node the orchestrator has ever observed as bonded, +/// ordered by `node_id` ascending. +/// +/// Nodes are only removed from this table if they are explicitly deleted; a +/// node that has unbonded remains visible with its last-known `last_seen_bonded` +/// timestamp. +#[utoipa::path( + operation_id = "v1_results_nym_nodes", + tag = "Network Monitor Results", + get, + params(Pagination), + path = "/nym-nodes", + context_path = "/v1/results", + security(("metrics_and_results_token" = [])), + responses( + (status = 200, content( + (PagedResult = "application/json"), + )), + (status = 500, description = "failed to read nodes from storage, or a stored field could not be decoded"), + ) +)] +async fn get_nym_nodes( + Query(pagination): Query, + State(state): State, +) -> Result>, ApiError> { + state.get_nym_nodes_paginated(pagination).await.map(Json) +} + +/// Paginated history of test runs for a single node, newest first. +/// +/// If `node_id` is unknown or has never been tested the response is a valid +/// empty page (`items: []`, `total: 0`) — there is no 404 here because the +/// orchestrator can't tell from a zero-row result whether the node simply has +/// no runs yet. Backed by the `idx_testrun_node_id_timestamp` index for +/// efficient per-node lookups. +#[utoipa::path( + operation_id = "v1_results_nym_node_testruns", + tag = "Network Monitor Results", + get, + params( + ("node_id" = u32, Path, description = "Mixnet-contract node id"), + Pagination, + ), + path = "/nym-node/{node_id}/testruns", + context_path = "/v1/results", + security(("metrics_and_results_token" = [])), + responses( + (status = 200, content( + (PagedResult = "application/json"), + )), + (status = 500, description = "failed to read test runs from storage"), + ) +)] +async fn get_nym_node_testruns( + Path(node_id): Path, + Query(pagination): Query, + State(state): State, +) -> Result>, ApiError> { + state + .get_testruns_for_node_paginated(node_id, pagination) + .await + .map(Json) +} + +/// Builds the router for the `/v1/results` sub-tree. The caller is expected to +/// nest this under [`routes::v1::RESULTS`] and to attach the shared +/// metrics-and-results bearer-auth layer at the parent level. +pub(super) fn routes() -> Router { + Router::new() + .route(routes::v1::results::TESTRUN_BY_ID, get(get_testrun_by_id)) + .route( + routes::v1::results::NYM_NODE_BY_NODE_ID, + get(get_nym_node_by_id), + ) + .route( + routes::v1::results::NYM_NODE_TESTRUNS, + get(get_nym_node_testruns), + ) + .route( + routes::v1::results::TESTRUNS_IN_PROGRESS, + get(get_testruns_in_progress), + ) + .route(routes::v1::results::TESTRUNS, get(get_testruns)) + .route(routes::v1::results::NYM_NODES, get(get_nym_nodes)) +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/mod.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/mod.rs new file mode 100644 index 0000000000..8ae6c1bd6c --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/mod.rs @@ -0,0 +1,5 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +pub(crate) mod api; +pub(crate) mod state; diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/state.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/state.rs new file mode 100644 index 0000000000..99776e382c --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/state.rs @@ -0,0 +1,471 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::http::api::v1::error::ApiError; +use crate::orchestrator::prometheus::{PROMETHEUS_METRICS, PrometheusMetric}; +use crate::storage::NetworkMonitorStorage; +use crate::storage::models::NewTestRun; +use axum::extract::FromRef; +use nym_crypto::asymmetric::x25519; +use nym_network_monitor_orchestrator_requests::models::{ + NymNodeData, NymNodeWithTestRun, PagedResult, Pagination, TestRunAssignment, TestRunData, + TestRunInProgressData, TestRunResult, +}; +use nym_validator_client::DirectSigningHttpRpcValidatorClient; +use nym_validator_client::client::NodeId; +use nym_validator_client::nyxd::nym_network_monitors_contract_common::AuthorisedNetworkMonitor; +use std::collections::HashMap; +use std::net::{IpAddr, SocketAddr}; +use std::sync::Arc; +use std::time::Duration; +use time::OffsetDateTime; +use tokio::sync::{Mutex, RwLock}; +use tracing::error; + +/// Thread-safe cache of all agents known to this orchestrator, keyed by host IP. +/// Used to short-circuit the contract tx for already-announced agents. +#[derive(Clone, Default)] +pub(crate) struct KnownAgents { + inner: Arc>, +} + +impl KnownAgents { + /// Looks up an agent by its full mixnet socket address (host IP + port). + /// Returns `None` if no agent is registered at that address. + pub(crate) async fn get_agent(&self, address: SocketAddr) -> Option { + let guard = self.inner.lock().await; + let host_agents = guard.agents.get(&address.ip())?; + + host_agents + .iter() + .find(|a| a.mixnet_port == address.port()) + .copied() + } + + /// Records an announcement from the agent at `mix_listener`. The cache entry + /// is upserted: a missing entry is inserted, and if the cached noise key differs + /// from the announced one it is overwritten and the agent is treated as + /// not-yet-announced so the caller re-runs the contract tx with the new key. + /// + /// Returns the current `announced` flag: `true` means the agent was already + /// announced to the contract and the caller should skip the contract tx; + /// `false` means the caller should submit the tx and call [`Self::mark_announced`] + /// on success. + pub(crate) async fn try_announce_agent( + &self, + mix_listener: SocketAddr, + noise_key: x25519::PublicKey, + ) -> bool { + let mut guard = self.inner.lock().await; + let host_agents = guard.agents.entry(mix_listener.ip()).or_default(); + + if let Some(agent) = host_agents + .iter_mut() + .find(|agent| agent.mixnet_port == mix_listener.port()) + { + agent.last_active_at = OffsetDateTime::now_utc(); + if agent.noise_key == noise_key { + return agent.announced; + } + agent.noise_key = noise_key; + agent.announced = false; + guard.publish_gauges(); + return false; + } + + host_agents.push(KnownAgent { + mixnet_port: mix_listener.port(), + last_active_at: OffsetDateTime::now_utc(), + noise_key, + announced: false, + }); + guard.publish_gauges(); + false + } + + /// Marks the agent at `mix_listener` as announced. Should be called after a + /// successful contract transaction. + pub(crate) async fn mark_announced(&self, mix_listener: SocketAddr) { + let mut guard = self.inner.lock().await; + let Some(host_agents) = guard.agents.get_mut(&mix_listener.ip()) else { + return; + }; + if let Some(agent) = host_agents + .iter_mut() + .find(|a| a.mixnet_port == mix_listener.port()) + { + agent.announced = true; + } + guard.publish_gauges(); + } +} + +/// Rebuilds the agent cache from on-chain data. Used at orchestrator startup to +/// restore state for agents that were authorised before a restart. +impl TryFrom> for KnownAgents { + type Error = anyhow::Error; + + fn try_from(agents: Vec) -> Result { + let mut agents_map = HashMap::new(); + + for agent in agents { + let host_ip = agent.mixnet_address.ip(); + let noise_key = x25519::PublicKey::from_base58_string(&agent.bs58_x25519_noise)?; + agents_map + .entry(host_ip) + .or_insert_with(Vec::new) + .push(KnownAgent { + mixnet_port: agent.mixnet_address.port(), + // or should we use the authorisation ts? + last_active_at: OffsetDateTime::now_utc(), + noise_key, + announced: true, + }); + } + + let inner = KnownAgentsInner { agents: agents_map }; + inner.publish_gauges(); + Ok(KnownAgents { + inner: Arc::new(Mutex::new(inner)), + }) + } +} + +/// Inner state behind the [`KnownAgents`] mutex. +#[derive(Default)] +struct KnownAgentsInner { + /// Map from host IP to the list of agents running on that host. + agents: HashMap>, +} + +impl KnownAgentsInner { + /// Recomputes and publishes the `known_agents_*` gauges. Called from every mutation of + /// the inner map — we recount rather than incrementally adjust so the gauges stay correct + /// even if a future code path mutates state without going through a dedicated helper. + fn publish_gauges(&self) { + let (total, announced) = + self.agents + .values() + .fold((0i64, 0i64), |(total, announced), agents| { + let t = total + agents.len() as i64; + let a = announced + agents.iter().filter(|a| a.announced).count() as i64; + (t, a) + }); + PROMETHEUS_METRICS.set(PrometheusMetric::KnownAgentsTotal, total); + PROMETHEUS_METRICS.set(PrometheusMetric::KnownAgentsAnnounced, announced); + } +} + +/// Cached state of a single known agent on a particular host. +#[derive(Clone, Copy, Debug)] +pub(crate) struct KnownAgent { + pub(crate) mixnet_port: u16, + pub(crate) last_active_at: OffsetDateTime, + pub(crate) noise_key: x25519::PublicKey, + + /// Whether this agent has been successfully registered in the smart contract. + /// Set to `true` when restored from the chain at startup, or after a successful + /// `/announce` contract transaction. + pub(crate) announced: bool, +} + +/// Coordinates test run assignment and result storage. +/// +/// Wraps the underlying [`NetworkMonitorStorage`] and applies the configured +/// `testrun_staleness_age` when deciding which nodes are eligible for testing. +#[derive(Clone)] +pub(crate) struct TestrunManager { + /// Minimum time that must elapse after a node's last test before it becomes + /// eligible for another one. Passed to the storage layer as a staleness gate. + testrun_staleness_age: Duration, +} + +impl TestrunManager { + /// Selects the most stale idle mixnode and atomically marks it as having a test + /// in progress. Returns `None` if no mixnode is currently eligible. + async fn assign_next_mixnode_testrun( + &self, + storage: &NetworkMonitorStorage, + ) -> Result, ApiError> { + let node_to_test = match storage + .assign_next_mixnode_testrun(self.testrun_staleness_age) + .await + { + Ok(node) => node, + Err(err) => { + error!("testrun assignment storage failure: {err}"); + return Err(ApiError::StorageFailure); + } + }; + + let Some(node) = node_to_test.map(|n| n.inner) else { + return Ok(None); + }; + + let (Some(address), Some(noise_key), Some(sphinx_key), Some(key_rotation)) = ( + node.mixnet_socket_address, + node.noise_key, + node.sphinx_key, + node.key_rotation_id, + ) else { + // this should never happen as the db query should ignore entries where those fields are set to NULL + error!( + "database inconsistency - attempted to assign node {} for stress testing, but we don't have its complete data", + node.node_id + ); + return Err(ApiError::StorageFailure); + }; + + let Ok(node_address) = address.parse() else { + return Err(ApiError::MalformedStoredData); + }; + + let Ok(noise_key) = noise_key.parse() else { + return Err(ApiError::MalformedStoredData); + }; + + let Ok(sphinx_key) = sphinx_key.parse() else { + return Err(ApiError::MalformedStoredData); + }; + + Ok(Some(TestRunAssignment { + node_id: node.node_id as u32, + node_address, + noise_key, + sphinx_key, + key_rotation_id: key_rotation as u32, + })) + } + + /// Persists a completed test run result to the database and updates the + /// node's `last_testrun` pointer. + async fn submit_testrun_result( + &self, + storage: &NetworkMonitorStorage, + result: TestRunResult, + node_id: NodeId, + ) -> Result<(), ApiError> { + // currently all testruns are mixnode results + let testrun = NewTestRun::from_mixnode_result(node_id, result); + if let Err(err) = storage.insert_test_run(&testrun).await { + error!("testrun result storage failure: {err}"); + return Err(ApiError::StorageFailure); + } + Ok(()) + } +} + +/// Shared application state available to all axum request handlers. +#[derive(Clone, FromRef)] +pub(crate) struct AppState { + pub(crate) agents: KnownAgents, + + pub(crate) testrun_manager: TestrunManager, + + pub(crate) storage: NetworkMonitorStorage, + + pub(crate) validator_client: Arc>, +} + +impl AppState { + pub(crate) fn new( + agents: KnownAgents, + storage: NetworkMonitorStorage, + testrun_staleness_age: Duration, + validator_client: Arc>, + ) -> Self { + AppState { + agents, + storage, + testrun_manager: TestrunManager { + testrun_staleness_age, + }, + validator_client, + } + } + + /// Selects the most stale idle mixnode and atomically marks it as having a test + /// in progress. Returns `None` if no mixnode is currently eligible. + pub(crate) async fn assign_next_mixnode_testrun( + &self, + ) -> Result, ApiError> { + self.testrun_manager + .assign_next_mixnode_testrun(&self.storage) + .await + } + + /// Persists a completed test run result to the database and updates the + /// node's `last_testrun` pointer. + pub(crate) async fn submit_testrun_result( + &self, + result: TestRunResult, + node_id: NodeId, + ) -> Result<(), ApiError> { + self.testrun_manager + .submit_testrun_result(&self.storage, result, node_id) + .await + } + + /// Backs `GET /v1/results/testrun/{id}`. `Ok(None)` means the row doesn't + /// exist (the handler maps this to a 404); storage errors are logged and + /// collapsed to [`ApiError::StorageFailure`]. + pub(crate) async fn get_testrun_by_id(&self, id: i64) -> Result, ApiError> { + let result = match self.storage.get_testrun_by_id(id).await { + Err(err) => { + error!("get_testrun_by_id storage failure: {err}"); + return Err(ApiError::StorageFailure); + } + Ok(None) => return Ok(None), + Ok(Some(testrun)) => testrun, + }; + + Ok(Some(result.into())) + } + + /// Backs `GET /v1/results/nym-node/{node_id}`. If the node is known, its + /// snapshot is returned along with the most recent completed test run + /// (fetched in a second query via [`Self::get_testrun_by_id`]); + /// `latest_test_run` is `None` when no such run exists. + /// + /// Malformed stored data (e.g. an unparsable base58 key) is surfaced as + /// [`ApiError::MalformedStoredData`]; this should never happen in practice + /// because the orchestrator writes these fields itself. + pub(crate) async fn get_nym_node_by_id( + &self, + node_id: NodeId, + ) -> Result, ApiError> { + let nym_node = match self.storage.get_nym_node_by_id(node_id).await { + Err(err) => { + error!("get_nym_node_by_id storage failure: {err}"); + return Err(ApiError::StorageFailure); + } + Ok(None) => return Ok(None), + Ok(Some(nym_node)) => nym_node, + }; + + let latest_test_run = match nym_node.last_testrun { + None => None, + Some(testrun_id) => self.get_testrun_by_id(testrun_id).await?, + }; + + Ok(Some(NymNodeWithTestRun { + node: nym_node.try_into().map_err(|err| { + error!("get_nym_node_by_id malformed stored data: {err}"); + ApiError::MalformedStoredData + })?, + latest_test_run, + })) + } + + /// Backs `GET /v1/results/testruns-in-progress`. Returns a page of rows + /// from `testrun_in_progress` ordered oldest `started_at` first so stale + /// runs surface at the top. + pub(crate) async fn get_testruns_in_progress_paginated( + &self, + pagination: Pagination, + ) -> Result, ApiError> { + let (in_progress, total) = match self + .storage + .get_testruns_in_progress_paginated(pagination) + .await + { + Err(err) => { + error!("get_testruns_in_progress_paginated storage failure: {err}"); + return Err(ApiError::StorageFailure); + } + Ok(result) => result, + }; + + Ok(PagedResult { + page: pagination.page(), + per_page: in_progress.len(), + total, + items: in_progress.into_iter().map(Into::into).collect(), + }) + } + + /// Backs `GET /v1/results/testruns`. Returns a single page of completed + /// runs ordered newest first, together with the total row count at the + /// time the page was read (fetched in the same transaction as the page + /// itself for consistency). + pub(crate) async fn get_testruns_paginated( + &self, + pagination: Pagination, + ) -> Result, ApiError> { + let (testruns, total) = match self.storage.get_testruns_paginated(pagination).await { + Err(err) => { + error!("get_testruns_paginated storage failure: {err}"); + return Err(ApiError::StorageFailure); + } + Ok(testruns) => testruns, + }; + + Ok(PagedResult { + page: pagination.page(), + per_page: testruns.len(), + total, + items: testruns.into_iter().map(Into::into).collect(), + }) + } + + /// Backs `GET /v1/results/nym-nodes`. Returns a page of nodes ordered by + /// `node_id` ascending. Each row is converted to [`NymNodeData`] via the + /// fallible `TryFrom` impl that decodes stored base58 keys; a failure + /// anywhere in the page produces [`ApiError::MalformedStoredData`]. + pub(crate) async fn get_nym_nodes_paginated( + &self, + pagination: Pagination, + ) -> Result, ApiError> { + let (nym_nodes, total) = match self.storage.get_nym_nodes_paginated(pagination).await { + Err(err) => { + error!("get_nym_nodes_paginated storage failure: {err}"); + return Err(ApiError::StorageFailure); + } + Ok((nym_nodes, total)) => (nym_nodes, total), + }; + + let mut items = Vec::with_capacity(nym_nodes.len()); + for node in nym_nodes { + items.push(node.try_into().map_err(|err| { + error!("get_nym_nodes_paginated malformed stored data: {err}"); + ApiError::MalformedStoredData + })?); + } + + Ok(PagedResult { + page: pagination.page(), + per_page: items.len(), + total, + items, + }) + } + + /// Backs `GET /v1/results/nym-node/{node_id}/testruns`. Returns a page of + /// completed runs for a single node ordered newest first. Unknown or + /// never-tested nodes produce a valid empty page (`total: 0`) rather than + /// a 404. + pub(crate) async fn get_testruns_for_node_paginated( + &self, + node_id: NodeId, + pagination: Pagination, + ) -> Result, ApiError> { + let (testruns, total) = match self + .storage + .get_testruns_for_node_paginated(node_id, pagination) + .await + { + Err(err) => { + error!("get_testruns_for_node_paginated storage failure: {err}"); + return Err(ApiError::StorageFailure); + } + Ok((testruns, total)) => (testruns, total), + }; + + Ok(PagedResult { + page: pagination.page(), + per_page: testruns.len(), + total, + items: testruns.into_iter().map(Into::into).collect(), + }) + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/main.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/main.rs new file mode 100644 index 0000000000..f6a5d993a2 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/main.rs @@ -0,0 +1,50 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::cli::Cli; +use clap::Parser; +use nym_bin_common::bin_info_owned; +use nym_bin_common::logging::tracing_subscriber::layer::SubscriberExt; +use nym_bin_common::logging::tracing_subscriber::util::SubscriberInitExt; +use nym_bin_common::logging::{ + default_tracing_env_filter, default_tracing_fmt_layer, tracing_subscriber, +}; +use nym_network_defaults::setup_env; +use tracing::info; + +pub(crate) mod cli; +mod http; +pub(crate) mod orchestrator; +mod storage; + +fn setup_logger() -> anyhow::Result<()> { + // crates that are more granularly filtered, regardless of default `RUST_LOG` value + let filter_crates = ["reqwest", "hyper"]; + + let mut env_filter = default_tracing_env_filter(); + for crate_name in filter_crates { + env_filter = env_filter.add_directive(format!("{crate_name}=warn").parse()?); + } + + tracing_subscriber::registry() + .with(default_tracing_fmt_layer(std::io::stderr)) + .with(env_filter) + .init(); + + Ok(()) +} + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + setup_logger()?; + let cli = Cli::parse(); + setup_env(cli.config_env_file.as_ref()); + + let bin_info = bin_info_owned!(); + info!("using the following version: {bin_info}"); + + cli.execute().await?; + + info!("network monitor orchestrator is done - quitting"); + Ok(()) +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/config.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/config.rs new file mode 100644 index 0000000000..cad15f3692 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/config.rs @@ -0,0 +1,123 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use anyhow::Context; +use nym_network_defaults::{NymNetworkDetails, env_configured}; +use nym_validator_client::nyxd::AccountId; +use nym_validator_client::{client, nyxd}; +use std::net::SocketAddr; +use std::num::NonZeroU32; +use std::path::PathBuf; +use std::time::Duration; +use tracing::info; +use url::Url; + +#[derive(Debug, Clone)] +pub(crate) struct Config { + /// HTTPS RPC URL of a Nyx node (e.g. `https://rpc.nymtech.net`). + /// If not provided, the default value from the environment will be retrieved (if available). + pub(crate) nyxd_rpc_endpoint: Option, + + /// HTTP endpoint of the nym-api to which test results are submitted. + pub(crate) nym_api_endpoint: Url, + + /// HTTP address to bind the HTTP server to (e.g. `0.0.0.0:8080`). + pub(crate) http_server_bind_address: SocketAddr, + + /// How often each node should be stress-tested (e.g. `30m`, `1h`). + pub(crate) test_interval: Duration, + + /// Maximum time a single test run is allowed to run before being considered timed out + /// (e.g. `5m`). + pub(crate) test_timeout: Duration, + + /// Path to the SQLite database file. + pub(crate) database_path: PathBuf, + + /// How often the list of bonded nym-nodes is refreshed from the mixnet contract + /// (e.g. `10m`, `1h`). + pub(crate) node_refresh_rate: Duration, + + /// Timeout for querying a single node for its detailed information (sphinx key, noise key, + /// etc.). Queries that exceed this budget leave the corresponding fields as `NULL` + /// (e.g. `10s`). + pub(crate) node_info_query_timeout: Duration, + + /// Bech32 address of the mixnet contract used to retrieve the list of bonded nodes. + /// If not provided, the default value from the environment will be retrieved (if available). + pub(crate) mixnet_contract_address: Option, + + /// Bech32 address of the networks monitors contract used to authorise agents + /// If not provided, the default value from the environment will be retrieved (if available). + pub(crate) network_monitors_contract_address: Option, + + /// Maximum age of a completed test run row before it is evicted from the local database. + /// Rows older than this are assumed to have already been submitted to the nym-api + /// (e.g. `7d`, `24h`). + pub(crate) testrun_eviction_age: Duration, + + /// Maximum number of nodes queried concurrently during a node refresh cycle. + pub(crate) number_of_concurrent_node_queries: usize, + + /// Maximum number of attempts (including the initial one) made to verify that the + /// orchestrator's account is authorised in the network monitors contract before start-up. + /// The process exits with an error once the budget is exhausted. + pub(crate) chain_authorisation_check_max_attempts: NonZeroU32, + + /// Delay between consecutive chain authorisation checks during start-up. Applied both when + /// the query itself fails and when it succeeds but the orchestrator is not (yet) listed. + pub(crate) chain_authorisation_check_retry_delay: Duration, + + /// How often the orchestrator flushes accumulated test results to the nym-api as a signed + /// batch submission (e.g. `15m`, `1h`). + pub(crate) result_submission_interval: Duration, +} + +impl Config { + /// Builds the validator client configuration from the orchestrator config. + /// Falls back to environment-provided network details when RPC endpoint or + /// contract addresses are not explicitly set. + pub(crate) fn try_build_validator_client_config(&self) -> anyhow::Result { + let mut base_network_details = if env_configured() { + info!("using base NymNetworkDetails from env vars"); + NymNetworkDetails::new_from_env() + } else { + info!("using mainnet as base for NymNetworkDetails"); + NymNetworkDetails::new_mainnet() + }; + + let nyxd_endpoint = if let Some(provided) = &self.nyxd_rpc_endpoint { + provided.clone() + } else { + base_network_details + .endpoints + .first() + .context("no nyxd endpoints provided")? + .nyxd_url + .parse()? + }; + + if let Some(mixnet_contract_address) = &self.mixnet_contract_address { + info!("overwriting mixnet contract address with {mixnet_contract_address}"); + base_network_details.contracts.mixnet_contract_address = + Some(mixnet_contract_address.to_string()); + } + + if let Some(network_monitors_contract_address) = &self.network_monitors_contract_address { + info!( + "overwriting network monitors contract address with {network_monitors_contract_address}" + ); + base_network_details + .contracts + .network_monitors_contract_address = + Some(network_monitors_contract_address.to_string()); + } + + let nyxd_config = nyxd::Config::try_from_nym_network_details(&base_network_details)?; + let client_config = + client::Config::new(nyxd_endpoint, self.nym_api_endpoint.clone(), nyxd_config); + + info!("using the following config: {client_config:#?}"); + Ok(client_config) + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/mod.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/mod.rs new file mode 100644 index 0000000000..fca8d4b62e --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/mod.rs @@ -0,0 +1,336 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::http::api::{build_router, run_http_server}; +use crate::http::state::{AppState, KnownAgents}; +use crate::orchestrator::config::Config; +use crate::orchestrator::node_refresher::NodeRefresher; +use crate::orchestrator::result_submitter::ResultSubmitter; +use crate::orchestrator::stale_results_eviction::StaleResultsEviction; +use crate::storage::NetworkMonitorStorage; +use anyhow::{Context, bail}; +use nym_crypto::asymmetric::ed25519; +use nym_task::ShutdownManager; +use nym_validator_client::DirectSigningHttpRpcValidatorClient; +use nym_validator_client::client::NymApiClientExt; +use nym_validator_client::nyxd::contract_traits::{ + NetworkMonitorsQueryClient, NetworkMonitorsSigningClient, PagedNetworkMonitorsQueryClient, +}; +use nym_validator_client::nyxd::{AccountId, CosmWasmClient, bip39}; +use std::sync::Arc; +use std::time::Duration; +use tokio::sync::RwLock; +use tokio::time::sleep; +use tracing::{info, warn}; +use zeroize::Zeroizing; + +pub(crate) mod config; +mod node_refresher; +pub(crate) mod prometheus; +mod result_submitter; +mod stale_results_eviction; +pub(crate) mod testruns; + +pub(crate) struct NetworkMonitorOrchestrator { + /// Runtime configuration for the orchestrator. + pub(crate) config: Config, + + /// Validator client used to: + /// - submit test results to the nym-api + /// - query node information from the chain + /// - send authorisation transactions to the network monitors contract + pub(crate) client: Arc>, + + /// Ed25519 key pair used to sign result submissions to the nym-api. + pub(crate) identity_keys: Arc, + + /// Bearer token presented by agents when requesting work assignments and submitting results. + pub(crate) agents_http_auth_token: Arc>, + + /// Bearer token required when attempting to access the metrics or results endpoints. + pub(crate) metrics_and_results_http_auth_token: Arc>, + + /// Handle to the local SQLite database used to track nodes and test runs. + pub(crate) storage: NetworkMonitorStorage, + + /// Manages graceful shutdown signalling across all orchestrator tasks. + pub(crate) shutdown_manager: ShutdownManager, +} + +impl NetworkMonitorOrchestrator { + /// Initialises the orchestrator: connects to the database, builds the validator client, + /// and verifies that the orchestrator is authorised on both the chain and the nym-api. + pub(crate) async fn new( + config: Config, + identity_keys: Arc, + agents_http_auth_token: Zeroizing, + metrics_and_results_http_auth_token: Zeroizing, + mnemonic: bip39::Mnemonic, + ) -> anyhow::Result { + let storage = NetworkMonitorStorage::init(&config.database_path).await?; + + let client_config = config.try_build_validator_client_config()?; + let client = Arc::new(RwLock::new( + DirectSigningHttpRpcValidatorClient::new_signing(client_config, mnemonic)?, + )); + + let this = NetworkMonitorOrchestrator { + config, + client, + identity_keys, + agents_http_auth_token: Arc::new(agents_http_auth_token), + metrics_and_results_http_auth_token: Arc::new(metrics_and_results_http_auth_token), + storage, + shutdown_manager: ShutdownManager::build_new_default()?, + }; + this.verify_on_chain_balance().await?; + + let announced_identity_key = this.verify_orchestrator_chain_authorisation().await?; + this.reconcile_announced_identity_key(announced_identity_key) + .await?; + this.verify_orchestrator_nym_api_authorisation().await?; + + Ok(this) + } + + /// Returns the on-chain bech32 address of the orchestrator's signing account. + async fn address(&self) -> AccountId { + self.client.read().await.nyxd.address() + } + + /// Ensure the orchestrator has sufficient balance for transaction fees + async fn verify_on_chain_balance(&self) -> anyhow::Result<()> { + let address = self.address().await; + let Some(balance) = self + .client + .read() + .await + .nyxd + .get_balance(&address, "unym".to_string()) + .await? + else { + bail!("the orchestrator does not hold any unym balance"); + }; + if balance.amount < 1_000_000 { + bail!( + "the orchestrator does not hold sufficient amount of tokens. its current balance is {balance}" + ) + } + Ok(()) + } + + /// Verifies that the orchestrator's account is authorised to send transactions to the network + /// monitors contract (i.e. to authorise agents on-chain) and returns the identity key it has + /// previously announced on-chain, if any. + /// + /// Retries both on query failures (RPC flakiness) and on successful queries that don't list + /// this orchestrator - the latter happens routinely when the admin has scheduled an + /// authorisation transaction that hasn't landed yet, so giving it a bounded window to appear + /// avoids crash-looping the process in that race. The total budget is + /// `chain_authorisation_check_max_attempts` attempts spaced by + /// `chain_authorisation_check_retry_delay`; once exhausted the function returns an error and + /// `new()` aborts before any background tasks are spawned. + async fn verify_orchestrator_chain_authorisation(&self) -> anyhow::Result> { + let query_client = self.client.read().await.nyxd.clone_query_client(); + let address = self.address().await; + let max_attempts = self.config.chain_authorisation_check_max_attempts.get(); + let retry_delay = self.config.chain_authorisation_check_retry_delay; + + for attempt in 1..=max_attempts { + match query_client.get_network_monitor_orchestrators().await { + Ok(res) => { + if let Some(entry) = res + .authorised + .into_iter() + .find(|o| o.address.as_str() == address.as_ref()) + { + info!( + "orchestrator {address} is authorised in the network monitors contract" + ); + return Ok(entry.identity_key); + } + warn!( + attempt, + max_attempts, + "orchestrator {address} is not (yet) listed in the network monitors contract" + ); + } + Err(err) => { + warn!( + attempt, + max_attempts, + "failed to query network monitors contract for orchestrator authorisation: {err}" + ); + } + } + + if attempt < max_attempts { + sleep(retry_delay).await; + } + } + + Err(anyhow::anyhow!( + "orchestrator {address} failed to confirm its authorisation in the network monitors contract after {max_attempts} attempts" + )) + } + + /// Ensures the identity key announced on-chain matches the key the orchestrator is running + /// with. If the on-chain key is missing or stale, an update transaction is submitted so that + /// agents and the nym-api can verify signatures against the correct key. + async fn reconcile_announced_identity_key( + &self, + announced: Option, + ) -> anyhow::Result<()> { + let current = self.identity_keys.public_key().to_base58_string(); + + if announced.as_deref() == Some(current.as_str()) { + info!("on-chain announced identity key matches the local identity key"); + return Ok(()); + } + + match &announced { + Some(stale) => info!( + "on-chain announced identity key ({stale}) does not match the local identity key ({current}); submitting an update" + ), + None => info!( + "no identity key currently announced on-chain for this orchestrator; submitting the local one ({current})" + ), + } + + self.client + .write() + .await + .nyxd + .update_orchestrator_identity_key(current, None) + .await + .context( + "failed to announce the orchestrator identity key to the network monitors contract", + )?; + + info!("waiting for the key information to propagate"); + sleep(Duration::from_secs(30)).await; + + Ok(()) + } + + /// Verifies that the orchestrator's identity key is authorised to submit + /// test results to the nym-api. + async fn verify_orchestrator_nym_api_authorisation(&self) -> anyhow::Result<()> { + // ensure our key is authorised to submit test results to the nym-api + let auth_result = self + .client + .read() + .await + .nym_api + .get_known_network_monitor(&self.identity_keys.public_key().to_base58_string()) + .await?; + if !auth_result.authorised { + bail!( + "orchestrator identity key is not authorised to submit test results to the nym-api" + ); + } + Ok(()) + } + + /// Starts all orchestrator background tasks (HTTP server, node refresher, etc.) + /// and blocks until a shutdown signal is received. + pub(crate) async fn run(&mut self) -> anyhow::Result<()> { + // this shouldn't fail as we have no tasks using this client yet + let query_client = self + .client + .try_read() + .context("failed to acquire read lock on client")? + .nyxd + .clone_query_client(); + + // 1. build the shared state + // 1.1. retrieve all registered agents (by this orchestrator) from the contract + // (we assume the orchestrator has restarted and the agents are still out there as authorised) + let address = self.address().await; + let agents = query_client + .get_all_network_monitor_agents() + .await? + .into_iter() + .filter(|a| a.authorised_by.as_str() == address.as_ref()) + .collect::>(); + let agents_state = KnownAgents::try_from(agents)?; + let app_state = AppState::new( + agents_state, + self.storage.clone(), + self.config.test_interval, + self.client.clone(), + ); + + // 2. build node information refresher + let node_refresher = NodeRefresher::new( + &self.config, + query_client, + self.storage.clone(), + self.shutdown_manager.clone_shutdown_token(), + ); + + // 3. build the http server + let http_router = build_router( + app_state, + self.agents_http_auth_token.clone(), + self.metrics_and_results_http_auth_token.clone(), + ); + + // 4. build task for evicting stale test run results + let stale_results_eviction = StaleResultsEviction::new( + self.storage.clone(), + self.config.testrun_eviction_age, + self.config.test_timeout, + self.shutdown_manager.clone_shutdown_token(), + ); + + // 5. build task for submitting accumulated results to the nym-api + let result_submitter = ResultSubmitter::new( + &self.config, + self.client.read().await.nym_api.clone(), + self.storage.clone(), + self.identity_keys.clone(), + self.shutdown_manager.clone_shutdown_token(), + ); + + // 6. evict stale data before starting anything else so any test runs + // left "in progress" by a prior crashed/restarted orchestrator are + // freed up before agents start polling for work. Note: this is a + // blocking call — a hung DB at start-up will prevent the + // orchestrator from serving, which is the desired fail-fast here. + stale_results_eviction + .evict_stale_results() + .await + .context("failed to evict stale data")?; + + // 7. start all the tasks + // http server + let http_server_fut = run_http_server( + http_router, + self.config.http_server_bind_address, + self.shutdown_manager.clone_shutdown_token(), + ); + self.shutdown_manager + .try_spawn_named(http_server_fut, "http-server"); + // node refresher + self.shutdown_manager.try_spawn_named( + async move { + node_refresher.run().await; + }, + "node-refresher", + ); + // stale results eviction + self.shutdown_manager.try_spawn_named( + async move { stale_results_eviction.run().await }, + "stale-data-eviction", + ); + // nym-api result submitter + self.shutdown_manager.try_spawn_named( + async move { result_submitter.run().await }, + "result-submitter", + ); + + self.shutdown_manager.run_until_shutdown().await; + Ok(()) + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/node_refresher.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/node_refresher.rs new file mode 100644 index 0000000000..b11bfbdc4e --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/node_refresher.rs @@ -0,0 +1,243 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::orchestrator::config::Config; +use crate::orchestrator::prometheus::{PROMETHEUS_METRICS, PrometheusMetric}; +use crate::storage::NetworkMonitorStorage; +use crate::storage::models::{NewNymNode, NodeType}; +use anyhow::Context; +use futures::{StreamExt, stream}; +use nym_bin_common::bin_info; +use nym_crypto::asymmetric::x25519; +use nym_network_defaults::DEFAULT_MIX_LISTENING_PORT; +use nym_node_requests::api::client::NymNodeApiClientExt; +use nym_node_requests::api::helpers::NymNodeApiClientRetriever; +use nym_node_requests::api::v1::node::models::NodeRoles; +use nym_task::ShutdownToken; +use nym_validator_client::QueryHttpRpcNyxdClient; +use nym_validator_client::models::KeyRotationId; +use nym_validator_client::nyxd::contract_traits::PagedMixnetQueryClient; +use nym_validator_client::nyxd::nym_mixnet_contract_common::NymNodeBond; +use rand::prelude::SliceRandom; +use std::collections::HashMap; +use std::net::SocketAddr; +use std::time::Duration; +use tokio::time::{Instant, interval}; +use tracing::{error, info, warn}; + +pub(crate) struct NodeRefresher { + pub(crate) client: QueryHttpRpcNyxdClient, + + pub(crate) storage: NetworkMonitorStorage, + + /// How often the list of bonded nym-nodes is refreshed from the mixnet contract + /// (e.g. `10m`, `1h`). + pub(crate) node_refresh_rate: Duration, + + /// Timeout for querying a single node for its detailed information (sphinx key, noise key, + /// etc.). Queries that exceed this budget leave the corresponding fields as `NULL` + /// (e.g. `10s`). + pub(crate) node_info_query_timeout: Duration, + + /// Maximum number of nodes queried concurrently during a node refresh cycle. + pub(crate) number_of_concurrent_node_queries: usize, + + pub(crate) shutdown_token: ShutdownToken, +} + +/// Information about the node retrieved from the node directly +struct SelfDescribedData { + /// Mixnet socket address (host:port) at which the node accepts sphinx packets. + mixnet_socket_address: SocketAddr, + + /// X25519 public key used for Noise handshakes + noise_key: x25519::PublicKey, + + /// Sphinx public key used for packet encryption + sphinx_key: x25519::PublicKey, + + /// Key rotation epoch ID that `sphinx_key` belongs to. + key_rotation_id: KeyRotationId, + + /// The supported roles of the node in the network. + roles: NodeRoles, +} + +impl NodeRefresher { + pub(crate) fn new( + config: &Config, + client: QueryHttpRpcNyxdClient, + storage: NetworkMonitorStorage, + shutdown_token: ShutdownToken, + ) -> Self { + NodeRefresher { + client, + storage, + node_refresh_rate: config.node_refresh_rate, + node_info_query_timeout: config.node_info_query_timeout, + number_of_concurrent_node_queries: config.number_of_concurrent_node_queries, + shutdown_token, + } + } + async fn get_node_details_inner(&self, bond: NymNodeBond) -> anyhow::Result { + let node_id = bond.node_id; + + let client = NymNodeApiClientRetriever::new(bin_info!()) + .with_expected_identity(Some(bond.node.identity_key)) + .with_verify_host_information() + .with_custom_port(bond.node.custom_http_port) + .get_client(&bond.node.host, node_id) + .await?; + + let api_client = client.client; + let host_info = client + .host_information + .context("failed to query node host information")?; + + // retrieve information on the announced ports in case a non-custom mixnet port + // is being used + let aux = api_client.get_auxiliary_details().await?; + + // if the noise key is missing, it means the node is outdated, + // so it does not support stress testing anyway + let noise_key = host_info + .keys + .x25519_versioned_noise + .context("missing noise key")? + .x25519_pubkey; + let sphinx_key = host_info.keys.primary_x25519_sphinx_key.public_key; + let key_rotation_id = host_info.keys.primary_x25519_sphinx_key.rotation_id; + + // pseudorandomly choose which ip address to use - each announced address should work! + let ip_address = host_info + .ip_address + .choose(&mut rand::thread_rng()) + .context("node hasn't announced any IPs")?; + let mix_port = aux + .announce_ports + .mix_port + .unwrap_or(DEFAULT_MIX_LISTENING_PORT); + + // retrieve information about the node roles so that we can classify the node + // (we're not testing gateways yet, but we still store them for completeness) + let roles = api_client + .get_roles() + .await + .context("failed to retrieve node roles")?; + + Ok(SelfDescribedData { + mixnet_socket_address: SocketAddr::new(*ip_address, mix_port), + noise_key, + sphinx_key, + key_rotation_id, + roles, + }) + } + + async fn get_node_details(&self, bond: NymNodeBond, timeout: Duration) -> NewNymNode { + let mut node_update = NewNymNode::from_bond(&bond); + + let node_id = bond.node_id; + let self_described = match tokio::time::timeout(timeout, self.get_node_details_inner(bond)) + .await + { + Err(_timeout) => { + warn!( + "timed out while attempting to retrieve self-described node details for node {node_id}" + ); + return node_update; + } + Ok(Err(err)) => { + error!("failed to retrieve self-described node details for node {node_id}: {err}"); + return node_update; + } + Ok(Ok(info)) => info, + }; + + node_update.mixnet_socket_address = Some(self_described.mixnet_socket_address.to_string()); + node_update.noise_key = Some(self_described.noise_key.to_base58_string()); + node_update.sphinx_key = Some(self_described.sphinx_key.to_base58_string()); + node_update.key_rotation_id = Some(self_described.key_rotation_id as i64); + node_update.node_type = NodeType::from_roles(&self_described.roles); + + node_update + } + + async fn refresh_bonded_nodes(&self) -> anyhow::Result<()> { + let start = Instant::now(); + + // 1. retrieve all nodes from the contract + let nodes = self.client.get_all_nymnode_bonds().await?; + let num_nodes = nodes.len(); + info!("retrieved {num_nodes} bonded nodes from the contract"); + + // 2. retrieve detailed information from the self-described endpoints + let timeout = self.node_info_query_timeout; + let refreshed_nodes: Vec<_> = stream::iter(nodes) + .map(|b| self.get_node_details(b, timeout)) + .buffer_unordered(self.number_of_concurrent_node_queries) + .collect() + .await; + + let mut per_type: HashMap = HashMap::new(); + for node in &refreshed_nodes { + *per_type.entry(node.node_type).or_insert(0) += 1; + } + let count_of = |t: NodeType| per_type.get(&t).copied().unwrap_or(0); + let unknown = count_of(NodeType::Unknown); + let successful = (refreshed_nodes.len() as i64) - unknown; + info!("managed to retrieve full node information on {successful} nodes ({unknown} failed)"); + + PROMETHEUS_METRICS.set( + PrometheusMetric::BondedMixnodeNymNodes, + count_of(NodeType::Mixnode), + ); + PROMETHEUS_METRICS.set( + PrometheusMetric::BondedGatewayNymNodes, + count_of(NodeType::Gateway), + ); + PROMETHEUS_METRICS.set( + PrometheusMetric::BondedMixnodeAndGatewayNymNodes, + count_of(NodeType::MixnodeAndGateway), + ); + PROMETHEUS_METRICS.set(PrometheusMetric::BondedUnknownNymNodes, unknown); + PROMETHEUS_METRICS.set(PrometheusMetric::SuccessfulNymNodeDataRetrieval, successful); + PROMETHEUS_METRICS.set(PrometheusMetric::FailedNymNodeDataRetrieval, unknown); + + // 3. persist every node (including unreachable ones so we keep their + // previously-learned keys around for the next refresh). The testrun + // assignment query filters out non-mixnode / unknown entries. + self.storage + .batch_insert_or_update_nym_nodes(&refreshed_nodes) + .await?; + + // Observe the cycle duration last so it reflects the full refresh path + // (contract query + per-node queries + storage write). + PROMETHEUS_METRICS.observe_histogram( + PrometheusMetric::NodeRefreshCycleSeconds, + start.elapsed().as_secs_f64(), + ); + Ok(()) + } + + pub(crate) async fn run(&self) { + let mut interval = interval(self.node_refresh_rate); + interval.set_missed_tick_behavior(tokio::time::MissedTickBehavior::Delay); + + loop { + tokio::select! { + biased; + _ = self.shutdown_token.cancelled() => { + break + } + _ = interval.tick() => { + if let Err(err) = self.refresh_bonded_nodes().await { + error!("failed to refresh bonded nodes: {err}"); + } + } + } + } + + info!("node refresher stopped"); + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/prometheus.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/prometheus.rs new file mode 100644 index 0000000000..f48829f731 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/prometheus.rs @@ -0,0 +1,437 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +//! Prometheus metrics exposed by the orchestrator. +//! +//! Every series this service emits is declared up-front as a variant of [`PrometheusMetric`]. +//! Each variant carries its Prometheus help string via strum's `EnumProperty` attribute and is +//! mapped to a concrete counter / gauge / histogram in [`PrometheusMetric::to_registrable_metric`]. +//! Call sites emit values through the process-wide [`PROMETHEUS_METRICS`] handle, which forwards +//! to the underlying [`nym_metrics`] registry. +//! +//! The registry is pre-populated in [`NetworkMonitorPrometheusMetrics::initialise`] so that every +//! series is present (with a zero value) from the very first scrape — this avoids dashboards and +//! alerts interpreting the first observation as a reset. + +use nym_metrics::{HistogramTimer, Metric, metrics_registry}; +use std::sync::LazyLock; +use strum::{Display, EnumCount, EnumIter, EnumProperty, IntoEnumIterator}; + +/// Process-wide handle to the orchestrator's Prometheus metrics. Lazily initialised on first +/// access; the initialisation pre-registers every [`PrometheusMetric`] variant so that scrapes +/// observe a complete set of zeroed series even before any event has fired. +pub static PROMETHEUS_METRICS: LazyLock = + LazyLock::new(NetworkMonitorPrometheusMetrics::initialise); + +/// Histogram buckets (upper bounds, in seconds) for [`PrometheusMetric::TestDurationSeconds`]. +/// Densely spaced in the 40–60 s range because most completed runs cluster there and small +/// shifts in that band are the most interesting signal. +const TESTRUN_DURATION: &[f64] = &[ + // sub 5s (implicitly) + 5., // 5s - 15s + 15., // 15s - 30s + 30., // 30s - 40s + 40., // 40s - 45s + 45., // 45s - 50s + 50., // 50s - 55s + 55., // 55s - 60s + 60., // 1min - 2min + 120., // 2min - 5min + 300., // 5min+ (implicitly) +]; + +/// Histogram buckets (upper bounds, in milliseconds) for +/// [`PrometheusMetric::ApproximateNodeLatencyMs`]. Log-ish spacing from 1 ms up to 1 s — typical +/// mixnet latencies are well under 500 ms and anything past 1 s lands in the overflow bucket. +const NODE_LATENCY: &[f64] = &[ + // sub 1ms (implicitly) + 1., // 1ms - 5ms + 5., // 5ms - 10ms + 10., // 10ms - 20ms + 20., // 20ms - 50ms + 50., // 50ms - 100ms + 100., // 100ms - 200ms + 200., // 200ms - 500ms + 500., // 500ms - 1s + 1000., // 1s+ (implicitly) +]; + +/// Histogram buckets for [`PrometheusMetric::TestrunReceivedPacketsRatio`] — `received / sent`, +/// so values live in `[0, 1]`. The dedicated `<= 0.0` bucket isolates the "got nothing" case from +/// "got a few", which otherwise would all collapse into a single low bucket; upper buckets are +/// dense near 1.0 because the difference between 99% and 95% delivery is operationally significant. +const RECEIVED_PACKETS_RATIO: &[f64] = &[ + 0., // 0 - 0.1 + 0.1, // 0.1 - 0.2 + 0.2, // 0.2 - 0.3 + 0.3, // 0.3 - 0.4 + 0.4, // 0.4 - 0.5 + 0.5, // 0.5 - 0.6 + 0.6, // 0.6 - 0.7 + 0.7, // 0.7 - 0.8 + 0.8, // 0.8 - 0.9 + 0.9, // 0.9 - 0.95 + 0.95, // 0.95 - 0.98 + 0.98, // 0.98 - 0.99 + 0.99, // 0.99+ (implicitly) +]; + +/// Histogram buckets (upper bounds, in seconds) for +/// [`PrometheusMetric::NodeRefreshCycleSeconds`]. Shape targets the expected range of a single +/// refresh sweep: under a minute when everything's healthy, up to ~10 min in degraded cases +/// (large topology × per-node timeouts × limited concurrency). +const NODE_REFRESH_CYCLE: &[f64] = &[ + // sub 1s (implicitly) + 1., // 1s - 5s + 5., // 5s - 10s + 10., // 10s - 30s + 30., // 30s - 60s + 60., // 1min - 2min + 120., // 2min - 5min + 300., // 5min - 10min + 600., // 10min+ (implicitly) +]; + +/// Histogram buckets (upper bounds, in milliseconds) for +/// [`PrometheusMetric::AverageTestPacketRTTMs`]. Same shape as [`NODE_LATENCY`] — this is the +/// mean per-packet round trip over a single testrun, not the approximation used for node latency. +const AVG_PACKET_RTT: &[f64] = &[ + // sub 1ms (implicitly) + 1., // 1ms - 5ms + 5., // 5ms - 10ms + 10., // 10ms - 20ms + 20., // 20ms - 50ms + 50., // 50ms - 100ms + 100., // 100ms - 200ms + 200., // 200ms - 500ms + 500., // 500ms - 1s + 1000., // 1s+ (implicitly) +]; + +/// Every Prometheus series emitted by the orchestrator. Each variant maps to exactly one metric +/// and must carry a `help` strum property — this is verified by the `every_variant_has_help_property` +/// test. +/// +/// The Prometheus metric name is derived from the variant name via strum: `serialize_all = +/// "snake_case"` + the `nym_network_monitor_` prefix. So `MixPortRequests` becomes +/// `nym_network_monitor_mix_port_requests`. The concrete metric kind (counter / gauge / histogram, +/// plus bucket bounds) is chosen in [`PrometheusMetric::to_registrable_metric`]. +#[derive(Clone, Debug, EnumIter, Display, EnumProperty, EnumCount, Eq, Hash, PartialEq)] +#[strum(serialize_all = "snake_case", prefix = "nym_network_monitor_")] +pub enum PrometheusMetric { + #[strum(props( + help = "The number of requests to announce an agent to the network monitors contract" + ))] + AgentAnnounceRequests, + + #[strum(props( + help = "The number of duplicate requests to announce an agent to the network monitors contract (agent has already been announced before)" + ))] + AgentDuplicateAnnouncementRequests, + + #[strum(props( + help = "The number of successful announcements of an agent to the network monitors contract" + ))] + AgentContractAnnounceSuccesses, + + #[strum(props( + help = "The number of failed announcements of an agent to the network monitors contract" + ))] + AgentContractAnnounceFailures, + + #[strum(props(help = "The number of requests to assign a test run to an agent"))] + AgentTestrunRequests, + + #[strum(props( + help = "The number of requests to assign a test run to an agent that was not known to the orchestrator" + ))] + AgentUnknownAgentTestrunRequests, + + #[strum(props( + help = "The number of requests to assign a test run to an agent that was not announced to the network monitors contract" + ))] + AgentTestrunRequestsWithoutAnnouncement, + + #[strum(props( + help = "The number of testrun requests that resulted in no work being assigned" + ))] + EmptyTestrunAssignments, + + #[strum(props(help = "The number of testrun requests that resulted in work being assigned"))] + NonEmptyTestrunAssignments, + + #[strum(props(help = "The number of testrun results that were submitted by agents"))] + TestRunResultSubmissions, + + #[strum(props(help = "The number of stale testruns that were evicted from the storage"))] + StaleTestrunsEvicted, + + #[strum(props( + help = "The number of testruns in progress that timed out and were evicted from the queue and the storage" + ))] + TimedOutTestrunsEvicted, + + #[strum(props(help = "The duration of a test run, in seconds"))] + TestDurationSeconds, + + #[strum(props(help = "The number of testruns that resulted in errors"))] + TestrunsErrors, + + #[strum(props(help = "The approximate latency to a node in milliseconds"))] + ApproximateNodeLatencyMs, + + #[strum(props( + help = "Ratio of packets sent to packets received in a testrun (received / sent)" + ))] + TestrunReceivedPacketsRatio, + + #[strum(props( + help = "The average time it took to receive a test packet back from a node under test" + ))] + AverageTestPacketRTTMs, + + #[strum(props( + help = "The number of bonded nodes classified as mixnode-only from their self-described roles" + ))] + BondedMixnodeNymNodes, + + #[strum(props( + help = "The number of bonded nodes classified as gateway-only from their self-described roles" + ))] + BondedGatewayNymNodes, + + #[strum(props(help = "The number of bonded nodes advertising both mixnode and gateway roles"))] + BondedMixnodeAndGatewayNymNodes, + + #[strum(props( + help = "The number of bonded nodes whose self-described role could not be determined (unreachable or no roles reported)" + ))] + BondedUnknownNymNodes, + + #[strum(props( + help = "The number of successful Nym node data retrievals from self-described endpoints" + ))] + SuccessfulNymNodeDataRetrieval, + + #[strum(props( + help = "The number of failed Nym node data retrievals from self-described endpoints" + ))] + FailedNymNodeDataRetrieval, + + #[strum(props(help = "The duration of a full bonded-node refresh cycle, in seconds"))] + NodeRefreshCycleSeconds, + + #[strum(props( + help = "The number of test runs currently in progress (rows in testrun_in_progress)" + ))] + TestrunsInProgress, + + #[strum(props(help = "The total number of agents known to the orchestrator"))] + KnownAgentsTotal, + + #[strum(props( + help = "The number of known agents that have been announced to the network monitors contract" + ))] + KnownAgentsAnnounced, + + #[strum(props( + help = "The total number of test packets dispatched across all submitted testruns" + ))] + TestPacketsSent, + + #[strum(props( + help = "The total number of test packets received back across all submitted testruns" + ))] + TestPacketsReceived, +} + +impl PrometheusMetric { + fn name(&self) -> String { + self.to_string() + } + + fn help(&self) -> &'static str { + // SAFETY: every variant has a `help` prop defined (and there's a unit test is checking for that) + #[allow(clippy::unwrap_used)] + self.get_str("help").unwrap() + } + + /// Builds the concrete [`Metric`] this variant should register as (counter / gauge / histogram + /// with the right bucket bounds). Called from [`NetworkMonitorPrometheusMetrics::initialise`] + /// to pre-populate the registry, and from the `set` / `observe_histogram` fallback paths to + /// lazily register a metric that somehow wasn't set up yet. + fn to_registrable_metric(&self) -> Option { + let name = self.name(); + let help = self.help(); + + match self { + PrometheusMetric::AgentAnnounceRequests => Metric::new_int_counter(&name, help), + PrometheusMetric::AgentDuplicateAnnouncementRequests => { + Metric::new_int_counter(&name, help) + } + PrometheusMetric::AgentContractAnnounceSuccesses => { + Metric::new_int_counter(&name, help) + } + PrometheusMetric::AgentContractAnnounceFailures => Metric::new_int_counter(&name, help), + PrometheusMetric::AgentTestrunRequests => Metric::new_int_counter(&name, help), + PrometheusMetric::AgentUnknownAgentTestrunRequests => { + Metric::new_int_counter(&name, help) + } + PrometheusMetric::AgentTestrunRequestsWithoutAnnouncement => { + Metric::new_int_counter(&name, help) + } + PrometheusMetric::EmptyTestrunAssignments => Metric::new_int_counter(&name, help), + PrometheusMetric::NonEmptyTestrunAssignments => Metric::new_int_counter(&name, help), + PrometheusMetric::TestRunResultSubmissions => Metric::new_int_counter(&name, help), + PrometheusMetric::StaleTestrunsEvicted => Metric::new_int_counter(&name, help), + PrometheusMetric::TimedOutTestrunsEvicted => Metric::new_int_counter(&name, help), + PrometheusMetric::TestDurationSeconds => { + Metric::new_histogram(&name, help, Some(TESTRUN_DURATION)) + } + PrometheusMetric::TestrunsErrors => Metric::new_int_counter(&name, help), + PrometheusMetric::ApproximateNodeLatencyMs => { + Metric::new_histogram(&name, help, Some(NODE_LATENCY)) + } + PrometheusMetric::TestrunReceivedPacketsRatio => { + Metric::new_histogram(&name, help, Some(RECEIVED_PACKETS_RATIO)) + } + PrometheusMetric::AverageTestPacketRTTMs => { + Metric::new_histogram(&name, help, Some(AVG_PACKET_RTT)) + } + PrometheusMetric::BondedMixnodeNymNodes => Metric::new_int_gauge(&name, help), + PrometheusMetric::BondedGatewayNymNodes => Metric::new_int_gauge(&name, help), + PrometheusMetric::BondedMixnodeAndGatewayNymNodes => Metric::new_int_gauge(&name, help), + PrometheusMetric::BondedUnknownNymNodes => Metric::new_int_gauge(&name, help), + PrometheusMetric::SuccessfulNymNodeDataRetrieval => Metric::new_int_gauge(&name, help), + PrometheusMetric::FailedNymNodeDataRetrieval => Metric::new_int_gauge(&name, help), + PrometheusMetric::NodeRefreshCycleSeconds => { + Metric::new_histogram(&name, help, Some(NODE_REFRESH_CYCLE)) + } + PrometheusMetric::TestrunsInProgress => Metric::new_int_gauge(&name, help), + PrometheusMetric::KnownAgentsTotal => Metric::new_int_gauge(&name, help), + PrometheusMetric::KnownAgentsAnnounced => Metric::new_int_gauge(&name, help), + PrometheusMetric::TestPacketsSent => Metric::new_int_counter(&name, help), + PrometheusMetric::TestPacketsReceived => Metric::new_int_counter(&name, help), + } + } + + /// Sets the gauge to `value`. If the metric has not yet been registered (shouldn't happen after + /// `initialise`, but we're defensive), falls back to registering it first and retrying. + fn set(&self, value: i64) { + let reg = metrics_registry(); + if !reg.set(&self.name(), value) + && let Some(registrable) = self.to_registrable_metric() + { + reg.register_metric(registrable); + reg.set(&self.name(), value); + } + } + + fn set_float(&self, value: f64) { + metrics_registry().set_float(&self.name(), value); + } + + fn inc(&self) { + metrics_registry().inc(&self.name()); + } + + fn inc_by(&self, value: i64) { + metrics_registry().inc_by(&self.name(), value); + } + + /// Records `value` into the histogram. Same register-on-miss fallback as [`Self::set`]. + fn observe_histogram(&self, value: f64) { + let reg = metrics_registry(); + if !reg.add_to_histogram(&self.name(), value) + && let Some(registrable) = self.to_registrable_metric() + { + reg.register_metric(registrable); + reg.add_to_histogram(&self.name(), value); + } + } + + fn start_timer(&self) -> Option { + metrics_registry().start_timer(&self.name()) + } +} + +/// Orchestrator-side handle to the process-wide Prometheus registry. Constructed once via +/// [`Self::initialise`] (held in the [`PROMETHEUS_METRICS`] static) and used from call sites to +/// emit values against the [`PrometheusMetric`] enum. All mutating methods are thin wrappers +/// around the corresponding methods on [`PrometheusMetric`]. +#[non_exhaustive] +pub struct NetworkMonitorPrometheusMetrics { + _private: (), +} + +impl NetworkMonitorPrometheusMetrics { + /// Pre-registers every [`PrometheusMetric`] variant in the shared registry so that the very + /// first scrape after startup already returns the full set of series with zero values. + /// Without this, series only appear after their first observation, which can make dashboards + /// and alerting rules misbehave (missing series vs. zeroed series are not the same signal). + pub(crate) fn initialise() -> Self { + let registry = metrics_registry(); + + // we can't initialise complex metrics as their names will only be fully known at runtime + for kind in PrometheusMetric::iter() { + if let Some(metric) = kind.to_registrable_metric() { + registry.register_metric(metric); + } + } + + NetworkMonitorPrometheusMetrics { _private: () } + } + + /// Renders the full registry in the Prometheus text exposition format — this is what the + /// `/v1/metrics/prometheus` scrape endpoint returns. + pub fn metrics(&self) -> String { + metrics_registry().to_string() + } + + pub fn set(&self, metric: PrometheusMetric, value: i64) { + metric.set(value) + } + + #[allow(dead_code)] + pub fn set_float(&self, metric: PrometheusMetric, value: f64) { + metric.set_float(value) + } + + pub fn inc(&self, metric: PrometheusMetric) { + metric.inc() + } + + pub fn inc_by(&self, metric: PrometheusMetric, value: i64) { + metric.inc_by(value) + } + + pub fn observe_histogram(&self, metric: PrometheusMetric, value: f64) { + metric.observe_histogram(value) + } + + #[allow(dead_code)] + pub fn start_timer(&self, metric: PrometheusMetric) -> Option { + metric.start_timer() + } +} + +#[cfg(test)] +mod tests { + use super::*; + use strum::IntoEnumIterator; + + #[test] + fn prometheus_metrics() { + // a sanity check for anyone adding new metrics. if this test fails, + // make sure any methods on `PrometheusMetric` enum don't need updating + // or require custom Display impl + assert_eq!(29, PrometheusMetric::COUNT) + } + + #[test] + fn every_variant_has_help_property() { + for variant in PrometheusMetric::iter() { + assert!(variant.get_str("help").is_some()) + } + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/result_submitter.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/result_submitter.rs new file mode 100644 index 0000000000..fbb97de233 --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/result_submitter.rs @@ -0,0 +1,141 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::orchestrator::config::Config; +use crate::storage::NetworkMonitorStorage; +use anyhow::Context; +use nym_crypto::asymmetric::ed25519; +use nym_node_requests::api::Client; +use nym_task::ShutdownToken; +use nym_validator_client::models::{StressTestBatchSubmissionContent, StressTestResult}; +use nym_validator_client::nym_api::NymApiClientExt; +use nym_validator_client::signable::SignableMessageBody; +use std::sync::Arc; +use std::time::Duration; +use tokio::time::{Instant, MissedTickBehavior, interval_at}; +use tracing::{debug, info}; + +/// Background task that periodically drains freshly-completed test run results from the local +/// storage, wraps them into a signed [`StressTestBatchSubmission`][batch], and POSTs the batch to +/// the nym-api. +/// +/// Results are kept in local storage (and subject to the `testrun_eviction_age` retention window) +/// so that a transient nym-api outage or a crashed orchestrator doesn't silently lose +/// measurements - the next successful submission sweep will pick up anything that was missed. +/// +/// [batch]: nym_api_requests::models::network_monitor::StressTestBatchSubmission +pub(crate) struct ResultSubmitter { + /// Nym-api client used to reach the api endpoint that accepts stress-test batches. + client: Client, + + /// Handle to the local SQLite database from which pending results are drained. + storage: NetworkMonitorStorage, + + /// Ed25519 key pair whose private half signs each batch submission and whose public half + /// is the `signer` nym-api validates against the authorised-monitors set. + identity_keys: Arc, + + /// Cadence at which [`Self::run`] attempts a submission sweep. + submission_interval: Duration, + + shutdown_token: ShutdownToken, +} + +impl ResultSubmitter { + pub(crate) fn new( + config: &Config, + client: Client, + storage: NetworkMonitorStorage, + identity_keys: Arc, + shutdown_token: ShutdownToken, + ) -> Self { + ResultSubmitter { + client, + storage, + identity_keys, + submission_interval: config.result_submission_interval, + shutdown_token, + } + } + + /// Perform a single submission sweep: read every `testrun` row produced since the last + /// acknowledged batch, wrap them into a signed [`StressTestBatchSubmission`][batch], POST the + /// batch to the nym-api, and - only on success - advance the `last_submitted_testrun_id` + /// watermark. + /// + /// No-ops silently when there is nothing new to submit. + /// + /// The watermark is intentionally advanced **after** the POST returns `Ok`. A crash or + /// network failure between these two steps re-sends the same rows under a fresh batch + /// timestamp on the next sweep - harmless because nym-api's replay protection is batch-level + /// (it rejects stale/duplicate batches, not re-seen row contents) and duplicate inserts at + /// the row level are rare and tolerable. This bias towards at-least-once delivery is + /// deliberate: losing measurements is worse than occasionally duplicating them. + /// + /// [batch]: nym_api_requests::models::network_monitor::StressTestBatchSubmission + async fn submit_pending_results(&self) -> anyhow::Result<()> { + info!("submitting stress-test results to nym-api"); + let last_submitted = self.storage.get_last_submitted_testrun_id().await?; + // `None` means "never submitted" - treat as 0, which pulls everything currently in the + // table (testrun.id is AUTOINCREMENT, so always >= 1). + let after_id = last_submitted.unwrap_or(0); + + let pending = self.storage.get_testruns_after(after_id).await?; + if pending.is_empty() { + debug!("stress-test result submission sweep: no new results"); + return Ok(()); + } + + // `get_testruns_after` returns rows ordered by id ASC, so the last row carries the + // highest id and is what we advance the watermark to once the batch is accepted. + #[allow(clippy::expect_used)] + let max_id = pending.last().expect("pending is non-empty").id; + let batch_size = pending.len(); + + let results: Vec = pending.into_iter().map(Into::into).collect(); + + let signer = *self.identity_keys.public_key(); + let body = StressTestBatchSubmissionContent::new(signer, results); + let signed = body.sign(self.identity_keys.private_key()); + + self.client + .submit_stress_testing_results(&signed) + .await + .context("failed to POST stress-test batch submission to nym-api")?; + + self.storage.set_last_submitted_testrun_id(max_id).await?; + info!("submitted {batch_size} stress-test results to nym-api (testrun ids up to {max_id})"); + Ok(()) + } + + /// Run the submission loop until the shutdown token is cancelled. + /// + /// The first tick is deliberately offset by `submission_interval` so the orchestrator has + /// time to finish start-up reconciliation (chain authorisation check, etc.) before the first + /// submission is attempted. `MissedTickBehavior::Delay` avoids burst catch-up ticks if a + /// sweep runs long under DB or network pressure. + pub(crate) async fn run(&self) { + let mut interval = interval_at( + Instant::now() + self.submission_interval, + self.submission_interval, + ); + interval.set_missed_tick_behavior(MissedTickBehavior::Delay); + + loop { + tokio::select! { + biased; + _ = self.shutdown_token.cancelled() => break, + _ = interval.tick() => { + if let Err(err) = self.submit_pending_results().await { + // Submission errors shouldn't kill the task - local storage retains the + // pending rows until the retention window expires, so the next tick will + // retry and eventually catch up once the nym-api is reachable again. + tracing::error!("failed to submit stress-test results: {err}"); + } + } + } + } + + info!("stress-test result submitter stopped"); + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/stale_results_eviction.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/stale_results_eviction.rs new file mode 100644 index 0000000000..eebd7a6b7f --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/stale_results_eviction.rs @@ -0,0 +1,146 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::orchestrator::prometheus::{PROMETHEUS_METRICS, PrometheusMetric}; +use crate::storage::NetworkMonitorStorage; +use nym_task::ShutdownToken; +use std::time::Duration; +use tokio::time::{Instant, MissedTickBehavior, interval_at}; +use tracing::{debug, error, info}; + +/// Background task that periodically purges stale data from the storage. +/// +/// Two distinct kinds of staleness are handled: +/// - in-progress test runs whose assigned agent has gone silent past +/// `test_timeout` (freed so they can be reassigned), +/// - finalised test runs older than `testrun_eviction_age` (dropped to keep +/// the results table bounded). +/// +/// The two deletions are deliberately issued as separate statements rather +/// than wrapped in a transaction: they touch disjoint tables, a partial +/// failure is self-healing on the next tick, and keeping them independent +/// avoids holding a write lock across both for the whole sweep. +pub(crate) struct StaleResultsEviction { + storage: NetworkMonitorStorage, + + /// Age past which a finalised test run is considered stale and removed. + /// Mirrors `Config::testrun_eviction_age`. + testrun_eviction_age: Duration, + + /// Maximum time a test run may remain "in progress" before we assume the + /// assigned agent has died and free the slot for reassignment. + /// Mirrors `Config::test_timeout`. + test_timeout: Duration, + + /// Cadence at which [`Self::run`] performs an eviction sweep. + check_interval: Duration, + + shutdown_token: ShutdownToken, +} + +/// Lower bound on the sweep cadence to avoid hammering the DB (or panicking +/// `interval_at`) when either timeout is configured to an unrealistically +/// small value. +const MIN_CHECK_INTERVAL: Duration = Duration::from_secs(60); + +impl StaleResultsEviction { + pub(crate) fn new( + storage: NetworkMonitorStorage, + testrun_eviction_age: Duration, + test_timeout: Duration, + shutdown_token: ShutdownToken, + ) -> Self { + // Sweep at least twice per shortest timeout window so the worst-case + // lag between an item going stale and being evicted is bounded by + // roughly 1.5x that timeout rather than 2x. Floored at + // `MIN_CHECK_INTERVAL` to stay safe under degenerate configs. + let check_interval = Duration::max( + MIN_CHECK_INTERVAL, + Duration::min(testrun_eviction_age, test_timeout) / 2, + ); + + Self { + storage, + testrun_eviction_age, + test_timeout, + check_interval, + shutdown_token, + } + } + + /// Performs a single eviction sweep: clears timed-out in-progress test + /// runs and deletes results older than the configured retention window. + /// Logs how many rows were affected so ops can confirm the task is doing + /// real work (and spot unexpected spikes). + pub(crate) async fn evict_stale_results(&self) -> anyhow::Result<()> { + let cleared_in_progress = self + .storage + .clear_timed_out_testruns_in_progress(self.test_timeout) + .await?; + let evicted_old = self + .storage + .evict_old_testruns(self.testrun_eviction_age) + .await?; + + if cleared_in_progress > 0 || evicted_old > 0 { + PROMETHEUS_METRICS.inc_by( + PrometheusMetric::TimedOutTestrunsEvicted, + cleared_in_progress as i64, + ); + PROMETHEUS_METRICS.inc_by(PrometheusMetric::StaleTestrunsEvicted, evicted_old as i64); + + info!( + cleared_in_progress, + evicted_old, "stale data eviction sweep completed" + ); + } else { + debug!("stale data eviction sweep completed: nothing to evict"); + } + + // Reconcile the in-flight gauge against the authoritative row count. The gauge is + // primarily maintained live via inc/dec at assign/submit/timeout paths; this sweep is + // a safety net that corrects any drift (e.g. from a future code path that forgets to + // update the gauge) and bounds the worst-case staleness to one sweep interval. + match self.storage.count_testruns_in_progress().await { + Ok(count) => PROMETHEUS_METRICS.set(PrometheusMetric::TestrunsInProgress, count), + Err(err) => error!("failed to count in-flight testruns for metric: {err}"), + } + Ok(()) + } + + /// Runs the eviction loop until the shutdown token is cancelled. + /// + /// Cancellation is cooperative: it is only observed between sweeps, so a + /// sweep already in flight is allowed to finish. This keeps partial + /// deletions from being left on the floor at shutdown. + /// + /// The first tick is deliberately offset by `check_interval` because the + /// orchestrator invokes [`Self::evict_stale_results`] once during start-up + /// (to reap anything left behind by a prior crash or restart), so an + /// immediate tick here would redo that work. + /// + /// `MissedTickBehavior::Delay` prevents burst catch-up ticks when a sweep + /// runs long under DB load — otherwise a slow sweep would queue multiple + /// back-to-back ticks and amplify the pressure that made it slow in the + /// first place. + pub(crate) async fn run(&self) { + let mut interval = interval_at(Instant::now() + self.check_interval, self.check_interval); + interval.set_missed_tick_behavior(MissedTickBehavior::Delay); + + loop { + tokio::select! { + biased; + _ = self.shutdown_token.cancelled() => break, + _ = interval.tick() => { + if let Err(err) = self.evict_stale_results().await { + // Transient storage errors shouldn't kill the task — the next + // tick will retry and any missed items simply age a bit longer. + error!("failed to evict stale results: {err}"); + } + } + } + } + + info!("stale results eviction stopped"); + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/testruns.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/testruns.rs new file mode 100644 index 0000000000..bdc05451cb --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/testruns.rs @@ -0,0 +1,2 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/storage/manager.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/storage/manager.rs new file mode 100644 index 0000000000..bcb479e1fd --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/storage/manager.rs @@ -0,0 +1,1540 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::storage::models::{NewNymNode, NewTestRun, NymNode, TestRun, TestRunInProgress}; +use time::OffsetDateTime; + +#[derive(Clone)] +pub(crate) struct StorageManager { + pub(crate) connection_pool: sqlx::SqlitePool, +} + +impl StorageManager { + /// Inserts or updates multiple node records in a single transaction. + /// + /// For each node, if a row with the same `node_id` already exists, all fields except + /// `identity_key` are updated — `identity_key` is intentionally left unchanged because + /// a given `node_id` always corresponds to exactly one identity key and is never reassigned. + /// + /// Wrapping the entire batch in one transaction means SQLite performs a single WAL sync + /// rather than one per row. + pub(crate) async fn batch_insert_or_update_nym_nodes( + &self, + nodes: &[NewNymNode], + ) -> anyhow::Result<()> { + let mut tx = self.connection_pool.begin().await?; + + for node in nodes { + sqlx::query!( + r#" + INSERT INTO nym_node ( + node_id, + identity_key, + last_seen_bonded, + mixnet_socket_address, + noise_key, + sphinx_key, + key_rotation_id, + node_type + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?) + ON CONFLICT (node_id) DO UPDATE SET + last_seen_bonded = excluded.last_seen_bonded, + mixnet_socket_address = excluded.mixnet_socket_address, + noise_key = excluded.noise_key, + sphinx_key = excluded.sphinx_key, + key_rotation_id = excluded.key_rotation_id, + node_type = excluded.node_type + "#, + node.node_id, + node.identity_key, + node.last_seen_bonded, + node.mixnet_socket_address, + node.noise_key, + node.sphinx_key, + node.key_rotation_id, + node.node_type, + ) + .execute(&mut *tx) + .await?; + } + + tx.commit().await?; + Ok(()) + } + + /// Inserts a completed test run and returns the auto-assigned row ID. + pub(crate) async fn insert_test_run(&self, run: &NewTestRun) -> anyhow::Result { + let id = sqlx::query!( + r#" + INSERT INTO testrun ( + node_id, + test_type, + test_timestamp, + time_taken_us, + ingress_noise_handshake_us, + egress_noise_handshake_us, + sphinx_packet_delay_us, + packets_sent, + packets_received, + approximate_latency_us, + packets_rtt_min_us, + packets_rtt_mean_us, + packets_rtt_median_us, + packets_rtt_max_us, + packets_rtt_std_dev_us, + sending_latency_min_us, + sending_latency_mean_us, + sending_latency_median_us, + sending_latency_max_us, + sending_latency_std_dev_us, + received_duplicates, + error + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + "#, + run.node_id, + run.test_type, + run.test_timestamp, + run.time_taken_us, + run.ingress_noise_handshake_us, + run.egress_noise_handshake_us, + run.sphinx_packet_delay_us, + run.packets_sent, + run.packets_received, + run.approximate_latency_us, + run.packets_rtt_min_us, + run.packets_rtt_mean_us, + run.packets_rtt_median_us, + run.packets_rtt_max_us, + run.packets_rtt_std_dev_us, + run.sending_latency_min_us, + run.sending_latency_mean_us, + run.sending_latency_median_us, + run.sending_latency_max_us, + run.sending_latency_std_dev_us, + run.received_duplicates, + run.error, + ) + .execute(&self.connection_pool) + .await? + .last_insert_rowid(); + Ok(id) + } + + /// Marks a node as having a test run in progress by inserting into `testrun_in_progress`. + /// Returns an error if the node already has a run in progress (PRIMARY KEY conflict). + #[cfg(test)] + pub(crate) async fn mark_testrun_in_progress( + &self, + node_id: i64, + started_at: OffsetDateTime, + ) -> anyhow::Result<()> { + sqlx::query!( + "INSERT INTO testrun_in_progress (node_id, started_at) VALUES (?, ?)", + node_id, + started_at, + ) + .execute(&self.connection_pool) + .await?; + Ok(()) + } + + /// Removes all in-progress markers with a `started_at` older than `cutoff`, on the + /// assumption that those runs have timed out and will never complete. + pub(crate) async fn clear_timed_out_testruns_in_progress( + &self, + cutoff: OffsetDateTime, + ) -> anyhow::Result { + let res = sqlx::query!( + "DELETE FROM testrun_in_progress WHERE started_at < ?", + cutoff, + ) + .execute(&self.connection_pool) + .await?; + Ok(res.rows_affected()) + } + + /// Returns the number of rows currently in `testrun_in_progress` — i.e. the number of + /// test runs that have been assigned to an agent but not yet submitted back. + pub(crate) async fn count_testruns_in_progress(&self) -> anyhow::Result { + let total: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM testrun_in_progress") + .fetch_one(&self.connection_pool) + .await?; + Ok(total) + } + + /// Removes the in-progress marker for a node once its test run has completed or been abandoned. + /// Returns the number of rows actually deleted — callers use this to avoid decrementing the + /// `TestrunsInProgress` gauge when the row had already been cleared out by eviction (e.g. a + /// result submission that arrives after the agent's slot timed out). + pub(crate) async fn clear_testrun_in_progress(&self, node_id: i64) -> anyhow::Result { + let res = sqlx::query!("DELETE FROM testrun_in_progress WHERE node_id = ?", node_id,) + .execute(&self.connection_pool) + .await?; + Ok(res.rows_affected()) + } + + /// Atomically selects the most stale idle mixnode and marks it as having a test run in + /// progress. + /// + /// "Most stale" is defined as: nodes that have never been tested come first, followed by + /// nodes whose last test run has the oldest timestamp. + /// + /// `last_tested_before` acts as a minimum-staleness gate: a node that has already been + /// tested is only eligible if its last test run completed before this timestamp. Nodes + /// that have never been tested are always eligible regardless of this value. The caller + /// is expected to pass `now - min_test_interval`. + /// + /// `now` is recorded as the `started_at` timestamp on the resulting `testrun_in_progress` + /// row. It is accepted as an argument rather than read from the clock internally so that + /// callers can use a consistent timestamp across related operations. + /// + /// Nodes with a row in `testrun_in_progress` are excluded entirely. + /// Nodes where `mixnet_socket_address`, `noise_key`, or `sphinx_key` is NULL are also + /// excluded, as they lack the information required to perform a test. + /// Only nodes whose `node_type` is `mixnode` or `mixnode_and_gateway` are eligible; + /// gateway-only and unclassified (`unknown`) nodes are excluded. + /// + /// Returns `None` if no eligible idle mixnode exists. + pub(crate) async fn assign_next_mixnode_testrun( + &self, + now: OffsetDateTime, + last_tested_before: OffsetDateTime, + ) -> anyhow::Result> { + // Starts a write (IMMEDIATE) transaction, to prevent issue when upgrading from a read one to a write one + let mut tx = self.connection_pool.begin_with("BEGIN IMMEDIATE").await?; + + let node = sqlx::query_as::<_, NymNode>( + r#" + SELECT + n.node_id, + n.identity_key, + n.last_seen_bonded, + n.mixnet_socket_address, + n.noise_key, + n.sphinx_key, + n.key_rotation_id, + n.node_type, + n.last_testrun + FROM nym_node n + LEFT JOIN testrun_in_progress tip ON tip.node_id = n.node_id + LEFT JOIN testrun tr ON tr.id = n.last_testrun + WHERE tip.node_id IS NULL + AND n.mixnet_socket_address IS NOT NULL + AND n.noise_key IS NOT NULL + AND n.sphinx_key IS NOT NULL + AND n.node_type IN ('mixnode', 'mixnode_and_gateway') + AND (n.last_testrun IS NULL OR tr.test_timestamp < ?) + ORDER BY tr.test_timestamp ASC NULLS FIRST + LIMIT 1 + "#, + ) + .bind(last_tested_before) + .fetch_optional(&mut *tx) + .await?; + + if let Some(ref node) = node { + sqlx::query!( + "INSERT INTO testrun_in_progress (node_id, started_at) VALUES (?, ?)", + node.inner.node_id, + now, + ) + .execute(&mut *tx) + .await?; + } + + tx.commit().await?; + Ok(node) + } + + /// Fetches a single `testrun` row by its primary key. + /// + /// Returns `None` if no row with that id exists. + pub(crate) async fn get_testrun_by_id(&self, id: i64) -> anyhow::Result> { + let row = sqlx::query_as::<_, TestRun>("SELECT * FROM testrun WHERE id = ?") + .bind(id) + .fetch_optional(&self.connection_pool) + .await?; + Ok(row) + } + + /// Fetches a single `nym_node` row by its `node_id`. + /// + /// Returns `None` if the orchestrator has never seen a bond for this node. + pub(crate) async fn get_nym_node_by_id(&self, node_id: i64) -> anyhow::Result> { + let row = sqlx::query_as::<_, NymNode>("SELECT * FROM nym_node WHERE node_id = ?") + .bind(node_id) + .fetch_optional(&self.connection_pool) + .await?; + Ok(row) + } + + /// Fetches a page of `testrun` rows filtered to a single `node_id`, ordered by + /// `test_timestamp` descending (newest first), together with the total number of rows + /// for that node (used to populate `PagedResult::total`). + /// + /// Backed by the `idx_testrun_node_id_timestamp` index. + /// + /// `limit` and `offset` translate directly to SQL `LIMIT` / `OFFSET`; the caller is + /// expected to derive them from the public pagination contract as + /// `limit = size` and `offset = page * size`. + /// + /// The page and total count are fetched inside a single transaction so that the `total` + /// is consistent with the rows returned. + pub(crate) async fn get_testruns_for_node_paginated( + &self, + node_id: i64, + limit: i64, + offset: i64, + ) -> anyhow::Result<(Vec, i64)> { + let mut tx = self.connection_pool.begin().await?; + + let rows = sqlx::query_as::<_, TestRun>( + "SELECT * FROM testrun WHERE node_id = ? ORDER BY test_timestamp DESC LIMIT ? OFFSET ?", + ) + .bind(node_id) + .bind(limit) + .bind(offset) + .fetch_all(&mut *tx) + .await?; + + let total: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM testrun WHERE node_id = ?") + .bind(node_id) + .fetch_one(&mut *tx) + .await?; + + tx.commit().await?; + Ok((rows, total)) + } + + /// Fetches a page of `testrun` rows, ordered by `test_timestamp` descending (newest first), + /// together with the total number of rows in the table (used to populate + /// `PagedResult::total`). + /// + /// `limit` and `offset` translate directly to SQL `LIMIT` / `OFFSET`; the caller is + /// expected to derive them from the public pagination contract as + /// `limit = size` and `offset = page * size`. + /// + /// The page and total count are fetched inside a single transaction so that the `total` + /// is consistent with the rows returned (no tearing if another writer commits in between). + pub(crate) async fn get_testruns_paginated( + &self, + limit: i64, + offset: i64, + ) -> anyhow::Result<(Vec, i64)> { + let mut tx = self.connection_pool.begin().await?; + + let rows = sqlx::query_as::<_, TestRun>( + "SELECT * FROM testrun ORDER BY test_timestamp DESC LIMIT ? OFFSET ?", + ) + .bind(limit) + .bind(offset) + .fetch_all(&mut *tx) + .await?; + + let total: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM testrun") + .fetch_one(&mut *tx) + .await?; + + tx.commit().await?; + Ok((rows, total)) + } + + /// Fetches a page of `nym_node` rows, ordered by `node_id` ascending, together with the + /// total number of rows in the table (used to populate `PagedResult::total`). + /// + /// `limit` and `offset` translate directly to SQL `LIMIT` / `OFFSET`; the caller is + /// expected to derive them from the public pagination contract as + /// `limit = size` and `offset = page * size`. + /// + /// The page and total count are fetched inside a single transaction so that the `total` + /// is consistent with the rows returned (no tearing if another writer commits in between). + pub(crate) async fn get_nym_nodes_paginated( + &self, + limit: i64, + offset: i64, + ) -> anyhow::Result<(Vec, i64)> { + let mut tx = self.connection_pool.begin().await?; + + let rows = sqlx::query_as::<_, NymNode>( + "SELECT * FROM nym_node ORDER BY node_id ASC LIMIT ? OFFSET ?", + ) + .bind(limit) + .bind(offset) + .fetch_all(&mut *tx) + .await?; + + let total: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM nym_node") + .fetch_one(&mut *tx) + .await?; + + tx.commit().await?; + Ok((rows, total)) + } + + /// Fetches a page of `testrun_in_progress` rows, ordered from oldest `started_at` to + /// newest (so stale/hung runs surface first), together with the total number of rows in + /// the table (used to populate `PagedResult::total`). + /// + /// `limit` and `offset` translate directly to SQL `LIMIT` / `OFFSET`; the caller is + /// expected to derive them from the public pagination contract as + /// `limit = size` and `offset = page * size`. + /// + /// The page and total count are fetched inside a single transaction so that the `total` + /// is consistent with the rows returned (no tearing if another writer commits in between). + /// + /// At steady state this table holds roughly one row per concurrently-testing agent, so + /// the ordinary page-size cap from [`Pagination`] is more than enough headroom. + pub(crate) async fn get_testruns_in_progress_paginated( + &self, + limit: i64, + offset: i64, + ) -> anyhow::Result<(Vec, i64)> { + let mut tx = self.connection_pool.begin().await?; + + let rows = sqlx::query_as::<_, TestRunInProgress>( + "SELECT * FROM testrun_in_progress ORDER BY started_at ASC LIMIT ? OFFSET ?", + ) + .bind(limit) + .bind(offset) + .fetch_all(&mut *tx) + .await?; + + let total: i64 = sqlx::query_scalar("SELECT COUNT(*) FROM testrun_in_progress") + .fetch_one(&mut *tx) + .await?; + + tx.commit().await?; + Ok((rows, total)) + } + + /// Deletes all `testrun` rows whose `test_timestamp` is older than `cutoff`. + /// + /// Intended to be called periodically with `now - eviction_age` as the cutoff to keep + /// the local database from growing unboundedly. Rows that are evicted are assumed to + /// have already been submitted to the nym-api for persistent storage. + /// + /// Any `nym_node.last_testrun` foreign key that pointed at an evicted row is automatically + /// set to `NULL` by the database (`ON DELETE SET NULL`). + pub(crate) async fn evict_old_testruns(&self, cutoff: OffsetDateTime) -> anyhow::Result { + let res = sqlx::query!("DELETE FROM testrun WHERE test_timestamp < ?", cutoff) + .execute(&self.connection_pool) + .await?; + Ok(res.rows_affected()) + } + + /// Returns the id of the most recent `testrun` that has been successfully submitted to the + /// nym-api, or `None` if no batch has been submitted yet (either because the orchestrator has + /// only just been started, or because no testruns have been produced at all). + /// + /// The underlying `metadata` row is allowed to not exist and is also allowed to exist with a + /// `NULL` column — both cases map to `None` here. + pub(crate) async fn get_last_submitted_testrun_id(&self) -> anyhow::Result> { + let id = sqlx::query_scalar!("SELECT last_submitted_testrun_id FROM metadata WHERE id = 0") + .fetch_optional(&self.connection_pool) + .await? + .flatten(); + Ok(id) + } + + /// Records that all testruns with `id <= testrun_id` have been successfully submitted to the + /// nym-api. Inserts the singleton `metadata` row if it does not yet exist. + pub(crate) async fn set_last_submitted_testrun_id( + &self, + testrun_id: i64, + ) -> anyhow::Result<()> { + sqlx::query!( + r#" + INSERT INTO metadata (id, last_submitted_testrun_id) VALUES (0, ?) + ON CONFLICT (id) DO UPDATE SET last_submitted_testrun_id = excluded.last_submitted_testrun_id + "#, + testrun_id, + ) + .execute(&self.connection_pool) + .await?; + Ok(()) + } + + /// Fetches every `testrun` row with an id strictly greater than `after_id`, ordered by id + /// ascending so the caller can pick the highest-id submitted row deterministically. + /// + /// `after_id = 0` (the default used before any batch has been submitted) returns every row in + /// the table, since `testrun.id` is `AUTOINCREMENT` and therefore always `>= 1`. + pub(crate) async fn get_testruns_after(&self, after_id: i64) -> anyhow::Result> { + let rows = + sqlx::query_as::<_, TestRun>("SELECT * FROM testrun WHERE id > ? ORDER BY id ASC") + .bind(after_id) + .fetch_all(&self.connection_pool) + .await?; + Ok(rows) + } + + /// Updates `nym_node.last_testrun` to point at the given test run ID. + pub(crate) async fn set_node_last_testrun( + &self, + node_id: i64, + testrun_id: i64, + ) -> anyhow::Result<()> { + sqlx::query!( + "UPDATE nym_node SET last_testrun = ? WHERE node_id = ?", + testrun_id, + node_id, + ) + .execute(&self.connection_pool) + .await?; + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::storage::models::{NewNymNode, NewTestRun, NodeType, TestType}; + use std::path::Path; + use time::macros::datetime; + + async fn setup() -> StorageManager { + let pool = sqlx::SqlitePool::connect("sqlite::memory:") + .await + .expect("failed to create in-memory SQLite pool"); + let migrations_path = Path::new(env!("CARGO_MANIFEST_DIR")).join("migrations"); + sqlx::migrate::Migrator::new(migrations_path.as_path()) + .await + .expect("failed to find migrations") + .run(&pool) + .await + .expect("failed to run migrations"); + StorageManager { + connection_pool: pool, + } + } + + fn node(id: i64, identity_key: &str) -> NewNymNode { + NewNymNode { + node_id: id, + identity_key: identity_key.to_string(), + last_seen_bonded: datetime!(2025-01-01 00:00:00 UTC), + mixnet_socket_address: Some("1.2.3.4:1789".to_string()), + noise_key: Some("placeholder_noise_key".to_string()), + sphinx_key: Some("placeholder_sphinx_key".to_string()), + key_rotation_id: Some(0), + node_type: NodeType::Mixnode, + } + } + + fn minimal_test_run(node_id: i64) -> NewTestRun { + NewTestRun { + node_id, + test_type: TestType::Mixnode, + test_timestamp: datetime!(2025-06-01 12:00:00 UTC), + time_taken_us: 0, + ingress_noise_handshake_us: None, + egress_noise_handshake_us: None, + sphinx_packet_delay_us: 0, + packets_sent: 0, + packets_received: 0, + approximate_latency_us: None, + packets_rtt_min_us: None, + packets_rtt_mean_us: None, + packets_rtt_median_us: None, + packets_rtt_max_us: None, + packets_rtt_std_dev_us: None, + sending_latency_min_us: None, + sending_latency_mean_us: None, + sending_latency_median_us: None, + sending_latency_max_us: None, + sending_latency_std_dev_us: None, + received_duplicates: false, + error: None, + } + } + + /// Seeds a single nym_node row so that testruns referencing `node_id` satisfy the FK. + async fn seed_node(db: &StorageManager, node_id: i64) { + db.batch_insert_or_update_nym_nodes(&[node(node_id, &format!("key_{node_id}"))]) + .await + .unwrap(); + } + + mod batch_insert_or_update_nym_nodes { + use super::*; + + #[tokio::test] + async fn inserts_multiple_nodes() { + let db = setup().await; + let nodes = vec![node(1, "key_a"), node(2, "key_b"), node(3, "key_c")]; + db.batch_insert_or_update_nym_nodes(&nodes).await.unwrap(); + + let count = sqlx::query_scalar!("SELECT COUNT(*) FROM nym_node") + .fetch_one(&db.connection_pool) + .await + .unwrap(); + assert_eq!(count, 3); + } + + #[tokio::test] + async fn updates_existing_nodes_in_batch() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[node(1, "key_a")]) + .await + .unwrap(); + + let mut updated = node(1, "key_a"); + updated.mixnet_socket_address = Some("9.9.9.9:1789".to_string()); + updated.noise_key = Some("new_noise".to_string()); + + let nodes = vec![updated, node(2, "key_b")]; + db.batch_insert_or_update_nym_nodes(&nodes).await.unwrap(); + + let row = sqlx::query!( + "SELECT mixnet_socket_address, noise_key FROM nym_node WHERE node_id = 1" + ) + .fetch_one(&db.connection_pool) + .await + .unwrap(); + assert_eq!(row.mixnet_socket_address.as_deref(), Some("9.9.9.9:1789")); + assert_eq!(row.noise_key.as_deref(), Some("new_noise")); + + let count = sqlx::query_scalar!("SELECT COUNT(*) FROM nym_node") + .fetch_one(&db.connection_pool) + .await + .unwrap(); + assert_eq!(count, 2); + } + + #[tokio::test] + async fn empty_batch_is_noop() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[]).await.unwrap(); + + let count = sqlx::query_scalar!("SELECT COUNT(*) FROM nym_node") + .fetch_one(&db.connection_pool) + .await + .unwrap(); + assert_eq!(count, 0); + } + } + + mod insert_test_run { + use super::*; + + #[tokio::test] + async fn returns_sequential_ids() { + let db = setup().await; + seed_node(&db, 1).await; + let id1 = db.insert_test_run(&minimal_test_run(1)).await.unwrap(); + let id2 = db.insert_test_run(&minimal_test_run(1)).await.unwrap(); + assert!(id2 > id1); + } + + #[tokio::test] + async fn persists_fields() { + let db = setup().await; + seed_node(&db, 1).await; + let mut run = minimal_test_run(1); + run.packets_sent = 100; + run.packets_received = 95; + run.received_duplicates = true; + run.error = Some("timeout".to_string()); + let id = db.insert_test_run(&run).await.unwrap(); + + let row = sqlx::query!( + "SELECT packets_sent, packets_received, received_duplicates, error + FROM testrun WHERE id = ?", + id + ) + .fetch_one(&db.connection_pool) + .await + .unwrap(); + assert_eq!(row.packets_sent, 100); + assert_eq!(row.packets_received, 95); + assert!(row.received_duplicates); + assert_eq!(row.error.as_deref(), Some("timeout")); + } + } + + mod set_node_last_testrun { + use super::*; + + #[tokio::test] + async fn links_run_to_node() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[node(1, "key_a")]) + .await + .unwrap(); + let run_id = db.insert_test_run(&minimal_test_run(1)).await.unwrap(); + db.set_node_last_testrun(1, run_id).await.unwrap(); + + let row = sqlx::query!("SELECT last_testrun FROM nym_node WHERE node_id = 1") + .fetch_one(&db.connection_pool) + .await + .unwrap(); + assert_eq!(row.last_testrun, Some(run_id)); + } + } + + mod mark_testrun_in_progress { + use super::*; + + #[tokio::test] + async fn inserts_row() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[node(1, "key_a")]) + .await + .unwrap(); + db.mark_testrun_in_progress(1, datetime!(2025-06-01 10:00:00 UTC)) + .await + .unwrap(); + + let count = + sqlx::query_scalar!("SELECT COUNT(*) FROM testrun_in_progress WHERE node_id = 1") + .fetch_one(&db.connection_pool) + .await + .unwrap(); + assert_eq!(count, 1); + } + + #[tokio::test] + async fn rejects_duplicate() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[node(1, "key_a")]) + .await + .unwrap(); + db.mark_testrun_in_progress(1, datetime!(2025-06-01 10:00:00 UTC)) + .await + .unwrap(); + let result = db + .mark_testrun_in_progress(1, datetime!(2025-06-01 11:00:00 UTC)) + .await; + assert!(result.is_err()); + } + } + + mod clear_testrun_in_progress { + use super::*; + + #[tokio::test] + async fn removes_row() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[node(1, "key_a")]) + .await + .unwrap(); + db.mark_testrun_in_progress(1, datetime!(2025-06-01 10:00:00 UTC)) + .await + .unwrap(); + db.clear_testrun_in_progress(1).await.unwrap(); + + let count = + sqlx::query_scalar!("SELECT COUNT(*) FROM testrun_in_progress WHERE node_id = 1") + .fetch_one(&db.connection_pool) + .await + .unwrap(); + assert_eq!(count, 0); + } + } + + mod clear_timed_out_testruns_in_progress { + use super::*; + + #[tokio::test] + async fn removes_only_old_entries() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[node(1, "key_a")]) + .await + .unwrap(); + db.batch_insert_or_update_nym_nodes(&[node(2, "key_b")]) + .await + .unwrap(); + db.mark_testrun_in_progress(1, datetime!(2025-06-01 08:00:00 UTC)) + .await + .unwrap(); + db.mark_testrun_in_progress(2, datetime!(2025-06-01 12:00:00 UTC)) + .await + .unwrap(); + + // cutoff between the two timestamps + db.clear_timed_out_testruns_in_progress(datetime!(2025-06-01 10:00:00 UTC)) + .await + .unwrap(); + + let remaining: Vec = + sqlx::query_scalar!("SELECT node_id FROM testrun_in_progress ORDER BY node_id") + .fetch_all(&db.connection_pool) + .await + .unwrap(); + assert_eq!(remaining, vec![2]); + } + } + + mod evict_old_testruns { + use super::*; + + #[tokio::test] + async fn evicts_runs_older_than_cutoff() { + let db = setup().await; + seed_node(&db, 1).await; + let mut old_run = minimal_test_run(1); + old_run.test_timestamp = datetime!(2025-01-01 00:00:00 UTC); + let old_id = db.insert_test_run(&old_run).await.unwrap(); + + let mut recent_run = minimal_test_run(1); + recent_run.test_timestamp = datetime!(2025-06-01 12:00:00 UTC); + let recent_id = db.insert_test_run(&recent_run).await.unwrap(); + + db.evict_old_testruns(datetime!(2025-03-01 00:00:00 UTC)) + .await + .unwrap(); + + let ids: Vec = sqlx::query_scalar!("SELECT id FROM testrun ORDER BY id") + .fetch_all(&db.connection_pool) + .await + .unwrap(); + assert!(!ids.contains(&old_id)); + assert!(ids.contains(&recent_id)); + } + + #[tokio::test] + async fn preserves_runs_at_or_after_cutoff() { + let db = setup().await; + seed_node(&db, 1).await; + let mut run = minimal_test_run(1); + run.test_timestamp = datetime!(2025-03-01 00:00:00 UTC); + let id = db.insert_test_run(&run).await.unwrap(); + + // cutoff is exactly at the run's timestamp — should NOT be evicted (strict <) + db.evict_old_testruns(datetime!(2025-03-01 00:00:00 UTC)) + .await + .unwrap(); + + let count = sqlx::query_scalar!("SELECT COUNT(*) FROM testrun WHERE id = ?", id) + .fetch_one(&db.connection_pool) + .await + .unwrap(); + assert_eq!(count, 1); + } + + #[tokio::test] + async fn nullifies_node_last_testrun_on_eviction() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[node(1, "key_a")]) + .await + .unwrap(); + + let mut run = minimal_test_run(1); + run.test_timestamp = datetime!(2025-01-01 00:00:00 UTC); + let run_id = db.insert_test_run(&run).await.unwrap(); + db.set_node_last_testrun(1, run_id).await.unwrap(); + + db.evict_old_testruns(datetime!(2025-06-01 00:00:00 UTC)) + .await + .unwrap(); + + let row = sqlx::query!("SELECT last_testrun FROM nym_node WHERE node_id = 1") + .fetch_one(&db.connection_pool) + .await + .unwrap(); + assert!(row.last_testrun.is_none()); + } + + #[tokio::test] + async fn does_nothing_when_no_old_runs() { + let db = setup().await; + seed_node(&db, 1).await; + db.insert_test_run(&minimal_test_run(1)).await.unwrap(); + + // cutoff is well in the past — nothing should be evicted + let result = db + .evict_old_testruns(datetime!(2000-01-01 00:00:00 UTC)) + .await; + assert!(result.is_ok()); + + let count = sqlx::query_scalar!("SELECT COUNT(*) FROM testrun") + .fetch_one(&db.connection_pool) + .await + .unwrap(); + assert_eq!(count, 1); + } + } + + mod assign_next_mixnode_testrun { + use super::*; + + // A far-future cutoff that effectively disables the staleness gate, + // used in tests that are not concerned with that behaviour. + fn no_staleness_gate() -> OffsetDateTime { + datetime!(9999-12-31 23:59:59 UTC) + } + + #[tokio::test] + async fn returns_none_when_no_nodes() { + let db = setup().await; + let result = db + .assign_next_mixnode_testrun( + datetime!(2025-06-01 12:00:00 UTC), + no_staleness_gate(), + ) + .await + .unwrap(); + assert!(result.is_none()); + } + + #[tokio::test] + async fn returns_none_when_all_nodes_in_progress() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[node(1, "key_a")]) + .await + .unwrap(); + db.assign_next_mixnode_testrun(datetime!(2025-06-01 12:00:00 UTC), no_staleness_gate()) + .await + .unwrap(); + + let result = db + .assign_next_mixnode_testrun( + datetime!(2025-06-01 12:00:00 UTC), + no_staleness_gate(), + ) + .await + .unwrap(); + assert!(result.is_none()); + } + + #[tokio::test] + async fn inserts_in_progress_row() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[node(1, "key_a")]) + .await + .unwrap(); + let assigned = db + .assign_next_mixnode_testrun( + datetime!(2025-06-01 12:00:00 UTC), + no_staleness_gate(), + ) + .await + .unwrap(); + assert!(assigned.is_some()); + + let count = + sqlx::query_scalar!("SELECT COUNT(*) FROM testrun_in_progress WHERE node_id = 1") + .fetch_one(&db.connection_pool) + .await + .unwrap(); + assert_eq!(count, 1); + } + + #[tokio::test] + async fn prefers_never_tested_node_over_stale_one() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[node(1, "key_a")]) + .await + .unwrap(); + db.batch_insert_or_update_nym_nodes(&[node(2, "key_b")]) + .await + .unwrap(); + + // give node 1 a completed test run + let run_id = db.insert_test_run(&minimal_test_run(1)).await.unwrap(); + db.set_node_last_testrun(1, run_id).await.unwrap(); + + // node 2 has never been tested — it should be picked first + let assigned = db + .assign_next_mixnode_testrun( + datetime!(2025-06-01 12:00:00 UTC), + no_staleness_gate(), + ) + .await + .unwrap() + .unwrap(); + assert_eq!(assigned.inner.node_id, 2); + } + + #[tokio::test] + async fn prefers_older_testrun_over_newer_one() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[node(1, "key_a")]) + .await + .unwrap(); + db.batch_insert_or_update_nym_nodes(&[node(2, "key_b")]) + .await + .unwrap(); + + let mut old_run = minimal_test_run(1); + old_run.test_timestamp = datetime!(2025-01-01 00:00:00 UTC); + let old_id = db.insert_test_run(&old_run).await.unwrap(); + db.set_node_last_testrun(1, old_id).await.unwrap(); + + let mut new_run = minimal_test_run(2); + new_run.test_timestamp = datetime!(2025-06-01 12:00:00 UTC); + let new_id = db.insert_test_run(&new_run).await.unwrap(); + db.set_node_last_testrun(2, new_id).await.unwrap(); + + // node 1 has the older run — it should be picked + let assigned = db + .assign_next_mixnode_testrun( + datetime!(2025-06-01 12:00:00 UTC), + no_staleness_gate(), + ) + .await + .unwrap() + .unwrap(); + assert_eq!(assigned.inner.node_id, 1); + } + + #[tokio::test] + async fn skips_node_already_in_progress() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[node(1, "key_a")]) + .await + .unwrap(); + db.batch_insert_or_update_nym_nodes(&[node(2, "key_b")]) + .await + .unwrap(); + + // both have no test run; node 1 is manually put in progress + db.mark_testrun_in_progress(1, datetime!(2025-06-01 11:00:00 UTC)) + .await + .unwrap(); + + let assigned = db + .assign_next_mixnode_testrun( + datetime!(2025-06-01 12:00:00 UTC), + no_staleness_gate(), + ) + .await + .unwrap() + .unwrap(); + assert_eq!(assigned.inner.node_id, 2); + } + + #[tokio::test] + async fn skips_node_tested_too_recently() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[node(1, "key_a")]) + .await + .unwrap(); + + let mut run = minimal_test_run(1); + run.test_timestamp = datetime!(2025-06-01 12:00:00 UTC); + let run_id = db.insert_test_run(&run).await.unwrap(); + db.set_node_last_testrun(1, run_id).await.unwrap(); + + // cutoff is before the last test — node is not stale enough + let result = db + .assign_next_mixnode_testrun( + datetime!(2025-06-01 13:00:00 UTC), + datetime!(2025-06-01 11:00:00 UTC), + ) + .await + .unwrap(); + assert!(result.is_none()); + } + + #[tokio::test] + async fn returns_node_tested_sufficiently_long_ago() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[node(1, "key_a")]) + .await + .unwrap(); + + let mut run = minimal_test_run(1); + run.test_timestamp = datetime!(2025-06-01 12:00:00 UTC); + let run_id = db.insert_test_run(&run).await.unwrap(); + db.set_node_last_testrun(1, run_id).await.unwrap(); + + // cutoff is after the last test — node is eligible + let assigned = db + .assign_next_mixnode_testrun( + datetime!(2025-06-01 14:00:00 UTC), + datetime!(2025-06-01 13:00:00 UTC), + ) + .await + .unwrap(); + assert!(assigned.is_some()); + } + + #[tokio::test] + async fn never_tested_node_bypasses_staleness_gate() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[node(1, "key_a")]) + .await + .unwrap(); + db.batch_insert_or_update_nym_nodes(&[node(2, "key_b")]) + .await + .unwrap(); + + // node 1 was tested very recently + let mut run = minimal_test_run(1); + run.test_timestamp = datetime!(2025-06-01 12:00:00 UTC); + let run_id = db.insert_test_run(&run).await.unwrap(); + db.set_node_last_testrun(1, run_id).await.unwrap(); + + // cutoff is before node 1's last test — it is filtered out + // node 2 has never been tested and must still be returned + let assigned = db + .assign_next_mixnode_testrun( + datetime!(2025-06-01 13:00:00 UTC), + datetime!(2025-06-01 11:00:00 UTC), + ) + .await + .unwrap() + .unwrap(); + assert_eq!(assigned.inner.node_id, 2); + } + } + + mod get_testrun_by_id { + use super::*; + + #[tokio::test] + async fn returns_none_when_missing() { + let db = setup().await; + let result = db.get_testrun_by_id(123).await.unwrap(); + assert!(result.is_none()); + } + + #[tokio::test] + async fn returns_inserted_run() { + let db = setup().await; + seed_node(&db, 1).await; + let mut run = minimal_test_run(1); + run.packets_sent = 42; + run.packets_received = 41; + run.error = Some("boom".to_string()); + let id = db.insert_test_run(&run).await.unwrap(); + + let fetched = db.get_testrun_by_id(id).await.unwrap().unwrap(); + assert_eq!(fetched.id, id); + assert_eq!(fetched.inner.node_id, 1); + assert_eq!(fetched.inner.packets_sent, 42); + assert_eq!(fetched.inner.packets_received, 41); + assert_eq!(fetched.inner.error.as_deref(), Some("boom")); + } + + #[tokio::test] + async fn returns_the_right_row_when_multiple_exist() { + let db = setup().await; + seed_node(&db, 1).await; + let _ = db.insert_test_run(&minimal_test_run(1)).await.unwrap(); + let mut other = minimal_test_run(1); + other.packets_sent = 7; + let target_id = db.insert_test_run(&other).await.unwrap(); + let _ = db.insert_test_run(&minimal_test_run(1)).await.unwrap(); + + let fetched = db.get_testrun_by_id(target_id).await.unwrap().unwrap(); + assert_eq!(fetched.id, target_id); + assert_eq!(fetched.inner.packets_sent, 7); + } + } + + mod get_nym_node_by_id { + use super::*; + + #[tokio::test] + async fn returns_none_when_missing() { + let db = setup().await; + let result = db.get_nym_node_by_id(1).await.unwrap(); + assert!(result.is_none()); + } + + #[tokio::test] + async fn returns_inserted_node() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[node(42, "key_a")]) + .await + .unwrap(); + + let fetched = db.get_nym_node_by_id(42).await.unwrap().unwrap(); + assert_eq!(fetched.inner.node_id, 42); + assert_eq!(fetched.inner.identity_key, "key_a"); + assert!(fetched.last_testrun.is_none()); + } + + #[tokio::test] + async fn reflects_last_testrun_when_linked() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[node(1, "key_a")]) + .await + .unwrap(); + let run_id = db.insert_test_run(&minimal_test_run(1)).await.unwrap(); + db.set_node_last_testrun(1, run_id).await.unwrap(); + + let fetched = db.get_nym_node_by_id(1).await.unwrap().unwrap(); + assert_eq!(fetched.last_testrun, Some(run_id)); + } + } + + mod get_testruns_in_progress_paginated { + use super::*; + + #[tokio::test] + async fn empty_when_table_empty() { + let db = setup().await; + let (rows, total) = db.get_testruns_in_progress_paginated(50, 0).await.unwrap(); + assert!(rows.is_empty()); + assert_eq!(total, 0); + } + + #[tokio::test] + async fn ordering_is_started_at_ascending() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[ + node(1, "key_a"), + node(2, "key_b"), + node(3, "key_c"), + ]) + .await + .unwrap(); + + db.mark_testrun_in_progress(2, datetime!(2025-06-01 12:00:00 UTC)) + .await + .unwrap(); + db.mark_testrun_in_progress(3, datetime!(2025-06-01 10:00:00 UTC)) + .await + .unwrap(); + db.mark_testrun_in_progress(1, datetime!(2025-06-01 11:00:00 UTC)) + .await + .unwrap(); + + let (rows, total) = db.get_testruns_in_progress_paginated(50, 0).await.unwrap(); + assert_eq!(total, 3); + let ordered_node_ids: Vec = rows.iter().map(|r| r.node_id).collect(); + assert_eq!(ordered_node_ids, vec![3, 1, 2]); + } + + #[tokio::test] + async fn limit_truncates_page_but_preserves_total() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[ + node(1, "key_a"), + node(2, "key_b"), + node(3, "key_c"), + ]) + .await + .unwrap(); + + db.mark_testrun_in_progress(1, datetime!(2025-06-01 10:00:00 UTC)) + .await + .unwrap(); + db.mark_testrun_in_progress(2, datetime!(2025-06-01 11:00:00 UTC)) + .await + .unwrap(); + db.mark_testrun_in_progress(3, datetime!(2025-06-01 12:00:00 UTC)) + .await + .unwrap(); + + let (rows, total) = db.get_testruns_in_progress_paginated(2, 0).await.unwrap(); + assert_eq!(total, 3); + let ordered_node_ids: Vec = rows.iter().map(|r| r.node_id).collect(); + assert_eq!(ordered_node_ids, vec![1, 2]); + } + + #[tokio::test] + async fn offset_skips_oldest_rows() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[ + node(1, "key_a"), + node(2, "key_b"), + node(3, "key_c"), + ]) + .await + .unwrap(); + + db.mark_testrun_in_progress(1, datetime!(2025-06-01 10:00:00 UTC)) + .await + .unwrap(); + db.mark_testrun_in_progress(2, datetime!(2025-06-01 11:00:00 UTC)) + .await + .unwrap(); + db.mark_testrun_in_progress(3, datetime!(2025-06-01 12:00:00 UTC)) + .await + .unwrap(); + + let (rows, total) = db.get_testruns_in_progress_paginated(2, 1).await.unwrap(); + assert_eq!(total, 3); + let ordered_node_ids: Vec = rows.iter().map(|r| r.node_id).collect(); + assert_eq!(ordered_node_ids, vec![2, 3]); + } + + #[tokio::test] + async fn offset_past_end_returns_empty_but_accurate_total() { + let db = setup().await; + db.batch_insert_or_update_nym_nodes(&[node(1, "key_a"), node(2, "key_b")]) + .await + .unwrap(); + + db.mark_testrun_in_progress(1, datetime!(2025-06-01 10:00:00 UTC)) + .await + .unwrap(); + db.mark_testrun_in_progress(2, datetime!(2025-06-01 11:00:00 UTC)) + .await + .unwrap(); + + let (rows, total) = db + .get_testruns_in_progress_paginated(10, 100) + .await + .unwrap(); + assert!(rows.is_empty()); + assert_eq!(total, 2); + } + } + + mod get_nym_nodes_paginated { + use super::*; + + #[tokio::test] + async fn empty_when_table_empty() { + let db = setup().await; + let (rows, total) = db.get_nym_nodes_paginated(50, 0).await.unwrap(); + assert!(rows.is_empty()); + assert_eq!(total, 0); + } + + #[tokio::test] + async fn returns_first_page_and_correct_total() { + let db = setup().await; + let nodes: Vec = (1..=5).map(|i| node(i, &format!("key_{i}"))).collect(); + db.batch_insert_or_update_nym_nodes(&nodes).await.unwrap(); + + let (rows, total) = db.get_nym_nodes_paginated(2, 0).await.unwrap(); + assert_eq!(total, 5); + let ids: Vec = rows.iter().map(|r| r.inner.node_id).collect(); + assert_eq!(ids, vec![1, 2]); + } + + #[tokio::test] + async fn offset_skips_earlier_rows() { + let db = setup().await; + let nodes: Vec = (1..=5).map(|i| node(i, &format!("key_{i}"))).collect(); + db.batch_insert_or_update_nym_nodes(&nodes).await.unwrap(); + + let (rows, total) = db.get_nym_nodes_paginated(2, 2).await.unwrap(); + assert_eq!(total, 5); + let ids: Vec = rows.iter().map(|r| r.inner.node_id).collect(); + assert_eq!(ids, vec![3, 4]); + } + + #[tokio::test] + async fn offset_past_end_returns_empty_but_accurate_total() { + let db = setup().await; + let nodes: Vec = (1..=3).map(|i| node(i, &format!("key_{i}"))).collect(); + db.batch_insert_or_update_nym_nodes(&nodes).await.unwrap(); + + let (rows, total) = db.get_nym_nodes_paginated(10, 100).await.unwrap(); + assert!(rows.is_empty()); + assert_eq!(total, 3); + } + + #[tokio::test] + async fn ordering_is_node_id_ascending() { + let db = setup().await; + // insert in non-ascending order to confirm ORDER BY actually sorts + db.batch_insert_or_update_nym_nodes(&[ + node(3, "key_c"), + node(1, "key_a"), + node(2, "key_b"), + ]) + .await + .unwrap(); + + let (rows, _) = db.get_nym_nodes_paginated(10, 0).await.unwrap(); + let ids: Vec = rows.iter().map(|r| r.inner.node_id).collect(); + assert_eq!(ids, vec![1, 2, 3]); + } + } + + mod get_testruns_paginated { + use super::*; + + fn run_at(node_id: i64, ts: OffsetDateTime) -> NewTestRun { + let mut r = minimal_test_run(node_id); + r.test_timestamp = ts; + r + } + + #[tokio::test] + async fn empty_when_table_empty() { + let db = setup().await; + let (rows, total) = db.get_testruns_paginated(50, 0).await.unwrap(); + assert!(rows.is_empty()); + assert_eq!(total, 0); + } + + #[tokio::test] + async fn ordering_is_test_timestamp_descending() { + let db = setup().await; + seed_node(&db, 1).await; + // insert in mixed order; ensure query returns newest first + let _ = db + .insert_test_run(&run_at(1, datetime!(2025-03-01 00:00:00 UTC))) + .await + .unwrap(); + let _ = db + .insert_test_run(&run_at(1, datetime!(2025-01-01 00:00:00 UTC))) + .await + .unwrap(); + let _ = db + .insert_test_run(&run_at(1, datetime!(2025-02-01 00:00:00 UTC))) + .await + .unwrap(); + + let (rows, total) = db.get_testruns_paginated(10, 0).await.unwrap(); + assert_eq!(total, 3); + let timestamps: Vec = + rows.iter().map(|r| r.inner.test_timestamp).collect(); + assert_eq!( + timestamps, + vec![ + datetime!(2025-03-01 00:00:00 UTC), + datetime!(2025-02-01 00:00:00 UTC), + datetime!(2025-01-01 00:00:00 UTC), + ] + ); + } + + #[tokio::test] + async fn offset_skips_newest_rows() { + let db = setup().await; + seed_node(&db, 1).await; + db.insert_test_run(&run_at(1, datetime!(2025-03-01 00:00:00 UTC))) + .await + .unwrap(); + db.insert_test_run(&run_at(1, datetime!(2025-02-01 00:00:00 UTC))) + .await + .unwrap(); + db.insert_test_run(&run_at(1, datetime!(2025-01-01 00:00:00 UTC))) + .await + .unwrap(); + + let (rows, total) = db.get_testruns_paginated(2, 1).await.unwrap(); + assert_eq!(total, 3); + let timestamps: Vec = + rows.iter().map(|r| r.inner.test_timestamp).collect(); + assert_eq!( + timestamps, + vec![ + datetime!(2025-02-01 00:00:00 UTC), + datetime!(2025-01-01 00:00:00 UTC), + ] + ); + } + + #[tokio::test] + async fn offset_past_end_returns_empty_but_accurate_total() { + let db = setup().await; + seed_node(&db, 1).await; + db.insert_test_run(&minimal_test_run(1)).await.unwrap(); + db.insert_test_run(&minimal_test_run(1)).await.unwrap(); + + let (rows, total) = db.get_testruns_paginated(10, 50).await.unwrap(); + assert!(rows.is_empty()); + assert_eq!(total, 2); + } + } + + mod get_testruns_for_node_paginated { + use super::*; + + fn run_at(node_id: i64, ts: OffsetDateTime) -> NewTestRun { + let mut r = minimal_test_run(node_id); + r.test_timestamp = ts; + r + } + + #[tokio::test] + async fn empty_when_node_has_no_runs() { + let db = setup().await; + seed_node(&db, 1).await; + + let (rows, total) = db.get_testruns_for_node_paginated(1, 50, 0).await.unwrap(); + assert!(rows.is_empty()); + assert_eq!(total, 0); + } + + #[tokio::test] + async fn returns_only_runs_for_requested_node() { + let db = setup().await; + seed_node(&db, 1).await; + seed_node(&db, 2).await; + + db.insert_test_run(&minimal_test_run(1)).await.unwrap(); + db.insert_test_run(&minimal_test_run(1)).await.unwrap(); + db.insert_test_run(&minimal_test_run(2)).await.unwrap(); + + let (rows, total) = db.get_testruns_for_node_paginated(1, 50, 0).await.unwrap(); + assert_eq!(total, 2); + assert_eq!(rows.len(), 2); + assert!(rows.iter().all(|r| r.inner.node_id == 1)); + + let (rows, total) = db.get_testruns_for_node_paginated(2, 50, 0).await.unwrap(); + assert_eq!(total, 1); + assert_eq!(rows.len(), 1); + assert_eq!(rows[0].inner.node_id, 2); + } + + #[tokio::test] + async fn ordering_is_test_timestamp_descending() { + let db = setup().await; + seed_node(&db, 1).await; + + db.insert_test_run(&run_at(1, datetime!(2025-02-01 00:00:00 UTC))) + .await + .unwrap(); + db.insert_test_run(&run_at(1, datetime!(2025-03-01 00:00:00 UTC))) + .await + .unwrap(); + db.insert_test_run(&run_at(1, datetime!(2025-01-01 00:00:00 UTC))) + .await + .unwrap(); + + let (rows, _) = db.get_testruns_for_node_paginated(1, 10, 0).await.unwrap(); + let timestamps: Vec = + rows.iter().map(|r| r.inner.test_timestamp).collect(); + assert_eq!( + timestamps, + vec![ + datetime!(2025-03-01 00:00:00 UTC), + datetime!(2025-02-01 00:00:00 UTC), + datetime!(2025-01-01 00:00:00 UTC), + ] + ); + } + + #[tokio::test] + async fn offset_skips_newest_rows() { + let db = setup().await; + seed_node(&db, 1).await; + + db.insert_test_run(&run_at(1, datetime!(2025-03-01 00:00:00 UTC))) + .await + .unwrap(); + db.insert_test_run(&run_at(1, datetime!(2025-02-01 00:00:00 UTC))) + .await + .unwrap(); + db.insert_test_run(&run_at(1, datetime!(2025-01-01 00:00:00 UTC))) + .await + .unwrap(); + + let (rows, total) = db.get_testruns_for_node_paginated(1, 2, 1).await.unwrap(); + assert_eq!(total, 3); + let timestamps: Vec = + rows.iter().map(|r| r.inner.test_timestamp).collect(); + assert_eq!( + timestamps, + vec![ + datetime!(2025-02-01 00:00:00 UTC), + datetime!(2025-01-01 00:00:00 UTC), + ] + ); + } + + #[tokio::test] + async fn unknown_node_returns_empty_with_zero_total() { + let db = setup().await; + seed_node(&db, 1).await; + db.insert_test_run(&minimal_test_run(1)).await.unwrap(); + + // node 99 was never seeded, so it has no runs and total is 0. + let (rows, total) = db.get_testruns_for_node_paginated(99, 50, 0).await.unwrap(); + assert!(rows.is_empty()); + assert_eq!(total, 0); + } + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/storage/mod.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/storage/mod.rs new file mode 100644 index 0000000000..a0ec448bdb --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/storage/mod.rs @@ -0,0 +1,279 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::orchestrator::prometheus::{PROMETHEUS_METRICS, PrometheusMetric}; +use crate::storage::manager::StorageManager; +use crate::storage::models::{NewNymNode, NewTestRun, NymNode, TestRun, TestRunInProgress}; +use anyhow::Context; +use nym_network_monitor_orchestrator_requests::models::Pagination; +use nym_validator_client::client::NodeId; +use sqlx::ConnectOptions; +use sqlx::sqlite::{SqliteAutoVacuum, SqliteSynchronous}; +use std::path::Path; +use std::time::Duration; +use time::OffsetDateTime; +use tracing::log::{LevelFilter, debug}; + +mod manager; +pub(crate) mod models; + +/// High-level handle to the orchestrator's local SQLite database. +/// +/// Wraps a [`StorageManager`] and translates between the orchestrator-level +/// types (e.g. [`NodeId`], [`Pagination`], [`Duration`]) used by callers and +/// the raw SQL-friendly primitives (`i64` ids, `limit`/`offset`, absolute +/// timestamps) understood by the manager. All public methods are +/// [`Clone`]-safe because [`sqlx::SqlitePool`] is internally reference-counted. +#[derive(Clone)] +pub(crate) struct NetworkMonitorStorage { + pub(crate) storage_manager: StorageManager, +} + +impl NetworkMonitorStorage { + /// Opens (or creates) the SQLite database at `database_path`, configures + /// WAL journaling and incremental auto-vacuum, and runs the embedded + /// migrations. Slow statements (>50ms) are logged at `WARN`. + pub(crate) async fn init>(database_path: P) -> anyhow::Result { + debug!( + "attempting to connect to database {}", + database_path.as_ref().display() + ); + + let connect_opts = sqlx::sqlite::SqliteConnectOptions::new() + .journal_mode(sqlx::sqlite::SqliteJournalMode::Wal) + .synchronous(SqliteSynchronous::Normal) + .auto_vacuum(SqliteAutoVacuum::Incremental) + .filename(database_path) + .create_if_missing(true) + .log_statements(LevelFilter::Trace) + .log_slow_statements(LevelFilter::Warn, Duration::from_millis(50)); + + let connection_pool = sqlx::SqlitePool::connect_with(connect_opts) + .await + .context("Failed to connect to SQLx database")?; + + sqlx::migrate!("./migrations") + .run(&connection_pool) + .await + .context("Failed to run database migrations")?; + + Ok(Self { + storage_manager: StorageManager { connection_pool }, + }) + } + + /// Inserts or updates multiple node records in a single transaction. + /// + /// For each node, if a row with the same `node_id` already exists, all fields except + /// `identity_key` are updated. The entire batch shares one transaction for efficiency. + pub(crate) async fn batch_insert_or_update_nym_nodes( + &self, + nodes: &[NewNymNode], + ) -> anyhow::Result<()> { + self.storage_manager + .batch_insert_or_update_nym_nodes(nodes) + .await + } + + /// Inserts a completed test run, updates the node's `last_testrun` pointer and + /// clears the corresponding `testrun_in_progress` marker. The target node is + /// taken from [`NewTestRun::node_id`]. + /// + /// Decrements the `TestrunsInProgress` gauge iff a row was actually cleared — a late + /// submission whose in-progress row was already reaped by the timeout sweep must not + /// double-decrement the gauge. + pub(crate) async fn insert_test_run(&self, run: &NewTestRun) -> anyhow::Result<()> { + let node_id = run.node_id; + let run_id = self.storage_manager.insert_test_run(run).await?; + self.storage_manager + .set_node_last_testrun(node_id, run_id) + .await?; + let cleared = self + .storage_manager + .clear_testrun_in_progress(node_id) + .await?; + if cleared > 0 { + PROMETHEUS_METRICS.inc_by(PrometheusMetric::TestrunsInProgress, -(cleared as i64)); + } + Ok(()) + } + + /// Returns the number of rows currently in `testrun_in_progress`. + pub(crate) async fn count_testruns_in_progress(&self) -> anyhow::Result { + self.storage_manager.count_testruns_in_progress().await + } + + /// Removes all in-progress markers whose `started_at` is older than `timeout`, on the + /// assumption that those runs have timed out and will never complete. Decrements the + /// `TestrunsInProgress` gauge by the number of rows actually cleared. + pub(crate) async fn clear_timed_out_testruns_in_progress( + &self, + timeout: Duration, + ) -> anyhow::Result { + let cutoff = OffsetDateTime::now_utc() - timeout; + let cleared = self + .storage_manager + .clear_timed_out_testruns_in_progress(cutoff) + .await?; + if cleared > 0 { + PROMETHEUS_METRICS.inc_by(PrometheusMetric::TestrunsInProgress, -(cleared as i64)); + } + Ok(cleared) + } + + /// Atomically selects the most stale idle mixnode and marks it as having a test run in + /// progress. + /// + /// "Most stale" is defined as: nodes that have never been tested come first, followed by + /// nodes whose last test run has the oldest timestamp. + /// + /// `staleness_age` acts as a minimum-staleness gate: a node that has already been tested + /// is only eligible if its last test run completed more than `staleness_age` ago. Nodes + /// that have never been tested are always eligible regardless of this value. + /// + /// The current time is used as the `started_at` timestamp on the resulting + /// `testrun_in_progress` row. + /// + /// Nodes with a row in `testrun_in_progress` are excluded entirely. Only nodes classified + /// as `mixnode` or `mixnode_and_gateway` are eligible. + /// + /// Returns `None` if no eligible idle mixnode exists. + pub(crate) async fn assign_next_mixnode_testrun( + &self, + staleness_age: Duration, + ) -> anyhow::Result> { + let now = OffsetDateTime::now_utc(); + let last_tested_before = now - staleness_age; + let assigned = self + .storage_manager + .assign_next_mixnode_testrun(now, last_tested_before) + .await?; + if assigned.is_some() { + PROMETHEUS_METRICS.inc(PrometheusMetric::TestrunsInProgress); + } + Ok(assigned) + } + + /// Fetches a single completed test run by its row id, or `None` if it has + /// been evicted or never existed. + pub(crate) async fn get_testrun_by_id(&self, id: i64) -> anyhow::Result> { + self.storage_manager.get_testrun_by_id(id).await + } + + /// Fetches a node by its contract-assigned `node_id`, or `None` if the + /// orchestrator has never observed a bond for it. + pub(crate) async fn get_nym_node_by_id( + &self, + node_id: NodeId, + ) -> anyhow::Result> { + self.storage_manager + .get_nym_node_by_id(node_id as i64) + .await + } + + /// Paginated list of outstanding `testrun_in_progress` rows, oldest `started_at` + /// first so stale/hung runs surface at the top, with the snapshot-consistent + /// total row count. + pub(crate) async fn get_testruns_in_progress_paginated( + &self, + pagination: Pagination, + ) -> anyhow::Result<(Vec, usize)> { + let (rows, total) = self + .storage_manager + .get_testruns_in_progress_paginated(pagination.limit(), pagination.offset()) + .await?; + + Ok((rows, total as usize)) + } + + /// Paginated list of nodes ordered by `node_id` ascending, with the + /// snapshot-consistent total row count. [`Pagination`] is resolved to + /// `limit`/`offset` here so the manager never sees the public contract. + pub(crate) async fn get_nym_nodes_paginated( + &self, + pagination: Pagination, + ) -> anyhow::Result<(Vec, usize)> { + let (nodes, total) = self + .storage_manager + .get_nym_nodes_paginated(pagination.limit(), pagination.offset()) + .await?; + + Ok((nodes, total as usize)) + } + + /// Paginated list of completed test runs ordered by `test_timestamp` + /// descending (newest first), with the snapshot-consistent total row count. + pub(crate) async fn get_testruns_paginated( + &self, + pagination: Pagination, + ) -> anyhow::Result<(Vec, usize)> { + let (test_results, total) = self + .storage_manager + .get_testruns_paginated(pagination.limit(), pagination.offset()) + .await?; + + Ok((test_results, total as usize)) + } + + /// Paginated list of completed test runs for a single node, ordered newest + /// first, with the snapshot-consistent total row count. Backed by the + /// `idx_testrun_node_id_timestamp` index. An unknown or never-tested + /// `node_id` produces `(vec![], 0)` rather than an error. + pub(crate) async fn get_testruns_for_node_paginated( + &self, + node_id: NodeId, + pagination: Pagination, + ) -> anyhow::Result<(Vec, usize)> { + let (test_results, total) = self + .storage_manager + .get_testruns_for_node_paginated( + node_id as i64, + pagination.limit(), + pagination.offset(), + ) + .await?; + + Ok((test_results, total as usize)) + } + + /// Returns the id of the newest `testrun` already submitted to the nym-api, or `None` if no + /// batch has been submitted yet. Callers treat `None` as "submit everything currently in + /// storage". + pub(crate) async fn get_last_submitted_testrun_id(&self) -> anyhow::Result> { + self.storage_manager.get_last_submitted_testrun_id().await + } + + /// Persists the id of the newest `testrun` whose batch submission to the nym-api has + /// succeeded. Subsequent [`Self::get_testruns_after`] calls use this value to avoid + /// resubmitting already-acknowledged rows. + pub(crate) async fn set_last_submitted_testrun_id( + &self, + testrun_id: i64, + ) -> anyhow::Result<()> { + self.storage_manager + .set_last_submitted_testrun_id(testrun_id) + .await + } + + /// Fetches every `testrun` row with `id > after_id`, ordered by id ascending. + /// + /// Used by the nym-api submission task to build the next batch of pending results. Ascending + /// ordering lets the caller record the highest-id row as the new submission watermark once + /// the batch is acknowledged. + pub(crate) async fn get_testruns_after(&self, after_id: i64) -> anyhow::Result> { + self.storage_manager.get_testruns_after(after_id).await + } + + /// Deletes all `testrun` rows older than `eviction_age` relative to the current time. + /// + /// Intended to be called periodically to keep the local database from growing unboundedly. + /// Rows that are evicted are assumed to have already been submitted to the nym-api for + /// persistent storage. + /// + /// Any `nym_node.last_testrun` foreign key that pointed at an evicted row is automatically + /// set to `NULL` by the database (`ON DELETE SET NULL`). + pub(crate) async fn evict_old_testruns(&self, eviction_age: Duration) -> anyhow::Result { + let cutoff = OffsetDateTime::now_utc() - eviction_age; + self.storage_manager.evict_old_testruns(cutoff).await + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/storage/models.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/storage/models.rs new file mode 100644 index 0000000000..9da074588a --- /dev/null +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/storage/models.rs @@ -0,0 +1,406 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use anyhow::Context; +use nym_api_requests::models::network_monitor::StressTestResult; +use nym_crypto::asymmetric::{ed25519, x25519}; +use nym_network_monitor_orchestrator_requests::models::{ + self as api, LatencyDistribution, NymNodeData, TestRunData, TestRunInProgressData, + TestRunResult, +}; +use nym_node_requests::api::v1::node::models::NodeRoles; +use nym_validator_client::client::NodeId; +use nym_validator_client::nyxd::nym_mixnet_contract_common::NymNodeBond; +use std::time::Duration; +use time::OffsetDateTime; + +/// Discriminator for the type of node targeted by a [`TestRun`]. +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, sqlx::Type)] +#[sqlx(type_name = "TEXT", rename_all = "lowercase")] +pub(crate) enum TestType { + #[default] + Mixnode, + Gateway, +} + +/// Classification of a node based on the roles reported via its self-described endpoint. +/// [`NodeType::Unknown`] is used both as the initial value before the node is successfully +/// queried and when a queried node reports no roles at all. +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, Hash, sqlx::Type)] +#[sqlx(type_name = "TEXT", rename_all = "snake_case")] +pub(crate) enum NodeType { + #[default] + Unknown, + Mixnode, + Gateway, + MixnodeAndGateway, +} + +impl NodeType { + /// Classifies a node from the `NodeRoles` reported by its self-described endpoint. + /// We key off `gateway_enabled` (entry-gateway capability) only — the `exit` property is + /// not a useful distinction for test-target selection. A node reporting neither role maps + /// to [`NodeType::Unknown`] and will be ignored by the mixnode testrun assignment query. + pub(crate) fn from_roles(roles: &NodeRoles) -> Self { + match (roles.mixnode_enabled, roles.gateway_enabled) { + (true, true) => NodeType::MixnodeAndGateway, + (true, false) => NodeType::Mixnode, + (false, true) => NodeType::Gateway, + (false, false) => NodeType::Unknown, + } + } +} + +/// The data required to insert a new row into `testrun`. Does not carry an `id` since that +/// is assigned by the database on insertion. +#[derive(Debug, Clone, sqlx::FromRow)] +pub(crate) struct NewTestRun { + /// Contract-assigned node id of the node under test. + pub(crate) node_id: i64, + + pub(crate) test_type: TestType, + pub(crate) test_timestamp: OffsetDateTime, + + /// How long the test took, in microseconds. + pub(crate) time_taken_us: i64, + + /// Noise handshake duration on the ingress (responder) side, in microseconds. + pub(crate) ingress_noise_handshake_us: Option, + + /// Noise handshake duration on the egress (initiator) side, in microseconds. + pub(crate) egress_noise_handshake_us: Option, + + /// Constant per-hop sphinx packet delay used during the test run, in microseconds. + pub(crate) sphinx_packet_delay_us: i64, + + pub(crate) packets_sent: i64, + pub(crate) packets_received: i64, + + /// RTT of the initial probe packet in microseconds. `None` if the probe did not complete. + pub(crate) approximate_latency_us: Option, + + // RTT distribution over received packets (all NULL when no packets were received). + pub(crate) packets_rtt_min_us: Option, + pub(crate) packets_rtt_mean_us: Option, + pub(crate) packets_rtt_median_us: Option, + pub(crate) packets_rtt_max_us: Option, + pub(crate) packets_rtt_std_dev_us: Option, + + // Batch send latency distribution (all NULL when no batches were sent). + pub(crate) sending_latency_min_us: Option, + pub(crate) sending_latency_mean_us: Option, + pub(crate) sending_latency_median_us: Option, + pub(crate) sending_latency_max_us: Option, + pub(crate) sending_latency_std_dev_us: Option, + + pub(crate) received_duplicates: bool, + + /// First error that caused the test to abort. `None` if the run completed without error. + pub(crate) error: Option, +} + +fn duration_to_us(d: std::time::Duration) -> i64 { + d.as_micros() as i64 +} + +impl NewTestRun { + /// Converts an API-level [`TestRunResult`] into a database-ready row, + /// flattening [`LatencyDistribution`](nym_network_monitor_orchestrator_requests::models::LatencyDistribution) + /// fields into individual microsecond columns and recording the current UTC time as the test timestamp. + fn from_result(test_type: TestType, node_id: NodeId, result: TestRunResult) -> Self { + NewTestRun { + node_id: node_id as i64, + test_type, + test_timestamp: OffsetDateTime::now_utc(), + time_taken_us: result.time_taken.as_micros() as i64, + ingress_noise_handshake_us: result.ingress_noise_handshake.map(duration_to_us), + egress_noise_handshake_us: result.egress_noise_handshake.map(duration_to_us), + sphinx_packet_delay_us: duration_to_us(result.sphinx_packet_delay), + packets_sent: result.packets_sent as i64, + packets_received: result.packets_received as i64, + approximate_latency_us: result.approximate_latency.map(duration_to_us), + packets_rtt_min_us: result.packets_statistics.map(|s| duration_to_us(s.minimum)), + packets_rtt_mean_us: result.packets_statistics.map(|s| duration_to_us(s.mean)), + packets_rtt_median_us: result.packets_statistics.map(|s| duration_to_us(s.median)), + packets_rtt_max_us: result.packets_statistics.map(|s| duration_to_us(s.maximum)), + packets_rtt_std_dev_us: result + .packets_statistics + .map(|s| duration_to_us(s.standard_deviation)), + sending_latency_min_us: result.sending_statistics.map(|s| duration_to_us(s.minimum)), + sending_latency_mean_us: result.sending_statistics.map(|s| duration_to_us(s.mean)), + sending_latency_median_us: result.sending_statistics.map(|s| duration_to_us(s.median)), + sending_latency_max_us: result.sending_statistics.map(|s| duration_to_us(s.maximum)), + sending_latency_std_dev_us: result + .sending_statistics + .map(|s| duration_to_us(s.standard_deviation)), + received_duplicates: result.received_duplicates, + error: result.error, + } + } + + /// Creates a new test run row for a mixnode stress test result. + pub(crate) fn from_mixnode_result(node_id: NodeId, result: TestRunResult) -> Self { + Self::from_result(TestType::Mixnode, node_id, result) + } + + /// Creates a new test run row for a gateway stress test result. + #[allow(dead_code)] + pub(crate) fn from_gateway_result(node_id: NodeId, result: TestRunResult) -> Self { + Self::from_result(TestType::Gateway, node_id, result) + } +} + +/// A row from the `testrun` table, as returned by a SELECT. +#[derive(Debug, Clone, sqlx::FromRow)] +pub(crate) struct TestRun { + pub(crate) id: i64, + + #[sqlx(flatten)] + pub(crate) inner: NewTestRun, +} + +fn us_to_duration(us: i64) -> Duration { + Duration::from_micros(us as u64) +} + +/// Reassembles a [`LatencyDistribution`] from its four flattened microsecond columns. +/// Returns `None` if any column is `NULL`; the four columns are always all-set or all-NULL +/// together (see [`NewTestRun::from_result`]). +fn latency_distribution( + min_us: Option, + mean_us: Option, + median_us: Option, + max_us: Option, + std_dev_us: Option, +) -> Option { + match (min_us, mean_us, median_us, max_us, std_dev_us) { + (Some(min), Some(mean), Some(median), Some(max), Some(std_dev)) => { + Some(LatencyDistribution { + minimum: us_to_duration(min), + mean: us_to_duration(mean), + median: us_to_duration(median), + maximum: us_to_duration(max), + standard_deviation: us_to_duration(std_dev), + }) + } + _ => None, + } +} + +/// Maps the internal enum onto its public API counterpart. Kept as a separate +/// type so `sqlx::Type` can be derived on the internal side without leaking +/// sqlx into the public request crate. +impl From for api::TestType { + fn from(t: TestType) -> Self { + match t { + TestType::Mixnode => api::TestType::Mixnode, + TestType::Gateway => api::TestType::Gateway, + } + } +} + +/// Lifts a `testrun` row into the public [`TestRunData`] shape: widens `i64` +/// ids/counters to the API's `u32`/`usize`, reconstitutes each +/// `LatencyDistribution` from its four microsecond columns, and converts +/// microsecond integers back into `std::time::Duration`. +impl From for TestRunData { + fn from(run: TestRun) -> Self { + let inner = run.inner; + TestRunData { + id: run.id, + node_id: inner.node_id as u32, + test_type: inner.test_type.into(), + test_timestamp: inner.test_timestamp, + result: TestRunResult { + time_taken: Duration::from_micros(inner.time_taken_us as u64), + ingress_noise_handshake: inner.ingress_noise_handshake_us.map(us_to_duration), + egress_noise_handshake: inner.egress_noise_handshake_us.map(us_to_duration), + sphinx_packet_delay: us_to_duration(inner.sphinx_packet_delay_us), + packets_sent: inner.packets_sent as usize, + packets_received: inner.packets_received as usize, + approximate_latency: inner.approximate_latency_us.map(us_to_duration), + packets_statistics: latency_distribution( + inner.packets_rtt_min_us, + inner.packets_rtt_mean_us, + inner.packets_rtt_median_us, + inner.packets_rtt_max_us, + inner.packets_rtt_std_dev_us, + ), + sending_statistics: latency_distribution( + inner.sending_latency_min_us, + inner.sending_latency_mean_us, + inner.sending_latency_median_us, + inner.sending_latency_max_us, + inner.sending_latency_std_dev_us, + ), + received_duplicates: inner.received_duplicates, + error: inner.error, + }, + } + } +} + +/// Projects a completed `testrun` row onto the nym-api's `StressTestResult` shape used by the +/// stress-test batch submission endpoint. +/// +/// Two fields are synthesised here rather than stored directly: +/// +/// - `test_performance` is `packets_received / packets_sent` clamped to `[0.0, 1.0]`. A run that +/// sent no packets collapses to `0.0`; `was_reachable` is the signal that lets the server tell +/// that case apart from a genuine zero score. +/// - `was_reachable` is `error.is_none()` — i.e. the test completed without an abort error. A run +/// that aborted before the node responded sets `error` to the first failure, so the inverse is +/// an accurate "did we reach the node at all" signal. +impl From for StressTestResult { + fn from(run: TestRun) -> Self { + let id = run.id; + let inner = run.inner; + + // if we have received any duplicate packets, we have to discard the entire result, + // as an honest node would never replay a packet + let test_performance = if inner.packets_sent > 0 && !inner.received_duplicates { + inner.packets_received as f64 / inner.packets_sent as f64 + } else { + 0.0 + }; + StressTestResult { + testrun_id: id, + node_id: inner.node_id as u32, + is_mixnode: matches!(inner.test_type, TestType::Mixnode), + test_timestamp: inner.test_timestamp, + test_performance, + was_reachable: inner.error.is_none(), + } + } +} + +/// The data required to insert or update a row in `nym_node`. Does not carry `last_testrun` +/// since that is managed separately via [`StorageManager::set_node_last_testrun`]. +#[derive(Debug, Clone, sqlx::FromRow)] +pub(crate) struct NewNymNode { + /// Node ID as assigned by the mixnet contract. + pub(crate) node_id: i64, + + /// Ed25519 identity key, base58-encoded. + /// A node_id always maps to exactly one identity_key and is never reassigned. + pub(crate) identity_key: String, + + /// When this node was last observed as bonded in the contract. + pub(crate) last_seen_bonded: OffsetDateTime, + + /// Mixnet socket address (host:port) at which the node accepts sphinx packets. + /// Stored as a string; parse with `str::parse::()` when needed. + pub(crate) mixnet_socket_address: Option, + + /// X25519 public key used for Noise handshakes, base58-encoded. + /// `None` if retrieval from the node failed. + pub(crate) noise_key: Option, + + /// Sphinx public key used for packet encryption, base58-encoded. + /// `None` if retrieval from the node failed. + /// Always `None`/`Some` together with `key_rotation_id`. + pub(crate) sphinx_key: Option, + + /// Key rotation epoch ID that `sphinx_key` belongs to. + /// `None` if retrieval from the node failed. + /// Always `None`/`Some` together with `sphinx_key`. + pub(crate) key_rotation_id: Option, + + /// Classification of the node based on the roles reported via its self-described endpoint. + /// [`NodeType::Unknown`] if the self-described retrieval failed. + pub(crate) node_type: NodeType, +} + +impl NewNymNode { + pub(crate) fn from_bond(bond: &NymNodeBond) -> Self { + NewNymNode { + node_id: bond.node_id as i64, + identity_key: bond.identity().to_string(), + last_seen_bonded: OffsetDateTime::now_utc(), + mixnet_socket_address: None, + noise_key: None, + sphinx_key: None, + key_rotation_id: None, + node_type: NodeType::Unknown, + } + } +} + +/// A row from the `testrun_in_progress` table. +#[derive(Debug, Clone, sqlx::FromRow)] +pub(crate) struct TestRunInProgress { + pub(crate) node_id: i64, + pub(crate) started_at: OffsetDateTime, +} + +/// Lifts a `testrun_in_progress` row into the public shape, narrowing `node_id` +/// from the sqlx-native `i64` to the API's `u32`. +impl From for TestRunInProgressData { + fn from(row: TestRunInProgress) -> Self { + TestRunInProgressData { + node_id: row.node_id as u32, + started_at: row.started_at, + } + } +} + +/// A row from the `nym_node` table, as returned by a SELECT. +#[derive(Debug, Clone, sqlx::FromRow)] +pub(crate) struct NymNode { + #[sqlx(flatten)] + pub(crate) inner: NewNymNode, + + /// ID of the most recent test run against this node. `None` if never tested. + pub(crate) last_testrun: Option, +} + +/// Decodes a node's stored base58 key strings and parses the socket address +/// into typed counterparts for the public API. Fails (with context) when any +/// stored value is malformed — this should not happen in practice because the +/// orchestrator writes these fields itself, so a failure here indicates +/// corruption or a schema regression and is surfaced as +/// [`crate::http::api::v1::error::ApiError::MalformedStoredData`] by callers. +impl TryFrom for NymNodeData { + type Error = anyhow::Error; + + fn try_from(node: NewNymNode) -> anyhow::Result { + let identity_key = ed25519::PublicKey::from_base58_string(&node.identity_key) + .context("invalid identity_key")?; + + let mixnet_socket_address = node + .mixnet_socket_address + .map(|s| s.parse().context("invalid mixnet_socket_address")) + .transpose()?; + + let noise_key = node + .noise_key + .map(|s| x25519::PublicKey::from_base58_string(&s).context("invalid noise_key")) + .transpose()?; + + let sphinx_key = node + .sphinx_key + .map(|s| x25519::PublicKey::from_base58_string(&s).context("invalid sphinx_key")) + .transpose()?; + + Ok(NymNodeData { + node_id: node.node_id as u32, + identity_key, + last_seen_bonded: node.last_seen_bonded, + mixnet_socket_address, + noise_key, + sphinx_key, + key_rotation_id: node.key_rotation_id, + }) + } +} + +/// Convenience pass-through that drops `last_testrun` (callers that need the +/// latest run fetch it explicitly via [`TestRun`]) and delegates to the +/// [`NewNymNode`] conversion for the rest of the fields. +impl TryFrom for NymNodeData { + type Error = anyhow::Error; + + fn try_from(node: NymNode) -> anyhow::Result { + node.inner.try_into() + } +} diff --git a/nym-node-status-api/nym-node-status-api/src/metrics_scraper/error.rs b/nym-node-status-api/nym-node-status-api/src/metrics_scraper/error.rs deleted file mode 100644 index 65004fbeaf..0000000000 --- a/nym-node-status-api/nym-node-status-api/src/metrics_scraper/error.rs +++ /dev/null @@ -1,155 +0,0 @@ -use nym_network_defaults::DEFAULT_NYM_NODE_HTTP_PORT; -use nym_node_requests::api::client::NymNodeApiClientError; -use nym_validator_client::client::NodeId; -use thiserror::Error; - -#[derive(Debug, Error)] -pub enum NodeScraperError { - #[error("node {node_id} has provided malformed host information ({host}: {source}")] - MalformedHost { - host: String, - node_id: NodeId, - #[source] - source: Box, - }, - - #[error( - "node {node_id} with host '{host}' doesn't seem to expose its declared http port nor any of the standard API ports, i.e.: 80, 443 or {}", - DEFAULT_NYM_NODE_HTTP_PORT - )] - NoHttpPortsAvailable { host: String, node_id: NodeId }, -} - -#[cfg(test)] -mod tests { - use super::*; - use std::error::Error; - - fn dummy_url() -> reqwest::Url { - "http://nym.com".parse().unwrap() - } - - #[test] - #[allow(deprecated)] - fn test_malformed_host_error() { - // Create a generic error to test with - let source_error = NymNodeApiClientError::GenericRequestFailure("Invalid URL".to_string()); - let error = NodeScraperError::MalformedHost { - host: "invalid-host:abc".to_string(), - node_id: 42, - source: Box::new(source_error), - }; - - // Test error message formatting - let error_msg = error.to_string(); - assert!(error_msg.contains("node 42")); - assert!(error_msg.contains("invalid-host:abc")); - assert!(error_msg.contains("malformed host information")); - - // Test that source error is accessible - assert!(error.source().is_some()); - } - - #[test] - #[allow(deprecated)] - fn test_malformed_host_error_edge_cases() { - // Test with empty host - let error = NodeScraperError::MalformedHost { - host: "".to_string(), - node_id: 0, - source: Box::new(NymNodeApiClientError::NotFound { - url: Box::new(dummy_url()), - }), - }; - - let error_msg = error.to_string(); - assert!(error_msg.contains("node 0")); - - // Test with very long host - let long_host = "x".repeat(1000); - let error = NodeScraperError::MalformedHost { - host: long_host.clone(), - node_id: u32::MAX, - source: Box::new(NymNodeApiClientError::GenericRequestFailure( - "Too long".to_string(), - )), - }; - - let error_msg = error.to_string(); - assert!(error_msg.contains(&format!("node {}", u32::MAX))); - assert!(error_msg.contains(&long_host)); - } - - #[test] - fn test_no_http_ports_available_error() { - let error = NodeScraperError::NoHttpPortsAvailable { - host: "example.com".to_string(), - node_id: 123, - }; - - let error_msg = error.to_string(); - assert!(error_msg.contains("node 123")); - assert!(error_msg.contains("example.com")); - assert!(error_msg.contains("doesn't seem to expose its declared http port")); - assert!(error_msg.contains("80, 443 or")); - assert!(error_msg.contains(&DEFAULT_NYM_NODE_HTTP_PORT.to_string())); - - // This error type has no source - assert!(error.source().is_none()); - } - - #[test] - fn test_no_http_ports_special_characters() { - // Test with host containing special characters - let error = NodeScraperError::NoHttpPortsAvailable { - host: "test-node_123.example.com:8080".to_string(), - node_id: 999, - }; - - let error_msg = error.to_string(); - assert!(error_msg.contains("test-node_123.example.com:8080")); - } - - #[test] - #[allow(deprecated)] - fn test_error_different_sources() { - // Test with different NymNodeApiClientError variants - let not_found_error = NymNodeApiClientError::NotFound { - url: Box::new(dummy_url()), - }; - let error1 = NodeScraperError::MalformedHost { - host: "host1".to_string(), - node_id: 1, - source: Box::new(not_found_error), - }; - - let generic_error = NymNodeApiClientError::GenericRequestFailure("404 error".to_string()); - let error2 = NodeScraperError::MalformedHost { - host: "host2".to_string(), - node_id: 2, - source: Box::new(generic_error), - }; - - // Both should format differently based on their source - assert!(error1.to_string().contains("host1")); - assert!(error2.to_string().contains("host2")); - } - - #[test] - fn test_error_trait_implementation() { - // Test that NodeScraperError implements std::error::Error properly - let error = NodeScraperError::NoHttpPortsAvailable { - host: "test.com".to_string(), - node_id: 42, - }; - - // Can be used as dyn Error - let _error_ref: &dyn std::error::Error = &error; - - // Display trait is implemented - let _display = format!("{error}"); - - // Debug trait is implemented - let _debug = format!("{error:?}"); - } -} diff --git a/nym-node-status-api/nym-node-status-api/src/metrics_scraper/mod.rs b/nym-node-status-api/nym-node-status-api/src/metrics_scraper/mod.rs index ab843af8e5..797ba8384f 100644 --- a/nym-node-status-api/nym-node-status-api/src/metrics_scraper/mod.rs +++ b/nym-node-status-api/nym-node-status-api/src/metrics_scraper/mod.rs @@ -1,6 +1,5 @@ use crate::db::{DbPool, models::GatewaySessionsRecord, queries}; -use error::NodeScraperError; -use nym_network_defaults::{DEFAULT_NYM_NODE_HTTP_PORT, NymNetworkDetails}; +use nym_network_defaults::NymNetworkDetails; use nym_node_requests::api::{client::NymNodeApiClientExt, v1::metrics::models::SessionStats}; use nym_validator_client::{ client::{NodeId, NymNodeDetails}, @@ -8,14 +7,14 @@ use nym_validator_client::{ }; use time::OffsetDateTime; +use nym_bin_common::bin_info; +use nym_node_requests::try_get_valid_nym_node_api_client; use nym_statistics_common::types::SessionType; use nym_validator_client::client::NymApiClientExt; use std::collections::HashMap; use tokio::time::Duration; use tracing::instrument; -mod error; - const FAILURE_RETRY_DELAY: Duration = Duration::from_secs(60); const REFRESH_INTERVAL: Duration = Duration::from_secs(60 * 60 * 6); const STALE_DURATION: Duration = Duration::from_secs(86400 * 365); //one year @@ -131,7 +130,10 @@ impl MetricsScrapingData { #[instrument(level = "info", name = "metrics_scraper", skip_all)] async fn try_scrape_metrics(&self) -> Option { - match self.try_get_client().await { + let client_fut = + try_get_valid_nym_node_api_client(&self.host, self.node_id, self.port, bin_info!()); + + match client_fut.await { Ok(client) => { match client.get_sessions_metrics().await { Ok(session_stats) => { @@ -154,54 +156,6 @@ impl MetricsScrapingData { } } } - - async fn try_get_client(&self) -> Result { - // first try the standard port in case the operator didn't put the node behind the proxy, - // then default https (443) - // finally default http (80) - let mut addresses_to_try = vec![ - format!("http://{0}:{DEFAULT_NYM_NODE_HTTP_PORT}", self.host), // 'standard' nym-node - format!("https://{0}", self.host), // node behind https proxy (443) - format!("http://{0}", self.host), // node behind http proxy (80) - ]; - - // note: I removed 'standard' legacy mixnode port because it should now be automatically pulled via - // the 'custom_port' since it should have been present in the contract. - - if let Some(port) = self.port { - addresses_to_try.insert(0, format!("http://{0}:{port}", self.host)); - } - - for address in addresses_to_try { - // if provided host was malformed, no point in continuing - let client = match nym_node_requests::api::Client::builder(address).and_then(|b| { - b.with_timeout(Duration::from_secs(5)) - .with_user_agent("node-status-api-metrics-scraper") - .no_hickory_dns() - .build() - }) { - Ok(client) => client, - Err(err) => { - return Err(NodeScraperError::MalformedHost { - host: self.host.to_string(), - node_id: self.node_id, - source: Box::new(err), - }); - } - }; - - if let Ok(health) = client.get_health().await { - if health.status.is_up() { - return Ok(client); - } - } - } - - Err(NodeScraperError::NoHttpPortsAvailable { - host: self.host.to_string(), - node_id: self.node_id, - }) - } } impl From for MetricsScrapingData { diff --git a/nym-node/Cargo.toml b/nym-node/Cargo.toml index c3f8aa0489..1a2e0b9d38 100644 --- a/nym-node/Cargo.toml +++ b/nym-node/Cargo.toml @@ -109,6 +109,7 @@ nym-node-requests = { workspace = true, default-features = false, features = [ "openapi", ] } nym-node-metrics = { workspace = true } +nyxd-scraper-shared = { workspace = true } # nodes: nym-gateway = { path = "../gateway" } @@ -123,9 +124,9 @@ bincode = { workspace = true } # throughput tester to recreate lioness # we don't care about particular versions - just pull whatever is used by sphinx -lioness = "*" +lioness = { workspace = true } chacha = "0.3.0" -arrayref = "*" +arrayref = { workspace = true } blake2 = "=0.8.1" sha2 = { workspace = true } hkdf = { workspace = true } diff --git a/nym-node/nym-node-metrics/src/mixnet.rs b/nym-node/nym-node-metrics/src/mixnet.rs index 75695e2cd4..2f9d6a456b 100644 --- a/nym-node/nym-node-metrics/src/mixnet.rs +++ b/nym-node/nym-node-metrics/src/mixnet.rs @@ -46,6 +46,7 @@ impl MixingStats { .store(update_timestamp, Ordering::Release); } + /// Record a packet that was dropped due to replay detection. pub fn ingress_replayed_packet(&self, source: IpAddr) { self.ingress .replayed_packets_received @@ -53,6 +54,20 @@ impl MixingStats { self.ingress.senders.entry(source).or_default().replayed += 1; } + /// Record a packet received from an authorised Network Monitor agent. + /// + /// # Purpose + /// + /// This metric tracks test traffic from network monitors, which is useful for: + /// - Distinguishing legitimate traffic from test traffic in dashboards + /// - Monitoring network monitor activity levels + /// - Debugging issues with network monitor authorisation + pub fn ingress_network_monitor_packet(&self) { + self.ingress + .test_packets_received + .fetch_add(1, Ordering::Relaxed); + } + pub fn ingress_malformed_packet(&self, source: IpAddr) { self.ingress .malformed_packets_received @@ -243,6 +258,9 @@ pub struct IngressMixingStats { // packets that were already received and processed before replayed_packets_received: AtomicUsize, + // packets that were received from a globally known network monitor agent + test_packets_received: AtomicUsize, + // (forward) packets that had invalid, i.e. too large, delays excessive_delay_packets: AtomicUsize, @@ -268,6 +286,10 @@ impl IngressMixingStats { self.replayed_packets_received.load(Ordering::Relaxed) } + pub fn test_packets_received(&self) -> usize { + self.test_packets_received.load(Ordering::Relaxed) + } + pub fn malformed_packets_received(&self) -> usize { self.malformed_packets_received.load(Ordering::Relaxed) } diff --git a/nym-node/nym-node-metrics/src/prometheus_wrapper.rs b/nym-node/nym-node-metrics/src/prometheus_wrapper.rs index ffdb66e5c0..72c4b2f4d0 100644 --- a/nym-node/nym-node-metrics/src/prometheus_wrapper.rs +++ b/nym-node/nym-node-metrics/src/prometheus_wrapper.rs @@ -54,6 +54,9 @@ pub enum PrometheusMetric { #[strum(props(help = "The number of ingress replayed sphinx packets received"))] MixnetIngressReplayedPacketsReceived, + #[strum(props(help = "The number of ingress test sphinx packets received"))] + MixnetIngressTestPacketsReceived, + #[strum(props(help = "The number of ingress malformed sphinx packets received"))] MixnetIngressMalformedPacketsReceived, @@ -254,6 +257,9 @@ impl PrometheusMetric { PrometheusMetric::MixnetIngressReplayedPacketsReceived => { Metric::new_int_gauge(&name, help) } + PrometheusMetric::MixnetIngressTestPacketsReceived => { + Metric::new_int_gauge(&name, help) + } PrometheusMetric::MixnetIngressMalformedPacketsReceived => { Metric::new_int_gauge(&name, help) } @@ -446,7 +452,7 @@ mod tests { // a sanity check for anyone adding new metrics. if this test fails, // make sure any methods on `PrometheusMetric` enum don't need updating // or require custom Display impl - assert_eq!(45, PrometheusMetric::COUNT) + assert_eq!(46, PrometheusMetric::COUNT) } #[test] diff --git a/nym-node/nym-node-requests/Cargo.toml b/nym-node/nym-node-requests/Cargo.toml index bd78701287..39d8fec616 100644 --- a/nym-node/nym-node-requests/Cargo.toml +++ b/nym-node/nym-node-requests/Cargo.toml @@ -42,6 +42,7 @@ nym-kkt-ciphersuite = { workspace = true } ## client: async-trait = { workspace = true, optional = true } nym-http-api-client = { workspace = true, optional = true } +nym-network-defaults = { workspace = true, optional = true } ## openapi: utoipa = { workspace = true, features = ["time"], optional = true } @@ -57,5 +58,8 @@ nym-crypto = { workspace = true, features = ["rand"] } [features] default = ["client"] -client = ["nym-http-api-client", "async-trait"] +client = ["nym-http-api-client", "async-trait", "nym-network-defaults"] openapi = ["utoipa", "nym-bin-common/openapi", "nym-exit-policy/openapi"] + +[lints] +workspace = true diff --git a/nym-node/nym-node-requests/src/api/helpers.rs b/nym-node/nym-node-requests/src/api/helpers.rs new file mode 100644 index 0000000000..8fe72eb548 --- /dev/null +++ b/nym-node/nym-node-requests/src/api/helpers.rs @@ -0,0 +1,255 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +#[cfg(feature = "client")] +pub use client_helpers::*; + +#[cfg(feature = "client")] +mod client_helpers { + use crate::api::SignedHostInformation; + use crate::api::client::NymNodeApiClientExt; + use nym_http_api_client::UserAgent; + use nym_network_defaults::DEFAULT_NYM_NODE_HTTP_PORT; + use std::time::Duration; + + /// Builder-style helper for obtaining a validated [`crate::api::Client`] for a nym-node. + /// + /// On top of the basic port-probing performed by [`try_get_valid_nym_node_api_client`], + /// this struct optionally: + /// - verifies that the node's self-reported ed25519 identity matches an expected value + /// (e.g. the identity committed on-chain during bonding), and + /// - checks the cryptographic signature on the node's host information. + /// + /// Both checks require an extra HTTP round-trip to the node's `/host-information` endpoint + /// and are skipped when neither option is enabled. + #[derive(Debug)] + pub struct NymNodeApiClientRetriever { + /// Expected (base58-encoded) ed25519 identity of the node. + /// used to check against data retrieved from the host information + expected_identity: Option, + + /// Custom port to use when attempting to query the node. + custom_port: Option, + + /// User agent to use when attempting to query the node. + user_agent: UserAgent, + + /// Specify whether the signature on the host information should be verified. + verify_host_information: bool, + } + + impl NymNodeApiClientRetriever { + /// Creates a new retriever with the given user agent. + /// All optional checks (identity verification, host information signature) + /// are disabled by default — use the builder methods to enable them. + pub fn new(user_agent: impl Into) -> Self { + Self { + expected_identity: None, + custom_port: None, + user_agent: user_agent.into(), + verify_host_information: false, + } + } + + /// If set, the node's self-reported ed25519 identity (from its `/host-information` + /// endpoint) will be compared against this value. A mismatch produces + /// [`crate::error::Error::MismatchedIdentity`]. + #[must_use] + pub fn with_expected_identity(mut self, expected_identity: Option) -> Self { + self.expected_identity = expected_identity; + self + } + + /// Prepend `http://:` to the list of addresses probed during + /// [`get_client`](Self::get_client), so it is tried before the standard ports. + #[must_use] + pub fn with_custom_port(mut self, port: Option) -> Self { + self.custom_port = port; + self + } + + /// Enable cryptographic verification of the node's host information signature. + /// When enabled, [`get_client`](Self::get_client) will return + /// [`crate::error::Error::MissignedHostInformation`] if the signature is invalid. + #[must_use] + pub fn with_verify_host_information(mut self) -> Self { + self.verify_host_information = true; + self + } + + /// Probe the node's HTTP API, perform any configured verification, and return the + /// client together with the [`SignedHostInformation`] if it was fetched. + /// + /// The host information is only retrieved when identity verification or signature + /// checking is enabled. When neither is active, the returned + /// [`ApiClientWithHostInformation::host_information`] will be `None`. + pub async fn get_client( + self, + base_host: &str, + node_id: u32, + ) -> Result { + let base_client = try_get_valid_nym_node_api_client( + base_host, + node_id, + self.custom_port, + self.user_agent, + ) + .await?; + + // no need to retrieve host information if we don't have to perform any verification + if !self.verify_host_information && self.expected_identity.is_none() { + return Ok(base_client.into()); + } + + let host_info = retrieve_validated_host_information( + &base_client, + node_id, + &self.expected_identity, + self.verify_host_information, + ) + .await?; + + Ok(ApiClientWithHostInformation::from(base_client).with_host_information(host_info)) + } + } + + /// Fetch a node's [`SignedHostInformation`] and optionally validate it. + /// + /// This is the standalone equivalent of the checks performed inside + /// [`NymNodeApiClientRetriever::get_client`], useful when the caller already + /// holds a [`crate::api::Client`] and only needs the host information. + /// + /// When `expected_ed25519_identity` is `Some`, the node's self-reported identity + /// is compared against it — a mismatch produces [`crate::error::Error::MismatchedIdentity`]. + /// When `verify_host_information` is `true`, the cryptographic signature on the + /// host information is checked — an invalid signature produces + /// [`crate::error::Error::MissignedHostInformation`]. + pub async fn retrieve_validated_host_information( + client: &crate::api::Client, + node_id: u32, + expected_ed25519_identity: &Option, + verify_host_information: bool, + ) -> Result { + let host_info = match client.get_host_information().await { + Ok(info) => info, + Err(err) => { + return Err(crate::error::Error::QueryFailure { + host: client.current_url().to_string(), + node_id, + source: Box::new(err), + }); + } + }; + + if let Some(expected_identity) = expected_ed25519_identity { + // check if the identity key matches the information provided during bonding + if expected_identity.as_str() != host_info.keys.ed25519_identity.to_base58_string() { + return Err(crate::error::Error::MismatchedIdentity { + node_id, + expected: expected_identity.clone(), + got: host_info.keys.ed25519_identity.to_base58_string(), + }); + } + } + + // check if the host information has been signed with the node's key + if verify_host_information && !host_info.verify_host_information() { + return Err(crate::error::Error::MissignedHostInformation { node_id }); + } + + Ok(host_info) + } + + /// A nym-node API client bundled with the node's [`SignedHostInformation`], + /// if it was retrieved during the connection/verification phase. + /// + /// This avoids a redundant second call to the `/host-information` endpoint + /// when the caller also needs the host information after obtaining the client. + pub struct ApiClientWithHostInformation { + pub client: crate::api::Client, + pub host_information: Option, + } + + impl ApiClientWithHostInformation { + fn with_host_information(self, host_information: SignedHostInformation) -> Self { + Self { + host_information: Some(host_information), + ..self + } + } + } + + impl From for ApiClientWithHostInformation { + fn from(client: crate::api::Client) -> Self { + Self { + client, + host_information: None, + } + } + } + + /// Probe a nym-node's HTTP API and return a connected [`crate::api::Client`]. + /// + /// `base_host` is a hostname (e.g. `nymtech.net`) or IP address (e.g. `127.0.0.1`). + /// The function tries the following addresses in order, returning the first one whose + /// `/health` endpoint reports an "up" status: + /// + /// 1. `http://:` (only when `custom_port` is `Some`) + /// 2. `http://:8080` — the standard nym-node API port + /// 3. `https://` — node behind an HTTPS reverse proxy (port 443) + /// 4. `http://` — node behind an HTTP reverse proxy (port 80) + /// + /// This function is intended for infrastructure binaries (nym-api, network monitor, etc.), + /// not regular clients, which is why hickory DNS is explicitly disabled. + pub async fn try_get_valid_nym_node_api_client( + base_host: &str, + node_id: u32, + custom_port: Option, + user_agent: impl Into, + ) -> Result { + // first try the standard port in case the operator didn't put the node behind the proxy, + // then default https (443) + // finally default http (80) + let mut addresses_to_try = vec![ + format!("http://{base_host}:{DEFAULT_NYM_NODE_HTTP_PORT}"), // 'standard' nym-node + format!("https://{base_host}"), // node behind https proxy (443) + format!("http://{base_host}"), // node behind http proxy (80) + ]; + + // if a custom port was provided, try to connect to it first + if let Some(port) = custom_port { + addresses_to_try.insert(0, format!("http://{base_host}:{port}")); + } + + let user_agent = user_agent.into(); + for address in addresses_to_try { + // if provided base_host was malformed, there's no point in continuing + let client = match crate::api::Client::builder(address).and_then(|b| { + b.with_timeout(Duration::from_secs(5)) + .no_hickory_dns() + .with_user_agent(user_agent.clone()) + .build() + }) { + Ok(client) => client, + Err(err) => { + return Err(crate::error::Error::MalformedHost { + host: base_host.to_string(), + node_id, + source: Box::new(err), + }); + } + }; + + if let Ok(health) = client.get_health().await + && health.status.is_up() + { + return Ok(client); + } + } + + Err(crate::error::Error::NoHttpPortsAvailable { + host: base_host.to_string(), + node_id, + }) + } +} diff --git a/nym-node/nym-node-requests/src/api/mod.rs b/nym-node/nym-node-requests/src/api/mod.rs index d9c9835af0..ea539a82f7 100644 --- a/nym-node/nym-node-requests/src/api/mod.rs +++ b/nym-node/nym-node-requests/src/api/mod.rs @@ -13,6 +13,7 @@ use std::ops::Deref; #[cfg(feature = "client")] pub mod client; +pub mod helpers; pub mod v1; #[cfg(feature = "client")] diff --git a/nym-node/nym-node-requests/src/api/v1/metrics/models.rs b/nym-node/nym-node-requests/src/api/v1/metrics/models.rs index 2d0eddfda4..6113d6e4be 100644 --- a/nym-node/nym-node-requests/src/api/v1/metrics/models.rs +++ b/nym-node/nym-node-requests/src/api/v1/metrics/models.rs @@ -43,6 +43,9 @@ pub mod packets { // packets that were already received and processed before pub replayed_packets_received: usize, + // packets that were received from a globally known network monitor agent + pub test_packets_received: usize, + // (forward) packets that had invalid, i.e. too large, delays pub excessive_delay_packets: usize, diff --git a/nym-node/nym-node-requests/src/error.rs b/nym-node/nym-node-requests/src/error.rs index d14e252270..57b63e0beb 100644 --- a/nym-node/nym-node-requests/src/error.rs +++ b/nym-node/nym-node-requests/src/error.rs @@ -16,4 +16,45 @@ pub enum Error { #[from] source: nym_wireguard_types::Error, }, + + #[cfg(feature = "client")] + #[error("node {node_id} has provided malformed host information ({host}: {source})")] + MalformedHost { + host: String, + + node_id: u32, + + #[source] + source: Box, + }, + + #[cfg(feature = "client")] + #[error("failed to query node {node_id} at host {host}: {source}")] + QueryFailure { + host: String, + + node_id: u32, + + #[source] + source: Box, + }, + + #[cfg(feature = "client")] + #[error( + "node {node_id} with host '{host}' doesn't seem to expose its declared http port nor any of the standard API ports, i.e.: 80, 443 or {}", + nym_network_defaults::DEFAULT_NYM_NODE_HTTP_PORT + )] + NoHttpPortsAvailable { host: String, node_id: u32 }, + + #[cfg(feature = "client")] + #[error("could not verify signed host information for node {node_id}")] + MissignedHostInformation { node_id: u32 }, + + #[cfg(feature = "client")] + #[error("identity of node {node_id} does not match. expected {expected} but got {got}")] + MismatchedIdentity { + node_id: u32, + expected: String, + got: String, + }, } diff --git a/nym-node/nym-node-requests/src/lib.rs b/nym-node/nym-node-requests/src/lib.rs index e237ba7bd1..f6b72055c7 100644 --- a/nym-node/nym-node-requests/src/lib.rs +++ b/nym-node/nym-node-requests/src/lib.rs @@ -1,11 +1,12 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -#![warn(clippy::expect_used)] -#![warn(clippy::unwrap_used)] - pub mod api; pub mod error; + +#[cfg(feature = "client")] +pub use crate::api::helpers::try_get_valid_nym_node_api_client; + macro_rules! absolute_route { ( $name:ident, $parent:expr, $suffix:expr ) => { pub fn $name() -> String { diff --git a/nym-node/src/cli/commands/reset_sphinx_keys.rs b/nym-node/src/cli/commands/reset_sphinx_keys.rs index 379196b934..804d4b3e96 100644 --- a/nym-node/src/cli/commands/reset_sphinx_keys.rs +++ b/nym-node/src/cli/commands/reset_sphinx_keys.rs @@ -47,7 +47,7 @@ pub async fn execute(args: Args) -> anyhow::Result<()> { // 1. attempt to retrieve current rotation id let current_rotation_id = - get_current_rotation_id(&config.mixnet.nym_api_urls, &config.mixnet.nyxd_urls).await?; + get_current_rotation_id(&config.mixnet.nym_api_urls, &config.nyx.nyxd_urls).await?; // 2. remove all bloomfilters info!("clearing old replay protection bloomfilters..."); diff --git a/nym-node/src/cli/commands/run/args.rs b/nym-node/src/cli/commands/run/args.rs index 2fbc4d3623..6647155438 100644 --- a/nym-node/src/cli/commands/run/args.rs +++ b/nym-node/src/cli/commands/run/args.rs @@ -3,7 +3,7 @@ use crate::cli::helpers::{ ConfigArgs, EntryGatewayArgs, ExitGatewayArgs, HostArgs, HttpArgs, LpArgs, MetricsArgs, - MixnetArgs, VerlocArgs, WireguardArgs, + MixnetArgs, NyxArgs, VerlocArgs, WireguardArgs, }; use crate::config::persistence::NymNodePaths; use crate::config::{Config, ConfigBuilder, NodeMode, NodeModes}; @@ -108,6 +108,9 @@ pub(crate) struct Args { #[clap(flatten)] http: HttpArgs, + #[clap(flatten)] + nyx: NyxArgs, + #[clap(flatten)] mixnet: MixnetArgs, @@ -170,6 +173,7 @@ impl Args { ) .with_host(self.host.build_config_section()) .with_http(self.http.build_config_section()) + .with_nyx(self.nyx.build_config_section()) .with_mixnet(self.mixnet.build_config_section(&data_dir)) .with_wireguard(self.wireguard.build_config_section(&data_dir)) .with_storage_paths(NymNodePaths::new(&data_dir)) @@ -189,6 +193,7 @@ impl Args { config.host = self.host.override_config_section(config.host); config.http = self.http.override_config_section(config.http); config.mixnet = self.mixnet.override_config_section(config.mixnet); + config.nyx = self.nyx.override_config_section(config.nyx); config.wireguard = self.wireguard.override_config_section(config.wireguard); config.metrics = self.metrics.override_config_section(config.metrics); config.gateway_tasks = self diff --git a/nym-node/src/cli/helpers.rs b/nym-node/src/cli/helpers.rs index 85e0df1b7e..970c537fa0 100644 --- a/nym-node/src/cli/helpers.rs +++ b/nym-node/src/cli/helpers.rs @@ -180,6 +180,44 @@ impl HttpArgs { } } +#[derive(clap::Args, Debug)] +pub(crate) struct NyxArgs { + /// Addresses to nyxd chain endpoint which the node will use for chain interactions. + #[clap( + long, + value_delimiter = ',', + env = NYMNODE_NYXD_URLS_ARG + )] + pub(crate) nyxd_urls: Option>, + + #[clap( + long, + env = NYMNODE_NYXD_WEBSOCKET_URL_ARG + )] + /// Url to the websocket endpoint of a nyx validator, for example `wss://rpc.nymtech.net/websocket`. + /// It is used for subscribing to new block events. + pub(crate) nyxd_websocket_url: Option, +} + +impl NyxArgs { + // TODO: could we perhaps make a clap error here and call `safe_exit` instead? + pub(crate) fn build_config_section(self) -> config::Nyx { + self.override_config_section(config::Nyx::default()) + } + + pub(crate) fn override_config_section(self, mut section: config::Nyx) -> config::Nyx { + if let Some(nyxd_urls) = self.nyxd_urls { + section.nyxd_urls = nyxd_urls + } + + if let Some(websocket) = self.nyxd_websocket_url { + section.nyxd_websocket_url = websocket + } + + section + } +} + #[derive(clap::Args, Debug)] pub(crate) struct MixnetArgs { /// Address this node will bind to for listening for mixnet packets @@ -207,14 +245,6 @@ pub(crate) struct MixnetArgs { )] pub(crate) nym_api_urls: Option>, - /// Addresses to nyxd chain endpoint which the node will use for chain interactions. - #[clap( - long, - value_delimiter = ',', - env = NYMNODE_NYXD_URLS_ARG - )] - pub(crate) nyxd_urls: Option>, - /// Specifies whether this node should **NOT** use noise protocol in the connections (currently not implemented) #[clap( hide = true, @@ -248,9 +278,6 @@ impl MixnetArgs { if let Some(nym_api_urls) = self.nym_api_urls { section.nym_api_urls = nym_api_urls } - if let Some(nyxd_urls) = self.nyxd_urls { - section.nyxd_urls = nyxd_urls - } if self.unsafe_disable_noise { section.debug.unsafe_disable_noise = true } diff --git a/nym-node/src/config/helpers.rs b/nym-node/src/config/helpers.rs index 8d43a10f3d..9d2bd9996b 100644 --- a/nym-node/src/config/helpers.rs +++ b/nym-node/src/config/helpers.rs @@ -18,7 +18,7 @@ fn ephemeral_gateway_config(config: &Config) -> nym_gateway::config::Config { enforce_zk_nyms: config.gateway_tasks.enforce_zk_nyms, websocket_bind_address: config.gateway_tasks.ws_bind_address, nym_api_urls: config.mixnet.nym_api_urls.clone(), - nyxd_urls: config.mixnet.nyxd_urls.clone(), + nyxd_urls: config.nyx.nyxd_urls.clone(), }, nym_gateway::config::NetworkRequester { enabled: config.service_providers.ip_packet_router.debug.enabled, @@ -79,7 +79,7 @@ pub fn base_client_config(config: &Config) -> nym_client_core_config_types::Clie id: config.id.clone(), // irrelevant field - no need for credentials in embedded mode disabled_credentials_mode: true, - nyxd_urls: config.mixnet.nyxd_urls.clone(), + nyxd_urls: config.nyx.nyxd_urls.clone(), nym_api_urls: config.mixnet.nym_api_urls.clone(), } } diff --git a/nym-node/src/config/mod.rs b/nym-node/src/config/mod.rs index 14b00b7f5e..963f1bf5dd 100644 --- a/nym-node/src/config/mod.rs +++ b/nym-node/src/config/mod.rs @@ -174,6 +174,8 @@ pub struct ConfigBuilder { pub host: Option, + pub nyx: Option, + pub http: Option, pub verloc: Option, @@ -200,6 +202,7 @@ impl ConfigBuilder { config_path, data_dir, host: None, + nyx: None, http: None, mixnet: None, verloc: None, @@ -214,56 +217,73 @@ impl ConfigBuilder { } } + #[must_use] pub fn with_modes(mut self, mode: impl Into) -> Self { self.modes = mode.into(); self } + #[must_use] + pub fn with_nyx(mut self, section: impl Into>) -> Self { + self.nyx = section.into(); + self + } + + #[must_use] pub fn with_host(mut self, section: impl Into>) -> Self { self.host = section.into(); self } + #[must_use] pub fn with_http(mut self, section: impl Into>) -> Self { self.http = section.into(); self } + #[must_use] pub fn with_verloc(mut self, section: impl Into>) -> Self { self.verloc = section.into(); self } + #[must_use] pub fn with_mixnet(mut self, section: impl Into>) -> Self { self.mixnet = section.into(); self } + #[must_use] pub fn with_lp(mut self, section: impl Into>) -> Self { self.lp = section.into(); self } + #[must_use] pub fn with_wireguard(mut self, section: impl Into>) -> Self { self.wireguard = section.into(); self } + #[must_use] pub fn with_storage_paths(mut self, section: impl Into>) -> Self { self.storage_paths = section.into(); self } + #[must_use] pub fn with_metrics(mut self, section: impl Into>) -> Self { self.metrics = section.into(); self } + #[must_use] pub fn with_gateway_tasks(mut self, section: impl Into>) -> Self { self.gateway_tasks = section.into(); self } + #[must_use] pub fn with_service_providers( mut self, section: impl Into>, @@ -302,6 +322,7 @@ impl ConfigBuilder { logging: self.logging.unwrap_or_default(), save_path: Some(self.config_path), debug: Default::default(), + nyx: self.nyx.unwrap_or_default(), }) } } @@ -326,6 +347,9 @@ pub struct Config { /// Storage paths to persistent nym-node data, such as its long term keys. pub storage_paths: NymNodePaths, + #[serde(default)] + pub nyx: Nyx, + #[serde(default)] pub http: Http, @@ -443,6 +467,7 @@ impl Config { } pub fn validate(&self) -> Result<(), NymNodeError> { + self.nyx.validate()?; self.mixnet.validate()?; // it's not allowed to run mixnode mode alongside entry mode @@ -540,6 +565,72 @@ impl Default for Http { } } +/// Configuration relevant to any interaction involving nyx chain +#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] +pub struct Nyx { + /// Url to the websocket endpoint of a nyx validator, for example `wss://rpc.nymtech.net/websocket`. + /// It is used for subscribing to new block events. + pub nyxd_websocket_url: Url, + + /// Addresses to nyxd which the node uses to interact with the nyx chain. + pub nyxd_urls: Vec, + // pub watcher: NyxdWatcher, +} + +impl Nyx { + pub fn validate(&self) -> Result<(), NymNodeError> { + if self.nyxd_urls.is_empty() { + return Err(NymNodeError::config_validation_failure( + "no nyxd urls provided", + )); + } + Ok(()) + } +} + +impl Default for Nyx { + fn default() -> Self { + // SAFETY: + // our hardcoded values should always be valid + // is if there's anything set in the environment, otherwise fallback to mainnet + #[allow(clippy::expect_used)] + let nyxd_urls = if let Ok(env_value) = env::var(var_names::NYXD_QUERY_LITE) { + // 1. try the lite node if available + parse_urls(&env_value) + } else if let Ok(env_value) = env::var(var_names::NYXD) { + // 2. then fallback to the main rpc node + parse_urls(&env_value) + } else { + // finally fallback to mainnet nodes + vec![ + mainnet::NYXD_QUERY_LITE + .parse() + .expect("invalid default nyxd lite URL"), + mainnet::NYXD_URL.parse().expect("invalid default nyxd URL"), + ] + }; + + #[allow(clippy::expect_used)] + let nyxd_websocket_url = if let Ok(env_value) = env::var(var_names::NYXD_WS_LITE) { + env_value + .parse() + .expect("malformed default nyxd lite websocket URL") + } else if let Ok(env_value) = env::var(var_names::NYXD_WEBSOCKET) { + env_value + .parse() + .expect("malformed default nyxd websocket URL") + } else { + mainnet::NYXD_WS_LITE + .parse() + .expect("invalid default mainnet nyxd websocket URL") + }; + Nyx { + nyxd_websocket_url, + nyxd_urls, + } + } +} + #[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] #[serde(deny_unknown_fields)] pub struct Mixnet { @@ -557,9 +648,6 @@ pub struct Mixnet { /// Addresses to nym APIs from which the node gets the view of the network. pub nym_api_urls: Vec, - /// Addresses to nyxd which the node uses to interact with the nyx chain. - pub nyxd_urls: Vec, - /// Settings for controlling replay detection pub replay_protection: ReplayProtection, @@ -578,12 +666,6 @@ impl Mixnet { )); } - if self.nyxd_urls.is_empty() { - return Err(NymNodeError::config_validation_failure( - "no nyxd urls provided", - )); - } - self.replay_protection.validate()?; Ok(()) @@ -821,29 +903,21 @@ impl Default for MixnetDebug { } impl Mixnet { + // SAFETY: + // our hardcoded values should always be valid + #[allow(clippy::expect_used)] pub fn new_default>(data_dir: P) -> Self { - // SAFETY: - // our hardcoded values should always be valid - #[allow(clippy::expect_used)] // is if there's anything set in the environment, otherwise fallback to mainnet let nym_api_urls = if let Ok(env_value) = env::var(var_names::NYM_API) { parse_urls(&env_value) } else { - vec![mainnet::NYM_API.parse().expect("Invalid default API URL")] - }; - - #[allow(clippy::expect_used)] - let nyxd_urls = if let Ok(env_value) = env::var(var_names::NYXD) { - parse_urls(&env_value) - } else { - vec![mainnet::NYXD_URL.parse().expect("Invalid default nyxd URL")] + vec![mainnet::NYM_API.parse().expect("invalid default API URL")] }; Mixnet { bind_address: SocketAddr::new(in6addr_any_init(), DEFAULT_MIXNET_PORT), announce_port: None, nym_api_urls, - nyxd_urls, replay_protection: ReplayProtection::new_default(data_dir), key_rotation: Default::default(), debug: Default::default(), diff --git a/nym-node/src/config/old_configs/mod.rs b/nym-node/src/config/old_configs/mod.rs index 2116f94ec8..6e9fa3ea28 100644 --- a/nym-node/src/config/old_configs/mod.rs +++ b/nym-node/src/config/old_configs/mod.rs @@ -5,6 +5,7 @@ mod old_config_v1; mod old_config_v10; mod old_config_v11; mod old_config_v12; +mod old_config_v13; mod old_config_v2; mod old_config_v3; mod old_config_v4; @@ -26,3 +27,4 @@ pub use old_config_v9::try_upgrade_config_v9; pub use old_config_v10::try_upgrade_config_v10; pub use old_config_v11::try_upgrade_config_v11; pub use old_config_v12::try_upgrade_config_v12; +pub use old_config_v13::try_upgrade_config_v13; diff --git a/nym-node/src/config/old_configs/old_config_v12.rs b/nym-node/src/config/old_configs/old_config_v12.rs index ce0b381e3f..170b5946ef 100644 --- a/nym-node/src/config/old_configs/old_config_v12.rs +++ b/nym-node/src/config/old_configs/old_config_v12.rs @@ -1,34 +1,15 @@ // Copyright 2026 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use crate::config::authenticator::{Authenticator, AuthenticatorDebug}; -use crate::config::gateway_tasks::{ - ClientBandwidthDebug, StaleMessageDebug, UpgradeModeWatcher, UpgradeModeWatcherDebug, - ZkNymTicketHandlerDebug, -}; use crate::config::helpers::log_error_and_return; -use crate::config::persistence::{ - AuthenticatorPaths, DEFAULT_MCELIECE_PRIVATE_KEY_FILENAME, - DEFAULT_MCELIECE_PUBLIC_KEY_FILENAME, DEFAULT_MLKEM768_PRIVATE_KEY_FILENAME, - DEFAULT_MLKEM768_PUBLIC_KEY_FILENAME, DEFAULT_X25519_PRIVATE_LP_KEY_FILENAME, - DEFAULT_X25519_PUBLIC_LP_KEY_FILENAME, GatewayTasksPaths, IpPacketRouterPaths, KeysPaths, - NetworkRequesterPaths, NymNodePaths, ReplayProtectionPaths, ServiceProvidersPaths, - WireguardPaths, -}; -use crate::config::service_providers::{ - IpPacketRouter, IpPacketRouterDebug, NetworkRequester, NetworkRequesterDebug, -}; -use crate::config::{ - Config, Debug, GatewayTasksConfig, Host, Http, KeyRotation, KeyRotationDebug, MetricsConfig, - Mixnet, MixnetDebug, NodeModes, ReplayProtection, ReplayProtectionDebug, - ServiceProvidersConfig, Verloc, VerlocDebug, Wireguard, gateway_tasks, metrics, - service_providers, +use crate::config::old_configs::old_config_v13::{ + ConfigV13, GatewayTasksConfigDebugV13, GatewayTasksConfigV13, KeysPathsV13, LpConfigV13, + LpDebugV13, NymNodePathsV13, }; use crate::error::NymNodeError; use crate::node::helpers::{ store_mceliece_keypair, store_mlkem768_keypair, store_x25519_lp_keypair, }; -use nym_bin_common::logging::LoggingSettings; use nym_config::defaults::{mainnet, var_names}; use nym_config::read_config_from_toml_file; use nym_config::serde_helpers::de_maybe_port; @@ -46,7 +27,11 @@ use std::time::Duration; use tracing::{debug, info, instrument}; use url::Url; -use crate::config::lp::{LpConfig, LpDebug}; +use crate::config::persistence::{ + DEFAULT_MCELIECE_PRIVATE_KEY_FILENAME, DEFAULT_MCELIECE_PUBLIC_KEY_FILENAME, + DEFAULT_MLKEM768_PRIVATE_KEY_FILENAME, DEFAULT_MLKEM768_PUBLIC_KEY_FILENAME, + DEFAULT_X25519_PRIVATE_LP_KEY_FILENAME, DEFAULT_X25519_PUBLIC_LP_KEY_FILENAME, +}; pub use unchanged_v12_types::*; // (while some of those are technically unused, they might be needed in future migrations, @@ -526,7 +511,7 @@ impl ConfigV12 { pub async fn try_upgrade_config_v12>( path: P, prev_config: Option, -) -> Result { +) -> Result { debug!("attempting to load v12 config..."); let old_cfg = if let Some(prev_config) = prev_config { @@ -544,7 +529,7 @@ pub async fn try_upgrade_config_v12>( .ok_or(NymNodeError::DataDirDerivationFailure)? .to_path_buf(); - let updated_keys = KeysPaths { + let updated_keys = KeysPathsV13 { private_ed25519_identity_key_file: old_cfg .storage_paths .keys @@ -586,145 +571,27 @@ pub async fn try_upgrade_config_v12>( let paths = updated_keys.mceliece_key_paths(); store_mceliece_keypair(&mceliece, &paths)?; - let cfg = Config { + let cfg = ConfigV13 { save_path: old_cfg.save_path, id: old_cfg.id, - modes: NodeModes { - mixnode: old_cfg.modes.mixnode, - entry: old_cfg.modes.entry, - exit: old_cfg.modes.exit, - }, - host: Host { - public_ips: old_cfg.host.public_ips, - hostname: old_cfg.host.hostname, - location: old_cfg.host.location, - }, - mixnet: Mixnet { - bind_address: old_cfg.mixnet.bind_address, - announce_port: old_cfg.mixnet.announce_port, - nym_api_urls: old_cfg.mixnet.nym_api_urls, - nyxd_urls: old_cfg.mixnet.nyxd_urls, - replay_protection: ReplayProtection { - storage_paths: ReplayProtectionPaths { - current_bloomfilters_directory: old_cfg - .mixnet - .replay_protection - .storage_paths - .current_bloomfilters_directory, - }, - debug: ReplayProtectionDebug { - unsafe_disabled: old_cfg.mixnet.replay_protection.debug.unsafe_disabled, - maximum_replay_detection_deferral: old_cfg - .mixnet - .replay_protection - .debug - .maximum_replay_detection_deferral, - maximum_replay_detection_pending_packets: old_cfg - .mixnet - .replay_protection - .debug - .maximum_replay_detection_pending_packets, - false_positive_rate: old_cfg.mixnet.replay_protection.debug.false_positive_rate, - initial_expected_packets_per_second: old_cfg - .mixnet - .replay_protection - .debug - .initial_expected_packets_per_second, - bloomfilter_minimum_packets_per_second_size: old_cfg - .mixnet - .replay_protection - .debug - .bloomfilter_minimum_packets_per_second_size, - bloomfilter_size_multiplier: old_cfg - .mixnet - .replay_protection - .debug - .bloomfilter_size_multiplier, - bloomfilter_disk_flushing_rate: old_cfg - .mixnet - .replay_protection - .debug - .bloomfilter_disk_flushing_rate, - }, - }, - key_rotation: KeyRotation { - debug: KeyRotationDebug { - rotation_state_poling_interval: old_cfg - .mixnet - .key_rotation - .debug - .rotation_state_poling_interval, - }, - }, - debug: MixnetDebug { - maximum_forward_packet_delay: old_cfg.mixnet.debug.maximum_forward_packet_delay, - packet_forwarding_initial_backoff: old_cfg - .mixnet - .debug - .packet_forwarding_initial_backoff, - packet_forwarding_maximum_backoff: old_cfg - .mixnet - .debug - .packet_forwarding_maximum_backoff, - initial_connection_timeout: old_cfg.mixnet.debug.initial_connection_timeout, - maximum_connection_buffer_size: old_cfg.mixnet.debug.maximum_connection_buffer_size, - unsafe_disable_noise: old_cfg.mixnet.debug.unsafe_disable_noise, - use_legacy_packet_encoding: old_cfg.mixnet.debug.use_legacy_packet_encoding, - }, - }, - storage_paths: NymNodePaths { + modes: old_cfg.modes, + host: old_cfg.host, + mixnet: old_cfg.mixnet, + // \/ UPDATED + storage_paths: NymNodePathsV13 { keys: updated_keys, description: old_cfg.storage_paths.description, }, - http: Http { - bind_address: old_cfg.http.bind_address, - landing_page_assets_path: old_cfg.http.landing_page_assets_path, - access_token: old_cfg.http.access_token, - expose_system_info: old_cfg.http.expose_system_info, - expose_system_hardware: old_cfg.http.expose_system_hardware, - expose_crypto_hardware: old_cfg.http.expose_crypto_hardware, - node_load_cache_ttl: old_cfg.http.node_load_cache_ttl, - }, - verloc: Verloc { - bind_address: old_cfg.verloc.bind_address, - announce_port: old_cfg.verloc.announce_port, - debug: VerlocDebug { - packets_per_node: old_cfg.verloc.debug.packets_per_node, - connection_timeout: old_cfg.verloc.debug.connection_timeout, - packet_timeout: old_cfg.verloc.debug.packet_timeout, - delay_between_packets: old_cfg.verloc.debug.delay_between_packets, - tested_nodes_batch_size: old_cfg.verloc.debug.tested_nodes_batch_size, - testing_interval: old_cfg.verloc.debug.testing_interval, - retry_timeout: old_cfg.verloc.debug.retry_timeout, - }, - }, - wireguard: Wireguard { - enabled: old_cfg.wireguard.enabled, - bind_address: old_cfg.wireguard.bind_address, - private_ipv4: old_cfg.wireguard.private_ipv4, - private_ipv6: old_cfg.wireguard.private_ipv6, - announced_tunnel_port: old_cfg.wireguard.announced_tunnel_port, - announced_metadata_port: old_cfg.wireguard.announced_metadata_port, - private_network_prefix_v4: old_cfg.wireguard.private_network_prefix_v4, - private_network_prefix_v6: old_cfg.wireguard.private_network_prefix_v6, - use_userspace: old_cfg.wireguard.use_userspace, - storage_paths: WireguardPaths { - private_diffie_hellman_key_file: old_cfg - .wireguard - .storage_paths - .private_diffie_hellman_key_file, - public_diffie_hellman_key_file: old_cfg - .wireguard - .storage_paths - .public_diffie_hellman_key_file, - }, - }, - lp: LpConfig { + // /\ UPDATED + http: old_cfg.http, + verloc: old_cfg.verloc, + wireguard: old_cfg.wireguard, + lp: LpConfigV13 { control_bind_address: old_cfg.gateway_tasks.lp.control_bind_address, data_bind_address: old_cfg.gateway_tasks.lp.data_bind_address, announce_control_port: old_cfg.gateway_tasks.lp.announce_control_port, announce_data_port: old_cfg.gateway_tasks.lp.announce_data_port, - debug: LpDebug { + debug: LpDebugV13 { max_connections: old_cfg.gateway_tasks.lp.debug.max_connections, use_mock_ecash: old_cfg.gateway_tasks.lp.debug.use_mock_ecash, handshake_ttl: old_cfg.gateway_tasks.lp.debug.handshake_ttl, @@ -733,290 +600,35 @@ pub async fn try_upgrade_config_v12>( max_concurrent_forwards: old_cfg.gateway_tasks.lp.debug.max_concurrent_forwards, }, }, - gateway_tasks: GatewayTasksConfig { - storage_paths: GatewayTasksPaths { - clients_storage: old_cfg.gateway_tasks.storage_paths.clients_storage, - stats_storage: old_cfg.gateway_tasks.storage_paths.stats_storage, - cosmos_mnemonic: old_cfg.gateway_tasks.storage_paths.cosmos_mnemonic, - bridge_client_params: old_cfg.gateway_tasks.storage_paths.bridge_client_params, - }, + gateway_tasks: GatewayTasksConfigV13 { + storage_paths: old_cfg.gateway_tasks.storage_paths, enforce_zk_nyms: old_cfg.gateway_tasks.enforce_zk_nyms, ws_bind_address: old_cfg.gateway_tasks.ws_bind_address, announce_ws_port: old_cfg.gateway_tasks.announce_ws_port, announce_wss_port: old_cfg.gateway_tasks.announce_wss_port, - upgrade_mode: UpgradeModeWatcher { - enabled: old_cfg.gateway_tasks.upgrade_mode.enabled, - attestation_url: old_cfg.gateway_tasks.upgrade_mode.attestation_url, - attester_public_key: old_cfg.gateway_tasks.upgrade_mode.attester_public_key, - debug: UpgradeModeWatcherDebug { - regular_polling_interval: old_cfg - .gateway_tasks - .upgrade_mode - .debug - .regular_polling_interval, - expedited_poll_interval: old_cfg - .gateway_tasks - .upgrade_mode - .debug - .expedited_poll_interval, - }, - }, - debug: gateway_tasks::Debug { + upgrade_mode: old_cfg.gateway_tasks.upgrade_mode, + debug: GatewayTasksConfigDebugV13 { message_retrieval_limit: old_cfg.gateway_tasks.debug.message_retrieval_limit, maximum_open_connections: old_cfg.gateway_tasks.debug.maximum_open_connections, minimum_mix_performance: old_cfg.gateway_tasks.debug.minimum_mix_performance, // \/ ADDED - maximum_initial_topology_waiting_time: gateway_tasks::Debug::default() + maximum_initial_topology_waiting_time: GatewayTasksConfigDebugV13::default() .maximum_initial_topology_waiting_time, // /\ ADDED max_request_timestamp_skew: old_cfg.gateway_tasks.debug.max_request_timestamp_skew, - stale_messages: StaleMessageDebug { - cleaner_run_interval: old_cfg - .gateway_tasks - .debug - .stale_messages - .cleaner_run_interval, - max_age: old_cfg.gateway_tasks.debug.stale_messages.max_age, - }, - client_bandwidth: ClientBandwidthDebug { - max_flushing_rate: old_cfg - .gateway_tasks - .debug - .client_bandwidth - .max_flushing_rate, - max_delta_flushing_amount: old_cfg - .gateway_tasks - .debug - .client_bandwidth - .max_delta_flushing_amount, - }, - zk_nym_tickets: ZkNymTicketHandlerDebug { - revocation_bandwidth_penalty: old_cfg - .gateway_tasks - .debug - .zk_nym_tickets - .revocation_bandwidth_penalty, - pending_poller: old_cfg.gateway_tasks.debug.zk_nym_tickets.pending_poller, - minimum_api_quorum: old_cfg - .gateway_tasks - .debug - .zk_nym_tickets - .minimum_api_quorum, - minimum_redemption_tickets: old_cfg - .gateway_tasks - .debug - .zk_nym_tickets - .minimum_redemption_tickets, - maximum_time_between_redemption: old_cfg - .gateway_tasks - .debug - .zk_nym_tickets - .maximum_time_between_redemption, - }, + stale_messages: old_cfg.gateway_tasks.debug.stale_messages, + client_bandwidth: old_cfg.gateway_tasks.debug.client_bandwidth, + zk_nym_tickets: old_cfg.gateway_tasks.debug.zk_nym_tickets, upgrade_mode_min_staleness_recheck: old_cfg .gateway_tasks .debug .upgrade_mode_min_staleness_recheck, }, }, - service_providers: ServiceProvidersConfig { - storage_paths: ServiceProvidersPaths { - clients_storage: old_cfg.service_providers.storage_paths.clients_storage, - stats_storage: old_cfg.service_providers.storage_paths.stats_storage, - network_requester: NetworkRequesterPaths { - private_ed25519_identity_key_file: old_cfg - .service_providers - .storage_paths - .network_requester - .private_ed25519_identity_key_file, - public_ed25519_identity_key_file: old_cfg - .service_providers - .storage_paths - .network_requester - .public_ed25519_identity_key_file, - private_x25519_diffie_hellman_key_file: old_cfg - .service_providers - .storage_paths - .network_requester - .private_x25519_diffie_hellman_key_file, - public_x25519_diffie_hellman_key_file: old_cfg - .service_providers - .storage_paths - .network_requester - .public_x25519_diffie_hellman_key_file, - ack_key_file: old_cfg - .service_providers - .storage_paths - .network_requester - .ack_key_file, - reply_surb_database: old_cfg - .service_providers - .storage_paths - .network_requester - .reply_surb_database, - gateway_registrations: old_cfg - .service_providers - .storage_paths - .network_requester - .gateway_registrations, - }, - ip_packet_router: IpPacketRouterPaths { - private_ed25519_identity_key_file: old_cfg - .service_providers - .storage_paths - .ip_packet_router - .private_ed25519_identity_key_file, - public_ed25519_identity_key_file: old_cfg - .service_providers - .storage_paths - .ip_packet_router - .public_ed25519_identity_key_file, - private_x25519_diffie_hellman_key_file: old_cfg - .service_providers - .storage_paths - .ip_packet_router - .private_x25519_diffie_hellman_key_file, - public_x25519_diffie_hellman_key_file: old_cfg - .service_providers - .storage_paths - .ip_packet_router - .public_x25519_diffie_hellman_key_file, - ack_key_file: old_cfg - .service_providers - .storage_paths - .ip_packet_router - .ack_key_file, - reply_surb_database: old_cfg - .service_providers - .storage_paths - .ip_packet_router - .reply_surb_database, - gateway_registrations: old_cfg - .service_providers - .storage_paths - .ip_packet_router - .gateway_registrations, - }, - authenticator: AuthenticatorPaths { - private_ed25519_identity_key_file: old_cfg - .service_providers - .storage_paths - .authenticator - .private_ed25519_identity_key_file, - public_ed25519_identity_key_file: old_cfg - .service_providers - .storage_paths - .authenticator - .public_ed25519_identity_key_file, - private_x25519_diffie_hellman_key_file: old_cfg - .service_providers - .storage_paths - .authenticator - .private_x25519_diffie_hellman_key_file, - public_x25519_diffie_hellman_key_file: old_cfg - .service_providers - .storage_paths - .authenticator - .public_x25519_diffie_hellman_key_file, - ack_key_file: old_cfg - .service_providers - .storage_paths - .authenticator - .ack_key_file, - reply_surb_database: old_cfg - .service_providers - .storage_paths - .authenticator - .reply_surb_database, - gateway_registrations: old_cfg - .service_providers - .storage_paths - .authenticator - .gateway_registrations, - }, - }, - open_proxy: old_cfg.service_providers.open_proxy, - upstream_exit_policy_url: old_cfg.service_providers.upstream_exit_policy_url, - network_requester: NetworkRequester { - allow_local_ips: false, - debug: NetworkRequesterDebug { - enabled: old_cfg.service_providers.network_requester.debug.enabled, - disable_poisson_rate: old_cfg - .service_providers - .network_requester - .debug - .disable_poisson_rate, - client_debug: old_cfg - .service_providers - .network_requester - .debug - .client_debug, - }, - }, - ip_packet_router: IpPacketRouter { - allow_local_ips: false, - debug: IpPacketRouterDebug { - enabled: old_cfg.service_providers.ip_packet_router.debug.enabled, - disable_poisson_rate: old_cfg - .service_providers - .ip_packet_router - .debug - .disable_poisson_rate, - client_debug: old_cfg - .service_providers - .ip_packet_router - .debug - .client_debug, - }, - }, - authenticator: Authenticator { - debug: AuthenticatorDebug { - enabled: old_cfg.service_providers.authenticator.debug.enabled, - disable_poisson_rate: old_cfg - .service_providers - .authenticator - .debug - .disable_poisson_rate, - client_debug: old_cfg.service_providers.authenticator.debug.client_debug, - }, - }, - debug: service_providers::Debug { - message_retrieval_limit: old_cfg.service_providers.debug.message_retrieval_limit, - }, - }, - metrics: MetricsConfig { - debug: metrics::Debug { - log_stats_to_console: old_cfg.metrics.debug.log_stats_to_console, - aggregator_update_rate: old_cfg.metrics.debug.aggregator_update_rate, - stale_mixnet_metrics_cleaner_rate: old_cfg - .metrics - .debug - .stale_mixnet_metrics_cleaner_rate, - global_prometheus_counters_update_rate: old_cfg - .metrics - .debug - .global_prometheus_counters_update_rate, - pending_egress_packets_update_rate: old_cfg - .metrics - .debug - .pending_egress_packets_update_rate, - clients_sessions_update_rate: old_cfg.metrics.debug.clients_sessions_update_rate, - console_logging_update_interval: old_cfg - .metrics - .debug - .console_logging_update_interval, - legacy_mixing_metrics_update_rate: old_cfg - .metrics - .debug - .legacy_mixing_metrics_update_rate, - }, - }, - logging: LoggingSettings {}, - debug: Debug { - topology_cache_ttl: old_cfg.debug.topology_cache_ttl, - routing_nodes_check_interval: old_cfg.debug.routing_nodes_check_interval, - testnet: old_cfg.debug.testnet, - }, + service_providers: old_cfg.service_providers, + metrics: old_cfg.metrics, + logging: old_cfg.logging, + debug: old_cfg.debug, }; Ok(cfg) } diff --git a/nym-node/src/config/old_configs/old_config_v13.rs b/nym-node/src/config/old_configs/old_config_v13.rs new file mode 100644 index 0000000000..b62320a7e7 --- /dev/null +++ b/nym-node/src/config/old_configs/old_config_v13.rs @@ -0,0 +1,923 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::config::authenticator::{Authenticator, AuthenticatorDebug}; +use crate::config::gateway_tasks::{ + ClientBandwidthDebug, StaleMessageDebug, UpgradeModeWatcher, UpgradeModeWatcherDebug, + ZkNymTicketHandlerDebug, +}; +use crate::config::old_configs::old_config_v13::unchanged_v13_types::{ + ClientBandwidthDebugV13, DebugV13, GatewayTasksPathsV13, HostV13, HttpV13, LoggingSettingsV13, + MetricsConfigV13, MixnetV13, NodeModesV13, ServiceProvidersConfigV13, StaleMessageDebugV13, + UpgradeModeWatcherV13, VerlocV13, WireguardV13, ZkNymTicketHandlerDebugV13, +}; +use crate::config::persistence::{ + AuthenticatorPaths, GatewayTasksPaths, IpPacketRouterPaths, KeysPaths, NetworkRequesterPaths, + NymNodePaths, ReplayProtectionPaths, ServiceProvidersPaths, WireguardPaths, +}; +use crate::config::service_providers::{ + IpPacketRouter, IpPacketRouterDebug, NetworkRequester, NetworkRequesterDebug, +}; +use crate::config::{ + Config, Debug, GatewayTasksConfig, Host, Http, KeyRotation, KeyRotationDebug, LpConfig, + LpDebug, MetricsConfig, Mixnet, MixnetDebug, NodeModes, Nyx, ReplayProtection, + ReplayProtectionDebug, ServiceProvidersConfig, Verloc, VerlocDebug, Wireguard, gateway_tasks, + metrics, service_providers, +}; +use crate::error::NymNodeError; +use nym_bin_common::logging::LoggingSettings; +use nym_config::read_config_from_toml_file; +use nym_config::serde_helpers::de_maybe_port; +use serde::{Deserialize, Serialize}; +use std::net::{IpAddr, Ipv6Addr, SocketAddr}; +use std::path::{Path, PathBuf}; +use std::time::Duration; +use tracing::{debug, info, instrument}; + +#[allow(unused_imports)] +pub use unchanged_v13_types::*; + +// (while some of those are technically unused, they might be needed in future migrations, +// thus allow them to exist) +#[allow(dead_code)] +pub mod unchanged_v13_types { + use crate::config::old_configs::old_config_v12::{ + AuthenticatorDebugV12, AuthenticatorPathsV12, AuthenticatorV12, ClientBandwidthDebugV12, + DebugV12, GatewayTasksPathsV12, HostV12, HttpV12, IpPacketRouterDebugV12, + IpPacketRouterPathsV12, IpPacketRouterV12, KeyRotationDebugV12, KeyRotationV12, + KeysPathsV12, LoggingSettingsV12, MetricsConfigV12, MetricsDebugV12, MixnetDebugV12, + MixnetV12, NetworkRequesterDebugV12, NetworkRequesterPathsV12, NetworkRequesterV12, + NodeModeV12, NodeModesV12, ReplayProtectionDebugV12, ReplayProtectionPathsV12, + ReplayProtectionV12, ServiceProvidersConfigDebugV12, ServiceProvidersConfigV12, + ServiceProvidersPathsV12, StaleMessageDebugV12, UpgradeModeWatcherV12, VerlocDebugV12, + VerlocV12, WireguardPathsV12, WireguardV12, ZkNymTicketHandlerDebugV12, + }; + + pub type WireguardPathsV13 = WireguardPathsV12; + pub type NodeModeV13 = NodeModeV12; + pub type NodeModesV13 = NodeModesV12; + pub type HostV13 = HostV12; + pub type KeyRotationDebugV13 = KeyRotationDebugV12; + pub type KeyRotationV13 = KeyRotationV12; + pub type MixnetDebugV13 = MixnetDebugV12; + pub type MixnetV13 = MixnetV12; + pub type ReplayProtectionV13 = ReplayProtectionV12; + pub type ReplayProtectionPathsV13 = ReplayProtectionPathsV12; + pub type ReplayProtectionDebugV13 = ReplayProtectionDebugV12; + pub type KeysPathsV13 = KeysPathsV12; + pub type HttpV13 = HttpV12; + pub type VerlocDebugV13 = VerlocDebugV12; + pub type VerlocV13 = VerlocV12; + pub type ZkNymTicketHandlerDebugV13 = ZkNymTicketHandlerDebugV12; + pub type NetworkRequesterPathsV13 = NetworkRequesterPathsV12; + pub type IpPacketRouterPathsV13 = IpPacketRouterPathsV12; + pub type AuthenticatorPathsV13 = AuthenticatorPathsV12; + pub type AuthenticatorV13 = AuthenticatorV12; + pub type AuthenticatorDebugV13 = AuthenticatorDebugV12; + pub type IpPacketRouterDebugV13 = IpPacketRouterDebugV12; + pub type IpPacketRouterV13 = IpPacketRouterV12; + pub type NetworkRequesterDebugV13 = NetworkRequesterDebugV12; + pub type NetworkRequesterV13 = NetworkRequesterV12; + pub type GatewayTasksPathsV13 = GatewayTasksPathsV12; + pub type StaleMessageDebugV13 = StaleMessageDebugV12; + pub type ClientBandwidthDebugV13 = ClientBandwidthDebugV12; + pub type ServiceProvidersPathsV13 = ServiceProvidersPathsV12; + pub type ServiceProvidersConfigDebugV13 = ServiceProvidersConfigDebugV12; + pub type ServiceProvidersConfigV13 = ServiceProvidersConfigV12; + pub type MetricsConfigV13 = MetricsConfigV12; + pub type MetricsDebugV13 = MetricsDebugV12; + pub type LoggingSettingsV13 = LoggingSettingsV12; + pub type WireguardV13 = WireguardV12; + pub type DebugV13 = DebugV12; + pub type UpgradeModeWatcherV13 = UpgradeModeWatcherV12; +} + +#[derive(Debug, Clone, Copy, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct LpConfigV13 { + /// Bind address for the TCP LP control traffic. + /// default: `[::]:41264` + pub control_bind_address: SocketAddr, + + /// Bind address for the UDP LP data traffic. + /// default: `[::]:51264` + pub data_bind_address: SocketAddr, + + /// Custom announced port for listening for the TCP LP control traffic. + /// If unspecified, the value from the `control_bind_address` will be used instead + /// (default: None) + #[serde(deserialize_with = "de_maybe_port")] + pub announce_control_port: Option, + + /// Custom announced port for listening for the UDP LP data traffic. + /// If unspecified, the value from the `data_bind_address` will be used instead + /// (default: None) + #[serde(deserialize_with = "de_maybe_port")] + pub announce_data_port: Option, + + /// Auxiliary configuration + #[serde(default)] + pub debug: LpDebugV13, +} + +impl Default for LpConfigV13 { + fn default() -> Self { + LpConfigV13 { + control_bind_address: SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), 41264), + data_bind_address: SocketAddr::new(IpAddr::V6(Ipv6Addr::UNSPECIFIED), 51264), + announce_control_port: None, + announce_data_port: None, + debug: Default::default(), + } + } +} + +#[derive(Debug, Clone, Copy, serde::Deserialize, serde::Serialize)] +#[serde(default)] +pub struct LpDebugV13 { + /// Maximum concurrent connections + pub max_connections: usize, + + /// Use mock ecash manager for testing (default: false) + /// + /// When enabled, the LP listener will use a mock ecash verifier that + /// accepts any credential without blockchain verification. This is + /// useful for testing the LP protocol implementation without requiring + /// a full blockchain/contract setup. + /// + /// WARNING: Only use this for local testing! Never enable in production. + pub use_mock_ecash: bool, + + /// Maximum age of in-progress handshakes before cleanup (default: 90s) + /// + /// Handshakes should complete quickly (3-5 packets). This TTL accounts for: + /// - Network latency and retransmits + /// - Slow clients + /// - Clock skew tolerance + /// + /// Stale handshakes are removed by the cleanup task to prevent memory leaks. + #[serde(with = "humantime_serde")] + pub handshake_ttl: Duration, + + /// Maximum age of established sessions before cleanup (default: 24h) + /// + /// Sessions can be long-lived for dVPN tunnels. This TTL should be set + /// high enough to accommodate expected usage patterns: + /// - dVPN sessions: hours to days + /// - Registration: minutes + /// + /// Sessions with no activity for this duration are removed by the cleanup task. + #[serde(with = "humantime_serde")] + pub session_ttl: Duration, + + /// How often to run the state cleanup task (default: 5 minutes) + /// + /// The cleanup task scans for and removes stale handshakes and sessions. + /// Lower values = more frequent cleanup but higher overhead. + /// Higher values = less overhead but slower memory reclamation. + #[serde(with = "humantime_serde")] + pub state_cleanup_interval: Duration, + + /// Maximum concurrent forward connections (default: 1000) + /// + /// Limits simultaneous outbound connections when forwarding LP packets to other gateways + /// during telescope setup. This prevents file descriptor exhaustion under high load. + /// + /// When at capacity, new forward requests return an error, signaling the client + /// to choose a different gateway. + pub max_concurrent_forwards: usize, +} + +impl LpDebugV13 { + pub const DEFAULT_MAX_CONNECTIONS: usize = 10000; + pub const DEFAULT_HANDSHAKE_TTL: Duration = Duration::from_secs(90); + pub const DEFAULT_SESSION_TTL: Duration = Duration::from_secs(86400); + pub const DEFAULT_STATE_CLEANUP_INTERVAL: Duration = Duration::from_secs(300); + pub const DEFAULT_MAX_CONCURRENT_FORWARDS: usize = 1000; +} + +impl Default for LpDebugV13 { + fn default() -> Self { + LpDebugV13 { + max_connections: Self::DEFAULT_MAX_CONNECTIONS, + use_mock_ecash: false, + handshake_ttl: Self::DEFAULT_HANDSHAKE_TTL, + session_ttl: Self::DEFAULT_SESSION_TTL, + state_cleanup_interval: Self::DEFAULT_STATE_CLEANUP_INTERVAL, + max_concurrent_forwards: Self::DEFAULT_MAX_CONCURRENT_FORWARDS, + } + } +} + +#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] +pub struct KeysPathsV13 { + /// Path to file containing ed25519 identity private key. + pub private_ed25519_identity_key_file: PathBuf, + + /// Path to file containing ed25519 identity public key. + pub public_ed25519_identity_key_file: PathBuf, + + /// Path to file containing the primary x25519 sphinx private key. + pub primary_x25519_sphinx_key_file: PathBuf, + + /// Path to file containing the secondary x25519 sphinx private key. + pub secondary_x25519_sphinx_key_file: PathBuf, + + /// Path to file containing x25519 noise private key. + pub private_x25519_noise_key_file: PathBuf, + + /// Path to file containing x25519 noise public key. + pub public_x25519_noise_key_file: PathBuf, + + // >> LP KEYS START: + /// Path to file containing x25519 lp private key. + pub private_x25519_lp_key_file: PathBuf, + + /// Path to file containing x25519 lp public key. + pub public_x25519_lp_key_file: PathBuf, + + /// Path to file containing mlkem768 lp private key. + pub private_mlkem768_lp_key_file: PathBuf, + + /// Path to file containing mlkem768 lp public key. + pub public_mlkem768_lp_key_file: PathBuf, + + /// Path to file containing mceliece lp private key. + pub private_mceliece_lp_key_file: PathBuf, + + /// Path to file containing mceliece lp public key. + pub public_mceliece_lp_key_file: PathBuf, + // >> LP KEYS END +} + +impl KeysPathsV13 { + pub fn x25519_lp_key_paths(&self) -> nym_pemstore::KeyPairPath { + nym_pemstore::KeyPairPath::new( + &self.private_x25519_lp_key_file, + &self.public_x25519_lp_key_file, + ) + } + + pub fn mlkem768_key_paths(&self) -> nym_pemstore::KeyPairPath { + nym_pemstore::KeyPairPath::new( + &self.private_mlkem768_lp_key_file, + &self.public_mlkem768_lp_key_file, + ) + } + + pub fn mceliece_key_paths(&self) -> nym_pemstore::KeyPairPath { + nym_pemstore::KeyPairPath::new( + &self.private_mceliece_lp_key_file, + &self.public_mceliece_lp_key_file, + ) + } +} + +#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct NymNodePathsV13 { + pub keys: KeysPathsV13, + pub description: PathBuf, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +#[serde(default)] +pub struct GatewayTasksConfigDebugV13 { + /// Number of messages from offline client that can be pulled at once (i.e. with a single SQL query) from the storage. + pub message_retrieval_limit: i64, + + /// The maximum number of client connections the gateway will keep open at once. + pub maximum_open_connections: usize, + + /// Specifies the minimum performance of mixnodes in the network that are to be used in internal topologies + /// of the services providers + pub minimum_mix_performance: u8, + + /// Specifies the maximum time this node will wait for its initial valid topology + #[serde(with = "humantime_serde")] + pub maximum_initial_topology_waiting_time: Duration, + + /// Defines the timestamp skew of a signed authentication request before it's deemed too excessive to process. + #[serde(alias = "maximum_auth_request_age")] + pub max_request_timestamp_skew: Duration, + + /// The minimum duration since the last explicit check for the upgrade mode to allow creation of new requests. + #[serde(with = "humantime_serde")] + pub upgrade_mode_min_staleness_recheck: Duration, + + pub stale_messages: StaleMessageDebugV13, + + pub client_bandwidth: ClientBandwidthDebugV13, + + pub zk_nym_tickets: ZkNymTicketHandlerDebugV13, +} + +impl GatewayTasksConfigDebugV13 { + pub const DEFAULT_MESSAGE_RETRIEVAL_LIMIT: i64 = 100; + pub const DEFAULT_MINIMUM_MIX_PERFORMANCE: u8 = 50; + pub const DEFAULT_MAXIMUM_AUTH_REQUEST_TIMESTAMP_SKEW: Duration = Duration::from_secs(120); + pub const DEFAULT_MAXIMUM_OPEN_CONNECTIONS: usize = 8192; + pub const DEFAULT_UPGRADE_MODE_MIN_STALENESS_RECHECK: Duration = Duration::from_secs(30); + pub const DEFAULT_MAXIMUM_INITIAL_TOPOLOGY_WAITING_TIME: Duration = + Duration::from_secs(15 * 60); +} + +impl Default for GatewayTasksConfigDebugV13 { + fn default() -> Self { + GatewayTasksConfigDebugV13 { + message_retrieval_limit: Self::DEFAULT_MESSAGE_RETRIEVAL_LIMIT, + maximum_open_connections: Self::DEFAULT_MAXIMUM_OPEN_CONNECTIONS, + max_request_timestamp_skew: Self::DEFAULT_MAXIMUM_AUTH_REQUEST_TIMESTAMP_SKEW, + minimum_mix_performance: Self::DEFAULT_MINIMUM_MIX_PERFORMANCE, + stale_messages: Default::default(), + client_bandwidth: Default::default(), + zk_nym_tickets: Default::default(), + upgrade_mode_min_staleness_recheck: Self::DEFAULT_UPGRADE_MODE_MIN_STALENESS_RECHECK, + maximum_initial_topology_waiting_time: + Self::DEFAULT_MAXIMUM_INITIAL_TOPOLOGY_WAITING_TIME, + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct GatewayTasksConfigV13 { + pub storage_paths: GatewayTasksPathsV13, + + /// Indicates whether this gateway is accepting only zk-nym credentials for accessing the mixnet + /// or if it also accepts non-paying clients + pub enforce_zk_nyms: bool, + + /// Socket address this node will use for binding its client websocket API. + /// default: `[::]:9000` + pub ws_bind_address: SocketAddr, + + /// Custom announced port for listening for websocket client traffic. + /// If unspecified, the value from the `bind_address` will be used instead + /// default: None + #[serde(deserialize_with = "de_maybe_port")] + pub announce_ws_port: Option, + + /// If applicable, announced port for listening for secure websocket client traffic. + /// (default: None) + #[serde(deserialize_with = "de_maybe_port")] + pub announce_wss_port: Option, + + pub upgrade_mode: UpgradeModeWatcherV13, + + #[serde(default)] + pub debug: GatewayTasksConfigDebugV13, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct ConfigV13 { + // additional metadata holding on-disk location of this config file + #[serde(skip)] + pub(crate) save_path: Option, + + /// Human-readable ID of this particular node. + pub id: String, + + /// Current modes of this nym-node. + pub modes: NodeModesV13, + + pub host: HostV13, + + pub mixnet: MixnetV13, + + /// Storage paths to persistent nym-node data, such as its long term keys. + pub storage_paths: NymNodePathsV13, + + #[serde(default)] + pub http: HttpV13, + + #[serde(default)] + pub verloc: VerlocV13, + + pub wireguard: WireguardV13, + + #[serde(default)] + pub lp: LpConfigV13, + + #[serde(alias = "entry_gateway")] + pub gateway_tasks: GatewayTasksConfigV13, + + #[serde(alias = "exit_gateway")] + pub service_providers: ServiceProvidersConfigV13, + + #[serde(default)] + pub metrics: MetricsConfigV13, + + #[serde(default)] + pub logging: LoggingSettingsV13, + + #[serde(default)] + pub debug: DebugV13, +} + +impl ConfigV13 { + // simple wrapper that reads config file and assigns path location + fn read_from_path>(path: P) -> Result { + let path = path.as_ref(); + let mut loaded: ConfigV13 = + read_config_from_toml_file(path).map_err(|source| NymNodeError::ConfigLoadFailure { + path: path.to_path_buf(), + source, + })?; + loaded.save_path = Some(path.to_path_buf()); + debug!("loaded config file from {}", path.display()); + Ok(loaded) + } +} + +#[instrument(skip_all)] +pub async fn try_upgrade_config_v13>( + path: P, + prev_config: Option, +) -> Result { + debug!("attempting to load v13 config..."); + + let old_cfg = if let Some(prev_config) = prev_config { + prev_config + } else { + ConfigV13::read_from_path(&path)? + }; + + info!("migrating the old config (v13)..."); + + let cfg = Config { + save_path: old_cfg.save_path, + id: old_cfg.id, + modes: NodeModes { + mixnode: old_cfg.modes.mixnode, + entry: old_cfg.modes.entry, + exit: old_cfg.modes.exit, + }, + host: Host { + public_ips: old_cfg.host.public_ips, + hostname: old_cfg.host.hostname, + location: old_cfg.host.location, + }, + // \/ ADDED + // use default to switch to the lite query node + nyx: Nyx::default(), + // /\ ADDED + mixnet: Mixnet { + bind_address: old_cfg.mixnet.bind_address, + announce_port: old_cfg.mixnet.announce_port, + nym_api_urls: old_cfg.mixnet.nym_api_urls, + replay_protection: ReplayProtection { + storage_paths: ReplayProtectionPaths { + current_bloomfilters_directory: old_cfg + .mixnet + .replay_protection + .storage_paths + .current_bloomfilters_directory, + }, + debug: ReplayProtectionDebug { + unsafe_disabled: old_cfg.mixnet.replay_protection.debug.unsafe_disabled, + maximum_replay_detection_deferral: old_cfg + .mixnet + .replay_protection + .debug + .maximum_replay_detection_deferral, + maximum_replay_detection_pending_packets: old_cfg + .mixnet + .replay_protection + .debug + .maximum_replay_detection_pending_packets, + false_positive_rate: old_cfg.mixnet.replay_protection.debug.false_positive_rate, + initial_expected_packets_per_second: old_cfg + .mixnet + .replay_protection + .debug + .initial_expected_packets_per_second, + bloomfilter_minimum_packets_per_second_size: old_cfg + .mixnet + .replay_protection + .debug + .bloomfilter_minimum_packets_per_second_size, + bloomfilter_size_multiplier: old_cfg + .mixnet + .replay_protection + .debug + .bloomfilter_size_multiplier, + bloomfilter_disk_flushing_rate: old_cfg + .mixnet + .replay_protection + .debug + .bloomfilter_disk_flushing_rate, + }, + }, + key_rotation: KeyRotation { + debug: KeyRotationDebug { + rotation_state_poling_interval: old_cfg + .mixnet + .key_rotation + .debug + .rotation_state_poling_interval, + }, + }, + debug: MixnetDebug { + maximum_forward_packet_delay: old_cfg.mixnet.debug.maximum_forward_packet_delay, + packet_forwarding_initial_backoff: old_cfg + .mixnet + .debug + .packet_forwarding_initial_backoff, + packet_forwarding_maximum_backoff: old_cfg + .mixnet + .debug + .packet_forwarding_maximum_backoff, + initial_connection_timeout: old_cfg.mixnet.debug.initial_connection_timeout, + maximum_connection_buffer_size: old_cfg.mixnet.debug.maximum_connection_buffer_size, + unsafe_disable_noise: old_cfg.mixnet.debug.unsafe_disable_noise, + use_legacy_packet_encoding: old_cfg.mixnet.debug.use_legacy_packet_encoding, + }, + }, + storage_paths: NymNodePaths { + keys: KeysPaths { + private_ed25519_identity_key_file: old_cfg + .storage_paths + .keys + .private_ed25519_identity_key_file, + public_ed25519_identity_key_file: old_cfg + .storage_paths + .keys + .public_ed25519_identity_key_file, + primary_x25519_sphinx_key_file: old_cfg + .storage_paths + .keys + .primary_x25519_sphinx_key_file, + secondary_x25519_sphinx_key_file: old_cfg + .storage_paths + .keys + .secondary_x25519_sphinx_key_file, + private_x25519_noise_key_file: old_cfg + .storage_paths + .keys + .private_x25519_noise_key_file, + public_x25519_noise_key_file: old_cfg + .storage_paths + .keys + .public_x25519_noise_key_file, + private_x25519_lp_key_file: old_cfg.storage_paths.keys.private_x25519_lp_key_file, + public_x25519_lp_key_file: old_cfg.storage_paths.keys.public_x25519_lp_key_file, + private_mlkem768_lp_key_file: old_cfg + .storage_paths + .keys + .private_mlkem768_lp_key_file, + public_mlkem768_lp_key_file: old_cfg.storage_paths.keys.public_mlkem768_lp_key_file, + private_mceliece_lp_key_file: old_cfg + .storage_paths + .keys + .private_mceliece_lp_key_file, + public_mceliece_lp_key_file: old_cfg.storage_paths.keys.public_mceliece_lp_key_file, + }, + description: old_cfg.storage_paths.description, + }, + http: Http { + bind_address: old_cfg.http.bind_address, + landing_page_assets_path: old_cfg.http.landing_page_assets_path, + access_token: old_cfg.http.access_token, + expose_system_info: old_cfg.http.expose_system_info, + expose_system_hardware: old_cfg.http.expose_system_hardware, + expose_crypto_hardware: old_cfg.http.expose_crypto_hardware, + node_load_cache_ttl: old_cfg.http.node_load_cache_ttl, + }, + verloc: Verloc { + bind_address: old_cfg.verloc.bind_address, + announce_port: old_cfg.verloc.announce_port, + debug: VerlocDebug { + packets_per_node: old_cfg.verloc.debug.packets_per_node, + connection_timeout: old_cfg.verloc.debug.connection_timeout, + packet_timeout: old_cfg.verloc.debug.packet_timeout, + delay_between_packets: old_cfg.verloc.debug.delay_between_packets, + tested_nodes_batch_size: old_cfg.verloc.debug.tested_nodes_batch_size, + testing_interval: old_cfg.verloc.debug.testing_interval, + retry_timeout: old_cfg.verloc.debug.retry_timeout, + }, + }, + wireguard: Wireguard { + enabled: old_cfg.wireguard.enabled, + bind_address: old_cfg.wireguard.bind_address, + private_ipv4: old_cfg.wireguard.private_ipv4, + private_ipv6: old_cfg.wireguard.private_ipv6, + announced_tunnel_port: old_cfg.wireguard.announced_tunnel_port, + announced_metadata_port: old_cfg.wireguard.announced_metadata_port, + private_network_prefix_v4: old_cfg.wireguard.private_network_prefix_v4, + private_network_prefix_v6: old_cfg.wireguard.private_network_prefix_v6, + use_userspace: old_cfg.wireguard.use_userspace, + storage_paths: WireguardPaths { + private_diffie_hellman_key_file: old_cfg + .wireguard + .storage_paths + .private_diffie_hellman_key_file, + public_diffie_hellman_key_file: old_cfg + .wireguard + .storage_paths + .public_diffie_hellman_key_file, + }, + }, + lp: LpConfig { + control_bind_address: old_cfg.lp.control_bind_address, + data_bind_address: old_cfg.lp.data_bind_address, + announce_control_port: old_cfg.lp.announce_control_port, + announce_data_port: old_cfg.lp.announce_data_port, + debug: LpDebug { + max_connections: old_cfg.lp.debug.max_connections, + use_mock_ecash: old_cfg.lp.debug.use_mock_ecash, + handshake_ttl: old_cfg.lp.debug.handshake_ttl, + session_ttl: old_cfg.lp.debug.session_ttl, + state_cleanup_interval: old_cfg.lp.debug.state_cleanup_interval, + max_concurrent_forwards: old_cfg.lp.debug.max_concurrent_forwards, + }, + }, + gateway_tasks: GatewayTasksConfig { + storage_paths: GatewayTasksPaths { + clients_storage: old_cfg.gateway_tasks.storage_paths.clients_storage, + stats_storage: old_cfg.gateway_tasks.storage_paths.stats_storage, + cosmos_mnemonic: old_cfg.gateway_tasks.storage_paths.cosmos_mnemonic, + bridge_client_params: old_cfg.gateway_tasks.storage_paths.bridge_client_params, + }, + enforce_zk_nyms: old_cfg.gateway_tasks.enforce_zk_nyms, + ws_bind_address: old_cfg.gateway_tasks.ws_bind_address, + announce_ws_port: old_cfg.gateway_tasks.announce_ws_port, + announce_wss_port: old_cfg.gateway_tasks.announce_wss_port, + upgrade_mode: UpgradeModeWatcher { + enabled: old_cfg.gateway_tasks.upgrade_mode.enabled, + attestation_url: old_cfg.gateway_tasks.upgrade_mode.attestation_url, + attester_public_key: old_cfg.gateway_tasks.upgrade_mode.attester_public_key, + debug: UpgradeModeWatcherDebug { + regular_polling_interval: old_cfg + .gateway_tasks + .upgrade_mode + .debug + .regular_polling_interval, + expedited_poll_interval: old_cfg + .gateway_tasks + .upgrade_mode + .debug + .expedited_poll_interval, + }, + }, + debug: gateway_tasks::Debug { + message_retrieval_limit: old_cfg.gateway_tasks.debug.message_retrieval_limit, + maximum_open_connections: old_cfg.gateway_tasks.debug.maximum_open_connections, + minimum_mix_performance: old_cfg.gateway_tasks.debug.minimum_mix_performance, + maximum_initial_topology_waiting_time: old_cfg + .gateway_tasks + .debug + .maximum_initial_topology_waiting_time, + max_request_timestamp_skew: old_cfg.gateway_tasks.debug.max_request_timestamp_skew, + stale_messages: StaleMessageDebug { + cleaner_run_interval: old_cfg + .gateway_tasks + .debug + .stale_messages + .cleaner_run_interval, + max_age: old_cfg.gateway_tasks.debug.stale_messages.max_age, + }, + client_bandwidth: ClientBandwidthDebug { + max_flushing_rate: old_cfg + .gateway_tasks + .debug + .client_bandwidth + .max_flushing_rate, + max_delta_flushing_amount: old_cfg + .gateway_tasks + .debug + .client_bandwidth + .max_delta_flushing_amount, + }, + zk_nym_tickets: ZkNymTicketHandlerDebug { + revocation_bandwidth_penalty: old_cfg + .gateway_tasks + .debug + .zk_nym_tickets + .revocation_bandwidth_penalty, + pending_poller: old_cfg.gateway_tasks.debug.zk_nym_tickets.pending_poller, + minimum_api_quorum: old_cfg + .gateway_tasks + .debug + .zk_nym_tickets + .minimum_api_quorum, + minimum_redemption_tickets: old_cfg + .gateway_tasks + .debug + .zk_nym_tickets + .minimum_redemption_tickets, + maximum_time_between_redemption: old_cfg + .gateway_tasks + .debug + .zk_nym_tickets + .maximum_time_between_redemption, + }, + upgrade_mode_min_staleness_recheck: old_cfg + .gateway_tasks + .debug + .upgrade_mode_min_staleness_recheck, + }, + }, + service_providers: ServiceProvidersConfig { + storage_paths: ServiceProvidersPaths { + clients_storage: old_cfg.service_providers.storage_paths.clients_storage, + stats_storage: old_cfg.service_providers.storage_paths.stats_storage, + network_requester: NetworkRequesterPaths { + private_ed25519_identity_key_file: old_cfg + .service_providers + .storage_paths + .network_requester + .private_ed25519_identity_key_file, + public_ed25519_identity_key_file: old_cfg + .service_providers + .storage_paths + .network_requester + .public_ed25519_identity_key_file, + private_x25519_diffie_hellman_key_file: old_cfg + .service_providers + .storage_paths + .network_requester + .private_x25519_diffie_hellman_key_file, + public_x25519_diffie_hellman_key_file: old_cfg + .service_providers + .storage_paths + .network_requester + .public_x25519_diffie_hellman_key_file, + ack_key_file: old_cfg + .service_providers + .storage_paths + .network_requester + .ack_key_file, + reply_surb_database: old_cfg + .service_providers + .storage_paths + .network_requester + .reply_surb_database, + gateway_registrations: old_cfg + .service_providers + .storage_paths + .network_requester + .gateway_registrations, + }, + ip_packet_router: IpPacketRouterPaths { + private_ed25519_identity_key_file: old_cfg + .service_providers + .storage_paths + .ip_packet_router + .private_ed25519_identity_key_file, + public_ed25519_identity_key_file: old_cfg + .service_providers + .storage_paths + .ip_packet_router + .public_ed25519_identity_key_file, + private_x25519_diffie_hellman_key_file: old_cfg + .service_providers + .storage_paths + .ip_packet_router + .private_x25519_diffie_hellman_key_file, + public_x25519_diffie_hellman_key_file: old_cfg + .service_providers + .storage_paths + .ip_packet_router + .public_x25519_diffie_hellman_key_file, + ack_key_file: old_cfg + .service_providers + .storage_paths + .ip_packet_router + .ack_key_file, + reply_surb_database: old_cfg + .service_providers + .storage_paths + .ip_packet_router + .reply_surb_database, + gateway_registrations: old_cfg + .service_providers + .storage_paths + .ip_packet_router + .gateway_registrations, + }, + authenticator: AuthenticatorPaths { + private_ed25519_identity_key_file: old_cfg + .service_providers + .storage_paths + .authenticator + .private_ed25519_identity_key_file, + public_ed25519_identity_key_file: old_cfg + .service_providers + .storage_paths + .authenticator + .public_ed25519_identity_key_file, + private_x25519_diffie_hellman_key_file: old_cfg + .service_providers + .storage_paths + .authenticator + .private_x25519_diffie_hellman_key_file, + public_x25519_diffie_hellman_key_file: old_cfg + .service_providers + .storage_paths + .authenticator + .public_x25519_diffie_hellman_key_file, + ack_key_file: old_cfg + .service_providers + .storage_paths + .authenticator + .ack_key_file, + reply_surb_database: old_cfg + .service_providers + .storage_paths + .authenticator + .reply_surb_database, + gateway_registrations: old_cfg + .service_providers + .storage_paths + .authenticator + .gateway_registrations, + }, + }, + open_proxy: old_cfg.service_providers.open_proxy, + upstream_exit_policy_url: old_cfg.service_providers.upstream_exit_policy_url, + network_requester: NetworkRequester { + allow_local_ips: false, + debug: NetworkRequesterDebug { + enabled: old_cfg.service_providers.network_requester.debug.enabled, + disable_poisson_rate: old_cfg + .service_providers + .network_requester + .debug + .disable_poisson_rate, + client_debug: old_cfg + .service_providers + .network_requester + .debug + .client_debug, + }, + }, + ip_packet_router: IpPacketRouter { + allow_local_ips: false, + debug: IpPacketRouterDebug { + enabled: old_cfg.service_providers.ip_packet_router.debug.enabled, + disable_poisson_rate: old_cfg + .service_providers + .ip_packet_router + .debug + .disable_poisson_rate, + client_debug: old_cfg + .service_providers + .ip_packet_router + .debug + .client_debug, + }, + }, + authenticator: Authenticator { + debug: AuthenticatorDebug { + enabled: old_cfg.service_providers.authenticator.debug.enabled, + disable_poisson_rate: old_cfg + .service_providers + .authenticator + .debug + .disable_poisson_rate, + client_debug: old_cfg.service_providers.authenticator.debug.client_debug, + }, + }, + debug: service_providers::Debug { + message_retrieval_limit: old_cfg.service_providers.debug.message_retrieval_limit, + }, + }, + metrics: MetricsConfig { + debug: metrics::Debug { + log_stats_to_console: old_cfg.metrics.debug.log_stats_to_console, + aggregator_update_rate: old_cfg.metrics.debug.aggregator_update_rate, + stale_mixnet_metrics_cleaner_rate: old_cfg + .metrics + .debug + .stale_mixnet_metrics_cleaner_rate, + global_prometheus_counters_update_rate: old_cfg + .metrics + .debug + .global_prometheus_counters_update_rate, + pending_egress_packets_update_rate: old_cfg + .metrics + .debug + .pending_egress_packets_update_rate, + clients_sessions_update_rate: old_cfg.metrics.debug.clients_sessions_update_rate, + console_logging_update_interval: old_cfg + .metrics + .debug + .console_logging_update_interval, + legacy_mixing_metrics_update_rate: old_cfg + .metrics + .debug + .legacy_mixing_metrics_update_rate, + }, + }, + logging: LoggingSettings {}, + debug: Debug { + topology_cache_ttl: old_cfg.debug.topology_cache_ttl, + routing_nodes_check_interval: old_cfg.debug.routing_nodes_check_interval, + testnet: old_cfg.debug.testnet, + }, + }; + Ok(cfg) +} diff --git a/nym-node/src/config/template.rs b/nym-node/src/config/template.rs index 6b5c1e39b7..52f4d4d178 100644 --- a/nym-node/src/config/template.rs +++ b/nym-node/src/config/template.rs @@ -60,10 +60,7 @@ nym_api_urls = [ {{#each mixnet.nym_api_urls }}'{{this}}',{{/each}} ] -# Addresses to nyxd which the node uses to interact with the nyx chain. -nyxd_urls = [ - {{#each mixnet.nyxd_urls }}'{{this}}',{{/each}} -] + [mixnet.replay_protection] @@ -77,6 +74,18 @@ current_bloomfilters_directory = '{{ mixnet.replay_protection.storage_paths.curr # Path to a file containing basic node description: human-readable name, website, details, etc. description = '{{ storage_paths.description }}' +[nyx] + +# Url to the websocket endpoint of a nyx validator, for example `wss://rpc.nymtech.net/websocket`. +# It is used for subscribing to new block events. +nyxd_websocket_url = '{{ nyx.nyxd_websocket_url }}' + +# Addresses to nyxd which the node uses to interact with the nyx chain. +nyxd_urls = [ + {{#each nyx.nyxd_urls }}'{{this}}',{{/each}} +] + + [storage_paths.keys] # Path to file containing ed25519 identity private key. private_ed25519_identity_key_file = '{{ storage_paths.keys.private_ed25519_identity_key_file }}' diff --git a/nym-node/src/config/upgrade_helpers.rs b/nym-node/src/config/upgrade_helpers.rs index 8c556b409d..b00534fc3c 100644 --- a/nym-node/src/config/upgrade_helpers.rs +++ b/nym-node/src/config/upgrade_helpers.rs @@ -19,7 +19,8 @@ async fn try_upgrade_config(path: &Path) -> Result<(), NymNodeError> { let cfg = try_upgrade_config_v9(path, cfg).await.ok(); let cfg = try_upgrade_config_v10(path, cfg).await.ok(); let cfg = try_upgrade_config_v11(path, cfg).await.ok(); - match try_upgrade_config_v12(path, cfg).await { + let cfg = try_upgrade_config_v12(path, cfg).await.ok(); + match try_upgrade_config_v13(path, cfg).await { Ok(cfg) => cfg.save(), Err(e) => { tracing::error!("Failed to finish upgrade: {e}"); diff --git a/nym-node/src/env.rs b/nym-node/src/env.rs index 196c5dcc2f..3b553d28b5 100644 --- a/nym-node/src/env.rs +++ b/nym-node/src/env.rs @@ -38,10 +38,13 @@ pub mod vars { pub const NYMNODE_MIXNET_BIND_ADDRESS_ARG: &str = "NYMNODE_MIXNET_BIND_ADDRESS"; pub const NYMNODE_MIXNET_ANNOUNCE_PORT_ARG: &str = "NYMNODE_MIXNET_ANNOUNCE_PORT"; pub const NYMNODE_NYM_APIS_ARG: &str = "NYMNODE_NYM_APIS"; - pub const NYMNODE_NYXD_URLS_ARG: &str = "NYMNODE_NYXD"; pub const NYMNODE_UNSAFE_DISABLE_NOISE: &str = "UNSAFE_DISABLE_NOISE"; pub const NYMNODE_UNSAFE_DISABLE_REPLAY_PROTECTION: &str = "UNSAFE_DISABLE_REPLAY_PROTECTION"; + // nyxd: + pub const NYMNODE_NYXD_URLS_ARG: &str = "NYMNODE_NYXD"; + pub const NYMNODE_NYXD_WEBSOCKET_URL_ARG: &str = "NYMNODE_NYXD_WEBSOCKET"; + // wireguard: pub const NYMNODE_WG_ENABLED_ARG: &str = "NYMNODE_WG_ENABLED"; pub const NYMNODE_WG_BIND_ADDRESS_ARG: &str = "NYMNODE_WG_BIND_ADDRESS"; diff --git a/nym-node/src/error.rs b/nym-node/src/error.rs index 582cf321a4..37f91729c5 100644 --- a/nym-node/src/error.rs +++ b/nym-node/src/error.rs @@ -9,6 +9,7 @@ use nym_ip_packet_router::error::ClientCoreError; use nym_kkt::keys::storage_wrappers::MalformedStoredKeyError; use nym_validator_client::ValidatorClientError; use nym_validator_client::nyxd::error::NyxdError; +use nyxd_scraper_shared::error::ScraperError; use std::io; use std::net::{IpAddr, SocketAddr}; use std::path::PathBuf; @@ -248,6 +249,12 @@ pub enum NymNodeError { #[error(transparent)] LpFailure(#[from] LpHandlerError), + + #[error("no valid network monitors contract address configured")] + MissingNetworkMonitorsContractAddress, + + #[error(transparent)] + ChainWatcherFailure(#[from] ScraperError), } impl From for NymNodeError { diff --git a/nym-node/src/node/http/router/api/v1/metrics/packets_stats.rs b/nym-node/src/node/http/router/api/v1/metrics/packets_stats.rs index aa2816637d..347a767789 100644 --- a/nym-node/src/node/http/router/api/v1/metrics/packets_stats.rs +++ b/nym-node/src/node/http/router/api/v1/metrics/packets_stats.rs @@ -39,6 +39,7 @@ fn build_response(metrics: &NymNodeMetrics) -> PacketsStats { final_hop_packets_received: metrics.mixnet.ingress.final_hop_packets_received(), malformed_packets_received: metrics.mixnet.ingress.malformed_packets_received(), replayed_packets_received: metrics.mixnet.ingress.replayed_packets_received(), + test_packets_received: metrics.mixnet.ingress.test_packets_received(), excessive_delay_packets: metrics.mixnet.ingress.excessive_delay_packets(), forward_hop_packets_dropped: metrics.mixnet.ingress.forward_hop_packets_dropped(), final_hop_packets_dropped: metrics.mixnet.ingress.final_hop_packets_dropped(), diff --git a/nym-node/src/node/metrics/handler/global_prometheus_updater/mod.rs b/nym-node/src/node/metrics/handler/global_prometheus_updater/mod.rs index 4578f6bd60..219adba8d1 100644 --- a/nym-node/src/node/metrics/handler/global_prometheus_updater/mod.rs +++ b/nym-node/src/node/metrics/handler/global_prometheus_updater/mod.rs @@ -68,6 +68,10 @@ impl OnUpdateMetricsHandler for PrometheusGlobalNodeMetricsRegistryUpdater { MixnetIngressReplayedPacketsReceived, self.metrics.mixnet.ingress.replayed_packets_received() as i64, ); + self.prometheus_wrapper.set( + MixnetIngressTestPacketsReceived, + self.metrics.mixnet.ingress.test_packets_received() as i64, + ); self.prometheus_wrapper.set( MixnetIngressExcessiveDelayPacketsReceived, self.metrics.mixnet.ingress.excessive_delay_packets() as i64, diff --git a/nym-node/src/node/mixnet/handler.rs b/nym-node/src/node/mixnet/handler.rs index 4b193bfe87..bd70892686 100644 --- a/nym-node/src/node/mixnet/handler.rs +++ b/nym-node/src/node/mixnet/handler.rs @@ -110,6 +110,7 @@ impl ConnectionHandler { final_hop: shared.final_hop.clone(), noise_config: shared.noise_config.clone(), metrics: shared.metrics.clone(), + authorised_network_monitor_agents: shared.authorised_network_monitor_agents.clone(), shutdown_token: shared.shutdown_token.child_token(), }, remote_address, @@ -117,8 +118,35 @@ impl ConnectionHandler { } } + /// Check if the current connection is from an authorised Network Monitor agent. + /// + /// # Replay Protection Bypass + /// + /// Network Monitor agents are granted special privileges to bypass replay protection. + /// This allows them to intentionally send replayed packets for testing purposes to reduce + /// the processing required to generate enough packets required for stress testing. + /// + /// # Security + /// + /// - Authorisation is controlled on-chain via the Network Monitors smart contract + /// - Only specific IP addresses can bypass replay protection (not public keys or other identifiers) + /// - All bypass events are logged and tracked via Prometheus metrics + /// - Regular nodes cannot bypass replay protection under any circumstances + /// + /// # Authorisation Source + /// + /// The list of authorised IPs is: + /// 1. Initially loaded from the contract at node startup + /// 2. Updated in real-time via blockchain subscription (see `NetworkMonitorAgentsModule`) + /// 3. Shared across all connection handlers via lock-free `ArcSwap` + fn is_from_authorised_network_monitor_agent(&self) -> bool { + self.shared + .authorised_network_monitor_agents + .is_known(&self.remote_address.ip()) + } + /// Determine instant at which packet should get forwarded to the next hop. - /// By using [`Instant`] rather than explicit [`Duration`] we minimise effects of + /// By using [`Instant`] rather than explicit [`Duration`], we minimise the effects of /// the skew caused by being stuck in the channel queue. /// This method also clamps the maximum allowed delay so that nobody could send a bunch of packets /// with, for example, delays of 1 year thus causing denial of service @@ -147,7 +175,13 @@ impl ConnectionHandler { delay_ms = tracing::field::Empty, ) )] - fn handle_forward_packet(&self, now: Instant, mix_packet: MixPacket, delay: Option) { + fn handle_forward_packet( + &self, + now: Instant, + mix_packet: MixPacket, + delay: Option, + network_monitor_packet: bool, + ) { if !self.shared.processing_config.forward_hop_processing_enabled { warn!( event = "packet.dropped.forward_disabled", @@ -165,7 +199,8 @@ impl ConnectionHandler { target.saturating_duration_since(now).as_millis() as u64, ); } - self.shared.forward_mix_packet(mix_packet, forward_instant); + self.shared + .forward_mix_packet(mix_packet, forward_instant, network_monitor_packet); } #[instrument( @@ -179,7 +214,11 @@ impl ConnectionHandler { ack_forwarded = false, ) )] - async fn handle_final_hop(&self, final_hop_data: ProcessedFinalHop) { + async fn handle_final_hop( + &self, + final_hop_data: ProcessedFinalHop, + network_monitor_packet: bool, + ) { if !self.shared.processing_config.final_hop_processing_enabled { warn!( event = "packet.dropped.final_hop_disabled", @@ -191,6 +230,17 @@ impl ConnectionHandler { return; } + if network_monitor_packet { + warn!( + event = "packet.dropped.network_monitor_final_hop", + remote_addr = %self.remote_address, + "dropping packet: unsupported network monitor final hop packets" + ); + self.shared + .dropped_final_hop_packet(self.remote_address.ip()); + return; + } + let client = final_hop_data.destination; let message = final_hop_data.message; let has_ack = final_hop_data.forward_ack.is_some(); @@ -411,6 +461,7 @@ impl ConnectionHandler { &self, now: Instant, unwrapped_packet: Result, + network_monitor_packet: bool, ) { // 2. increment our favourite metrics stats self.shared @@ -423,10 +474,11 @@ impl ConnectionHandler { } Ok(processed_packet) => match processed_packet.processing_data { MixProcessingResultData::ForwardHop { packet, delay } => { - self.handle_forward_packet(now, packet, delay); + self.handle_forward_packet(now, packet, delay, network_monitor_packet); } MixProcessingResultData::FinalHop { final_hop_data } => { - self.handle_final_hop(final_hop_data).await; + self.handle_final_hop(final_hop_data, network_monitor_packet) + .await; } }, } @@ -446,7 +498,26 @@ impl ConnectionHandler { continue; }; for (packet, &replayed) in packets.into_iter().zip(replay_checks) { - let unwrapped_packet = if replayed { + // CRITICAL SECURITY DECISION POINT: Replay Protection Bypass for Network Monitors + // + // This is where we decide whether to enforce replay protection for this packet. + // The decision tree is: + // + // 1. Is packet replayed? (bloomfilter check already completed) + // NO → Process normally (finalise_unwrapping) + // YES → Go to step 2 + // + // 2. Is source IP an authorised network monitor? + // YES → BYPASS replay protection, process packet normally + // NO → DROP packet, increment metrics, log warning + // + // Why we allow network monitors to replay: + // - They need to be able to generate high volumes of packets in short bursts + // - Authorisation is on-chain and strictly controlled + // + // All bypass activity is tracked via `ingress_network_monitor_packet` metric. + let network_monitor_packet = self.is_from_authorised_network_monitor_agent(); + if replayed && !network_monitor_packet { replays_detected += 1; warn!( event = "packet.dropped.replay", @@ -454,12 +525,18 @@ impl ConnectionHandler { rotation_id, "dropping replayed packet" ); - Err(PacketProcessingError::PacketReplay) - } else { - packet.finalise_unwrapping() - }; + self.handle_unwrapped_packet( + now, + Err(PacketProcessingError::PacketReplay), + network_monitor_packet, + ) + .await; + continue; + } - self.handle_unwrapped_packet(now, unwrapped_packet).await; + let unwrapped_packet = packet.finalise_unwrapping(); + self.handle_unwrapped_packet(now, unwrapped_packet, network_monitor_packet) + .await; } } if replays_detected > 0 { @@ -551,7 +628,10 @@ impl ConnectionHandler { packet: FramedNymPacket, ) { let unwrapped_packet = self.try_full_unwrap_packet(packet); - self.handle_unwrapped_packet(now, unwrapped_packet).await; + + let is_network_monitor_packet = self.is_from_authorised_network_monitor_agent(); + self.handle_unwrapped_packet(now, unwrapped_packet, is_network_monitor_packet) + .await; } #[instrument(skip(self, packet), level = "debug")] diff --git a/nym-node/src/node/mixnet/packet_forwarding/mod.rs b/nym-node/src/node/mixnet/packet_forwarding/mod.rs index dc8d4af7d4..7b87e546ba 100644 --- a/nym-node/src/node/mixnet/packet_forwarding/mod.rs +++ b/nym-node/src/node/mixnet/packet_forwarding/mod.rs @@ -89,7 +89,10 @@ impl PacketForwarder { { let next_hop = new_packet.packet.next_hop(); - if !self.routing_filter.should_route(next_hop.as_ref().ip()) { + if !self + .routing_filter + .should_route(next_hop.as_ref().ip(), new_packet.network_monitor_packet) + { warn!( event = "packet.dropped.routing_filter", next_hop = %next_hop, diff --git a/nym-node/src/node/mixnet/shared/mod.rs b/nym-node/src/node/mixnet/shared/mod.rs index 19b15d9116..cbe3418d6a 100644 --- a/nym-node/src/node/mixnet/shared/mod.rs +++ b/nym-node/src/node/mixnet/shared/mod.rs @@ -6,6 +6,7 @@ use crate::node::key_rotation::active_keys::ActiveSphinxKeys; use crate::node::mixnet::SharedFinalHopData; use crate::node::mixnet::handler::ConnectionHandler; use crate::node::replay_protection::bloomfilter::ReplayProtectionBloomfilters; +use crate::node::routing_filter::network_filter::RoutableNetworkMonitors; use nym_gateway::node::GatewayStorageError; use nym_mixnet_client::forwarder::{MixForwardingSender, PacketToForward}; use nym_node_metrics::NymNodeMetrics; @@ -66,7 +67,9 @@ impl ProcessingConfig { // explicitly do NOT derive clone as we want the childs to use CHILD shutdown tokens pub(crate) struct SharedData { pub(super) processing_config: ProcessingConfig, + pub(super) sphinx_keys: ActiveSphinxKeys, + pub(super) replay_protection_filter: ReplayProtectionBloomfilters, // used for FORWARD mix packets and FINAL ack packets @@ -80,6 +83,10 @@ pub(crate) struct SharedData { pub(super) metrics: NymNodeMetrics, + // list of all known network monitor agents that are permitted + // to forward packets even if they replay them + pub(super) authorised_network_monitor_agents: RoutableNetworkMonitors, + pub(super) shutdown_token: ShutdownToken, } @@ -100,6 +107,7 @@ impl SharedData { final_hop: SharedFinalHopData, noise_config: NoiseConfig, metrics: NymNodeMetrics, + authorised_network_monitor_agents: RoutableNetworkMonitors, shutdown_token: ShutdownToken, ) -> Self { SharedData { @@ -110,6 +118,7 @@ impl SharedData { final_hop, noise_config, metrics, + authorised_network_monitor_agents, shutdown_token, } } @@ -136,11 +145,23 @@ impl SharedData { processing_result: &Result, source: IpAddr, ) { - let Ok(processing_result) = processing_result else { - self.metrics.mixnet.ingress_malformed_packet(source); - return; + let processing_result = match processing_result { + Ok(processing_result) => processing_result, + Err(err) => { + if err.is_replay() { + self.metrics.mixnet.ingress_replayed_packet(source); + } else { + self.metrics.mixnet.ingress_malformed_packet(source); + } + + return; + } }; + if self.authorised_network_monitor_agents.is_known(&source) { + self.metrics.mixnet.ingress_network_monitor_packet(); + } + let packet_version = convert_to_metrics_version(processing_result.packet_version); match processing_result.processing_data { @@ -184,11 +205,20 @@ impl SharedData { } } - pub(super) fn forward_mix_packet(&self, packet: MixPacket, delay_until: Option) { + pub(super) fn forward_mix_packet( + &self, + packet: MixPacket, + delay_until: Option, + network_monitor_packet: bool, + ) { let has_delay = delay_until.is_some(); if self .mixnet_forwarder - .forward_packet(PacketToForward::new(packet, delay_until)) + .forward_packet(PacketToForward::new( + packet, + delay_until, + network_monitor_packet, + )) .is_err() && !self.shutdown_token.is_cancelled() { @@ -203,7 +233,7 @@ impl SharedData { pub(super) fn forward_ack_packet(&self, forward_ack: Option) { if let Some(forward_ack) = forward_ack { - self.forward_mix_packet(forward_ack, None); + self.forward_mix_packet(forward_ack, None, false); self.metrics.mixnet.egress_sent_ack(); } } diff --git a/nym-node/src/node/mod.rs b/nym-node/src/node/mod.rs index 7f857f3a5b..af1a511c96 100644 --- a/nym-node/src/node/mod.rs +++ b/nym-node/src/node/mod.rs @@ -23,6 +23,7 @@ use crate::node::key_rotation::active_keys::ActiveSphinxKeys; use crate::node::key_rotation::controller::KeyRotationController; use crate::node::key_rotation::manager::SphinxKeyManager; use crate::node::lp::LpSetup; +use crate::node::lp::directory::LpNodes; use crate::node::metrics::aggregator::MetricsAggregator; use crate::node::metrics::console_logger::ConsoleLogger; use crate::node::metrics::handler::client_sessions::GatewaySessionStatsHandler; @@ -34,16 +35,21 @@ use crate::node::mixnet::SharedFinalHopData; use crate::node::mixnet::packet_forwarding::PacketForwarder; use crate::node::mixnet::shared::ProcessingConfig; use crate::node::nym_apis_client::NymApisClient; +use crate::node::nyxd_watcher::network_monitor_agents::NetworkMonitorAgentsModule; use crate::node::replay_protection::background_task::ReplayProtectionDiskFlush; use crate::node::replay_protection::bloomfilter::ReplayProtectionBloomfilters; use crate::node::replay_protection::manager::ReplayProtectionBloomfiltersManager; +use crate::node::routing_filter::network_filter::{NetworkRoutingFilter, RoutableNetworkMonitors}; use crate::node::routing_filter::{OpenFilter, RoutingFilter}; -use crate::node::shared_network::{ - CachedNetwork, CachedTopologyProvider, LocalGatewayNode, NetworkRefresher, -}; +use crate::node::shared_network::CachedNetwork; +use crate::node::shared_network::refresher::{NetworkRefresher, NetworkRefresherConfig}; +use crate::node::shared_network::topology_provider::{CachedTopologyProvider, LocalGatewayNode}; use nym_bin_common::bin_info; +use nym_config::defaults::NymNetworkDetails; use nym_credential_verification::UpgradeModeState; use nym_crypto::asymmetric::{ed25519, x25519}; +pub use nym_gateway::node::ActiveClientsStore; +pub use nym_gateway::node::GatewayStorage; use nym_gateway::node::wireguard::PeerRegistrator; use nym_gateway::node::{GatewayTasksBuilder, UpgradeModeCheckRequestSender}; use nym_kkt::key_utils::{ @@ -63,31 +69,30 @@ use nym_node_metrics::events::MetricEventsSender; use nym_node_requests::api::SignedData; use nym_node_requests::api::v1::lewes_protocol::models::{LPHashFunction, LPKEM, LewesProtocol}; use nym_node_requests::api::v1::node::models::{AnnouncePorts, NodeDescription}; -use nym_noise::config::{NoiseConfig, NoiseNetworkView}; +use nym_noise::config::{NetworkMonitorAgentNode, NoiseConfig, NoiseNetworkView}; use nym_noise_keys::VersionedNoiseKeyV1; use nym_sphinx_acknowledgements::AckKey; use nym_sphinx_addressing::Recipient; use nym_task::{ShutdownManager, ShutdownToken, ShutdownTracker}; -use nym_validator_client::UserAgent; +use nym_validator_client::nyxd::contract_traits::PagedNetworkMonitorsQueryClient; +use nym_validator_client::nyxd::nym_network_monitors_contract_common::AuthorisedNetworkMonitor; +use nym_validator_client::{QueryHttpRpcNyxdClient, UserAgent}; use nym_verloc::measurements::SharedVerlocStats; use nym_verloc::{self, measurements::VerlocMeasurer}; use nym_wireguard::{WireguardGatewayData, peer_controller::PeerControlRequest}; +use nyxd_scraper_shared::watcher::{NyxdWatcher, WatcherConfig}; use rand::rngs::OsRng; use rand::{CryptoRng, RngCore}; use rand09::SeedableRng; -use std::collections::BTreeMap; -use std::net::SocketAddr; +use std::collections::{BTreeMap, HashMap, HashSet}; +use std::net::{IpAddr, SocketAddr}; use std::ops::Deref; use std::path::Path; use std::sync::Arc; use tokio::sync::mpsc; -use tracing::{debug, info, trace}; +use tracing::{debug, error, info, trace}; use zeroize::Zeroizing; -use crate::node::lp::directory::LpNodes; -pub use nym_gateway::node::ActiveClientsStore; -pub use nym_gateway::node::GatewayStorage; - pub mod bonding_information; pub mod description; pub mod helpers; @@ -97,6 +102,7 @@ pub mod lp; pub(crate) mod metrics; pub(crate) mod mixnet; mod nym_apis_client; +mod nyxd_watcher; pub(crate) mod replay_protection; mod routing_filter; mod shared_network; @@ -391,6 +397,8 @@ pub struct NymNode { accepted_operator_terms_and_conditions: bool, shutdown_manager: ShutdownManager, + network: NymNetworkDetails, + description: NodeDescription, metrics: NymNodeMetrics, @@ -434,7 +442,7 @@ impl NymNode { let mceliece = generate_keypair_mceliece(&mut rng09); let current_rotation_id = - get_current_rotation_id(&config.mixnet.nym_api_urls, &config.mixnet.nyxd_urls).await?; + get_current_rotation_id(&config.mixnet.nym_api_urls, &config.nyx.nyxd_urls).await?; let _ = SphinxKeyManager::initialise_new( &mut rng, current_rotation_id, @@ -512,7 +520,7 @@ impl NymNode { pub(crate) async fn new(config: Config) -> Result { let wireguard_data = WireguardData::new(&config.wireguard)?; let current_rotation_id = - get_current_rotation_id(&config.mixnet.nym_api_urls, &config.mixnet.nyxd_urls).await?; + get_current_rotation_id(&config.mixnet.nym_api_urls, &config.nyx.nyxd_urls).await?; let ed25519_identity_keys = load_ed25519_identity_keypair( &config.storage_paths.keys.ed25519_identity_storage_paths(), @@ -549,6 +557,7 @@ impl NymNode { shutdown_manager: ShutdownManager::build_new_default() .map_err(|source| NymNodeError::ShutdownSignalFailure { source })?, x25519_lp_keys: Arc::new(x25519_lp_keys), + network: NymNetworkDetails::new_from_env(), }) } @@ -638,11 +647,13 @@ impl NymNode { Ok(self.sphinx_keys()?.keys.clone()) } - async fn build_network_refresher(&self) -> Result { - NetworkRefresher::initialise_new( - self.config.debug.testnet, - Self::user_agent(), - self.config.mixnet.nym_api_urls.clone(), + async fn build_network_refresher( + &self, + routing_filter: NetworkRoutingFilter, + client: NymApisClient, + noise_view: NoiseNetworkView, + ) -> Result { + let config = NetworkRefresherConfig::new( self.config.debug.topology_cache_ttl, self.config.debug.routing_nodes_check_interval, self.config @@ -650,6 +661,12 @@ impl NymNode { .debug .maximum_initial_topology_waiting_time, self.config.gateway_tasks.debug.minimum_mix_performance, + ); + NetworkRefresher::initialise_new( + config, + client, + routing_filter, + noise_view, self.shutdown_manager.clone_shutdown_token(), ) .await @@ -706,6 +723,7 @@ impl NymNode { let mut gateway_tasks_builder = GatewayTasksBuilder::new( config.gateway, + self.network.clone(), self.ed25519_identity_keys.clone(), self.entry_gateway.client_storage.clone(), mix_packet_sender.clone(), @@ -1240,6 +1258,7 @@ impl NymNode { active_clients_store: &ActiveClientsStore, replay_protection_bloomfilter: ReplayProtectionBloomfilters, routing_filter: F, + authorised_network_monitor_agents: RoutableNetworkMonitors, noise_config: NoiseConfig, ) -> Result<(MixForwardingSender, ActiveConnections), NymNodeError> where @@ -1295,6 +1314,7 @@ impl NymNode { final_hop_data, noise_config, self.metrics.clone(), + authorised_network_monitor_agents, self.shutdown_token(), ); @@ -1321,6 +1341,7 @@ impl NymNode { &ActiveClientsStore::new(), ReplayProtectionBloomfilters::new_disabled(), OpenFilter, + RoutableNetworkMonitors::default(), noise_config, ) .await?; @@ -1331,6 +1352,56 @@ impl NymNode { Ok(()) } + async fn known_network_monitors(&self) -> Result, NymNodeError> { + // 1. create a nyx rpc client + // (TODO: we should have unified client later on for all chain interactions) + let client = QueryHttpRpcNyxdClient::connect_with_network_details( + self.config.nyx.nyxd_urls[0].as_str(), + self.network.clone(), + )?; + + // 2. run the queries to retrieve all agents + Ok(client.get_all_network_monitor_agents().await?) + } + + async fn setup_nyx_chain_watcher( + &self, + network_monitors_handle: RoutableNetworkMonitors, + noise_network_view: NoiseNetworkView, + ) -> Result<(), NymNodeError> { + // START: module creation + let Some(Ok(contract_address)) = self + .network + .contracts + .network_monitors_contract_address + .as_ref() + .map(|addr| addr.parse()) + else { + // **THEORETICALLY** this should be impossible, for we have already created a nyxd client and + // queried this very contract before + return Err(NymNodeError::MissingNetworkMonitorsContractAddress); + }; + let nm_agents = NetworkMonitorAgentsModule::new( + contract_address, + network_monitors_handle, + noise_network_view, + ); + + // END: module creation + let cancellation = self.shutdown_manager.clone_shutdown_token(); + + let config = WatcherConfig { + websocket_url: self.config.nyx.nyxd_websocket_url.clone(), + rpc_url: self.config.nyx.nyxd_urls[0].clone(), + }; + let watcher = NyxdWatcher::builder(config) + .with_msg_module(nm_agents) + .with_custom_shutdown(cancellation.to_cancellation_token()); + + watcher.build_and_start().await?; + Ok(()) + } + async fn start_nym_node_tasks(mut self) -> Result { info!( "starting Nym Node {} with the following modes: mixnode: {}, entry: {}, exit: {}, wireguard: {}", @@ -1342,6 +1413,7 @@ impl NymNode { ); debug!("config: {:#?}", self.config); + // ##### START HTTP SERVER ##### let http_server = self.build_http_server().await?; let bind_address = self.config.http.bind_address; let server_shutdown = self.shutdown_manager.clone_shutdown_token(); @@ -1355,31 +1427,87 @@ impl NymNode { }, "HttpApi", ); + // ##### END HTTP SERVER ##### + // shared client for querying nym-apis let nym_apis_client = self.setup_nym_apis_client()?; + // announce current sphinx key to all nym apis self.try_refresh_remote_nym_api_cache(&nym_apis_client) .await?; + + // start verloc self.start_verloc_measurements(); - let network_refresher = self.build_network_refresher().await?; + // obtain the initial list of known network monitors + let known_network_monitors = self.known_network_monitors().await?; + + let mut known_network_monitor_ips = HashSet::new(); + let mut known_network_monitor_nodes: HashMap> = + HashMap::new(); + for agent in known_network_monitors { + let Ok(x25519_pubkey) = x25519::PublicKey::from_base58_string(&agent.bs58_x25519_noise) + else { + error!( + "network monitor agent {} has announced an invalid noise key - ignoring", + agent.mixnet_address + ); + continue; + }; + + let ip = agent.mixnet_address.ip(); + known_network_monitor_ips.insert(ip); + + let entry = known_network_monitor_nodes.entry(ip).or_default(); + entry.push(NetworkMonitorAgentNode { + port: agent.mixnet_address.port(), + key: VersionedNoiseKeyV1 { + supported_version: agent.noise_version.into(), + x25519_pubkey, + }, + }) + } + + // build routing filter + let routing_filter = NetworkRoutingFilter::new_empty(self.config.debug.testnet) + .with_known_network_monitors(known_network_monitor_ips); + let network_monitors_ref = routing_filter.known_network_monitors_handle(); + + let noise_view = NoiseNetworkView::new_with_agents(known_network_monitor_nodes); + // retrieve the initial view of the network and update the known set of nym nodes in the routing filter + let network_refresher = self + .build_network_refresher( + routing_filter.clone(), + nym_apis_client.clone(), + noise_view.clone(), + ) + .await?; + + // setup nyx chain watcher (currently only used for updating the network monitors view) + self.setup_nyx_chain_watcher(network_monitors_ref, noise_view.clone()) + .await?; + let active_clients_store = ActiveClientsStore::new(); let lp_nodes = network_refresher.lp_nodes(); + // start building a replay detection manager (bloomfilters, etc.) let bloomfilters_manager = self.setup_replay_detection().await?; - let noise_config = nym_noise::config::NoiseConfig::new( + let noise_config = NoiseConfig::new( self.x25519_noise_keys.clone(), - network_refresher.noise_view(), + noise_view, self.config.mixnet.debug.initial_connection_timeout, ) .with_unsafe_disabled(self.config.mixnet.debug.unsafe_disable_noise); + // start the listener for the mixnet packet(s) + let authorised_network_monitor_agents = routing_filter.known_network_monitors_handle(); let (mix_packet_sender, active_egress_mixnet_connections) = self .start_mixnet_listener( &active_clients_store, bloomfilters_manager.bloomfilters(), - network_refresher.routing_filter(), + routing_filter, + authorised_network_monitor_agents, noise_config, ) .await?; @@ -1392,6 +1520,7 @@ impl NymNode { let network = network_refresher.cached_network(); network_refresher.start(); + // setup all gateway-related tasks (client websocket, wireguard, lp, etc.) self.start_gateway_tasks( network, lp_nodes, @@ -1401,6 +1530,7 @@ impl NymNode { ) .await?; + // start watching for key rotation and update the keys accordingly self.setup_key_rotation(nym_apis_client, bloomfilters_manager) .await?; diff --git a/nym-node/src/node/nym_apis_client.rs b/nym-node/src/node/nym_apis_client.rs index f9d97a93d9..92d0e4dfcf 100644 --- a/nym-node/src/node/nym_apis_client.rs +++ b/nym-node/src/node/nym_apis_client.rs @@ -1,4 +1,4 @@ -// Copyright 2025 - Nym Technologies SA +// Copyright 2025-2026 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only use crate::error::NymNodeError; @@ -7,16 +7,19 @@ use futures::{StreamExt, stream}; use nym_crypto::asymmetric::ed25519; use nym_http_api_client::Client; use nym_task::ShutdownToken; +use nym_topology::EpochRewardedSet; use nym_validator_client::client::NymApiClientExt; use nym_validator_client::models::{KeyRotationInfoResponse, NodeRefreshBody}; use nym_validator_client::nym_api::error::NymAPIError; +use nym_validator_client::nym_api::{NodesByAddressesResponse, SemiSkimmedNodesWithMetadata}; use rand::prelude::SliceRandom; use rand::thread_rng; +use std::net::IpAddr; use std::sync::Arc; use std::time::Duration; -use tokio::sync::RwLock; +use tokio::sync::{RwLock, RwLockReadGuard}; use tokio::time::sleep; -use tracing::{debug, warn}; +use tracing::{debug, error, warn}; use url::Url; #[derive(Clone)] @@ -60,17 +63,9 @@ impl NymApisClient { }) } - // async fn use_next_endpoint(&self) { - // let mut guard = self.inner.write().await; - // if guard.available_urls.len() == 1 { - // return; - // } - // - // let next_index = (guard.currently_used_api + 1) % guard.available_urls.len(); - // let next = guard.available_urls[next_index].clone(); - // guard.currently_used_api = next_index; - // guard.active_client.change_nym_api(next) - // } + async fn active_client(&self) -> RwLockReadGuard<'_, Client> { + RwLockReadGuard::map(self.inner.read().await, |inner| &inner.active_client) + } pub(crate) async fn query_exhaustively( &self, @@ -122,6 +117,38 @@ impl NymApisClient { ) .await } + + // non-critical best-effort queries to the current available endpoint: + + pub(crate) async fn rewarded_set(&mut self) -> Result { + self.active_client() + .await + .get_current_rewarded_set() + .await + .inspect_err(|err| error!("failed to get current rewarded set: {err}")) + .map(Into::into) + } + + pub(crate) async fn current_nymnodes( + &mut self, + ) -> Result { + self.active_client() + .await + .get_all_expanded_nodes() + .await + .inspect_err(|err| error!("failed to get network nodes: {err}")) + } + + pub(crate) async fn query_nym_nodes_addresses( + &mut self, + ips: Vec, + ) -> Result { + self.active_client() + .await + .nodes_by_addresses(ips) + .await + .inspect_err(|err| error!("failed to obtain node information: {err}")) + } } impl InnerClient { diff --git a/nym-node/src/node/nyxd_watcher/mod.rs b/nym-node/src/node/nyxd_watcher/mod.rs new file mode 100644 index 0000000000..47b0749bbe --- /dev/null +++ b/nym-node/src/node/nyxd_watcher/mod.rs @@ -0,0 +1,4 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +pub(crate) mod network_monitor_agents; diff --git a/nym-node/src/node/nyxd_watcher/network_monitor_agents.rs b/nym-node/src/node/nyxd_watcher/network_monitor_agents.rs new file mode 100644 index 0000000000..dfdaa208de --- /dev/null +++ b/nym-node/src/node/nyxd_watcher/network_monitor_agents.rs @@ -0,0 +1,295 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +//! Real-time blockchain watcher for Network Monitor agents changes. +//! +//! This module processes blockchain transactions involving the Network Monitors smart contract +//! and automatically updates the list of authorised network monitor agents whenever it is invoked. +//! +//! # Authorisation Flow +//! +//! 1. Network Monitor orchestrator submits `AuthoriseNetworkMonitor { address }` to the contract +//! 2. Transaction is committed to Nyx blockchain +//! 3. This module receives the message via `MsgModule::handle_msg()` +//! 4. The IP address is added to `DeclaredNetworkMonitors` (lock-free via ArcSwap) +//! 5. Future packets from that IP can bypass replay protection until revoked +//! +//! # Security +//! +//! Only transactions executed against the configured Network Monitors contract address are +//! processed. + +use crate::node::routing_filter::network_filter::RoutableNetworkMonitors; +use async_trait::async_trait; +use nym_crypto::asymmetric::x25519; +use nym_noise::config::{NetworkMonitorAgentNode, NoiseNetworkView, NoiseNode}; +use nym_noise_keys::{NoiseVersion, VersionedNoiseKeyV1}; +use nym_validator_client::nyxd::cosmwasm::MsgExecuteContract; +use nym_validator_client::nyxd::nym_network_monitors_contract_common::ExecuteMsg; +use nym_validator_client::nyxd::{AccountId, Any, Msg, Name}; +use nyxd_scraper_shared::error::ScraperError; +use nyxd_scraper_shared::{DecodedMessage, MsgModule, ParsedTransactionDetails, parse_msg}; +use std::net::SocketAddr; +use tracing::{debug, error, info, warn}; + +/// Blockchain message handler for Network Monitor agent authorisation events. +/// +/// Watches for `MsgExecuteContract` messages targeting the Network Monitors smart contract +/// and updates the runtime list of authorised agents accordingly. +pub(crate) struct NetworkMonitorAgentsModule { + /// The on-chain address of the Network Monitors smart contract. + /// Only messages to this contract are processed. + pub(crate) contract_address: AccountId, + + /// Shared handle to the runtime list of authorised network monitor IPs. + /// Updates are immediately visible to all packet processing threads. + pub(crate) routable_network_monitors: RoutableNetworkMonitors, + + /// Shared handle to the runtime list of noise keys of all network nodes + pub(crate) noise_view: NoiseNetworkView, +} + +impl NetworkMonitorAgentsModule { + pub(crate) fn new( + contract_address: AccountId, + routable_network_monitors: RoutableNetworkMonitors, + noise_view: NoiseNetworkView, + ) -> Self { + Self { + contract_address, + routable_network_monitors, + noise_view, + } + } + + /// Register a newly authorised NM agent in both the routing filter and the noise key map. + async fn new_agent( + &mut self, + address: SocketAddr, + bs58_x25519_noise: String, + noise_version: u8, + ) { + debug!("adding new NM agent {address}"); + + let Ok(x25519_pubkey) = x25519::PublicKey::from_base58_string(&bs58_x25519_noise) else { + error!("network monitor agent {address} has announced an invalid noise key - ignoring"); + return; + }; + + let key = VersionedNoiseKeyV1 { + supported_version: NoiseVersion::from(noise_version), + x25519_pubkey, + }; + + // add ip to the routing filter (it's a no-op if it already exists) + self.routable_network_monitors.add_known(address.ip()); + + // add noise key to the known nodes + let update_permit = self.noise_view.get_update_permit().await; + let mut nodes = self.noise_view.all_nodes(); + // canonicalise so lookups via supports_noise (which canonicalises) always match + let ip = address.ip().to_canonical(); + let port = address.port(); + + match nodes.get_mut(&ip) { + None => { + nodes.insert(ip, NoiseNode::new_agent(address, key)); + } + Some(existing_entry) => match existing_entry { + NoiseNode::NymNode { .. } => { + error!( + "the authorised agent runs on the same host as a known nym-node! ignoring" + ); + } + NoiseNode::NetworkMonitorAgent { nodes } => { + if let Some(existing) = nodes.iter_mut().find(|n| n.port == address.port()) { + existing.key = key; + } else { + nodes.push(NetworkMonitorAgentNode { port, key }); + } + } + }, + } + + self.noise_view.swap_view(update_permit, nodes); + } + + async fn revoked_agent(&mut self, address: SocketAddr) { + debug!("revoking NM agent {address}"); + + // canonicalise to match the stored representation + let ip = address.ip().to_canonical(); + + let update_permit = self.noise_view.get_update_permit().await; + let mut nodes = self.noise_view.all_nodes(); + + let mut final_agent = false; + match nodes.get_mut(&ip) { + None => { + warn!("attempted to revoke a non-existent agent at {address}"); + return; + } + Some(node) => match node { + NoiseNode::NymNode { .. } => { + error!( + "the revoked agent runs on the same host as a known nym-node! ignoring the revocation" + ); + return; + } + NoiseNode::NetworkMonitorAgent { nodes } => { + nodes.retain(|agent| agent.port != address.port()); + if nodes.is_empty() { + final_agent = true; + } + } + }, + } + + if final_agent { + nodes.remove(&ip); + self.routable_network_monitors.remove_known(ip); + } + self.noise_view.swap_view(update_permit, nodes); + } + + async fn revoked_all_agents(&mut self) { + info!("revoking all NM agents"); + + self.routable_network_monitors.reset(); + + // remove all noise keys from the known nodes + let update_permit = self.noise_view.get_update_permit().await; + let mut nodes = self.noise_view.all_nodes(); + + // Only remove NM agent entries; nym-node entries must be preserved because they are + // managed by a completely separate code path (the nym-api topology refresher) and + // would not be restored until the next full topology refresh cycle. + nodes.retain(|_, node| node.is_nym_node()); + self.noise_view.swap_view(update_permit, nodes); + } +} + +#[async_trait] +impl MsgModule for NetworkMonitorAgentsModule { + // we're only interested in contract messages + fn type_url(&self) -> String { + ::Proto::type_url() + } + + async fn handle_msg( + &mut self, + _: usize, + msg: &Any, + _: &DecodedMessage, + tx: &ParsedTransactionDetails, + ) -> Result<(), ScraperError> { + // don't process failed transactions + if !tx.tx_result.code.is_ok() { + return Ok(()); + } + + // propagate error as this is a critical failure indicating our code is incompatible with + // the current CometBFT schema so parsing can't proceed + let execute_msg: MsgExecuteContract = parse_msg(msg)?; + + // not the contract we're interested in + if execute_msg.contract != self.contract_address { + return Ok(()); + } + + let exec_msg: ExecuteMsg = match serde_json::from_slice(&execute_msg.msg) { + Ok(msg) => msg, + Err(err) => { + // do NOT propagate error. this just means the contract might have updated. + // further block processing should continue + error!( + "failed to parse out network monitors contract ExecuteMsg - has the contact schema been updated? error was: {err}" + ); + return Ok(()); + } + }; + + match exec_msg { + ExecuteMsg::AuthoriseNetworkMonitor { + mixnet_address, + bs58_x25519_noise, + noise_version, + } => { + self.new_agent(mixnet_address, bs58_x25519_noise, noise_version) + .await + } + ExecuteMsg::RevokeNetworkMonitor { address } => self.revoked_agent(address).await, + ExecuteMsg::RevokeAllNetworkMonitors => self.revoked_all_agents().await, + + // we're not interested in those messages + ExecuteMsg::UpdateAdmin { .. } + | ExecuteMsg::AuthoriseNetworkMonitorOrchestrator { .. } + | ExecuteMsg::RevokeNetworkMonitorOrchestrator { .. } + | ExecuteMsg::UpdateOrchestratorIdentityKey { .. } => {} + } + + Ok(()) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use nym_crypto::asymmetric::x25519; + use nym_test_utils::helpers::deterministic_rng; + use std::net::{IpAddr, Ipv4Addr}; + + fn module() -> NetworkMonitorAgentsModule { + NetworkMonitorAgentsModule::new( + "n1pefc2utwpy5w78p2kqdsfmpjxfwmn9d39k5mqa".parse().unwrap(), + RoutableNetworkMonitors::default(), + NoiseNetworkView::new_empty(), + ) + } + + // Regression: an agent registered via blockchain events must end up keyed in the noise map + // under the **canonical** IP form, so the responder's `supports_noise` (which canonicalises + // on lookup) finds it regardless of whether the inbound socket presents plain IPv4 or the + // v4-mapped IPv6 form. Before the fix, `new_agent` inserted `address.ip()` raw, leaving the + // map keyed on a non-canonical IPv4-mapped IPv6 address whenever the contract submission used + // that form, while the routing filter (which canonicalises on both sides) accepted the + // packet — producing the "can't speak Noise yet, falling back to TCP" warning. + #[tokio::test] + async fn new_agent_stores_under_canonical_ip() { + let mut module = module(); + let pubkey = x25519::PublicKey::from(&x25519::PrivateKey::new(&mut deterministic_rng())); + let bs58 = pubkey.to_base58_string(); + + let v4 = IpAddr::V4(Ipv4Addr::new(1, 2, 3, 4)); + let v6_mapped = IpAddr::V6(Ipv4Addr::new(1, 2, 3, 4).to_ipv6_mapped()); + + // register agent using v4-mapped IPv6 form (the form that triggered the bug) + module + .new_agent(SocketAddr::new(v6_mapped, 39322), bs58, 1) + .await; + + let stored = module.noise_view.all_nodes(); + // the stored key must be canonical so canonical-form lookups succeed + assert!( + stored.contains_key(&v4), + "noise map must contain the canonical IPv4 key, got: {:?}", + stored.keys().collect::>() + ); + } + + // Counterpart: same invariant when the contract submission already used plain IPv4 — the + // map should still be keyed on the canonical form (which for plain IPv4 is itself). + #[tokio::test] + async fn new_agent_stores_under_canonical_ip_for_plain_v4_input() { + let mut module = module(); + let pubkey = x25519::PublicKey::from(&x25519::PrivateKey::new(&mut deterministic_rng())); + let bs58 = pubkey.to_base58_string(); + + let v4 = IpAddr::V4(Ipv4Addr::new(1, 2, 3, 4)); + + module.new_agent(SocketAddr::new(v4, 39322), bs58, 1).await; + + let stored = module.noise_view.all_nodes(); + assert!(stored.contains_key(&v4)); + } +} diff --git a/nym-node/src/node/routing_filter/mod.rs b/nym-node/src/node/routing_filter/mod.rs index 751ff2bc58..38fd205dfb 100644 --- a/nym-node/src/node/routing_filter/mod.rs +++ b/nym-node/src/node/routing_filter/mod.rs @@ -6,14 +6,14 @@ use std::net::IpAddr; pub(crate) mod network_filter; pub(crate) trait RoutingFilter { - fn should_route(&self, ip: IpAddr) -> bool; + fn should_route(&self, ip: IpAddr, is_network_monitor_packet: bool) -> bool; } #[derive(Debug, Copy, Clone, Default)] pub(crate) struct OpenFilter; impl RoutingFilter for OpenFilter { - fn should_route(&self, _: IpAddr) -> bool { + fn should_route(&self, _: IpAddr, _: bool) -> bool { true } } diff --git a/nym-node/src/node/routing_filter/network_filter.rs b/nym-node/src/node/routing_filter/network_filter.rs index 274015f784..ec9e692f5a 100644 --- a/nym-node/src/node/routing_filter/network_filter.rs +++ b/nym-node/src/node/routing_filter/network_filter.rs @@ -10,13 +10,14 @@ use std::sync::Arc; use tokio::sync::RwLock; impl RoutingFilter for NetworkRoutingFilter { - fn should_route(&self, ip: IpAddr) -> bool { + fn should_route(&self, ip: IpAddr, is_network_monitor_packet: bool) -> bool { // only allow non-global ips on testnets if self.testnet_mode && !is_global_ip(&ip) { return true; } - self.attempt_resolve(ip).should_route() + self.attempt_resolve(ip, is_network_monitor_packet) + .should_route() } } @@ -40,26 +41,72 @@ impl NetworkRoutingFilter { } } - pub(crate) fn attempt_resolve(&self, ip: IpAddr) -> Resolution { - if self.resolved.inner.allowed.load().contains(&ip) { + #[must_use] + pub(crate) fn with_known_network_monitors( + mut self, + known_network_monitors: HashSet, + ) -> Self { + self.resolved.network_monitors = RoutableNetworkMonitors::new(known_network_monitors); + self + } + + pub(crate) fn known_network_monitors_handle(&self) -> RoutableNetworkMonitors { + self.resolved.network_monitors.clone() + } + + pub(crate) fn attempt_resolve( + &self, + ip: IpAddr, + is_network_monitor_packet: bool, + ) -> Resolution { + // if packet has come from a network monitor it can ONLY go to another network monitor + if is_network_monitor_packet { + return if self.resolved.network_monitors.is_known(&ip) { + Resolution::Accept + } else { + Resolution::Deny + }; + } + + if self.resolved.nym_nodes.inner.allowed.load().contains(&ip) { + // accept any traffic to known and resolved nym-nodes Resolution::Accept - } else if self.resolved.inner.denied.load().contains(&ip) { + } else if self.resolved.nym_nodes.inner.denied.load().contains(&ip) { + // deny any traffic to confirmed non-nym nodes Resolution::Deny + } else if self.resolved.network_monitors.is_known(&ip) { + // accept any traffic to known network monitors + Resolution::Accept } else { + // put any unknown destinations into resolution queue self.pending.try_insert(ip); Resolution::Unknown } } pub(crate) fn allowed_nodes_copy(&self) -> HashSet { - self.resolved.inner.allowed.load_full().as_ref().clone() + self.resolved.nym_nodes.clone_allowed() } pub(crate) fn denied_nodes_copy(&self) -> HashSet { - self.resolved.inner.denied.load_full().as_ref().clone() + self.resolved.nym_nodes.clone_denied() } } +/// Temporary queue of IP addresses that need resolution (are they Nym nodes or not?). +/// +/// # Behaviour +/// +/// - Packets from unknown IPs are denied initially and the IP is queued here +/// - A background task periodically processes this queue via nym-api lookups +/// - Once resolved, IPs are moved to either `allowed` or `denied` sets +/// +/// # Lock Strategy +/// +/// Uses `try_insert()` to avoid blocking the packet processing path: +/// - If lock is immediately available: insert the IP +/// - If lock is contended: skip insertion, will retry on next packet from same IP +/// - This is acceptable because resolution happens periodically anyway #[derive(Clone, Default)] pub(crate) struct UnknownNodes(Arc>>); @@ -84,17 +131,125 @@ impl UnknownNodes { // for now we don't care about keys, etc. // we only want to know if given ip belongs to a known node -#[derive(Debug, Default, Clone)] +#[derive(Debug, Clone, Default)] pub(crate) struct KnownNodes { - inner: Arc, + nym_nodes: KnownNymNodes, + network_monitors: RoutableNetworkMonitors, +} + +impl KnownNodes { + pub(crate) fn swap_allowed(&self, new: HashSet) { + self.nym_nodes.swap_allowed(new) + } + + pub(crate) fn swap_denied(&self, new: HashSet) { + self.nym_nodes.swap_denied(new) + } +} + +/// Thread-safe, lock-free storage for authorised Network Monitor agents IP addresses. +/// +/// # Concurrency Strategy +/// +/// Uses `ArcSwap` for lock-free reads on the hot path (packet processing). Writes are rare +/// (only when blockchain authorisation events occur) +/// and involve cloning the HashSet, but this is acceptable because: +/// - Network monitor authorisations change extremely infrequently (on orchestrator startup with >5s per block) +/// - Read performance is critical (happens on every packet from unknown IPs) +/// - The HashSet is typically very small (<100 entries) +/// +/// # Cloning +/// +/// Cloning `DeclaredNetworkMonitors` is cheap (only clones the `Arc`), not the underlying data. +#[derive(Clone, Debug, Default)] +pub(crate) struct RoutableNetworkMonitors { + inner: Arc, +} + +impl RoutableNetworkMonitors { + pub(crate) fn new(known: HashSet) -> Self { + // ensure the provided addresses are always canonical + Self { + inner: Arc::new(DeclaredNetworkMonitorsInner { + known: ArcSwap::from_pointee(known.iter().map(IpAddr::to_canonical).collect()), + }), + } + } + + fn swap(&self, new: HashSet) { + self.inner.known.store(Arc::new(new)) + } + + pub(crate) fn add_known(&self, address: IpAddr) { + let to_add = address.to_canonical(); + if self.is_known(&to_add) { + return; + } + let mut known = self.inner.known.load().as_ref().clone(); + known.insert(to_add); + self.swap(known); + } + + pub(crate) fn remove_known(&self, address: IpAddr) { + let to_remove = address.to_canonical(); + if !self.is_known(&to_remove) { + return; + } + let mut known = self.inner.known.load().as_ref().clone(); + known.remove(&to_remove); + self.swap(known); + } + + pub(crate) fn reset(&self) { + self.swap(HashSet::new()) + } + + pub(crate) fn is_known(&self, address: &IpAddr) -> bool { + self.inner.known.load().contains(&address.to_canonical()) + } } #[derive(Debug, Default)] -struct KnownNodesInner { +struct DeclaredNetworkMonitorsInner { + known: ArcSwap>, +} + +#[derive(Clone, Debug, Default)] +struct KnownNymNodes { + inner: Arc, +} + +impl KnownNymNodes { + fn clone_allowed(&self) -> HashSet { + self.inner.allowed.load_full().as_ref().clone() + } + + fn clone_denied(&self) -> HashSet { + self.inner.denied.load_full().as_ref().clone() + } + + fn swap_allowed(&self, new: HashSet) { + self.inner.allowed.store(Arc::new(new)) + } + + fn swap_denied(&self, new: HashSet) { + self.inner.denied.store(Arc::new(new)) + } +} + +#[derive(Debug, Default)] +struct KnownNymNodesInner { allowed: ArcSwap>, denied: ArcSwap>, } +/// Result of attempting to resolve whether an IP address should be allowed to route packets. +/// +/// # Semantics +/// +/// - `Accept`: IP is a known Nym node OR authorised network monitor - route the packet +/// - `Deny`: IP has been confirmed as NOT a Nym node - drop the packet +/// - `Unknown`: IP hasn't been resolved yet - queue for lookup but DENY the packet pub(crate) enum Resolution { Unknown, Deny, @@ -117,12 +272,35 @@ impl Resolution { } } -impl KnownNodes { - pub(crate) fn swap_allowed(&self, new: HashSet) { - self.inner.allowed.store(Arc::new(new)) +#[cfg(test)] +mod tests { + use super::*; + use std::net::SocketAddr; + + #[test] + fn test_canonical_address_init() { + let registered = "80.200.100.60".parse::().unwrap(); + let received = "[::ffff:80.200.100.60]:39322" + .parse::() + .unwrap(); + let mut initial = HashSet::new(); + initial.insert(registered); + + let monitors = RoutableNetworkMonitors::new(initial); + + assert!(monitors.is_known(&received.ip())) } - pub(crate) fn swap_denied(&self, new: HashSet) { - self.inner.denied.store(Arc::new(new)) + #[test] + fn test_canonical_address_add() { + let registered = "80.200.100.60".parse::().unwrap(); + let received = "[::ffff:80.200.100.60]:39322" + .parse::() + .unwrap(); + + let monitors = RoutableNetworkMonitors::new(HashSet::new()); + monitors.add_known(registered); + + assert!(monitors.is_known(&received.ip())) } } diff --git a/nym-node/src/node/shared_network.rs b/nym-node/src/node/shared_network.rs deleted file mode 100644 index d89ad44a1b..0000000000 --- a/nym-node/src/node/shared_network.rs +++ /dev/null @@ -1,446 +0,0 @@ -// Copyright 2024 - Nym Technologies SA -// SPDX-License-Identifier: GPL-3.0-only - -use crate::error::NymNodeError; -use crate::node::key_rotation::active_keys::ActiveSphinxKeys; -use crate::node::lp::directory::LpNodes; -use crate::node::routing_filter::network_filter::NetworkRoutingFilter; -use async_trait::async_trait; -use nym_crypto::asymmetric::ed25519; -use nym_gateway::node::UserAgent; -use nym_http_api_client::Client; -use nym_node_metrics::prometheus_wrapper::{PROMETHEUS_METRICS, PrometheusMetric}; -use nym_noise::config::NoiseNetworkView; -use nym_task::ShutdownToken; -use nym_topology::node::RoutingNode; -use nym_topology::provider_trait::ToTopologyMetadata; -use nym_topology::{ - EntryDetails, EpochRewardedSet, NodeId, NymTopology, NymTopologyMetadata, Role, - TopologyProvider, -}; -use nym_validator_client::ValidatorClientError; -use nym_validator_client::nym_api::NymApiClientExt; -use nym_validator_client::nym_nodes::{ - NodesByAddressesResponse, SemiSkimmedNodeV1, SemiSkimmedNodesWithMetadata, -}; -use std::collections::{HashMap, HashSet}; -use std::net::{IpAddr, SocketAddr}; -use std::ops::Deref; -use std::sync::Arc; -use std::time::Duration; -use tokio::sync::RwLock; -use tokio::time::{Instant, interval, sleep}; -use tracing::log::error; -use tracing::{debug, trace, warn}; -use url::Url; - -const LOCAL_NODE_ID: NodeId = 1234567890; - -struct NodesQuerier { - client: Client, - nym_api_urls: Vec, - currently_used_api: usize, -} - -impl NodesQuerier { - fn use_next_nym_api(&mut self) { - if self.nym_api_urls.len() == 1 { - warn!( - "There's only a single nym API available - it won't be possible to use a different one" - ); - return; - } - - self.currently_used_api = (self.currently_used_api + 1) % self.nym_api_urls.len(); - self.client - .change_base_urls(self.nym_api_urls.iter().map(|u| u.clone().into()).collect()) - } - - async fn rewarded_set(&mut self) -> Result { - let res = self - .client - .get_current_rewarded_set() - .await - .inspect_err(|err| error!("failed to get current rewarded set: {err}")); - - if res.is_err() { - self.use_next_nym_api() - } - Ok(res?.into()) - } - - async fn current_nymnodes( - &mut self, - ) -> Result { - let res = self - .client - .get_all_expanded_nodes() - .await - .inspect_err(|err| error!("failed to get network nodes: {err}")); - - if res.is_err() { - self.use_next_nym_api() - } - Ok(res?) - } - - async fn query_for_info( - &mut self, - ips: Vec, - ) -> Result { - let res = self - .client - .nodes_by_addresses(ips) - .await - .inspect_err(|err| error!("failed to obtain node information: {err}")); - - if res.is_err() { - self.use_next_nym_api() - } - Ok(res?) - } -} - -pub(crate) struct LocalGatewayNode { - pub(crate) active_sphinx_keys: ActiveSphinxKeys, - pub(crate) mix_host: SocketAddr, - pub(crate) identity_key: ed25519::PublicKey, - pub(crate) entry: EntryDetails, -} - -impl LocalGatewayNode { - pub(crate) fn to_routing_node(&self) -> RoutingNode { - RoutingNode { - node_id: LOCAL_NODE_ID, - mix_host: self.mix_host, - entry: Some(self.entry.clone()), - identity_key: self.identity_key, - sphinx_key: self.active_sphinx_keys.primary().deref().x25519_pubkey(), - supported_roles: nym_topology::SupportedRoles { - mixnode: false, - mixnet_entry: true, - mixnet_exit: true, - }, - } - } -} - -#[derive(Clone)] -pub struct CachedTopologyProvider { - gateway_node: Arc, - cached_network: CachedNetwork, - min_mix_performance: u8, -} - -impl CachedTopologyProvider { - pub(crate) fn new( - gateway_node: LocalGatewayNode, - cached_network: CachedNetwork, - min_mix_performance: u8, - ) -> Self { - CachedTopologyProvider { - gateway_node: Arc::new(gateway_node), - cached_network, - min_mix_performance, - } - } -} - -#[async_trait] -impl TopologyProvider for CachedTopologyProvider { - async fn get_new_topology(&mut self) -> Option { - let self_node = self.gateway_node.identity_key; - - let mut topology = self - .cached_network - .network_topology(self.min_mix_performance) - .await; - - if !topology.has_node(self.gateway_node.identity_key) { - debug!("{self_node} didn't exist in topology. inserting it.",); - topology.insert_node_details(self.gateway_node.to_routing_node()); - } - topology.force_set_active(LOCAL_NODE_ID, Role::EntryGateway); - - Some(topology) - } -} - -#[derive(Clone)] -pub(crate) struct CachedNetwork { - inner: Arc>, -} - -impl CachedNetwork { - fn new_empty() -> Self { - CachedNetwork { - inner: Arc::new(RwLock::new(CachedNetworkInner { - rewarded_set: Default::default(), - topology_metadata: Default::default(), - network_nodes: vec![], - })), - } - } - - async fn network_topology(&self, min_mix_performance: u8) -> NymTopology { - let network_guard = self.inner.read().await; - - NymTopology::new( - network_guard.topology_metadata, - network_guard.rewarded_set.clone(), - Vec::new(), - ) - .with_additional_nodes( - network_guard - .network_nodes - .iter() - .map(|node| &node.basic) - .filter(|node| { - if node.supported_roles.mixnode { - node.performance.round_to_integer() >= min_mix_performance - } else { - true - } - }), - ) - } -} - -struct CachedNetworkInner { - rewarded_set: EpochRewardedSet, - topology_metadata: NymTopologyMetadata, - network_nodes: Vec, -} - -pub struct NetworkRefresher { - querier: NodesQuerier, - full_refresh_interval: Duration, - pending_check_interval: Duration, - shutdown_token: ShutdownToken, - - network: CachedNetwork, - routing_filter: NetworkRoutingFilter, - noise_view: NoiseNetworkView, - lp_nodes: LpNodes, -} - -impl NetworkRefresher { - #[allow(clippy::too_many_arguments)] - pub(crate) async fn initialise_new( - testnet: bool, - user_agent: UserAgent, - nym_api_urls: Vec, - full_refresh_interval: Duration, - pending_check_interval: Duration, - max_startup_waiting_period: Duration, - min_mix_performance: u8, - shutdown_token: ShutdownToken, - ) -> Result { - let nym_api = nym_http_api_client::Client::builder(nym_api_urls[0].clone())? - .no_hickory_dns() - .with_user_agent(user_agent) - .build()?; - - let mut this = NetworkRefresher { - querier: NodesQuerier { - client: nym_api, - nym_api_urls, - currently_used_api: 0, - }, - full_refresh_interval, - pending_check_interval, - shutdown_token, - network: CachedNetwork::new_empty(), - routing_filter: NetworkRoutingFilter::new_empty(testnet), - noise_view: NoiseNetworkView::new_empty(), - lp_nodes: Default::default(), - }; - - this.obtain_initial_network(max_startup_waiting_period, min_mix_performance) - .await?; - Ok(this) - } - - async fn inspect_pending(&mut self) { - let to_resolve = self.routing_filter.pending.nodes().await; - - // no pending requests to resolve - if to_resolve.is_empty() { - return; - } - - let mut allowed = self.routing_filter().allowed_nodes_copy(); - let mut denied = self.routing_filter().denied_nodes_copy(); - - // short circuit: check if the pending nodes are not already resolved - // (it could happen due to lack of full sync between pending lock and arcswap(s)) - if to_resolve - .iter() - .all(|p| allowed.contains(p) || denied.contains(p)) - { - return; - } - - // 1. attempt to use the new nym-api query to get information just by ips - let nodes = to_resolve.into_iter().collect(); - if let Ok(res) = self.querier.query_for_info(nodes).await { - for (ip, maybe_id) in res.existence { - if maybe_id.is_some() { - allowed.insert(ip); - } else { - denied.insert(ip); - } - } - - self.routing_filter.resolved.swap_allowed(allowed); - self.routing_filter.resolved.swap_denied(denied); - self.routing_filter.pending.clear().await; - return; - } - - // 2. we assume nym-api doesn't support that query yet - we have to do the full refresh - self.refresh_network_nodes().await; - } - - async fn refresh_network_nodes_inner(&mut self) -> Result<(), ValidatorClientError> { - let rewarded_set = self.querier.rewarded_set().await?; - let res = self.querier.current_nymnodes().await?; - let nodes = res.nodes; - let metadata = res.metadata; - - // collect all known/allowed nodes information - let known_nodes = nodes - .iter() - .flat_map(|n| n.basic.ip_addresses.iter()) - .copied() - .collect::>(); - - let pending = self.routing_filter.pending.nodes().await; - let mut current_denied = self.routing_filter.denied_nodes_copy(); - - for allowed in &known_nodes { - // if some node has become known, it should be removed from the denied set - current_denied.remove(allowed); - } - - // any pending node, if not present in the new set of allowed nodes, should be added in the denied set - for pending_node in pending { - if !known_nodes.contains(&pending_node) { - current_denied.insert(pending_node); - } - } - - self.routing_filter.resolved.swap_allowed(known_nodes); - self.routing_filter.resolved.swap_denied(current_denied); - self.routing_filter.pending.clear().await; - - //update noise Nodes - let noise_nodes = nodes - .iter() - .filter(|n| n.x25519_noise_versioned_key.is_some()) - .flat_map(|n| { - n.basic.ip_addresses.iter().map(|ip_addr| { - ( - SocketAddr::new(*ip_addr, n.basic.mix_port), - #[allow(clippy::unwrap_used)] - n.x25519_noise_versioned_key.unwrap(), // SAFETY : we filtered out nodes where this option can be None - ) - }) - }) - .collect::>(); - self.noise_view.swap_view(noise_nodes); - debug!("unimplemented: update LP nodes data"); - - let mut network_guard = self.network.inner.write().await; - network_guard.topology_metadata = metadata.to_topology_metadata(); - network_guard.network_nodes = nodes; - network_guard.rewarded_set = rewarded_set; - - Ok(()) - } - - async fn refresh_network_nodes(&mut self) { - let timer = - PROMETHEUS_METRICS.start_timer(PrometheusMetric::ProcessTopologyQueryResolutionLatency); - - if self.refresh_network_nodes_inner().await.is_err() { - // don't use the histogram observation as some queries didn't complete - if let Some(obs) = timer { - obs.stop_and_discard(); - } - } - } - - pub(crate) async fn obtain_initial_network( - &mut self, - max_startup_waiting_period: Duration, - min_mix_performance: u8, - ) -> Result<(), NymNodeError> { - // make it configurable - const STARTUP_REFRESH_INTERVAL: Duration = Duration::from_secs(30); - - let start = Instant::now(); - - loop { - self.refresh_network_nodes_inner() - .await - .map_err(|source| NymNodeError::InitialTopologyQueryFailure { source })?; - - let topology = self.network.network_topology(min_mix_performance).await; - if topology.is_minimally_routable() { - return Ok(()); - } - - if start.elapsed() > max_startup_waiting_period { - return Err(NymNodeError::InitialTopologyTimeout); - } - - sleep(STARTUP_REFRESH_INTERVAL).await; - } - } - - pub(crate) fn routing_filter(&self) -> NetworkRoutingFilter { - self.routing_filter.clone() - } - - pub(crate) fn cached_network(&self) -> CachedNetwork { - self.network.clone() - } - - pub(crate) fn noise_view(&self) -> NoiseNetworkView { - self.noise_view.clone() - } - - pub(crate) fn lp_nodes(&self) -> LpNodes { - self.lp_nodes.clone() - } - - pub(crate) async fn run(&mut self) { - let mut full_refresh_interval = interval(self.full_refresh_interval); - full_refresh_interval.reset(); - - let mut pending_check_interval = interval(self.pending_check_interval); - pending_check_interval.reset(); - - loop { - tokio::select! { - biased; - _ = self.shutdown_token.cancelled() => { - trace!("NetworkRefresher: Received shutdown"); - break; - } - _ = pending_check_interval.tick() => { - self.inspect_pending().await; - } - _ = full_refresh_interval.tick() => { - self.refresh_network_nodes().await; - } - } - } - trace!("NetworkRefresher: Exiting"); - } - - pub(crate) fn start(mut self) { - tokio::spawn(async move { self.run().await }); - } -} diff --git a/nym-node/src/node/shared_network/mod.rs b/nym-node/src/node/shared_network/mod.rs new file mode 100644 index 0000000000..d900f6cc1a --- /dev/null +++ b/nym-node/src/node/shared_network/mod.rs @@ -0,0 +1,56 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use nym_topology::{EpochRewardedSet, NymTopology, NymTopologyMetadata}; +use nym_validator_client::nym_nodes::SemiSkimmedNodeV1; +use std::sync::Arc; +use tokio::sync::RwLock; + +pub(crate) mod refresher; +pub(crate) mod topology_provider; + +#[derive(Clone)] +pub(crate) struct CachedNetwork { + inner: Arc>, +} + +impl CachedNetwork { + fn new_empty() -> Self { + CachedNetwork { + inner: Arc::new(RwLock::new(CachedNetworkInner { + rewarded_set: Default::default(), + topology_metadata: Default::default(), + network_nodes: vec![], + })), + } + } + + async fn network_topology(&self, min_mix_performance: u8) -> NymTopology { + let network_guard = self.inner.read().await; + + NymTopology::new( + network_guard.topology_metadata, + network_guard.rewarded_set.clone(), + Vec::new(), + ) + .with_additional_nodes( + network_guard + .network_nodes + .iter() + .map(|node| &node.basic) + .filter(|node| { + if node.supported_roles.mixnode { + node.performance.round_to_integer() >= min_mix_performance + } else { + true + } + }), + ) + } +} + +struct CachedNetworkInner { + rewarded_set: EpochRewardedSet, + topology_metadata: NymTopologyMetadata, + network_nodes: Vec, +} diff --git a/nym-node/src/node/shared_network/refresher.rs b/nym-node/src/node/shared_network/refresher.rs new file mode 100644 index 0000000000..dc54a67404 --- /dev/null +++ b/nym-node/src/node/shared_network/refresher.rs @@ -0,0 +1,337 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +//! Background task that periodically refreshes network topology and routing information. +//! +//! # Responsibilities +//! +//! - Fetches the current Nym node list from nym-api +//! - Resolves pending (unknown) IP addresses from ingress mixnet packets +//! - Updates routing filter with allowed/denied node lists +//! - Maintains Noise protocol key mappings +//! - Ensures minimally routable topology at startup +//! +//! # Refresh Strategy +//! +//! Two independent refresh cycles run in parallel: +//! 1. **Full refresh** (typically every 60s): Complete network state from nym-api +//! 2. **Pending check** (typically every 5s): Quick resolution of recently seen unknown IPs +//! +//! The pending check uses an optimized nym-api endpoint when available, falling back to +//! full refresh if the endpoint is not supported. + +use crate::error::NymNodeError; +use crate::node::lp::directory::LpNodes; +use crate::node::nym_apis_client::NymApisClient; +use crate::node::routing_filter::network_filter::NetworkRoutingFilter; +use crate::node::shared_network::CachedNetwork; +use nym_node_metrics::prometheus_wrapper::{PROMETHEUS_METRICS, PrometheusMetric}; +use nym_noise::config::{NoiseNetworkView, NoiseNode}; +use nym_task::ShutdownToken; +use nym_topology::provider_trait::ToTopologyMetadata; +use nym_validator_client::ValidatorClientError; +use std::collections::{HashMap, HashSet}; +use std::time::Duration; +use tokio::time::{Instant, interval, sleep}; +use tracing::{debug, trace}; + +pub struct NetworkRefresher { + config: NetworkRefresherConfig, + client: NymApisClient, + shutdown_token: ShutdownToken, + + network: CachedNetwork, + routing_filter: NetworkRoutingFilter, + noise_view: NoiseNetworkView, + lp_nodes: LpNodes, +} + +#[derive(Debug, Clone, Copy)] +pub struct NetworkRefresherConfig { + full_refresh_interval: Duration, + pending_check_interval: Duration, + max_startup_waiting_period: Duration, + min_mix_performance: u8, +} + +impl NetworkRefresherConfig { + pub fn new( + full_refresh_interval: Duration, + pending_check_interval: Duration, + max_startup_waiting_period: Duration, + min_mix_performance: u8, + ) -> Self { + Self { + full_refresh_interval, + pending_check_interval, + max_startup_waiting_period, + min_mix_performance, + } + } +} + +impl NetworkRefresher { + pub(crate) async fn initialise_new( + config: NetworkRefresherConfig, + client: NymApisClient, + routing_filter: NetworkRoutingFilter, + noise_view: NoiseNetworkView, + shutdown_token: ShutdownToken, + ) -> Result { + let mut this = NetworkRefresher { + config, + client, + shutdown_token, + network: CachedNetwork::new_empty(), + routing_filter, + noise_view, + lp_nodes: Default::default(), + }; + + this.obtain_initial_network( + config.max_startup_waiting_period, + config.min_mix_performance, + ) + .await?; + Ok(this) + } + + /// Attempt to resolve pending (unknown) IP addresses that were recently seen in packet traffic. + /// + /// # Algorithm + /// + /// 1. Collect all pending IPs that need resolution (lock required) + /// 2. Short-circuit if all pending IPs are already in allowed/denied sets (race condition check) + /// 3. Try optimised nym-api query: `query_nym_nodes_addresses(ips)` for bulk lookup + /// - If supported: Get immediate results, update allowed/denied sets, clear pending queue + /// - If not supported (404): Fall back to full network refresh + /// + /// # Performance + /// + /// The optimised query avoids fetching the entire network topology (~1000 nodes) when we only + /// need to check a handful of IPs. This is crucial for minimising latency between when a new + /// node joins and when it can successfully route packets. + /// + /// # Fallback Behaviour + /// + /// If nym-api doesn't support the optimised endpoint, we do a full refresh. This is acceptable + /// because: + /// - Full refresh is needed anyway for topology updates + /// - The pending queue typically has <10 entries + /// - This only affects older nym-api versions + async fn inspect_pending(&mut self) { + let to_resolve = self.routing_filter.pending.nodes().await; + + // no pending requests to resolve + if to_resolve.is_empty() { + return; + } + + let mut allowed = self.routing_filter.allowed_nodes_copy(); + let mut denied = self.routing_filter.denied_nodes_copy(); + + // short circuit: check if the pending nodes are not already resolved + // (it could happen due to lack of full sync between pending lock and arcswap(s)) + if to_resolve + .iter() + .all(|p| allowed.contains(p) || denied.contains(p)) + { + return; + } + + // 1. attempt to use the new nym-api query to get information just by ips + let nodes = to_resolve.into_iter().collect(); + if let Ok(res) = self.client.query_nym_nodes_addresses(nodes).await { + for (ip, maybe_id) in res.existence { + if maybe_id.is_some() { + allowed.insert(ip); + } else { + denied.insert(ip); + } + } + + self.routing_filter.resolved.swap_allowed(allowed); + self.routing_filter.resolved.swap_denied(denied); + self.routing_filter.pending.clear().await; + return; + } + + // 2. we assume nym-api doesn't support that query yet - we have to do the full refresh + self.refresh_network_nodes().await; + } + + async fn refresh_network_nodes_inner(&mut self) -> Result<(), ValidatorClientError> { + let rewarded_set = self.client.rewarded_set().await?; + let res = self.client.current_nymnodes().await?; + let nodes = res.nodes; + let metadata = res.metadata; + + // collect all known/allowed nodes information + let known_nodes = nodes + .iter() + .flat_map(|n| n.basic.ip_addresses.iter()) + .copied() + .collect::>(); + + let pending = self.routing_filter.pending.nodes().await; + let mut current_denied = self.routing_filter.denied_nodes_copy(); + + for allowed in &known_nodes { + // if some node has become known, it should be removed from the denied set + current_denied.remove(allowed); + } + + // any pending node, if not present in the new set of allowed nodes, should be added in the denied set + for pending_node in pending { + if !known_nodes.contains(&pending_node) { + current_denied.insert(pending_node); + } + } + + self.routing_filter.resolved.swap_allowed(known_nodes); + self.routing_filter.resolved.swap_denied(current_denied); + self.routing_filter.pending.clear().await; + + let noise_update_permit = self.noise_view.get_update_permit().await; + let current_nodes = self.noise_view.all_nodes(); + + // update noise Nodes + let mut new_noise_nodes = HashMap::new(); + + // Rebuild the noise map in two passes to respect the two independent data sources: + // + // 1. Preserve existing NM agent entries — these come from blockchain events processed + // by `NetworkMonitorAgentsModule` and are NOT available from nym-api. Dropping them + // here would leave agents unable to perform noise handshakes until their + // registration is renewed. + // Keys are canonicalised so the map matches what supports_noise/get_noise_key look up. + for (ip, node) in current_nodes { + if !node.is_nym_node() { + new_noise_nodes.insert(ip.to_canonical(), node); + } + } + + // 2. Replace all nym-node entries with fresh data from nym-api. + // (Stale nym-node keys are safe to overwrite — the source of truth is always nym-api) + for node in &nodes { + let Some(noise_key) = node.x25519_noise_versioned_key else { + continue; + }; + let entry = NoiseNode::new_nym_node(noise_key); + for ip_addr in &node.basic.ip_addresses { + new_noise_nodes.insert(ip_addr.to_canonical(), entry.clone()); + } + } + self.noise_view + .swap_view(noise_update_permit, new_noise_nodes); + debug!("unimplemented: update LP nodes data - will work very similarly to noise nodes"); + + let mut network_guard = self.network.inner.write().await; + network_guard.topology_metadata = metadata.to_topology_metadata(); + network_guard.network_nodes = nodes; + network_guard.rewarded_set = rewarded_set; + + Ok(()) + } + + async fn refresh_network_nodes(&mut self) { + let timer = + PROMETHEUS_METRICS.start_timer(PrometheusMetric::ProcessTopologyQueryResolutionLatency); + + if self.refresh_network_nodes_inner().await.is_err() { + // don't use the histogram observation as some queries didn't complete + if let Some(obs) = timer { + obs.stop_and_discard(); + } + } + } + + /// Block until we obtain a minimally routable network topology at startup. + /// + /// # Startup Sequence + /// + /// 1. Query nym-api for full network state (nodes + rewarded set) + /// 2. Check if topology has sufficient mixnodes in each layer for routing + /// 3. If not routable: wait `STARTUP_REFRESH_INTERVAL` (30s) and retry + /// 4. If still not routable after `max_startup_waiting_period`: return error and abort startup + /// + /// # Why Block Startup? + /// + /// We MUST have a routable topology before accepting packets, otherwise: + /// - Packets would be dropped due to incomplete routing tables + /// - The node would appear non-functional to the network + /// - Internal service providers would be unable to construct return packets + /// + /// # Timeout Behavior + /// + /// If the network remains non-routable for too long, this indicates: + /// - Network-wide outage (not enough mixnodes online) + /// - nym-api connectivity issues + /// - Configuration error (wrong nym-api URL) + /// + /// In any case, the node should NOT start packet processing. + pub(crate) async fn obtain_initial_network( + &mut self, + max_startup_waiting_period: Duration, + min_mix_performance: u8, + ) -> Result<(), NymNodeError> { + // make it configurable + const STARTUP_REFRESH_INTERVAL: Duration = Duration::from_secs(30); + + let start = Instant::now(); + + loop { + self.refresh_network_nodes_inner() + .await + .map_err(|source| NymNodeError::InitialTopologyQueryFailure { source })?; + + let topology = self.network.network_topology(min_mix_performance).await; + if topology.is_minimally_routable() { + return Ok(()); + } + + if start.elapsed() > max_startup_waiting_period { + return Err(NymNodeError::InitialTopologyTimeout); + } + + sleep(STARTUP_REFRESH_INTERVAL).await; + } + } + + pub(crate) fn cached_network(&self) -> CachedNetwork { + self.network.clone() + } + + pub(crate) fn lp_nodes(&self) -> LpNodes { + self.lp_nodes.clone() + } + + pub(crate) async fn run(&mut self) { + let mut full_refresh_interval = interval(self.config.full_refresh_interval); + full_refresh_interval.reset(); + + let mut pending_check_interval = interval(self.config.pending_check_interval); + pending_check_interval.reset(); + + loop { + tokio::select! { + biased; + _ = self.shutdown_token.cancelled() => { + trace!("NetworkRefresher: Received shutdown"); + break; + } + _ = pending_check_interval.tick() => { + self.inspect_pending().await; + } + _ = full_refresh_interval.tick() => { + self.refresh_network_nodes().await; + } + } + } + trace!("NetworkRefresher: Exiting"); + } + + pub(crate) fn start(mut self) { + tokio::spawn(async move { self.run().await }); + } +} diff --git a/nym-node/src/node/shared_network/topology_provider.rs b/nym-node/src/node/shared_network/topology_provider.rs new file mode 100644 index 0000000000..1002ad7e21 --- /dev/null +++ b/nym-node/src/node/shared_network/topology_provider.rs @@ -0,0 +1,79 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: GPL-3.0-only + +use crate::node::key_rotation::active_keys::ActiveSphinxKeys; +use crate::node::shared_network::CachedNetwork; +use async_trait::async_trait; +use nym_crypto::asymmetric::ed25519; +use nym_topology::{EntryDetails, NodeId, NymTopology, Role, RoutingNode, TopologyProvider}; +use std::net::SocketAddr; +use std::ops::Deref; +use std::sync::Arc; +use tracing::debug; + +const LOCAL_NODE_ID: NodeId = 1234567890; + +pub(crate) struct LocalGatewayNode { + pub(crate) active_sphinx_keys: ActiveSphinxKeys, + pub(crate) mix_host: SocketAddr, + pub(crate) identity_key: ed25519::PublicKey, + pub(crate) entry: EntryDetails, +} + +impl LocalGatewayNode { + pub(crate) fn to_routing_node(&self) -> RoutingNode { + RoutingNode { + node_id: LOCAL_NODE_ID, + mix_host: self.mix_host, + entry: Some(self.entry.clone()), + identity_key: self.identity_key, + sphinx_key: self.active_sphinx_keys.primary().deref().x25519_pubkey(), + supported_roles: nym_topology::SupportedRoles { + mixnode: false, + mixnet_entry: true, + mixnet_exit: true, + }, + } + } +} + +#[derive(Clone)] +pub struct CachedTopologyProvider { + gateway_node: Arc, + cached_network: CachedNetwork, + min_mix_performance: u8, +} + +impl CachedTopologyProvider { + pub(crate) fn new( + gateway_node: LocalGatewayNode, + cached_network: CachedNetwork, + min_mix_performance: u8, + ) -> Self { + CachedTopologyProvider { + gateway_node: Arc::new(gateway_node), + cached_network, + min_mix_performance, + } + } +} + +#[async_trait] +impl TopologyProvider for CachedTopologyProvider { + async fn get_new_topology(&mut self) -> Option { + let self_node = self.gateway_node.identity_key; + + let mut topology = self + .cached_network + .network_topology(self.min_mix_performance) + .await; + + if !topology.has_node(self.gateway_node.identity_key) { + debug!("{self_node} didn't exist in topology. inserting it.",); + topology.insert_node_details(self.gateway_node.to_routing_node()); + } + topology.force_set_active(LOCAL_NODE_ID, Role::EntryGateway); + + Some(topology) + } +} diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index e8d51ea07c..cce78b4a2a 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -4833,7 +4833,6 @@ version = "1.20.4" dependencies = [ "cargo_metadata 0.19.2", "dotenvy", - "log", "regex", "schemars", "serde", @@ -4843,6 +4842,18 @@ dependencies = [ "utoipa", ] +[[package]] +name = "nym-network-monitors-contract-common" +version = "1.20.4" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers", + "schemars", + "serde", + "thiserror 2.0.12", +] + [[package]] name = "nym-node-requests" version = "1.20.4" @@ -4855,6 +4866,7 @@ dependencies = [ "nym-exit-policy", "nym-http-api-client", "nym-kkt-ciphersuite", + "nym-network-defaults", "nym-noise-keys", "nym-upgrade-mode-check", "nym-wireguard-types", @@ -5018,6 +5030,7 @@ dependencies = [ "nym-mixnet-contract-common", "nym-multisig-contract-common", "nym-network-defaults", + "nym-network-monitors-contract-common", "nym-performance-contract-common", "nym-serde-helpers", "nym-vesting-contract-common", diff --git a/nym-wallet/nym-wallet-types/src/network/sandbox.rs b/nym-wallet/nym-wallet-types/src/network/sandbox.rs index f8e66ebe3e..a70bf52613 100644 --- a/nym-wallet/nym-wallet-types/src/network/sandbox.rs +++ b/nym-wallet/nym-wallet-types/src/network/sandbox.rs @@ -28,6 +28,9 @@ pub(crate) const COCONUT_DKG_CONTRACT_ADDRESS: &str = pub(crate) const PERFORMANCE_CONTRACT_ADDRESS: &str = ""; // /\ TODO: this has to be updated once the contract is deployed +pub const NETWORK_MONITORS_CONTRACT_ADDRESS: &str = + "n1x5krtvyqklj360x38v62ze42g8s8trfsfqzlv8c9296chcpvqadssqnem5"; + // -- Constructor functions -- pub(crate) fn validators() -> Vec { @@ -51,6 +54,9 @@ pub(crate) fn network_details() -> nym_network_defaults::NymNetworkDetails { mixnet_contract_address: parse_optional_str(MIXNET_CONTRACT_ADDRESS), vesting_contract_address: parse_optional_str(VESTING_CONTRACT_ADDRESS), performance_contract_address: parse_optional_str(PERFORMANCE_CONTRACT_ADDRESS), + network_monitors_contract_address: parse_optional_str( + NETWORK_MONITORS_CONTRACT_ADDRESS, + ), ecash_contract_address: parse_optional_str(ECASH_CONTRACT_ADDRESS), group_contract_address: parse_optional_str(GROUP_CONTRACT_ADDRESS), multisig_contract_address: parse_optional_str(MULTISIG_CONTRACT_ADDRESS), diff --git a/nym-wallet/src-tauri/src/operations/nym_api/status.rs b/nym-wallet/src-tauri/src/operations/nym_api/status.rs index e17c828514..9b88b22435 100644 --- a/nym-wallet/src-tauri/src/operations/nym_api/status.rs +++ b/nym-wallet/src-tauri/src/operations/nym_api/status.rs @@ -14,7 +14,7 @@ use nym_mixnet_contract_common::{ }; use nym_validator_client::client::NymApiClientExt; use nym_validator_client::models::{ - AnnotationResponse, DisplayRole, GatewayCoreStatusResponse, GatewayStatusReportResponse, + AnnotationResponseV1, DisplayRole, GatewayCoreStatusResponse, GatewayStatusReportResponse, MixnodeCoreStatusResponse, MixnodeStatusResponse, StakeSaturationResponse, }; use serde::{Deserialize, Serialize}; @@ -167,6 +167,6 @@ pub async fn get_nymnode_role( pub async fn get_nymnode_annotation( node_id: NodeId, state: tauri::State<'_, WalletState>, -) -> Result { +) -> Result { Ok(api_client!(state).get_node_annotation(node_id).await?) } diff --git a/nyx-chain-watcher/src/chain_scraper/mod.rs b/nyx-chain-watcher/src/chain_scraper/mod.rs index 5bf6eff337..2228a6f6d4 100644 --- a/nyx-chain-watcher/src/chain_scraper/mod.rs +++ b/nyx-chain-watcher/src/chain_scraper/mod.rs @@ -5,9 +5,10 @@ use crate::env::vars::{ }; use crate::http::state::BankScraperModuleState; use async_trait::async_trait; -use nym_validator_client::nyxd::{Any, Coin, CosmosCoin, Hash, Msg, MsgSend, Name}; +use nym_validator_client::nyxd::{Any, Coin, CosmosCoin, Msg, MsgSend, Name}; use nyxd_scraper_sqlite::{ - MsgModule, ParsedTransactionResponse, PruningOptions, ScraperError, SqliteNyxdScraper, + DecodedMessage, MsgModule, ParsedTransactionDetails, PruningOptions, ScraperError, + SqliteNyxdScraper, parse_msg, }; use sqlx::SqlitePool; use std::fs; @@ -130,22 +131,8 @@ impl BankScraperModule { .find(|coin| coin.denom.as_ref() == "unym") .map(|c| c.clone().into()) } - - // TODO: ideally this should be done by the scraper itself - fn recover_bank_msg( - &self, - tx_hash: Hash, - index: usize, - msg: &Any, - ) -> Result { - MsgSend::from_any(msg).map_err(|source| ScraperError::MsgParseFailure { - hash: tx_hash, - index, - type_url: self.type_url(), - source, - }) - } } + #[async_trait] impl MsgModule for BankScraperModule { fn type_url(&self) -> String { @@ -156,7 +143,8 @@ impl MsgModule for BankScraperModule { &mut self, index: usize, msg: &Any, - tx: &ParsedTransactionResponse, + _: &DecodedMessage, + tx: &ParsedTransactionDetails, ) -> Result<(), ScraperError> { let memo = tx.tx.body.memo.clone(); @@ -165,7 +153,7 @@ impl MsgModule for BankScraperModule { return Ok(()); } - let msg = self.recover_bank_msg(tx.hash, index, msg)?; + let msg: MsgSend = parse_msg(msg)?; // Check if any watcher is watching this recipient let is_watched = self @@ -184,7 +172,7 @@ impl MsgModule for BankScraperModule { ); warn!("{warn}"); self.shared_state - .new_rejection(tx.hash.to_string(), tx.height.value(), index as u32, warn) + .new_rejection(tx.hash.to_string(), tx.height().value(), index as u32, warn) .await; // we don't want to fail the whole processing - this is not a failure in that sense! @@ -194,7 +182,7 @@ impl MsgModule for BankScraperModule { if let Err(err) = self .store_transfer_event( &tx.hash.to_string(), - tx.height.value() as i64, + tx.height().value() as i64, index as i64, msg.from_address.to_string(), msg.to_address.to_string(), @@ -207,7 +195,7 @@ impl MsgModule for BankScraperModule { self.shared_state .new_rejection( tx.hash.to_string(), - tx.height.value(), + tx.height().value(), index as u32, format!("storage failure: {err}"), ) diff --git a/nyx-chain-watcher/src/http/state.rs b/nyx-chain-watcher/src/http/state.rs index 8ab26dff9b..05f1b2119b 100644 --- a/nyx-chain-watcher/src/http/state.rs +++ b/nyx-chain-watcher/src/http/state.rs @@ -7,7 +7,7 @@ use axum::extract::FromRef; use nym_bin_common::bin_info; use nym_bin_common::build_information::BinaryBuildInformation; use nym_validator_client::nyxd::{Coin, MsgSend}; -use nyxd_scraper_sqlite::ParsedTransactionResponse; +use nyxd_scraper_sqlite::ParsedTransactionDetails; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::ops::Deref; @@ -289,7 +289,7 @@ impl BankScraperModuleState { pub(crate) async fn new_bank_msg( &self, - tx: &ParsedTransactionResponse, + tx: &ParsedTransactionDetails, index: usize, msg: &MsgSend, is_watched: bool, @@ -300,7 +300,7 @@ impl BankScraperModuleState { let details = BankMsgDetails { processed_at: OffsetDateTime::now_utc(), tx_hash: tx.hash.to_string(), - height: tx.height.value(), + height: tx.height().value(), index: index as u32, from: msg.from_address.to_string(), to: msg.to_address.to_string(), diff --git a/tools/ts-rs-cli/src/main.rs b/tools/ts-rs-cli/src/main.rs index 4b21ada952..79ba3ef7ee 100644 --- a/tools/ts-rs-cli/src/main.rs +++ b/tools/ts-rs-cli/src/main.rs @@ -1,11 +1,11 @@ #![allow(deprecated)] use nym_api_requests::models::{ - AnnotationResponse, DeclaredRolesV1, DescribedNodeTypeV1, GatewayCoreStatusResponse, - HistoricalPerformanceResponse, HistoricalUptimeResponse, MixnodeCoreStatusResponse, - MixnodeStatus, MixnodeStatusResponse, NodeAnnotation, NodeDatePerformanceResponse, - NodePerformanceResponse, PerformanceHistoryResponse, StakeSaturationResponse, - UptimeHistoryResponse, + AnnotationResponseV1, AnnotationResponseV2, DeclaredRolesV1, DescribedNodeTypeV1, + GatewayCoreStatusResponse, HistoricalPerformanceResponse, HistoricalUptimeResponse, + MixnodeCoreStatusResponse, MixnodeStatus, MixnodeStatusResponse, NodeAnnotationV1, + NodeAnnotationV2, NodeDatePerformanceResponse, NodePerformanceResponse, + PerformanceHistoryResponse, StakeSaturationResponse, UptimeHistoryResponse, }; use nym_api_requests::pagination::{PaginatedResponse, Pagination}; use nym_mixnet_contract_common::nym_node::{NodeConfigUpdate, Role}; @@ -150,8 +150,10 @@ fn main() -> anyhow::Result<()> { do_export!(MixnodeStatus); do_export!(MixnodeStatusResponse); do_export!(StakeSaturationResponse); - do_export!(NodeAnnotation); - do_export!(AnnotationResponse); + do_export!(NodeAnnotationV1); + do_export!(AnnotationResponseV1); + do_export!(NodeAnnotationV2); + do_export!(AnnotationResponseV2); do_export!(NodePerformanceResponse); do_export!(NodeDatePerformanceResponse); do_export!(PerformanceHistoryResponse); From f2e379f10ae8b293fffb04210bd935ead4890e3e Mon Sep 17 00:00:00 2001 From: import this <97586125+serinko@users.noreply.github.com> Date: Fri, 22 May 2026 11:36:28 +0200 Subject: [PATCH 38/94] [DOCs/operators]: Indenpendent devrel tool release (#6809) * operators updates * placeholding reminder for later * new component import * correct comment syntax * turtle beats the rabbitai * syntax fix * syntax fix * rm platform release and finish pr * fix header --- .../docs/pages/operators/changelog.mdx | 74 ++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/documentation/docs/pages/operators/changelog.mdx b/documentation/docs/pages/operators/changelog.mdx index 4cfb438764..16f72c28ca 100644 --- a/documentation/docs/pages/operators/changelog.mdx +++ b/documentation/docs/pages/operators/changelog.mdx @@ -16,6 +16,8 @@ import { Steps } from 'nextra/components'; import AbuseResponse from 'components/operators/templates/dmca_response.md'; import OperatorIntroduction from 'components/operators/templates/provider_introduction.md'; import QuicDeploymentSteps from 'components/operators/snippets/quic-bridge-deployment-script-setup.mdx'; +import NTMExplanation from 'components/operators/snippets/ntm-accordion-explanation.mdx'; + export const TestingSteps = () => ( @@ -48,7 +50,6 @@ export const LoadEndpointInfo = () => ( ); - # Changelog This page displays a full list of all the changes during our release cycle from `v2024.3-eclipse` onward. Operators can find here the newest updates together with links to relevant documentation. The list is sorted so that the newest changes appear first. @@ -57,6 +58,77 @@ This page displays a full list of all the changes during our release cycle from +## Operators Tools + +As the upcoming platform release has been posponed, we prepared this indenpendent release of tools and updates important for node operators. + + +[**Security steps required**](/operators/troubleshooting/vps-isp#security-patch-copyfail--dirtyfrag): Several critical [Linux kernel vulnerabilities](https://ubuntu.com/blog/copy-fail-vulnerability-fixes-available) had been disclosed. Check out your servers and if needed apply required mitigations! + + +- [**NIP-11 - NTM updated: Telegram voice and video call works now!**](https://github.com/nymtech/nym/pull/6807) Please re-run [Nym network tunnel manager](https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/nym-node-setup/network-tunnel-manager.sh) (NTM) on your hosting servers: + +

+ Manual steps, + <>Ansible, + ]} defaultIndex="0"> + + +- Get the latest version of NTM + +```sh +curl -L "https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/nym-node-setup/network-tunnel-manager.sh" -o network-tunnel-manager.sh && chmod +x ./network-tunnel-manager.sh +``` + +- Run NTM (Standard SSH on port 22 (default)): +```sh +./network-tunnel-manager.sh complete_networking_configuration +``` + +- Run NTM on non-standard SSH port: +```sh +HOST_SSH_PORT= ./network-tunnel-manager.sh complete_networking_configuration + +# example - replace 2222 with your actual port: +# HOST_SSH_PORT=2222 ./network-tunnel-manager.sh complete_networking_configuration +``` + + + + + + +- Navigate to your Nym node Ansible directory with all playbooks (`/playbooks`) + +- For safety start only with one node: +```sh +ansible-playbook deploy.yml -t ntm -l node1 +``` + +- Check if everything worked smooth and the node works on VPN + +- Run on all machines in your inventory +```sh +ansible-playbook deploy.yml -t ntm +``` + + + + + +
+ +- [**New docs**](https://github.com/nymtech/nym/pull/6716): Max's leg work on [exit services documentation](/network/infrastructure/exit-services), [`Mixfetch`](/developers/mix-fetch) and [`smolmix`](/developers/smolmix) + +### Operators UX Improvements + +- [NTM: Split IPv4 / IPv6 uplinks](https://github.com/nymtech/nym/pull/6640): Now NTM can work with different uplink interfaces for IPv4 and IPv6 + +- [Nym Node CLI: Split IPv4 / IPv6 uplinks](https://github.com/nymtech/nym/pull/6743): `nym-node-cli.py` uplinks sync up with NTM + +- [NTM & Nym Node CLI: Alternative SSH port](https://github.com/nymtech/nym/pull/6633): Operators can use these tools with `HOST_SSH_PORT` allowing them to define any alternative port instead of only using hard-coded 22 + ## `v2026.9-venaco` - [Release Binaries](https://github.com/nymtech/nym/releases/tag/nym-binaries-v2026.9-venaco) From d2833c76c0294cf8b1cb6c5e7d575b5b8643e9c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 22 May 2026 15:30:08 +0100 Subject: [PATCH 39/94] experiment: attempt to retroactively generate specs for node families and ecash contracts (#6813) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * experiment: add openspec details for node families contract * add openspec for the ecash contract * fix(ecash): correct latest_deposit off-by-one DepositStorage::latest_deposit() returned the counter value, but the counter holds the *next* free id (after next_id() saves counter+1). The GetLatestDeposit handler then tried try_load_by_id(counter), which always returned None — meaning the query yielded { deposit: None } both on a fresh contract and after every successful deposit. Fix: return counter.checked_sub(1) so latest_deposit() yields the most recently assigned id (or None on a fresh contract). The getting_latest_deposit unit test is updated to assert Some(0) and Some(1) after one and two next_id() calls respectively. No downstream consumer was relying on the buggy semantics (validator-client exposes the query as a passthrough trait method that nothing currently calls). * experiment: add openspec details for ecash contract Reverse-engineered openspec change `ecash-contract-spec` documenting the existing CosmWasm contract at `contracts/ecash/`. Mirrors the node-families workflow: docs-only deliverable, no migration, no dependency changes. Archived as openspec/changes/archive/2026-05-21-ecash-contract-spec/ and promoted to openspec/specs/ecash-contract/spec.md as the canonical reference. The spec captures 25 normative requirements with 64 scenarios covering instantiation, migration, deposit submission (default + reduced tier), RequestRedemption + redemption-proposal reply, legacy RedeemTickets (dead code retained), stubbed blacklist surface, the ticketbook-size invariant tripwire, the full query surface, and the public storage / event / error surface. Key documented points the source-of-truth phrasing pins down: - The contract stores claimed ed25519 pubkeys opaquely; ownership is enforced off-chain by nym-api signers via `validate_deposit`. - Per-signer-local de-duplication via `state.already_issued`; no on-chain "issued" state. - Raw 32-byte deposit storage under the `"deposit"` namespace; deposit ids are sequential `u32` starting at 0. - Statistics invariant: default_count + sum(custom_count) = total. - `cw_controllers::Admin` is used as a generic address-equality helper for the `multisig` slot (the wrapper's full admin semantics are not exercised on that slot). - `RedeemTickets` is dead code retained on the public surface; flagged as a candidate for removal. Stubbed-blacklist final disposition is the only Open Question left for the redesign change owner. * docs(ecash): add rustdoc derived from archived ecash-contract spec Drop short doc-comments on the ecash contract surface — handlers, storage slots, message variants, error variants, event constants, shared types — derived from the canonical spec at openspec/specs/ecash-contract/spec.md (archived 2026-05-21). Coverage: - contracts/ecash/src/*.rs: crate-root summary, both DepositStorage and DepositStatsStorage with their invariants called out, every #[sv::msg(...)] handler in contract/mod.rs, reply id constants, Config + invariants snapshot, migration entry point. - common/cosmwasm-smart-contracts/ecash-contract/src/*.rs: every ExecuteMsg / QueryMsg variant, every reachable EcashContractError variant (with unreachable-but-preserved variants flagged), every event constant, every response type, Deposit + DepositId. Explicitly out of scope (separate concerns): - Removing event_attributes::BANDWIDTH_PROPOSAL_ID (dead constant, documented as such for now). - Removing ExecuteMsg::RedeemTickets (dead handler, documented as such; removal is a breaking-schema change). - contracts/ecash/Cargo.toml version bump (docs-only). No behaviour change; all 38 contract tests pass and cargo doc emits no warnings on the touched crates. --- .../ecash-contract/src/blacklist.rs | 12 + .../ecash-contract/src/counters.rs | 3 + .../ecash-contract/src/deposit.rs | 18 + .../ecash-contract/src/error.rs | 45 +- .../ecash-contract/src/event_attributes.rs | 3 + .../ecash-contract/src/events.rs | 14 +- .../ecash-contract/src/lib.rs | 6 + .../ecash-contract/src/msg.rs | 94 ++-- .../ecash-contract/src/redeem_credential.rs | 3 + .../ecash-contract/src/reduced_deposit.rs | 4 + contracts/ecash/schema/nym-ecash.json | 45 +- contracts/ecash/schema/raw/execute.json | 10 +- contracts/ecash/schema/raw/instantiate.json | 11 +- contracts/ecash/schema/raw/query.json | 9 + ...ponse_to_get_all_whitelisted_accounts.json | 2 + .../raw/response_to_get_blacklist_paged.json | 3 + .../response_to_get_blacklisted_account.json | 2 + .../schema/raw/response_to_get_deposit.json | 2 + .../raw/response_to_get_deposits_paged.json | 3 + .../raw/response_to_get_latest_deposit.json | 3 + contracts/ecash/src/constants.rs | 10 + contracts/ecash/src/contract/helpers.rs | 9 + contracts/ecash/src/contract/mod.rs | 70 ++- .../ecash/src/contract/queued_migrations.rs | 11 +- contracts/ecash/src/contract/test.rs | 2 +- contracts/ecash/src/deposit.rs | 30 +- contracts/ecash/src/deposit_stats.rs | 10 + contracts/ecash/src/helpers.rs | 28 +- contracts/ecash/src/lib.rs | 10 + contracts/ecash/src/multitest.rs | 2 +- .../.openspec.yaml | 2 + .../README.md | 3 + .../design.md | 149 ++++++ .../proposal.md | 36 ++ .../specs/node-families-contract/spec.md | 428 +++++++++++++++ .../tasks.md | 33 ++ .../.openspec.yaml | 2 + .../2026-05-21-ecash-contract-spec/design.md | 186 +++++++ .../proposal.md | 48 ++ .../specs/ecash-contract/spec.md | 501 +++++++++++++++++ .../2026-05-21-ecash-contract-spec/tasks.md | 35 ++ openspec/config.yaml | 20 + openspec/specs/ecash-contract/spec.md | 505 ++++++++++++++++++ openspec/specs/node-families-contract/spec.md | 432 +++++++++++++++ 44 files changed, 2795 insertions(+), 59 deletions(-) create mode 100644 openspec/changes/archive/2026-05-20-node-families-contract-spec/.openspec.yaml create mode 100644 openspec/changes/archive/2026-05-20-node-families-contract-spec/README.md create mode 100644 openspec/changes/archive/2026-05-20-node-families-contract-spec/design.md create mode 100644 openspec/changes/archive/2026-05-20-node-families-contract-spec/proposal.md create mode 100644 openspec/changes/archive/2026-05-20-node-families-contract-spec/specs/node-families-contract/spec.md create mode 100644 openspec/changes/archive/2026-05-20-node-families-contract-spec/tasks.md create mode 100644 openspec/changes/archive/2026-05-21-ecash-contract-spec/.openspec.yaml create mode 100644 openspec/changes/archive/2026-05-21-ecash-contract-spec/design.md create mode 100644 openspec/changes/archive/2026-05-21-ecash-contract-spec/proposal.md create mode 100644 openspec/changes/archive/2026-05-21-ecash-contract-spec/specs/ecash-contract/spec.md create mode 100644 openspec/changes/archive/2026-05-21-ecash-contract-spec/tasks.md create mode 100644 openspec/config.yaml create mode 100644 openspec/specs/ecash-contract/spec.md create mode 100644 openspec/specs/node-families-contract/spec.md diff --git a/common/cosmwasm-smart-contracts/ecash-contract/src/blacklist.rs b/common/cosmwasm-smart-contracts/ecash-contract/src/blacklist.rs index 00b6dfc6ae..17473c2660 100644 --- a/common/cosmwasm-smart-contracts/ecash-contract/src/blacklist.rs +++ b/common/cosmwasm-smart-contracts/ecash-contract/src/blacklist.rs @@ -1,8 +1,14 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +//! Blacklist types. **The blacklist surface is stubbed today** - the execute +//! handlers always return `UnimplementedBlacklisting` and the storage map is +//! never populated. These types are kept for the planned redesign. + use cosmwasm_schema::cw_serde; +/// Public-key + metadata pair surfaced by `GetBlacklistedAccount` / +/// `GetBlacklistPaged`. Always empty on a freshly deployed contract. #[cw_serde] pub struct BlacklistedAccount { pub public_key: String, @@ -15,6 +21,8 @@ impl From<(String, Blacklisting)> for BlacklistedAccount { } } +/// Per-key blacklist record: the multisig proposal that approved it and the +/// block height at which finalisation landed (None until finalised). #[cw_serde] pub struct Blacklisting { pub proposal_id: u64, @@ -36,6 +44,8 @@ impl BlacklistedAccount { } } +/// Page of blacklist entries returned by `GetBlacklistPaged`. Always empty on +/// a freshly deployed contract. #[cw_serde] pub struct PagedBlacklistedAccountResponse { pub accounts: Vec, @@ -59,6 +69,8 @@ impl PagedBlacklistedAccountResponse { } } +/// Response shape for `GetBlacklistedAccount`. `account` is `None` for any +/// key not present in the (currently always-empty) blacklist. #[cw_serde] pub struct BlacklistedAccountResponse { pub account: Option, diff --git a/common/cosmwasm-smart-contracts/ecash-contract/src/counters.rs b/common/cosmwasm-smart-contracts/ecash-contract/src/counters.rs index 48ee6766bd..9212f9217f 100644 --- a/common/cosmwasm-smart-contracts/ecash-contract/src/counters.rs +++ b/common/cosmwasm-smart-contracts/ecash-contract/src/counters.rs @@ -4,6 +4,9 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::Coin; +/// Pool-level deposit accounting. Updated by every successful +/// `DepositTicketBookFunds` and (for the unredeemed-tickets counter) by every +/// successful legacy `RedeemTickets`. #[cw_serde] pub struct PoolCounters { /// Represents the total amount of funds deposited into the contract. diff --git a/common/cosmwasm-smart-contracts/ecash-contract/src/deposit.rs b/common/cosmwasm-smart-contracts/ecash-contract/src/deposit.rs index 6992e87a0c..6457f24328 100644 --- a/common/cosmwasm-smart-contracts/ecash-contract/src/deposit.rs +++ b/common/cosmwasm-smart-contracts/ecash-contract/src/deposit.rs @@ -5,8 +5,13 @@ use crate::error::EcashContractError; use cosmwasm_schema::cw_serde; use cosmwasm_std::{StdError, StdResult}; +/// Sequential identifier assigned to every accepted deposit. Starts at 0 and +/// is never recycled. pub type DepositId = u32; +/// Opaque on-chain record of a deposit: the depositor-claimed bs58-encoded +/// ed25519 identity public key. The contract does not verify control of the +/// corresponding private key. #[cw_serde] pub struct Deposit { pub bs58_encoded_ed25519_pubkey: String, @@ -19,6 +24,8 @@ impl Deposit { } } + /// Decode a bs58-encoded ed25519 public key to its 32-byte raw form. + /// Surfaces `MalformedEd25519Identity` on any bs58 / length failure. pub fn get_ed25519_pubkey_bytes(raw: &str) -> Result<[u8; 32], EcashContractError> { let mut ed25519_pubkey_bytes = [0u8; 32]; bs58::decode(raw) @@ -32,10 +39,13 @@ impl Deposit { bs58::encode(raw).into_string() } + /// Decode this deposit's identity key to its 32-byte raw form for storage. pub fn to_bytes(&self) -> Result<[u8; 32], EcashContractError> { Self::get_ed25519_pubkey_bytes(&self.bs58_encoded_ed25519_pubkey) } + /// Reconstruct a `Deposit` from a raw 32-byte ed25519 pubkey as stored + /// under the `"deposit"` namespace. pub fn try_from_bytes(bytes: &[u8]) -> StdResult { if bytes.len() != 32 { return Err(StdError::generic_err("malformed deposit data")); @@ -47,12 +57,16 @@ impl Deposit { } } +/// Response shape for `GetLatestDeposit`. `deposit` is `None` on a freshly +/// deployed contract. #[cw_serde] #[derive(Default)] pub struct LatestDepositResponse { pub deposit: Option, } +/// Response shape for `GetDeposit { deposit_id }`. `deposit` is `None` when +/// the id has not yet been assigned (`id >= total_deposits_made`). #[cw_serde] pub struct DepositResponse { pub id: DepositId, @@ -60,6 +74,8 @@ pub struct DepositResponse { pub deposit: Option, } +/// `(deposit_id, deposit)` pair surfaced by the latest-deposit and paginated +/// deposit queries. #[cw_serde] pub struct DepositData { pub id: DepositId, @@ -73,6 +89,8 @@ impl From<(DepositId, Deposit)> for DepositData { } } +/// Page of deposits returned by `GetDepositsPaged`. `start_next_after` is the +/// id of the last returned entry; pass it as the next call's `start_after`. #[cw_serde] pub struct PagedDepositsResponse { pub deposits: Vec, diff --git a/common/cosmwasm-smart-contracts/ecash-contract/src/error.rs b/common/cosmwasm-smart-contracts/ecash-contract/src/error.rs index 9fd94ab81a..e9484ad545 100644 --- a/common/cosmwasm-smart-contracts/ecash-contract/src/error.rs +++ b/common/cosmwasm-smart-contracts/ecash-contract/src/error.rs @@ -6,69 +6,108 @@ use cw_controllers::AdminError; use cw_utils::PaymentError; use thiserror::Error; +/// Errors surfaced by the ecash contract. Each reachable variant is named in at +/// least one scenario of `openspec/specs/ecash-contract/spec.md`. #[derive(Error, Debug, PartialEq)] pub enum EcashContractError { + /// Wrapper for any underlying `cosmwasm_std::StdError` (storage faults, + /// address validation, etc.). #[error(transparent)] Std(#[from] StdError), + /// Raised by `cw_utils::must_pay` on `DepositTicketBookFunds` when funds + /// are missing, multi-denom, or in the wrong denom. Inner variants + /// `NoFunds`, `MultipleDenoms`, `MissingDenom` are all reachable. #[error("Invalid deposit")] InvalidDeposit(#[from] PaymentError), + /// `DepositTicketBookFunds` with the right denom but a non-matching amount. + /// `amount` is the reduced amount (if the sender is whitelisted) or the + /// default amount. #[error("received wrong amount for deposit. got: {received}. required: {amount}")] WrongAmount { received: Coin, amount: Coin }, + /// **Unreachable** - preserved for forward compatibility (no current + /// execute path triggers this). #[error("There aren't enough funds in the contract")] NotEnoughFunds, + /// Wrapper for `cw_controllers::AdminError`. Raised by every admin-gated + /// and multisig-gated handler when the sender is wrong. #[error(transparent)] Admin(#[from] AdminError), + /// Redemption-proposal reply could not find a `proposal_id` attribute on + /// the multisig `wasm` event. #[error("could not find proposal id inside the multisig reply SubMsg")] MissingProposalId, - // realistically this should NEVER be thrown + /// Redemption-proposal reply found a `proposal_id` attribute that could + /// not be parsed as `u64`. Realistically unreachable. #[error("the proposal id returned by the multisig contract could not be parsed into an u64")] MalformedProposalId, + /// Instantiation given a `group_addr` that failed bech32 validation. #[error("Group contract invalid address '{addr}'")] InvalidGroup { addr: String }, + /// **Unreachable** - no current execute path triggers this. #[error("Unauthorized")] Unauthorized, + /// **Unreachable** - preserved for future SemVer comparisons during migration. #[error("Failed to parse {value} into a valid SemVer version: {error_message}")] SemVerFailure { value: String, error_message: String, }, + /// Reply dispatcher saw an `id` that does not match + /// `BLACKLIST_PROPOSAL_REPLY_ID` or `REDEMPTION_PROPOSAL_REPLY_ID`. #[error("received an invalid reply id: {id}. it does not correspond to any sent SubMsg")] InvalidReplyId { id: u64 }, + /// **Unreachable** - preserved for the (future) typed-deposit-info feature. #[error("reached the maximum of 255 different deposit types")] MaximumDepositTypesReached, + /// **Unreachable** - preserved for the (future) typed-deposit-info feature. #[error("compressed deposit info {typ} does not corresponds to any known type")] UnknownCompressedDepositInfoType { typ: u8 }, + /// **Unreachable** - preserved for the (future) typed-deposit-info feature. #[error("deposit info {typ} does not corresponds to any previously seen type")] UnknownDepositInfoType { typ: String }, + /// `DepositTicketBookFunds` with an `identity_key` that fails to bs58-decode + /// to exactly 32 bytes. Raised inside `Deposit::to_bytes` during + /// `save_deposit`. #[error("the provided ed25519 identity was malformed")] MalformedEd25519Identity, + /// `nym_network_defaults::TICKETBOOK_SIZE` has diverged from the value + /// snapshotted at instantiation in `Item`. Tripwire for + /// uncoordinated network-defaults bumps. #[error("the ticket book size has changed since the contract was created! This was not expected! It used to be {at_init} but it's {current} now! Please let the developers know ASAP!")] TicketBookSizeChanged { at_init: u64, current: u64 }, + /// `RequestRedemption` with a `commitment_bs58` that does not decode to a + /// 32-byte sha256 digest. #[error("the provided tickets redemption commitment is malformed")] MalformedRedemptionCommitment, + /// Always thrown by `ProposeToBlacklist` and `AddToBlacklist` until the + /// blacklist redesign lands. #[error("the account blacklisting hasn't been fully implemented yet")] UnimplementedBlacklisting, + /// `SetReducedDepositPrice` (or migration whitelist seeding) given a coin + /// whose denom does not match `Config::deposit_amount.denom`. #[error("reduced deposit must use the same denom as the default deposit (expected '{expected}', got '{got}')")] InvalidReducedDepositDenom { expected: String, got: String }, + /// `SetReducedDepositPrice` (or migration whitelist seeding) given a + /// reduced amount not strictly less than the current default. #[error( "reduced deposit amount ({reduced}) must be strictly less than the default ({default})" )] @@ -77,9 +116,13 @@ pub enum EcashContractError { default: cosmwasm_std::Uint128, }, + /// `RemoveReducedDepositPrice` invoked for an address with no current + /// reduced-deposit entry. #[error("address '{address}' does not have a custom reduced deposit price set")] NoReducedDepositPrice { address: String }, + /// `UpdateDefaultDepositValue` or `SetReducedDepositPrice` given an amount + /// below `nym_network_defaults::TICKETBOOK_SIZE`. #[error( "deposit amount ({amount}) must be at least the ticket book size ({ticket_book_size})" )] diff --git a/common/cosmwasm-smart-contracts/ecash-contract/src/event_attributes.rs b/common/cosmwasm-smart-contracts/ecash-contract/src/event_attributes.rs index 80f5daf68a..8d50174468 100644 --- a/common/cosmwasm-smart-contracts/ecash-contract/src/event_attributes.rs +++ b/common/cosmwasm-smart-contracts/ecash-contract/src/event_attributes.rs @@ -1,4 +1,7 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +/// Duplicate of `events::PROPOSAL_ID_ATTRIBUTE_NAME`. **Dead code**: not +/// referenced anywhere in the workspace today; preserved here pending a +/// follow-on cleanup. Use `events::PROPOSAL_ID_ATTRIBUTE_NAME` instead. pub const BANDWIDTH_PROPOSAL_ID: &str = "proposal_id"; diff --git a/common/cosmwasm-smart-contracts/ecash-contract/src/events.rs b/common/cosmwasm-smart-contracts/ecash-contract/src/events.rs index a1f243b151..5e8f7d2db0 100644 --- a/common/cosmwasm-smart-contracts/ecash-contract/src/events.rs +++ b/common/cosmwasm-smart-contracts/ecash-contract/src/events.rs @@ -1,9 +1,21 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -// event types +//! Event names and attribute keys emitted by the ecash contract. Renaming any +//! of these is a breaking change for indexers and downstream tooling. + +/// Event type emitted by every successful `DepositTicketBookFunds`. Carries a +/// single `deposit-id` attribute with the assigned id as a decimal string. pub const DEPOSITED_FUNDS_EVENT_TYPE: &str = "deposited-funds"; +/// Attribute key on the `deposited-funds` event: the newly assigned deposit id. pub const DEPOSIT_ID: &str = "deposit-id"; + +/// Name of the cosmwasm-std auto-generated event that carries handler +/// attributes (`updated_deposit`, `action`, `address`, `deposit`, +/// `proposal_id`). pub const WASM_EVENT_NAME: &str = "wasm"; + +/// Attribute key carrying the multisig-issued `proposal_id` on the `wasm` +/// event from the redemption-proposal reply handler. pub const PROPOSAL_ID_ATTRIBUTE_NAME: &str = "proposal_id"; diff --git a/common/cosmwasm-smart-contracts/ecash-contract/src/lib.rs b/common/cosmwasm-smart-contracts/ecash-contract/src/lib.rs index 5495094d70..e09ea9a9da 100644 --- a/common/cosmwasm-smart-contracts/ecash-contract/src/lib.rs +++ b/common/cosmwasm-smart-contracts/ecash-contract/src/lib.rs @@ -1,6 +1,12 @@ // Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +//! Shared types, messages, events, and errors for the ecash contract. +//! +//! Consumed by both the contract crate (`contracts/ecash`) and any off-chain +//! client (gateways, nym-api signers, indexers, validator-client). See +//! `openspec/specs/ecash-contract/spec.md` for the normative interface. + pub mod blacklist; pub mod counters; pub mod deposit; diff --git a/common/cosmwasm-smart-contracts/ecash-contract/src/msg.rs b/common/cosmwasm-smart-contracts/ecash-contract/src/msg.rs index 7ba734c294..fe37486234 100644 --- a/common/cosmwasm-smart-contracts/ecash-contract/src/msg.rs +++ b/common/cosmwasm-smart-contracts/ecash-contract/src/msg.rs @@ -15,100 +15,134 @@ use crate::reduced_deposit::WhitelistedAccountsResponse; #[cfg(feature = "schema")] use cosmwasm_schema::QueryResponses; +/// Instantiation payload. The sender of the instantiate transaction becomes the +/// contract admin; the three addresses are bech32-validated and persisted as +/// immutable cross-contract pointers (see spec requirement "Contract instantiation"). #[cw_serde] pub struct InstantiateMsg { + /// Cosmos SDK address reserved for the future pool-contract transition. + /// Stored in `Config` but never debited by the current contract. pub holding_account: String, + + /// cw3 multisig contract that gates `RedeemTickets` and (in the redesign) + /// blacklist proposals. Not updatable through any execute path. pub multisig_addr: String, + + /// cw4 group contract referenced by the (stubbed) blacklist proposal flow. pub group_addr: String, + + /// Default per-deposit price. The denom of this coin is the contract's + /// canonical denom for the rest of its lifetime. pub deposit_amount: Coin, } #[cw_serde] pub enum ExecuteMsg { - /// Used by clients to request ticket books from the signers - DepositTicketBookFunds { - identity_key: String, - }, + /// Submitted by clients to escrow funds and register a claimed ed25519 + /// identity key. Mints a sequential `deposit_id`. The contract does not + /// verify control of the identity key - that proof is checked off-chain by + /// nym-api signers at blind-sign time. + DepositTicketBookFunds { identity_key: String }, - /// Used by gateways to batch redeem tokens from the spent tickets + /// Submitted by gateways to request batch redemption of spent tickets. + /// Dispatches a `Propose` SubMsg to the multisig contract; the actual + /// transfer effect is gated behind multisig approval. RequestRedemption { commitment_bs58: String, number_of_tickets: u16, }, - /// The actual message that gets executed, after multisig votes, that transfers the ticket tokens into gateway's (and the holding) account - RedeemTickets { - n: u16, - gw: String, - }, + /// **Legacy / dead code.** Only callable by the multisig; bumps the + /// unredeemed-tickets counter and emits a `ticket_redemption` event with + /// `moved_to_holding_account = "false"`. No known consumer depends on the + /// side effects; candidate for removal in a follow-on breaking-schema + /// change. + RedeemTickets { n: u16, gw: String }, - UpdateAdmin { - admin: String, - }, + /// Transfer the contract admin role. Only the current admin may sign. + /// Dispatches via the cw_controllers `execute_update_admin` handshake. + UpdateAdmin { admin: String }, + /// Overwrite `Config::deposit_amount`. Only callable by the contract admin. + /// Rejects values below `nym_network_defaults::TICKETBOOK_SIZE` and trips + /// `TicketBookSizeChanged` if the snapshotted invariant has diverged from + /// the current crate constant. #[serde(alias = "update_deposit_value")] - UpdateDefaultDepositValue { - new_deposit: Coin, - }, + UpdateDefaultDepositValue { new_deposit: Coin }, /// Set (or overwrite) a reduced deposit price for a specific address. /// Only callable by the contract admin. - SetReducedDepositPrice { - address: String, - deposit: Coin, - }, + SetReducedDepositPrice { address: String, deposit: Coin }, /// Remove the reduced deposit price for a specific address, reverting them to /// the default price. Returns an error if the address has no custom price set. /// Only callable by the contract admin. - RemoveReducedDepositPrice { - address: String, - }, + RemoveReducedDepositPrice { address: String }, - // TODO: properly implement - ProposeToBlacklist { - public_key: String, - }, - AddToBlacklist { - public_key: String, - }, + /// **Stubbed**: always returns `EcashContractError::UnimplementedBlacklisting`. + /// Storage, reply handler, and helper paths exist but are unreachable from + /// the public ExecuteMsg surface. Preserved for the redesign. + ProposeToBlacklist { public_key: String }, + + /// **Stubbed**: always returns `EcashContractError::UnimplementedBlacklisting`. + AddToBlacklist { public_key: String }, } #[cw_serde] #[cfg_attr(feature = "schema", derive(QueryResponses))] pub enum QueryMsg { + /// Look up a blacklist entry by its bs58-encoded ed25519 public key. Always + /// returns `None` on a freshly deployed contract because the blacklist + /// execute paths are stubbed. #[cfg_attr(feature = "schema", returns(BlacklistedAccountResponse))] GetBlacklistedAccount { public_key: String }, + /// Paginated listing of blacklist entries. Always empty today (see stubbed + /// blacklist surface). Defaults: limit 50, max 75. #[cfg_attr(feature = "schema", returns(PagedBlacklistedAccountResponse))] GetBlacklistPaged { limit: Option, start_after: Option, }, + /// Default per-deposit price (`Config::deposit_amount`). The + /// `GetRequiredDepositAmount` aliases are kept for backwards compatibility. #[cfg_attr(feature = "schema", returns(Coin))] #[serde(alias = "get_required_deposit_amount")] #[serde(alias = "GetRequiredDepositAmount")] GetDefaultDepositAmount {}, + /// Per-address reduced deposit price override, if any. `None` for any + /// non-whitelisted address. #[cfg_attr(feature = "schema", returns(Option))] GetReducedDepositAmount { address: String }, + /// Enumerate every reduced-deposit whitelist entry in ascending address + /// order. Unpaginated by design (the whitelist is expected to stay small). #[cfg_attr(feature = "schema", returns(WhitelistedAccountsResponse))] GetAllWhitelistedAccounts {}, + /// Look up a deposit by id. Returns `{ id, deposit: None }` when the id has + /// not yet been assigned. #[cfg_attr(feature = "schema", returns(DepositResponse))] GetDeposit { deposit_id: u32 }, + /// Most recently assigned deposit (or `{ deposit: None }` on a fresh + /// contract). See `DepositStorage::latest_deposit`. #[cfg_attr(feature = "schema", returns(LatestDepositResponse))] GetLatestDeposit {}, + /// Paginated listing of deposits in ascending id order. Defaults: limit 50, + /// max 100. #[cfg_attr(feature = "schema", returns(PagedDepositsResponse))] GetDepositsPaged { limit: Option, start_after: Option, }, + /// Aggregate statistics: global totals + per-account custom-price + /// breakdowns. Reassembled in a single read pass from `PoolCounters` and + /// `DepositStatsStorage`. #[cfg_attr(feature = "schema", returns(DepositsStatistics))] GetDepositsStatistics {}, } diff --git a/common/cosmwasm-smart-contracts/ecash-contract/src/redeem_credential.rs b/common/cosmwasm-smart-contracts/ecash-contract/src/redeem_credential.rs index 76bf86f5a8..d6117e816a 100644 --- a/common/cosmwasm-smart-contracts/ecash-contract/src/redeem_credential.rs +++ b/common/cosmwasm-smart-contracts/ecash-contract/src/redeem_credential.rs @@ -1,5 +1,8 @@ // Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +/// Title used for the cw3 `Propose` message dispatched by `RequestRedemption`. +/// nym-api signers cross-check this exact string when validating that an +/// in-flight proposal originated from the ecash contract. // TODO: to be moved to multisig pub const BATCH_REDEMPTION_PROPOSAL_TITLE: &str = "ecash-redemption"; diff --git a/common/cosmwasm-smart-contracts/ecash-contract/src/reduced_deposit.rs b/common/cosmwasm-smart-contracts/ecash-contract/src/reduced_deposit.rs index 95f7355e24..8d78ac328f 100644 --- a/common/cosmwasm-smart-contracts/ecash-contract/src/reduced_deposit.rs +++ b/common/cosmwasm-smart-contracts/ecash-contract/src/reduced_deposit.rs @@ -4,12 +4,16 @@ use cosmwasm_schema::cw_serde; use cosmwasm_std::{Addr, Coin}; +/// Whitelist entry: an address and the reduced deposit price it may pay. +/// Persisted in the `"reduced_deposits"` storage map. #[cw_serde] pub struct WhitelistedAccount { pub address: Addr, pub deposit: Coin, } +/// Response shape for `GetAllWhitelistedAccounts`. Unpaginated - the whitelist +/// is expected to stay small. #[cw_serde] pub struct WhitelistedAccountsResponse { pub whitelisted_accounts: Vec, diff --git a/contracts/ecash/schema/nym-ecash.json b/contracts/ecash/schema/nym-ecash.json index 7bf0c27804..71f7a0c8f6 100644 --- a/contracts/ecash/schema/nym-ecash.json +++ b/contracts/ecash/schema/nym-ecash.json @@ -5,6 +5,7 @@ "instantiate": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "InstantiateMsg", + "description": "Instantiation payload. The sender of the instantiate transaction becomes the contract admin; the three addresses are bech32-validated and persisted as immutable cross-contract pointers (see spec requirement \"Contract instantiation\").", "type": "object", "required": [ "deposit_amount", @@ -14,15 +15,23 @@ ], "properties": { "deposit_amount": { - "$ref": "#/definitions/Coin" + "description": "Default per-deposit price. The denom of this coin is the contract's canonical denom for the rest of its lifetime.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] }, "group_addr": { + "description": "cw4 group contract referenced by the (stubbed) blacklist proposal flow.", "type": "string" }, "holding_account": { + "description": "Cosmos SDK address reserved for the future pool-contract transition. Stored in `Config` but never debited by the current contract.", "type": "string" }, "multisig_addr": { + "description": "cw3 multisig contract that gates `RedeemTickets` and (in the redesign) blacklist proposals. Not updatable through any execute path.", "type": "string" } }, @@ -55,7 +64,7 @@ "title": "ExecuteMsg", "oneOf": [ { - "description": "Used by clients to request ticket books from the signers", + "description": "Submitted by clients to escrow funds and register a claimed ed25519 identity key. Mints a sequential `deposit_id`. The contract does not verify control of the identity key - that proof is checked off-chain by nym-api signers at blind-sign time.", "type": "object", "required": [ "deposit_ticket_book_funds" @@ -77,7 +86,7 @@ "additionalProperties": false }, { - "description": "Used by gateways to batch redeem tokens from the spent tickets", + "description": "Submitted by gateways to request batch redemption of spent tickets. Dispatches a `Propose` SubMsg to the multisig contract; the actual transfer effect is gated behind multisig approval.", "type": "object", "required": [ "request_redemption" @@ -105,7 +114,7 @@ "additionalProperties": false }, { - "description": "The actual message that gets executed, after multisig votes, that transfers the ticket tokens into gateway's (and the holding) account", + "description": "**Legacy / dead code.** Only callable by the multisig; bumps the unredeemed-tickets counter and emits a `ticket_redemption` event with `moved_to_holding_account = \"false\"`. No known consumer depends on the side effects; candidate for removal in a follow-on breaking-schema change.", "type": "object", "required": [ "redeem_tickets" @@ -133,6 +142,7 @@ "additionalProperties": false }, { + "description": "Transfer the contract admin role. Only the current admin may sign. Dispatches via the cw_controllers `execute_update_admin` handshake.", "type": "object", "required": [ "update_admin" @@ -154,6 +164,7 @@ "additionalProperties": false }, { + "description": "Overwrite `Config::deposit_amount`. Only callable by the contract admin. Rejects values below `nym_network_defaults::TICKETBOOK_SIZE` and trips `TicketBookSizeChanged` if the snapshotted invariant has diverged from the current crate constant.", "type": "object", "required": [ "update_default_deposit_value" @@ -223,6 +234,7 @@ "additionalProperties": false }, { + "description": "**Stubbed**: always returns `EcashContractError::UnimplementedBlacklisting`. Storage, reply handler, and helper paths exist but are unreachable from the public ExecuteMsg surface. Preserved for the redesign.", "type": "object", "required": [ "propose_to_blacklist" @@ -244,6 +256,7 @@ "additionalProperties": false }, { + "description": "*Stubbed**: always returns `EcashContractError::UnimplementedBlacklisting`.", "type": "object", "required": [ "add_to_blacklist" @@ -293,6 +306,7 @@ "title": "QueryMsg", "oneOf": [ { + "description": "Look up a blacklist entry by its bs58-encoded ed25519 public key. Always returns `None` on a freshly deployed contract because the blacklist execute paths are stubbed.", "type": "object", "required": [ "get_blacklisted_account" @@ -314,6 +328,7 @@ "additionalProperties": false }, { + "description": "Paginated listing of blacklist entries. Always empty today (see stubbed blacklist surface). Defaults: limit 50, max 75.", "type": "object", "required": [ "get_blacklist_paged" @@ -343,6 +358,7 @@ "additionalProperties": false }, { + "description": "Default per-deposit price (`Config::deposit_amount`). The `GetRequiredDepositAmount` aliases are kept for backwards compatibility.", "type": "object", "required": [ "get_default_deposit_amount" @@ -356,6 +372,7 @@ "additionalProperties": false }, { + "description": "Per-address reduced deposit price override, if any. `None` for any non-whitelisted address.", "type": "object", "required": [ "get_reduced_deposit_amount" @@ -377,6 +394,7 @@ "additionalProperties": false }, { + "description": "Enumerate every reduced-deposit whitelist entry in ascending address order. Unpaginated by design (the whitelist is expected to stay small).", "type": "object", "required": [ "get_all_whitelisted_accounts" @@ -390,6 +408,7 @@ "additionalProperties": false }, { + "description": "Look up a deposit by id. Returns `{ id, deposit: None }` when the id has not yet been assigned.", "type": "object", "required": [ "get_deposit" @@ -413,6 +432,7 @@ "additionalProperties": false }, { + "description": "Most recently assigned deposit (or `{ deposit: None }` on a fresh contract). See `DepositStorage::latest_deposit`.", "type": "object", "required": [ "get_latest_deposit" @@ -426,6 +446,7 @@ "additionalProperties": false }, { + "description": "Paginated listing of deposits in ascending id order. Defaults: limit 50, max 100.", "type": "object", "required": [ "get_deposits_paged" @@ -457,6 +478,7 @@ "additionalProperties": false }, { + "description": "Aggregate statistics: global totals + per-account custom-price breakdowns. Reassembled in a single read pass from `PoolCounters` and `DepositStatsStorage`.", "type": "object", "required": [ "get_deposits_statistics" @@ -533,6 +555,7 @@ "get_all_whitelisted_accounts": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "WhitelistedAccountsResponse", + "description": "Response shape for `GetAllWhitelistedAccounts`. Unpaginated - the whitelist is expected to stay small.", "type": "object", "required": [ "whitelisted_accounts" @@ -572,6 +595,7 @@ "type": "string" }, "WhitelistedAccount": { + "description": "Whitelist entry: an address and the reduced deposit price it may pay. Persisted in the `\"reduced_deposits\"` storage map.", "type": "object", "required": [ "address", @@ -592,6 +616,7 @@ "get_blacklist_paged": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "PagedBlacklistedAccountResponse", + "description": "Page of blacklist entries returned by `GetBlacklistPaged`. Always empty on a freshly deployed contract.", "type": "object", "required": [ "accounts", @@ -620,6 +645,7 @@ "additionalProperties": false, "definitions": { "BlacklistedAccount": { + "description": "Public-key + metadata pair surfaced by `GetBlacklistedAccount` / `GetBlacklistPaged`. Always empty on a freshly deployed contract.", "type": "object", "required": [ "info", @@ -636,6 +662,7 @@ "additionalProperties": false }, "Blacklisting": { + "description": "Per-key blacklist record: the multisig proposal that approved it and the block height at which finalisation landed (None until finalised).", "type": "object", "required": [ "proposal_id" @@ -662,6 +689,7 @@ "get_blacklisted_account": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "BlacklistedAccountResponse", + "description": "Response shape for `GetBlacklistedAccount`. `account` is `None` for any key not present in the (currently always-empty) blacklist.", "type": "object", "properties": { "account": { @@ -678,6 +706,7 @@ "additionalProperties": false, "definitions": { "Blacklisting": { + "description": "Per-key blacklist record: the multisig proposal that approved it and the block height at which finalisation landed (None until finalised).", "type": "object", "required": [ "proposal_id" @@ -728,6 +757,7 @@ "get_deposit": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "DepositResponse", + "description": "Response shape for `GetDeposit { deposit_id }`. `deposit` is `None` when the id has not yet been assigned (`id >= total_deposits_made`).", "type": "object", "required": [ "id" @@ -752,6 +782,7 @@ "additionalProperties": false, "definitions": { "Deposit": { + "description": "Opaque on-chain record of a deposit: the depositor-claimed bs58-encoded ed25519 identity public key. The contract does not verify control of the corresponding private key.", "type": "object", "required": [ "bs58_encoded_ed25519_pubkey" @@ -768,6 +799,7 @@ "get_deposits_paged": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "PagedDepositsResponse", + "description": "Page of deposits returned by `GetDepositsPaged`. `start_next_after` is the id of the last returned entry; pass it as the next call's `start_after`.", "type": "object", "required": [ "deposits" @@ -792,6 +824,7 @@ "additionalProperties": false, "definitions": { "Deposit": { + "description": "Opaque on-chain record of a deposit: the depositor-claimed bs58-encoded ed25519 identity public key. The contract does not verify control of the corresponding private key.", "type": "object", "required": [ "bs58_encoded_ed25519_pubkey" @@ -804,6 +837,7 @@ "additionalProperties": false }, "DepositData": { + "description": "`(deposit_id, deposit)` pair surfaced by the latest-deposit and paginated deposit queries.", "type": "object", "required": [ "deposit", @@ -919,6 +953,7 @@ "get_latest_deposit": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "LatestDepositResponse", + "description": "Response shape for `GetLatestDeposit`. `deposit` is `None` on a freshly deployed contract.", "type": "object", "properties": { "deposit": { @@ -935,6 +970,7 @@ "additionalProperties": false, "definitions": { "Deposit": { + "description": "Opaque on-chain record of a deposit: the depositor-claimed bs58-encoded ed25519 identity public key. The contract does not verify control of the corresponding private key.", "type": "object", "required": [ "bs58_encoded_ed25519_pubkey" @@ -947,6 +983,7 @@ "additionalProperties": false }, "DepositData": { + "description": "`(deposit_id, deposit)` pair surfaced by the latest-deposit and paginated deposit queries.", "type": "object", "required": [ "deposit", diff --git a/contracts/ecash/schema/raw/execute.json b/contracts/ecash/schema/raw/execute.json index 3f64fb7f29..766d010bd4 100644 --- a/contracts/ecash/schema/raw/execute.json +++ b/contracts/ecash/schema/raw/execute.json @@ -3,7 +3,7 @@ "title": "ExecuteMsg", "oneOf": [ { - "description": "Used by clients to request ticket books from the signers", + "description": "Submitted by clients to escrow funds and register a claimed ed25519 identity key. Mints a sequential `deposit_id`. The contract does not verify control of the identity key - that proof is checked off-chain by nym-api signers at blind-sign time.", "type": "object", "required": [ "deposit_ticket_book_funds" @@ -25,7 +25,7 @@ "additionalProperties": false }, { - "description": "Used by gateways to batch redeem tokens from the spent tickets", + "description": "Submitted by gateways to request batch redemption of spent tickets. Dispatches a `Propose` SubMsg to the multisig contract; the actual transfer effect is gated behind multisig approval.", "type": "object", "required": [ "request_redemption" @@ -53,7 +53,7 @@ "additionalProperties": false }, { - "description": "The actual message that gets executed, after multisig votes, that transfers the ticket tokens into gateway's (and the holding) account", + "description": "**Legacy / dead code.** Only callable by the multisig; bumps the unredeemed-tickets counter and emits a `ticket_redemption` event with `moved_to_holding_account = \"false\"`. No known consumer depends on the side effects; candidate for removal in a follow-on breaking-schema change.", "type": "object", "required": [ "redeem_tickets" @@ -81,6 +81,7 @@ "additionalProperties": false }, { + "description": "Transfer the contract admin role. Only the current admin may sign. Dispatches via the cw_controllers `execute_update_admin` handshake.", "type": "object", "required": [ "update_admin" @@ -102,6 +103,7 @@ "additionalProperties": false }, { + "description": "Overwrite `Config::deposit_amount`. Only callable by the contract admin. Rejects values below `nym_network_defaults::TICKETBOOK_SIZE` and trips `TicketBookSizeChanged` if the snapshotted invariant has diverged from the current crate constant.", "type": "object", "required": [ "update_default_deposit_value" @@ -171,6 +173,7 @@ "additionalProperties": false }, { + "description": "**Stubbed**: always returns `EcashContractError::UnimplementedBlacklisting`. Storage, reply handler, and helper paths exist but are unreachable from the public ExecuteMsg surface. Preserved for the redesign.", "type": "object", "required": [ "propose_to_blacklist" @@ -192,6 +195,7 @@ "additionalProperties": false }, { + "description": "*Stubbed**: always returns `EcashContractError::UnimplementedBlacklisting`.", "type": "object", "required": [ "add_to_blacklist" diff --git a/contracts/ecash/schema/raw/instantiate.json b/contracts/ecash/schema/raw/instantiate.json index 540a22ab4e..bbf1f393cf 100644 --- a/contracts/ecash/schema/raw/instantiate.json +++ b/contracts/ecash/schema/raw/instantiate.json @@ -1,6 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "title": "InstantiateMsg", + "description": "Instantiation payload. The sender of the instantiate transaction becomes the contract admin; the three addresses are bech32-validated and persisted as immutable cross-contract pointers (see spec requirement \"Contract instantiation\").", "type": "object", "required": [ "deposit_amount", @@ -10,15 +11,23 @@ ], "properties": { "deposit_amount": { - "$ref": "#/definitions/Coin" + "description": "Default per-deposit price. The denom of this coin is the contract's canonical denom for the rest of its lifetime.", + "allOf": [ + { + "$ref": "#/definitions/Coin" + } + ] }, "group_addr": { + "description": "cw4 group contract referenced by the (stubbed) blacklist proposal flow.", "type": "string" }, "holding_account": { + "description": "Cosmos SDK address reserved for the future pool-contract transition. Stored in `Config` but never debited by the current contract.", "type": "string" }, "multisig_addr": { + "description": "cw3 multisig contract that gates `RedeemTickets` and (in the redesign) blacklist proposals. Not updatable through any execute path.", "type": "string" } }, diff --git a/contracts/ecash/schema/raw/query.json b/contracts/ecash/schema/raw/query.json index 00b2db97bb..bd4b0e4dd8 100644 --- a/contracts/ecash/schema/raw/query.json +++ b/contracts/ecash/schema/raw/query.json @@ -3,6 +3,7 @@ "title": "QueryMsg", "oneOf": [ { + "description": "Look up a blacklist entry by its bs58-encoded ed25519 public key. Always returns `None` on a freshly deployed contract because the blacklist execute paths are stubbed.", "type": "object", "required": [ "get_blacklisted_account" @@ -24,6 +25,7 @@ "additionalProperties": false }, { + "description": "Paginated listing of blacklist entries. Always empty today (see stubbed blacklist surface). Defaults: limit 50, max 75.", "type": "object", "required": [ "get_blacklist_paged" @@ -53,6 +55,7 @@ "additionalProperties": false }, { + "description": "Default per-deposit price (`Config::deposit_amount`). The `GetRequiredDepositAmount` aliases are kept for backwards compatibility.", "type": "object", "required": [ "get_default_deposit_amount" @@ -66,6 +69,7 @@ "additionalProperties": false }, { + "description": "Per-address reduced deposit price override, if any. `None` for any non-whitelisted address.", "type": "object", "required": [ "get_reduced_deposit_amount" @@ -87,6 +91,7 @@ "additionalProperties": false }, { + "description": "Enumerate every reduced-deposit whitelist entry in ascending address order. Unpaginated by design (the whitelist is expected to stay small).", "type": "object", "required": [ "get_all_whitelisted_accounts" @@ -100,6 +105,7 @@ "additionalProperties": false }, { + "description": "Look up a deposit by id. Returns `{ id, deposit: None }` when the id has not yet been assigned.", "type": "object", "required": [ "get_deposit" @@ -123,6 +129,7 @@ "additionalProperties": false }, { + "description": "Most recently assigned deposit (or `{ deposit: None }` on a fresh contract). See `DepositStorage::latest_deposit`.", "type": "object", "required": [ "get_latest_deposit" @@ -136,6 +143,7 @@ "additionalProperties": false }, { + "description": "Paginated listing of deposits in ascending id order. Defaults: limit 50, max 100.", "type": "object", "required": [ "get_deposits_paged" @@ -167,6 +175,7 @@ "additionalProperties": false }, { + "description": "Aggregate statistics: global totals + per-account custom-price breakdowns. Reassembled in a single read pass from `PoolCounters` and `DepositStatsStorage`.", "type": "object", "required": [ "get_deposits_statistics" diff --git a/contracts/ecash/schema/raw/response_to_get_all_whitelisted_accounts.json b/contracts/ecash/schema/raw/response_to_get_all_whitelisted_accounts.json index 256867acb3..39d0c0a1ed 100644 --- a/contracts/ecash/schema/raw/response_to_get_all_whitelisted_accounts.json +++ b/contracts/ecash/schema/raw/response_to_get_all_whitelisted_accounts.json @@ -1,6 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "title": "WhitelistedAccountsResponse", + "description": "Response shape for `GetAllWhitelistedAccounts`. Unpaginated - the whitelist is expected to stay small.", "type": "object", "required": [ "whitelisted_accounts" @@ -40,6 +41,7 @@ "type": "string" }, "WhitelistedAccount": { + "description": "Whitelist entry: an address and the reduced deposit price it may pay. Persisted in the `\"reduced_deposits\"` storage map.", "type": "object", "required": [ "address", diff --git a/contracts/ecash/schema/raw/response_to_get_blacklist_paged.json b/contracts/ecash/schema/raw/response_to_get_blacklist_paged.json index fd40f5ccef..08ed947196 100644 --- a/contracts/ecash/schema/raw/response_to_get_blacklist_paged.json +++ b/contracts/ecash/schema/raw/response_to_get_blacklist_paged.json @@ -1,6 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "title": "PagedBlacklistedAccountResponse", + "description": "Page of blacklist entries returned by `GetBlacklistPaged`. Always empty on a freshly deployed contract.", "type": "object", "required": [ "accounts", @@ -29,6 +30,7 @@ "additionalProperties": false, "definitions": { "BlacklistedAccount": { + "description": "Public-key + metadata pair surfaced by `GetBlacklistedAccount` / `GetBlacklistPaged`. Always empty on a freshly deployed contract.", "type": "object", "required": [ "info", @@ -45,6 +47,7 @@ "additionalProperties": false }, "Blacklisting": { + "description": "Per-key blacklist record: the multisig proposal that approved it and the block height at which finalisation landed (None until finalised).", "type": "object", "required": [ "proposal_id" diff --git a/contracts/ecash/schema/raw/response_to_get_blacklisted_account.json b/contracts/ecash/schema/raw/response_to_get_blacklisted_account.json index 64873f42cd..8938398065 100644 --- a/contracts/ecash/schema/raw/response_to_get_blacklisted_account.json +++ b/contracts/ecash/schema/raw/response_to_get_blacklisted_account.json @@ -1,6 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "title": "BlacklistedAccountResponse", + "description": "Response shape for `GetBlacklistedAccount`. `account` is `None` for any key not present in the (currently always-empty) blacklist.", "type": "object", "properties": { "account": { @@ -17,6 +18,7 @@ "additionalProperties": false, "definitions": { "Blacklisting": { + "description": "Per-key blacklist record: the multisig proposal that approved it and the block height at which finalisation landed (None until finalised).", "type": "object", "required": [ "proposal_id" diff --git a/contracts/ecash/schema/raw/response_to_get_deposit.json b/contracts/ecash/schema/raw/response_to_get_deposit.json index a0f7ffbff8..956d8dc6b5 100644 --- a/contracts/ecash/schema/raw/response_to_get_deposit.json +++ b/contracts/ecash/schema/raw/response_to_get_deposit.json @@ -1,6 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "title": "DepositResponse", + "description": "Response shape for `GetDeposit { deposit_id }`. `deposit` is `None` when the id has not yet been assigned (`id >= total_deposits_made`).", "type": "object", "required": [ "id" @@ -25,6 +26,7 @@ "additionalProperties": false, "definitions": { "Deposit": { + "description": "Opaque on-chain record of a deposit: the depositor-claimed bs58-encoded ed25519 identity public key. The contract does not verify control of the corresponding private key.", "type": "object", "required": [ "bs58_encoded_ed25519_pubkey" diff --git a/contracts/ecash/schema/raw/response_to_get_deposits_paged.json b/contracts/ecash/schema/raw/response_to_get_deposits_paged.json index d93401a3ba..44e2e5dad8 100644 --- a/contracts/ecash/schema/raw/response_to_get_deposits_paged.json +++ b/contracts/ecash/schema/raw/response_to_get_deposits_paged.json @@ -1,6 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "title": "PagedDepositsResponse", + "description": "Page of deposits returned by `GetDepositsPaged`. `start_next_after` is the id of the last returned entry; pass it as the next call's `start_after`.", "type": "object", "required": [ "deposits" @@ -25,6 +26,7 @@ "additionalProperties": false, "definitions": { "Deposit": { + "description": "Opaque on-chain record of a deposit: the depositor-claimed bs58-encoded ed25519 identity public key. The contract does not verify control of the corresponding private key.", "type": "object", "required": [ "bs58_encoded_ed25519_pubkey" @@ -37,6 +39,7 @@ "additionalProperties": false }, "DepositData": { + "description": "`(deposit_id, deposit)` pair surfaced by the latest-deposit and paginated deposit queries.", "type": "object", "required": [ "deposit", diff --git a/contracts/ecash/schema/raw/response_to_get_latest_deposit.json b/contracts/ecash/schema/raw/response_to_get_latest_deposit.json index 016a159498..f08e04cace 100644 --- a/contracts/ecash/schema/raw/response_to_get_latest_deposit.json +++ b/contracts/ecash/schema/raw/response_to_get_latest_deposit.json @@ -1,6 +1,7 @@ { "$schema": "http://json-schema.org/draft-07/schema#", "title": "LatestDepositResponse", + "description": "Response shape for `GetLatestDeposit`. `deposit` is `None` on a freshly deployed contract.", "type": "object", "properties": { "deposit": { @@ -17,6 +18,7 @@ "additionalProperties": false, "definitions": { "Deposit": { + "description": "Opaque on-chain record of a deposit: the depositor-claimed bs58-encoded ed25519 identity public key. The contract does not verify control of the corresponding private key.", "type": "object", "required": [ "bs58_encoded_ed25519_pubkey" @@ -29,6 +31,7 @@ "additionalProperties": false }, "DepositData": { + "description": "`(deposit_id, deposit)` pair surfaced by the latest-deposit and paginated deposit queries.", "type": "object", "required": [ "deposit", diff --git a/contracts/ecash/src/constants.rs b/contracts/ecash/src/constants.rs index ce5ff212fe..958d031421 100644 --- a/contracts/ecash/src/constants.rs +++ b/contracts/ecash/src/constants.rs @@ -1,5 +1,15 @@ // Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +//! Reply-id constants for the contract's reply dispatcher. Both ids are part +//! of the public contract surface - changing them between versions invalidates +//! any in-flight submessage. + +/// Reply id for the cw3 propose dispatched by the (stubbed) blacklist flow. +/// Wired but unreachable from the public ExecuteMsg surface today. pub const BLACKLIST_PROPOSAL_REPLY_ID: u64 = 7759; + +/// Reply id for the cw3 propose dispatched by `RequestRedemption`. The handler +/// captures the multisig-issued `proposal_id` and re-exposes it as the +/// response data. pub const REDEMPTION_PROPOSAL_REPLY_ID: u64 = 2137; diff --git a/contracts/ecash/src/contract/helpers.rs b/contracts/ecash/src/contract/helpers.rs index cb7acde076..a75ebab062 100644 --- a/contracts/ecash/src/contract/helpers.rs +++ b/contracts/ecash/src/contract/helpers.rs @@ -11,12 +11,21 @@ use nym_multisig_contract_common::msg::QueryMsg as MultisigQueryMsg; use nym_network_defaults::TICKETBOOK_SIZE; use sylvia::ctx::ExecCtx; +/// Snapshot of network-defaults values that the contract considers immutable +/// over its lifetime. Persisted at the `"expected_invariants"` storage key on +/// instantiation; every priced operation cross-checks the snapshot against +/// the current crate constant. #[cw_serde] pub(crate) struct Invariants { + /// `nym_network_defaults::TICKETBOOK_SIZE` at instantiation time. Mismatch + /// against the live constant trips `TicketBookSizeChanged`. pub(crate) ticket_book_size: u64, } impl NymEcashContract { + /// Return `nym_network_defaults::TICKETBOOK_SIZE` if it matches the value + /// snapshotted at instantiation; otherwise surface `TicketBookSizeChanged` + /// so the caller halts before any state mutation. pub(crate) fn get_ticketbook_size( &self, storage: &dyn Storage, diff --git a/contracts/ecash/src/contract/mod.rs b/contracts/ecash/src/contract/mod.rs index 78b415c457..694aaf6be5 100644 --- a/contracts/ecash/src/contract/mod.rs +++ b/contracts/ecash/src/contract/mod.rs @@ -76,6 +76,9 @@ impl NymEcashContract { } } + /// One-shot contract setup. Persists the cross-contract pointers, snapshots + /// the ticketbook-size invariant, zero-initialises the pool counters and + /// default-tier stats, and records the cw2 version + build metadata. #[sv::msg(instantiate)] pub fn instantiate( &self, @@ -144,6 +147,8 @@ impl NymEcashContract { /*================== ======QUERIES======= ==================*/ + /// Paginated listing of blacklist entries. Always empty today - see the + /// stubbed blacklist requirement in the spec. #[sv::msg(query)] pub fn get_blacklist_paged( &self, @@ -175,6 +180,8 @@ impl NymEcashContract { )) } + /// Single-key blacklist lookup. Always returns `None` on a freshly deployed + /// contract because the blacklist execute surface is stubbed. #[sv::msg(query)] pub fn get_blacklisted_account( &self, @@ -185,6 +192,7 @@ impl NymEcashContract { Ok(BlacklistedAccountResponse::new(account)) } + /// Default per-deposit price (`Config::deposit_amount`). #[sv::msg(query)] pub fn get_default_deposit_amount(&self, ctx: QueryCtx) -> StdResult { let deposit_amount = self.config.load(ctx.deps.storage)?.deposit_amount; @@ -192,12 +200,16 @@ impl NymEcashContract { Ok(deposit_amount) } + /// Backwards-compatible alias for `get_default_deposit_amount`. Returns the + /// same value; clients picking either name see identical behaviour. // Poor man's alias for backwards compatibility as sv::attr didn't seem to work #[sv::msg(query)] pub fn get_required_deposit_amount(&self, ctx: QueryCtx) -> StdResult { self.get_default_deposit_amount(ctx) } + /// Per-address reduced deposit price override. `None` for any + /// non-whitelisted sender. #[sv::msg(query)] pub fn get_reduced_deposit_amount( &self, @@ -210,6 +222,8 @@ impl NymEcashContract { Ok(deposit_amount) } + /// Enumerate every reduced-deposit whitelist entry. Unpaginated - the + /// whitelist is expected to stay small. #[sv::msg(query)] pub fn get_all_whitelisted_accounts( &self, @@ -229,6 +243,8 @@ impl NymEcashContract { }) } + /// Look up a deposit by id. Returns `{ id, deposit: None }` when the id + /// has not yet been assigned. #[sv::msg(query)] pub fn get_deposit( &self, @@ -241,6 +257,8 @@ impl NymEcashContract { }) } + /// Most recently assigned deposit, or `{ deposit: None }` on a fresh + /// contract. See `DepositStorage::latest_deposit`. #[sv::msg(query)] pub fn get_latest_deposit( &self, @@ -260,6 +278,8 @@ impl NymEcashContract { }) } + /// Paginated listing of deposits in ascending id order. Defaults to a + /// limit of 50, clamped at 100. #[sv::msg(query)] pub fn get_deposits_paged( &self, @@ -288,6 +308,8 @@ impl NymEcashContract { }) } + /// Aggregate statistics - global totals plus per-account custom-price + /// breakdowns. Single read pass over `PoolCounters` and the stats storage. #[sv::msg(query)] pub fn get_deposits_statistics( &self, @@ -326,6 +348,9 @@ impl NymEcashContract { ======EXECUTIONS======= =====================*/ + /// Submit a deposit. Classifies the sent amount (default → reduced → + /// `WrongAmount`), bumps the relevant counters, persists the deposit, and + /// emits a `deposited-funds` event with the assigned id. #[sv::msg(exec)] pub fn deposit_ticket_book_funds( &self, @@ -390,6 +415,10 @@ impl NymEcashContract { .set_data(deposit_id.to_be_bytes())) } + /// Dispatch a multisig `Propose` SubMsg for batch ticket redemption. + /// Validates `commitment_bs58` decodes to a 32-byte sha256 digest; the + /// actual transfer happens (via the embedded `RedeemTickets`) only after + /// the multisig approves. #[sv::msg(exec)] pub fn request_redemption( &self, @@ -409,8 +438,10 @@ impl NymEcashContract { Ok(Response::new().add_submessage(msg)) } - /// Old legacy method for requesting ticket redemption by moving them into the holding accounts - /// currently only executed by legacy gateways + /// **Dead code.** Legacy multisig-gated redemption that bumps a counter + /// and emits a `ticket_redemption` event with `moved_to_holding_account = + /// "false"`. No known consumer depends on the side effects; candidate for + /// removal in a follow-on breaking-schema change. #[sv::msg(exec)] pub fn redeem_tickets( &self, @@ -438,6 +469,10 @@ impl NymEcashContract { )) } + /// Transfer the contract admin role. Dispatches via the cw_controllers + /// `execute_update_admin` handshake; the sender-equality check happens + /// inside that call. The handler always forwards `Some(new_admin)` - + /// admin renunciation is not exposed. #[sv::msg(exec)] pub fn update_admin( &self, @@ -452,6 +487,10 @@ impl NymEcashContract { .execute_update_admin(ctx.deps, ctx.info, Some(new_admin))?) } + /// Overwrite `Config::deposit_amount`. Admin-gated; trips + /// `TicketBookSizeChanged` if the snapshotted invariant diverged from the + /// crate constant, and `DepositBelowTicketBookSize` if the new amount is + /// below `TICKETBOOK_SIZE`. #[sv::msg(exec)] pub fn update_default_deposit_value( &self, @@ -479,6 +518,10 @@ impl NymEcashContract { Ok(Response::new().add_attribute("updated_deposit", deposit_str)) } + /// Validate and persist a reduced-deposit entry. Shared between + /// `SetReducedDepositPrice` and migration whitelist seeding; enforces + /// matching denom, strictly-less-than-default amount, and amount at least + /// the snapshotted ticketbook size. pub(crate) fn add_reduced_deposit_address( &self, deps: DepsMut, @@ -513,6 +556,8 @@ impl NymEcashContract { Ok(()) } + /// Set or overwrite the reduced-deposit price for a single address. + /// Admin-gated; delegates validation to `add_reduced_deposit_address`. #[sv::msg(exec)] pub fn set_reduced_deposit_price( &self, @@ -534,7 +579,7 @@ impl NymEcashContract { /// Removes the reduced deposit price for a given address, reverting them to /// the default deposit amount. This is safe to call even if the address has - /// already deposited at the reduced price — their next deposit will simply + /// already deposited at the reduced price - their next deposit will simply /// use the default price. Historical deposit statistics are not affected. #[sv::msg(exec)] pub fn remove_reduced_deposit_price( @@ -558,6 +603,9 @@ impl NymEcashContract { .add_attribute("address", address)) } + /// **Stubbed.** Always returns `UnimplementedBlacklisting`. The + /// commented-out body shows the intended group-gated propose flow for the + /// blacklist redesign. #[sv::msg(exec)] pub fn propose_to_blacklist( &self, @@ -587,6 +635,9 @@ impl NymEcashContract { // } } + /// **Stubbed.** Always returns `UnimplementedBlacklisting`. The + /// commented-out body shows the intended multisig-gated finalisation for + /// the blacklist redesign. #[sv::msg(exec)] pub fn add_to_blacklist( &self, @@ -611,6 +662,9 @@ impl NymEcashContract { /*===================== =========REPLY========= =====================*/ + /// Dispatch reply messages by id. Surfaces `InvalidReplyId` for any id + /// not matching `BLACKLIST_PROPOSAL_REPLY_ID` or + /// `REDEMPTION_PROPOSAL_REPLY_ID`. #[sv::msg(reply)] #[allow(deprecated)] pub fn reply( @@ -627,6 +681,9 @@ impl NymEcashContract { } } + /// Reply handler for the (currently dead) blacklist propose flow. + /// Reachable from the dispatcher in theory but no public ExecuteMsg path + /// dispatches a SubMsg with `BLACKLIST_PROPOSAL_REPLY_ID` today. #[allow(deprecated)] fn handle_blacklist_proposal_reply( &self, @@ -647,6 +704,9 @@ impl NymEcashContract { Ok(Response::new().add_attribute(PROPOSAL_ID_ATTRIBUTE_NAME, proposal_id.to_string())) } + /// Reply handler for the redemption propose flow. Captures the multisig + /// `proposal_id` from the SubMsg result and re-exposes it as the response + /// `set_data` payload (big-endian `u64`). #[allow(deprecated)] fn handle_redemption_proposal_reply( &self, @@ -664,6 +724,10 @@ impl NymEcashContract { /*===================== =======MIGRATION======= =====================*/ + /// Migration entry point. Refreshes build metadata, gates against + /// downgrades via `cw2::ensure_from_older_version`, and runs + /// `add_tiered_pricing` to backfill the default-tier stats and seed the + /// whitelist atomically. #[sv::msg(migrate)] pub fn migrate( &self, diff --git a/contracts/ecash/src/contract/queued_migrations.rs b/contracts/ecash/src/contract/queued_migrations.rs index 284b8bf81c..5e88b39d43 100644 --- a/contracts/ecash/src/contract/queued_migrations.rs +++ b/contracts/ecash/src/contract/queued_migrations.rs @@ -6,6 +6,11 @@ use cosmwasm_std::DepsMut; use nym_ecash_contract_common::msg::WhitelistedDeposit; use nym_ecash_contract_common::EcashContractError; +/// One-way migration that introduces tiered pricing. Backfills the +/// default-tier stats accumulators from the pre-migration totals (since every +/// pre-migration deposit was at the single default price) and seeds the +/// whitelist. Re-running on already-migrated state would clobber the default +/// counters with figures that include custom-price deposits. pub fn add_tiered_pricing( mut deps: DepsMut, initial_whitelist: Vec, @@ -101,7 +106,7 @@ mod tests { fn migration_with_no_prior_deposits_initialises_stats_to_zero() { let mut deps = mock_dependencies(); - // No deposit_id_counter saved — contract never had a deposit. + // No deposit_id_counter saved - contract never had a deposit. save_pool_counters(deps.as_mut().storage, 0); add_tiered_pricing(deps.as_mut(), vec![]).unwrap(); @@ -249,7 +254,7 @@ mod tests { save_pool_counters(deps.as_mut().storage, 0); save_config_and_invariants(&mut deps); - // Equal to default — should fail + // Equal to default - should fail let whitelist = vec![WhitelistedDeposit { address: deps.api.addr_make("alice").to_string(), deposit: coin(DEFAULT_DEPOSIT, DENOM), @@ -264,7 +269,7 @@ mod tests { } ); - // Greater than default — should also fail + // Greater than default - should also fail let whitelist = vec![WhitelistedDeposit { address: deps.api.addr_make("alice").to_string(), deposit: coin(DEFAULT_DEPOSIT + 1, DENOM), diff --git a/contracts/ecash/src/contract/test.rs b/contracts/ecash/src/contract/test.rs index cdf79f6195..847ba7a7eb 100644 --- a/contracts/ecash/src/contract/test.rs +++ b/contracts/ecash/src/contract/test.rs @@ -475,7 +475,7 @@ mod tests { "GLdR2NRVZBiCoCbv4fNqt9wUJZAnNjGXHkx3TjVAUzrK".to_string(), )?; - // alice deposits at the default price — should be treated as a normal deposit + // alice deposits at the default price - should be treated as a normal deposit let alice_info = message_info(&alice, &[coin(75_000_000, TEST_DENOM)]); CONTRACT.deposit_ticket_book_funds( test.exec_ctx(alice_info), diff --git a/contracts/ecash/src/deposit.rs b/contracts/ecash/src/deposit.rs index f71b23a55d..62ce15a689 100644 --- a/contracts/ecash/src/deposit.rs +++ b/contracts/ecash/src/deposit.rs @@ -7,6 +7,10 @@ use nym_ecash_contract_common::deposit::DepositId; use nym_ecash_contract_common::{deposit::Deposit, EcashContractError}; use std::ops::Deref; +/// Sequential-id-keyed deposit store. Deposits live under the `"deposit"` +/// raw-bytes namespace (32-byte ed25519 pubkeys, not a `Map`); the +/// `"deposit_ids"` `Item` holds the **next** free id, which after `N` +/// deposits equals `N`. pub(crate) struct DepositStorage { pub(crate) deposit_id_counter: Item, pub(crate) deposits: StoredDeposits, @@ -20,13 +24,17 @@ impl DepositStorage { } } + /// Returns the id of the most recently assigned deposit, or `None` if no deposit has ever been made. + /// + /// The counter stores the *next* available id, so the latest assigned id is `counter - 1`. pub fn latest_deposit( &self, storage: &dyn Storage, ) -> Result, EcashContractError> { - self.deposit_id_counter - .may_load(storage) - .map_err(Into::into) + let Some(counter) = self.deposit_id_counter.may_load(storage)? else { + return Ok(None); + }; + Ok(counter.checked_sub(1)) } /// Returns the total number of deposits ever made. @@ -44,6 +52,10 @@ impl DepositStorage { Ok(id) } + /// Assign the next sequential id, persist the deposit's 32-byte raw ed25519 + /// pubkey under the `"deposit"` namespace, and return the new id. Surfaces + /// `MalformedEd25519Identity` when the supplied bs58 string does not + /// decode to exactly 32 bytes. pub fn save_deposit( &self, storage: &mut dyn Storage, @@ -61,6 +73,8 @@ impl DepositStorage { Ok(id) } + /// Load the deposit at `id`. Returns `None` when the id has not yet been + /// assigned. pub fn try_load_by_id( &self, storage: &dyn Storage, @@ -94,7 +108,9 @@ impl DepositStorage { } } -// a helper structure for storing deposits to bypass json serialisation and use more efficient and compact representation +/// Raw-bytes reader/writer for the `"deposit"` storage namespace. Bypasses +/// `cw_storage_plus::Map` to store deposits as exactly 32 raw bytes per +/// entry (vs. ~44 bytes for the JSON-serialised bs58 representation). pub(crate) struct StoredDeposits; impl StoredDeposits { @@ -138,14 +154,14 @@ mod tests { let _ = storage.next_id(deps.as_mut().storage)?; - // is correctly incremented for each subsequent id + // first deposit got id 0; latest_deposit returns Some(0) let second = storage.latest_deposit(deps.as_ref().storage)?; - assert_eq!(second, Some(1)); + assert_eq!(second, Some(0)); let _ = storage.next_id(deps.as_mut().storage)?; let third = storage.latest_deposit(deps.as_ref().storage)?; - assert_eq!(third, Some(2)); + assert_eq!(third, Some(1)); Ok(()) } diff --git a/contracts/ecash/src/deposit_stats.rs b/contracts/ecash/src/deposit_stats.rs index 3dcc935c28..da022d7c3e 100644 --- a/contracts/ecash/src/deposit_stats.rs +++ b/contracts/ecash/src/deposit_stats.rs @@ -6,6 +6,10 @@ use cw_storage_plus::{Item, Map}; use nym_ecash_contract_common::EcashContractError; use std::collections::HashMap; +/// Tier-stratified deposit accounting. Maintains the invariant +/// `default_count + sum(custom_count_per_account) == total_deposits_made`. +/// Any code that writes to the `"deposit"` namespace MUST go through +/// `new_default_deposit` / `new_reduced_deposit` or it breaks the invariant. pub(crate) struct DepositStatsStorage { /// Total deposits performed with the default price pub(crate) deposits_with_default_price: Item, @@ -30,6 +34,9 @@ impl DepositStatsStorage { } } + /// Bump the global default-price counter + amount accumulator. Called by + /// `DepositTicketBookFunds` whenever the sender paid the default amount + /// (regardless of whether they are also whitelisted for a reduced price). pub(crate) fn new_default_deposit( &self, store: &mut dyn Storage, @@ -47,6 +54,9 @@ impl DepositStatsStorage { Ok(()) } + /// Bump the per-account custom-price counter + amount accumulator. Called + /// by `DepositTicketBookFunds` when a whitelisted sender paid their + /// configured reduced amount. pub(crate) fn new_reduced_deposit( &self, store: &mut dyn Storage, diff --git a/contracts/ecash/src/helpers.rs b/contracts/ecash/src/helpers.rs index ec313af2a6..60b2d35610 100644 --- a/contracts/ecash/src/helpers.rs +++ b/contracts/ecash/src/helpers.rs @@ -18,28 +18,43 @@ use serde::{Deserialize, Serialize}; pub(crate) const CONTRACT_NAME: &str = "crate:nym-ecash"; pub(crate) const CONTRACT_VERSION: &str = env!("CARGO_PKG_VERSION"); +/// Runtime configuration persisted at the `"config"` storage key. Set on +/// instantiation; the only field mutable through an execute path is +/// `deposit_amount` (via `UpdateDefaultDepositValue`). #[derive(Serialize, Deserialize, Clone, Debug)] pub struct Config { + /// cw4 group contract referenced by the (stubbed) blacklist proposal flow. pub group_addr: Cw4Contract, + + /// Cosmos SDK address reserved for the future pool-contract transition. + /// Currently never debited. pub holding_account: Addr, - /// Specifies the expected default deposit amount if the sender is not in the whitelisted set. + /// Default per-deposit price. Whitelisted senders may pay this *or* their + /// per-account reduced amount; everyone else must pay this exact value. #[serde(alias = "default_deposit_amount")] pub deposit_amount: Coin, } -//type aliases for easier reasoning +/// Blacklist storage key - a bs58-encoded ed25519 public key. pub(crate) type BlacklistKey = String; + +/// Multisig-issued `proposal_id` returned via the reply pipeline. pub(crate) type ProposalId = u64; -// paged retrieval limits for all blacklist queries and transactions +/// Hard upper bound on the `limit` accepted by paginated blacklist queries. pub(crate) const BLACKLIST_PAGE_MAX_LIMIT: u32 = 75; +/// Default `limit` for paginated blacklist queries when the caller passes None. pub(crate) const BLACKLIST_PAGE_DEFAULT_LIMIT: u32 = 50; -// paged retrieval limits for all deposit queries and transactions +/// Hard upper bound on the `limit` accepted by paginated deposit queries. pub(crate) const DEPOSITS_PAGE_MAX_LIMIT: u32 = 100; +/// Default `limit` for paginated deposit queries when the caller passes None. pub(crate) const DEPOSITS_PAGE_DEFAULT_LIMIT: u32 = 50; +/// Build the cw3 `Propose` SubMsg dispatched by `RequestRedemption`. The +/// embedded message is a self-targeted `RedeemTickets` call that the multisig +/// will execute once the proposal passes. pub(crate) fn create_batch_redemption_proposal( tickets_digest: String, gw: String, @@ -70,6 +85,8 @@ pub(crate) fn create_batch_redemption_proposal( Ok(submsg) } +/// Build the cw3 `Propose` SubMsg for the blacklist flow. **Dead path**: not +/// reachable from any public ExecuteMsg today; preserved for the redesign. pub(crate) fn create_blacklist_proposal( public_key: String, ecash_bandwidth_address: String, @@ -100,6 +117,9 @@ pub(crate) fn create_blacklist_proposal( Ok(submsg) } +/// Extract the multisig-issued `proposal_id` from a cw3 `Propose` reply. +/// Surfaces `MissingProposalId` / `MalformedProposalId` for the typed-failure +/// cases the reply handler distinguishes. pub(crate) trait MultisigReply { fn multisig_proposal_id(&self) -> Result; } diff --git a/contracts/ecash/src/lib.rs b/contracts/ecash/src/lib.rs index 83359af34b..63c9f94dc4 100644 --- a/contracts/ecash/src/lib.rs +++ b/contracts/ecash/src/lib.rs @@ -1,6 +1,16 @@ // Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +//! On-chain anchor of the ticketbook credential pipeline. +//! +//! Clients escrow funds via `ExecuteMsg::DepositTicketBookFunds`, which mints a +//! sequential `deposit_id` and persists the depositor-claimed ed25519 identity +//! key for off-chain nym-api signers to read at blind-sign time. The contract +//! does **not** verify control of the ed25519 key - that proof is enforced +//! off-chain by `nym-api/src/ecash/deposit.rs::validate_deposit`. +//! +//! See `openspec/specs/ecash-contract/spec.md` for the normative interface. + mod constants; pub mod contract; mod deposit; diff --git a/contracts/ecash/src/multitest.rs b/contracts/ecash/src/multitest.rs index e157eeda00..f48350d795 100644 --- a/contracts/ecash/src/multitest.rs +++ b/contracts/ecash/src/multitest.rs @@ -211,7 +211,7 @@ fn reduced_price_deposit_end_to_end() { .call(&whitelisted) .unwrap(); - // whitelisted address can also deposit at the default price — + // whitelisted address can also deposit at the default price - // treated as a normal (non-reduced) deposit for statistics purposes contract .deposit_ticket_book_funds(vk.to_string()) diff --git a/openspec/changes/archive/2026-05-20-node-families-contract-spec/.openspec.yaml b/openspec/changes/archive/2026-05-20-node-families-contract-spec/.openspec.yaml new file mode 100644 index 0000000000..8b76914981 --- /dev/null +++ b/openspec/changes/archive/2026-05-20-node-families-contract-spec/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-05-20 diff --git a/openspec/changes/archive/2026-05-20-node-families-contract-spec/README.md b/openspec/changes/archive/2026-05-20-node-families-contract-spec/README.md new file mode 100644 index 0000000000..45b439bb52 --- /dev/null +++ b/openspec/changes/archive/2026-05-20-node-families-contract-spec/README.md @@ -0,0 +1,3 @@ +# node-families-contract-spec + +Reverse-engineer specifications for the existing node-families CosmWasm contract diff --git a/openspec/changes/archive/2026-05-20-node-families-contract-spec/design.md b/openspec/changes/archive/2026-05-20-node-families-contract-spec/design.md new file mode 100644 index 0000000000..59efcaa8a0 --- /dev/null +++ b/openspec/changes/archive/2026-05-20-node-families-contract-spec/design.md @@ -0,0 +1,149 @@ +## Context + +The node-families CosmWasm contract is the on-chain authority for declaring that two or more Nym nodes belong to the same operator. Route-selection code is expected to consult this data so that the entry and exit gateways of a single NymVPN connection cannot both be in the same family — closing one of the two surveillance windows called out in the proposal (the other being same-subnet detection, which is out of scope here). + +The contract is implemented in `contracts/node-families/` with the shared message/type surface in `common/cosmwasm-smart-contracts/node-families-contract/`. The entire feature landed in a single commit (`a21a01cf1a`, "node families (#6715)") on 2026-05-19. No previous CosmWasm contract in the workspace handled families; the design is a fresh build with no migration baseline. The implementation has shipped behind a network-defaults wiring (`NODE_FAMILIES_CONTRACT_ADDRESS` env var, mainnet defaults, sandbox wallet types) — it is live, not aspirational. + +This document captures the architectural choices behind the contract as it exists today, so reviewers, integrators (nym-api caches, node-status-api indexers), and future maintainers have a single normative reference. There is no behaviour change being proposed. + +## Goals / Non-Goals + +**Goals:** +- Capture the trust boundary between the node-families contract and the mixnet contract — which checks each side owns and what each side relies on the other for. +- Pin down the data model: storage maps, secondary indexes, and the rationale for the composite archive keys. +- Pin down the invariants the contract guarantees externally (one family per owner, one family per node, unique normalised family names, monotonic family ids). +- Pin down the cross-contract callback flow that handles node unbonding. +- Document the policy choices around invitation expiry (no background sweeper, expired entries are inert). +- Document the storage-key and event constants as part of the public contract surface, since indexers consume them. + +**Non-Goals:** +- Route-selection policy on the client or nym-api side. The contract is a data source; the consumers decide what to do with the data. +- Operator verification ("verified families"). The contract has no notion of vetting beyond ownership of a bonded node. +- Geographic / subnet-distinctness checks. These live entirely outside the contract. +- Sybil resistance. The proposal explicitly accepts that a malicious operator can refuse to declare a family — the contract does not try to detect this. +- Cryptographic family-key signing à la Tor. The Nym design substitutes chain-level identity (bond control via the mixnet contract) for Tor's per-family key signature — see Decision 1. + +## Decisions + +### Decision 1: Authority is delegated to the mixnet contract; there is no family key + +**Choice.** Membership and invitation paths do not require any application-level signature beyond the chain's transaction signature. The contract proves "the sender controls this node" by cross-querying the mixnet contract (`query_nymnode_ownership` / `check_node_existence`), and relies on chain-level replay protection for every transaction. + +**Why.** Tor's family-key construction protects against an off-chain attacker that can forge messages to a directory server. On Nym there is no off-chain channel — every state transition is a signed Cosmos SDK transaction whose sender address is authenticated by the chain itself. Bond ownership is already attested on-chain by the mixnet contract. Adding a second signing key per operator would duplicate the trust anchor at no security gain and complicate key management. + +**Alternative considered.** A per-family signing key recorded on family creation, with every membership change requiring a signature from that key. Rejected as redundant given chain-level authentication. + +**Consequence.** The contract is tightly coupled to the mixnet contract — its instantiate message *requires* the mixnet contract address, and that address is the sole authority for `OnNymNodeUnbond`. The address is bech32-validated at instantiation and persisted; it cannot be changed by a privileged update path (today). Replacing the mixnet contract would therefore require redeploying the families contract. + +### Decision 2: Family names are normalised at the storage boundary + +**Choice.** Family names are normalised by dropping every non-ASCII-alphanumeric character and lowercasing the rest (`crate::helpers::normalise_family_name`). The normalised form is stored alongside the user-supplied `name` and is what the unique-name index keys on. + +**Why.** Users will submit `"My Family"`, `"my-family"`, `" MyFamily "` and expect them to be the same entity. A unique index on the raw `name` would let an adversary squat the canonical form with cosmetic variants. Doing the normalisation contract-side rather than client-side means every consumer sees the same uniqueness behaviour without trusting clients. + +**Alternative considered.** Case-insensitive Unicode normalisation (NFKC + lowercasing). Rejected because CosmWasm contracts run in a deterministic Wasm sandbox where importing `unicode-normalization` materially grows the binary and increases gas cost; the operator population is small enough that ASCII-alphanumerics-only is acceptable. + +**Consequence.** Non-ASCII names normalise to whatever ASCII letters remain (`"café"` → `"caf"`, `"名前"` → `""`). Names that normalise to the empty string are explicitly rejected with `EmptyFamilyName`. This is documented behaviour, not a bug. + +### Decision 3: Family ids are monotonic and never recycled; `0` is the "no family" sentinel + +**Choice.** The contract holds an `Item` counter that starts unset (treated as `0`) and is incremented to issue the next id. Disbanding a family does not free its id. + +**Why.** Off-chain archives (the past-members and past-invitations maps) are keyed by `family_id`. Recycling ids would silently merge the history of two unrelated families and break correlation in downstream indexers. A monotonic counter is the simplest safe option. + +**Alternative considered.** Hash-of-name ids. Rejected because the name can be normalised but the index must remain stable across renames (none today, but worth preserving headroom) and because numeric ids serialise more cheaply. + +**Consequence.** The id space is `u32`. At realistic operator counts (single thousands) overflow is not a practical concern. + +### Decision 4: Both archives use `((family_id, node_id), counter: u64)` keys + +**Choice.** `past_family_members` and `past_family_invitations` are keyed by a composite of the `(family, node)` pair plus an explicit per-pair counter (`past_family_member_counter`, `past_family_invitation_counter` — both `Map<(NodeFamilyId, NodeId), u64>`). + +**Why.** A node can be invited to (and join, leave, re-join, etc.) the same family multiple times. Using `env.block.time` as a disambiguator is unsafe because multiple transactions can share a block. Maintaining an explicit per-pair counter keeps archival writes O(1) (vs. an O(log n) range scan to find the next free slot) and gives the archive a stable, total order per pair. + +**Alternative considered.** Storing every archive entry under a global sequence counter. Rejected because per-family and per-node listings (the dominant query shape) would then need to scan and filter rather than prefix-iterate. + +**Consequence.** Archive cursors are composite (`(NodeId, u64)` per-family-scoped, `(NodeFamilyId, u64)` per-node-scoped, `((NodeFamilyId, NodeId), u64)` globally-scoped). They are publicly typed in the common crate so clients pass them back verbatim. + +### Decision 5: No background sweeper for expired pending invitations + +**Choice.** When an invitation's `expires_at` passes, the entry remains in `pending_family_invitations`. The only paths that clear it are explicit revoke (by the family owner), explicit reject (by the node controller), the unbonding callback (sweeps all invitations for a node), and disband (sweeps all invitations for a family). Read queries surface a boolean `expired` flag so consumers don't have to compare the timestamp themselves. + +**Why.** A background sweeper would need either a CosmWasm cron extension (none available) or a per-block hook (no such hook exists in the contract — the only cross-contract entry is `OnNymNodeUnbond`). Triggering sweeps from the families contract's own execute paths only would still leave drift between expiry and removal. Surfacing `expired` lets read consumers decide their own policy without paying contract storage churn. + +**Consequence.** `accept_invitation` is the only handler that refuses to act on an expired entry. Revoke and reject are explicit and idempotent under expiry — they are the operator's tool to clean storage. The expired-but-still-pending state is not pathological; it is the documented baseline. + +### Decision 6: Owner-gated handlers derive the family from sender ownership, not from arguments + +**Choice.** `DisbandFamily`, `InviteToFamily`, `RevokeFamilyInvitation`, and `KickFromFamily` do not accept a `family_id` argument — the family is resolved from the sender's ownership via the `families.owner` unique index. + +**Why.** Passing the family id would force every handler to validate that the sender owns the supplied id, with one error path for "wrong family" and another for "no family". Deriving the family from ownership collapses both into the single `SenderDoesntOwnAFamily` error path and makes it impossible to act on someone else's family. The `KickFromFamily` case additionally checks that the target node's current family matches the owner's family, because `family_members` is keyed by node alone and the storage helper would otherwise silently strip a node from an unrelated family. + +**Alternative considered.** Explicit `family_id` argument on every handler. Rejected as ergonomic noise that adds error surface without security gain. + +**Consequence.** Accept and reject *do* carry `family_id` in the message, because the sender there is the *invitee* (node controller), not the family owner — they may simultaneously hold invitations from multiple families and must say which one they are acting on. + +### Decision 7: Defence-in-depth pre-checks complement unique-index enforcement + +**Choice.** `try_create_family` explicitly checks `may_get_owned_family` and `families.idx.normalised_name.item` *before* calling `register_new_family`, even though both invariants are also enforced by the underlying `IndexedMap` `UniqueIndex`. Likewise `add_pending_invitation` checks `may_load` before insert. + +**Why.** A `UniqueIndex` violation surfaces as a generic CosmWasm storage error without any context (no family ids, no addresses). Pre-checking yields typed errors (`SenderAlreadyOwnsAFamily { address, family_id }`, `FamilyNameAlreadyTaken { name, family_id }`, `PendingInvitationAlreadyExists { family_id, node_id }`) that downstream wallets and tooling can surface meaningfully. The unique index is retained as a hard backstop so a bug in the pre-check cannot corrupt invariants. + +**Consequence.** The cost is one extra storage read per checked invariant per call — negligible relative to the typical multi-write transaction body. + +### Decision 8: The unbonding callback archives invitations as `Rejected`, not `Revoked` + +**Choice.** When `OnNymNodeUnbond` sweeps a node's pending invitations, each is archived with `FamilyInvitationStatus::Rejected { at: now }`. The `Revoked` status is reserved exclusively for owner-side withdrawal (the explicit `RevokeFamilyInvitation` execute and the all-family sweep during `DisbandFamily`). + +**Why.** From the *family's* point of view, an invitation that auto-clears because its target unbonded looks identical to one the target explicitly declined: both are invitee-side terminations beyond the family's control. Lumping them together as `Rejected` keeps the semantic boundary clean — `Revoked` means "the family changed its mind," `Rejected` means "the invitee said no (whether via explicit reject or by leaving the network)." Off-chain indexers that group by status get sensible buckets without needing a separate "auto-rejected" tier. + +**Alternative considered.** A new `FamilyInvitationStatus::AutoExpired` (or `NodeUnbonded`) variant. Rejected because it adds enum surface for a distinction that no current consumer cares about, and because the historical record already preserves the *event* that triggered the archival (a `family_node_unbond_cleanup` event fires alongside, and on-chain tx history can be cross-referenced). + +**Consequence.** Past-invitation queries cannot distinguish "node controller explicitly rejected" from "node unbonded and the invitation was swept" from the `status` field alone. Consumers that need the distinction must correlate with the emitted event or with the mixnet-contract unbonding history. Adding a new variant later would be a breaking schema change. + +### Decision 9: Schema-feature-gated response types in the common crate + +**Choice.** The common crate's `msg.rs` puts every `#[cfg_attr(feature = "schema", returns(...))]` annotation behind a `schema` feature, and the response types are only imported when the feature is active. + +**Why.** The contract crate itself does not need `cosmwasm-schema` at runtime; only the `bin/schema.rs` schema-emitter (which writes `schema/node-families.json` and the per-message JSON files) does. Gating keeps the production Wasm binary lean. + +**Consequence.** When generating schemas, builds must enable the `schema` feature on `nym_node_families_contract_common`. This is automated in the contract's `Makefile` and `bin/schema.rs`. + +### Decision 10: Unknown scope ids on paginated queries return an empty page, not an error + +**Choice.** Per-family and per-node paginated queries (`GetFamilyMembersPaged`, `GetPendingInvitationsForFamilyPaged`, `GetPastMembersForNodePaged`, etc.) do not verify that the supplied `family_id` or `node_id` corresponds to an existing entity. An unknown scope id silently yields an empty page (`entries: []`, `start_next_after: None`) rather than a `FamilyNotFound`-style error. + +**Why.** The underlying `cw_storage_plus::IndexedMap::range` over a `MultiIndex` prefix has no native existence check on the prefix itself — an unknown prefix is simply a range that yields zero entries. Surfacing this as an error would require an extra storage read per query to confirm the scope exists, and the per-family/per-node membership maps don't carry a "this scope was ever populated" sentinel anyway (a disbanded family has zero remaining members, and so does one that never had any). Treating "no entries" identically in both cases collapses two paths into one. Callers who care about the distinction can pair the listing with `GetFamilyById { family_id }` (which *does* return `Option`). + +**Alternative considered.** Returning `FamilyNotFound { family_id }` (or analogous) when the scope id is unknown. Rejected because (a) it inflates the cost of every paginated read by one extra storage check, (b) it makes paginate-then-filter consumer patterns more awkward without payoff, and (c) the "scope known but empty" and "scope unknown" cases are observationally identical to most consumers. + +**Consequence.** Spec scenario "Unknown scope id yields an empty page rather than an error" makes this explicit. Tooling that surfaces "family not found" errors needs to perform its own existence check via the single-family query — the listing endpoints do not provide it. + +## Risks / Trade-offs + +- **[Mixnet contract address is locked at instantiation]** → If the mixnet contract is ever redeployed at a different address, the families contract becomes orphaned (the unbonding callback path no longer fires). **Mitigation:** documented as an operational constraint; a future migration could add an `UpdateMixnetContractAddress` admin-only execute. Today there is no such path. +- **[No sybil resistance]** → A malicious operator running multiple nodes can simply not declare a family. **Mitigation:** out of scope here; the proposal explicitly accepts this and points to operator verification as a follow-on. +- **[Expired invitations bloat storage]** → A family that issues invitations and never sweeps them accrues dead entries. **Mitigation:** disband sweeps all of them at once; the family can also revoke individually. The `expired` flag on read queries means consumers don't need them gone to act correctly. +- **[Counter overflow in archive maps]** → `u64` per pair counter cannot realistically overflow but is technically unbounded. **Mitigation:** not a real concern at any practical operator/node scale. +- **[Cross-contract query gas cost]** → Every invite/accept/reject/leave/kick does at least one `query_nymnode_ownership` or `check_node_existence`. **Mitigation:** these are simple `Item`/`Map` reads on the mixnet contract side; cost is bounded. +- **[Disband cost scales with pending invitation count]** → Disband sweeps all of a family's pending invitations in a single transaction. A family with thousands of pending invitations could push past gas limits. **Mitigation:** documented; in the worst case the owner can pre-revoke invitations in batches. + +## Migration Plan + +Not applicable to this change — this is a documentation-only artefact for code that has already shipped. The contract itself is initially deployed via the standard `cosmwasm_contracts.rs` orchestrator wiring (which the anchor commit added), and its `migrate` entry point uses `cw2::ensure_from_older_version` to gate version bumps. There is no state migration in the anchor commit; `queued_migrations.rs` is a stub awaiting future need. + +Future spec deltas that *do* change behaviour should: + +1. Document the storage-key change (if any) and add a corresponding entry to `queued_migrations`. +2. Bump `CARGO_PKG_VERSION` in `contracts/node-families/Cargo.toml`. +3. Coordinate the `MigrateMsg` invocation with the chain-governance migration tx that pushes the new code id. + +## Resolved Questions + +The three questions considered during the spec walk-through, with the team's resolutions on 2026-05-20: + +- **Mixnet contract address updatability** → keep locked at instantiation. The mixnet contract is not expected to be redeployed under a new address; if it ever is, the families contract is redeployed alongside it. Avoiding the admin-gated `UpdateMixnetContractAddress` execute means admin compromise cannot hijack the unbonding callback authority. +- **Length-limit units** → keep byte-counted via `String::len`. Operator-supplied family names are overwhelmingly ASCII in practice; pulling in `unicode-segmentation` or even paying the `chars().count()` cost is not justified for short identifiers. +- **Rename / update handlers** → do not add. The only post-creation mutation remains the `members` counter. Owners who want to change a name or description disband and recreate (the fee is refunded). Keeps the execute surface, event surface, and test surface minimal. + +No questions remain open. diff --git a/openspec/changes/archive/2026-05-20-node-families-contract-spec/proposal.md b/openspec/changes/archive/2026-05-20-node-families-contract-spec/proposal.md new file mode 100644 index 0000000000..2c01a72750 --- /dev/null +++ b/openspec/changes/archive/2026-05-20-node-families-contract-spec/proposal.md @@ -0,0 +1,36 @@ +## Why + +The node-families CosmWasm contract (`contracts/node-families/`) ships and is live, but the design exists only as Rust source and inline doc comments — there is no externally-readable specification of *what* the contract guarantees, *who* is authorised to do *what*, or *how* it interacts with the mixnet contract. Without that artefact: + +- Route-selection logic in clients and the nym-api currently treats node-families data as opaque inputs; reviewers and integrators have no normative reference to check assumptions against. +- The single-commit origin (`a21a01cf1a`, "node families (#6715)") means there is no PR-by-PR trail of design decisions to reverse later — capturing the spec now is materially cheaper than reconstructing it from `git blame` once memory fades. +- Follow-on work (operator verification, route-policy enforcement, indexer expansion in node-status-api) needs a stable interface to plan against. + +The goal of this change is to **reverse-engineer specifications** for the on-chain contract that already exists at HEAD on `develop`. No behaviour change is proposed; this is a documentation/spec-only deliverable that ratifies the current implementation as the baseline. + +## What Changes + +- Introduce a new capability spec `node-families-contract` covering the on-chain CosmWasm contract: instantiation, runtime config, family lifecycle (create/disband), invitation lifecycle (invite/accept/reject/revoke/expire), membership lifecycle (join/leave/kick), the mixnet-contract unbonding callback, and the full read-query surface. +- Document the contract's external invariants (one family per owner, one family per node, globally unique normalised family names, monotonic family ids, sequential per-`(family,node)` archive counters, no background sweeper for expired invitations). +- Document the cross-contract trust boundary with the mixnet contract: which checks the families contract delegates (node existence, node controller, unbonding state) and which it owns (family ownership, invitation state, membership archives). +- Document the event surface emitted by each execute path, since indexers (node-status-api) and downstream tooling consume those names/attributes as a public API. + +No code changes. No migrations. No new dependencies. + +## Capabilities + +### New Capabilities + +- `node-families-contract`: the CosmWasm contract that lets node operators declare groupings of co-owned nodes ("families"), issue and resolve invitations, and exposes the queryable state that route-selection logic uses to disallow entry+exit pairs from the same family. + +### Modified Capabilities + +_None — there are no existing specs in `openspec/specs/` and this change does not alter on-chain behaviour._ + +## Impact + +- **Affected code**: none modified. The spec is derived from `contracts/node-families/` and `common/cosmwasm-smart-contracts/node-families-contract/` at HEAD on `develop` (anchor commit `a21a01cf1a`). +- **Affected consumers** (documented for traceability, not changed): `validator-client` (`NodeFamiliesQueryClient` / `NodeFamiliesSigningClient` traits), `nym-api` (`src/node_families/` cache + HTTP routes), `nym-node-status-api` (`db/queries/node_families.rs` + DVpn gateway routes), and the mixnet contract's unbonding flow which fires `ExecuteMsg::OnNymNodeUnbond`. +- **Dependencies**: none. CosmWasm storage layout (storage-key constants in `common/cosmwasm-smart-contracts/node-families-contract/src/constants.rs`) is part of the spec surface — changing those constants is a breaking change for already-deployed contracts and must be treated as such by any future delta. +- **Non-goals**: route-policy enforcement (client-side or nym-api-side filtering using family data), operator verification, geographic/subnet-distinctness checks, indexer schema, HTTP API shapes. These all consume the contract but live outside its boundary and will get their own specs in follow-on changes. +- **Known limitation — ASCII-only names**: family-name normalisation drops every character that is not an ASCII letter or digit. Non-ASCII letters (`"café"` → `"caf"`, `"Ω-team"` → `"team"`, `"名前"` → `""`) and emoji are stripped entirely; names that normalise to the empty string are rejected with `EmptyFamilyName`. This is intentional, deterministic, and gas-efficient (no Unicode segmentation dependency in the Wasm binary), but it does mean operators picking non-ASCII branding cannot use it as their family name. Documented here so it surfaces in the change log and not just buried inside `normalise_family_name`. diff --git a/openspec/changes/archive/2026-05-20-node-families-contract-spec/specs/node-families-contract/spec.md b/openspec/changes/archive/2026-05-20-node-families-contract-spec/specs/node-families-contract/spec.md new file mode 100644 index 0000000000..2acb3dd5bd --- /dev/null +++ b/openspec/changes/archive/2026-05-20-node-families-contract-spec/specs/node-families-contract/spec.md @@ -0,0 +1,428 @@ +## ADDED Requirements + +### Requirement: Contract instantiation persists the runtime config, mixnet contract address, and admin + +The contract SHALL be instantiable exactly once via the standard CosmWasm `instantiate` entry point. The instantiation message SHALL carry a `Config` (creation fee, family-name length limit, family-description length limit, default invitation validity in seconds) and a string-form `mixnet_contract_address`. The handler MUST: + +- bech32-validate `mixnet_contract_address` and reject malformed inputs; +- persist the validated mixnet contract address, the `Config`, and `info.sender` as the contract admin; +- record the contract name and `CARGO_PKG_VERSION` via `cw2::set_contract_version`; +- record build information via `set_build_information!`. + +#### Scenario: Valid instantiation persists config, mixnet address, and admin +- **WHEN** `instantiate` is called with a valid bech32 mixnet contract address and a well-formed `Config` +- **THEN** the contract stores the `Config` verbatim, the validated `Addr` for the mixnet contract, and sets `info.sender` as the contract admin queryable via `cw-controllers::Admin::assert_admin` +- **AND** `cw2::get_contract_version` returns the crate's `CARGO_PKG_VERSION` + +#### Scenario: Invalid mixnet contract address is rejected +- **WHEN** `instantiate` is called with a `mixnet_contract_address` string that fails `Addr::validate` +- **THEN** the call returns an error and no state is persisted + +### Requirement: Migration entry point forbids version downgrades + +The contract SHALL expose a `migrate` entry point that refreshes recorded build information and uses `cw2::ensure_from_older_version` to guarantee the on-chain contract version is at most the current `CARGO_PKG_VERSION`. Downgrade attempts MUST be rejected. + +#### Scenario: Equal or older on-chain version is accepted +- **WHEN** `migrate` is called against an on-chain `cw2` version less than or equal to `CARGO_PKG_VERSION` +- **THEN** the call succeeds and `set_build_information!` updates the stored build metadata + +#### Scenario: Newer on-chain version is rejected +- **WHEN** `migrate` is called against an on-chain `cw2` version strictly greater than `CARGO_PKG_VERSION` +- **THEN** the call returns an error and storage is unchanged + +### Requirement: Only the contract admin can replace the runtime config + +The `ExecuteMsg::UpdateConfig` handler SHALL overwrite the stored `Config` with the value supplied by the caller. The handler MUST call `Admin::assert_admin` and return the underlying `AdminError` (wrapped in `NodeFamiliesContractError::Admin`) when the sender is not the admin. + +#### Scenario: Admin replaces the config +- **WHEN** the contract admin sends `ExecuteMsg::UpdateConfig { config }` +- **THEN** the stored `Config` equals the supplied value on subsequent reads + +#### Scenario: Non-admin is rejected +- **WHEN** a non-admin sender sends `ExecuteMsg::UpdateConfig` +- **THEN** the call returns an `Admin` error and the stored `Config` is unchanged + +### Requirement: Family names are normalised and globally unique under their normalised form + +Family names SHALL be normalised to a canonical form by lowercasing ASCII letters, preserving ASCII digits, and dropping every other character (whitespace, punctuation, non-ASCII letters). The normalised form SHALL be stored alongside the user-supplied `name` and SHALL be the key of the `families.normalised_name` unique index. Inputs whose normalised form is the empty string SHALL be rejected with `EmptyFamilyName`. Inputs whose original length exceeds `Config::family_name_length_limit` (measured in **bytes**, via `String::len`) SHALL be rejected with `FamilyNameTooLong { length, limit }`. Creation of a family whose normalised name collides with an existing family SHALL fail with `FamilyNameAlreadyTaken { name, family_id }`. + +**Important**: this normalisation is ASCII-only by design. Non-ASCII letters and emoji are stripped entirely (`"café"` → `"caf"`, `"名前"` → `""`, `"⭐stars"` → `"stars"`). Names consisting solely of non-ASCII characters or symbols are rejected as `EmptyFamilyName`. Operators who want a non-ASCII brand cannot encode it in the on-chain family name; the user-supplied `name` field preserves the original formatting but only the normalised ASCII form is enforced for uniqueness and emptiness. + +#### Scenario: Normalisation strips punctuation, whitespace, casing, and non-ASCII letters +- **WHEN** the contract normalises any of `"Foo Bar"`, `"foobar"`, `"FOO-BAR"`, or `" f.o.o.b.a.r "` +- **THEN** every result equals `"foobar"` + +#### Scenario: All-symbol name is rejected +- **WHEN** `CreateFamily` is sent with `name = "!!!---"` (normalises to the empty string) +- **THEN** the call fails with `EmptyFamilyName` and no family is persisted + +#### Scenario: Name length is checked against the original string, not the normalised form +- **WHEN** `CreateFamily` is sent with a `name` whose `name.len()` (byte length) exceeds `Config::family_name_length_limit` +- **THEN** the call fails with `FamilyNameTooLong { length, limit }` + +#### Scenario: Multi-byte characters count their full byte length toward the limit +- **WHEN** `Config::family_name_length_limit = 8` and `CreateFamily` is sent with `name = "🚀rocket"` (a 4-byte emoji followed by `"rocket"`, totalling `name.len() == 10` bytes — but only 7 user-perceived characters) +- **THEN** the call fails with `FamilyNameTooLong { length: 10, limit: 8 }` even though the visible character count is within the limit +- **AND** had the limit been `>= 10`, the name would have been accepted and the normalised form would be `"rocket"` (the emoji dropped during normalisation) + +#### Scenario: Two formattings of the same canonical name collide +- **WHEN** family `A` is created with `name = "Shared"` and `B` later tries to create with `name = "$$shared$$"` +- **THEN** the second call fails with `FamilyNameAlreadyTaken { name: "shared", family_id: A.id }` + +### Requirement: An address may own at most one family at a time + +A given owner address SHALL own at most one family at any time, enforced by the `families.owner` unique index. `CreateFamily` SHALL pre-check this and fail with `SenderAlreadyOwnsAFamily { address, family_id }` for better error context. The pre-check is in addition to (not instead of) the unique-index defence-in-depth check. Owner-gated handlers (`DisbandFamily`, `InviteToFamily`, `RevokeFamilyInvitation`, `KickFromFamily`) SHALL look up the family by owner and fail with `SenderDoesntOwnAFamily { address }` when none exists. + +#### Scenario: Same address cannot create a second family while still owning one +- **WHEN** address `alice` already owns family `A` and `CreateFamily` is sent again with `alice` as sender +- **THEN** the call fails with `SenderAlreadyOwnsAFamily { address: alice, family_id: A.id }` + +#### Scenario: Address can create a family again after disbanding its previous one +- **WHEN** `alice` creates family `A` then disbands it, then sends `CreateFamily` again +- **THEN** a new family with a strictly greater id than `A` is created (ids are monotonic and never recycled) + +#### Scenario: Owner-gated handler rejects a sender that owns no family +- **WHEN** any of `DisbandFamily`, `InviteToFamily`, `RevokeFamilyInvitation`, or `KickFromFamily` is sent by an address that owns no family +- **THEN** the call fails with `SenderDoesntOwnAFamily { address }` + +### Requirement: Family creation requires the configured fee and is rejected if the owner's bonded node is already in a family + +`ExecuteMsg::CreateFamily` SHALL require the sender to attach exactly one coin matching `Config::create_family_fee` in both denom and amount. Payment validation MUST go through `cw_utils::must_pay`; mismatches in amount MUST surface as `InvalidFamilyCreationFee { expected, received }`. The handler MUST additionally check that any bonded node the sender controls (as reported by the mixnet contract via `query_nymnode_ownership`) is not currently a member of any family, failing with `AlreadyInFamily { address, node_id, family_id }` otherwise. The handler MUST validate the description length against `Config::family_description_length_limit` and reject overlong descriptions with `FamilyDescriptionTooLong { length, limit }`. On success the handler SHALL emit a `family_creation` event with attributes `family_name`, `owner_address`, `family_id`, `paid_fee`. + +#### Scenario: Successful family creation persists the family and emits the event +- **WHEN** a sender with no bonded family-member node and no existing-owned family sends `CreateFamily { name, description }` with the correct fee attached +- **THEN** a new family is persisted with monotonically increasing `id`, the supplied `name` and `description`, the computed `normalised_name`, `members = 0`, `created_at = env.block.time.seconds()`, and `paid_fee` equal to the configured fee +- **AND** the response carries an event named `family_creation` with attributes `family_name`, `owner_address`, `family_id`, `paid_fee` + +#### Scenario: Wrong fee denom or missing funds is rejected +- **WHEN** `CreateFamily` is sent with no funds, with multiple denoms, or with a denom different from `Config::create_family_fee.denom` +- **THEN** the call fails with `InvalidDeposit(PaymentError)` + +#### Scenario: Wrong fee amount is rejected +- **WHEN** `CreateFamily` is sent with the correct denom but an amount different from `Config::create_family_fee.amount` +- **THEN** the call fails with `InvalidFamilyCreationFee { expected, received }` and the funds remain unspent + +#### Scenario: Sender whose bonded node is already in a family is rejected +- **WHEN** `CreateFamily` is sent by an address whose bonded node (per the mixnet contract) is already a member of some family `F` +- **THEN** the call fails with `AlreadyInFamily { address, node_id, family_id: F.id }` + +#### Scenario: Overlong description is rejected +- **WHEN** `CreateFamily` is sent with a `description` whose byte length exceeds `Config::family_description_length_limit` +- **THEN** the call fails with `FamilyDescriptionTooLong { length, limit }` + +### Requirement: Family ids are monotonic, never recycled, and start at 1 + +The contract SHALL assign family ids sequentially starting at `1`. The id counter SHALL be persisted as an `Item` and incremented on each successful family creation. Disbanding a family MUST NOT free or recycle its id. `0` SHALL be reserved as a "no family" sentinel and never assigned. + +#### Scenario: First-ever family receives id 1 +- **WHEN** the contract is freshly instantiated and the first successful `CreateFamily` runs +- **THEN** the persisted `NodeFamily.id` equals `1` + +#### Scenario: Ids are not reused after disband +- **WHEN** family with id `N` is disbanded and a new family is then created +- **THEN** the new family's id is strictly greater than `N` (it is `N+1` if no other families were created in between) + +### Requirement: A family can only be disbanded by its owner, must be empty, and refunds the creation fee + +`ExecuteMsg::DisbandFamily` SHALL look up the sender's family via the `owner` unique index and fail with `SenderDoesntOwnAFamily` when none exists. The handler MUST reject disbanding while `NodeFamily.members > 0`, failing with `FamilyNotEmpty { family_id, members }`. On success the handler SHALL sweep every still-pending invitation issued by the family (archiving each as `FamilyInvitationStatus::Revoked { at: now }` with status timestamp = `env.block.time.seconds()`), remove the family record, and attach a `BankMsg::Send { to_address: owner, amount: vec![family.paid_fee] }` to the response as a CosmWasm sub-message. The response SHALL include a `family_disband` event with `family_id`, `owner_address`, `refunded_fee` attributes. + +**Operational note (non-normative)**: the pending-invitation sweep iterates every entry of `pending_family_invitations` keyed by `family_id` and archives each in a single transaction. Gas cost therefore scales linearly with the number of leftover pending invitations. An owner whose family has accumulated an unusually large number of pending invitations is expected to revoke them in batches (via `RevokeFamilyInvitation`) *before* invoking `DisbandFamily`, since a single disband call that exceeds the per-tx gas limit will fail and leave the family in place. There is no contract-side chunking; the responsibility lies with the caller. + +#### Scenario: Owner disbands an empty family and is refunded +- **WHEN** family owner sends `DisbandFamily` while `members == 0` +- **THEN** the family is removed from storage, the response carries a `BankMsg::Send` of `family.paid_fee` to the owner, and a `family_disband` event is emitted + +#### Scenario: Refund is attached as a BankMsg::Send sub-message, not a direct bank-module call +- **WHEN** a successful `DisbandFamily` returns its `Response` +- **THEN** the response's `messages` field contains exactly one `CosmosMsg::Bank(BankMsg::Send { to_address: , amount: vec![] })` and the contract performs no other balance-changing side effect for the refund +- **AND** tx simulators that inspect outbound sub-messages observe the refund there (this is the contract's only avenue for returning funds; integrators rely on it) + +#### Scenario: Non-empty family cannot be disbanded +- **WHEN** family owner sends `DisbandFamily` while `members > 0` +- **THEN** the call fails with `FamilyNotEmpty { family_id, members }` and storage is unchanged + +#### Scenario: Disbanding sweeps still-pending invitations as Revoked +- **WHEN** family `F` has pending invitations to nodes `n1`, `n2` and the owner sends `DisbandFamily` +- **THEN** the pending entries for `(F.id, n1)` and `(F.id, n2)` are removed from `pending_family_invitations` and archived under `past_family_invitations` with `status = Revoked { at: env.block.time.seconds() }` + +### Requirement: A node belongs to at most one family at any time + +The `family_members` map SHALL be keyed by `NodeId` alone; the value SHALL carry the `family_id` so the storage layer enforces the one-family-per-node invariant by construction. Handlers that add a membership (`AcceptFamilyInvitation`) and handlers that issue an invitation (`InviteToFamily`) SHALL pre-check the absence of any existing membership for the node and fail with `NodeAlreadyInFamily { node_id, family_id }` otherwise. + +#### Scenario: Inviting a node already in a family is rejected +- **WHEN** `InviteToFamily { node_id }` targets a node that already has a membership record for family `F` +- **THEN** the call fails with `NodeAlreadyInFamily { node_id, family_id: F.id }` + +#### Scenario: Accepting a second invitation after joining a family is rejected +- **WHEN** node `n` is a member of family `F` and `AcceptFamilyInvitation { family_id: G, node_id: n }` is sent (for a different family `G`) +- **THEN** the call fails with `NodeAlreadyInFamily { node_id: n, family_id: F.id }` + +### Requirement: Invitations require an existing family, a bonded target node, and strictly positive validity + +`ExecuteMsg::InviteToFamily` SHALL be owner-gated (the family acted on is the sender's owned family, never an argument). The handler MUST: + +- compute `validity = validity_secs.unwrap_or(Config::default_invitation_validity_secs)`; +- reject `validity == 0` with `ZeroInvitationValidity`; +- verify `node_id` refers to a currently-bonded, not-unbonding node in the mixnet contract via `MixnetContractQuerier::check_node_existence` (which returns `false` both when no bond exists and when the bond is in the unbonding state), failing with `NodeDoesntExist { node_id }` otherwise; +- verify the node is not already in any family (see "A node belongs to at most one family"); +- persist a `FamilyInvitation` with `expires_at = env.block.time.seconds() + validity`; +- reject `(family_id, node_id)` pairs that already have a pending invitation with `PendingInvitationAlreadyExists { family_id, node_id }`; +- emit a `family_invitation` event with `family_id`, `node_id`, `expires_at`. + +#### Scenario: Successful invitation persists with the computed expiry +- **WHEN** family owner sends `InviteToFamily { node_id, validity_secs: Some(v) }` and all preconditions hold +- **THEN** a pending invitation for `(owned.id, node_id)` is persisted with `expires_at = env.block.time.seconds() + v` +- **AND** the response carries a `family_invitation` event with `family_id = owned.id`, `node_id`, `expires_at` + +#### Scenario: Missing validity falls back to the configured default +- **WHEN** `InviteToFamily { node_id, validity_secs: None }` is sent +- **THEN** the persisted invitation has `expires_at = env.block.time.seconds() + Config::default_invitation_validity_secs` + +#### Scenario: Zero validity is rejected +- **WHEN** `InviteToFamily { node_id, validity_secs: Some(0) }` is sent +- **THEN** the call fails with `ZeroInvitationValidity` and no invitation is persisted + +#### Scenario: Inviting a non-bonded node is rejected +- **WHEN** `InviteToFamily { node_id }` targets a `node_id` for which the mixnet contract's `check_node_existence` returns `false` +- **THEN** the call fails with `NodeDoesntExist { node_id }` + +#### Scenario: Duplicate pending invitation is rejected +- **WHEN** family `F` already has a pending invitation for node `n` and `InviteToFamily { node_id: n }` is sent again by `F`'s owner +- **THEN** the call fails with `PendingInvitationAlreadyExists { family_id: F.id, node_id: n }` (the existing invitation is preserved) + +### Requirement: Acceptance and rejection of an invitation are gated on node control + +`ExecuteMsg::AcceptFamilyInvitation` and `ExecuteMsg::RejectFamilyInvitation` SHALL each verify that the sender is the controller of the bonded node `node_id` per the mixnet contract (`query_nymnode_ownership` returns a `nym_node` with `node_id == node_id` and `is_unbonding == false`). Failures MUST surface as `SenderDoesntControlNode { address, node_id }`. This single error covers the cases of: sender owns no bonded node, sender owns a different node id, and sender owns the node but it has entered unbonding. + +#### Scenario: Non-controller cannot accept an invitation +- **WHEN** `AcceptFamilyInvitation { family_id, node_id }` is sent by an address that does not control `node_id` (per mixnet contract) +- **THEN** the call fails with `SenderDoesntControlNode { address, node_id }` + +#### Scenario: Unbonding node cannot accept an invitation +- **WHEN** the sender controls `node_id` but the mixnet contract reports the node as unbonding +- **THEN** `AcceptFamilyInvitation` fails with `SenderDoesntControlNode { address, node_id }` + +#### Scenario: Non-controller cannot reject an invitation +- **WHEN** `RejectFamilyInvitation { family_id, node_id }` is sent by an address that does not control `node_id` +- **THEN** the call fails with `SenderDoesntControlNode { address, node_id }` + +### Requirement: Accepting an invitation moves it from pending to archived and increments the family member count + +A successful `AcceptFamilyInvitation` SHALL: + +- load the pending invitation for `(family_id, node_id)`, failing with `InvitationNotFound { family_id, node_id }` if absent; +- check `now < invitation.expires_at`, failing with `InvitationExpired { family_id, node_id, expires_at, now }` otherwise (`now == expires_at` is considered expired); +- remove the entry from `pending_family_invitations`; +- write `family_members[node_id] = FamilyMembership { family_id, joined_at: now }`; +- increment `NodeFamily::members` by 1 (failing with `FamilyNotFound { family_id }` if the family has somehow been removed); +- archive a `PastFamilyInvitation { invitation, status: Accepted { at: now } }` under `((family_id, node_id), counter)` where `counter` is the next free per-`(family, node)` archive slot; +- emit a `family_invitation_accepted` event with `family_id`, `node_id`. + +#### Scenario: Happy-path acceptance +- **WHEN** node controller accepts a not-yet-expired pending invitation +- **THEN** the membership is recorded with `joined_at = env.block.time.seconds()`, the family's `members` count is incremented, the pending entry is removed, and the archive contains the invitation with status `Accepted { at: now }` + +#### Scenario: Acceptance of an already-expired invitation is rejected +- **WHEN** `AcceptFamilyInvitation` is called with `env.block.time.seconds() >= invitation.expires_at` +- **THEN** the call fails with `InvitationExpired { family_id, node_id, expires_at, now }` and storage is unchanged + +#### Scenario: Acceptance with no pending invitation is rejected +- **WHEN** `AcceptFamilyInvitation { family_id, node_id }` is called with no pending invitation stored for that pair +- **THEN** the call fails with `InvitationNotFound { family_id, node_id }` + +### Requirement: Rejection and revocation work on expired invitations and archive them with terminal status + +`RejectFamilyInvitation` (sent by the node controller) and `RevokeFamilyInvitation` (sent by the family owner) SHALL each: + +- remove the pending invitation; +- archive a `PastFamilyInvitation` with status `Rejected { at: now }` or `Revoked { at: now }` respectively, under `((family_id, node_id), counter)` using the next free per-`(family, node)` archive slot; +- emit `family_invitation_rejected` or `family_invitation_revoked` respectively, with `family_id` and `node_id` attributes; +- fail with `InvitationNotFound { family_id, node_id }` if no pending invitation exists. + +These two paths SHALL be the only ways to clear an expired invitation out of `pending_family_invitations` — the contract performs no background sweep of expired entries. + +#### Scenario: Owner revokes a still-pending invitation +- **WHEN** family owner sends `RevokeFamilyInvitation { node_id }` for a node currently in their pending invitations +- **THEN** the pending entry is removed and the archive contains the invitation with status `Revoked { at: env.block.time.seconds() }` + +#### Scenario: Node controller rejects a still-pending invitation +- **WHEN** node controller sends `RejectFamilyInvitation { family_id, node_id }` for a pending invitation +- **THEN** the pending entry is removed and the archive contains the invitation with status `Rejected { at: env.block.time.seconds() }` + +#### Scenario: Expired invitations can still be rejected or revoked +- **WHEN** an invitation's `expires_at` is at or before `env.block.time.seconds()` and either `RejectFamilyInvitation` or `RevokeFamilyInvitation` is sent for it +- **THEN** the call succeeds, the pending entry is removed, and the archive records the appropriate terminal status + +### Requirement: Leave and kick remove the membership and archive a past-member record + +`ExecuteMsg::LeaveFamily { node_id }` SHALL require the sender to be the controller of `node_id` (failing with `SenderDoesntControlNode` otherwise). `ExecuteMsg::KickFromFamily { node_id }` SHALL require the sender to be the current owner of a family, and the node MUST be a member of *that* family — kicking a node belonging to a different family fails with `NodeNotMemberOfFamily { node_id, family_id }`; kicking a node that has no membership at all fails with `NodeNotInFamily { node_id }`. Both handlers SHALL share the same storage operation: remove `family_members[node_id]`, decrement `NodeFamily::members`, and archive a `PastFamilyMember { family_id, node_id, removed_at: env.block.time.seconds() }` under `((family_id, node_id), counter)` using the next free per-`(family, node)` slot. The respective events are `family_member_left` (carrying the leaver's `family_id` and `node_id`) and `family_member_kicked` (carrying the owner's `family_id` and the kicked `node_id`). + +#### Scenario: Node controller leaves the family +- **WHEN** node controller sends `LeaveFamily { node_id }` for a node currently in family `F` +- **THEN** `family_members[node_id]` is removed, `F.members` is decremented, the archive contains a `PastFamilyMember` with `removed_at = env.block.time.seconds()`, and the response carries a `family_member_left` event + +#### Scenario: Owner kicks a member of their family +- **WHEN** family owner sends `KickFromFamily { node_id }` for a member of their family +- **THEN** the same storage transition as a leave occurs and the response carries a `family_member_kicked` event + +#### Scenario: Owner cannot kick a node belonging to another family +- **WHEN** family owner sends `KickFromFamily { node_id }` for a node whose membership is in a different family `G` +- **THEN** the call fails with `NodeNotMemberOfFamily { node_id, family_id: owned.id }` and storage is unchanged + +#### Scenario: Repeated join/leave of the same family uses sequential archive counters +- **WHEN** node `n` joins, leaves, joins again, and leaves again the same family `F` +- **THEN** the archive contains `past_family_members[((F.id, n), 0)]` and `past_family_members[((F.id, n), 1)]` with the respective `removed_at` timestamps + +### Requirement: Only the configured mixnet contract may invoke the unbonding callback + +`ExecuteMsg::OnNymNodeUnbond { node_id }` SHALL be authorised solely by checking `info.sender == stored mixnet_contract_address`, failing with `UnauthorisedMixnetCallback { sender }` otherwise. There is no node-side or admin override. + +#### Scenario: Mixnet contract triggers the callback +- **WHEN** the mixnet contract sends `OnNymNodeUnbond { node_id }` +- **THEN** the call proceeds and the cleanup (see next requirement) is applied + +#### Scenario: Arbitrary sender is rejected +- **WHEN** any address other than the stored mixnet contract sends `OnNymNodeUnbond` +- **THEN** the call fails with `UnauthorisedMixnetCallback { sender }` + +### Requirement: The unbonding callback is idempotent over membership and sweeps every pending invitation addressed to the node + +A successful `OnNymNodeUnbond { node_id }` SHALL: + +- if `family_members[node_id]` exists, remove the membership and archive a `PastFamilyMember` exactly as the `leave` / `kick` path does (decrementing the family's `members` count); +- if no such membership exists, leave membership state untouched (this is the common case — most unbonding nodes were never in a family); +- iterate every entry of `pending_family_invitations` keyed by `node_id` (via the `node` multi-index), remove each from the pending map, and archive each as `PastFamilyInvitation { invitation, status: Rejected { at: env.block.time.seconds() } }` using the next free per-`(family, node)` counter; +- emit a `family_node_unbond_cleanup` event with `node_id` attribute. + +The auto-cleared invitations share the `Rejected` terminal state with invitations the node controller would have explicitly declined — `Revoked` is reserved for owner-side actions. + +**Operational note (non-normative)**: like the disband sweep, the per-node invitation sweep iterates every pending invitation addressed to `node_id` and archives each in a single transaction. Gas cost therefore scales linearly with the number of outstanding invitations the unbonding node holds. If a node has accumulated an unusually large number of pending invitations, the operator-initiated unbond transaction on the mixnet contract may fail because *this* callback exceeds the per-tx gas limit. The fix is operator-side: explicitly `RejectFamilyInvitation` the outstanding invitations (in batches if needed) before retrying the unbond. There is no contract-side chunking, and the mixnet contract has no path to bypass or partial-apply the callback. + +#### Scenario: Unbonding node with no family and no pending invitations is a no-op +- **WHEN** `OnNymNodeUnbond { node_id }` is invoked for a node with no membership and no pending invitations +- **THEN** the call succeeds, no storage is changed (apart from emitting the cleanup event), and no error is returned + +#### Scenario: Unbonding node in a family loses its membership +- **WHEN** `OnNymNodeUnbond { node_id }` is invoked for a node currently in family `F` +- **THEN** `family_members[node_id]` is removed, `F.members` is decremented, and a `PastFamilyMember` is archived with `removed_at = env.block.time.seconds()` + +#### Scenario: Unbonding node's pending invitations are archived as Rejected +- **WHEN** node `n` has pending invitations from families `F1` and `F2` and `OnNymNodeUnbond { node_id: n }` is invoked +- **THEN** both pending entries are removed and `past_family_invitations[((F1.id, n), …)]` and `past_family_invitations[((F2.id, n), …)]` each carry `status = Rejected { at: env.block.time.seconds() }` + +### Requirement: Expired pending invitations remain in storage until explicitly cleared + +The contract SHALL NOT run any background sweep of expired pending invitations. A `FamilyInvitation` whose `expires_at <= env.block.time.seconds()` SHALL remain in `pending_family_invitations` until either the family owner revokes it, the node controller rejects it, or the family is disbanded. Accept attempts against such entries MUST fail with `InvitationExpired`. Read queries SHALL surface a boolean `expired` flag (`now >= invitation.expires_at`) on each returned `PendingFamilyInvitationDetails` so callers can filter without doing the comparison themselves. + +#### Scenario: Expired invitation is still listed by pending queries +- **WHEN** family `F` has a pending invitation for node `n` whose `expires_at` is in the past and `GetPendingInvitationsForFamilyPaged { family_id: F.id }` is queried +- **THEN** the result includes the entry with `expired = true` + +#### Scenario: Expired invitation can be revoked or rejected but not accepted +- **WHEN** an expired invitation exists for `(F.id, n)` +- **THEN** `AcceptFamilyInvitation` fails with `InvitationExpired`, but `RevokeFamilyInvitation` (by `F`'s owner) and `RejectFamilyInvitation` (by `n`'s controller) both succeed and archive the invitation with the corresponding terminal status + +### Requirement: Per-`(family, node)` archive slots use sequential counters starting at 0 + +Both `past_family_invitations` and `past_family_members` SHALL be keyed by `((family_id, node_id), counter: u64)`. The contract SHALL maintain explicit per-`(family, node)` counter maps (`past_family_invitation_counter`, `past_family_member_counter`), starting at `0` for each new pair and incrementing by `1` on each archival write. Counters MUST be independent across distinct `(family, node)` pairs and across the two archive types. + +#### Scenario: First archive slot for a new pair is 0 +- **WHEN** a node and family appear in either archive for the first time +- **THEN** the entry is keyed with `counter = 0` + +#### Scenario: Distinct pairs have independent counters +- **WHEN** archive entries are written under keys `(F1, n)` and `(F2, n)` in any order +- **THEN** each pair's counter starts independently at `0` + +### Requirement: GetFamilyMembership returns the family id a node belongs to, or None + +`QueryMsg::GetFamilyMembership { node_id }` SHALL return `NodeFamilyMembershipResponse { node_id, family_id }` where `family_id` is `Some(NodeFamilyId)` iff `family_members[node_id]` is populated, and `None` otherwise. The query MUST NOT fail when `node_id` is unknown — it returns `family_id: None`. The query is the canonical way for route-selection consumers to check whether two node ids belong to the same family without scanning members. + +#### Scenario: Member node returns its family id +- **WHEN** node `n` is currently a member of family `F` and `GetFamilyMembership { node_id: n }` is queried +- **THEN** the response carries `family_id = Some(F.id)` + +#### Scenario: Non-member node returns None +- **WHEN** `GetFamilyMembership { node_id }` is queried for a node that has no membership record (never joined, or has since left/been kicked/unbonded) +- **THEN** the response carries `family_id = None` and `node_id` echoed back + +### Requirement: Single-family-by-id, by-name, and by-owner queries return an `Option` + +The contract SHALL expose three single-family lookups via `QueryMsg::GetFamilyById`, `GetFamilyByName`, and `GetFamilyByOwner`, each returning a response that echoes the queried key back to the caller for correlation and a `family: Option` field that is `None` when no match exists. `GetFamilyByName` MUST normalise the input via the same `normalise_family_name` function the create path uses before consulting the unique index. `GetFamilyByOwner` MUST bech32-validate the input. + +#### Scenario: GetFamilyByName is invariant under input formatting +- **WHEN** family `F` exists with `name = "MyFamily"` and `GetFamilyByName { name: "my family" }` is queried +- **THEN** the response carries `family = Some(F)` (the lookup hits the unique normalised-name index) + +#### Scenario: Missing match returns None +- **WHEN** any of the three single-family queries is called with a key that matches no family +- **THEN** the response carries `family = None` and echoes the queried key + +#### Scenario: GetFamilyByOwner rejects an invalid bech32 address +- **WHEN** `GetFamilyByOwner { owner }` is called with a non-bech32 string +- **THEN** the call returns an error sourced from `Addr::validate` + +### Requirement: Paginated queries use exclusive `start_after`, default limit 50, max limit 100 + +Every paginated query (`GetFamiliesPaged`, `GetFamilyMembersPaged`, `GetAllFamilyMembersPaged`, `GetPendingInvitationsForFamilyPaged`, `GetPendingInvitationsForNodePaged`, `GetAllPendingInvitationsPaged`, `GetPastInvitationsForFamilyPaged`, `GetPastInvitationsForNodePaged`, `GetAllPastInvitationsPaged`, `GetPastMembersForFamilyPaged`, `GetPastMembersForNodePaged`) SHALL accept `start_after: Option` (exclusive) and `limit: Option`. The default `limit` SHALL be `50` and SHALL be clamped to `100` as a hard cap. Results SHALL be in ascending cursor order. Each response SHALL include a `start_next_after: Option` derived from the last entry of the page, with `None` indicating the page is empty (the caller treats this as end-of-list). + +Per-family / per-node paginated queries SHALL NOT verify that the supplied `family_id` or `node_id` corresponds to an existing entity — an unknown id simply yields an empty page. + +#### Scenario: Limit is defaulted and clamped +- **WHEN** any paginated query is called with `limit = None` +- **THEN** at most 50 entries are returned +- **AND** when called with `limit = Some(10_000)` at most 100 entries are returned + +#### Scenario: Empty page signals end-of-list +- **WHEN** a paginated query has no more entries past the supplied `start_after` +- **THEN** the response carries an empty entry list and `start_next_after = None` + +#### Scenario: Unknown scope id yields an empty page rather than an error +- **WHEN** `GetFamilyMembersPaged { family_id: 999_999, .. }` is queried for a non-existent family id +- **THEN** the response carries an empty `members` list and `start_next_after = None` (no error is returned) + +### Requirement: Pending-invitation queries stamp each entry with its expiry flag + +Queries returning pending invitations (`GetPendingInvitation`, `GetPendingInvitationsForFamilyPaged`, `GetPendingInvitationsForNodePaged`, `GetAllPendingInvitationsPaged`) SHALL wrap each invitation in `PendingFamilyInvitationDetails { invitation, expired }` where `expired = env.block.time.seconds() >= invitation.expires_at`. Past-invitation and past-member queries do not carry this flag (they are terminal-state archives). + +#### Scenario: Future-dated invitation is marked not expired +- **WHEN** a pending invitation has `expires_at = env.block.time.seconds() + 60` and any pending-invitation query returns it +- **THEN** the returned `PendingFamilyInvitationDetails.expired` is `false` + +#### Scenario: Past-dated invitation is marked expired +- **WHEN** a pending invitation has `expires_at = env.block.time.seconds() - 1` +- **THEN** any pending-invitation query that returns it sets `expired = true` + +### Requirement: Storage-key constants are part of the public contract + +Every constant exported under `nym_node_families_contract_common::constants::storage_keys` SHALL be treated as part of the public contract surface. Off-chain indexers and migration tooling may depend on these exact byte strings. Changing the value of any existing constant — including renaming a namespace — SHALL be considered a breaking change for already-deployed contracts and SHALL be accompanied by a data migration via `queued_migrations`. Adding new constants for new storage maps is non-breaking. The current set covers the contract-level items (admin, config, mixnet contract address, family id counter), the primary maps (`families`, `node-family-members`, `invitations`, `past-invitations`, `past-family-member`), every secondary index (`__owner`, `__name`, `__family`, `__node`), and the per-`(family, node)` archive counters — refer to `constants.rs` for the authoritative list. + +#### Scenario: Storage key constants are reachable from the common crate +- **WHEN** an off-chain consumer imports `nym_node_families_contract_common::constants::storage_keys` +- **THEN** it observes the full set of storage-key constants the contract uses, without taking a dependency on the contract crate itself + +### Requirement: Emitted events form a stable public surface + +Every event name and attribute key exported under `nym_node_families_contract_common::constants::events` SHALL be treated as part of the public contract surface. Each successful **state-mutating user-facing execute path** (every variant of `ExecuteMsg` except `UpdateConfig`, which is an admin handler that returns `Response::default()` without an event) SHALL emit exactly one event whose name and attribute keys come from these constants. Renaming an event name constant, renaming an attribute-key constant, or changing the set of attributes a given event carries SHALL be treated as breaking changes. Adding new constants for new events / attributes is non-breaking. + +At the time of this spec the constant surface comprises (refer to `constants.rs` for the authoritative list): + +- `family_creation` — attributes: `family_name`, `owner_address`, `family_id`, `paid_fee` +- `family_disband` — attributes: `family_id`, `owner_address`, `refunded_fee` +- `family_invitation` — attributes: `family_id`, `node_id`, `expires_at` +- `family_invitation_revoked` — attributes: `family_id`, `node_id` +- `family_invitation_accepted` — attributes: `family_id`, `node_id` +- `family_invitation_rejected` — attributes: `family_id`, `node_id` +- `family_member_left` — attributes: `family_id`, `node_id` +- `family_member_kicked` — attributes: `family_id`, `node_id` +- `family_node_unbond_cleanup` — attributes: `node_id` + +**Note for indexer authors (non-normative)**: CosmWasm wraps user-emitted events in a `wasm-` prefix when they land in the tendermint event log. So `family_creation` appears as `wasm-family_creation` on the chain side, `family_invitation` as `wasm-family_invitation`, etc. The constants in `constants::events` are the *unprefixed* names — indexers querying the chain need to add the `wasm-` prefix themselves (or use the prefix-stripping helpers most Cosmos indexer SDKs already provide). + +#### Scenario: Each successful state-mutating execute path emits exactly its named event +- **WHEN** any of the execute paths listed above succeeds (i.e. every `ExecuteMsg` variant other than `UpdateConfig`) +- **THEN** the response carries exactly one event whose `ty` equals the corresponding constant from `constants::events` and whose attributes include each of the listed keys + +#### Scenario: UpdateConfig is the exception — no event is emitted +- **WHEN** the admin sends `ExecuteMsg::UpdateConfig` and the call succeeds +- **THEN** the response is `Response::default()` and carries no event (this is intentional — `UpdateConfig` is administrative metadata, not a tracked state transition) diff --git a/openspec/changes/archive/2026-05-20-node-families-contract-spec/tasks.md b/openspec/changes/archive/2026-05-20-node-families-contract-spec/tasks.md new file mode 100644 index 0000000000..fec25dd9f3 --- /dev/null +++ b/openspec/changes/archive/2026-05-20-node-families-contract-spec/tasks.md @@ -0,0 +1,33 @@ +## 1. Verify spec coverage against the live contract + +- [x] 1.1 Compare each `ExecuteMsg` variant in `common/cosmwasm-smart-contracts/node-families-contract/src/msg.rs` against the spec to confirm every execute path has a corresponding requirement with scenarios. +- [x] 1.2 Compare each `QueryMsg` variant against the spec to confirm every read path is covered (single-family lookups, current-membership listings, pending-invitation listings, past-invitation archive listings, past-member archive listings). +- [x] 1.3 Compare each `NodeFamiliesContractError` variant against the spec to confirm every error has a scenario that triggers it, and that the error name in the scenario matches the enum variant exactly. +- [x] 1.4 Confirm every event name and attribute key in `nym_node_families_contract_common::constants::events` is named verbatim in the spec's events requirement. +- [x] 1.5 Confirm every storage-key constant in `nym_node_families_contract_common::constants::storage_keys` is named verbatim in the spec's storage-keys requirement. + +## 2. Cross-check against the contract unit tests + +- [x] 2.1 For each `#[test]` in `contracts/node-families/src/storage/mod.rs`, identify the requirement(s) and scenario(s) in the spec that it exercises. Flag any test that asserts behaviour not yet captured in the spec. +- [x] 2.2 Do the same for `contracts/node-families/src/transactions.rs` tests (handler-level). +- [x] 2.3 Do the same for `contracts/node-families/src/queries.rs` tests. +- [x] 2.4 Do the same for `contracts/node-families/src/helpers.rs` tests (notably `normalise_family_name`). +- [x] 2.5 For each spec scenario that has no corresponding contract unit test, decide whether to add a test or annotate the scenario as covered indirectly. + +## 3. Validate via openspec tooling + +- [x] 3.1 Run `openspec validate node-families-contract-spec` and confirm it reports "valid". +- [x] 3.2 Run `openspec show node-families-contract-spec` and review the rendered output for readability and section ordering. +- [x] 3.3 Run `openspec status --change node-families-contract-spec` and confirm `applyRequires` is satisfied (`tasks` artifact present, all dependencies done). + +## 4. Reviewer pass + +- [x] 4.1 Walk through `proposal.md` with a reviewer to confirm the "Why" and "Capabilities" sections reflect the team's understanding of what node families is for. +- [x] 4.2 Walk through `design.md` Decisions 1–10 with a reviewer to confirm each rationale matches the team's reasoning at the time the contract was built (anchor commit `a21a01cf1a`). +- [x] 4.3 Walk through `specs/node-families-contract/spec.md` requirement by requirement; for each disagreement, decide whether the spec is wrong (update the spec) or the implementation is wrong (open a follow-on change). +- [x] 4.4 Resolve the three Open Questions in `design.md` or move them to a follow-on change. + +## 5. Archive the change + +- [x] 5.1 Once reviewed and accepted, run `openspec archive node-families-contract-spec` to promote `specs/node-families-contract/spec.md` into `openspec/specs/node-families-contract/spec.md` as the canonical spec. +- [x] 5.2 Confirm the archived spec is the one referenced by future delta specs (route-policy, operator-verification, etc.). diff --git a/openspec/changes/archive/2026-05-21-ecash-contract-spec/.openspec.yaml b/openspec/changes/archive/2026-05-21-ecash-contract-spec/.openspec.yaml new file mode 100644 index 0000000000..8b76914981 --- /dev/null +++ b/openspec/changes/archive/2026-05-21-ecash-contract-spec/.openspec.yaml @@ -0,0 +1,2 @@ +schema: spec-driven +created: 2026-05-20 diff --git a/openspec/changes/archive/2026-05-21-ecash-contract-spec/design.md b/openspec/changes/archive/2026-05-21-ecash-contract-spec/design.md new file mode 100644 index 0000000000..62e0a3f7be --- /dev/null +++ b/openspec/changes/archive/2026-05-21-ecash-contract-spec/design.md @@ -0,0 +1,186 @@ +## Context + +The ecash CosmWasm contract is the on-chain leg of the ticketbook credential protocol. It receives deposits from clients, mints a globally-unique sequential `deposit_id`, persists the depositor-claimed ed25519 identity public key, and exposes that record to off-chain nym-api signers that perform the blind-signing protocol. The contract is implemented in `contracts/ecash/` with the shared message / type / event surface in `common/cosmwasm-smart-contracts/ecash-contract/`, and is built on the [`sylvia`](https://docs.cosmwasm.com/sylvia) macro framework rather than hand-rolled `instantiate`/`execute`/`query` dispatchers. + +The contract has shipped, is in active use, and integrates with two other contracts in the workspace: a `cw4` group contract (referenced via `Config::group_addr`) and a `cw3`-style multisig contract (referenced via the `multisig` `Admin` slot). The mixnet contract is **not** in the trust path here — that is a node-families concern. + +This document captures the architectural choices behind the contract as it exists today, so reviewers, integrators (nym-api signers, gateways, indexers), and future maintainers have a single normative reference. There is no behaviour change being proposed. + +## Goals / Non-Goals + +**Goals:** +- Capture the trust boundary between the contract and nym-api signers: which checks the contract owns (deposit price, deposit-id uniqueness, persistence of claimed pubkey) and which it relies on signers to perform off-chain (ed25519 ownership proof, double-issue prevention, blacklist enforcement). +- Document the **authorisation model**: `contract_admin` is a real admin (pricing / whitelist mutations, replaceable via `UpdateAdmin`); `multisig` is a stored cw3 contract pointer that gates `RedeemTickets`. Both happen to live in `cw_controllers::Admin` slots, but the wrapper is used only as a generic address-equality helper for the second. +- Document the **tiered-pricing data model** (default deposit + per-address `reduced_deposits` overrides) and the statistics invariant tying them together. +- Document the **raw-bytes deposit storage** shortcut and its trade-offs. +- Document the **stubbed blacklist surface** as part of the public schema, including the dead-but-wired code paths. +- Document the **storage-key, event, and reply-id constants** that form the contract's external interface for indexers and upgrades. + +**Non-Goals:** +- The off-chain blind-signature protocol or nym-api signer state machine (`already_issued`, blacklist enforcement, DKG epoch gating, partial-signature aggregation). +- The cw3 multisig contract internals (proposal voting, threshold logic). +- The cw4 group contract internals. +- The ticketbook protocol itself (zkSNARK construction, partial vs aggregate signature combination, expiration date signatures, coin-indices signatures). +- The eventual pool contract that `holding_account` is reserved for — its scope and storage transition is out of scope here. +- Re-enabling the blacklist. The redesign is acknowledged as future work; the spec captures the *current* surface, which is stubbed. + +## Decisions + +### Decision 1: `cw_controllers::Admin` is used as a generic address-equality helper, not as a "two admins" model + +**Choice.** The contract has two `cw_controllers::Admin` slots, but only one is an admin in the operational sense: + +- `contract_admin` — a real admin. A single Cosmos SDK address that gates pricing mutations (`UpdateDefaultDepositValue`, `SetReducedDepositPrice`, `RemoveReducedDepositPrice`) and admin transfer (`UpdateAdmin`). Set on instantiation to the message sender. Replaceable via the `cw_controllers::Admin::execute_update_admin` handshake (driven by `UpdateAdmin`). +- `multisig` — a stored pointer to the cw3 multisig contract. Used only for its address-equality mechanics: `assert_admin(deps, sender)` reduces to "is the caller equal to the stored address?", which on the ecash contract's side is the entire gating logic for `RedeemTickets`. There is no admin-transfer handshake on this slot and no execute path that mutates it. + +**Why this shape.** Putting `multisig` in an `Admin` slot is a misuse of the wrapper's name — `cw_controllers::Admin` was designed for full admin semantics (set / get / assert / transfer), but the contract uses only `set` (once, at instantiation), `get` (in `must_get_multisig_addr`), and `assert_admin` (in `RedeemTickets`). The wrapper happened to be a convenient "remember-this-address-and-let-us-check-equality-later" helper. A reviewer reading `self.multisig.assert_admin(...)` should mentally substitute "is the caller our configured cw3 contract?" — there is no internal multi-signature scheme on the ecash contract itself. + +**Alternative considered.** A plain `Item` for the multisig pointer with a small inline `assert_caller_is_multisig` helper. Equivalent at runtime; would have made the naming honest. Not changed because storage key `"multisig"` is part of the public surface and renaming it would require a coordinated migration. + +**Consequence.** The `"multisig"` storage key is preserved (renaming would break already-deployed contracts) and the spec describes the actual mechanics rather than the suggestive wrapper name. The `multisig` slot's `Admin`-shape transfer machinery is reachable in code but is never exercised by any execute path. New reviewers should read the wrapper choice as historical, not as a statement about authorisation design. + +### Decision 2: The contract stores the claimed ed25519 pubkey but never verifies control of the private key + +**Choice.** `DepositTicketBookFunds { identity_key }` accepts a bs58-encoded ed25519 public key as an opaque string and persists it under the deposit's id. The contract performs only schema-level validation (the bs58 string must decode to exactly 32 bytes when read back via `Deposit::to_bytes` / `try_from_bytes`). + +**Why.** Verifying possession of the corresponding private key on-chain would require either a signature over a contract-supplied challenge (round-trip + chain-state machinery that CosmWasm does not provide ergonomically) or trusting the depositor's Cosmos SDK transaction signature, which is keyed on a separate address and proves nothing about the supplied ed25519 key. The ownership proof is naturally produced where the key is *used*: in the `BlindSignRequestBody` that the depositor later sends to nym-api signers, where they bind a request-specific signature to the claimed key. + +**Consequence.** Anyone willing to pay the deposit can submit a deposit claiming any ed25519 pubkey. nym-api signers MUST verify the ed25519 ownership proof at `post_blind_sign` time before issuing a partial blind signature; the contract is not the enforcement point. Spec scenarios make this explicit so that future readers do not mistake the contract for an authentication boundary. + +### Decision 3: Deposit-issue de-duplication is per-signer-local, not on-chain + +**Choice.** Each `deposit_id` is unique globally (monotonic `u32` counter), but the contract has no notion of "issued" or "consumed." It is the responsibility of each nym-api signer to maintain its own ledger (`state.already_issued(deposit_id)`) and return the cached blinded signature instead of re-signing. + +**Why.** The blind-signature protocol is partial per signer — different signers operate independently and must each refuse to re-issue against the same deposit. A contract-side "issued" flag would either need every signer to write back (cross-contract write storm, signer-trust assumption) or would only enforce single-issuance globally without preventing a malicious signer from re-issuing locally. Local ledgers solve the actual threat (a signer being tricked into issuing twice) at the right layer. + +**Consequence.** A deposit can be queried any number of times and its `(deposit_id, identity_key)` pair is always retrievable. Replay protection at the credential layer is entirely a signer concern. The spec calls this out as a deliberate boundary so that the absence of an "issued" state on the contract is not read as a bug. + +### Decision 4: Deposits are stored as raw 32-byte ed25519 pubkeys under a custom namespace, bypassing `cw_storage_plus` JSON serialisation + +**Choice.** `DepositStorage` writes deposits via `storage.set(&storage_key, &bytes)` where `bytes` is the 32-byte raw ed25519 pubkey extracted from the bs58 string. The namespace is `b"deposit"`, keyed by the big-endian `u32` deposit id. Reads use a matching custom `StoredDeposits` reader. This sits alongside a normal `cw_storage_plus::Item` for the counter (`"deposit_ids"`). + +**Why.** A bs58-encoded ed25519 public key is ~44 bytes; raw is exactly 32 bytes. The JSON-serialised `Deposit { bs58_encoded_ed25519_pubkey: "..." }` adds the field-name overhead on top. Over a contract lifetime that may accumulate hundreds of thousands of deposits, the savings compound and meaningfully reduce storage gas for paginated reads. + +**Alternative considered.** A standard `Map` keyed on `DepositId`. Rejected for storage cost; the duplication of a thin custom reader/writer is judged worth the gas savings. + +**Consequence.** The `deposit` namespace is *not* a `cw_storage_plus::Map` — it cannot be iterated via `Map::range` and its key encoding is bespoke (`Path::new(b"deposit", ...)`). Any future migration that needs to walk deposits must use `StoredDeposits::deserialize_deposit_record`. Audit notes: this is the one spot where the contract steps outside the framework, deliberately. The spec lists `"deposit"` as a public storage namespace alongside `"deposit_ids"`. + +### Decision 5: Deposit ids are sequential `u32`, start at 0, and the counter holds the *next* id + +**Choice.** The counter `Item` (`"deposit_ids"`) is unset on a fresh contract and treated as zero. `next_id` returns the current value (the id assigned to the new deposit) and persists `current + 1`. `total_deposits_made` reads the counter directly — it always equals the number of deposits already performed. `latest_deposit` returns the counter as-is too, which is "the *next* id" — currently consumed only via `GetLatestDeposit`, which re-loads the deposit at that id (yielding `None` if the contract has not yet seen a deposit). + +**Why.** Counting via the "next id" convention costs zero extra storage compared to a separate count field. The first deposit getting id `0` (rather than `1`) is convenient for protobuf-style optional defaults but is otherwise immaterial. + +**Consequence.** A consumer that calls `GetLatestDeposit` on a fresh contract receives `LatestDepositResponse { deposit: None }`. The id space is `u32`; overflow at billions of deposits is not a practical concern but is technically unbounded. + +### Decision 6: Three-tier pricing with explicit fall-back rules + +**Choice.** Each `DepositTicketBookFunds` is classified at deposit time: + +1. If the sent amount equals the configured **default** deposit, the deposit is treated as a default-price deposit (regardless of whether the sender is in the reduced-deposit whitelist). +2. Otherwise, if the sender has a reduced-deposit entry and the sent amount equals that reduced price, the deposit is treated as a reduced-price deposit and attributed to the sender's per-account counters. +3. Otherwise, the transaction errors with `EcashContractError::WrongAmount { received, amount }`, where `amount` is the reduced amount (if the sender is whitelisted) or the default amount. + +**Why.** Whitelisted accounts often run automation that pre-dates their whitelist entry, sending the default amount. Treating that as "wrong amount" would break in-flight integrations; treating it as a default-price deposit gracefully degrades. Conversely, a whitelisted account that pays the *wrong* reduced amount is almost certainly misconfigured and should be told so explicitly. + +**Consequence.** The statistics buckets (`deposits_with_default_price` vs `deposits_with_custom_price`) reflect what was actually paid, not the account's tier. The reduced-price storage map (`reduced_deposits`) is consulted only when classifying a non-default amount; it is never auto-applied. The invariant captured under Decision 7 binds these together. + +### Decision 7: Statistics invariant: `default_count + sum(custom_count_per_account) == total_deposits_made` + +**Choice.** Three accumulators run in parallel on every deposit: + +- `PoolCounters.total_deposited` (`Item`) — global value across all tiers; used by the eventual pool-contract migration. +- `DepositStatsStorage.deposits_with_default_price` (`Item`) and `..._amounts` (`Item`) — global default-price totals. +- `DepositStatsStorage.deposits_with_custom_price` (`Map`) and `..._amounts` (`Map`) — per-account custom-price totals. + +The contract test suite asserts `default_count + custom_total_count == deposits.total_deposits_made()` after every deposit. `total_deposits_made` is derived from the deposit-id counter (Decision 5), tying everything back to a single source of truth. + +**Why.** The query `GetDepositsStatistics` reassembles the picture by joining all three; without the invariant, indexers could observe inconsistencies (default + custom < total, or > total) during multi-tx blocks. Maintaining the invariant requires that *all* deposit writes go through `deposit_ticket_book_funds`. Raw storage writes (`storage.set(...)`) on the `deposit` namespace would silently break this. + +**Consequence.** Future code that touches the `deposits` storage *must* also update the corresponding stats counter, or it violates the invariant. The migration path (`queued_migrations::add_tiered_pricing`) handles this by reading the pre-migration totals and backfilling them into `deposits_with_default_price[_amounts]` (since all pre-migration deposits were at the default price). The `assert_counts_consistent` test helper is shipped under `#[cfg(test)]` as the canonical post-deposit assertion. + +### Decision 8: `expected_invariants.ticket_book_size` as a coordination tripwire + +**Choice.** On instantiation, the contract snapshots `nym_network_defaults::TICKETBOOK_SIZE` into `Item { ticket_book_size }` (`"expected_invariants"`). Every code path that consults the ticketbook size (`get_ticketbook_size`) re-reads the stored value and compares it to the *current* crate constant; on mismatch it errors with `TicketBookSizeChanged { at_init, current }` — a guaranteed-loud failure intended to be impossible to silently ignore. + +**Why.** The ticketbook size is a network-wide protocol parameter that pricing decisions bake in (default deposit min, reduced deposit min). If `nym-network-defaults` ever ships a new constant without a coordinated contract migration, every priced operation will fail loudly rather than silently mis-price. The check is a one-storage-read tax per priced operation in exchange for a hard-to-misconfigure deploy. + +**Consequence.** Bumping `TICKETBOOK_SIZE` in network-defaults is a coordinated migration: deploy a new contract version, run `MigrateMsg`, which must overwrite `expected_invariants` with the new constant. The current `migrate` handler does *not* do this — it would need an additional queued migration. The spec captures the storage key and the error variant so the failure mode is discoverable. + +### Decision 9: Reply IDs are hard-coded numeric constants with no schema metadata + +**Choice.** `BLACKLIST_PROPOSAL_REPLY_ID = 7759` and `REDEMPTION_PROPOSAL_REPLY_ID = 2137`. The reply dispatcher returns `EcashContractError::InvalidReplyId { id }` for any unknown id. + +**Why.** Reply IDs are private contract metadata — they carry no semantic content for external observers. Hard-coding keeps the dispatch path branchless and is consistent with the rest of the contract codebase. The arbitrary chosen integers do not need to be stable across redeploys, but *are* stable for any given deployed version. + +**Consequence.** Tests that mock submessage replies must use these exact integers. Changing them between contract versions would invalidate any in-flight submessage (the in-flight reply would arrive after a chain restart with a different code id and dispatch to "unknown"). The spec lists them as part of the public surface even though no off-chain consumer reads them. + +### Decision 10: Stubbed blacklist remains in the public schema as wired-but-unreachable code + +**Choice.** `ExecuteMsg::ProposeToBlacklist`, `ExecuteMsg::AddToBlacklist`, `QueryMsg::GetBlacklistedAccount`, `QueryMsg::GetBlacklistPaged`, the `blacklist: Map` storage, the `Blacklisting` type, the `create_blacklist_proposal` helper, and the `handle_blacklist_proposal_reply` reply handler are all present in source. Both execute handlers short-circuit with `EcashContractError::UnimplementedBlacklisting`; the queries succeed but always return empty results on a freshly deployed contract. + +**Why.** The blacklist is an acknowledged-incomplete feature. Removing the schema entries would be a breaking change for any client that already encodes them; removing the storage would obstruct future migrations. Keeping the wiring with explicit `Err(UnimplementedBlacklisting)` plus commented-out original implementations makes the redesign starting point obvious without exposing partial behaviour. + +**Alternative considered.** Delete the schema variants outright. Rejected because (a) the schema is consumed by `cosmwasm-schema`-generated TypeScript clients and removal would cascade through gateway / indexer codebases, and (b) keeping the entries documents the intended future shape of the contract. + +**Consequence.** The spec captures the stubbed handlers as first-class scenarios that always error, the blacklist queries as scenarios that always succeed with empty data, and the storage map as a public-surface namespace that exists but is unused. Any consumer treating an empty blacklist as a security guarantee is misreading the contract; the only enforcement is the off-chain `aux.ensure_not_blacklisted` check inside nym-api. + +### Decision 11: `RedeemTickets` is a legacy multisig-gated path; `RequestRedemption` is the current entry point + +**Choice.** Two redemption paths coexist: + +- `RequestRedemption { commitment_bs58, number_of_tickets }` — callable by any gateway. Validates `commitment_bs58` is a 32-byte sha256 digest (bs58-decoded). Creates a `Propose` SubMsg to the multisig contract under the title `BATCH_REDEMPTION_PROPOSAL_TITLE = "ecash-redemption"` with `commitment_bs58` as the description. The reply handler records the multisig-issued `proposal_id` and exposes it via `Response::set_data(proposal_id.to_be_bytes())` so the gateway sees it back. +- `RedeemTickets { n, gw }` — callable only by the multisig (`self.multisig.assert_admin(...)`). Bumps `pool_counters.tickets_requested_and_not_redeemed += n`. Emits `Event::new("ticket_redemption").add_attribute("moved_to_holding_account", "false")`. The `gw` argument is intentionally unused at runtime — preserved in source comments as `"_ = gw;"` so that chain scrapers can attribute the redemption to a gateway by reading the raw transaction body. + +**Why.** Originally `RedeemTickets` was the only redemption path and moved funds into the holding account. That mechanism was deprecated; the live path is the commitment-anchored `RequestRedemption` flow, which writes the proposal id and lets the multisig run the actual transfer logic. **`RedeemTickets` is dead code that has not been cleaned up yet.** It is still callable from any held multisig grant, still emits a recognisable event, and still bumps `tickets_requested_and_not_redeemed` — but no active code path or operational workflow relies on those side effects. The "_ = gw;" pattern and the `moved_to_holding_account="false"` attribute are remnants of the deprecated semantics, not load-bearing surface. + +**Consequence.** New gateway code should call `RequestRedemption`. `RedeemTickets` is documented in the spec as "legacy, multisig-only, near-noop" to describe current behaviour accurately, without claiming any consumer depends on it. A follow-on cleanup change should consider removing the handler (breaking-schema for any client still encoding `RedeemTickets`, but no live consumer is known to do so). Until then, the spec describes the handler honestly and the rustdoc follow-on can flag it for deletion. + +### Decision 12: Migration backfills default-price statistics from pre-tiered counters + +**Choice.** `MigrateMsg { initial_whitelist }` runs `queued_migrations::add_tiered_pricing`, which: + +1. Reads `deposits.total_deposits_made(storage)` and `pool_counters.total_deposited` from the pre-migration state. +2. Writes those values verbatim into `deposit_stats.deposits_with_default_price` and `deposits_with_default_price_amounts`. +3. Validates each entry in `initial_whitelist` (denom matches, amount strictly less than default, amount at least the ticketbook size) and saves it into `reduced_deposits`. + +`cw2::ensure_from_older_version` and `set_build_information!` run alongside. + +**Why.** Before the tiered-pricing migration, every deposit was made at the (single) default price. The migration formalises that invariant by populating the default-tier counters with the historical totals, so `GetDepositsStatistics` returns coherent numbers immediately after migration. Validating whitelist entries during migration prevents instantly-broken state on the new code path. + +**Consequence.** The migration is **one-way** — it assumes the pre-migration state had no custom-price counters. Re-running it on an already-migrated state would clobber the default-tier accumulators with the *current* `total_deposits_made` (which now includes custom-price deposits). The spec calls this out; `queued_migrations.rs` is named with the expectation that future deltas will add new entries (each guarded by a version check) rather than mutate `add_tiered_pricing`. + +## Risks / Trade-offs + +- **[Pubkey-claim spoofing on deposit]** → Anyone with the configured funds can submit a deposit claiming any ed25519 pubkey, exhausting that pubkey's ability to be re-deposited at the same id later. **Mitigation:** nym-api signers verify ownership in `post_blind_sign`; a spoofed deposit is unredeemable. Documented as the trust boundary in Decision 2. +- **[Statistics invariant relies on entry-point discipline]** → Any code path that bypasses `deposit_ticket_book_funds` (raw storage writes, direct `next_id` calls in migrations) silently breaks `default + custom == total`. **Mitigation:** invariant enforced by the `assert_counts_consistent` test helper; documented as a maintenance contract. +- **[Stubbed blacklist creates a false expectation]** → Operators reading the schema may think the contract enforces blacklisting. **Mitigation:** spec scenarios marked explicit; `UnimplementedBlacklisting` error variant exists specifically to be a discoverable runtime indicator. +- **[Multisig address is locked at instantiation]** → If the cw3 contract is redeployed, the ecash contract orphans (redemption proposals can no longer be created against the new multisig). **Mitigation:** documented as an operational constraint; a future migration could add `UpdateMultisigAddress`. Today there is no such path. +- **[Holding account is reserved but unused]** → Funds never transfer to `holding_account` in the current contract; the field exists for the future pool-contract transition. **Mitigation:** documented; `Config` query exposes it, so off-chain monitoring can verify it remains the expected address. +- **[`RequestRedemption` gas grows with commitment churn]** → Each call creates a multisig proposal. A gateway issuing high-frequency redemptions accrues many open proposals. **Mitigation:** out of scope here; multisig-side concern. +- **[Reply-id collisions across upgrades]** → Hard-coded `7759` / `2137` cannot collide today but could if a future upgrade adds a third reply variant. **Mitigation:** noted; new reply ids should pick distinct integers and never reuse old ones. + +## Migration Plan + +Not applicable to this change — this is a documentation-only artefact for code that has already shipped. The contract's most recent state-altering migration was `add_tiered_pricing` (Decision 12), which has already been executed on live deployments. + +Future spec deltas that *do* change behaviour should: + +1. Add a new function to `queued_migrations.rs` rather than amending `add_tiered_pricing`. +2. Bump `CARGO_PKG_VERSION` in `contracts/ecash/Cargo.toml`. +3. Coordinate the `MigrateMsg` invocation with the chain-governance migration transaction that pushes the new code id. +4. Document any new storage namespace, event, or reply id under the corresponding spec requirement. + +## Resolved Questions + +Three of the four questions considered during the spec walk-through were resolved on 2026-05-21 by keeping current behaviour: + +- **`holding_account` updatability** → keep locked at instantiation. The eventual pool-contract transition is handled as a fresh contract deploy rather than a mid-life mutation; matches the node-families precedent of treating cross-contract pointers as redeploy events. Avoiding an admin-gated update means admin compromise cannot retarget where future redemption funds would flow. +- **`multisig` address updatability** → keep locked at instantiation. Same rationale: if the cw3 multisig is redeployed under a new address, the ecash contract is redeployed alongside it. Not exposing an update path prevents admin compromise from hijacking redemption-finalisation authority. +- **`update_admin` renunciation** → keep the handler's mandatory-`Some(new_admin)` shape. Renunciation would leave pricing, whitelist, and admin-gated paths permanently unreachable — a one-way foot-gun with no operational benefit at the contract's current maturity. + +## Open Questions + +One question remains open and is deferred to a follow-on change rather than to this spec: + +- **Stubbed blacklist final disposition.** `ProposeToBlacklist`, `AddToBlacklist`, `GetBlacklistedAccount`, and `GetBlacklistPaged` remain in the public schema; the execute handlers always return `UnimplementedBlacklisting`; the `blacklist` storage map, `Blacklisting` type, `create_blacklist_proposal` helper, and `handle_blacklist_proposal_reply` reply handler are wired but unreachable. The choice between (a) finalising the redesign, (b) removing the stubbed schema entries (breaking change), or (c) leaving them as-is is left to the blacklist redesign change owner. This spec captures the current surface — the stubbed schema is part of the contract surface today and the spec describes that faithfully (Decision 10, Requirement "Stubbed blacklist execute handlers", Requirement "Blacklist queries succeed and return empty"). diff --git a/openspec/changes/archive/2026-05-21-ecash-contract-spec/proposal.md b/openspec/changes/archive/2026-05-21-ecash-contract-spec/proposal.md new file mode 100644 index 0000000000..9513cf843f --- /dev/null +++ b/openspec/changes/archive/2026-05-21-ecash-contract-spec/proposal.md @@ -0,0 +1,48 @@ +## Why + +The ecash CosmWasm contract (`contracts/ecash/`) is the on-chain anchor of the ticketbook credential pipeline. Clients escrow funds with the contract, which mints a sequential `deposit_id` and persists the ed25519 identity public key that the depositor will later use when requesting a blind signature from nym-api signers (`post_blind_sign` at `nym-api/src/ecash/api_routes/partial_signing.rs:55`). The contract itself does **not** verify ed25519 ownership — that proof lives in `BlindSignRequestBody` and is enforced off-chain; the contract's job is to provide a tamper-evident, gas-efficient on-chain record that signers can read by id. Gateways do not escrow funds here; they only participate on the redemption side (see `RequestRedemption` / `RedeemTickets`). + +The contract has shipped, is live, and exists only as Rust source plus inline comments. Several design choices are non-obvious from reading the code alone and have a habit of being re-derived during incident triage: + +- The use of `cw_controllers::Admin` as a generic address-equality helper for two distinct slots (`contract_admin` and `multisig`). The wrapper is named for the role it was designed for, but the contract uses it only for its `set` / `assert_admin` / `get` mechanics — `multisig` is not an "admin" in any operational sense, it is a stored pointer to the cw3 contract that gates `RedeemTickets`. Only `contract_admin` carries actual admin semantics (replaceable via `UpdateAdmin`). +- The deposit-storage shortcut that bypasses `cw_storage_plus` JSON serialisation in favour of raw 32-byte ed25519 representation under the `deposit` namespace. +- The tier-stratified bookkeeping (`PoolCounters` + `DepositStatsStorage`) that maintains a global total **and** a per-account custom-price total, while preserving the invariant `default_count + sum(custom_count) == total_deposits_made`. +- The blacklist surface is **fully wired but stubbed**: storage, helpers, reply handler, and event attribute exist; both `ProposeToBlacklist` and `AddToBlacklist` short-circuit to `UnimplementedBlacklisting`. This is intentional and the dead branches are preserved in source as commented-out reference for the eventual redesign. +- The `RedeemTickets` path is legacy dead code — still callable by the multisig, still bumps a counter and emits an event with `moved_to_holding_account="false"`, but no active code path or consumer depends on those side effects. Retained because it has not been cleaned up yet, not because anything requires it. A follow-on cleanup change should consider removing it (breaking-schema, but no known live consumer). + +Capturing the spec now — while the original author and reviewers are still around — is materially cheaper than reconstructing it from `git blame` later. + +## What Changes + +- Introduce a new capability spec `ecash-contract` covering the on-chain CosmWasm contract: instantiation, deposit submission (default + reduced tier), legacy redemption (`RedeemTickets`), redemption-proposal creation (`RequestRedemption`) and reply handling, admin operations (admin transfer, default deposit value, set/remove reduced price), the stubbed blacklist surface, the full query surface, migration (tiered-pricing backfill), and the storage / event / error surface that downstream tooling treats as a public contract. +- Document the **authorisation model**: `contract_admin` (a real admin, replaceable via `UpdateAdmin`) gates pricing / whitelist mutations; `multisig` (a stored cw3 contract pointer using the same `cw_controllers::Admin` wrapper for address-equality only) gates `RedeemTickets`. Per-handler authorisation is enumerated. +- Document the **deposit identity semantics**: the contract stores the claimed bs58-encoded ed25519 public key but does not verify control of the corresponding private key — that proof is performed off-chain by nym-api signers when honoring the `post_blind_sign` request. +- Document the **anti-double-issue boundary**: the contract guarantees globally-unique sequential `deposit_id`s, but de-duplication of credential issuance per deposit is enforced by each nym-api signer's local store (`state.already_issued`), not by the contract. +- Document the **stubbed blacklist surface** as a public-surface fact (current versions always return `UnimplementedBlacklisting`). +- Document the **storage layout** (raw key namespaces, `Item`/`Map` keys, the custom raw-bytes encoding used for the `deposit` namespace) and **event surface** (`deposited-funds`, `ticket_redemption`, plus attributes on auto-generated `wasm` events) since indexers and signers consume these as a stable interface. + +No code changes. No migrations. No new dependencies. This is a documentation-only deliverable that ratifies the current implementation as the baseline. A follow-on change `ecash-contract-rustdoc` will tighten in-source rustdoc to mirror the captured spec. + +## Capabilities + +### New Capabilities + +- `ecash-contract`: the CosmWasm contract that escrows deposits for ticketbook credentials, mints sequential deposit ids, stores claimed ed25519 identity keys for off-chain signer validation, gates redemption finalisation behind a multisig, and tracks tier-stratified deposit statistics. + +### Modified Capabilities + +_None — there are no existing specs in `openspec/specs/` for the ecash contract and this change does not alter on-chain behaviour._ + +## Impact + +- **Affected code**: none modified. The spec is derived from `contracts/ecash/` and `common/cosmwasm-smart-contracts/ecash-contract/` at HEAD on `develop`. +- **Affected consumers** (documented for traceability, not changed): + - `nym-api/src/ecash/` — reads deposits by id via `state.get_deposit(deposit_id)`, then at `post_blind_sign` (`partial_signing.rs:55`) enforces (a) per-signer-local double-issue prevention by checking `state.already_issued(deposit_id)` against its local `issued_partial_signature` store and returning the cached signature on a hit, and (b) ed25519 ownership by parsing `deposit.bs58_encoded_ed25519_pubkey` and verifying `request.signature` against the plaintext `IssuanceTicketBook::request_plaintext(&request.inner_sign_request, request.deposit_id)` (`nym-api/src/ecash/deposit.rs::validate_deposit`). Additional gating performed at the same entry point — signer-epoch eligibility (`ensure_signer`), expiration-date sanity, DKG-not-in-progress (`ensure_dkg_not_in_progress`), and an off-chain blacklist check (`aux.ensure_not_blacklisted`) — is independent of contract state. + - Clients — submit `DepositTicketBookFunds` to escrow funds and register a claimed ed25519 identity key. + - Gateways (legacy + current) — request batch redemption via `RequestRedemption` (current) or receive the transfer via `RedeemTickets` (legacy multisig-gated path); they do not call `DepositTicketBookFunds`. + - The cw3 multisig contract — receives `Propose` messages for batch redemption and (eventually) blacklisting; the ecash contract reads back the resulting `proposal_id` in its reply handler. + - The cw4 group contract — referenced via `Config::group_addr`; intended to gate the (currently stubbed) blacklist proposal flow to voting members. + - Chain indexers — consume the `deposited-funds` event (`deposit-id` attribute), the `ticket_redemption` event, and the `proposal_id` attribute on the auto-generated `wasm` event from redemption-proposal replies. +- **Dependencies**: none. CosmWasm storage layout (raw key strings: `"contract_admin"`, `"multisig"`, `"config"`, `"pool_counters"`, `"expected_invariants"`, `"deposit_ids"`, `"deposit"`, `"reduced_deposits"`, `"blacklist"`, `"deposits_with_default_price"`, `"deposits_with_default_price_amounts"`, `"deposits_with_custom_price"`, `"deposits_with_custom_price_amounts"`) is part of the spec surface — changing those keys is a breaking change for already-deployed contracts and must be treated as such by any future delta. The two reply IDs (`BLACKLIST_PROPOSAL_REPLY_ID = 7759`, `REDEMPTION_PROPOSAL_REPLY_ID = 2137`) are similarly load-bearing. +- **Non-goals**: the off-chain blind-signature protocol, nym-api signer state machine (`already_issued`, blacklist enforcement, DKG epoch gating), the ticketbook protocol itself, gateway-side commitment construction, the multisig contract internals, and the (currently stubbed) blacklist redesign. These all consume the contract or are consumed by it but live outside its boundary and will get their own specs in follow-on changes. +- **Known limitation — blacklist is stubbed**: `ExecuteMsg::ProposeToBlacklist` and `ExecuteMsg::AddToBlacklist` are part of the public schema but always return `EcashContractError::UnimplementedBlacklisting`. The reply handler for `BLACKLIST_PROPOSAL_REPLY_ID`, the `blacklist` storage map, and the `Blacklisting` type are all wired in code but unreachable from the public ExecuteMsg surface. Existing queries (`GetBlacklistedAccount`, `GetBlacklistPaged`) succeed but will return empty results on a freshly deployed contract. The spec documents this as the current contract surface; the redesign is out of scope. diff --git a/openspec/changes/archive/2026-05-21-ecash-contract-spec/specs/ecash-contract/spec.md b/openspec/changes/archive/2026-05-21-ecash-contract-spec/specs/ecash-contract/spec.md new file mode 100644 index 0000000000..716df4bdc2 --- /dev/null +++ b/openspec/changes/archive/2026-05-21-ecash-contract-spec/specs/ecash-contract/spec.md @@ -0,0 +1,501 @@ +## ADDED Requirements + +### Requirement: Contract instantiation persists the runtime config, multisig and admin addresses, and the ticketbook-size invariant + +The contract SHALL be instantiable exactly once via the standard CosmWasm `instantiate` entry point. The instantiation message SHALL carry `holding_account` (a string-form Cosmos SDK address reserved for the future pool-contract transition), `multisig_addr` (the cw3 multisig contract address that gates redemption finalisation), `group_addr` (the cw4 group contract referenced by future blacklist proposals), and `deposit_amount` (the default per-deposit price). The handler MUST: + +- bech32-validate `multisig_addr`, `holding_account`, and `group_addr`; an invalid `group_addr` MUST surface as `InvalidGroup { addr }`, an invalid `multisig_addr` or `holding_account` MUST surface as the underlying `StdError` from `addr_validate`; +- persist `info.sender` as the `contract_admin` via `cw_controllers::Admin::set` (the message itself does not carry an admin field; the sender becomes admin by convention); +- persist the validated `multisig_addr` as the `multisig` `Admin` slot; +- snapshot `nym_network_defaults::TICKETBOOK_SIZE` into `Item { ticket_book_size }` under the storage key `"expected_invariants"`; +- zero-initialise `PoolCounters` (`total_deposited`, `total_redeemed`, `tickets_requested_and_not_redeemed`) using the denom of the supplied `deposit_amount`; +- persist the assembled `Config { group_addr (as cw4::Cw4Contract), holding_account, deposit_amount }`; +- zero-initialise the default-price statistics accumulators (`deposits_with_default_price` and `deposits_with_default_price_amounts`); +- record the contract name and `CARGO_PKG_VERSION` via `cw2::set_contract_version`; +- record build information via `set_build_information!`. + +The instantiation handler SHALL return `Response::default()` (no events, no attributes, no data). + +#### Scenario: Valid instantiation persists every state slot +- **WHEN** `instantiate` is called with valid bech32 strings for `holding_account`, `multisig_addr`, `group_addr` and a well-formed `deposit_amount` +- **THEN** the contract stores `Config` verbatim, the validated multisig address (queryable via `multisig.assert_admin`), `info.sender` as the contract admin, the snapshotted `Invariants { ticket_book_size: TICKETBOOK_SIZE }`, zeroed `PoolCounters`, and zeroed default-price stats +- **AND** `cw2::get_contract_version` returns the crate's `CARGO_PKG_VERSION` +- **AND** the returned `Response` carries no events, attributes, or data + +#### Scenario: Invalid group address is rejected with a typed error +- **WHEN** `instantiate` is called with a `group_addr` that fails `Addr::validate` +- **THEN** the call returns `EcashContractError::InvalidGroup { addr }` and no state is persisted + +#### Scenario: Invalid multisig address propagates the `StdError` +- **WHEN** `instantiate` is called with a `multisig_addr` that fails `Addr::validate` +- **THEN** the call returns an `EcashContractError::Std` wrapping the underlying validation error and no state is persisted + +### Requirement: Migration handles version gating, default-price backfill, and whitelist seeding atomically + +The contract SHALL expose a `migrate` entry point taking `MigrateMsg { initial_whitelist: Vec }`. The handler MUST: + +- call `set_build_information!` to refresh stored build metadata; +- call `cw2::ensure_from_older_version` against `CONTRACT_NAME` and `CONTRACT_VERSION`; an on-chain version strictly greater than `CARGO_PKG_VERSION` MUST be rejected; +- run `queued_migrations::add_tiered_pricing(deps, initial_whitelist)`, which (a) reads `DepositStorage::total_deposits_made` and `PoolCounters::total_deposited` from the pre-migration state, (b) writes those values into `deposits_with_default_price` and `deposits_with_default_price_amounts` respectively (because every pre-migration deposit was at the default price), and (c) iterates `initial_whitelist`, validating each entry's denom and amount (see Requirement "Setting a reduced deposit price"), persisting each into `reduced_deposits`; +- return `Response::default()`. + +The migration MUST fail atomically if any whitelist entry fails validation — partial whitelist seeding MUST NOT be persisted. + +#### Scenario: Migration on contract with prior default-price deposits backfills both counters +- **WHEN** `migrate` is called with `initial_whitelist = []` on a contract that has performed `N > 0` deposits totalling `T` units +- **THEN** `deposits_with_default_price` reads `N` and `deposits_with_default_price_amounts` reads `T` (same denom as the contract config) + +#### Scenario: Migration with a valid whitelist persists every entry +- **WHEN** `migrate` is called with two well-formed `WhitelistedDeposit` entries +- **THEN** `reduced_deposits` returns the matching `Coin` for each address on subsequent reads + +#### Scenario: Migration with a single invalid whitelist entry rolls back the entire transaction +- **WHEN** `migrate` is called with `initial_whitelist = [valid_entry, invalid_entry]` where `invalid_entry` uses the wrong denom +- **THEN** the call returns `InvalidReducedDepositDenom { expected, got }` and `reduced_deposits` contains no entries from this migration + +#### Scenario: Newer on-chain version is rejected +- **WHEN** `migrate` is called against an on-chain `cw2` version strictly greater than `CARGO_PKG_VERSION` +- **THEN** the call returns an error and storage is unchanged + +### Requirement: Authorisation — contract admin and multisig pointer + +The contract SHALL maintain two `cw_controllers::Admin` slots at storage keys `"contract_admin"` and `"multisig"`. Only the first carries admin semantics in the operational sense; the second is a stored cw3 contract pointer that uses the same wrapper purely as a generic address-equality helper. + +- `contract_admin` SHALL gate `UpdateAdmin`, `UpdateDefaultDepositValue`, `SetReducedDepositPrice`, `RemoveReducedDepositPrice`. It is replaceable through `UpdateAdmin`, which dispatches `cw_controllers::Admin::execute_update_admin` (requiring the current admin to sign the transaction). +- `multisig` SHALL gate `RedeemTickets` via `assert_admin` (which on this slot is effectively "is the caller equal to the stored cw3 contract address?"). It SHALL NOT be updatable through any execute path; replacing it requires redeploying the contract. + +The wrapper's full admin-transfer machinery is reachable in code on both slots but is exercised only on `contract_admin`. + +#### Scenario: Non-admin call to a contract-admin-gated handler is rejected +- **WHEN** any of `UpdateDefaultDepositValue`, `SetReducedDepositPrice`, `RemoveReducedDepositPrice` is sent by an address other than the current `contract_admin` +- **THEN** the call returns `EcashContractError::Admin` wrapping `AdminError::NotAdmin` and state is unchanged + +#### Scenario: Non-multisig call to `RedeemTickets` is rejected +- **WHEN** `RedeemTickets { n, gw }` is sent by an address other than the configured `multisig` +- **THEN** the call returns `EcashContractError::Admin` wrapping `AdminError::NotAdmin` and `PoolCounters::tickets_requested_and_not_redeemed` is unchanged + +### Requirement: `DepositTicketBookFunds` classifies the sent amount and updates the correct statistics bucket + +`ExecuteMsg::DepositTicketBookFunds { identity_key }` SHALL accept exactly one coin in the configured denom (validated via `cw_utils::must_pay`) and classify the sender at deposit time: + +1. If the sent amount equals `Config::deposit_amount.amount`, the deposit is treated as a **default-price** deposit. The handler MUST call `DepositStatsStorage::new_default_deposit`, which increments `deposits_with_default_price` by 1 and adds the deposited amount to `deposits_with_default_price_amounts`. This branch fires *regardless* of whether the sender has a reduced-deposit entry. +2. Otherwise, if the sender has a `reduced_deposits[sender]` entry whose `amount` equals the sent amount, the deposit is treated as a **reduced-price** deposit. The handler MUST call `DepositStatsStorage::new_reduced_deposit`, which increments `deposits_with_custom_price[sender]` by 1 and adds the deposited amount to `deposits_with_custom_price_amounts[sender]`. +3. Otherwise, the call MUST fail with `EcashContractError::WrongAmount { received, amount }`, where `amount` is the reduced amount if the sender is whitelisted, else the default amount. + +After successful classification the handler MUST: + +- add the deposited amount to `PoolCounters.total_deposited.amount`; +- assign and persist a sequential `deposit_id` via `DepositStorage::save_deposit` (which decodes `identity_key` from bs58 to a 32-byte raw representation and writes it under the `"deposit"` namespace); +- emit a `deposited-funds` event with attribute `deposit-id` carrying the assigned id as a decimal string; +- set the response data to `deposit_id.to_be_bytes()` so callers can recover the id from the transaction result. + +The handler MUST NOT verify that the sender controls the private key matching the supplied `identity_key`. The identity-ownership proof is delegated to off-chain nym-api signers (`post_blind_sign` at `nym-api/src/ecash/api_routes/partial_signing.rs:55`). + +#### Scenario: Default-price deposit increments default counters and emits event with deposit id +- **WHEN** a sender with no reduced-deposit entry sends `DepositTicketBookFunds { identity_key }` with funds matching the default amount +- **THEN** `deposits_with_default_price` increases by 1, `deposits_with_default_price_amounts` increases by the deposited amount, `PoolCounters.total_deposited` increases by the deposited amount, a new `deposit_id` is persisted with the supplied `identity_key`, a `deposited-funds` event is emitted with the `deposit-id` attribute set to the new id, and the response data is the big-endian byte representation of the new id + +#### Scenario: Whitelisted sender paying the default amount is bucketed as default-price +- **WHEN** a whitelisted sender (entry in `reduced_deposits`) sends `DepositTicketBookFunds` with funds matching the **default** amount (not their reduced amount) +- **THEN** the deposit is recorded under `deposits_with_default_price` (not under `deposits_with_custom_price[sender]`), and the deposit is persisted normally + +#### Scenario: Whitelisted sender paying the reduced amount is bucketed as custom-price +- **WHEN** a whitelisted sender sends `DepositTicketBookFunds` with funds matching their reduced amount +- **THEN** `deposits_with_custom_price[sender]` increases by 1, `deposits_with_custom_price_amounts[sender]` increases by the reduced amount, and the deposit is persisted normally + +#### Scenario: Whitelisted sender paying neither default nor their reduced amount is rejected with the reduced amount as the expected +- **WHEN** a whitelisted sender sends an amount equal to neither `Config::deposit_amount.amount` nor `reduced_deposits[sender].amount` +- **THEN** the call returns `EcashContractError::WrongAmount { received, amount }` where `amount` is the sender's reduced amount + +#### Scenario: Non-whitelisted sender paying the wrong amount is rejected with the default amount as the expected +- **WHEN** a sender with no reduced-deposit entry sends an amount different from `Config::deposit_amount.amount` +- **THEN** the call returns `EcashContractError::WrongAmount { received, amount }` where `amount` is `Config::deposit_amount` + +#### Scenario: Missing, mismatched, or multi-denom funds are rejected by `must_pay` before amount classification +- **WHEN** `DepositTicketBookFunds` is sent with no attached coins, with multiple denom coins, or with a single coin in a denom different from `Config::deposit_amount.denom` +- **THEN** the call returns `EcashContractError::InvalidDeposit(PaymentError::NoFunds)`, `EcashContractError::InvalidDeposit(PaymentError::MultipleDenoms)`, or `EcashContractError::InvalidDeposit(PaymentError::MissingDenom())` respectively, before any classification, counter, or storage write + +### Requirement: Deposit identity-key payload is opaque to the contract; ownership is enforced off-chain + +The contract SHALL accept `identity_key: String` as an opaque payload at deposit submission time. The handler MUST NOT verify control of the corresponding ed25519 private key. The handler MUST persist the payload such that it round-trips losslessly through `Deposit::to_bytes` → 32-byte raw storage → `Deposit::try_from_bytes` → bs58 string; any payload that fails to decode to exactly 32 bytes via `bs58::decode` MUST surface as `EcashContractError::MalformedEd25519Identity` (raised by `Deposit::to_bytes` during the `save_deposit` flow). The proof-of-control check is performed off-chain by nym-api signers when honouring `post_blind_sign`. + +#### Scenario: Sender can claim any well-formed ed25519 pubkey +- **WHEN** sender `A` submits `DepositTicketBookFunds { identity_key: B_pubkey }` where `B_pubkey` is sender `B`'s ed25519 public key, paying the correct amount +- **THEN** the deposit is accepted and `GetDeposit { deposit_id }` returns `Deposit { bs58_encoded_ed25519_pubkey: B_pubkey }` + +#### Scenario: Malformed bs58 ed25519 payload is rejected at save time +- **WHEN** `DepositTicketBookFunds { identity_key: "not-a-valid-bs58-key" }` is submitted with the correct funds +- **THEN** the call returns `EcashContractError::MalformedEd25519Identity` and no deposit is persisted, no counters are incremented + +### Requirement: Deposit ids are sequential `u32` starting at 0, never recycled + +The contract SHALL maintain a single `Item` counter at the storage key `"deposit_ids"`. The counter SHALL be unset on a freshly instantiated contract and treated as zero. Each successful `DepositTicketBookFunds` invocation SHALL: + +- read the current counter value (defaulting to 0 when absent), which becomes the new deposit's id; +- persist `counter + 1` as the new counter value; +- write the 32-byte raw ed25519 pubkey for that id under the `"deposit"` storage namespace (bypassing JSON serialisation for storage efficiency — see `StoredDeposits`). + +`DepositStorage::total_deposits_made(storage)` and `DepositStorage::latest_deposit(storage)` SHALL both read the counter directly — `total_deposits_made` returns `unwrap_or(0)` (count of deposits ever performed), `latest_deposit` returns `may_load` (the *next* unused id, which is also the count). Deposit ids SHALL NOT be recycled even if the deposit can later be invalidated off-chain. + +#### Scenario: First deposit on a fresh contract gets id 0 +- **WHEN** the first-ever `DepositTicketBookFunds` is processed +- **THEN** the assigned `deposit_id` is `0`, the persisted counter becomes `1`, and `total_deposits_made` returns `1` + +#### Scenario: Subsequent deposits get strictly increasing ids +- **WHEN** three deposits are processed in sequence +- **THEN** they receive ids `0`, `1`, `2` and the counter becomes `3` + +### Requirement: Deposit statistics invariant — default count plus per-account custom counts equals total + +The contract SHALL maintain the invariant `DepositStatsStorage::get_total_deposits_made_with_default_price(storage) + sum(deposits_with_custom_price[a] for a in addrs) == DepositStorage::total_deposits_made(storage)` at all times after instantiation. This invariant MUST hold across every successful and failed transaction (a failed deposit MUST NOT touch any counter). The `#[cfg(test)] assert_counts_consistent` helper in `DepositStatsStorage` SHALL exist solely to validate this invariant in tests and is part of the maintenance contract for any code that writes to the `"deposit"` namespace. + +#### Scenario: Mixed default and reduced deposits maintain the invariant +- **WHEN** two default-price deposits and one reduced-price deposit by address `alice` are processed in any order +- **THEN** `deposits_with_default_price` reads `2`, `deposits_with_custom_price[alice]` reads `1`, `total_deposits_made` reads `3`, and `2 + 1 == 3` + +#### Scenario: A rejected `DepositTicketBookFunds` does not touch any counter +- **WHEN** `DepositTicketBookFunds` is rejected with `WrongAmount` +- **THEN** none of `deposit_ids`, `deposits_with_default_price`, `deposits_with_custom_price` change + +### Requirement: `UpdateDefaultDepositValue` is admin-gated and refuses values below the ticketbook size + +`ExecuteMsg::UpdateDefaultDepositValue { new_deposit: Coin }` SHALL be callable only by the contract admin (`contract_admin.assert_admin`). The handler MUST consult the on-chain `Invariants::ticket_book_size` via `get_ticketbook_size`; if the snapshotted value differs from the current crate `TICKETBOOK_SIZE`, the call MUST fail with `TicketBookSizeChanged { at_init, current }` *before* any further work. If `new_deposit.amount < TICKETBOOK_SIZE`, the call MUST fail with `DepositBelowTicketBookSize { amount, ticket_book_size }`. On success the handler SHALL overwrite `Config::deposit_amount` with `new_deposit` and emit a `wasm` event attribute `updated_deposit` carrying the new value as its `Coin::to_string()` form. + +Note: the handler does *not* validate that `new_deposit.denom` matches the existing config's denom. Changing the denom is permitted by the current handler but is operationally hazardous (existing reduced-deposit entries and statistics use the old denom). Reviewers should treat denom changes as a coordinated migration concern, not an admin operation. + +#### Scenario: Admin successfully bumps the default price +- **WHEN** the contract admin sends `UpdateDefaultDepositValue { new_deposit }` with `new_deposit.amount >= TICKETBOOK_SIZE` and the network-defaults `TICKETBOOK_SIZE` matches the snapshotted invariant +- **THEN** `Config::deposit_amount` equals `new_deposit` and the response contains a `wasm` attribute `updated_deposit = new_deposit.to_string()` + +#### Scenario: Non-admin call is rejected +- **WHEN** any non-admin sends `UpdateDefaultDepositValue` +- **THEN** the call returns `EcashContractError::Admin` and `Config::deposit_amount` is unchanged + +#### Scenario: Value below ticketbook size is rejected +- **WHEN** the admin sends `UpdateDefaultDepositValue { new_deposit }` with `new_deposit.amount < TICKETBOOK_SIZE` +- **THEN** the call returns `DepositBelowTicketBookSize { amount: new_deposit.amount, ticket_book_size: TICKETBOOK_SIZE }` + +### Requirement: `SetReducedDepositPrice` is admin-gated with denom, strict-less-than, and ticketbook-size validation + +`ExecuteMsg::SetReducedDepositPrice { address, deposit }` SHALL be callable only by the contract admin. The handler MUST validate `address` via `addr_validate`, then call `add_reduced_deposit_address`, which MUST: + +- reject `deposit.denom != Config::deposit_amount.denom` with `InvalidReducedDepositDenom { expected, got }`; +- reject `deposit.amount >= Config::deposit_amount.amount` with `ReducedDepositNotReduced { reduced, default }` (the reduced amount must be **strictly less than** the default); +- reject `deposit.amount < TICKETBOOK_SIZE` with `DepositBelowTicketBookSize { amount, ticket_book_size }` (subject to the same `get_ticketbook_size` tripwire as Requirement "UpdateDefaultDepositValue"); +- persist `reduced_deposits[address] = deposit` (overwriting any existing entry). + +On success the handler SHALL emit `wasm` attributes `action = "set_reduced_deposit_price"`, `address`, and `deposit` (as `Coin::to_string()`). + +#### Scenario: Admin sets a valid reduced price +- **WHEN** the admin sends `SetReducedDepositPrice { address, deposit }` with matching denom, amount strictly less than default, and amount at least the ticketbook size +- **THEN** `reduced_deposits[address] = deposit` and the response carries attributes `action = "set_reduced_deposit_price"`, `address`, `deposit` + +#### Scenario: Overwriting an existing entry succeeds +- **WHEN** the admin sends `SetReducedDepositPrice` for an address that already has a reduced entry +- **THEN** the existing entry is replaced with the new value (no error, no archiving of the old value) + +#### Scenario: Reduced amount not strictly less than default is rejected +- **WHEN** the admin sends `SetReducedDepositPrice` with `deposit.amount == Config::deposit_amount.amount` +- **THEN** the call returns `ReducedDepositNotReduced { reduced, default }` with both fields equal + +#### Scenario: Mismatched denom is rejected +- **WHEN** the admin sends `SetReducedDepositPrice` with a denom different from `Config::deposit_amount.denom` +- **THEN** the call returns `InvalidReducedDepositDenom { expected, got }` + +### Requirement: `RemoveReducedDepositPrice` is admin-gated and requires an existing entry + +`ExecuteMsg::RemoveReducedDepositPrice { address }` SHALL be callable only by the contract admin. The handler MUST validate `address`, then check `reduced_deposits.has(storage, address)`; if no entry exists, the call MUST fail with `NoReducedDepositPrice { address }`. On success the entry is removed from `reduced_deposits` and the response carries `wasm` attributes `action = "remove_reduced_deposit_price"` and `address`. + +Removal does not retroactively affect historical statistics for the removed address — past `deposits_with_custom_price[address]` and `..._amounts[address]` entries remain. + +#### Scenario: Admin removes an existing entry +- **WHEN** the admin sends `RemoveReducedDepositPrice` for an address with an existing reduced entry +- **THEN** `reduced_deposits[address]` is absent, historical `deposits_with_custom_price[address]` is unchanged, and the response carries `action` and `address` attributes + +#### Scenario: Removing a non-existent entry is rejected +- **WHEN** the admin sends `RemoveReducedDepositPrice` for an address with no reduced entry +- **THEN** the call returns `NoReducedDepositPrice { address }` + +### Requirement: `UpdateAdmin` requires the current admin and validates the new address + +`ExecuteMsg::UpdateAdmin { admin }` SHALL be callable only by the current `contract_admin`. The handler MUST `addr_validate` the supplied string, then call `cw_controllers::Admin::execute_update_admin(deps, info, Some(new_admin))`. The cw_controllers handshake performs the sender-equality check internally. On success the new address replaces the current `contract_admin` slot, and the response carries the cw_controllers-standard attributes (`action = "update_admin"`, `admin = `, `sender = `). + +The handler always passes `Some(new_admin)` — admin renunciation (passing `None`) is not exposed through the public surface today. + +#### Scenario: Current admin transfers admin rights +- **WHEN** the current admin sends `UpdateAdmin { admin: new_admin }` with a valid bech32 string +- **THEN** subsequent `contract_admin.assert_admin` checks succeed only for `new_admin`, and the old admin's calls to admin-gated handlers fail + +#### Scenario: Non-admin call is rejected +- **WHEN** an address other than the current admin sends `UpdateAdmin` +- **THEN** the call returns `EcashContractError::Admin` wrapping `AdminError::NotAdmin` + +#### Scenario: Invalid bech32 address is rejected +- **WHEN** the current admin sends `UpdateAdmin { admin: "not-bech32" }` +- **THEN** the call returns an `EcashContractError::Std` wrapping the underlying `addr_validate` failure + +### Requirement: `RequestRedemption` validates the commitment and dispatches a multisig propose SubMsg + +`ExecuteMsg::RequestRedemption { commitment_bs58, number_of_tickets }` SHALL be callable by any address. The handler MUST: + +- decode `commitment_bs58` via `bs58::decode(...).into_vec()`; on decode failure or if the decoded length is not exactly 32 bytes (sha256 digest length), the call MUST fail with `MalformedRedemptionCommitment`; +- construct a `cw3` `Propose` message via `create_batch_redemption_proposal`, with title `BATCH_REDEMPTION_PROPOSAL_TITLE = "ecash-redemption"`, description equal to `commitment_bs58`, and a single embedded `ExecuteMsg::RedeemTickets { n: number_of_tickets, gw: }` targeting the ecash contract itself; +- wrap that proposal in a `SubMsg::reply_always(..., REDEMPTION_PROPOSAL_REPLY_ID)`; +- return `Response::new().add_submessage(submsg)`. + +The handler does NOT itself transfer funds, mark tickets as redeemed, or modify any storage on the ecash contract directly. The actual redemption effect (incrementing `tickets_requested_and_not_redeemed`) only fires when the multisig contract subsequently executes the embedded `RedeemTickets` after a successful vote (see Requirement "Legacy `RedeemTickets`"). + +#### Scenario: Valid commitment dispatches a multisig propose with the right shape +- **WHEN** any sender sends `RequestRedemption` with a 32-byte sha256 digest encoded in bs58 and `number_of_tickets = N` +- **THEN** the response carries a single `SubMsg` with `id == REDEMPTION_PROPOSAL_REPLY_ID`, targeting the multisig contract, encoding a `Propose` with title `"ecash-redemption"`, description equal to the input `commitment_bs58`, and a single inner `WasmMsg::Execute` calling `RedeemTickets { n: N, gw: }` on the ecash contract + +#### Scenario: Non-bs58 commitment is rejected +- **WHEN** `RequestRedemption { commitment_bs58: "!!!" }` is sent +- **THEN** the call returns `MalformedRedemptionCommitment` and no SubMsg is dispatched + +#### Scenario: Bs58-decodable but wrong-length commitment is rejected +- **WHEN** `RequestRedemption` is sent with a `commitment_bs58` whose decoded bytes have length != 32 +- **THEN** the call returns `MalformedRedemptionCommitment` + +### Requirement: The redemption-proposal reply handler captures the multisig proposal id and surfaces it as response data + +The contract SHALL register a single `reply` entry point that dispatches by `Reply::id`. For `REDEMPTION_PROPOSAL_REPLY_ID`, the handler MUST call `Reply::multisig_proposal_id()`, which extracts the `proposal_id` attribute (`PROPOSAL_ID_ATTRIBUTE_NAME = "proposal_id"`) from the `wasm` event of the embedded multisig result. On success the handler MUST return `Response::new().set_data(proposal_id.to_be_bytes())` so callers can recover the multisig-issued id from the transaction result. On failure of the embedded SubMsg, the handler MUST return `EcashContractError::Std(StdError::generic_err(reply_err))`. If the `proposal_id` attribute is missing or malformed, the handler MUST return `MissingProposalId` or `MalformedProposalId` respectively. + +#### Scenario: Successful multisig propose flows the proposal id back to the gateway +- **WHEN** the redemption-proposal SubMsg succeeds and the multisig contract emits a `wasm` event with attribute `proposal_id = "42"` +- **THEN** the reply handler returns `Response::new().set_data([0,0,0,0,0,0,0,42])` (big-endian u64) + +#### Scenario: Missing proposal_id attribute is reported as a typed error +- **WHEN** the SubMsg succeeds but no `wasm` event carries a `proposal_id` attribute +- **THEN** the reply handler returns `MissingProposalId` + +#### Scenario: Failed SubMsg propagates as a generic StdError +- **WHEN** the SubMsg fails with error string `e` +- **THEN** the reply handler returns `EcashContractError::Std(StdError::generic_err(e))` + +#### Scenario: Unknown reply id is rejected +- **WHEN** the reply entry point is invoked with `Reply::id` not equal to `REDEMPTION_PROPOSAL_REPLY_ID` or `BLACKLIST_PROPOSAL_REPLY_ID` +- **THEN** the handler returns `InvalidReplyId { id }` + +### Requirement: Legacy `RedeemTickets` is multisig-gated, bumps the unredeemed-tickets counter, and emits a single event + +`ExecuteMsg::RedeemTickets { n, gw }` is **dead code retained on the public surface for backwards compatibility only**. It SHALL be callable **only** by the configured `multisig` address (`multisig.assert_admin`). The handler MUST: + +- ignore `gw` at runtime (the argument is preserved in the transaction body but not consumed); +- increment `PoolCounters.tickets_requested_and_not_redeemed` by `n` (as `u64`); +- emit `Event::new("ticket_redemption").add_attribute("moved_to_holding_account", "false")`. + +The handler does not move funds. No known active consumer depends on the counter increment or the event; both are remnants of the deprecated semantics. A follow-on change may remove this variant entirely. + +#### Scenario: Multisig successfully redeems n tickets +- **WHEN** the configured multisig sends `RedeemTickets { n: 5, gw: "" }` +- **THEN** `PoolCounters.tickets_requested_and_not_redeemed` increases by 5, and the response carries a `ticket_redemption` event with `moved_to_holding_account = "false"` + +#### Scenario: Non-multisig caller is rejected +- **WHEN** an address other than the configured multisig sends `RedeemTickets` +- **THEN** the call returns `EcashContractError::Admin` and the counter is unchanged + +### Requirement: Stubbed blacklist execute handlers always return `UnimplementedBlacklisting` + +`ExecuteMsg::ProposeToBlacklist { public_key }` and `ExecuteMsg::AddToBlacklist { public_key }` SHALL be present in the public schema but SHALL always return `EcashContractError::UnimplementedBlacklisting`. The handlers MUST NOT touch storage, dispatch SubMsgs, or emit events. + +The blacklist storage map (`blacklist: Map` at storage key `"blacklist"`), the reply handler for `BLACKLIST_PROPOSAL_REPLY_ID`, and the `create_blacklist_proposal` helper remain wired in source. They are preserved as the starting point for the redesign and are NOT reachable from the current public ExecuteMsg surface. + +#### Scenario: `ProposeToBlacklist` always errors +- **WHEN** any sender (admin, multisig, or other) sends `ProposeToBlacklist { public_key }` +- **THEN** the call returns `EcashContractError::UnimplementedBlacklisting` and the `blacklist` storage is unchanged + +#### Scenario: `AddToBlacklist` always errors +- **WHEN** any sender sends `AddToBlacklist { public_key }` +- **THEN** the call returns `EcashContractError::UnimplementedBlacklisting` and the `blacklist` storage is unchanged + +### Requirement: The ticketbook-size invariant tripwire catches uncoordinated network-defaults bumps + +The contract SHALL persist `Item { ticket_book_size }` at storage key `"expected_invariants"` on instantiation, snapshotting `nym_network_defaults::TICKETBOOK_SIZE`. Every priced operation that consults the ticketbook size (currently `UpdateDefaultDepositValue` and `SetReducedDepositPrice` / migration whitelist seeding via `add_reduced_deposit_address`) SHALL call `NymEcashContract::get_ticketbook_size`, which compares the stored value to the crate's current `TICKETBOOK_SIZE`. A mismatch MUST surface as `TicketBookSizeChanged { at_init, current }`, halting the operation before any state mutation. + +#### Scenario: Snapshot equals current crate constant — operation proceeds +- **WHEN** the snapshotted `Invariants::ticket_book_size` equals `nym_network_defaults::TICKETBOOK_SIZE` and an admin sends a valid `UpdateDefaultDepositValue` +- **THEN** the operation succeeds normally + +#### Scenario: Snapshot differs from current crate constant — operation halted +- **WHEN** the snapshotted `Invariants::ticket_book_size` is `T_init` and the contract has been redeployed with a new crate constant `T_current != T_init`, then an admin sends `UpdateDefaultDepositValue` or migration seeds a reduced-deposit entry +- **THEN** the call returns `TicketBookSizeChanged { at_init: T_init, current: T_current }` before any further work + +### Requirement: Default-deposit queries + +The contract SHALL expose two equivalent queries for the default deposit amount, kept aliased for backwards compatibility: + +- `QueryMsg::GetDefaultDepositAmount {}` — returns `Coin = Config::deposit_amount`. +- `QueryMsg::GetRequiredDepositAmount {}` (also accepted via the `get_required_deposit_amount` `serde` alias on `GetDefaultDepositAmount`) — equivalent to the above; the handler delegates to `get_default_deposit_amount`. + +Both queries SHALL succeed unconditionally for any sender (queries are read-only). + +#### Scenario: Both query variants return identical data +- **WHEN** both `GetDefaultDepositAmount {}` and `GetRequiredDepositAmount {}` are queried on the same contract state +- **THEN** both return the same `Coin`, equal to `Config::deposit_amount` + +### Requirement: Reduced-deposit queries + +The contract SHALL expose two queries for tier-pricing state: + +- `QueryMsg::GetReducedDepositAmount { address }` — validates `address` via `addr_validate`, then returns `Option = reduced_deposits.may_load(storage, addr)`. An invalid bech32 input MUST return an `EcashContractError::Std` wrapping the underlying validation error. +- `QueryMsg::GetAllWhitelistedAccounts {}` — returns `WhitelistedAccountsResponse { whitelisted_accounts }` enumerating all entries in `reduced_deposits` in ascending address order. + +`GetAllWhitelistedAccounts` is unpaginated by design (the whitelist is expected to remain small). + +#### Scenario: Reduced amount is returned when an entry exists +- **WHEN** address `alice` has `reduced_deposits[alice] = Coin { 10, "unym" }` and `GetReducedDepositAmount { address: alice }` is queried +- **THEN** the response is `Some(Coin { 10, "unym" })` + +#### Scenario: Absent entry returns None +- **WHEN** address `bob` has no entry and `GetReducedDepositAmount { address: bob }` is queried +- **THEN** the response is `None` + +#### Scenario: All whitelisted accounts are enumerated +- **WHEN** the contract has entries for `alice` and `bob` and `GetAllWhitelistedAccounts {}` is queried +- **THEN** the response contains both entries + +### Requirement: Deposit-by-id and latest-deposit queries + +The contract SHALL expose: + +- `QueryMsg::GetDeposit { deposit_id }` — returns `DepositResponse { id: deposit_id, deposit: Option }`. The `deposit` field is `Some` if a deposit was ever persisted under that id (deposits are not deletable). It is `None` if the id has not yet been issued (i.e. `id >= total_deposits_made`). +- `QueryMsg::GetLatestDeposit {}` — returns `LatestDepositResponse { deposit: Option }`. The handler MUST consult `DepositStorage::latest_deposit`, which returns the id of the most recently assigned deposit (`counter - 1` when the counter has been incremented at least once, else `None`), and then load that id. On a fresh contract with no prior deposit, the response is `LatestDepositResponse { deposit: None }`; after any successful deposit, the response is `LatestDepositResponse { deposit: Some(DepositData { id, deposit }) }` where `id` is the most recent assignment. + +#### Scenario: Existing deposit is returned by id +- **WHEN** a deposit was persisted at id `0` with `identity_key = K` and `GetDeposit { deposit_id: 0 }` is queried +- **THEN** the response is `DepositResponse { id: 0, deposit: Some(Deposit { bs58_encoded_ed25519_pubkey: K }) }` + +#### Scenario: Unknown id returns None +- **WHEN** `GetDeposit { deposit_id: 999 }` is queried and the counter is less than 999 +- **THEN** the response is `DepositResponse { id: 999, deposit: None }` + +#### Scenario: Fresh contract latest-deposit query returns None +- **WHEN** `GetLatestDeposit {}` is queried on a contract with no deposits +- **THEN** the response is `LatestDepositResponse { deposit: None }` + +#### Scenario: After deposits exist, latest-deposit query returns the most recent assignment +- **WHEN** two deposits have been processed (ids `0` and `1`) and `GetLatestDeposit {}` is queried +- **THEN** the response is `LatestDepositResponse { deposit: Some(DepositData { id: 1, deposit: }) }` + +### Requirement: Paginated deposits query + +`QueryMsg::GetDepositsPaged { limit, start_after }` SHALL return at most `limit.unwrap_or(DEPOSITS_PAGE_DEFAULT_LIMIT).min(DEPOSITS_PAGE_MAX_LIMIT)` deposits in ascending id order, starting strictly after `start_after`. The defaults `DEPOSITS_PAGE_DEFAULT_LIMIT = 50` and `DEPOSITS_PAGE_MAX_LIMIT = 100` are part of the public surface and changing them is a behavioural change. The response SHALL be `PagedDepositsResponse { deposits, start_next_after }`, where `start_next_after` is the id of the last entry returned (or `None` if zero entries were returned). + +#### Scenario: Default limits clamp to the maximum +- **WHEN** `GetDepositsPaged { limit: Some(1000), start_after: None }` is queried on a contract with 200 deposits +- **THEN** the response contains 100 entries (ids 0..=99) and `start_next_after = Some(99)` + +#### Scenario: Pagination via `start_after` +- **WHEN** the previous query returned `start_next_after = Some(99)` and a follow-up sends `GetDepositsPaged { limit: None, start_after: Some(99) }` +- **THEN** the response starts at id 100 + +### Requirement: `GetDepositsStatistics` reassembles the global and per-account picture + +`QueryMsg::GetDepositsStatistics {}` SHALL return `DepositsStatistics` populated from: + +- `total_deposits_made` ← `DepositStorage::total_deposits_made(storage)`; +- `total_deposited` ← `PoolCounters::total_deposited`; +- `total_deposits_made_with_default_price` ← `deposits_with_default_price`; +- `total_deposited_with_default_price` ← `deposits_with_default_price_amounts`; +- `total_deposits_made_with_custom_price` ← `sum(deposits_with_custom_price[a])` across all addresses; +- `total_deposited_with_custom_price` ← `sum(deposits_with_custom_price_amounts[a])` across all addresses (using `Config::deposit_amount.denom`); +- `deposits_made_with_custom_price: HashMap` and `deposited_with_custom_price: HashMap` ← per-account aggregates from the custom-price maps, keyed by the stringified `Addr`. + +The query MUST be a single read pass (no execute-side write) and is callable by any sender. + +#### Scenario: Statistics reflect the post-mixed-deposit state +- **WHEN** two default-price deposits of value 75 each, and one reduced-price deposit by `alice` of value 10, have been processed; then `GetDepositsStatistics {}` is queried +- **THEN** the response has `total_deposits_made = 3`, `total_deposits_made_with_default_price = 2`, `total_deposited_with_default_price.amount = 150`, `total_deposits_made_with_custom_price = 1`, `total_deposited_with_custom_price.amount = 10`, and `deposits_made_with_custom_price["alice"] = 1` + +### Requirement: Blacklist queries succeed and return empty on a freshly deployed contract + +`QueryMsg::GetBlacklistedAccount { public_key }` and `QueryMsg::GetBlacklistPaged { limit, start_after }` SHALL be callable by any sender and SHALL NOT error on a contract that has no blacklist entries. + +- `GetBlacklistedAccount` returns `BlacklistedAccountResponse { account: Option }`. On a contract where no entry exists for `public_key`, the response is `BlacklistedAccountResponse { account: None }`. +- `GetBlacklistPaged` returns `PagedBlacklistedAccountResponse` with at most `limit.unwrap_or(BLACKLIST_PAGE_DEFAULT_LIMIT).min(BLACKLIST_PAGE_MAX_LIMIT)` entries (`BLACKLIST_PAGE_DEFAULT_LIMIT = 50`, `BLACKLIST_PAGE_MAX_LIMIT = 75`). On a contract with no entries, the response is empty (`accounts: []`, `start_next_after: None`). + +Because the blacklist execute handlers always error (Requirement "Stubbed blacklist execute handlers"), the only way for blacklist storage to contain entries on a live deployment is through the reply path for `BLACKLIST_PROPOSAL_REPLY_ID` — which is itself unreachable from the public ExecuteMsg surface today. Consumers MUST NOT treat an empty blacklist as a security guarantee. + +#### Scenario: Querying an absent blacklist entry returns None +- **WHEN** `GetBlacklistedAccount { public_key: K }` is queried on a contract that has never blacklisted `K` +- **THEN** the response is `BlacklistedAccountResponse { account: None }` + +#### Scenario: Paginated blacklist on empty contract returns empty +- **WHEN** `GetBlacklistPaged { limit: None, start_after: None }` is queried on a freshly deployed contract +- **THEN** the response is `PagedBlacklistedAccountResponse { accounts: [], per_page: 50, start_next_after: None }` + +### Requirement: Public storage layout + +The following raw CosmWasm storage keys SHALL be considered part of the public contract surface. Any change to these keys is a breaking change for already-deployed contracts and MUST be accompanied by a coordinated migration: + +- `"contract_admin"` — `cw_controllers::Admin` slot for the contract admin (single Cosmos SDK address). +- `"multisig"` — `cw_controllers::Admin` slot for the multisig contract address. +- `"config"` — `Item { group_addr, holding_account, deposit_amount }`. +- `"pool_counters"` — `Item { total_deposited, total_redeemed, tickets_requested_and_not_redeemed }`. +- `"expected_invariants"` — `Item { ticket_book_size }`. +- `"deposit_ids"` — `Item` deposit-id counter (next free id). +- `"deposit"` — custom raw-bytes namespace for stored deposits (32-byte ed25519 pubkeys), keyed by big-endian `u32`. **Not** a `cw_storage_plus::Map`. +- `"reduced_deposits"` — `Map` per-address reduced-deposit price. +- `"blacklist"` — `Map` reserved for the future blacklist redesign; unreachable through public execute paths today. +- `"deposits_with_default_price"` — `Item` count of default-price deposits. +- `"deposits_with_default_price_amounts"` — `Item` total amount of default-price deposits. +- `"deposits_with_custom_price"` — `Map` per-account count of custom-price deposits. +- `"deposits_with_custom_price_amounts"` — `Map` per-account total amount of custom-price deposits. + +In addition, the two reply-id constants `BLACKLIST_PROPOSAL_REPLY_ID = 7759` and `REDEMPTION_PROPOSAL_REPLY_ID = 2137` form part of the public surface for any contract upgrade — changing them invalidates in-flight submessage replies. + +#### Scenario: Reading any storage key listed above on a v1 deployment succeeds with the documented type +- **WHEN** a CosmWasm raw-state inspection tool reads any of the listed keys on a contract deployed at the spec's anchor version +- **THEN** the deserialised value matches the documented type (`Item`, `Map`, raw bytes, or `Admin` slot as listed) + +### Requirement: Public event surface + +The following events SHALL form the public contract surface consumed by chain indexers and downstream tooling. Renaming events or attribute keys MUST be treated as a breaking change: + +- `deposited-funds` event, emitted by `DepositTicketBookFunds` on success. Carries attribute `deposit-id` (decimal string form of the new `u32`). Event type constant: `DEPOSITED_FUNDS_EVENT_TYPE`. Attribute constant: `DEPOSIT_ID`. +- `ticket_redemption` event, emitted by `RedeemTickets` on success. Carries attribute `moved_to_holding_account = "false"` (the literal string `"false"`). This event is a remnant of the deprecated `RedeemTickets` flow (see the "Legacy `RedeemTickets`" requirement) and is preserved by the contract today but not consumed by any known live indexer. +- The auto-generated `wasm` event emitted by the redemption-proposal reply handler — carries attribute `proposal_id` (decimal string form of the multisig-issued `u64`). Attribute constant: `PROPOSAL_ID_ATTRIBUTE_NAME`. The `wasm` event name itself is the cosmwasm-std auto-event; the attribute is added via `Response::add_attribute`. +- The auto-generated `wasm` event emitted by `UpdateDefaultDepositValue` — carries attribute `updated_deposit = Coin::to_string()`. +- The auto-generated `wasm` event emitted by `SetReducedDepositPrice` — carries attributes `action = "set_reduced_deposit_price"`, `address`, `deposit = Coin::to_string()`. +- The auto-generated `wasm` event emitted by `RemoveReducedDepositPrice` — carries attributes `action = "remove_reduced_deposit_price"`, `address`. +- The auto-generated `wasm` events from `UpdateAdmin` and the embedded multisig propose carry standard cw_controllers / cw3 attributes; the ecash contract does not add additional attributes on those paths. + +Handlers that explicitly return `Response::default()` (instantiation, migration) MUST NOT emit any events. + +#### Scenario: Successful default-price deposit emits exactly one `deposited-funds` event with the new id +- **WHEN** a default-price `DepositTicketBookFunds` succeeds and assigns id `42` +- **THEN** the response carries exactly one `deposited-funds` event with attribute `deposit-id = "42"` + +#### Scenario: Successful `RedeemTickets` carries the legacy `moved_to_holding_account = "false"` attribute +- **WHEN** a `RedeemTickets { n: 3, gw: "..." }` succeeds +- **THEN** the response carries exactly one `ticket_redemption` event with attribute `moved_to_holding_account = "false"` + +#### Scenario: Instantiation emits no events +- **WHEN** the contract is instantiated successfully +- **THEN** the response has no events and no attributes + +### Requirement: Public error variants + +The `EcashContractError` enum forms part of the public surface — its variants are observable through transaction failure messages and are encoded in JSON schema artefacts. The following variants MUST be reachable through the current public execute / migration surface and MUST NOT be removed without a coordinated schema bump: + +- `Std`, `Admin` — wrapper variants over `StdError` and `AdminError`. +- `InvalidDeposit(PaymentError)` — wrapper variant raised by `cw_utils::must_pay` on `DepositTicketBookFunds` when funds are missing, multi-denom, or in the wrong denom. The inner `PaymentError` variants `NoFunds`, `MultipleDenoms`, `MissingDenom()` are all reachable. +- `WrongAmount { received, amount }` — `DepositTicketBookFunds` with the right denom but a non-matching amount. +- `InvalidGroup { addr }` — instantiation with an unparseable group address. +- `MalformedRedemptionCommitment` — `RequestRedemption` with a non-32-byte commitment. +- `MalformedEd25519Identity` — `DepositTicketBookFunds` with a non-32-byte bs58 identity payload at save time. +- `InvalidReducedDepositDenom { expected, got }` — denom mismatch in `SetReducedDepositPrice` or migration whitelist seeding. +- `ReducedDepositNotReduced { reduced, default }` — reduced amount not strictly less than default. +- `DepositBelowTicketBookSize { amount, ticket_book_size }` — reduced or default amount below the ticketbook-size floor. +- `NoReducedDepositPrice { address }` — `RemoveReducedDepositPrice` against an absent entry. +- `TicketBookSizeChanged { at_init, current }` — invariant tripwire mismatch. +- `UnimplementedBlacklisting` — `ProposeToBlacklist` or `AddToBlacklist` (always thrown). +- `InvalidReplyId { id }` — reply dispatcher with an unknown id. +- `MissingProposalId` / `MalformedProposalId` — multisig-reply parsing failures. + +`NotEnoughFunds`, `MaximumDepositTypesReached`, `UnknownCompressedDepositInfoType { typ }`, `UnknownDepositInfoType { typ }`, `Unauthorized`, and `SemVerFailure { value, error_message }` are present in the enum but are **not reachable** through any current public execute path. They are preserved for forward compatibility (notably for the eventual blacklist redesign and deposit-info-typing feature work) and SHOULD NOT be relied upon by downstream tooling. + +#### Scenario: Each reachable variant has at least one triggering scenario in this spec +- **WHEN** a reviewer cross-references the reachable variants listed above against the requirements in this spec +- **THEN** every reachable variant appears as the documented error of at least one scenario diff --git a/openspec/changes/archive/2026-05-21-ecash-contract-spec/tasks.md b/openspec/changes/archive/2026-05-21-ecash-contract-spec/tasks.md new file mode 100644 index 0000000000..70951068ad --- /dev/null +++ b/openspec/changes/archive/2026-05-21-ecash-contract-spec/tasks.md @@ -0,0 +1,35 @@ +## 1. Verify spec coverage against the live contract + +- [x] 1.1 Compare each `ExecuteMsg` variant in `common/cosmwasm-smart-contracts/ecash-contract/src/msg.rs` against the spec to confirm every execute path has a corresponding requirement with scenarios (Deposit, RequestRedemption, RedeemTickets, UpdateAdmin, UpdateDefaultDepositValue, SetReducedDepositPrice, RemoveReducedDepositPrice, ProposeToBlacklist, AddToBlacklist). +- [x] 1.2 Compare each `QueryMsg` variant against the spec to confirm every read path is covered (GetBlacklistedAccount, GetBlacklistPaged, GetDefaultDepositAmount, GetRequiredDepositAmount alias, GetReducedDepositAmount, GetAllWhitelistedAccounts, GetDeposit, GetLatestDeposit, GetDepositsPaged, GetDepositsStatistics). +- [x] 1.3 Compare each `EcashContractError` variant against the spec to confirm every reachable error has a scenario that triggers it, and that the error name in the scenario matches the enum variant exactly. Annotate the unreachable variants (`NotEnoughFunds`, `MaximumDepositTypesReached`, `UnknownCompressedDepositInfoType`, `UnknownDepositInfoType`, `Unauthorized`, `SemVerFailure`) as preserved-but-unreachable. **Finding**: added `InvalidDeposit(PaymentError)` to the public-error requirement and a triggering scenario under the Deposit requirement; multitest::invalid_deposit exercises `NoFunds`, `MultipleDenoms`, `MissingDenom`. +- [x] 1.4 Confirm every event name and attribute key in `nym_ecash_contract_common::events` (`DEPOSITED_FUNDS_EVENT_TYPE`, `DEPOSIT_ID`, `WASM_EVENT_NAME`, `PROPOSAL_ID_ATTRIBUTE_NAME`) is named verbatim in the events requirement. Cross-check the `"ticket_redemption"` event and its `"moved_to_holding_account"` attribute (defined inline, not via a constant) and verify the `"updated_deposit"`, `"action"`, `"address"`, `"deposit"` attributes from the admin handlers. **Finding**: `event_attributes::BANDWIDTH_PROPOSAL_ID = "proposal_id"` is dead code (no in-tree references); duplicates `events::PROPOSAL_ID_ATTRIBUTE_NAME`. Worth removing in the rustdoc follow-on; no spec impact. +- [x] 1.5 Confirm every storage key (raw string literal in `Item::new(...)` / `Map::new(...)` / `StoredDeposits::NAMESPACE`) is named verbatim in the storage-layout requirement. Specifically: `"contract_admin"`, `"multisig"`, `"config"`, `"pool_counters"`, `"expected_invariants"`, `"deposit_ids"`, `"deposit"`, `"reduced_deposits"`, `"blacklist"`, `"deposits_with_default_price"`, `"deposits_with_default_price_amounts"`, `"deposits_with_custom_price"`, `"deposits_with_custom_price_amounts"`. +- [x] 1.6 Confirm both reply-id constants (`BLACKLIST_PROPOSAL_REPLY_ID = 7759`, `REDEMPTION_PROPOSAL_REPLY_ID = 2137`) are listed verbatim in the storage-layout requirement. + +## 2. Cross-check against the contract unit tests + +- [x] 2.1 For each `#[test]` in `contracts/ecash/src/deposit.rs`, identify the requirement(s) and scenario(s) in the spec that it exercises. Flag any test that asserts behaviour not yet captured in the spec. Tests: `getting_latest_deposit`, `total_deposits_made_tracks_count`, `iterating_over_deposits` — all covered by "Deposit ids are sequential u32" + "Deposit-by-id and latest-deposit queries" + "Paginated deposits query" requirements. +- [x] 2.2 Do the same for `contracts/ecash/src/deposit_stats.rs` tests (statistics invariant and per-account bookkeeping). Six tests on default/reduced accumulation and per-address independence — all covered by the "Statistics invariant" requirement and the Deposit classification scenarios. +- [x] 2.3 Do the same for `contracts/ecash/src/contract/test.rs` (handler-level integration tests). ~15 tests covering query handlers, set/remove reduced price (admin gating, validations, overwrite), and `deposit_stats_invariant_holds_after_mixed_deposits` — all map to existing requirements. +- [x] 2.4 Do the same for `contracts/ecash/src/contract/queued_migrations.rs` tests (migration backfill + whitelist seeding). Six tests covering empty-stats init, deposit-count backfill, whitelist seeding, denom/amount/ticketbook-size rejections — all map to the Migration requirement. +- [x] 2.5 Do the same for `contracts/ecash/src/multitest.rs` tests (multi-contract integration with the multisig harness). Four tests: `invalid_deposit` (drove the spec edit in 1.3), `wrong_deposit_amount`, `correct_default_deposit_succeeds`, `reduced_price_deposit_end_to_end` — all covered. +- [x] 2.6 For each spec scenario that has no corresponding contract unit test, decide whether to add a test or annotate the scenario as covered indirectly (e.g. by the sylvia-generated dispatcher). **Annotation**: the `MalformedEd25519Identity` scenario is reachable only when funds are correct AND `identity_key` is a malformed bs58 string — currently no test exercises this directly (the `must_pay` check fires first in the invalid-deposit test). Documented in the rustdoc follow-on as a candidate for a new test. The `TicketBookSizeChanged` tripwire is also indirectly covered (no test redeploys with a different `TICKETBOOK_SIZE`); acceptable since the assertion guards a deployment-time invariant. + +## 3. Validate via openspec tooling + +- [x] 3.1 Run `openspec validate ecash-contract-spec` and confirm it reports "valid". +- [x] 3.2 Run `openspec show ecash-contract-spec` and review the rendered output for readability and section ordering. +- [x] 3.3 Run `openspec status --change ecash-contract-spec` and confirm `applyRequires` is satisfied (`tasks` artifact present, all dependencies done). + +## 4. Reviewer pass + +- [x] 4.1 Walk through `proposal.md` with a reviewer to confirm the "Why" section accurately captures the design intent of the ecash contract (deposit anchor for the blind-signature pipeline) and that the "Known limitation — blacklist is stubbed" note matches operational understanding. **Resolved 2026-05-21**: contract role confirmed accurate; blacklist limitation note confirmed OK. Two changes landed: (a) the "two-admin model" framing was wrong — the team uses `cw_controllers::Admin` only as a generic address-equality helper for the `multisig` slot, not as an admin in the operational sense. Reworded the bullet, mirrored in design.md "What to document" + Decision 1 + spec.md authorisation requirement. (b) The "off-chain ownership/double-issue checks" wording was vague — replaced with a precise bullet citing `state.already_issued(deposit_id)` for the per-signer cache and the specific ed25519 verification path in `validate_deposit` (signs the plaintext `IssuanceTicketBook::request_plaintext(&request.inner_sign_request, request.deposit_id)`), plus the surrounding signer-eligibility / expiration / DKG / off-chain-blacklist gates. +- [x] 4.2 Walk through `design.md` Decisions 1–12 with a reviewer to confirm each rationale matches the team's reasoning at the time the contract was built. Pay particular attention to Decision 2 (off-chain ed25519 ownership), Decision 3 (per-signer-local de-duplication), Decision 4 (raw-bytes storage), and Decision 11 (legacy `RedeemTickets` retention). **Resolved 2026-05-21**: Decision 1 already rewritten in 4.1 (Admin-wrapper misuse). Decisions 3 (adversarial framing), 4 (storage-gas framing), 6 (graceful-degradation framing) confirmed as-is. Decisions 2, 5, 7, 8, 9, 10, 12 confirmed without changes. **Decision 11 substantively rewritten**: `RedeemTickets` is dead code that hasn't been cleaned up — not retained for indexer compatibility or held multisig grants. Removed the "load-bearing for chain scrapers" framing from design.md Decision 11, proposal.md non-obvious-choices bullet, and spec.md (events requirement + the legacy-RedeemTickets requirement title and scenario name). Spec still validates at 25 reqs / 63 scenarios. +- [x] 4.3 Walk through `specs/ecash-contract/spec.md` requirement by requirement; for each disagreement, decide whether the spec is wrong (update the spec) or the implementation is wrong (open a follow-on change). Specifically confirm the client-vs-gateway role split (clients deposit, gateways redeem) is correctly worded throughout. **Resolved 2026-05-21**: all 25 requirements walked in six batches (1–3, 4–7, 8–11, 12–16, 17–22, 23–25). One real bug found in Req 19: `DepositStorage::latest_deposit()` returned the counter (the next free id), so `GetLatestDeposit` always returned `{ deposit: None }` even after deposits. Fixed in `contracts/ecash/src/deposit.rs` (`counter.checked_sub(1)` semantics) and the existing `getting_latest_deposit` test updated; all 38 contract tests pass. Spec Req 19 rewritten to describe the corrected semantics and gained a new "After deposits exist..." scenario. Final shape: 25 requirements, 64 scenarios, valid. +- [x] 4.4 Resolve the four Open Questions in `design.md` (holding_account updatability, multisig address updatability, admin renunciation, stubbed-blacklist final disposition) or move them to follow-on changes. **Resolved 2026-05-21**: three kept current behaviour (locked holding_account, locked multisig address, no admin renunciation) and folded into a new "Resolved Questions" section in design.md; stubbed-blacklist final disposition deferred to the blacklist redesign change owner, kept as the sole entry in "Open Questions". + +## 5. Archive the change + +- [x] 5.1 Once reviewed and accepted, run `openspec archive ecash-contract-spec` to promote `specs/ecash-contract/spec.md` into `openspec/specs/ecash-contract/spec.md` as the canonical spec. +- [x] 5.2 Open the follow-on change `ecash-contract-rustdoc` once the canonical spec is archived, so that the rustdoc pass references the archived spec for normative phrasing. **Plan**: deferred to a fresh session (per the apply-loop decision on 2026-05-21). The rustdoc change will start with `/opsx:propose ecash-contract-rustdoc` and reference `openspec/specs/ecash-contract/spec.md` for normative phrasing. diff --git a/openspec/config.yaml b/openspec/config.yaml new file mode 100644 index 0000000000..392946c67c --- /dev/null +++ b/openspec/config.yaml @@ -0,0 +1,20 @@ +schema: spec-driven + +# Project context (optional) +# This is shown to AI when creating artifacts. +# Add your tech stack, conventions, style guides, domain knowledge, etc. +# Example: +# context: | +# Tech stack: TypeScript, React, Node.js +# We use conventional commits +# Domain: e-commerce platform + +# Per-artifact rules (optional) +# Add custom rules for specific artifacts. +# Example: +# rules: +# proposal: +# - Keep proposals under 500 words +# - Always include a "Non-goals" section +# tasks: +# - Break tasks into chunks of max 2 hours diff --git a/openspec/specs/ecash-contract/spec.md b/openspec/specs/ecash-contract/spec.md new file mode 100644 index 0000000000..8a3ec8379c --- /dev/null +++ b/openspec/specs/ecash-contract/spec.md @@ -0,0 +1,505 @@ +# ecash-contract Specification + +## Purpose +TBD - created by archiving change ecash-contract-spec. Update Purpose after archive. +## Requirements +### Requirement: Contract instantiation persists the runtime config, multisig and admin addresses, and the ticketbook-size invariant + +The contract SHALL be instantiable exactly once via the standard CosmWasm `instantiate` entry point. The instantiation message SHALL carry `holding_account` (a string-form Cosmos SDK address reserved for the future pool-contract transition), `multisig_addr` (the cw3 multisig contract address that gates redemption finalisation), `group_addr` (the cw4 group contract referenced by future blacklist proposals), and `deposit_amount` (the default per-deposit price). The handler MUST: + +- bech32-validate `multisig_addr`, `holding_account`, and `group_addr`; an invalid `group_addr` MUST surface as `InvalidGroup { addr }`, an invalid `multisig_addr` or `holding_account` MUST surface as the underlying `StdError` from `addr_validate`; +- persist `info.sender` as the `contract_admin` via `cw_controllers::Admin::set` (the message itself does not carry an admin field; the sender becomes admin by convention); +- persist the validated `multisig_addr` as the `multisig` `Admin` slot; +- snapshot `nym_network_defaults::TICKETBOOK_SIZE` into `Item { ticket_book_size }` under the storage key `"expected_invariants"`; +- zero-initialise `PoolCounters` (`total_deposited`, `total_redeemed`, `tickets_requested_and_not_redeemed`) using the denom of the supplied `deposit_amount`; +- persist the assembled `Config { group_addr (as cw4::Cw4Contract), holding_account, deposit_amount }`; +- zero-initialise the default-price statistics accumulators (`deposits_with_default_price` and `deposits_with_default_price_amounts`); +- record the contract name and `CARGO_PKG_VERSION` via `cw2::set_contract_version`; +- record build information via `set_build_information!`. + +The instantiation handler SHALL return `Response::default()` (no events, no attributes, no data). + +#### Scenario: Valid instantiation persists every state slot +- **WHEN** `instantiate` is called with valid bech32 strings for `holding_account`, `multisig_addr`, `group_addr` and a well-formed `deposit_amount` +- **THEN** the contract stores `Config` verbatim, the validated multisig address (queryable via `multisig.assert_admin`), `info.sender` as the contract admin, the snapshotted `Invariants { ticket_book_size: TICKETBOOK_SIZE }`, zeroed `PoolCounters`, and zeroed default-price stats +- **AND** `cw2::get_contract_version` returns the crate's `CARGO_PKG_VERSION` +- **AND** the returned `Response` carries no events, attributes, or data + +#### Scenario: Invalid group address is rejected with a typed error +- **WHEN** `instantiate` is called with a `group_addr` that fails `Addr::validate` +- **THEN** the call returns `EcashContractError::InvalidGroup { addr }` and no state is persisted + +#### Scenario: Invalid multisig address propagates the `StdError` +- **WHEN** `instantiate` is called with a `multisig_addr` that fails `Addr::validate` +- **THEN** the call returns an `EcashContractError::Std` wrapping the underlying validation error and no state is persisted + +### Requirement: Migration handles version gating, default-price backfill, and whitelist seeding atomically + +The contract SHALL expose a `migrate` entry point taking `MigrateMsg { initial_whitelist: Vec }`. The handler MUST: + +- call `set_build_information!` to refresh stored build metadata; +- call `cw2::ensure_from_older_version` against `CONTRACT_NAME` and `CONTRACT_VERSION`; an on-chain version strictly greater than `CARGO_PKG_VERSION` MUST be rejected; +- run `queued_migrations::add_tiered_pricing(deps, initial_whitelist)`, which (a) reads `DepositStorage::total_deposits_made` and `PoolCounters::total_deposited` from the pre-migration state, (b) writes those values into `deposits_with_default_price` and `deposits_with_default_price_amounts` respectively (because every pre-migration deposit was at the default price), and (c) iterates `initial_whitelist`, validating each entry's denom and amount (see Requirement "Setting a reduced deposit price"), persisting each into `reduced_deposits`; +- return `Response::default()`. + +The migration MUST fail atomically if any whitelist entry fails validation — partial whitelist seeding MUST NOT be persisted. + +#### Scenario: Migration on contract with prior default-price deposits backfills both counters +- **WHEN** `migrate` is called with `initial_whitelist = []` on a contract that has performed `N > 0` deposits totalling `T` units +- **THEN** `deposits_with_default_price` reads `N` and `deposits_with_default_price_amounts` reads `T` (same denom as the contract config) + +#### Scenario: Migration with a valid whitelist persists every entry +- **WHEN** `migrate` is called with two well-formed `WhitelistedDeposit` entries +- **THEN** `reduced_deposits` returns the matching `Coin` for each address on subsequent reads + +#### Scenario: Migration with a single invalid whitelist entry rolls back the entire transaction +- **WHEN** `migrate` is called with `initial_whitelist = [valid_entry, invalid_entry]` where `invalid_entry` uses the wrong denom +- **THEN** the call returns `InvalidReducedDepositDenom { expected, got }` and `reduced_deposits` contains no entries from this migration + +#### Scenario: Newer on-chain version is rejected +- **WHEN** `migrate` is called against an on-chain `cw2` version strictly greater than `CARGO_PKG_VERSION` +- **THEN** the call returns an error and storage is unchanged + +### Requirement: Authorisation — contract admin and multisig pointer + +The contract SHALL maintain two `cw_controllers::Admin` slots at storage keys `"contract_admin"` and `"multisig"`. Only the first carries admin semantics in the operational sense; the second is a stored cw3 contract pointer that uses the same wrapper purely as a generic address-equality helper. + +- `contract_admin` SHALL gate `UpdateAdmin`, `UpdateDefaultDepositValue`, `SetReducedDepositPrice`, `RemoveReducedDepositPrice`. It is replaceable through `UpdateAdmin`, which dispatches `cw_controllers::Admin::execute_update_admin` (requiring the current admin to sign the transaction). +- `multisig` SHALL gate `RedeemTickets` via `assert_admin` (which on this slot is effectively "is the caller equal to the stored cw3 contract address?"). It SHALL NOT be updatable through any execute path; replacing it requires redeploying the contract. + +The wrapper's full admin-transfer machinery is reachable in code on both slots but is exercised only on `contract_admin`. + +#### Scenario: Non-admin call to a contract-admin-gated handler is rejected +- **WHEN** any of `UpdateDefaultDepositValue`, `SetReducedDepositPrice`, `RemoveReducedDepositPrice` is sent by an address other than the current `contract_admin` +- **THEN** the call returns `EcashContractError::Admin` wrapping `AdminError::NotAdmin` and state is unchanged + +#### Scenario: Non-multisig call to `RedeemTickets` is rejected +- **WHEN** `RedeemTickets { n, gw }` is sent by an address other than the configured `multisig` +- **THEN** the call returns `EcashContractError::Admin` wrapping `AdminError::NotAdmin` and `PoolCounters::tickets_requested_and_not_redeemed` is unchanged + +### Requirement: `DepositTicketBookFunds` classifies the sent amount and updates the correct statistics bucket + +`ExecuteMsg::DepositTicketBookFunds { identity_key }` SHALL accept exactly one coin in the configured denom (validated via `cw_utils::must_pay`) and classify the sender at deposit time: + +1. If the sent amount equals `Config::deposit_amount.amount`, the deposit is treated as a **default-price** deposit. The handler MUST call `DepositStatsStorage::new_default_deposit`, which increments `deposits_with_default_price` by 1 and adds the deposited amount to `deposits_with_default_price_amounts`. This branch fires *regardless* of whether the sender has a reduced-deposit entry. +2. Otherwise, if the sender has a `reduced_deposits[sender]` entry whose `amount` equals the sent amount, the deposit is treated as a **reduced-price** deposit. The handler MUST call `DepositStatsStorage::new_reduced_deposit`, which increments `deposits_with_custom_price[sender]` by 1 and adds the deposited amount to `deposits_with_custom_price_amounts[sender]`. +3. Otherwise, the call MUST fail with `EcashContractError::WrongAmount { received, amount }`, where `amount` is the reduced amount if the sender is whitelisted, else the default amount. + +After successful classification the handler MUST: + +- add the deposited amount to `PoolCounters.total_deposited.amount`; +- assign and persist a sequential `deposit_id` via `DepositStorage::save_deposit` (which decodes `identity_key` from bs58 to a 32-byte raw representation and writes it under the `"deposit"` namespace); +- emit a `deposited-funds` event with attribute `deposit-id` carrying the assigned id as a decimal string; +- set the response data to `deposit_id.to_be_bytes()` so callers can recover the id from the transaction result. + +The handler MUST NOT verify that the sender controls the private key matching the supplied `identity_key`. The identity-ownership proof is delegated to off-chain nym-api signers (`post_blind_sign` at `nym-api/src/ecash/api_routes/partial_signing.rs:55`). + +#### Scenario: Default-price deposit increments default counters and emits event with deposit id +- **WHEN** a sender with no reduced-deposit entry sends `DepositTicketBookFunds { identity_key }` with funds matching the default amount +- **THEN** `deposits_with_default_price` increases by 1, `deposits_with_default_price_amounts` increases by the deposited amount, `PoolCounters.total_deposited` increases by the deposited amount, a new `deposit_id` is persisted with the supplied `identity_key`, a `deposited-funds` event is emitted with the `deposit-id` attribute set to the new id, and the response data is the big-endian byte representation of the new id + +#### Scenario: Whitelisted sender paying the default amount is bucketed as default-price +- **WHEN** a whitelisted sender (entry in `reduced_deposits`) sends `DepositTicketBookFunds` with funds matching the **default** amount (not their reduced amount) +- **THEN** the deposit is recorded under `deposits_with_default_price` (not under `deposits_with_custom_price[sender]`), and the deposit is persisted normally + +#### Scenario: Whitelisted sender paying the reduced amount is bucketed as custom-price +- **WHEN** a whitelisted sender sends `DepositTicketBookFunds` with funds matching their reduced amount +- **THEN** `deposits_with_custom_price[sender]` increases by 1, `deposits_with_custom_price_amounts[sender]` increases by the reduced amount, and the deposit is persisted normally + +#### Scenario: Whitelisted sender paying neither default nor their reduced amount is rejected with the reduced amount as the expected +- **WHEN** a whitelisted sender sends an amount equal to neither `Config::deposit_amount.amount` nor `reduced_deposits[sender].amount` +- **THEN** the call returns `EcashContractError::WrongAmount { received, amount }` where `amount` is the sender's reduced amount + +#### Scenario: Non-whitelisted sender paying the wrong amount is rejected with the default amount as the expected +- **WHEN** a sender with no reduced-deposit entry sends an amount different from `Config::deposit_amount.amount` +- **THEN** the call returns `EcashContractError::WrongAmount { received, amount }` where `amount` is `Config::deposit_amount` + +#### Scenario: Missing, mismatched, or multi-denom funds are rejected by `must_pay` before amount classification +- **WHEN** `DepositTicketBookFunds` is sent with no attached coins, with multiple denom coins, or with a single coin in a denom different from `Config::deposit_amount.denom` +- **THEN** the call returns `EcashContractError::InvalidDeposit(PaymentError::NoFunds)`, `EcashContractError::InvalidDeposit(PaymentError::MultipleDenoms)`, or `EcashContractError::InvalidDeposit(PaymentError::MissingDenom())` respectively, before any classification, counter, or storage write + +### Requirement: Deposit identity-key payload is opaque to the contract; ownership is enforced off-chain + +The contract SHALL accept `identity_key: String` as an opaque payload at deposit submission time. The handler MUST NOT verify control of the corresponding ed25519 private key. The handler MUST persist the payload such that it round-trips losslessly through `Deposit::to_bytes` → 32-byte raw storage → `Deposit::try_from_bytes` → bs58 string; any payload that fails to decode to exactly 32 bytes via `bs58::decode` MUST surface as `EcashContractError::MalformedEd25519Identity` (raised by `Deposit::to_bytes` during the `save_deposit` flow). The proof-of-control check is performed off-chain by nym-api signers when honouring `post_blind_sign`. + +#### Scenario: Sender can claim any well-formed ed25519 pubkey +- **WHEN** sender `A` submits `DepositTicketBookFunds { identity_key: B_pubkey }` where `B_pubkey` is sender `B`'s ed25519 public key, paying the correct amount +- **THEN** the deposit is accepted and `GetDeposit { deposit_id }` returns `Deposit { bs58_encoded_ed25519_pubkey: B_pubkey }` + +#### Scenario: Malformed bs58 ed25519 payload is rejected at save time +- **WHEN** `DepositTicketBookFunds { identity_key: "not-a-valid-bs58-key" }` is submitted with the correct funds +- **THEN** the call returns `EcashContractError::MalformedEd25519Identity` and no deposit is persisted, no counters are incremented + +### Requirement: Deposit ids are sequential `u32` starting at 0, never recycled + +The contract SHALL maintain a single `Item` counter at the storage key `"deposit_ids"`. The counter SHALL be unset on a freshly instantiated contract and treated as zero. Each successful `DepositTicketBookFunds` invocation SHALL: + +- read the current counter value (defaulting to 0 when absent), which becomes the new deposit's id; +- persist `counter + 1` as the new counter value; +- write the 32-byte raw ed25519 pubkey for that id under the `"deposit"` storage namespace (bypassing JSON serialisation for storage efficiency — see `StoredDeposits`). + +`DepositStorage::total_deposits_made(storage)` and `DepositStorage::latest_deposit(storage)` SHALL both read the counter directly — `total_deposits_made` returns `unwrap_or(0)` (count of deposits ever performed), `latest_deposit` returns `may_load` (the *next* unused id, which is also the count). Deposit ids SHALL NOT be recycled even if the deposit can later be invalidated off-chain. + +#### Scenario: First deposit on a fresh contract gets id 0 +- **WHEN** the first-ever `DepositTicketBookFunds` is processed +- **THEN** the assigned `deposit_id` is `0`, the persisted counter becomes `1`, and `total_deposits_made` returns `1` + +#### Scenario: Subsequent deposits get strictly increasing ids +- **WHEN** three deposits are processed in sequence +- **THEN** they receive ids `0`, `1`, `2` and the counter becomes `3` + +### Requirement: Deposit statistics invariant — default count plus per-account custom counts equals total + +The contract SHALL maintain the invariant `DepositStatsStorage::get_total_deposits_made_with_default_price(storage) + sum(deposits_with_custom_price[a] for a in addrs) == DepositStorage::total_deposits_made(storage)` at all times after instantiation. This invariant MUST hold across every successful and failed transaction (a failed deposit MUST NOT touch any counter). The `#[cfg(test)] assert_counts_consistent` helper in `DepositStatsStorage` SHALL exist solely to validate this invariant in tests and is part of the maintenance contract for any code that writes to the `"deposit"` namespace. + +#### Scenario: Mixed default and reduced deposits maintain the invariant +- **WHEN** two default-price deposits and one reduced-price deposit by address `alice` are processed in any order +- **THEN** `deposits_with_default_price` reads `2`, `deposits_with_custom_price[alice]` reads `1`, `total_deposits_made` reads `3`, and `2 + 1 == 3` + +#### Scenario: A rejected `DepositTicketBookFunds` does not touch any counter +- **WHEN** `DepositTicketBookFunds` is rejected with `WrongAmount` +- **THEN** none of `deposit_ids`, `deposits_with_default_price`, `deposits_with_custom_price` change + +### Requirement: `UpdateDefaultDepositValue` is admin-gated and refuses values below the ticketbook size + +`ExecuteMsg::UpdateDefaultDepositValue { new_deposit: Coin }` SHALL be callable only by the contract admin (`contract_admin.assert_admin`). The handler MUST consult the on-chain `Invariants::ticket_book_size` via `get_ticketbook_size`; if the snapshotted value differs from the current crate `TICKETBOOK_SIZE`, the call MUST fail with `TicketBookSizeChanged { at_init, current }` *before* any further work. If `new_deposit.amount < TICKETBOOK_SIZE`, the call MUST fail with `DepositBelowTicketBookSize { amount, ticket_book_size }`. On success the handler SHALL overwrite `Config::deposit_amount` with `new_deposit` and emit a `wasm` event attribute `updated_deposit` carrying the new value as its `Coin::to_string()` form. + +Note: the handler does *not* validate that `new_deposit.denom` matches the existing config's denom. Changing the denom is permitted by the current handler but is operationally hazardous (existing reduced-deposit entries and statistics use the old denom). Reviewers should treat denom changes as a coordinated migration concern, not an admin operation. + +#### Scenario: Admin successfully bumps the default price +- **WHEN** the contract admin sends `UpdateDefaultDepositValue { new_deposit }` with `new_deposit.amount >= TICKETBOOK_SIZE` and the network-defaults `TICKETBOOK_SIZE` matches the snapshotted invariant +- **THEN** `Config::deposit_amount` equals `new_deposit` and the response contains a `wasm` attribute `updated_deposit = new_deposit.to_string()` + +#### Scenario: Non-admin call is rejected +- **WHEN** any non-admin sends `UpdateDefaultDepositValue` +- **THEN** the call returns `EcashContractError::Admin` and `Config::deposit_amount` is unchanged + +#### Scenario: Value below ticketbook size is rejected +- **WHEN** the admin sends `UpdateDefaultDepositValue { new_deposit }` with `new_deposit.amount < TICKETBOOK_SIZE` +- **THEN** the call returns `DepositBelowTicketBookSize { amount: new_deposit.amount, ticket_book_size: TICKETBOOK_SIZE }` + +### Requirement: `SetReducedDepositPrice` is admin-gated with denom, strict-less-than, and ticketbook-size validation + +`ExecuteMsg::SetReducedDepositPrice { address, deposit }` SHALL be callable only by the contract admin. The handler MUST validate `address` via `addr_validate`, then call `add_reduced_deposit_address`, which MUST: + +- reject `deposit.denom != Config::deposit_amount.denom` with `InvalidReducedDepositDenom { expected, got }`; +- reject `deposit.amount >= Config::deposit_amount.amount` with `ReducedDepositNotReduced { reduced, default }` (the reduced amount must be **strictly less than** the default); +- reject `deposit.amount < TICKETBOOK_SIZE` with `DepositBelowTicketBookSize { amount, ticket_book_size }` (subject to the same `get_ticketbook_size` tripwire as Requirement "UpdateDefaultDepositValue"); +- persist `reduced_deposits[address] = deposit` (overwriting any existing entry). + +On success the handler SHALL emit `wasm` attributes `action = "set_reduced_deposit_price"`, `address`, and `deposit` (as `Coin::to_string()`). + +#### Scenario: Admin sets a valid reduced price +- **WHEN** the admin sends `SetReducedDepositPrice { address, deposit }` with matching denom, amount strictly less than default, and amount at least the ticketbook size +- **THEN** `reduced_deposits[address] = deposit` and the response carries attributes `action = "set_reduced_deposit_price"`, `address`, `deposit` + +#### Scenario: Overwriting an existing entry succeeds +- **WHEN** the admin sends `SetReducedDepositPrice` for an address that already has a reduced entry +- **THEN** the existing entry is replaced with the new value (no error, no archiving of the old value) + +#### Scenario: Reduced amount not strictly less than default is rejected +- **WHEN** the admin sends `SetReducedDepositPrice` with `deposit.amount == Config::deposit_amount.amount` +- **THEN** the call returns `ReducedDepositNotReduced { reduced, default }` with both fields equal + +#### Scenario: Mismatched denom is rejected +- **WHEN** the admin sends `SetReducedDepositPrice` with a denom different from `Config::deposit_amount.denom` +- **THEN** the call returns `InvalidReducedDepositDenom { expected, got }` + +### Requirement: `RemoveReducedDepositPrice` is admin-gated and requires an existing entry + +`ExecuteMsg::RemoveReducedDepositPrice { address }` SHALL be callable only by the contract admin. The handler MUST validate `address`, then check `reduced_deposits.has(storage, address)`; if no entry exists, the call MUST fail with `NoReducedDepositPrice { address }`. On success the entry is removed from `reduced_deposits` and the response carries `wasm` attributes `action = "remove_reduced_deposit_price"` and `address`. + +Removal does not retroactively affect historical statistics for the removed address — past `deposits_with_custom_price[address]` and `..._amounts[address]` entries remain. + +#### Scenario: Admin removes an existing entry +- **WHEN** the admin sends `RemoveReducedDepositPrice` for an address with an existing reduced entry +- **THEN** `reduced_deposits[address]` is absent, historical `deposits_with_custom_price[address]` is unchanged, and the response carries `action` and `address` attributes + +#### Scenario: Removing a non-existent entry is rejected +- **WHEN** the admin sends `RemoveReducedDepositPrice` for an address with no reduced entry +- **THEN** the call returns `NoReducedDepositPrice { address }` + +### Requirement: `UpdateAdmin` requires the current admin and validates the new address + +`ExecuteMsg::UpdateAdmin { admin }` SHALL be callable only by the current `contract_admin`. The handler MUST `addr_validate` the supplied string, then call `cw_controllers::Admin::execute_update_admin(deps, info, Some(new_admin))`. The cw_controllers handshake performs the sender-equality check internally. On success the new address replaces the current `contract_admin` slot, and the response carries the cw_controllers-standard attributes (`action = "update_admin"`, `admin = `, `sender = `). + +The handler always passes `Some(new_admin)` — admin renunciation (passing `None`) is not exposed through the public surface today. + +#### Scenario: Current admin transfers admin rights +- **WHEN** the current admin sends `UpdateAdmin { admin: new_admin }` with a valid bech32 string +- **THEN** subsequent `contract_admin.assert_admin` checks succeed only for `new_admin`, and the old admin's calls to admin-gated handlers fail + +#### Scenario: Non-admin call is rejected +- **WHEN** an address other than the current admin sends `UpdateAdmin` +- **THEN** the call returns `EcashContractError::Admin` wrapping `AdminError::NotAdmin` + +#### Scenario: Invalid bech32 address is rejected +- **WHEN** the current admin sends `UpdateAdmin { admin: "not-bech32" }` +- **THEN** the call returns an `EcashContractError::Std` wrapping the underlying `addr_validate` failure + +### Requirement: `RequestRedemption` validates the commitment and dispatches a multisig propose SubMsg + +`ExecuteMsg::RequestRedemption { commitment_bs58, number_of_tickets }` SHALL be callable by any address. The handler MUST: + +- decode `commitment_bs58` via `bs58::decode(...).into_vec()`; on decode failure or if the decoded length is not exactly 32 bytes (sha256 digest length), the call MUST fail with `MalformedRedemptionCommitment`; +- construct a `cw3` `Propose` message via `create_batch_redemption_proposal`, with title `BATCH_REDEMPTION_PROPOSAL_TITLE = "ecash-redemption"`, description equal to `commitment_bs58`, and a single embedded `ExecuteMsg::RedeemTickets { n: number_of_tickets, gw: }` targeting the ecash contract itself; +- wrap that proposal in a `SubMsg::reply_always(..., REDEMPTION_PROPOSAL_REPLY_ID)`; +- return `Response::new().add_submessage(submsg)`. + +The handler does NOT itself transfer funds, mark tickets as redeemed, or modify any storage on the ecash contract directly. The actual redemption effect (incrementing `tickets_requested_and_not_redeemed`) only fires when the multisig contract subsequently executes the embedded `RedeemTickets` after a successful vote (see Requirement "Legacy `RedeemTickets`"). + +#### Scenario: Valid commitment dispatches a multisig propose with the right shape +- **WHEN** any sender sends `RequestRedemption` with a 32-byte sha256 digest encoded in bs58 and `number_of_tickets = N` +- **THEN** the response carries a single `SubMsg` with `id == REDEMPTION_PROPOSAL_REPLY_ID`, targeting the multisig contract, encoding a `Propose` with title `"ecash-redemption"`, description equal to the input `commitment_bs58`, and a single inner `WasmMsg::Execute` calling `RedeemTickets { n: N, gw: }` on the ecash contract + +#### Scenario: Non-bs58 commitment is rejected +- **WHEN** `RequestRedemption { commitment_bs58: "!!!" }` is sent +- **THEN** the call returns `MalformedRedemptionCommitment` and no SubMsg is dispatched + +#### Scenario: Bs58-decodable but wrong-length commitment is rejected +- **WHEN** `RequestRedemption` is sent with a `commitment_bs58` whose decoded bytes have length != 32 +- **THEN** the call returns `MalformedRedemptionCommitment` + +### Requirement: The redemption-proposal reply handler captures the multisig proposal id and surfaces it as response data + +The contract SHALL register a single `reply` entry point that dispatches by `Reply::id`. For `REDEMPTION_PROPOSAL_REPLY_ID`, the handler MUST call `Reply::multisig_proposal_id()`, which extracts the `proposal_id` attribute (`PROPOSAL_ID_ATTRIBUTE_NAME = "proposal_id"`) from the `wasm` event of the embedded multisig result. On success the handler MUST return `Response::new().set_data(proposal_id.to_be_bytes())` so callers can recover the multisig-issued id from the transaction result. On failure of the embedded SubMsg, the handler MUST return `EcashContractError::Std(StdError::generic_err(reply_err))`. If the `proposal_id` attribute is missing or malformed, the handler MUST return `MissingProposalId` or `MalformedProposalId` respectively. + +#### Scenario: Successful multisig propose flows the proposal id back to the gateway +- **WHEN** the redemption-proposal SubMsg succeeds and the multisig contract emits a `wasm` event with attribute `proposal_id = "42"` +- **THEN** the reply handler returns `Response::new().set_data([0,0,0,0,0,0,0,42])` (big-endian u64) + +#### Scenario: Missing proposal_id attribute is reported as a typed error +- **WHEN** the SubMsg succeeds but no `wasm` event carries a `proposal_id` attribute +- **THEN** the reply handler returns `MissingProposalId` + +#### Scenario: Failed SubMsg propagates as a generic StdError +- **WHEN** the SubMsg fails with error string `e` +- **THEN** the reply handler returns `EcashContractError::Std(StdError::generic_err(e))` + +#### Scenario: Unknown reply id is rejected +- **WHEN** the reply entry point is invoked with `Reply::id` not equal to `REDEMPTION_PROPOSAL_REPLY_ID` or `BLACKLIST_PROPOSAL_REPLY_ID` +- **THEN** the handler returns `InvalidReplyId { id }` + +### Requirement: Legacy `RedeemTickets` is multisig-gated, bumps the unredeemed-tickets counter, and emits a single event + +`ExecuteMsg::RedeemTickets { n, gw }` is **dead code retained on the public surface for backwards compatibility only**. It SHALL be callable **only** by the configured `multisig` address (`multisig.assert_admin`). The handler MUST: + +- ignore `gw` at runtime (the argument is preserved in the transaction body but not consumed); +- increment `PoolCounters.tickets_requested_and_not_redeemed` by `n` (as `u64`); +- emit `Event::new("ticket_redemption").add_attribute("moved_to_holding_account", "false")`. + +The handler does not move funds. No known active consumer depends on the counter increment or the event; both are remnants of the deprecated semantics. A follow-on change may remove this variant entirely. + +#### Scenario: Multisig successfully redeems n tickets +- **WHEN** the configured multisig sends `RedeemTickets { n: 5, gw: "" }` +- **THEN** `PoolCounters.tickets_requested_and_not_redeemed` increases by 5, and the response carries a `ticket_redemption` event with `moved_to_holding_account = "false"` + +#### Scenario: Non-multisig caller is rejected +- **WHEN** an address other than the configured multisig sends `RedeemTickets` +- **THEN** the call returns `EcashContractError::Admin` and the counter is unchanged + +### Requirement: Stubbed blacklist execute handlers always return `UnimplementedBlacklisting` + +`ExecuteMsg::ProposeToBlacklist { public_key }` and `ExecuteMsg::AddToBlacklist { public_key }` SHALL be present in the public schema but SHALL always return `EcashContractError::UnimplementedBlacklisting`. The handlers MUST NOT touch storage, dispatch SubMsgs, or emit events. + +The blacklist storage map (`blacklist: Map` at storage key `"blacklist"`), the reply handler for `BLACKLIST_PROPOSAL_REPLY_ID`, and the `create_blacklist_proposal` helper remain wired in source. They are preserved as the starting point for the redesign and are NOT reachable from the current public ExecuteMsg surface. + +#### Scenario: `ProposeToBlacklist` always errors +- **WHEN** any sender (admin, multisig, or other) sends `ProposeToBlacklist { public_key }` +- **THEN** the call returns `EcashContractError::UnimplementedBlacklisting` and the `blacklist` storage is unchanged + +#### Scenario: `AddToBlacklist` always errors +- **WHEN** any sender sends `AddToBlacklist { public_key }` +- **THEN** the call returns `EcashContractError::UnimplementedBlacklisting` and the `blacklist` storage is unchanged + +### Requirement: The ticketbook-size invariant tripwire catches uncoordinated network-defaults bumps + +The contract SHALL persist `Item { ticket_book_size }` at storage key `"expected_invariants"` on instantiation, snapshotting `nym_network_defaults::TICKETBOOK_SIZE`. Every priced operation that consults the ticketbook size (currently `UpdateDefaultDepositValue` and `SetReducedDepositPrice` / migration whitelist seeding via `add_reduced_deposit_address`) SHALL call `NymEcashContract::get_ticketbook_size`, which compares the stored value to the crate's current `TICKETBOOK_SIZE`. A mismatch MUST surface as `TicketBookSizeChanged { at_init, current }`, halting the operation before any state mutation. + +#### Scenario: Snapshot equals current crate constant — operation proceeds +- **WHEN** the snapshotted `Invariants::ticket_book_size` equals `nym_network_defaults::TICKETBOOK_SIZE` and an admin sends a valid `UpdateDefaultDepositValue` +- **THEN** the operation succeeds normally + +#### Scenario: Snapshot differs from current crate constant — operation halted +- **WHEN** the snapshotted `Invariants::ticket_book_size` is `T_init` and the contract has been redeployed with a new crate constant `T_current != T_init`, then an admin sends `UpdateDefaultDepositValue` or migration seeds a reduced-deposit entry +- **THEN** the call returns `TicketBookSizeChanged { at_init: T_init, current: T_current }` before any further work + +### Requirement: Default-deposit queries + +The contract SHALL expose two equivalent queries for the default deposit amount, kept aliased for backwards compatibility: + +- `QueryMsg::GetDefaultDepositAmount {}` — returns `Coin = Config::deposit_amount`. +- `QueryMsg::GetRequiredDepositAmount {}` (also accepted via the `get_required_deposit_amount` `serde` alias on `GetDefaultDepositAmount`) — equivalent to the above; the handler delegates to `get_default_deposit_amount`. + +Both queries SHALL succeed unconditionally for any sender (queries are read-only). + +#### Scenario: Both query variants return identical data +- **WHEN** both `GetDefaultDepositAmount {}` and `GetRequiredDepositAmount {}` are queried on the same contract state +- **THEN** both return the same `Coin`, equal to `Config::deposit_amount` + +### Requirement: Reduced-deposit queries + +The contract SHALL expose two queries for tier-pricing state: + +- `QueryMsg::GetReducedDepositAmount { address }` — validates `address` via `addr_validate`, then returns `Option = reduced_deposits.may_load(storage, addr)`. An invalid bech32 input MUST return an `EcashContractError::Std` wrapping the underlying validation error. +- `QueryMsg::GetAllWhitelistedAccounts {}` — returns `WhitelistedAccountsResponse { whitelisted_accounts }` enumerating all entries in `reduced_deposits` in ascending address order. + +`GetAllWhitelistedAccounts` is unpaginated by design (the whitelist is expected to remain small). + +#### Scenario: Reduced amount is returned when an entry exists +- **WHEN** address `alice` has `reduced_deposits[alice] = Coin { 10, "unym" }` and `GetReducedDepositAmount { address: alice }` is queried +- **THEN** the response is `Some(Coin { 10, "unym" })` + +#### Scenario: Absent entry returns None +- **WHEN** address `bob` has no entry and `GetReducedDepositAmount { address: bob }` is queried +- **THEN** the response is `None` + +#### Scenario: All whitelisted accounts are enumerated +- **WHEN** the contract has entries for `alice` and `bob` and `GetAllWhitelistedAccounts {}` is queried +- **THEN** the response contains both entries + +### Requirement: Deposit-by-id and latest-deposit queries + +The contract SHALL expose: + +- `QueryMsg::GetDeposit { deposit_id }` — returns `DepositResponse { id: deposit_id, deposit: Option }`. The `deposit` field is `Some` if a deposit was ever persisted under that id (deposits are not deletable). It is `None` if the id has not yet been issued (i.e. `id >= total_deposits_made`). +- `QueryMsg::GetLatestDeposit {}` — returns `LatestDepositResponse { deposit: Option }`. The handler MUST consult `DepositStorage::latest_deposit`, which returns the id of the most recently assigned deposit (`counter - 1` when the counter has been incremented at least once, else `None`), and then load that id. On a fresh contract with no prior deposit, the response is `LatestDepositResponse { deposit: None }`; after any successful deposit, the response is `LatestDepositResponse { deposit: Some(DepositData { id, deposit }) }` where `id` is the most recent assignment. + +#### Scenario: Existing deposit is returned by id +- **WHEN** a deposit was persisted at id `0` with `identity_key = K` and `GetDeposit { deposit_id: 0 }` is queried +- **THEN** the response is `DepositResponse { id: 0, deposit: Some(Deposit { bs58_encoded_ed25519_pubkey: K }) }` + +#### Scenario: Unknown id returns None +- **WHEN** `GetDeposit { deposit_id: 999 }` is queried and the counter is less than 999 +- **THEN** the response is `DepositResponse { id: 999, deposit: None }` + +#### Scenario: Fresh contract latest-deposit query returns None +- **WHEN** `GetLatestDeposit {}` is queried on a contract with no deposits +- **THEN** the response is `LatestDepositResponse { deposit: None }` + +#### Scenario: After deposits exist, latest-deposit query returns the most recent assignment +- **WHEN** two deposits have been processed (ids `0` and `1`) and `GetLatestDeposit {}` is queried +- **THEN** the response is `LatestDepositResponse { deposit: Some(DepositData { id: 1, deposit: }) }` + +### Requirement: Paginated deposits query + +`QueryMsg::GetDepositsPaged { limit, start_after }` SHALL return at most `limit.unwrap_or(DEPOSITS_PAGE_DEFAULT_LIMIT).min(DEPOSITS_PAGE_MAX_LIMIT)` deposits in ascending id order, starting strictly after `start_after`. The defaults `DEPOSITS_PAGE_DEFAULT_LIMIT = 50` and `DEPOSITS_PAGE_MAX_LIMIT = 100` are part of the public surface and changing them is a behavioural change. The response SHALL be `PagedDepositsResponse { deposits, start_next_after }`, where `start_next_after` is the id of the last entry returned (or `None` if zero entries were returned). + +#### Scenario: Default limits clamp to the maximum +- **WHEN** `GetDepositsPaged { limit: Some(1000), start_after: None }` is queried on a contract with 200 deposits +- **THEN** the response contains 100 entries (ids 0..=99) and `start_next_after = Some(99)` + +#### Scenario: Pagination via `start_after` +- **WHEN** the previous query returned `start_next_after = Some(99)` and a follow-up sends `GetDepositsPaged { limit: None, start_after: Some(99) }` +- **THEN** the response starts at id 100 + +### Requirement: `GetDepositsStatistics` reassembles the global and per-account picture + +`QueryMsg::GetDepositsStatistics {}` SHALL return `DepositsStatistics` populated from: + +- `total_deposits_made` ← `DepositStorage::total_deposits_made(storage)`; +- `total_deposited` ← `PoolCounters::total_deposited`; +- `total_deposits_made_with_default_price` ← `deposits_with_default_price`; +- `total_deposited_with_default_price` ← `deposits_with_default_price_amounts`; +- `total_deposits_made_with_custom_price` ← `sum(deposits_with_custom_price[a])` across all addresses; +- `total_deposited_with_custom_price` ← `sum(deposits_with_custom_price_amounts[a])` across all addresses (using `Config::deposit_amount.denom`); +- `deposits_made_with_custom_price: HashMap` and `deposited_with_custom_price: HashMap` ← per-account aggregates from the custom-price maps, keyed by the stringified `Addr`. + +The query MUST be a single read pass (no execute-side write) and is callable by any sender. + +#### Scenario: Statistics reflect the post-mixed-deposit state +- **WHEN** two default-price deposits of value 75 each, and one reduced-price deposit by `alice` of value 10, have been processed; then `GetDepositsStatistics {}` is queried +- **THEN** the response has `total_deposits_made = 3`, `total_deposits_made_with_default_price = 2`, `total_deposited_with_default_price.amount = 150`, `total_deposits_made_with_custom_price = 1`, `total_deposited_with_custom_price.amount = 10`, and `deposits_made_with_custom_price["alice"] = 1` + +### Requirement: Blacklist queries succeed and return empty on a freshly deployed contract + +`QueryMsg::GetBlacklistedAccount { public_key }` and `QueryMsg::GetBlacklistPaged { limit, start_after }` SHALL be callable by any sender and SHALL NOT error on a contract that has no blacklist entries. + +- `GetBlacklistedAccount` returns `BlacklistedAccountResponse { account: Option }`. On a contract where no entry exists for `public_key`, the response is `BlacklistedAccountResponse { account: None }`. +- `GetBlacklistPaged` returns `PagedBlacklistedAccountResponse` with at most `limit.unwrap_or(BLACKLIST_PAGE_DEFAULT_LIMIT).min(BLACKLIST_PAGE_MAX_LIMIT)` entries (`BLACKLIST_PAGE_DEFAULT_LIMIT = 50`, `BLACKLIST_PAGE_MAX_LIMIT = 75`). On a contract with no entries, the response is empty (`accounts: []`, `start_next_after: None`). + +Because the blacklist execute handlers always error (Requirement "Stubbed blacklist execute handlers"), the only way for blacklist storage to contain entries on a live deployment is through the reply path for `BLACKLIST_PROPOSAL_REPLY_ID` — which is itself unreachable from the public ExecuteMsg surface today. Consumers MUST NOT treat an empty blacklist as a security guarantee. + +#### Scenario: Querying an absent blacklist entry returns None +- **WHEN** `GetBlacklistedAccount { public_key: K }` is queried on a contract that has never blacklisted `K` +- **THEN** the response is `BlacklistedAccountResponse { account: None }` + +#### Scenario: Paginated blacklist on empty contract returns empty +- **WHEN** `GetBlacklistPaged { limit: None, start_after: None }` is queried on a freshly deployed contract +- **THEN** the response is `PagedBlacklistedAccountResponse { accounts: [], per_page: 50, start_next_after: None }` + +### Requirement: Public storage layout + +The following raw CosmWasm storage keys SHALL be considered part of the public contract surface. Any change to these keys is a breaking change for already-deployed contracts and MUST be accompanied by a coordinated migration: + +- `"contract_admin"` — `cw_controllers::Admin` slot for the contract admin (single Cosmos SDK address). +- `"multisig"` — `cw_controllers::Admin` slot for the multisig contract address. +- `"config"` — `Item { group_addr, holding_account, deposit_amount }`. +- `"pool_counters"` — `Item { total_deposited, total_redeemed, tickets_requested_and_not_redeemed }`. +- `"expected_invariants"` — `Item { ticket_book_size }`. +- `"deposit_ids"` — `Item` deposit-id counter (next free id). +- `"deposit"` — custom raw-bytes namespace for stored deposits (32-byte ed25519 pubkeys), keyed by big-endian `u32`. **Not** a `cw_storage_plus::Map`. +- `"reduced_deposits"` — `Map` per-address reduced-deposit price. +- `"blacklist"` — `Map` reserved for the future blacklist redesign; unreachable through public execute paths today. +- `"deposits_with_default_price"` — `Item` count of default-price deposits. +- `"deposits_with_default_price_amounts"` — `Item` total amount of default-price deposits. +- `"deposits_with_custom_price"` — `Map` per-account count of custom-price deposits. +- `"deposits_with_custom_price_amounts"` — `Map` per-account total amount of custom-price deposits. + +In addition, the two reply-id constants `BLACKLIST_PROPOSAL_REPLY_ID = 7759` and `REDEMPTION_PROPOSAL_REPLY_ID = 2137` form part of the public surface for any contract upgrade — changing them invalidates in-flight submessage replies. + +#### Scenario: Reading any storage key listed above on a v1 deployment succeeds with the documented type +- **WHEN** a CosmWasm raw-state inspection tool reads any of the listed keys on a contract deployed at the spec's anchor version +- **THEN** the deserialised value matches the documented type (`Item`, `Map`, raw bytes, or `Admin` slot as listed) + +### Requirement: Public event surface + +The following events SHALL form the public contract surface consumed by chain indexers and downstream tooling. Renaming events or attribute keys MUST be treated as a breaking change: + +- `deposited-funds` event, emitted by `DepositTicketBookFunds` on success. Carries attribute `deposit-id` (decimal string form of the new `u32`). Event type constant: `DEPOSITED_FUNDS_EVENT_TYPE`. Attribute constant: `DEPOSIT_ID`. +- `ticket_redemption` event, emitted by `RedeemTickets` on success. Carries attribute `moved_to_holding_account = "false"` (the literal string `"false"`). This event is a remnant of the deprecated `RedeemTickets` flow (see the "Legacy `RedeemTickets`" requirement) and is preserved by the contract today but not consumed by any known live indexer. +- The auto-generated `wasm` event emitted by the redemption-proposal reply handler — carries attribute `proposal_id` (decimal string form of the multisig-issued `u64`). Attribute constant: `PROPOSAL_ID_ATTRIBUTE_NAME`. The `wasm` event name itself is the cosmwasm-std auto-event; the attribute is added via `Response::add_attribute`. +- The auto-generated `wasm` event emitted by `UpdateDefaultDepositValue` — carries attribute `updated_deposit = Coin::to_string()`. +- The auto-generated `wasm` event emitted by `SetReducedDepositPrice` — carries attributes `action = "set_reduced_deposit_price"`, `address`, `deposit = Coin::to_string()`. +- The auto-generated `wasm` event emitted by `RemoveReducedDepositPrice` — carries attributes `action = "remove_reduced_deposit_price"`, `address`. +- The auto-generated `wasm` events from `UpdateAdmin` and the embedded multisig propose carry standard cw_controllers / cw3 attributes; the ecash contract does not add additional attributes on those paths. + +Handlers that explicitly return `Response::default()` (instantiation, migration) MUST NOT emit any events. + +#### Scenario: Successful default-price deposit emits exactly one `deposited-funds` event with the new id +- **WHEN** a default-price `DepositTicketBookFunds` succeeds and assigns id `42` +- **THEN** the response carries exactly one `deposited-funds` event with attribute `deposit-id = "42"` + +#### Scenario: Successful `RedeemTickets` carries the legacy `moved_to_holding_account = "false"` attribute +- **WHEN** a `RedeemTickets { n: 3, gw: "..." }` succeeds +- **THEN** the response carries exactly one `ticket_redemption` event with attribute `moved_to_holding_account = "false"` + +#### Scenario: Instantiation emits no events +- **WHEN** the contract is instantiated successfully +- **THEN** the response has no events and no attributes + +### Requirement: Public error variants + +The `EcashContractError` enum forms part of the public surface — its variants are observable through transaction failure messages and are encoded in JSON schema artefacts. The following variants MUST be reachable through the current public execute / migration surface and MUST NOT be removed without a coordinated schema bump: + +- `Std`, `Admin` — wrapper variants over `StdError` and `AdminError`. +- `InvalidDeposit(PaymentError)` — wrapper variant raised by `cw_utils::must_pay` on `DepositTicketBookFunds` when funds are missing, multi-denom, or in the wrong denom. The inner `PaymentError` variants `NoFunds`, `MultipleDenoms`, `MissingDenom()` are all reachable. +- `WrongAmount { received, amount }` — `DepositTicketBookFunds` with the right denom but a non-matching amount. +- `InvalidGroup { addr }` — instantiation with an unparseable group address. +- `MalformedRedemptionCommitment` — `RequestRedemption` with a non-32-byte commitment. +- `MalformedEd25519Identity` — `DepositTicketBookFunds` with a non-32-byte bs58 identity payload at save time. +- `InvalidReducedDepositDenom { expected, got }` — denom mismatch in `SetReducedDepositPrice` or migration whitelist seeding. +- `ReducedDepositNotReduced { reduced, default }` — reduced amount not strictly less than default. +- `DepositBelowTicketBookSize { amount, ticket_book_size }` — reduced or default amount below the ticketbook-size floor. +- `NoReducedDepositPrice { address }` — `RemoveReducedDepositPrice` against an absent entry. +- `TicketBookSizeChanged { at_init, current }` — invariant tripwire mismatch. +- `UnimplementedBlacklisting` — `ProposeToBlacklist` or `AddToBlacklist` (always thrown). +- `InvalidReplyId { id }` — reply dispatcher with an unknown id. +- `MissingProposalId` / `MalformedProposalId` — multisig-reply parsing failures. + +`NotEnoughFunds`, `MaximumDepositTypesReached`, `UnknownCompressedDepositInfoType { typ }`, `UnknownDepositInfoType { typ }`, `Unauthorized`, and `SemVerFailure { value, error_message }` are present in the enum but are **not reachable** through any current public execute path. They are preserved for forward compatibility (notably for the eventual blacklist redesign and deposit-info-typing feature work) and SHOULD NOT be relied upon by downstream tooling. + +#### Scenario: Each reachable variant has at least one triggering scenario in this spec +- **WHEN** a reviewer cross-references the reachable variants listed above against the requirements in this spec +- **THEN** every reachable variant appears as the documented error of at least one scenario + diff --git a/openspec/specs/node-families-contract/spec.md b/openspec/specs/node-families-contract/spec.md new file mode 100644 index 0000000000..8446cdcf97 --- /dev/null +++ b/openspec/specs/node-families-contract/spec.md @@ -0,0 +1,432 @@ +# node-families-contract Specification + +## Purpose +TBD - created by archiving change node-families-contract-spec. Update Purpose after archive. +## Requirements +### Requirement: Contract instantiation persists the runtime config, mixnet contract address, and admin + +The contract SHALL be instantiable exactly once via the standard CosmWasm `instantiate` entry point. The instantiation message SHALL carry a `Config` (creation fee, family-name length limit, family-description length limit, default invitation validity in seconds) and a string-form `mixnet_contract_address`. The handler MUST: + +- bech32-validate `mixnet_contract_address` and reject malformed inputs; +- persist the validated mixnet contract address, the `Config`, and `info.sender` as the contract admin; +- record the contract name and `CARGO_PKG_VERSION` via `cw2::set_contract_version`; +- record build information via `set_build_information!`. + +#### Scenario: Valid instantiation persists config, mixnet address, and admin +- **WHEN** `instantiate` is called with a valid bech32 mixnet contract address and a well-formed `Config` +- **THEN** the contract stores the `Config` verbatim, the validated `Addr` for the mixnet contract, and sets `info.sender` as the contract admin queryable via `cw-controllers::Admin::assert_admin` +- **AND** `cw2::get_contract_version` returns the crate's `CARGO_PKG_VERSION` + +#### Scenario: Invalid mixnet contract address is rejected +- **WHEN** `instantiate` is called with a `mixnet_contract_address` string that fails `Addr::validate` +- **THEN** the call returns an error and no state is persisted + +### Requirement: Migration entry point forbids version downgrades + +The contract SHALL expose a `migrate` entry point that refreshes recorded build information and uses `cw2::ensure_from_older_version` to guarantee the on-chain contract version is at most the current `CARGO_PKG_VERSION`. Downgrade attempts MUST be rejected. + +#### Scenario: Equal or older on-chain version is accepted +- **WHEN** `migrate` is called against an on-chain `cw2` version less than or equal to `CARGO_PKG_VERSION` +- **THEN** the call succeeds and `set_build_information!` updates the stored build metadata + +#### Scenario: Newer on-chain version is rejected +- **WHEN** `migrate` is called against an on-chain `cw2` version strictly greater than `CARGO_PKG_VERSION` +- **THEN** the call returns an error and storage is unchanged + +### Requirement: Only the contract admin can replace the runtime config + +The `ExecuteMsg::UpdateConfig` handler SHALL overwrite the stored `Config` with the value supplied by the caller. The handler MUST call `Admin::assert_admin` and return the underlying `AdminError` (wrapped in `NodeFamiliesContractError::Admin`) when the sender is not the admin. + +#### Scenario: Admin replaces the config +- **WHEN** the contract admin sends `ExecuteMsg::UpdateConfig { config }` +- **THEN** the stored `Config` equals the supplied value on subsequent reads + +#### Scenario: Non-admin is rejected +- **WHEN** a non-admin sender sends `ExecuteMsg::UpdateConfig` +- **THEN** the call returns an `Admin` error and the stored `Config` is unchanged + +### Requirement: Family names are normalised and globally unique under their normalised form + +Family names SHALL be normalised to a canonical form by lowercasing ASCII letters, preserving ASCII digits, and dropping every other character (whitespace, punctuation, non-ASCII letters). The normalised form SHALL be stored alongside the user-supplied `name` and SHALL be the key of the `families.normalised_name` unique index. Inputs whose normalised form is the empty string SHALL be rejected with `EmptyFamilyName`. Inputs whose original length exceeds `Config::family_name_length_limit` (measured in **bytes**, via `String::len`) SHALL be rejected with `FamilyNameTooLong { length, limit }`. Creation of a family whose normalised name collides with an existing family SHALL fail with `FamilyNameAlreadyTaken { name, family_id }`. + +**Important**: this normalisation is ASCII-only by design. Non-ASCII letters and emoji are stripped entirely (`"café"` → `"caf"`, `"名前"` → `""`, `"⭐stars"` → `"stars"`). Names consisting solely of non-ASCII characters or symbols are rejected as `EmptyFamilyName`. Operators who want a non-ASCII brand cannot encode it in the on-chain family name; the user-supplied `name` field preserves the original formatting but only the normalised ASCII form is enforced for uniqueness and emptiness. + +#### Scenario: Normalisation strips punctuation, whitespace, casing, and non-ASCII letters +- **WHEN** the contract normalises any of `"Foo Bar"`, `"foobar"`, `"FOO-BAR"`, or `" f.o.o.b.a.r "` +- **THEN** every result equals `"foobar"` + +#### Scenario: All-symbol name is rejected +- **WHEN** `CreateFamily` is sent with `name = "!!!---"` (normalises to the empty string) +- **THEN** the call fails with `EmptyFamilyName` and no family is persisted + +#### Scenario: Name length is checked against the original string, not the normalised form +- **WHEN** `CreateFamily` is sent with a `name` whose `name.len()` (byte length) exceeds `Config::family_name_length_limit` +- **THEN** the call fails with `FamilyNameTooLong { length, limit }` + +#### Scenario: Multi-byte characters count their full byte length toward the limit +- **WHEN** `Config::family_name_length_limit = 8` and `CreateFamily` is sent with `name = "🚀rocket"` (a 4-byte emoji followed by `"rocket"`, totalling `name.len() == 10` bytes — but only 7 user-perceived characters) +- **THEN** the call fails with `FamilyNameTooLong { length: 10, limit: 8 }` even though the visible character count is within the limit +- **AND** had the limit been `>= 10`, the name would have been accepted and the normalised form would be `"rocket"` (the emoji dropped during normalisation) + +#### Scenario: Two formattings of the same canonical name collide +- **WHEN** family `A` is created with `name = "Shared"` and `B` later tries to create with `name = "$$shared$$"` +- **THEN** the second call fails with `FamilyNameAlreadyTaken { name: "shared", family_id: A.id }` + +### Requirement: An address may own at most one family at a time + +A given owner address SHALL own at most one family at any time, enforced by the `families.owner` unique index. `CreateFamily` SHALL pre-check this and fail with `SenderAlreadyOwnsAFamily { address, family_id }` for better error context. The pre-check is in addition to (not instead of) the unique-index defence-in-depth check. Owner-gated handlers (`DisbandFamily`, `InviteToFamily`, `RevokeFamilyInvitation`, `KickFromFamily`) SHALL look up the family by owner and fail with `SenderDoesntOwnAFamily { address }` when none exists. + +#### Scenario: Same address cannot create a second family while still owning one +- **WHEN** address `alice` already owns family `A` and `CreateFamily` is sent again with `alice` as sender +- **THEN** the call fails with `SenderAlreadyOwnsAFamily { address: alice, family_id: A.id }` + +#### Scenario: Address can create a family again after disbanding its previous one +- **WHEN** `alice` creates family `A` then disbands it, then sends `CreateFamily` again +- **THEN** a new family with a strictly greater id than `A` is created (ids are monotonic and never recycled) + +#### Scenario: Owner-gated handler rejects a sender that owns no family +- **WHEN** any of `DisbandFamily`, `InviteToFamily`, `RevokeFamilyInvitation`, or `KickFromFamily` is sent by an address that owns no family +- **THEN** the call fails with `SenderDoesntOwnAFamily { address }` + +### Requirement: Family creation requires the configured fee and is rejected if the owner's bonded node is already in a family + +`ExecuteMsg::CreateFamily` SHALL require the sender to attach exactly one coin matching `Config::create_family_fee` in both denom and amount. Payment validation MUST go through `cw_utils::must_pay`; mismatches in amount MUST surface as `InvalidFamilyCreationFee { expected, received }`. The handler MUST additionally check that any bonded node the sender controls (as reported by the mixnet contract via `query_nymnode_ownership`) is not currently a member of any family, failing with `AlreadyInFamily { address, node_id, family_id }` otherwise. The handler MUST validate the description length against `Config::family_description_length_limit` and reject overlong descriptions with `FamilyDescriptionTooLong { length, limit }`. On success the handler SHALL emit a `family_creation` event with attributes `family_name`, `owner_address`, `family_id`, `paid_fee`. + +#### Scenario: Successful family creation persists the family and emits the event +- **WHEN** a sender with no bonded family-member node and no existing-owned family sends `CreateFamily { name, description }` with the correct fee attached +- **THEN** a new family is persisted with monotonically increasing `id`, the supplied `name` and `description`, the computed `normalised_name`, `members = 0`, `created_at = env.block.time.seconds()`, and `paid_fee` equal to the configured fee +- **AND** the response carries an event named `family_creation` with attributes `family_name`, `owner_address`, `family_id`, `paid_fee` + +#### Scenario: Wrong fee denom or missing funds is rejected +- **WHEN** `CreateFamily` is sent with no funds, with multiple denoms, or with a denom different from `Config::create_family_fee.denom` +- **THEN** the call fails with `InvalidDeposit(PaymentError)` + +#### Scenario: Wrong fee amount is rejected +- **WHEN** `CreateFamily` is sent with the correct denom but an amount different from `Config::create_family_fee.amount` +- **THEN** the call fails with `InvalidFamilyCreationFee { expected, received }` and the funds remain unspent + +#### Scenario: Sender whose bonded node is already in a family is rejected +- **WHEN** `CreateFamily` is sent by an address whose bonded node (per the mixnet contract) is already a member of some family `F` +- **THEN** the call fails with `AlreadyInFamily { address, node_id, family_id: F.id }` + +#### Scenario: Overlong description is rejected +- **WHEN** `CreateFamily` is sent with a `description` whose byte length exceeds `Config::family_description_length_limit` +- **THEN** the call fails with `FamilyDescriptionTooLong { length, limit }` + +### Requirement: Family ids are monotonic, never recycled, and start at 1 + +The contract SHALL assign family ids sequentially starting at `1`. The id counter SHALL be persisted as an `Item` and incremented on each successful family creation. Disbanding a family MUST NOT free or recycle its id. `0` SHALL be reserved as a "no family" sentinel and never assigned. + +#### Scenario: First-ever family receives id 1 +- **WHEN** the contract is freshly instantiated and the first successful `CreateFamily` runs +- **THEN** the persisted `NodeFamily.id` equals `1` + +#### Scenario: Ids are not reused after disband +- **WHEN** family with id `N` is disbanded and a new family is then created +- **THEN** the new family's id is strictly greater than `N` (it is `N+1` if no other families were created in between) + +### Requirement: A family can only be disbanded by its owner, must be empty, and refunds the creation fee + +`ExecuteMsg::DisbandFamily` SHALL look up the sender's family via the `owner` unique index and fail with `SenderDoesntOwnAFamily` when none exists. The handler MUST reject disbanding while `NodeFamily.members > 0`, failing with `FamilyNotEmpty { family_id, members }`. On success the handler SHALL sweep every still-pending invitation issued by the family (archiving each as `FamilyInvitationStatus::Revoked { at: now }` with status timestamp = `env.block.time.seconds()`), remove the family record, and attach a `BankMsg::Send { to_address: owner, amount: vec![family.paid_fee] }` to the response as a CosmWasm sub-message. The response SHALL include a `family_disband` event with `family_id`, `owner_address`, `refunded_fee` attributes. + +**Operational note (non-normative)**: the pending-invitation sweep iterates every entry of `pending_family_invitations` keyed by `family_id` and archives each in a single transaction. Gas cost therefore scales linearly with the number of leftover pending invitations. An owner whose family has accumulated an unusually large number of pending invitations is expected to revoke them in batches (via `RevokeFamilyInvitation`) *before* invoking `DisbandFamily`, since a single disband call that exceeds the per-tx gas limit will fail and leave the family in place. There is no contract-side chunking; the responsibility lies with the caller. + +#### Scenario: Owner disbands an empty family and is refunded +- **WHEN** family owner sends `DisbandFamily` while `members == 0` +- **THEN** the family is removed from storage, the response carries a `BankMsg::Send` of `family.paid_fee` to the owner, and a `family_disband` event is emitted + +#### Scenario: Refund is attached as a BankMsg::Send sub-message, not a direct bank-module call +- **WHEN** a successful `DisbandFamily` returns its `Response` +- **THEN** the response's `messages` field contains exactly one `CosmosMsg::Bank(BankMsg::Send { to_address: , amount: vec![] })` and the contract performs no other balance-changing side effect for the refund +- **AND** tx simulators that inspect outbound sub-messages observe the refund there (this is the contract's only avenue for returning funds; integrators rely on it) + +#### Scenario: Non-empty family cannot be disbanded +- **WHEN** family owner sends `DisbandFamily` while `members > 0` +- **THEN** the call fails with `FamilyNotEmpty { family_id, members }` and storage is unchanged + +#### Scenario: Disbanding sweeps still-pending invitations as Revoked +- **WHEN** family `F` has pending invitations to nodes `n1`, `n2` and the owner sends `DisbandFamily` +- **THEN** the pending entries for `(F.id, n1)` and `(F.id, n2)` are removed from `pending_family_invitations` and archived under `past_family_invitations` with `status = Revoked { at: env.block.time.seconds() }` + +### Requirement: A node belongs to at most one family at any time + +The `family_members` map SHALL be keyed by `NodeId` alone; the value SHALL carry the `family_id` so the storage layer enforces the one-family-per-node invariant by construction. Handlers that add a membership (`AcceptFamilyInvitation`) and handlers that issue an invitation (`InviteToFamily`) SHALL pre-check the absence of any existing membership for the node and fail with `NodeAlreadyInFamily { node_id, family_id }` otherwise. + +#### Scenario: Inviting a node already in a family is rejected +- **WHEN** `InviteToFamily { node_id }` targets a node that already has a membership record for family `F` +- **THEN** the call fails with `NodeAlreadyInFamily { node_id, family_id: F.id }` + +#### Scenario: Accepting a second invitation after joining a family is rejected +- **WHEN** node `n` is a member of family `F` and `AcceptFamilyInvitation { family_id: G, node_id: n }` is sent (for a different family `G`) +- **THEN** the call fails with `NodeAlreadyInFamily { node_id: n, family_id: F.id }` + +### Requirement: Invitations require an existing family, a bonded target node, and strictly positive validity + +`ExecuteMsg::InviteToFamily` SHALL be owner-gated (the family acted on is the sender's owned family, never an argument). The handler MUST: + +- compute `validity = validity_secs.unwrap_or(Config::default_invitation_validity_secs)`; +- reject `validity == 0` with `ZeroInvitationValidity`; +- verify `node_id` refers to a currently-bonded, not-unbonding node in the mixnet contract via `MixnetContractQuerier::check_node_existence` (which returns `false` both when no bond exists and when the bond is in the unbonding state), failing with `NodeDoesntExist { node_id }` otherwise; +- verify the node is not already in any family (see "A node belongs to at most one family"); +- persist a `FamilyInvitation` with `expires_at = env.block.time.seconds() + validity`; +- reject `(family_id, node_id)` pairs that already have a pending invitation with `PendingInvitationAlreadyExists { family_id, node_id }`; +- emit a `family_invitation` event with `family_id`, `node_id`, `expires_at`. + +#### Scenario: Successful invitation persists with the computed expiry +- **WHEN** family owner sends `InviteToFamily { node_id, validity_secs: Some(v) }` and all preconditions hold +- **THEN** a pending invitation for `(owned.id, node_id)` is persisted with `expires_at = env.block.time.seconds() + v` +- **AND** the response carries a `family_invitation` event with `family_id = owned.id`, `node_id`, `expires_at` + +#### Scenario: Missing validity falls back to the configured default +- **WHEN** `InviteToFamily { node_id, validity_secs: None }` is sent +- **THEN** the persisted invitation has `expires_at = env.block.time.seconds() + Config::default_invitation_validity_secs` + +#### Scenario: Zero validity is rejected +- **WHEN** `InviteToFamily { node_id, validity_secs: Some(0) }` is sent +- **THEN** the call fails with `ZeroInvitationValidity` and no invitation is persisted + +#### Scenario: Inviting a non-bonded node is rejected +- **WHEN** `InviteToFamily { node_id }` targets a `node_id` for which the mixnet contract's `check_node_existence` returns `false` +- **THEN** the call fails with `NodeDoesntExist { node_id }` + +#### Scenario: Duplicate pending invitation is rejected +- **WHEN** family `F` already has a pending invitation for node `n` and `InviteToFamily { node_id: n }` is sent again by `F`'s owner +- **THEN** the call fails with `PendingInvitationAlreadyExists { family_id: F.id, node_id: n }` (the existing invitation is preserved) + +### Requirement: Acceptance and rejection of an invitation are gated on node control + +`ExecuteMsg::AcceptFamilyInvitation` and `ExecuteMsg::RejectFamilyInvitation` SHALL each verify that the sender is the controller of the bonded node `node_id` per the mixnet contract (`query_nymnode_ownership` returns a `nym_node` with `node_id == node_id` and `is_unbonding == false`). Failures MUST surface as `SenderDoesntControlNode { address, node_id }`. This single error covers the cases of: sender owns no bonded node, sender owns a different node id, and sender owns the node but it has entered unbonding. + +#### Scenario: Non-controller cannot accept an invitation +- **WHEN** `AcceptFamilyInvitation { family_id, node_id }` is sent by an address that does not control `node_id` (per mixnet contract) +- **THEN** the call fails with `SenderDoesntControlNode { address, node_id }` + +#### Scenario: Unbonding node cannot accept an invitation +- **WHEN** the sender controls `node_id` but the mixnet contract reports the node as unbonding +- **THEN** `AcceptFamilyInvitation` fails with `SenderDoesntControlNode { address, node_id }` + +#### Scenario: Non-controller cannot reject an invitation +- **WHEN** `RejectFamilyInvitation { family_id, node_id }` is sent by an address that does not control `node_id` +- **THEN** the call fails with `SenderDoesntControlNode { address, node_id }` + +### Requirement: Accepting an invitation moves it from pending to archived and increments the family member count + +A successful `AcceptFamilyInvitation` SHALL: + +- load the pending invitation for `(family_id, node_id)`, failing with `InvitationNotFound { family_id, node_id }` if absent; +- check `now < invitation.expires_at`, failing with `InvitationExpired { family_id, node_id, expires_at, now }` otherwise (`now == expires_at` is considered expired); +- remove the entry from `pending_family_invitations`; +- write `family_members[node_id] = FamilyMembership { family_id, joined_at: now }`; +- increment `NodeFamily::members` by 1 (failing with `FamilyNotFound { family_id }` if the family has somehow been removed); +- archive a `PastFamilyInvitation { invitation, status: Accepted { at: now } }` under `((family_id, node_id), counter)` where `counter` is the next free per-`(family, node)` archive slot; +- emit a `family_invitation_accepted` event with `family_id`, `node_id`. + +#### Scenario: Happy-path acceptance +- **WHEN** node controller accepts a not-yet-expired pending invitation +- **THEN** the membership is recorded with `joined_at = env.block.time.seconds()`, the family's `members` count is incremented, the pending entry is removed, and the archive contains the invitation with status `Accepted { at: now }` + +#### Scenario: Acceptance of an already-expired invitation is rejected +- **WHEN** `AcceptFamilyInvitation` is called with `env.block.time.seconds() >= invitation.expires_at` +- **THEN** the call fails with `InvitationExpired { family_id, node_id, expires_at, now }` and storage is unchanged + +#### Scenario: Acceptance with no pending invitation is rejected +- **WHEN** `AcceptFamilyInvitation { family_id, node_id }` is called with no pending invitation stored for that pair +- **THEN** the call fails with `InvitationNotFound { family_id, node_id }` + +### Requirement: Rejection and revocation work on expired invitations and archive them with terminal status + +`RejectFamilyInvitation` (sent by the node controller) and `RevokeFamilyInvitation` (sent by the family owner) SHALL each: + +- remove the pending invitation; +- archive a `PastFamilyInvitation` with status `Rejected { at: now }` or `Revoked { at: now }` respectively, under `((family_id, node_id), counter)` using the next free per-`(family, node)` archive slot; +- emit `family_invitation_rejected` or `family_invitation_revoked` respectively, with `family_id` and `node_id` attributes; +- fail with `InvitationNotFound { family_id, node_id }` if no pending invitation exists. + +These two paths SHALL be the only ways to clear an expired invitation out of `pending_family_invitations` — the contract performs no background sweep of expired entries. + +#### Scenario: Owner revokes a still-pending invitation +- **WHEN** family owner sends `RevokeFamilyInvitation { node_id }` for a node currently in their pending invitations +- **THEN** the pending entry is removed and the archive contains the invitation with status `Revoked { at: env.block.time.seconds() }` + +#### Scenario: Node controller rejects a still-pending invitation +- **WHEN** node controller sends `RejectFamilyInvitation { family_id, node_id }` for a pending invitation +- **THEN** the pending entry is removed and the archive contains the invitation with status `Rejected { at: env.block.time.seconds() }` + +#### Scenario: Expired invitations can still be rejected or revoked +- **WHEN** an invitation's `expires_at` is at or before `env.block.time.seconds()` and either `RejectFamilyInvitation` or `RevokeFamilyInvitation` is sent for it +- **THEN** the call succeeds, the pending entry is removed, and the archive records the appropriate terminal status + +### Requirement: Leave and kick remove the membership and archive a past-member record + +`ExecuteMsg::LeaveFamily { node_id }` SHALL require the sender to be the controller of `node_id` (failing with `SenderDoesntControlNode` otherwise). `ExecuteMsg::KickFromFamily { node_id }` SHALL require the sender to be the current owner of a family, and the node MUST be a member of *that* family — kicking a node belonging to a different family fails with `NodeNotMemberOfFamily { node_id, family_id }`; kicking a node that has no membership at all fails with `NodeNotInFamily { node_id }`. Both handlers SHALL share the same storage operation: remove `family_members[node_id]`, decrement `NodeFamily::members`, and archive a `PastFamilyMember { family_id, node_id, removed_at: env.block.time.seconds() }` under `((family_id, node_id), counter)` using the next free per-`(family, node)` slot. The respective events are `family_member_left` (carrying the leaver's `family_id` and `node_id`) and `family_member_kicked` (carrying the owner's `family_id` and the kicked `node_id`). + +#### Scenario: Node controller leaves the family +- **WHEN** node controller sends `LeaveFamily { node_id }` for a node currently in family `F` +- **THEN** `family_members[node_id]` is removed, `F.members` is decremented, the archive contains a `PastFamilyMember` with `removed_at = env.block.time.seconds()`, and the response carries a `family_member_left` event + +#### Scenario: Owner kicks a member of their family +- **WHEN** family owner sends `KickFromFamily { node_id }` for a member of their family +- **THEN** the same storage transition as a leave occurs and the response carries a `family_member_kicked` event + +#### Scenario: Owner cannot kick a node belonging to another family +- **WHEN** family owner sends `KickFromFamily { node_id }` for a node whose membership is in a different family `G` +- **THEN** the call fails with `NodeNotMemberOfFamily { node_id, family_id: owned.id }` and storage is unchanged + +#### Scenario: Repeated join/leave of the same family uses sequential archive counters +- **WHEN** node `n` joins, leaves, joins again, and leaves again the same family `F` +- **THEN** the archive contains `past_family_members[((F.id, n), 0)]` and `past_family_members[((F.id, n), 1)]` with the respective `removed_at` timestamps + +### Requirement: Only the configured mixnet contract may invoke the unbonding callback + +`ExecuteMsg::OnNymNodeUnbond { node_id }` SHALL be authorised solely by checking `info.sender == stored mixnet_contract_address`, failing with `UnauthorisedMixnetCallback { sender }` otherwise. There is no node-side or admin override. + +#### Scenario: Mixnet contract triggers the callback +- **WHEN** the mixnet contract sends `OnNymNodeUnbond { node_id }` +- **THEN** the call proceeds and the cleanup (see next requirement) is applied + +#### Scenario: Arbitrary sender is rejected +- **WHEN** any address other than the stored mixnet contract sends `OnNymNodeUnbond` +- **THEN** the call fails with `UnauthorisedMixnetCallback { sender }` + +### Requirement: The unbonding callback is idempotent over membership and sweeps every pending invitation addressed to the node + +A successful `OnNymNodeUnbond { node_id }` SHALL: + +- if `family_members[node_id]` exists, remove the membership and archive a `PastFamilyMember` exactly as the `leave` / `kick` path does (decrementing the family's `members` count); +- if no such membership exists, leave membership state untouched (this is the common case — most unbonding nodes were never in a family); +- iterate every entry of `pending_family_invitations` keyed by `node_id` (via the `node` multi-index), remove each from the pending map, and archive each as `PastFamilyInvitation { invitation, status: Rejected { at: env.block.time.seconds() } }` using the next free per-`(family, node)` counter; +- emit a `family_node_unbond_cleanup` event with `node_id` attribute. + +The auto-cleared invitations share the `Rejected` terminal state with invitations the node controller would have explicitly declined — `Revoked` is reserved for owner-side actions. + +**Operational note (non-normative)**: like the disband sweep, the per-node invitation sweep iterates every pending invitation addressed to `node_id` and archives each in a single transaction. Gas cost therefore scales linearly with the number of outstanding invitations the unbonding node holds. If a node has accumulated an unusually large number of pending invitations, the operator-initiated unbond transaction on the mixnet contract may fail because *this* callback exceeds the per-tx gas limit. The fix is operator-side: explicitly `RejectFamilyInvitation` the outstanding invitations (in batches if needed) before retrying the unbond. There is no contract-side chunking, and the mixnet contract has no path to bypass or partial-apply the callback. + +#### Scenario: Unbonding node with no family and no pending invitations is a no-op +- **WHEN** `OnNymNodeUnbond { node_id }` is invoked for a node with no membership and no pending invitations +- **THEN** the call succeeds, no storage is changed (apart from emitting the cleanup event), and no error is returned + +#### Scenario: Unbonding node in a family loses its membership +- **WHEN** `OnNymNodeUnbond { node_id }` is invoked for a node currently in family `F` +- **THEN** `family_members[node_id]` is removed, `F.members` is decremented, and a `PastFamilyMember` is archived with `removed_at = env.block.time.seconds()` + +#### Scenario: Unbonding node's pending invitations are archived as Rejected +- **WHEN** node `n` has pending invitations from families `F1` and `F2` and `OnNymNodeUnbond { node_id: n }` is invoked +- **THEN** both pending entries are removed and `past_family_invitations[((F1.id, n), …)]` and `past_family_invitations[((F2.id, n), …)]` each carry `status = Rejected { at: env.block.time.seconds() }` + +### Requirement: Expired pending invitations remain in storage until explicitly cleared + +The contract SHALL NOT run any background sweep of expired pending invitations. A `FamilyInvitation` whose `expires_at <= env.block.time.seconds()` SHALL remain in `pending_family_invitations` until either the family owner revokes it, the node controller rejects it, or the family is disbanded. Accept attempts against such entries MUST fail with `InvitationExpired`. Read queries SHALL surface a boolean `expired` flag (`now >= invitation.expires_at`) on each returned `PendingFamilyInvitationDetails` so callers can filter without doing the comparison themselves. + +#### Scenario: Expired invitation is still listed by pending queries +- **WHEN** family `F` has a pending invitation for node `n` whose `expires_at` is in the past and `GetPendingInvitationsForFamilyPaged { family_id: F.id }` is queried +- **THEN** the result includes the entry with `expired = true` + +#### Scenario: Expired invitation can be revoked or rejected but not accepted +- **WHEN** an expired invitation exists for `(F.id, n)` +- **THEN** `AcceptFamilyInvitation` fails with `InvitationExpired`, but `RevokeFamilyInvitation` (by `F`'s owner) and `RejectFamilyInvitation` (by `n`'s controller) both succeed and archive the invitation with the corresponding terminal status + +### Requirement: Per-`(family, node)` archive slots use sequential counters starting at 0 + +Both `past_family_invitations` and `past_family_members` SHALL be keyed by `((family_id, node_id), counter: u64)`. The contract SHALL maintain explicit per-`(family, node)` counter maps (`past_family_invitation_counter`, `past_family_member_counter`), starting at `0` for each new pair and incrementing by `1` on each archival write. Counters MUST be independent across distinct `(family, node)` pairs and across the two archive types. + +#### Scenario: First archive slot for a new pair is 0 +- **WHEN** a node and family appear in either archive for the first time +- **THEN** the entry is keyed with `counter = 0` + +#### Scenario: Distinct pairs have independent counters +- **WHEN** archive entries are written under keys `(F1, n)` and `(F2, n)` in any order +- **THEN** each pair's counter starts independently at `0` + +### Requirement: GetFamilyMembership returns the family id a node belongs to, or None + +`QueryMsg::GetFamilyMembership { node_id }` SHALL return `NodeFamilyMembershipResponse { node_id, family_id }` where `family_id` is `Some(NodeFamilyId)` iff `family_members[node_id]` is populated, and `None` otherwise. The query MUST NOT fail when `node_id` is unknown — it returns `family_id: None`. The query is the canonical way for route-selection consumers to check whether two node ids belong to the same family without scanning members. + +#### Scenario: Member node returns its family id +- **WHEN** node `n` is currently a member of family `F` and `GetFamilyMembership { node_id: n }` is queried +- **THEN** the response carries `family_id = Some(F.id)` + +#### Scenario: Non-member node returns None +- **WHEN** `GetFamilyMembership { node_id }` is queried for a node that has no membership record (never joined, or has since left/been kicked/unbonded) +- **THEN** the response carries `family_id = None` and `node_id` echoed back + +### Requirement: Single-family-by-id, by-name, and by-owner queries return an `Option` + +The contract SHALL expose three single-family lookups via `QueryMsg::GetFamilyById`, `GetFamilyByName`, and `GetFamilyByOwner`, each returning a response that echoes the queried key back to the caller for correlation and a `family: Option` field that is `None` when no match exists. `GetFamilyByName` MUST normalise the input via the same `normalise_family_name` function the create path uses before consulting the unique index. `GetFamilyByOwner` MUST bech32-validate the input. + +#### Scenario: GetFamilyByName is invariant under input formatting +- **WHEN** family `F` exists with `name = "MyFamily"` and `GetFamilyByName { name: "my family" }` is queried +- **THEN** the response carries `family = Some(F)` (the lookup hits the unique normalised-name index) + +#### Scenario: Missing match returns None +- **WHEN** any of the three single-family queries is called with a key that matches no family +- **THEN** the response carries `family = None` and echoes the queried key + +#### Scenario: GetFamilyByOwner rejects an invalid bech32 address +- **WHEN** `GetFamilyByOwner { owner }` is called with a non-bech32 string +- **THEN** the call returns an error sourced from `Addr::validate` + +### Requirement: Paginated queries use exclusive `start_after`, default limit 50, max limit 100 + +Every paginated query (`GetFamiliesPaged`, `GetFamilyMembersPaged`, `GetAllFamilyMembersPaged`, `GetPendingInvitationsForFamilyPaged`, `GetPendingInvitationsForNodePaged`, `GetAllPendingInvitationsPaged`, `GetPastInvitationsForFamilyPaged`, `GetPastInvitationsForNodePaged`, `GetAllPastInvitationsPaged`, `GetPastMembersForFamilyPaged`, `GetPastMembersForNodePaged`) SHALL accept `start_after: Option` (exclusive) and `limit: Option`. The default `limit` SHALL be `50` and SHALL be clamped to `100` as a hard cap. Results SHALL be in ascending cursor order. Each response SHALL include a `start_next_after: Option` derived from the last entry of the page, with `None` indicating the page is empty (the caller treats this as end-of-list). + +Per-family / per-node paginated queries SHALL NOT verify that the supplied `family_id` or `node_id` corresponds to an existing entity — an unknown id simply yields an empty page. + +#### Scenario: Limit is defaulted and clamped +- **WHEN** any paginated query is called with `limit = None` +- **THEN** at most 50 entries are returned +- **AND** when called with `limit = Some(10_000)` at most 100 entries are returned + +#### Scenario: Empty page signals end-of-list +- **WHEN** a paginated query has no more entries past the supplied `start_after` +- **THEN** the response carries an empty entry list and `start_next_after = None` + +#### Scenario: Unknown scope id yields an empty page rather than an error +- **WHEN** `GetFamilyMembersPaged { family_id: 999_999, .. }` is queried for a non-existent family id +- **THEN** the response carries an empty `members` list and `start_next_after = None` (no error is returned) + +### Requirement: Pending-invitation queries stamp each entry with its expiry flag + +Queries returning pending invitations (`GetPendingInvitation`, `GetPendingInvitationsForFamilyPaged`, `GetPendingInvitationsForNodePaged`, `GetAllPendingInvitationsPaged`) SHALL wrap each invitation in `PendingFamilyInvitationDetails { invitation, expired }` where `expired = env.block.time.seconds() >= invitation.expires_at`. Past-invitation and past-member queries do not carry this flag (they are terminal-state archives). + +#### Scenario: Future-dated invitation is marked not expired +- **WHEN** a pending invitation has `expires_at = env.block.time.seconds() + 60` and any pending-invitation query returns it +- **THEN** the returned `PendingFamilyInvitationDetails.expired` is `false` + +#### Scenario: Past-dated invitation is marked expired +- **WHEN** a pending invitation has `expires_at = env.block.time.seconds() - 1` +- **THEN** any pending-invitation query that returns it sets `expired = true` + +### Requirement: Storage-key constants are part of the public contract + +Every constant exported under `nym_node_families_contract_common::constants::storage_keys` SHALL be treated as part of the public contract surface. Off-chain indexers and migration tooling may depend on these exact byte strings. Changing the value of any existing constant — including renaming a namespace — SHALL be considered a breaking change for already-deployed contracts and SHALL be accompanied by a data migration via `queued_migrations`. Adding new constants for new storage maps is non-breaking. The current set covers the contract-level items (admin, config, mixnet contract address, family id counter), the primary maps (`families`, `node-family-members`, `invitations`, `past-invitations`, `past-family-member`), every secondary index (`__owner`, `__name`, `__family`, `__node`), and the per-`(family, node)` archive counters — refer to `constants.rs` for the authoritative list. + +#### Scenario: Storage key constants are reachable from the common crate +- **WHEN** an off-chain consumer imports `nym_node_families_contract_common::constants::storage_keys` +- **THEN** it observes the full set of storage-key constants the contract uses, without taking a dependency on the contract crate itself + +### Requirement: Emitted events form a stable public surface + +Every event name and attribute key exported under `nym_node_families_contract_common::constants::events` SHALL be treated as part of the public contract surface. Each successful **state-mutating user-facing execute path** (every variant of `ExecuteMsg` except `UpdateConfig`, which is an admin handler that returns `Response::default()` without an event) SHALL emit exactly one event whose name and attribute keys come from these constants. Renaming an event name constant, renaming an attribute-key constant, or changing the set of attributes a given event carries SHALL be treated as breaking changes. Adding new constants for new events / attributes is non-breaking. + +At the time of this spec the constant surface comprises (refer to `constants.rs` for the authoritative list): + +- `family_creation` — attributes: `family_name`, `owner_address`, `family_id`, `paid_fee` +- `family_disband` — attributes: `family_id`, `owner_address`, `refunded_fee` +- `family_invitation` — attributes: `family_id`, `node_id`, `expires_at` +- `family_invitation_revoked` — attributes: `family_id`, `node_id` +- `family_invitation_accepted` — attributes: `family_id`, `node_id` +- `family_invitation_rejected` — attributes: `family_id`, `node_id` +- `family_member_left` — attributes: `family_id`, `node_id` +- `family_member_kicked` — attributes: `family_id`, `node_id` +- `family_node_unbond_cleanup` — attributes: `node_id` + +**Note for indexer authors (non-normative)**: CosmWasm wraps user-emitted events in a `wasm-` prefix when they land in the tendermint event log. So `family_creation` appears as `wasm-family_creation` on the chain side, `family_invitation` as `wasm-family_invitation`, etc. The constants in `constants::events` are the *unprefixed* names — indexers querying the chain need to add the `wasm-` prefix themselves (or use the prefix-stripping helpers most Cosmos indexer SDKs already provide). + +#### Scenario: Each successful state-mutating execute path emits exactly its named event +- **WHEN** any of the execute paths listed above succeeds (i.e. every `ExecuteMsg` variant other than `UpdateConfig`) +- **THEN** the response carries exactly one event whose `ty` equals the corresponding constant from `constants::events` and whose attributes include each of the listed keys + +#### Scenario: UpdateConfig is the exception — no event is emitted +- **WHEN** the admin sends `ExecuteMsg::UpdateConfig` and the call succeeds +- **THEN** the response is `Response::default()` and carries no event (this is intentional — `UpdateConfig` is administrative metadata, not a tracked state transition) + From 6b0a904d101778d33e975fc5b8f9d1e3c9796a6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 22 May 2026 15:30:24 +0100 Subject: [PATCH 40/94] Chore/bugfixes (#6783) * added unit tests for MemoryEcachTicketbookManager * bugfix: propagate socks5 proxy errors instead of panicking * introduce guard against providing too short verification keyduring signature validation * add checked overflow checks for icmp packet construction * fix kcp loggin * forbid construction of illegal sphninx fragments * fix division by zero in packet statistics calculations --- .../credential-storage/src/backends/memory.rs | 340 +++++++++++++++++- common/nym-connection-monitor/src/error.rs | 3 + .../src/packet_helpers.rs | 136 ++++++- common/nym-kcp/src/session.rs | 29 +- .../src/scheme/mod.rs | 4 + common/nymsphinx/chunking/src/fragment.rs | 35 +- common/socks5-client-core/src/socks/client.rs | 13 +- .../proxy-helpers/src/proxy_runner/mod.rs | 23 +- .../src/clients/packet_statistics.rs | 5 + .../network-requester/src/socks5/tcp.rs | 13 +- 10 files changed, 563 insertions(+), 38 deletions(-) diff --git a/common/credential-storage/src/backends/memory.rs b/common/credential-storage/src/backends/memory.rs index 28b99e4196..189350f604 100644 --- a/common/credential-storage/src/backends/memory.rs +++ b/common/credential-storage/src/backends/memory.rs @@ -230,8 +230,8 @@ impl MemoryEcachTicketbookManager { expiration_date: t.ticketbook.expiration_date(), ticketbook_type: t.ticketbook.ticketbook_type().to_string(), epoch_id: t.ticketbook.epoch_id() as u32, - total_tickets: t.ticketbook.spent_tickets() as u32, - used_tickets: t.total_tickets, + total_tickets: t.total_tickets, + used_tickets: t.ticketbook.spent_tickets() as u32, }) .collect() } @@ -333,3 +333,339 @@ impl MemoryEcachTicketbookManager { guard.emergency_credentials.remove(typ); } } + +#[cfg(test)] +mod tests { + use super::*; + use nym_compact_ecash::tests::helpers::generate_expiration_date_signatures; + use nym_compact_ecash::{issue, ttp_keygen}; + use nym_credentials_interface::TicketType; + use nym_crypto::asymmetric::ed25519; + use nym_ecash_time::EcashTime; + use nym_test_utils::helpers::deterministic_rng; + + fn mock_issuance(deposit_id: u32) -> IssuanceTicketBook { + let identifier = "foomp"; + let mut rng = deterministic_rng(); + let key = ed25519::PrivateKey::new(&mut rng); + let typ = TicketType::V1MixnetEntry; + IssuanceTicketBook::new(deposit_id, identifier, key, typ) + } + + fn mock_ticketbook() -> anyhow::Result { + let signing_keys = ttp_keygen(1, 1)?.remove(0); + let issuance = mock_issuance(42); + let expiration_date = issuance.expiration_date(); + + let sig_req = issuance.prepare_for_signing(); + let _exp_date_sigs = generate_expiration_date_signatures( + sig_req.expiration_date.ecash_unix_timestamp(), + &[signing_keys.secret_key()], + &[signing_keys.verification_key()], + &signing_keys.verification_key(), + &[1], + )?; + let blind_sig = issue( + signing_keys.secret_key(), + sig_req.ecash_pub_key, + &sig_req.withdrawal_request, + expiration_date.ecash_unix_timestamp(), + issuance.ticketbook_type().encode(), + )?; + + let partial_wallet = + issuance.unblind_signature(&signing_keys.verification_key(), &sig_req, blind_sig, 1)?; + + let wallet = issuance.aggregate_signature_shares( + &signing_keys.verification_key(), + &[partial_wallet], + sig_req, + )?; + + Ok(issuance.into_issued_ticketbook(wallet, 1)) + } + + fn mock_verification_key() -> VerificationKeyAuth { + ttp_keygen(1, 1).unwrap().remove(0).verification_key() + } + + #[tokio::test] + async fn get_ticketbooks_info_empty() { + let manager = MemoryEcachTicketbookManager::new(); + let info = manager.get_ticketbooks_info().await; + assert!(info.is_empty()); + } + + #[tokio::test] + async fn get_ticketbooks_info_maps_inserted_ticketbook() -> anyhow::Result<()> { + let manager = MemoryEcachTicketbookManager::new(); + let ticketbook = mock_ticketbook()?; + let total_tickets = 100; + let used_tickets = 25; + + manager + .insert_new_ticketbook(&ticketbook, total_tickets, used_tickets) + .await; + + let info = manager.get_ticketbooks_info().await; + assert_eq!(info.len(), 1); + let entry = &info[0]; + assert_eq!(entry.id, 0); + assert_eq!(entry.expiration_date, ticketbook.expiration_date()); + assert_eq!( + entry.ticketbook_type, + ticketbook.ticketbook_type().to_string() + ); + assert_eq!(entry.epoch_id, ticketbook.epoch_id() as u32); + assert_eq!(entry.total_tickets, total_tickets); + assert_eq!(entry.used_tickets, used_tickets); + + Ok(()) + } + + #[tokio::test] + async fn contains_ticketbook_reflects_insertion() -> anyhow::Result<()> { + let manager = MemoryEcachTicketbookManager::new(); + let ticketbook = mock_ticketbook()?; + + assert!(!manager.contains_ticketbook(&ticketbook).await); + + manager.insert_new_ticketbook(&ticketbook, 100, 0).await; + + assert!(manager.contains_ticketbook(&ticketbook).await); + Ok(()) + } + + #[tokio::test] + async fn insert_new_ticketbook_assigns_incrementing_ids() -> anyhow::Result<()> { + let manager = MemoryEcachTicketbookManager::new(); + let ticketbook = mock_ticketbook()?; + + manager.insert_new_ticketbook(&ticketbook, 100, 0).await; + manager.insert_new_ticketbook(&ticketbook, 100, 0).await; + + let mut ids: Vec = manager + .get_ticketbooks_info() + .await + .into_iter() + .map(|i| i.id) + .collect(); + ids.sort(); + assert_eq!(ids, vec![0, 1]); + Ok(()) + } + + #[tokio::test] + async fn get_next_unspent_ticketbook_updates_spent_and_exhausts() -> anyhow::Result<()> { + let manager = MemoryEcachTicketbookManager::new(); + let ticketbook = mock_ticketbook()?; + let typ = ticketbook.ticketbook_type().to_string(); + + // total = 3, used = 0 — leaves 3 tickets available + manager.insert_new_ticketbook(&ticketbook, 3, 0).await; + + let first = manager + .get_next_unspent_ticketbook_and_update(typ.clone(), 2) + .await; + assert!(first.is_some()); + let first = first.unwrap(); + assert_eq!(first.total_tickets, 3); + // returned ticketbook reflects state *before* the update + assert_eq!(first.ticketbook.spent_tickets(), 0); + + // next withdrawal of 2 should be rejected (only 1 left) + let second = manager + .get_next_unspent_ticketbook_and_update(typ.clone(), 2) + .await; + assert!(second.is_none()); + + // but a withdrawal of 1 succeeds + let third = manager + .get_next_unspent_ticketbook_and_update(typ.clone(), 1) + .await; + assert!(third.is_some()); + + // and now nothing left + let fourth = manager.get_next_unspent_ticketbook_and_update(typ, 1).await; + assert!(fourth.is_none()); + + Ok(()) + } + + #[tokio::test] + async fn get_next_unspent_ticketbook_filters_by_type() -> anyhow::Result<()> { + let manager = MemoryEcachTicketbookManager::new(); + let ticketbook = mock_ticketbook()?; + + manager.insert_new_ticketbook(&ticketbook, 5, 0).await; + + let mismatched = manager + .get_next_unspent_ticketbook_and_update("nonexistent_type".to_string(), 1) + .await; + assert!(mismatched.is_none()); + Ok(()) + } + + #[tokio::test] + async fn revert_ticketbook_withdrawal_resets_spent_only_when_expected_matches( + ) -> anyhow::Result<()> { + let manager = MemoryEcachTicketbookManager::new(); + let ticketbook = mock_ticketbook()?; + let typ = ticketbook.ticketbook_type().to_string(); + + manager.insert_new_ticketbook(&ticketbook, 10, 0).await; + manager + .get_next_unspent_ticketbook_and_update(typ.clone(), 4) + .await + .expect("should withdraw"); + + // stale expected_current_total_spent — should be rejected + assert!(!manager.revert_ticketbook_withdrawal(0, 4, 99).await); + // spent_tickets unchanged + let used_after_failed = manager.get_ticketbooks_info().await[0].used_tickets; + assert_eq!(used_after_failed, 4); + + // matching expected — should succeed and restore + assert!(manager.revert_ticketbook_withdrawal(0, 4, 4).await); + let used_after_revert = manager.get_ticketbooks_info().await[0].used_tickets; + assert_eq!(used_after_revert, 0); + + // unknown ticketbook_id is rejected + assert!(!manager.revert_ticketbook_withdrawal(999, 1, 0).await); + + Ok(()) + } + + #[tokio::test] + async fn pending_ticketbook_round_trip() { + let manager = MemoryEcachTicketbookManager::new(); + let issuance = mock_issuance(7); + let deposit_id = issuance.deposit_id() as i64; + + assert!(manager.get_pending_ticketbooks().await.is_empty()); + + manager.insert_pending_ticketbook(&issuance).await; + + let pending = manager.get_pending_ticketbooks().await; + assert_eq!(pending.len(), 1); + assert_eq!(pending[0].pending_id, deposit_id); + assert_eq!( + pending[0].pending_ticketbook.deposit_id(), + issuance.deposit_id() + ); + + manager.remove_pending_ticketbook(deposit_id).await; + assert!(manager.get_pending_ticketbooks().await.is_empty()); + + // removing a non-existent id is a no-op + manager.remove_pending_ticketbook(999).await; + } + + #[tokio::test] + async fn emergency_credential_lifecycle() { + let manager = MemoryEcachTicketbookManager::new(); + + let cred_a = EmergencyCredentialContent { + typ: "type-a".to_string(), + content: vec![1, 2, 3], + expiration: None, + }; + let cred_b = EmergencyCredentialContent { + typ: "type-a".to_string(), + content: vec![4, 5, 6], + expiration: None, + }; + let cred_c = EmergencyCredentialContent { + typ: "type-b".to_string(), + content: vec![7, 8, 9], + expiration: None, + }; + + assert!(manager.get_emergency_credential("type-a").await.is_none()); + + manager.insert_emergency_credential(&cred_a).await; + manager.insert_emergency_credential(&cred_b).await; + manager.insert_emergency_credential(&cred_c).await; + + // get returns the first inserted entry for the type + let first = manager.get_emergency_credential("type-a").await.unwrap(); + assert_eq!(first.id, 0); + assert_eq!(first.data.content, vec![1, 2, 3]); + + // remove by id drops only that entry; type-a now exposes cred_b + manager.remove_emergency_credential(0).await; + let after_remove = manager.get_emergency_credential("type-a").await.unwrap(); + assert_eq!(after_remove.id, 1); + assert_eq!(after_remove.data.content, vec![4, 5, 6]); + + // remove by type clears the bucket entirely + manager.remove_emergency_credentials_of_type("type-a").await; + assert!(manager.get_emergency_credential("type-a").await.is_none()); + + // unrelated type is untouched + assert!(manager.get_emergency_credential("type-b").await.is_some()); + } + + #[tokio::test] + async fn master_verification_key_round_trip() { + let manager = MemoryEcachTicketbookManager::new(); + let key = mock_verification_key(); + let epoch = EpochVerificationKey { + epoch_id: 7, + key: key.clone(), + }; + + assert!(manager.get_master_verification_key(7).await.is_none()); + + manager.insert_master_verification_key(&epoch).await; + + assert_eq!(manager.get_master_verification_key(7).await, Some(key)); + assert!(manager.get_master_verification_key(8).await.is_none()); + } + + #[tokio::test] + async fn coin_index_signatures_round_trip() { + let manager = MemoryEcachTicketbookManager::new(); + let sigs = AggregatedCoinIndicesSignatures { + epoch_id: 3, + signatures: vec![], + }; + + assert!(manager.get_coin_index_signatures(3).await.is_none()); + + manager.insert_coin_index_signatures(&sigs).await; + + let retrieved = manager.get_coin_index_signatures(3).await; + assert!(retrieved.is_some()); + assert!(retrieved.unwrap().is_empty()); + assert!(manager.get_coin_index_signatures(4).await.is_none()); + } + + #[tokio::test] + async fn expiration_date_signatures_round_trip() { + let manager = MemoryEcachTicketbookManager::new(); + let date = nym_ecash_time::ecash_today().date(); + let sigs = AggregatedExpirationDateSignatures { + epoch_id: 5, + expiration_date: date, + signatures: vec![], + }; + + assert!(manager + .get_expiration_date_signatures(date, 5) + .await + .is_none()); + + manager.insert_expiration_date_signatures(&sigs).await; + + let retrieved = manager.get_expiration_date_signatures(date, 5).await; + assert!(retrieved.is_some()); + assert!(retrieved.unwrap().is_empty()); + + // wrong epoch / wrong date → miss + assert!(manager + .get_expiration_date_signatures(date, 6) + .await + .is_none()); + } +} diff --git a/common/nym-connection-monitor/src/error.rs b/common/nym-connection-monitor/src/error.rs index 463499a95d..2a4dd10d24 100644 --- a/common/nym-connection-monitor/src/error.rs +++ b/common/nym-connection-monitor/src/error.rs @@ -25,6 +25,9 @@ pub enum Error { #[error("failed to create ipv4 packet")] Ipv4PacketCreationFailure, + + #[error("packet length {length} exceeds the u16 IP header field")] + PacketLengthOverflow { length: usize }, } // Result type based on our error type diff --git a/common/nym-connection-monitor/src/packet_helpers.rs b/common/nym-connection-monitor/src/packet_helpers.rs index 8dfdc9e02a..cb23d5ce2b 100644 --- a/common/nym-connection-monitor/src/packet_helpers.rs +++ b/common/nym-connection-monitor/src/packet_helpers.rs @@ -79,9 +79,14 @@ pub fn wrap_icmp_in_ipv4( let mut ipv4_packet = MutableIpv4Packet::owned(ipv4_buffer).ok_or(Error::Ipv4PacketCreationFailure)?; + let total_length_u16 = + u16::try_from(total_length).map_err(|_| Error::PacketLengthOverflow { + length: total_length, + })?; + ipv4_packet.set_version(4); ipv4_packet.set_header_length(5); - ipv4_packet.set_total_length(total_length as u16); + ipv4_packet.set_total_length(total_length_u16); ipv4_packet.set_ttl(64); ipv4_packet.set_next_level_protocol(pnet_packet::ip::IpNextHeaderProtocols::Icmp); ipv4_packet.set_source(source); @@ -101,12 +106,18 @@ pub fn wrap_icmp_in_ipv6( source: Ipv6Addr, destination: Ipv6Addr, ) -> Result { - let ipv6_buffer = vec![0u8; 40 + icmp_echo_request.packet().len()]; + let payload_length = icmp_echo_request.packet().len(); + let payload_length_u16 = + u16::try_from(payload_length).map_err(|_| Error::PacketLengthOverflow { + length: payload_length, + })?; + + let ipv6_buffer = vec![0u8; 40 + payload_length]; let mut ipv6_packet = MutableIpv6Packet::owned(ipv6_buffer).ok_or(Error::Ipv4PacketCreationFailure)?; ipv6_packet.set_version(6); - ipv6_packet.set_payload_length(icmp_echo_request.packet().len() as u16); + ipv6_packet.set_payload_length(payload_length_u16); ipv6_packet.set_next_header(pnet_packet::ip::IpNextHeaderProtocols::Icmpv6); ipv6_packet.set_hop_limit(64); ipv6_packet.set_source(source); @@ -164,3 +175,122 @@ pub(crate) fn is_icmp_v6_echo_reply(packet: &Bytes) -> Option<(u16, Ipv6Addr, Ip } None } + +#[cfg(test)] +mod tests { + use super::*; + use pnet_packet::icmp::IcmpTypes; + use pnet_packet::icmpv6::Icmpv6Types; + use pnet_packet::ip::IpNextHeaderProtocols; + + const V4_SRC: Ipv4Addr = Ipv4Addr::new(10, 0, 0, 1); + const V4_DST: Ipv4Addr = Ipv4Addr::new(10, 0, 0, 2); + const V6_SRC: Ipv6Addr = Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 1); + const V6_DST: Ipv6Addr = Ipv6Addr::new(0xfe80, 0, 0, 0, 0, 0, 0, 2); + + #[test] + fn icmpv4_echo_request_sets_fields_and_valid_checksum() { + let echo = create_icmpv4_echo_request(42, 7).unwrap(); + assert_eq!(echo.get_sequence_number(), 42); + assert_eq!(echo.get_identifier(), 7); + assert_eq!(echo.get_icmp_type(), IcmpTypes::EchoRequest); + + // pnet's `checksum` skips the checksum word, so recomputing on the produced + // packet must equal the stored value. + let icmp = IcmpPacket::new(echo.packet()).unwrap(); + assert_eq!(echo.get_checksum(), pnet_packet::icmp::checksum(&icmp)); + } + + #[test] + fn icmpv6_echo_request_sets_fields_and_valid_checksum() { + let echo = create_icmpv6_echo_request(99, 12, &V6_SRC, &V6_DST).unwrap(); + assert_eq!(echo.get_sequence_number(), 99); + assert_eq!(echo.get_identifier(), 12); + assert_eq!(echo.get_icmpv6_type(), Icmpv6Types::EchoRequest); + + let icmpv6 = icmpv6::Icmpv6Packet::new(echo.packet()).unwrap(); + assert_eq!( + echo.get_checksum(), + pnet_packet::icmpv6::checksum(&icmpv6, &V6_SRC, &V6_DST) + ); + } + + #[test] + fn wrap_icmp_in_ipv4_sets_headers_and_payload() { + let echo = create_icmpv4_echo_request(1, 2).unwrap(); + let echo_bytes = echo.packet().to_vec(); + let packet = wrap_icmp_in_ipv4(echo, V4_SRC, V4_DST).unwrap(); + + assert_eq!(packet.get_version(), 4); + assert_eq!(packet.get_header_length(), 5); + assert_eq!(packet.get_total_length() as usize, 20 + echo_bytes.len()); + assert_eq!(packet.get_ttl(), 64); + assert_eq!( + packet.get_next_level_protocol(), + IpNextHeaderProtocols::Icmp + ); + assert_eq!(packet.get_source(), V4_SRC); + assert_eq!(packet.get_destination(), V4_DST); + assert_eq!(packet.payload(), echo_bytes.as_slice()); + } + + #[test] + fn wrap_icmp_in_ipv6_sets_headers_and_payload() { + let echo = create_icmpv6_echo_request(1, 2, &V6_SRC, &V6_DST).unwrap(); + let echo_bytes = echo.packet().to_vec(); + let packet = wrap_icmp_in_ipv6(echo, V6_SRC, V6_DST).unwrap(); + + assert_eq!(packet.get_version(), 6); + assert_eq!(packet.get_payload_length() as usize, echo_bytes.len()); + assert_eq!(packet.get_next_header(), IpNextHeaderProtocols::Icmpv6); + assert_eq!(packet.get_hop_limit(), 64); + assert_eq!(packet.get_source(), V6_SRC); + assert_eq!(packet.get_destination(), V6_DST); + assert_eq!(packet.payload(), echo_bytes.as_slice()); + } + + #[test] + fn compute_ipv4_checksum_is_zero_on_correctly_checksummed_packet() { + let echo = create_icmpv4_echo_request(1, 2).unwrap(); + let packet = wrap_icmp_in_ipv4(echo, V4_SRC, V4_DST).unwrap(); + // RFC 1071: summing every 16-bit word of a header that already contains its + // own checksum yields all-ones; the one's complement is therefore zero. + assert_eq!(compute_ipv4_checksum(&packet), 0); + } + + #[test] + fn is_icmp_echo_reply_extracts_identifier_and_addresses() { + // pnet's EchoReply/EchoRequest share the same byte layout (only the ICMP + // type field differs) and `is_icmp_echo_reply` does not check the type, + // so a wrapped echo *request* exercises the same parsing path. + let identifier = 1234; + let echo = create_icmpv4_echo_request(7, identifier).unwrap(); + let packet = wrap_icmp_in_ipv4(echo, V4_SRC, V4_DST).unwrap(); + let bytes = Bytes::copy_from_slice(packet.packet()); + + assert_eq!( + is_icmp_echo_reply(&bytes), + Some((identifier, V4_SRC, V4_DST)) + ); + } + + #[test] + fn is_icmp_v6_echo_reply_extracts_identifier_and_addresses() { + let identifier = 5678; + let echo = create_icmpv6_echo_request(7, identifier, &V6_SRC, &V6_DST).unwrap(); + let packet = wrap_icmp_in_ipv6(echo, V6_SRC, V6_DST).unwrap(); + let bytes = Bytes::copy_from_slice(packet.packet()); + + assert_eq!( + is_icmp_v6_echo_reply(&bytes), + Some((identifier, V6_SRC, V6_DST)) + ); + } + + #[test] + fn is_icmp_echo_reply_returns_none_for_undersized_bytes() { + let bytes = Bytes::from_static(&[0u8; 4]); + assert!(is_icmp_echo_reply(&bytes).is_none()); + assert!(is_icmp_v6_echo_reply(&bytes).is_none()); + } +} diff --git a/common/nym-kcp/src/session.rs b/common/nym-kcp/src/session.rs index e6924c5be7..35657b977a 100644 --- a/common/nym-kcp/src/session.rs +++ b/common/nym-kcp/src/session.rs @@ -6,7 +6,7 @@ use std::{ use ansi_term::Color::Yellow; use bytes::{Buf, BytesMut}; -use log::{debug, error, warn}; +use log::{debug, error, trace, warn}; use std::thread; use crate::MAX_RTO; @@ -499,21 +499,9 @@ impl KcpSession { self.snd_buf.len(), post_retain_sns ); - // Corrected format string arguments for the removed count log - debug!( - "[ConvID: {}, Thread: {:?}] parse_una(una={}): Removed {} segment(s) from snd_buf ({} -> {}). Remaining sns: {:?}", - self.conv, - thread::current().id(), - una, - removed_count, - original_len, - self.snd_buf.len(), - post_retain_sns - ); - if removed_count > 0 { - // Use trace level if no segments were removed but buffer wasn't empty - debug!( + if removed_count == 0 { + trace!( "[ConvID: {}, Thread: {:?}] parse_una(una={}): No segments removed from snd_buf (len={}). Remaining sns: {:?}", self.conv, thread::current().id(), @@ -521,6 +509,17 @@ impl KcpSession { original_len, self.snd_buf.iter().map(|s| s.sn).collect::>() ); + } else { + debug!( + "[ConvID: {}, Thread: {:?}] parse_una(una={}): Removed {} segment(s) from snd_buf ({} -> {}). Remaining sns: {:?}", + self.conv, + thread::current().id(), + una, + removed_count, + original_len, + self.snd_buf.len(), + post_retain_sns + ); } // Update the known acknowledged sequence number. diff --git a/common/nym_offline_compact_ecash/src/scheme/mod.rs b/common/nym_offline_compact_ecash/src/scheme/mod.rs index 8d830c1aaf..9fba6bfd7e 100644 --- a/common/nym_offline_compact_ecash/src/scheme/mod.rs +++ b/common/nym_offline_compact_ecash/src/scheme/mod.rs @@ -719,6 +719,10 @@ impl Payment { return Err(CompactEcashError::SpendSignaturesValidity); } + if verification_key.beta_g2.len() < 4 { + return Err(CompactEcashError::VerificationKeyTooShort); + } + let kappa_type = self.kappa + verification_key.beta_g2[3] * type_scalar(self.t_type); if !check_bilinear_pairing( &self.sig.h.to_affine(), diff --git a/common/nymsphinx/chunking/src/fragment.rs b/common/nymsphinx/chunking/src/fragment.rs index f823d9d3bc..3abae28166 100644 --- a/common/nymsphinx/chunking/src/fragment.rs +++ b/common/nymsphinx/chunking/src/fragment.rs @@ -386,8 +386,13 @@ impl FragmentHeader { { return Err(ChunkingError::MalformedHeaderError); } + // post-link requires total == current == u8::MAX so the constructor + // stays in lockstep with `try_from_bytes`'s deserialiser check. if let Some(nfid) = next_fragments_set_id - && (nfid <= 0 || current_fragment != total_fragments || nfid == id) + && (nfid <= 0 + || current_fragment != u8::MAX + || total_fragments != u8::MAX + || nfid == id) { return Err(ChunkingError::MalformedHeaderError); } @@ -1124,9 +1129,13 @@ mod fragment_header { } #[test] - fn can_only_be_post_linked_for_last_fragment() { - assert!(FragmentHeader::try_new(12345, 10, 10, None, Some(1234)).is_ok()); - assert!(FragmentHeader::try_new(12345, u8::MAX, u8::MAX, None, Some(1234),).is_ok()); + fn can_only_be_post_linked_for_last_fragment_of_full_set() { + // post-linking requires total == current == u8::MAX (a *full* set) + assert!(FragmentHeader::try_new(12345, u8::MAX, u8::MAX, None, Some(1234)).is_ok()); + assert!(FragmentHeader::try_new(12345, 10, 10, None, Some(1234)).is_err()); + assert!( + FragmentHeader::try_new(12345, u8::MAX - 1, u8::MAX - 1, None, Some(1234)).is_err() + ); assert!(FragmentHeader::try_new(12345, 10, 2, Some(1234), None).is_err()); } @@ -1192,5 +1201,23 @@ mod fragment_header { assert_eq!(fragmented_header, recovered_header); assert_eq!(LINKED_FRAGMENTED_HEADER_LEN, bytes_used); } + + #[test] + fn post_linked_with_non_max_total_is_rejected_by_constructor_and_deserialiser() { + // Regression: try_new used to accept post-linked headers where + // total/current != u8::MAX, but try_from_bytes rejects them, so + // such headers could never round-trip. + assert!(FragmentHeader::try_new(12345, 10, 10, None, Some(1234)).is_err()); + + // The deserialiser must still reject the corresponding bytes if + // some future change tries to emit them. Build the malformed bytes + // by hand from a valid post-linked header, then overwrite the + // total/current fragment counts. + let valid = FragmentHeader::try_new(12345, u8::MAX, u8::MAX, None, Some(1234)).unwrap(); + let mut malformed = valid.to_bytes(); + malformed[4] = 10; // total_fragments + malformed[5] = 10; // current_fragment + assert!(FragmentHeader::try_from_bytes(&malformed).is_err()); + } } } diff --git a/common/socks5-client-core/src/socks/client.rs b/common/socks5-client-core/src/socks/client.rs index ffdca82a70..db5bf475dd 100644 --- a/common/socks5-client-core/src/socks/client.rs +++ b/common/socks5-client-core/src/socks/client.rs @@ -411,7 +411,7 @@ impl SocksClient { let recipient = self.service_provider; let packet_type = self.packet_type; - let (stream, _) = ProxyRunner::new( + let proxy_result = ProxyRunner::new( stream, local_stream_remote, remote_proxy_target, @@ -449,8 +449,15 @@ impl SocksClient { ) } }) - .await - .into_inner(); + .await; + + let (stream, _) = match proxy_result { + Ok(runner) => runner.into_inner(), + Err(err) => { + log::error!("proxy runner for connection {connection_id} failed: {err}"); + return; + } + }; // recover stream from the proxy self.stream.finish_proxy(stream) } diff --git a/common/socks5/proxy-helpers/src/proxy_runner/mod.rs b/common/socks5/proxy-helpers/src/proxy_runner/mod.rs index 75a51e366a..a0ce6f25e4 100644 --- a/common/socks5/proxy-helpers/src/proxy_runner/mod.rs +++ b/common/socks5/proxy-helpers/src/proxy_runner/mod.rs @@ -8,6 +8,7 @@ use nym_task::connections::LaneQueueLengths; use nym_task::ShutdownTracker; use std::fmt::Debug; use std::{sync::Arc, time::Duration}; +use tokio::task::JoinError; use tokio::{net::TcpStream, sync::Notify}; mod inbound; @@ -92,7 +93,7 @@ where // The `adapter_fn` is used to transform whatever was read into appropriate // request/response as required by entity running particular side of the proxy. - pub async fn run(mut self, adapter_fn: F) -> Self + pub async fn run(mut self, adapter_fn: F) -> Result where F: Fn(SocketData) -> S + Send + Sync + 'static, { @@ -148,16 +149,22 @@ where let (inbound_result, outbound_result) = futures::future::join(handle_inbound, handle_outbound).await; - if inbound_result.is_err() || outbound_result.is_err() { - panic!("TODO: some future error?") - } - - let read_half = inbound_result.unwrap(); - let (write_half, mix_receiver) = outbound_result.unwrap(); + let read_half = inbound_result.inspect_err(|err| { + log::error!( + "inbound proxy task for connection {} failed: {err}", + self.connection_id + ) + })?; + let (write_half, mix_receiver) = outbound_result.inspect_err(|err| { + log::error!( + "outbound proxy task for connection {} failed: {err}", + self.connection_id + ) + })?; self.socket = Some(write_half.reunite(read_half).unwrap()); self.mix_receiver = Some(mix_receiver); - self + Ok(self) } pub fn into_inner(mut self) -> (TcpStream, ConnectionReceiver) { diff --git a/common/statistics/src/clients/packet_statistics.rs b/common/statistics/src/clients/packet_statistics.rs index 81de7e35f6..c9c853c2a0 100644 --- a/common/statistics/src/clients/packet_statistics.rs +++ b/common/statistics/src/clients/packet_statistics.rs @@ -490,6 +490,11 @@ impl PacketStatisticsControl { // Do basic averaging over the entire history, which just uses the first and last if let Some((start, start_stats)) = self.history.front() { let duration_secs = Instant::now().duration_since(start).as_secs_f64(); + // skip when only one entry was just pushed in this tick: dividing by 0 + // would yield inf/NaN rates that downstream consumers treat as real values. + if duration_secs == 0.0 { + return None; + } let delta = self.stats.clone() - start_stats.clone(); let rates = PacketRates::from(delta) / duration_secs; Some(rates) diff --git a/service-providers/network-requester/src/socks5/tcp.rs b/service-providers/network-requester/src/socks5/tcp.rs index 7eb593facd..4e9b0fea8b 100644 --- a/service-providers/network-requester/src/socks5/tcp.rs +++ b/service-providers/network-requester/src/socks5/tcp.rs @@ -53,7 +53,7 @@ impl Connection { let remote_source_address = "???".to_string(); // we don't know ip address of requester let connection_id = self.id; let return_address = self.return_address.clone(); - let (stream, _) = ProxyRunner::new( + let proxy_result = ProxyRunner::new( stream, self.address.clone(), remote_source_address, @@ -76,8 +76,15 @@ impl Connection { socket_data.header.local_socket_closed, ) }) - .await - .into_inner(); + .await; + + let (stream, _) = match proxy_result { + Ok(runner) => runner.into_inner(), + Err(err) => { + log::error!("proxy runner for connection {connection_id} failed: {err}"); + return; + } + }; self.conn = Some(stream); } } From 28b22f6b222bbe2207e57237726a9d69f628e20e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 22 May 2026 15:39:33 +0100 Subject: [PATCH 41/94] upgrade axum to 0.8.9 (and side deps) (#6808) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * upgrade axum to 0.8.9 (and side deps) Bumps axum 0.7.5 → 0.8.9, axum-extra 0.9.4 → 0.12.6, axum-client-ip 0.6.1 → 1.3.1, axum-test 16.2.0 → 20.0.0, utoipa-swagger-ui 8.1 → 9.0.2. * warn upon using fallback ip Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> * chore: replace use of deprecated try_next() * update console-subscriber to ensure single version of axum in the lock file * removed unused axum-test dev-dep --------- Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- Cargo.lock | 832 ++++++++---------- Cargo.toml | 12 +- .../src/middleware/client_ip.rs | 39 + .../http-api-common/src/middleware/logging.rs | 12 +- common/http-api-common/src/middleware/mod.rs | 1 + .../tests/src/mock_connect_info.rs | 2 - .../tests/src/v2/network.rs | 2 +- gateway/src/node/upgrade_mode/watcher.rs | 2 +- nym-api/src/ecash/api_routes/issued.rs | 6 +- nym-api/src/ecash/tests/mod.rs | 3 +- nym-api/src/node_families/handlers/mod.rs | 4 +- nym-api/src/node_families/tests.rs | 3 +- .../handlers/network_monitor.rs | 10 +- nym-api/src/nym_nodes/handlers/v1.rs | 15 +- nym-api/src/unstable_routes/v1/account/mod.rs | 2 +- .../nym-credential-proxy-requests/src/lib.rs | 4 +- nym-data-observatory/src/http/api/mod.rs | 10 + nym-network-monitor/src/http.rs | 42 +- .../nym-node-status-api/Cargo.toml | 1 - .../src/http/api/dvpn/country.rs | 2 +- .../src/http/api/dvpn/entry.rs | 2 +- .../src/http/api/dvpn/exit.rs | 2 +- .../src/http/api/gateways.rs | 2 +- .../src/http/api/metrics/sessions.rs | 4 +- .../src/http/api/nym_nodes.rs | 2 +- .../src/http/api/testruns.rs | 4 +- nym-node/src/node/http/mod.rs | 11 +- nym-node/src/node/http/router/landing_page.rs | 2 +- nym-node/src/node/http/router/mod.rs | 28 +- nym-node/src/node/http/state/mod.rs | 26 + nym-node/src/node/mod.rs | 19 +- nym-statistics-api/src/http/api/stats.rs | 22 +- nyx-chain-watcher/src/http/api/mod.rs | 10 + 33 files changed, 580 insertions(+), 558 deletions(-) create mode 100644 common/http-api-common/src/middleware/client_ip.rs diff --git a/Cargo.lock b/Cargo.lock index 6e2144a4fd..86c27fcced 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,7 +11,7 @@ dependencies = [ "macroific", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -24,15 +24,6 @@ dependencies = [ "psl-types", ] -[[package]] -name = "addr2line" -version = "0.24.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" -dependencies = [ - "gimli", -] - [[package]] name = "adler2" version = "2.0.1" @@ -165,12 +156,6 @@ dependencies = [ "url", ] -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -451,7 +436,7 @@ dependencies = [ "rustc-hash", "serde", "serde_derive", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -468,7 +453,7 @@ dependencies = [ "rustc-hash", "serde", "serde_derive", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -495,16 +480,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "assert-json-diff" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12" -dependencies = [ - "serde", - "serde_json", -] - [[package]] name = "async-compression" version = "0.4.27" @@ -551,7 +526,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -562,7 +537,7 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -608,12 +583,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "auto-future" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c1e7e457ea78e524f48639f551fd79703ac3f2237f5ecccdf4708f8a75ad373" - [[package]] name = "autocfg" version = "1.5.0" @@ -652,96 +621,49 @@ dependencies = [ [[package]] name = "axum" -version = "0.7.9" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" +checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" dependencies = [ - "async-trait", - "axum-core 0.4.5", + "axum-core", "axum-macros", "bytes", + "form_urlencoded", "futures-util", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", - "hyper 1.6.0", + "hyper 1.9.0", "hyper-util", "itoa", - "matchit 0.7.3", - "memchr", - "mime", - "percent-encoding", - "pin-project-lite", - "rustversion", - "serde", - "serde_json", - "serde_path_to_error", - "serde_urlencoded", - "sync_wrapper 1.0.2", - "tokio", - "tower 0.5.2", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "axum" -version = "0.8.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b52af3cb4058c895d37317bb27508dccc8e5f2d39454016b297bf4a400597b8" -dependencies = [ - "axum-core 0.5.6", - "bytes", - "futures-util", - "http 1.3.1", - "http-body 1.0.1", - "http-body-util", - "itoa", - "matchit 0.8.4", + "matchit", "memchr", "mime", "percent-encoding", "pin-project-lite", "serde_core", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", "sync_wrapper 1.0.2", - "tower 0.5.2", + "tokio", + "tower", "tower-layer", "tower-service", + "tracing", ] [[package]] name = "axum-client-ip" -version = "0.6.1" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eefda7e2b27e1bda4d6fa8a06b50803b8793769045918bc37ad062d48a6efac" +checksum = "a8ba1af5b620232acf37f2eb6d22151ea465491e0b4c25f552d1990f64ec5a67" dependencies = [ - "axum 0.7.9", - "forwarded-header-value", + "axum", + "client-ip", "serde", ] -[[package]] -name = "axum-core" -version = "0.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199" -dependencies = [ - "async-trait", - "bytes", - "futures-util", - "http 1.3.1", - "http-body 1.0.1", - "http-body-util", - "mime", - "pin-project-lite", - "rustversion", - "sync_wrapper 1.0.2", - "tower-layer", - "tower-service", - "tracing", -] - [[package]] name = "axum-core" version = "0.5.6" @@ -750,7 +672,7 @@ checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" dependencies = [ "bytes", "futures-core", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", "mime", @@ -758,59 +680,57 @@ dependencies = [ "sync_wrapper 1.0.2", "tower-layer", "tower-service", + "tracing", ] [[package]] name = "axum-extra" -version = "0.9.6" +version = "0.12.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c794b30c904f0a1c2fb7740f7df7f7972dfaa14ef6f57cb6178dc63e5dca2f04" +checksum = "be44683b41ccb9ab2d23a5230015c9c3c55be97a25e4428366de8873103f7970" dependencies = [ - "axum 0.7.9", - "axum-core 0.4.5", + "axum", + "axum-core", "bytes", - "fastrand", + "futures-core", "futures-util", "headers", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", "mime", - "multer", "pin-project-lite", - "serde", - "tower 0.5.2", "tower-layer", "tower-service", + "tracing", ] [[package]] name = "axum-macros" -version = "0.4.2" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57d123550fa8d071b7255cb0cc04dc302baa6c8c4a79f55701552684d8399bce" +checksum = "7aa268c23bfbbd2c4363b9cd302a4f504fb2a9dfe7e3451d66f35dd392e20aca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] name = "axum-test" -version = "16.4.1" +version = "20.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63e3a443d2608936a02a222da7b746eb412fede7225b3030b64fe9be99eab8dc" +checksum = "3a86bfe2ef15bee102ac34912f7f4542b0bb37dc464fa55461763999c4d625e7" dependencies = [ "anyhow", - "assert-json-diff", - "auto-future", - "axum 0.7.9", + "axum", "bytes", "bytesize", "cookie", - "http 1.3.1", + "expect-json", + "http 1.4.0", "http-body-util", - "hyper 1.6.0", + "hyper 1.9.0", "hyper-util", "mime", "pretty_assertions", @@ -819,27 +739,11 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", - "smallvec", "tokio", - "tower 0.5.2", + "tower", "url", ] -[[package]] -name = "backtrace" -version = "0.3.75" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" -dependencies = [ - "addr2line", - "cfg-if", - "libc", - "miniz_oxide", - "object", - "rustc-demangle", - "windows-targets 0.52.6", -] - [[package]] name = "base16ct" version = "0.2.0" @@ -1157,9 +1061,9 @@ dependencies = [ [[package]] name = "bytesize" -version = "1.3.3" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e93abca9e28e0a1b9877922aacb20576e05d4679ffa78c3d6dc22a26a216659" +checksum = "6bd91ee7b2422bcb158d90ef4d14f75ef67f340943fc4149891dcce8f8b972a3" [[package]] name = "camino" @@ -1368,17 +1272,16 @@ dependencies = [ [[package]] name = "chrono" -version = "0.4.41" +version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" dependencies = [ - "android-tzdata", "iana-time-zone", "js-sys", "num-traits", "serde", "wasm-bindgen", - "windows-link 0.1.3", + "windows-link 0.2.1", ] [[package]] @@ -1500,7 +1403,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -1520,6 +1423,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "client-ip" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39d2056bf065c8b4bce5a8898d40e175211ff4410add2a84d695845d3937c729" +dependencies = [ + "http 1.4.0", +] + [[package]] name = "cmake" version = "0.1.57" @@ -1624,22 +1536,23 @@ dependencies = [ [[package]] name = "console-api" -version = "0.8.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8030735ecb0d128428b64cd379809817e620a40e5001c54465b99ec5feec2857" +checksum = "e8599749b6667e2f0c910c1d0dff6901163ff698a52d5a39720f61b5be4b20d3" dependencies = [ "futures-core", - "prost 0.13.5", + "prost 0.14.3", "prost-types", - "tonic 0.12.3", + "tonic 0.14.4", + "tonic-prost", "tracing-core", ] [[package]] name = "console-subscriber" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6539aa9c6a4cd31f4b1c040f860a1eac9aa80e7df6b05d506a6e7179936d6a01" +checksum = "fb4915b7d8dd960457a1b6c380114c2944f728e7c65294ab247ae6b6f1f37592" dependencies = [ "console-api", "crossbeam-channel", @@ -1648,14 +1561,14 @@ dependencies = [ "hdrhistogram", "humantime", "hyper-util", - "prost 0.13.5", + "prost 0.14.3", "prost-types", "serde", "serde_json", "thread_local", "tokio", "tokio-stream", - "tonic 0.12.3", + "tonic 0.14.4", "tracing", "tracing-core", "tracing-subscriber", @@ -1840,7 +1753,7 @@ checksum = "a782b93fae93e57ca8ad3e9e994e784583f5933aeaaa5c80a545c4b437be2047" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -1864,7 +1777,7 @@ checksum = "e01c9214319017f6ebd8e299036e1f717fa9bb6724e758f7d6fb2477599d1a29" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -2134,7 +2047,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -2217,7 +2130,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -2369,7 +2282,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -2380,7 +2293,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -2484,7 +2397,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -2507,7 +2420,7 @@ dependencies = [ "macroific", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -2560,7 +2473,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -2581,7 +2494,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -2591,7 +2504,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" dependencies = [ "derive_builder_core", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -2620,7 +2533,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", "unicode-xid", ] @@ -2632,7 +2545,7 @@ checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", "unicode-xid", ] @@ -2711,7 +2624,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -2770,7 +2683,7 @@ version = "1.21.0" dependencies = [ "cosmwasm-std", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -2908,6 +2821,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "email_address" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e079f19b08ca6239f47f8ba8509c11cf3ea30095831f7fed61441475edd8c449" +dependencies = [ + "serde", +] + [[package]] name = "encode_unicode" version = "1.0.0" @@ -3014,6 +2936,35 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "expect-json" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "869f97f4abe8e78fc812a94ad6b721d72c4fb5532877c79610f2c238d7ccf6c4" +dependencies = [ + "chrono", + "email_address", + "expect-json-macros", + "num", + "regex", + "serde", + "serde_json", + "thiserror 2.0.18", + "typetag", + "uuid", +] + +[[package]] +name = "expect-json-macros" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e6fdf550180a6c29a28cb9aac262dc0064c25735641d2317f670075e9a469d9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "extension-storage" version = "1.4.1" @@ -3055,7 +3006,7 @@ dependencies = [ "macroific", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -3111,6 +3062,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a3d7db9596fecd151c5f638c0ee5d5bd487b6e0ea232e5dc96d5250f6f94b1d" dependencies = [ "crc32fast", + "libz-rs-sys", "miniz_oxide", ] @@ -3156,16 +3108,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "forwarded-header-value" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835f84f38484cc86f110a805655697908257fb9a7af005234060891557198e9" -dependencies = [ - "nonempty", - "thiserror 1.0.69", -] - [[package]] name = "fs-err" version = "2.11.0" @@ -3223,9 +3165,9 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" dependencies = [ "futures-core", "futures-sink", @@ -3233,9 +3175,9 @@ dependencies = [ [[package]] name = "futures-core" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" [[package]] name = "futures-executor" @@ -3261,38 +3203,38 @@ dependencies = [ [[package]] name = "futures-io" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" +checksum = "cecba35d7ad927e23624b22ad55235f2239cfa44fd10428eecbeba6d6a717718" [[package]] name = "futures-macro" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +checksum = "e835b70203e41293343137df5c0664546da5745f82ec9b84d40be8336958447b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] name = "futures-sink" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" +checksum = "c39754e157331b013978ec91992bde1ac089843443c49cbc7f46150b0fad0893" [[package]] name = "futures-task" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-util" -version = "0.3.31" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ "futures-channel", "futures-core", @@ -3302,7 +3244,6 @@ dependencies = [ "futures-task", "memchr", "pin-project-lite", - "pin-utils", "slab", ] @@ -3400,12 +3341,6 @@ dependencies = [ "polyval", ] -[[package]] -name = "gimli" -version = "0.31.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" - [[package]] name = "glob" version = "0.3.2" @@ -3422,7 +3357,7 @@ dependencies = [ "futures-core", "futures-sink", "gloo-utils 0.2.0", - "http 1.3.1", + "http 1.4.0", "js-sys", "pin-project", "serde", @@ -3523,7 +3458,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http 1.3.1", + "http 1.4.0", "indexmap 2.13.0", "slab", "tokio", @@ -3636,7 +3571,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -3674,7 +3609,7 @@ dependencies = [ "base64 0.22.1", "bytes", "headers-core", - "http 1.3.1", + "http 1.4.0", "httpdate", "mime", "sha1", @@ -3686,7 +3621,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" dependencies = [ - "http 1.3.1", + "http 1.4.0", ] [[package]] @@ -3759,7 +3694,7 @@ dependencies = [ "futures-util", "h2 0.4.11", "hickory-proto", - "http 1.3.1", + "http 1.4.0", "idna", "ipnet", "jni 0.22.4", @@ -3910,12 +3845,11 @@ dependencies = [ [[package]] name = "http" -version = "1.3.1" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" dependencies = [ "bytes", - "fnv", "itoa", ] @@ -3937,7 +3871,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.3.1", + "http 1.4.0", ] [[package]] @@ -3948,7 +3882,7 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "pin-project-lite", ] @@ -4039,15 +3973,16 @@ dependencies = [ [[package]] name = "hyper" -version = "1.6.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" +checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" dependencies = [ + "atomic-waker", "bytes", "futures-channel", - "futures-util", + "futures-core", "h2 0.4.11", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "httparse", "httpdate", @@ -4078,8 +4013,8 @@ version = "0.27.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ - "http 1.3.1", - "hyper 1.6.0", + "http 1.4.0", + "hyper 1.9.0", "hyper-util", "rustls 0.23.37", "rustls-native-certs 0.8.3", @@ -4096,7 +4031,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0" dependencies = [ - "hyper 1.6.0", + "hyper 1.9.0", "hyper-util", "pin-project-lite", "tokio", @@ -4105,23 +4040,22 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.15" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f66d5bd4c6f02bf0542fad85d626775bab9258cf795a4256dcaf3161114d1df" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ "base64 0.22.1", "bytes", "futures-channel", - "futures-core", "futures-util", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", - "hyper 1.6.0", + "hyper 1.9.0", "ipnet", "libc", "percent-encoding", "pin-project-lite", - "socket2 0.5.10", + "socket2 0.6.0", "tokio", "tower-service", "tracing", @@ -4311,7 +4245,7 @@ checksum = "0ab604ee7085efba6efc65e4ebca0e9533e3aff6cb501d7d77b211e3a781c6d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -4380,7 +4314,7 @@ dependencies = [ "macroific", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -4517,17 +4451,6 @@ dependencies = [ "rustversion", ] -[[package]] -name = "io-uring" -version = "0.7.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013" -dependencies = [ - "bitflags 2.9.1", - "cfg-if", - "libc", -] - [[package]] name = "ip_network" version = "0.4.1" @@ -4652,7 +4575,7 @@ checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -4698,7 +4621,7 @@ dependencies = [ "quote", "rustc_version 0.4.1", "simd_cesu8", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -4723,7 +4646,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" dependencies = [ "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -5015,7 +4938,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffd6aa2dcd5be681662001b81d493f1569c6d49a32361f470b0c955465cd0338" dependencies = [ "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -5184,6 +5107,15 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "libz-rs-sys" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c10501e7805cee23da17c7790e59df2870c0d4043ec6d03f67d31e2b53e77415" +dependencies = [ + "zlib-rs", +] + [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -5321,7 +5253,7 @@ dependencies = [ "proc-macro2", "quote", "sealed", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -5333,7 +5265,7 @@ dependencies = [ "proc-macro2", "quote", "sealed", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -5346,7 +5278,7 @@ dependencies = [ "macroific_core", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -5380,7 +5312,7 @@ checksum = "ac84fd3f360fcc43dc5f5d186f02a94192761a080e8bc58621ad4d12296a58cf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -5392,12 +5324,6 @@ dependencies = [ "regex-automata", ] -[[package]] -name = "matchit" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" - [[package]] name = "matchit" version = "0.8.4" @@ -5589,23 +5515,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "multer" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" -dependencies = [ - "bytes", - "encoding_rs", - "futures-util", - "http 1.3.1", - "httparse", - "memchr", - "mime", - "spin", - "version_check", -] - [[package]] name = "ndk-context" version = "0.1.1" @@ -5750,12 +5659,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "nonempty" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9e591e719385e6ebaeb5ce5d3887f7d5676fceca6411d1925ccc95745f3d6f7" - [[package]] name = "notify" version = "5.2.0" @@ -5792,6 +5695,20 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "num" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + [[package]] name = "num-bigint" version = "0.4.6" @@ -5818,6 +5735,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "num-complex" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" +dependencies = [ + "num-traits", +] + [[package]] name = "num-conv" version = "0.1.0" @@ -5844,6 +5770,17 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-rational" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83d14da390562dca69fc84082e73e548e1ad308d24accdedd2720017cb37824" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "num-traits" version = "0.2.19" @@ -5873,7 +5810,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -5891,7 +5828,7 @@ version = "1.1.79" dependencies = [ "anyhow", "async-trait", - "axum 0.7.9", + "axum", "axum-test", "bincode", "bip39", @@ -6266,7 +6203,7 @@ dependencies = [ "gloo-timers", "http-body-util", "humantime", - "hyper 1.6.0", + "hyper 1.9.0", "hyper-util", "nym-bandwidth-controller", "nym-client-core-config-types", @@ -6529,7 +6466,7 @@ name = "nym-credential-proxy" version = "0.3.2-rc" dependencies = [ "anyhow", - "axum 0.7.9", + "axum", "bip39", "bs58", "cfg-if", @@ -6578,7 +6515,7 @@ name = "nym-credential-proxy-lib" version = "1.21.0" dependencies = [ "anyhow", - "axum 0.7.9", + "axum", "bip39", "bs58", "futures", @@ -6790,7 +6727,7 @@ version = "1.0.1" dependencies = [ "anyhow", "async-trait", - "axum 0.7.9", + "axum", "blake3", "chrono", "clap", @@ -7183,7 +7120,7 @@ dependencies = [ "encoding_rs", "fastrand", "hickory-resolver", - "http 1.3.1", + "http 1.4.0", "inventory", "itertools 0.14.0", "mime", @@ -7215,7 +7152,7 @@ dependencies = [ "proc-macro2", "quote", "reqwest 0.13.1", - "syn 2.0.106", + "syn 2.0.117", "uuid", ] @@ -7223,7 +7160,7 @@ dependencies = [ name = "nym-http-api-common" version = "1.21.0" dependencies = [ - "axum 0.7.9", + "axum", "axum-client-ip", "bincode", "bytes", @@ -7235,7 +7172,7 @@ dependencies = [ "serde_yaml", "subtle 2.6.1", "time", - "tower 0.5.2", + "tower", "tracing", "utoipa", "zeroize", @@ -7609,7 +7546,7 @@ name = "nym-network-monitor" version = "1.0.2" dependencies = [ "anyhow", - "axum 0.7.9", + "axum", "clap", "dashmap", "futures", @@ -7697,7 +7634,7 @@ dependencies = [ "arc-swap", "arrayref", "async-trait", - "axum 0.7.9", + "axum", "bincode", "bip39", "blake2 0.8.1", @@ -7869,8 +7806,7 @@ version = "4.6.1" dependencies = [ "ammonia", "anyhow", - "axum 0.7.9", - "axum-test", + "axum", "bip39", "bs58", "celes", @@ -8159,7 +8095,7 @@ dependencies = [ "dotenvy", "futures", "hex", - "http 1.3.1", + "http 1.4.0", "httpcodec", "log", "nym-bandwidth-controller", @@ -8538,7 +8474,7 @@ name = "nym-statistics-api" version = "0.3.1" dependencies = [ "anyhow", - "axum 0.7.9", + "axum", "axum-client-ip", "axum-extra", "celes", @@ -8994,7 +8930,7 @@ version = "1.21.0" dependencies = [ "anyhow", "async-trait", - "axum 0.7.9", + "axum", "futures", "nym-credential-verification", "nym-credentials-interface", @@ -9012,7 +8948,7 @@ dependencies = [ name = "nym-wireguard-private-metadata-shared" version = "1.21.0" dependencies = [ - "axum 0.7.9", + "axum", "bincode", "nym-credentials-interface", "schemars 0.8.22", @@ -9026,7 +8962,7 @@ name = "nym-wireguard-private-metadata-tests" version = "1.21.0" dependencies = [ "async-trait", - "axum 0.7.9", + "axum", "futures", "nym-credential-verification", "nym-credentials-interface", @@ -9040,7 +8976,7 @@ dependencies = [ "nym-wireguard-private-metadata-shared", "time", "tokio", - "tower 0.5.2", + "tower", "tower-http", "utoipa", ] @@ -9094,7 +9030,7 @@ version = "0.1.15" dependencies = [ "anyhow", "async-trait", - "axum 0.7.9", + "axum", "chrono", "clap", "nym-bin-common", @@ -9196,15 +9132,6 @@ dependencies = [ "objc2-core-foundation", ] -[[package]] -name = "object" -version = "0.36.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" -dependencies = [ - "memchr", -] - [[package]] name = "once_cell" version = "1.21.3" @@ -9273,7 +9200,7 @@ checksum = "d7a6d09a73194e6b66df7c8f1b680f156d916a1a942abf2de06823dd02b7855d" dependencies = [ "async-trait", "bytes", - "http 1.3.1", + "http 1.4.0", "opentelemetry", "reqwest 0.12.22", ] @@ -9284,7 +9211,7 @@ version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2366db2dca4d2ad033cad11e6ee42844fd727007af5ad04a1730f4cb8163bf" dependencies = [ - "http 1.3.1", + "http 1.4.0", "opentelemetry", "opentelemetry-http", "opentelemetry-proto", @@ -9521,7 +9448,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -9584,7 +9511,7 @@ dependencies = [ "phf_shared", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -9613,7 +9540,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -9717,7 +9644,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -9866,7 +9793,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" dependencies = [ "proc-macro2", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -9906,14 +9833,14 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" dependencies = [ "unicode-ident", ] @@ -9972,7 +9899,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -9985,16 +9912,16 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] name = "prost-types" -version = "0.13.5" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16" +checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7" dependencies = [ - "prost 0.13.5", + "prost 0.14.3", ] [[package]] @@ -10106,9 +10033,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.40" +version = "1.0.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" dependencies = [ "proc-macro2", ] @@ -10268,7 +10195,7 @@ checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -10354,10 +10281,10 @@ dependencies = [ "futures-core", "futures-util", "h2 0.4.11", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", - "hyper 1.6.0", + "hyper 1.9.0", "hyper-rustls 0.27.7", "hyper-util", "js-sys", @@ -10375,7 +10302,7 @@ dependencies = [ "tokio", "tokio-rustls 0.26.2", "tokio-util", - "tower 0.5.2", + "tower", "tower-http", "tower-service", "url", @@ -10395,10 +10322,10 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", - "hyper 1.6.0", + "hyper 1.9.0", "hyper-rustls 0.27.7", "hyper-util", "js-sys", @@ -10416,7 +10343,7 @@ dependencies = [ "tokio", "tokio-rustls 0.26.2", "tokio-util", - "tower 0.5.2", + "tower", "tower-http", "tower-service", "url", @@ -10428,9 +10355,9 @@ dependencies = [ [[package]] name = "reserve-port" -version = "2.3.0" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21918d6644020c6f6ef1993242989bf6d4952d2e025617744f184c02df51c356" +checksum = "94070964579245eb2f76e62a7668fe87bd9969ed6c41256f3bf614e3323dd3cc" dependencies = [ "thiserror 2.0.18", ] @@ -10546,7 +10473,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.106", + "syn 2.0.117", "walkdir", ] @@ -10562,26 +10489,19 @@ dependencies = [ [[package]] name = "rust-multipart-rfc7578_2" -version = "0.6.1" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03b748410c0afdef2ebbe3685a6a862e2ee937127cdaae623336a459451c8d57" +checksum = "00bdaa068902270ca7fa8619775e1838e23a63620abac0947ce0f715819b8cec" dependencies = [ "bytes", "futures-core", "futures-util", - "http 0.2.12", + "http 1.4.0", "mime", - "mime_guess", - "rand 0.8.6", - "thiserror 1.0.69", + "rand 0.10.1", + "thiserror 2.0.18", ] -[[package]] -name = "rustc-demangle" -version = "0.1.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "989e6739f80c4ad5b13e0fd7fe89531180375b18520cc8c82080e4dc4035b84f" - [[package]] name = "rustc-hash" version = "2.1.1" @@ -10882,7 +10802,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals 0.29.1", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -10914,7 +10834,7 @@ checksum = "1783eabc414609e28a5ba76aee5ddd52199f7107a0b24c2e9746a1ecc34a683d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -10935,7 +10855,7 @@ checksum = "22f968c5ea23d555e670b449c1c5e7b2fc399fdaec1d304a17cd48e288abc107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -11121,7 +11041,7 @@ checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -11132,7 +11052,7 @@ checksum = "e578a843d40b4189a4d66bba51d7684f57da5bd7c304c64e14bd63efbef49509" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -11143,7 +11063,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -11206,7 +11126,7 @@ checksum = "aafbefbe175fa9bf03ca83ef89beecff7d2a95aaacd5732325b90ac8c3bd7b90" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -11236,7 +11156,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -11298,7 +11218,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -11533,7 +11453,7 @@ dependencies = [ "hickory-proto", "hickory-resolver", "http-body-util", - "hyper 1.6.0", + "hyper 1.9.0", "hyper-util", "nym-bin-common", "nym-ip-packet-requests", @@ -11740,7 +11660,7 @@ dependencies = [ "quote", "sqlx-core", "sqlx-macros-core", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -11763,7 +11683,7 @@ dependencies = [ "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn 2.0.106", + "syn 2.0.117", "tokio", "url", ] @@ -11968,7 +11888,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -11980,7 +11900,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -12039,9 +11959,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.106" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -12071,7 +11991,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -12146,7 +12066,7 @@ dependencies = [ "camino", "crossbeam-channel", "home", - "http 1.3.1", + "http 1.4.0", "libc", "memchr", "rayon", @@ -12326,7 +12246,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -12364,7 +12284,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -12375,7 +12295,7 @@ checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -12474,39 +12394,36 @@ checksum = "2d2e76690929402faae40aebdda620a2c0e25dd6d3b9afe48867dfd95991f4bd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] name = "tokio" -version = "1.47.1" +version = "1.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" +checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" dependencies = [ - "backtrace", "bytes", - "io-uring", "libc", "mio 1.0.4", "parking_lot", "pin-project-lite", "signal-hook-registry", - "slab", "socket2 0.6.0", "tokio-macros", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] name = "tokio-macros" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -12669,7 +12586,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37e04c1865c281139e5ccf633cb9f76ffdaabeebfe53b703984cf82878e2aabb" dependencies = [ "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -12783,36 +12700,6 @@ version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" -[[package]] -name = "tonic" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52" -dependencies = [ - "async-stream", - "async-trait", - "axum 0.7.9", - "base64 0.22.1", - "bytes", - "h2 0.4.11", - "http 1.3.1", - "http-body 1.0.1", - "http-body-util", - "hyper 1.6.0", - "hyper-timeout", - "hyper-util", - "percent-encoding", - "pin-project", - "prost 0.13.5", - "socket2 0.5.10", - "tokio", - "tokio-stream", - "tower 0.4.13", - "tower-layer", - "tower-service", - "tracing", -] - [[package]] name = "tonic" version = "0.13.1" @@ -12823,10 +12710,10 @@ dependencies = [ "base64 0.22.1", "bytes", "h2 0.4.11", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", - "hyper 1.6.0", + "hyper 1.9.0", "hyper-timeout", "hyper-util", "percent-encoding", @@ -12835,7 +12722,7 @@ dependencies = [ "socket2 0.5.10", "tokio", "tokio-stream", - "tower 0.5.2", + "tower", "tower-layer", "tower-service", "tracing", @@ -12848,14 +12735,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f32a6f80051a4111560201420c7885d0082ba9efe2ab61875c587bb6b18b9a0" dependencies = [ "async-trait", - "axum 0.8.8", + "axum", "base64 0.22.1", "bytes", "h2 0.4.11", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", - "hyper 1.6.0", + "hyper 1.9.0", "hyper-timeout", "hyper-util", "percent-encoding", @@ -12866,7 +12753,7 @@ dependencies = [ "tokio", "tokio-rustls 0.26.2", "tokio-stream", - "tower 0.5.2", + "tower", "tower-layer", "tower-service", "tracing", @@ -12885,29 +12772,9 @@ dependencies = [ [[package]] name = "tower" -version = "0.4.13" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" -dependencies = [ - "futures-core", - "futures-util", - "indexmap 1.9.3", - "pin-project", - "pin-project-lite", - "rand 0.8.6", - "slab", - "tokio", - "tokio-util", - "tower-layer", - "tower-service", - "tracing", -] - -[[package]] -name = "tower" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ "futures-core", "futures-util", @@ -12933,7 +12800,7 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http 1.3.1", + "http 1.4.0", "http-body 1.0.1", "http-body-util", "http-range-header", @@ -12945,7 +12812,7 @@ dependencies = [ "pin-project-lite", "tokio", "tokio-util", - "tower 0.5.2", + "tower", "tower-layer", "tower-service", "tracing", @@ -12983,7 +12850,7 @@ checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -13071,7 +12938,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" dependencies = [ "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -13142,7 +13009,7 @@ checksum = "38d90eea51bc7988ef9e674bf80a85ba6804739e535e9cab48e4bb34a8b652aa" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", "termcolor", ] @@ -13169,7 +13036,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals 0.28.0", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -13202,7 +13069,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 1.3.1", + "http 1.4.0", "httparse", "log", "rand 0.8.6", @@ -13237,7 +13104,7 @@ checksum = "016c26257f448222014296978b2c8456e2cad4de308c35bdb1e383acd569ef5b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -13252,6 +13119,30 @@ version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" +[[package]] +name = "typetag" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be2212c8a9b9bcfca32024de14998494cf9a5dfa59ea1b829de98bac374b86bf" +dependencies = [ + "erased-serde", + "inventory", + "once_cell", + "serde", + "typetag-impl", +] + +[[package]] +name = "typetag-impl" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27a7a9b72ba121f6f1f6c3632b85604cac41aedb5ddc70accbebb6cac83de846" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "ucd-trie" version = "0.1.7" @@ -13457,7 +13348,7 @@ dependencies = [ "indexmap 2.13.0", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -13470,7 +13361,7 @@ dependencies = [ "indexmap 2.13.0", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -13485,7 +13376,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.106", + "syn 2.0.117", "toml 0.5.11", "uniffi_meta 0.29.3", ] @@ -13502,7 +13393,7 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.106", + "syn 2.0.117", "toml 0.9.12+spec-1.1.0", "uniffi_meta 0.31.0", ] @@ -13661,17 +13552,17 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.106", + "syn 2.0.117", "uuid", ] [[package]] name = "utoipa-swagger-ui" -version = "8.1.0" +version = "9.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db4b5ac679cc6dfc5ea3f2823b0291c777750ffd5e13b21137e0f7ac0e8f9617" +checksum = "d047458f1b5b65237c2f6dc6db136945667f40a7668627b3490b9513a3d43a55" dependencies = [ - "axum 0.7.9", + "axum", "base64 0.22.1", "mime_guess", "regex", @@ -13700,7 +13591,7 @@ checksum = "268d76aaebb80eba79240b805972e52d7d410d4bcc52321b951318b0f440cd60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -13711,7 +13602,7 @@ checksum = "382673bda1d05c85b4550d32fd4192ccd4cffe9a908543a0795d1e7682b36246" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", "utoipauto-core", ] @@ -13942,7 +13833,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", "wasm-bindgen-shared", ] @@ -13977,7 +13868,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -14012,7 +13903,7 @@ checksum = "17d5042cc5fa009658f9a7333ef24291b1291a25b6382dd68862a7f3b969f69b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -14312,7 +14203,7 @@ checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -14323,7 +14214,7 @@ checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -14782,7 +14673,7 @@ dependencies = [ "heck 0.5.0", "indexmap 2.13.0", "prettyplease", - "syn 2.0.106", + "syn 2.0.117", "wasm-metadata", "wit-bindgen-core", "wit-component", @@ -14798,7 +14689,7 @@ dependencies = [ "prettyplease", "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", "wit-bindgen-core", "wit-bindgen-rust", ] @@ -14903,7 +14794,7 @@ checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", "synstructure", ] @@ -14924,7 +14815,7 @@ checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -14944,7 +14835,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", "synstructure", ] @@ -14965,7 +14856,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] @@ -14998,23 +14889,20 @@ checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.106", + "syn 2.0.117", ] [[package]] name = "zip" -version = "2.4.2" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fabe6324e908f85a1c52063ce7aa26b68dcb7eb6dbc83a2d148403c9bc3eba50" +checksum = "12598812502ed0105f607f941c386f43d441e00148fce9dec3ca5ffb0bde9308" dependencies = [ "arbitrary", "crc32fast", - "crossbeam-utils", - "displaydoc", "flate2", "indexmap 2.13.0", "memchr", - "thiserror 2.0.18", "zopfli", ] @@ -15037,6 +14925,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "zlib-rs" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40990edd51aae2c2b6907af74ffb635029d5788228222c4bb811e9351c0caad3" + [[package]] name = "zmij" version = "1.0.21" diff --git a/Cargo.toml b/Cargo.toml index 95d08ed7be..41bdb09cf1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -222,10 +222,10 @@ anyhow = "1.0.98" arc-swap = "1.7.1" argon2 = "0.5.0" async-trait = "0.1.88" -axum = "0.7.5" -axum-client-ip = "0.6.1" -axum-extra = "0.9.4" -axum-test = "16.2.0" +axum = "0.8.9" +axum-client-ip = "1.3.1" +axum-extra = "0.12.6" +axum-test = "20.0.0" base64 = "0.22.1" base85rs = "0.1.3" bincode = "1.3.3" @@ -250,7 +250,7 @@ clap_complete_fig = "4.5" colored = "2.2" comfy-table = "7.1.4" console = "0.16.0" -console-subscriber = "0.4.1" +console-subscriber = "0.5.0" console_error_panic_hook = "0.1" const-str = "0.5.6" const_format = "0.2.34" @@ -392,7 +392,7 @@ uniffi = "0.29.2" uniffi_build = "0.29.0" url = "2.5" utoipa = "5.2" -utoipa-swagger-ui = "8.1" +utoipa-swagger-ui = "9.0.2" utoipauto = "0.2" uuid = "1.19.0" vergen = { version = "=8.3.1", default-features = false } diff --git a/common/http-api-common/src/middleware/client_ip.rs b/common/http-api-common/src/middleware/client_ip.rs new file mode 100644 index 0000000000..a206ce9ec8 --- /dev/null +++ b/common/http-api-common/src/middleware/client_ip.rs @@ -0,0 +1,39 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use axum::extract::{ConnectInfo, FromRequestParts}; +use axum::http::request::Parts; +use axum_client_ip::RightmostXForwardedFor; +use std::convert::Infallible; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; +use tracing::warn; + +/// Best-effort client IP extractor. +/// +/// Prefers the rightmost entry of `X-Forwarded-For` (set by a trusted reverse +/// proxy); falls back to the TCP peer address when the header is absent, and to +/// the unspecified address when neither is available (tests). +#[derive(Debug, Clone, Copy)] +pub struct ClientIpAddr(pub IpAddr); + +impl FromRequestParts for ClientIpAddr +where + S: Send + Sync, +{ + type Rejection = Infallible; + + async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { + if let Ok(RightmostXForwardedFor(ip)) = + RightmostXForwardedFor::from_request_parts(parts, state).await + { + return Ok(ClientIpAddr(ip)); + } + if let Ok(ConnectInfo(addr)) = + ConnectInfo::::from_request_parts(parts, state).await + { + return Ok(ClientIpAddr(addr.ip())); + } + warn!("ClientIpAddr: no X-Forwarded-For or ConnectInfo found; using 0.0.0.0 fallback"); + Ok(ClientIpAddr(IpAddr::V4(Ipv4Addr::UNSPECIFIED))) + } +} diff --git a/common/http-api-common/src/middleware/logging.rs b/common/http-api-common/src/middleware/logging.rs index dfa03d5b50..f5ca3639d9 100644 --- a/common/http-api-common/src/middleware/logging.rs +++ b/common/http-api-common/src/middleware/logging.rs @@ -1,12 +1,12 @@ // Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::middleware::client_ip::ClientIpAddr; use axum::extract::Request; use axum::http::HeaderValue; use axum::http::header::{HOST, USER_AGENT}; use axum::middleware::Next; use axum::response::IntoResponse; -use axum_client_ip::InsecureClientIp; use colored::Colorize; use std::time::Instant; use tracing::{debug, info}; @@ -17,24 +17,24 @@ enum LogLevel { } pub async fn log_request_info( - insecure_client_ip: InsecureClientIp, + client_ip: ClientIpAddr, request: Request, next: Next, ) -> impl IntoResponse { - log_request(insecure_client_ip, request, next, LogLevel::Info).await + log_request(client_ip, request, next, LogLevel::Info).await } pub async fn log_request_debug( - insecure_client_ip: InsecureClientIp, + client_ip: ClientIpAddr, request: Request, next: Next, ) -> impl IntoResponse { - log_request(insecure_client_ip, request, next, LogLevel::Debug).await + log_request(client_ip, request, next, LogLevel::Debug).await } /// Simple logger for requests async fn log_request( - InsecureClientIp(addr): InsecureClientIp, + ClientIpAddr(addr): ClientIpAddr, request: Request, next: Next, level: LogLevel, diff --git a/common/http-api-common/src/middleware/mod.rs b/common/http-api-common/src/middleware/mod.rs index d81923bce5..13763b71dd 100644 --- a/common/http-api-common/src/middleware/mod.rs +++ b/common/http-api-common/src/middleware/mod.rs @@ -2,4 +2,5 @@ // SPDX-License-Identifier: Apache-2.0 pub mod bearer_auth; +pub mod client_ip; pub mod logging; diff --git a/common/wireguard-private-metadata/tests/src/mock_connect_info.rs b/common/wireguard-private-metadata/tests/src/mock_connect_info.rs index 95633d9e01..d9b05695ee 100644 --- a/common/wireguard-private-metadata/tests/src/mock_connect_info.rs +++ b/common/wireguard-private-metadata/tests/src/mock_connect_info.rs @@ -1,7 +1,6 @@ // Copyright 2025 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use async_trait::async_trait; use axum::extract::FromRequestParts; use axum::http::Request; use axum::http::request::Parts; @@ -56,7 +55,6 @@ impl DummyConnectInfo { } } -#[async_trait] impl FromRequestParts for DummyConnectInfo where S: Send + Sync, diff --git a/common/wireguard-private-metadata/tests/src/v2/network.rs b/common/wireguard-private-metadata/tests/src/v2/network.rs index fd2520e8e5..3d289ae97e 100644 --- a/common/wireguard-private-metadata/tests/src/v2/network.rs +++ b/common/wireguard-private-metadata/tests/src/v2/network.rs @@ -57,7 +57,7 @@ pub(crate) mod test { async fn handle_check_request(&mut self, polled_request: CheckRequest) { let mut requests = vec![polled_request]; - while let Ok(Some(queued_up)) = self.check_request_receiver.try_next() { + while let Ok(queued_up) = self.check_request_receiver.try_recv() { requests.push(queued_up); } diff --git a/gateway/src/node/upgrade_mode/watcher.rs b/gateway/src/node/upgrade_mode/watcher.rs index 509e89c5f5..34bab4346e 100644 --- a/gateway/src/node/upgrade_mode/watcher.rs +++ b/gateway/src/node/upgrade_mode/watcher.rs @@ -121,7 +121,7 @@ impl UpgradeModeWatcher { async fn handle_check_request(&mut self, polled_request: CheckRequest) { let mut requests = vec![polled_request]; - while let Ok(Some(queued_up)) = self.check_request_receiver.try_next() { + while let Ok(queued_up) = self.check_request_receiver.try_recv() { requests.push(queued_up); } diff --git a/nym-api/src/ecash/api_routes/issued.rs b/nym-api/src/ecash/api_routes/issued.rs index 914b087b97..34c0db5aa5 100644 --- a/nym-api/src/ecash/api_routes/issued.rs +++ b/nym-api/src/ecash/api_routes/issued.rs @@ -32,15 +32,15 @@ pub(crate) fn issued_routes() -> Router { axum::routing::get(issued_ticketbooks_count), ) .route( - "/issued-ticketbooks-for-count/:expiration_date", + "/issued-ticketbooks-for-count/{expiration_date}", axum::routing::get(issued_ticketbooks_for_count), ) .route( - "/issued-ticketbooks-on-count/:issuance_date", + "/issued-ticketbooks-on-count/{issuance_date}", axum::routing::get(issued_ticketbooks_on_count), ) .route( - "/issued-ticketbooks-for/:expiration_date", + "/issued-ticketbooks-for/{expiration_date}", axum::routing::get(issued_ticketbooks_for), ) .route( diff --git a/nym-api/src/ecash/tests/mod.rs b/nym-api/src/ecash/tests/mod.rs index 20781ccbaf..78394fbd75 100644 --- a/nym-api/src/ecash/tests/mod.rs +++ b/nym-api/src/ecash/tests/mod.rs @@ -1369,8 +1369,7 @@ impl TestFixture { Router::new() .nest("/v1/ecash", ecash_routes()) .with_state(app_state), - ) - .unwrap(), + ), storage, chain_state: bundle.chain_state, epoch: bundle.epoch, diff --git a/nym-api/src/node_families/handlers/mod.rs b/nym-api/src/node_families/handlers/mod.rs index f0a587c783..bda7dc06d6 100644 --- a/nym-api/src/node_families/handlers/mod.rs +++ b/nym-api/src/node_families/handlers/mod.rs @@ -23,8 +23,8 @@ const MAX_FAMILIES_PAGE_SIZE: u32 = 200; pub(crate) fn routes() -> Router { Router::new() .route("/", get(get_families)) - .route("/:family_id", get(get_family_by_id)) - .route("/by-node/:node_id", get(get_family_for_node)) + .route("/{family_id}", get(get_family_by_id)) + .route("/by-node/{node_id}", get(get_family_for_node)) } #[utoipa::path( diff --git a/nym-api/src/node_families/tests.rs b/nym-api/src/node_families/tests.rs index 9db626acc8..e6f5014218 100644 --- a/nym-api/src/node_families/tests.rs +++ b/nym-api/src/node_families/tests.rs @@ -52,8 +52,7 @@ impl NodeFamiliesTestFixture { Router::new() .nest("/v1/node-families", handlers::routes()) .with_state(app_state), - ) - .unwrap(); + ); NodeFamiliesTestFixture { axum: server, diff --git a/nym-api/src/node_status_api/handlers/network_monitor.rs b/nym-api/src/node_status_api/handlers/network_monitor.rs index 5a29f09b30..14942d520e 100644 --- a/nym-api/src/node_status_api/handlers/network_monitor.rs +++ b/nym-api/src/node_status_api/handlers/network_monitor.rs @@ -25,7 +25,7 @@ use utoipa::IntoParams; pub(super) fn network_monitor_routes() -> Router { Router::new() .nest( - "/gateway/:identity", + "/gateway/{identity}", Router::new() .route("/history", axum::routing::get(gateway_uptime_history)) .route( @@ -34,7 +34,7 @@ pub(super) fn network_monitor_routes() -> Router { ), ) .nest( - "/mixnode/:mix_id", + "/mixnode/{mix_id}", Router::new() .route("/history", axum::routing::get(mixnode_uptime_history)) .route( @@ -45,14 +45,14 @@ pub(super) fn network_monitor_routes() -> Router { .nest( "/mixnodes", Router::new().route( - "/unstable/:mix_id/test-results", + "/unstable/{mix_id}/test-results", axum::routing::get(unstable::mixnode_test_results), ), ) .nest( "/gateways", Router::new().route( - "/unstable/:gateway_identity/test-results", + "/unstable/{gateway_identity}/test-results", axum::routing::get(unstable::gateway_test_results), ), ) @@ -60,7 +60,7 @@ pub(super) fn network_monitor_routes() -> Router { "/network-monitor/unstable", Router::new() .route( - "/run/:monitor_run_id/details", + "/run/{monitor_run_id}/details", axum::routing::get(monitor_run_report), ) .route( diff --git a/nym-api/src/nym_nodes/handlers/v1.rs b/nym-api/src/nym_nodes/handlers/v1.rs index ce004731ed..1b0968084f 100644 --- a/nym-api/src/nym_nodes/handlers/v1.rs +++ b/nym-api/src/nym_nodes/handlers/v1.rs @@ -30,19 +30,22 @@ pub(crate) fn routes() -> Router { .route("/noise", get(nodes_noise)) .route("/bonded", get(get_bonded_nodes)) .route("/described", get(get_described_nodes)) - .route("/annotation/:node_id", get(get_node_annotation)) - .route("/performance/:node_id", get(get_current_node_performance)) - .route("/stake-saturation/:node_id", get(get_node_stake_saturation)) + .route("/annotation/{node_id}", get(get_node_annotation)) + .route("/performance/{node_id}", get(get_current_node_performance)) .route( - "/historical-performance/:node_id", + "/stake-saturation/{node_id}", + get(get_node_stake_saturation), + ) + .route( + "/historical-performance/{node_id}", get(get_historical_performance), ) .route( - "/performance-history/:node_id", + "/performance-history/{node_id}", get(get_node_performance_history), ) // to make it compatible with all the explorers that were used to using 0-100 values - .route("/uptime-history/:node_id", get(get_node_uptime_history)) + .route("/uptime-history/{node_id}", get(get_node_uptime_history)) .route("/rewarded-set", get(rewarded_set)) .layer(CompressionLayer::new()) } diff --git a/nym-api/src/unstable_routes/v1/account/mod.rs b/nym-api/src/unstable_routes/v1/account/mod.rs index 8b7b83d11c..7186f50105 100644 --- a/nym-api/src/unstable_routes/v1/account/mod.rs +++ b/nym-api/src/unstable_routes/v1/account/mod.rs @@ -22,7 +22,7 @@ pub(crate) mod data_collector; pub(crate) mod models; pub(crate) fn routes() -> Router { - Router::new().route("/:address", get(address)) + Router::new().route("/{address}", get(address)) } #[derive(Clone, Debug, Serialize, Deserialize, ToSchema, utoipa::IntoParams)] diff --git a/nym-credential-proxy/nym-credential-proxy-requests/src/lib.rs b/nym-credential-proxy/nym-credential-proxy-requests/src/lib.rs index 54ba8126b5..9a0e5ea7c4 100644 --- a/nym-credential-proxy/nym-credential-proxy-requests/src/lib.rs +++ b/nym-credential-proxy/nym-credential-proxy-requests/src/lib.rs @@ -62,9 +62,9 @@ pub mod routes { pub mod shares { use super::*; - pub const SHARE_BY_ID: &str = "/:share_id"; + pub const SHARE_BY_ID: &str = "/{share_id}"; pub const SHARE_BY_DEVICE_AND_CREDENTIAL_ID: &str = - "/device/:device_id/credential/:credential_id"; + "/device/{device_id}/credential/{credential_id}"; absolute_route!(share_by_id_absolute, shares_absolute(), SHARE_BY_ID); absolute_route!( diff --git a/nym-data-observatory/src/http/api/mod.rs b/nym-data-observatory/src/http/api/mod.rs index ee0fbe8563..1cd024c4f8 100644 --- a/nym-data-observatory/src/http/api/mod.rs +++ b/nym-data-observatory/src/http/api/mod.rs @@ -77,3 +77,13 @@ fn setup_cors() -> CorsLayer { .allow_headers(tower_http::cors::Any) .allow_credentials(false) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn router_constructs_without_panic() { + let _ = RouterBuilder::with_default_routes().finalize_routes(); + } +} diff --git a/nym-network-monitor/src/http.rs b/nym-network-monitor/src/http.rs index b2eedd53fc..57fc0bcfa9 100644 --- a/nym-network-monitor/src/http.rs +++ b/nym-network-monitor/src/http.rs @@ -58,6 +58,21 @@ impl AppState { } } +fn build_router(state: AppState) -> Router { + Router::new() + .route("/v1/send", post(send_handler).with_state(state)) + .merge(SwaggerUi::new("/v1/ui").url("/v1/docs/openapi.json", ApiDoc::openapi())) + .route("/v1/accounting", get(accounting_handler)) + .route("/v1/sent", get(sent_handler)) + .route("/v1/dot/{mix_id}", get(mix_dot_handler)) + .route("/v1/dot", get(graph_handler)) + .route("/v1/mermaid", get(mermaid_handler)) + .route("/v1/stats", get(stats_handler)) + .route("/v1/node_stats/{mix_id}", get(node_stats_handler)) + .route("/v1/node_stats", get(all_nodes_stats_handler)) + .route("/v1/received", get(recv_handler)) +} + impl HttpServer { pub fn new(listener: SocketAddr, cancel: CancellationToken) -> Self { HttpServer { listener, cancel } @@ -66,18 +81,7 @@ impl HttpServer { pub async fn run(self, clients: ClientsWrapper) -> anyhow::Result<()> { let n_clients = clients.read().await.len(); let state = AppState { clients }; - let app = Router::new() - .route("/v1/send", post(send_handler).with_state(state)) - .merge(SwaggerUi::new("/v1/ui").url("/v1/docs/openapi.json", ApiDoc::openapi())) - .route("/v1/accounting", get(accounting_handler)) - .route("/v1/sent", get(sent_handler)) - .route("/v1/dot/:mix_id", get(mix_dot_handler)) - .route("/v1/dot", get(graph_handler)) - .route("/v1/mermaid", get(mermaid_handler)) - .route("/v1/stats", get(stats_handler)) - .route("/v1/node_stats/:mix_id", get(node_stats_handler)) - .route("/v1/node_stats", get(all_nodes_stats_handler)) - .route("/v1/received", get(recv_handler)); + let app = build_router(state); let listener = tokio::net::TcpListener::bind(self.listener).await?; let server_future = @@ -98,3 +102,17 @@ impl HttpServer { Ok(()) } } + +#[cfg(test)] +mod tests { + use super::*; + use std::collections::VecDeque; + use std::sync::Arc; + use tokio::sync::RwLock; + + #[test] + fn router_constructs_without_panic() { + let clients: ClientsWrapper = Arc::new(RwLock::new(VecDeque::new())); + let _ = build_router(AppState { clients }); + } +} diff --git a/nym-node-status-api/nym-node-status-api/Cargo.toml b/nym-node-status-api/nym-node-status-api/Cargo.toml index 94fd77efe1..4cc150bc6f 100644 --- a/nym-node-status-api/nym-node-status-api/Cargo.toml +++ b/nym-node-status-api/nym-node-status-api/Cargo.toml @@ -84,6 +84,5 @@ sqlx = { workspace = true, features = [ ] } [dev-dependencies] -axum-test = { workspace = true } time = { workspace = true, features = ["macros"] } nym-gateway-probe = { workspace = true, features = ["test-utils"] } diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/dvpn/country.rs b/nym-node-status-api/nym-node-status-api/src/http/api/dvpn/country.rs index 3279a08447..0a4db47549 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/dvpn/country.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/dvpn/country.rs @@ -13,7 +13,7 @@ use crate::http::{error::HttpResult, state::AppState}; pub(crate) fn routes() -> Router { Router::new() .route( - "/country/:two_letter_country_code", + "/country/{two_letter_country_code}", axum::routing::get(get_gateways_by_country), ) .route("/countries", axum::routing::get(get_gateway_countries)) diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/dvpn/entry.rs b/nym-node-status-api/nym-node-status-api/src/http/api/dvpn/entry.rs index 03bfa3f0b6..d1ede3b909 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/dvpn/entry.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/dvpn/entry.rs @@ -18,7 +18,7 @@ pub(crate) fn routes() -> Router { axum::routing::get(get_entry_gateway_countries), ) .route( - "/entry/country/:two_letter_country_code", + "/entry/country/{two_letter_country_code}", axum::routing::get(get_entry_gateways_by_country), ) } diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/dvpn/exit.rs b/nym-node-status-api/nym-node-status-api/src/http/api/dvpn/exit.rs index e745df9068..7f3341e92c 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/dvpn/exit.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/dvpn/exit.rs @@ -18,7 +18,7 @@ pub(crate) fn routes() -> Router { axum::routing::get(get_entry_gateway_countries), ) .route( - "/exit/country/:two_letter_country_code", + "/exit/country/{two_letter_country_code}", axum::routing::get(get_exit_gateways_by_country), ) } diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/gateways.rs b/nym-node-status-api/nym-node-status-api/src/http/api/gateways.rs index ac24be2351..0270de9abf 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/gateways.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/gateways.rs @@ -16,7 +16,7 @@ pub(crate) fn routes() -> Router { Router::new() .route("/", axum::routing::get(gateways)) .route("/skinny", axum::routing::get(gateways_skinny)) - .route("/:identity_key", axum::routing::get(get_gateway)) + .route("/{identity_key}", axum::routing::get(get_gateway)) } #[utoipa::path( diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/metrics/sessions.rs b/nym-node-status-api/nym-node-status-api/src/http/api/metrics/sessions.rs index f65389f8d8..707a12393b 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/metrics/sessions.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/metrics/sessions.rs @@ -14,8 +14,8 @@ use crate::http::{ pub(crate) fn routes() -> Router { Router::new().route("/", axum::routing::get(get_all_sessions)) - // .route("/:node_id", axum::routing::get(get_node_sessions)) - // .route("/:day", axum::routing::get(get_daily_sessions)) + // .route("/{node_id}", axum::routing::get(get_node_sessions)) + // .route("/{day}", axum::routing::get(get_daily_sessions)) } #[derive(Debug, Clone, serde::Serialize, serde::Deserialize, utoipa::IntoParams)] diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/nym_nodes.rs b/nym-node-status-api/nym-node-status-api/src/http/api/nym_nodes.rs index ab8e4539c0..e125fa8bac 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/nym_nodes.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/nym_nodes.rs @@ -18,7 +18,7 @@ pub(crate) fn routes() -> Router { Router::new() .route("/", axum::routing::get(nym_nodes)) .route( - "/:node_id/delegations", + "/{node_id}/delegations", axum::routing::get(node_delegations), ) } diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs b/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs index d26db1d7df..a449be4ed0 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs @@ -26,8 +26,8 @@ use tracing::error; pub(crate) fn routes() -> Router { Router::new() .route("/", axum::routing::get(request_testrun)) - .route("/:testrun_id", axum::routing::post(submit_testrun)) - .route("/:testrun_id/v2", axum::routing::post(submit_testrun_v2)) + .route("/{testrun_id}", axum::routing::post(submit_testrun)) + .route("/{testrun_id}/v2", axum::routing::post(submit_testrun_v2)) .layer(DefaultBodyLimit::max(1024 * 1024 * 5)) } diff --git a/nym-node/src/node/http/mod.rs b/nym-node/src/node/http/mod.rs index 17943a71cd..ce3f153b2c 100644 --- a/nym-node/src/node/http/mod.rs +++ b/nym-node/src/node/http/mod.rs @@ -5,8 +5,10 @@ use axum::Router; use axum::extract::ConnectInfo; use axum::extract::connect_info::IntoMakeServiceWithConnectInfo; use axum::middleware::AddExtension; -use axum::serve::Serve; +use axum::serve::WithGracefulShutdown; use std::net::SocketAddr; +use tokio::net::TcpListener; +use tokio_util::sync::WaitForCancellationFutureOwned; pub use router::{HttpServerConfig, NymNodeRouter, api}; @@ -15,6 +17,7 @@ pub mod helpers; pub mod router; pub mod state; -type InnerService = IntoMakeServiceWithConnectInfo; -type ConnectInfoExt = AddExtension>; -pub type NymNodeHttpServer = Serve; +type MakeService = IntoMakeServiceWithConnectInfo; +type InnerService = AddExtension>; +pub type NymNodeHttpServer = + WithGracefulShutdown; diff --git a/nym-node/src/node/http/router/landing_page.rs b/nym-node/src/node/http/router/landing_page.rs index ed3536e371..65d3427dd0 100644 --- a/nym-node/src/node/http/router/landing_page.rs +++ b/nym-node/src/node/http/router/landing_page.rs @@ -14,7 +14,7 @@ pub struct Config { pub(super) fn routes(config: Config) -> Router { if let Some(assets) = config.assets_path { - Router::new().nest_service("/", ServeDir::new(assets)) + Router::new().fallback_service(ServeDir::new(assets)) } else { Router::new().route("/", get(default)) } diff --git a/nym-node/src/node/http/router/mod.rs b/nym-node/src/node/http/router/mod.rs index 4c3618c76f..dfb0c84b08 100644 --- a/nym-node/src/node/http/router/mod.rs +++ b/nym-node/src/node/http/router/mod.rs @@ -22,6 +22,7 @@ use nym_node_requests::routes; use std::net::SocketAddr; use std::path::Path; use std::sync::Arc; +use tokio_util::sync::WaitForCancellationFutureOwned; use zeroize::Zeroizing; pub mod api; @@ -176,7 +177,7 @@ impl NymNodeRouter { Redirect::to(&routes::api::v1::metrics::prometheus_absolute()) }), ) - .nest(routes::LANDING_PAGE, landing_page::routes(config.landing)) + .merge(landing_page::routes(config.landing)) .nest(routes::API, api::routes(config.api)) .layer(axum::middleware::from_fn(logging::log_request_info)) .with_state(state), @@ -186,6 +187,7 @@ impl NymNodeRouter { pub async fn build_server( self, bind_address: &SocketAddr, + shutdown: WaitForCancellationFutureOwned, ) -> Result { let listener = tokio::net::TcpListener::bind(bind_address) .await @@ -198,6 +200,28 @@ impl NymNodeRouter { listener, self.inner .into_make_service_with_connect_info::(), - )) + ) + .with_graceful_shutdown(shutdown)) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use nym_crypto::asymmetric::{ed25519, x25519}; + use nym_node_requests::api::SignedData; + use nym_node_requests::api::v1::lewes_protocol::models::LewesProtocol; + use nym_test_utils::helpers::deterministic_rng; + use std::collections::BTreeMap; + + #[test] + fn router_constructs_without_panic() { + let mut rng = deterministic_rng(); + let signing = ed25519::KeyPair::new(&mut rng); + let x25519_pub: x25519::DHPublicKey = x25519::PrivateKey::new(&mut rng).public_key().into(); + let lp = LewesProtocol::new(false, 0, 0, x25519_pub, BTreeMap::new()); + let signed = SignedData::new(lp, signing.private_key()).unwrap(); + let config = HttpServerConfig::new(signed); + let _ = NymNodeRouter::new(config, AppState::dummy()); } } diff --git a/nym-node/src/node/http/state/mod.rs b/nym-node/src/node/http/state/mod.rs index f1c9f2d81b..cc72217439 100644 --- a/nym-node/src/node/http/state/mod.rs +++ b/nym-node/src/node/http/state/mod.rs @@ -73,4 +73,30 @@ impl AppState { }, } } + + #[cfg(test)] + pub(crate) fn dummy() -> Self { + use crate::node::key_rotation::key::SphinxPrivateKey; + use rand::rngs::OsRng; + + let ed25519_keys = ed25519::KeyPair::new(&mut OsRng); + let attester_pk = *ed25519_keys.public_key(); + let static_information = StaticNodeInformation { + ed25519_identity_keys: Arc::new(ed25519_keys), + x25519_versioned_noise_key: None, + ip_addresses: vec![], + hostname: None, + }; + let active_sphinx = ActiveSphinxKeys::new_fresh(SphinxPrivateKey::new(&mut OsRng, 0)); + + AppState::new( + static_information, + active_sphinx, + NymNodeMetrics::new(), + SharedVerlocStats::default(), + Url::parse("https://attestation.test").unwrap(), + UpgradeModeState::new(attester_pk), + Duration::from_secs(60), + ) + } } diff --git a/nym-node/src/node/mod.rs b/nym-node/src/node/mod.rs index 7f857f3a5b..fef5c629ef 100644 --- a/nym-node/src/node/mod.rs +++ b/nym-node/src/node/mod.rs @@ -81,6 +81,7 @@ use std::ops::Deref; use std::path::Path; use std::sync::Arc; use tokio::sync::mpsc; +use tokio_util::sync::WaitForCancellationFutureOwned; use tracing::{debug, info, trace}; use zeroize::Zeroizing; @@ -872,7 +873,10 @@ impl NymNode { .collect() } - pub(crate) async fn build_http_server(&self) -> Result { + pub(crate) async fn build_http_server( + &self, + shutdown: WaitForCancellationFutureOwned, + ) -> Result { let auxiliary_details = api_requests::v1::node::models::AuxiliaryDetails { location: self.config.host.location, announce_ports: AnnouncePorts { @@ -1023,7 +1027,7 @@ impl NymNode { ); Ok(NymNodeRouter::new(config, app_state) - .build_server(&self.config.http.bind_address) + .build_server(&self.config.http.bind_address, shutdown) .await?) } @@ -1342,16 +1346,17 @@ impl NymNode { ); debug!("config: {:#?}", self.config); - let http_server = self.build_http_server().await?; let bind_address = self.config.http.bind_address; - let server_shutdown = self.shutdown_manager.clone_shutdown_token(); + let shutdown = self + .shutdown_manager + .clone_shutdown_token() + .cancelled_owned(); + let http_server = self.build_http_server(shutdown).await?; self.shutdown_manager.try_spawn_named( async move { info!("starting NymNodeHTTPServer on {bind_address}"); - http_server - .with_graceful_shutdown(async move { server_shutdown.cancelled().await }) - .await + http_server.await }, "HttpApi", ); diff --git a/nym-statistics-api/src/http/api/stats.rs b/nym-statistics-api/src/http/api/stats.rs index 79a3a1180b..5fca0f61b8 100644 --- a/nym-statistics-api/src/http/api/stats.rs +++ b/nym-statistics-api/src/http/api/stats.rs @@ -1,6 +1,6 @@ use axum::{Json, Router, extract::State}; -use axum_client_ip::InsecureClientIp; use axum_extra::{TypedHeader, headers::UserAgent}; +use nym_http_api_common::middleware::client_ip::ClientIpAddr; use nym_statistics_common::report::vpn_client::{ ActiveDeviceReport, StaticInformationReport, VpnClientStatsReport, VpnClientStatsReportV2, }; @@ -35,15 +35,12 @@ pub(crate) fn routes() -> Router { async fn submit_stats_report( State(mut state): State, TypedHeader(user_agent): TypedHeader, - insecure_ip_addr: InsecureClientIp, + ClientIpAddr(client_ip): ClientIpAddr, Json(report): Json, ) -> HttpResult> { let now = time::OffsetDateTime::now_utc(); - let gateway_record = state - .network_view() - .get_country_by_ip(&insecure_ip_addr.0) - .await; + let gateway_record = state.network_view().get_country_by_ip(&client_ip).await; let from_mixnet = gateway_record.is_some(); let maybe_location = gateway_record.unwrap_or_default(); @@ -60,7 +57,7 @@ async fn submit_stats_report( &report, user_agent, from_mixnet, - insecure_ip_addr.0, + client_ip, maybe_location, ); @@ -93,15 +90,12 @@ async fn submit_stats_report( async fn submit_active_device( State(mut state): State, TypedHeader(user_agent): TypedHeader, - insecure_ip_addr: InsecureClientIp, + ClientIpAddr(client_ip): ClientIpAddr, Json(report): Json, ) -> HttpResult> { let now = time::OffsetDateTime::now_utc(); - let gateway_record = state - .network_view() - .get_country_by_ip(&insecure_ip_addr.0) - .await; + let gateway_record = state.network_view().get_country_by_ip(&client_ip).await; let from_mixnet = gateway_record.is_some(); @@ -140,7 +134,7 @@ async fn submit_active_device( async fn submit_session_report( State(mut state): State, TypedHeader(user_agent): TypedHeader, - insecure_ip_addr: InsecureClientIp, // This is the reverse proxy IP for now, but maybe in the future? + ClientIpAddr(client_ip): ClientIpAddr, Json(report): Json, ) -> HttpResult> { let now = time::OffsetDateTime::now_utc(); @@ -164,7 +158,7 @@ async fn submit_session_report( &report, user_agent, from_mixnet, - insecure_ip_addr.0, + client_ip, maybe_location, ); diff --git a/nyx-chain-watcher/src/http/api/mod.rs b/nyx-chain-watcher/src/http/api/mod.rs index 50f95d84ca..8d5ef97599 100644 --- a/nyx-chain-watcher/src/http/api/mod.rs +++ b/nyx-chain-watcher/src/http/api/mod.rs @@ -79,3 +79,13 @@ fn setup_cors() -> CorsLayer { .allow_headers(tower_http::cors::Any) .allow_credentials(false) } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn router_constructs_without_panic() { + let _ = RouterBuilder::with_default_routes().finalize_routes(); + } +} From 626d013547c3906accfdcaffe057f9613276bea4 Mon Sep 17 00:00:00 2001 From: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com> Date: Fri, 22 May 2026 20:29:51 +0100 Subject: [PATCH 42/94] Switch from yarn to pnpm (#6779) * switch from yarn to pnpm * Remove full-nym-wasm (#6796) * Remove nym-browser-extension (#6798) * Remove nym-browser-extension * remove unused from makefile * Remove Node tester (#6800) * Remove dom-utils (#6801) * gh-actions: remove pnpm version * nuke dist and pkg * add missing dependency * set node version to 24 and pnpm version to 11 * upgrade lock file from pnpm version 9 to 11 * pnpm add approved builds * yarn -> pnpm * upgrade jest version * yarn -> pnpm * Remove unused cfg; clippy! * pnpm: when dev mode is on, unfreeze the lock file * pnpm approve more scripts * pnpm syntax error * add `pnpm i` * disable eslint temporarily while switching to biome in later PR --------- Co-authored-by: Mark Sinclair Co-authored-by: mfahampshire --- .github/workflows/cd-docs.yml | 4 +- .github/workflows/ci-build-ts.yml | 11 +- .github/workflows/ci-build.yml | 1 - .../workflows/ci-crates-publish-dry-run.yml | 2 +- .github/workflows/ci-crates-version-bump.yml | 2 +- .github/workflows/ci-docs.yml | 4 +- .github/workflows/ci-lint-typescript.yml | 20 +- .github/workflows/ci-nym-wallet-frontend.yml | 24 +- .github/workflows/ci-sdk-wasm.yml | 2 +- .../workflows/publish-nym-wallet-macos.yml | 21 +- .../workflows/publish-nym-wallet-ubuntu.yml | 17 +- .../workflows/publish-nym-wallet-win11.yml | 21 +- .github/workflows/publish-sdk-npm.yml | 14 +- .github/workflows/release-calculate-hash.yml | 2 +- .gitignore | 4 + .npmrc | 9 + Cargo.lock | 38 - Cargo.toml | 12 - Makefile | 12 +- README.md | 4 +- explorer-v2/package.json | 32 +- .../components/countryFlag/CountryFlag.tsx | 3 +- .../src/components/footer/SocialIcon.tsx | 3 +- explorer-v2/src/components/header/Switch.tsx | 2 +- lefthook.yml | 4 +- lerna.json | 3 +- nym-browser-extension/.gitignore | 14 - nym-browser-extension/README.md | 125 - .../storage/.cargo/config.toml | 4 - nym-browser-extension/storage/.gitignore | 36 - nym-browser-extension/storage/Cargo.toml | 37 - nym-browser-extension/storage/Makefile | 65 - .../storage/internal-dev/index.html | 161 - .../storage/internal-dev/index.js | 303 - nym-browser-extension/storage/src/error.rs | 32 - nym-browser-extension/storage/src/lib.rs | 17 - nym-browser-extension/storage/src/storage.rs | 189 - nym-node/tests/package.json | 2 +- nym-wallet/.nvmrc | 2 +- nym-wallet/package.json | 284 +- nym-wallet/scripts/regenerate-tauri-icons.sh | 2 +- .../src-tauri/gen/schemas/acl-manifests.json | 2 +- .../src-tauri/gen/schemas/desktop-schema.json | 60 +- .../src-tauri/gen/schemas/macOS-schema.json | 60 +- nym-wallet/src/context/bonding.tsx | 2 +- nym-wallet/src/context/mocks/bonding.tsx | 2 +- .../bonding/node-settings/node-test/index.tsx | 123 - .../general-settings/ParametersSettings.tsx | 2 +- package.json | 47 +- pnpm-lock.yaml | 31489 ++++++++++++++++ pnpm-workspace.yaml | 244 + .../internal-dev/package.json | 2 +- .../codegen/contract-clients/package.json | 4 +- .../scripts/build-prod-docs-collect.sh | 2 +- .../examples/chat-app/parcel/package.json | 30 +- .../examples/chat-app/plain-html/package.json | 68 +- .../package.json | 100 +- .../examples/chrome-extension/README.md | 22 - .../examples/chrome-extension/manifest.json | 17 - .../examples/chrome-extension/package.json | 21 - .../examples/chrome-extension/popup.css | 8 - .../examples/chrome-extension/popup.html | 23 - .../chrome-extension/src/dom-utils.js | 66 - .../examples/chrome-extension/src/main.js | 53 - .../examples/chrome-extension/tsconfig.json | 9 - .../chrome-extension/webpack.config.js | 25 - .../examples/firefox-extension/.gitignore | 1 - .../examples/firefox-extension/README.md | 35 - .../examples/firefox-extension/manifest.json | 23 - .../examples/firefox-extension/package.json | 21 - .../examples/firefox-extension/popup.css | 8 - .../examples/firefox-extension/popup.html | 23 - .../firefox-extension/src/background.js | 107 - .../firefox-extension/src/background.ts | 114 - .../firefox-extension/src/dom-utils.js | 74 - .../firefox-extension/src/dom-utils.ts | 35 - .../examples/firefox-extension/src/popup.js | 40 - .../examples/firefox-extension/src/popup.ts | 40 - .../examples/firefox-extension/tsconfig.json | 9 - .../firefox-extension/webpack.config.js | 38 - .../examples/node-tester/parcel/README.md | 14 - .../examples/node-tester/parcel/package.json | 44 - .../node-tester/parcel/src/index.html | 29 - .../examples/node-tester/parcel/src/index.ts | 118 - .../examples/node-tester/parcel/tsconfig.json | 8 - .../examples/node-tester/plain-html/README.md | 14 - .../node-tester/plain-html/package.json | 65 - .../node-tester/plain-html/src/index.html | 29 - .../node-tester/plain-html/src/index.ts | 116 - .../node-tester/plain-html/tsconfig.json | 8 - .../node-tester/plain-html/tsconfig.prod.json | 10 - .../node-tester/plain-html/webpack.common.js | 30 - .../node-tester/plain-html/webpack.config.js | 67 - .../node-tester/plain-html/webpack.prod.js | 42 - .../examples/node-tester/react/README.md | 14 - .../examples/node-tester/react/index.html | 13 - .../examples/node-tester/react/package.json | 20 - .../examples/node-tester/react/src/App.tsx | 127 - .../react/src/components/ScoreIndicator.tsx | 61 - .../react/src/components/TestStatusLabel.tsx | 34 - .../react/src/hooks/useNodeTesterClient.ts | 71 - .../examples/node-tester/react/src/index.tsx | 14 - .../node-tester/react/src/layouts/index.tsx | 6 - .../node-tester/react/src/theme/theme.tsx | 28 - .../node-tester/react/src/typesDefs.ts | 4 - .../examples/node-tester/react/tsconfig.json | 16 - .../examples/react/mui-theme/README.md | 6 +- .../examples/react/mui-theme/package.json | 96 +- .../examples/react/sdk-react/package.json | 30 +- sdk/typescript/packages/dom-utils/README.md | 7 - sdk/typescript/packages/dom-utils/index.ts | 61 - .../packages/mix-fetch-node/package.json | 32 +- .../packages/mix-fetch/internal-dev/README.md | 10 +- .../mix-fetch/internal-dev/package.json | 62 +- .../packages/mix-fetch/package.json | 47 +- .../scripts/build-prod-docs-collect.sh | 2 +- sdk/typescript/packages/mui-theme/README.md | 8 +- .../packages/mui-theme/package.json | 44 +- sdk/typescript/packages/node-tester/.babelrc | 3 - .../packages/node-tester/.gitignore | 1 - .../node-tester/README-CommonJS-full-fat.md | 7 - .../packages/node-tester/README-CommonJS.md | 7 - .../packages/node-tester/README-full-fat.md | 7 - sdk/typescript/packages/node-tester/README.md | 7 - .../packages/node-tester/jest.config.mjs | 15 - .../packages/node-tester/package.json | 74 - .../rollup-cjs-full-fat.config.mjs | 8 - .../node-tester/rollup-cjs.config.mjs | 5 - .../rollup-esm-full-fat.config.mjs | 8 - .../node-tester/rollup-esm.config.mjs | 8 - .../node-tester/rollup-worker.config.mjs | 28 - .../packages/node-tester/rollup/cjs.mjs | 30 - .../packages/node-tester/rollup/esm.mjs | 28 - .../node-tester/scripts/build-dev-esm.sh | 33 - .../node-tester/scripts/build-prod.sh | 20 - .../packages/node-tester/scripts/build.sh | 69 - .../node-tester/scripts/buildPackageJson.mjs | 29 - .../packages/node-tester/scripts/publish.sh | 19 - .../packages/node-tester/src/index.ts | 52 - .../packages/node-tester/src/types.ts | 35 - .../packages/node-tester/src/worker.js | 2011 + .../packages/node-tester/src/worker.ts | 103 - .../packages/node-tester/tsconfig.jest.json | 43 - .../packages/node-tester/tsconfig.json | 45 - .../node-tester/typings/rollup-worker.d.ts | 4 - .../packages/nodejs-client/package.json | 34 +- .../scripts/build-prod-docs-collect.sh | 2 +- .../packages/react-components/package.json | 88 +- .../packages/sdk-react/package.json | 70 +- sdk/typescript/packages/sdk/DEVELOPERS.md | 20 +- .../packages/sdk/README-GenerateDocs.md | 8 +- sdk/typescript/packages/sdk/package.json | 46 +- .../sdk/scripts/build-prod-docs-collect.sh | 2 +- sdk/typescript/packages/sdk/scripts/hbs.mjs | 4 +- .../packages/validator-client/package.json | 20 +- sdk/typescript/scripts/build-prod-examples.sh | 5 - sdk/typescript/scripts/build-prod-sdk.sh | 14 +- sdk/typescript/scripts/dev-mode-add.mjs | 25 +- sdk/typescript/scripts/dev-mode-remove.mjs | 22 +- sdk/typescript/scripts/publish.sh | 14 +- sdk/typescript/scripts/release.sh | 4 +- tools/internal/sdk-version-bump/src/main.rs | 11 - .../package.json | 26 +- ts-packages/types/package.json | 39 +- ts-packages/webpack/package.json | 58 +- wasm/client/Cargo.toml | 7 +- wasm/client/Makefile | 15 +- wasm/client/src/client.rs | 97 +- wasm/client/src/config.rs | 11 - wasm/client/src/error.rs | 13 - wasm/client/src/helpers.rs | 82 +- wasm/full-nym-wasm/.cargo/config.toml | 4 - wasm/full-nym-wasm/Cargo.toml | 30 - wasm/full-nym-wasm/Makefile | 5 - wasm/full-nym-wasm/src/lib.rs | 11 - wasm/mix-fetch/Makefile | 13 +- wasm/node-tester/.cargo/config.toml | 4 - wasm/node-tester/Cargo.toml | 36 - wasm/node-tester/Makefile | 5 - wasm/node-tester/internal-dev/.gitignore | 2 - wasm/node-tester/internal-dev/bootstrap.js | 5 - wasm/node-tester/internal-dev/index.html | 44 - wasm/node-tester/internal-dev/index.js | 173 - wasm/node-tester/internal-dev/package.json | 40 - .../internal-dev/webpack.config.js | 33 - wasm/node-tester/internal-dev/worker.js | 152 - wasm/node-tester/internal-dev/yarn-error.log | 2261 -- wasm/node-tester/internal-dev/yarn.lock | 2172 -- wasm/node-tester/src/ephemeral_receiver.rs | 113 - wasm/node-tester/src/error.rs | 63 - wasm/node-tester/src/helpers.rs | 97 - wasm/node-tester/src/lib.rs | 16 - wasm/node-tester/src/tester.rs | 380 - wasm/node-tester/src/types.rs | 59 - yarn.lock | 24029 ------------ 195 files changed, 34745 insertions(+), 34438 deletions(-) create mode 100644 .npmrc delete mode 100644 nym-browser-extension/.gitignore delete mode 100644 nym-browser-extension/README.md delete mode 100644 nym-browser-extension/storage/.cargo/config.toml delete mode 100644 nym-browser-extension/storage/.gitignore delete mode 100644 nym-browser-extension/storage/Cargo.toml delete mode 100644 nym-browser-extension/storage/Makefile delete mode 100644 nym-browser-extension/storage/internal-dev/index.html delete mode 100644 nym-browser-extension/storage/internal-dev/index.js delete mode 100644 nym-browser-extension/storage/src/error.rs delete mode 100644 nym-browser-extension/storage/src/lib.rs delete mode 100644 nym-browser-extension/storage/src/storage.rs delete mode 100644 nym-wallet/src/pages/bonding/node-settings/node-test/index.tsx create mode 100644 pnpm-lock.yaml create mode 100644 pnpm-workspace.yaml delete mode 100644 sdk/typescript/examples/chrome-extension/README.md delete mode 100644 sdk/typescript/examples/chrome-extension/manifest.json delete mode 100644 sdk/typescript/examples/chrome-extension/package.json delete mode 100644 sdk/typescript/examples/chrome-extension/popup.css delete mode 100644 sdk/typescript/examples/chrome-extension/popup.html delete mode 100644 sdk/typescript/examples/chrome-extension/src/dom-utils.js delete mode 100644 sdk/typescript/examples/chrome-extension/src/main.js delete mode 100644 sdk/typescript/examples/chrome-extension/tsconfig.json delete mode 100644 sdk/typescript/examples/chrome-extension/webpack.config.js delete mode 100644 sdk/typescript/examples/firefox-extension/.gitignore delete mode 100644 sdk/typescript/examples/firefox-extension/README.md delete mode 100644 sdk/typescript/examples/firefox-extension/manifest.json delete mode 100644 sdk/typescript/examples/firefox-extension/package.json delete mode 100644 sdk/typescript/examples/firefox-extension/popup.css delete mode 100644 sdk/typescript/examples/firefox-extension/popup.html delete mode 100644 sdk/typescript/examples/firefox-extension/src/background.js delete mode 100644 sdk/typescript/examples/firefox-extension/src/background.ts delete mode 100644 sdk/typescript/examples/firefox-extension/src/dom-utils.js delete mode 100644 sdk/typescript/examples/firefox-extension/src/dom-utils.ts delete mode 100644 sdk/typescript/examples/firefox-extension/src/popup.js delete mode 100644 sdk/typescript/examples/firefox-extension/src/popup.ts delete mode 100644 sdk/typescript/examples/firefox-extension/tsconfig.json delete mode 100644 sdk/typescript/examples/firefox-extension/webpack.config.js delete mode 100644 sdk/typescript/examples/node-tester/parcel/README.md delete mode 100644 sdk/typescript/examples/node-tester/parcel/package.json delete mode 100644 sdk/typescript/examples/node-tester/parcel/src/index.html delete mode 100644 sdk/typescript/examples/node-tester/parcel/src/index.ts delete mode 100644 sdk/typescript/examples/node-tester/parcel/tsconfig.json delete mode 100644 sdk/typescript/examples/node-tester/plain-html/README.md delete mode 100644 sdk/typescript/examples/node-tester/plain-html/package.json delete mode 100644 sdk/typescript/examples/node-tester/plain-html/src/index.html delete mode 100644 sdk/typescript/examples/node-tester/plain-html/src/index.ts delete mode 100644 sdk/typescript/examples/node-tester/plain-html/tsconfig.json delete mode 100644 sdk/typescript/examples/node-tester/plain-html/tsconfig.prod.json delete mode 100644 sdk/typescript/examples/node-tester/plain-html/webpack.common.js delete mode 100644 sdk/typescript/examples/node-tester/plain-html/webpack.config.js delete mode 100644 sdk/typescript/examples/node-tester/plain-html/webpack.prod.js delete mode 100644 sdk/typescript/examples/node-tester/react/README.md delete mode 100644 sdk/typescript/examples/node-tester/react/index.html delete mode 100644 sdk/typescript/examples/node-tester/react/package.json delete mode 100644 sdk/typescript/examples/node-tester/react/src/App.tsx delete mode 100644 sdk/typescript/examples/node-tester/react/src/components/ScoreIndicator.tsx delete mode 100644 sdk/typescript/examples/node-tester/react/src/components/TestStatusLabel.tsx delete mode 100644 sdk/typescript/examples/node-tester/react/src/hooks/useNodeTesterClient.ts delete mode 100644 sdk/typescript/examples/node-tester/react/src/index.tsx delete mode 100644 sdk/typescript/examples/node-tester/react/src/layouts/index.tsx delete mode 100644 sdk/typescript/examples/node-tester/react/src/theme/theme.tsx delete mode 100644 sdk/typescript/examples/node-tester/react/src/typesDefs.ts delete mode 100644 sdk/typescript/examples/node-tester/react/tsconfig.json delete mode 100644 sdk/typescript/packages/dom-utils/README.md delete mode 100644 sdk/typescript/packages/dom-utils/index.ts delete mode 100644 sdk/typescript/packages/node-tester/.babelrc delete mode 100644 sdk/typescript/packages/node-tester/.gitignore delete mode 100644 sdk/typescript/packages/node-tester/README-CommonJS-full-fat.md delete mode 100644 sdk/typescript/packages/node-tester/README-CommonJS.md delete mode 100644 sdk/typescript/packages/node-tester/README-full-fat.md delete mode 100644 sdk/typescript/packages/node-tester/README.md delete mode 100644 sdk/typescript/packages/node-tester/jest.config.mjs delete mode 100644 sdk/typescript/packages/node-tester/package.json delete mode 100644 sdk/typescript/packages/node-tester/rollup-cjs-full-fat.config.mjs delete mode 100644 sdk/typescript/packages/node-tester/rollup-cjs.config.mjs delete mode 100644 sdk/typescript/packages/node-tester/rollup-esm-full-fat.config.mjs delete mode 100644 sdk/typescript/packages/node-tester/rollup-esm.config.mjs delete mode 100644 sdk/typescript/packages/node-tester/rollup-worker.config.mjs delete mode 100644 sdk/typescript/packages/node-tester/rollup/cjs.mjs delete mode 100644 sdk/typescript/packages/node-tester/rollup/esm.mjs delete mode 100755 sdk/typescript/packages/node-tester/scripts/build-dev-esm.sh delete mode 100755 sdk/typescript/packages/node-tester/scripts/build-prod.sh delete mode 100755 sdk/typescript/packages/node-tester/scripts/build.sh delete mode 100644 sdk/typescript/packages/node-tester/scripts/buildPackageJson.mjs delete mode 100755 sdk/typescript/packages/node-tester/scripts/publish.sh delete mode 100644 sdk/typescript/packages/node-tester/src/index.ts delete mode 100644 sdk/typescript/packages/node-tester/src/types.ts create mode 100644 sdk/typescript/packages/node-tester/src/worker.js delete mode 100644 sdk/typescript/packages/node-tester/src/worker.ts delete mode 100644 sdk/typescript/packages/node-tester/tsconfig.jest.json delete mode 100644 sdk/typescript/packages/node-tester/tsconfig.json delete mode 100644 sdk/typescript/packages/node-tester/typings/rollup-worker.d.ts delete mode 100644 wasm/full-nym-wasm/.cargo/config.toml delete mode 100644 wasm/full-nym-wasm/Cargo.toml delete mode 100644 wasm/full-nym-wasm/Makefile delete mode 100644 wasm/full-nym-wasm/src/lib.rs delete mode 100644 wasm/node-tester/.cargo/config.toml delete mode 100644 wasm/node-tester/Cargo.toml delete mode 100644 wasm/node-tester/Makefile delete mode 100644 wasm/node-tester/internal-dev/.gitignore delete mode 100644 wasm/node-tester/internal-dev/bootstrap.js delete mode 100644 wasm/node-tester/internal-dev/index.html delete mode 100644 wasm/node-tester/internal-dev/index.js delete mode 100644 wasm/node-tester/internal-dev/package.json delete mode 100644 wasm/node-tester/internal-dev/webpack.config.js delete mode 100644 wasm/node-tester/internal-dev/worker.js delete mode 100644 wasm/node-tester/internal-dev/yarn-error.log delete mode 100644 wasm/node-tester/internal-dev/yarn.lock delete mode 100644 wasm/node-tester/src/ephemeral_receiver.rs delete mode 100644 wasm/node-tester/src/error.rs delete mode 100644 wasm/node-tester/src/helpers.rs delete mode 100644 wasm/node-tester/src/lib.rs delete mode 100644 wasm/node-tester/src/tester.rs delete mode 100644 wasm/node-tester/src/types.rs delete mode 100644 yarn.lock diff --git a/.github/workflows/cd-docs.yml b/.github/workflows/cd-docs.yml index 507fe18b70..cb49561a7a 100644 --- a/.github/workflows/cd-docs.yml +++ b/.github/workflows/cd-docs.yml @@ -23,10 +23,10 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v5.0.0 with: - version: 9 + version: 11.1.2 - uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 24 - name: Install Rust toolchain uses: actions-rs/toolchain@v1 with: diff --git a/.github/workflows/ci-build-ts.yml b/.github/workflows/ci-build-ts.yml index 5c61977c48..3586a0dc54 100644 --- a/.github/workflows/ci-build-ts.yml +++ b/.github/workflows/ci-build-ts.yml @@ -17,13 +17,16 @@ jobs: run: sudo apt-get install rsync continue-on-error: true - uses: rlespinasse/github-slug-action@v3.x + - name: Setup pnpm + uses: pnpm/action-setup@v5.0.0 + with: + version: 11.1.2 - uses: actions/setup-node@v4 with: - node-version: 20 - - name: Setup yarn - run: npm install -g yarn + node-version: 24 + cache: pnpm - name: Build - run: yarn && yarn build && yarn build:ci:storybook + run: pnpm install && pnpm build && pnpm build:ci:storybook - name: Deploy branch to CI www (storybook) continue-on-error: true uses: easingthemes/ssh-deploy@main diff --git a/.github/workflows/ci-build.yml b/.github/workflows/ci-build.yml index 1546b9d4dc..b4d5a87a6d 100644 --- a/.github/workflows/ci-build.yml +++ b/.github/workflows/ci-build.yml @@ -23,7 +23,6 @@ on: - 'sdk/ffi/**' - 'sdk/rust/**' - 'service-providers/**' - - 'nym-browser-extension/storage/**' - 'tools/**' - 'wasm/**' - 'Cargo.toml' diff --git a/.github/workflows/ci-crates-publish-dry-run.yml b/.github/workflows/ci-crates-publish-dry-run.yml index 8c3af47db6..5aef78c8c3 100644 --- a/.github/workflows/ci-crates-publish-dry-run.yml +++ b/.github/workflows/ci-crates-publish-dry-run.yml @@ -40,7 +40,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: "20" + node-version: 24 - name: Validate version format run: | diff --git a/.github/workflows/ci-crates-version-bump.yml b/.github/workflows/ci-crates-version-bump.yml index 0539d6b9f4..21c34e0784 100644 --- a/.github/workflows/ci-crates-version-bump.yml +++ b/.github/workflows/ci-crates-version-bump.yml @@ -42,7 +42,7 @@ jobs: - name: Setup Node.js uses: actions/setup-node@v4 with: - node-version: "20" + node-version: 24 - name: Validate version format run: | diff --git a/.github/workflows/ci-docs.yml b/.github/workflows/ci-docs.yml index dd4a2ff1f7..7a76619701 100644 --- a/.github/workflows/ci-docs.yml +++ b/.github/workflows/ci-docs.yml @@ -30,10 +30,10 @@ jobs: - name: Setup pnpm uses: pnpm/action-setup@v5.0.0 with: - version: 9 + version: 11.1.2 - uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 24 - name: Install Rust toolchain uses: actions-rs/toolchain@v1 with: diff --git a/.github/workflows/ci-lint-typescript.yml b/.github/workflows/ci-lint-typescript.yml index 51bacc44f8..ad5ae63fac 100644 --- a/.github/workflows/ci-lint-typescript.yml +++ b/.github/workflows/ci-lint-typescript.yml @@ -20,12 +20,14 @@ jobs: - uses: actions/checkout@v6 - uses: rlespinasse/github-slug-action@v3.x + - name: Setup pnpm + uses: pnpm/action-setup@v5.0.0 + with: + version: 11.1.2 - uses: actions/setup-node@v4 with: - node-version: 20 - - - name: Setup yarn - run: npm install -g yarn + node-version: 24 + cache: pnpm - name: Install Rust toolchain uses: actions-rs/toolchain@v1 @@ -44,16 +46,16 @@ jobs: go-version: "1.24.6" - name: Install - run: yarn + run: pnpm i - name: Build packages - run: yarn build:ci + run: pnpm build:ci - name: Install again - run: yarn + run: pnpm i - name: Lint - run: yarn lint + run: pnpm lint - name: Typecheck with tsc - run: yarn tsc + run: pnpm tsc diff --git a/.github/workflows/ci-nym-wallet-frontend.yml b/.github/workflows/ci-nym-wallet-frontend.yml index 2365379634..3bc746959a 100644 --- a/.github/workflows/ci-nym-wallet-frontend.yml +++ b/.github/workflows/ci-nym-wallet-frontend.yml @@ -12,30 +12,34 @@ jobs: steps: - uses: actions/checkout@v6 + - name: Setup pnpm + uses: pnpm/action-setup@v5.0.0 + with: + version: 11.1.2 + - uses: actions/setup-node@v4 with: node-version-file: nym-wallet/.nvmrc - cache: yarn - cache-dependency-path: yarn.lock + cache: pnpm - name: Install dependencies - run: yarn install --network-timeout 100000 + run: pnpm install - name: Build TypeScript packages (wallet depends on @nymproject/types, etc.) - run: yarn build:types + run: pnpm build:types - name: Build @nymproject/mui-theme and @nymproject/react (wallet imports subpaths) - run: yarn build:packages + run: pnpm build:packages - name: Typecheck nym-wallet - run: yarn --cwd nym-wallet tsc + run: pnpm --filter @nymproject/nym-wallet-app tsc - name: Lint nym-wallet - run: yarn --cwd nym-wallet lint + run: pnpm --filter @nymproject/nym-wallet-app lint - - name: Yarn audit (workspace lockfile; informational) - run: yarn audit --level critical + - name: pnpm audit (workspace lockfile; informational) + run: pnpm audit --audit-level critical continue-on-error: true - name: Unit tests (nym-wallet) - run: yarn --cwd nym-wallet test + run: pnpm --filter @nymproject/nym-wallet-app test diff --git a/.github/workflows/ci-sdk-wasm.yml b/.github/workflows/ci-sdk-wasm.yml index 702cdfbfa3..94cdca9e22 100644 --- a/.github/workflows/ci-sdk-wasm.yml +++ b/.github/workflows/ci-sdk-wasm.yml @@ -20,7 +20,7 @@ jobs: - uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 24 - uses: actions-rs/toolchain@v1 with: diff --git a/.github/workflows/publish-nym-wallet-macos.yml b/.github/workflows/publish-nym-wallet-macos.yml index fad6f3ef0b..95746a92f2 100644 --- a/.github/workflows/publish-nym-wallet-macos.yml +++ b/.github/workflows/publish-nym-wallet-macos.yml @@ -23,10 +23,13 @@ jobs: steps: - uses: actions/checkout@v6 - - name: Node - uses: actions/setup-node@v4 + - name: Setup pnpm + uses: pnpm/action-setup@v5.0.0 with: - node-version: 22.13.0 + version: 11.1.2 + - uses: actions/setup-node@v4 + with: + node-version: 24 - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable @@ -68,17 +71,17 @@ jobs: fileName: '.env' encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }} - - name: Yarn cache clean + - name: pnpm cache clean shell: bash - run: cd .. && yarn cache clean + run: cd .. && pnpm cache delete - name: Install project dependencies shell: bash - run: cd .. && yarn --network-timeout 100000 + run: cd .. && pnpm i - - name: Yarn build + - name: Build shell: bash - run: cd .. && yarn build + run: cd .. && pnpm build - name: Install dependencies and build it env: @@ -97,7 +100,7 @@ jobs: TAURI_NOTARIZATION_PASSWORD: ${{ secrets.APPLE_PASSWORD }} TAURI_NOTARIZATION_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }} run: | - yarn build-macx86 + pnpm build-macx86 - name: Create app tarball run: | diff --git a/.github/workflows/publish-nym-wallet-ubuntu.yml b/.github/workflows/publish-nym-wallet-ubuntu.yml index 18cebe43bc..f1c95d1f4f 100644 --- a/.github/workflows/publish-nym-wallet-ubuntu.yml +++ b/.github/workflows/publish-nym-wallet-ubuntu.yml @@ -26,12 +26,17 @@ jobs: libwebkit2gtk-4.1-dev build-essential curl wget libssl-dev jq \ libgtk-3-dev squashfs-tools libayatana-appindicator3-dev make libfuse2 unzip librsvg2-dev file \ libsoup-3.0-dev libjavascriptcoregtk-4.1-dev - + + - name: Setup pnpm + uses: pnpm/action-setup@v5.0.0 + with: + version: 11.1.2 + - name: Node uses: actions/setup-node@v4 with: - node-version: 22.13.0 - cache: 'yarn' + node-version: 24 + cache: 'pnpm' - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable @@ -40,10 +45,10 @@ jobs: - name: Install project dependencies shell: bash - run: cd .. && yarn --network-timeout 100000 + run: cd .. && pnpm i - name: Install app dependencies - run: yarn + run: pnpm - name: Create env file uses: timheuer/base64-to-file@v1.2 @@ -52,7 +57,7 @@ jobs: encodedString: ${{ secrets.WALLET_ADMIN_ADDRESS }} - name: Build app - run: yarn build + run: pnpm build env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} TAURI_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }} diff --git a/.github/workflows/publish-nym-wallet-win11.yml b/.github/workflows/publish-nym-wallet-win11.yml index dc692cda36..060a84ab18 100644 --- a/.github/workflows/publish-nym-wallet-win11.yml +++ b/.github/workflows/publish-nym-wallet-win11.yml @@ -40,16 +40,13 @@ jobs: - name: Setup MSBuild.exe uses: microsoft/setup-msbuild@v3 - # No cache:yarn here: setup-node needs yarn on PATH to populate the cache, but this runner - # only gets yarn from the step below. - - name: Node - uses: actions/setup-node@v4 + - name: Setup pnpm + uses: pnpm/action-setup@v5.0.0 with: - node-version: 22.13.0 - - - name: Install Yarn (classic) - shell: bash - run: npm install -g yarn@1.22.22 + version: 11.1.2 + - uses: actions/setup-node@v4 + with: + node-version: 24 - name: Strip Authenticode thumbprint (avoid signtool on runner) working-directory: nym-wallet/src-tauri @@ -118,11 +115,11 @@ jobs: ' tauri.conf.json - name: Install project dependencies shell: bash - run: cd .. && yarn --network-timeout 100000 + run: cd .. && pnpm i - name: Install app dependencies shell: bash - run: yarn --network-timeout 100000 + run: pnpm i - name: Build and sign it shell: bash @@ -136,7 +133,7 @@ jobs: SSL_COM_TOTP_SECRET: ${{ env.SIGN_WINDOWS == 'true' && secrets.SSL_COM_TOTP_SECRET }} run: | echo "Starting build process..." - yarn build + pnpm build - name: Check bundle directory shell: bash diff --git a/.github/workflows/publish-sdk-npm.yml b/.github/workflows/publish-sdk-npm.yml index 7eed254d1e..fa474ae048 100644 --- a/.github/workflows/publish-sdk-npm.yml +++ b/.github/workflows/publish-sdk-npm.yml @@ -8,15 +8,17 @@ jobs: steps: - uses: actions/checkout@v6 + - name: Setup pnpm + uses: pnpm/action-setup@v5.0.0 + with: + version: 11.1.2 + - name: Install Node uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 24 registry-url: "https://registry.npmjs.org" - - name: Setup yarn - run: npm install -g yarn - - name: Install rust toolchain uses: actions-rs/toolchain@v1 with: @@ -40,10 +42,10 @@ jobs: run: ./wasm/mix-fetch/go-mix-conn/scripts/update-root-certs.sh - name: Install dependencies - run: yarn + run: pnpm i - name: Build WASM and Typescript SDK - run: yarn sdk:build + run: pnpm sdk:build - name: Publish to NPM env: diff --git a/.github/workflows/release-calculate-hash.yml b/.github/workflows/release-calculate-hash.yml index 4e927f9bdb..1384d223c5 100644 --- a/.github/workflows/release-calculate-hash.yml +++ b/.github/workflows/release-calculate-hash.yml @@ -23,7 +23,7 @@ jobs: uses: actions/checkout@v6 - uses: actions/setup-node@v4 with: - node-version: 20 + node-version: 24 - uses: nymtech/nym/.github/actions/nym-hash-releases@develop env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index 72c468a3fd..c1b82af03c 100644 --- a/.gitignore +++ b/.gitignore @@ -79,3 +79,7 @@ CLAUDE.md /notes /target-otel test-tutorials/ + +# pnpm +.pnpm-store/ + diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000000..7d2410d2ff --- /dev/null +++ b/.npmrc @@ -0,0 +1,9 @@ +shamefully-hoist=false +prefer-workspace-packages=true +hoist-pattern[]=*eslint* +hoist-pattern[]=*prettier* +hoist-pattern[]=*typescript* +hoist-pattern[]=*@types* + +auto-install-peers=true +strict-peer-dependencies=false diff --git a/Cargo.lock b/Cargo.lock index 86c27fcced..da312fc8ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2965,22 +2965,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "extension-storage" -version = "1.4.1" -dependencies = [ - "bip39", - "console_error_panic_hook", - "js-sys", - "nym-wasm-storage", - "nym-wasm-utils", - "serde-wasm-bindgen 0.6.5", - "thiserror 2.0.18", - "wasm-bindgen", - "wasm-bindgen-futures", - "zeroize", -] - [[package]] name = "eyre" version = "0.6.12" @@ -6312,8 +6296,6 @@ dependencies = [ "js-sys", "nym-bin-common", "nym-gateway-requests", - "nym-node-tester-utils", - "nym-node-tester-wasm", "nym-wasm-client-core", "nym-wasm-utils", "once_cell", @@ -7897,26 +7879,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "nym-node-tester-wasm" -version = "1.3.1" -dependencies = [ - "futures", - "js-sys", - "nym-node-tester-utils", - "nym-wasm-client-core", - "nym-wasm-utils", - "rand 0.8.6", - "serde", - "serde-wasm-bindgen 0.6.5", - "thiserror 2.0.18", - "tokio", - "tsify", - "wasm-bindgen", - "wasm-bindgen-futures", - "wasmtimer", -] - [[package]] name = "nym-noise" version = "1.21.0" diff --git a/Cargo.toml b/Cargo.toml index 41bdb09cf1..cabaa3bb7e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -130,7 +130,6 @@ members = [ "nym-api", "nym-api/nym-api-requests", "nym-authenticator-client", - "nym-browser-extension/storage", "nym-credential-proxy/nym-credential-proxy", "nym-credential-proxy/nym-credential-proxy-requests", "nym-data-observatory", @@ -174,9 +173,7 @@ members = [ "tools/nymvisor", "tools/ts-rs-cli", "wasm/client", - # "wasm/full-nym-wasm", # If we uncomment this again, remember to also uncomment the profile settings below "wasm/mix-fetch", - "wasm/node-tester", "wasm/zknym-lib", ] @@ -589,16 +586,7 @@ opt-level = 3 # lto = true opt-level = 'z' -[profile.release.package.nym-node-tester-wasm] -# lto = true -opt-level = 'z' -# Commented out since the crate is also commented out from the inclusion in the -# workspace above. We should uncomment this if we re-include it in the -# workspace -#[profile.release.package.nym-wasm-sdk] -## lto = true -#opt-level = 'z' [profile.release.package.mix-fetch-wasm] # lto = true diff --git a/Makefile b/Makefile index b88a99d79f..3ed8a5babc 100644 --- a/Makefile +++ b/Makefile @@ -104,23 +104,19 @@ $(eval $(call add_cargo_workspace,wallet,nym-wallet)) sdk-wasm: sdk-wasm-build sdk-wasm-test sdk-wasm-lint sdk-wasm-build: -# $(MAKE) -C nym-browser-extension/storage wasm-pack $(MAKE) -C wasm/client - $(MAKE) -C wasm/node-tester $(MAKE) -C wasm/mix-fetch # $(MAKE) -C wasm/zknym-lib - # $(MAKE) -C wasm/full-nym-wasm # run this from npm/yarn to ensure tools are in the path, e.g. yarn build:sdk from root of repo sdk-typescript-build: npx lerna run --scope @nymproject/sdk build --stream npx lerna run --scope @nymproject/mix-fetch build --stream - npx lerna run --scope @nymproject/node-tester build --stream - yarn --cwd sdk/typescript/codegen/contract-clients build + pnpm --pwd sdk/typescript/codegen/contract-clients build # NOTE: These targets are part of the main workspace (but not as wasm32-unknown-unknown) -# WASM_CRATES = extension-storage nym-client-wasm nym-node-tester-wasm zknym-lib -WASM_CRATES = nym-client-wasm nym-node-tester-wasm + +WASM_CRATES = nym-client-wasm sdk-wasm-test: #cargo test $(addprefix -p , $(WASM_CRATES)) --target wasm32-unknown-unknown -- -Dwarnings @@ -223,7 +219,7 @@ build-nym-cli: generate-typescript: cd tools/ts-rs-cli && cargo run && cd ../.. - yarn types:lint:fix + pnpm types:lint:fix # Run the integration tests for public nym-api endpoints run-api-tests: diff --git a/README.md b/README.md index 198b4d90aa..2e7610ed7f 100644 --- a/README.md +++ b/README.md @@ -74,9 +74,9 @@ Nym Node Operators and Validators Terms and Conditions can be found [here](https ## Getting Started ```bash -yarn install +pnpm install ``` ```bash -yarn build +pnpm build ``` diff --git a/explorer-v2/package.json b/explorer-v2/package.json index 912e87ccc5..74a6fb6161 100644 --- a/explorer-v2/package.json +++ b/explorer-v2/package.json @@ -4,7 +4,7 @@ "scripts": { "dev": "next dev", "build": "next build", - "build:prod": "yarn --cwd .. build && next build", + "build:prod": "pnpm --dir .. build && next build", "start": "next start", "lint": "biome check --fix" }, @@ -13,21 +13,28 @@ }, "dependencies": { "@chain-registry/types": "^0.50.36", + "@cosmjs/cosmwasm-stargate": "catalog:", + "@cosmjs/stargate": "catalog:", + "axios": "catalog:", + "big.js": "catalog:", + "long": "catalog:", "@cosmos-kit/keplr-extension": "^2.14.0", "@cosmos-kit/react": "^2.20.1", - "@emotion/cache": "^11.13.5", - "@emotion/react": "^11.13.5", - "@emotion/styled": "^11.13.5", + "@emotion/cache": "catalog:", + "@emotion/react": "catalog:", + "@emotion/styled": "catalog:", "@interchain-ui/react": "^1.26.1", "@keplr-wallet/types": "^0.12.211", - "@mui/icons-material": "^5.16.11", + "@mui/icons-material": "catalog:", "@mui/material": "^6.1.10", + "@mui/system": "^6.1.10", "@mui/material-nextjs": "^6.1.9", "@mui/x-date-pickers": "^7.23.2", "@nivo/line": "^0.88.0", "@nymproject/contract-clients": "^1.4.1", - "@nymproject/react": "1.0.0", - "@tanstack/react-query": "^5.64.2", + "@nymproject/react": "workspace:*", + "@nymproject/types": "workspace:*", + "@tanstack/react-query": "catalog:", "@tanstack/react-query-devtools": "^5.64.2", "@tanstack/react-query-next-experimental": "^5.66.0", "@tanstack/react-table": "^8.20.6", @@ -44,8 +51,8 @@ "openapi-fetch": "^0.13.4", "qrcode.react": "^4.1.0", "qs": "^6.14.0", - "react": "^18.0.0", - "react-dom": "^18.0.0", + "react": "catalog:", + "react-dom": "catalog:", "react-i18next": "^15.4.0", "react-markdown": "^9.0.3", "react-random-avatars": "^1.3.1", @@ -54,10 +61,11 @@ }, "devDependencies": { "@biomejs/biome": "1.9.4", + "@types/big.js": "catalog:", "@types/node": "^20", - "@types/react": "^18", - "@types/react-dom": "^18", - "eslint": "^9", + "@types/react": "catalog:", + "@types/react-dom": "catalog:", + "eslint": "catalog:", "eslint-config-next": "15.0.3", "lefthook": "^1.8.5", "typescript": "^5" diff --git a/explorer-v2/src/components/countryFlag/CountryFlag.tsx b/explorer-v2/src/components/countryFlag/CountryFlag.tsx index ef8f33bd15..a4218da0f7 100644 --- a/explorer-v2/src/components/countryFlag/CountryFlag.tsx +++ b/explorer-v2/src/components/countryFlag/CountryFlag.tsx @@ -1,9 +1,10 @@ import { Stack, Typography, useTheme } from "@mui/material"; import Flag from "react-world-flags"; +import type React from "react"; interface ICountryFlag { countryCode: string; - countryName?: string | JSX.Element; + countryName?: string | React.JSX.Element; } const CountryFlag = ({ countryCode, countryName }: ICountryFlag) => { diff --git a/explorer-v2/src/components/footer/SocialIcon.tsx b/explorer-v2/src/components/footer/SocialIcon.tsx index 3067506d8a..d80cda29d3 100644 --- a/explorer-v2/src/components/footer/SocialIcon.tsx +++ b/explorer-v2/src/components/footer/SocialIcon.tsx @@ -1,9 +1,10 @@ "use client"; +import type React from "react"; import { icons } from "@/utils/getIconByName"; import Image from "next/image"; // import { useMainContext } from "@/context"; -export const SocialIcon = ({ channel }: { channel: string }): JSX.Element => { +export const SocialIcon = ({ channel }: { channel: string }): React.JSX.Element => { // const { mode } = useMainContext(); const modeType = "light"; diff --git a/explorer-v2/src/components/header/Switch.tsx b/explorer-v2/src/components/header/Switch.tsx index 4e967d1c7e..8fb5c0ff3d 100644 --- a/explorer-v2/src/components/header/Switch.tsx +++ b/explorer-v2/src/components/header/Switch.tsx @@ -52,7 +52,7 @@ export const DarkLightSwitch = styled(Switch)(({ theme }) => ({ }, })); -export const DarkLightSwitchDesktop = (): JSX.Element => { +export const DarkLightSwitchDesktop = (): React.JSX.Element => { const [mode, setMode] = useLocalStorage("mode", "dark"); const toggleMode = () => setMode((m) => (m !== "light" ? "light" : "dark")); diff --git a/lefthook.yml b/lefthook.yml index 734de256a6..ef09e27cf1 100644 --- a/lefthook.yml +++ b/lefthook.yml @@ -43,9 +43,9 @@ pre-commit: commands: check: - root: "explorer-nextjs/" + root: "explorer-v2/" glob: "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc,css}" - run: yarn biome check --write --no-errors-on-unmatched --files-ignore-unknown=true --colors=off {staged_files} + run: pnpm biome check --write --no-errors-on-unmatched --files-ignore-unknown=true --colors=off {staged_files} stage_fixed: true rust-lint: glob: "*.rs" diff --git a/lerna.json b/lerna.json index 053f72e27e..eaebf0e4c9 100644 --- a/lerna.json +++ b/lerna.json @@ -1,3 +1,4 @@ { - "version": "independent" + "version": "independent", + "npmClient": "pnpm" } diff --git a/nym-browser-extension/.gitignore b/nym-browser-extension/.gitignore deleted file mode 100644 index 19ec59dff0..0000000000 --- a/nym-browser-extension/.gitignore +++ /dev/null @@ -1,14 +0,0 @@ -dist/ -build/ -**/*.wasm -**/*.js.map -.env* -!.env.example -.vscode/ -.idea/ -*.swp -*.swo -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* diff --git a/nym-browser-extension/README.md b/nym-browser-extension/README.md deleted file mode 100644 index 1479abd955..0000000000 --- a/nym-browser-extension/README.md +++ /dev/null @@ -1,125 +0,0 @@ -# Nym Browser Extension Storage - -A WebAssembly-based storage component for securely managing mnemonics in extensions. This component provides encrypted storage functionality using IndexedDB with password-based encryption. - -## Overview - -This storage component is built in Rust and compiled to WebAssembly, providing: - -- **Secure mnemonic storage**: Password-encrypted storage of BIP39 mnemonics -- **IndexedDB integration**: Browser-native persistent storage -- **Multiple account support**: Store and manage multiple mnemonic phrases with custom names -- **Type-safe API**: Promise-based JavaScript API with proper error handling - -## Getting Started - -### Prerequisites - -- Rust (latest stable) -- `wasm-pack` tool for building WebAssembly -- Node.js (for the demo server) - -### Building - -```bash -cd storage -make wasm-pack -``` - -This will compile the Rust code to WebAssembly and generate the necessary JavaScript bindings. - -### Example Usage - -See the [internal-dev example](./storage/internal-dev/index.js) for complete usage examples. - -Basic usage: - -```javascript -import init, { ExtensionStorage, set_panic_hook } from "@nymproject/extension-storage" - -// Initialize the WASM module first -await init(); - -// Set up better error handling -set_panic_hook(); - -// Create storage instance with password -const storage = await new ExtensionStorage("your-secure-password"); - -// Store a mnemonic -const mnemonic = "your twenty four word mnemonic phrase goes here..."; -await storage.store_mnemonic("my-wallet", mnemonic); - -// Read a mnemonic -const retrievedMnemonic = await storage.read_mnemonic("my-wallet"); - -// Check if a mnemonic exists -const exists = await storage.has_mnemonic("my-wallet"); - -// Get all stored mnemonic keys -const allKeys = await storage.get_all_mnemonic_keys(); - -// Remove a mnemonic -await storage.remove_mnemonic("my-wallet"); -``` - -## Development - -To run the internal development example: - -```bash -cd storage - -make demo - -# Option 2: Manual server setup -cd internal-dev && node serve.js - -# Then open http://localhost:8000 in your browser -``` - -**Note**: The demo requires a server that properly serves WASM files with `application/wasm` MIME type. The Node.js server is recommended as it handles MIME types more reliably. - -## API Reference - -### Initialization -- `init()` - **Required**: Initialize the WASM module before using other functions - -### Constructor -- `new ExtensionStorage(password: string)` - Creates a new storage instance with the given password - -### Static Methods -- `ExtensionStorage.exists()` - Check if storage database exists - -### Instance Methods -- `store_mnemonic(name: string, mnemonic: string)` - Store a mnemonic with the given name -- `read_mnemonic(name: string)` - Retrieve a mnemonic by name (returns null if not found) -- `has_mnemonic(name: string)` - Check if a mnemonic with the given name exists -- `get_all_mnemonic_keys()` - Get all stored mnemonic names -- `remove_mnemonic(name: string)` - Remove a mnemonic by name - -### Error Handling -- `set_panic_hook()` - Set up better stack traces for Rust panics in development - -## Security Features - -- **Password-based encryption**: All data is encrypted using the provided password -- **BIP39 validation**: Mnemonics are validated before storage -- **Secure memory handling**: Sensitive data is zeroed from memory when no longer needed -- **Browser sandbox**: Runs within the browser's security model - -## Architecture - -The storage component consists of: - -- **Rust core** (`src/storage.rs`): Main storage implementation with encryption -- **WASM bindings** (`src/lib.rs`): WebAssembly interface layer -- **Error handling** (`src/error.rs`): Comprehensive error types -- **Build configuration** (`Cargo.toml`, `Makefile`): Build and dependency management - -## Important Notes - -1. **WASM Initialization**: Always call `await init()` before using any other functions -2. **MIME Types**: The demo requires a server that properly serves WASM files -3. **Browser Compatibility**: Requires modern browsers with WebAssembly support -4. **Module Loading**: Uses ES modules - ensure your build system supports them diff --git a/nym-browser-extension/storage/.cargo/config.toml b/nym-browser-extension/storage/.cargo/config.toml deleted file mode 100644 index 33e7edcb17..0000000000 --- a/nym-browser-extension/storage/.cargo/config.toml +++ /dev/null @@ -1,4 +0,0 @@ -[build] -target = "wasm32-unknown-unknown" -target_arch = "wasm32" -rustflags = ["--cfg=getrandom_backend=\"wasm_js\""] diff --git a/nym-browser-extension/storage/.gitignore b/nym-browser-extension/storage/.gitignore deleted file mode 100644 index 821d2e38f2..0000000000 --- a/nym-browser-extension/storage/.gitignore +++ /dev/null @@ -1,36 +0,0 @@ -pkg -target -Cargo.lock - -*.wasm -*.js -*.ts -*.d.ts - -.vscode/ -.idea/ -*.swp -*.swo -*~ - -.DS_Store -.DS_Store? -._* -.Spotlight-V100 -.Trashes -ehthumbs.db -Thumbs.db - -node_modules/ -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -.env -.env.local -.env.development.local -.env.test.local -.env.production.local - - -internal-dev/wasm/ \ No newline at end of file diff --git a/nym-browser-extension/storage/Cargo.toml b/nym-browser-extension/storage/Cargo.toml deleted file mode 100644 index 5ee0d1b961..0000000000 --- a/nym-browser-extension/storage/Cargo.toml +++ /dev/null @@ -1,37 +0,0 @@ -[package] -name = "extension-storage" -description = "WebAssembly-based secure storage for browser extension mnemonics" -version = "1.4.1" -authors = ["Nym Technologies SA "] -edition = "2024" -license = "Apache-2.0" -repository = "https://github.com/nymtech/nym" -publish = false - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -crate-type = ["cdylib", "rlib"] - -[dependencies] -bip39 = { workspace = true } -zeroize = { workspace = true } - -js-sys = { workspace = true } -wasm-bindgen = { workspace = true } -wasm-bindgen-futures = { workspace = true } -serde-wasm-bindgen = { workspace = true } - -thiserror = { workspace = true } - -console_error_panic_hook = { workspace = true, optional = true } - -nym-wasm-utils = { workspace = true } -nym-wasm-storage = { workspace = true } - - -#[package.metadata.wasm-pack.profile.release] -#wasm-opt = false - -[features] -default = ["console_error_panic_hook"] diff --git a/nym-browser-extension/storage/Makefile b/nym-browser-extension/storage/Makefile deleted file mode 100644 index 137652b242..0000000000 --- a/nym-browser-extension/storage/Makefile +++ /dev/null @@ -1,65 +0,0 @@ -# Nym Extension Storage - Build Configuration -# -# This Makefile helps build the WebAssembly storage component -# and run development examples. - -wasm-pack: - @echo "🔨 Building WebAssembly package..." - unset RUSTC_WRAPPER && wasm-pack build --target web --scope nymproject --out-dir ../../dist/wasm/extension-storage - @echo "✅ Build complete! Output in ../../dist/wasm/extension-storage" - -wasm-pack-dev: - @echo "🔨 Building WebAssembly package (development mode)..." - unset RUSTC_WRAPPER && wasm-pack build --dev --target web --scope nymproject --out-dir ../../dist/wasm/extension-storage - @echo "✅ Development build complete!" - - -copy-wasm-to-demo: - @echo "📁 Copying WASM files to demo directory..." - @mkdir -p internal-dev/wasm - @cp ../../dist/wasm/extension-storage/extension_storage.js internal-dev/wasm/ - @cp ../../dist/wasm/extension-storage/extension_storage_bg.wasm internal-dev/wasm/ - @cp ../../dist/wasm/extension-storage/extension_storage.d.ts internal-dev/wasm/ - @echo "✅ WASM files copied to internal-dev/wasm/" - - -clean: - @echo "🧹 Cleaning build artifacts..." - cargo clean - rm -rf ../../dist/wasm/extension-storage - rm -rf pkg - rm -rf internal-dev/wasm - @echo "✅ Clean complete!" - -demo: wasm-pack-dev copy-wasm-to-demo - cd internal-dev && node serve.js - - -check-deps: - @echo "🔍 Checking dependencies..." - @command -v cargo >/dev/null 2>&1 || { echo "❌ cargo is required but not installed. Please install Rust."; exit 1; } - @command -v wasm-pack >/dev/null 2>&1 || { echo "❌ wasm-pack is required but not installed. Run: cargo install wasm-pack"; exit 1; } - @echo "✅ All dependencies are installed!" - -help: - @echo "Nym Extension Storage Build Commands:" - @echo "" - @echo "📦 Building:" - @echo " make wasm-pack - Build optimized WASM package for production" - @echo " make wasm-pack-dev - Build WASM package with debug symbols" - @echo " make copy-wasm-to-demo - Copy WASM files to demo directory" - @echo "" - @echo "🧪 Development:" - @echo " make demo - Build and serve the interactive demo (Node.js)" - @echo " make check-deps - Verify all required tools are installed" - @echo "" - @echo "🧹 Maintenance:" - @echo " make clean - Remove all build artifacts" - @echo " make help - Show this help message" - @echo "" - @echo "💡 Quick start: make demo" - - -.DEFAULT_GOAL := help - -.PHONY: wasm-pack wasm-pack-dev copy-wasm-to-demo clean demo check-deps help diff --git a/nym-browser-extension/storage/internal-dev/index.html b/nym-browser-extension/storage/internal-dev/index.html deleted file mode 100644 index bcbf4bbd53..0000000000 --- a/nym-browser-extension/storage/internal-dev/index.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - Nym Extension Storage - Demo - - - -
-

🚀 Nym Extension Storage Demo

- -
- ⚠️ Demo Environment
- This is a development demo. The mnemonics used here are for testing only and should never be used in production. -
- -
- 📋 How to use this demo:
- 1. Open your browser's developer console (F12)
- 2. The demo will run automatically when the page loads
- 3. You can also use the interactive functions shown below
- 4. Check the IndexedDB in your browser's dev tools to see stored data -
- -
- ✅ What this demo shows:
- • Creating encrypted storage instances
- • Storing and retrieving BIP39 mnemonics
- • Managing multiple wallets
- • Error handling for invalid data
- • Cleaning up stored data -
- -

Interactive Functions

-

Open the browser console and try these commands:

- -
- // Create a storage instance
- const storage = await window.nymStorageDemo.createStorage();
-
- // Run a quick test
- await window.nymStorageDemo.quickTest(storage);
-
- // Access test mnemonics
- console.log(window.nymStorageDemo.mnemonics);
-
- // Manual operations
- await storage.store_mnemonic("my-wallet", "your mnemonic here...");
-
- const mnemonic = await storage.read_mnemonic("my-wallet");
- const exists = await storage.has_mnemonic("my-wallet");
- const allKeys = await storage.get_all_mnemonic_keys();
- await storage.remove_mnemonic("my-wallet"); -
- -
- - -
- -

Architecture Overview

-

This storage component uses:

-
    -
  • Rust/WASM - Core storage logic compiled to WebAssembly
  • -
  • IndexedDB - Browser-native persistent storage
  • -
  • AES Encryption - Password-based encryption for sensitive data
  • -
  • BIP39 Validation - Ensures mnemonic phrases are valid
  • -
- -
- 🔒 Security Notes:
- • All data is encrypted with your password before storage
- • Mnemonics are validated against BIP39 standards
- • Sensitive data is zeroed from memory when no longer needed
- • Storage is isolated per browser origin -
-
- - - - - \ No newline at end of file diff --git a/nym-browser-extension/storage/internal-dev/index.js b/nym-browser-extension/storage/internal-dev/index.js deleted file mode 100644 index 86e2ea016f..0000000000 --- a/nym-browser-extension/storage/internal-dev/index.js +++ /dev/null @@ -1,303 +0,0 @@ -/** - * Nym Extension Storage - Internal Development Example - * - * This file demonstrates how to use the ExtensionStorage WASM module - * for securely storing and managing BIP39 mnemonics in browser extensions. - * - * To run this example: - * 1. Build the WASM module: `cd .. && make wasm-pack` - * 2. Serve this directory: `python3 -m http.server 8000` - * 3. Open http://localhost:8000 in your browser - * 4. Open the browser's developer console to see the output - */ - -import init, { - ExtensionStorage, - set_panic_hook -} from "./wasm/extension_storage.js" - -/** - * Test mnemonics for demonstration - * Note: These are for testing only - never use these in production! - */ -const TEST_MNEMONICS = { - valid: { - wallet1: "figure aspect pill salute review sponsor army city muffin engine army kid rival chunk unit insect blouse paddle velvet shallow box crawl grace never", - wallet2: "salmon picture danger pill tomato hour hand chaos tray bargain frequent fuel scheme coil divert season lucky ginger mom stem mistake blanket lake suffer", - wallet3: "cat quiz circle letter trade unhappy quarter garlic sting gravity zone stock scatter merge account barrel forward fame club chest camp under crop connect", - wallet4: "mammal fashion rice two marble high brain achieve first harsh infant timber flush cloud hunt address brand immune tip identify aspect call beyond once" - }, - invalid: "this is not a valid mnemonic phrase" -}; - -const STORAGE_PASSWORD = "my-super-secure-password-123"; - -/** - * Helper function to log results with better formatting - */ -function logResult(operation, result, error = null) { - const timestamp = new Date().toISOString(); - console.group(`🔍 [${timestamp}] ${operation}`); - - if (error) { - console.error("❌ Error:", error); - } else { - console.log("✅ Result:", result); - } - - console.groupEnd(); -} - -/** - * Test basic storage operations - */ -async function testBasicOperations(storage) { - console.log("\n📦 Testing Basic Storage Operations"); - console.log("=" .repeat(50)); - - // Test storing a valid mnemonic - try { - await storage.store_mnemonic("test-wallet", TEST_MNEMONICS.valid.wallet1); - logResult("Store valid mnemonic", "Successfully stored"); - } catch (error) { - logResult("Store valid mnemonic", null, error); - } - - // Test reading the stored mnemonic - try { - const result = await storage.read_mnemonic("test-wallet"); - logResult("Read stored mnemonic", result); - } catch (error) { - logResult("Read stored mnemonic", null, error); - } - - // Test reading a non-existent mnemonic - try { - const result = await storage.read_mnemonic("non-existent"); - logResult("Read non-existent mnemonic", result); - } catch (error) { - logResult("Read non-existent mnemonic", null, error); - } - - // Test storing an invalid mnemonic - try { - await storage.store_mnemonic("invalid-wallet", TEST_MNEMONICS.invalid); - logResult("Store invalid mnemonic", "Should not reach here"); - } catch (error) { - logResult("Store invalid mnemonic", null, error.toString()); - } - - // Clean up - try { - await storage.remove_mnemonic("test-wallet"); - logResult("Remove test wallet", "Successfully removed"); - } catch (error) { - logResult("Remove test wallet", null, error); - } -} - -/** - * Test multiple wallet management - */ -async function testMultipleWallets(storage) { - console.log("\n👥 Testing Multiple Wallet Management"); - console.log("=" .repeat(50)); - - // Store multiple wallets - const walletNames = Object.keys(TEST_MNEMONICS.valid); - const walletMnemonics = Object.values(TEST_MNEMONICS.valid); - - for (let i = 0; i < walletNames.length; i++) { - try { - await storage.store_mnemonic(walletNames[i], walletMnemonics[i]); - logResult(`Store wallet: ${walletNames[i]}`, "Success"); - } catch (error) { - logResult(`Store wallet: ${walletNames[i]}`, null, error); - } - } - - // Get all wallet keys - try { - const allKeys = await storage.get_all_mnemonic_keys(); - logResult("Get all wallet keys", allKeys); - } catch (error) { - logResult("Get all wallet keys", null, error); - } - - // Check if specific wallets exist - for (const walletName of walletNames) { - try { - const exists = await storage.has_mnemonic(walletName); - logResult(`Check wallet exists: ${walletName}`, exists); - } catch (error) { - logResult(`Check wallet exists: ${walletName}`, null, error); - } - } - - // Read each wallet - for (const walletName of walletNames) { - try { - const mnemonic = await storage.read_mnemonic(walletName); - logResult(`Read wallet: ${walletName}`, `${mnemonic.substring(0, 20)}...`); - } catch (error) { - logResult(`Read wallet: ${walletName}`, null, error); - } - } -} - -/** - * Test wallet removal and cleanup - */ -async function testWalletRemoval(storage) { - console.log("\n🗑️ Testing Wallet Removal"); - console.log("=" .repeat(50)); - - const walletNames = Object.keys(TEST_MNEMONICS.valid); - - // Remove wallets one by one - for (const walletName of walletNames) { - try { - await storage.remove_mnemonic(walletName); - logResult(`Remove wallet: ${walletName}`, "Success"); - } catch (error) { - logResult(`Remove wallet: ${walletName}`, null, error); - } - - // Verify removal - try { - const exists = await storage.has_mnemonic(walletName); - logResult(`Verify removal: ${walletName}`, `Exists: ${exists}`); - } catch (error) { - logResult(`Verify removal: ${walletName}`, null, error); - } - } - - // Check final state - try { - const allKeys = await storage.get_all_mnemonic_keys(); - logResult("Final wallet count", `${allKeys.length} wallets remaining`); - } catch (error) { - logResult("Final wallet count", null, error); - } -} - -/** - * Test storage existence check - */ -async function testStorageExistence() { - console.log("\n💾 Testing Storage Existence"); - console.log("=" .repeat(50)); - - try { - const exists = await ExtensionStorage.exists(); - logResult("Storage database exists", exists); - } catch (error) { - logResult("Storage database exists", null, error); - } -} - -/** - * Main demonstration function - */ -async function runDemo() { - console.log("🚀 Nym Extension Storage Demo"); - console.log("=" .repeat(60)); - console.log("This demo shows how to use the ExtensionStorage WASM module"); - console.log("Check the browser console for detailed output\n"); - - try { - // Initialize the WASM module - console.log("🔧 Initializing WASM module..."); - await init(); - console.log("✅ WASM module initialized successfully\n"); - - // Set up better stack traces for Rust panics - set_panic_hook(); - } catch (error) { - console.error("💥 Failed to initialize WASM module:", error); - return; - } - - // Test storage existence before creating instance - await testStorageExistence(); - - try { - // Create storage instance with password - console.log("🔐 Creating storage instance with password..."); - const storage = await new ExtensionStorage(STORAGE_PASSWORD); - console.log("✅ Storage instance created successfully\n"); - - // Run all tests - await testBasicOperations(storage); - await testMultipleWallets(storage); - await testWalletRemoval(storage); - - // Test storage existence after operations - await testStorageExistence(); - - console.log("\n🎉 Demo completed successfully!"); - console.log("Check the IndexedDB in your browser's developer tools to see the stored data."); - - } catch (error) { - console.error("💥 Fatal error during demo:", error); - } -} - -/** - * Additional utility functions for interactive testing - */ -window.nymStorageDemo = { - /** - * Create a new storage instance for manual testing - */ - async createStorage(password = STORAGE_PASSWORD) { - try { - await init(); - set_panic_hook(); - return await new ExtensionStorage(password); - } catch (error) { - console.error("Failed to initialize WASM or create storage:", error); - throw error; - } - }, - - /** - * Quick test with a storage instance - */ - async quickTest(storage, name = "test", mnemonic = TEST_MNEMONICS.valid.wallet1) { - console.log(`Testing with wallet: ${name}`); - - await storage.store_mnemonic(name, mnemonic); - console.log("✅ Stored"); - - const retrieved = await storage.read_mnemonic(name); - console.log("✅ Retrieved:", retrieved); - - const exists = await storage.has_mnemonic(name); - console.log("✅ Exists:", exists); - - await storage.remove_mnemonic(name); - console.log("✅ Removed"); - - return "Test completed"; - }, - - /** - * Available test mnemonics - */ - mnemonics: TEST_MNEMONICS -}; - -// Start the demo when the page loads -document.addEventListener('DOMContentLoaded', () => { - console.log("📚 Interactive Demo Functions Available:"); - console.log("- window.nymStorageDemo.createStorage() - Create storage instance"); - console.log("- window.nymStorageDemo.quickTest(storage) - Run quick test"); - console.log("- window.nymStorageDemo.mnemonics - Test mnemonic phrases"); - console.log("\nStarting automated demo...\n"); - - runDemo(); -}); - -// Export for module usage -export { runDemo, TEST_MNEMONICS, STORAGE_PASSWORD }; \ No newline at end of file diff --git a/nym-browser-extension/storage/src/error.rs b/nym-browser-extension/storage/src/error.rs deleted file mode 100644 index 88f3a60582..0000000000 --- a/nym-browser-extension/storage/src/error.rs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use nym_wasm_storage::error::StorageError; -use nym_wasm_utils::wasm_error; -use thiserror::Error; - -#[derive(Debug, Error)] -pub enum ExtensionStorageError { - #[error("serialization failure: {source}")] - JsonError { - #[from] - source: serde_wasm_bindgen::Error, - }, - - #[error("failed to use the storage: {source}")] - StorageError { - #[from] - source: StorageError, - }, - - #[error("there's already a stored mnemonic with name {name}")] - DuplicateMnemonic { name: String }, - - #[error("the provided mnemonic is malformed: {source}")] - InvalidMnemonic { - #[from] - source: bip39::Error, - }, -} - -wasm_error!(ExtensionStorageError); diff --git a/nym-browser-extension/storage/src/lib.rs b/nym-browser-extension/storage/src/lib.rs deleted file mode 100644 index 94e5809cc8..0000000000 --- a/nym-browser-extension/storage/src/lib.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -#[cfg(target_arch = "wasm32")] -pub mod error; - -#[cfg(target_arch = "wasm32")] -pub mod storage; - -#[cfg(target_arch = "wasm32")] -pub use error::ExtensionStorageError; - -#[cfg(target_arch = "wasm32")] -pub use storage::ExtensionStorage; - -#[cfg(target_arch = "wasm32")] -pub use nym_wasm_utils::set_panic_hook; diff --git a/nym-browser-extension/storage/src/storage.rs b/nym-browser-extension/storage/src/storage.rs deleted file mode 100644 index 88c93eaa59..0000000000 --- a/nym-browser-extension/storage/src/storage.rs +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -// I'm not convinced by the lint (on Arc). -// Sure. wasm is currently single threaded and does not require `Send` or `Sync` -// but this data is moved across futures, so imo we should leave the Arc as it is, -// because it might cause us headache in the future -#![allow(clippy::arc_with_non_send_sync)] - -use crate::ExtensionStorageError; -use js_sys::Promise; -use nym_wasm_storage::RawDbResult; -use nym_wasm_storage::{Build, Database, VersionChangeEvent, WasmStorage}; -use nym_wasm_utils::check_promise_result; -use nym_wasm_utils::error::{PromisableResult, PromisableResultError}; -use std::sync::Arc; -use wasm_bindgen::prelude::*; -use wasm_bindgen_futures::future_to_promise; -use zeroize::Zeroizing; - -const STORAGE_NAME: &str = "nym-extension-storage"; -const STORAGE_VERSION: u32 = 1; - -// v1 tables -mod v1 { - // stores - pub const MNEMONICS_STORE: &str = "mnemonics"; -} - -#[wasm_bindgen] -#[derive(Clone)] -pub struct ExtensionStorage { - inner: Arc, -} - -#[allow(clippy::type_complexity)] -fn db_migration() -> Box RawDbResult<()>> { - Box::new(|evt: VersionChangeEvent, db: Database| -> RawDbResult<()> { - // Even if the web-sys bindings expose the version as a f64, the IndexedDB API - // works with an unsigned integer. - // See - let old_version = evt.old_version() as u32; - - if old_version < 1 { - // migrating to version 1 - db.create_object_store(v1::MNEMONICS_STORE).build()?; - } - - Ok(()) - }) -} - -#[wasm_bindgen] -impl ExtensionStorage { - pub(crate) async fn new_async(passphrase: String) -> Result { - // make sure the password is zeroized when no longer used, especially if we error out. - // special care must be taken on JS side to ensure it's correctly used there. - let passphrase = Zeroizing::new(passphrase); - - let pass_ref: &str = passphrase.as_ref(); - - let inner = WasmStorage::new( - STORAGE_NAME, - STORAGE_VERSION, - Some(db_migration()), - Some(pass_ref.as_bytes()), - ) - .await?; - - Ok(ExtensionStorage { - inner: Arc::new(inner), - }) - } - - #[wasm_bindgen(constructor)] - #[allow(clippy::new_ret_no_self)] - pub fn new(passphrase: String) -> Promise { - future_to_promise(async move { Self::new_async(passphrase).await.into_promise_result() }) - } - - pub(crate) async fn exists_async() -> Result { - Ok(WasmStorage::exists(STORAGE_NAME).await?) - } - - pub fn exists() -> Promise { - future_to_promise(async move { Self::exists_async().await.into_promise_result() }) - } - - async fn store_mnemonic_async( - &self, - name: String, - value: &bip39::Mnemonic, - ) -> Result<(), ExtensionStorageError> { - self.inner - .store_value(v1::MNEMONICS_STORE, JsValue::from_str(&name), value) - .await - .map_err(Into::into) - } - - async fn read_mnemonic_async( - &self, - name: String, - ) -> Result, ExtensionStorageError> { - self.inner - .read_value(v1::MNEMONICS_STORE, JsValue::from_str(&name)) - .await - .map_err(Into::into) - } - - async fn remove_mnemonic_async(&self, name: String) -> Result<(), ExtensionStorageError> { - self.inner - .remove_value(v1::MNEMONICS_STORE, JsValue::from_str(&name)) - .await - .map_err(Into::into) - } - - async fn has_mnemonic_async(&self, name: String) -> Result { - self.inner - .has_value(v1::MNEMONICS_STORE, JsValue::from_str(&name)) - .await - .map_err(Into::into) - } - - async fn get_all_mnemonic_keys_async(&self) -> Result, ExtensionStorageError> { - self.inner - .get_all_keys(v1::MNEMONICS_STORE) - .await - .map_err(Into::into) - } - - #[wasm_bindgen] - pub fn store_mnemonic(&self, name: String, value: String) -> Promise { - let wrapped = Zeroizing::new(value); - let inner: &str = wrapped.as_ref(); - - let mnemonic = check_promise_result!( - bip39::Mnemonic::parse(inner).map_err(ExtensionStorageError::from) - ); - - // this clones the Arc pointer - let this = self.clone(); - future_to_promise(async move { - this.store_mnemonic_async(name, &mnemonic) - .await - .map(|_| JsValue::null()) - .map_promise_err() - }) - } - - #[wasm_bindgen] - pub fn read_mnemonic(&self, name: String) -> Promise { - // this clones the Arc pointer - let this = self.clone(); - future_to_promise(async move { - let maybe_mnemonic = this.read_mnemonic_async(name).await?; - Ok(serde_wasm_bindgen::to_value(&maybe_mnemonic)?) - }) - } - - #[wasm_bindgen] - pub fn remove_mnemonic(&self, name: String) -> Promise { - // this clones the Arc pointer - let this = self.clone(); - future_to_promise(async move { - this.remove_mnemonic_async(name) - .await - .map(|_| JsValue::null()) - .map_promise_err() - }) - } - - #[wasm_bindgen] - pub fn has_mnemonic(&self, name: String) -> Promise { - // this clones the Arc pointer - let this = self.clone(); - future_to_promise(async move { this.has_mnemonic_async(name).await.into_promise_result() }) - } - - #[wasm_bindgen] - pub fn get_all_mnemonic_keys(&self) -> Promise { - // this clones the Arc pointer - let this = self.clone(); - future_to_promise(async move { - this.get_all_mnemonic_keys_async() - .await - .into_promise_result() - }) - } -} diff --git a/nym-node/tests/package.json b/nym-node/tests/package.json index 18e97e5bcf..3a14e1bb67 100644 --- a/nym-node/tests/package.json +++ b/nym-node/tests/package.json @@ -11,7 +11,7 @@ "test:prod": "TEST_ENV=prod jest --forceExit --detectOpenHandles --passWithNoTests", "build": "tsc", "lint": "eslint --fix --ext .js,.ts,.tsx .", - "cleanup": "rm -rf node_modules; rm -rf dist; yarn install" + "cleanup": "rm -rf node_modules; rm -rf dist; pnpm install" }, "author": "Nymtech", "license": "MIT", diff --git a/nym-wallet/.nvmrc b/nym-wallet/.nvmrc index b087cc9af8..cabf43b5dd 100644 --- a/nym-wallet/.nvmrc +++ b/nym-wallet/.nvmrc @@ -1 +1 @@ -22.13.0 \ No newline at end of file +24 \ No newline at end of file diff --git a/nym-wallet/package.json b/nym-wallet/package.json index 09541d0e09..72b9576dc5 100644 --- a/nym-wallet/package.json +++ b/nym-wallet/package.json @@ -10,133 +10,195 @@ "dev": "run-p tauri:dev webpack:dev", "lint": "eslint src", "lint:fix": "eslint src --fix", - "prebuild": "yarn --cwd .. build", - "prewebpack:dev": "yarn --cwd .. build", - "prewebpack:prod": "yarn check:singletons", + "prebuild": "pnpm --dir .. run build", + "prewebpack:dev": "pnpm --dir .. run build", + "prewebpack:prod": "pnpm run check:singletons", "check:singletons": "node scripts/check-mui-singletons.js", - "tauri:build": "yarn tauri build", - "tauri:build:no-sign": "yarn tauri build --no-sign -b app", - "tauri:build:adhoc": "APPLE_SIGNING_IDENTITY=- yarn tauri build -b app", - "tauri:dev": "yarn tauri dev", - "tauri:buildx86": "yarn tauri build --target x86_64-apple-darwin", + "tauri:build": "tauri build", + "tauri:build:no-sign": "tauri build --no-sign -b app", + "tauri:build:adhoc": "APPLE_SIGNING_IDENTITY=- tauri build -b app", + "tauri:dev": "tauri dev", + "tauri:buildx86": "tauri build --target x86_64-apple-darwin", "test": "jest --config jest.config.cjs", "tsc": "tsc --noEmit true", "tsc:watch": "tsc --noEmit true --watch", - "webpack:dev": "yarn webpack serve --config webpack.dev.js", - "webpack:prod": "yarn webpack --progress --config webpack.prod.js" + "webpack:dev": "webpack serve --config webpack.dev.js", + "webpack:prod": "webpack --progress --config webpack.prod.js" }, "dependencies": { - "@babel/helper-simple-access": "^7.25.9", - "@emotion/cache": "^11.14.0", - "@emotion/react": "^11.7.0", - "@emotion/styled": "^11.6.0", - "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0", - "@hookform/resolvers": "^2.8.0", - "@mui/icons-material": "^5.2.0", - "@mui/material": "^5.2.2", - "@mui/styles": "^5.18.0", - "@mui/utils": "^5.7.0", - "@nymproject/node-tester": "^1.3.1", - "@nymproject/react": "^1.0.0", - "@nymproject/types": "^1.0.0", - "@tanstack/react-query": "^5.62.0", - "@tauri-apps/api": "^2.10.1", - "@tauri-apps/plugin-clipboard-manager": "^2.3.2", - "@tauri-apps/plugin-opener": "^2.5.3", - "@tauri-apps/plugin-process": "^2.3.1", - "@tauri-apps/plugin-updater": "^2.10.1", - "@tauri-apps/tauri-forage": "^1.0.0-beta.2", - "big.js": "^6.2.1", - "bs58": "^4.0.1", - "clsx": "^1.1.1", - "date-fns": "^2.28.0", - "joi": "^17.11.0", - "lodash": "^4.17.21", - "notistack": "^2.0.3", - "npm-run-all": "^4.1.5", + "@babel/helper-simple-access": "catalog:", + "@babel/runtime": "catalog:", + "@cosmjs/math": "catalog:", + "@emotion/cache": "catalog:", + "@emotion/hash": "catalog:", + "@emotion/is-prop-valid": "catalog:", + "@emotion/memoize": "catalog:", + "@emotion/react": "catalog:", + "@emotion/serialize": "catalog:", + "@emotion/sheet": "catalog:", + "@emotion/styled": "catalog:", + "@emotion/unitless": "catalog:", + "@emotion/use-insertion-effect-with-fallbacks": "catalog:", + "@emotion/utils": "catalog:", + "@emotion/weak-memoize": "catalog:", + "@hookform/resolvers": "catalog:", + "@mui/base": "catalog:", + "@mui/lab": "catalog:", + "@mui/material": "catalog:", + "@mui/private-theming": "catalog:", + "@mui/styles": "catalog:", + "@mui/system": "catalog:", + "@mui/icons-material": "catalog:", + "@mui/utils": "catalog:", + "@nymproject/react": "workspace:*", + "@nymproject/types": "workspace:*", + "@popperjs/core": "catalog:", + "@remix-run/router": "catalog:", + "@tanstack/react-query": "catalog:", + "@tanstack/query-core": "catalog:", + "@tauri-apps/api": "catalog:", + "@tauri-apps/plugin-clipboard-manager": "catalog:", + "@tauri-apps/plugin-opener": "catalog:", + "@tauri-apps/plugin-process": "catalog:", + "@tauri-apps/plugin-updater": "catalog:", + "@tauri-apps/tauri-forage": "catalog:", + "base-x": "catalog:", + "base64-js": "catalog:", + "bech32": "catalog:", + "big.js": "catalog:", + "bn.js": "catalog:", + "bs58": "catalog:", + "buffer": "catalog:", + "clsx": "catalog:", + "clipboard-copy": "catalog:", + "colornames": "catalog:", + "d3-array": "catalog:", + "d3-color": "catalog:", + "d3-format": "catalog:", + "d3-interpolate": "catalog:", + "d3-path": "catalog:", + "d3-scale": "catalog:", + "d3-shape": "catalog:", + "d3-time": "catalog:", + "d3-time-format": "catalog:", + "date-fns": "catalog:", + "decimal.js-light": "catalog:", + "dom-helpers": "catalog:", + "eventemitter3": "catalog:", + "fast-equals": "catalog:", + "hex-rgb": "catalog:", + "hoist-non-react-statics": "catalog:", + "ieee754": "catalog:", + "internmap": "catalog:", + "joi": "catalog:", + "localforage": "catalog:", + "lodash": "catalog:", + "lodash.padend": "catalog:", + "lodash.trimstart": "catalog:", + "lodash.words": "catalog:", + "nanoclone": "catalog:", + "notistack": "catalog:", + "npm-run-all": "catalog:", + "prop-types": "catalog:", + "property-expr": "catalog:", + "qr.js": "catalog:", "qrcode.react": "^1.0.1", - "react": "^19.2.0", - "react-dom": "^19.2.0", - "react-error-boundary": "^3.1.3", - "react-hook-form": "^7.14.2", - "react-router-dom": "6", - "recharts": "^2.1.13", - "semver": "^6.3.0", - "string-to-color": "^2.2.2", - "use-clipboard-copy": "^0.2.0", - "uuid": "^8.3.2", - "yup": "^0.32.9", - "zxcvbn": "^4.4.2" + "ramda": "catalog:", + "react": "catalog:", + "react-dom": "catalog:", + "react-error-boundary": "catalog:", + "react-hook-form": "catalog:", + "react-is": "catalog:", + "react-router": "catalog:", + "react-router-dom": "catalog:", + "react-smooth": "catalog:", + "react-transition-group": "catalog:", + "recharts": "catalog:", + "recharts-scale": "catalog:", + "rgb-hex": "catalog:", + "safe-buffer": "catalog:", + "scheduler": "catalog:", + "semver": "catalog:", + "string-to-color": "catalog:", + "stylis": "catalog:", + "tiny-invariant": "catalog:", + "toposort": "catalog:", + "tweetnacl": "catalog:", + "tweetnacl-util": "catalog:", + "use-clipboard-copy": "catalog:", + "uuid": "catalog:", + "victory-vendor": "catalog:", + "yup": "catalog:", + "zxcvbn": "catalog:" }, "devDependencies": { - "@babel/core": "^7.15.0", - "@babel/plugin-transform-async-to-generator": "^7.14.5", - "@babel/preset-env": "^7.15.0", - "@babel/preset-react": "^7.14.5", - "@babel/preset-typescript": "^7.15.0", - "@nymproject/eslint-config-react-typescript": "^1.0.0", - "@pmmmwh/react-refresh-webpack-plugin": "^0.5.4", - "@svgr/webpack": "^6.1.1", - "@tauri-apps/cli": "^2.10.1", - "@testing-library/dom": "^10.4.1", - "@testing-library/jest-dom": "^6.9.1", - "@testing-library/react": "^16.3.2", - "@types/big.js": "^6.1.6", - "@types/bs58": "^4.0.1", - "@types/jest": "^29.5.14", - "@types/minimatch": "5.1.2", + "@babel/core": "catalog:", + "@babel/plugin-transform-async-to-generator": "catalog:", + "@babel/preset-env": "catalog:", + "@babel/preset-react": "catalog:", + "@babel/preset-typescript": "catalog:", + "@nymproject/webpack": "workspace:*", + "@nymproject/eslint-config-react-typescript": "workspace:*", + "@pmmmwh/react-refresh-webpack-plugin": "catalog:", + "@svgr/webpack": "catalog:", + "@tauri-apps/cli": "catalog:", + "@testing-library/dom": "catalog:", + "@testing-library/jest-dom": "catalog:", + "@testing-library/react": "catalog:", + "@types/big.js": "catalog:", + "@types/bs58": "catalog:", + "@types/jest": "catalog:", + "@types/lodash": "catalog:", + "@types/minimatch": "catalog:", "@types/node": "^22.15.29", - "@types/qrcode.react": "^1.0.2", - "@types/react": "^19.2.14", - "@types/react-dom": "^19.2.3", - "@types/semver": "^7.3.8", - "@types/uuid": "^8.3.4", - "@types/zxcvbn": "^4.4.1", + "@types/qrcode.react": "catalog:", + "@types/react": "catalog:", + "@types/react-dom": "catalog:", + "@types/semver": "catalog:", + "@types/uuid": "catalog:", + "@types/zxcvbn": "catalog:", "@typescript-eslint/eslint-plugin": "^8.56.1", "@typescript-eslint/parser": "^8.56.1", - "babel-loader": "^8.3.0", + "babel-loader": "catalog:", "babel-plugin-root-import": "^6.6.0", - "clean-webpack-plugin": "^4.0.0", - "css-loader": "^6.7.3", - "css-minimizer-webpack-plugin": "^3.0.2", - "dotenv-webpack": "^7.0.3", + "clean-webpack-plugin": "catalog:", + "css-loader": "catalog:", + "css-minimizer-webpack-plugin": "catalog:", + "dotenv-webpack": "catalog:", "eslint": "^8.57.1", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^16.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-react": "^7.29.2", - "eslint-plugin-react-hooks": "^4.3.0", - "favicons": "^7.0.2", - "favicons-webpack-plugin": "^5.0.2", - "file-loader": "^6.2.0", - "fork-ts-checker-webpack-plugin": "^7.2.1", - "html-webpack-plugin": "^5.3.2", - "jest": "^30.3.0", - "mini-css-extract-plugin": "^2.2.2", - "npm-run-all": "^4.1.5", - "prettier": "^2.8.7", - "react-refresh": "^0.10.0", - "react-refresh-typescript": "^2.0.2", - "style-loader": "^3.3.1", - "thread-loader": "^3.0.4", + "eslint-config-airbnb": "catalog:", + "eslint-config-airbnb-typescript": "catalog:", + "eslint-config-prettier": "catalog:", + "eslint-import-resolver-root-import": "catalog:", + "eslint-plugin-import": "catalog:", + "eslint-plugin-jest": "catalog:", + "eslint-plugin-jsx-a11y": "catalog:", + "eslint-plugin-prettier": "catalog:", + "eslint-plugin-react": "catalog:", + "eslint-plugin-react-hooks": "catalog:", + "favicons": "catalog:", + "favicons-webpack-plugin": "catalog:", + "file-loader": "catalog:", + "fork-ts-checker-webpack-plugin": "catalog:", + "html-webpack-plugin": "catalog:", + "jest": "^29.7.0", + "mini-css-extract-plugin": "catalog:", + "npm-run-all": "catalog:", + "prettier": "catalog:", + "react-refresh": "catalog:", + "react-refresh-typescript": "catalog:", + "style-loader": "catalog:", + "thread-loader": "catalog:", "ts-jest": "^29.4.9", - "ts-loader": "^9.4.2", - "tsconfig-paths-webpack-plugin": "^3.5.2", + "ts-loader": "catalog:", + "tsconfig-paths-webpack-plugin": "catalog:", "typescript": "^5.9.3", - "url-loader": "^4.1.1", - "webpack": "^5.75.0", - "webpack-cli": "^4.8.0", - "webpack-dev-server": "^4.5.0", - "webpack-favicons": "^1.3.8", - "webpack-merge": "^5.8.0" - }, - "resolutions": { - "@types/minimatch": "5.1.2" + "url-loader": "catalog:", + "webpack": "catalog:", + "webpack-cli": "catalog:", + "webpack-dev-server": "catalog:", + "webpack-favicons": "catalog:", + "webpack-merge": "catalog:" }, "private": false } diff --git a/nym-wallet/scripts/regenerate-tauri-icons.sh b/nym-wallet/scripts/regenerate-tauri-icons.sh index ed3a75a4c8..69cdd2cf5f 100755 --- a/nym-wallet/scripts/regenerate-tauri-icons.sh +++ b/nym-wallet/scripts/regenerate-tauri-icons.sh @@ -6,7 +6,7 @@ set -euo pipefail ROOT="$(cd "$(dirname "$0")/.." && pwd)" SRC="$ROOT/src-tauri/icons/app-icon-source.png" -yarn --cwd "$ROOT" tauri icon "$SRC" -o "$ROOT/src-tauri/icons" +pnpm --dir "$ROOT" exec tauri icon "$SRC" -o "$ROOT/src-tauri/icons" rm -rf "$ROOT/src-tauri/icons/android" "$ROOT/src-tauri/icons/ios" rm -f "$ROOT/src-tauri/icons"/Square*.png "$ROOT/src-tauri/icons/StoreLogo.png" python3 - <({ isVestingAccount: false, }); -export const BondingContextProvider: FCWithChildren = ({ children }): JSX.Element => { +export const BondingContextProvider: FCWithChildren = ({ children }): React.JSX.Element => { const [isLoading, setIsLoading] = useState(false); const [error, setError] = useState(); diff --git a/nym-wallet/src/context/mocks/bonding.tsx b/nym-wallet/src/context/mocks/bonding.tsx index 234365ee73..565d791cfb 100644 --- a/nym-wallet/src/context/mocks/bonding.tsx +++ b/nym-wallet/src/context/mocks/bonding.tsx @@ -74,7 +74,7 @@ export const MockBondingContextProvider = ({ }: { network?: Network; children?: React.ReactNode; -}): JSX.Element => { +}): React.JSX.Element => { const [isLoading, setIsLoading] = useState(true); const [feeLoading, setFeeLoading] = useState(false); const [fee, setFee] = useState(); diff --git a/nym-wallet/src/pages/bonding/node-settings/node-test/index.tsx b/nym-wallet/src/pages/bonding/node-settings/node-test/index.tsx deleted file mode 100644 index 75203bc09e..0000000000 --- a/nym-wallet/src/pages/bonding/node-settings/node-test/index.tsx +++ /dev/null @@ -1,123 +0,0 @@ -import React, { useCallback, useContext, useEffect, useRef, useState } from 'react'; -import { Box, Button } from '@mui/material'; -import { Download } from '@mui/icons-material'; -import { NodeTestResultResponse, NodeTester, createNodeTesterClient } from '@nymproject/node-tester'; -import { format } from 'date-fns'; -import { AppContext, useBondingContext } from 'src/context'; -import { LoadingModal } from 'src/components/Modals/LoadingModal'; -import { Results } from 'src/components/TestNode/Results'; -import { ErrorModal } from 'src/components/Modals/ErrorModal'; -import { PrintResults } from 'src/components/TestNode/PrintResults'; -import { MAINNET_VALIDATOR_URL } from 'src/constants'; -import { TestStatus } from 'src/components/TestNode/types'; -import { isMixnode } from 'src/types'; - -export const NodeTestPage = () => { - const [nodeTestClient, setNodeTestClient] = useState(); - const [error, setError] = useState(); - const [isLoading, setIsLoading] = useState(false); - const [results, setResults] = useState(); - const [printResults, setPrintResults] = useState(false); - const [testDate, setTestDate] = useState(); - - const testStateRef = useRef('Stopped'); - const timerRef = useRef(null); - - const { network } = useContext(AppContext); - const { bondedNode } = useBondingContext(); - - const handleTestTimeout = () => { - if (timerRef.current) { - clearTimeout(timerRef.current); - } - timerRef.current = setTimeout(() => { - if (testStateRef.current === 'Running') { - setIsLoading(false); - setError('Test has timed out, please try again'); - testStateRef.current = 'Stopped'; - } - }, 15000); - }; - - const handleTestNode = async () => { - if (nodeTestClient && bondedNode && isMixnode(bondedNode)) { - setResults(undefined); - setTestDate(format(new Date(), 'dd/MM/yyyy HH:mm')); - setIsLoading(true); - setError(undefined); - testStateRef.current = 'Running'; - handleTestTimeout(); - try { - const result = await nodeTestClient.tester.startTest(bondedNode.identityKey); - setResults(result); - testStateRef.current = 'Complete'; - } catch (e) { - setError('Node test failed, please try again'); - testStateRef.current = 'Stopped'; - // eslint-disable-next-line no-console - console.log(e); - } finally { - setIsLoading(false); - } - } - }; - - const loadNodeTestClient = useCallback(async () => { - try { - const nodeTesterId = new Date().toISOString(); // make a new tester id for each session - const validator = network === 'MAINNET' ? MAINNET_VALIDATOR_URL : 'https://rpc.nymtech.net/api/'; - const client = await createNodeTesterClient(); - await client.tester.init(validator, nodeTesterId); - setNodeTestClient(client); - } catch (e) { - // eslint-disable-next-line no-console - console.log(e); - setError('Failed to load node tester client, please try again'); - } - }, []); - - useEffect(() => { - loadNodeTestClient(); - - return () => { - if (timerRef.current) { - clearTimeout(timerRef.current); - } - if (nodeTestClient) { - nodeTestClient.tester.disconnectFromGateway(); - nodeTestClient.terminate(); - } - }; - }, [loadNodeTestClient]); - - return ( - - {isLoading && } - {error && setError(undefined)} />} - {printResults && results && bondedNode && isMixnode(bondedNode) && ( - setPrintResults(false)} - /> - )} - - - - - - ); -}; diff --git a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx index 6f8ed79ec9..e3218ac14f 100644 --- a/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx +++ b/nym-wallet/src/pages/bonding/node-settings/settings-pages/general-settings/ParametersSettings.tsx @@ -41,7 +41,7 @@ const operatorCostHint = `This is your (operator) rewards including the PM and c const profitMarginHint = 'PM is the percentage of the node rewards that you as the node operator take before rewards are distributed to the delegators.'; -export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode }): JSX.Element => { +export const ParametersSettings = ({ bondedNode }: { bondedNode: TBondedMixnode }): React.JSX.Element => { const [openConfirmationModal, setOpenConfirmationModal] = useState(false); const [intervalTime, setIntervalTime] = useState(); const [pendingUpdates, setPendingUpdates] = useState(); diff --git a/package.json b/package.json index 3bf14d70ab..e27496154a 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,14 @@ { "name": "@nymproject/nymsphere", "version": "1.0.1", + "packageManager": "pnpm@11.1.2", "license": "Apache 2.0", "scripts": { - "audit:fix": "npm_config_yes=true npx yarn-audit-fix -- --dry-run", + "audit:fix": "pnpm audit --fix", "build": "run-s build:types build:packages", "build:ci": "run-s build:types build:packages build:wasm build:ci:sdk", - "build:ci:sdk": "lerna run --scope '{@nymproject/sdk,@nymproject/node-tester,@nymproject/sdk-react,@nymproject/mix-fetch,@nymproject/nodejs-client,@nymproject/mix-fetch-node}' build --stream", - "build:ci:storybook": "yarn build && yarn dev:on && run-p build:playground && yarn build:ci:storybook:collect-artifacts ", + "build:ci:sdk": "lerna run --scope '{@nymproject/sdk,@nymproject/sdk-react,@nymproject/mix-fetch,@nymproject/nodejs-client,@nymproject/mix-fetch-node}' build --stream", + "build:ci:storybook": "pnpm build && pnpm dev:on && run-p build:playground && pnpm build:ci:storybook:collect-artifacts ", "build:ci:storybook:collect-artifacts": "mkdir -p ts-packages/dist && mv sdk/typescript/packages/react-components/storybook-static ts-packages/dist/storybook ", "build:packages": "run-s build:packages:theme build:packages:react", "build:packages:react": "lerna run --scope @nymproject/react build", @@ -20,11 +21,12 @@ "dev:on": "node sdk/typescript/scripts/dev-mode-add.mjs", "docs:prod:build": "run-s docs:prod:build:ws", "docs:prod:build:ws": "lerna run docs:prod:build --stream", - "lint": "lerna run lint --stream", + "lint": "echo 'linting disabled in preparation of switch to biome'", + "eslint:lint": "lerna run lint --stream", "lint:fix": "lerna run lint:fix --stream", - "nuke": "npx rimraf **/node_modules node_modules", - "postbuild:ci": "yarn dev:off", - "prebuild:ci": "yarn dev:on && yarn", + "nuke": "npx rimraf **/node_modules node_modules dist pkg", + "postbuild:ci": "pnpm dev:off", + "prebuild:ci": "pnpm dev:on && pnpm install --frozen-lockfile false", "scrub": "npx rimraf **/dist dist", "sdk:build": "./sdk/typescript/scripts/build-prod-sdk.sh", "sdk:publish": "./sdk/typescript/scripts/publish.sh", @@ -46,7 +48,24 @@ "tslog": "3.3.3" }, "private": true, - "resolutions": { + "packageExtensions": { + "@cosmos-kit/core@*": { + "dependencies": { + "axios": "*" + } + }, + "@cosmos-kit/keplr-extension@*": { + "dependencies": { + "long": "*" + } + }, + "@nivo/line@*": { + "dependencies": { + "lodash": "*" + } + } + }, + "overrides": { "eslint": "8.57.1", "@cosmjs/amino": "^0.32.4", "@cosmjs/cosmwasm-stargate": "^0.32.4", @@ -62,15 +81,5 @@ "@typescript-eslint/typescript-estree": "5.62.0", "@typescript-eslint/utils": "5.62.0", "cosmjs-types": "^0.9.0" - }, - "workspaces": [ - "ts-packages/*", - "nym-wallet", - "explorer-nextjs", - "explorer-v2", - "types", - "sdk/typescript/packages/mix-fetch/internal-dev", - "sdk/typescript/packages/react-components", - "sdk/typescript/packages/mui-theme" - ] + } } \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml new file mode 100644 index 0000000000..995a3591b3 --- /dev/null +++ b/pnpm-lock.yaml @@ -0,0 +1,31489 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +catalogs: + default: + '@babel/core': + specifier: ^7.22.10 + version: 7.29.0 + '@babel/helper-simple-access': + specifier: ^7.25.9 + version: 7.27.1 + '@babel/plugin-transform-async-to-generator': + specifier: ^7.22.5 + version: 7.28.6 + '@babel/preset-env': + specifier: ^7.22.10 + version: 7.29.5 + '@babel/preset-react': + specifier: ^7.14.5 + version: 7.28.5 + '@babel/preset-typescript': + specifier: ^7.22.5 + version: 7.28.5 + '@babel/runtime': + specifier: ^7.29.2 + version: 7.29.2 + '@cosmjs/cosmwasm-stargate': + specifier: ^0.32.4 + version: 0.32.4 + '@cosmjs/math': + specifier: ^0.32.4 + version: 0.32.4 + '@cosmjs/stargate': + specifier: ^0.32.4 + version: 0.32.4 + '@emotion/cache': + specifier: ^11.14.0 + version: 11.14.0 + '@emotion/hash': + specifier: ^0.9.2 + version: 0.9.2 + '@emotion/is-prop-valid': + specifier: ^1.4.0 + version: 1.4.0 + '@emotion/memoize': + specifier: ^0.9.0 + version: 0.9.0 + '@emotion/react': + specifier: ^11.13.5 + version: 11.14.0 + '@emotion/serialize': + specifier: ^1.3.3 + version: 1.3.3 + '@emotion/sheet': + specifier: ^1.4.0 + version: 1.4.0 + '@emotion/styled': + specifier: ^11.13.5 + version: 11.14.1 + '@emotion/unitless': + specifier: ^0.10.0 + version: 0.10.0 + '@emotion/use-insertion-effect-with-fallbacks': + specifier: ^1.2.0 + version: 1.2.0 + '@emotion/utils': + specifier: ^1.4.2 + version: 1.4.2 + '@emotion/weak-memoize': + specifier: ^0.4.0 + version: 0.4.0 + '@hookform/resolvers': + specifier: ^2.8.0 + version: 2.9.11 + '@mui/base': + specifier: 5.0.0-beta.40 + version: 5.0.0-beta.40 + '@mui/icons-material': + specifier: ^5.2.0 + version: 5.18.0 + '@mui/lab': + specifier: 5.0.0-alpha.170 + version: 5.0.0-alpha.170 + '@mui/material': + specifier: ^5.2.2 + version: 5.18.0 + '@mui/private-theming': + specifier: ^5.17.1 + version: 5.17.1 + '@mui/styles': + specifier: ^5.18.0 + version: 5.18.0 + '@mui/system': + specifier: ^5.18.0 + version: 5.18.0 + '@mui/utils': + specifier: ^5.7.0 + version: 5.17.1 + '@mui/x-tree-view': + specifier: ^7.11.1 + version: 7.29.10 + '@pmmmwh/react-refresh-webpack-plugin': + specifier: ^0.5.4 + version: 0.5.17 + '@popperjs/core': + specifier: ^2.11.8 + version: 2.11.8 + '@remix-run/router': + specifier: ^1.23.2 + version: 1.23.2 + '@storybook/addon-actions': + specifier: ^6.5.8 + version: 6.5.16 + '@storybook/addon-docs': + specifier: ^6.5.8 + version: 6.5.16 + '@storybook/addon-essentials': + specifier: ^6.5.8 + version: 6.5.16 + '@storybook/addon-interactions': + specifier: ^6.5.8 + version: 6.5.16 + '@storybook/addon-links': + specifier: ^6.5.8 + version: 6.5.16 + '@storybook/builder-webpack5': + specifier: ^6.5.8 + version: 6.5.16 + '@storybook/manager-webpack5': + specifier: ^6.5.8 + version: 6.5.16 + '@storybook/react': + specifier: ^6.5.15 + version: 6.5.16 + '@storybook/testing-library': + specifier: ^0.0.9 + version: 0.0.9 + '@svgr/webpack': + specifier: ^6.1.1 + version: 6.5.1 + '@tanstack/query-core': + specifier: ^5.64.2 + version: 5.100.10 + '@tanstack/react-query': + specifier: ^5.64.2 + version: 5.100.10 + '@tauri-apps/api': + specifier: ^2.10.1 + version: 2.10.1 + '@tauri-apps/cli': + specifier: ^2.10.1 + version: 2.11.1 + '@tauri-apps/plugin-clipboard-manager': + specifier: ^2.3.2 + version: 2.3.2 + '@tauri-apps/plugin-opener': + specifier: ^2.5.3 + version: 2.5.4 + '@tauri-apps/plugin-process': + specifier: ^2.3.1 + version: 2.3.1 + '@tauri-apps/plugin-updater': + specifier: ^2.10.1 + version: 2.10.1 + '@tauri-apps/tauri-forage': + specifier: ^1.0.0-beta.2 + version: 1.0.0-beta.2 + '@testing-library/dom': + specifier: ^10.4.1 + version: 10.4.1 + '@testing-library/jest-dom': + specifier: ^6.9.1 + version: 6.9.1 + '@testing-library/react': + specifier: ^16.3.2 + version: 16.3.2 + '@types/big.js': + specifier: ^6.1.6 + version: 6.2.2 + '@types/bs58': + specifier: ^4.0.1 + version: 4.0.4 + '@types/flat': + specifier: ^5.0.2 + version: 5.0.5 + '@types/jest': + specifier: ^29.5.14 + version: 29.5.14 + '@types/lodash': + specifier: ^4.17.21 + version: 4.17.24 + '@types/minimatch': + specifier: 5.1.2 + version: 5.1.2 + '@types/qrcode.react': + specifier: ^1.0.2 + version: 1.0.5 + '@types/react': + specifier: ^19.2.14 + version: 19.2.14 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3 + '@types/semver': + specifier: ^7.3.8 + version: 7.7.1 + '@types/uuid': + specifier: ^8.3.4 + version: 8.3.4 + '@types/zxcvbn': + specifier: ^4.4.1 + version: 4.4.5 + '@typescript-eslint/eslint-plugin': + specifier: ^5.13.0 + version: 5.62.0 + '@typescript-eslint/parser': + specifier: ^5.13.0 + version: 5.62.0 + axios: + specifier: ^1.16.0 + version: 1.16.0 + babel-loader: + specifier: ^8.3.0 + version: 8.4.1 + base-x: + specifier: ^3.0.11 + version: 3.0.11 + base64-js: + specifier: ^1.5.1 + version: 1.5.1 + bech32: + specifier: ^1.1.4 + version: 1.1.4 + big.js: + specifier: ^6.2.1 + version: 6.2.2 + bn.js: + specifier: ^5.2.3 + version: 5.2.3 + bs58: + specifier: ^4.0.1 + version: 4.0.1 + buffer: + specifier: ^6.0.3 + version: 6.0.3 + clean-webpack-plugin: + specifier: ^4.0.0 + version: 4.0.0 + clipboard-copy: + specifier: ^3.2.0 + version: 3.2.0 + clsx: + specifier: ^1.1.1 + version: 1.2.1 + colornames: + specifier: ^1.1.1 + version: 1.1.1 + css-loader: + specifier: ^6.8.1 + version: 6.11.0 + css-minimizer-webpack-plugin: + specifier: ^3.0.2 + version: 3.4.1 + d3-array: + specifier: ^3.2.4 + version: 3.2.4 + d3-color: + specifier: ^3.1.0 + version: 3.1.0 + d3-format: + specifier: ^1.4.5 + version: 1.4.5 + d3-interpolate: + specifier: ^3.0.1 + version: 3.0.1 + d3-path: + specifier: ^3.1.0 + version: 3.1.0 + d3-scale: + specifier: ^4.0.2 + version: 4.0.2 + d3-shape: + specifier: ^3.2.0 + version: 3.2.0 + d3-time: + specifier: ^3.1.0 + version: 3.1.0 + d3-time-format: + specifier: ^3.0.0 + version: 3.0.0 + date-fns: + specifier: ^2.28.0 + version: 2.30.0 + decimal.js-light: + specifier: ^2.5.1 + version: 2.5.1 + dom-helpers: + specifier: ^5.2.1 + version: 5.2.1 + dotenv-webpack: + specifier: ^7.0.3 + version: 7.1.1 + eslint: + specifier: ^9.26.0 + version: 9.39.4 + eslint-config-airbnb: + specifier: ^19.0.4 + version: 19.0.4 + eslint-config-airbnb-typescript: + specifier: ^16.1.0 + version: 16.2.0 + eslint-config-prettier: + specifier: ^8.5.0 + version: 8.10.2 + eslint-import-resolver-root-import: + specifier: ^1.0.4 + version: 1.0.4 + eslint-plugin-import: + specifier: ^2.25.4 + version: 2.32.0 + eslint-plugin-jest: + specifier: ^26.1.1 + version: 26.9.0 + eslint-plugin-jsx-a11y: + specifier: ^6.5.1 + version: 6.10.2 + eslint-plugin-prettier: + specifier: ^4.0.0 + version: 4.2.5 + eslint-plugin-react: + specifier: ^7.29.2 + version: 7.37.5 + eslint-plugin-react-hooks: + specifier: ^4.3.0 + version: 4.6.2 + eslint-plugin-storybook: + specifier: ^0.5.12 + version: 0.5.13 + eventemitter3: + specifier: ^4.0.7 + version: 4.0.7 + fast-equals: + specifier: ^5.4.0 + version: 5.4.0 + favicons: + specifier: ^7.0.2 + version: 7.2.0 + favicons-webpack-plugin: + specifier: ^5.0.2 + version: 5.0.2 + file-loader: + specifier: ^6.2.0 + version: 6.2.0 + flat: + specifier: ^5.0.2 + version: 5.0.2 + fork-ts-checker-webpack-plugin: + specifier: ^7.2.1 + version: 7.3.0 + hex-rgb: + specifier: ^4.3.0 + version: 4.3.0 + hoist-non-react-statics: + specifier: ^3.3.2 + version: 3.3.2 + html-webpack-plugin: + specifier: ^5.5.3 + version: 5.6.7 + ieee754: + specifier: ^1.2.1 + version: 1.2.1 + internmap: + specifier: ^2.0.3 + version: 2.0.3 + jest: + specifier: ^27.1.0 + version: 27.5.1 + joi: + specifier: ^17.11.0 + version: 17.13.3 + localforage: + specifier: ^1.10.0 + version: 1.10.0 + lodash: + specifier: ^4.17.21 + version: 4.18.1 + lodash.padend: + specifier: ^4.6.1 + version: 4.6.1 + lodash.trimstart: + specifier: ^4.5.1 + version: 4.5.1 + lodash.words: + specifier: ^4.2.0 + version: 4.2.0 + long: + specifier: ^4.0.0 + version: 4.0.0 + mini-css-extract-plugin: + specifier: ^2.7.6 + version: 2.10.2 + nanoclone: + specifier: ^0.2.1 + version: 0.2.1 + notistack: + specifier: ^2.0.3 + version: 2.0.8 + npm-run-all: + specifier: ^4.1.5 + version: 4.1.5 + prettier: + specifier: ^2.8.7 + version: 2.8.8 + prop-types: + specifier: ^15.8.1 + version: 15.8.1 + property-expr: + specifier: ^2.0.6 + version: 2.0.6 + qr.js: + specifier: 0.0.0 + version: 0.0.0 + ramda: + specifier: ^0.28.0 + version: 0.28.0 + react: + specifier: ^19.2.6 + version: 19.2.6 + react-dom: + specifier: ^19.2.6 + version: 19.2.6 + react-error-boundary: + specifier: ^3.1.3 + version: 3.1.4 + react-hook-form: + specifier: ^7.14.2 + version: 7.75.0 + react-is: + specifier: ^19.2.6 + version: 19.2.6 + react-refresh: + specifier: ^0.10.0 + version: 0.10.0 + react-refresh-typescript: + specifier: ^2.0.2 + version: 2.0.12 + react-router: + specifier: ^6.30.3 + version: 6.30.3 + react-router-dom: + specifier: '6' + version: 6.30.3 + react-smooth: + specifier: ^4.0.4 + version: 4.0.4 + react-transition-group: + specifier: ^4.4.5 + version: 4.4.5 + recharts: + specifier: ^2.1.13 + version: 2.15.4 + recharts-scale: + specifier: ^0.4.5 + version: 0.4.5 + rgb-hex: + specifier: ^3.0.0 + version: 3.0.0 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + safe-buffer: + specifier: ^5.2.1 + version: 5.2.1 + scheduler: + specifier: ^0.27.0 + version: 0.27.0 + semver: + specifier: ^6.3.0 + version: 6.3.1 + string-to-color: + specifier: ^2.2.2 + version: 2.2.2 + style-loader: + specifier: ^3.3.3 + version: 3.3.4 + stylis: + specifier: ^4.2.0 + version: 4.2.0 + thread-loader: + specifier: ^3.0.4 + version: 3.0.4 + tiny-invariant: + specifier: ^1.3.3 + version: 1.3.3 + toposort: + specifier: ^2.0.2 + version: 2.0.2 + ts-jest: + specifier: ^27.0.5 + version: 27.1.5 + ts-loader: + specifier: ^9.4.4 + version: 9.5.7 + tsconfig-paths-webpack-plugin: + specifier: ^3.5.2 + version: 3.5.2 + tweetnacl: + specifier: ^1.0.3 + version: 1.0.3 + tweetnacl-util: + specifier: ^0.15.1 + version: 0.15.1 + url-loader: + specifier: ^4.1.1 + version: 4.1.1 + use-clipboard-copy: + specifier: ^0.2.0 + version: 0.2.0 + uuid: + specifier: ^8.3.2 + version: 8.3.2 + victory-vendor: + specifier: ^36.9.2 + version: 36.9.2 + webpack: + specifier: ^5.88.2 + version: 5.106.2 + webpack-cli: + specifier: ^4.8.0 + version: 4.10.0 + webpack-dev-server: + specifier: ^4.15.1 + version: 4.15.2 + webpack-favicons: + specifier: ^1.3.8 + version: 1.5.43 + webpack-merge: + specifier: ^5.9.0 + version: 5.10.0 + yup: + specifier: ^0.32.9 + version: 0.32.11 + zxcvbn: + specifier: ^4.4.2 + version: 4.4.2 + +importers: + + .: + dependencies: + lucide-react: + specifier: ^0.453.0 + version: 0.453.0(react@19.2.6) + devDependencies: + '@npmcli/node-gyp': + specifier: ^3.0.0 + version: 3.0.0 + '@types/minimatch': + specifier: 5.1.2 + version: 5.1.2 + lerna: + specifier: ^7.3.0 + version: 7.4.2(@types/node@22.19.19)(encoding@0.1.13) + node-gyp: + specifier: ^9.3.1 + version: 9.4.1 + npm-run-all: + specifier: ^4.1.5 + version: 4.1.5 + tslog: + specifier: 3.3.3 + version: 3.3.3 + + explorer-v2: + dependencies: + '@chain-registry/types': + specifier: ^0.50.36 + version: 0.50.356 + '@cosmjs/cosmwasm-stargate': + specifier: 'catalog:' + version: 0.32.4 + '@cosmjs/stargate': + specifier: 'catalog:' + version: 0.32.4 + '@cosmos-kit/keplr-extension': + specifier: ^2.14.0 + version: 2.17.1(@cosmjs/amino@0.36.2)(@cosmjs/proto-signing@0.36.2)(encoding@0.1.13)(starknet@8.9.2) + '@cosmos-kit/react': + specifier: ^2.20.1 + version: 2.24.1(@cosmjs/amino@0.36.2)(@cosmjs/proto-signing@0.36.2)(@interchain-ui/react@1.26.3(@types/react@19.2.14)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(encoding@0.1.13)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@emotion/cache': + specifier: 'catalog:' + version: 11.14.0 + '@emotion/react': + specifier: 'catalog:' + version: 11.14.0(@types/react@19.2.14)(react@19.2.6) + '@emotion/styled': + specifier: 'catalog:' + version: 11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@interchain-ui/react': + specifier: ^1.26.1 + version: 1.26.3(@types/react@19.2.14)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@keplr-wallet/types': + specifier: ^0.12.211 + version: 0.12.313(starknet@8.9.2) + '@mui/icons-material': + specifier: 'catalog:' + version: 5.18.0(@mui/material@6.5.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@mui/material': + specifier: ^6.1.10 + version: 6.5.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mui/material-nextjs': + specifier: ^6.1.9 + version: 6.5.0(@emotion/cache@11.14.0)(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(next@14.2.35(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + '@mui/system': + specifier: ^6.1.10 + version: 6.5.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@mui/x-date-pickers': + specifier: ^7.23.2 + version: 7.29.4(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@mui/material@6.5.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mui/system@6.5.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@nivo/line': + specifier: ^0.88.0 + version: 0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@nymproject/contract-clients': + specifier: ^1.4.1 + version: 1.4.1 + '@nymproject/react': + specifier: workspace:* + version: link:../sdk/typescript/packages/react-components + '@nymproject/types': + specifier: workspace:* + version: link:../ts-packages/types + '@tanstack/react-query': + specifier: 'catalog:' + version: 5.100.10(react@19.2.6) + '@tanstack/react-query-devtools': + specifier: ^5.64.2 + version: 5.100.10(@tanstack/react-query@5.100.10(react@19.2.6))(react@19.2.6) + '@tanstack/react-query-next-experimental': + specifier: ^5.66.0 + version: 5.100.10(@tanstack/react-query@5.100.10(react@19.2.6))(next@14.2.35(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6) + '@tanstack/react-table': + specifier: ^8.20.6 + version: 8.21.3(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/qs': + specifier: ^6.9.18 + version: 6.15.1 + '@uidotdev/usehooks': + specifier: ^2.4.1 + version: 2.4.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + axios: + specifier: 'catalog:' + version: 1.16.0 + big.js: + specifier: 'catalog:' + version: 6.2.2 + chain-registry: + specifier: ^1.69.64 + version: 1.69.578 + cldr-compact-number: + specifier: ^0.4.0 + version: 0.4.0 + date-fns: + specifier: ^4.1.0 + version: 4.1.0 + i18next: + specifier: ^24.2.2 + version: 24.2.3(typescript@5.9.3) + i18next-resources-to-backend: + specifier: ^1.2.1 + version: 1.2.1 + isomorphic-dompurify: + specifier: ^2.21.0 + version: 2.36.0(@noble/hashes@1.8.0) + long: + specifier: 'catalog:' + version: 4.0.0 + material-react-table: + specifier: ^3.0.3 + version: 3.2.1(010425a9628d654b3c54ea7b922081d1) + next: + specifier: ^14.2.26 + version: 14.2.35(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + openapi-fetch: + specifier: ^0.13.4 + version: 0.13.8 + qrcode.react: + specifier: ^4.1.0 + version: 4.2.0(react@19.2.6) + qs: + specifier: ^6.14.0 + version: 6.15.1 + react: + specifier: 'catalog:' + version: 19.2.6 + react-dom: + specifier: 'catalog:' + version: 19.2.6(react@19.2.6) + react-i18next: + specifier: ^15.4.0 + version: 15.7.4(i18next@24.2.3(typescript@5.9.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@5.9.3) + react-markdown: + specifier: ^9.0.3 + version: 9.1.0(@types/react@19.2.14)(react@19.2.6) + react-random-avatars: + specifier: ^1.3.1 + version: 1.3.1(react@19.2.6) + react-world-flags: + specifier: ^1.6.0 + version: 1.6.0(react@19.2.6) + zod: + specifier: ^3.24.1 + version: 3.25.76 + devDependencies: + '@biomejs/biome': + specifier: 1.9.4 + version: 1.9.4 + '@types/big.js': + specifier: 'catalog:' + version: 6.2.2 + '@types/node': + specifier: ^20 + version: 20.19.41 + '@types/react': + specifier: 'catalog:' + version: 19.2.14 + '@types/react-dom': + specifier: 'catalog:' + version: 19.2.3(@types/react@19.2.14) + eslint: + specifier: 'catalog:' + version: 9.39.4 + eslint-config-next: + specifier: 15.0.3 + version: 15.0.3(eslint@9.39.4)(typescript@5.9.3) + lefthook: + specifier: ^1.8.5 + version: 1.13.6 + typescript: + specifier: ^5 + version: 5.9.3 + + nym-wallet: + dependencies: + '@babel/helper-simple-access': + specifier: 'catalog:' + version: 7.27.1 + '@babel/runtime': + specifier: 'catalog:' + version: 7.29.2 + '@cosmjs/math': + specifier: 'catalog:' + version: 0.32.4 + '@emotion/cache': + specifier: 'catalog:' + version: 11.14.0 + '@emotion/hash': + specifier: 'catalog:' + version: 0.9.2 + '@emotion/is-prop-valid': + specifier: 'catalog:' + version: 1.4.0 + '@emotion/memoize': + specifier: 'catalog:' + version: 0.9.0 + '@emotion/react': + specifier: 'catalog:' + version: 11.14.0(@types/react@19.2.14)(react@19.2.6) + '@emotion/serialize': + specifier: 'catalog:' + version: 1.3.3 + '@emotion/sheet': + specifier: 'catalog:' + version: 1.4.0 + '@emotion/styled': + specifier: 'catalog:' + version: 11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@emotion/unitless': + specifier: 'catalog:' + version: 0.10.0 + '@emotion/use-insertion-effect-with-fallbacks': + specifier: 'catalog:' + version: 1.2.0(react@19.2.6) + '@emotion/utils': + specifier: 'catalog:' + version: 1.4.2 + '@emotion/weak-memoize': + specifier: 'catalog:' + version: 0.4.0 + '@hookform/resolvers': + specifier: 'catalog:' + version: 2.9.11(react-hook-form@7.75.0(react@19.2.6)) + '@mui/base': + specifier: 'catalog:' + version: 5.0.0-beta.40(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mui/icons-material': + specifier: 'catalog:' + version: 5.18.0(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@mui/lab': + specifier: 'catalog:' + version: 5.0.0-alpha.170(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mui/material': + specifier: 'catalog:' + version: 5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mui/private-theming': + specifier: 'catalog:' + version: 5.17.1(@types/react@19.2.14)(react@19.2.6) + '@mui/styles': + specifier: 'catalog:' + version: 5.18.0(@types/react@19.2.14)(react@19.2.6) + '@mui/system': + specifier: 'catalog:' + version: 5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@mui/utils': + specifier: 'catalog:' + version: 5.17.1(@types/react@19.2.14)(react@19.2.6) + '@nymproject/react': + specifier: workspace:* + version: link:../sdk/typescript/packages/react-components + '@nymproject/types': + specifier: workspace:* + version: link:../ts-packages/types + '@popperjs/core': + specifier: 'catalog:' + version: 2.11.8 + '@remix-run/router': + specifier: 'catalog:' + version: 1.23.2 + '@tanstack/query-core': + specifier: 'catalog:' + version: 5.100.10 + '@tanstack/react-query': + specifier: 'catalog:' + version: 5.100.10(react@19.2.6) + '@tauri-apps/api': + specifier: 'catalog:' + version: 2.10.1 + '@tauri-apps/plugin-clipboard-manager': + specifier: 'catalog:' + version: 2.3.2 + '@tauri-apps/plugin-opener': + specifier: 'catalog:' + version: 2.5.4 + '@tauri-apps/plugin-process': + specifier: 'catalog:' + version: 2.3.1 + '@tauri-apps/plugin-updater': + specifier: 'catalog:' + version: 2.10.1 + '@tauri-apps/tauri-forage': + specifier: 'catalog:' + version: 1.0.0-beta.2 + base-x: + specifier: 'catalog:' + version: 3.0.11 + base64-js: + specifier: 'catalog:' + version: 1.5.1 + bech32: + specifier: 'catalog:' + version: 1.1.4 + big.js: + specifier: 'catalog:' + version: 6.2.2 + bn.js: + specifier: 'catalog:' + version: 5.2.3 + bs58: + specifier: 'catalog:' + version: 4.0.1 + buffer: + specifier: 'catalog:' + version: 6.0.3 + clipboard-copy: + specifier: 'catalog:' + version: 3.2.0 + clsx: + specifier: 'catalog:' + version: 1.2.1 + colornames: + specifier: 'catalog:' + version: 1.1.1 + d3-array: + specifier: 'catalog:' + version: 3.2.4 + d3-color: + specifier: 'catalog:' + version: 3.1.0 + d3-format: + specifier: 'catalog:' + version: 1.4.5 + d3-interpolate: + specifier: 'catalog:' + version: 3.0.1 + d3-path: + specifier: 'catalog:' + version: 3.1.0 + d3-scale: + specifier: 'catalog:' + version: 4.0.2 + d3-shape: + specifier: 'catalog:' + version: 3.2.0 + d3-time: + specifier: 'catalog:' + version: 3.1.0 + d3-time-format: + specifier: 'catalog:' + version: 3.0.0 + date-fns: + specifier: 'catalog:' + version: 2.30.0 + decimal.js-light: + specifier: 'catalog:' + version: 2.5.1 + dom-helpers: + specifier: 'catalog:' + version: 5.2.1 + eventemitter3: + specifier: 'catalog:' + version: 4.0.7 + fast-equals: + specifier: 'catalog:' + version: 5.4.0 + hex-rgb: + specifier: 'catalog:' + version: 4.3.0 + hoist-non-react-statics: + specifier: 'catalog:' + version: 3.3.2 + ieee754: + specifier: 'catalog:' + version: 1.2.1 + internmap: + specifier: 'catalog:' + version: 2.0.3 + joi: + specifier: 'catalog:' + version: 17.13.3 + localforage: + specifier: 'catalog:' + version: 1.10.0 + lodash: + specifier: 'catalog:' + version: 4.18.1 + lodash.padend: + specifier: 'catalog:' + version: 4.6.1 + lodash.trimstart: + specifier: 'catalog:' + version: 4.5.1 + lodash.words: + specifier: 'catalog:' + version: 4.2.0 + nanoclone: + specifier: 'catalog:' + version: 0.2.1 + notistack: + specifier: 'catalog:' + version: 2.0.8(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + npm-run-all: + specifier: 'catalog:' + version: 4.1.5 + prop-types: + specifier: 'catalog:' + version: 15.8.1 + property-expr: + specifier: 'catalog:' + version: 2.0.6 + qr.js: + specifier: 'catalog:' + version: 0.0.0 + qrcode.react: + specifier: ^1.0.1 + version: 1.0.1(react@19.2.6) + ramda: + specifier: 'catalog:' + version: 0.28.0 + react: + specifier: 'catalog:' + version: 19.2.6 + react-dom: + specifier: 'catalog:' + version: 19.2.6(react@19.2.6) + react-error-boundary: + specifier: 'catalog:' + version: 3.1.4(react@19.2.6) + react-hook-form: + specifier: 'catalog:' + version: 7.75.0(react@19.2.6) + react-is: + specifier: 'catalog:' + version: 19.2.6 + react-router: + specifier: 'catalog:' + version: 6.30.3(react@19.2.6) + react-router-dom: + specifier: 'catalog:' + version: 6.30.3(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react-smooth: + specifier: 'catalog:' + version: 4.0.4(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react-transition-group: + specifier: 'catalog:' + version: 4.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + recharts: + specifier: 'catalog:' + version: 2.15.4(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + recharts-scale: + specifier: 'catalog:' + version: 0.4.5 + rgb-hex: + specifier: 'catalog:' + version: 3.0.0 + safe-buffer: + specifier: 'catalog:' + version: 5.2.1 + scheduler: + specifier: 'catalog:' + version: 0.27.0 + semver: + specifier: 'catalog:' + version: 6.3.1 + string-to-color: + specifier: 'catalog:' + version: 2.2.2 + stylis: + specifier: 'catalog:' + version: 4.2.0 + tiny-invariant: + specifier: 'catalog:' + version: 1.3.3 + toposort: + specifier: 'catalog:' + version: 2.0.2 + tweetnacl: + specifier: 'catalog:' + version: 1.0.3 + tweetnacl-util: + specifier: 'catalog:' + version: 0.15.1 + use-clipboard-copy: + specifier: 'catalog:' + version: 0.2.0(react@19.2.6) + uuid: + specifier: 'catalog:' + version: 8.3.2 + victory-vendor: + specifier: 'catalog:' + version: 36.9.2 + yup: + specifier: 'catalog:' + version: 0.32.11 + zxcvbn: + specifier: 'catalog:' + version: 4.4.2 + devDependencies: + '@babel/core': + specifier: 'catalog:' + version: 7.29.0 + '@babel/plugin-transform-async-to-generator': + specifier: 'catalog:' + version: 7.28.6(@babel/core@7.29.0) + '@babel/preset-env': + specifier: 'catalog:' + version: 7.29.5(@babel/core@7.29.0) + '@babel/preset-react': + specifier: 'catalog:' + version: 7.28.5(@babel/core@7.29.0) + '@babel/preset-typescript': + specifier: 'catalog:' + version: 7.28.5(@babel/core@7.29.0) + '@nymproject/eslint-config-react-typescript': + specifier: workspace:* + version: link:../ts-packages/eslint-config-react-typescript + '@nymproject/webpack': + specifier: workspace:* + version: link:../ts-packages/webpack + '@pmmmwh/react-refresh-webpack-plugin': + specifier: 'catalog:' + version: 0.5.17(@types/webpack@4.41.40)(react-refresh@0.10.0)(type-fest@4.41.0)(webpack-dev-server@4.15.2)(webpack-hot-middleware@2.26.1)(webpack@5.106.2) + '@svgr/webpack': + specifier: 'catalog:' + version: 6.5.1 + '@tauri-apps/cli': + specifier: 'catalog:' + version: 2.11.1 + '@testing-library/dom': + specifier: 'catalog:' + version: 10.4.1 + '@testing-library/jest-dom': + specifier: 'catalog:' + version: 6.9.1 + '@testing-library/react': + specifier: 'catalog:' + version: 16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/big.js': + specifier: 'catalog:' + version: 6.2.2 + '@types/bs58': + specifier: 'catalog:' + version: 4.0.4 + '@types/jest': + specifier: 'catalog:' + version: 29.5.14 + '@types/lodash': + specifier: 'catalog:' + version: 4.17.24 + '@types/minimatch': + specifier: 'catalog:' + version: 5.1.2 + '@types/node': + specifier: ^22.15.29 + version: 22.19.19 + '@types/qrcode.react': + specifier: 'catalog:' + version: 1.0.5 + '@types/react': + specifier: 'catalog:' + version: 19.2.14 + '@types/react-dom': + specifier: 'catalog:' + version: 19.2.3(@types/react@19.2.14) + '@types/semver': + specifier: 'catalog:' + version: 7.7.1 + '@types/uuid': + specifier: 'catalog:' + version: 8.3.4 + '@types/zxcvbn': + specifier: 'catalog:' + version: 4.4.5 + '@typescript-eslint/eslint-plugin': + specifier: ^8.56.1 + version: 8.59.4(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/parser': + specifier: ^8.56.1 + version: 8.59.4(eslint@8.57.1)(typescript@5.9.3) + babel-loader: + specifier: 'catalog:' + version: 8.4.1(@babel/core@7.29.0)(webpack@5.106.2) + babel-plugin-root-import: + specifier: ^6.6.0 + version: 6.6.0 + clean-webpack-plugin: + specifier: 'catalog:' + version: 4.0.0(webpack@5.106.2) + css-loader: + specifier: 'catalog:' + version: 6.11.0(webpack@5.106.2) + css-minimizer-webpack-plugin: + specifier: 'catalog:' + version: 3.4.1(webpack@5.106.2) + dotenv-webpack: + specifier: 'catalog:' + version: 7.1.1(webpack@5.106.2) + eslint: + specifier: ^8.57.1 + version: 8.57.1 + eslint-config-airbnb: + specifier: 'catalog:' + version: 19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.1))(eslint-plugin-react@7.37.5(eslint@8.57.1))(eslint@8.57.1) + eslint-config-airbnb-typescript: + specifier: 'catalog:' + version: 16.2.0(@typescript-eslint/eslint-plugin@8.59.4(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3))(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1) + eslint-config-prettier: + specifier: 'catalog:' + version: 8.10.2(eslint@8.57.1) + eslint-import-resolver-root-import: + specifier: 'catalog:' + version: 1.0.4(babel-plugin-root-import@6.6.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)) + eslint-plugin-import: + specifier: 'catalog:' + version: 2.32.0(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1) + eslint-plugin-jest: + specifier: 'catalog:' + version: 26.9.0(@typescript-eslint/eslint-plugin@8.59.4(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(jest@29.7.0(@types/node@22.19.19)(babel-plugin-macros@3.1.0))(typescript@5.9.3) + eslint-plugin-jsx-a11y: + specifier: 'catalog:' + version: 6.10.2(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 'catalog:' + version: 4.2.5(eslint-config-prettier@8.10.2(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8) + eslint-plugin-react: + specifier: 'catalog:' + version: 7.37.5(eslint@8.57.1) + eslint-plugin-react-hooks: + specifier: 'catalog:' + version: 4.6.2(eslint@8.57.1) + favicons: + specifier: 'catalog:' + version: 7.2.0 + favicons-webpack-plugin: + specifier: 'catalog:' + version: 5.0.2(favicons@7.2.0)(webpack@5.106.2) + file-loader: + specifier: 'catalog:' + version: 6.2.0(webpack@5.106.2) + fork-ts-checker-webpack-plugin: + specifier: 'catalog:' + version: 7.3.0(typescript@5.9.3)(webpack@5.106.2) + html-webpack-plugin: + specifier: 'catalog:' + version: 5.6.7(webpack@5.106.2) + jest: + specifier: ^29.7.0 + version: 29.7.0(@types/node@22.19.19)(babel-plugin-macros@3.1.0) + mini-css-extract-plugin: + specifier: 'catalog:' + version: 2.10.2(webpack@5.106.2) + prettier: + specifier: 'catalog:' + version: 2.8.8 + react-refresh: + specifier: 'catalog:' + version: 0.10.0 + react-refresh-typescript: + specifier: 'catalog:' + version: 2.0.12(react-refresh@0.10.0)(typescript@5.9.3) + style-loader: + specifier: 'catalog:' + version: 3.3.4(webpack@5.106.2) + thread-loader: + specifier: 'catalog:' + version: 3.0.4(webpack@5.106.2) + ts-jest: + specifier: ^29.4.9 + version: 29.4.9(@babel/core@7.29.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.19.19)(babel-plugin-macros@3.1.0))(typescript@5.9.3) + ts-loader: + specifier: 'catalog:' + version: 9.5.7(typescript@5.9.3)(webpack@5.106.2) + tsconfig-paths-webpack-plugin: + specifier: 'catalog:' + version: 3.5.2 + typescript: + specifier: ^5.9.3 + version: 5.9.3 + url-loader: + specifier: 'catalog:' + version: 4.1.1(file-loader@6.2.0(webpack@5.106.2))(webpack@5.106.2) + webpack: + specifier: 'catalog:' + version: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack-cli: + specifier: 'catalog:' + version: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.106.2) + webpack-dev-server: + specifier: 'catalog:' + version: 4.15.2(webpack-cli@4.10.0)(webpack@5.106.2) + webpack-favicons: + specifier: 'catalog:' + version: 1.5.43 + webpack-merge: + specifier: 'catalog:' + version: 5.10.0 + + sdk/typescript/packages/mix-fetch/internal-dev: + dependencies: + '@nymproject/mix-fetch': + specifier: '>=1.4.2-rc.0 || ^1' + version: 1.4.4 + devDependencies: + '@babel/core': + specifier: 'catalog:' + version: 7.29.0 + '@babel/plugin-transform-async-to-generator': + specifier: 'catalog:' + version: 7.28.6(@babel/core@7.29.0) + '@babel/preset-env': + specifier: 'catalog:' + version: 7.29.5(@babel/core@7.29.0) + '@babel/preset-typescript': + specifier: 'catalog:' + version: 7.28.5(@babel/core@7.29.0) + '@types/jest': + specifier: ^27.0.1 + version: 27.5.2 + '@types/node': + specifier: ^16.7.13 + version: 16.18.126 + '@typescript-eslint/eslint-plugin': + specifier: 'catalog:' + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: 'catalog:' + version: 5.62.0(eslint@9.39.4)(typescript@4.9.5) + babel-loader: + specifier: ^9.1.3 + version: 9.2.1(@babel/core@7.29.0)(webpack@5.106.2) + babel-plugin-root-import: + specifier: ^6.6.0 + version: 6.6.0 + clean-webpack-plugin: + specifier: 'catalog:' + version: 4.0.0(webpack@5.106.2) + copy-webpack-plugin: + specifier: ^11.0.0 + version: 11.0.0(webpack@5.106.2) + css-loader: + specifier: 'catalog:' + version: 6.11.0(webpack@5.106.2) + css-minimizer-webpack-plugin: + specifier: ^5.0.1 + version: 5.0.1(webpack@5.106.2) + dotenv-webpack: + specifier: ^8.0.1 + version: 8.1.1(webpack@5.106.2) + eslint: + specifier: 'catalog:' + version: 9.39.4 + eslint-config-airbnb: + specifier: 'catalog:' + version: 19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4))(eslint-plugin-react-hooks@5.2.0(eslint@9.39.4))(eslint-plugin-react@7.37.5(eslint@9.39.4))(eslint@9.39.4) + eslint-config-airbnb-typescript: + specifier: 'catalog:' + version: 16.2.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint@9.39.4) + eslint-config-prettier: + specifier: 'catalog:' + version: 8.10.2(eslint@9.39.4) + eslint-import-resolver-root-import: + specifier: 'catalog:' + version: 1.0.4(babel-plugin-root-import@6.6.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)) + eslint-plugin-import: + specifier: 'catalog:' + version: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4) + eslint-plugin-jest: + specifier: 'catalog:' + version: 26.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(jest@27.5.1)(typescript@4.9.5) + eslint-plugin-jsx-a11y: + specifier: 'catalog:' + version: 6.10.2(eslint@9.39.4) + eslint-plugin-prettier: + specifier: 'catalog:' + version: 4.2.5(eslint-config-prettier@8.10.2(eslint@9.39.4))(eslint@9.39.4)(prettier@2.8.8) + file-loader: + specifier: 'catalog:' + version: 6.2.0(webpack@5.106.2) + fork-ts-checker-webpack-plugin: + specifier: ^8.0.0 + version: 8.0.0(typescript@4.9.5)(webpack@5.106.2) + html-webpack-plugin: + specifier: 'catalog:' + version: 5.6.7(webpack@5.106.2) + jest: + specifier: 'catalog:' + version: 27.5.1 + mini-css-extract-plugin: + specifier: 'catalog:' + version: 2.10.2(webpack@5.106.2) + npm-run-all: + specifier: 'catalog:' + version: 4.1.5 + prettier: + specifier: 'catalog:' + version: 2.8.8 + style-loader: + specifier: 'catalog:' + version: 3.3.4(webpack@5.106.2) + thread-loader: + specifier: ^4.0.2 + version: 4.0.4(webpack@5.106.2) + ts-jest: + specifier: 'catalog:' + version: 27.1.5(@babel/core@7.29.0)(@types/jest@27.5.2)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) + ts-loader: + specifier: 'catalog:' + version: 9.5.7(typescript@4.9.5)(webpack@5.106.2) + tsconfig-paths-webpack-plugin: + specifier: ^4.1.0 + version: 4.2.0 + typescript: + specifier: ^4.6.2 + version: 4.9.5 + url-loader: + specifier: 'catalog:' + version: 4.1.1(file-loader@6.2.0(webpack@5.106.2))(webpack@5.106.2) + webpack: + specifier: 'catalog:' + version: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) + webpack-cli: + specifier: ^5.1.4 + version: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.106.2) + webpack-dev-server: + specifier: 'catalog:' + version: 4.15.2(webpack-cli@5.1.4)(webpack@5.106.2) + webpack-merge: + specifier: 'catalog:' + version: 5.10.0 + + sdk/typescript/packages/mui-theme: + dependencies: + '@mui/material': + specifier: ^5.2.2 + version: 5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mui/styles': + specifier: ^5.2.2 + version: 5.18.0(@types/react@19.2.14)(react@19.2.6) + react: + specifier: 'catalog:' + version: 19.2.6 + react-dom: + specifier: 'catalog:' + version: 19.2.6(react@19.2.6) + devDependencies: + '@nymproject/eslint-config-react-typescript': + specifier: workspace:* + version: link:../../../../ts-packages/eslint-config-react-typescript + '@types/react': + specifier: 'catalog:' + version: 19.2.14 + '@typescript-eslint/eslint-plugin': + specifier: 'catalog:' + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: 'catalog:' + version: 5.62.0(eslint@9.39.4)(typescript@4.9.5) + babel-plugin-root-import: + specifier: ^5.1.0 + version: 5.1.0 + eslint: + specifier: 'catalog:' + version: 9.39.4 + eslint-config-airbnb: + specifier: 'catalog:' + version: 19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4))(eslint-plugin-react-hooks@4.6.2(eslint@9.39.4))(eslint-plugin-react@7.37.5(eslint@9.39.4))(eslint@9.39.4) + eslint-config-airbnb-typescript: + specifier: 'catalog:' + version: 16.2.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint@9.39.4) + eslint-config-prettier: + specifier: 'catalog:' + version: 8.10.2(eslint@9.39.4) + eslint-import-resolver-root-import: + specifier: 'catalog:' + version: 1.0.4(babel-plugin-root-import@5.1.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)) + eslint-plugin-import: + specifier: 'catalog:' + version: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4) + eslint-plugin-jest: + specifier: 'catalog:' + version: 26.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(jest@27.5.1)(typescript@4.9.5) + eslint-plugin-jsx-a11y: + specifier: 'catalog:' + version: 6.10.2(eslint@9.39.4) + eslint-plugin-prettier: + specifier: 'catalog:' + version: 4.2.5(eslint-config-prettier@8.10.2(eslint@9.39.4))(eslint@9.39.4)(prettier@2.8.8) + eslint-plugin-react: + specifier: 'catalog:' + version: 7.37.5(eslint@9.39.4) + eslint-plugin-react-hooks: + specifier: 'catalog:' + version: 4.6.2(eslint@9.39.4) + jest: + specifier: 'catalog:' + version: 27.5.1 + prettier: + specifier: 'catalog:' + version: 2.8.8 + rimraf: + specifier: 'catalog:' + version: 3.0.2 + ts-jest: + specifier: 'catalog:' + version: 27.1.5(@babel/core@7.29.0)(@types/jest@27.5.2)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) + typescript: + specifier: ^4.6.2 + version: 4.9.5 + + sdk/typescript/packages/react-components: + dependencies: + '@cosmjs/math': + specifier: ^0.27.1 + version: 0.27.1 + '@mui/icons-material': + specifier: '>= 5' + version: 5.18.0(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@mui/lab': + specifier: 'catalog:' + version: 5.0.0-alpha.170(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mui/material': + specifier: '5' + version: 5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mui/styles': + specifier: '5' + version: 5.18.0(@types/react@19.2.14)(react@19.2.6) + '@mui/system': + specifier: '5' + version: 5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@mui/x-tree-view': + specifier: 'catalog:' + version: 7.29.10(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mui/system@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@nymproject/mui-theme': + specifier: workspace:* + version: link:../mui-theme + '@nymproject/nym-validator-client': + specifier: ^0.18.0 + version: 0.18.0 + '@nymproject/types': + specifier: workspace:* + version: link:../../../../ts-packages/types + base58: + specifier: '2' + version: 2.0.1 + bech32: + specifier: ^1.1.4 + version: 1.1.4 + flat: + specifier: 'catalog:' + version: 5.0.2 + react: + specifier: 'catalog:' + version: 19.2.6 + react-dom: + specifier: 'catalog:' + version: 19.2.6(react@19.2.6) + use-clipboard-copy: + specifier: 'catalog:' + version: 0.2.0(react@19.2.6) + zxcvbn: + specifier: ^4.4.2 + version: 4.4.2 + devDependencies: + '@babel/core': + specifier: 'catalog:' + version: 7.29.0 + '@nymproject/eslint-config-react-typescript': + specifier: workspace:* + version: link:../../../../ts-packages/eslint-config-react-typescript + '@storybook/addon-actions': + specifier: 'catalog:' + version: 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/addon-docs': + specifier: 'catalog:' + version: 6.5.16(@babel/core@7.29.0)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + '@storybook/addon-essentials': + specifier: 'catalog:' + version: 6.5.16(@babel/core@7.29.0)(@storybook/builder-webpack5@6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + '@storybook/addon-interactions': + specifier: 'catalog:' + version: 6.5.16(@types/react@19.2.14)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/addon-links': + specifier: 'catalog:' + version: 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/builder-webpack5': + specifier: 'catalog:' + version: 6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/manager-webpack5': + specifier: 'catalog:' + version: 6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/react': + specifier: 'catalog:' + version: 6.5.16(@babel/core@7.29.0)(@storybook/builder-webpack5@6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@types/webpack@4.41.40)(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(require-from-string@2.0.2)(type-fest@4.41.0)(typescript@4.9.5)(webpack-dev-server@4.15.2(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)))(webpack-hot-middleware@2.26.1) + '@storybook/testing-library': + specifier: 'catalog:' + version: 0.0.9(storybook@8.6.18(prettier@2.8.8)) + '@svgr/webpack': + specifier: 'catalog:' + version: 6.5.1 + '@types/flat': + specifier: 'catalog:' + version: 5.0.5 + '@types/react': + specifier: 'catalog:' + version: 19.2.14 + '@types/react-dom': + specifier: 'catalog:' + version: 19.2.3(@types/react@19.2.14) + '@types/zxcvbn': + specifier: 'catalog:' + version: 4.4.5 + '@typescript-eslint/eslint-plugin': + specifier: 'catalog:' + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: 'catalog:' + version: 5.62.0(eslint@9.39.4)(typescript@4.9.5) + babel-loader: + specifier: 'catalog:' + version: 8.4.1(@babel/core@7.29.0)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + babel-plugin-root-import: + specifier: ^5.1.0 + version: 5.1.0 + eslint: + specifier: 'catalog:' + version: 9.39.4 + eslint-config-airbnb: + specifier: 'catalog:' + version: 19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4))(eslint-plugin-react-hooks@4.6.2(eslint@9.39.4))(eslint-plugin-react@7.37.5(eslint@9.39.4))(eslint@9.39.4) + eslint-config-airbnb-typescript: + specifier: 'catalog:' + version: 16.2.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint@9.39.4) + eslint-config-prettier: + specifier: 'catalog:' + version: 8.10.2(eslint@9.39.4) + eslint-import-resolver-root-import: + specifier: 'catalog:' + version: 1.0.4(babel-plugin-root-import@5.1.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)) + eslint-plugin-import: + specifier: 'catalog:' + version: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4) + eslint-plugin-jest: + specifier: 'catalog:' + version: 26.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(jest@27.5.1)(typescript@4.9.5) + eslint-plugin-jsx-a11y: + specifier: 'catalog:' + version: 6.10.2(eslint@9.39.4) + eslint-plugin-prettier: + specifier: 'catalog:' + version: 4.2.5(eslint-config-prettier@8.10.2(eslint@9.39.4))(eslint@9.39.4)(prettier@2.8.8) + eslint-plugin-react: + specifier: 'catalog:' + version: 7.37.5(eslint@9.39.4) + eslint-plugin-react-hooks: + specifier: 'catalog:' + version: 4.6.2(eslint@9.39.4) + eslint-plugin-storybook: + specifier: 'catalog:' + version: 0.5.13(eslint@9.39.4)(typescript@4.9.5) + jest: + specifier: 'catalog:' + version: 27.5.1 + prettier: + specifier: 'catalog:' + version: 2.8.8 + rimraf: + specifier: 'catalog:' + version: 3.0.2 + ts-jest: + specifier: 'catalog:' + version: 27.1.5(@babel/core@7.29.0)(@types/jest@27.5.2)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) + tsconfig-paths-webpack-plugin: + specifier: 'catalog:' + version: 3.5.2 + typescript: + specifier: ^4.6.2 + version: 4.9.5 + + ts-packages/eslint-config-react-typescript: + dependencies: + '@typescript-eslint/eslint-plugin': + specifier: '>= 5' + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/parser': + specifier: '>= 5' + version: 5.62.0(eslint@9.39.4)(typescript@5.9.3) + eslint-config-airbnb-typescript: + specifier: '>= 16' + version: 16.2.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3))(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4))(eslint@9.39.4) + eslint-plugin-storybook: + specifier: '*' + version: 0.5.13(eslint@9.39.4)(typescript@5.9.3) + react: + specifier: 'catalog:' + version: 19.2.6 + react-dom: + specifier: 'catalog:' + version: 19.2.6(react@19.2.6) + devDependencies: + eslint: + specifier: 'catalog:' + version: 9.39.4 + eslint-config-airbnb: + specifier: 'catalog:' + version: 19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4))(eslint-plugin-react-hooks@4.6.2(eslint@9.39.4))(eslint-plugin-react@7.37.5(eslint@9.39.4))(eslint@9.39.4) + eslint-config-prettier: + specifier: 'catalog:' + version: 8.10.2(eslint@9.39.4) + eslint-import-resolver-root-import: + specifier: 'catalog:' + version: 1.0.4(babel-plugin-root-import@6.6.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)) + eslint-plugin-import: + specifier: 'catalog:' + version: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4) + eslint-plugin-jest: + specifier: 'catalog:' + version: 26.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) + eslint-plugin-jsx-a11y: + specifier: 'catalog:' + version: 6.10.2(eslint@9.39.4) + eslint-plugin-prettier: + specifier: 'catalog:' + version: 4.2.5(eslint-config-prettier@8.10.2(eslint@9.39.4))(eslint@9.39.4)(prettier@2.8.8) + eslint-plugin-react: + specifier: 'catalog:' + version: 7.37.5(eslint@9.39.4) + eslint-plugin-react-hooks: + specifier: 'catalog:' + version: 4.6.2(eslint@9.39.4) + prettier: + specifier: 'catalog:' + version: 2.8.8 + + ts-packages/types: + dependencies: + '@cosmjs/math': + specifier: ^0.27.1 + version: 0.27.1 + bech32: + specifier: ^1.1.4 + version: 1.1.4 + bs58: + specifier: '4' + version: 4.0.1 + devDependencies: + '@nymproject/eslint-config-react-typescript': + specifier: workspace:* + version: link:../eslint-config-react-typescript + '@types/bs58': + specifier: 'catalog:' + version: 4.0.4 + '@typescript-eslint/eslint-plugin': + specifier: 'catalog:' + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: 'catalog:' + version: 5.62.0(eslint@9.39.4)(typescript@4.9.5) + babel-plugin-root-import: + specifier: ^5.1.0 + version: 5.1.0 + eslint: + specifier: 'catalog:' + version: 9.39.4 + eslint-config-airbnb: + specifier: 'catalog:' + version: 19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4))(eslint-plugin-react-hooks@4.6.2(eslint@9.39.4))(eslint-plugin-react@7.37.5(eslint@9.39.4))(eslint@9.39.4) + eslint-config-airbnb-typescript: + specifier: 'catalog:' + version: 16.2.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint@9.39.4) + eslint-config-prettier: + specifier: 'catalog:' + version: 8.10.2(eslint@9.39.4) + eslint-import-resolver-root-import: + specifier: 'catalog:' + version: 1.0.4(babel-plugin-root-import@5.1.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)) + eslint-plugin-import: + specifier: 'catalog:' + version: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4) + eslint-plugin-jest: + specifier: 'catalog:' + version: 26.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(jest@27.5.1)(typescript@4.9.5) + eslint-plugin-jsx-a11y: + specifier: 'catalog:' + version: 6.10.2(eslint@9.39.4) + eslint-plugin-prettier: + specifier: 'catalog:' + version: 4.2.5(eslint-config-prettier@8.10.2(eslint@9.39.4))(eslint@9.39.4)(prettier@2.8.8) + eslint-plugin-react: + specifier: 'catalog:' + version: 7.37.5(eslint@9.39.4) + eslint-plugin-react-hooks: + specifier: 'catalog:' + version: 4.6.2(eslint@9.39.4) + jest: + specifier: 'catalog:' + version: 27.5.1 + prettier: + specifier: 'catalog:' + version: 2.8.8 + rimraf: + specifier: 'catalog:' + version: 3.0.2 + ts-jest: + specifier: 'catalog:' + version: 27.1.5(@babel/core@7.29.0)(@types/jest@27.5.2)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) + typescript: + specifier: ^4.6.2 + version: 4.9.5 + + ts-packages/webpack: + dependencies: + react: + specifier: 'catalog:' + version: 19.2.6 + react-dom: + specifier: 'catalog:' + version: 19.2.6(react@19.2.6) + devDependencies: + '@babel/core': + specifier: 'catalog:' + version: 7.29.0 + '@babel/plugin-transform-async-to-generator': + specifier: 'catalog:' + version: 7.28.6(@babel/core@7.29.0) + '@babel/preset-env': + specifier: 'catalog:' + version: 7.29.5(@babel/core@7.29.0) + '@babel/preset-react': + specifier: 'catalog:' + version: 7.28.5(@babel/core@7.29.0) + '@babel/preset-typescript': + specifier: 'catalog:' + version: 7.28.5(@babel/core@7.29.0) + '@svgr/webpack': + specifier: 'catalog:' + version: 6.5.1 + babel-loader: + specifier: 'catalog:' + version: 8.4.1(@babel/core@7.29.0)(webpack@5.106.2) + clean-webpack-plugin: + specifier: 'catalog:' + version: 4.0.0(webpack@5.106.2) + css-loader: + specifier: 'catalog:' + version: 6.11.0(webpack@5.106.2) + dotenv-webpack: + specifier: 'catalog:' + version: 7.1.1(webpack@5.106.2) + eslint: + specifier: 'catalog:' + version: 9.39.4 + eslint-config-prettier: + specifier: 'catalog:' + version: 8.10.2(eslint@9.39.4) + eslint-plugin-prettier: + specifier: 'catalog:' + version: 4.2.5(eslint-config-prettier@8.10.2(eslint@9.39.4))(eslint@9.39.4)(prettier@2.8.8) + favicons: + specifier: 'catalog:' + version: 7.2.0 + favicons-webpack-plugin: + specifier: 'catalog:' + version: 5.0.2(favicons@7.2.0)(webpack@5.106.2) + file-loader: + specifier: 'catalog:' + version: 6.2.0(webpack@5.106.2) + fork-ts-checker-webpack-plugin: + specifier: 'catalog:' + version: 7.3.0(typescript@5.9.3)(webpack@5.106.2) + html-webpack-plugin: + specifier: 'catalog:' + version: 5.6.7(webpack@5.106.2) + prettier: + specifier: 'catalog:' + version: 2.8.8 + style-loader: + specifier: 'catalog:' + version: 3.3.4(webpack@5.106.2) + tsconfig-paths-webpack-plugin: + specifier: 'catalog:' + version: 3.5.2 + url-loader: + specifier: 'catalog:' + version: 4.1.1(file-loader@6.2.0(webpack@5.106.2))(webpack@5.106.2) + webpack: + specifier: 'catalog:' + version: 5.106.2(webpack-cli@4.10.0) + webpack-cli: + specifier: 'catalog:' + version: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.106.2) + webpack-dev-server: + specifier: 'catalog:' + version: 4.15.2(webpack-cli@4.10.0)(webpack@5.106.2) + webpack-favicons: + specifier: 'catalog:' + version: 1.5.43 + webpack-merge: + specifier: 'catalog:' + version: 5.10.0 + +packages: + + '@acemir/cssom@0.9.31': + resolution: {integrity: sha512-ZnR3GSaH+/vJ0YlHau21FjfLYjMpYVIzTD8M8vIEQvIGxeOXyXdzCI140rrCY862p/C/BbzWsjc1dgnM9mkoTA==} + + '@adobe/css-tools@4.4.4': + resolution: {integrity: sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg==} + + '@asamuzakjp/css-color@5.1.11': + resolution: {integrity: sha512-KVw6qIiCTUQhByfTd78h2yD1/00waTmm9uy/R7Ck/ctUyAPj+AEDLkQIdJW0T8+qGgj3j5bpNKK7Q3G+LedJWg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + '@asamuzakjp/dom-selector@6.8.1': + resolution: {integrity: sha512-MvRz1nCqW0fsy8Qz4dnLIvhOlMzqDVBabZx6lH+YywFDdjXhMY37SmpV1XFX3JzG5GWHn63j6HX6QPr3lZXHvQ==} + + '@asamuzakjp/generational-cache@1.0.1': + resolution: {integrity: sha512-wajfB8KqzMCN2KGNFdLkReeHncd0AslUSrvHVvvYWuU8ghncRJoA50kT3zP9MVL0+9g4/67H+cdvBskj9THPzg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + '@asamuzakjp/nwsapi@2.3.9': + resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} + + '@babel/code-frame@7.29.0': + resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + engines: {node: '>=6.9.0'} + + '@babel/compat-data@7.29.3': + resolution: {integrity: sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.12.9': + resolution: {integrity: sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==} + engines: {node: '>=6.9.0'} + + '@babel/core@7.29.0': + resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} + engines: {node: '>=6.9.0'} + + '@babel/generator@7.29.1': + resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-annotate-as-pure@7.27.3': + resolution: {integrity: sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-compilation-targets@7.28.6': + resolution: {integrity: sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-create-class-features-plugin@7.29.3': + resolution: {integrity: sha512-RpLYy2sb51oNLjuu1iD3bwBqCBWUzjO0ocp+iaCP/lJtb2CPLcnC2Fftw+4sAzaMELGeWTgExSKADbdo0GFVzA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-create-regexp-features-plugin@7.28.5': + resolution: {integrity: sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-define-polyfill-provider@0.1.5': + resolution: {integrity: sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg==} + peerDependencies: + '@babel/core': ^7.4.0-0 + + '@babel/helper-define-polyfill-provider@0.6.8': + resolution: {integrity: sha512-47UwBLPpQi1NoWzLuHNjRoHlYXMwIJoBf7MFou6viC/sIHWYygpvr0B6IAyh5sBdA2nr2LPIRww8lfaUVQINBA==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + '@babel/helper-globals@7.28.0': + resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-member-expression-to-functions@7.28.5': + resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-imports@7.28.6': + resolution: {integrity: sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-module-transforms@7.28.6': + resolution: {integrity: sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-optimise-call-expression@7.27.1': + resolution: {integrity: sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-plugin-utils@7.10.4': + resolution: {integrity: sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==} + + '@babel/helper-plugin-utils@7.28.6': + resolution: {integrity: sha512-S9gzZ/bz83GRysI7gAD4wPT/AI3uCnY+9xn+Mx/KPs2JwHJIz1W8PZkg2cqyt3RNOBM8ejcXhV6y8Og7ly/Dug==} + engines: {node: '>=6.9.0'} + + '@babel/helper-remap-async-to-generator@7.27.1': + resolution: {integrity: sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-replace-supers@7.28.6': + resolution: {integrity: sha512-mq8e+laIk94/yFec3DxSjCRD2Z0TAjhVbEJY3UQrlwVo15Lmt7C2wAUbK4bjnTs4APkwsYLTahXRraQXhb1WCg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/helper-simple-access@7.27.1': + resolution: {integrity: sha512-OU4zVQrJgFBNXMjrHs1yFSdlTgufO4tefcUZoqNhukVfw0p8x1Asht/gcGZ3bpHbi8gu/76m4JhrlKPqkrs/WQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-string-parser@7.27.1': + resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.28.5': + resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-option@7.27.1': + resolution: {integrity: sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==} + engines: {node: '>=6.9.0'} + + '@babel/helper-wrap-function@7.28.6': + resolution: {integrity: sha512-z+PwLziMNBeSQJonizz2AGnndLsP2DeGHIxDAn+wdHOGuo4Fo1x1HBPPXeE9TAOPHNNWQKCSlA2VZyYyyibDnQ==} + engines: {node: '>=6.9.0'} + + '@babel/helpers@7.29.2': + resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.3': + resolution: {integrity: sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5': + resolution: {integrity: sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1': + resolution: {integrity: sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1': + resolution: {integrity: sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@7.29.3': + resolution: {integrity: sha512-SRS46DFR4HqzUzCVgi90/xMoL+zeBDBvWdKYXSEzh79kXswNFEglUpMKxR04//dPqwYXWUBJ3mpUd933ru9Kmg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1': + resolution: {integrity: sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.13.0 + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6': + resolution: {integrity: sha512-a0aBScVTlNaiUe35UtfxAN7A/tehvvG4/ByO6+46VPKTRSlfnAFsgKy0FUh+qAkQrDTmhDkT+IBOKlOoMUxQ0g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-proposal-class-properties@7.18.6': + resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-class-properties instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-decorators@7.29.0': + resolution: {integrity: sha512-CVBVv3VY/XRMxRYq5dwr2DS7/MvqPm23cOCjbwNnVrfOqcWlnefua1uUs0sjdKOGjvPUG633o07uWzJq4oI6dA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-export-default-from@7.27.1': + resolution: {integrity: sha512-hjlsMBl1aJc5lp8MoCDEZCiYzlgdRAShOjAfRw6X+GlpLpUPU7c3XNLsKFZbQk/1cRzBlJ7CXg3xJAJMrFa1Uw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-nullish-coalescing-operator@7.18.6': + resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-nullish-coalescing-operator instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-object-rest-spread@7.12.1': + resolution: {integrity: sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-object-rest-spread@7.20.7': + resolution: {integrity: sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-optional-chaining@7.21.0': + resolution: {integrity: sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-optional-chaining instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-private-methods@7.18.6': + resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-methods instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2': + resolution: {integrity: sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-proposal-private-property-in-object@7.21.11': + resolution: {integrity: sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw==} + engines: {node: '>=6.9.0'} + deprecated: This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-private-property-in-object instead. + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-async-generators@7.8.4': + resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-bigint@7.8.3': + resolution: {integrity: sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-properties@7.12.13': + resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-class-static-block@7.14.5': + resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-decorators@7.28.6': + resolution: {integrity: sha512-71EYI0ONURHJBL4rSFXnITXqXrrY8q4P0q006DPfN+Rk+ASM+++IBXem/ruokgBZR8YNEWZ8R6B+rCb8VcUTqA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-dynamic-import@7.8.3': + resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-flow@7.28.6': + resolution: {integrity: sha512-D+OrJumc9McXNEBI/JmFnc/0uCM2/Y3PEBG3gfV3QIYkKv5pvnpzFrl1kYCrcHJP8nOeFB/SHi1IHz29pNGuew==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-assertions@7.28.6': + resolution: {integrity: sha512-pSJUpFHdx9z5nqTSirOCMtYVP2wFgoWhP0p3g8ONK/4IHhLIBd0B9NYqAvIUAhq+OkhO4VM1tENCt0cjlsNShw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-attributes@7.28.6': + resolution: {integrity: sha512-jiLC0ma9XkQT3TKJ9uYvlakm66Pamywo+qwL+oL8HJOvc6TWdZXVfhqJr8CCzbSGUAbDOzlGHJC1U+vRfLQDvw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-import-meta@7.10.4': + resolution: {integrity: sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-json-strings@7.8.3': + resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.12.1': + resolution: {integrity: sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-jsx@7.28.6': + resolution: {integrity: sha512-wgEmr06G6sIpqr8YDwA2dSRTE3bJ+V0IfpzfSY3Lfgd7YWOaAdlykvJi13ZKBt8cZHfgH1IXN+CL656W3uUa4w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4': + resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3': + resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-numeric-separator@7.10.4': + resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-object-rest-spread@7.8.3': + resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3': + resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-optional-chaining@7.8.3': + resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-private-property-in-object@7.14.5': + resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-top-level-await@7.14.5': + resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-typescript@7.28.6': + resolution: {integrity: sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6': + resolution: {integrity: sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-arrow-functions@7.27.1': + resolution: {integrity: sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-generator-functions@7.29.0': + resolution: {integrity: sha512-va0VdWro4zlBr2JsXC+ofCPB2iG12wPtVGTWFx2WLDOM3nYQZZIGP82qku2eW/JR83sD+k2k+CsNtyEbUqhU6w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-async-to-generator@7.28.6': + resolution: {integrity: sha512-ilTRcmbuXjsMmcZ3HASTe4caH5Tpo93PkTxF9oG2VZsSWsahydmcEHhix9Ik122RcTnZnUzPbmux4wh1swfv7g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoped-functions@7.27.1': + resolution: {integrity: sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-block-scoping@7.28.6': + resolution: {integrity: sha512-tt/7wOtBmwHPNMPu7ax4pdPz6shjFrmHDghvNC+FG9Qvj7D6mJcoRQIF5dy4njmxR941l6rgtvfSB2zX3VlUIw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-properties@7.28.6': + resolution: {integrity: sha512-dY2wS3I2G7D697VHndN91TJr8/AAfXQNt5ynCTI/MpxMsSzHp+52uNivYT5wCPax3whc47DR8Ba7cmlQMg24bw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-class-static-block@7.28.6': + resolution: {integrity: sha512-rfQ++ghVwTWTqQ7w8qyDxL1XGihjBss4CmTgGRCTAC9RIbhVpyp4fOeZtta0Lbf+dTNIVJer6ych2ibHwkZqsQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.12.0 + + '@babel/plugin-transform-classes@7.28.6': + resolution: {integrity: sha512-EF5KONAqC5zAqT783iMGuM2ZtmEBy+mJMOKl2BCvPZ2lVrwvXnB6o+OBWCS+CoeCCpVRF2sA2RBKUxvT8tQT5Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-computed-properties@7.28.6': + resolution: {integrity: sha512-bcc3k0ijhHbc2lEfpFHgx7eYw9KNXqOerKWfzbxEHUGKnS3sz9C4CNL9OiFN1297bDNfUiSO7DaLzbvHQQQ1BQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-destructuring@7.28.5': + resolution: {integrity: sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-dotall-regex@7.28.6': + resolution: {integrity: sha512-SljjowuNKB7q5Oayv4FoPzeB74g3QgLt8IVJw9ADvWy3QnUb/01aw8I4AVv8wYnPvQz2GDDZ/g3GhcNyDBI4Bg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-keys@7.27.1': + resolution: {integrity: sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0': + resolution: {integrity: sha512-zBPcW2lFGxdiD8PUnPwJjag2J9otbcLQzvbiOzDxpYXyCuYX9agOwMPGn1prVH0a4qzhCKu24rlH4c1f7yA8rw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-dynamic-import@7.27.1': + resolution: {integrity: sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-explicit-resource-management@7.28.6': + resolution: {integrity: sha512-Iao5Konzx2b6g7EPqTy40UZbcdXE126tTxVFr/nAIj+WItNxjKSYTEw3RC+A2/ZetmdJsgueL1KhaMCQHkLPIg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-exponentiation-operator@7.28.6': + resolution: {integrity: sha512-WitabqiGjV/vJ0aPOLSFfNY1u9U3R7W36B03r5I2KoNix+a3sOhJ3pKFB3R5It9/UiK78NiO0KE9P21cMhlPkw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-export-namespace-from@7.27.1': + resolution: {integrity: sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-flow-strip-types@7.27.1': + resolution: {integrity: sha512-G5eDKsu50udECw7DL2AcsysXiQyB7Nfg521t2OAJ4tbfTJ27doHLeF/vlI1NZGlLdbb/v+ibvtL1YBQqYOwJGg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-for-of@7.27.1': + resolution: {integrity: sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-function-name@7.27.1': + resolution: {integrity: sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-json-strings@7.28.6': + resolution: {integrity: sha512-Nr+hEN+0geQkzhbdgQVPoqr47lZbm+5fCUmO70722xJZd0Mvb59+33QLImGj6F+DkK3xgDi1YVysP8whD6FQAw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-literals@7.27.1': + resolution: {integrity: sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-logical-assignment-operators@7.28.6': + resolution: {integrity: sha512-+anKKair6gpi8VsM/95kmomGNMD0eLz1NQ8+Pfw5sAwWH9fGYXT50E55ZpV0pHUHWf6IUTWPM+f/7AAff+wr9A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-member-expression-literals@7.27.1': + resolution: {integrity: sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-amd@7.27.1': + resolution: {integrity: sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-commonjs@7.28.6': + resolution: {integrity: sha512-jppVbf8IV9iWWwWTQIxJMAJCWBuuKx71475wHwYytrRGQ2CWiDvYlADQno3tcYpS/T2UUWFQp3nVtYfK/YBQrA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-systemjs@7.29.4': + resolution: {integrity: sha512-N7QmZ0xRZfjHOfZeQLJjwgX2zS9pdGHSVl/cjSGlo4dXMqvurfxXDMKY4RqEKzPozV78VMcd0lxyG13mlbKc4w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-modules-umd@7.27.1': + resolution: {integrity: sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0': + resolution: {integrity: sha512-1CZQA5KNAD6ZYQLPw7oi5ewtDNxH/2vuCh+6SmvgDfhumForvs8a1o9n0UrEoBD8HU4djO2yWngTQlXl1NDVEQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-new-target@7.27.1': + resolution: {integrity: sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6': + resolution: {integrity: sha512-3wKbRgmzYbw24mDJXT7N+ADXw8BC/imU9yo9c9X9NKaLF1fW+e5H1U5QjMUBe4Qo4Ox/o++IyUkl1sVCLgevKg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-numeric-separator@7.28.6': + resolution: {integrity: sha512-SJR8hPynj8outz+SlStQSwvziMN4+Bq99it4tMIf5/Caq+3iOc0JtKyse8puvyXkk3eFRIA5ID/XfunGgO5i6w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-rest-spread@7.28.6': + resolution: {integrity: sha512-5rh+JR4JBC4pGkXLAcYdLHZjXudVxWMXbB6u6+E9lRL5TrGVbHt1TjxGbZ8CkmYw9zjkB7jutzOROArsqtncEA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-object-super@7.27.1': + resolution: {integrity: sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-catch-binding@7.28.6': + resolution: {integrity: sha512-R8ja/Pyrv0OGAvAXQhSTmWyPJPml+0TMqXlO5w+AsMEiwb2fg3WkOvob7UxFSL3OIttFSGSRFKQsOhJ/X6HQdQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-optional-chaining@7.28.6': + resolution: {integrity: sha512-A4zobikRGJTsX9uqVFdafzGkqD30t26ck2LmOzAuLL8b2x6k3TIqRiT2xVvA9fNmFeTX484VpsdgmKNA0bS23w==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-parameters@7.27.7': + resolution: {integrity: sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-methods@7.28.6': + resolution: {integrity: sha512-piiuapX9CRv7+0st8lmuUlRSmX6mBcVeNQ1b4AYzJxfCMuBfB0vBXDiGSmm03pKJw1v6cZ8KSeM+oUnM6yAExg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-private-property-in-object@7.28.6': + resolution: {integrity: sha512-b97jvNSOb5+ehyQmBpmhOCiUC5oVK4PMnpRvO7+ymFBoqYjeDHIU9jnrNUuwHOiL9RpGDoKBpSViarV+BU+eVA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-property-literals@7.27.1': + resolution: {integrity: sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-constant-elements@7.27.1': + resolution: {integrity: sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-display-name@7.28.0': + resolution: {integrity: sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx-development@7.27.1': + resolution: {integrity: sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-jsx@7.28.6': + resolution: {integrity: sha512-61bxqhiRfAACulXSLd/GxqmAedUSrRZIu/cbaT18T1CetkTmtDN15it7i80ru4DVqRK1WMxQhXs+Lf9kajm5Ow==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-react-pure-annotations@7.27.1': + resolution: {integrity: sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-regenerator@7.29.0': + resolution: {integrity: sha512-FijqlqMA7DmRdg/aINBSs04y8XNTYw/lr1gJ2WsmBnnaNw1iS43EPkJW+zK7z65auG3AWRFXWj+NcTQwYptUog==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-regexp-modifiers@7.28.6': + resolution: {integrity: sha512-QGWAepm9qxpaIs7UM9FvUSnCGlb8Ua1RhyM4/veAxLwt3gMat/LSGrZixyuj4I6+Kn9iwvqCyPTtbdxanYoWYg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/plugin-transform-reserved-words@7.27.1': + resolution: {integrity: sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-shorthand-properties@7.27.1': + resolution: {integrity: sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-spread@7.28.6': + resolution: {integrity: sha512-9U4QObUC0FtJl05AsUcodau/RWDytrU6uKgkxu09mLR9HLDAtUMoPuuskm5huQsoktmsYpI+bGmq+iapDcriKA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-sticky-regex@7.27.1': + resolution: {integrity: sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-template-literals@7.27.1': + resolution: {integrity: sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typeof-symbol@7.27.1': + resolution: {integrity: sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-typescript@7.28.6': + resolution: {integrity: sha512-0YWL2RFxOqEm9Efk5PvreamxPME8OyY0wM5wh5lHjF+VtVhdneCWGzZeSqzOfiobVqQaNCd2z0tQvnI9DaPWPw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-escapes@7.27.1': + resolution: {integrity: sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-property-regex@7.28.6': + resolution: {integrity: sha512-4Wlbdl/sIZjzi/8St0evF0gEZrgOswVO6aOzqxh1kDZOl9WmLrHq2HtGhnOJZmHZYKP8WZ1MDLCt5DAWwRo57A==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-regex@7.27.1': + resolution: {integrity: sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/plugin-transform-unicode-sets-regex@7.28.6': + resolution: {integrity: sha512-/wHc/paTUmsDYN7SZkpWxogTOBNnlx7nBQYfy6JJlCT7G3mVhltk3e++N7zV0XfgGsrqBxd4rJQt9H16I21Y1Q==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0 + + '@babel/preset-env@7.29.5': + resolution: {integrity: sha512-/69t2aEzGKHD76DyLbHysF/QH2LJOB8iFnYO37unDTKBTubzcMRv0f3H5EiN1Q6ajOd/eB7dAInF0qdFVS06kA==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-flow@7.27.1': + resolution: {integrity: sha512-ez3a2it5Fn6P54W8QkbfIyyIbxlXvcxyWHHvno1Wg0Ej5eiJY5hBb8ExttoIOJJk7V2dZE6prP7iby5q2aQ0Lg==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-modules@0.1.6-no-external-plugins': + resolution: {integrity: sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==} + peerDependencies: + '@babel/core': ^7.0.0-0 || ^8.0.0-0 <8.0.0 + + '@babel/preset-react@7.28.5': + resolution: {integrity: sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/preset-typescript@7.28.5': + resolution: {integrity: sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/register@7.29.3': + resolution: {integrity: sha512-F6C1KpIdoImKQfsD6HSxZ+mS4YY/2Q+JsqrmTC5ApVkTR2rG+nnbpjhWwzA5bDNu8mJjB3AryqDaWFLd4gCbJQ==} + engines: {node: '>=6.9.0'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} + engines: {node: '>=6.9.0'} + + '@babel/runtime@7.5.5': + resolution: {integrity: sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ==} + + '@babel/runtime@7.7.2': + resolution: {integrity: sha512-JONRbXbTXc9WQE2mAZd1p0Z3DZ/6vaQIkgYMSTP3KjRCyd7rCZCcfhCyX+YjwcKxcZ82UrxbRD358bpExNgrjw==} + + '@babel/template@7.28.6': + resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} + engines: {node: '>=6.9.0'} + + '@babel/traverse@7.29.0': + resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} + engines: {node: '>=6.9.0'} + + '@babel/types@7.29.0': + resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} + engines: {node: '>=6.9.0'} + + '@base2/pretty-print-object@1.0.1': + resolution: {integrity: sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA==} + + '@bcoe/v8-coverage@0.2.3': + resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} + + '@biomejs/biome@1.9.4': + resolution: {integrity: sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==} + engines: {node: '>=14.21.3'} + hasBin: true + + '@biomejs/cli-darwin-arm64@1.9.4': + resolution: {integrity: sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [darwin] + + '@biomejs/cli-darwin-x64@1.9.4': + resolution: {integrity: sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [darwin] + + '@biomejs/cli-linux-arm64-musl@1.9.4': + resolution: {integrity: sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@biomejs/cli-linux-arm64@1.9.4': + resolution: {integrity: sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@biomejs/cli-linux-x64-musl@1.9.4': + resolution: {integrity: sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@biomejs/cli-linux-x64@1.9.4': + resolution: {integrity: sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@biomejs/cli-win32-arm64@1.9.4': + resolution: {integrity: sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==} + engines: {node: '>=14.21.3'} + cpu: [arm64] + os: [win32] + + '@biomejs/cli-win32-x64@1.9.4': + resolution: {integrity: sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==} + engines: {node: '>=14.21.3'} + cpu: [x64] + os: [win32] + + '@bramus/specificity@2.4.2': + resolution: {integrity: sha512-ctxtJ/eA+t+6q2++vj5j7FYX3nRu311q1wfYH3xjlLOsczhlhxAg2FWNUXhpGvAw3BWo1xBcvOV6/YLc2r5FJw==} + hasBin: true + + '@chain-registry/client@1.53.356': + resolution: {integrity: sha512-d/9rj1XhZT6G7OoYuJ0KNiKvNH/LfFfv6Y0JzwAKbhOy3bXWET+brepGLIR3Es0/5FKuBGWT5TFGeQXqJmvbdA==} + + '@chain-registry/keplr@1.74.578': + resolution: {integrity: sha512-ma6I7f5JkdNcW89paufIbw+psMs4P8vtsqU3LuZM4uY4KQCnurPeDECoRwVnaCGjrouRMx4wDBoGWLEJkYdulQ==} + + '@chain-registry/types@0.46.15': + resolution: {integrity: sha512-gzf+pkAbEZ7fKuTuwmrEAEcx1K/BNrKuCnB9s+WwSo9Ad/3s+GV5LOXcOOxjjHh9Mrs9kvnxKvzKjOwWu8gDJw==} + + '@chain-registry/types@0.50.356': + resolution: {integrity: sha512-TOZCg/qfY3PoSPe+cPSOtMz30o+jGYKlvJgq2zTCQOkfufm1souN5EydUxL4RJzsj4eqar3Aq0oilc6KvdEcOg==} + + '@chain-registry/utils@1.51.356': + resolution: {integrity: sha512-I8/MJEnBvrXvFcSYnzXAM75UHsBMVdBUSYz/20f3clsTyDQyBiKdZRclO7k59IcrSDkbNYP546uXgfrW5CNuWA==} + + '@cnakazawa/watch@1.0.4': + resolution: {integrity: sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==} + engines: {node: '>=0.1.95'} + hasBin: true + + '@colors/colors@1.5.0': + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} + + '@confio/ics23@0.6.8': + resolution: {integrity: sha512-wB6uo+3A50m0sW/EWcU64xpV/8wShZ6bMTa7pF8eYsTrSkQA7oLUIJcs/wb8g4y2Oyq701BaGiO6n/ak5WXO1w==} + deprecated: Unmaintained. The codebase for this package was moved to https://github.com/cosmos/ics23 but then the JS implementation was removed in https://github.com/cosmos/ics23/pull/353. Please consult the maintainers of https://github.com/cosmos for further assistance. + + '@cosmjs/amino@0.25.6': + resolution: {integrity: sha512-9dXN2W7LHjDtJUGNsQ9ok0DfxeN3ca/TXnxCR3Ikh/5YqBqxI8Gel1J9PQO9L6EheYyh045Wff4bsMaLjyEeqQ==} + + '@cosmjs/amino@0.32.4': + resolution: {integrity: sha512-zKYOt6hPy8obIFtLie/xtygCkH9ZROiQ12UHfKsOkWaZfPQUvVbtgmu6R4Kn1tFLI/SRkw7eqhaogmW/3NYu/Q==} + + '@cosmjs/amino@0.36.2': + resolution: {integrity: sha512-r4yV1bhl412gwHGlyaUaJHIJnmldtyGsAwyz3oHHVxduiECj06Rv6wqeyLZfQa9W6hU+MlZwy7LabSUkkyGwjA==} + + '@cosmjs/cosmwasm-launchpad@0.25.6': + resolution: {integrity: sha512-rzpYg/A8tvXbY6p89LabPB1mqCtTUv+33nN+s+VWMH0oOl0LSIgLE0yIT61kwTaf2dWQvRVeFaiRLFC72/w/zw==} + + '@cosmjs/cosmwasm-stargate@0.25.6': + resolution: {integrity: sha512-STaxur5Xk5hqndLEztpa1TqvpdQyg2xD//2ZNFw2fgxf1JQtP0RfFbA3bnBkYwbGARx5cnng8QeZmSUcXnTVxA==} + + '@cosmjs/cosmwasm-stargate@0.32.4': + resolution: {integrity: sha512-Fuo9BGEiB+POJ5WeRyBGuhyKR1ordvxZGLPuPosFJOH9U0gKMgcjwKMCgAlWFkMlHaTB+tNdA8AifWiHrI7VgA==} + + '@cosmjs/cosmwasm-stargate@0.36.2': + resolution: {integrity: sha512-BU7i/gpvOkghR7XOhI5yT/KJuq3Sqexge2LrU+sBG//vN2ZKDdbLmjwP0S1IMP7aD8IWJfgEM41qbzWEILoPxw==} + + '@cosmjs/crypto@0.25.6': + resolution: {integrity: sha512-ec+YcQLrg2ibcxtNrh4FqQnG9kG9IE/Aik2NH6+OXQdFU/qFuBTxSFcKDgzzBOChwlkXwydllM9Jjbp+dgIzRw==} + deprecated: This uses elliptic for cryptographic operations, which contains several security-relevant bugs. To what degree this affects your application is something you need to carefully investigate. See https://github.com/cosmos/cosmjs/issues/1708 for further pointers. Starting with version 0.34.0 the cryptographic library has been replaced. However, private keys might still be at risk. + + '@cosmjs/crypto@0.32.4': + resolution: {integrity: sha512-zicjGU051LF1V9v7bp8p7ovq+VyC91xlaHdsFOTo2oVry3KQikp8L/81RkXmUIT8FxMwdx1T7DmFwVQikcSDIw==} + deprecated: This uses elliptic for cryptographic operations, which contains several security-relevant bugs. To what degree this affects your application is something you need to carefully investigate. See https://github.com/cosmos/cosmjs/issues/1708 for further pointers. Starting with version 0.34.0 the cryptographic library has been replaced. However, private keys might still be at risk. + + '@cosmjs/crypto@0.36.2': + resolution: {integrity: sha512-QL4NHtcqR6DEKIN200aLeR8gKO433K0f5avKV0TVFP/g12UtnEGSk79PJq5Gv1PLc9GtATHgLLQI/3D8TEe+ig==} + + '@cosmjs/encoding@0.25.6': + resolution: {integrity: sha512-0imUOB8XkUstI216uznPaX1hqgvLQ2Xso3zJj5IV5oJuNlsfDj9nt/iQxXWbJuettc6gvrFfpf+Vw2vBZSZ75g==} + + '@cosmjs/encoding@0.32.4': + resolution: {integrity: sha512-tjvaEy6ZGxJchiizzTn7HVRiyTg1i4CObRRaTRPknm5EalE13SV+TCHq38gIDfyUeden4fCuaBVEdBR5+ti7Hw==} + + '@cosmjs/encoding@0.36.2': + resolution: {integrity: sha512-i3+P1EKYoLcONAsmpJPhDAc3Wh3ajZNRHt/hczi/JEQXmleTJLVzv2mXUyllM6Qa+B6ybbr3Z2lnEFa8L3yLqg==} + + '@cosmjs/json-rpc@0.25.6': + resolution: {integrity: sha512-Mn9og3/IEzC6jWoYXs0ONqFJc8HxVjXzrZPLgaRRdMZEUBvctxdhynau1wbE4LdkYQHbu4aiRu1q1jMYGFAj4A==} + + '@cosmjs/json-rpc@0.32.4': + resolution: {integrity: sha512-/jt4mBl7nYzfJ2J/VJ+r19c92mUKF0Lt0JxM3MXEJl7wlwW5haHAWtzRujHkyYMXOwIR+gBqT2S0vntXVBRyhQ==} + + '@cosmjs/json-rpc@0.36.2': + resolution: {integrity: sha512-3IRamylHVCxBevXGlnIoWUdJCLsP5LwHbXYUsBnC9T8UttZ5oYRN5gDf6+2dQEPk+p9xOv2i8xrCwNWxo7675Q==} + + '@cosmjs/launchpad@0.25.6': + resolution: {integrity: sha512-4Yhn4cX50UE6jZz/hWqKeeCmvrlrz0BBwOdYX/29k25FqP+oLAow1xKm6UxgYuuAq8Pg/bUvswxSqwegZJTb6g==} + + '@cosmjs/math@0.25.6': + resolution: {integrity: sha512-Fmyc9FJ8KMU34n7rdapMJrT/8rx5WhMw2F7WLBu7AVLcBh0yWsXIcMSJCoPHTOnMIiABjXsnrrwEaLrOOBfu6A==} + + '@cosmjs/math@0.27.1': + resolution: {integrity: sha512-cHWVjmfIjtRc7f80n7x+J5k8pe+vTVTQ0lA82tIxUgqUvgS6rogPP/TmGtTiZ4+NxWxd11DUISY6gVpr18/VNQ==} + + '@cosmjs/math@0.32.4': + resolution: {integrity: sha512-++dqq2TJkoB8zsPVYCvrt88oJWsy1vMOuSOKcdlnXuOA/ASheTJuYy4+oZlTQ3Fr8eALDLGGPhJI02W2HyAQaw==} + + '@cosmjs/math@0.36.2': + resolution: {integrity: sha512-uJZRzxqnBk3MgxFgeyUwLgUzWkAIcmznWSB/tgGCjGCnUNebzI+44dA3ncEDCMqQysi/MZ+cSwAcDU7IY2PFeA==} + + '@cosmjs/proto-signing@0.25.6': + resolution: {integrity: sha512-JpQ+Vnv9s6i3x8f3Jo0lJZ3VMnj3R5sMgX+8ti1LtB7qEYRR85qbDrEG9hDGIKqJJabvrAuCHnO6hYi0vJEJHA==} + + '@cosmjs/proto-signing@0.32.4': + resolution: {integrity: sha512-QdyQDbezvdRI4xxSlyM1rSVBO2st5sqtbEIl3IX03uJ7YiZIQHyv6vaHVf1V4mapusCqguiHJzm4N4gsFdLBbQ==} + + '@cosmjs/proto-signing@0.36.2': + resolution: {integrity: sha512-dyZsgZBQgGkaE4cazHVX8GDwrRJVKUVDnrODkyFXVNbxMnm4t6nxpK1qwgY9GHlWUhck3Dh9NT3BoMbXiMYTZQ==} + + '@cosmjs/socket@0.25.6': + resolution: {integrity: sha512-hu+pW3Fy0IuhstXgxnZ2Iq0RUnGYoTWfqrxbTsgXBJge4MpEQs2YwGXgJZPMJXedBQivG0tU3r/Wvam0EWuRkQ==} + + '@cosmjs/socket@0.32.4': + resolution: {integrity: sha512-davcyYziBhkzfXQTu1l5NrpDYv0K9GekZCC9apBRvL1dvMc9F/ygM7iemHjUA+z8tJkxKxrt/YPjJ6XNHzLrkw==} + + '@cosmjs/socket@0.36.2': + resolution: {integrity: sha512-Pb7JcTFWnq6yfY0IEejHrpSxNDJYcqjjAa1D29a6b/obk4qa4o3oIV5bIx6zAbdRq8uLoBfvWs0bHTNnVuBWJg==} + + '@cosmjs/stargate@0.25.6': + resolution: {integrity: sha512-+LM1sK6vGuotJF9fBCBlaDL/yJhfzCV6KbsaWt3teHAKZhKYOd/9mKGiB4H9bfg4h3r+e+FZGiNkH/mdXkcgEw==} + + '@cosmjs/stargate@0.32.4': + resolution: {integrity: sha512-usj08LxBSsPRq9sbpCeVdyLx2guEcOHfJS9mHGCLCXpdAPEIEQEtWLDpEUc0LEhWOx6+k/ChXTc5NpFkdrtGUQ==} + + '@cosmjs/stargate@0.36.2': + resolution: {integrity: sha512-vnNK4dXF+s2v1aKPfYxKVrvXPcnBQb8rPoBScnTpPWnRt3XXbLw7Oo6fTQQWwKYNKQzi6DOApeEB+bCYcaPAAw==} + + '@cosmjs/stream@0.25.6': + resolution: {integrity: sha512-2mXIzf+WaFd+GSrRaJJETVXeZoC5sosuKChFERxSY8zXQ/f3OaG9J6m+quHpPbU3nAIEtnF1jgBVqJiD+NKwGQ==} + + '@cosmjs/stream@0.32.4': + resolution: {integrity: sha512-Gih++NYHEiP+oyD4jNEUxU9antoC0pFSg+33Hpp0JlHwH0wXhtD3OOKnzSfDB7OIoEbrzLJUpEjOgpCp5Z+W3A==} + + '@cosmjs/stream@0.36.2': + resolution: {integrity: sha512-FlZx2Buovem837LdTLPkPFcxzuQ7zierAqSXwMPr/MG3k+qMxHNfLFTTCXMNWQ4ZlbYedud8ZqCL3/HKdS5mig==} + + '@cosmjs/tendermint-rpc@0.25.6': + resolution: {integrity: sha512-wsvxTI7DReWJu+SVlXLblzh5NJppnh1mljuaTHodMf7HBxrXdbcCcBAO8oMbMgEqOASEY5G+z51wktxhrn9RtA==} + + '@cosmjs/tendermint-rpc@0.32.4': + resolution: {integrity: sha512-MWvUUno+4bCb/LmlMIErLypXxy7ckUuzEmpufYYYd9wgbdCXaTaO08SZzyFM5PI8UJ/0S2AmUrgWhldlbxO8mw==} + + '@cosmjs/tendermint-rpc@0.36.2': + resolution: {integrity: sha512-76Z99C1NVf/Yv/1bWU0wul8MhRwVdqiZxqU5bcHqvJLoQ2nKUfGpSSYRdbMHfZ63J8ryRqQ95uPvPTfrBb+agw==} + + '@cosmjs/utils@0.25.6': + resolution: {integrity: sha512-ofOYiuxVKNo238vCPPlaDzqPXy2AQ/5/nashBo5rvPZJkxt9LciGfUEQWPCOb1BIJDNx2Dzu0z4XCf/dwzl0Dg==} + + '@cosmjs/utils@0.32.4': + resolution: {integrity: sha512-D1Yc+Zy8oL/hkUkFUL/bwxvuDBzRGpc4cF7/SkdhxX4iHpSLgdOuTt1mhCh9+kl6NQREy9t7SYZ6xeW5gFe60w==} + + '@cosmjs/utils@0.36.2': + resolution: {integrity: sha512-OOr2HU/Ph+/GI1Fx2UCf3LOyX9YTCP51d2HitTOjjEJRYnkfKXP3lMBl1FZo5QaFWxnfuBc+Cj+cSoiQUJRyzQ==} + + '@cosmos-kit/core@2.18.1': + resolution: {integrity: sha512-LIOPHJevy3kuaE/U6gAsIAb+HOpEn8zeqrp3nGJdqyTR1oYOyaGDFZUfjMph1wXTJ+vgu7Loix49TIgFCxDVXw==} + + '@cosmos-kit/keplr-extension@2.17.1': + resolution: {integrity: sha512-81fxThFG4m4Am4cUaNVYo99nF0KBfWN+Zz6Kmgskff7FBdOlh8wGk0kEHKExX7GOnpTV2xK50lf3cVJ1ZQTYKA==} + peerDependencies: + '@cosmjs/amino': '>=0.32.3' + '@cosmjs/proto-signing': '>=0.32.3' + + '@cosmos-kit/react-lite@2.18.1': + resolution: {integrity: sha512-Us7gBZtb1eYxcwMu74ii+pIeR4TE5Q+JhSXkyKUJHh/wDQyTNhCYGpp9PJUMUAiuLuPsv1qToEoeuk6gcD7XaQ==} + peerDependencies: + '@types/react': latest + '@types/react-dom': latest + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@cosmos-kit/react@2.24.1': + resolution: {integrity: sha512-jNTye1dyw8QeVa2BCZccZPxTQBoqX8R9KchhNJFX74tWVgE4jjcz4bLlegjs/G1C8NLEqbDlUCRAiDTg9B92oA==} + peerDependencies: + '@interchain-ui/react': ^1.26.3 + '@types/react': latest + '@types/react-dom': latest + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@csstools/color-helpers@6.0.2': + resolution: {integrity: sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==} + engines: {node: '>=20.19.0'} + + '@csstools/css-calc@3.2.1': + resolution: {integrity: sha512-DtdHlgXh5ZkA43cwBcAm+huzgJiwx3ZTWVjBs94kwz2xKqSimDA3lBgCjphYgwgVUMWatSM0pDd8TILB1yrVVg==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@csstools/css-parser-algorithms': ^4.0.0 + '@csstools/css-tokenizer': ^4.0.0 + + '@csstools/css-color-parser@4.1.1': + resolution: {integrity: sha512-eZ5XOtyhK+mggRafYUWzA0tvaYOFgdY8AkgQiCJF9qNAePnUo/zmsqqYubBBb3sQ8uNUaSKTY9s9klfRaAXL0g==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@csstools/css-parser-algorithms': ^4.0.0 + '@csstools/css-tokenizer': ^4.0.0 + + '@csstools/css-parser-algorithms@4.0.0': + resolution: {integrity: sha512-+B87qS7fIG3L5h3qwJ/IFbjoVoOe/bpOdh9hAjXbvx0o8ImEmUsGXN0inFOnk2ChCFgqkkGFQ+TpM5rbhkKe4w==} + engines: {node: '>=20.19.0'} + peerDependencies: + '@csstools/css-tokenizer': ^4.0.0 + + '@csstools/css-syntax-patches-for-csstree@1.1.4': + resolution: {integrity: sha512-wgsqt92b7C7tQhIdPNxj0n9zuUbQlvAuI1exyzeNrOKOi62SD7ren8zqszmpVREjAOqg8cD2FqYhQfAuKjk4sw==} + peerDependencies: + css-tree: ^3.2.1 + peerDependenciesMeta: + css-tree: + optional: true + + '@csstools/css-tokenizer@4.0.0': + resolution: {integrity: sha512-QxULHAm7cNu72w97JUNCBFODFaXpbDg+dP8b/oWFAZ2MTRppA3U00Y2L1HqaS4J6yBqxwa/Y3nMBaxVKbB/NsA==} + engines: {node: '>=20.19.0'} + + '@dao-dao/cosmiframe@1.0.0': + resolution: {integrity: sha512-xPaD9MV1tUueYl+VIJD7CEi4+MCdcgo4E1R9w8XplKlM7pvmBaSBeTz88HwITpKxWKI+DWoJngeCWu5/8oqLJQ==} + peerDependencies: + '@cosmjs/amino': '>= ^0.32' + '@cosmjs/proto-signing': '>= ^0.32' + + '@design-systems/utils@2.12.0': + resolution: {integrity: sha512-Y/d2Zzr+JJfN6u1gbuBUb1ufBuLMJJRZQk+dRmw8GaTpqKx5uf7cGUYGTwN02dIb3I+Tf+cW8jcGBTRiFxdYFg==} + peerDependencies: + '@types/react': '*' + react: '>= 16.8.6' + react-dom: '>= 16.8.6' + + '@devtools-ds/object-inspector@1.2.1': + resolution: {integrity: sha512-nrAVVj4c4Iv9958oE4HA7Mk6T+4Mn/4xBRlFDeX4Ps6SMzsqO8bKhw/y6+bOfNyb/TYHmC0/pnPS68GDVZcg5Q==} + peerDependencies: + react: '>= 16.8.6' + + '@devtools-ds/object-parser@1.2.1': + resolution: {integrity: sha512-6qB+THhQfJqXyHn8wpJ1KFxXcbpLTlRyCVmkelhr0c1+MPLZcC+0XJxpVZ1AOEXPa6CWVZThBYSCvnYQEvfCqw==} + + '@devtools-ds/themes@1.2.1': + resolution: {integrity: sha512-4/KFsHnokGxUq8CSCchINcVBb6fQ74HtEfNtMuitGtGg3VCRV0kaVSOsz6wzShzhLEaVLd5coSRQKaZj7yx72w==} + peerDependencies: + react: '>= 16.8.6' + + '@devtools-ds/tree@1.2.1': + resolution: {integrity: sha512-2ZHG28oWJno0gD+20EoSJO0yffm6JS5r7YzYhGMkrnLGvcCRZuwXSxMmIshSPLIR0cjidiAfGCqsrigHIR4ZQA==} + peerDependencies: + react: '>= 16.8.6' + + '@discoveryjs/json-ext@0.5.7': + resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} + engines: {node: '>=10.0.0'} + + '@emnapi/core@1.10.0': + resolution: {integrity: sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==} + + '@emnapi/runtime@1.10.0': + resolution: {integrity: sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==} + + '@emnapi/wasi-threads@1.2.1': + resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==} + + '@emotion/babel-plugin@11.13.5': + resolution: {integrity: sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==} + + '@emotion/cache@11.14.0': + resolution: {integrity: sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==} + + '@emotion/hash@0.9.2': + resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==} + + '@emotion/is-prop-valid@1.4.0': + resolution: {integrity: sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw==} + + '@emotion/memoize@0.9.0': + resolution: {integrity: sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==} + + '@emotion/react@11.14.0': + resolution: {integrity: sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==} + peerDependencies: + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + + '@emotion/serialize@1.3.3': + resolution: {integrity: sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==} + + '@emotion/sheet@1.4.0': + resolution: {integrity: sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==} + + '@emotion/styled@11.14.1': + resolution: {integrity: sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw==} + peerDependencies: + '@emotion/react': ^11.0.0-rc.0 + '@types/react': '*' + react: '>=16.8.0' + peerDependenciesMeta: + '@types/react': + optional: true + + '@emotion/unitless@0.10.0': + resolution: {integrity: sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==} + + '@emotion/use-insertion-effect-with-fallbacks@1.2.0': + resolution: {integrity: sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==} + peerDependencies: + react: '>=16.8.0' + + '@emotion/utils@1.4.2': + resolution: {integrity: sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==} + + '@emotion/weak-memoize@0.4.0': + resolution: {integrity: sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==} + + '@esbuild/aix-ppc64@0.25.12': + resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.25.12': + resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.25.12': + resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.25.12': + resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.25.12': + resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.25.12': + resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.25.12': + resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.25.12': + resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.25.12': + resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.25.12': + resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.25.12': + resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.25.12': + resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.25.12': + resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.25.12': + resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.25.12': + resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.25.12': + resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.25.12': + resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.12': + resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.25.12': + resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.25.12': + resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.25.12': + resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.25.12': + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.25.12': + resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.25.12': + resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.25.12': + resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.25.12': + resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@eslint-community/eslint-utils@4.9.1': + resolution: {integrity: sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + + '@eslint-community/regexpp@4.12.2': + resolution: {integrity: sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==} + engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} + + '@eslint/config-array@0.21.2': + resolution: {integrity: sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/config-helpers@0.4.2': + resolution: {integrity: sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/core@0.17.0': + resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/eslintrc@2.1.4': + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@eslint/eslintrc@3.3.5': + resolution: {integrity: sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/js@8.57.1': + resolution: {integrity: sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@eslint/js@9.39.4': + resolution: {integrity: sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/object-schema@2.1.7': + resolution: {integrity: sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@eslint/plugin-kit@0.4.1': + resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@ethersproject/address@5.8.0': + resolution: {integrity: sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==} + + '@ethersproject/bignumber@5.8.0': + resolution: {integrity: sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==} + + '@ethersproject/bytes@5.8.0': + resolution: {integrity: sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==} + + '@ethersproject/keccak256@5.8.0': + resolution: {integrity: sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==} + + '@ethersproject/logger@5.8.0': + resolution: {integrity: sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==} + + '@ethersproject/rlp@5.8.0': + resolution: {integrity: sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==} + + '@exodus/bytes@1.15.0': + resolution: {integrity: sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + '@noble/hashes': ^1.8.0 || ^2.0.0 + peerDependenciesMeta: + '@noble/hashes': + optional: true + + '@floating-ui/core@1.7.5': + resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} + + '@floating-ui/dom@1.7.6': + resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==} + + '@floating-ui/react-dom@2.1.8': + resolution: {integrity: sha512-cC52bHwM/n/CxS87FH0yWdngEZrjdtLW/qVruo68qg+prK7ZQ4YGdut2GyDVpoGeAYe/h899rVeOVm6Oi40k2A==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/react@0.26.28': + resolution: {integrity: sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==} + peerDependencies: + react: '>=16.8.0' + react-dom: '>=16.8.0' + + '@floating-ui/utils@0.2.11': + resolution: {integrity: sha512-RiB/yIh78pcIxl6lLMG0CgBXAZ2Y0eVHqMPYugu+9U0AeT6YBeiJpf7lbdJNIugFP5SIjwNRgo4DhR1Qxi26Gg==} + + '@formkit/auto-animate@0.8.4': + resolution: {integrity: sha512-DHHC01EJ1p70Q0z/ZFRBIY8NDnmfKccQoyoM84Tgb6omLMat6jivCdf272Y8k3nf4Lzdin/Y4R9q8uFtU0GbnA==} + + '@gar/promisify@1.1.3': + resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} + + '@hapi/hoek@9.3.0': + resolution: {integrity: sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==} + + '@hapi/topo@5.1.0': + resolution: {integrity: sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==} + + '@hookform/resolvers@2.9.11': + resolution: {integrity: sha512-bA3aZ79UgcHj7tFV7RlgThzwSSHZgvfbt2wprldRkYBcMopdMvHyO17Wwp/twcJasNFischFfS7oz8Katz8DdQ==} + peerDependencies: + react-hook-form: ^7.0.0 + + '@humanfs/core@0.19.2': + resolution: {integrity: sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==} + engines: {node: '>=18.18.0'} + + '@humanfs/node@0.16.8': + resolution: {integrity: sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==} + engines: {node: '>=18.18.0'} + + '@humanfs/types@0.15.0': + resolution: {integrity: sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==} + engines: {node: '>=18.18.0'} + + '@humanwhocodes/config-array@0.13.0': + resolution: {integrity: sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + + '@humanwhocodes/module-importer@1.0.1': + resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} + engines: {node: '>=12.22'} + + '@humanwhocodes/object-schema@2.0.3': + resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} + deprecated: Use @eslint/object-schema instead + + '@humanwhocodes/retry@0.4.3': + resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} + engines: {node: '>=18.18'} + + '@hutson/parse-repository-url@3.0.2': + resolution: {integrity: sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==} + engines: {node: '>=6.9.0'} + + '@img/sharp-darwin-arm64@0.33.5': + resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.33.5': + resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.0.4': + resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.0.4': + resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.0.4': + resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-arm@1.0.5': + resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-s390x@1.0.4': + resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linux-x64@1.0.4': + resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-linux-arm64@0.33.5': + resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-arm@0.33.5': + resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-s390x@0.33.5': + resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@img/sharp-linux-x64@0.33.5': + resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@img/sharp-linuxmusl-arm64@0.33.5': + resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@img/sharp-linuxmusl-x64@0.33.5': + resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@img/sharp-wasm32@0.33.5': + resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-ia32@0.33.5': + resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.33.5': + resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + + '@inquirer/external-editor@1.0.3': + resolution: {integrity: sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==} + engines: {node: '>=18'} + peerDependencies: + '@types/node': '>=18' + peerDependenciesMeta: + '@types/node': + optional: true + + '@interchain-ui/react@1.26.3': + resolution: {integrity: sha512-kvGOZaSDJLNxtxieiyPMHOzxBGkpHR/BCpg/UEMDl2l7nLoPrygB/Oux1QEv/cwkw8GvepOBM7pzfJf8xk1IbQ==} + peerDependencies: + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + + '@internationalized/date@3.12.1': + resolution: {integrity: sha512-6IedsVWXyq4P9Tj+TxuU8WGWM70hYLl12nbYU8jkikVpa6WXapFazPUcHUMDMoWftIDE2ILDkFFte6W2nFCkRQ==} + + '@internationalized/number@3.6.6': + resolution: {integrity: sha512-iFgmQaXHE0vytNfpLZWOC2mEJCBRzcUxt53Xf/yCXG93lRvqas237i3r7X4RKMwO3txiyZD4mQjKAByFv6UGSQ==} + + '@internationalized/string@3.2.8': + resolution: {integrity: sha512-NdbMQUSfXLYIQol5VyMtinm9pZDciiMfN7RtmSuSB78io1hqwJ0naYfxyW6vgxWBkzWymQa/3uLDlbfmshtCaA==} + + '@isaacs/cliui@8.0.2': + resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} + engines: {node: '>=12'} + + '@istanbuljs/load-nyc-config@1.1.0': + resolution: {integrity: sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==} + engines: {node: '>=8'} + + '@istanbuljs/schema@0.1.6': + resolution: {integrity: sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==} + engines: {node: '>=8'} + + '@jest/console@27.5.1': + resolution: {integrity: sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + '@jest/console@29.7.0': + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/core@27.5.1': + resolution: {integrity: sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/core@29.7.0': + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/environment@27.5.1': + resolution: {integrity: sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + '@jest/environment@29.7.0': + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect-utils@29.7.0': + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/expect@29.7.0': + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/fake-timers@27.5.1': + resolution: {integrity: sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + '@jest/fake-timers@29.7.0': + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/globals@27.5.1': + resolution: {integrity: sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + '@jest/globals@29.7.0': + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/reporters@27.5.1': + resolution: {integrity: sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/reporters@29.7.0': + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/source-map@27.5.1': + resolution: {integrity: sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + '@jest/source-map@29.6.3': + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-result@27.5.1': + resolution: {integrity: sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + '@jest/test-result@29.7.0': + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/test-sequencer@27.5.1': + resolution: {integrity: sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + '@jest/test-sequencer@29.7.0': + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/transform@26.6.2': + resolution: {integrity: sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA==} + engines: {node: '>= 10.14.2'} + + '@jest/transform@27.5.1': + resolution: {integrity: sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + '@jest/transform@29.7.0': + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jest/types@26.6.2': + resolution: {integrity: sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ==} + engines: {node: '>= 10.14.2'} + + '@jest/types@27.5.1': + resolution: {integrity: sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/remapping@2.3.5': + resolution: {integrity: sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.11': + resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@keplr-wallet/common@0.12.28': + resolution: {integrity: sha512-ESQorPZw8PRiUXhsrxED+E1FEWkAdc6Kwi3Az7ce204gMBQDI2j0XJtTd4uCUp+C24Em9fk0samdHzdoB4caIg==} + + '@keplr-wallet/cosmos@0.12.28': + resolution: {integrity: sha512-IuqmSBgKgIeWBA0XGQKKs28IXFeFMCrfadCbtiZccNc7qnNr5Y/Cyyk01BPC8Dd1ZyEyAByoICgrxvtGN0GGvA==} + + '@keplr-wallet/crypto@0.12.28': + resolution: {integrity: sha512-le1je+78/4213qshSMgQTYqhCCvzsL9+YfhjXg1kd/ali69MLWK8L8Z09ducHPS6C+LqQXXTNJQpbH2uiFSd5w==} + + '@keplr-wallet/proto-types@0.12.28': + resolution: {integrity: sha512-ukti/eCTltPUP64jxtk5TjtwJogyfKPqlBIT3KGUCGzBLIPeYMsffL5w5aoHsMjINzOITjYqzXyEF8LTIK/fmw==} + + '@keplr-wallet/provider-extension@0.12.313': + resolution: {integrity: sha512-ffIXfUiZUfakEzcn1cE6gcnUs3p8IDRpopb1Xu87W+8aGVKv8HCDReIesE/jmJ6cj2TZc11BjKh4EdXKCscX2w==} + peerDependencies: + starknet: ^8 + + '@keplr-wallet/simple-fetch@0.12.28': + resolution: {integrity: sha512-T2CiKS2B5n0ZA7CWw0CA6qIAH0XYI1siE50MP+i+V0ZniCGBeL+BMcDw64vFJUcEH+1L5X4sDAzV37fQxGwllA==} + + '@keplr-wallet/types@0.12.28': + resolution: {integrity: sha512-EcM9d46hYDm3AO4lf4GUbTSLRySONtTmhKb7p88q56OQOgJN3MMjRacEo2p9jX9gpPe7gRIjMUalhAfUiFpZoQ==} + + '@keplr-wallet/types@0.12.313': + resolution: {integrity: sha512-of3e8ISp8h9skE6NXHvaj7yKoNLhVkSdbFgcjSKH6JGg584zSIRrlyawjbNg3JI1kqi3MiuuOrFQZ+SOztGK9Q==} + peerDependencies: + starknet: ^8 + + '@keplr-wallet/unit@0.12.28': + resolution: {integrity: sha512-kpXigHDBJGOmhtPkv9hqsQid9zkFo7OQPeKgO2n8GUlOINIXW6kWG5LXYTi/Yg9Uiw1CQF69gFMuZCJ8IzVHlA==} + + '@leichtgewicht/ip-codec@2.0.5': + resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} + + '@lerna/child-process@7.4.2': + resolution: {integrity: sha512-je+kkrfcvPcwL5Tg8JRENRqlbzjdlZXyaR88UcnCdNW0AJ1jX9IfHRys1X7AwSroU2ug8ESNC+suoBw1vX833Q==} + engines: {node: '>=16.0.0'} + + '@lerna/create@7.4.2': + resolution: {integrity: sha512-1wplFbQ52K8E/unnqB0Tq39Z4e+NEoNrpovEnl6GpsTUrC6WDp8+w0Le2uCBV0hXyemxChduCkLz4/y1H1wTeg==} + engines: {node: '>=16.0.0'} + deprecated: This package is an implementation detail of Lerna and is no longer published separately. + + '@mdx-js/mdx@1.6.22': + resolution: {integrity: sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA==} + + '@mdx-js/react@1.6.22': + resolution: {integrity: sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==} + peerDependencies: + react: ^16.13.1 || ^17.0.0 + + '@mdx-js/util@1.6.22': + resolution: {integrity: sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==} + + '@mrmlnc/readdir-enhanced@2.2.1': + resolution: {integrity: sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==} + engines: {node: '>=4'} + + '@mui/base@5.0.0-beta.40': + resolution: {integrity: sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==} + engines: {node: '>=12.0.0'} + deprecated: This package has been replaced by @base-ui/react + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@mui/core-downloads-tracker@5.18.0': + resolution: {integrity: sha512-jbhwoQ1AY200PSSOrNXmrFCaSDSJWP7qk6urkTmIirvRXDROkqe+QwcLlUiw/PrREwsIF/vm3/dAXvjlMHF0RA==} + + '@mui/core-downloads-tracker@6.5.0': + resolution: {integrity: sha512-LGb8t8i6M2ZtS3Drn3GbTI1DVhDY6FJ9crEey2lZ0aN2EMZo8IZBZj9wRf4vqbZHaWjsYgtbOnJw5V8UWbmK2Q==} + + '@mui/icons-material@5.18.0': + resolution: {integrity: sha512-1s0vEZj5XFXDMmz3Arl/R7IncFqJ+WQ95LDp1roHWGDE2oCO3IS4/hmiOv1/8SD9r6B7tv9GLiqVZYHo+6PkTg==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@mui/material': ^5.0.0 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@mui/lab@5.0.0-alpha.170': + resolution: {integrity: sha512-0bDVECGmrNjd3+bLdcLiwYZ0O4HP5j5WSQm5DV6iA/Z9kr8O6AnvZ1bv9ImQbbX7Gj3pX4o43EKwCutj3EQxQg==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@mui/material': '>=5.15.0' + '@types/react': ^17.0.0 || ^18.0.0 + react: ^17.0.0 || ^18.0.0 + react-dom: ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@types/react': + optional: true + + '@mui/material-nextjs@6.5.0': + resolution: {integrity: sha512-VV+4BhmnY32pbPuIevs+rPl0R+bkVvqGCqRqZqNhkdBdX0pn1IHQ5mG/EfYJKoKUkF7q9FKSag5wduSTUxDqnQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@emotion/cache': ^11.11.0 + '@emotion/react': ^11.11.4 + '@emotion/server': ^11.11.0 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + next: ^13.0.0 || ^14.0.0 || ^15.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/cache': + optional: true + '@emotion/server': + optional: true + '@types/react': + optional: true + + '@mui/material@5.18.0': + resolution: {integrity: sha512-bbH/HaJZpFtXGvWg3TsBWG4eyt3gah3E7nCNU8GLyRjVoWcA91Vm/T+sjHfUcwgJSw9iLtucfHBoq+qW/T30aA==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@types/react': + optional: true + + '@mui/material@6.5.0': + resolution: {integrity: sha512-yjvtXoFcrPLGtgKRxFaH6OQPtcLPhkloC0BML6rBG5UeldR0nPULR/2E2BfXdo5JNV7j7lOzrrLX2Qf/iSidow==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@mui/material-pigment-css': ^6.5.0 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@mui/material-pigment-css': + optional: true + '@types/react': + optional: true + + '@mui/private-theming@5.17.1': + resolution: {integrity: sha512-XMxU0NTYcKqdsG8LRmSoxERPXwMbp16sIXPcLVgLGII/bVNagX0xaheWAwFv8+zDK7tI3ajllkuD3GZZE++ICQ==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@mui/private-theming@6.4.9': + resolution: {integrity: sha512-LktcVmI5X17/Q5SkwjCcdOLBzt1hXuc14jYa7NPShog0GBDCDvKtcnP0V7a2s6EiVRlv7BzbWEJzH6+l/zaCxw==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@mui/styled-engine@5.18.0': + resolution: {integrity: sha512-BN/vKV/O6uaQh2z5rXV+MBlVrEkwoS/TK75rFQ2mjxA7+NBo8qtTAOA4UaM0XeJfn7kh2wZ+xQw2HAx0u+TiBg==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@emotion/react': ^11.4.1 + '@emotion/styled': ^11.3.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + + '@mui/styled-engine@6.5.0': + resolution: {integrity: sha512-8woC2zAqF4qUDSPIBZ8v3sakj+WgweolpyM/FXf8jAx6FMls+IE4Y8VDZc+zS805J7PRz31vz73n2SovKGaYgw==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@emotion/react': ^11.4.1 + '@emotion/styled': ^11.3.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + + '@mui/styles@5.18.0': + resolution: {integrity: sha512-GDgFUfl2MMN8iGrYTuhJ0hHRoja2kVOlXnHb5d3BBQCHFxOBaAPDKQxaNkoAwRf/vBhhwXWDsJA2XlkNHUPBgA==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@mui/system@5.18.0': + resolution: {integrity: sha512-ojZGVcRWqWhu557cdO3pWHloIGJdzVtxs3rk0F9L+x55LsUjcMUVkEhiF7E4TMxZoF9MmIHGGs0ZX3FDLAf0Xw==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@types/react': + optional: true + + '@mui/system@6.5.0': + resolution: {integrity: sha512-XcbBYxDS+h/lgsoGe78ExXFZXtuIlSBpn/KsZq8PtZcIkUNJInkuDqcLd2rVBQrDC1u+rvVovdaWPf2FHKJf3w==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@emotion/react': ^11.5.0 + '@emotion/styled': ^11.3.0 + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + '@types/react': + optional: true + + '@mui/types@7.2.24': + resolution: {integrity: sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@mui/types@7.4.12': + resolution: {integrity: sha512-iKNAF2u9PzSIj40CjvKJWxFXJo122jXVdrmdh0hMYd+FR+NuJMkr/L88XwWLCRiJ5P1j+uyac25+Kp6YC4hu6w==} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@mui/utils@5.17.1': + resolution: {integrity: sha512-jEZ8FTqInt2WzxDV8bhImWBqeQRD99c/id/fq83H0ER9tFl+sfZlaAoCdznGvbSQQ9ividMxqSV2c7cC1vBcQg==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@mui/utils@6.4.9': + resolution: {integrity: sha512-Y12Q9hbK9g+ZY0T3Rxrx9m2m10gaphDuUMgWxyV5kNJevVxXYCLclYUCC9vXaIk1/NdNDTcW2Yfr2OGvNFNmHg==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + + '@mui/x-date-pickers@7.29.4': + resolution: {integrity: sha512-wJ3tsqk/y6dp+mXGtT9czciAMEO5Zr3IIAHg9x6IL0Eqanqy0N3chbmQQZv3iq0m2qUpQDLvZ4utZBUTJdjNzw==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@emotion/react': ^11.9.0 + '@emotion/styled': ^11.8.1 + '@mui/material': ^5.15.14 || ^6.0.0 || ^7.0.0 + '@mui/system': ^5.15.14 || ^6.0.0 || ^7.0.0 + date-fns: ^2.25.0 || ^3.2.0 || ^4.0.0 + date-fns-jalali: ^2.13.0-0 || ^3.2.0-0 || ^4.0.0-0 + dayjs: ^1.10.7 + luxon: ^3.0.2 + moment: ^2.29.4 + moment-hijri: ^2.1.2 || ^3.0.0 + moment-jalaali: ^0.7.4 || ^0.8.0 || ^0.9.0 || ^0.10.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + date-fns: + optional: true + date-fns-jalali: + optional: true + dayjs: + optional: true + luxon: + optional: true + moment: + optional: true + moment-hijri: + optional: true + moment-jalaali: + optional: true + + '@mui/x-internals@7.29.0': + resolution: {integrity: sha512-+Gk6VTZIFD70XreWvdXBwKd8GZ2FlSCuecQFzm6znwqXg1ZsndavrhG9tkxpxo2fM1Zf7Tk8+HcOO0hCbhTQFA==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@mui/x-tree-view@7.29.10': + resolution: {integrity: sha512-/ZcM582yIaQN2PmadIlQYRJzc3yXV7bh463J4GHtTmFw+PEjzUfzETBWe3VxmU3EPgIFzVQPjqAAJwylmQSJOg==} + engines: {node: '>=14.0.0'} + peerDependencies: + '@emotion/react': ^11.9.0 + '@emotion/styled': ^11.8.1 + '@mui/material': ^5.15.14 || ^6.0.0 || ^7.0.0 + '@mui/system': ^5.15.14 || ^6.0.0 || ^7.0.0 + react: ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + + '@napi-rs/wasm-runtime@0.2.12': + resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} + + '@next/env@14.2.35': + resolution: {integrity: sha512-DuhvCtj4t9Gwrx80dmz2F4t/zKQ4ktN8WrMwOuVzkJfBilwAwGr6v16M5eI8yCuZ63H9TTuEU09Iu2HqkzFPVQ==} + + '@next/eslint-plugin-next@15.0.3': + resolution: {integrity: sha512-3Ln/nHq2V+v8uIaxCR6YfYo7ceRgZNXfTd3yW1ukTaFbO+/I8jNakrjYWODvG9BuR2v5kgVtH/C8r0i11quOgw==} + + '@next/swc-darwin-arm64@14.2.33': + resolution: {integrity: sha512-HqYnb6pxlsshoSTubdXKu15g3iivcbsMXg4bYpjL2iS/V6aQot+iyF4BUc2qA/J/n55YtvE4PHMKWBKGCF/+wA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@next/swc-darwin-x64@14.2.33': + resolution: {integrity: sha512-8HGBeAE5rX3jzKvF593XTTFg3gxeU4f+UWnswa6JPhzaR6+zblO5+fjltJWIZc4aUalqTclvN2QtTC37LxvZAA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@next/swc-linux-arm64-gnu@14.2.33': + resolution: {integrity: sha512-JXMBka6lNNmqbkvcTtaX8Gu5by9547bukHQvPoLe9VRBx1gHwzf5tdt4AaezW85HAB3pikcvyqBToRTDA4DeLw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@next/swc-linux-arm64-musl@14.2.33': + resolution: {integrity: sha512-Bm+QulsAItD/x6Ih8wGIMfRJy4G73tu1HJsrccPW6AfqdZd0Sfm5Imhgkgq2+kly065rYMnCOxTBvmvFY1BKfg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@next/swc-linux-x64-gnu@14.2.33': + resolution: {integrity: sha512-FnFn+ZBgsVMbGDsTqo8zsnRzydvsGV8vfiWwUo1LD8FTmPTdV+otGSWKc4LJec0oSexFnCYVO4hX8P8qQKaSlg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@next/swc-linux-x64-musl@14.2.33': + resolution: {integrity: sha512-345tsIWMzoXaQndUTDv1qypDRiebFxGYx9pYkhwY4hBRaOLt8UGfiWKr9FSSHs25dFIf8ZqIFaPdy5MljdoawA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@next/swc-win32-arm64-msvc@14.2.33': + resolution: {integrity: sha512-nscpt0G6UCTkrT2ppnJnFsYbPDQwmum4GNXYTeoTIdsmMydSKFz9Iny2jpaRupTb+Wl298+Rh82WKzt9LCcqSQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@next/swc-win32-ia32-msvc@14.2.33': + resolution: {integrity: sha512-pc9LpGNKhJ0dXQhZ5QMmYxtARwwmWLpeocFmVG5Z0DzWq5Uf0izcI8tLc+qOpqxO1PWqZ5A7J1blrUIKrIFc7Q==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + + '@next/swc-win32-x64-msvc@14.2.33': + resolution: {integrity: sha512-nOjfZMy8B94MdisuzZo9/57xuFVLHJaDj5e/xrduJp9CV2/HrfxTRH2fbyLe+K9QT41WBLUd4iXX3R7jBp0EUg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@nivo/annotations@0.88.0': + resolution: {integrity: sha512-NXE+1oIUn+EGWMQpnpeRMLgi2wyuzhGDoJQY4OUHissCUiNotid2oNQ/PXJwN0toiu+/j9SyhzI32xr70OPi7Q==} + peerDependencies: + react: '>= 16.14.0 < 19.0.0' + + '@nivo/axes@0.88.0': + resolution: {integrity: sha512-jF7aIxzTNayV5cI1J/b9Q1FfpMBxTXGk3OwSigXMSfYWlliskDn2u0qGRLiYhuXFdQAWIp4oXsO1GcAQ0eRVdg==} + peerDependencies: + react: '>= 16.14.0 < 19.0.0' + + '@nivo/colors@0.88.0': + resolution: {integrity: sha512-IZ+leYIqAlo7dyLHmsQwujanfRgXyoQ5H7PU3RWLEn1PP0zxDKLgEjFEDADpDauuslh2Tx0L81GNkWR6QSP0Mw==} + peerDependencies: + react: '>= 16.14.0 < 19.0.0' + + '@nivo/core@0.88.0': + resolution: {integrity: sha512-XjUkA5MmwjLP38bdrJwn36Gj7T5SYMKD55LYQp/1nIJPdxqJ38dUfE4XyBDfIEgfP6yrHOihw3C63cUdnUBoiw==} + peerDependencies: + react: '>= 16.14.0 < 19.0.0' + + '@nivo/legends@0.88.0': + resolution: {integrity: sha512-d4DF9pHbD8LmGJlp/Gp1cF4e8y2wfQTcw3jVhbZj9zkb7ZWB7JfeF60VHRfbXNux9bjQ9U78/SssQqueVDPEmg==} + peerDependencies: + react: '>= 16.14.0 < 19.0.0' + + '@nivo/line@0.88.0': + resolution: {integrity: sha512-hFTyZ3BdAZvq2HwdwMj2SJGUeodjEW+7DLtFMIIoVIxmjZlAs3z533HcJ9cJd3it928fDm8SF/rgHs0TztYf9Q==} + peerDependencies: + react: '>= 16.14.0 < 19.0.0' + + '@nivo/scales@0.88.0': + resolution: {integrity: sha512-HbpxkQp6tHCltZ1yDGeqdLcaJl5ze54NPjurfGtx/Uq+H5IQoBd4Tln49bUar5CsFAMsXw8yF1HQvASr7I1SIA==} + + '@nivo/tooltip@0.88.0': + resolution: {integrity: sha512-iEjVfQA8gumAzg/yUinjTwswygCkE5Iwuo8opwnrbpNIqMrleBV+EAKIgB0PrzepIoW8CFG/SJhoiRfbU8jhOw==} + peerDependencies: + react: '>= 16.14.0 < 19.0.0' + + '@nivo/voronoi@0.88.0': + resolution: {integrity: sha512-MyiNLvODthFoMjQ7Wjp693nogbTmVEx8Yn/7QkJhyPQbFyyA37TF/D1a/ox4h2OslXtP6K9QFN+42gB/zu7ixw==} + peerDependencies: + react: '>= 16.14.0 < 19.0.0' + + '@noble/ciphers@1.3.0': + resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.7.0': + resolution: {integrity: sha512-UTMhXK9SeDhFJVrHeUJ5uZlI6ajXg10O6Ddocf9S6GjbSBVZsJo88HzKwXznNfGpMTRDyJkqMjNDPYgf0qFWnw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.7': + resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.6.0': + resolution: {integrity: sha512-YUULf0Uk4/mAA89w+k3+yUYh6NrEvxZa5T6SY3wlMvE2chHkxFUUIDI8/XW1QSC357iA5pSnqt7XEhvFOqmDyQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.6.1': + resolution: {integrity: sha512-pq5D8h10hHBjyqX+cfBm0i8JUXJ0UhczFc4r74zbuT9XgewFo2E3J1cOaGtdZynILNmQ685YWGzGE1Zv6io50w==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@1.1.3': + resolution: {integrity: sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==} + engines: {node: '>= 6'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nolyfill/is-core-module@1.0.39': + resolution: {integrity: sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==} + engines: {node: '>=12.4.0'} + + '@npmcli/fs@1.1.1': + resolution: {integrity: sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==} + + '@npmcli/fs@2.1.2': + resolution: {integrity: sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + '@npmcli/fs@3.1.1': + resolution: {integrity: sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/git@4.1.0': + resolution: {integrity: sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/installed-package-contents@2.1.0': + resolution: {integrity: sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + + '@npmcli/move-file@1.1.2': + resolution: {integrity: sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==} + engines: {node: '>=10'} + deprecated: This functionality has been moved to @npmcli/fs + + '@npmcli/move-file@2.0.1': + resolution: {integrity: sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This functionality has been moved to @npmcli/fs + + '@npmcli/node-gyp@3.0.0': + resolution: {integrity: sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/promise-spawn@6.0.2': + resolution: {integrity: sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@npmcli/run-script@6.0.2': + resolution: {integrity: sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@nrwl/devkit@16.10.0': + resolution: {integrity: sha512-fRloARtsDQoQgQ7HKEy0RJiusg/HSygnmg4gX/0n/Z+SUS+4KoZzvHjXc6T5ZdEiSjvLypJ+HBM8dQzIcVACPQ==} + + '@nrwl/tao@16.10.0': + resolution: {integrity: sha512-QNAanpINbr+Pod6e1xNgFbzK1x5wmZl+jMocgiEFXZ67KHvmbD6MAQQr0MMz+GPhIu7EE4QCTLTyCEMlAG+K5Q==} + hasBin: true + + '@nx/devkit@16.10.0': + resolution: {integrity: sha512-IvKQqRJFDDiaj33SPfGd3ckNHhHi6ceEoqCbAP4UuMXOPPVOX6H0KVk+9tknkPb48B7jWIw6/AgOeWkBxPRO5w==} + peerDependencies: + nx: '>= 15 <= 17' + + '@nx/nx-darwin-arm64@16.10.0': + resolution: {integrity: sha512-YF+MIpeuwFkyvM5OwgY/rTNRpgVAI/YiR0yTYCZR+X3AAvP775IVlusNgQ3oedTBRUzyRnI4Tknj1WniENFsvQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@nx/nx-darwin-x64@16.10.0': + resolution: {integrity: sha512-ypi6YxwXgb0kg2ixKXE3pwf5myVNUgWf1CsV5OzVccCM8NzheMO51KDXTDmEpXdzUsfT0AkO1sk5GZeCjhVONg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@nx/nx-freebsd-x64@16.10.0': + resolution: {integrity: sha512-UeEYFDmdbbDkTQamqvtU8ibgu5jQLgFF1ruNb/U4Ywvwutw2d4ruOMl2e0u9hiNja9NFFAnDbvzrDcMo7jYqYw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [freebsd] + + '@nx/nx-linux-arm-gnueabihf@16.10.0': + resolution: {integrity: sha512-WV3XUC2DB6/+bz1sx+d1Ai9q2Cdr+kTZRN50SOkfmZUQyEBaF6DRYpx/a4ahhxH3ktpNfyY8Maa9OEYxGCBkQA==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@nx/nx-linux-arm64-gnu@16.10.0': + resolution: {integrity: sha512-aWIkOUw995V3ItfpAi5FuxQ+1e9EWLS1cjWM1jmeuo+5WtaKToJn5itgQOkvSlPz+HSLgM3VfXMvOFALNk125g==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@nx/nx-linux-arm64-musl@16.10.0': + resolution: {integrity: sha512-uO6Gg+irqpVcCKMcEPIQcTFZ+tDI02AZkqkP7koQAjniLEappd8DnUBSQdcn53T086pHpdc264X/ZEpXFfrKWQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@nx/nx-linux-x64-gnu@16.10.0': + resolution: {integrity: sha512-134PW/u/arNFAQKpqMJniC7irbChMPz+W+qtyKPAUXE0XFKPa7c1GtlI/wK2dvP9qJDZ6bKf0KtA0U/m2HMUOA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@nx/nx-linux-x64-musl@16.10.0': + resolution: {integrity: sha512-q8sINYLdIJxK/iUx9vRk5jWAWb/2O0PAbOJFwv4qkxBv4rLoN7y+otgCZ5v0xfx/zztFgk/oNY4lg5xYjIso2Q==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@nx/nx-win32-arm64-msvc@16.10.0': + resolution: {integrity: sha512-moJkL9kcqxUdJSRpG7dET3UeLIciwrfP08mzBQ12ewo8K8FzxU8ZUsTIVVdNrwt01CXOdXoweGfdQLjJ4qTURA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@nx/nx-win32-x64-msvc@16.10.0': + resolution: {integrity: sha512-5iV2NKZnzxJwZZ4DM5JVbRG/nkhAbzEskKaLBB82PmYGKzaDHuMHP1lcPoD/rtYMlowZgNA/RQndfKvPBPwmXA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@nymproject/contract-clients@1.4.1': + resolution: {integrity: sha512-HuJZ4Hv+Rl6ZZEtCHKgurNLJapM+QQRJlGkevFH2a4UdqUqF9omUkUi3AVes4679dPoSFgvA7plyVSDBdbgV6w==} + + '@nymproject/mix-fetch@1.4.4': + resolution: {integrity: sha512-sdyXXJG7sYv2OFOEf6FYm7HglKfMvJmJjrQC3Rbusy5rH5C2ajg2KyuBbZReLgIIbkkx3mK8sc5WRUOKTcKt2Q==} + + '@nymproject/nym-validator-client@0.18.0': + resolution: {integrity: sha512-FO1T15S2BJVuMoPA2yOaH40aD3hKJPKJVyX5ix7eJEbBWIdsYNoVeVc/soHhaAU1FIy2uU0G/FZQkaUYJGGb7Q==} + + '@octokit/auth-token@3.0.4': + resolution: {integrity: sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==} + engines: {node: '>= 14'} + + '@octokit/core@4.2.4': + resolution: {integrity: sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ==} + engines: {node: '>= 14'} + + '@octokit/endpoint@7.0.6': + resolution: {integrity: sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg==} + engines: {node: '>= 14'} + + '@octokit/graphql@5.0.6': + resolution: {integrity: sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw==} + engines: {node: '>= 14'} + + '@octokit/openapi-types@18.1.1': + resolution: {integrity: sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw==} + + '@octokit/plugin-enterprise-rest@6.0.1': + resolution: {integrity: sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw==} + + '@octokit/plugin-paginate-rest@6.1.2': + resolution: {integrity: sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ==} + engines: {node: '>= 14'} + peerDependencies: + '@octokit/core': '>=4' + + '@octokit/plugin-request-log@1.0.4': + resolution: {integrity: sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==} + peerDependencies: + '@octokit/core': '>=3' + + '@octokit/plugin-rest-endpoint-methods@7.2.3': + resolution: {integrity: sha512-I5Gml6kTAkzVlN7KCtjOM+Ruwe/rQppp0QU372K1GP7kNOYEKe8Xn5BW4sE62JAHdwpq95OQK/qGNyKQMUzVgA==} + engines: {node: '>= 14'} + peerDependencies: + '@octokit/core': '>=3' + + '@octokit/request-error@3.0.3': + resolution: {integrity: sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ==} + engines: {node: '>= 14'} + + '@octokit/request@6.2.8': + resolution: {integrity: sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw==} + engines: {node: '>= 14'} + + '@octokit/rest@19.0.11': + resolution: {integrity: sha512-m2a9VhaP5/tUw8FwfnW2ICXlXpLPIqxtg3XcAiGMLj/Xhw3RSBfZ8le/466ktO1Gcjr8oXudGnHhxV1TXJgFxw==} + engines: {node: '>= 14'} + + '@octokit/tsconfig@1.0.2': + resolution: {integrity: sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA==} + + '@octokit/types@10.0.0': + resolution: {integrity: sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg==} + + '@octokit/types@9.3.2': + resolution: {integrity: sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==} + + '@parcel/watcher@2.0.4': + resolution: {integrity: sha512-cTDi+FUDBIUOBKEtj+nhiJ71AZVlkAsQFuGQTun5tV9mwQBQgZvhCzG+URPQc8myeN32yRVZEfVAPCs1RW+Jvg==} + engines: {node: '>= 10.0.0'} + + '@pkgjs/parseargs@0.11.0': + resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} + engines: {node: '>=14'} + + '@pmmmwh/react-refresh-webpack-plugin@0.5.17': + resolution: {integrity: sha512-tXDyE1/jzFsHXjhRZQ3hMl0IVhYe5qula43LDWIhVfjp9G/nT5OQY5AORVOrkEGAUltBJOfOWeETbmhm6kHhuQ==} + engines: {node: '>= 10.13'} + peerDependencies: + '@types/webpack': 4.x || 5.x + react-refresh: '>=0.10.0 <1.0.0' + sockjs-client: ^1.4.0 + type-fest: '>=0.17.0 <5.0.0' + webpack: '>=4.43.0 <6.0.0' + webpack-dev-server: 3.x || 4.x || 5.x + webpack-hot-middleware: 2.x + webpack-plugin-serve: 0.x || 1.x + peerDependenciesMeta: + '@types/webpack': + optional: true + sockjs-client: + optional: true + type-fest: + optional: true + webpack-dev-server: + optional: true + webpack-hot-middleware: + optional: true + webpack-plugin-serve: + optional: true + + '@popperjs/core@2.11.8': + resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.5': + resolution: {integrity: sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==} + + '@protobufjs/eventemitter@1.1.0': + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + + '@protobufjs/fetch@1.1.0': + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/inquire@1.1.1': + resolution: {integrity: sha512-mnzgDV26ueAvk7rsbt9L7bE0SuAoqyuys/sMMrmVcN5x9VsxpcG3rqAUSgDyLp0UZlmNfIbQ4fHfCtreVBk8Ew==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.1': + resolution: {integrity: sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==} + + '@react-aria/listbox@3.16.0': + resolution: {integrity: sha512-Jv6aTJECRntBvG+0ZQtXniAtHEQjvEi2QSm35FxRcsB8kgv7TmcinUOSZuHe5r8RDY2djILwdrqmfy6ApX0MDA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/overlays@3.32.0': + resolution: {integrity: sha512-H9meBB14/M0bDwk8gZl8Fu8bwZN2El9LDlk5cNkgAozbEiRuQvTFOeE3RoP6XI6bwEnSBvb0ovPmx3/kNyOehQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-aria/utils@3.34.0': + resolution: {integrity: sha512-ZM1ZXIqpwGTJjjL6o3JhlZkEaBpQdxuOCqLEvwEwooaj5GsYI3E9UfOl5vy3UW6bYiEEWl9pNBntrb9CR9kItQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@react-icons/all-files@4.1.0': + resolution: {integrity: sha512-hxBI2UOuVaI3O/BhQfhtb4kcGn9ft12RWAFVMUeNjqqhLsHvFtzIkFaptBJpFDANTKoDfdVoHTKZDlwKCACbMQ==} + peerDependencies: + react: '*' + + '@react-spring/animated@9.7.5': + resolution: {integrity: sha512-Tqrwz7pIlsSDITzxoLS3n/v/YCUHQdOIKtOJf4yL6kYVSDTSmVK1LI1Q3M/uu2Sx4X3pIWF3xLUhlsA6SPNTNg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@react-spring/core@9.7.5': + resolution: {integrity: sha512-rmEqcxRcu7dWh7MnCcMXLvrf6/SDlSokLaLTxiPlAYi11nN3B5oiCUAblO72o+9z/87j2uzxa2Inm8UbLjXA+w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@react-spring/rafz@9.7.5': + resolution: {integrity: sha512-5ZenDQMC48wjUzPAm1EtwQ5Ot3bLIAwwqP2w2owG5KoNdNHpEJV263nGhCeKKmuA3vG2zLLOdu3or6kuDjA6Aw==} + + '@react-spring/shared@9.7.5': + resolution: {integrity: sha512-wdtoJrhUeeyD/PP/zo+np2s1Z820Ohr/BbuVYv+3dVLW7WctoiN7std8rISoYoHpUXtbkpesSKuPIw/6U1w1Pw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@react-spring/types@9.7.5': + resolution: {integrity: sha512-HVj7LrZ4ReHWBimBvu2SKND3cDVUPWKLqRTmWe/fNY6o1owGOX0cAHbdPDTMelgBlVbrTKrre6lFkhqGZErK/g==} + + '@react-spring/web@9.7.5': + resolution: {integrity: sha512-lmvqGwpe+CSttsWNZVr+Dg62adtKhauGwLyGE/RRyZ8AAMLgb9x3NDMA5RMElXo+IMyTkPp7nxTB8ZQlmhb6JQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@react-types/shared@3.34.0': + resolution: {integrity: sha512-gp6xo/s2lX54AlTjOiqwDnxA7UW79BNvI9dB9pr3LZTzRKCd1ZA+ZbgKw/ReIiWuvvVw/8QFJpnqeeFyLocMcQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + '@remix-run/router@1.23.2': + resolution: {integrity: sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==} + engines: {node: '>=14.0.0'} + + '@rtsao/scc@1.1.0': + resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} + + '@rushstack/eslint-patch@1.16.1': + resolution: {integrity: sha512-TvZbIpeKqGQQ7X0zSCvPH9riMSFQFSggnfBjFZ1mEoILW+UuXCKwOoPcgjMwiUtRqFZ8jWhPJc4um14vC6I4ag==} + + '@scure/base@1.2.6': + resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} + + '@scure/starknet@1.1.0': + resolution: {integrity: sha512-83g3M6Ix2qRsPN4wqLDqiRZ2GBNbjVWfboJE/9UjfG+MHr6oDSu/CWgy8hsBSJejr09DkkL+l0Ze4KVrlCIdtQ==} + + '@sideway/address@4.1.5': + resolution: {integrity: sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==} + + '@sideway/formula@3.0.1': + resolution: {integrity: sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==} + + '@sideway/pinpoint@2.0.0': + resolution: {integrity: sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==} + + '@sigstore/bundle@1.1.0': + resolution: {integrity: sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@sigstore/protobuf-specs@0.2.1': + resolution: {integrity: sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@sigstore/sign@1.0.0': + resolution: {integrity: sha512-INxFVNQteLtcfGmcoldzV6Je0sbbfh9I16DM4yJPw3j5+TFP8X6uIiA18mvpEa9yyeycAKgPmOA3X9hVdVTPUA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@sigstore/tuf@1.0.3': + resolution: {integrity: sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@sinclair/typebox@0.27.10': + resolution: {integrity: sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==} + + '@sinonjs/commons@1.8.6': + resolution: {integrity: sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==} + + '@sinonjs/commons@3.0.1': + resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + + '@sinonjs/fake-timers@10.3.0': + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + + '@sinonjs/fake-timers@8.1.0': + resolution: {integrity: sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==} + + '@starknet-io/types-js@0.8.4': + resolution: {integrity: sha512-0RZ3TZHcLsUTQaq1JhDSCM8chnzO4/XNsSCozwDET64JK5bjFDIf2ZUkta+tl5Nlbf4usoU7uZiDI/Q57kt2SQ==} + + '@starknet-io/types-js@0.9.2': + resolution: {integrity: sha512-vWOc0FVSn+RmabozIEWcEny1I73nDGTvOrLYJsR1x7LGA3AZmqt4i/aW69o/3i2NN5CVP8Ok6G1ayRQJKye3Wg==} + + '@storybook/addon-actions@6.5.16': + resolution: {integrity: sha512-aADjilFmuD6TNGz2CRPSupnyiA/IGkPJHDBTqMpsDXTUr8xnuD122xkIhg6UxmCM2y1c+ncwYXy3WPK2xXK57g==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + + '@storybook/addon-backgrounds@6.5.16': + resolution: {integrity: sha512-t7qooZ892BruhilFmzYPbysFwpULt/q4zYXNSmKVbAYta8UVvitjcU4F18p8FpWd9WvhiTr0SDlyhNZuzvDfug==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + + '@storybook/addon-controls@6.5.16': + resolution: {integrity: sha512-kShSGjq1MjmmyL3l8i+uPz6yddtf82mzys0l82VKtcuyjrr5944wYFJ5NTXMfZxrO/U6FeFsfuFZE/k6ex3EMg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + + '@storybook/addon-docs@6.5.16': + resolution: {integrity: sha512-QM9WDZG9P02UvbzLu947a8ZngOrQeAKAT8jCibQFM/+RJ39xBlfm8rm+cQy3dm94wgtjmVkA3mKGOV/yrrsddg==} + peerDependencies: + '@storybook/mdx2-csf': ^0.0.3 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@storybook/mdx2-csf': + optional: true + react: + optional: true + react-dom: + optional: true + + '@storybook/addon-essentials@6.5.16': + resolution: {integrity: sha512-TeoMr6tEit4Pe91GH6f8g/oar1P4M0JL9S6oMcFxxrhhtOGO7XkWD5EnfyCx272Ok2VYfE58FNBTGPNBVIqYKQ==} + peerDependencies: + '@babel/core': ^7.9.6 + '@storybook/angular': '*' + '@storybook/builder-manager4': '*' + '@storybook/builder-manager5': '*' + '@storybook/builder-webpack4': '*' + '@storybook/builder-webpack5': '*' + '@storybook/html': '*' + '@storybook/vue': '*' + '@storybook/vue3': '*' + '@storybook/web-components': '*' + lit: '*' + lit-html: '*' + react: '*' + react-dom: '*' + svelte: '*' + sveltedoc-parser: '*' + vue: '*' + webpack: '*' + peerDependenciesMeta: + '@storybook/angular': + optional: true + '@storybook/builder-manager4': + optional: true + '@storybook/builder-manager5': + optional: true + '@storybook/builder-webpack4': + optional: true + '@storybook/builder-webpack5': + optional: true + '@storybook/html': + optional: true + '@storybook/vue': + optional: true + '@storybook/vue3': + optional: true + '@storybook/web-components': + optional: true + lit: + optional: true + lit-html: + optional: true + react: + optional: true + react-dom: + optional: true + svelte: + optional: true + sveltedoc-parser: + optional: true + vue: + optional: true + webpack: + optional: true + + '@storybook/addon-interactions@6.5.16': + resolution: {integrity: sha512-DdTtyp3DgB/SpbM1GQgMnuSEBCkadxmj1mUcPk+Wp2iY+fDwsuoRDkr1H9Oe7IvlBKe7ciR79LEjoaABXNdw4w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + + '@storybook/addon-links@6.5.16': + resolution: {integrity: sha512-P/mmqK57NGXnR0i3d/T5B0rIt0Lg8Yq+qionRr3LK3AwG/4yGnYt4GNomLEknn/eEwABYq1Q/Z1aOpgIhNdq5A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + + '@storybook/addon-measure@6.5.16': + resolution: {integrity: sha512-DMwnXkmM2L6POTh4KaOWvOAtQ2p9Tr1UUNxz6VXiN5cKFohpCs6x0txdLU5WN8eWIq0VFsO7u5ZX34CGCc6gCg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + + '@storybook/addon-outline@6.5.16': + resolution: {integrity: sha512-0du96nha4qltexO0Xq1xB7LeRSbqjC9XqtZLflXG7/X3ABoPD2cXgOV97eeaXUodIyb2qYBbHUfftBeA75x0+w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + + '@storybook/addon-toolbars@6.5.16': + resolution: {integrity: sha512-y3PuUKiwOWrAvqx1YdUvArg0UaAwmboXFeR2bkrowk1xcT+xnRO3rML4npFeUl26OQ1FzwxX/cw6nknREBBLEA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + + '@storybook/addon-viewport@6.5.16': + resolution: {integrity: sha512-1Vyqf1U6Qng6TXlf4SdqUKyizlw1Wn6+qW8YeA2q1lbkJqn3UlnHXIp8Q0t/5q1dK5BFtREox3+jkGwbJrzkmA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + react: + optional: true + react-dom: + optional: true + + '@storybook/addons@6.5.16': + resolution: {integrity: sha512-p3DqQi+8QRL5k7jXhXmJZLsE/GqHqyY6PcoA1oNTJr0try48uhTGUOYkgzmqtDaa/qPFO5LP+xCPzZXckGtquQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@storybook/api@6.5.16': + resolution: {integrity: sha512-HOsuT8iomqeTMQJrRx5U8nsC7lJTwRr1DhdD0SzlqL4c80S/7uuCy4IZvOt4sYQjOzW5fOo/kamcoBXyLproTA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@storybook/builder-webpack4@6.5.16': + resolution: {integrity: sha512-YqDIrVNsUo8r9xc6AxsYDLxVYtMgl5Bxk+8/h1adsOko+jAFhdg6hOcAVxEmoSI0TMASOOVMFlT2hr23ppN2rQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@storybook/builder-webpack5@6.5.16': + resolution: {integrity: sha512-kh8Sofm1sbijaHDWtm0sXabqACHVFjikU/fIkkW786kpjoPIPIec1a+hrLgDsZxMU3I7XapSOaCFzWt6FjVXjg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@storybook/channel-postmessage@6.5.16': + resolution: {integrity: sha512-fZZSN29dsUArWOx7e7lTdMA9+7zijVwCwbvi2Fo4fqhRLh1DsTb/VXfz1FKMCWAjNlcX7QQvV25tnxbqsD6lyw==} + + '@storybook/channel-websocket@6.5.16': + resolution: {integrity: sha512-wJg2lpBjmRC2GJFzmhB9kxlh109VE58r/0WhFtLbwKvPqsvGf82xkBEl6BtBCvIQ4stzYnj/XijjA8qSi2zpOg==} + + '@storybook/channels@6.5.16': + resolution: {integrity: sha512-VylzaWQZaMozEwZPJdyJoz+0jpDa8GRyaqu9TGG6QGv+KU5POoZaGLDkRE7TzWkyyP0KQLo80K99MssZCpgSeg==} + + '@storybook/client-api@6.5.16': + resolution: {integrity: sha512-i3UwkzzUFw8I+E6fOcgB5sc4oU2fhvaKnqC1mpd9IYGJ9JN9MnGIaVl3Ko28DtFItu/QabC9JsLIJVripFLktQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@storybook/client-logger@6.5.16': + resolution: {integrity: sha512-pxcNaCj3ItDdicPTXTtmYJE3YC1SjxFrBmHcyrN+nffeNyiMuViJdOOZzzzucTUG0wcOOX8jaSyak+nnHg5H1Q==} + + '@storybook/client-logger@8.6.14': + resolution: {integrity: sha512-DqB54TiXr58nCS2QO2YxxY14uc0yGEhgTgtw1eIGFEC1RKxgbOos+4lDtwhU7EYI6kHewVlZ4NXi85wnj/Qq+A==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + + '@storybook/components@6.5.16': + resolution: {integrity: sha512-LzBOFJKITLtDcbW9jXl0/PaG+4xAz25PK8JxPZpIALbmOpYWOAPcO6V9C2heX6e6NgWFMUxjplkULEk9RCQMNA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@storybook/core-client@6.5.16': + resolution: {integrity: sha512-14IRaDrVtKrQ+gNWC0wPwkCNfkZOKghYV/swCUnQX3rP99defsZK8Hc7xHIYoAiOP5+sc3sweRAxgmFiJeQ1Ig==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + typescript: '*' + webpack: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@storybook/core-common@6.5.16': + resolution: {integrity: sha512-2qtnKP3TTOzt2cp6LXKRTh7XrI9z5VanMnMTgeoFcA5ebnndD4V6BExQUdYPClE/QooLx6blUWNgS9dFEpjSqQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@storybook/core-events@6.5.16': + resolution: {integrity: sha512-qMZQwmvzpH5F2uwNUllTPg6eZXr2OaYZQRRN8VZJiuorZzDNdAFmiVWMWdkThwmyLEJuQKXxqCL8lMj/7PPM+g==} + + '@storybook/core-server@6.5.16': + resolution: {integrity: sha512-/3NPfmNyply395Dm0zaVZ8P9aruwO+tPx4D6/jpw8aqrRSwvAMndPMpoMCm0NXcpSm5rdX+Je4S3JW6JcggFkA==} + peerDependencies: + '@storybook/builder-webpack5': '*' + '@storybook/manager-webpack5': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + typescript: '*' + peerDependenciesMeta: + '@storybook/builder-webpack5': + optional: true + '@storybook/manager-webpack5': + optional: true + typescript: + optional: true + + '@storybook/core@6.5.16': + resolution: {integrity: sha512-CEF3QFTsm/VMnMKtRNr4rRdLeIkIG0g1t26WcmxTdSThNPBd8CsWzQJ7Jqu7CKiut+MU4A1LMOwbwCE5F2gmyA==} + peerDependencies: + '@storybook/builder-webpack5': '*' + '@storybook/manager-webpack5': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + typescript: '*' + webpack: '*' + peerDependenciesMeta: + '@storybook/builder-webpack5': + optional: true + '@storybook/manager-webpack5': + optional: true + typescript: + optional: true + + '@storybook/core@8.6.18': + resolution: {integrity: sha512-dRBP2TnX6fGdS0T2mXBHjkS/3Nlu1ra1huovZVFuM67CYMzrhM/3hX/zru1vWSC5rqY93ZaAhjMciPW4pK5mMQ==} + peerDependencies: + prettier: ^2 || ^3 + peerDependenciesMeta: + prettier: + optional: true + + '@storybook/csf-tools@6.5.16': + resolution: {integrity: sha512-+WD4sH/OwAfXZX3IN6/LOZ9D9iGEFcN+Vvgv9wOsLRgsAZ10DG/NK6c1unXKDM/ogJtJYccNI8Hd+qNE/GFV6A==} + peerDependencies: + '@storybook/mdx2-csf': ^0.0.3 + peerDependenciesMeta: + '@storybook/mdx2-csf': + optional: true + + '@storybook/csf@0.0.1': + resolution: {integrity: sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw==} + + '@storybook/csf@0.0.2--canary.4566f4d.1': + resolution: {integrity: sha512-9OVvMVh3t9znYZwb0Svf/YQoxX2gVOeQTGe2bses2yj+a3+OJnCrUF3/hGv6Em7KujtOdL2LL+JnG49oMVGFgQ==} + + '@storybook/docs-tools@6.5.16': + resolution: {integrity: sha512-o+rAWPRGifjBF5xZzTKOqnHN3XQWkl0QFJYVDIiJYJrVll7ExCkpEq/PahOGzIBBV+tpMstJgmKM3lr/lu/jmg==} + + '@storybook/global@5.0.0': + resolution: {integrity: sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ==} + + '@storybook/instrumenter@6.5.16': + resolution: {integrity: sha512-q8/GaBk8PA/cL7m5OW+ec5t63+Zja9YvYSPGXrYtW17koSv7OnNPmk6RvI7tIHHO0mODBYnaHjF4zQfEGoyR5Q==} + + '@storybook/instrumenter@8.6.14': + resolution: {integrity: sha512-iG4MlWCcz1L7Yu8AwgsnfVAmMbvyRSk700Mfy2g4c8y5O+Cv1ejshE1LBBsCwHgkuqU0H4R0qu4g23+6UnUemQ==} + peerDependencies: + storybook: ^8.6.14 + + '@storybook/manager-webpack4@6.5.16': + resolution: {integrity: sha512-5VJZwmQU6AgdsBPsYdu886UKBHQ9SJEnFMaeUxKEclXk+iRsmbzlL4GHKyVd6oGX/ZaecZtcHPR6xrzmA4Ziew==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@storybook/manager-webpack5@6.5.16': + resolution: {integrity: sha512-OtxXv8JCe0r/0rE5HxaFicsNsXA+fqZxzokxquFFgrYf/1Jg4d7QX6/pG5wINF+5qInJfVkRG6xhPzv1s5bk9Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@storybook/mdx1-csf@0.0.1': + resolution: {integrity: sha512-4biZIWWzoWlCarMZmTpqcJNgo/RBesYZwGFbQeXiGYsswuvfWARZnW9RE9aUEMZ4XPn7B1N3EKkWcdcWe/K2tg==} + + '@storybook/node-logger@6.5.16': + resolution: {integrity: sha512-YjhBKrclQtjhqFNSO+BZK+RXOx6EQypAELJKoLFaawg331e8VUfvUuRCNB3fcEWp8G9oH13PQQte0OTjLyyOYg==} + + '@storybook/postinstall@6.5.16': + resolution: {integrity: sha512-08K2q+qN6pqyPW7PHLCZ5G5Xa6Wosd6t0F16PQ4abX2ItlJLabVoJN5mZ0gm/aeLTjD8QYr8IDvacu4eXh0SVA==} + + '@storybook/preview-web@6.5.16': + resolution: {integrity: sha512-IJnvfe2sKCfk7apN9Fu9U8qibbarrPX5JB55ZzK1amSHVmSDuYk5MIMc/U3NnSQNnvd1DO5v/zMcGgj563hrtg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@storybook/react-docgen-typescript-plugin@1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0': + resolution: {integrity: sha512-eVg3BxlOm2P+chijHBTByr90IZVUtgRW56qEOLX7xlww2NBuKrcavBlcmn+HH7GIUktquWkMPtvy6e0W0NgA5w==} + peerDependencies: + typescript: '>= 3.x' + webpack: '>= 4' + + '@storybook/react@6.5.16': + resolution: {integrity: sha512-cBtNlOzf/MySpNLBK22lJ8wFU22HnfTB2xJyBk7W7Zi71Lm7Uxkhv1Pz8HdiQndJ0SlsAAQOWjQYsSZsGkZIaA==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + '@babel/core': ^7.11.5 + '@storybook/builder-webpack4': '*' + '@storybook/builder-webpack5': '*' + '@storybook/manager-webpack4': '*' + '@storybook/manager-webpack5': '*' + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + require-from-string: ^2.0.2 + typescript: '*' + peerDependenciesMeta: + '@babel/core': + optional: true + '@storybook/builder-webpack4': + optional: true + '@storybook/builder-webpack5': + optional: true + '@storybook/manager-webpack4': + optional: true + '@storybook/manager-webpack5': + optional: true + typescript: + optional: true + + '@storybook/router@6.5.16': + resolution: {integrity: sha512-ZgeP8a5YV/iuKbv31V8DjPxlV4AzorRiR8OuSt/KqaiYXNXlOoQDz/qMmiNcrshrfLpmkzoq7fSo4T8lWo2UwQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@storybook/semver@7.3.2': + resolution: {integrity: sha512-SWeszlsiPsMI0Ps0jVNtH64cI5c0UF3f7KgjVKJoNP30crQ6wUSddY2hsdeczZXEKVJGEn50Q60flcGsQGIcrg==} + engines: {node: '>=10'} + hasBin: true + + '@storybook/source-loader@6.5.16': + resolution: {integrity: sha512-fyVl4jrM/5JLrb48aqXPu7sTsmySQaVGFp1zfeqvPPlJRFMastDrePm5XGPN7Qjv1wsKmpuBvuweFKOT1pru3g==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@storybook/store@6.5.16': + resolution: {integrity: sha512-g+bVL5hmMq/9cM51K04e37OviUPHT0rHHrRm5wj/hrf18Kd9120b3sxdQ5Dc+HZ292yuME0n+cyrQPTYx9Epmw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@storybook/telemetry@6.5.16': + resolution: {integrity: sha512-CWr5Uko1l9jJW88yTXsZTj/3GTabPvw0o7pDPOXPp8JRZiJTxv1JFaFCafhK9UzYbgcRuGfCC8kEWPZims7iKA==} + + '@storybook/testing-library@0.0.9': + resolution: {integrity: sha512-X4/Tk7RryB0tZ/9NLUHYTBXW01zRpf6+IhdhqsVl6WOWRyUaIv3zEhr43gQyZhBe4ZZyt5d90FJC9qWmY1oFKg==} + + '@storybook/theming@6.5.16': + resolution: {integrity: sha512-hNLctkjaYLRdk1+xYTkC1mg4dYz2wSv6SqbLpcKMbkPHTE0ElhddGPHQqB362md/w9emYXNkt1LSMD8Xk9JzVQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@storybook/theming@8.6.18': + resolution: {integrity: sha512-n6OEjEtHupa2PdTwWzRepr7cO8NkDd4rgF6BKLitRbujOspLxzMBEqdphs+QLcuiCIgf33SqmEA64QWnbSMhPw==} + peerDependencies: + storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0 + + '@storybook/ui@6.5.16': + resolution: {integrity: sha512-rHn/n12WM8BaXtZ3IApNZCiS+C4Oc5+Lkl4MoctX8V7QSml0SxZBB5hsJ/AiWkgbRxjQpa/L/Nt7/Qw0FjTH/A==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + + '@svgr/babel-plugin-add-jsx-attribute@6.5.1': + resolution: {integrity: sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ==} + engines: {node: '>=10'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0': + resolution: {integrity: sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0': + resolution: {integrity: sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA==} + engines: {node: '>=14'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-replace-jsx-attribute-value@6.5.1': + resolution: {integrity: sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg==} + engines: {node: '>=10'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-svg-dynamic-title@6.5.1': + resolution: {integrity: sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw==} + engines: {node: '>=10'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-svg-em-dimensions@6.5.1': + resolution: {integrity: sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA==} + engines: {node: '>=10'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-transform-react-native-svg@6.5.1': + resolution: {integrity: sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg==} + engines: {node: '>=10'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-plugin-transform-svg-component@6.5.1': + resolution: {integrity: sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ==} + engines: {node: '>=12'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/babel-preset@6.5.1': + resolution: {integrity: sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw==} + engines: {node: '>=10'} + peerDependencies: + '@babel/core': ^7.0.0-0 + + '@svgr/core@6.5.1': + resolution: {integrity: sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw==} + engines: {node: '>=10'} + + '@svgr/hast-util-to-babel-ast@6.5.1': + resolution: {integrity: sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw==} + engines: {node: '>=10'} + + '@svgr/plugin-jsx@6.5.1': + resolution: {integrity: sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw==} + engines: {node: '>=10'} + peerDependencies: + '@svgr/core': ^6.0.0 + + '@svgr/plugin-svgo@6.5.1': + resolution: {integrity: sha512-omvZKf8ixP9z6GWgwbtmP9qQMPX4ODXi+wzbVZgomNFsUIlHA1sf4fThdwTWSsZGgvGAG6yE+b/F5gWUkcZ/iQ==} + engines: {node: '>=10'} + peerDependencies: + '@svgr/core': '*' + + '@svgr/webpack@6.5.1': + resolution: {integrity: sha512-cQ/AsnBkXPkEK8cLbv4Dm7JGXq2XrumKnL1dRpJD9rIO2fTIlJI9a1uCciYG1F2aUsox/hJQyNGbt3soDxSRkA==} + engines: {node: '>=10'} + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/helpers@0.5.21': + resolution: {integrity: sha512-jI/VAmtdjB/RnI8GTnokyX7Ug8c+g+ffD6QRLa6XQewtnGyukKkKSk3wLTM3b5cjt1jNh9x0jfVlagdN2gDKQg==} + + '@swc/helpers@0.5.5': + resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==} + + '@tanstack/match-sorter-utils@8.19.4': + resolution: {integrity: sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg==} + engines: {node: '>=12'} + + '@tanstack/query-core@5.100.10': + resolution: {integrity: sha512-8UR0yJR+GiQ40m3lPhUr0xbfAupe6GSQiksSBSa9SM2NjezFyxXCIA69/lz8cSoNKZLrw1/PktIyQBJcVeMi3w==} + + '@tanstack/query-devtools@5.100.10': + resolution: {integrity: sha512-3DmJf25hDPus5IpVvp6ujXv6bKV2zPzI9vpbAmpJigsL/H6DPvPjmf7/Q9yVKEke//8fgeQ45abjgnLuyYxAiw==} + + '@tanstack/react-query-devtools@5.100.10': + resolution: {integrity: sha512-zes0+o9ef5rAZXJ9f/SeaLs2nufJaeVkZkl/Or9NGrWVF41kL9Od9ED9nCwtQlgiF2VGtrzhEw5AU/igAO+aAg==} + peerDependencies: + '@tanstack/react-query': ^5.100.10 + react: ^18 || ^19 + + '@tanstack/react-query-next-experimental@5.100.10': + resolution: {integrity: sha512-/f2DlErD06XbR7k4Q62oFHVcx2z5hOVRewRQV85irU7C0SK4CHuo6n8wLhTTn1npzwS4BVMuocXNNp9MiK62jg==} + peerDependencies: + '@tanstack/react-query': ^5.100.10 + next: ^13 || ^14 || ^15 || ^16 + react: ^18 || ^19 + + '@tanstack/react-query@5.100.10': + resolution: {integrity: sha512-FLaZf2RCrA/Zgp4aiu5tG3TyasTRO7aZ99skxQpr3Hg/zXOhu6yq5FZCYQ/tRaJtM9ylnoK8tFK7PolXQadv6Q==} + peerDependencies: + react: ^18 || ^19 + + '@tanstack/react-table@8.20.6': + resolution: {integrity: sha512-w0jluT718MrOKthRcr2xsjqzx+oEM7B7s/XXyfs19ll++hlId3fjTm+B2zrR3ijpANpkzBAr15j1XGVOMxpggQ==} + engines: {node: '>=12'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + + '@tanstack/react-table@8.21.3': + resolution: {integrity: sha512-5nNMTSETP4ykGegmVkhjcS8tTLW6Vl4axfEGQN3v0zdHYbK4UfoqfPChclTrJ4EoK9QynqAu9oUf8VEmrpZ5Ww==} + engines: {node: '>=12'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + + '@tanstack/react-virtual@3.11.2': + resolution: {integrity: sha512-OuFzMXPF4+xZgx8UzJha0AieuMihhhaWG0tCqpp6tDzlFwOmNBPYMuLOtMJ1Tr4pXLHmgjcWhG6RlknY2oNTdQ==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@tanstack/react-virtual@3.13.24': + resolution: {integrity: sha512-aIJvz5OSkhNIhZIpYivrxrPTKYsjW9Uzy+sP/mx0S3sev2HyvPb7xmjbYvokzEpfgYHy/HjzJ2zFAETuUfgCpg==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + '@tanstack/table-core@8.20.5': + resolution: {integrity: sha512-P9dF7XbibHph2PFRz8gfBKEXEY/HJPOhym8CHmjF8y3q5mWpKx9xtZapXQUWCgkqvsK0R46Azuz+VaxD4Xl+Tg==} + engines: {node: '>=12'} + + '@tanstack/table-core@8.21.3': + resolution: {integrity: sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg==} + engines: {node: '>=12'} + + '@tanstack/virtual-core@3.11.2': + resolution: {integrity: sha512-vTtpNt7mKCiZ1pwU9hfKPhpdVO2sVzFQsxoVBGtOSHxlrRRzYr8iQ2TlwbAcRYCcEiZ9ECAM8kBzH0v2+VzfKw==} + + '@tanstack/virtual-core@3.14.0': + resolution: {integrity: sha512-JLANqGy/D6k4Ujmh8Tr25lGimuOXNiaVyXaCAZS0W+1390sADdGnyUdSWNIfd49gebtIxGMij4IktRVzrdr12Q==} + + '@tauri-apps/api@2.10.1': + resolution: {integrity: sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw==} + + '@tauri-apps/api@2.11.0': + resolution: {integrity: sha512-7CinYODhky9lmO23xHnUFv0Xt43fbtWMyxZcLcRBlFkcgXKuEirBvHpmtJ89YMhyeGcq20Wuc47Fa4XjyniywA==} + + '@tauri-apps/cli-darwin-arm64@2.11.1': + resolution: {integrity: sha512-6eEKMBXsQPCuM1EmvrjT2+aBuxWQuFdKdW8pzNuNQtpq45nEEpBlD5gr8pUeAyOU1DQKlkFaEc/MPBxb/Pfjtg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@tauri-apps/cli-darwin-x64@2.11.1': + resolution: {integrity: sha512-LQUO7exfRWjWALNhetph5guWpMeHphRpokOLk0OIbTTExaNwJNFu3I4vb+CCM/4G/QGoZe/5XikZOJdNEFP1ig==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@tauri-apps/cli-linux-arm-gnueabihf@2.11.1': + resolution: {integrity: sha512-5i/awiBCRRhOUG8yjn0fMHXIWD5Ez8eEk5LtvOxyQrKuJkRaZDvnbIjZbE183blAwkoA4xN3aO/prJiqscl02Q==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@tauri-apps/cli-linux-arm64-gnu@2.11.1': + resolution: {integrity: sha512-9LrwDw3S9Fygtw/Q6WDhOP+3svJRGAsejeE+GKrc0eO1ThMVhwi2LL6hw4dlKw93IfS7VY1G19sWGxJ/NcU4nA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@tauri-apps/cli-linux-arm64-musl@2.11.1': + resolution: {integrity: sha512-mNA5dbbqPqDUdTIwdUYYuhO2GvIe9UnB2r0VU2njxBOS3Opbx4gKNC5yP0Iu4rYmEmqdlwry9VzGZQ3wq9dyFg==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@tauri-apps/cli-linux-riscv64-gnu@2.11.1': + resolution: {integrity: sha512-fZj3Gwq+6fUs305T5WQiD5iSGJw+j/4w/HGmk4sHDAcy+rp9zU5eaxB7nOyz5/I/nkNAuKPqfp6uIbiUBXkBCw==} + engines: {node: '>= 10'} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@tauri-apps/cli-linux-x64-gnu@2.11.1': + resolution: {integrity: sha512-XFxGxOvHM7jjeD6ozCKdGfhzJ7lERYDGZl1/Kb4fsvchaJsfLJ981TlyTG8Qy/gFq+f5GitH3bfrX9JAkjPEyw==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@tauri-apps/cli-linux-x64-musl@2.11.1': + resolution: {integrity: sha512-d5C2/Zm+68v7R9wTuTCjRQEVrWjcdMkJBZ1+rXse+QdMMlTB9+u9PDNDLw9PQflWxYLaYZ7tjxxL9Nb9II6PbA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@tauri-apps/cli-win32-arm64-msvc@2.11.1': + resolution: {integrity: sha512-YdeVWFAR1pTXzUU6NLstPq4G6OLxuDrXCXEBdmBH+5EZIDXUx0D2kJlz3+YjpazkKvAzYpgziTsyRagls0OfRQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@tauri-apps/cli-win32-ia32-msvc@2.11.1': + resolution: {integrity: sha512-VBGkuH0eB9K9LLSMv361Gzr5Ou72sCS4+ztpmkWEQ+wd/amhcYOsf3X6qn1RJZDzIhiOYHJEOysZUC3baD01rA==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + + '@tauri-apps/cli-win32-x64-msvc@2.11.1': + resolution: {integrity: sha512-b3ORhIAKgp9ZYY+zBt7b7r0kLU2kjvyGF0+MS2SBym3emsweGPybEqocJcmtMuxyBhkOKHP4CiuEJEDuAlTx6A==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@tauri-apps/cli@2.11.1': + resolution: {integrity: sha512-rpEbaJ/HzNb6fwsquwoAbq29/Vt4gADhS423A8fdkwL4edJ0wZmoB8ar7O6JPDL834MUKOCm/rrJ7c9oAaEaYQ==} + engines: {node: '>= 10'} + hasBin: true + + '@tauri-apps/plugin-clipboard-manager@2.3.2': + resolution: {integrity: sha512-CUlb5Hqi2oZbcZf4VUyUH53XWPPdtpw43EUpCza5HWZJwxEoDowFzNUDt1tRUXA8Uq+XPn17Ysfptip33sG4eQ==} + + '@tauri-apps/plugin-opener@2.5.4': + resolution: {integrity: sha512-1HnPkb+AmgO29HBazm4uPLKB+r7zzcTBW1d0fyYp1uP+jwtpoiNDGKMMzz58SFp49nOIrxdE3aUJtT57lfO9CQ==} + + '@tauri-apps/plugin-process@2.3.1': + resolution: {integrity: sha512-nCa4fGVaDL/B9ai03VyPOjfAHRHSBz5v6F/ObsB73r/dA3MHHhZtldaDMIc0V/pnUw9ehzr2iEG+XkSEyC0JJA==} + + '@tauri-apps/plugin-updater@2.10.1': + resolution: {integrity: sha512-NFYMg+tWOZPJdzE/PpFj2qfqwAWwNS3kXrb1tm1gnBJ9mYzZ4WDRrwy8udzWoAnfGCHLuePNLY1WVCNHnh3eRA==} + + '@tauri-apps/tauri-forage@1.0.0-beta.2': + resolution: {integrity: sha512-aGObWlY8sgEfImt8+Cv4D+hqWhWB4KwPLVRQTv2uPtHSrXpXrvkJ8vTjy+QsT7tGPyVhcLPBchbyGu0JReErSQ==} + engines: {node: '>= 10.18.1', npm: '>= 6.13.4', yarn: '>= 1.21.1'} + + '@testing-library/dom@10.4.1': + resolution: {integrity: sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg==} + engines: {node: '>=18'} + + '@testing-library/dom@8.20.1': + resolution: {integrity: sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==} + engines: {node: '>=12'} + + '@testing-library/jest-dom@6.9.1': + resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} + engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + + '@testing-library/react@16.3.2': + resolution: {integrity: sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==} + engines: {node: '>=18'} + peerDependencies: + '@testing-library/dom': ^10.0.0 + '@types/react': ^18.0.0 || ^19.0.0 + '@types/react-dom': ^18.0.0 || ^19.0.0 + react: ^18.0.0 || ^19.0.0 + react-dom: ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + + '@testing-library/user-event@13.5.0': + resolution: {integrity: sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==} + engines: {node: '>=10', npm: '>=6'} + peerDependencies: + '@testing-library/dom': '>=7.21.4' + + '@tootallnate/once@1.1.2': + resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} + engines: {node: '>= 6'} + + '@tootallnate/once@2.0.1': + resolution: {integrity: sha512-HqmEUIGRJ5fSXchkVgR5F7qn48bDBzv0kWj/Kfu5e6uci4UlEeng4331LnBkWffb++Ei3FOVLxo8JJWMFBDMeQ==} + engines: {node: '>= 10'} + + '@tufjs/canonical-json@1.0.0': + resolution: {integrity: sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@tufjs/models@1.0.4': + resolution: {integrity: sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + '@tybys/wasm-util@0.10.2': + resolution: {integrity: sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==} + + '@types/aria-query@5.0.4': + resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} + + '@types/babel__core@7.20.5': + resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} + + '@types/babel__generator@7.27.0': + resolution: {integrity: sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==} + + '@types/babel__template@7.4.4': + resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==} + + '@types/babel__traverse@7.28.0': + resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==} + + '@types/big.js@6.2.2': + resolution: {integrity: sha512-e2cOW9YlVzFY2iScnGBBkplKsrn2CsObHQ2Hiw4V1sSyiGbgWL8IyqE3zFi1Pt5o1pdAtYkDAIsF3KKUPjdzaA==} + + '@types/body-parser@1.19.6': + resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} + + '@types/bonjour@3.5.13': + resolution: {integrity: sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==} + + '@types/bs58@4.0.4': + resolution: {integrity: sha512-0IEpMFXXQi2zXaXl9GJ3sRwQo0uEkD+yFOv+FnAU5lkPtcu6h61xb7jc2CFPEZ5BUOaiP13ThuGc9HD4R8lR5g==} + + '@types/connect-history-api-fallback@1.5.4': + resolution: {integrity: sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/d3-array@3.2.2': + resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==} + + '@types/d3-color@3.1.3': + resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==} + + '@types/d3-delaunay@6.0.4': + resolution: {integrity: sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw==} + + '@types/d3-ease@3.0.2': + resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==} + + '@types/d3-format@1.4.5': + resolution: {integrity: sha512-mLxrC1MSWupOSncXN/HOlWUAAIffAEBaI4+PKy2uMPsKe4FNZlk7qrbTjmzJXITQQqBHivaks4Td18azgqnotA==} + + '@types/d3-interpolate@3.0.4': + resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==} + + '@types/d3-path@3.1.1': + resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==} + + '@types/d3-scale-chromatic@3.1.0': + resolution: {integrity: sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ==} + + '@types/d3-scale@4.0.9': + resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==} + + '@types/d3-shape@3.1.8': + resolution: {integrity: sha512-lae0iWfcDeR7qt7rA88BNiqdvPS5pFVPpo5OfjElwNaT2yyekbM0C9vK+yqBqEmHr6lDkRnYNoTBYlAgJa7a4w==} + + '@types/d3-time-format@2.3.4': + resolution: {integrity: sha512-xdDXbpVO74EvadI3UDxjxTdR6QIxm1FKzEA/+F8tL4GWWUg/hgvBqf6chql64U5A9ZUGWo7pEu4eNlyLwbKdhg==} + + '@types/d3-time-format@3.0.4': + resolution: {integrity: sha512-or9DiDnYI1h38J9hxKEsw513+KVuFbEVhl7qdxcaudoiqWWepapUen+2vAriFGexr6W5+P4l9+HJrB39GG+oRg==} + + '@types/d3-time@1.1.4': + resolution: {integrity: sha512-JIvy2HjRInE+TXOmIGN5LCmeO0hkFZx5f9FZ7kiN+D+YTcc8pptsiLiuHsvwxwC7VVKmJ2ExHUgNlAiV7vQM9g==} + + '@types/d3-time@3.0.4': + resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==} + + '@types/d3-timer@3.0.2': + resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==} + + '@types/debug@4.1.13': + resolution: {integrity: sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==} + + '@types/eslint-scope@3.7.7': + resolution: {integrity: sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==} + + '@types/eslint@9.6.1': + resolution: {integrity: sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==} + + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + + '@types/estree@0.0.51': + resolution: {integrity: sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/express-serve-static-core@4.19.8': + resolution: {integrity: sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==} + + '@types/express-serve-static-core@5.1.1': + resolution: {integrity: sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A==} + + '@types/express@4.17.25': + resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==} + + '@types/favicons@5.5.0': + resolution: {integrity: sha512-s76OlRaBfqtGu2ZBobnZv2NETfqsQUVfKKlOkKNGo4ArBsqiblodKsnQ3j29hCCgmpQacEfLxealV96za+tzVQ==} + + '@types/flat@5.0.5': + resolution: {integrity: sha512-nPLljZQKSnac53KDUDzuzdRfGI0TDb5qPrb+SrQyN3MtdQrOnGsKniHN1iYZsJEBIVQve94Y6gNz22sgISZq+Q==} + + '@types/glob@7.2.0': + resolution: {integrity: sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==} + + '@types/glob@9.0.0': + resolution: {integrity: sha512-00UxlRaIUvYm4R4W9WYkN8/J+kV8fmOQ7okeH6YFtGWFMt3odD45tpG5yA5wnL7HE6lLgjaTW5n14ju2hl2NNA==} + deprecated: This is a stub types definition. glob provides its own type definitions, so you do not need this installed. + + '@types/graceful-fs@4.1.9': + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + + '@types/hast@2.3.10': + resolution: {integrity: sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw==} + + '@types/hast@3.0.4': + resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} + + '@types/html-minifier-terser@5.1.2': + resolution: {integrity: sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w==} + + '@types/html-minifier-terser@6.1.0': + resolution: {integrity: sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==} + + '@types/http-errors@2.0.5': + resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} + + '@types/http-proxy@1.17.17': + resolution: {integrity: sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==} + + '@types/is-function@1.0.3': + resolution: {integrity: sha512-/CLhCW79JUeLKznI6mbVieGbl4QU5Hfn+6udw1YHZoofASjbQ5zaP5LzAUZYDpRYEjS4/P+DhEgyJ/PQmGGTWw==} + + '@types/istanbul-lib-coverage@2.0.6': + resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} + + '@types/istanbul-lib-report@3.0.3': + resolution: {integrity: sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==} + + '@types/istanbul-reports@3.0.4': + resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + + '@types/jest@27.5.2': + resolution: {integrity: sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==} + + '@types/jest@29.5.14': + resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/json5@0.0.29': + resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} + + '@types/lodash@4.17.24': + resolution: {integrity: sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==} + + '@types/long@4.0.2': + resolution: {integrity: sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==} + + '@types/mdast@3.0.15': + resolution: {integrity: sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + + '@types/minimatch@3.0.5': + resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==} + + '@types/minimatch@5.1.2': + resolution: {integrity: sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==} + + '@types/minimist@1.2.5': + resolution: {integrity: sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==} + + '@types/ms@2.1.0': + resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} + + '@types/node-fetch@2.6.13': + resolution: {integrity: sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==} + + '@types/node-forge@1.3.14': + resolution: {integrity: sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw==} + + '@types/node@10.12.18': + resolution: {integrity: sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==} + + '@types/node@13.13.52': + resolution: {integrity: sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ==} + + '@types/node@16.18.126': + resolution: {integrity: sha512-OTcgaiwfGFBKacvfwuHzzn1KLxH/er8mluiy8/uM3sGXHaRe73RrSIj01jow9t4kJEW633Ov+cOexXeiApTyAw==} + + '@types/node@20.19.41': + resolution: {integrity: sha512-ECymXOukMnOoVkC2bb1Vc/w/836DXncOg5m8Xj1RH7xSHZJWNYY6Zh7EH477vcnD5egKNNfy2RpNOmuChhFPgQ==} + + '@types/node@22.19.19': + resolution: {integrity: sha512-dyh/xO2Fh5bYrfWaaqGrRQQGkNdmYw6AmaAUvYeUMNTWQtvb796ikLdmTchRmOlOiIJ1TDXfWgVx1QkUlQ6Hew==} + + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + + '@types/npmlog@4.1.6': + resolution: {integrity: sha512-0l3z16vnlJGl2Mi/rgJFrdwfLZ4jfNYgE6ZShEpjqhHuGTqdEzNles03NpYHwUMVYZa+Tj46UxKIEpE78lQ3DQ==} + + '@types/parse-json@4.0.2': + resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} + + '@types/parse5@5.0.3': + resolution: {integrity: sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==} + + '@types/prettier@2.7.3': + resolution: {integrity: sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA==} + + '@types/pretty-hrtime@1.0.3': + resolution: {integrity: sha512-nj39q0wAIdhwn7DGUyT9irmsKK1tV0bd5WFEhgpqNTMFZ8cE+jieuTphCW0tfdm47S2zVT5mr09B28b1chmQMA==} + + '@types/prop-types@15.7.15': + resolution: {integrity: sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==} + + '@types/qrcode.react@1.0.5': + resolution: {integrity: sha512-BghPtnlwvrvq8QkGa1H25YnN+5OIgCKFuQruncGWLGJYOzeSKiix/4+B9BtfKF2wf5ja8yfyWYA3OXju995G8w==} + + '@types/qs@6.15.1': + resolution: {integrity: sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + + '@types/react-dom@19.2.3': + resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} + peerDependencies: + '@types/react': ^19.2.0 + + '@types/react-transition-group@4.4.12': + resolution: {integrity: sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==} + peerDependencies: + '@types/react': '*' + + '@types/react@19.2.14': + resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + + '@types/retry@0.12.0': + resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} + + '@types/semver@7.7.1': + resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} + + '@types/send@0.17.6': + resolution: {integrity: sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==} + + '@types/send@1.2.1': + resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} + + '@types/serve-index@1.9.4': + resolution: {integrity: sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==} + + '@types/serve-static@1.15.10': + resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==} + + '@types/sockjs@0.3.36': + resolution: {integrity: sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==} + + '@types/source-list-map@0.1.6': + resolution: {integrity: sha512-5JcVt1u5HDmlXkwOD2nslZVllBBc7HDuOICfiZah2Z0is8M8g+ddAEawbmd3VjedfDHBzxCaXLs07QEmb7y54g==} + + '@types/stack-utils@2.0.3': + resolution: {integrity: sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==} + + '@types/tapable@1.0.12': + resolution: {integrity: sha512-bTHG8fcxEqv1M9+TD14P8ok8hjxoOCkfKc8XXLaaD05kI7ohpeI956jtDOD3XHKBQrlyPughUtzm1jtVhHpA5Q==} + + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + + '@types/uglify-js@3.17.5': + resolution: {integrity: sha512-TU+fZFBTBcXj/GpDpDaBmgWk/gn96kMZ+uocaFUlV2f8a6WdMzzI44QBCmGcCiYR0Y6ZlNRiyUyKKt5nl/lbzQ==} + + '@types/unist@2.0.11': + resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@types/uuid@8.3.4': + resolution: {integrity: sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==} + + '@types/webpack-env@1.18.8': + resolution: {integrity: sha512-G9eAoJRMLjcvN4I08wB5I7YofOb/kaJNd5uoCMX+LbKXTPCF+ZIHuqTnFaK9Jz1rgs035f9JUPUhNFtqgucy/A==} + + '@types/webpack-sources@3.2.3': + resolution: {integrity: sha512-4nZOdMwSPHZ4pTEZzSp0AsTM4K7Qmu40UKW4tJDiOVs20UzYF9l+qUe4s0ftfN0pin06n+5cWWDJXH+sbhAiDw==} + + '@types/webpack@4.41.40': + resolution: {integrity: sha512-u6kMFSBM9HcoTpUXnL6mt2HSzftqb3JgYV6oxIgL2dl6sX6aCa5k6SOkzv5DuZjBTPUE/dJltKtwwuqrkZHpfw==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + + '@types/yargs-parser@21.0.3': + resolution: {integrity: sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==} + + '@types/yargs@15.0.20': + resolution: {integrity: sha512-KIkX+/GgfFitlASYCGoSF+T4XRXhOubJLhkLVtSfsRTe9jWMmuM2g28zQ41BtPTG7TRBb2xHW+LCNVE9QR/vsg==} + + '@types/yargs@16.0.11': + resolution: {integrity: sha512-sbtvk8wDN+JvEdabmZExoW/HNr1cB7D/j4LT08rMiuikfA7m/JNJg7ATQcgzs34zHnoScDkY0ZRSl29Fkmk36g==} + + '@types/yargs@17.0.35': + resolution: {integrity: sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg==} + + '@types/zxcvbn@4.4.5': + resolution: {integrity: sha512-FZJgC5Bxuqg7Rhsm/bx6gAruHHhDQ55r+s0JhDh8CQ16fD7NsJJ+p8YMMQDhSQoIrSmjpqqYWA96oQVMNkjRyA==} + + '@typescript-eslint/eslint-plugin@5.62.0': + resolution: {integrity: sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/parser': ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/eslint-plugin@8.59.4': + resolution: {integrity: sha512-PegsU+XfyJJNjd4+u/k6f9yTyp0lEXXiPopUNobZcIAUJFGICFLN+sP0Rb3JehVmiij1Ph0dFGYqODoRo/2+6A==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + '@typescript-eslint/parser': ^8.59.4 + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/experimental-utils@5.62.0': + resolution: {integrity: sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + + '@typescript-eslint/parser@5.62.0': + resolution: {integrity: sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/parser@8.59.4': + resolution: {integrity: sha512-zORHqO/tuhxY1zWuTvMUqddRxpiFJ72xVfcNoWpqdLjs6lfPbuQBJuW4pk+49/uBMy7Ssr4bzgjiKmmDB1UbZQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/project-service@8.59.4': + resolution: {integrity: sha512-Ly00Vu4oAacfDeHp2Zg85ioNG6l8HG+tN1D7J+xTHSxu9y0awYKJ2zH1rFBn8ZSfuGK+7FxK3Cgl3uAz0aZZLg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/scope-manager@5.62.0': + resolution: {integrity: sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/scope-manager@8.59.4': + resolution: {integrity: sha512-mUeR/3H1WrTAddJrwut8OoPjfauaztMQmRwV5fQTUyNVJCLiUXXe4lGEyYIL2oFDpP7UtgbGJXCt72wT0z2S3Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/tsconfig-utils@8.59.4': + resolution: {integrity: sha512-DLCpnKgD4alVxTBSKulK+gU1KCqOgUXfDRDXh2mZgzokQKa/70ax93I2uVO3m/LLvIAtWZIFoiifudmIqAxpMA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/type-utils@5.62.0': + resolution: {integrity: sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: '*' + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/type-utils@8.59.4': + resolution: {integrity: sha512-uonTuPAAKr9XaBGqJ3LjYTh72zy5DyGesljO9gtmk/eFW0W1fRHjnwVYKB35Lm8d5Q5CluEW3gPHjTvZTmgrfA==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/types@5.62.0': + resolution: {integrity: sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/types@8.59.4': + resolution: {integrity: sha512-F1o7WJcCq+bc8dwcO/YsSEOudAH8RDtaOhM6wcAQhcUsFhnWQl81JKy48q1hoxAU0qrzM89+31GYh1515Zde3Q==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@typescript-eslint/typescript-estree@5.62.0': + resolution: {integrity: sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + '@typescript-eslint/typescript-estree@8.59.4': + resolution: {integrity: sha512-F+RuOmcDXo4+TPdfd/TCLS3m2nw8gE9XXyZLrA3JBfaA5tz9TtdkyD3YJFmPxulyc2cKbEok/CvFE3MgSLWnag==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/utils@5.62.0': + resolution: {integrity: sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + + '@typescript-eslint/utils@8.59.4': + resolution: {integrity: sha512-cYXeNAUsG4lJo5dbc1FcKm+JwIWrj1/UpTORsC6tGMjEZ81DYcvIr9/ueikhMa/Y/gDQYGp+YX9/xQrXje5BJw==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 || ^10.0.0 + typescript: '>=4.8.4 <6.1.0' + + '@typescript-eslint/visitor-keys@5.62.0': + resolution: {integrity: sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + '@typescript-eslint/visitor-keys@8.59.4': + resolution: {integrity: sha512-U3gxVaDVnuZKhSspW/MzMxE1kq7zOdc072FcSNoqA1I9p8HyKbBFfEHoWckBAMgNMph4MamwS5iTVzFmrnt8TQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + '@uidotdev/usehooks@2.4.1': + resolution: {integrity: sha512-1I+RwWyS+kdv3Mv0Vmc+p0dPYH0DTRAo04HLyXReYBL9AeseDWUJyi4THuksBJcu9F0Pih69Ak150VDnqbVnXg==} + engines: {node: '>=16'} + peerDependencies: + react: '>=18.0.0' + react-dom: '>=18.0.0' + + '@ungap/structured-clone@1.3.1': + resolution: {integrity: sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==} + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + resolution: {integrity: sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw==} + cpu: [arm] + os: [android] + + '@unrs/resolver-binding-android-arm64@1.11.1': + resolution: {integrity: sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g==} + cpu: [arm64] + os: [android] + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + resolution: {integrity: sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g==} + cpu: [arm64] + os: [darwin] + + '@unrs/resolver-binding-darwin-x64@1.11.1': + resolution: {integrity: sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ==} + cpu: [x64] + os: [darwin] + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + resolution: {integrity: sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw==} + cpu: [x64] + os: [freebsd] + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + resolution: {integrity: sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + resolution: {integrity: sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw==} + cpu: [arm] + os: [linux] + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + resolution: {integrity: sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + resolution: {integrity: sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + resolution: {integrity: sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA==} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + resolution: {integrity: sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ==} + cpu: [riscv64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + resolution: {integrity: sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew==} + cpu: [riscv64] + os: [linux] + libc: [musl] + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + resolution: {integrity: sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg==} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + resolution: {integrity: sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + resolution: {integrity: sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + resolution: {integrity: sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + resolution: {integrity: sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw==} + cpu: [arm64] + os: [win32] + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + resolution: {integrity: sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ==} + cpu: [ia32] + os: [win32] + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + resolution: {integrity: sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g==} + cpu: [x64] + os: [win32] + + '@vanilla-extract/css-utils@0.1.6': + resolution: {integrity: sha512-iICpaHma0s2EEnQDw/JRqudQJwYw1JERyWfIllNQplps226KVphjGb3jyGMiBK5Waw69RD3q4gulgRVQAQmKmA==} + + '@vanilla-extract/css@1.20.1': + resolution: {integrity: sha512-5I9RNo5uZW9tsBnqrWzJqELegOqTHBrZyDFnES0gR9gJJHBB9dom1N0bwITM9tKwBcfKrTX4a6DHVeQdJ2ubQA==} + + '@vanilla-extract/dynamic@2.1.5': + resolution: {integrity: sha512-QGIFGb1qyXQkbzx6X6i3+3LMc/iv/ZMBttMBL+Wm/DetQd36KsKsFg5CtH3qy+1hCA/5w93mEIIAiL4fkM8ycw==} + + '@vanilla-extract/private@1.0.9': + resolution: {integrity: sha512-gT2jbfZuaaCLrAxwXbRgIhGhcXbRZCG3v4TTUnjw0EJ7ArdBRxkq4msNJkbuRkCgfIK5ATmprB5t9ljvLeFDEA==} + + '@vanilla-extract/recipes@0.5.7': + resolution: {integrity: sha512-Fvr+htdyb6LVUu+PhH61UFPhwkjgDEk8L4Zq9oIdte42sntpKrgFy90MyTRtGwjVALmrJ0pwRUVr8UoByYeW8A==} + peerDependencies: + '@vanilla-extract/css': ^1.0.0 + + '@vitest/pretty-format@2.1.9': + resolution: {integrity: sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==} + + '@vitest/utils@2.1.9': + resolution: {integrity: sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==} + + '@walletconnect/events@1.0.1': + resolution: {integrity: sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ==} + + '@walletconnect/heartbeat@1.2.1': + resolution: {integrity: sha512-yVzws616xsDLJxuG/28FqtZ5rzrTA4gUjdEMTbWB5Y8V1XHRmqq4efAxCw5ie7WjbXFSUyBHaWlMR+2/CpQC5Q==} + + '@walletconnect/jsonrpc-types@1.0.3': + resolution: {integrity: sha512-iIQ8hboBl3o5ufmJ8cuduGad0CQm3ZlsHtujv9Eu16xq89q+BG7Nh5VLxxUgmtpnrePgFkTwXirCTkwJH1v+Yw==} + + '@walletconnect/keyvaluestorage@1.1.1': + resolution: {integrity: sha512-V7ZQq2+mSxAq7MrRqDxanTzu2RcElfK1PfNYiaVnJgJ7Q7G7hTVwF8voIBx92qsRyGHZihrwNPHuZd1aKkd0rA==} + peerDependencies: + '@react-native-async-storage/async-storage': 1.x + peerDependenciesMeta: + '@react-native-async-storage/async-storage': + optional: true + + '@walletconnect/logger@2.1.3': + resolution: {integrity: sha512-wRsD0eDQSajj8YMM/jpxoH1yeSLyS7FPkh0VKCQ1BWrERTy1Z7/DmOE8FYm/gmd7Cg6BNXVWiymhGq6wnmlq8w==} + + '@walletconnect/safe-json@1.0.2': + resolution: {integrity: sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA==} + + '@walletconnect/time@1.0.2': + resolution: {integrity: sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g==} + + '@walletconnect/types@2.11.0': + resolution: {integrity: sha512-AB5b1lrEbCGHxqS2vqfCkIoODieH+ZAUp9rA1O2ftrhnqDJiJK983Df87JhYhECsQUBHHfALphA8ydER0q+9sw==} + + '@webassemblyjs/ast@1.14.1': + resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} + + '@webassemblyjs/ast@1.9.0': + resolution: {integrity: sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==} + + '@webassemblyjs/floating-point-hex-parser@1.13.2': + resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} + + '@webassemblyjs/floating-point-hex-parser@1.9.0': + resolution: {integrity: sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==} + + '@webassemblyjs/helper-api-error@1.13.2': + resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} + + '@webassemblyjs/helper-api-error@1.9.0': + resolution: {integrity: sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==} + + '@webassemblyjs/helper-buffer@1.14.1': + resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} + + '@webassemblyjs/helper-buffer@1.9.0': + resolution: {integrity: sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==} + + '@webassemblyjs/helper-code-frame@1.9.0': + resolution: {integrity: sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==} + + '@webassemblyjs/helper-fsm@1.9.0': + resolution: {integrity: sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==} + + '@webassemblyjs/helper-module-context@1.9.0': + resolution: {integrity: sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==} + + '@webassemblyjs/helper-numbers@1.13.2': + resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': + resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} + + '@webassemblyjs/helper-wasm-bytecode@1.9.0': + resolution: {integrity: sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==} + + '@webassemblyjs/helper-wasm-section@1.14.1': + resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} + + '@webassemblyjs/helper-wasm-section@1.9.0': + resolution: {integrity: sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==} + + '@webassemblyjs/ieee754@1.13.2': + resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} + + '@webassemblyjs/ieee754@1.9.0': + resolution: {integrity: sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==} + + '@webassemblyjs/leb128@1.13.2': + resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} + + '@webassemblyjs/leb128@1.9.0': + resolution: {integrity: sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==} + + '@webassemblyjs/utf8@1.13.2': + resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} + + '@webassemblyjs/utf8@1.9.0': + resolution: {integrity: sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==} + + '@webassemblyjs/wasm-edit@1.14.1': + resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} + + '@webassemblyjs/wasm-edit@1.9.0': + resolution: {integrity: sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==} + + '@webassemblyjs/wasm-gen@1.14.1': + resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} + + '@webassemblyjs/wasm-gen@1.9.0': + resolution: {integrity: sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==} + + '@webassemblyjs/wasm-opt@1.14.1': + resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} + + '@webassemblyjs/wasm-opt@1.9.0': + resolution: {integrity: sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==} + + '@webassemblyjs/wasm-parser@1.14.1': + resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} + + '@webassemblyjs/wasm-parser@1.9.0': + resolution: {integrity: sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==} + + '@webassemblyjs/wast-parser@1.9.0': + resolution: {integrity: sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==} + + '@webassemblyjs/wast-printer@1.14.1': + resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} + + '@webassemblyjs/wast-printer@1.9.0': + resolution: {integrity: sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==} + + '@webpack-cli/configtest@1.2.0': + resolution: {integrity: sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg==} + peerDependencies: + webpack: 4.x.x || 5.x.x + webpack-cli: 4.x.x + + '@webpack-cli/configtest@2.1.1': + resolution: {integrity: sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==} + engines: {node: '>=14.15.0'} + peerDependencies: + webpack: 5.x.x + webpack-cli: 5.x.x + + '@webpack-cli/info@1.5.0': + resolution: {integrity: sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==} + peerDependencies: + webpack-cli: 4.x.x + + '@webpack-cli/info@2.0.2': + resolution: {integrity: sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==} + engines: {node: '>=14.15.0'} + peerDependencies: + webpack: 5.x.x + webpack-cli: 5.x.x + + '@webpack-cli/serve@1.7.0': + resolution: {integrity: sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==} + peerDependencies: + webpack-cli: 4.x.x + webpack-dev-server: '*' + peerDependenciesMeta: + webpack-dev-server: + optional: true + + '@webpack-cli/serve@2.0.5': + resolution: {integrity: sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==} + engines: {node: '>=14.15.0'} + peerDependencies: + webpack: 5.x.x + webpack-cli: 5.x.x + webpack-dev-server: '*' + peerDependenciesMeta: + webpack-dev-server: + optional: true + + '@xtuc/ieee754@1.2.0': + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + + '@xtuc/long@4.2.2': + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + + '@yarnpkg/lockfile@1.1.0': + resolution: {integrity: sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==} + + '@yarnpkg/parsers@3.0.0-rc.46': + resolution: {integrity: sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q==} + engines: {node: '>=14.15.0'} + + '@zkochan/js-yaml@0.0.6': + resolution: {integrity: sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg==} + hasBin: true + + JSONStream@1.3.5: + resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} + hasBin: true + + abab@2.0.6: + resolution: {integrity: sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==} + deprecated: Use your platform's native atob() and btoa() methods instead + + abbrev@1.1.1: + resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} + + abi-wan-kanabi@2.2.4: + resolution: {integrity: sha512-0aA81FScmJCPX+8UvkXLki3X1+yPQuWxEkqXBVKltgPAK79J+NB+Lp5DouMXa7L6f+zcRlIA/6XO7BN/q9fnvg==} + hasBin: true + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + acorn-globals@6.0.0: + resolution: {integrity: sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==} + + acorn-import-phases@1.0.4: + resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==} + engines: {node: '>=10.13.0'} + peerDependencies: + acorn: ^8.14.0 + + acorn-jsx@5.3.2: + resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} + peerDependencies: + acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 + + acorn-walk@7.2.0: + resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} + engines: {node: '>=0.4.0'} + + acorn@6.4.2: + resolution: {integrity: sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==} + engines: {node: '>=0.4.0'} + hasBin: true + + acorn@7.4.1: + resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} + engines: {node: '>=0.4.0'} + hasBin: true + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + add-stream@1.0.0: + resolution: {integrity: sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==} + + address@1.2.2: + resolution: {integrity: sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA==} + engines: {node: '>= 10.0.0'} + + agent-base@6.0.2: + resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} + engines: {node: '>= 6.0.0'} + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + agentkeepalive@4.6.0: + resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} + engines: {node: '>= 8.0.0'} + + aggregate-error@3.1.0: + resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} + engines: {node: '>=8'} + + airbnb-js-shims@2.2.1: + resolution: {integrity: sha512-wJNXPH66U2xjgo1Zwyjf9EydvJ2Si94+vSdk6EERcBfB2VZkeltpqIats0cqIZMLCXP3zcyaUKGYQeIBT6XjsQ==} + + ajv-errors@1.0.1: + resolution: {integrity: sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==} + peerDependencies: + ajv: '>=5.0.0' + + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-keywords@3.5.2: + resolution: {integrity: sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==} + peerDependencies: + ajv: ^6.9.1 + + ajv-keywords@5.1.0: + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + + ajv@6.15.0: + resolution: {integrity: sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==} + + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} + + animejs@3.2.2: + resolution: {integrity: sha512-Ao95qWLpDPXXM+WrmwcKbl6uNlC5tjnowlaRYtuVDHHoygjtIPfDUoK9NthrlZsQSKjZXlmji2TrBUAVbiH0LQ==} + + ansi-align@3.0.1: + resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==} + + ansi-colors@3.2.4: + resolution: {integrity: sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==} + engines: {node: '>=6'} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-escapes@4.3.2: + resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} + engines: {node: '>=8'} + + ansi-html-community@0.0.8: + resolution: {integrity: sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==} + engines: {'0': node >= 0.8.0} + hasBin: true + + ansi-html@0.0.9: + resolution: {integrity: sha512-ozbS3LuenHVxNRh/wdnN16QapUHzauqSomAl1jwwJRRsGwFwtj644lIhxfWu0Fy0acCij2+AEgHvjscq3dlVXg==} + engines: {'0': node >= 0.8.0} + hasBin: true + + ansi-regex@2.1.1: + resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} + engines: {node: '>=0.10.0'} + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} + engines: {node: '>=12'} + + ansi-styles@3.2.1: + resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} + engines: {node: '>=4'} + + ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + ansi-to-html@0.6.15: + resolution: {integrity: sha512-28ijx2aHJGdzbs+O5SNQF65r6rrKYnkuwTYm8lZlChuoJ9P1vVzIpWO20sQTqTPDXYp6NFwk326vApTtLVFXpQ==} + engines: {node: '>=8.0.0'} + hasBin: true + + ansicolors@0.3.2: + resolution: {integrity: sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==} + + anymatch@2.0.0: + resolution: {integrity: sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + app-root-dir@1.0.2: + resolution: {integrity: sha512-jlpIfsOoNoafl92Sz//64uQHGSyMrD2vYG5d8o2a4qGvyNCvXur7bzIsWtAC/6flI2RYAp3kv8rsfBtaLm7w0g==} + + aproba@1.2.0: + resolution: {integrity: sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==} + + aproba@2.1.0: + resolution: {integrity: sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==} + + are-we-there-yet@2.0.0: + resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==} + engines: {node: '>=10'} + deprecated: This package is no longer supported. + + are-we-there-yet@3.0.1: + resolution: {integrity: sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. + + argparse@1.0.10: + resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} + + argparse@2.0.1: + resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} + + aria-hidden@1.2.6: + resolution: {integrity: sha512-ik3ZgC9dY/lYVVM++OISsaYDeg1tb0VtP5uL3ouh1koGOaUMDPpbFIei4JkFimWUFPn90sbMNMXQAIVOlnYKJA==} + engines: {node: '>=10'} + + aria-query@5.1.3: + resolution: {integrity: sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ==} + + aria-query@5.3.0: + resolution: {integrity: sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + + arr-diff@4.0.0: + resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} + engines: {node: '>=0.10.0'} + + arr-flatten@1.1.0: + resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} + engines: {node: '>=0.10.0'} + + arr-union@3.1.0: + resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} + engines: {node: '>=0.10.0'} + + array-buffer-byte-length@1.0.2: + resolution: {integrity: sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw==} + engines: {node: '>= 0.4'} + + array-differ@3.0.0: + resolution: {integrity: sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==} + engines: {node: '>=8'} + + array-find-index@1.0.2: + resolution: {integrity: sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==} + engines: {node: '>=0.10.0'} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + array-ify@1.0.0: + resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} + + array-includes@3.1.9: + resolution: {integrity: sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ==} + engines: {node: '>= 0.4'} + + array-union@1.0.2: + resolution: {integrity: sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==} + engines: {node: '>=0.10.0'} + + array-union@2.1.0: + resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} + engines: {node: '>=8'} + + array-uniq@1.0.3: + resolution: {integrity: sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==} + engines: {node: '>=0.10.0'} + + array-unique@0.3.2: + resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} + engines: {node: '>=0.10.0'} + + array.prototype.findlast@1.2.5: + resolution: {integrity: sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==} + engines: {node: '>= 0.4'} + + array.prototype.findlastindex@1.2.6: + resolution: {integrity: sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ==} + engines: {node: '>= 0.4'} + + array.prototype.flat@1.3.3: + resolution: {integrity: sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg==} + engines: {node: '>= 0.4'} + + array.prototype.flatmap@1.3.3: + resolution: {integrity: sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg==} + engines: {node: '>= 0.4'} + + array.prototype.map@1.0.8: + resolution: {integrity: sha512-YocPM7bYYu2hXGxWpb5vwZ8cMeudNHYtYBcUDY4Z1GWa53qcnQMWSl25jeBHNzitjl9HW2AWW4ro/S/nftUaOQ==} + engines: {node: '>= 0.4'} + + array.prototype.reduce@1.0.8: + resolution: {integrity: sha512-DwuEqgXFBwbmZSRqt3BpQigWNUoqw9Ml2dTWdF3B2zQlQX4OeUE0zyuzX0fX0IbTvjdkZbcBTU3idgpO78qkTw==} + engines: {node: '>= 0.4'} + + array.prototype.tosorted@1.1.4: + resolution: {integrity: sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==} + engines: {node: '>= 0.4'} + + arraybuffer.prototype.slice@1.0.4: + resolution: {integrity: sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ==} + engines: {node: '>= 0.4'} + + arrify@1.0.1: + resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} + engines: {node: '>=0.10.0'} + + arrify@2.0.1: + resolution: {integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==} + engines: {node: '>=8'} + + asn1.js@4.10.1: + resolution: {integrity: sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==} + + assert@1.5.1: + resolution: {integrity: sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A==} + + assign-symbols@1.0.0: + resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} + engines: {node: '>=0.10.0'} + + ast-types-flow@0.0.8: + resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} + + ast-types@0.14.2: + resolution: {integrity: sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA==} + engines: {node: '>=4'} + + ast-types@0.16.1: + resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} + engines: {node: '>=4'} + + async-each@1.0.6: + resolution: {integrity: sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==} + + async-function@1.0.0: + resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} + engines: {node: '>= 0.4'} + + async@3.2.6: + resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} + + asynckit@0.4.0: + resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} + + at-least-node@1.0.0: + resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} + engines: {node: '>= 4.0.0'} + + atob@2.1.2: + resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} + engines: {node: '>= 4.5.0'} + hasBin: true + + atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + + author-regex@1.0.0: + resolution: {integrity: sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g==} + engines: {node: '>=0.8'} + + autoprefixer@9.8.8: + resolution: {integrity: sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==} + hasBin: true + + available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + + axe-core@4.11.4: + resolution: {integrity: sha512-KunSNx+TVpkAw/6ULfhnx+HWRecjqZGTOyquAoWHYLRSdK1tB5Ihce1ZW+UY3fj33bYAFWPu7W/GRSmmrCGuxA==} + engines: {node: '>=4'} + + axios@0.21.4: + resolution: {integrity: sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==} + + axios@1.16.0: + resolution: {integrity: sha512-6hp5CwvTPlN2A31g5dxnwAX0orzM7pmCRDLnZSX772mv8WDqICwFjowHuPs04Mc8deIld1+ejhtaMn5vp6b+1w==} + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + babel-jest@27.5.1: + resolution: {integrity: sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + + babel-jest@29.7.0: + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + + babel-loader@8.4.1: + resolution: {integrity: sha512-nXzRChX+Z1GoE6yWavBQg6jDslyFF3SDjl2paADuoQtQW10JqShJt62R6eJQ5m/pjJFDT8xgKIWSP85OY8eXeA==} + engines: {node: '>= 8.9'} + peerDependencies: + '@babel/core': ^7.0.0 + webpack: '>=2' + + babel-loader@9.2.1: + resolution: {integrity: sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==} + engines: {node: '>= 14.15.0'} + peerDependencies: + '@babel/core': ^7.12.0 + webpack: '>=5' + + babel-plugin-add-react-displayname@0.0.5: + resolution: {integrity: sha512-LY3+Y0XVDYcShHHorshrDbt4KFWL4bSeniCtl4SYZbask+Syngk1uMPCeN9+nSiZo6zX5s0RTq/J9Pnaaf/KHw==} + + babel-plugin-apply-mdx-type-prop@1.6.22: + resolution: {integrity: sha512-VefL+8o+F/DfK24lPZMtJctrCVOfgbqLAGZSkxwhazQv4VxPg3Za/i40fu22KR2m8eEda+IfSOlPLUSIiLcnCQ==} + peerDependencies: + '@babel/core': ^7.11.6 + + babel-plugin-extract-import-names@1.6.22: + resolution: {integrity: sha512-yJ9BsJaISua7d8zNT7oRG1ZLBJCIdZ4PZqmH8qa9N5AK01ifk3fnkc98AXhtzE7UkfCsEumvoQWgoYLhOnJ7jQ==} + + babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + + babel-plugin-jest-hoist@27.5.1: + resolution: {integrity: sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + babel-plugin-macros@3.1.0: + resolution: {integrity: sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==} + engines: {node: '>=10', npm: '>=6'} + + babel-plugin-named-exports-order@0.0.2: + resolution: {integrity: sha512-OgOYHOLoRK+/mvXU9imKHlG6GkPLYrUCvFXG/CM93R/aNNO8pOOF4aS+S8CCHMDQoNSeiOYEZb/G6RwL95Jktw==} + + babel-plugin-polyfill-corejs2@0.4.17: + resolution: {integrity: sha512-aTyf30K/rqAsNwN76zYrdtx8obu0E4KoUME29B1xj+B3WxgvWkp943vYQ+z8Mv3lw9xHXMHpvSPOBxzAkIa94w==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-corejs3@0.1.7: + resolution: {integrity: sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw==} + peerDependencies: + '@babel/core': ^7.0.0-0 + + babel-plugin-polyfill-corejs3@0.14.2: + resolution: {integrity: sha512-coWpDLJ410R781Npmn/SIBZEsAetR4xVi0SxLMXPaMO4lSf1MwnkGYMtkFxew0Dn8B3/CpbpYxN0JCgg8mn67g==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-polyfill-regenerator@0.6.8: + resolution: {integrity: sha512-M762rNHfSF1EV3SLtnCJXFoQbbIIz0OyRwnCmV0KPC7qosSfCO0QLTSuJX3ayAebubhE6oYBAYPrBA5ljowaZg==} + peerDependencies: + '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + + babel-plugin-react-docgen@4.2.1: + resolution: {integrity: sha512-UQ0NmGHj/HAqi5Bew8WvNfCk8wSsmdgNd8ZdMjBCICtyCJCq9LiqgqvjCYe570/Wg7AQArSq1VQ60Dd/CHN7mQ==} + + babel-plugin-root-import@5.1.0: + resolution: {integrity: sha512-9VYUlnHtM7zjM9vM3kFClUDH7jjhqnvQwxWYGP18EciPsPZYZD9wGqVGwry6gQv0UdZS0+WmbPSlKSjKv1wZFw==} + + babel-plugin-root-import@6.6.0: + resolution: {integrity: sha512-SPzVOHd7nDh5loZwZBxtX/oOu1MXeKjTkz+1VnnzLWC0dk8sJIGC2IDQ2uWIBjE5mUtXlQ35MTHSqN0Xn7qHrg==} + + babel-preset-current-node-syntax@1.2.0: + resolution: {integrity: sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg==} + peerDependencies: + '@babel/core': ^7.0.0 || ^8.0.0-0 + + babel-preset-jest@27.5.1: + resolution: {integrity: sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + + babel-preset-jest@29.6.3: + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + + bail@1.0.5: + resolution: {integrity: sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==} + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + + balanced-match@1.0.2: + resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + + base-x@3.0.11: + resolution: {integrity: sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA==} + + base58@2.0.1: + resolution: {integrity: sha512-qK6gt2fMSxN2xGOi+btI5oAnXL+vEq0AsHWHhf5jfm2hE6MwmW+2414qF96utV3Xfg3En8hEA9Q4lif4lbXcgw==} + engines: {node: '>= 6'} + + base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + + base@0.11.2: + resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} + engines: {node: '>=0.10.0'} + + baseline-browser-mapping@2.10.29: + resolution: {integrity: sha512-Asa2krT+XTPZINCS+2QcyS8WTkObE77RwkydwF7h6DmnKqbvlalz93m/dnphUyCa6SWSP51VgtEUf2FN+gelFQ==} + engines: {node: '>=6.0.0'} + hasBin: true + + batch@0.6.1: + resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} + + bech32@1.1.4: + resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==} + + before-after-hook@2.2.3: + resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} + + better-opn@2.1.1: + resolution: {integrity: sha512-kIPXZS5qwyKiX/HcRvDYfmBQUa8XP17I0mYZZ0y4UhpYOSvtsLHDYqmomS+Mj20aDvD3knEiQ0ecQy2nhio3yA==} + engines: {node: '>8.0.0'} + + better-opn@3.0.2: + resolution: {integrity: sha512-aVNobHnJqLiUelTaHat9DZ1qM2w0C0Eym4LPI/3JxOnSokGVdsl1T1kN7TFvsEAD8G47A6VKQ0TVHqbBnYMJlQ==} + engines: {node: '>=12.0.0'} + + bfs-path@1.0.2: + resolution: {integrity: sha512-KTKx2JJtAAAT7C/rJYDXXWA2VLPycAS4kwFktKsxUo0hj4UTtw/Gm5PJuY7Uf3xSlIQNo7HRCSWei2ivncVwbQ==} + + bidi-js@1.0.3: + resolution: {integrity: sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw==} + + big-integer@1.6.52: + resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==} + engines: {node: '>=0.6'} + + big.js@5.2.2: + resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} + + big.js@6.2.2: + resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} + + bignumber.js@9.1.2: + resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} + + bignumber.js@9.3.1: + resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + + binary-extensions@1.13.1: + resolution: {integrity: sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==} + engines: {node: '>=0.10.0'} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + bindings@1.5.0: + resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} + + bip32@2.0.6: + resolution: {integrity: sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA==} + engines: {node: '>=6.0.0'} + + bip39@3.1.0: + resolution: {integrity: sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A==} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + + bn.js@4.12.3: + resolution: {integrity: sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g==} + + bn.js@5.2.3: + resolution: {integrity: sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w==} + + body-parser@1.20.5: + resolution: {integrity: sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + bonjour-service@1.3.0: + resolution: {integrity: sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + bowser@2.11.0: + resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} + + boxen@5.1.2: + resolution: {integrity: sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ==} + engines: {node: '>=10'} + + bplist-parser@0.1.1: + resolution: {integrity: sha512-2AEM0FXy8ZxVLBuqX0hqt1gDwcnz2zygEkQ6zaD5Wko/sB9paUNwlpawrFtKeHUAQUOzjVy9AO4oeonqIHKA9Q==} + + brace-expansion@1.1.14: + resolution: {integrity: sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==} + + brace-expansion@2.1.0: + resolution: {integrity: sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==} + + brace-expansion@5.0.6: + resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} + engines: {node: 18 || 20 || >=22} + + braces@2.3.2: + resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==} + engines: {node: '>=0.10.0'} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + brorand@1.1.0: + resolution: {integrity: sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==} + + browser-assert@1.2.1: + resolution: {integrity: sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ==} + + browser-process-hrtime@1.0.0: + resolution: {integrity: sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==} + + browserify-aes@1.2.0: + resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} + + browserify-cipher@1.0.1: + resolution: {integrity: sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==} + + browserify-des@1.0.2: + resolution: {integrity: sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==} + + browserify-rsa@4.1.1: + resolution: {integrity: sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ==} + engines: {node: '>= 0.10'} + + browserify-sign@4.2.5: + resolution: {integrity: sha512-C2AUdAJg6rlM2W5QMp2Q4KGQMVBwR1lIimTsUnutJ8bMpW5B52pGpR2gEnNBNwijumDo5FojQ0L9JrXA8m4YEw==} + engines: {node: '>= 0.10'} + + browserify-zlib@0.2.0: + resolution: {integrity: sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==} + + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + bs-logger@0.2.6: + resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} + engines: {node: '>= 6'} + + bs58@4.0.1: + resolution: {integrity: sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw==} + + bs58check@2.1.2: + resolution: {integrity: sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==} + + bser@2.1.1: + resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + buffer-xor@1.0.3: + resolution: {integrity: sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==} + + buffer@4.9.2: + resolution: {integrity: sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==} + + buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + + buffer@6.0.3: + resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + + builtin-status-codes@3.0.0: + resolution: {integrity: sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==} + + builtins@1.0.3: + resolution: {integrity: sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==} + + builtins@5.1.0: + resolution: {integrity: sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==} + + busboy@1.6.0: + resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} + engines: {node: '>=10.16.0'} + + byte-size@8.1.1: + resolution: {integrity: sha512-tUkzZWK0M/qdoLEqikxBWe4kumyuwjl3HO6zHTr4yEI23EojPtLYXdG1+AQY7MN0cGyNDvEaJ8wiYQm6P2bPxg==} + engines: {node: '>=12.17'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + c8@7.14.0: + resolution: {integrity: sha512-i04rtkkcNcCf7zsQcSv/T9EbUn4RXQ6mropeMcjFOsQXQ0iGLAr/xT6TImQg4+U9hmNpN9XdvPkjUL1IzbgxJw==} + engines: {node: '>=10.12.0'} + hasBin: true + + cacache@12.0.4: + resolution: {integrity: sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==} + + cacache@15.3.0: + resolution: {integrity: sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==} + engines: {node: '>= 10'} + + cacache@16.1.3: + resolution: {integrity: sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + cacache@17.1.4: + resolution: {integrity: sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + cache-base@1.0.1: + resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} + engines: {node: '>=0.10.0'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bind@1.0.9: + resolution: {integrity: sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + call-me-maybe@1.0.2: + resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} + + callsites@3.1.0: + resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} + engines: {node: '>=6'} + + camel-case@4.1.2: + resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} + + camelcase-css@2.0.1: + resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} + engines: {node: '>= 6'} + + camelcase-keys@2.1.0: + resolution: {integrity: sha512-bA/Z/DERHKqoEOrp+qeGKw1QlvEQkGZSc0XaY6VnTxZr+Kv1G5zFwttpjv8qxZ/sBPT4nthwZaAcsAZTJlSKXQ==} + engines: {node: '>=0.10.0'} + + camelcase-keys@6.2.2: + resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} + engines: {node: '>=8'} + + camelcase@2.1.1: + resolution: {integrity: sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw==} + engines: {node: '>=0.10.0'} + + camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + + camelcase@6.3.0: + resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} + engines: {node: '>=10'} + + caniuse-api@3.0.0: + resolution: {integrity: sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==} + + caniuse-lite@1.0.30001792: + resolution: {integrity: sha512-hVLMUZFgR4JJ6ACt1uEESvQN1/dBVqPAKY0hgrV70eN3391K6juAfTjKZLKvOMsx8PxA7gsY1/tLMMTcfFLLpw==} + + capture-exit@2.0.0: + resolution: {integrity: sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g==} + engines: {node: 6.* || 8.* || >= 10.*} + + cardinal@2.1.1: + resolution: {integrity: sha512-JSr5eOgoEymtYHBjNWyjrMqet9Am2miJhlfKNdqLp6zoeAh0KN5dRAcxlecj5mAJrmQomgiOBj35xHLrFjqBpw==} + hasBin: true + + case-sensitive-paths-webpack-plugin@2.4.0: + resolution: {integrity: sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==} + engines: {node: '>=4'} + + ccount@1.1.0: + resolution: {integrity: sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + + chain-registry@1.69.578: + resolution: {integrity: sha512-+e8L9LiKbeY2ixZNwd3zK5betftJfe+ZFl6sWbcmUoKm2vkK0VFnojbUu3aWZqq6FtDHHuaYib/CkUYXWxZHYg==} + + chalk@2.4.2: + resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} + engines: {node: '>=4'} + + chalk@4.1.0: + resolution: {integrity: sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==} + engines: {node: '>=10'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + + char-regex@1.0.2: + resolution: {integrity: sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==} + engines: {node: '>=10'} + + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@1.1.4: + resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + + character-entities@1.2.4: + resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} + + character-entities@2.0.2: + resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} + + character-reference-invalid@1.1.4: + resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} + + character-reference-invalid@2.0.1: + resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + + chardet@2.1.1: + resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} + + chokidar@2.1.8: + resolution: {integrity: sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + + chownr@2.0.0: + resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} + engines: {node: '>=10'} + + chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + engines: {node: '>=6.0'} + + ci-info@2.0.0: + resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} + + ci-info@3.9.0: + resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} + engines: {node: '>=8'} + + cipher-base@1.0.7: + resolution: {integrity: sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA==} + engines: {node: '>= 0.10'} + + cjs-module-lexer@1.4.3: + resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + + class-utils@0.3.6: + resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} + engines: {node: '>=0.10.0'} + + cldr-compact-number@0.4.0: + resolution: {integrity: sha512-f/Wz46qoQrfhF2Mq4TcsSbIXMaB70LhioR4fJAbYi5nTnczh1LnSsWuBOXuyKTwFsyrMCRnPFr0OHjl0XB6y9A==} + + clean-css@4.2.4: + resolution: {integrity: sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==} + engines: {node: '>= 4.0'} + + clean-css@5.3.3: + resolution: {integrity: sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg==} + engines: {node: '>= 10.0'} + + clean-stack@2.2.0: + resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} + engines: {node: '>=6'} + + clean-webpack-plugin@4.0.0: + resolution: {integrity: sha512-WuWE1nyTNAyW5T7oNyys2EN0cfP2fdRxhxnIQWiAp0bMabPdHhoGxM8A6YL2GhqwgrPnnaemVE7nv5XJ2Fhh2w==} + engines: {node: '>=10.0.0'} + peerDependencies: + webpack: '>=4.0.0 <6.0.0' + + cli-boxes@2.2.1: + resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==} + engines: {node: '>=6'} + + cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + + cli-spinners@2.6.1: + resolution: {integrity: sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==} + engines: {node: '>=6'} + + cli-spinners@2.9.2: + resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} + engines: {node: '>=6'} + + cli-table3@0.6.5: + resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} + engines: {node: 10.* || >= 12.*} + + cli-width@3.0.0: + resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} + engines: {node: '>= 10'} + + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + + clipboard-copy@3.2.0: + resolution: {integrity: sha512-vooFaGFL6ulEP1liiaWFBmmfuPm3cY3y7T9eB83ZTnYc/oFeAKsq3NcDrOkBC8XaauEE8zHQwI7k0+JSYiVQSQ==} + + cliui@7.0.4: + resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + + clone-deep@4.0.1: + resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} + engines: {node: '>=6'} + + clone@1.0.4: + resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} + engines: {node: '>=0.8'} + + clsx@1.1.0: + resolution: {integrity: sha512-3avwM37fSK5oP6M5rQ9CNe99lwxhXDOeSWVPAOYF6OazUTgZCMb0yWlJpmdD74REy1gkEaFiub2ULv4fq9GUhA==} + engines: {node: '>=6'} + + clsx@1.2.1: + resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} + engines: {node: '>=6'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + + cmd-shim@6.0.1: + resolution: {integrity: sha512-S9iI9y0nKR4hwEQsVWpyxld/6kRfGepGfzff83FcaiEBpmvlbA2nnGe7Cylgrx2f/p1P5S5wpRm9oL8z1PbS3Q==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + co@4.6.0: + resolution: {integrity: sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + + collapse-white-space@1.0.6: + resolution: {integrity: sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==} + + collect-v8-coverage@1.0.3: + resolution: {integrity: sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==} + + collection-visit@1.0.0: + resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} + engines: {node: '>=0.10.0'} + + color-convert@1.9.3: + resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} + + color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + + color-name@1.1.3: + resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} + + color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + + color-string@1.9.1: + resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==} + + color-support@1.1.3: + resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} + hasBin: true + + color@4.2.3: + resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==} + engines: {node: '>=12.5.0'} + + colord@2.9.3: + resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==} + + colorette@1.4.0: + resolution: {integrity: sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + colornames@1.1.1: + resolution: {integrity: sha512-/pyV40IrsdulWv+wFPmERh9k/mjsPZ64yUMDmWrtj/k1nmgrzzIENWKdaVKyBbvFdQWqkcaRxr+polCo3VMe7A==} + + columnify@1.6.0: + resolution: {integrity: sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==} + engines: {node: '>=8.0.0'} + + combined-stream@1.0.8: + resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} + engines: {node: '>= 0.8'} + + comma-separated-tokens@1.0.8: + resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==} + + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + commander@4.1.1: + resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} + engines: {node: '>= 6'} + + commander@6.2.1: + resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} + engines: {node: '>= 6'} + + commander@7.2.0: + resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} + engines: {node: '>= 10'} + + commander@8.3.0: + resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} + engines: {node: '>= 12'} + + common-path-prefix@3.0.0: + resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} + + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + + compare-func@2.0.0: + resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} + + component-emitter@1.3.1: + resolution: {integrity: sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ==} + + compressible@2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + + compression@1.8.1: + resolution: {integrity: sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==} + engines: {node: '>= 0.8.0'} + + concat-map@0.0.1: + resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + + concat-stream@1.6.2: + resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} + engines: {'0': node >= 0.8} + + concat-stream@2.0.0: + resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} + engines: {'0': node >= 6.0} + + confusing-browser-globals@1.0.11: + resolution: {integrity: sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==} + + connect-history-api-fallback@2.0.0: + resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} + engines: {node: '>=0.8'} + + console-browserify@1.2.0: + resolution: {integrity: sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==} + + console-control-strings@1.1.0: + resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} + + constants-browserify@1.0.0: + resolution: {integrity: sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + conventional-changelog-angular@7.0.0: + resolution: {integrity: sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==} + engines: {node: '>=16'} + + conventional-changelog-core@5.0.1: + resolution: {integrity: sha512-Rvi5pH+LvgsqGwZPZ3Cq/tz4ty7mjijhr3qR4m9IBXNbxGGYgTVVO+duXzz9aArmHxFtwZ+LRkrNIMDQzgoY4A==} + engines: {node: '>=14'} + + conventional-changelog-preset-loader@3.0.0: + resolution: {integrity: sha512-qy9XbdSLmVnwnvzEisjxdDiLA4OmV3o8db+Zdg4WiFw14fP3B6XNz98X0swPPpkTd/pc1K7+adKgEDM1JCUMiA==} + engines: {node: '>=14'} + + conventional-changelog-writer@6.0.1: + resolution: {integrity: sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ==} + engines: {node: '>=14'} + hasBin: true + + conventional-commits-filter@3.0.0: + resolution: {integrity: sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q==} + engines: {node: '>=14'} + + conventional-commits-parser@4.0.0: + resolution: {integrity: sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg==} + engines: {node: '>=14'} + hasBin: true + + conventional-recommended-bump@7.0.1: + resolution: {integrity: sha512-Ft79FF4SlOFvX4PkwFDRnaNiIVX7YbmqGU0RwccUaiGvgp3S0a8ipR2/Qxk31vclDNM+GSdJOVs2KrsUCjblVA==} + engines: {node: '>=14'} + hasBin: true + + convert-source-map@1.9.0: + resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + + convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + + cookie-es@1.2.3: + resolution: {integrity: sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==} + + cookie-signature@1.0.7: + resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + copy-concurrently@1.0.5: + resolution: {integrity: sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==} + deprecated: This package is no longer supported. + + copy-descriptor@0.1.1: + resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} + engines: {node: '>=0.10.0'} + + copy-to-clipboard@3.3.3: + resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} + + copy-webpack-plugin@11.0.0: + resolution: {integrity: sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==} + engines: {node: '>= 14.15.0'} + peerDependencies: + webpack: ^5.1.0 + + core-js-compat@3.49.0: + resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==} + + core-js-pure@3.49.0: + resolution: {integrity: sha512-XM4RFka59xATyJv/cS3O3Kml72hQXUeGRuuTmMYFxwzc9/7C8OYTaIR/Ji+Yt8DXzsFLNhat15cE/JP15HrCgw==} + + core-js@3.49.0: + resolution: {integrity: sha512-es1U2+YTtzpwkxVLwAFdSpaIMyQaq0PBgm3YD1W3Qpsn1NAmO3KSgZfu+oGSWVu6NvLHoHCV/aYcsE5wiB7ALg==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cosmiconfig@6.0.0: + resolution: {integrity: sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==} + engines: {node: '>=8'} + + cosmiconfig@7.1.0: + resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} + engines: {node: '>=10'} + + cosmiconfig@8.3.6: + resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + engines: {node: '>=14'} + peerDependencies: + typescript: '>=4.9.5' + peerDependenciesMeta: + typescript: + optional: true + + cosmjs-types@0.10.1: + resolution: {integrity: sha512-CENXb4O5GN+VyB68HYXFT2SOhv126Z59631rZC56m8uMWa6/cSlFeai8BwZGT1NMepw0Ecf+U8XSOnBzZUWh9Q==} + + cosmjs-types@0.9.0: + resolution: {integrity: sha512-MN/yUe6mkJwHnCFfsNPeCfXVhyxHYW6c/xDUzrSbBycYzw++XvWDMJArXp2pLdgD6FQ8DW79vkPjeNKVrXaHeQ==} + + cp-file@7.0.0: + resolution: {integrity: sha512-0Cbj7gyvFVApzpK/uhCtQ/9kE9UnYpxMzaq5nQQC/Dh4iaj5fxp7iEFIullrYwzj8nf0qnsI1Qsx34hAeAebvw==} + engines: {node: '>=8'} + + cpy@8.1.2: + resolution: {integrity: sha512-dmC4mUesv0OYH2kNFEidtf/skUwv4zePmGeepjyyJ0qTo5+8KhA1o99oIAwVVLzQMAeDJml74d6wPPKb6EZUTg==} + engines: {node: '>=8'} + + create-ecdh@4.0.4: + resolution: {integrity: sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==} + + create-hash@1.2.0: + resolution: {integrity: sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==} + + create-hmac@1.1.7: + resolution: {integrity: sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==} + + create-jest@29.7.0: + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + + cross-fetch@3.2.0: + resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} + + cross-spawn@6.0.6: + resolution: {integrity: sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw==} + engines: {node: '>=4.8'} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + crossws@0.3.5: + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + + crypto-browserify@3.12.1: + resolution: {integrity: sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ==} + engines: {node: '>= 0.10'} + + crypto-js@4.2.0: + resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} + + css-declaration-sorter@6.4.1: + resolution: {integrity: sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g==} + engines: {node: ^10 || ^12 || >=14} + peerDependencies: + postcss: ^8.0.9 + + css-declaration-sorter@7.4.0: + resolution: {integrity: sha512-LTuzjPoyA2vMGKKcaOqKSp7Ub2eGrNfKiZH4LpezxpNrsICGCSFvsQOI29psISxNZtaXibkC2CXzrQ5enMeGGw==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.0.9 + + css-loader@3.6.0: + resolution: {integrity: sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==} + engines: {node: '>= 8.9.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + + css-loader@5.2.7: + resolution: {integrity: sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg==} + engines: {node: '>= 10.13.0'} + peerDependencies: + webpack: ^4.27.0 || ^5.0.0 + + css-loader@6.11.0: + resolution: {integrity: sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g==} + engines: {node: '>= 12.13.0'} + peerDependencies: + '@rspack/core': 0.x || 1.x + webpack: ^5.0.0 + peerDependenciesMeta: + '@rspack/core': + optional: true + webpack: + optional: true + + css-minimizer-webpack-plugin@3.4.1: + resolution: {integrity: sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==} + engines: {node: '>= 12.13.0'} + peerDependencies: + '@parcel/css': '*' + clean-css: '*' + csso: '*' + esbuild: '*' + webpack: ^5.0.0 + peerDependenciesMeta: + '@parcel/css': + optional: true + clean-css: + optional: true + csso: + optional: true + esbuild: + optional: true + + css-minimizer-webpack-plugin@5.0.1: + resolution: {integrity: sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==} + engines: {node: '>= 14.15.0'} + peerDependencies: + '@parcel/css': '*' + '@swc/css': '*' + clean-css: '*' + csso: '*' + esbuild: '*' + lightningcss: '*' + webpack: ^5.0.0 + peerDependenciesMeta: + '@parcel/css': + optional: true + '@swc/css': + optional: true + clean-css: + optional: true + csso: + optional: true + esbuild: + optional: true + lightningcss: + optional: true + + css-select@4.3.0: + resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} + + css-select@5.2.2: + resolution: {integrity: sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==} + + css-tree@1.1.3: + resolution: {integrity: sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==} + engines: {node: '>=8.0.0'} + + css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + css-tree@2.3.1: + resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-tree@3.2.1: + resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-vendor@2.0.8: + resolution: {integrity: sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==} + + css-what@6.2.2: + resolution: {integrity: sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==} + engines: {node: '>= 6'} + + css.escape@1.5.1: + resolution: {integrity: sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg==} + + cssesc@3.0.0: + resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} + engines: {node: '>=4'} + hasBin: true + + cssnano-preset-default@5.2.14: + resolution: {integrity: sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + cssnano-preset-default@6.1.2: + resolution: {integrity: sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + cssnano-utils@3.1.0: + resolution: {integrity: sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + cssnano-utils@4.0.2: + resolution: {integrity: sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + cssnano@5.1.15: + resolution: {integrity: sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + cssnano@6.1.2: + resolution: {integrity: sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + csso@4.2.0: + resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==} + engines: {node: '>=8.0.0'} + + csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + cssom@0.3.8: + resolution: {integrity: sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==} + + cssom@0.4.4: + resolution: {integrity: sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==} + + cssstyle@2.3.0: + resolution: {integrity: sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==} + engines: {node: '>=8'} + + cssstyle@6.2.0: + resolution: {integrity: sha512-Fm5NvhYathRnXNVndkUsCCuR63DCLVVwGOOwQw782coXFi5HhkXdu289l59HlXZBawsyNccXfWRYvLzcDCdDig==} + engines: {node: '>=20'} + + csstype@3.2.3: + resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} + + currently-unhandled@0.4.1: + resolution: {integrity: sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==} + engines: {node: '>=0.10.0'} + + cyclist@1.0.2: + resolution: {integrity: sha512-0sVXIohTfLqVIW3kb/0n6IiWF3Ifj5nm2XaSrLq2DI6fKIGa2fYAZdk917rUneaeLVpYfFcyXE2ft0fe3remsA==} + + d3-array@2.12.1: + resolution: {integrity: sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ==} + + d3-array@3.2.4: + resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==} + engines: {node: '>=12'} + + d3-color@3.1.0: + resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==} + engines: {node: '>=12'} + + d3-delaunay@6.0.4: + resolution: {integrity: sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==} + engines: {node: '>=12'} + + d3-ease@3.0.1: + resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==} + engines: {node: '>=12'} + + d3-format@1.4.5: + resolution: {integrity: sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ==} + + d3-interpolate@3.0.1: + resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==} + engines: {node: '>=12'} + + d3-path@3.1.0: + resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==} + engines: {node: '>=12'} + + d3-scale-chromatic@3.1.0: + resolution: {integrity: sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==} + engines: {node: '>=12'} + + d3-scale@4.0.2: + resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==} + engines: {node: '>=12'} + + d3-shape@3.2.0: + resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==} + engines: {node: '>=12'} + + d3-time-format@3.0.0: + resolution: {integrity: sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag==} + + d3-time@1.1.0: + resolution: {integrity: sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA==} + + d3-time@2.1.1: + resolution: {integrity: sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ==} + + d3-time@3.1.0: + resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==} + engines: {node: '>=12'} + + d3-timer@3.0.1: + resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} + engines: {node: '>=12'} + + damerau-levenshtein@1.0.8: + resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} + + dargs@7.0.0: + resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} + engines: {node: '>=8'} + + data-urls@2.0.0: + resolution: {integrity: sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==} + engines: {node: '>=10'} + + data-urls@7.0.0: + resolution: {integrity: sha512-23XHcCF+coGYevirZceTVD7NdJOqVn+49IHyxgszm+JIiHLoB2TkmPtsYkNWT1pvRSGkc35L6NHs0yHkN2SumA==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + data-view-buffer@1.0.2: + resolution: {integrity: sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ==} + engines: {node: '>= 0.4'} + + data-view-byte-length@1.0.2: + resolution: {integrity: sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ==} + engines: {node: '>= 0.4'} + + data-view-byte-offset@1.0.1: + resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} + engines: {node: '>= 0.4'} + + date-fns@2.30.0: + resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} + engines: {node: '>=0.11'} + + date-fns@4.1.0: + resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} + + dateformat@3.0.3: + resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@3.2.7: + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + decamelize-keys@1.1.1: + resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} + engines: {node: '>=0.10.0'} + + decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + + decimal.js-light@2.5.1: + resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} + + decimal.js@10.6.0: + resolution: {integrity: sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==} + + decode-named-character-reference@1.3.0: + resolution: {integrity: sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==} + + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + + dedent@0.7.0: + resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} + + dedent@1.7.2: + resolution: {integrity: sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==} + peerDependencies: + babel-plugin-macros: ^3.1.0 + peerDependenciesMeta: + babel-plugin-macros: + optional: true + + deep-equal@2.2.3: + resolution: {integrity: sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA==} + engines: {node: '>= 0.4'} + + deep-is@0.1.4: + resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} + + deep-object-diff@1.1.9: + resolution: {integrity: sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==} + + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + default-browser-id@1.0.4: + resolution: {integrity: sha512-qPy925qewwul9Hifs+3sx1ZYn14obHxpkX+mPD369w4Rzg+YkJBgi3SOvwUq81nWSjqGUegIgEPwD8u+HUnxlw==} + engines: {node: '>=0.10.0'} + hasBin: true + + default-gateway@6.0.3: + resolution: {integrity: sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==} + engines: {node: '>= 10'} + + defaults@1.0.4: + resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} + + define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + + define-lazy-prop@2.0.0: + resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} + engines: {node: '>=8'} + + define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} + engines: {node: '>= 0.4'} + + define-property@0.2.5: + resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==} + engines: {node: '>=0.10.0'} + + define-property@1.0.0: + resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} + engines: {node: '>=0.10.0'} + + define-property@2.0.2: + resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} + engines: {node: '>=0.10.0'} + + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + + del@4.1.1: + resolution: {integrity: sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==} + engines: {node: '>=6'} + + delaunator@5.1.0: + resolution: {integrity: sha512-AGrQ4QSgssa1NGmWmLPqN5NY2KajF5MqxetNEO+o0n3ZwZZeTmt7bBnvzHWrmkZFxGgr4HdyFgelzgi06otLuQ==} + + delay@4.4.1: + resolution: {integrity: sha512-aL3AhqtfhOlT/3ai6sWXeqwnw63ATNpnUiN4HL7x9q+My5QtHlO3OIkasmug9LKzpheLdmUKGRKnYXYAS7FQkQ==} + engines: {node: '>=6'} + + delayed-stream@1.0.0: + resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} + engines: {node: '>=0.4.0'} + + delegates@1.0.0: + resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} + + depd@1.1.2: + resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} + engines: {node: '>= 0.6'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + deprecation@2.3.1: + resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + des.js@1.1.0: + resolution: {integrity: sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg==} + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + detab@2.0.4: + resolution: {integrity: sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g==} + + detect-indent@5.0.0: + resolution: {integrity: sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==} + engines: {node: '>=4'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + detect-newline@3.1.0: + resolution: {integrity: sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==} + engines: {node: '>=8'} + + detect-node@2.1.0: + resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} + + detect-package-manager@2.0.1: + resolution: {integrity: sha512-j/lJHyoLlWi6G1LDdLgvUtz60Zo5GEj+sVYtTVXnYLDPuzgC3llMxonXym9zIwhhUII8vjdw0LXxavpLqTbl1A==} + engines: {node: '>=12'} + + detect-port@1.6.1: + resolution: {integrity: sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==} + engines: {node: '>= 4.0.0'} + hasBin: true + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + diff-sequences@27.5.1: + resolution: {integrity: sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + diffie-hellman@5.0.3: + resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==} + + dir-glob@2.2.2: + resolution: {integrity: sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==} + engines: {node: '>=4'} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + dns-packet@5.6.1: + resolution: {integrity: sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==} + engines: {node: '>=6'} + + doctrine@2.1.0: + resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} + engines: {node: '>=0.10.0'} + + doctrine@3.0.0: + resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} + engines: {node: '>=6.0.0'} + + dom-accessibility-api@0.5.16: + resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} + + dom-accessibility-api@0.6.3: + resolution: {integrity: sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w==} + + dom-converter@0.2.0: + resolution: {integrity: sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==} + + dom-helpers@5.2.1: + resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + + dom-serializer@1.4.1: + resolution: {integrity: sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag==} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + dom-walk@0.1.2: + resolution: {integrity: sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w==} + + domain-browser@1.2.0: + resolution: {integrity: sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==} + engines: {node: '>=0.4', npm: '>=1.2'} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domexception@2.0.1: + resolution: {integrity: sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==} + engines: {node: '>=8'} + deprecated: Use your platform's native DOMException instead + + domhandler@4.3.1: + resolution: {integrity: sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==} + engines: {node: '>= 4'} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + dompurify@3.4.3: + resolution: {integrity: sha512-VVwJidIJcp1hpg2OMXML3ZVRPYSZiq4aX7qBh83BSIpOaRDqI+qxhXjjIWnpzkOXhmp0L81lnoME1mnCc9H48A==} + + domutils@2.8.0: + resolution: {integrity: sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + + dot-prop@5.3.0: + resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} + engines: {node: '>=8'} + + dotenv-defaults@2.0.2: + resolution: {integrity: sha512-iOIzovWfsUHU91L5i8bJce3NYK5JXeAwH50Jh6+ARUdLiiGlYWfGw6UkzsYqaXZH/hjE/eCd/PlfM/qqyK0AMg==} + + dotenv-expand@10.0.0: + resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==} + engines: {node: '>=12'} + + dotenv-expand@5.1.0: + resolution: {integrity: sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==} + + dotenv-webpack@7.1.1: + resolution: {integrity: sha512-xw/19VqHDkXALtBOJAnnrSU/AZDIQRXczAmJyp0lZv6SH2aBLzUTl96W1MVryJZ7okZ+djZS4Gj4KlZ0xP7deA==} + engines: {node: '>=10'} + peerDependencies: + webpack: ^4 || ^5 + + dotenv-webpack@8.1.1: + resolution: {integrity: sha512-+TY/AJ2k9bU2EML3mxgLmaAvEcqs1Wbv6deCIUSI3eW3Xeo8LBQumYib6puyaSwbjC9JCzg/y5Pwjd/lePX04w==} + engines: {node: '>=10'} + peerDependencies: + webpack: ^4 || ^5 + + dotenv@16.3.2: + resolution: {integrity: sha512-HTlk5nmhkm8F6JcdXvHIzaorzCoziNQT9mGxLPVXW8wJF1TiGSL60ZGB4gHWabHOaMmWmhvk2/lPHfnBiT78AQ==} + engines: {node: '>=12'} + + dotenv@8.6.0: + resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==} + engines: {node: '>=10'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + duplexer@0.1.2: + resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} + + duplexify@3.7.1: + resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==} + + duplexify@4.1.3: + resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} + + eastasianwidth@0.2.0: + resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + ejs@3.1.10: + resolution: {integrity: sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==} + engines: {node: '>=0.10.0'} + hasBin: true + + electron-to-chromium@1.5.354: + resolution: {integrity: sha512-JaBHwWcfIdmSAfWM5l3uwjGd431j8YEMikZ+K/2nXVuBqJKyZ0f+2h4n4JY5AyNiZmnY9qQr2RU3v9DxDmHMNg==} + + elliptic@6.6.1: + resolution: {integrity: sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g==} + + emittery@0.13.1: + resolution: {integrity: sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==} + engines: {node: '>=12'} + + emittery@0.8.1: + resolution: {integrity: sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==} + engines: {node: '>=10'} + + emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + + emoji-regex@9.2.2: + resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + + emojis-list@3.0.0: + resolution: {integrity: sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==} + engines: {node: '>= 4'} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + encoding@0.1.13: + resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} + + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + + endent@2.1.0: + resolution: {integrity: sha512-r8VyPX7XL8U01Xgnb1CjZ3XV+z90cXIJ9JPE/R9SEC9vpw2P6CfsRPJmp20DppC5N7ZAMCmjYkJIa744Iyg96w==} + + enhanced-resolve@4.5.0: + resolution: {integrity: sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg==} + engines: {node: '>=6.9.0'} + + enhanced-resolve@5.21.3: + resolution: {integrity: sha512-QyL119InA+XXEkNLNTPCXPugSvOfhwv0JOlGNzvxs0hZaiHLNvXSpudUWsOlsXGWJh8G6ckCScEkVHfX3kw/2Q==} + engines: {node: '>=10.13.0'} + + enquirer@2.3.6: + resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} + engines: {node: '>=8.6'} + + entities@2.2.0: + resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + + entities@8.0.0: + resolution: {integrity: sha512-zwfzJecQ/Uej6tusMqwAqU/6KL2XaB2VZ2Jg54Je6ahNBGNH6Ek6g3jjNCF0fG9EWQKGZNddNjU5F1ZQn/sBnA==} + engines: {node: '>=20.19.0'} + + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + + envinfo@7.21.0: + resolution: {integrity: sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==} + engines: {node: '>=4'} + hasBin: true + + envinfo@7.8.1: + resolution: {integrity: sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==} + engines: {node: '>=4'} + hasBin: true + + err-code@2.0.3: + resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} + + errno@0.1.8: + resolution: {integrity: sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==} + hasBin: true + + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + + error-stack-parser@2.1.4: + resolution: {integrity: sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ==} + + es-abstract@1.24.2: + resolution: {integrity: sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==} + engines: {node: '>= 0.4'} + + es-array-method-boxes-properly@1.0.0: + resolution: {integrity: sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==} + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-get-iterator@1.1.3: + resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} + + es-iterator-helpers@1.3.2: + resolution: {integrity: sha512-HVLACW1TppGYjJ8H6/jqH/pqOtKRw6wMlrB23xfExmFWxFquAIWCmwoLsOyN96K4a5KbmOf5At9ZUO3GZbetAw==} + engines: {node: '>= 0.4'} + + es-module-lexer@2.1.0: + resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} + + es-object-atoms@1.1.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + es-set-tostringtag@2.1.0: + resolution: {integrity: sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==} + engines: {node: '>= 0.4'} + + es-shim-unscopables@1.1.0: + resolution: {integrity: sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw==} + engines: {node: '>= 0.4'} + + es-to-primitive@1.3.0: + resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} + engines: {node: '>= 0.4'} + + es5-shim@4.6.7: + resolution: {integrity: sha512-jg21/dmlrNQI7JyyA2w7n+yifSxBng0ZralnSfVZjoCawgNTCnS+yBCyVM9DL5itm7SUnDGgv7hcq2XCZX4iRQ==} + engines: {node: '>=0.4.0'} + + es6-shim@0.35.8: + resolution: {integrity: sha512-Twf7I2v4/1tLoIXMT8HlqaBSS5H2wQTs2wx3MNYCI8K1R1/clXyCazrcVCPm/FuO9cyV8+leEaZOWD5C253NDg==} + + esbuild-register@3.6.0: + resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==} + peerDependencies: + esbuild: '>=0.12 <1' + + esbuild@0.25.12: + resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} + engines: {node: '>=18'} + hasBin: true + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + escape-string-regexp@1.0.5: + resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} + engines: {node: '>=0.8.0'} + + escape-string-regexp@2.0.0: + resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} + engines: {node: '>=8'} + + escape-string-regexp@4.0.0: + resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} + engines: {node: '>=10'} + + escodegen@2.1.0: + resolution: {integrity: sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==} + engines: {node: '>=6.0'} + hasBin: true + + eslint-config-airbnb-base@15.0.0: + resolution: {integrity: sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==} + engines: {node: ^10.12.0 || >=12.0.0} + peerDependencies: + eslint: ^7.32.0 || ^8.2.0 + eslint-plugin-import: ^2.25.2 + + eslint-config-airbnb-typescript@16.2.0: + resolution: {integrity: sha512-OUaMPZpTOZGKd5tXOjJ9PRU4iYNW/Z5DoHIynjsVK/FpkWdiY5+nxQW6TiJAlLwVI1l53xUOrnlZWtVBVQzuWA==} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^5.0.0 + '@typescript-eslint/parser': ^5.0.0 + eslint: ^7.32.0 || ^8.2.0 + eslint-plugin-import: ^2.25.3 + + eslint-config-airbnb@19.0.4: + resolution: {integrity: sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==} + engines: {node: ^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + eslint: ^7.32.0 || ^8.2.0 + eslint-plugin-import: ^2.25.3 + eslint-plugin-jsx-a11y: ^6.5.1 + eslint-plugin-react: ^7.28.0 + eslint-plugin-react-hooks: ^4.3.0 + + eslint-config-next@15.0.3: + resolution: {integrity: sha512-IGP2DdQQrgjcr4mwFPve4DrCqo7CVVez1WoYY47XwKSrYO4hC0Dlb+iJA60i0YfICOzgNADIb8r28BpQ5Zs0wg==} + peerDependencies: + eslint: ^7.23.0 || ^8.0.0 || ^9.0.0 + typescript: '>=3.3.1' + peerDependenciesMeta: + typescript: + optional: true + + eslint-config-prettier@8.10.2: + resolution: {integrity: sha512-/IGJ6+Dka158JnP5n5YFMOszjDWrXggGz1LaK/guZq9vZTmniaKlHcsscvkAhn9y4U+BU3JuUdYvtAMcv30y4A==} + hasBin: true + peerDependencies: + eslint: '>=7.0.0' + + eslint-import-resolver-node@0.3.10: + resolution: {integrity: sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==} + + eslint-import-resolver-root-import@1.0.4: + resolution: {integrity: sha512-c8cUQcELRBe0mnblBZJKEfL+jIUGR8pctK5gdru5N7bBOIve2WZ0R3KoO5GOksXJ4WzZhtcBS2xPaTJYEe4IdQ==} + peerDependencies: + babel-plugin-root-import: ^5.1.0 + eslint-plugin-import: '>=1.9.2' + + eslint-import-resolver-typescript@3.10.1: + resolution: {integrity: sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==} + engines: {node: ^14.18.0 || >=16.0.0} + peerDependencies: + eslint: '*' + eslint-plugin-import: '*' + eslint-plugin-import-x: '*' + peerDependenciesMeta: + eslint-plugin-import: + optional: true + eslint-plugin-import-x: + optional: true + + eslint-module-utils@2.12.1: + resolution: {integrity: sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: '*' + eslint-import-resolver-node: '*' + eslint-import-resolver-typescript: '*' + eslint-import-resolver-webpack: '*' + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + eslint: + optional: true + eslint-import-resolver-node: + optional: true + eslint-import-resolver-typescript: + optional: true + eslint-import-resolver-webpack: + optional: true + + eslint-plugin-import@2.32.0: + resolution: {integrity: sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==} + engines: {node: '>=4'} + peerDependencies: + '@typescript-eslint/parser': '*' + eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9 + peerDependenciesMeta: + '@typescript-eslint/parser': + optional: true + + eslint-plugin-jest@26.9.0: + resolution: {integrity: sha512-TWJxWGp1J628gxh2KhaH1H1paEdgE2J61BBF1I59c6xWeL5+D1BzMxGDN/nXAfX+aSkR5u80K+XhskK6Gwq9ng==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + peerDependencies: + '@typescript-eslint/eslint-plugin': ^5.0.0 + eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + jest: '*' + peerDependenciesMeta: + '@typescript-eslint/eslint-plugin': + optional: true + jest: + optional: true + + eslint-plugin-jsx-a11y@6.10.2: + resolution: {integrity: sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q==} + engines: {node: '>=4.0'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + + eslint-plugin-prettier@4.2.5: + resolution: {integrity: sha512-9Ni+xgemM2IWLq6aXEpP2+V/V30GeA/46Ar629vcMqVPodFFWC9skHu/D1phvuqtS8bJCFnNf01/qcmqYEwNfg==} + engines: {node: '>=12.0.0'} + peerDependencies: + eslint: '>=7.28.0' + eslint-config-prettier: '*' + prettier: '>=2.0.0' + peerDependenciesMeta: + eslint-config-prettier: + optional: true + + eslint-plugin-react-hooks@4.6.2: + resolution: {integrity: sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 + + eslint-plugin-react-hooks@5.2.0: + resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} + engines: {node: '>=10'} + peerDependencies: + eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 + + eslint-plugin-react@7.37.5: + resolution: {integrity: sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==} + engines: {node: '>=4'} + peerDependencies: + eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 + + eslint-plugin-storybook@0.5.13: + resolution: {integrity: sha512-82x3FH1VAi68Awu1VEjn/hLkzFZsOP8ItcC5/uGF9WszIrj6n7Q3MZD57oE26k3aKwuPfFtAPnSjFnaBkBab+g==} + engines: {node: 12.x || 14.x || >= 16} + peerDependencies: + eslint: '>=6' + + eslint-scope@4.0.3: + resolution: {integrity: sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==} + engines: {node: '>=4.0.0'} + + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + + eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-scope@8.4.0: + resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + eslint-visitor-keys@4.2.1: + resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + eslint-visitor-keys@5.0.1: + resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=24} + + eslint@8.57.1: + resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. + hasBin: true + + eslint@9.39.4: + resolution: {integrity: sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + hasBin: true + peerDependencies: + jiti: '*' + peerDependenciesMeta: + jiti: + optional: true + + espree@10.4.0: + resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + + espree@9.6.1: + resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} + engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + + esprima@4.0.1: + resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} + engines: {node: '>=4'} + hasBin: true + + esquery@1.7.0: + resolution: {integrity: sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==} + engines: {node: '>=0.10'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + estree-to-babel@3.2.1: + resolution: {integrity: sha512-YNF+mZ/Wu2FU/gvmzuWtYc8rloubL7wfXCTgouFrnjGVXPA/EeYYA7pupXWrb3Iv1cTBeSSxxJIbK23l4MRNqg==} + engines: {node: '>=8.3.0'} + + estree-util-is-identifier-name@3.0.0: + resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + + esutils@2.0.3: + resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} + engines: {node: '>=0.10.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + evp_bytestokey@1.0.3: + resolution: {integrity: sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==} + + exec-sh@0.3.6: + resolution: {integrity: sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w==} + + execa@1.0.0: + resolution: {integrity: sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==} + engines: {node: '>=6'} + + execa@5.0.0: + resolution: {integrity: sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==} + engines: {node: '>=10'} + + execa@5.1.1: + resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} + engines: {node: '>=10'} + + exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + + expand-brackets@2.1.4: + resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==} + engines: {node: '>=0.10.0'} + + expect@27.5.1: + resolution: {integrity: sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + exponential-backoff@3.1.3: + resolution: {integrity: sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==} + + express@4.22.2: + resolution: {integrity: sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==} + engines: {node: '>= 0.10.0'} + + extend-shallow@2.0.1: + resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} + engines: {node: '>=0.10.0'} + + extend-shallow@3.0.2: + resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} + engines: {node: '>=0.10.0'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + extglob@2.0.4: + resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} + engines: {node: '>=0.10.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-diff@1.3.0: + resolution: {integrity: sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==} + + fast-equals@5.4.0: + resolution: {integrity: sha512-jt2DW/aNFNwke7AUd+Z+e6pz39KO5rzdbbFCg2sGafS4mk13MI7Z8O5z9cADNn5lhGODIgLwug6TZO2ctf7kcw==} + engines: {node: '>=6.0.0'} + + fast-glob@2.2.7: + resolution: {integrity: sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==} + engines: {node: '>=4.0.0'} + + fast-glob@3.3.1: + resolution: {integrity: sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg==} + engines: {node: '>=8.6.0'} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-json-parse@1.0.3: + resolution: {integrity: sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw==} + + fast-json-stable-stringify@2.1.0: + resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + + fast-levenshtein@2.0.6: + resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + + fast-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + engines: {node: '>=6'} + + fast-uri@3.1.2: + resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==} + + fastest-levenshtein@1.0.16: + resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} + engines: {node: '>= 4.9.1'} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + favicons-webpack-plugin@5.0.2: + resolution: {integrity: sha512-D/A+Ze0x57+YZBU69hK/lR3NI636qQnKduWyQm0THGl1y3jt16whPHHsi8yjsuXvetv84Eh/I/yYJbAMC2iQxg==} + engines: {node: '>=10.13.0'} + peerDependencies: + favicons: '>= 6.2.0' + webpack: ^5.0.0 + + favicons@7.2.0: + resolution: {integrity: sha512-k/2rVBRIRzOeom3wI9jBPaSEvoTSQEW4iM0EveBmBBKFxO8mSyyRWtDlfC3VnEfu0avmjrMzy8/ZFPSe6F71Hw==} + engines: {node: '>=14.0.0'} + + faye-websocket@0.11.4: + resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==} + engines: {node: '>=0.8.0'} + + fb-watchman@2.0.2: + resolution: {integrity: sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==} + + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + + fetch-retry@5.0.6: + resolution: {integrity: sha512-3yurQZ2hD9VISAhJJP9bpYFNQrHHBXE2JxxjY5aLEcDi46RmAzJE2OC9FAde0yis5ElW0jTTzs0zfg/Cca4XqQ==} + + figgy-pudding@3.5.2: + resolution: {integrity: sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==} + deprecated: This module is no longer supported. + + figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + + file-entry-cache@6.0.1: + resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} + engines: {node: ^10.12.0 || >=12.0.0} + + file-entry-cache@8.0.0: + resolution: {integrity: sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==} + engines: {node: '>=16.0.0'} + + file-loader@6.2.0: + resolution: {integrity: sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==} + engines: {node: '>= 10.13.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + + file-system-cache@1.1.0: + resolution: {integrity: sha512-IzF5MBq+5CR0jXx5RxPe4BICl/oEhBSXKaL9fLhAXrIfIUS77Hr4vzrYyqYMHN6uTt+BOqi3fDCTjjEBCjERKw==} + + file-uri-to-path@1.0.0: + resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} + + filelist@1.0.6: + resolution: {integrity: sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==} + + fill-range@4.0.0: + resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==} + engines: {node: '>=0.10.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + finalhandler@1.3.2: + resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} + engines: {node: '>= 0.8'} + + find-cache-dir@2.1.0: + resolution: {integrity: sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==} + engines: {node: '>=6'} + + find-cache-dir@3.3.2: + resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} + engines: {node: '>=8'} + + find-cache-dir@4.0.0: + resolution: {integrity: sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==} + engines: {node: '>=14.16'} + + find-root@1.1.0: + resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} + + find-up@1.1.2: + resolution: {integrity: sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==} + engines: {node: '>=0.10.0'} + + find-up@2.1.0: + resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} + engines: {node: '>=4'} + + find-up@3.0.0: + resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} + engines: {node: '>=6'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + find-up@5.0.0: + resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} + engines: {node: '>=10'} + + find-up@6.3.0: + resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + flat-cache@3.2.0: + resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} + engines: {node: ^10.12.0 || >=12.0.0} + + flat-cache@4.0.1: + resolution: {integrity: sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==} + engines: {node: '>=16'} + + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + + flatted@3.4.2: + resolution: {integrity: sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==} + + flush-write-stream@1.1.1: + resolution: {integrity: sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==} + + focus-lock@0.8.1: + resolution: {integrity: sha512-/LFZOIo82WDsyyv7h7oc0MJF9ACOvDRdx9rWPZ2pgMfNWu/z8hQDBtOchuB/0BVLmuFOZjV02YwUVzNsWx/EzA==} + engines: {node: '>=10'} + + follow-redirects@1.16.0: + resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + for-each@0.3.5: + resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} + engines: {node: '>= 0.4'} + + for-in@1.0.2: + resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} + engines: {node: '>=0.10.0'} + + foreground-child@2.0.0: + resolution: {integrity: sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==} + engines: {node: '>=8.0.0'} + + foreground-child@3.3.1: + resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} + engines: {node: '>=14'} + + fork-ts-checker-webpack-plugin@4.1.6: + resolution: {integrity: sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw==} + engines: {node: '>=6.11.5', yarn: '>=1.0.0'} + peerDependencies: + eslint: '>= 6' + typescript: '>= 2.7' + vue-template-compiler: '*' + webpack: '>= 4' + peerDependenciesMeta: + eslint: + optional: true + vue-template-compiler: + optional: true + + fork-ts-checker-webpack-plugin@6.5.3: + resolution: {integrity: sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ==} + engines: {node: '>=10', yarn: '>=1.0.0'} + peerDependencies: + eslint: '>= 6' + typescript: '>= 2.7' + vue-template-compiler: '*' + webpack: '>= 4' + peerDependenciesMeta: + eslint: + optional: true + vue-template-compiler: + optional: true + + fork-ts-checker-webpack-plugin@7.3.0: + resolution: {integrity: sha512-IN+XTzusCjR5VgntYFgxbxVx3WraPRnKehBFrf00cMSrtUuW9MsG9dhL6MWpY6MkjC3wVwoujfCDgZZCQwbswA==} + engines: {node: '>=12.13.0', yarn: '>=1.0.0'} + peerDependencies: + typescript: '>3.6.0' + vue-template-compiler: '*' + webpack: ^5.11.0 + peerDependenciesMeta: + vue-template-compiler: + optional: true + + fork-ts-checker-webpack-plugin@8.0.0: + resolution: {integrity: sha512-mX3qW3idpueT2klaQXBzrIM/pHw+T0B/V9KHEvNrqijTq9NFnMZU6oreVxDYcf33P8a5cW+67PjodNHthGnNVg==} + engines: {node: '>=12.13.0', yarn: '>=1.0.0'} + peerDependencies: + typescript: '>3.6.0' + webpack: ^5.11.0 + + form-data@3.0.4: + resolution: {integrity: sha512-f0cRzm6dkyVYV3nPoooP8XlccPQukegwhAnpoLcXy+X+A8KfpGOoXwDr9FLZd3wzgLaBGQBE3lY93Zm/i1JvIQ==} + engines: {node: '>= 6'} + + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} + engines: {node: '>= 6'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fragment-cache@0.2.1: + resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} + engines: {node: '>=0.10.0'} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + from2@2.3.0: + resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} + + fs-constants@1.0.0: + resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} + + fs-extra@10.1.0: + resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==} + engines: {node: '>=12'} + + fs-extra@11.3.5: + resolution: {integrity: sha512-eKpRKAovdpZtR1WopLHxlBWvAgPny3c4gX1G5Jhwmmw4XJj0ifSD5qB5TOo8hmA0wlRKDAOAhEE1yVPgs6Fgcg==} + engines: {node: '>=14.14'} + + fs-extra@9.1.0: + resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} + engines: {node: '>=10'} + + fs-minipass@2.1.0: + resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} + engines: {node: '>= 8'} + + fs-minipass@3.0.3: + resolution: {integrity: sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + fs-monkey@1.1.0: + resolution: {integrity: sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw==} + + fs-write-stream-atomic@1.0.10: + resolution: {integrity: sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA==} + deprecated: This package is no longer supported. + + fs.realpath@1.0.0: + resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + + fsevents@1.2.13: + resolution: {integrity: sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==} + engines: {node: '>= 4.0'} + os: [darwin] + deprecated: Upgrade to fsevents v2 to mitigate potential security issues + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + function.prototype.name@1.1.8: + resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} + engines: {node: '>= 0.4'} + + functions-have-names@1.2.3: + resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + + gauge@3.0.2: + resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} + engines: {node: '>=10'} + deprecated: This package is no longer supported. + + gauge@4.0.4: + resolution: {integrity: sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. + + generator-function@2.0.1: + resolution: {integrity: sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==} + engines: {node: '>= 0.4'} + + gensync@1.0.0-beta.2: + resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} + engines: {node: '>=6.9.0'} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + + get-pkg-repo@4.2.1: + resolution: {integrity: sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==} + engines: {node: '>=6.9.0'} + hasBin: true + + get-port@5.1.1: + resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} + engines: {node: '>=8'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-stdin@4.0.1: + resolution: {integrity: sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==} + engines: {node: '>=0.10.0'} + + get-stream@4.1.0: + resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} + engines: {node: '>=6'} + + get-stream@6.0.0: + resolution: {integrity: sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==} + engines: {node: '>=10'} + + get-stream@6.0.1: + resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} + engines: {node: '>=10'} + + get-symbol-description@1.1.0: + resolution: {integrity: sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg==} + engines: {node: '>= 0.4'} + + get-tsconfig@4.14.0: + resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} + + get-value@2.0.6: + resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} + engines: {node: '>=0.10.0'} + + git-raw-commits@3.0.0: + resolution: {integrity: sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw==} + engines: {node: '>=14'} + deprecated: This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead. + hasBin: true + + git-remote-origin-url@2.0.0: + resolution: {integrity: sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==} + engines: {node: '>=4'} + + git-semver-tags@5.0.1: + resolution: {integrity: sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA==} + engines: {node: '>=14'} + deprecated: This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead. + hasBin: true + + git-up@7.0.0: + resolution: {integrity: sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ==} + + git-url-parse@13.1.0: + resolution: {integrity: sha512-5FvPJP/70WkIprlUZ33bm4UAaFdjcLkJLpWft1BeZKqwR0uhhNGoKwlUaPtVb4LxCSQ++erHapRak9kWGj+FCA==} + + gitconfiglocal@1.0.0: + resolution: {integrity: sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==} + + github-slugger@1.5.0: + resolution: {integrity: sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==} + + glob-parent@3.1.0: + resolution: {integrity: sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob-promise@3.4.0: + resolution: {integrity: sha512-q08RJ6O+eJn+dVanerAndJwIcumgbDdYiUT7zFQl3Wm1xD6fBKtah7H8ZJChj4wP+8C+QfeVy8xautR7rdmKEw==} + engines: {node: '>=4'} + peerDependencies: + glob: '*' + + glob-to-regexp@0.3.0: + resolution: {integrity: sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==} + + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + + glob@10.5.0: + resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + hasBin: true + + glob@7.1.4: + resolution: {integrity: sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + glob@7.2.3: + resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + glob@8.1.0: + resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==} + engines: {node: '>=12'} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + glob@9.3.5: + resolution: {integrity: sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==} + engines: {node: '>=16 || 14 >=14.17'} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + global@4.4.0: + resolution: {integrity: sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==} + + globals@13.24.0: + resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} + engines: {node: '>=8'} + + globals@14.0.0: + resolution: {integrity: sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==} + engines: {node: '>=18'} + + globalthis@1.0.4: + resolution: {integrity: sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==} + engines: {node: '>= 0.4'} + + globby@11.1.0: + resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} + engines: {node: '>=10'} + + globby@13.2.2: + resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + globby@6.1.0: + resolution: {integrity: sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==} + engines: {node: '>=0.10.0'} + + globby@9.2.0: + resolution: {integrity: sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==} + engines: {node: '>=6'} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + graphemer@1.4.0: + resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} + + h3@1.15.11: + resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==} + + handle-thing@2.0.1: + resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==} + + handlebars@4.7.9: + resolution: {integrity: sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==} + engines: {node: '>=0.4.7'} + hasBin: true + + hard-rejection@2.1.0: + resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} + engines: {node: '>=6'} + + has-bigints@1.1.0: + resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} + engines: {node: '>= 0.4'} + + has-flag@3.0.0: + resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} + engines: {node: '>=4'} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-glob@1.0.0: + resolution: {integrity: sha512-D+8A457fBShSEI3tFCj65PAbT++5sKiFtdCdOam0gnfBgw9D277OERk+HM9qYJXmdVLZ/znez10SqHN0BBQ50g==} + engines: {node: '>=0.10.0'} + + has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + + has-proto@1.2.0: + resolution: {integrity: sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ==} + engines: {node: '>= 0.4'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + + has-unicode@2.0.1: + resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} + + has-value@0.3.1: + resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==} + engines: {node: '>=0.10.0'} + + has-value@1.0.0: + resolution: {integrity: sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==} + engines: {node: '>=0.10.0'} + + has-values@0.1.4: + resolution: {integrity: sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==} + engines: {node: '>=0.10.0'} + + has-values@1.0.0: + resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} + engines: {node: '>=0.10.0'} + + hash-base@3.0.5: + resolution: {integrity: sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg==} + engines: {node: '>= 0.10'} + + hash-base@3.1.2: + resolution: {integrity: sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg==} + engines: {node: '>= 0.8'} + + hash-wasm@4.12.0: + resolution: {integrity: sha512-+/2B2rYLb48I/evdOIhP+K/DD2ca2fgBjp6O+GBEnCDk2e4rpeXIK8GvIyRPjTezgmWn9gmKwkQjjx6BtqDHVQ==} + + hash.js@1.1.7: + resolution: {integrity: sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==} + + hasown@2.0.3: + resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} + engines: {node: '>= 0.4'} + + hast-to-hyperscript@9.0.1: + resolution: {integrity: sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA==} + + hast-util-from-parse5@6.0.1: + resolution: {integrity: sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA==} + + hast-util-parse-selector@2.2.5: + resolution: {integrity: sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==} + + hast-util-raw@6.0.1: + resolution: {integrity: sha512-ZMuiYA+UF7BXBtsTBNcLBF5HzXzkyE6MLzJnL605LKE8GJylNjGc4jjxazAHUtcwT5/CEt6afRKViYB4X66dig==} + + hast-util-to-jsx-runtime@2.3.6: + resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==} + + hast-util-to-parse5@6.0.0: + resolution: {integrity: sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + + hastscript@6.0.0: + resolution: {integrity: sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==} + + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + hex-rgb@4.3.0: + resolution: {integrity: sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw==} + engines: {node: '>=6'} + + highlight-words@2.0.0: + resolution: {integrity: sha512-If5n+IhSBRXTScE7wl16VPmd+44Vy7kof24EdqhjsZsDuHikpv1OCagVcJFpB4fS4UPUniedlWqrjIO8vWOsIQ==} + engines: {node: '>= 20', npm: '>= 9'} + + hmac-drbg@1.0.1: + resolution: {integrity: sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==} + + hoist-non-react-statics@3.3.2: + resolution: {integrity: sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==} + + hosted-git-info@2.8.9: + resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} + + hosted-git-info@3.0.8: + resolution: {integrity: sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==} + engines: {node: '>=10'} + + hosted-git-info@4.1.0: + resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} + engines: {node: '>=10'} + + hosted-git-info@6.1.3: + resolution: {integrity: sha512-HVJyzUrLIL1c0QmviVh5E8VGyUS7xCFPS6yydaVd1UegW+ibV/CohqTH9MkOLDp5o+rb82DMo77PTuc9F/8GKw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + hpack.js@2.1.6: + resolution: {integrity: sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==} + + html-encoding-sniffer@2.0.1: + resolution: {integrity: sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==} + engines: {node: '>=10'} + + html-encoding-sniffer@6.0.0: + resolution: {integrity: sha512-CV9TW3Y3f8/wT0BRFc1/KAVQ3TUHiXmaAb6VW9vtiMFf7SLoMd1PdAc4W3KFOFETBJUb90KatHqlsZMWV+R9Gg==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + html-entities@2.6.0: + resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==} + + html-escaper@2.0.2: + resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} + + html-minifier-terser@5.1.1: + resolution: {integrity: sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg==} + engines: {node: '>=6'} + hasBin: true + + html-minifier-terser@6.1.0: + resolution: {integrity: sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==} + engines: {node: '>=12'} + hasBin: true + + html-parse-stringify@3.0.1: + resolution: {integrity: sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==} + + html-tags@3.3.1: + resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==} + engines: {node: '>=8'} + + html-url-attributes@3.0.1: + resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==} + + html-void-elements@1.0.5: + resolution: {integrity: sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==} + + html-webpack-plugin@4.5.2: + resolution: {integrity: sha512-q5oYdzjKUIPQVjOosjgvCHQOv9Ett9CYYHlgvJeXG0qQvdSojnBq4vAdQBwn1+yGveAwHCoe/rMR86ozX3+c2A==} + engines: {node: '>=6.9'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + + html-webpack-plugin@5.6.7: + resolution: {integrity: sha512-md+vXtdCAe60s1k6AU3dUyMJnDxUyQAwfwPKoLisvgUF1IXjtlLsk2se54+qfL9Mdm26bbwvjJybpNx48NKRLw==} + engines: {node: '>=10.13.0'} + peerDependencies: + '@rspack/core': 0.x || 1.x + webpack: ^5.20.0 + peerDependenciesMeta: + '@rspack/core': + optional: true + webpack: + optional: true + + htmlparser2@6.1.0: + resolution: {integrity: sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==} + + http-cache-semantics@4.2.0: + resolution: {integrity: sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==} + + http-deceiver@1.2.7: + resolution: {integrity: sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==} + + http-errors@1.8.1: + resolution: {integrity: sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==} + engines: {node: '>= 0.6'} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + http-parser-js@0.5.10: + resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==} + + http-proxy-agent@4.0.1: + resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==} + engines: {node: '>= 6'} + + http-proxy-agent@5.0.0: + resolution: {integrity: sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==} + engines: {node: '>= 6'} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + http-proxy-middleware@2.0.9: + resolution: {integrity: sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/express': ^4.17.13 + peerDependenciesMeta: + '@types/express': + optional: true + + http-proxy@1.18.1: + resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} + engines: {node: '>=8.0.0'} + + https-browserify@1.0.0: + resolution: {integrity: sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==} + + https-proxy-agent@5.0.1: + resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} + engines: {node: '>= 6'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + human-signals@2.1.0: + resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} + engines: {node: '>=10.17.0'} + + humanize-ms@1.2.1: + resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} + + hyphenate-style-name@1.1.0: + resolution: {integrity: sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw==} + + i18next-resources-to-backend@1.2.1: + resolution: {integrity: sha512-okHbVA+HZ7n1/76MsfhPqDou0fptl2dAlhRDu2ideXloRRduzHsqDOznJBef+R3DFZnbvWoBW+KxJ7fnFjd6Yw==} + + i18next@24.2.3: + resolution: {integrity: sha512-lfbf80OzkocvX7nmZtu7nSTNbrTYR52sLWxPtlXX1zAhVw8WEnFk4puUkCR4B1dNQwbSpEHHHemcZu//7EcB7A==} + peerDependencies: + typescript: ^5 + peerDependenciesMeta: + typescript: + optional: true + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.6.3: + resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} + engines: {node: '>=0.10.0'} + + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + engines: {node: '>=0.10.0'} + + icss-utils@4.1.1: + resolution: {integrity: sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA==} + engines: {node: '>= 6'} + + icss-utils@5.1.0: + resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + idb-keyval@6.2.2: + resolution: {integrity: sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==} + + ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + + iferr@0.1.5: + resolution: {integrity: sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==} + + ignore-walk@5.0.1: + resolution: {integrity: sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + ignore-walk@6.0.5: + resolution: {integrity: sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + ignore@4.0.6: + resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} + engines: {node: '>= 4'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + immediate@3.0.6: + resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==} + + immer@10.2.0: + resolution: {integrity: sha512-d/+XTN3zfODyjr89gM3mPq1WNX2B8pYsu7eORitdwyA2sBubnTl3laYlBk4sXY5FUa5qTZGBDPJICVbvqzjlbw==} + + import-fresh@3.3.1: + resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} + engines: {node: '>=6'} + + import-local@3.1.0: + resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} + engines: {node: '>=8'} + hasBin: true + + import-local@3.2.0: + resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} + engines: {node: '>=8'} + hasBin: true + + imurmurhash@0.1.4: + resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} + engines: {node: '>=0.8.19'} + + indent-string@2.1.0: + resolution: {integrity: sha512-aqwDFWSgSgfRaEwao5lg5KEcVd/2a+D1rvoG7NdilmYz0NwRk6StWpWdz/Hpk34MKPpx7s8XxUqimfcQK6gGlg==} + engines: {node: '>=0.10.0'} + + indent-string@4.0.0: + resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} + engines: {node: '>=8'} + + infer-owner@1.0.4: + resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==} + + inflight@1.0.6: + resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} + deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful. + + inherits@2.0.3: + resolution: {integrity: sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==} + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + + init-package-json@5.0.0: + resolution: {integrity: sha512-kBhlSheBfYmq3e0L1ii+VKe3zBTLL5lDCDWR+f9dLmEGSB3MqLlMlsolubSsyI88Bg6EA+BIMlomAnQ1SwgQBw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + inline-style-parser@0.1.1: + resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==} + + inline-style-parser@0.2.7: + resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + + inquirer@8.2.7: + resolution: {integrity: sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==} + engines: {node: '>=12.0.0'} + + internal-slot@1.1.0: + resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} + engines: {node: '>= 0.4'} + + internmap@1.0.1: + resolution: {integrity: sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==} + + internmap@2.0.3: + resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} + engines: {node: '>=12'} + + interpret@2.2.0: + resolution: {integrity: sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==} + engines: {node: '>= 0.10'} + + interpret@3.1.1: + resolution: {integrity: sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==} + engines: {node: '>=10.13.0'} + + ip-address@10.2.0: + resolution: {integrity: sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==} + engines: {node: '>= 12'} + + ip@2.0.1: + resolution: {integrity: sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + ipaddr.js@2.4.0: + resolution: {integrity: sha512-9VGk3HGanVE6JoZXHiCpnGy5X0jYDnN4EA4lntFPj+1vIWlFhIylq2CrrCOJH9EAhc5CYhq18F2Av2tgoAPsYQ==} + engines: {node: '>= 10'} + + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + + is-absolute-url@3.0.3: + resolution: {integrity: sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==} + engines: {node: '>=8'} + + is-accessor-descriptor@1.0.2: + resolution: {integrity: sha512-AIbwAcazqP3R65dGvqk1V+a+vE5Fg1yu/ZKMOiBWSUIXXiwQkYmXQcVa2O0nh0tSDKDFKxG2mY7dB1Sr4hEP1g==} + engines: {node: '>= 0.4'} + + is-alphabetical@1.0.4: + resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} + + is-alphabetical@2.0.1: + resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} + + is-alphanumerical@1.0.4: + resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} + + is-alphanumerical@2.0.1: + resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + + is-array-buffer@3.0.5: + resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} + engines: {node: '>= 0.4'} + + is-arrayish@0.2.1: + resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} + + is-arrayish@0.3.4: + resolution: {integrity: sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA==} + + is-async-function@2.1.1: + resolution: {integrity: sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ==} + engines: {node: '>= 0.4'} + + is-bigint@1.1.0: + resolution: {integrity: sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ==} + engines: {node: '>= 0.4'} + + is-binary-path@1.0.1: + resolution: {integrity: sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==} + engines: {node: '>=0.10.0'} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-boolean-object@1.2.2: + resolution: {integrity: sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==} + engines: {node: '>= 0.4'} + + is-buffer@1.1.6: + resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} + + is-buffer@2.0.5: + resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} + engines: {node: '>=4'} + + is-bun-module@2.0.0: + resolution: {integrity: sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ==} + + is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + + is-ci@2.0.0: + resolution: {integrity: sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==} + hasBin: true + + is-ci@3.0.1: + resolution: {integrity: sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==} + hasBin: true + + is-core-module@2.16.2: + resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} + engines: {node: '>= 0.4'} + + is-data-descriptor@1.0.1: + resolution: {integrity: sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw==} + engines: {node: '>= 0.4'} + + is-data-view@1.0.2: + resolution: {integrity: sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw==} + engines: {node: '>= 0.4'} + + is-date-object@1.1.0: + resolution: {integrity: sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg==} + engines: {node: '>= 0.4'} + + is-decimal@1.0.4: + resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} + + is-decimal@2.0.1: + resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} + + is-descriptor@0.1.8: + resolution: {integrity: sha512-SceYGWXvdqlWa/OnQ5FQuV+NxvNmMRhMw/w9AHkH71hTzveND4BTYgvp16g+oITK47qbOl/3D0bl0iygehWAWQ==} + engines: {node: '>= 0.4'} + + is-descriptor@1.0.4: + resolution: {integrity: sha512-bv5z95W0dDtLfKwDfkTNxaRxmISBD3eQBKJeVxv2AQ7MjuUnDNG7cIQqvFtMOUYhsILWHhMayWdoGqNqYYYjww==} + engines: {node: '>= 0.4'} + + is-docker@2.2.1: + resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} + engines: {node: '>=8'} + hasBin: true + + is-dom@1.1.0: + resolution: {integrity: sha512-u82f6mvhYxRPKpw8V1N0W8ce1xXwOrQtgGcxl6UCL5zBmZu3is/18K0rR7uFCnMDuAsS/3W54mGL4vsaFUQlEQ==} + + is-extendable@0.1.1: + resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} + engines: {node: '>=0.10.0'} + + is-extendable@1.0.1: + resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} + engines: {node: '>=0.10.0'} + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-finalizationregistry@1.1.1: + resolution: {integrity: sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg==} + engines: {node: '>= 0.4'} + + is-finite@1.1.0: + resolution: {integrity: sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==} + engines: {node: '>=0.10.0'} + + is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + + is-function@1.0.2: + resolution: {integrity: sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ==} + + is-generator-fn@2.1.0: + resolution: {integrity: sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==} + engines: {node: '>=6'} + + is-generator-function@1.1.2: + resolution: {integrity: sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==} + engines: {node: '>= 0.4'} + + is-glob@3.1.0: + resolution: {integrity: sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-hexadecimal@1.0.4: + resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} + + is-hexadecimal@2.0.1: + resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==} + + is-in-browser@1.1.3: + resolution: {integrity: sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==} + + is-interactive@1.0.0: + resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} + engines: {node: '>=8'} + + is-lambda@1.0.1: + resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} + + is-map@2.0.3: + resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} + engines: {node: '>= 0.4'} + + is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} + engines: {node: '>= 0.4'} + + is-number-object@1.1.1: + resolution: {integrity: sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw==} + engines: {node: '>= 0.4'} + + is-number@3.0.0: + resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} + engines: {node: '>=0.10.0'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-obj@2.0.0: + resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} + engines: {node: '>=8'} + + is-object@1.0.2: + resolution: {integrity: sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA==} + + is-path-cwd@2.2.0: + resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} + engines: {node: '>=6'} + + is-path-in-cwd@2.1.0: + resolution: {integrity: sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==} + engines: {node: '>=6'} + + is-path-inside@2.1.0: + resolution: {integrity: sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==} + engines: {node: '>=6'} + + is-path-inside@3.0.3: + resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} + engines: {node: '>=8'} + + is-plain-obj@1.1.0: + resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} + engines: {node: '>=0.10.0'} + + is-plain-obj@2.1.0: + resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} + engines: {node: '>=8'} + + is-plain-obj@3.0.0: + resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==} + engines: {node: '>=10'} + + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + + is-plain-object@5.0.0: + resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} + engines: {node: '>=0.10.0'} + + is-potential-custom-element-name@1.0.1: + resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + + is-regex@1.2.1: + resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} + engines: {node: '>= 0.4'} + + is-set@2.0.3: + resolution: {integrity: sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg==} + engines: {node: '>= 0.4'} + + is-shared-array-buffer@1.0.4: + resolution: {integrity: sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A==} + engines: {node: '>= 0.4'} + + is-ssh@1.4.1: + resolution: {integrity: sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg==} + + is-stream@1.1.0: + resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} + engines: {node: '>=0.10.0'} + + is-stream@2.0.0: + resolution: {integrity: sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==} + engines: {node: '>=8'} + + is-stream@2.0.1: + resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} + engines: {node: '>=8'} + + is-string@1.1.1: + resolution: {integrity: sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA==} + engines: {node: '>= 0.4'} + + is-symbol@1.1.1: + resolution: {integrity: sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w==} + engines: {node: '>= 0.4'} + + is-text-path@1.0.1: + resolution: {integrity: sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==} + engines: {node: '>=0.10.0'} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + is-typedarray@1.0.0: + resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} + + is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + + is-utf8@0.2.1: + resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==} + + is-weakmap@2.0.2: + resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} + engines: {node: '>= 0.4'} + + is-weakref@1.1.1: + resolution: {integrity: sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==} + engines: {node: '>= 0.4'} + + is-weakset@2.0.4: + resolution: {integrity: sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ==} + engines: {node: '>= 0.4'} + + is-whitespace-character@1.0.4: + resolution: {integrity: sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==} + + is-window@1.0.2: + resolution: {integrity: sha512-uj00kdXyZb9t9RcAUAwMZAnkBUwdYGhYlt7djMXhfyhUCzwNba50tIiBKR7q0l7tdoBtFVw/3JmLY6fI3rmZmg==} + + is-windows@1.0.2: + resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} + engines: {node: '>=0.10.0'} + + is-word-character@1.0.4: + resolution: {integrity: sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==} + + is-wsl@1.1.0: + resolution: {integrity: sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw==} + engines: {node: '>=4'} + + is-wsl@2.2.0: + resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} + engines: {node: '>=8'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isobject@2.1.0: + resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} + engines: {node: '>=0.10.0'} + + isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + + isobject@4.0.0: + resolution: {integrity: sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==} + engines: {node: '>=0.10.0'} + + isomorphic-dompurify@2.36.0: + resolution: {integrity: sha512-E8YkGyPY3a/U5s0WOoc8Ok+3SWL/33yn2IHCoxCFLBUUPVy9WGa++akJZFxQCcJIhI+UvYhbrbnTIFQkHKZbgA==} + engines: {node: '>=20.19.5'} + + isomorphic-unfetch@3.1.0: + resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==} + + isomorphic-ws@4.0.1: + resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} + peerDependencies: + ws: '*' + + istanbul-lib-coverage@3.2.2: + resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + + istanbul-lib-instrument@6.0.3: + resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} + engines: {node: '>=10'} + + istanbul-lib-report@3.0.1: + resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} + engines: {node: '>=10'} + + istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + + istanbul-reports@3.2.0: + resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} + engines: {node: '>=8'} + + iterate-iterator@1.0.2: + resolution: {integrity: sha512-t91HubM4ZDQ70M9wqp+pcNpu8OyJ9UAtXntT/Bcsvp5tZMnz9vRa+IunKXeI8AnfZMTv0jNuVEmGeLSMjVvfPw==} + + iterate-value@1.0.2: + resolution: {integrity: sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ==} + + iterator.prototype@1.1.5: + resolution: {integrity: sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==} + engines: {node: '>= 0.4'} + + jackspeak@3.4.3: + resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + + jake@10.9.4: + resolution: {integrity: sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==} + engines: {node: '>=10'} + hasBin: true + + jest-changed-files@27.5.1: + resolution: {integrity: sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-changed-files@29.7.0: + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-circus@27.5.1: + resolution: {integrity: sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-circus@29.7.0: + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-cli@27.5.1: + resolution: {integrity: sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jest-cli@29.7.0: + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jest-config@27.5.1: + resolution: {integrity: sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + peerDependencies: + ts-node: '>=9.0.0' + peerDependenciesMeta: + ts-node: + optional: true + + jest-config@29.7.0: + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + + jest-diff@27.5.1: + resolution: {integrity: sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-docblock@27.5.1: + resolution: {integrity: sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-docblock@29.7.0: + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-each@27.5.1: + resolution: {integrity: sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-each@29.7.0: + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-environment-jsdom@27.5.1: + resolution: {integrity: sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-environment-node@27.5.1: + resolution: {integrity: sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-get-type@27.5.1: + resolution: {integrity: sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-haste-map@26.6.2: + resolution: {integrity: sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w==} + engines: {node: '>= 10.14.2'} + + jest-haste-map@27.5.1: + resolution: {integrity: sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-haste-map@29.7.0: + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-jasmine2@27.5.1: + resolution: {integrity: sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-leak-detector@27.5.1: + resolution: {integrity: sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-leak-detector@29.7.0: + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-matcher-utils@27.5.1: + resolution: {integrity: sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-message-util@27.5.1: + resolution: {integrity: sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-mock@27.5.1: + resolution: {integrity: sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-pnp-resolver@1.2.3: + resolution: {integrity: sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==} + engines: {node: '>=6'} + peerDependencies: + jest-resolve: '*' + peerDependenciesMeta: + jest-resolve: + optional: true + + jest-regex-util@26.0.0: + resolution: {integrity: sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A==} + engines: {node: '>= 10.14.2'} + + jest-regex-util@27.5.1: + resolution: {integrity: sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve-dependencies@27.5.1: + resolution: {integrity: sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-resolve-dependencies@29.7.0: + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-resolve@27.5.1: + resolution: {integrity: sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-resolve@29.7.0: + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runner@27.5.1: + resolution: {integrity: sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-runner@29.7.0: + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-runtime@27.5.1: + resolution: {integrity: sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-runtime@29.7.0: + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-serializer@26.6.2: + resolution: {integrity: sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g==} + engines: {node: '>= 10.14.2'} + + jest-serializer@27.5.1: + resolution: {integrity: sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-snapshot@27.5.1: + resolution: {integrity: sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-snapshot@29.7.0: + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-util@26.6.2: + resolution: {integrity: sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q==} + engines: {node: '>= 10.14.2'} + + jest-util@27.5.1: + resolution: {integrity: sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-validate@27.5.1: + resolution: {integrity: sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-watcher@27.5.1: + resolution: {integrity: sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + jest-watcher@29.7.0: + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-worker@26.6.2: + resolution: {integrity: sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==} + engines: {node: '>= 10.13.0'} + + jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + + jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest@27.5.1: + resolution: {integrity: sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + jest@29.7.0: + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + + joi@17.13.3: + resolution: {integrity: sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==} + + js-sha3@0.8.0: + resolution: {integrity: sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q==} + + js-string-escape@1.0.1: + resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==} + engines: {node: '>= 0.8'} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + + js-yaml@3.14.2: + resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} + hasBin: true + + js-yaml@4.1.0: + resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} + hasBin: true + + js-yaml@4.1.1: + resolution: {integrity: sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==} + hasBin: true + + jsdoc-type-pratt-parser@4.8.0: + resolution: {integrity: sha512-iZ8Bdb84lWRuGHamRXFyML07r21pcwBrLkHEuHgEY5UbCouBwv7ECknDRKzsQIXMiqpPymqtIf8TC/shYKB5rw==} + engines: {node: '>=12.0.0'} + + jsdom@16.7.0: + resolution: {integrity: sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==} + engines: {node: '>=10'} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true + + jsdom@28.1.0: + resolution: {integrity: sha512-0+MoQNYyr2rBHqO1xilltfDjV9G7ymYGlAUazgcDLQaUf8JDHbuGwsxN6U9qWaElZ4w1B2r7yEGIL3GdeW3Rug==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + peerDependencies: + canvas: ^3.0.0 + peerDependenciesMeta: + canvas: + optional: true + + jsesc@3.1.0: + resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} + engines: {node: '>=6'} + hasBin: true + + json-buffer@3.0.1: + resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==} + + json-parse-better-errors@1.0.2: + resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} + + json-parse-even-better-errors@2.3.1: + resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + + json-parse-even-better-errors@3.0.2: + resolution: {integrity: sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + json-schema-traverse@0.4.1: + resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-stable-stringify-without-jsonify@1.0.1: + resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} + + json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + + json5@1.0.2: + resolution: {integrity: sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==} + hasBin: true + + json5@2.2.3: + resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} + engines: {node: '>=6'} + hasBin: true + + jsonc-parser@3.2.0: + resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} + + jsonfile@6.2.1: + resolution: {integrity: sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==} + + jsonparse@1.3.1: + resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} + engines: {'0': node >= 0.2.0} + + jss-plugin-camel-case@10.10.0: + resolution: {integrity: sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw==} + + jss-plugin-default-unit@10.10.0: + resolution: {integrity: sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ==} + + jss-plugin-global@10.10.0: + resolution: {integrity: sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A==} + + jss-plugin-nested@10.10.0: + resolution: {integrity: sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA==} + + jss-plugin-props-sort@10.10.0: + resolution: {integrity: sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg==} + + jss-plugin-rule-value-function@10.10.0: + resolution: {integrity: sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g==} + + jss-plugin-vendor-prefixer@10.10.0: + resolution: {integrity: sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg==} + + jss@10.10.0: + resolution: {integrity: sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw==} + + jsx-ast-utils@3.3.5: + resolution: {integrity: sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==} + engines: {node: '>=4.0'} + + junk@3.1.0: + resolution: {integrity: sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ==} + engines: {node: '>=8'} + + keyv@4.5.4: + resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + + keyvaluestorage-interface@1.0.0: + resolution: {integrity: sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g==} + + kind-of@3.2.2: + resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} + engines: {node: '>=0.10.0'} + + kind-of@4.0.0: + resolution: {integrity: sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==} + engines: {node: '>=0.10.0'} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + + klona@2.0.6: + resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==} + engines: {node: '>= 8'} + + language-subtag-registry@0.3.23: + resolution: {integrity: sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ==} + + language-tags@1.0.9: + resolution: {integrity: sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA==} + engines: {node: '>=0.10'} + + launch-editor@2.13.2: + resolution: {integrity: sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==} + + lazy-universal-dotenv@3.0.1: + resolution: {integrity: sha512-prXSYk799h3GY3iOWnC6ZigYzMPjxN2svgjJ9shk7oMadSNX3wXy0B6F32PMJv7qtMnrIbUxoEHzbutvxR2LBQ==} + engines: {node: '>=6.0.0', npm: '>=6.0.0', yarn: '>=1.0.0'} + + lefthook-darwin-arm64@1.13.6: + resolution: {integrity: sha512-m6Lb77VGc84/Qo21Lhq576pEvcgFCnvloEiP02HbAHcIXD0RTLy9u2yAInrixqZeaz13HYtdDaI7OBYAAdVt8A==} + cpu: [arm64] + os: [darwin] + + lefthook-darwin-x64@1.13.6: + resolution: {integrity: sha512-CoRpdzanu9RK3oXR1vbEJA5LN7iB+c7hP+sONeQJzoOXuq4PNKVtEaN84Gl1BrVtCNLHWFAvCQaZPPiiXSy8qg==} + cpu: [x64] + os: [darwin] + + lefthook-freebsd-arm64@1.13.6: + resolution: {integrity: sha512-X4A7yfvAJ68CoHTqP+XvQzdKbyd935sYy0bQT6Ajz7FL1g7hFiro8dqHSdPdkwei9hs8hXeV7feyTXbYmfjKQQ==} + cpu: [arm64] + os: [freebsd] + + lefthook-freebsd-x64@1.13.6: + resolution: {integrity: sha512-ai2m+Sj2kGdY46USfBrCqLKe9GYhzeq01nuyDYCrdGISePeZ6udOlD1k3lQKJGQCHb0bRz4St0r5nKDSh1x/2A==} + cpu: [x64] + os: [freebsd] + + lefthook-linux-arm64@1.13.6: + resolution: {integrity: sha512-cbo4Wtdq81GTABvikLORJsAWPKAJXE8Q5RXsICFUVznh5PHigS9dFW/4NXywo0+jfFPCT6SYds2zz4tCx6DA0Q==} + cpu: [arm64] + os: [linux] + + lefthook-linux-x64@1.13.6: + resolution: {integrity: sha512-uJl9vjCIIBTBvMZkemxCE+3zrZHlRO7Oc+nZJ+o9Oea3fu+W82jwX7a7clw8jqNfaeBS+8+ZEQgiMHWCloTsGw==} + cpu: [x64] + os: [linux] + + lefthook-openbsd-arm64@1.13.6: + resolution: {integrity: sha512-7r153dxrNRQ9ytRs2PmGKKkYdvZYFPre7My7XToSTiRu5jNCq++++eAKVkoyWPduk97dGIA+YWiEr5Noe0TK2A==} + cpu: [arm64] + os: [openbsd] + + lefthook-openbsd-x64@1.13.6: + resolution: {integrity: sha512-Z+UhLlcg1xrXOidK3aLLpgH7KrwNyWYE3yb7ITYnzJSEV8qXnePtVu8lvMBHs/myzemjBzeIr/U/+ipjclR06g==} + cpu: [x64] + os: [openbsd] + + lefthook-windows-arm64@1.13.6: + resolution: {integrity: sha512-Uxef6qoDxCmUNQwk8eBvddYJKSBFglfwAY9Y9+NnnmiHpWTjjYiObE9gT2mvGVpEgZRJVAatBXc+Ha5oDD/OgQ==} + cpu: [arm64] + os: [win32] + + lefthook-windows-x64@1.13.6: + resolution: {integrity: sha512-mOZoM3FQh3o08M8PQ/b3IYuL5oo36D9ehczIw1dAgp1Ly+Tr4fJ96A+4SEJrQuYeRD4mex9bR7Ps56I73sBSZA==} + cpu: [x64] + os: [win32] + + lefthook@1.13.6: + resolution: {integrity: sha512-ojj4/4IJ29Xn4drd5emqVgilegAPN3Kf0FQM2p/9+lwSTpU+SZ1v4Ig++NF+9MOa99UKY8bElmVrLhnUUNFh5g==} + hasBin: true + + lerna@7.4.2: + resolution: {integrity: sha512-gxavfzHfJ4JL30OvMunmlm4Anw7d7Tq6tdVHzUukLdS9nWnxCN/QB21qR+VJYp5tcyXogHKbdUEGh6qmeyzxSA==} + engines: {node: '>=16.0.0'} + hasBin: true + + leven@3.1.0: + resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} + engines: {node: '>=6'} + + levn@0.4.1: + resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} + engines: {node: '>= 0.8.0'} + + libnpmaccess@7.0.2: + resolution: {integrity: sha512-vHBVMw1JFMTgEk15zRsJuSAg7QtGGHpUSEfnbcRL1/gTBag9iEfJbyjpDmdJmwMhvpoLoNBtdAUCdGnaP32hhw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + libnpmpublish@7.3.0: + resolution: {integrity: sha512-fHUxw5VJhZCNSls0KLNEG0mCD2PN1i14gH5elGOgiVnU3VgTcRahagYP2LKI1m0tFCJ+XrAm0zVYyF5RCbXzcg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + libsodium-sumo@0.7.16: + resolution: {integrity: sha512-x6atrz2AdXCJg6G709x9W9TTJRI6/0NcL5dD0l5GGVqNE48UJmDsjO4RUWYTeyXXUpg+NXZ2SHECaZnFRYzwGA==} + + libsodium-wrappers-sumo@0.7.16: + resolution: {integrity: sha512-gR0JEFPeN3831lB9+ogooQk0KH4K5LSMIO5Prd5Q5XYR2wHFtZfPg0eP7t1oJIWq+UIzlU4WVeBxZ97mt28tXw==} + + libsodium-wrappers@0.7.16: + resolution: {integrity: sha512-Gtr/WBx4dKjvRL1pvfwZqu7gO6AfrQ0u9vFL+kXihtHf6NfkROR8pjYWn98MFDI3jN19Ii1ZUfPR9afGiPyfHg==} + + libsodium@0.7.16: + resolution: {integrity: sha512-3HrzSPuzm6Yt9aTYCDxYEG8x8/6C0+ag655Y7rhhWZM9PT4NpdnbqlzXhGZlDnkgR6MeSTnOt/VIyHLs9aSf+Q==} + + lie@3.1.1: + resolution: {integrity: sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==} + + lilconfig@2.1.0: + resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} + engines: {node: '>=10'} + + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + + lines-and-columns@1.2.4: + resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} + + lines-and-columns@2.0.4: + resolution: {integrity: sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + load-json-file@1.1.0: + resolution: {integrity: sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==} + engines: {node: '>=0.10.0'} + + load-json-file@4.0.0: + resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} + engines: {node: '>=4'} + + load-json-file@6.2.0: + resolution: {integrity: sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ==} + engines: {node: '>=8'} + + loader-runner@2.4.0: + resolution: {integrity: sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==} + engines: {node: '>=4.3.0 <5.0.0 || >=5.10'} + + loader-runner@4.3.2: + resolution: {integrity: sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w==} + engines: {node: '>=6.11.5'} + + loader-utils@1.4.2: + resolution: {integrity: sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==} + engines: {node: '>=4.0.0'} + + loader-utils@2.0.4: + resolution: {integrity: sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==} + engines: {node: '>=8.9.0'} + + localforage@1.10.0: + resolution: {integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==} + + locate-path@2.0.0: + resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} + engines: {node: '>=4'} + + locate-path@3.0.0: + resolution: {integrity: sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==} + engines: {node: '>=6'} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + locate-path@6.0.0: + resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} + engines: {node: '>=10'} + + locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + lodash-es@4.18.1: + resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} + + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + + lodash.ismatch@4.4.0: + resolution: {integrity: sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==} + + lodash.memoize@4.1.2: + resolution: {integrity: sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==} + + lodash.merge@4.6.2: + resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} + + lodash.padend@4.6.1: + resolution: {integrity: sha512-sOQs2aqGpbl27tmCS1QNZA09Uqp01ZzWfDUoD+xzTii0E7dSQfRKcRetFwa+uXaxaqL+TKm7CgD2JdKP7aZBSw==} + + lodash.trimstart@4.5.1: + resolution: {integrity: sha512-b/+D6La8tU76L/61/aN0jULWHkT0EeJCmVstPBn/K9MtD2qBW83AsBNrr63dKuWYwVMO7ucv13QNO/Ek/2RKaQ==} + + lodash.uniq@4.5.0: + resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} + + lodash.words@4.2.0: + resolution: {integrity: sha512-mXxqd8Yx9BGPij3lZKFSdOsjOTbL4krbCCp9slEozaN4EMppA2dFmK/f8HeohodprY6W0vOdiQ5WFgPaTI75xQ==} + + lodash@4.18.1: + resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + + log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + + long@4.0.0: + resolution: {integrity: sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==} + + longest-streak@3.1.0: + resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} + + loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + + lossless-json@4.3.0: + resolution: {integrity: sha512-ToxOC+SsduRmdSuoLZLYAr5zy1Qu7l5XhmPWM3zefCZ5IcrzW/h108qbJUKfOlDlhvhjUK84+8PSVX0kxnit0g==} + + loud-rejection@1.6.0: + resolution: {integrity: sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==} + engines: {node: '>=0.10.0'} + + loupe@3.2.1: + resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} + + lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + + lru-cache@11.3.6: + resolution: {integrity: sha512-Gf/KoL3C/MlI7Bt0PGI9I+TeTC/I6r/csU58N4BSNc4lppLBeKsOdFYkK+dX0ABDUMJNfCHTyPpzwwO21Awd3A==} + engines: {node: 20 || >=22} + + lru-cache@5.1.1: + resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==} + + lru-cache@6.0.0: + resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} + engines: {node: '>=10'} + + lru-cache@7.18.3: + resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} + engines: {node: '>=12'} + + lucide-react@0.453.0: + resolution: {integrity: sha512-kL+RGZCcJi9BvJtzg2kshO192Ddy9hv3ij+cPrVPWSRzgCWCVazoQJxOjAwgK53NomL07HB7GPHW120FimjNhQ==} + peerDependencies: + react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc + + lz-string@1.5.0: + resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} + hasBin: true + + make-dir@2.1.0: + resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} + engines: {node: '>=6'} + + make-dir@3.1.0: + resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} + engines: {node: '>=8'} + + make-dir@4.0.0: + resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} + engines: {node: '>=10'} + + make-error@1.3.6: + resolution: {integrity: sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==} + + make-fetch-happen@10.2.1: + resolution: {integrity: sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + make-fetch-happen@11.1.1: + resolution: {integrity: sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + makeerror@1.0.12: + resolution: {integrity: sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==} + + map-age-cleaner@0.1.3: + resolution: {integrity: sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==} + engines: {node: '>=6'} + + map-cache@0.2.2: + resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} + engines: {node: '>=0.10.0'} + + map-obj@1.0.1: + resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} + engines: {node: '>=0.10.0'} + + map-obj@4.3.0: + resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} + engines: {node: '>=8'} + + map-or-similar@1.5.0: + resolution: {integrity: sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==} + + map-visit@1.0.0: + resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} + engines: {node: '>=0.10.0'} + + markdown-escapes@1.0.4: + resolution: {integrity: sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==} + + material-react-table@3.2.1: + resolution: {integrity: sha512-sQtTf7bETpkPN2Hm5BVtz89wrfXCVQguz6XlwMChSnfKFO5QCKAJJC5aSIKnUc3S0AvTz/k/ILi00FnnY1Gixw==} + engines: {node: '>=16'} + peerDependencies: + '@emotion/react': '>=11.13' + '@emotion/styled': '>=11.13' + '@mui/icons-material': '>=6' + '@mui/material': '>=6' + '@mui/x-date-pickers': '>=7.15' + react: '>=18.0' + react-dom: '>=18.0' + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + md5.js@1.3.5: + resolution: {integrity: sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==} + + mdast-squeeze-paragraphs@4.0.0: + resolution: {integrity: sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ==} + + mdast-util-definitions@4.0.0: + resolution: {integrity: sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==} + + mdast-util-from-markdown@2.0.3: + resolution: {integrity: sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==} + + mdast-util-mdx-expression@2.0.1: + resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==} + + mdast-util-mdx-jsx@3.2.0: + resolution: {integrity: sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==} + + mdast-util-mdxjs-esm@2.0.1: + resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==} + + mdast-util-phrasing@4.1.0: + resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==} + + mdast-util-to-hast@10.0.1: + resolution: {integrity: sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA==} + + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + + mdast-util-to-markdown@2.1.2: + resolution: {integrity: sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==} + + mdast-util-to-string@1.1.0: + resolution: {integrity: sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==} + + mdast-util-to-string@4.0.0: + resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + + mdn-data@2.0.14: + resolution: {integrity: sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==} + + mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + + mdn-data@2.0.30: + resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==} + + mdn-data@2.27.1: + resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} + + mdurl@1.0.1: + resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} + + media-query-parser@2.0.2: + resolution: {integrity: sha512-1N4qp+jE0pL5Xv4uEcwVUhIkwdUO3S/9gML90nqKA7v7FcOS5vUtatfzok9S9U1EJU8dHWlcv95WLnKmmxZI9w==} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + mem@8.1.1: + resolution: {integrity: sha512-qFCFUDs7U3b8mBDPyz5EToEKoAkgCzqquIgi9nkkR9bixxOVOre+09lbuH7+9Kn2NFpm56M3GUWVbU2hQgdACA==} + engines: {node: '>=10'} + + memfs@3.5.3: + resolution: {integrity: sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==} + engines: {node: '>= 4.0.0'} + + memoizerific@1.11.3: + resolution: {integrity: sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==} + + memory-fs@0.4.1: + resolution: {integrity: sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ==} + + memory-fs@0.5.0: + resolution: {integrity: sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==} + engines: {node: '>=4.3.0 <5.0.0 || >=5.10'} + + memorystream@0.3.1: + resolution: {integrity: sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw==} + engines: {node: '>= 0.10.0'} + + meow@3.7.0: + resolution: {integrity: sha512-TNdwZs0skRlpPpCUK25StC4VH+tP5GgeY1HQOOGP+lQ2xtdkN2VtT/5tiX9k3IWpkBPV9b3LsAWXn4GGi/PrSA==} + engines: {node: '>=0.10.0'} + + meow@8.1.2: + resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==} + engines: {node: '>=10'} + + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + microevent.ts@0.1.1: + resolution: {integrity: sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g==} + + micromark-core-commonmark@2.0.3: + resolution: {integrity: sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==} + + micromark-factory-destination@2.0.1: + resolution: {integrity: sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==} + + micromark-factory-label@2.0.1: + resolution: {integrity: sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==} + + micromark-factory-space@2.0.1: + resolution: {integrity: sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==} + + micromark-factory-title@2.0.1: + resolution: {integrity: sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==} + + micromark-factory-whitespace@2.0.1: + resolution: {integrity: sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-chunked@2.0.1: + resolution: {integrity: sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==} + + micromark-util-classify-character@2.0.1: + resolution: {integrity: sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==} + + micromark-util-combine-extensions@2.0.1: + resolution: {integrity: sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==} + + micromark-util-decode-numeric-character-reference@2.0.2: + resolution: {integrity: sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==} + + micromark-util-decode-string@2.0.1: + resolution: {integrity: sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-html-tag-name@2.0.1: + resolution: {integrity: sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==} + + micromark-util-normalize-identifier@2.0.1: + resolution: {integrity: sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==} + + micromark-util-resolve-all@2.0.1: + resolution: {integrity: sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-subtokenize@2.1.0: + resolution: {integrity: sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.2: + resolution: {integrity: sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==} + + micromark@4.0.2: + resolution: {integrity: sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==} + + micromatch@3.1.10: + resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} + engines: {node: '>=0.10.0'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + miller-rabin@4.0.1: + resolution: {integrity: sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==} + hasBin: true + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + mime@2.6.0: + resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} + engines: {node: '>=4.0.0'} + hasBin: true + + mimic-fn@2.1.0: + resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} + engines: {node: '>=6'} + + mimic-fn@3.1.0: + resolution: {integrity: sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==} + engines: {node: '>=8'} + + min-document@2.19.2: + resolution: {integrity: sha512-8S5I8db/uZN8r9HSLFVWPdJCvYOejMcEC82VIzNUc6Zkklf/d1gg2psfE79/vyhWOj4+J8MtwmoOz3TmvaGu5A==} + + min-indent@1.0.1: + resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} + engines: {node: '>=4'} + + mini-css-extract-plugin@2.10.2: + resolution: {integrity: sha512-AOSS0IdEB95ayVkxn5oGzNQwqAi2J0Jb/kKm43t7H73s8+f5873g0yuj0PNvK4dO75mu5DHg4nlgp4k6Kga8eg==} + engines: {node: '>= 12.13.0'} + peerDependencies: + webpack: ^5.0.0 + + minimalistic-assert@1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + + minimalistic-crypto-utils@1.0.1: + resolution: {integrity: sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==} + + minimatch@10.2.5: + resolution: {integrity: sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==} + engines: {node: 18 || 20 || >=22} + + minimatch@3.0.5: + resolution: {integrity: sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw==} + + minimatch@3.1.5: + resolution: {integrity: sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==} + + minimatch@5.1.9: + resolution: {integrity: sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==} + engines: {node: '>=10'} + + minimatch@8.0.7: + resolution: {integrity: sha512-V+1uQNdzybxa14e/p00HZnQNNcTjnRJjDxg2V8wtkjFctq4M7hXFws4oekyTP0Jebeq7QYtpFyOeBAjc88zvYg==} + engines: {node: '>=16 || 14 >=14.17'} + + minimatch@9.0.9: + resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} + engines: {node: '>=16 || 14 >=14.17'} + + minimist-options@4.1.0: + resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} + engines: {node: '>= 6'} + + minimist@1.2.8: + resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} + + minipass-collect@1.0.2: + resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} + engines: {node: '>= 8'} + + minipass-fetch@2.1.2: + resolution: {integrity: sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + minipass-fetch@3.0.5: + resolution: {integrity: sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + minipass-flush@1.0.7: + resolution: {integrity: sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA==} + engines: {node: '>= 8'} + + minipass-json-stream@1.0.2: + resolution: {integrity: sha512-myxeeTm57lYs8pH2nxPzmEEg8DGIgW+9mv6D4JZD2pa81I/OBjeU7PtICXV6c9eRGTA5JMDsuIPUZRCyBMYNhg==} + + minipass-pipeline@1.2.4: + resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} + engines: {node: '>=8'} + + minipass-sized@1.0.3: + resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} + engines: {node: '>=8'} + + minipass@3.3.6: + resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==} + engines: {node: '>=8'} + + minipass@4.2.8: + resolution: {integrity: sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==} + engines: {node: '>=8'} + + minipass@5.0.0: + resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==} + engines: {node: '>=8'} + + minipass@7.1.3: + resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} + engines: {node: '>=16 || 14 >=14.17'} + + minizlib@2.1.2: + resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} + engines: {node: '>= 8'} + + mississippi@3.0.0: + resolution: {integrity: sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==} + engines: {node: '>=4.0.0'} + + mixin-deep@1.3.2: + resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} + engines: {node: '>=0.10.0'} + + mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + + mkdirp@1.0.4: + resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} + engines: {node: '>=10'} + hasBin: true + + mobx@6.15.3: + resolution: {integrity: sha512-6+ZSYDs5zgH5CdGfEU2q2Lsa5PztVryL1ys7kAImTU25n2A9LAMj/yneVsQpd03MfwMLDQF+7kakJR9Z+cQxSw==} + + modern-ahocorasick@1.1.0: + resolution: {integrity: sha512-sEKPVl2rM+MNVkGQt3ChdmD8YsigmXdn5NifZn6jiwn9LRJpWm8F3guhaqrJT/JOat6pwpbXEk6kv+b9DMIjsQ==} + + modify-values@1.0.1: + resolution: {integrity: sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==} + engines: {node: '>=0.10.0'} + + move-concurrently@1.0.1: + resolution: {integrity: sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==} + deprecated: This package is no longer supported. + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + multicast-dns@7.2.5: + resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} + hasBin: true + + multimatch@5.0.0: + resolution: {integrity: sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==} + engines: {node: '>=10'} + + mute-stream@0.0.8: + resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} + + mute-stream@1.0.0: + resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + nan@2.27.0: + resolution: {integrity: sha512-hC+0LidcL3XE4rp1C4H54KujgXKzbfyTngZTwBByQxsOxCEKZT0MPQ4hOKUH2jU1OYstqdDH4onyHPDzcV0XdQ==} + + nanoclone@0.2.1: + resolution: {integrity: sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==} + + nanoid@3.3.12: + resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + + nanomatch@1.2.13: + resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} + engines: {node: '>=0.10.0'} + + napi-postinstall@0.3.4: + resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} + engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} + hasBin: true + + natural-compare-lite@1.4.0: + resolution: {integrity: sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==} + + natural-compare@1.4.0: + resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + negotiator@0.6.4: + resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} + engines: {node: '>= 0.6'} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + nested-error-stacks@2.1.1: + resolution: {integrity: sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==} + + next@14.2.35: + resolution: {integrity: sha512-KhYd2Hjt/O1/1aZVX3dCwGXM1QmOV4eNM2UTacK5gipDdPN/oHHK/4oVGy7X8GMfPMsUTUEmGlsy0EY1YGAkig==} + engines: {node: '>=18.17.0'} + hasBin: true + peerDependencies: + '@opentelemetry/api': ^1.1.0 + '@playwright/test': ^1.41.2 + react: ^18.2.0 + react-dom: ^18.2.0 + sass: ^1.3.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true + '@playwright/test': + optional: true + sass: + optional: true + + nice-try@1.0.5: + resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} + + no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + + nock@13.5.4: + resolution: {integrity: sha512-yAyTfdeNJGGBFxWdzSKCBYxs5FxLbCg5X5Q4ets974hcQzG1+qCxvIyOo4j2Ry6MUlhWVMX4OoYDefAIIwupjw==} + engines: {node: '>= 10.13'} + + node-abort-controller@3.1.1: + resolution: {integrity: sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==} + + node-addon-api@3.2.1: + resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} + + node-dir@0.1.17: + resolution: {integrity: sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==} + engines: {node: '>= 0.10.5'} + + node-exports-info@1.6.0: + resolution: {integrity: sha512-pyFS63ptit/P5WqUkt+UUfe+4oevH+bFeIiPPdfb0pFeYEu/1ELnJu5l+5EcTKYL5M7zaAa7S8ddywgXypqKCw==} + engines: {node: '>= 0.4'} + + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + + node-fetch@2.6.7: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + + node-forge@1.4.0: + resolution: {integrity: sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==} + engines: {node: '>= 6.13.0'} + + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + + node-gyp@9.4.1: + resolution: {integrity: sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ==} + engines: {node: ^12.13 || ^14.13 || >=16} + hasBin: true + + node-int64@0.4.0: + resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + + node-libs-browser@2.2.1: + resolution: {integrity: sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==} + + node-machine-id@1.1.12: + resolution: {integrity: sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ==} + + node-mock-http@1.0.4: + resolution: {integrity: sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ==} + + node-releases@2.0.44: + resolution: {integrity: sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==} + + nopt@6.0.0: + resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + hasBin: true + + normalize-package-data@2.5.0: + resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} + + normalize-package-data@3.0.3: + resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} + engines: {node: '>=10'} + + normalize-package-data@5.0.0: + resolution: {integrity: sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + normalize-path@2.1.1: + resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} + engines: {node: '>=0.10.0'} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + normalize-range@0.1.2: + resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} + engines: {node: '>=0.10.0'} + + normalize-url@6.1.0: + resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} + engines: {node: '>=10'} + + notistack@2.0.8: + resolution: {integrity: sha512-/IY14wkFp5qjPgKNvAdfL5Jp6q90+MjgKTPh4c81r/lW70KeuX6b9pE/4f8L4FG31cNudbN9siiFS5ql1aSLRw==} + peerDependencies: + '@emotion/react': ^11.4.1 + '@emotion/styled': ^11.3.0 + '@mui/material': ^5.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 + peerDependenciesMeta: + '@emotion/react': + optional: true + '@emotion/styled': + optional: true + + npm-bundled@1.1.2: + resolution: {integrity: sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==} + + npm-bundled@3.0.1: + resolution: {integrity: sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-install-checks@6.3.0: + resolution: {integrity: sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-normalize-package-bin@1.0.1: + resolution: {integrity: sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==} + + npm-normalize-package-bin@3.0.1: + resolution: {integrity: sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-package-arg@10.1.0: + resolution: {integrity: sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-package-arg@8.1.1: + resolution: {integrity: sha512-CsP95FhWQDwNqiYS+Q0mZ7FAEDytDZAkNxQqea6IaAFJTAY9Lhhqyl0irU/6PMc7BGfUmnsbHcqxJD7XuVM/rg==} + engines: {node: '>=10'} + + npm-packlist@5.1.1: + resolution: {integrity: sha512-UfpSvQ5YKwctmodvPPkK6Fwk603aoVsf8AEbmVKAEECrfvL8SSe1A2YIwrJ6xmTHAITKPwwZsWo7WwEbNk0kxw==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + hasBin: true + + npm-packlist@7.0.4: + resolution: {integrity: sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-pick-manifest@8.0.2: + resolution: {integrity: sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-registry-fetch@14.0.5: + resolution: {integrity: sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + npm-run-all@4.1.5: + resolution: {integrity: sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ==} + engines: {node: '>= 4'} + hasBin: true + + npm-run-path@2.0.2: + resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==} + engines: {node: '>=4'} + + npm-run-path@4.0.1: + resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} + engines: {node: '>=8'} + + npmlog@5.0.1: + resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==} + deprecated: This package is no longer supported. + + npmlog@6.0.2: + resolution: {integrity: sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + deprecated: This package is no longer supported. + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + num2fraction@1.2.2: + resolution: {integrity: sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==} + + nwsapi@2.2.23: + resolution: {integrity: sha512-7wfH4sLbt4M0gCDzGE6vzQBo0bfTKjU7Sfpqy/7gs1qBfYz2vEJH6vXcBKpO3+6Yu1telwd0t9HpyOoLEQQbIQ==} + + nx@16.10.0: + resolution: {integrity: sha512-gZl4iCC0Hx0Qe1VWmO4Bkeul2nttuXdPpfnlcDKSACGu3ZIo+uySqwOF8yBAxSTIf8xe2JRhgzJN1aFkuezEBg==} + hasBin: true + peerDependencies: + '@swc-node/register': ^1.6.7 + '@swc/core': ^1.3.85 + peerDependenciesMeta: + '@swc-node/register': + optional: true + '@swc/core': + optional: true + + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-copy@0.1.0: + resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + object-is@1.1.6: + resolution: {integrity: sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==} + engines: {node: '>= 0.4'} + + object-keys@1.1.1: + resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} + engines: {node: '>= 0.4'} + + object-visit@1.0.1: + resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} + engines: {node: '>=0.10.0'} + + object.assign@4.1.7: + resolution: {integrity: sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw==} + engines: {node: '>= 0.4'} + + object.entries@1.1.9: + resolution: {integrity: sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==} + engines: {node: '>= 0.4'} + + object.fromentries@2.0.8: + resolution: {integrity: sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==} + engines: {node: '>= 0.4'} + + object.getownpropertydescriptors@2.1.9: + resolution: {integrity: sha512-mt8YM6XwsTTovI+kdZdHSxoyF2DI59up034orlC9NfweclcWOt7CVascNNLp6U+bjFVCVCIh9PwS76tDM/rH8g==} + engines: {node: '>= 0.4'} + + object.groupby@1.0.3: + resolution: {integrity: sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==} + engines: {node: '>= 0.4'} + + object.pick@1.3.0: + resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} + engines: {node: '>=0.10.0'} + + object.values@1.2.1: + resolution: {integrity: sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA==} + engines: {node: '>= 0.4'} + + objectorarray@1.0.5: + resolution: {integrity: sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg==} + + obuf@1.1.2: + resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} + + ofetch@1.5.1: + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} + + on-exit-leak-free@0.2.0: + resolution: {integrity: sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + on-headers@1.1.0: + resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@5.1.2: + resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} + engines: {node: '>=6'} + + open@7.4.2: + resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} + engines: {node: '>=8'} + + open@8.4.2: + resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} + engines: {node: '>=12'} + + openapi-fetch@0.13.8: + resolution: {integrity: sha512-yJ4QKRyNxE44baQ9mY5+r/kAzZ8yXMemtNAOFwOzRXJscdjSxxzWSNlyBAr+o5JjkUw9Lc3W7OIoca0cY3PYnQ==} + + openapi-typescript-helpers@0.0.15: + resolution: {integrity: sha512-opyTPaunsklCBpTK8JGef6mfPhLSnyy5a0IN9vKtx3+4aExf+KxEqYwIy3hqkedXIB97u357uLMJsOnm3GVjsw==} + + optionator@0.9.4: + resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} + engines: {node: '>= 0.8.0'} + + ora@5.4.1: + resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} + engines: {node: '>=10'} + + os-browserify@0.3.0: + resolution: {integrity: sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==} + + os-homedir@1.0.2: + resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} + engines: {node: '>=0.10.0'} + + own-keys@1.0.1: + resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} + engines: {node: '>= 0.4'} + + p-all@2.1.0: + resolution: {integrity: sha512-HbZxz5FONzz/z2gJfk6bFca0BCiSRF8jU3yCsWOen/vR6lZjfPOu/e7L3uFzTW1i0H8TlC3vqQstEJPQL4/uLA==} + engines: {node: '>=6'} + + p-defer@1.0.0: + resolution: {integrity: sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw==} + engines: {node: '>=4'} + + p-event@4.2.0: + resolution: {integrity: sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==} + engines: {node: '>=8'} + + p-filter@2.1.0: + resolution: {integrity: sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw==} + engines: {node: '>=8'} + + p-finally@1.0.0: + resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} + engines: {node: '>=4'} + + p-limit@1.3.0: + resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} + engines: {node: '>=4'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-limit@3.1.0: + resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} + engines: {node: '>=10'} + + p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-locate@2.0.0: + resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} + engines: {node: '>=4'} + + p-locate@3.0.0: + resolution: {integrity: sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==} + engines: {node: '>=6'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-locate@5.0.0: + resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} + engines: {node: '>=10'} + + p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + p-map-series@2.1.0: + resolution: {integrity: sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q==} + engines: {node: '>=8'} + + p-map@2.1.0: + resolution: {integrity: sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==} + engines: {node: '>=6'} + + p-map@3.0.0: + resolution: {integrity: sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==} + engines: {node: '>=8'} + + p-map@4.0.0: + resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} + engines: {node: '>=10'} + + p-pipe@3.1.0: + resolution: {integrity: sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw==} + engines: {node: '>=8'} + + p-queue@6.6.2: + resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} + engines: {node: '>=8'} + + p-reduce@2.1.0: + resolution: {integrity: sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==} + engines: {node: '>=8'} + + p-retry@4.6.2: + resolution: {integrity: sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==} + engines: {node: '>=8'} + + p-timeout@3.2.0: + resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} + engines: {node: '>=8'} + + p-try@1.0.0: + resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} + engines: {node: '>=4'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + p-waterfall@2.1.1: + resolution: {integrity: sha512-RRTnDb2TBG/epPRI2yYXsimO0v3BXC8Yd3ogr1545IaqKK17VGhbWVeGGN+XfCm/08OK8635nH31c8bATkHuSw==} + engines: {node: '>=8'} + + package-json-from-dist@1.0.1: + resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + + pacote@15.2.0: + resolution: {integrity: sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + + pako@2.1.0: + resolution: {integrity: sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==} + + parallel-transform@1.2.0: + resolution: {integrity: sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==} + + param-case@3.0.4: + resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} + + parent-module@1.0.1: + resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} + engines: {node: '>=6'} + + parse-asn1@5.1.9: + resolution: {integrity: sha512-fIYNuZ/HastSb80baGOuPRo1O9cf4baWw5WsAp7dBuUzeTD/BoaG8sVTdlPFksBE2lF21dN+A1AnrpIjSWqHHg==} + engines: {node: '>= 0.10'} + + parse-author@2.0.0: + resolution: {integrity: sha512-yx5DfvkN8JsHL2xk2Os9oTia467qnvRgey4ahSm2X8epehBLx/gWLcy5KI+Y36ful5DzGbCS6RazqZGgy1gHNw==} + engines: {node: '>=0.10.0'} + + parse-entities@2.0.0: + resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} + + parse-entities@4.0.2: + resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==} + + parse-json@2.2.0: + resolution: {integrity: sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==} + engines: {node: '>=0.10.0'} + + parse-json@4.0.0: + resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} + engines: {node: '>=4'} + + parse-json@5.2.0: + resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} + engines: {node: '>=8'} + + parse-path@7.1.0: + resolution: {integrity: sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==} + + parse-url@8.1.0: + resolution: {integrity: sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w==} + + parse5@6.0.1: + resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} + + parse5@8.0.1: + resolution: {integrity: sha512-z1e/HMG90obSGeidlli3hj7cbocou0/wa5HacvI3ASx34PecNjNQeaHNo5WIZpWofN9kgkqV1q5YvXe3F0FoPw==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + pascal-case@3.1.2: + resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + + pascalcase@0.1.1: + resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} + engines: {node: '>=0.10.0'} + + path-browserify@0.0.1: + resolution: {integrity: sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + + path-dirname@1.0.2: + resolution: {integrity: sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==} + + path-exists@2.1.0: + resolution: {integrity: sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==} + engines: {node: '>=0.10.0'} + + path-exists@3.0.0: + resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} + engines: {node: '>=4'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + path-is-absolute@1.0.1: + resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} + engines: {node: '>=0.10.0'} + + path-is-inside@1.0.2: + resolution: {integrity: sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==} + + path-key@2.0.1: + resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} + engines: {node: '>=4'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-scurry@1.11.1: + resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} + engines: {node: '>=16 || 14 >=14.18'} + + path-to-regexp@0.1.13: + resolution: {integrity: sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==} + + path-type@1.1.0: + resolution: {integrity: sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==} + engines: {node: '>=0.10.0'} + + path-type@3.0.0: + resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} + engines: {node: '>=4'} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + pbkdf2@3.1.5: + resolution: {integrity: sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ==} + engines: {node: '>= 0.10'} + + picocolors@0.2.1: + resolution: {integrity: sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + + picomatch@4.0.4: + resolution: {integrity: sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==} + engines: {node: '>=12'} + + pidtree@0.3.1: + resolution: {integrity: sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA==} + engines: {node: '>=0.10'} + hasBin: true + + pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + + pify@4.0.1: + resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} + engines: {node: '>=6'} + + pify@5.0.0: + resolution: {integrity: sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==} + engines: {node: '>=10'} + + pinkie-promise@2.0.1: + resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} + engines: {node: '>=0.10.0'} + + pinkie@2.0.4: + resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} + engines: {node: '>=0.10.0'} + + pino-abstract-transport@0.5.0: + resolution: {integrity: sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==} + + pino-std-serializers@4.0.0: + resolution: {integrity: sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==} + + pino@7.11.0: + resolution: {integrity: sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==} + hasBin: true + + pirates@4.0.7: + resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} + engines: {node: '>= 6'} + + pkg-dir@3.0.0: + resolution: {integrity: sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==} + engines: {node: '>=6'} + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + pkg-dir@5.0.0: + resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==} + engines: {node: '>=10'} + + pkg-dir@7.0.0: + resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==} + engines: {node: '>=14.16'} + + pnp-webpack-plugin@1.6.4: + resolution: {integrity: sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==} + engines: {node: '>=6'} + + polished@4.3.1: + resolution: {integrity: sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA==} + engines: {node: '>=10'} + + posix-character-classes@0.1.1: + resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==} + engines: {node: '>=0.10.0'} + + possible-typed-array-names@1.1.0: + resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} + engines: {node: '>= 0.4'} + + postcss-calc@8.2.4: + resolution: {integrity: sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==} + peerDependencies: + postcss: ^8.2.2 + + postcss-calc@9.0.1: + resolution: {integrity: sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.2.2 + + postcss-colormin@5.3.1: + resolution: {integrity: sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-colormin@6.1.0: + resolution: {integrity: sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-convert-values@5.1.3: + resolution: {integrity: sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-convert-values@6.1.0: + resolution: {integrity: sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-comments@5.1.2: + resolution: {integrity: sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-discard-comments@6.0.2: + resolution: {integrity: sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-duplicates@5.1.0: + resolution: {integrity: sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-discard-duplicates@6.0.3: + resolution: {integrity: sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-empty@5.1.1: + resolution: {integrity: sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-discard-empty@6.0.3: + resolution: {integrity: sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-discard-overridden@5.1.0: + resolution: {integrity: sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-discard-overridden@6.0.2: + resolution: {integrity: sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-flexbugs-fixes@4.2.1: + resolution: {integrity: sha512-9SiofaZ9CWpQWxOwRh1b/r85KD5y7GgvsNt1056k6OYLvWUun0czCvogfJgylC22uJTwW1KzY3Gz65NZRlvoiQ==} + + postcss-loader@4.3.0: + resolution: {integrity: sha512-M/dSoIiNDOo8Rk0mUqoj4kpGq91gcxCfb9PoyZVdZ76/AuhxylHDYZblNE8o+EQ9AMSASeMFEKxZf5aU6wlx1Q==} + engines: {node: '>= 10.13.0'} + peerDependencies: + postcss: ^7.0.0 || ^8.0.1 + webpack: ^4.0.0 || ^5.0.0 + + postcss-merge-longhand@5.1.7: + resolution: {integrity: sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-merge-longhand@6.0.5: + resolution: {integrity: sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-merge-rules@5.1.4: + resolution: {integrity: sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-merge-rules@6.1.1: + resolution: {integrity: sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-font-values@5.1.0: + resolution: {integrity: sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-minify-font-values@6.1.0: + resolution: {integrity: sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-gradients@5.1.1: + resolution: {integrity: sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-minify-gradients@6.0.3: + resolution: {integrity: sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-params@5.1.4: + resolution: {integrity: sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-minify-params@6.1.0: + resolution: {integrity: sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-minify-selectors@5.2.1: + resolution: {integrity: sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-minify-selectors@6.0.4: + resolution: {integrity: sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-modules-extract-imports@2.0.0: + resolution: {integrity: sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==} + engines: {node: '>= 6'} + + postcss-modules-extract-imports@3.1.0: + resolution: {integrity: sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-local-by-default@3.0.3: + resolution: {integrity: sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw==} + engines: {node: '>= 6'} + + postcss-modules-local-by-default@4.2.0: + resolution: {integrity: sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-scope@2.2.0: + resolution: {integrity: sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ==} + engines: {node: '>= 6'} + + postcss-modules-scope@3.2.1: + resolution: {integrity: sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-modules-values@3.0.0: + resolution: {integrity: sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg==} + + postcss-modules-values@4.0.0: + resolution: {integrity: sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==} + engines: {node: ^10 || ^12 || >= 14} + peerDependencies: + postcss: ^8.1.0 + + postcss-normalize-charset@5.1.0: + resolution: {integrity: sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-normalize-charset@6.0.2: + resolution: {integrity: sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-display-values@5.1.0: + resolution: {integrity: sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-normalize-display-values@6.0.2: + resolution: {integrity: sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-positions@5.1.1: + resolution: {integrity: sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-normalize-positions@6.0.2: + resolution: {integrity: sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-repeat-style@5.1.1: + resolution: {integrity: sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-normalize-repeat-style@6.0.2: + resolution: {integrity: sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-string@5.1.0: + resolution: {integrity: sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-normalize-string@6.0.2: + resolution: {integrity: sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-timing-functions@5.1.0: + resolution: {integrity: sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-normalize-timing-functions@6.0.2: + resolution: {integrity: sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-unicode@5.1.1: + resolution: {integrity: sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-normalize-unicode@6.1.0: + resolution: {integrity: sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-url@5.1.0: + resolution: {integrity: sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-normalize-url@6.0.2: + resolution: {integrity: sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-normalize-whitespace@5.1.1: + resolution: {integrity: sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-normalize-whitespace@6.0.2: + resolution: {integrity: sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-ordered-values@5.1.3: + resolution: {integrity: sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-ordered-values@6.0.2: + resolution: {integrity: sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-reduce-initial@5.1.2: + resolution: {integrity: sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-reduce-initial@6.1.0: + resolution: {integrity: sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-reduce-transforms@5.1.0: + resolution: {integrity: sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-reduce-transforms@6.0.2: + resolution: {integrity: sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-selector-parser@6.1.2: + resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} + engines: {node: '>=4'} + + postcss-selector-parser@7.1.1: + resolution: {integrity: sha512-orRsuYpJVw8LdAwqqLykBj9ecS5/cRHlI5+nvTo8LcCKmzDmqVORXtOIYEEQuL9D4BxtA1lm5isAqzQZCoQ6Eg==} + engines: {node: '>=4'} + + postcss-svgo@5.1.0: + resolution: {integrity: sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-svgo@6.0.3: + resolution: {integrity: sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==} + engines: {node: ^14 || ^16 || >= 18} + peerDependencies: + postcss: ^8.4.31 + + postcss-unique-selectors@5.1.1: + resolution: {integrity: sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + postcss-unique-selectors@6.0.4: + resolution: {integrity: sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + postcss-value-parser@4.2.0: + resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} + + postcss@7.0.39: + resolution: {integrity: sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==} + engines: {node: '>=6.0.0'} + + postcss@8.4.31: + resolution: {integrity: sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ==} + engines: {node: ^10 || ^12 || >=14} + + postcss@8.5.14: + resolution: {integrity: sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==} + engines: {node: ^10 || ^12 || >=14} + + prelude-ls@1.2.1: + resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} + engines: {node: '>= 0.8.0'} + + prettier-linter-helpers@1.0.1: + resolution: {integrity: sha512-SxToR7P8Y2lWmv/kTzVLC1t/GDI2WGjMwNhLLE9qtH8Q13C+aEmuRlzDst4Up4s0Wc8sF2M+J57iB3cMLqftfg==} + engines: {node: '>=6.0.0'} + + prettier@2.3.0: + resolution: {integrity: sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w==} + engines: {node: '>=10.13.0'} + hasBin: true + + prettier@2.8.8: + resolution: {integrity: sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==} + engines: {node: '>=10.13.0'} + hasBin: true + + pretty-error@2.1.2: + resolution: {integrity: sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw==} + + pretty-error@4.0.0: + resolution: {integrity: sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==} + + pretty-format@27.5.1: + resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + pretty-hrtime@1.0.3: + resolution: {integrity: sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==} + engines: {node: '>= 0.8'} + + proc-log@3.0.0: + resolution: {integrity: sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process-warning@1.0.0: + resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} + + process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + + promise-inflight@1.0.1: + resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} + peerDependencies: + bluebird: '*' + peerDependenciesMeta: + bluebird: + optional: true + + promise-retry@2.0.1: + resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} + engines: {node: '>=10'} + + promise.allsettled@1.0.7: + resolution: {integrity: sha512-hezvKvQQmsFkOdrZfYxUxkyxl8mgFQeT259Ajj9PXdbg9VzBCWrItOev72JyWxkCD5VSSqAeHmlN3tWx4DlmsA==} + engines: {node: '>= 0.4'} + + promise.prototype.finally@3.1.8: + resolution: {integrity: sha512-aVDtsXOml9iuMJzUco9J1je/UrIT3oMYfWkCTiUhkt+AvZw72q4dUZnR/R/eB3h5GeAagQVXvM1ApoYniJiwoA==} + engines: {node: '>= 0.4'} + + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + + promzard@1.0.2: + resolution: {integrity: sha512-2FPputGL+mP3jJ3UZg/Dl9YOkovB7DX0oOr+ck5QbZ5MtORtds8k/BZdn+02peDLI8/YWbmzx34k5fA+fHvCVQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + prop-types@15.8.1: + resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + + propagate@2.0.1: + resolution: {integrity: sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==} + engines: {node: '>= 8'} + + property-expr@2.0.6: + resolution: {integrity: sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA==} + + property-information@5.6.0: + resolution: {integrity: sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==} + + property-information@7.1.0: + resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + + protobufjs@6.10.3: + resolution: {integrity: sha512-yvAslS0hNdBhlSKckI4R1l7wunVilX66uvrjzE4MimiAt7/qw1nLpMhZrn/ObuUTM/c3Xnfl01LYMdcSJe6dwg==} + hasBin: true + + protobufjs@6.11.6: + resolution: {integrity: sha512-k8BHqgPBOtrlougZZqF2uUk5Z7bN8f0wj+3e8M3hvtSv0NBAz4VBy5f6R5Nxq/l+i7mRFTgNZb2trxqTpHNY/A==} + hasBin: true + + protocols@2.0.2: + resolution: {integrity: sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ==} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + proxy-from-env@2.1.0: + resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} + engines: {node: '>=10'} + + prr@1.0.1: + resolution: {integrity: sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==} + + psl@1.15.0: + resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} + + public-encrypt@4.0.3: + resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} + + pump@2.0.1: + resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==} + + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + + pumpify@1.5.1: + resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==} + + punycode@1.4.1: + resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} + + punycode@2.3.1: + resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} + engines: {node: '>=6'} + + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + + qr.js@0.0.0: + resolution: {integrity: sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ==} + + qrcode.react@1.0.1: + resolution: {integrity: sha512-8d3Tackk8IRLXTo67Y+c1rpaiXjoz/Dd2HpcMdW//62/x8J1Nbho14Kh8x974t9prsLHN6XqVgcnRiBGFptQmg==} + peerDependencies: + react: ^15.5.3 || ^16.0.0 || ^17.0.0 + + qrcode.react@4.2.0: + resolution: {integrity: sha512-QpgqWi8rD9DsS9EP3z7BT+5lY5SFhsqGjpgW5DY/i3mK4M9DTBNz3ErMi8BWYEfI3L0d8GIbGmcdFAS1uIRGjA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + qs@6.15.1: + resolution: {integrity: sha512-6YHEFRL9mfgcAvql/XhwTvf5jKcOiiupt2FiJxHkiX1z4j7WL8J/jRHYLluORvc1XxB5rV20KoeK00gVJamspg==} + engines: {node: '>=0.6'} + + querystring-es3@0.2.1: + resolution: {integrity: sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==} + engines: {node: '>=0.4.x'} + + querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + + quick-lru@4.0.1: + resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} + engines: {node: '>=8'} + + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + + rainbow-sprinkles@0.17.3: + resolution: {integrity: sha512-tu00bbDozceDz/ajL8YzDn5L0mf0uVHR93v2tfGKKbemKeuPk8R4mXUokleKsA24vzrPiw26iMK53HdRy6HLag==} + peerDependencies: + '@vanilla-extract/css': ^1 + '@vanilla-extract/dynamic': ^2 + + ramda@0.26.1: + resolution: {integrity: sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==} + + ramda@0.28.0: + resolution: {integrity: sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA==} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + randomfill@1.0.4: + resolution: {integrity: sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.3: + resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} + engines: {node: '>= 0.8'} + + raw-loader@4.0.2: + resolution: {integrity: sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==} + engines: {node: '>= 10.13.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + + react-aria@3.48.0: + resolution: {integrity: sha512-jQjd4rBEIMqecBaAKYJbVGK6EqIHLa5znVQ7jwFyK5vCyljoj6KhgtiahmcIPsG5vG5vEDLw+ba+bEWn6A2P4w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + react-dom: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + react-docgen-typescript@2.4.0: + resolution: {integrity: sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg==} + peerDependencies: + typescript: '>= 4.3.x' + + react-docgen@5.4.3: + resolution: {integrity: sha512-xlLJyOlnfr8lLEEeaDZ+X2J/KJoe6Nr9AzxnkdQWush5hz2ZSu66w6iLMOScMmxoSHWpWMn+k3v5ZiyCfcWsOA==} + engines: {node: '>=8.10.0'} + hasBin: true + + react-dom@19.2.6: + resolution: {integrity: sha512-0prMI+hvBbPjsWnxDLxlCGyM8PN6UuWjEUCYmZhO67xIV9Xasa/r/vDnq+Xyq4Lo27g8QSbO5YzARu0D1Sps3g==} + peerDependencies: + react: ^19.2.6 + + react-element-to-jsx-string@14.3.4: + resolution: {integrity: sha512-t4ZwvV6vwNxzujDQ+37bspnLwA4JlgUPWhLjBJWsNIDceAf6ZKUTCjdm08cN6WeZ5pTMKiCJkmAYnpmR4Bm+dg==} + peerDependencies: + react: ^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 + react-dom: ^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 + + react-error-boundary@3.1.4: + resolution: {integrity: sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==} + engines: {node: '>=10', npm: '>=6'} + peerDependencies: + react: '>=16.13.1' + + react-hook-form@7.75.0: + resolution: {integrity: sha512-Ovv94H+0p3sJ7B9B5QxPuCP1u8V/cHuVGyH55cSwodYDtoJwK+fqk3vjfIgSX59I2U/bU4z0nRJ9HMLpNiWEmw==} + engines: {node: '>=18.0.0'} + peerDependencies: + react: ^16.8.0 || ^17 || ^18 || ^19 + + react-i18next@15.7.4: + resolution: {integrity: sha512-nyU8iKNrI5uDJch0z9+Y5XEr34b0wkyYj3Rp+tfbahxtlswxSCjcUL9H0nqXo9IR3/t5Y5PKIA3fx3MfUyR9Xw==} + peerDependencies: + i18next: '>= 23.4.0' + react: '>= 16.8.0' + react-dom: '*' + react-native: '*' + typescript: ^5 + peerDependenciesMeta: + react-dom: + optional: true + react-native: + optional: true + typescript: + optional: true + + react-inspector@5.1.1: + resolution: {integrity: sha512-GURDaYzoLbW8pMGXwYPDBIv6nqei4kK7LPRZ9q9HCZF54wqXz/dnylBp/kfE9XmekBhHvLDdcYeyIwSrvtOiWg==} + peerDependencies: + react: ^16.8.4 || ^17.0.0 + + react-is@16.13.1: + resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} + + react-is@17.0.2: + resolution: {integrity: sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + react-is@19.2.6: + resolution: {integrity: sha512-XjBR15BhXuylgWGuslhDKqlSayuqvqBX91BP8pauG8kd1zY8kotkNWbXksTCNRarse4kuGbe2kIY05ARtwNIvw==} + + react-markdown@9.1.0: + resolution: {integrity: sha512-xaijuJB0kzGiUdG7nc2MOMDUDBWPyGAjZtUrow9XxUeua8IqeP+VlIfAZ3bphpcLTnSZXz6z9jcVC/TCwbfgdw==} + peerDependencies: + '@types/react': '>=18' + react: '>=18' + + react-merge-refs@1.1.0: + resolution: {integrity: sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ==} + + react-random-avatars@1.3.1: + resolution: {integrity: sha512-HyMGoWniK2D5CRthoA1he4c6LVFIX/yBjp4qarEXN/DsgJ+1R6M5gJwYhTBoATO+3itrGCAGnKZNqimG1sDjAA==} + peerDependencies: + react: ^18.2.0 + + react-refresh-typescript@2.0.12: + resolution: {integrity: sha512-kFuSHaP8CbNtBJ4UrdCD0nHLac5k0V4yQnGbQQCZ5Xy8uoQwiIrtncm7Nwxwia6mCzmc8+LDmhslsO3FyzhCkA==} + peerDependencies: + react-refresh: 0.10.x || 0.11.x || 0.12.x || 0.13.x || 0.14.x || 0.15.x || 0.16.x || 0.17.x || 0.18.x || 0.19.x + typescript: ^4.8 || ^5.0 || ^6.0 + + react-refresh@0.10.0: + resolution: {integrity: sha512-PgidR3wST3dDYKr6b4pJoqQFpPGNKDSCDx4cZoshjXipw3LzO7mG1My2pwEzz2JVkF+inx3xRpDeQLFQGH/hsQ==} + engines: {node: '>=0.10.0'} + + react-refresh@0.11.0: + resolution: {integrity: sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==} + engines: {node: '>=0.10.0'} + + react-router-dom@6.30.3: + resolution: {integrity: sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + react-dom: '>=16.8' + + react-router@6.30.3: + resolution: {integrity: sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw==} + engines: {node: '>=14.0.0'} + peerDependencies: + react: '>=16.8' + + react-smooth@4.0.4: + resolution: {integrity: sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + react-stately@3.46.0: + resolution: {integrity: sha512-OdxhWvHgs2L4OJGIs7hnuTr5WjjMM6enhNEAMRqiekhF8+ITvA2LRwNftOZwcogaoCslGYq5S2VQTQwnm0GbCA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1 + + react-transition-group@4.4.5: + resolution: {integrity: sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==} + peerDependencies: + react: '>=16.6.0' + react-dom: '>=16.6.0' + + react-world-flags@1.6.0: + resolution: {integrity: sha512-eutSeAy5YKoVh14js/JUCSlA6EBk1n4k+bDaV+NkNB50VhnG+f4QDTpYycnTUTsZ5cqw/saPmk0Z4Fa0VVZ1Iw==} + peerDependencies: + react: '>=0.14' + + react@19.2.6: + resolution: {integrity: sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q==} + engines: {node: '>=0.10.0'} + + read-cmd-shim@4.0.0: + resolution: {integrity: sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + read-package-json-fast@3.0.2: + resolution: {integrity: sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + read-package-json@6.0.4: + resolution: {integrity: sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + deprecated: This package is no longer supported. Please use @npmcli/package-json instead. + + read-pkg-up@1.0.1: + resolution: {integrity: sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==} + engines: {node: '>=0.10.0'} + + read-pkg-up@3.0.0: + resolution: {integrity: sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==} + engines: {node: '>=4'} + + read-pkg-up@7.0.1: + resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} + engines: {node: '>=8'} + + read-pkg@1.1.0: + resolution: {integrity: sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==} + engines: {node: '>=0.10.0'} + + read-pkg@3.0.0: + resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} + engines: {node: '>=4'} + + read-pkg@5.2.0: + resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} + engines: {node: '>=8'} + + read@2.1.0: + resolution: {integrity: sha512-bvxi1QLJHcaywCAEsAk4DG3nVoqiY2Csps3qzWalhj5hFqRn1d/OixkFXtLO1PrgHUcAP0FNaSY/5GYNfENFFQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + read@3.0.1: + resolution: {integrity: sha512-SLBrDU/Srs/9EoWhU5GdbAoxG1GzpQHo/6qiGItaoLJ1thmYpcNIM1qISEUvyHBzfGlWIyd6p2DNi1oV1VmAuw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@2.2.1: + resolution: {integrity: sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==} + engines: {node: '>=0.10'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + readdirp@5.0.0: + resolution: {integrity: sha512-9u/XQ1pvrQtYyMpZe7DXKv2p5CNvyVwzUB6uhLAnQwHMSgKMBR62lc7AHljaeteeHXn11XTAaLLUVZYVZyuRBQ==} + engines: {node: '>= 20.19.0'} + + readonly-date@1.0.0: + resolution: {integrity: sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ==} + + real-require@0.1.0: + resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} + engines: {node: '>= 12.13.0'} + + recast@0.23.11: + resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} + engines: {node: '>= 4'} + + recharts-scale@0.4.5: + resolution: {integrity: sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w==} + + recharts@2.15.4: + resolution: {integrity: sha512-UT/q6fwS3c1dHbXv2uFgYJ9BMFHu3fwnd7AYZaEQhXuYQ4hgsxLvsUXzGdKeZrW5xopzDCvuA2N41WJ88I7zIw==} + engines: {node: '>=14'} + peerDependencies: + react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + rechoir@0.7.1: + resolution: {integrity: sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==} + engines: {node: '>= 0.10'} + + rechoir@0.8.0: + resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==} + engines: {node: '>= 10.13.0'} + + redent@1.0.0: + resolution: {integrity: sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g==} + engines: {node: '>=0.10.0'} + + redent@3.0.0: + resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} + engines: {node: '>=8'} + + redeyed@2.1.1: + resolution: {integrity: sha512-FNpGGo1DycYAdnrKFxCMmKYgo/mILAqtRYbkdQD8Ep/Hk2PQ5+aEAEx+IU713RTDmuBaH0c8P5ZozurNu5ObRQ==} + + reflect.getprototypeof@1.0.10: + resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==} + engines: {node: '>= 0.4'} + + regenerate-unicode-properties@10.2.2: + resolution: {integrity: sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g==} + engines: {node: '>=4'} + + regenerate@1.4.2: + resolution: {integrity: sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==} + + regenerator-runtime@0.13.11: + resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + + regex-not@1.0.2: + resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} + engines: {node: '>=0.10.0'} + + regexp.prototype.flags@1.5.4: + resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} + engines: {node: '>= 0.4'} + + regexpu-core@6.4.0: + resolution: {integrity: sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==} + engines: {node: '>=4'} + + regjsgen@0.8.0: + resolution: {integrity: sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==} + + regjsparser@0.13.1: + resolution: {integrity: sha512-dLsljMd9sqwRkby8zhO1gSg3PnJIBFid8f4CQj/sXx+7cKx+E7u0PKhZ+U4wmhx7EfmtvnA318oVaIkAB1lRJw==} + hasBin: true + + relateurl@0.2.7: + resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} + engines: {node: '>= 0.10'} + + remark-external-links@8.0.0: + resolution: {integrity: sha512-5vPSX0kHoSsqtdftSHhIYofVINC8qmp0nctkeU9YoJwV3YfiBRiI6cbFRJ0oI/1F9xS+bopXG0m2KS8VFscuKA==} + + remark-footnotes@2.0.0: + resolution: {integrity: sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ==} + + remark-mdx@1.6.22: + resolution: {integrity: sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ==} + + remark-parse@11.0.0: + resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==} + + remark-parse@8.0.3: + resolution: {integrity: sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q==} + + remark-rehype@11.1.2: + resolution: {integrity: sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==} + + remark-slug@6.1.0: + resolution: {integrity: sha512-oGCxDF9deA8phWvxFuyr3oSJsdyUAxMFbA0mZ7Y1Sas+emILtO+e5WutF9564gDsEN4IXaQXm5pFo6MLH+YmwQ==} + + remark-squeeze-paragraphs@4.0.0: + resolution: {integrity: sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw==} + + remove-accents@0.5.0: + resolution: {integrity: sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A==} + + remove-trailing-separator@1.1.0: + resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} + + renderkid@2.0.7: + resolution: {integrity: sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ==} + + renderkid@3.0.0: + resolution: {integrity: sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==} + + repeat-element@1.1.4: + resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} + engines: {node: '>=0.10.0'} + + repeat-string@1.6.1: + resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} + engines: {node: '>=0.10'} + + repeating@2.0.1: + resolution: {integrity: sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A==} + engines: {node: '>=0.10.0'} + + require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + requireindex@1.2.0: + resolution: {integrity: sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==} + engines: {node: '>=0.10.5'} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + + resolve-from@4.0.0: + resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} + engines: {node: '>=4'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve-url@0.2.1: + resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} + deprecated: https://github.com/lydell/resolve-url#deprecated + + resolve.exports@1.1.1: + resolution: {integrity: sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ==} + engines: {node: '>=10'} + + resolve.exports@2.0.3: + resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} + engines: {node: '>=10'} + + resolve@1.22.12: + resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} + engines: {node: '>= 0.4'} + hasBin: true + + resolve@2.0.0-next.6: + resolution: {integrity: sha512-3JmVl5hMGtJ3kMmB3zi3DL25KfkCEyy3Tw7Gmw7z5w8M9WlwoPFnIvwChzu1+cF3iaK3sp18hhPz8ANeimdJfA==} + engines: {node: '>= 0.4'} + hasBin: true + + restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + + ret@0.1.15: + resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} + engines: {node: '>=0.12'} + + retry@0.12.0: + resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} + engines: {node: '>= 4'} + + retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + rgb-hex@3.0.0: + resolution: {integrity: sha512-8h7ZcwxCBDKvchSWbWngJuSCqJGQ6nDuLLg+QcRyQDbX9jMWt+PpPeXAhSla0GOooEomk3lCprUpGkMdsLjKyg==} + engines: {node: '>=8'} + + rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@3.0.2: + resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} + deprecated: Rimraf versions prior to v4 are no longer supported + hasBin: true + + rimraf@4.4.1: + resolution: {integrity: sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==} + engines: {node: '>=14'} + hasBin: true + + ripemd160@2.0.3: + resolution: {integrity: sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==} + engines: {node: '>= 0.8'} + + robust-predicates@3.0.3: + resolution: {integrity: sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==} + + rsvp@4.8.5: + resolution: {integrity: sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==} + engines: {node: 6.* || >= 7.*} + + run-async@2.4.1: + resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} + engines: {node: '>=0.12.0'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + run-queue@1.0.3: + resolution: {integrity: sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==} + + rxjs@7.8.2: + resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} + + safe-array-concat@1.1.4: + resolution: {integrity: sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==} + engines: {node: '>=0.4'} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safe-push-apply@1.0.0: + resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} + engines: {node: '>= 0.4'} + + safe-regex-test@1.1.0: + resolution: {integrity: sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==} + engines: {node: '>= 0.4'} + + safe-regex@1.1.0: + resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} + + safe-stable-stringify@2.5.0: + resolution: {integrity: sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==} + engines: {node: '>=10'} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + sane@4.1.0: + resolution: {integrity: sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA==} + engines: {node: 6.* || 8.* || >= 10.*} + deprecated: some dependency vulnerabilities fixed, support for node < 10 dropped, and newer ECMAScript syntax/features added + hasBin: true + + sax@1.6.0: + resolution: {integrity: sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==} + engines: {node: '>=11.0.0'} + + saxes@5.0.1: + resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==} + engines: {node: '>=10'} + + saxes@6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} + + scheduler@0.27.0: + resolution: {integrity: sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q==} + + schema-utils@1.0.0: + resolution: {integrity: sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==} + engines: {node: '>= 4'} + + schema-utils@2.7.0: + resolution: {integrity: sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==} + engines: {node: '>= 8.9.0'} + + schema-utils@2.7.1: + resolution: {integrity: sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==} + engines: {node: '>= 8.9.0'} + + schema-utils@3.3.0: + resolution: {integrity: sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==} + engines: {node: '>= 10.13.0'} + + schema-utils@4.3.3: + resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} + engines: {node: '>= 10.13.0'} + + select-hose@2.0.0: + resolution: {integrity: sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==} + + selfsigned@2.4.1: + resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} + engines: {node: '>=10'} + + semver@5.7.2: + resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==} + hasBin: true + + semver@6.3.1: + resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} + hasBin: true + + semver@7.5.3: + resolution: {integrity: sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==} + engines: {node: '>=10'} + hasBin: true + + semver@7.8.0: + resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==} + engines: {node: '>=10'} + hasBin: true + + send@0.19.2: + resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} + engines: {node: '>= 0.8.0'} + + serialize-javascript@4.0.0: + resolution: {integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==} + + serialize-javascript@5.0.1: + resolution: {integrity: sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==} + + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + + serve-favicon@2.5.1: + resolution: {integrity: sha512-JndLBslCLA/ebr7rS3d+/EKkzTsTi1jI2T9l+vHfAaGJ7A7NhtDpSZ0lx81HCNWnnE0yHncG+SSnVf9IMxOwXQ==} + engines: {node: '>= 0.8.0'} + + serve-index@1.9.2: + resolution: {integrity: sha512-KDj11HScOaLmrPxl70KYNW1PksP4Nb/CLL2yvC+Qd2kHMPEEpfc4Re2e4FOay+bC/+XQl/7zAcWON3JVo5v3KQ==} + engines: {node: '>= 0.8.0'} + + serve-static@1.16.3: + resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} + engines: {node: '>= 0.8.0'} + + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + + set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + + set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + + set-proto@1.0.0: + resolution: {integrity: sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw==} + engines: {node: '>= 0.4'} + + set-value@2.0.1: + resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} + engines: {node: '>=0.10.0'} + + setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + sha.js@2.4.12: + resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} + engines: {node: '>= 0.10'} + hasBin: true + + shallow-clone@3.0.1: + resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} + engines: {node: '>=8'} + + sharp@0.33.5: + resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + + shebang-command@1.2.0: + resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} + engines: {node: '>=0.10.0'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@1.0.0: + resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} + engines: {node: '>=0.10.0'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.8.3: + resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} + engines: {node: '>= 0.4'} + + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + signal-exit@3.0.7: + resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} + + signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} + + sigstore@1.9.0: + resolution: {integrity: sha512-0Zjz0oe37d08VeOtBIuB6cRriqXse2e8w+7yIy2XSXjshRKxbc2KkhXjL229jXSxEm7UbcjS76wcJDGQddVI9A==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + + simple-swizzle@0.2.4: + resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} + + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + + slash@1.0.0: + resolution: {integrity: sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==} + engines: {node: '>=0.10.0'} + + slash@2.0.0: + resolution: {integrity: sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==} + engines: {node: '>=6'} + + slash@3.0.0: + resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} + engines: {node: '>=8'} + + slash@4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + + smart-buffer@4.2.0: + resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} + engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + + snapdragon-node@2.1.1: + resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} + engines: {node: '>=0.10.0'} + + snapdragon-util@3.0.1: + resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==} + engines: {node: '>=0.10.0'} + + snapdragon@0.8.2: + resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} + engines: {node: '>=0.10.0'} + + sockjs@0.3.24: + resolution: {integrity: sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==} + + socks-proxy-agent@7.0.0: + resolution: {integrity: sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==} + engines: {node: '>= 10'} + + socks@2.8.9: + resolution: {integrity: sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==} + engines: {node: '>= 10.0.0', npm: '>= 3.0.0'} + + sonic-boom@2.8.0: + resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==} + + sort-keys@2.0.0: + resolution: {integrity: sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==} + engines: {node: '>=4'} + + source-list-map@2.0.1: + resolution: {integrity: sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==} + + source-map-js@1.2.1: + resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} + engines: {node: '>=0.10.0'} + + source-map-resolve@0.5.3: + resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} + deprecated: See https://github.com/lydell/source-map-resolve#deprecated + + source-map-support@0.5.13: + resolution: {integrity: sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map-url@0.4.1: + resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} + deprecated: See https://github.com/lydell/source-map-url#deprecated + + source-map@0.5.7: + resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} + engines: {node: '>=0.10.0'} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + source-map@0.7.6: + resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} + engines: {node: '>= 12'} + + space-separated-tokens@1.1.5: + resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==} + + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.23: + resolution: {integrity: sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==} + + spdy-transport@3.0.0: + resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} + + spdy@4.0.2: + resolution: {integrity: sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==} + engines: {node: '>=6.0.0'} + + split-string@3.1.0: + resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} + engines: {node: '>=0.10.0'} + + split2@3.2.2: + resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} + + split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} + + split@1.0.1: + resolution: {integrity: sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==} + + sprintf-js@1.0.3: + resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + + ssri@10.0.6: + resolution: {integrity: sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + ssri@6.0.2: + resolution: {integrity: sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==} + + ssri@8.0.1: + resolution: {integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==} + engines: {node: '>= 8'} + + ssri@9.0.1: + resolution: {integrity: sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + stable-hash@0.0.5: + resolution: {integrity: sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==} + + stable@0.1.8: + resolution: {integrity: sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==} + deprecated: 'Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility' + + stack-utils@2.0.6: + resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} + engines: {node: '>=10'} + + stackframe@1.3.4: + resolution: {integrity: sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==} + + starknet@8.9.2: + resolution: {integrity: sha512-+dp+o2w67fV6JyVOVkYeM1Ec71aORHc/JrF4VHLlfeGee0nLilooCQLE2u6hUcSGQG2x2/fvzkxYpIN+k1JBvA==} + engines: {node: '>=22'} + + state-toggle@1.0.3: + resolution: {integrity: sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==} + + static-extend@0.1.2: + resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} + engines: {node: '>=0.10.0'} + + statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + stop-iteration-iterator@1.1.0: + resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} + engines: {node: '>= 0.4'} + + store2@2.14.4: + resolution: {integrity: sha512-srTItn1GOvyvOycgxjAnPA63FZNwy0PTyUBFMHRM+hVFltAeoh0LmNBz9SZqUS9mMqGk8rfyWyXn3GH5ReJ8Zw==} + + storybook@8.6.18: + resolution: {integrity: sha512-p8seiSI6FiVY6P3V0pG+5v7c8pDMehMAFRWEhG5XqIBSQszzOjDnW2rNvm3odoLKfo3V3P6Cs6Hv9ILzymULyQ==} + hasBin: true + peerDependencies: + prettier: ^2 || ^3 + peerDependenciesMeta: + prettier: + optional: true + + stream-browserify@2.0.2: + resolution: {integrity: sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==} + + stream-each@1.2.3: + resolution: {integrity: sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==} + + stream-http@2.8.3: + resolution: {integrity: sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==} + + stream-shift@1.0.3: + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + + streamsearch@1.1.0: + resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} + engines: {node: '>=10.0.0'} + + string-length@4.0.2: + resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} + engines: {node: '>=10'} + + string-to-color@2.2.2: + resolution: {integrity: sha512-XeA2goP7PNsSlz8RRn6KhYswnMf5Tl+38ajfy8n4oZJyMGC4qqKgHNHsZ/3qwvr42NRIjf9eSr721SyetDeMkA==} + + string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} + + string-width@5.1.2: + resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} + engines: {node: '>=12'} + + string.prototype.includes@2.0.1: + resolution: {integrity: sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg==} + engines: {node: '>= 0.4'} + + string.prototype.matchall@4.0.12: + resolution: {integrity: sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==} + engines: {node: '>= 0.4'} + + string.prototype.padend@3.1.6: + resolution: {integrity: sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q==} + engines: {node: '>= 0.4'} + + string.prototype.padstart@3.1.7: + resolution: {integrity: sha512-hc5ZFzw8H2Bl4AeHxE5s+CniFg+bPcr7lRRS189GCM6KhJQBACNRhtMsdcnpBNbjc1XisnUOqbP0c94RZU4GCw==} + engines: {node: '>= 0.4'} + + string.prototype.repeat@1.0.0: + resolution: {integrity: sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==} + + string.prototype.trim@1.2.10: + resolution: {integrity: sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==} + engines: {node: '>= 0.4'} + + string.prototype.trimend@1.0.9: + resolution: {integrity: sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==} + engines: {node: '>= 0.4'} + + string.prototype.trimstart@1.0.8: + resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} + engines: {node: '>= 0.4'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + + strip-ansi@3.0.1: + resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} + engines: {node: '>=0.10.0'} + + strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} + + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + + strip-bom@2.0.0: + resolution: {integrity: sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==} + engines: {node: '>=0.10.0'} + + strip-bom@3.0.0: + resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} + engines: {node: '>=4'} + + strip-bom@4.0.0: + resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} + engines: {node: '>=8'} + + strip-eof@1.0.0: + resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==} + engines: {node: '>=0.10.0'} + + strip-final-newline@2.0.0: + resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} + engines: {node: '>=6'} + + strip-indent@1.0.1: + resolution: {integrity: sha512-I5iQq6aFMM62fBEAIB/hXzwJD6EEZ0xEGCX2t7oXqaKPIRgt4WruAQ285BISgdkP+HLGWyeGmNJcpIwFeRYRUA==} + engines: {node: '>=0.10.0'} + hasBin: true + + strip-indent@3.0.0: + resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} + engines: {node: '>=8'} + + strip-json-comments@3.1.1: + resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} + engines: {node: '>=8'} + + strong-log-transformer@2.1.0: + resolution: {integrity: sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==} + engines: {node: '>=4'} + hasBin: true + + style-loader@1.3.0: + resolution: {integrity: sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q==} + engines: {node: '>= 8.9.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + + style-loader@2.0.0: + resolution: {integrity: sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ==} + engines: {node: '>= 10.13.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + + style-loader@3.3.4: + resolution: {integrity: sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w==} + engines: {node: '>= 12.13.0'} + peerDependencies: + webpack: ^5.0.0 + + style-to-js@1.1.21: + resolution: {integrity: sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==} + + style-to-object@0.3.0: + resolution: {integrity: sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==} + + style-to-object@1.0.14: + resolution: {integrity: sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==} + + styled-jsx@5.1.1: + resolution: {integrity: sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==} + engines: {node: '>= 12.0.0'} + peerDependencies: + '@babel/core': '*' + babel-plugin-macros: '*' + react: '>= 16.8.0 || 17.x.x || ^18.0.0-0' + peerDependenciesMeta: + '@babel/core': + optional: true + babel-plugin-macros: + optional: true + + stylehacks@5.1.1: + resolution: {integrity: sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw==} + engines: {node: ^10 || ^12 || >=14.0} + peerDependencies: + postcss: ^8.2.15 + + stylehacks@6.1.1: + resolution: {integrity: sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + + stylis@4.2.0: + resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} + + supports-color@5.5.0: + resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} + engines: {node: '>=4'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-hyperlinks@2.3.0: + resolution: {integrity: sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + svg-country-flags@1.2.10: + resolution: {integrity: sha512-xrqwo0TYf/h2cfPvGpjdSuSguUbri4vNNizBnwzoZnX0xGo3O5nGJMlbYEp7NOYcnPGBm6LE2axqDWSB847bLw==} + + svg-parser@2.0.4: + resolution: {integrity: sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ==} + + svgo@2.8.2: + resolution: {integrity: sha512-TyzE4NVGLUFy+H/Uy4N6c3G0HEeprsVfge6Lmq+0FdQQ/zqoVYB62IsBZORsiL+o96s6ff/V6/3UQo/C0cgCAA==} + engines: {node: '>=10.13.0'} + hasBin: true + + svgo@3.3.3: + resolution: {integrity: sha512-+wn7I4p7YgJhHs38k2TNjy1vCfPIfLIJWR5MnCStsN8WuuTcBnRKcMHQLMM2ijxGZmDoZwNv8ipl5aTTen62ng==} + engines: {node: '>=14.0.0'} + hasBin: true + + symbol-observable@2.0.3: + resolution: {integrity: sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA==} + engines: {node: '>=0.10'} + + symbol-tree@3.2.4: + resolution: {integrity: sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==} + + symbol.prototype.description@1.0.7: + resolution: {integrity: sha512-HHGLabwmDRorfrwBGt3dD6iakQ1gNxbNK1jRb3rvr8XVsHmbAzaMdZGJtzL2W8IXdwfm3GEdw27qG86CWpuqOQ==} + engines: {node: '>= 0.4'} + + synchronous-promise@2.0.17: + resolution: {integrity: sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g==} + + tabbable@6.4.0: + resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==} + + tapable@1.1.3: + resolution: {integrity: sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==} + engines: {node: '>=6'} + + tapable@2.3.3: + resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} + engines: {node: '>=6'} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + tar@6.1.11: + resolution: {integrity: sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==} + engines: {node: '>= 10'} + deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + tar@6.2.1: + resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==} + engines: {node: '>=10'} + deprecated: Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me + + telejson@6.0.8: + resolution: {integrity: sha512-nerNXi+j8NK1QEfBHtZUN/aLdDcyupA//9kAboYLrtzZlPLpUfqbVGWb9zz91f/mIjRbAYhbgtnJHY8I1b5MBg==} + + temp-dir@1.0.0: + resolution: {integrity: sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==} + engines: {node: '>=4'} + + terminal-link@2.1.1: + resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==} + engines: {node: '>=8'} + + terser-webpack-plugin@1.4.6: + resolution: {integrity: sha512-2lBVf/VMVIddjSn3GqbT90GvIJ/eYXJkt8cTzU7NbjKqK8fwv18Ftr4PlbF46b/e88743iZFL5Dtr/rC4hjIeA==} + engines: {node: '>= 6.9.0'} + peerDependencies: + webpack: ^4.0.0 + + terser-webpack-plugin@4.2.3: + resolution: {integrity: sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ==} + engines: {node: '>= 10.13.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + + terser-webpack-plugin@5.6.0: + resolution: {integrity: sha512-Eum+5ajkaOhf5KbM26osvv21kLD7BaGqQ1UA4Ami4arYwylmGUQTgHFpHDdmJod1q4QXa66p0to/FBKID+J1vA==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@minify-html/node': '*' + '@swc/core': '*' + '@swc/css': '*' + '@swc/html': '*' + clean-css: '*' + cssnano: '*' + csso: '*' + esbuild: '*' + html-minifier-terser: '*' + lightningcss: '*' + postcss: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@minify-html/node': + optional: true + '@swc/core': + optional: true + '@swc/css': + optional: true + '@swc/html': + optional: true + clean-css: + optional: true + cssnano: + optional: true + csso: + optional: true + esbuild: + optional: true + html-minifier-terser: + optional: true + lightningcss: + optional: true + postcss: + optional: true + uglify-js: + optional: true + + terser@4.8.1: + resolution: {integrity: sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw==} + engines: {node: '>=6.0.0'} + hasBin: true + + terser@5.47.1: + resolution: {integrity: sha512-tPbLXTI6ohPASb/1YViL428oEHu6/qv1OxqYnfaonVCFHqx4+wCd95pHrQWsL5X4pl90CTyW9piSAsS2L0VoMw==} + engines: {node: '>=10'} + hasBin: true + + test-exclude@6.0.0: + resolution: {integrity: sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==} + engines: {node: '>=8'} + + text-extensions@1.9.0: + resolution: {integrity: sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==} + engines: {node: '>=0.10'} + + text-table@0.2.0: + resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + + thread-loader@3.0.4: + resolution: {integrity: sha512-ByaL2TPb+m6yArpqQUZvP+5S1mZtXsEP7nWKKlAUTm7fCml8kB5s1uI3+eHRP2bk5mVYfRSBI7FFf+tWEyLZwA==} + engines: {node: '>= 10.13.0'} + peerDependencies: + webpack: ^4.27.0 || ^5.0.0 + + thread-loader@4.0.4: + resolution: {integrity: sha512-tXagu6Hivd03wB2tiS1bqvw345sc7mKei32EgpYpq31ZLes9FN0mEK2nKzXLRFgwt3PsBB0E/MZDp159rDoqwg==} + engines: {node: '>= 16.10.0'} + peerDependencies: + webpack: ^5.0.0 + + thread-stream@0.15.2: + resolution: {integrity: sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==} + + throat@6.0.2: + resolution: {integrity: sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==} + + through2@2.0.5: + resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} + + through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + + thunky@1.1.0: + resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} + + timers-browserify@2.0.12: + resolution: {integrity: sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==} + engines: {node: '>=0.6.0'} + + tiny-invariant@1.3.3: + resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} + + tiny-secp256k1@1.1.7: + resolution: {integrity: sha512-eb+F6NabSnjbLwNoC+2o5ItbmP1kg7HliWue71JgLegQt6A5mTN8YbvTLCazdlg6e5SV6A+r8OGvZYskdlmhqQ==} + engines: {node: '>=6.0.0'} + + tiny-warning@1.0.3: + resolution: {integrity: sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==} + + tinyglobby@0.2.16: + resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} + engines: {node: '>=12.0.0'} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tldts-core@7.0.30: + resolution: {integrity: sha512-uiHN8PIB1VmWyS98eZYja4xzlYqeFZVjb4OuYlJQnZAuJhMw4PbKQOKgHKhBdJR3FE/t5mUQ1Kd80++B+qhD1Q==} + + tldts@7.0.30: + resolution: {integrity: sha512-ELrFxuqsDdHUwoh0XxDbxuLD3Wnz49Z57IFvTtvWy1hJdcMZjXLIuonjilCiWHlT2GbE4Wlv1wKVTzDFnXH1aw==} + hasBin: true + + tmp@0.2.5: + resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} + engines: {node: '>=14.14'} + + tmpl@1.0.5: + resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + + to-arraybuffer@1.0.1: + resolution: {integrity: sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==} + + to-buffer@1.2.2: + resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} + engines: {node: '>= 0.4'} + + to-object-path@0.3.0: + resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} + engines: {node: '>=0.10.0'} + + to-regex-range@2.1.1: + resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==} + engines: {node: '>=0.10.0'} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + to-regex@3.0.2: + resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} + engines: {node: '>=0.10.0'} + + toggle-selection@1.0.6: + resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + toposort@2.0.2: + resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} + + tough-cookie@4.1.4: + resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} + engines: {node: '>=6'} + + tough-cookie@6.0.1: + resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==} + engines: {node: '>=16'} + + tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + + tr46@2.1.0: + resolution: {integrity: sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==} + engines: {node: '>=8'} + + tr46@6.0.0: + resolution: {integrity: sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw==} + engines: {node: '>=20'} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trim-newlines@1.0.0: + resolution: {integrity: sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw==} + engines: {node: '>=0.10.0'} + + trim-newlines@3.0.1: + resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} + engines: {node: '>=8'} + + trim-trailing-lines@1.1.4: + resolution: {integrity: sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==} + + trim@0.0.1: + resolution: {integrity: sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==} + deprecated: Use String.prototype.trim() instead + + trough@1.0.5: + resolution: {integrity: sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + + ts-api-utils@2.5.0: + resolution: {integrity: sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==} + engines: {node: '>=18.12'} + peerDependencies: + typescript: '>=4.8.4' + + ts-dedent@2.2.0: + resolution: {integrity: sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==} + engines: {node: '>=6.10'} + + ts-jest@27.1.5: + resolution: {integrity: sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA==} + engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@types/jest': ^27.0.0 + babel-jest: '>=27.0.0 <28' + esbuild: '*' + jest: ^27.0.0 + typescript: '>=3.8 <5.0' + peerDependenciesMeta: + '@babel/core': + optional: true + '@types/jest': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + + ts-jest@29.4.9: + resolution: {integrity: sha512-LTb9496gYPMCqjeDLdPrKuXtncudeV1yRZnF4Wo5l3SFi0RYEnYRNgMrFIdg+FHvfzjCyQk1cLncWVqiSX+EvQ==} + engines: {node: ^14.15.0 || ^16.10.0 || ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@babel/core': '>=7.0.0-beta.0 <8' + '@jest/transform': ^29.0.0 || ^30.0.0 + '@jest/types': ^29.0.0 || ^30.0.0 + babel-jest: ^29.0.0 || ^30.0.0 + esbuild: '*' + jest: ^29.0.0 || ^30.0.0 + jest-util: ^29.0.0 || ^30.0.0 + typescript: '>=4.3 <7' + peerDependenciesMeta: + '@babel/core': + optional: true + '@jest/transform': + optional: true + '@jest/types': + optional: true + babel-jest: + optional: true + esbuild: + optional: true + jest-util: + optional: true + + ts-loader@9.5.7: + resolution: {integrity: sha512-/ZNrKgA3K3PtpMYOC71EeMWIloGw3IYEa5/t1cyz2r5/PyUwTXGzYJvcD3kfUvmhlfpz1rhV8B2O6IVTQ0avsg==} + engines: {node: '>=12.0.0'} + peerDependencies: + typescript: '*' + webpack: ^5.0.0 + + ts-mixer@6.0.4: + resolution: {integrity: sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==} + + ts-pnp@1.2.0: + resolution: {integrity: sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==} + engines: {node: '>=6'} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + + tsconfig-paths-webpack-plugin@3.5.2: + resolution: {integrity: sha512-EhnfjHbzm5IYI9YPNVIxx1moxMI4bpHD2e0zTXeDNQcwjjRaGepP7IhTHJkyDBG0CAOoxRfe7jCG630Ou+C6Pw==} + + tsconfig-paths-webpack-plugin@4.2.0: + resolution: {integrity: sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA==} + engines: {node: '>=10.13.0'} + + tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + + tsconfig-paths@4.2.0: + resolution: {integrity: sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==} + engines: {node: '>=6'} + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tslog@3.3.3: + resolution: {integrity: sha512-lGrkndwpAohZ9ntQpT+xtUw5k9YFV1DjsksiWQlBSf82TTqsSAWBARPRD9juI730r8o3Awpkjp2aXy9k+6vr+g==} + engines: {node: '>=10'} + + tsutils@3.21.0: + resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} + engines: {node: '>= 6'} + peerDependencies: + typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' + + tty-browserify@0.0.0: + resolution: {integrity: sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==} + + tuf-js@1.1.7: + resolution: {integrity: sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + tweetnacl-util@0.15.1: + resolution: {integrity: sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw==} + + tweetnacl@1.0.3: + resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} + + type-check@0.4.0: + resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} + engines: {node: '>= 0.8.0'} + + type-detect@4.0.8: + resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} + engines: {node: '>=4'} + + type-fest@0.18.1: + resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==} + engines: {node: '>=10'} + + type-fest@0.20.2: + resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} + engines: {node: '>=10'} + + type-fest@0.21.3: + resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} + engines: {node: '>=10'} + + type-fest@0.4.1: + resolution: {integrity: sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw==} + engines: {node: '>=6'} + + type-fest@0.6.0: + resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} + engines: {node: '>=8'} + + type-fest@0.8.1: + resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} + engines: {node: '>=8'} + + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + typed-array-buffer@1.0.3: + resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} + engines: {node: '>= 0.4'} + + typed-array-byte-length@1.0.3: + resolution: {integrity: sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg==} + engines: {node: '>= 0.4'} + + typed-array-byte-offset@1.0.4: + resolution: {integrity: sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ==} + engines: {node: '>= 0.4'} + + typed-array-length@1.0.7: + resolution: {integrity: sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==} + engines: {node: '>= 0.4'} + + typedarray-to-buffer@3.1.5: + resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} + + typedarray@0.0.6: + resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + + typeforce@1.18.0: + resolution: {integrity: sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==} + + typescript@4.9.5: + resolution: {integrity: sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==} + engines: {node: '>=4.2.0'} + hasBin: true + + typescript@5.9.3: + resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} + engines: {node: '>=14.17'} + hasBin: true + + ufo@1.6.4: + resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} + + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + + unbox-primitive@1.1.0: + resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} + engines: {node: '>= 0.4'} + + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + + undici-types@6.21.0: + resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + + undici@7.25.0: + resolution: {integrity: sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==} + engines: {node: '>=20.18.1'} + + unfetch@4.2.0: + resolution: {integrity: sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==} + + unherit@1.1.3: + resolution: {integrity: sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==} + + unicode-canonical-property-names-ecmascript@2.0.1: + resolution: {integrity: sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==} + engines: {node: '>=4'} + + unicode-match-property-ecmascript@2.0.0: + resolution: {integrity: sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==} + engines: {node: '>=4'} + + unicode-match-property-value-ecmascript@2.2.1: + resolution: {integrity: sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg==} + engines: {node: '>=4'} + + unicode-property-aliases-ecmascript@2.2.0: + resolution: {integrity: sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ==} + engines: {node: '>=4'} + + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unified@9.2.0: + resolution: {integrity: sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==} + + union-value@1.0.1: + resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} + engines: {node: '>=0.10.0'} + + unique-filename@1.1.1: + resolution: {integrity: sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==} + + unique-filename@2.0.1: + resolution: {integrity: sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + unique-filename@3.0.0: + resolution: {integrity: sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + unique-slug@2.0.2: + resolution: {integrity: sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==} + + unique-slug@3.0.0: + resolution: {integrity: sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + unique-slug@4.0.0: + resolution: {integrity: sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + unist-builder@2.0.3: + resolution: {integrity: sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw==} + + unist-util-generated@1.1.6: + resolution: {integrity: sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg==} + + unist-util-is@4.1.0: + resolution: {integrity: sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-position@3.1.0: + resolution: {integrity: sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-remove-position@2.0.1: + resolution: {integrity: sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA==} + + unist-util-remove@2.1.0: + resolution: {integrity: sha512-J8NYPyBm4baYLdCbjmf1bhPu45Cr1MWTm77qd9istEkzWpnN6O9tMsEbB2JhNnBCqGENRqEWomQ+He6au0B27Q==} + + unist-util-stringify-position@2.0.3: + resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@3.1.1: + resolution: {integrity: sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@2.0.3: + resolution: {integrity: sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + + universal-user-agent@6.0.1: + resolution: {integrity: sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ==} + + universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + unrs-resolver@1.11.1: + resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + + unset-value@1.0.0: + resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} + engines: {node: '>=0.10.0'} + + unstorage@1.17.5: + resolution: {integrity: sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==} + peerDependencies: + '@azure/app-configuration': ^1.8.0 + '@azure/cosmos': ^4.2.0 + '@azure/data-tables': ^13.3.0 + '@azure/identity': ^4.6.0 + '@azure/keyvault-secrets': ^4.9.0 + '@azure/storage-blob': ^12.26.0 + '@capacitor/preferences': ^6 || ^7 || ^8 + '@deno/kv': '>=0.9.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.34.3 + '@vercel/blob': '>=0.27.1' + '@vercel/functions': ^2.2.12 || ^3.0.0 + '@vercel/kv': ^1 || ^2 || ^3 + aws4fetch: ^1.0.20 + db0: '>=0.2.1' + idb-keyval: ^6.2.1 + ioredis: ^5.4.2 + uploadthing: ^7.4.4 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@deno/kv': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/blob': + optional: true + '@vercel/functions': + optional: true + '@vercel/kv': + optional: true + aws4fetch: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + uploadthing: + optional: true + + untildify@2.1.0: + resolution: {integrity: sha512-sJjbDp2GodvkB0FZZcn7k6afVisqX5BZD7Yq3xp4nN2O15BBK0cLm3Vwn2vQaF7UDS0UUsrQMkkplmDI5fskig==} + engines: {node: '>=0.10.0'} + + upath@1.2.0: + resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} + engines: {node: '>=4'} + + upath@2.0.1: + resolution: {integrity: sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==} + engines: {node: '>=4'} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + uri-js@4.4.1: + resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + + urix@0.1.0: + resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} + deprecated: Please see https://github.com/lydell/urix#deprecated + + url-loader@4.1.1: + resolution: {integrity: sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==} + engines: {node: '>= 10.13.0'} + peerDependencies: + file-loader: '*' + webpack: ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + file-loader: + optional: true + + url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + + url@0.11.4: + resolution: {integrity: sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg==} + engines: {node: '>= 0.4'} + + use-clipboard-copy@0.2.0: + resolution: {integrity: sha512-f0PMMwZ2/Hh9/54L12capx4s6ASdd6edNJxg2OcqWVNM8BPvtOSmNFIN1Dg/q//fPp8MpUZceHfr7cnWOS0RxA==} + peerDependencies: + react: '>=16.8.0' + + use-sync-external-store@1.6.0: + resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + + use@3.1.1: + resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} + engines: {node: '>=0.10.0'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + util.promisify@1.0.0: + resolution: {integrity: sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==} + + util@0.10.4: + resolution: {integrity: sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==} + + util@0.11.1: + resolution: {integrity: sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==} + + util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + + utila@0.4.0: + resolution: {integrity: sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==} + + utility-types@3.11.0: + resolution: {integrity: sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw==} + engines: {node: '>= 4'} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + uuid-browser@3.1.0: + resolution: {integrity: sha512-dsNgbLaTrd6l3MMxTtouOCFw4CBFc/3a+GgYA2YyrJvyQ1u6q4pcu3ktLoUZ/VN/Aw9WsauazbgsgdfVWgAKQg==} + deprecated: Package no longer supported and required. Use the uuid package or crypto.randomUUID instead + + uuid@11.1.1: + resolution: {integrity: sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==} + hasBin: true + + uuid@3.4.0: + resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} + 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). + hasBin: true + + uuid@8.3.2: + resolution: {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). + hasBin: true + + uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + 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). + hasBin: true + + v8-compile-cache@2.3.0: + resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} + + v8-to-istanbul@8.1.1: + resolution: {integrity: sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==} + engines: {node: '>=10.12.0'} + + v8-to-istanbul@9.3.0: + resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} + engines: {node: '>=10.12.0'} + + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + + validate-npm-package-name@3.0.0: + resolution: {integrity: sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==} + + validate-npm-package-name@5.0.0: + resolution: {integrity: sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + vfile-location@3.2.0: + resolution: {integrity: sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==} + + vfile-message@2.0.4: + resolution: {integrity: sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@4.2.1: + resolution: {integrity: sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + + victory-vendor@36.9.2: + resolution: {integrity: sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ==} + + vm-browserify@1.1.2: + resolution: {integrity: sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==} + + void-elements@3.1.0: + resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} + engines: {node: '>=0.10.0'} + + w3c-hr-time@1.0.2: + resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} + deprecated: Use your platform's native performance.now() and performance.timeOrigin. + + w3c-xmlserializer@2.0.0: + resolution: {integrity: sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==} + engines: {node: '>=10'} + + w3c-xmlserializer@5.0.0: + resolution: {integrity: sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==} + engines: {node: '>=18'} + + walker@1.0.8: + resolution: {integrity: sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==} + + watchpack-chokidar2@2.0.1: + resolution: {integrity: sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww==} + + watchpack@1.7.5: + resolution: {integrity: sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ==} + + watchpack@2.5.1: + resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} + engines: {node: '>=10.13.0'} + + wbuf@1.7.3: + resolution: {integrity: sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==} + + wcwidth@1.0.1: + resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + + web-namespaces@1.1.4: + resolution: {integrity: sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==} + + webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + + webidl-conversions@5.0.0: + resolution: {integrity: sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==} + engines: {node: '>=8'} + + webidl-conversions@6.1.0: + resolution: {integrity: sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==} + engines: {node: '>=10.4'} + + webidl-conversions@8.0.1: + resolution: {integrity: sha512-BMhLD/Sw+GbJC21C/UgyaZX41nPt8bUTg+jWyDeg7e7YN4xOM05YPSIXceACnXVtqyEw/LMClUQMtMZ+PGGpqQ==} + engines: {node: '>=20'} + + webpack-cli@4.10.0: + resolution: {integrity: sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + '@webpack-cli/generators': '*' + '@webpack-cli/migrate': '*' + webpack: 4.x.x || 5.x.x + webpack-bundle-analyzer: '*' + webpack-dev-server: '*' + peerDependenciesMeta: + '@webpack-cli/generators': + optional: true + '@webpack-cli/migrate': + optional: true + webpack-bundle-analyzer: + optional: true + webpack-dev-server: + optional: true + + webpack-cli@5.1.4: + resolution: {integrity: sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==} + engines: {node: '>=14.15.0'} + hasBin: true + peerDependencies: + '@webpack-cli/generators': '*' + webpack: 5.x.x + webpack-bundle-analyzer: '*' + webpack-dev-server: '*' + peerDependenciesMeta: + '@webpack-cli/generators': + optional: true + webpack-bundle-analyzer: + optional: true + webpack-dev-server: + optional: true + + webpack-dev-middleware@3.7.3: + resolution: {integrity: sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==} + engines: {node: '>= 6'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + + webpack-dev-middleware@4.3.0: + resolution: {integrity: sha512-PjwyVY95/bhBh6VUqt6z4THplYcsvQ8YNNBTBM873xLVmw8FLeALn0qurHbs9EmcfhzQis/eoqypSnZeuUz26w==} + engines: {node: '>= v10.23.3'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + + webpack-dev-middleware@5.3.4: + resolution: {integrity: sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q==} + engines: {node: '>= 12.13.0'} + peerDependencies: + webpack: ^4.0.0 || ^5.0.0 + + webpack-dev-server@4.15.2: + resolution: {integrity: sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g==} + engines: {node: '>= 12.13.0'} + hasBin: true + peerDependencies: + webpack: ^4.37.0 || ^5.0.0 + webpack-cli: '*' + peerDependenciesMeta: + webpack: + optional: true + webpack-cli: + optional: true + + webpack-favicons@1.5.43: + resolution: {integrity: sha512-prAavTPgWzn8c7uc9s6XQEqywdyg5wa1jzmGbd3nn6fE1G2OXMl14PcprYB2xa/+b/Kplndd48oLbt8Nc6MwQw==} + engines: {node: '>=18.17.0'} + + webpack-filter-warnings-plugin@1.2.1: + resolution: {integrity: sha512-Ez6ytc9IseDMLPo0qCuNNYzgtUl8NovOqjIq4uAU8LTD4uoa1w1KpZyyzFtLTEMZpkkOkLfL9eN+KGYdk1Qtwg==} + engines: {node: '>= 4.3 < 5.0.0 || >= 5.10'} + peerDependencies: + webpack: ^2.0.0 || ^3.0.0 || ^4.0.0 + + webpack-hot-middleware@2.26.1: + resolution: {integrity: sha512-khZGfAeJx6I8K9zKohEWWYN6KDlVw2DHownoe+6Vtwj1LP9WFgegXnVMSkZ/dBEBtXFwrkkydsaPFlB7f8wU2A==} + + webpack-log@2.0.0: + resolution: {integrity: sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==} + engines: {node: '>= 6'} + + webpack-merge@5.10.0: + resolution: {integrity: sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==} + engines: {node: '>=10.0.0'} + + webpack-sources@1.4.3: + resolution: {integrity: sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==} + + webpack-sources@3.4.1: + resolution: {integrity: sha512-eACpxRN02yaawnt+uUNIF7Qje6A9zArxBbcAJjK1PK3S9Ycg5jIuJ8pW4q8EMnwNZCEGltcjkRx1QzOxOkKD8A==} + engines: {node: '>=10.13.0'} + + webpack-virtual-modules@0.2.2: + resolution: {integrity: sha512-kDUmfm3BZrei0y+1NTHJInejzxfhtU8eDj2M7OKb2IWrPFAeO1SOH2KuQ68MSZu9IGEHcxbkKKR1v18FrUSOmA==} + + webpack-virtual-modules@0.4.6: + resolution: {integrity: sha512-5tyDlKLqPfMqjT3Q9TAqf2YqjwmnUleZwzJi1A5qXnlBCdj2AtOJ6wAWdglTIDOPgOiOrXeBeFcsQ8+aGQ6QbA==} + + webpack@4.47.0: + resolution: {integrity: sha512-td7fYwgLSrky3fI1EuU5cneU4+pbH6GgOfuKNS1tNPcfdGinGELAqsb/BP4nnvZyKSG2i/xFGU7+n2PvZA8HJQ==} + engines: {node: '>=6.11.5'} + hasBin: true + peerDependencies: + webpack-cli: '*' + webpack-command: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + webpack-command: + optional: true + + webpack@5.106.2: + resolution: {integrity: sha512-wGN3qcrBQIFmQ/c0AiOAQBvrZ5lmY8vbbMv4Mxfgzqd/B6+9pXtLo73WuS1dSGXM5QYY3hZnIbvx+K1xxe6FyA==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + + websocket-driver@0.7.4: + resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} + engines: {node: '>=0.8.0'} + + websocket-extensions@0.1.4: + resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==} + engines: {node: '>=0.8.0'} + + whatwg-encoding@1.0.5: + resolution: {integrity: sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==} + deprecated: Use @exodus/bytes instead for a more spec-conformant and faster implementation + + whatwg-mimetype@2.3.0: + resolution: {integrity: sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==} + + whatwg-mimetype@5.0.0: + resolution: {integrity: sha512-sXcNcHOC51uPGF0P/D4NVtrkjSU2fNsm9iog4ZvZJsL3rjoDAzXZhkm2MWt1y+PUdggKAYVoMAIYcs78wJ51Cw==} + engines: {node: '>=20'} + + whatwg-url@16.0.1: + resolution: {integrity: sha512-1to4zXBxmXHV3IiSSEInrreIlu02vUOvrhxJJH5vcxYTBDAx51cqZiKdyTxlecdKNSjj8EcxGBxNf6Vg+945gw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} + + whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + + whatwg-url@8.7.0: + resolution: {integrity: sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==} + engines: {node: '>=10'} + + which-boxed-primitive@1.1.1: + resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==} + engines: {node: '>= 0.4'} + + which-builtin-type@1.2.1: + resolution: {integrity: sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q==} + engines: {node: '>= 0.4'} + + which-collection@1.0.2: + resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} + engines: {node: '>= 0.4'} + + which-typed-array@1.1.20: + resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} + engines: {node: '>= 0.4'} + + which@1.3.1: + resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} + hasBin: true + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + which@3.0.1: + resolution: {integrity: sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + hasBin: true + + wide-align@1.1.5: + resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} + + widest-line@3.1.0: + resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==} + engines: {node: '>=8'} + + wif@2.0.6: + resolution: {integrity: sha512-HIanZn1zmduSF+BQhkE+YXIbEiH0xPr1012QbFEGB0xsKqJii0/SqJjyn8dFv6y36kOznMgMB+LGcbZTJ1xACQ==} + + wildcard@2.0.1: + resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} + + word-wrap@1.2.5: + resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} + engines: {node: '>=0.10.0'} + + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + + worker-farm@1.7.0: + resolution: {integrity: sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==} + + worker-rpc@0.1.1: + resolution: {integrity: sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg==} + + world-countries@5.1.0: + resolution: {integrity: sha512-CXR6EBvTbArDlDDIWU3gfKb7Qk0ck2WNZ234b/A0vuecPzIfzzxH+O6Ejnvg1sT8XuiZjVlzOH0h08ZtaO7g0w==} + + wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + + wrap-ansi@7.0.0: + resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} + engines: {node: '>=10'} + + wrap-ansi@8.1.0: + resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} + engines: {node: '>=12'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + write-file-atomic@2.4.3: + resolution: {integrity: sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==} + + write-file-atomic@3.0.3: + resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} + + write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + + write-file-atomic@5.0.1: + resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + + write-json-file@3.2.0: + resolution: {integrity: sha512-3xZqT7Byc2uORAatYiP3DHUUAVEkNOswEWNs9H5KXiicRTvzYzYqKjYc4G7p+8pltvAw641lVByKVtMpf+4sYQ==} + engines: {node: '>=6'} + + write-pkg@4.0.0: + resolution: {integrity: sha512-v2UQ+50TNf2rNHJ8NyWttfm/EJUBWMJcx6ZTYZr6Qp52uuegWw/lBkCtCbnYZEmPRNL61m+u67dAmGxo+HTULA==} + engines: {node: '>=8'} + + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + 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 + + ws@8.20.1: + resolution: {integrity: sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==} + 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 + + x-default-browser@0.4.0: + resolution: {integrity: sha512-7LKo7RtWfoFN/rHx1UELv/2zHGMx8MkZKDq1xENmOCTkfIqZJ0zZ26NEJX8czhnPXVcqS0ARjjfJB+eJ0/5Cvw==} + hasBin: true + + xml-name-validator@3.0.0: + resolution: {integrity: sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==} + + xml-name-validator@5.0.0: + resolution: {integrity: sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==} + engines: {node: '>=18'} + + xml2js@0.6.2: + resolution: {integrity: sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==} + engines: {node: '>=4.0.0'} + + xmlbuilder@11.0.1: + resolution: {integrity: sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==} + engines: {node: '>=4.0'} + + xmlchars@2.2.0: + resolution: {integrity: sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==} + + xstream@11.14.0: + resolution: {integrity: sha512-1bLb+kKKtKPbgTK6i/BaoAn03g47PpFstlbe1BA+y3pNS/LfvcaghS5BFf9+EE1J+KwSQsEpfJvFN5GqFtiNmw==} + + xtend@4.0.2: + resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} + engines: {node: '>=0.4'} + + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yallist@3.1.1: + resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} + + yallist@4.0.0: + resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} + + yaml@1.10.3: + resolution: {integrity: sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==} + engines: {node: '>= 6'} + + yargs-parser@20.2.4: + resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} + engines: {node: '>=10'} + + yargs-parser@20.2.9: + resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} + engines: {node: '>=10'} + + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + + yargs@16.2.0: + resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} + engines: {node: '>=10'} + + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + + yocto-queue@0.1.0: + resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} + engines: {node: '>=10'} + + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} + engines: {node: '>=12.20'} + + yup@0.32.11: + resolution: {integrity: sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==} + engines: {node: '>=10'} + + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + + zustand@4.5.7: + resolution: {integrity: sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==} + engines: {node: '>=12.7.0'} + peerDependencies: + '@types/react': '>=16.8' + immer: '>=9.0.6' + react: '>=16.8' + peerDependenciesMeta: + '@types/react': + optional: true + immer: + optional: true + react: + optional: true + + zwitch@1.0.5: + resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + + zxcvbn@4.4.2: + resolution: {integrity: sha512-Bq0B+ixT/DMyG8kgX2xWcI5jUvCwqrMxSFam7m0lAf78nf04hv6lNCsyLYdyYTrCVMqNDY/206K7eExYCeSyUQ==} + +snapshots: + + '@acemir/cssom@0.9.31': {} + + '@adobe/css-tools@4.4.4': {} + + '@asamuzakjp/css-color@5.1.11': + dependencies: + '@asamuzakjp/generational-cache': 1.0.1 + '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-color-parser': 4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) + '@csstools/css-tokenizer': 4.0.0 + + '@asamuzakjp/dom-selector@6.8.1': + dependencies: + '@asamuzakjp/nwsapi': 2.3.9 + bidi-js: 1.0.3 + css-tree: 3.2.1 + is-potential-custom-element-name: 1.0.1 + lru-cache: 11.3.6 + + '@asamuzakjp/generational-cache@1.0.1': {} + + '@asamuzakjp/nwsapi@2.3.9': {} + + '@babel/code-frame@7.29.0': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + js-tokens: 4.0.0 + picocolors: 1.1.1 + + '@babel/compat-data@7.29.3': {} + + '@babel/core@7.12.9': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.12.9) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.3 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + convert-source-map: 1.9.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + lodash: 4.18.1 + resolve: 1.22.12 + semver: 5.7.2 + source-map: 0.5.7 + transitivePeerDependencies: + - supports-color + + '@babel/core@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helpers': 7.29.2 + '@babel/parser': 7.29.3 + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jridgewell/remapping': 2.3.5 + convert-source-map: 2.0.0 + debug: 4.4.3 + gensync: 1.0.0-beta.2 + json5: 2.2.3 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/generator@7.29.1': + dependencies: + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 3.1.0 + + '@babel/helper-annotate-as-pure@7.27.3': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-compilation-targets@7.28.6': + dependencies: + '@babel/compat-data': 7.29.3 + '@babel/helper-validator-option': 7.27.1 + browserslist: 4.28.2 + lru-cache: 5.1.1 + semver: 6.3.1 + + '@babel/helper-create-class-features-plugin@7.29.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@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.28.6(@babel/core@7.29.0) + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/traverse': 7.29.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-create-regexp-features-plugin@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + regexpu-core: 6.4.0 + semver: 6.3.1 + + '@babel/helper-define-polyfill-provider@0.1.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + debug: 4.4.3 + lodash.debounce: 4.0.8 + resolve: 1.22.12 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/helper-define-polyfill-provider@0.6.8(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + debug: 4.4.3 + lodash.debounce: 4.0.8 + resolve: 1.22.12 + transitivePeerDependencies: + - supports-color + + '@babel/helper-globals@7.28.0': {} + + '@babel/helper-member-expression-to-functions@7.28.5': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-imports@7.28.6': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.12.9)': + dependencies: + '@babel/core': 7.12.9 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-module-transforms@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-optimise-call-expression@7.27.1': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-plugin-utils@7.10.4': {} + + '@babel/helper-plugin-utils@7.28.6': {} + + '@babel/helper-remap-async-to-generator@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-wrap-function': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-replace-supers@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-member-expression-to-functions': 7.28.5 + '@babel/helper-optimise-call-expression': 7.27.1 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-simple-access@7.27.1': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-skip-transparent-expression-wrappers@7.27.1': + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helper-string-parser@7.27.1': {} + + '@babel/helper-validator-identifier@7.28.5': {} + + '@babel/helper-validator-option@7.27.1': {} + + '@babel/helper-wrap-function@7.28.6': + dependencies: + '@babel/template': 7.28.6 + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/helpers@7.29.2': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + + '@babel/parser@7.29.3': + dependencies: + '@babel/types': 7.29.0 + + '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-safari-class-field-initializer-scope@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array@7.29.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.29.3(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-decorators@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.29.3(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-decorators': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-export-default-from@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.29.0) + + '@babel/plugin-proposal-object-rest-spread@7.12.1(@babel/core@7.12.9)': + dependencies: + '@babel/core': 7.12.9 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.12.9) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.12.9) + + '@babel/plugin-proposal-object-rest-spread@7.20.7(@babel/core@7.29.0)': + dependencies: + '@babel/compat-data': 7.29.3 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + + '@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.29.3(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@babel/plugin-proposal-private-property-in-object@7.21.11(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.29.3(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-bigint@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-decorators@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-flow@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-import-assertions@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-import-attributes@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-import-meta@7.10.4(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-jsx@7.12.1(@babel/core@7.12.9)': + dependencies: + '@babel/core': 7.12.9 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-jsx@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.12.9)': + dependencies: + '@babel/core': 7.12.9 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-typescript@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-syntax-unicode-sets-regex@7.18.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-arrow-functions@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-async-generator-functions@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-async-to-generator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-block-scoped-functions@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-block-scoping@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-class-properties@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.29.3(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-class-static-block@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.29.3(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-classes@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-globals': 7.28.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-computed-properties@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/template': 7.28.6 + + '@babel/plugin-transform-destructuring@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-dotall-regex@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-duplicate-keys@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-duplicate-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-dynamic-import@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-explicit-resource-management@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-exponentiation-operator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-export-namespace-from@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-flow-strip-types@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-flow': 7.28.6(@babel/core@7.29.0) + + '@babel/plugin-transform-for-of@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-function-name@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-json-strings@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-logical-assignment-operators@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-member-expression-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-modules-amd@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-commonjs@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-systemjs@7.29.4(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-identifier': 7.28.5 + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-modules-umd@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-module-transforms': 7.28.6(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-named-capturing-groups-regex@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-new-target@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-nullish-coalescing-operator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-numeric-separator@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-object-rest-spread@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-object-super@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-replace-supers': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-optional-catch-binding@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-optional-chaining@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.12.9)': + dependencies: + '@babel/core': 7.12.9 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-parameters@7.27.7(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-private-methods@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-class-features-plugin': 7.29.3(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-private-property-in-object@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.29.3(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-property-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-react-constant-elements@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-react-display-name@7.28.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-react-jsx-development@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-react-jsx@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-module-imports': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/types': 7.29.0 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-react-pure-annotations@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-regenerator@7.29.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-regexp-modifiers@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-reserved-words@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-shorthand-properties@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-spread@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-sticky-regex@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-template-literals@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-typeof-symbol@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-typescript@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-annotate-as-pure': 7.27.3 + '@babel/helper-create-class-features-plugin': 7.29.3(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/plugin-transform-unicode-escapes@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-property-regex@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-regex@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/plugin-transform-unicode-sets-regex@7.28.6(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-create-regexp-features-plugin': 7.28.5(@babel/core@7.29.0) + '@babel/helper-plugin-utils': 7.28.6 + + '@babel/preset-env@7.29.5(@babel/core@7.29.0)': + dependencies: + '@babel/compat-data': 7.29.3 + '@babel/core': 7.29.0 + '@babel/helper-compilation-targets': 7.28.6 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-bugfix-firefox-class-in-computed-class-key': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-bugfix-safari-class-field-initializer-scope': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-safari-rest-destructuring-rhs-array': 7.29.3(@babel/core@7.29.0) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-proposal-private-property-in-object': 7.21.0-placeholder-for-preset-env.2(@babel/core@7.29.0) + '@babel/plugin-syntax-import-assertions': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-unicode-sets-regex': 7.18.6(@babel/core@7.29.0) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-async-generator-functions': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-async-to-generator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoped-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-class-static-block': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-classes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-computed-properties': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-dotall-regex': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-duplicate-keys': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-duplicate-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-explicit-resource-management': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-exponentiation-operator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-export-namespace-from': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-function-name': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-json-strings': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-logical-assignment-operators': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-member-expression-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-amd': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-systemjs': 7.29.4(@babel/core@7.29.0) + '@babel/plugin-transform-modules-umd': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-named-capturing-groups-regex': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-new-target': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-nullish-coalescing-operator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-numeric-separator': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-object-rest-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-object-super': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-optional-catch-binding': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-optional-chaining': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/plugin-transform-private-methods': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-private-property-in-object': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-property-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-regenerator': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-transform-regexp-modifiers': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-reserved-words': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-spread': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-sticky-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-typeof-symbol': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-escapes': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-property-regex': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-regex': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-unicode-sets-regex': 7.28.6(@babel/core@7.29.0) + '@babel/preset-modules': 0.1.6-no-external-plugins(@babel/core@7.29.0) + babel-plugin-polyfill-corejs2: 0.4.17(@babel/core@7.29.0) + babel-plugin-polyfill-corejs3: 0.14.2(@babel/core@7.29.0) + babel-plugin-polyfill-regenerator: 0.6.8(@babel/core@7.29.0) + core-js-compat: 3.49.0 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + '@babel/preset-flow@7.27.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-transform-flow-strip-types': 7.27.1(@babel/core@7.29.0) + + '@babel/preset-modules@0.1.6-no-external-plugins(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/types': 7.29.0 + esutils: 2.0.3 + + '@babel/preset-react@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-transform-react-display-name': 7.28.0(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-react-jsx-development': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-react-pure-annotations': 7.27.1(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/preset-typescript@7.28.5(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-plugin-utils': 7.28.6 + '@babel/helper-validator-option': 7.27.1 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-modules-commonjs': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-typescript': 7.28.6(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + '@babel/register@7.29.3(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + clone-deep: 4.0.1 + find-cache-dir: 2.1.0 + make-dir: 2.1.0 + pirates: 4.0.7 + source-map-support: 0.5.21 + + '@babel/runtime@7.29.2': {} + + '@babel/runtime@7.5.5': + dependencies: + regenerator-runtime: 0.13.11 + + '@babel/runtime@7.7.2': + dependencies: + regenerator-runtime: 0.13.11 + + '@babel/template@7.28.6': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + + '@babel/traverse@7.29.0': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-globals': 7.28.0 + '@babel/parser': 7.29.3 + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + '@babel/types@7.29.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + + '@base2/pretty-print-object@1.0.1': {} + + '@bcoe/v8-coverage@0.2.3': {} + + '@biomejs/biome@1.9.4': + optionalDependencies: + '@biomejs/cli-darwin-arm64': 1.9.4 + '@biomejs/cli-darwin-x64': 1.9.4 + '@biomejs/cli-linux-arm64': 1.9.4 + '@biomejs/cli-linux-arm64-musl': 1.9.4 + '@biomejs/cli-linux-x64': 1.9.4 + '@biomejs/cli-linux-x64-musl': 1.9.4 + '@biomejs/cli-win32-arm64': 1.9.4 + '@biomejs/cli-win32-x64': 1.9.4 + + '@biomejs/cli-darwin-arm64@1.9.4': + optional: true + + '@biomejs/cli-darwin-x64@1.9.4': + optional: true + + '@biomejs/cli-linux-arm64-musl@1.9.4': + optional: true + + '@biomejs/cli-linux-arm64@1.9.4': + optional: true + + '@biomejs/cli-linux-x64-musl@1.9.4': + optional: true + + '@biomejs/cli-linux-x64@1.9.4': + optional: true + + '@biomejs/cli-win32-arm64@1.9.4': + optional: true + + '@biomejs/cli-win32-x64@1.9.4': + optional: true + + '@bramus/specificity@2.4.2': + dependencies: + css-tree: 3.2.1 + + '@chain-registry/client@1.53.356(encoding@0.1.13)': + dependencies: + '@chain-registry/types': 0.50.356 + '@chain-registry/utils': 1.51.356 + bfs-path: 1.0.2 + cross-fetch: 3.2.0(encoding@0.1.13) + transitivePeerDependencies: + - encoding + + '@chain-registry/keplr@1.74.578': + dependencies: + '@chain-registry/types': 0.50.356 + '@keplr-wallet/cosmos': 0.12.28 + '@keplr-wallet/crypto': 0.12.28 + semver: 7.8.0 + + '@chain-registry/types@0.46.15': {} + + '@chain-registry/types@0.50.356': {} + + '@chain-registry/utils@1.51.356': + dependencies: + '@chain-registry/types': 0.50.356 + bignumber.js: 9.1.2 + sha.js: 2.4.12 + + '@cnakazawa/watch@1.0.4': + dependencies: + exec-sh: 0.3.6 + minimist: 1.2.8 + + '@colors/colors@1.5.0': + optional: true + + '@confio/ics23@0.6.8': + dependencies: + '@noble/hashes': 1.8.0 + protobufjs: 6.11.6 + + '@cosmjs/amino@0.25.6': + dependencies: + '@cosmjs/crypto': 0.25.6 + '@cosmjs/encoding': 0.25.6 + '@cosmjs/math': 0.25.6 + '@cosmjs/utils': 0.25.6 + + '@cosmjs/amino@0.32.4': + dependencies: + '@cosmjs/crypto': 0.32.4 + '@cosmjs/encoding': 0.32.4 + '@cosmjs/math': 0.32.4 + '@cosmjs/utils': 0.32.4 + + '@cosmjs/amino@0.36.2': + dependencies: + '@cosmjs/crypto': 0.36.2 + '@cosmjs/encoding': 0.36.2 + '@cosmjs/math': 0.36.2 + '@cosmjs/utils': 0.36.2 + + '@cosmjs/cosmwasm-launchpad@0.25.6': + dependencies: + '@cosmjs/crypto': 0.25.6 + '@cosmjs/encoding': 0.25.6 + '@cosmjs/launchpad': 0.25.6 + '@cosmjs/math': 0.25.6 + '@cosmjs/utils': 0.25.6 + pako: 2.1.0 + transitivePeerDependencies: + - debug + + '@cosmjs/cosmwasm-stargate@0.25.6': + dependencies: + '@cosmjs/amino': 0.25.6 + '@cosmjs/cosmwasm-launchpad': 0.25.6 + '@cosmjs/crypto': 0.25.6 + '@cosmjs/encoding': 0.25.6 + '@cosmjs/math': 0.25.6 + '@cosmjs/proto-signing': 0.25.6 + '@cosmjs/stargate': 0.25.6 + '@cosmjs/tendermint-rpc': 0.25.6 + '@cosmjs/utils': 0.25.6 + long: 4.0.0 + pako: 2.1.0 + protobufjs: 6.10.3 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + + '@cosmjs/cosmwasm-stargate@0.32.4': + dependencies: + '@cosmjs/amino': 0.32.4 + '@cosmjs/crypto': 0.32.4 + '@cosmjs/encoding': 0.32.4 + '@cosmjs/math': 0.32.4 + '@cosmjs/proto-signing': 0.32.4 + '@cosmjs/stargate': 0.32.4 + '@cosmjs/tendermint-rpc': 0.32.4 + '@cosmjs/utils': 0.32.4 + cosmjs-types: 0.9.0 + pako: 2.1.0 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + + '@cosmjs/cosmwasm-stargate@0.36.2': + dependencies: + '@cosmjs/amino': 0.36.2 + '@cosmjs/crypto': 0.36.2 + '@cosmjs/encoding': 0.36.2 + '@cosmjs/math': 0.36.2 + '@cosmjs/proto-signing': 0.36.2 + '@cosmjs/stargate': 0.36.2 + '@cosmjs/tendermint-rpc': 0.36.2 + '@cosmjs/utils': 0.36.2 + cosmjs-types: 0.10.1 + pako: 2.1.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@cosmjs/crypto@0.25.6': + dependencies: + '@cosmjs/encoding': 0.25.6 + '@cosmjs/math': 0.25.6 + '@cosmjs/utils': 0.25.6 + bip39: 3.1.0 + bn.js: 4.12.3 + elliptic: 6.6.1 + js-sha3: 0.8.0 + libsodium-wrappers: 0.7.16 + ripemd160: 2.0.3 + sha.js: 2.4.12 + + '@cosmjs/crypto@0.32.4': + dependencies: + '@cosmjs/encoding': 0.32.4 + '@cosmjs/math': 0.32.4 + '@cosmjs/utils': 0.32.4 + '@noble/hashes': 1.8.0 + bn.js: 5.2.3 + elliptic: 6.6.1 + libsodium-wrappers-sumo: 0.7.16 + + '@cosmjs/crypto@0.36.2': + dependencies: + '@cosmjs/encoding': 0.36.2 + '@cosmjs/math': 0.36.2 + '@cosmjs/utils': 0.36.2 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + hash-wasm: 4.12.0 + + '@cosmjs/encoding@0.25.6': + dependencies: + base64-js: 1.5.1 + bech32: 1.1.4 + readonly-date: 1.0.0 + + '@cosmjs/encoding@0.32.4': + dependencies: + base64-js: 1.5.1 + bech32: 1.1.4 + readonly-date: 1.0.0 + + '@cosmjs/encoding@0.36.2': + dependencies: + base64-js: 1.5.1 + bech32: 1.1.4 + readonly-date: 1.0.0 + + '@cosmjs/json-rpc@0.25.6': + dependencies: + '@cosmjs/stream': 0.25.6 + xstream: 11.14.0 + + '@cosmjs/json-rpc@0.32.4': + dependencies: + '@cosmjs/stream': 0.32.4 + xstream: 11.14.0 + + '@cosmjs/json-rpc@0.36.2': + dependencies: + '@cosmjs/stream': 0.36.2 + xstream: 11.14.0 + + '@cosmjs/launchpad@0.25.6': + dependencies: + '@cosmjs/amino': 0.25.6 + '@cosmjs/crypto': 0.25.6 + '@cosmjs/encoding': 0.25.6 + '@cosmjs/math': 0.25.6 + '@cosmjs/utils': 0.25.6 + axios: 0.21.4 + fast-deep-equal: 3.1.3 + transitivePeerDependencies: + - debug + + '@cosmjs/math@0.25.6': + dependencies: + bn.js: 4.12.3 + + '@cosmjs/math@0.27.1': + dependencies: + bn.js: 5.2.3 + + '@cosmjs/math@0.32.4': + dependencies: + bn.js: 5.2.3 + + '@cosmjs/math@0.36.2': {} + + '@cosmjs/proto-signing@0.25.6': + dependencies: + '@cosmjs/amino': 0.25.6 + long: 4.0.0 + protobufjs: 6.10.3 + + '@cosmjs/proto-signing@0.32.4': + dependencies: + '@cosmjs/amino': 0.32.4 + '@cosmjs/crypto': 0.32.4 + '@cosmjs/encoding': 0.32.4 + '@cosmjs/math': 0.32.4 + '@cosmjs/utils': 0.32.4 + cosmjs-types: 0.9.0 + + '@cosmjs/proto-signing@0.36.2': + dependencies: + '@cosmjs/amino': 0.36.2 + '@cosmjs/crypto': 0.36.2 + '@cosmjs/encoding': 0.36.2 + '@cosmjs/math': 0.36.2 + '@cosmjs/utils': 0.36.2 + cosmjs-types: 0.10.1 + + '@cosmjs/socket@0.25.6': + dependencies: + '@cosmjs/stream': 0.25.6 + isomorphic-ws: 4.0.1(ws@7.5.10) + ws: 7.5.10 + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@cosmjs/socket@0.32.4': + dependencies: + '@cosmjs/stream': 0.32.4 + isomorphic-ws: 4.0.1(ws@7.5.10) + ws: 7.5.10 + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@cosmjs/socket@0.36.2': + dependencies: + '@cosmjs/stream': 0.36.2 + isomorphic-ws: 4.0.1(ws@7.5.10) + ws: 7.5.10 + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@cosmjs/stargate@0.25.6': + dependencies: + '@confio/ics23': 0.6.8 + '@cosmjs/amino': 0.25.6 + '@cosmjs/encoding': 0.25.6 + '@cosmjs/math': 0.25.6 + '@cosmjs/proto-signing': 0.25.6 + '@cosmjs/stream': 0.25.6 + '@cosmjs/tendermint-rpc': 0.25.6 + '@cosmjs/utils': 0.25.6 + long: 4.0.0 + protobufjs: 6.10.3 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + + '@cosmjs/stargate@0.32.4': + dependencies: + '@confio/ics23': 0.6.8 + '@cosmjs/amino': 0.32.4 + '@cosmjs/encoding': 0.32.4 + '@cosmjs/math': 0.32.4 + '@cosmjs/proto-signing': 0.32.4 + '@cosmjs/stream': 0.32.4 + '@cosmjs/tendermint-rpc': 0.32.4 + '@cosmjs/utils': 0.32.4 + cosmjs-types: 0.9.0 + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + + '@cosmjs/stargate@0.36.2': + dependencies: + '@cosmjs/amino': 0.36.2 + '@cosmjs/encoding': 0.36.2 + '@cosmjs/math': 0.36.2 + '@cosmjs/proto-signing': 0.36.2 + '@cosmjs/stream': 0.36.2 + '@cosmjs/tendermint-rpc': 0.36.2 + '@cosmjs/utils': 0.36.2 + cosmjs-types: 0.10.1 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@cosmjs/stream@0.25.6': + dependencies: + xstream: 11.14.0 + + '@cosmjs/stream@0.32.4': + dependencies: + xstream: 11.14.0 + + '@cosmjs/stream@0.36.2': + dependencies: + xstream: 11.14.0 + + '@cosmjs/tendermint-rpc@0.25.6': + dependencies: + '@cosmjs/crypto': 0.25.6 + '@cosmjs/encoding': 0.25.6 + '@cosmjs/json-rpc': 0.25.6 + '@cosmjs/math': 0.25.6 + '@cosmjs/socket': 0.25.6 + '@cosmjs/stream': 0.25.6 + axios: 0.21.4 + readonly-date: 1.0.0 + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + + '@cosmjs/tendermint-rpc@0.32.4': + dependencies: + '@cosmjs/crypto': 0.32.4 + '@cosmjs/encoding': 0.32.4 + '@cosmjs/json-rpc': 0.32.4 + '@cosmjs/math': 0.32.4 + '@cosmjs/socket': 0.32.4 + '@cosmjs/stream': 0.32.4 + '@cosmjs/utils': 0.32.4 + axios: 1.16.0 + readonly-date: 1.0.0 + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + + '@cosmjs/tendermint-rpc@0.36.2': + dependencies: + '@cosmjs/crypto': 0.36.2 + '@cosmjs/encoding': 0.36.2 + '@cosmjs/json-rpc': 0.36.2 + '@cosmjs/math': 0.36.2 + '@cosmjs/socket': 0.36.2 + '@cosmjs/stream': 0.36.2 + '@cosmjs/utils': 0.36.2 + readonly-date: 1.0.0 + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@cosmjs/utils@0.25.6': {} + + '@cosmjs/utils@0.32.4': {} + + '@cosmjs/utils@0.36.2': {} + + '@cosmos-kit/core@2.18.1(encoding@0.1.13)': + dependencies: + '@chain-registry/client': 1.53.356(encoding@0.1.13) + '@chain-registry/keplr': 1.74.578 + '@chain-registry/types': 0.46.15 + '@cosmjs/amino': 0.36.2 + '@cosmjs/cosmwasm-stargate': 0.36.2 + '@cosmjs/proto-signing': 0.36.2 + '@cosmjs/stargate': 0.36.2 + '@dao-dao/cosmiframe': 1.0.0(@cosmjs/amino@0.36.2)(@cosmjs/proto-signing@0.36.2) + '@walletconnect/types': 2.11.0 + bowser: 2.11.0 + cosmjs-types: 0.10.1 + events: 3.3.0 + nock: 13.5.4 + uuid: 9.0.1 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - supports-color + - uploadthing + - utf-8-validate + + '@cosmos-kit/keplr-extension@2.17.1(@cosmjs/amino@0.36.2)(@cosmjs/proto-signing@0.36.2)(encoding@0.1.13)(starknet@8.9.2)': + dependencies: + '@chain-registry/keplr': 1.74.578 + '@cosmjs/amino': 0.36.2 + '@cosmjs/proto-signing': 0.36.2 + '@cosmos-kit/core': 2.18.1(encoding@0.1.13) + '@keplr-wallet/provider-extension': 0.12.313(starknet@8.9.2) + '@keplr-wallet/types': 0.12.313(starknet@8.9.2) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - starknet + - supports-color + - uploadthing + - utf-8-validate + + '@cosmos-kit/react-lite@2.18.1(@cosmjs/amino@0.36.2)(@cosmjs/proto-signing@0.36.2)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(encoding@0.1.13)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@chain-registry/types': 0.46.15 + '@cosmos-kit/core': 2.18.1(encoding@0.1.13) + '@dao-dao/cosmiframe': 1.0.0(@cosmjs/amino@0.36.2)(@cosmjs/proto-signing@0.36.2) + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@cosmjs/amino' + - '@cosmjs/proto-signing' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - supports-color + - uploadthing + - utf-8-validate + + '@cosmos-kit/react@2.24.1(@cosmjs/amino@0.36.2)(@cosmjs/proto-signing@0.36.2)(@interchain-ui/react@1.26.3(@types/react@19.2.14)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(encoding@0.1.13)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@chain-registry/types': 0.46.15 + '@cosmos-kit/core': 2.18.1(encoding@0.1.13) + '@cosmos-kit/react-lite': 2.18.1(@cosmjs/amino@0.36.2)(@cosmjs/proto-signing@0.36.2)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(encoding@0.1.13)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@interchain-ui/react': 1.26.3(@types/react@19.2.14)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@react-icons/all-files': 4.1.0(react@19.2.6) + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@cosmjs/amino' + - '@cosmjs/proto-signing' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - supports-color + - uploadthing + - utf-8-validate + + '@csstools/color-helpers@6.0.2': {} + + '@csstools/css-calc@3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + dependencies: + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) + '@csstools/css-tokenizer': 4.0.0 + + '@csstools/css-color-parser@4.1.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': + dependencies: + '@csstools/color-helpers': 6.0.2 + '@csstools/css-calc': 3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0) + '@csstools/css-parser-algorithms': 4.0.0(@csstools/css-tokenizer@4.0.0) + '@csstools/css-tokenizer': 4.0.0 + + '@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0)': + dependencies: + '@csstools/css-tokenizer': 4.0.0 + + '@csstools/css-syntax-patches-for-csstree@1.1.4(css-tree@3.2.1)': + optionalDependencies: + css-tree: 3.2.1 + + '@csstools/css-tokenizer@4.0.0': {} + + '@dao-dao/cosmiframe@1.0.0(@cosmjs/amino@0.36.2)(@cosmjs/proto-signing@0.36.2)': + dependencies: + '@cosmjs/amino': 0.36.2 + '@cosmjs/proto-signing': 0.36.2 + uuid: 9.0.1 + + '@design-systems/utils@2.12.0(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@types/react': 19.2.14 + clsx: 1.2.1 + focus-lock: 0.8.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-merge-refs: 1.1.0 + + '@devtools-ds/object-inspector@1.2.1(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@babel/runtime': 7.7.2 + '@devtools-ds/object-parser': 1.2.1 + '@devtools-ds/themes': 1.2.1(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@devtools-ds/tree': 1.2.1(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + clsx: 1.1.0 + react: 19.2.6 + transitivePeerDependencies: + - '@types/react' + - react-dom + + '@devtools-ds/object-parser@1.2.1': + dependencies: + '@babel/runtime': 7.5.5 + + '@devtools-ds/themes@1.2.1(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@babel/runtime': 7.5.5 + '@design-systems/utils': 2.12.0(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + clsx: 1.1.0 + react: 19.2.6 + transitivePeerDependencies: + - '@types/react' + - react-dom + + '@devtools-ds/tree@1.2.1(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@babel/runtime': 7.7.2 + '@devtools-ds/themes': 1.2.1(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + clsx: 1.1.0 + react: 19.2.6 + transitivePeerDependencies: + - '@types/react' + - react-dom + + '@discoveryjs/json-ext@0.5.7': {} + + '@emnapi/core@1.10.0': + dependencies: + '@emnapi/wasi-threads': 1.2.1 + tslib: 2.8.1 + optional: true + + '@emnapi/runtime@1.10.0': + dependencies: + tslib: 2.8.1 + optional: true + + '@emnapi/wasi-threads@1.2.1': + dependencies: + tslib: 2.8.1 + optional: true + + '@emotion/babel-plugin@11.13.5': + dependencies: + '@babel/helper-module-imports': 7.28.6 + '@babel/runtime': 7.29.2 + '@emotion/hash': 0.9.2 + '@emotion/memoize': 0.9.0 + '@emotion/serialize': 1.3.3 + babel-plugin-macros: 3.1.0 + convert-source-map: 1.9.0 + escape-string-regexp: 4.0.0 + find-root: 1.1.0 + source-map: 0.5.7 + stylis: 4.2.0 + transitivePeerDependencies: + - supports-color + + '@emotion/cache@11.14.0': + dependencies: + '@emotion/memoize': 0.9.0 + '@emotion/sheet': 1.4.0 + '@emotion/utils': 1.4.2 + '@emotion/weak-memoize': 0.4.0 + stylis: 4.2.0 + + '@emotion/hash@0.9.2': {} + + '@emotion/is-prop-valid@1.4.0': + dependencies: + '@emotion/memoize': 0.9.0 + + '@emotion/memoize@0.9.0': {} + + '@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@emotion/babel-plugin': 11.13.5 + '@emotion/cache': 11.14.0 + '@emotion/serialize': 1.3.3 + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.6) + '@emotion/utils': 1.4.2 + '@emotion/weak-memoize': 0.4.0 + hoist-non-react-statics: 3.3.2 + react: 19.2.6 + optionalDependencies: + '@types/react': 19.2.14 + transitivePeerDependencies: + - supports-color + + '@emotion/serialize@1.3.3': + dependencies: + '@emotion/hash': 0.9.2 + '@emotion/memoize': 0.9.0 + '@emotion/unitless': 0.10.0 + '@emotion/utils': 1.4.2 + csstype: 3.2.3 + + '@emotion/sheet@1.4.0': {} + + '@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@emotion/babel-plugin': 11.13.5 + '@emotion/is-prop-valid': 1.4.0 + '@emotion/react': 11.14.0(@types/react@19.2.14)(react@19.2.6) + '@emotion/serialize': 1.3.3 + '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.2.6) + '@emotion/utils': 1.4.2 + react: 19.2.6 + optionalDependencies: + '@types/react': 19.2.14 + transitivePeerDependencies: + - supports-color + + '@emotion/unitless@0.10.0': {} + + '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.2.6)': + dependencies: + react: 19.2.6 + + '@emotion/utils@1.4.2': {} + + '@emotion/weak-memoize@0.4.0': {} + + '@esbuild/aix-ppc64@0.25.12': + optional: true + + '@esbuild/android-arm64@0.25.12': + optional: true + + '@esbuild/android-arm@0.25.12': + optional: true + + '@esbuild/android-x64@0.25.12': + optional: true + + '@esbuild/darwin-arm64@0.25.12': + optional: true + + '@esbuild/darwin-x64@0.25.12': + optional: true + + '@esbuild/freebsd-arm64@0.25.12': + optional: true + + '@esbuild/freebsd-x64@0.25.12': + optional: true + + '@esbuild/linux-arm64@0.25.12': + optional: true + + '@esbuild/linux-arm@0.25.12': + optional: true + + '@esbuild/linux-ia32@0.25.12': + optional: true + + '@esbuild/linux-loong64@0.25.12': + optional: true + + '@esbuild/linux-mips64el@0.25.12': + optional: true + + '@esbuild/linux-ppc64@0.25.12': + optional: true + + '@esbuild/linux-riscv64@0.25.12': + optional: true + + '@esbuild/linux-s390x@0.25.12': + optional: true + + '@esbuild/linux-x64@0.25.12': + optional: true + + '@esbuild/netbsd-arm64@0.25.12': + optional: true + + '@esbuild/netbsd-x64@0.25.12': + optional: true + + '@esbuild/openbsd-arm64@0.25.12': + optional: true + + '@esbuild/openbsd-x64@0.25.12': + optional: true + + '@esbuild/openharmony-arm64@0.25.12': + optional: true + + '@esbuild/sunos-x64@0.25.12': + optional: true + + '@esbuild/win32-arm64@0.25.12': + optional: true + + '@esbuild/win32-ia32@0.25.12': + optional: true + + '@esbuild/win32-x64@0.25.12': + optional: true + + '@eslint-community/eslint-utils@4.9.1(eslint@8.57.1)': + dependencies: + eslint: 8.57.1 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/eslint-utils@4.9.1(eslint@9.39.4)': + dependencies: + eslint: 9.39.4 + eslint-visitor-keys: 3.4.3 + + '@eslint-community/regexpp@4.12.2': {} + + '@eslint/config-array@0.21.2': + dependencies: + '@eslint/object-schema': 2.1.7 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@eslint/config-helpers@0.4.2': + dependencies: + '@eslint/core': 0.17.0 + + '@eslint/core@0.17.0': + dependencies: + '@types/json-schema': 7.0.15 + + '@eslint/eslintrc@2.1.4': + dependencies: + ajv: 6.15.0 + debug: 4.4.3 + espree: 9.6.1 + globals: 13.24.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/eslintrc@3.3.5': + dependencies: + ajv: 6.15.0 + debug: 4.4.3 + espree: 10.4.0 + globals: 14.0.0 + ignore: 5.3.2 + import-fresh: 3.3.1 + js-yaml: 4.1.1 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + + '@eslint/js@8.57.1': {} + + '@eslint/js@9.39.4': {} + + '@eslint/object-schema@2.1.7': {} + + '@eslint/plugin-kit@0.4.1': + dependencies: + '@eslint/core': 0.17.0 + levn: 0.4.1 + + '@ethersproject/address@5.8.0': + dependencies: + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/rlp': 5.8.0 + + '@ethersproject/bignumber@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + bn.js: 5.2.3 + + '@ethersproject/bytes@5.8.0': + dependencies: + '@ethersproject/logger': 5.8.0 + + '@ethersproject/keccak256@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + js-sha3: 0.8.0 + + '@ethersproject/logger@5.8.0': {} + + '@ethersproject/rlp@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + + '@exodus/bytes@1.15.0(@noble/hashes@1.8.0)': + optionalDependencies: + '@noble/hashes': 1.8.0 + + '@floating-ui/core@1.7.5': + dependencies: + '@floating-ui/utils': 0.2.11 + + '@floating-ui/dom@1.7.6': + dependencies: + '@floating-ui/core': 1.7.5 + '@floating-ui/utils': 0.2.11 + + '@floating-ui/react-dom@2.1.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@floating-ui/dom': 1.7.6 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + + '@floating-ui/react@0.26.28(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@floating-ui/react-dom': 2.1.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@floating-ui/utils': 0.2.11 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + tabbable: 6.4.0 + + '@floating-ui/utils@0.2.11': {} + + '@formkit/auto-animate@0.8.4': {} + + '@gar/promisify@1.1.3': {} + + '@hapi/hoek@9.3.0': {} + + '@hapi/topo@5.1.0': + dependencies: + '@hapi/hoek': 9.3.0 + + '@hookform/resolvers@2.9.11(react-hook-form@7.75.0(react@19.2.6))': + dependencies: + react-hook-form: 7.75.0(react@19.2.6) + + '@humanfs/core@0.19.2': + dependencies: + '@humanfs/types': 0.15.0 + + '@humanfs/node@0.16.8': + dependencies: + '@humanfs/core': 0.19.2 + '@humanfs/types': 0.15.0 + '@humanwhocodes/retry': 0.4.3 + + '@humanfs/types@0.15.0': {} + + '@humanwhocodes/config-array@0.13.0': + dependencies: + '@humanwhocodes/object-schema': 2.0.3 + debug: 4.4.3 + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/module-importer@1.0.1': {} + + '@humanwhocodes/object-schema@2.0.3': {} + + '@humanwhocodes/retry@0.4.3': {} + + '@hutson/parse-repository-url@3.0.2': {} + + '@img/sharp-darwin-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.0.4 + optional: true + + '@img/sharp-darwin-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.0.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.0.5': + optional: true + + '@img/sharp-libvips-linux-s390x@1.0.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.0.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.0.4': + optional: true + + '@img/sharp-linux-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.0.4 + optional: true + + '@img/sharp-linux-arm@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.0.5 + optional: true + + '@img/sharp-linux-s390x@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.0.4 + optional: true + + '@img/sharp-linux-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.33.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + optional: true + + '@img/sharp-wasm32@0.33.5': + dependencies: + '@emnapi/runtime': 1.10.0 + optional: true + + '@img/sharp-win32-ia32@0.33.5': + optional: true + + '@img/sharp-win32-x64@0.33.5': + optional: true + + '@inquirer/external-editor@1.0.3(@types/node@22.19.19)': + dependencies: + chardet: 2.1.1 + iconv-lite: 0.7.2 + optionalDependencies: + '@types/node': 22.19.19 + + '@interchain-ui/react@1.26.3(@types/react@19.2.14)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@floating-ui/core': 1.7.5 + '@floating-ui/dom': 1.7.6 + '@floating-ui/react': 0.26.28(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@floating-ui/react-dom': 2.1.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@floating-ui/utils': 0.2.11 + '@formkit/auto-animate': 0.8.4 + '@react-aria/listbox': 3.16.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@react-aria/overlays': 3.32.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@react-aria/utils': 3.34.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@tanstack/react-virtual': 3.13.24(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@vanilla-extract/css': 1.20.1(babel-plugin-macros@3.1.0) + '@vanilla-extract/css-utils': 0.1.6 + '@vanilla-extract/dynamic': 2.1.5 + '@vanilla-extract/private': 1.0.9 + '@vanilla-extract/recipes': 0.5.7(@vanilla-extract/css@1.20.1(babel-plugin-macros@3.1.0)) + animejs: 3.2.2 + bignumber.js: 9.3.1 + client-only: 0.0.1 + clsx: 2.1.1 + copy-to-clipboard: 3.3.3 + immer: 10.2.0 + lodash: 4.18.1 + rainbow-sprinkles: 0.17.3(@vanilla-extract/css@1.20.1(babel-plugin-macros@3.1.0))(@vanilla-extract/dynamic@2.1.5) + react: 19.2.6 + react-aria: 3.48.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react-dom: 19.2.6(react@19.2.6) + react-stately: 3.46.0(react@19.2.6) + zustand: 4.5.7(@types/react@19.2.14)(immer@10.2.0)(react@19.2.6) + transitivePeerDependencies: + - '@types/react' + - babel-plugin-macros + + '@internationalized/date@3.12.1': + dependencies: + '@swc/helpers': 0.5.21 + + '@internationalized/number@3.6.6': + dependencies: + '@swc/helpers': 0.5.21 + + '@internationalized/string@3.2.8': + dependencies: + '@swc/helpers': 0.5.21 + + '@isaacs/cliui@8.0.2': + dependencies: + string-width: 5.1.2 + string-width-cjs: string-width@4.2.3 + strip-ansi: 7.2.0 + strip-ansi-cjs: strip-ansi@6.0.1 + wrap-ansi: 8.1.0 + wrap-ansi-cjs: wrap-ansi@7.0.0 + + '@istanbuljs/load-nyc-config@1.1.0': + dependencies: + camelcase: 5.3.1 + find-up: 4.1.0 + get-package-type: 0.1.0 + js-yaml: 3.14.2 + resolve-from: 5.0.0 + + '@istanbuljs/schema@0.1.6': {} + + '@jest/console@27.5.1': + dependencies: + '@jest/types': 27.5.1 + '@types/node': 22.19.19 + chalk: 4.1.2 + jest-message-util: 27.5.1 + jest-util: 27.5.1 + slash: 3.0.0 + + '@jest/console@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@types/node': 22.19.19 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + + '@jest/core@27.5.1': + dependencies: + '@jest/console': 27.5.1 + '@jest/reporters': 27.5.1 + '@jest/test-result': 27.5.1 + '@jest/transform': 27.5.1 + '@jest/types': 27.5.1 + '@types/node': 22.19.19 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.8.1 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 27.5.1 + jest-config: 27.5.1 + jest-haste-map: 27.5.1 + jest-message-util: 27.5.1 + jest-regex-util: 27.5.1 + jest-resolve: 27.5.1 + jest-resolve-dependencies: 27.5.1 + jest-runner: 27.5.1 + jest-runtime: 27.5.1 + jest-snapshot: 27.5.1 + jest-util: 27.5.1 + jest-validate: 27.5.1 + jest-watcher: 27.5.1 + micromatch: 4.0.8 + rimraf: 3.0.2 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - ts-node + - utf-8-validate + + '@jest/core@29.7.0(babel-plugin-macros@3.1.0)': + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.19.19 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@22.19.19)(babel-plugin-macros@3.1.0) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + + '@jest/environment@27.5.1': + dependencies: + '@jest/fake-timers': 27.5.1 + '@jest/types': 27.5.1 + '@types/node': 22.19.19 + jest-mock: 27.5.1 + + '@jest/environment@29.7.0': + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.19.19 + jest-mock: 29.7.0 + + '@jest/expect-utils@29.7.0': + dependencies: + jest-get-type: 29.6.3 + + '@jest/expect@29.7.0': + dependencies: + expect: 29.7.0 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/fake-timers@27.5.1': + dependencies: + '@jest/types': 27.5.1 + '@sinonjs/fake-timers': 8.1.0 + '@types/node': 22.19.19 + jest-message-util: 27.5.1 + jest-mock: 27.5.1 + jest-util: 27.5.1 + + '@jest/fake-timers@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 22.19.19 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + '@jest/globals@27.5.1': + dependencies: + '@jest/environment': 27.5.1 + '@jest/types': 27.5.1 + expect: 27.5.1 + + '@jest/globals@29.7.0': + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 + jest-mock: 29.7.0 + transitivePeerDependencies: + - supports-color + + '@jest/reporters@27.5.1': + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 27.5.1 + '@jest/test-result': 27.5.1 + '@jest/transform': 27.5.1 + '@jest/types': 27.5.1 + '@types/node': 22.19.19 + chalk: 4.1.2 + collect-v8-coverage: 1.0.3 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 5.2.1 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.2.0 + jest-haste-map: 27.5.1 + jest-resolve: 27.5.1 + jest-util: 27.5.1 + jest-worker: 27.5.1 + slash: 3.0.0 + source-map: 0.6.1 + string-length: 4.0.2 + terminal-link: 2.1.1 + v8-to-istanbul: 8.1.1 + transitivePeerDependencies: + - supports-color + + '@jest/reporters@29.7.0': + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.31 + '@types/node': 22.19.19 + chalk: 4.1.2 + collect-v8-coverage: 1.0.3 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.2.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + jest-worker: 29.7.0 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.3.0 + transitivePeerDependencies: + - supports-color + + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.10 + + '@jest/source-map@27.5.1': + dependencies: + callsites: 3.1.0 + graceful-fs: 4.2.11 + source-map: 0.6.1 + + '@jest/source-map@29.6.3': + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + callsites: 3.1.0 + graceful-fs: 4.2.11 + + '@jest/test-result@27.5.1': + dependencies: + '@jest/console': 27.5.1 + '@jest/types': 27.5.1 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.3 + + '@jest/test-result@29.7.0': + dependencies: + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.3 + + '@jest/test-sequencer@27.5.1': + dependencies: + '@jest/test-result': 27.5.1 + graceful-fs: 4.2.11 + jest-haste-map: 27.5.1 + jest-runtime: 27.5.1 + transitivePeerDependencies: + - supports-color + + '@jest/test-sequencer@29.7.0': + dependencies: + '@jest/test-result': 29.7.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + slash: 3.0.0 + + '@jest/transform@26.6.2': + dependencies: + '@babel/core': 7.29.0 + '@jest/types': 26.6.2 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 1.9.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 26.6.2 + jest-regex-util: 26.0.0 + jest-util: 26.6.2 + micromatch: 4.0.8 + pirates: 4.0.7 + slash: 3.0.0 + source-map: 0.6.1 + write-file-atomic: 3.0.3 + transitivePeerDependencies: + - supports-color + + '@jest/transform@27.5.1': + dependencies: + '@babel/core': 7.29.0 + '@jest/types': 27.5.1 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 1.9.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 27.5.1 + jest-regex-util: 27.5.1 + jest-util: 27.5.1 + micromatch: 4.0.8 + pirates: 4.0.7 + slash: 3.0.0 + source-map: 0.6.1 + write-file-atomic: 3.0.3 + transitivePeerDependencies: + - supports-color + + '@jest/transform@29.7.0': + dependencies: + '@babel/core': 7.29.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.31 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.8 + pirates: 4.0.7 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + + '@jest/types@26.6.2': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 22.19.19 + '@types/yargs': 15.0.20 + chalk: 4.1.2 + + '@jest/types@27.5.1': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 22.19.19 + '@types/yargs': 16.0.11 + chalk: 4.1.2 + + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 22.19.19 + '@types/yargs': 17.0.35 + chalk: 4.1.2 + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/remapping@2.3.5': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/source-map@0.3.11': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@keplr-wallet/common@0.12.28': + dependencies: + '@keplr-wallet/crypto': 0.12.28 + '@keplr-wallet/types': 0.12.28 + buffer: 6.0.3 + delay: 4.4.1 + mobx: 6.15.3 + + '@keplr-wallet/cosmos@0.12.28': + dependencies: + '@ethersproject/address': 5.8.0 + '@keplr-wallet/common': 0.12.28 + '@keplr-wallet/crypto': 0.12.28 + '@keplr-wallet/proto-types': 0.12.28 + '@keplr-wallet/simple-fetch': 0.12.28 + '@keplr-wallet/types': 0.12.28 + '@keplr-wallet/unit': 0.12.28 + bech32: 1.1.4 + buffer: 6.0.3 + long: 4.0.0 + protobufjs: 6.11.6 + + '@keplr-wallet/crypto@0.12.28': + dependencies: + '@ethersproject/keccak256': 5.8.0 + bip32: 2.0.6 + bip39: 3.1.0 + bs58check: 2.1.2 + buffer: 6.0.3 + crypto-js: 4.2.0 + elliptic: 6.6.1 + sha.js: 2.4.12 + + '@keplr-wallet/proto-types@0.12.28': + dependencies: + long: 4.0.0 + protobufjs: 6.11.6 + + '@keplr-wallet/provider-extension@0.12.313(starknet@8.9.2)': + dependencies: + '@keplr-wallet/types': 0.12.313(starknet@8.9.2) + deepmerge: 4.3.1 + long: 4.0.0 + starknet: 8.9.2 + uuid: 11.1.1 + + '@keplr-wallet/simple-fetch@0.12.28': {} + + '@keplr-wallet/types@0.12.28': + dependencies: + long: 4.0.0 + + '@keplr-wallet/types@0.12.313(starknet@8.9.2)': + dependencies: + long: 4.0.0 + starknet: 8.9.2 + + '@keplr-wallet/unit@0.12.28': + dependencies: + '@keplr-wallet/types': 0.12.28 + big-integer: 1.6.52 + utility-types: 3.11.0 + + '@leichtgewicht/ip-codec@2.0.5': {} + + '@lerna/child-process@7.4.2': + dependencies: + chalk: 4.1.2 + execa: 5.0.0 + strong-log-transformer: 2.1.0 + + '@lerna/create@7.4.2(@types/node@22.19.19)(encoding@0.1.13)(typescript@5.9.3)': + dependencies: + '@lerna/child-process': 7.4.2 + '@npmcli/run-script': 6.0.2 + '@nx/devkit': 16.10.0(nx@16.10.0) + '@octokit/plugin-enterprise-rest': 6.0.1 + '@octokit/rest': 19.0.11(encoding@0.1.13) + byte-size: 8.1.1 + chalk: 4.1.0 + clone-deep: 4.0.1 + cmd-shim: 6.0.1 + columnify: 1.6.0 + conventional-changelog-core: 5.0.1 + conventional-recommended-bump: 7.0.1 + cosmiconfig: 8.3.6(typescript@5.9.3) + dedent: 0.7.0 + execa: 5.0.0 + fs-extra: 11.3.5 + get-stream: 6.0.0 + git-url-parse: 13.1.0 + glob-parent: 5.1.2 + globby: 11.1.0 + graceful-fs: 4.2.11 + has-unicode: 2.0.1 + ini: 1.3.8 + init-package-json: 5.0.0 + inquirer: 8.2.7(@types/node@22.19.19) + is-ci: 3.0.1 + is-stream: 2.0.0 + js-yaml: 4.1.0 + libnpmpublish: 7.3.0 + load-json-file: 6.2.0 + lodash: 4.18.1 + make-dir: 4.0.0 + minimatch: 3.0.5 + multimatch: 5.0.0 + node-fetch: 2.6.7(encoding@0.1.13) + npm-package-arg: 8.1.1 + npm-packlist: 5.1.1 + npm-registry-fetch: 14.0.5 + npmlog: 6.0.2 + nx: 16.10.0 + p-map: 4.0.0 + p-map-series: 2.1.0 + p-queue: 6.6.2 + p-reduce: 2.1.0 + pacote: 15.2.0 + pify: 5.0.0 + read-cmd-shim: 4.0.0 + read-package-json: 6.0.4 + resolve-from: 5.0.0 + rimraf: 4.4.1 + semver: 7.8.0 + signal-exit: 3.0.7 + slash: 3.0.0 + ssri: 9.0.1 + strong-log-transformer: 2.1.0 + tar: 6.1.11 + temp-dir: 1.0.0 + upath: 2.0.1 + uuid: 9.0.1 + validate-npm-package-license: 3.0.4 + validate-npm-package-name: 5.0.0 + write-file-atomic: 5.0.1 + write-pkg: 4.0.0 + yargs: 16.2.0 + yargs-parser: 20.2.4 + transitivePeerDependencies: + - '@swc-node/register' + - '@swc/core' + - '@types/node' + - bluebird + - debug + - encoding + - supports-color + - typescript + + '@mdx-js/mdx@1.6.22': + dependencies: + '@babel/core': 7.12.9 + '@babel/plugin-syntax-jsx': 7.12.1(@babel/core@7.12.9) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.12.9) + '@mdx-js/util': 1.6.22 + babel-plugin-apply-mdx-type-prop: 1.6.22(@babel/core@7.12.9) + babel-plugin-extract-import-names: 1.6.22 + camelcase-css: 2.0.1 + detab: 2.0.4 + hast-util-raw: 6.0.1 + lodash.uniq: 4.5.0 + mdast-util-to-hast: 10.0.1 + remark-footnotes: 2.0.0 + remark-mdx: 1.6.22 + remark-parse: 8.0.3 + remark-squeeze-paragraphs: 4.0.0 + style-to-object: 0.3.0 + unified: 9.2.0 + unist-builder: 2.0.3 + unist-util-visit: 2.0.3 + transitivePeerDependencies: + - supports-color + + '@mdx-js/react@1.6.22(react@19.2.6)': + dependencies: + react: 19.2.6 + + '@mdx-js/util@1.6.22': {} + + '@mrmlnc/readdir-enhanced@2.2.1': + dependencies: + call-me-maybe: 1.0.2 + glob-to-regexp: 0.3.0 + + '@mui/base@5.0.0-beta.40(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@floating-ui/react-dom': 2.1.8(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mui/types': 7.4.12(@types/react@19.2.14) + '@mui/utils': 5.17.1(@types/react@19.2.14)(react@19.2.6) + '@popperjs/core': 2.11.8 + clsx: 2.1.1 + prop-types: 15.8.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + optionalDependencies: + '@types/react': 19.2.14 + + '@mui/core-downloads-tracker@5.18.0': {} + + '@mui/core-downloads-tracker@6.5.0': {} + + '@mui/icons-material@5.18.0(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react@19.2.14)(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@mui/material': 5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react: 19.2.6 + optionalDependencies: + '@types/react': 19.2.14 + + '@mui/icons-material@5.18.0(@mui/material@6.5.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react@19.2.14)(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@mui/material': 6.5.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react: 19.2.6 + optionalDependencies: + '@types/react': 19.2.14 + + '@mui/lab@5.0.0-alpha.170(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@mui/base': 5.0.0-beta.40(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mui/material': 5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mui/system': 5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@mui/types': 7.4.12(@types/react@19.2.14) + '@mui/utils': 5.17.1(@types/react@19.2.14)(react@19.2.6) + clsx: 2.1.1 + prop-types: 15.8.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + optionalDependencies: + '@emotion/react': 11.14.0(@types/react@19.2.14)(react@19.2.6) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@types/react': 19.2.14 + + '@mui/material-nextjs@6.5.0(@emotion/cache@11.14.0)(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(next@14.2.35(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@emotion/react': 11.14.0(@types/react@19.2.14)(react@19.2.6) + next: 14.2.35(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react: 19.2.6 + optionalDependencies: + '@emotion/cache': 11.14.0 + '@types/react': 19.2.14 + + '@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@mui/core-downloads-tracker': 5.18.0 + '@mui/system': 5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@mui/types': 7.2.24(@types/react@19.2.14) + '@mui/utils': 5.17.1(@types/react@19.2.14)(react@19.2.6) + '@popperjs/core': 2.11.8 + '@types/react-transition-group': 4.4.12(@types/react@19.2.14) + clsx: 2.1.1 + csstype: 3.2.3 + prop-types: 15.8.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-is: 19.2.6 + react-transition-group: 4.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + optionalDependencies: + '@emotion/react': 11.14.0(@types/react@19.2.14)(react@19.2.6) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@types/react': 19.2.14 + + '@mui/material@6.5.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@mui/core-downloads-tracker': 6.5.0 + '@mui/system': 6.5.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@mui/types': 7.2.24(@types/react@19.2.14) + '@mui/utils': 6.4.9(@types/react@19.2.14)(react@19.2.6) + '@popperjs/core': 2.11.8 + '@types/react-transition-group': 4.4.12(@types/react@19.2.14) + clsx: 2.1.1 + csstype: 3.2.3 + prop-types: 15.8.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-is: 19.2.6 + react-transition-group: 4.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + optionalDependencies: + '@emotion/react': 11.14.0(@types/react@19.2.14)(react@19.2.6) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@types/react': 19.2.14 + + '@mui/private-theming@5.17.1(@types/react@19.2.14)(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@mui/utils': 5.17.1(@types/react@19.2.14)(react@19.2.6) + prop-types: 15.8.1 + react: 19.2.6 + optionalDependencies: + '@types/react': 19.2.14 + + '@mui/private-theming@6.4.9(@types/react@19.2.14)(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@mui/utils': 6.4.9(@types/react@19.2.14)(react@19.2.6) + prop-types: 15.8.1 + react: 19.2.6 + optionalDependencies: + '@types/react': 19.2.14 + + '@mui/styled-engine@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@emotion/cache': 11.14.0 + '@emotion/serialize': 1.3.3 + csstype: 3.2.3 + prop-types: 15.8.1 + react: 19.2.6 + optionalDependencies: + '@emotion/react': 11.14.0(@types/react@19.2.14)(react@19.2.6) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + + '@mui/styled-engine@6.5.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@emotion/cache': 11.14.0 + '@emotion/serialize': 1.3.3 + '@emotion/sheet': 1.4.0 + csstype: 3.2.3 + prop-types: 15.8.1 + react: 19.2.6 + optionalDependencies: + '@emotion/react': 11.14.0(@types/react@19.2.14)(react@19.2.6) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + + '@mui/styles@5.18.0(@types/react@19.2.14)(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@emotion/hash': 0.9.2 + '@mui/private-theming': 5.17.1(@types/react@19.2.14)(react@19.2.6) + '@mui/types': 7.2.24(@types/react@19.2.14) + '@mui/utils': 5.17.1(@types/react@19.2.14)(react@19.2.6) + clsx: 2.1.1 + csstype: 3.2.3 + hoist-non-react-statics: 3.3.2 + jss: 10.10.0 + jss-plugin-camel-case: 10.10.0 + jss-plugin-default-unit: 10.10.0 + jss-plugin-global: 10.10.0 + jss-plugin-nested: 10.10.0 + jss-plugin-props-sort: 10.10.0 + jss-plugin-rule-value-function: 10.10.0 + jss-plugin-vendor-prefixer: 10.10.0 + prop-types: 15.8.1 + react: 19.2.6 + optionalDependencies: + '@types/react': 19.2.14 + + '@mui/system@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@mui/private-theming': 5.17.1(@types/react@19.2.14)(react@19.2.6) + '@mui/styled-engine': 5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(react@19.2.6) + '@mui/types': 7.2.24(@types/react@19.2.14) + '@mui/utils': 5.17.1(@types/react@19.2.14)(react@19.2.6) + clsx: 2.1.1 + csstype: 3.2.3 + prop-types: 15.8.1 + react: 19.2.6 + optionalDependencies: + '@emotion/react': 11.14.0(@types/react@19.2.14)(react@19.2.6) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@types/react': 19.2.14 + + '@mui/system@6.5.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@mui/private-theming': 6.4.9(@types/react@19.2.14)(react@19.2.6) + '@mui/styled-engine': 6.5.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(react@19.2.6) + '@mui/types': 7.2.24(@types/react@19.2.14) + '@mui/utils': 6.4.9(@types/react@19.2.14)(react@19.2.6) + clsx: 2.1.1 + csstype: 3.2.3 + prop-types: 15.8.1 + react: 19.2.6 + optionalDependencies: + '@emotion/react': 11.14.0(@types/react@19.2.14)(react@19.2.6) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@types/react': 19.2.14 + + '@mui/types@7.2.24(@types/react@19.2.14)': + optionalDependencies: + '@types/react': 19.2.14 + + '@mui/types@7.4.12(@types/react@19.2.14)': + dependencies: + '@babel/runtime': 7.29.2 + optionalDependencies: + '@types/react': 19.2.14 + + '@mui/utils@5.17.1(@types/react@19.2.14)(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@mui/types': 7.2.24(@types/react@19.2.14) + '@types/prop-types': 15.7.15 + clsx: 2.1.1 + prop-types: 15.8.1 + react: 19.2.6 + react-is: 19.2.6 + optionalDependencies: + '@types/react': 19.2.14 + + '@mui/utils@6.4.9(@types/react@19.2.14)(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@mui/types': 7.2.24(@types/react@19.2.14) + '@types/prop-types': 15.7.15 + clsx: 2.1.1 + prop-types: 15.8.1 + react: 19.2.6 + react-is: 19.2.6 + optionalDependencies: + '@types/react': 19.2.14 + + '@mui/x-date-pickers@7.29.4(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@mui/material@6.5.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mui/system@6.5.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@mui/material': 6.5.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mui/system': 6.5.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@mui/utils': 5.17.1(@types/react@19.2.14)(react@19.2.6) + '@mui/x-internals': 7.29.0(@types/react@19.2.14)(react@19.2.6) + '@types/react-transition-group': 4.4.12(@types/react@19.2.14) + clsx: 2.1.1 + prop-types: 15.8.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-transition-group: 4.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + optionalDependencies: + '@emotion/react': 11.14.0(@types/react@19.2.14)(react@19.2.6) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + date-fns: 4.1.0 + transitivePeerDependencies: + - '@types/react' + + '@mui/x-internals@7.29.0(@types/react@19.2.14)(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@mui/utils': 6.4.9(@types/react@19.2.14)(react@19.2.6) + react: 19.2.6 + transitivePeerDependencies: + - '@types/react' + + '@mui/x-tree-view@7.29.10(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mui/system@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@mui/material': 5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mui/system': 5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@mui/utils': 6.4.9(@types/react@19.2.14)(react@19.2.6) + '@mui/x-internals': 7.29.0(@types/react@19.2.14)(react@19.2.6) + '@types/react-transition-group': 4.4.12(@types/react@19.2.14) + clsx: 2.1.1 + prop-types: 15.8.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-transition-group: 4.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + optionalDependencies: + '@emotion/react': 11.14.0(@types/react@19.2.14)(react@19.2.6) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + transitivePeerDependencies: + - '@types/react' + + '@napi-rs/wasm-runtime@0.2.12': + dependencies: + '@emnapi/core': 1.10.0 + '@emnapi/runtime': 1.10.0 + '@tybys/wasm-util': 0.10.2 + optional: true + + '@next/env@14.2.35': {} + + '@next/eslint-plugin-next@15.0.3': + dependencies: + fast-glob: 3.3.1 + + '@next/swc-darwin-arm64@14.2.33': + optional: true + + '@next/swc-darwin-x64@14.2.33': + optional: true + + '@next/swc-linux-arm64-gnu@14.2.33': + optional: true + + '@next/swc-linux-arm64-musl@14.2.33': + optional: true + + '@next/swc-linux-x64-gnu@14.2.33': + optional: true + + '@next/swc-linux-x64-musl@14.2.33': + optional: true + + '@next/swc-win32-arm64-msvc@14.2.33': + optional: true + + '@next/swc-win32-ia32-msvc@14.2.33': + optional: true + + '@next/swc-win32-x64-msvc@14.2.33': + optional: true + + '@nivo/annotations@0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@nivo/colors': 0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@nivo/core': 0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@react-spring/web': 9.7.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + lodash: 4.18.1 + react: 19.2.6 + transitivePeerDependencies: + - react-dom + + '@nivo/axes@0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@nivo/core': 0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@nivo/scales': 0.88.0 + '@react-spring/web': 9.7.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/d3-format': 1.4.5 + '@types/d3-time-format': 2.3.4 + d3-format: 1.4.5 + d3-time-format: 3.0.0 + react: 19.2.6 + transitivePeerDependencies: + - react-dom + + '@nivo/colors@0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@nivo/core': 0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/d3-color': 3.1.3 + '@types/d3-scale': 4.0.9 + '@types/d3-scale-chromatic': 3.1.0 + '@types/prop-types': 15.7.15 + d3-color: 3.1.0 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.1.0 + lodash: 4.18.1 + prop-types: 15.8.1 + react: 19.2.6 + transitivePeerDependencies: + - react-dom + + '@nivo/core@0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@nivo/tooltip': 0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@react-spring/web': 9.7.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/d3-shape': 3.1.8 + d3-color: 3.1.0 + d3-format: 1.4.5 + d3-interpolate: 3.0.1 + d3-scale: 4.0.2 + d3-scale-chromatic: 3.1.0 + d3-shape: 3.2.0 + d3-time-format: 3.0.0 + lodash: 4.18.1 + prop-types: 15.8.1 + react: 19.2.6 + transitivePeerDependencies: + - react-dom + + '@nivo/legends@0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@nivo/colors': 0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@nivo/core': 0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/d3-scale': 4.0.9 + d3-scale: 4.0.2 + react: 19.2.6 + transitivePeerDependencies: + - react-dom + + '@nivo/line@0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@nivo/annotations': 0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@nivo/axes': 0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@nivo/colors': 0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@nivo/core': 0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@nivo/legends': 0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@nivo/scales': 0.88.0 + '@nivo/tooltip': 0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@nivo/voronoi': 0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@react-spring/web': 9.7.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + d3-shape: 3.2.0 + react: 19.2.6 + transitivePeerDependencies: + - react-dom + + '@nivo/scales@0.88.0': + dependencies: + '@types/d3-scale': 4.0.9 + '@types/d3-time': 1.1.4 + '@types/d3-time-format': 3.0.4 + d3-scale: 4.0.2 + d3-time: 1.1.0 + d3-time-format: 3.0.0 + lodash: 4.18.1 + + '@nivo/tooltip@0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@nivo/core': 0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@react-spring/web': 9.7.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react: 19.2.6 + transitivePeerDependencies: + - react-dom + + '@nivo/voronoi@0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@nivo/core': 0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@nivo/tooltip': 0.88.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/d3-delaunay': 6.0.4 + '@types/d3-scale': 4.0.9 + d3-delaunay: 6.0.4 + d3-scale: 4.0.2 + react: 19.2.6 + transitivePeerDependencies: + - react-dom + + '@noble/ciphers@1.3.0': {} + + '@noble/curves@1.7.0': + dependencies: + '@noble/hashes': 1.6.0 + + '@noble/curves@1.9.7': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/hashes@1.6.0': {} + + '@noble/hashes@1.6.1': {} + + '@noble/hashes@1.8.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@1.1.3': {} + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@nolyfill/is-core-module@1.0.39': {} + + '@npmcli/fs@1.1.1': + dependencies: + '@gar/promisify': 1.1.3 + semver: 7.8.0 + + '@npmcli/fs@2.1.2': + dependencies: + '@gar/promisify': 1.1.3 + semver: 7.8.0 + + '@npmcli/fs@3.1.1': + dependencies: + semver: 7.8.0 + + '@npmcli/git@4.1.0': + dependencies: + '@npmcli/promise-spawn': 6.0.2 + lru-cache: 7.18.3 + npm-pick-manifest: 8.0.2 + proc-log: 3.0.0 + promise-inflight: 1.0.1(bluebird@3.7.2) + promise-retry: 2.0.1 + semver: 7.8.0 + which: 3.0.1 + transitivePeerDependencies: + - bluebird + + '@npmcli/installed-package-contents@2.1.0': + dependencies: + npm-bundled: 3.0.1 + npm-normalize-package-bin: 3.0.1 + + '@npmcli/move-file@1.1.2': + dependencies: + mkdirp: 1.0.4 + rimraf: 3.0.2 + + '@npmcli/move-file@2.0.1': + dependencies: + mkdirp: 1.0.4 + rimraf: 3.0.2 + + '@npmcli/node-gyp@3.0.0': {} + + '@npmcli/promise-spawn@6.0.2': + dependencies: + which: 3.0.1 + + '@npmcli/run-script@6.0.2': + dependencies: + '@npmcli/node-gyp': 3.0.0 + '@npmcli/promise-spawn': 6.0.2 + node-gyp: 9.4.1 + read-package-json-fast: 3.0.2 + which: 3.0.1 + transitivePeerDependencies: + - bluebird + - supports-color + + '@nrwl/devkit@16.10.0(nx@16.10.0)': + dependencies: + '@nx/devkit': 16.10.0(nx@16.10.0) + transitivePeerDependencies: + - nx + + '@nrwl/tao@16.10.0': + dependencies: + nx: 16.10.0 + tslib: 2.8.1 + transitivePeerDependencies: + - '@swc-node/register' + - '@swc/core' + - debug + + '@nx/devkit@16.10.0(nx@16.10.0)': + dependencies: + '@nrwl/devkit': 16.10.0(nx@16.10.0) + ejs: 3.1.10 + enquirer: 2.3.6 + ignore: 5.3.2 + nx: 16.10.0 + semver: 7.5.3 + tmp: 0.2.5 + tslib: 2.8.1 + + '@nx/nx-darwin-arm64@16.10.0': + optional: true + + '@nx/nx-darwin-x64@16.10.0': + optional: true + + '@nx/nx-freebsd-x64@16.10.0': + optional: true + + '@nx/nx-linux-arm-gnueabihf@16.10.0': + optional: true + + '@nx/nx-linux-arm64-gnu@16.10.0': + optional: true + + '@nx/nx-linux-arm64-musl@16.10.0': + optional: true + + '@nx/nx-linux-x64-gnu@16.10.0': + optional: true + + '@nx/nx-linux-x64-musl@16.10.0': + optional: true + + '@nx/nx-win32-arm64-msvc@16.10.0': + optional: true + + '@nx/nx-win32-x64-msvc@16.10.0': + optional: true + + '@nymproject/contract-clients@1.4.1': {} + + '@nymproject/mix-fetch@1.4.4': {} + + '@nymproject/nym-validator-client@0.18.0': + dependencies: + '@cosmjs/cosmwasm-stargate': 0.25.6 + '@cosmjs/math': 0.25.6 + '@cosmjs/proto-signing': 0.25.6 + '@cosmjs/stargate': 0.25.6 + axios: 0.21.4 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + + '@octokit/auth-token@3.0.4': {} + + '@octokit/core@4.2.4(encoding@0.1.13)': + dependencies: + '@octokit/auth-token': 3.0.4 + '@octokit/graphql': 5.0.6(encoding@0.1.13) + '@octokit/request': 6.2.8(encoding@0.1.13) + '@octokit/request-error': 3.0.3 + '@octokit/types': 9.3.2 + before-after-hook: 2.2.3 + universal-user-agent: 6.0.1 + transitivePeerDependencies: + - encoding + + '@octokit/endpoint@7.0.6': + dependencies: + '@octokit/types': 9.3.2 + is-plain-object: 5.0.0 + universal-user-agent: 6.0.1 + + '@octokit/graphql@5.0.6(encoding@0.1.13)': + dependencies: + '@octokit/request': 6.2.8(encoding@0.1.13) + '@octokit/types': 9.3.2 + universal-user-agent: 6.0.1 + transitivePeerDependencies: + - encoding + + '@octokit/openapi-types@18.1.1': {} + + '@octokit/plugin-enterprise-rest@6.0.1': {} + + '@octokit/plugin-paginate-rest@6.1.2(@octokit/core@4.2.4(encoding@0.1.13))': + dependencies: + '@octokit/core': 4.2.4(encoding@0.1.13) + '@octokit/tsconfig': 1.0.2 + '@octokit/types': 9.3.2 + + '@octokit/plugin-request-log@1.0.4(@octokit/core@4.2.4(encoding@0.1.13))': + dependencies: + '@octokit/core': 4.2.4(encoding@0.1.13) + + '@octokit/plugin-rest-endpoint-methods@7.2.3(@octokit/core@4.2.4(encoding@0.1.13))': + dependencies: + '@octokit/core': 4.2.4(encoding@0.1.13) + '@octokit/types': 10.0.0 + + '@octokit/request-error@3.0.3': + dependencies: + '@octokit/types': 9.3.2 + deprecation: 2.3.1 + once: 1.4.0 + + '@octokit/request@6.2.8(encoding@0.1.13)': + dependencies: + '@octokit/endpoint': 7.0.6 + '@octokit/request-error': 3.0.3 + '@octokit/types': 9.3.2 + is-plain-object: 5.0.0 + node-fetch: 2.7.0(encoding@0.1.13) + universal-user-agent: 6.0.1 + transitivePeerDependencies: + - encoding + + '@octokit/rest@19.0.11(encoding@0.1.13)': + dependencies: + '@octokit/core': 4.2.4(encoding@0.1.13) + '@octokit/plugin-paginate-rest': 6.1.2(@octokit/core@4.2.4(encoding@0.1.13)) + '@octokit/plugin-request-log': 1.0.4(@octokit/core@4.2.4(encoding@0.1.13)) + '@octokit/plugin-rest-endpoint-methods': 7.2.3(@octokit/core@4.2.4(encoding@0.1.13)) + transitivePeerDependencies: + - encoding + + '@octokit/tsconfig@1.0.2': {} + + '@octokit/types@10.0.0': + dependencies: + '@octokit/openapi-types': 18.1.1 + + '@octokit/types@9.3.2': + dependencies: + '@octokit/openapi-types': 18.1.1 + + '@parcel/watcher@2.0.4': + dependencies: + node-addon-api: 3.2.1 + node-gyp-build: 4.8.4 + + '@pkgjs/parseargs@0.11.0': + optional: true + + '@pmmmwh/react-refresh-webpack-plugin@0.5.17(@types/webpack@4.41.40)(react-refresh@0.10.0)(type-fest@4.41.0)(webpack-dev-server@4.15.2)(webpack-hot-middleware@2.26.1)(webpack@5.106.2)': + dependencies: + ansi-html: 0.0.9 + core-js-pure: 3.49.0 + error-stack-parser: 2.1.4 + html-entities: 2.6.0 + loader-utils: 2.0.4 + react-refresh: 0.10.0 + schema-utils: 4.3.3 + source-map: 0.7.6 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + optionalDependencies: + '@types/webpack': 4.41.40 + type-fest: 4.41.0 + webpack-dev-server: 4.15.2(webpack-cli@4.10.0)(webpack@5.106.2) + webpack-hot-middleware: 2.26.1 + + '@pmmmwh/react-refresh-webpack-plugin@0.5.17(@types/webpack@4.41.40)(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@4.15.2(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)))(webpack-hot-middleware@2.26.1)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14))': + dependencies: + ansi-html: 0.0.9 + core-js-pure: 3.49.0 + error-stack-parser: 2.1.4 + html-entities: 2.6.0 + loader-utils: 2.0.4 + react-refresh: 0.11.0 + schema-utils: 4.3.3 + source-map: 0.7.6 + webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + optionalDependencies: + '@types/webpack': 4.41.40 + type-fest: 4.41.0 + webpack-dev-server: 4.15.2(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + webpack-hot-middleware: 2.26.1 + + '@popperjs/core@2.11.8': {} + + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.5': {} + + '@protobufjs/eventemitter@1.1.0': {} + + '@protobufjs/fetch@1.1.0': + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.1 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/inquire@1.1.1': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.1': {} + + '@react-aria/listbox@3.16.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@swc/helpers': 0.5.21 + react: 19.2.6 + react-aria: 3.48.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react-dom: 19.2.6(react@19.2.6) + + '@react-aria/overlays@3.32.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@swc/helpers': 0.5.21 + react: 19.2.6 + react-aria: 3.48.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react-dom: 19.2.6(react@19.2.6) + + '@react-aria/utils@3.34.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@swc/helpers': 0.5.21 + react: 19.2.6 + react-aria: 3.48.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react-dom: 19.2.6(react@19.2.6) + react-stately: 3.46.0(react@19.2.6) + + '@react-icons/all-files@4.1.0(react@19.2.6)': + dependencies: + react: 19.2.6 + + '@react-spring/animated@9.7.5(react@19.2.6)': + dependencies: + '@react-spring/shared': 9.7.5(react@19.2.6) + '@react-spring/types': 9.7.5 + react: 19.2.6 + + '@react-spring/core@9.7.5(react@19.2.6)': + dependencies: + '@react-spring/animated': 9.7.5(react@19.2.6) + '@react-spring/shared': 9.7.5(react@19.2.6) + '@react-spring/types': 9.7.5 + react: 19.2.6 + + '@react-spring/rafz@9.7.5': {} + + '@react-spring/shared@9.7.5(react@19.2.6)': + dependencies: + '@react-spring/rafz': 9.7.5 + '@react-spring/types': 9.7.5 + react: 19.2.6 + + '@react-spring/types@9.7.5': {} + + '@react-spring/web@9.7.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@react-spring/animated': 9.7.5(react@19.2.6) + '@react-spring/core': 9.7.5(react@19.2.6) + '@react-spring/shared': 9.7.5(react@19.2.6) + '@react-spring/types': 9.7.5 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + + '@react-types/shared@3.34.0(react@19.2.6)': + dependencies: + react: 19.2.6 + + '@remix-run/router@1.23.2': {} + + '@rtsao/scc@1.1.0': {} + + '@rushstack/eslint-patch@1.16.1': {} + + '@scure/base@1.2.6': {} + + '@scure/starknet@1.1.0': + dependencies: + '@noble/curves': 1.7.0 + '@noble/hashes': 1.6.1 + + '@sideway/address@4.1.5': + dependencies: + '@hapi/hoek': 9.3.0 + + '@sideway/formula@3.0.1': {} + + '@sideway/pinpoint@2.0.0': {} + + '@sigstore/bundle@1.1.0': + dependencies: + '@sigstore/protobuf-specs': 0.2.1 + + '@sigstore/protobuf-specs@0.2.1': {} + + '@sigstore/sign@1.0.0': + dependencies: + '@sigstore/bundle': 1.1.0 + '@sigstore/protobuf-specs': 0.2.1 + make-fetch-happen: 11.1.1 + transitivePeerDependencies: + - supports-color + + '@sigstore/tuf@1.0.3': + dependencies: + '@sigstore/protobuf-specs': 0.2.1 + tuf-js: 1.1.7 + transitivePeerDependencies: + - supports-color + + '@sinclair/typebox@0.27.10': {} + + '@sinonjs/commons@1.8.6': + dependencies: + type-detect: 4.0.8 + + '@sinonjs/commons@3.0.1': + dependencies: + type-detect: 4.0.8 + + '@sinonjs/fake-timers@10.3.0': + dependencies: + '@sinonjs/commons': 3.0.1 + + '@sinonjs/fake-timers@8.1.0': + dependencies: + '@sinonjs/commons': 1.8.6 + + '@starknet-io/types-js@0.8.4': {} + + '@starknet-io/types-js@0.9.2': {} + + '@storybook/addon-actions@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/components': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-events': 6.5.16 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + core-js: 3.49.0 + fast-deep-equal: 3.1.3 + global: 4.4.0 + lodash: 4.18.1 + polished: 4.3.1 + prop-types: 15.8.1 + react-inspector: 5.1.1(react@19.2.6) + regenerator-runtime: 0.13.11 + telejson: 6.0.8 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + uuid-browser: 3.1.0 + optionalDependencies: + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + + '@storybook/addon-backgrounds@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/components': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-events': 6.5.16 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + core-js: 3.49.0 + global: 4.4.0 + memoizerific: 1.11.3 + regenerator-runtime: 0.13.11 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + optionalDependencies: + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + + '@storybook/addon-controls@6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': + dependencies: + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/components': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-common': 6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/node-logger': 6.5.16 + '@storybook/store': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + core-js: 3.49.0 + lodash: 4.18.1 + ts-dedent: 2.2.0 + optionalDependencies: + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + transitivePeerDependencies: + - eslint + - supports-color + - typescript + - vue-template-compiler + - webpack-cli + - webpack-command + + '@storybook/addon-docs@6.5.16(@babel/core@7.29.0)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14))': + dependencies: + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/preset-env': 7.29.5(@babel/core@7.29.0) + '@jest/transform': 26.6.2 + '@mdx-js/react': 1.6.22(react@19.2.6) + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/components': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-common': 6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/core-events': 6.5.16 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/docs-tools': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/mdx1-csf': 0.0.1(@babel/core@7.29.0) + '@storybook/node-logger': 6.5.16 + '@storybook/postinstall': 6.5.16 + '@storybook/preview-web': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/source-loader': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/store': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + core-js: 3.49.0 + fast-deep-equal: 3.1.3 + global: 4.4.0 + lodash: 4.18.1 + regenerator-runtime: 0.13.11 + remark-external-links: 8.0.0 + remark-slug: 6.1.0 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + optionalDependencies: + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + transitivePeerDependencies: + - '@babel/core' + - eslint + - supports-color + - typescript + - vue-template-compiler + - webpack + - webpack-cli + - webpack-command + + '@storybook/addon-essentials@6.5.16(@babel/core@7.29.0)(@storybook/builder-webpack5@6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14))': + dependencies: + '@babel/core': 7.29.0 + '@storybook/addon-actions': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/addon-backgrounds': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/addon-controls': 6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/addon-docs': 6.5.16(@babel/core@7.29.0)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + '@storybook/addon-measure': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/addon-outline': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/addon-toolbars': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/addon-viewport': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-common': 6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/node-logger': 6.5.16 + core-js: 3.49.0 + regenerator-runtime: 0.13.11 + ts-dedent: 2.2.0 + optionalDependencies: + '@storybook/builder-webpack5': 6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + transitivePeerDependencies: + - '@storybook/mdx2-csf' + - eslint + - supports-color + - typescript + - vue-template-compiler + - webpack-cli + - webpack-command + + '@storybook/addon-interactions@6.5.16(@types/react@19.2.14)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': + dependencies: + '@devtools-ds/object-inspector': 1.2.1(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/components': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-common': 6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/core-events': 6.5.16 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/instrumenter': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + core-js: 3.49.0 + global: 4.4.0 + jest-mock: 27.5.1 + polished: 4.3.1 + ts-dedent: 2.2.0 + optionalDependencies: + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + transitivePeerDependencies: + - '@types/react' + - eslint + - supports-color + - typescript + - vue-template-compiler + - webpack-cli + - webpack-command + + '@storybook/addon-links@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/core-events': 6.5.16 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/router': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/qs': 6.15.1 + core-js: 3.49.0 + global: 4.4.0 + prop-types: 15.8.1 + qs: 6.15.1 + regenerator-runtime: 0.13.11 + ts-dedent: 2.2.0 + optionalDependencies: + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + + '@storybook/addon-measure@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/components': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-events': 6.5.16 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + core-js: 3.49.0 + global: 4.4.0 + optionalDependencies: + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + + '@storybook/addon-outline@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/components': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-events': 6.5.16 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + core-js: 3.49.0 + global: 4.4.0 + regenerator-runtime: 0.13.11 + ts-dedent: 2.2.0 + optionalDependencies: + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + + '@storybook/addon-toolbars@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/components': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + core-js: 3.49.0 + regenerator-runtime: 0.13.11 + optionalDependencies: + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + + '@storybook/addon-viewport@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/components': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-events': 6.5.16 + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + core-js: 3.49.0 + global: 4.4.0 + memoizerific: 1.11.3 + prop-types: 15.8.1 + regenerator-runtime: 0.13.11 + optionalDependencies: + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + + '@storybook/addons@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@storybook/api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/channels': 6.5.16 + '@storybook/client-logger': 6.5.16 + '@storybook/core-events': 6.5.16 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/router': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/webpack-env': 1.18.8 + core-js: 3.49.0 + global: 4.4.0 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + regenerator-runtime: 0.13.11 + + '@storybook/api@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@storybook/channels': 6.5.16 + '@storybook/client-logger': 6.5.16 + '@storybook/core-events': 6.5.16 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/router': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/semver': 7.3.2 + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + core-js: 3.49.0 + fast-deep-equal: 3.1.3 + global: 4.4.0 + lodash: 4.18.1 + memoizerific: 1.11.3 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + regenerator-runtime: 0.13.11 + store2: 2.14.4 + telejson: 6.0.8 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + + '@storybook/builder-webpack4@6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': + dependencies: + '@babel/core': 7.29.0 + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/channel-postmessage': 6.5.16 + '@storybook/channels': 6.5.16 + '@storybook/client-api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/components': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-common': 6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/core-events': 6.5.16 + '@storybook/node-logger': 6.5.16 + '@storybook/preview-web': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/router': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/semver': 7.3.2 + '@storybook/store': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/ui': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/node': 16.18.126 + '@types/webpack': 4.41.40 + autoprefixer: 9.8.8 + babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@4.47.0) + case-sensitive-paths-webpack-plugin: 2.4.0 + core-js: 3.49.0 + css-loader: 3.6.0(webpack@4.47.0) + file-loader: 6.2.0(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + find-up: 5.0.0 + fork-ts-checker-webpack-plugin: 4.1.6(eslint@9.39.4)(typescript@4.9.5)(webpack@4.47.0) + glob: 7.2.3 + glob-promise: 3.4.0(glob@7.2.3) + global: 4.4.0 + html-webpack-plugin: 4.5.2(webpack@4.47.0) + pnp-webpack-plugin: 1.6.4(typescript@4.9.5) + postcss: 7.0.39 + postcss-flexbugs-fixes: 4.2.1 + postcss-loader: 4.3.0(postcss@7.0.39)(webpack@4.47.0) + raw-loader: 4.0.2(webpack@4.47.0) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + stable: 0.1.8 + style-loader: 1.3.0(webpack@4.47.0) + terser-webpack-plugin: 4.2.3(webpack@4.47.0) + ts-dedent: 2.2.0 + url-loader: 4.1.1(file-loader@6.2.0(webpack@4.47.0))(webpack@4.47.0) + util-deprecate: 1.0.2 + webpack: 4.47.0 + webpack-dev-middleware: 3.7.3(webpack@4.47.0) + webpack-filter-warnings-plugin: 1.2.1(webpack@4.47.0) + webpack-hot-middleware: 2.26.1 + webpack-virtual-modules: 0.2.2 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - bluebird + - eslint + - supports-color + - vue-template-compiler + - webpack-cli + - webpack-command + + '@storybook/builder-webpack5@6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': + dependencies: + '@babel/core': 7.29.0 + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/channel-postmessage': 6.5.16 + '@storybook/channels': 6.5.16 + '@storybook/client-api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/components': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-common': 6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/core-events': 6.5.16 + '@storybook/node-logger': 6.5.16 + '@storybook/preview-web': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/router': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/semver': 7.3.2 + '@storybook/store': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/node': 16.18.126 + babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + babel-plugin-named-exports-order: 0.0.2 + browser-assert: 1.2.1 + case-sensitive-paths-webpack-plugin: 2.4.0 + core-js: 3.49.0 + css-loader: 5.2.7(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + fork-ts-checker-webpack-plugin: 6.5.3(eslint@9.39.4)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + glob: 7.2.3 + glob-promise: 3.4.0(glob@7.2.3) + html-webpack-plugin: 5.6.7(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + path-browserify: 1.0.1 + process: 0.11.10 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + stable: 0.1.8 + style-loader: 2.0.0(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + terser-webpack-plugin: 5.6.0(esbuild@0.25.12)(postcss@8.5.14)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + webpack-dev-middleware: 4.3.0(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + webpack-hot-middleware: 2.26.1 + webpack-virtual-modules: 0.4.6 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - '@minify-html/node' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - esbuild + - eslint + - html-minifier-terser + - lightningcss + - postcss + - supports-color + - uglify-js + - vue-template-compiler + - webpack-cli + - webpack-command + + '@storybook/channel-postmessage@6.5.16': + dependencies: + '@storybook/channels': 6.5.16 + '@storybook/client-logger': 6.5.16 + '@storybook/core-events': 6.5.16 + core-js: 3.49.0 + global: 4.4.0 + qs: 6.15.1 + telejson: 6.0.8 + + '@storybook/channel-websocket@6.5.16': + dependencies: + '@storybook/channels': 6.5.16 + '@storybook/client-logger': 6.5.16 + core-js: 3.49.0 + global: 4.4.0 + telejson: 6.0.8 + + '@storybook/channels@6.5.16': + dependencies: + core-js: 3.49.0 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + + '@storybook/client-api@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/channel-postmessage': 6.5.16 + '@storybook/channels': 6.5.16 + '@storybook/client-logger': 6.5.16 + '@storybook/core-events': 6.5.16 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/store': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/qs': 6.15.1 + '@types/webpack-env': 1.18.8 + core-js: 3.49.0 + fast-deep-equal: 3.1.3 + global: 4.4.0 + lodash: 4.18.1 + memoizerific: 1.11.3 + qs: 6.15.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + regenerator-runtime: 0.13.11 + store2: 2.14.4 + synchronous-promise: 2.0.17 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + + '@storybook/client-logger@6.5.16': + dependencies: + core-js: 3.49.0 + global: 4.4.0 + + '@storybook/client-logger@8.6.14(storybook@8.6.18(prettier@2.8.8))': + dependencies: + storybook: 8.6.18(prettier@2.8.8) + + '@storybook/components@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@storybook/client-logger': 6.5.16 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + core-js: 3.49.0 + memoizerific: 1.11.3 + qs: 6.15.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + regenerator-runtime: 0.13.11 + util-deprecate: 1.0.2 + + '@storybook/core-client@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@4.47.0)': + dependencies: + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/channel-postmessage': 6.5.16 + '@storybook/channel-websocket': 6.5.16 + '@storybook/client-api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/core-events': 6.5.16 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/preview-web': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/store': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/ui': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + airbnb-js-shims: 2.2.1 + ansi-to-html: 0.6.15 + core-js: 3.49.0 + global: 4.4.0 + lodash: 4.18.1 + qs: 6.15.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + regenerator-runtime: 0.13.11 + ts-dedent: 2.2.0 + unfetch: 4.2.0 + util-deprecate: 1.0.2 + webpack: 4.47.0 + optionalDependencies: + typescript: 4.9.5 + + '@storybook/core-client@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14))': + dependencies: + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/channel-postmessage': 6.5.16 + '@storybook/channel-websocket': 6.5.16 + '@storybook/client-api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/core-events': 6.5.16 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/preview-web': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/store': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/ui': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + airbnb-js-shims: 2.2.1 + ansi-to-html: 0.6.15 + core-js: 3.49.0 + global: 4.4.0 + lodash: 4.18.1 + qs: 6.15.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + regenerator-runtime: 0.13.11 + ts-dedent: 2.2.0 + unfetch: 4.2.0 + util-deprecate: 1.0.2 + webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + optionalDependencies: + typescript: 4.9.5 + + '@storybook/core-common@6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.29.0) + '@babel/plugin-proposal-decorators': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-proposal-export-default-from': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.29.0) + '@babel/plugin-proposal-object-rest-spread': 7.20.7(@babel/core@7.29.0) + '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.29.0) + '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.29.0) + '@babel/plugin-proposal-private-property-in-object': 7.21.11(@babel/core@7.29.0) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-classes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-spread': 7.28.6(@babel/core@7.29.0) + '@babel/preset-env': 7.29.5(@babel/core@7.29.0) + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) + '@babel/register': 7.29.3(@babel/core@7.29.0) + '@storybook/node-logger': 6.5.16 + '@storybook/semver': 7.3.2 + '@types/node': 16.18.126 + '@types/pretty-hrtime': 1.0.3 + babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@4.47.0) + babel-plugin-macros: 3.1.0 + babel-plugin-polyfill-corejs3: 0.1.7(@babel/core@7.29.0) + chalk: 4.1.2 + core-js: 3.49.0 + express: 4.22.2 + file-system-cache: 1.1.0 + find-up: 5.0.0 + fork-ts-checker-webpack-plugin: 6.5.3(eslint@9.39.4)(typescript@4.9.5)(webpack@4.47.0) + fs-extra: 9.1.0 + glob: 7.2.3 + handlebars: 4.7.9 + interpret: 2.2.0 + json5: 2.2.3 + lazy-universal-dotenv: 3.0.1 + picomatch: 2.3.2 + pkg-dir: 5.0.0 + pretty-hrtime: 1.0.3 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + resolve-from: 5.0.0 + slash: 3.0.0 + telejson: 6.0.8 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + webpack: 4.47.0 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - eslint + - supports-color + - vue-template-compiler + - webpack-cli + - webpack-command + + '@storybook/core-events@6.5.16': + dependencies: + core-js: 3.49.0 + + '@storybook/core-server@6.5.16(@storybook/builder-webpack5@6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(encoding@0.1.13)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': + dependencies: + '@discoveryjs/json-ext': 0.5.7 + '@storybook/builder-webpack4': 6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/core-client': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@4.47.0) + '@storybook/core-common': 6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/core-events': 6.5.16 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/csf-tools': 6.5.16 + '@storybook/manager-webpack4': 6.5.16(encoding@0.1.13)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/node-logger': 6.5.16 + '@storybook/semver': 7.3.2 + '@storybook/store': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/telemetry': 6.5.16(encoding@0.1.13)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@types/node': 16.18.126 + '@types/node-fetch': 2.6.13 + '@types/pretty-hrtime': 1.0.3 + '@types/webpack': 4.41.40 + better-opn: 2.1.1 + boxen: 5.1.2 + chalk: 4.1.2 + cli-table3: 0.6.5 + commander: 6.2.1 + compression: 1.8.1 + core-js: 3.49.0 + cpy: 8.1.2 + detect-port: 1.6.1 + express: 4.22.2 + fs-extra: 9.1.0 + global: 4.4.0 + globby: 11.1.0 + ip: 2.0.1 + lodash: 4.18.1 + node-fetch: 2.7.0(encoding@0.1.13) + open: 8.4.2 + pretty-hrtime: 1.0.3 + prompts: 2.4.2 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + regenerator-runtime: 0.13.11 + serve-favicon: 2.5.1 + slash: 3.0.0 + telejson: 6.0.8 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + watchpack: 2.5.1 + webpack: 4.47.0 + ws: 8.20.1 + x-default-browser: 0.4.0 + optionalDependencies: + '@storybook/builder-webpack5': 6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/manager-webpack5': 6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - '@storybook/mdx2-csf' + - bluebird + - bufferutil + - encoding + - eslint + - supports-color + - utf-8-validate + - vue-template-compiler + - webpack-cli + - webpack-command + + '@storybook/core@6.5.16(@storybook/builder-webpack5@6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(encoding@0.1.13)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14))': + dependencies: + '@storybook/core-client': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + '@storybook/core-server': 6.5.16(@storybook/builder-webpack5@6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(encoding@0.1.13)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + optionalDependencies: + '@storybook/builder-webpack5': 6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/manager-webpack5': 6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - '@storybook/mdx2-csf' + - bluebird + - bufferutil + - encoding + - eslint + - supports-color + - utf-8-validate + - vue-template-compiler + - webpack-cli + - webpack-command + + '@storybook/core@8.6.18(prettier@2.8.8)(storybook@8.6.18(prettier@2.8.8))': + dependencies: + '@storybook/theming': 8.6.18(storybook@8.6.18(prettier@2.8.8)) + better-opn: 3.0.2 + browser-assert: 1.2.1 + esbuild: 0.25.12 + esbuild-register: 3.6.0(esbuild@0.25.12) + jsdoc-type-pratt-parser: 4.8.0 + process: 0.11.10 + recast: 0.23.11 + semver: 7.8.0 + util: 0.12.5 + ws: 8.20.1 + optionalDependencies: + prettier: 2.8.8 + transitivePeerDependencies: + - bufferutil + - storybook + - supports-color + - utf-8-validate + + '@storybook/csf-tools@6.5.16': + dependencies: + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.3 + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/preset-env': 7.29.5(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/mdx1-csf': 0.0.1(@babel/core@7.29.0) + core-js: 3.49.0 + fs-extra: 9.1.0 + global: 4.4.0 + regenerator-runtime: 0.13.11 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - supports-color + + '@storybook/csf@0.0.1': + dependencies: + lodash: 4.18.1 + + '@storybook/csf@0.0.2--canary.4566f4d.1': + dependencies: + lodash: 4.18.1 + + '@storybook/docs-tools@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@babel/core': 7.29.0 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/store': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + core-js: 3.49.0 + doctrine: 3.0.0 + lodash: 4.18.1 + regenerator-runtime: 0.13.11 + transitivePeerDependencies: + - react + - react-dom + - supports-color + + '@storybook/global@5.0.0': {} + + '@storybook/instrumenter@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/core-events': 6.5.16 + core-js: 3.49.0 + global: 4.4.0 + transitivePeerDependencies: + - react + - react-dom + + '@storybook/instrumenter@8.6.14(storybook@8.6.18(prettier@2.8.8))': + dependencies: + '@storybook/global': 5.0.0 + '@vitest/utils': 2.1.9 + storybook: 8.6.18(prettier@2.8.8) + + '@storybook/manager-webpack4@6.5.16(encoding@0.1.13)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.29.0) + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-client': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@4.47.0) + '@storybook/core-common': 6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/node-logger': 6.5.16 + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/ui': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/node': 16.18.126 + '@types/webpack': 4.41.40 + babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@4.47.0) + case-sensitive-paths-webpack-plugin: 2.4.0 + chalk: 4.1.2 + core-js: 3.49.0 + css-loader: 3.6.0(webpack@4.47.0) + express: 4.22.2 + file-loader: 6.2.0(webpack@4.47.0) + find-up: 5.0.0 + fs-extra: 9.1.0 + html-webpack-plugin: 4.5.2(webpack@4.47.0) + node-fetch: 2.7.0(encoding@0.1.13) + pnp-webpack-plugin: 1.6.4(typescript@4.9.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + read-pkg-up: 7.0.1 + regenerator-runtime: 0.13.11 + resolve-from: 5.0.0 + style-loader: 1.3.0(webpack@4.47.0) + telejson: 6.0.8 + terser-webpack-plugin: 4.2.3(webpack@4.47.0) + ts-dedent: 2.2.0 + url-loader: 4.1.1(file-loader@6.2.0(webpack@4.47.0))(webpack@4.47.0) + util-deprecate: 1.0.2 + webpack: 4.47.0 + webpack-dev-middleware: 3.7.3(webpack@4.47.0) + webpack-virtual-modules: 0.2.2 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - bluebird + - encoding + - eslint + - supports-color + - vue-template-compiler + - webpack-cli + - webpack-command + + '@storybook/manager-webpack5@6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.29.0) + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-client': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + '@storybook/core-common': 6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/node-logger': 6.5.16 + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/ui': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/node': 16.18.126 + babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + case-sensitive-paths-webpack-plugin: 2.4.0 + chalk: 4.1.2 + core-js: 3.49.0 + css-loader: 5.2.7(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + express: 4.22.2 + find-up: 5.0.0 + fs-extra: 9.1.0 + html-webpack-plugin: 5.6.7(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + node-fetch: 2.7.0(encoding@0.1.13) + process: 0.11.10 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + read-pkg-up: 7.0.1 + regenerator-runtime: 0.13.11 + resolve-from: 5.0.0 + style-loader: 2.0.0(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + telejson: 6.0.8 + terser-webpack-plugin: 5.6.0(esbuild@0.25.12)(postcss@8.5.14)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + webpack-dev-middleware: 4.3.0(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + webpack-virtual-modules: 0.4.6 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - '@minify-html/node' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - encoding + - esbuild + - eslint + - html-minifier-terser + - lightningcss + - postcss + - supports-color + - uglify-js + - vue-template-compiler + - webpack-cli + - webpack-command + + '@storybook/mdx1-csf@0.0.1(@babel/core@7.29.0)': + dependencies: + '@babel/generator': 7.29.1 + '@babel/parser': 7.29.3 + '@babel/preset-env': 7.29.5(@babel/core@7.29.0) + '@babel/types': 7.29.0 + '@mdx-js/mdx': 1.6.22 + '@types/lodash': 4.17.24 + js-string-escape: 1.0.1 + loader-utils: 2.0.4 + lodash: 4.18.1 + prettier: 2.3.0 + ts-dedent: 2.2.0 + transitivePeerDependencies: + - '@babel/core' + - supports-color + + '@storybook/node-logger@6.5.16': + dependencies: + '@types/npmlog': 4.1.6 + chalk: 4.1.2 + core-js: 3.49.0 + npmlog: 5.0.1 + pretty-hrtime: 1.0.3 + + '@storybook/postinstall@6.5.16': + dependencies: + core-js: 3.49.0 + + '@storybook/preview-web@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/channel-postmessage': 6.5.16 + '@storybook/client-logger': 6.5.16 + '@storybook/core-events': 6.5.16 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/store': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + ansi-to-html: 0.6.15 + core-js: 3.49.0 + global: 4.4.0 + lodash: 4.18.1 + qs: 6.15.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + regenerator-runtime: 0.13.11 + synchronous-promise: 2.0.17 + ts-dedent: 2.2.0 + unfetch: 4.2.0 + util-deprecate: 1.0.2 + + '@storybook/react-docgen-typescript-plugin@1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14))': + dependencies: + debug: 4.4.3 + endent: 2.1.0 + find-cache-dir: 3.3.2 + flat-cache: 3.2.0 + micromatch: 4.0.8 + react-docgen-typescript: 2.4.0(typescript@4.9.5) + tslib: 2.8.1 + typescript: 4.9.5 + webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + transitivePeerDependencies: + - supports-color + + '@storybook/react@6.5.16(@babel/core@7.29.0)(@storybook/builder-webpack5@6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@types/webpack@4.41.40)(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(require-from-string@2.0.2)(type-fest@4.41.0)(typescript@4.9.5)(webpack-dev-server@4.15.2(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)))(webpack-hot-middleware@2.26.1)': + dependencies: + '@babel/preset-flow': 7.27.1(@babel/core@7.29.0) + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@pmmmwh/react-refresh-webpack-plugin': 0.5.17(@types/webpack@4.41.40)(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@4.15.2(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)))(webpack-hot-middleware@2.26.1)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/core': 6.5.16(@storybook/builder-webpack5@6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(encoding@0.1.13)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + '@storybook/core-common': 6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/docs-tools': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/node-logger': 6.5.16 + '@storybook/react-docgen-typescript-plugin': 1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + '@storybook/semver': 7.3.2 + '@storybook/store': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/estree': 0.0.51 + '@types/node': 16.18.126 + '@types/webpack-env': 1.18.8 + acorn: 7.4.1 + acorn-jsx: 5.3.2(acorn@7.4.1) + acorn-walk: 7.2.0 + babel-plugin-add-react-displayname: 0.0.5 + babel-plugin-react-docgen: 4.2.1 + core-js: 3.49.0 + escodegen: 2.1.0 + fs-extra: 9.1.0 + global: 4.4.0 + html-tags: 3.3.1 + lodash: 4.18.1 + prop-types: 15.8.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-element-to-jsx-string: 14.3.4(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react-refresh: 0.11.0 + read-pkg-up: 7.0.1 + regenerator-runtime: 0.13.11 + require-from-string: 2.0.2 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + optionalDependencies: + '@babel/core': 7.29.0 + '@storybook/builder-webpack5': 6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/manager-webpack5': 6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - '@minify-html/node' + - '@storybook/mdx2-csf' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - '@types/webpack' + - bluebird + - bufferutil + - clean-css + - cssnano + - csso + - encoding + - esbuild + - eslint + - html-minifier-terser + - lightningcss + - postcss + - sockjs-client + - supports-color + - type-fest + - uglify-js + - utf-8-validate + - vue-template-compiler + - webpack-cli + - webpack-command + - webpack-dev-server + - webpack-hot-middleware + - webpack-plugin-serve + + '@storybook/router@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@storybook/client-logger': 6.5.16 + core-js: 3.49.0 + memoizerific: 1.11.3 + qs: 6.15.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + regenerator-runtime: 0.13.11 + + '@storybook/semver@7.3.2': + dependencies: + core-js: 3.49.0 + find-up: 4.1.0 + + '@storybook/source-loader@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + core-js: 3.49.0 + estraverse: 5.3.0 + global: 4.4.0 + loader-utils: 2.0.4 + lodash: 4.18.1 + prettier: 2.3.0 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + regenerator-runtime: 0.13.11 + + '@storybook/store@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/core-events': 6.5.16 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + core-js: 3.49.0 + fast-deep-equal: 3.1.3 + global: 4.4.0 + lodash: 4.18.1 + memoizerific: 1.11.3 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + regenerator-runtime: 0.13.11 + slash: 3.0.0 + stable: 0.1.8 + synchronous-promise: 2.0.17 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + + '@storybook/telemetry@6.5.16(encoding@0.1.13)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': + dependencies: + '@storybook/client-logger': 6.5.16 + '@storybook/core-common': 6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + chalk: 4.1.2 + core-js: 3.49.0 + detect-package-manager: 2.0.1 + fetch-retry: 5.0.6 + fs-extra: 9.1.0 + global: 4.4.0 + isomorphic-unfetch: 3.1.0(encoding@0.1.13) + nanoid: 3.3.12 + read-pkg-up: 7.0.1 + regenerator-runtime: 0.13.11 + transitivePeerDependencies: + - encoding + - eslint + - react + - react-dom + - supports-color + - typescript + - vue-template-compiler + - webpack-cli + - webpack-command + + '@storybook/testing-library@0.0.9(storybook@8.6.18(prettier@2.8.8))': + dependencies: + '@storybook/client-logger': 8.6.14(storybook@8.6.18(prettier@2.8.8)) + '@storybook/instrumenter': 8.6.14(storybook@8.6.18(prettier@2.8.8)) + '@testing-library/dom': 8.20.1 + '@testing-library/user-event': 13.5.0(@testing-library/dom@8.20.1) + ts-dedent: 2.2.0 + transitivePeerDependencies: + - storybook + + '@storybook/theming@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@storybook/client-logger': 6.5.16 + core-js: 3.49.0 + memoizerific: 1.11.3 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + regenerator-runtime: 0.13.11 + + '@storybook/theming@8.6.18(storybook@8.6.18(prettier@2.8.8))': + dependencies: + storybook: 8.6.18(prettier@2.8.8) + + '@storybook/ui@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/channels': 6.5.16 + '@storybook/client-logger': 6.5.16 + '@storybook/components': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-events': 6.5.16 + '@storybook/router': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/semver': 7.3.2 + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + core-js: 3.49.0 + memoizerific: 1.11.3 + qs: 6.15.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + regenerator-runtime: 0.13.11 + resolve-from: 5.0.0 + + '@svgr/babel-plugin-add-jsx-attribute@6.5.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-plugin-remove-jsx-attribute@8.0.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-plugin-remove-jsx-empty-expression@8.0.0(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-plugin-replace-jsx-attribute-value@6.5.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-plugin-svg-dynamic-title@6.5.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-plugin-svg-em-dimensions@6.5.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-plugin-transform-react-native-svg@6.5.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-plugin-transform-svg-component@6.5.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + + '@svgr/babel-preset@6.5.1(@babel/core@7.29.0)': + dependencies: + '@babel/core': 7.29.0 + '@svgr/babel-plugin-add-jsx-attribute': 6.5.1(@babel/core@7.29.0) + '@svgr/babel-plugin-remove-jsx-attribute': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-remove-jsx-empty-expression': 8.0.0(@babel/core@7.29.0) + '@svgr/babel-plugin-replace-jsx-attribute-value': 6.5.1(@babel/core@7.29.0) + '@svgr/babel-plugin-svg-dynamic-title': 6.5.1(@babel/core@7.29.0) + '@svgr/babel-plugin-svg-em-dimensions': 6.5.1(@babel/core@7.29.0) + '@svgr/babel-plugin-transform-react-native-svg': 6.5.1(@babel/core@7.29.0) + '@svgr/babel-plugin-transform-svg-component': 6.5.1(@babel/core@7.29.0) + + '@svgr/core@6.5.1': + dependencies: + '@babel/core': 7.29.0 + '@svgr/babel-preset': 6.5.1(@babel/core@7.29.0) + '@svgr/plugin-jsx': 6.5.1(@svgr/core@6.5.1) + camelcase: 6.3.0 + cosmiconfig: 7.1.0 + transitivePeerDependencies: + - supports-color + + '@svgr/hast-util-to-babel-ast@6.5.1': + dependencies: + '@babel/types': 7.29.0 + entities: 4.5.0 + + '@svgr/plugin-jsx@6.5.1(@svgr/core@6.5.1)': + dependencies: + '@babel/core': 7.29.0 + '@svgr/babel-preset': 6.5.1(@babel/core@7.29.0) + '@svgr/core': 6.5.1 + '@svgr/hast-util-to-babel-ast': 6.5.1 + svg-parser: 2.0.4 + transitivePeerDependencies: + - supports-color + + '@svgr/plugin-svgo@6.5.1(@svgr/core@6.5.1)': + dependencies: + '@svgr/core': 6.5.1 + cosmiconfig: 7.1.0 + deepmerge: 4.3.1 + svgo: 2.8.2 + + '@svgr/webpack@6.5.1': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-react-constant-elements': 7.27.1(@babel/core@7.29.0) + '@babel/preset-env': 7.29.5(@babel/core@7.29.0) + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) + '@svgr/core': 6.5.1 + '@svgr/plugin-jsx': 6.5.1(@svgr/core@6.5.1) + '@svgr/plugin-svgo': 6.5.1(@svgr/core@6.5.1) + transitivePeerDependencies: + - supports-color + + '@swc/counter@0.1.3': {} + + '@swc/helpers@0.5.21': + dependencies: + tslib: 2.8.1 + + '@swc/helpers@0.5.5': + dependencies: + '@swc/counter': 0.1.3 + tslib: 2.8.1 + + '@tanstack/match-sorter-utils@8.19.4': + dependencies: + remove-accents: 0.5.0 + + '@tanstack/query-core@5.100.10': {} + + '@tanstack/query-devtools@5.100.10': {} + + '@tanstack/react-query-devtools@5.100.10(@tanstack/react-query@5.100.10(react@19.2.6))(react@19.2.6)': + dependencies: + '@tanstack/query-devtools': 5.100.10 + '@tanstack/react-query': 5.100.10(react@19.2.6) + react: 19.2.6 + + '@tanstack/react-query-next-experimental@5.100.10(@tanstack/react-query@5.100.10(react@19.2.6))(next@14.2.35(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react@19.2.6)': + dependencies: + '@tanstack/react-query': 5.100.10(react@19.2.6) + next: 14.2.35(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react: 19.2.6 + + '@tanstack/react-query@5.100.10(react@19.2.6)': + dependencies: + '@tanstack/query-core': 5.100.10 + react: 19.2.6 + + '@tanstack/react-table@8.20.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@tanstack/table-core': 8.20.5 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + + '@tanstack/react-table@8.21.3(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@tanstack/table-core': 8.21.3 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + + '@tanstack/react-virtual@3.11.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@tanstack/virtual-core': 3.11.2 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + + '@tanstack/react-virtual@3.13.24(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@tanstack/virtual-core': 3.14.0 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + + '@tanstack/table-core@8.20.5': {} + + '@tanstack/table-core@8.21.3': {} + + '@tanstack/virtual-core@3.11.2': {} + + '@tanstack/virtual-core@3.14.0': {} + + '@tauri-apps/api@2.10.1': {} + + '@tauri-apps/api@2.11.0': {} + + '@tauri-apps/cli-darwin-arm64@2.11.1': + optional: true + + '@tauri-apps/cli-darwin-x64@2.11.1': + optional: true + + '@tauri-apps/cli-linux-arm-gnueabihf@2.11.1': + optional: true + + '@tauri-apps/cli-linux-arm64-gnu@2.11.1': + optional: true + + '@tauri-apps/cli-linux-arm64-musl@2.11.1': + optional: true + + '@tauri-apps/cli-linux-riscv64-gnu@2.11.1': + optional: true + + '@tauri-apps/cli-linux-x64-gnu@2.11.1': + optional: true + + '@tauri-apps/cli-linux-x64-musl@2.11.1': + optional: true + + '@tauri-apps/cli-win32-arm64-msvc@2.11.1': + optional: true + + '@tauri-apps/cli-win32-ia32-msvc@2.11.1': + optional: true + + '@tauri-apps/cli-win32-x64-msvc@2.11.1': + optional: true + + '@tauri-apps/cli@2.11.1': + optionalDependencies: + '@tauri-apps/cli-darwin-arm64': 2.11.1 + '@tauri-apps/cli-darwin-x64': 2.11.1 + '@tauri-apps/cli-linux-arm-gnueabihf': 2.11.1 + '@tauri-apps/cli-linux-arm64-gnu': 2.11.1 + '@tauri-apps/cli-linux-arm64-musl': 2.11.1 + '@tauri-apps/cli-linux-riscv64-gnu': 2.11.1 + '@tauri-apps/cli-linux-x64-gnu': 2.11.1 + '@tauri-apps/cli-linux-x64-musl': 2.11.1 + '@tauri-apps/cli-win32-arm64-msvc': 2.11.1 + '@tauri-apps/cli-win32-ia32-msvc': 2.11.1 + '@tauri-apps/cli-win32-x64-msvc': 2.11.1 + + '@tauri-apps/plugin-clipboard-manager@2.3.2': + dependencies: + '@tauri-apps/api': 2.10.1 + + '@tauri-apps/plugin-opener@2.5.4': + dependencies: + '@tauri-apps/api': 2.11.0 + + '@tauri-apps/plugin-process@2.3.1': + dependencies: + '@tauri-apps/api': 2.10.1 + + '@tauri-apps/plugin-updater@2.10.1': + dependencies: + '@tauri-apps/api': 2.10.1 + + '@tauri-apps/tauri-forage@1.0.0-beta.2': + dependencies: + localforage: 1.10.0 + ramda: 0.26.1 + tweetnacl: 1.0.3 + tweetnacl-util: 0.15.1 + + '@testing-library/dom@10.4.1': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/runtime': 7.29.2 + '@types/aria-query': 5.0.4 + aria-query: 5.3.0 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + picocolors: 1.1.1 + pretty-format: 27.5.1 + + '@testing-library/dom@8.20.1': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/runtime': 7.29.2 + '@types/aria-query': 5.0.4 + aria-query: 5.1.3 + chalk: 4.1.2 + dom-accessibility-api: 0.5.16 + lz-string: 1.5.0 + pretty-format: 27.5.1 + + '@testing-library/jest-dom@6.9.1': + dependencies: + '@adobe/css-tools': 4.4.4 + aria-query: 5.3.2 + css.escape: 1.5.1 + dom-accessibility-api: 0.6.3 + picocolors: 1.1.1 + redent: 3.0.0 + + '@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@testing-library/dom': 10.4.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + optionalDependencies: + '@types/react': 19.2.14 + '@types/react-dom': 19.2.3(@types/react@19.2.14) + + '@testing-library/user-event@13.5.0(@testing-library/dom@8.20.1)': + dependencies: + '@babel/runtime': 7.29.2 + '@testing-library/dom': 8.20.1 + + '@tootallnate/once@1.1.2': {} + + '@tootallnate/once@2.0.1': {} + + '@tufjs/canonical-json@1.0.0': {} + + '@tufjs/models@1.0.4': + dependencies: + '@tufjs/canonical-json': 1.0.0 + minimatch: 9.0.9 + + '@tybys/wasm-util@0.10.2': + dependencies: + tslib: 2.8.1 + optional: true + + '@types/aria-query@5.0.4': {} + + '@types/babel__core@7.20.5': + dependencies: + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + '@types/babel__generator': 7.27.0 + '@types/babel__template': 7.4.4 + '@types/babel__traverse': 7.28.0 + + '@types/babel__generator@7.27.0': + dependencies: + '@babel/types': 7.29.0 + + '@types/babel__template@7.4.4': + dependencies: + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + + '@types/babel__traverse@7.28.0': + dependencies: + '@babel/types': 7.29.0 + + '@types/big.js@6.2.2': {} + + '@types/body-parser@1.19.6': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 22.19.19 + + '@types/bonjour@3.5.13': + dependencies: + '@types/node': 22.19.19 + + '@types/bs58@4.0.4': + dependencies: + '@types/node': 22.19.19 + base-x: 3.0.11 + + '@types/connect-history-api-fallback@1.5.4': + dependencies: + '@types/express-serve-static-core': 5.1.1 + '@types/node': 22.19.19 + + '@types/connect@3.4.38': + dependencies: + '@types/node': 22.19.19 + + '@types/d3-array@3.2.2': {} + + '@types/d3-color@3.1.3': {} + + '@types/d3-delaunay@6.0.4': {} + + '@types/d3-ease@3.0.2': {} + + '@types/d3-format@1.4.5': {} + + '@types/d3-interpolate@3.0.4': + dependencies: + '@types/d3-color': 3.1.3 + + '@types/d3-path@3.1.1': {} + + '@types/d3-scale-chromatic@3.1.0': {} + + '@types/d3-scale@4.0.9': + dependencies: + '@types/d3-time': 3.0.4 + + '@types/d3-shape@3.1.8': + dependencies: + '@types/d3-path': 3.1.1 + + '@types/d3-time-format@2.3.4': {} + + '@types/d3-time-format@3.0.4': {} + + '@types/d3-time@1.1.4': {} + + '@types/d3-time@3.0.4': {} + + '@types/d3-timer@3.0.2': {} + + '@types/debug@4.1.13': + dependencies: + '@types/ms': 2.1.0 + + '@types/eslint-scope@3.7.7': + dependencies: + '@types/eslint': 9.6.1 + '@types/estree': 1.0.9 + + '@types/eslint@9.6.1': + dependencies: + '@types/estree': 1.0.9 + '@types/json-schema': 7.0.15 + + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.9 + + '@types/estree@0.0.51': {} + + '@types/estree@1.0.9': {} + + '@types/express-serve-static-core@4.19.8': + dependencies: + '@types/node': 22.19.19 + '@types/qs': 6.15.1 + '@types/range-parser': 1.2.7 + '@types/send': 1.2.1 + + '@types/express-serve-static-core@5.1.1': + dependencies: + '@types/node': 22.19.19 + '@types/qs': 6.15.1 + '@types/range-parser': 1.2.7 + '@types/send': 1.2.1 + + '@types/express@4.17.25': + dependencies: + '@types/body-parser': 1.19.6 + '@types/express-serve-static-core': 4.19.8 + '@types/qs': 6.15.1 + '@types/serve-static': 1.15.10 + + '@types/favicons@5.5.0': + dependencies: + '@types/node': 22.19.19 + + '@types/flat@5.0.5': {} + + '@types/glob@7.2.0': + dependencies: + '@types/minimatch': 5.1.2 + '@types/node': 22.19.19 + + '@types/glob@9.0.0': + dependencies: + glob: 10.5.0 + + '@types/graceful-fs@4.1.9': + dependencies: + '@types/node': 22.19.19 + + '@types/hast@2.3.10': + dependencies: + '@types/unist': 2.0.11 + + '@types/hast@3.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/html-minifier-terser@5.1.2': {} + + '@types/html-minifier-terser@6.1.0': {} + + '@types/http-errors@2.0.5': {} + + '@types/http-proxy@1.17.17': + dependencies: + '@types/node': 22.19.19 + + '@types/is-function@1.0.3': {} + + '@types/istanbul-lib-coverage@2.0.6': {} + + '@types/istanbul-lib-report@3.0.3': + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + + '@types/istanbul-reports@3.0.4': + dependencies: + '@types/istanbul-lib-report': 3.0.3 + + '@types/jest@27.5.2': + dependencies: + jest-matcher-utils: 27.5.1 + pretty-format: 27.5.1 + + '@types/jest@29.5.14': + dependencies: + expect: 29.7.0 + pretty-format: 29.7.0 + + '@types/json-schema@7.0.15': {} + + '@types/json5@0.0.29': {} + + '@types/lodash@4.17.24': {} + + '@types/long@4.0.2': {} + + '@types/mdast@3.0.15': + dependencies: + '@types/unist': 2.0.11 + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/mime@1.3.5': {} + + '@types/minimatch@3.0.5': {} + + '@types/minimatch@5.1.2': {} + + '@types/minimist@1.2.5': {} + + '@types/ms@2.1.0': {} + + '@types/node-fetch@2.6.13': + dependencies: + '@types/node': 22.19.19 + form-data: 4.0.5 + + '@types/node-forge@1.3.14': + dependencies: + '@types/node': 22.19.19 + + '@types/node@10.12.18': {} + + '@types/node@13.13.52': {} + + '@types/node@16.18.126': {} + + '@types/node@20.19.41': + dependencies: + undici-types: 6.21.0 + + '@types/node@22.19.19': + dependencies: + undici-types: 6.21.0 + + '@types/normalize-package-data@2.4.4': {} + + '@types/npmlog@4.1.6': + dependencies: + '@types/node': 22.19.19 + + '@types/parse-json@4.0.2': {} + + '@types/parse5@5.0.3': {} + + '@types/prettier@2.7.3': {} + + '@types/pretty-hrtime@1.0.3': {} + + '@types/prop-types@15.7.15': {} + + '@types/qrcode.react@1.0.5': + dependencies: + '@types/react': 19.2.14 + + '@types/qs@6.15.1': {} + + '@types/range-parser@1.2.7': {} + + '@types/react-dom@19.2.3(@types/react@19.2.14)': + dependencies: + '@types/react': 19.2.14 + + '@types/react-transition-group@4.4.12(@types/react@19.2.14)': + dependencies: + '@types/react': 19.2.14 + + '@types/react@19.2.14': + dependencies: + csstype: 3.2.3 + + '@types/retry@0.12.0': {} + + '@types/semver@7.7.1': {} + + '@types/send@0.17.6': + dependencies: + '@types/mime': 1.3.5 + '@types/node': 22.19.19 + + '@types/send@1.2.1': + dependencies: + '@types/node': 22.19.19 + + '@types/serve-index@1.9.4': + dependencies: + '@types/express': 4.17.25 + + '@types/serve-static@1.15.10': + dependencies: + '@types/http-errors': 2.0.5 + '@types/node': 22.19.19 + '@types/send': 0.17.6 + + '@types/sockjs@0.3.36': + dependencies: + '@types/node': 22.19.19 + + '@types/source-list-map@0.1.6': {} + + '@types/stack-utils@2.0.3': {} + + '@types/tapable@1.0.12': {} + + '@types/trusted-types@2.0.7': + optional: true + + '@types/uglify-js@3.17.5': + dependencies: + source-map: 0.6.1 + + '@types/unist@2.0.11': {} + + '@types/unist@3.0.3': {} + + '@types/uuid@8.3.4': {} + + '@types/webpack-env@1.18.8': {} + + '@types/webpack-sources@3.2.3': + dependencies: + '@types/node': 22.19.19 + '@types/source-list-map': 0.1.6 + source-map: 0.7.6 + + '@types/webpack@4.41.40': + dependencies: + '@types/node': 22.19.19 + '@types/tapable': 1.0.12 + '@types/uglify-js': 3.17.5 + '@types/webpack-sources': 3.2.3 + anymatch: 3.1.3 + source-map: 0.6.1 + + '@types/ws@8.18.1': + dependencies: + '@types/node': 22.19.19 + + '@types/yargs-parser@21.0.3': {} + + '@types/yargs@15.0.20': + dependencies: + '@types/yargs-parser': 21.0.3 + + '@types/yargs@16.0.11': + dependencies: + '@types/yargs-parser': 21.0.3 + + '@types/yargs@17.0.35': + dependencies: + '@types/yargs-parser': 21.0.3 + + '@types/zxcvbn@4.4.5': {} + + '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 5.62.0(eslint@9.39.4)(typescript@4.9.5) + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/type-utils': 5.62.0(eslint@9.39.4)(typescript@4.9.5) + '@typescript-eslint/utils': 5.62.0(eslint@9.39.4)(typescript@4.9.5) + debug: 4.4.3 + eslint: 9.39.4 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare-lite: 1.4.0 + semver: 7.8.0 + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 5.62.0(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/type-utils': 5.62.0(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/utils': 5.62.0(eslint@9.39.4)(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.39.4 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare-lite: 1.4.0 + semver: 7.8.0 + tsutils: 3.21.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/eslint-plugin@8.59.4(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 8.59.4(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.59.4 + '@typescript-eslint/type-utils': 8.59.4(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.4(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.59.4 + eslint: 8.57.1 + ignore: 7.0.5 + natural-compare: 1.4.0 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/experimental-utils@5.62.0(eslint@9.39.4)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/utils': 5.62.0(eslint@9.39.4)(typescript@4.9.5) + eslint: 9.39.4 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/experimental-utils@5.62.0(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/utils': 5.62.0(eslint@9.39.4)(typescript@5.9.3) + eslint: 9.39.4 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + debug: 4.4.3 + eslint: 9.39.4 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.39.4 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/scope-manager': 8.59.4 + '@typescript-eslint/types': 8.59.4 + '@typescript-eslint/typescript-estree': 8.59.4(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.59.4 + debug: 4.4.3 + eslint: 8.57.1 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/project-service@8.59.4(typescript@5.9.3)': + dependencies: + '@typescript-eslint/tsconfig-utils': 8.59.4(typescript@5.9.3) + '@typescript-eslint/types': 8.59.4 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/scope-manager@5.62.0': + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + + '@typescript-eslint/scope-manager@8.59.4': + dependencies: + '@typescript-eslint/types': 8.59.4 + '@typescript-eslint/visitor-keys': 8.59.4 + + '@typescript-eslint/tsconfig-utils@8.59.4(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@typescript-eslint/type-utils@5.62.0(eslint@9.39.4)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + '@typescript-eslint/utils': 5.62.0(eslint@9.39.4)(typescript@4.9.5) + debug: 4.4.3 + eslint: 9.39.4 + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/type-utils@5.62.0(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.9.3) + '@typescript-eslint/utils': 5.62.0(eslint@9.39.4)(typescript@5.9.3) + debug: 4.4.3 + eslint: 9.39.4 + tsutils: 3.21.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/type-utils@8.59.4(eslint@8.57.1)(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.59.4 + '@typescript-eslint/typescript-estree': 8.59.4(typescript@5.9.3) + '@typescript-eslint/utils': 8.59.4(eslint@8.57.1)(typescript@5.9.3) + debug: 4.4.3 + eslint: 8.57.1 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/types@5.62.0': {} + + '@typescript-eslint/types@8.59.4': {} + + '@typescript-eslint/typescript-estree@5.62.0(typescript@4.9.5)': + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + debug: 4.4.3 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.8.0 + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/typescript-estree@5.62.0(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/visitor-keys': 5.62.0 + debug: 4.4.3 + globby: 11.1.0 + is-glob: 4.0.3 + semver: 7.8.0 + tsutils: 3.21.0(typescript@5.9.3) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/typescript-estree@8.59.4(typescript@5.9.3)': + dependencies: + '@typescript-eslint/project-service': 8.59.4(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.59.4(typescript@5.9.3) + '@typescript-eslint/types': 8.59.4 + '@typescript-eslint/visitor-keys': 8.59.4 + debug: 4.4.3 + minimatch: 10.2.5 + semver: 7.8.0 + tinyglobby: 0.2.16 + ts-api-utils: 2.5.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) + '@types/json-schema': 7.0.15 + '@types/semver': 7.7.1 + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.9.3) + eslint: 8.57.1 + eslint-scope: 5.1.1 + semver: 7.8.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/utils@5.62.0(eslint@9.39.4)(typescript@4.9.5)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@types/json-schema': 7.0.15 + '@types/semver': 7.7.1 + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + eslint: 9.39.4 + eslint-scope: 5.1.1 + semver: 7.8.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/utils@5.62.0(eslint@9.39.4)(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@types/json-schema': 7.0.15 + '@types/semver': 7.7.1 + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.9.3) + eslint: 9.39.4 + eslint-scope: 5.1.1 + semver: 7.8.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/utils@8.59.4(eslint@8.57.1)(typescript@5.9.3)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) + '@typescript-eslint/scope-manager': 8.59.4 + '@typescript-eslint/types': 8.59.4 + '@typescript-eslint/typescript-estree': 8.59.4(typescript@5.9.3) + eslint: 8.57.1 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/visitor-keys@5.62.0': + dependencies: + '@typescript-eslint/types': 5.62.0 + eslint-visitor-keys: 3.4.3 + + '@typescript-eslint/visitor-keys@8.59.4': + dependencies: + '@typescript-eslint/types': 8.59.4 + eslint-visitor-keys: 5.0.1 + + '@uidotdev/usehooks@2.4.1(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + + '@ungap/structured-clone@1.3.1': {} + + '@unrs/resolver-binding-android-arm-eabi@1.11.1': + optional: true + + '@unrs/resolver-binding-android-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-arm64@1.11.1': + optional: true + + '@unrs/resolver-binding-darwin-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-freebsd-x64@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm-musleabihf@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-arm64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-ppc64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + dependencies: + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + optional: true + + '@vanilla-extract/css-utils@0.1.6': {} + + '@vanilla-extract/css@1.20.1(babel-plugin-macros@3.1.0)': + dependencies: + '@emotion/hash': 0.9.2 + '@vanilla-extract/private': 1.0.9 + css-what: 6.2.2 + csstype: 3.2.3 + dedent: 1.7.2(babel-plugin-macros@3.1.0) + deep-object-diff: 1.1.9 + deepmerge: 4.3.1 + lru-cache: 10.4.3 + media-query-parser: 2.0.2 + modern-ahocorasick: 1.1.0 + picocolors: 1.1.1 + transitivePeerDependencies: + - babel-plugin-macros + + '@vanilla-extract/dynamic@2.1.5': + dependencies: + '@vanilla-extract/private': 1.0.9 + + '@vanilla-extract/private@1.0.9': {} + + '@vanilla-extract/recipes@0.5.7(@vanilla-extract/css@1.20.1(babel-plugin-macros@3.1.0))': + dependencies: + '@vanilla-extract/css': 1.20.1(babel-plugin-macros@3.1.0) + + '@vitest/pretty-format@2.1.9': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/utils@2.1.9': + dependencies: + '@vitest/pretty-format': 2.1.9 + loupe: 3.2.1 + tinyrainbow: 1.2.0 + + '@walletconnect/events@1.0.1': + dependencies: + keyvaluestorage-interface: 1.0.0 + tslib: 1.14.1 + + '@walletconnect/heartbeat@1.2.1': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/time': 1.0.2 + tslib: 1.14.1 + + '@walletconnect/jsonrpc-types@1.0.3': + dependencies: + keyvaluestorage-interface: 1.0.0 + tslib: 1.14.1 + + '@walletconnect/keyvaluestorage@1.1.1': + dependencies: + '@walletconnect/safe-json': 1.0.2 + idb-keyval: 6.2.2 + unstorage: 1.17.5(idb-keyval@6.2.2) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@walletconnect/logger@2.1.3': + dependencies: + '@walletconnect/safe-json': 1.0.2 + pino: 7.11.0 + + '@walletconnect/safe-json@1.0.2': + dependencies: + tslib: 1.14.1 + + '@walletconnect/time@1.0.2': + dependencies: + tslib: 1.14.1 + + '@walletconnect/types@2.11.0': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.1 + '@walletconnect/jsonrpc-types': 1.0.3 + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/logger': 2.1.3 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@webassemblyjs/ast@1.14.1': + dependencies: + '@webassemblyjs/helper-numbers': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + + '@webassemblyjs/ast@1.9.0': + dependencies: + '@webassemblyjs/helper-module-context': 1.9.0 + '@webassemblyjs/helper-wasm-bytecode': 1.9.0 + '@webassemblyjs/wast-parser': 1.9.0 + + '@webassemblyjs/floating-point-hex-parser@1.13.2': {} + + '@webassemblyjs/floating-point-hex-parser@1.9.0': {} + + '@webassemblyjs/helper-api-error@1.13.2': {} + + '@webassemblyjs/helper-api-error@1.9.0': {} + + '@webassemblyjs/helper-buffer@1.14.1': {} + + '@webassemblyjs/helper-buffer@1.9.0': {} + + '@webassemblyjs/helper-code-frame@1.9.0': + dependencies: + '@webassemblyjs/wast-printer': 1.9.0 + + '@webassemblyjs/helper-fsm@1.9.0': {} + + '@webassemblyjs/helper-module-context@1.9.0': + dependencies: + '@webassemblyjs/ast': 1.9.0 + + '@webassemblyjs/helper-numbers@1.13.2': + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.13.2 + '@webassemblyjs/helper-api-error': 1.13.2 + '@xtuc/long': 4.2.2 + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} + + '@webassemblyjs/helper-wasm-bytecode@1.9.0': {} + + '@webassemblyjs/helper-wasm-section@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/wasm-gen': 1.14.1 + + '@webassemblyjs/helper-wasm-section@1.9.0': + dependencies: + '@webassemblyjs/ast': 1.9.0 + '@webassemblyjs/helper-buffer': 1.9.0 + '@webassemblyjs/helper-wasm-bytecode': 1.9.0 + '@webassemblyjs/wasm-gen': 1.9.0 + + '@webassemblyjs/ieee754@1.13.2': + dependencies: + '@xtuc/ieee754': 1.2.0 + + '@webassemblyjs/ieee754@1.9.0': + dependencies: + '@xtuc/ieee754': 1.2.0 + + '@webassemblyjs/leb128@1.13.2': + dependencies: + '@xtuc/long': 4.2.2 + + '@webassemblyjs/leb128@1.9.0': + dependencies: + '@xtuc/long': 4.2.2 + + '@webassemblyjs/utf8@1.13.2': {} + + '@webassemblyjs/utf8@1.9.0': {} + + '@webassemblyjs/wasm-edit@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/helper-wasm-section': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-opt': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + '@webassemblyjs/wast-printer': 1.14.1 + + '@webassemblyjs/wasm-edit@1.9.0': + dependencies: + '@webassemblyjs/ast': 1.9.0 + '@webassemblyjs/helper-buffer': 1.9.0 + '@webassemblyjs/helper-wasm-bytecode': 1.9.0 + '@webassemblyjs/helper-wasm-section': 1.9.0 + '@webassemblyjs/wasm-gen': 1.9.0 + '@webassemblyjs/wasm-opt': 1.9.0 + '@webassemblyjs/wasm-parser': 1.9.0 + '@webassemblyjs/wast-printer': 1.9.0 + + '@webassemblyjs/wasm-gen@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wasm-gen@1.9.0': + dependencies: + '@webassemblyjs/ast': 1.9.0 + '@webassemblyjs/helper-wasm-bytecode': 1.9.0 + '@webassemblyjs/ieee754': 1.9.0 + '@webassemblyjs/leb128': 1.9.0 + '@webassemblyjs/utf8': 1.9.0 + + '@webassemblyjs/wasm-opt@1.14.1': + dependencies: + '@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-opt@1.9.0': + dependencies: + '@webassemblyjs/ast': 1.9.0 + '@webassemblyjs/helper-buffer': 1.9.0 + '@webassemblyjs/wasm-gen': 1.9.0 + '@webassemblyjs/wasm-parser': 1.9.0 + + '@webassemblyjs/wasm-parser@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-api-error': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wasm-parser@1.9.0': + dependencies: + '@webassemblyjs/ast': 1.9.0 + '@webassemblyjs/helper-api-error': 1.9.0 + '@webassemblyjs/helper-wasm-bytecode': 1.9.0 + '@webassemblyjs/ieee754': 1.9.0 + '@webassemblyjs/leb128': 1.9.0 + '@webassemblyjs/utf8': 1.9.0 + + '@webassemblyjs/wast-parser@1.9.0': + dependencies: + '@webassemblyjs/ast': 1.9.0 + '@webassemblyjs/floating-point-hex-parser': 1.9.0 + '@webassemblyjs/helper-api-error': 1.9.0 + '@webassemblyjs/helper-code-frame': 1.9.0 + '@webassemblyjs/helper-fsm': 1.9.0 + '@xtuc/long': 4.2.2 + + '@webassemblyjs/wast-printer@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@xtuc/long': 4.2.2 + + '@webassemblyjs/wast-printer@1.9.0': + dependencies: + '@webassemblyjs/ast': 1.9.0 + '@webassemblyjs/wast-parser': 1.9.0 + '@xtuc/long': 4.2.2 + + '@webpack-cli/configtest@1.2.0(webpack-cli@4.10.0)(webpack@5.106.2)': + dependencies: + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.106.2) + + '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.106.2)': + dependencies: + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.106.2) + + '@webpack-cli/info@1.5.0(webpack-cli@4.10.0)': + dependencies: + envinfo: 7.21.0 + webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.106.2) + + '@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.106.2)': + dependencies: + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.106.2) + + '@webpack-cli/serve@1.7.0(webpack-cli@4.10.0)(webpack-dev-server@4.15.2)': + dependencies: + webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.106.2) + optionalDependencies: + webpack-dev-server: 4.15.2(webpack-cli@4.10.0)(webpack@5.106.2) + + '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack-dev-server@4.15.2)(webpack@5.106.2)': + dependencies: + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.106.2) + optionalDependencies: + webpack-dev-server: 4.15.2(webpack-cli@5.1.4)(webpack@5.106.2) + + '@xtuc/ieee754@1.2.0': {} + + '@xtuc/long@4.2.2': {} + + '@yarnpkg/lockfile@1.1.0': {} + + '@yarnpkg/parsers@3.0.0-rc.46': + dependencies: + js-yaml: 3.14.2 + tslib: 2.8.1 + + '@zkochan/js-yaml@0.0.6': + dependencies: + argparse: 2.0.1 + + JSONStream@1.3.5: + dependencies: + jsonparse: 1.3.1 + through: 2.3.8 + + abab@2.0.6: {} + + abbrev@1.1.1: {} + + abi-wan-kanabi@2.2.4: + dependencies: + ansicolors: 0.3.2 + cardinal: 2.1.1 + fs-extra: 10.1.0 + yargs: 17.7.2 + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + acorn-globals@6.0.0: + dependencies: + acorn: 7.4.1 + acorn-walk: 7.2.0 + + acorn-import-phases@1.0.4(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn-jsx@5.3.2(acorn@7.4.1): + dependencies: + acorn: 7.4.1 + + acorn-jsx@5.3.2(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn-walk@7.2.0: {} + + acorn@6.4.2: {} + + acorn@7.4.1: {} + + acorn@8.16.0: {} + + add-stream@1.0.0: {} + + address@1.2.2: {} + + agent-base@6.0.2: + dependencies: + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + agent-base@7.1.4: {} + + agentkeepalive@4.6.0: + dependencies: + humanize-ms: 1.2.1 + + aggregate-error@3.1.0: + dependencies: + clean-stack: 2.2.0 + indent-string: 4.0.0 + + airbnb-js-shims@2.2.1: + dependencies: + array-includes: 3.1.9 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + es5-shim: 4.6.7 + es6-shim: 0.35.8 + function.prototype.name: 1.1.8 + globalthis: 1.0.4 + object.entries: 1.1.9 + object.fromentries: 2.0.8 + object.getownpropertydescriptors: 2.1.9 + object.values: 1.2.1 + promise.allsettled: 1.0.7 + promise.prototype.finally: 3.1.8 + string.prototype.matchall: 4.0.12 + string.prototype.padend: 3.1.6 + string.prototype.padstart: 3.1.7 + symbol.prototype.description: 1.0.7 + + ajv-errors@1.0.1(ajv@6.15.0): + dependencies: + ajv: 6.15.0 + + ajv-formats@2.1.1(ajv@8.20.0): + optionalDependencies: + ajv: 8.20.0 + + ajv-keywords@3.5.2(ajv@6.15.0): + dependencies: + ajv: 6.15.0 + + ajv-keywords@5.1.0(ajv@8.20.0): + dependencies: + ajv: 8.20.0 + fast-deep-equal: 3.1.3 + + ajv@6.15.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-json-stable-stringify: 2.1.0 + json-schema-traverse: 0.4.1 + uri-js: 4.4.1 + + ajv@8.20.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.2 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + animejs@3.2.2: {} + + ansi-align@3.0.1: + dependencies: + string-width: 4.2.3 + + ansi-colors@3.2.4: {} + + ansi-colors@4.1.3: {} + + ansi-escapes@4.3.2: + dependencies: + type-fest: 0.21.3 + + ansi-html-community@0.0.8: {} + + ansi-html@0.0.9: {} + + ansi-regex@2.1.1: {} + + ansi-regex@5.0.1: {} + + ansi-regex@6.2.2: {} + + ansi-styles@3.2.1: + dependencies: + color-convert: 1.9.3 + + ansi-styles@4.3.0: + dependencies: + color-convert: 2.0.1 + + ansi-styles@5.2.0: {} + + ansi-styles@6.2.3: {} + + ansi-to-html@0.6.15: + dependencies: + entities: 2.2.0 + + ansicolors@0.3.2: {} + + anymatch@2.0.0: + dependencies: + micromatch: 3.1.10 + normalize-path: 2.1.1 + transitivePeerDependencies: + - supports-color + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.2 + + app-root-dir@1.0.2: {} + + aproba@1.2.0: {} + + aproba@2.1.0: {} + + are-we-there-yet@2.0.0: + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + + are-we-there-yet@3.0.1: + dependencies: + delegates: 1.0.0 + readable-stream: 3.6.2 + + argparse@1.0.10: + dependencies: + sprintf-js: 1.0.3 + + argparse@2.0.1: {} + + aria-hidden@1.2.6: + dependencies: + tslib: 2.8.1 + + aria-query@5.1.3: + dependencies: + deep-equal: 2.2.3 + + aria-query@5.3.0: + dependencies: + dequal: 2.0.3 + + aria-query@5.3.2: {} + + arr-diff@4.0.0: {} + + arr-flatten@1.1.0: {} + + arr-union@3.1.0: {} + + array-buffer-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + is-array-buffer: 3.0.5 + + array-differ@3.0.0: {} + + array-find-index@1.0.2: + optional: true + + array-flatten@1.1.1: {} + + array-ify@1.0.0: {} + + array-includes@3.1.9: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + is-string: 1.1.1 + math-intrinsics: 1.1.0 + + array-union@1.0.2: + dependencies: + array-uniq: 1.0.3 + + array-union@2.1.0: {} + + array-uniq@1.0.3: {} + + array-unique@0.3.2: {} + + array.prototype.findlast@1.2.5: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.findlastindex@1.2.6: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-shim-unscopables: 1.1.0 + + array.prototype.flat@1.3.3: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-shim-unscopables: 1.1.0 + + array.prototype.flatmap@1.3.3: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-shim-unscopables: 1.1.0 + + array.prototype.map@1.0.8: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-array-method-boxes-properly: 1.0.0 + es-object-atoms: 1.1.1 + is-string: 1.1.1 + + array.prototype.reduce@1.0.8: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-array-method-boxes-properly: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + is-string: 1.1.1 + + array.prototype.tosorted@1.1.4: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-shim-unscopables: 1.1.0 + + arraybuffer.prototype.slice@1.0.4: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + is-array-buffer: 3.0.5 + + arrify@1.0.1: {} + + arrify@2.0.1: {} + + asn1.js@4.10.1: + dependencies: + bn.js: 4.12.3 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + + assert@1.5.1: + dependencies: + object.assign: 4.1.7 + util: 0.10.4 + + assign-symbols@1.0.0: {} + + ast-types-flow@0.0.8: {} + + ast-types@0.14.2: + dependencies: + tslib: 2.8.1 + + ast-types@0.16.1: + dependencies: + tslib: 2.8.1 + + async-each@1.0.6: + optional: true + + async-function@1.0.0: {} + + async@3.2.6: {} + + asynckit@0.4.0: {} + + at-least-node@1.0.0: {} + + atob@2.1.2: {} + + atomic-sleep@1.0.0: {} + + author-regex@1.0.0: {} + + autoprefixer@9.8.8: + dependencies: + browserslist: 4.28.2 + caniuse-lite: 1.0.30001792 + normalize-range: 0.1.2 + num2fraction: 1.2.2 + picocolors: 0.2.1 + postcss: 7.0.39 + postcss-value-parser: 4.2.0 + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + axe-core@4.11.4: {} + + axios@0.21.4: + dependencies: + follow-redirects: 1.16.0 + transitivePeerDependencies: + - debug + + axios@1.16.0: + dependencies: + follow-redirects: 1.16.0 + form-data: 4.0.5 + proxy-from-env: 2.1.0 + transitivePeerDependencies: + - debug + + axobject-query@4.1.0: {} + + babel-jest@27.5.1(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@jest/transform': 27.5.1 + '@jest/types': 27.5.1 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 27.5.1(@babel/core@7.29.0) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + + babel-jest@29.7.0(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@jest/transform': 29.7.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.29.0) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + + babel-loader@8.4.1(@babel/core@7.29.0)(webpack@4.47.0): + dependencies: + '@babel/core': 7.29.0 + find-cache-dir: 3.3.2 + loader-utils: 2.0.4 + make-dir: 3.1.0 + schema-utils: 2.7.1 + webpack: 4.47.0 + + babel-loader@8.4.1(@babel/core@7.29.0)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)): + dependencies: + '@babel/core': 7.29.0 + find-cache-dir: 3.3.2 + loader-utils: 2.0.4 + make-dir: 3.1.0 + schema-utils: 2.7.1 + webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + + babel-loader@8.4.1(@babel/core@7.29.0)(webpack@5.106.2): + dependencies: + '@babel/core': 7.29.0 + find-cache-dir: 3.3.2 + loader-utils: 2.0.4 + make-dir: 3.1.0 + schema-utils: 2.7.1 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + + babel-loader@9.2.1(@babel/core@7.29.0)(webpack@5.106.2): + dependencies: + '@babel/core': 7.29.0 + find-cache-dir: 4.0.0 + schema-utils: 4.3.3 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) + + babel-plugin-add-react-displayname@0.0.5: {} + + babel-plugin-apply-mdx-type-prop@1.6.22(@babel/core@7.12.9): + dependencies: + '@babel/core': 7.12.9 + '@babel/helper-plugin-utils': 7.10.4 + '@mdx-js/util': 1.6.22 + + babel-plugin-extract-import-names@1.6.22: + dependencies: + '@babel/helper-plugin-utils': 7.10.4 + + babel-plugin-istanbul@6.1.1: + dependencies: + '@babel/helper-plugin-utils': 7.28.6 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.6 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-jest-hoist@27.5.1: + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.28.0 + + babel-plugin-jest-hoist@29.6.3: + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.28.0 + + babel-plugin-macros@3.1.0: + dependencies: + '@babel/runtime': 7.29.2 + cosmiconfig: 7.1.0 + resolve: 1.22.12 + + babel-plugin-named-exports-order@0.0.2: {} + + babel-plugin-polyfill-corejs2@0.4.17(@babel/core@7.29.0): + dependencies: + '@babel/compat-data': 7.29.3 + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs3@0.1.7(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.1.5(@babel/core@7.29.0) + core-js-compat: 3.49.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-corejs3@0.14.2(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + core-js-compat: 3.49.0 + transitivePeerDependencies: + - supports-color + + babel-plugin-polyfill-regenerator@0.6.8(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/helper-define-polyfill-provider': 0.6.8(@babel/core@7.29.0) + transitivePeerDependencies: + - supports-color + + babel-plugin-react-docgen@4.2.1: + dependencies: + ast-types: 0.14.2 + lodash: 4.18.1 + react-docgen: 5.4.3 + transitivePeerDependencies: + - supports-color + + babel-plugin-root-import@5.1.0: + dependencies: + slash: 1.0.0 + + babel-plugin-root-import@6.6.0: + dependencies: + slash: 3.0.0 + + babel-preset-current-node-syntax@1.2.0(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.29.0) + '@babel/plugin-syntax-bigint': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.29.0) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.29.0) + '@babel/plugin-syntax-import-attributes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-import-meta': 7.10.4(@babel/core@7.29.0) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.29.0) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.29.0) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.29.0) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.29.0) + + babel-preset-jest@27.5.1(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + babel-plugin-jest-hoist: 27.5.1 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0) + + babel-preset-jest@29.6.3(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0) + + bail@1.0.5: {} + + bail@2.0.2: {} + + balanced-match@1.0.2: {} + + balanced-match@4.0.4: {} + + base-x@3.0.11: + dependencies: + safe-buffer: 5.2.1 + + base58@2.0.1: {} + + base64-js@1.5.1: {} + + base@0.11.2: + dependencies: + cache-base: 1.0.1 + class-utils: 0.3.6 + component-emitter: 1.3.1 + define-property: 1.0.0 + isobject: 3.0.1 + mixin-deep: 1.3.2 + pascalcase: 0.1.1 + + baseline-browser-mapping@2.10.29: {} + + batch@0.6.1: {} + + bech32@1.1.4: {} + + before-after-hook@2.2.3: {} + + better-opn@2.1.1: + dependencies: + open: 7.4.2 + + better-opn@3.0.2: + dependencies: + open: 8.4.2 + + bfs-path@1.0.2: {} + + bidi-js@1.0.3: + dependencies: + require-from-string: 2.0.2 + + big-integer@1.6.52: {} + + big.js@5.2.2: {} + + big.js@6.2.2: {} + + bignumber.js@9.1.2: {} + + bignumber.js@9.3.1: {} + + binary-extensions@1.13.1: + optional: true + + binary-extensions@2.3.0: {} + + bindings@1.5.0: + dependencies: + file-uri-to-path: 1.0.0 + + bip32@2.0.6: + dependencies: + '@types/node': 10.12.18 + bs58check: 2.1.2 + create-hash: 1.2.0 + create-hmac: 1.1.7 + tiny-secp256k1: 1.1.7 + typeforce: 1.18.0 + wif: 2.0.6 + + bip39@3.1.0: + dependencies: + '@noble/hashes': 1.8.0 + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + + bluebird@3.7.2: {} + + bn.js@4.12.3: {} + + bn.js@5.2.3: {} + + body-parser@1.20.5: + 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 + transitivePeerDependencies: + - supports-color + + bonjour-service@1.3.0: + dependencies: + fast-deep-equal: 3.1.3 + multicast-dns: 7.2.5 + + boolbase@1.0.0: {} + + bowser@2.11.0: {} + + boxen@5.1.2: + dependencies: + ansi-align: 3.0.1 + camelcase: 6.3.0 + chalk: 4.1.2 + cli-boxes: 2.2.1 + string-width: 4.2.3 + type-fest: 0.20.2 + widest-line: 3.1.0 + wrap-ansi: 7.0.0 + + bplist-parser@0.1.1: + dependencies: + big-integer: 1.6.52 + optional: true + + brace-expansion@1.1.14: + dependencies: + balanced-match: 1.0.2 + concat-map: 0.0.1 + + brace-expansion@2.1.0: + dependencies: + balanced-match: 1.0.2 + + brace-expansion@5.0.6: + dependencies: + balanced-match: 4.0.4 + + braces@2.3.2: + dependencies: + arr-flatten: 1.1.0 + array-unique: 0.3.2 + extend-shallow: 2.0.1 + fill-range: 4.0.0 + isobject: 3.0.1 + repeat-element: 1.1.4 + snapdragon: 0.8.2 + snapdragon-node: 2.1.1 + split-string: 3.1.0 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + brorand@1.1.0: {} + + browser-assert@1.2.1: {} + + browser-process-hrtime@1.0.0: {} + + browserify-aes@1.2.0: + dependencies: + buffer-xor: 1.0.3 + cipher-base: 1.0.7 + create-hash: 1.2.0 + evp_bytestokey: 1.0.3 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + browserify-cipher@1.0.1: + dependencies: + browserify-aes: 1.2.0 + browserify-des: 1.0.2 + evp_bytestokey: 1.0.3 + + browserify-des@1.0.2: + dependencies: + cipher-base: 1.0.7 + des.js: 1.1.0 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + browserify-rsa@4.1.1: + dependencies: + bn.js: 5.2.3 + randombytes: 2.1.0 + safe-buffer: 5.2.1 + + browserify-sign@4.2.5: + dependencies: + bn.js: 5.2.3 + browserify-rsa: 4.1.1 + create-hash: 1.2.0 + create-hmac: 1.1.7 + elliptic: 6.6.1 + inherits: 2.0.4 + parse-asn1: 5.1.9 + readable-stream: 2.3.8 + safe-buffer: 5.2.1 + + browserify-zlib@0.2.0: + dependencies: + pako: 1.0.11 + + browserslist@4.28.2: + dependencies: + baseline-browser-mapping: 2.10.29 + caniuse-lite: 1.0.30001792 + electron-to-chromium: 1.5.354 + node-releases: 2.0.44 + update-browserslist-db: 1.2.3(browserslist@4.28.2) + + bs-logger@0.2.6: + dependencies: + fast-json-stable-stringify: 2.1.0 + + bs58@4.0.1: + dependencies: + base-x: 3.0.11 + + bs58check@2.1.2: + dependencies: + bs58: 4.0.1 + create-hash: 1.2.0 + safe-buffer: 5.2.1 + + bser@2.1.1: + dependencies: + node-int64: 0.4.0 + + buffer-from@1.1.2: {} + + buffer-xor@1.0.3: {} + + buffer@4.9.2: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + isarray: 1.0.0 + + buffer@5.7.1: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + buffer@6.0.3: + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + + builtin-status-codes@3.0.0: {} + + builtins@1.0.3: {} + + builtins@5.1.0: + dependencies: + semver: 7.8.0 + + busboy@1.6.0: + dependencies: + streamsearch: 1.1.0 + + byte-size@8.1.1: {} + + bytes@3.1.2: {} + + c8@7.14.0: + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@istanbuljs/schema': 0.1.6 + find-up: 5.0.0 + foreground-child: 2.0.0 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-report: 3.0.1 + istanbul-reports: 3.2.0 + rimraf: 3.0.2 + test-exclude: 6.0.0 + v8-to-istanbul: 9.3.0 + yargs: 16.2.0 + yargs-parser: 20.2.9 + + cacache@12.0.4: + dependencies: + bluebird: 3.7.2 + chownr: 1.1.4 + figgy-pudding: 3.5.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + infer-owner: 1.0.4 + lru-cache: 5.1.1 + mississippi: 3.0.0 + mkdirp: 0.5.6 + move-concurrently: 1.0.1 + promise-inflight: 1.0.1(bluebird@3.7.2) + rimraf: 2.7.1 + ssri: 6.0.2 + unique-filename: 1.1.1 + y18n: 4.0.3 + + cacache@15.3.0: + dependencies: + '@npmcli/fs': 1.1.1 + '@npmcli/move-file': 1.1.2 + chownr: 2.0.0 + fs-minipass: 2.1.0 + glob: 7.2.3 + infer-owner: 1.0.4 + lru-cache: 6.0.0 + minipass: 3.3.6 + minipass-collect: 1.0.2 + minipass-flush: 1.0.7 + minipass-pipeline: 1.2.4 + mkdirp: 1.0.4 + p-map: 4.0.0 + promise-inflight: 1.0.1(bluebird@3.7.2) + rimraf: 3.0.2 + ssri: 8.0.1 + tar: 6.2.1 + unique-filename: 1.1.1 + transitivePeerDependencies: + - bluebird + + cacache@16.1.3: + dependencies: + '@npmcli/fs': 2.1.2 + '@npmcli/move-file': 2.0.1 + chownr: 2.0.0 + fs-minipass: 2.1.0 + glob: 8.1.0 + infer-owner: 1.0.4 + lru-cache: 7.18.3 + minipass: 3.3.6 + minipass-collect: 1.0.2 + minipass-flush: 1.0.7 + minipass-pipeline: 1.2.4 + mkdirp: 1.0.4 + p-map: 4.0.0 + promise-inflight: 1.0.1(bluebird@3.7.2) + rimraf: 3.0.2 + ssri: 9.0.1 + tar: 6.2.1 + unique-filename: 2.0.1 + transitivePeerDependencies: + - bluebird + + cacache@17.1.4: + dependencies: + '@npmcli/fs': 3.1.1 + fs-minipass: 3.0.3 + glob: 10.5.0 + lru-cache: 7.18.3 + minipass: 7.1.3 + minipass-collect: 1.0.2 + minipass-flush: 1.0.7 + minipass-pipeline: 1.2.4 + p-map: 4.0.0 + ssri: 10.0.6 + tar: 6.1.11 + unique-filename: 3.0.0 + + cache-base@1.0.1: + dependencies: + collection-visit: 1.0.0 + component-emitter: 1.3.1 + get-value: 2.0.6 + has-value: 1.0.0 + isobject: 3.0.1 + set-value: 2.0.1 + to-object-path: 0.3.0 + union-value: 1.0.1 + unset-value: 1.0.0 + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bind@1.0.9: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + get-intrinsic: 1.3.0 + set-function-length: 1.2.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + call-me-maybe@1.0.2: {} + + callsites@3.1.0: {} + + camel-case@4.1.2: + dependencies: + pascal-case: 3.1.2 + tslib: 2.8.1 + + camelcase-css@2.0.1: {} + + camelcase-keys@2.1.0: + dependencies: + camelcase: 2.1.1 + map-obj: 1.0.1 + optional: true + + camelcase-keys@6.2.2: + dependencies: + camelcase: 5.3.1 + map-obj: 4.3.0 + quick-lru: 4.0.1 + + camelcase@2.1.1: + optional: true + + camelcase@5.3.1: {} + + camelcase@6.3.0: {} + + caniuse-api@3.0.0: + dependencies: + browserslist: 4.28.2 + caniuse-lite: 1.0.30001792 + lodash.memoize: 4.1.2 + lodash.uniq: 4.5.0 + + caniuse-lite@1.0.30001792: {} + + capture-exit@2.0.0: + dependencies: + rsvp: 4.8.5 + + cardinal@2.1.1: + dependencies: + ansicolors: 0.3.2 + redeyed: 2.1.1 + + case-sensitive-paths-webpack-plugin@2.4.0: {} + + ccount@1.1.0: {} + + ccount@2.0.1: {} + + chain-registry@1.69.578: + dependencies: + '@chain-registry/types': 0.50.356 + + chalk@2.4.2: + dependencies: + ansi-styles: 3.2.1 + escape-string-regexp: 1.0.5 + supports-color: 5.5.0 + + chalk@4.1.0: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + + char-regex@1.0.2: {} + + character-entities-html4@2.1.0: {} + + character-entities-legacy@1.1.4: {} + + character-entities-legacy@3.0.0: {} + + character-entities@1.2.4: {} + + character-entities@2.0.2: {} + + character-reference-invalid@1.1.4: {} + + character-reference-invalid@2.0.1: {} + + chardet@2.1.1: {} + + chokidar@2.1.8: + dependencies: + anymatch: 2.0.0 + async-each: 1.0.6 + braces: 2.3.2 + glob-parent: 3.1.0 + inherits: 2.0.4 + is-binary-path: 1.0.1 + is-glob: 4.0.3 + normalize-path: 3.0.0 + path-is-absolute: 1.0.1 + readdirp: 2.2.1 + upath: 1.2.0 + optionalDependencies: + fsevents: 1.2.13 + transitivePeerDependencies: + - supports-color + optional: true + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chokidar@5.0.0: + dependencies: + readdirp: 5.0.0 + + chownr@1.1.4: {} + + chownr@2.0.0: {} + + chrome-trace-event@1.0.4: {} + + ci-info@2.0.0: {} + + ci-info@3.9.0: {} + + cipher-base@1.0.7: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + to-buffer: 1.2.2 + + cjs-module-lexer@1.4.3: {} + + class-utils@0.3.6: + dependencies: + arr-union: 3.1.0 + define-property: 0.2.5 + isobject: 3.0.1 + static-extend: 0.1.2 + + cldr-compact-number@0.4.0: {} + + clean-css@4.2.4: + dependencies: + source-map: 0.6.1 + + clean-css@5.3.3: + dependencies: + source-map: 0.6.1 + + clean-stack@2.2.0: {} + + clean-webpack-plugin@4.0.0(webpack@5.106.2): + dependencies: + del: 4.1.1 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + + cli-boxes@2.2.1: {} + + cli-cursor@3.1.0: + dependencies: + restore-cursor: 3.1.0 + + cli-spinners@2.6.1: {} + + cli-spinners@2.9.2: {} + + cli-table3@0.6.5: + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + + cli-width@3.0.0: {} + + client-only@0.0.1: {} + + clipboard-copy@3.2.0: {} + + cliui@7.0.4: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + + clone-deep@4.0.1: + dependencies: + is-plain-object: 2.0.4 + kind-of: 6.0.3 + shallow-clone: 3.0.1 + + clone@1.0.4: {} + + clsx@1.1.0: {} + + clsx@1.2.1: {} + + clsx@2.1.1: {} + + cmd-shim@6.0.1: {} + + co@4.6.0: {} + + collapse-white-space@1.0.6: {} + + collect-v8-coverage@1.0.3: {} + + collection-visit@1.0.0: + dependencies: + map-visit: 1.0.0 + object-visit: 1.0.1 + + color-convert@1.9.3: + dependencies: + color-name: 1.1.3 + + color-convert@2.0.1: + dependencies: + color-name: 1.1.4 + + color-name@1.1.3: {} + + color-name@1.1.4: {} + + color-string@1.9.1: + dependencies: + color-name: 1.1.4 + simple-swizzle: 0.2.4 + + color-support@1.1.3: {} + + color@4.2.3: + dependencies: + color-convert: 2.0.1 + color-string: 1.9.1 + + colord@2.9.3: {} + + colorette@1.4.0: {} + + colorette@2.0.20: {} + + colornames@1.1.1: {} + + columnify@1.6.0: + dependencies: + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + + combined-stream@1.0.8: + dependencies: + delayed-stream: 1.0.0 + + comma-separated-tokens@1.0.8: {} + + comma-separated-tokens@2.0.3: {} + + commander@10.0.1: {} + + commander@2.20.3: {} + + commander@4.1.1: {} + + commander@6.2.1: {} + + commander@7.2.0: {} + + commander@8.3.0: {} + + common-path-prefix@3.0.0: {} + + commondir@1.0.1: {} + + compare-func@2.0.0: + dependencies: + array-ify: 1.0.0 + dot-prop: 5.3.0 + + component-emitter@1.3.1: {} + + compressible@2.0.18: + dependencies: + mime-db: 1.54.0 + + compression@1.8.1: + dependencies: + 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 + transitivePeerDependencies: + - supports-color + + concat-map@0.0.1: {} + + concat-stream@1.6.2: + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + typedarray: 0.0.6 + + concat-stream@2.0.0: + dependencies: + buffer-from: 1.1.2 + inherits: 2.0.4 + readable-stream: 3.6.2 + typedarray: 0.0.6 + + confusing-browser-globals@1.0.11: {} + + connect-history-api-fallback@2.0.0: {} + + console-browserify@1.2.0: {} + + console-control-strings@1.1.0: {} + + constants-browserify@1.0.0: {} + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + conventional-changelog-angular@7.0.0: + dependencies: + compare-func: 2.0.0 + + conventional-changelog-core@5.0.1: + dependencies: + add-stream: 1.0.0 + conventional-changelog-writer: 6.0.1 + conventional-commits-parser: 4.0.0 + dateformat: 3.0.3 + get-pkg-repo: 4.2.1 + git-raw-commits: 3.0.0 + git-remote-origin-url: 2.0.0 + git-semver-tags: 5.0.1 + normalize-package-data: 3.0.3 + read-pkg: 3.0.0 + read-pkg-up: 3.0.0 + + conventional-changelog-preset-loader@3.0.0: {} + + conventional-changelog-writer@6.0.1: + dependencies: + conventional-commits-filter: 3.0.0 + dateformat: 3.0.3 + handlebars: 4.7.9 + json-stringify-safe: 5.0.1 + meow: 8.1.2 + semver: 7.8.0 + split: 1.0.1 + + conventional-commits-filter@3.0.0: + dependencies: + lodash.ismatch: 4.4.0 + modify-values: 1.0.1 + + conventional-commits-parser@4.0.0: + dependencies: + JSONStream: 1.3.5 + is-text-path: 1.0.1 + meow: 8.1.2 + split2: 3.2.2 + + conventional-recommended-bump@7.0.1: + dependencies: + concat-stream: 2.0.0 + conventional-changelog-preset-loader: 3.0.0 + conventional-commits-filter: 3.0.0 + conventional-commits-parser: 4.0.0 + git-raw-commits: 3.0.0 + git-semver-tags: 5.0.1 + meow: 8.1.2 + + convert-source-map@1.9.0: {} + + convert-source-map@2.0.0: {} + + cookie-es@1.2.3: {} + + cookie-signature@1.0.7: {} + + cookie@0.7.2: {} + + copy-concurrently@1.0.5: + dependencies: + aproba: 1.2.0 + fs-write-stream-atomic: 1.0.10 + iferr: 0.1.5 + mkdirp: 0.5.6 + rimraf: 2.7.1 + run-queue: 1.0.3 + + copy-descriptor@0.1.1: {} + + copy-to-clipboard@3.3.3: + dependencies: + toggle-selection: 1.0.6 + + copy-webpack-plugin@11.0.0(webpack@5.106.2): + dependencies: + fast-glob: 3.3.3 + glob-parent: 6.0.2 + globby: 13.2.2 + normalize-path: 3.0.0 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) + + core-js-compat@3.49.0: + dependencies: + browserslist: 4.28.2 + + core-js-pure@3.49.0: {} + + core-js@3.49.0: {} + + core-util-is@1.0.3: {} + + cosmiconfig@6.0.0: + dependencies: + '@types/parse-json': 4.0.2 + import-fresh: 3.3.1 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.3 + + cosmiconfig@7.1.0: + dependencies: + '@types/parse-json': 4.0.2 + import-fresh: 3.3.1 + parse-json: 5.2.0 + path-type: 4.0.0 + yaml: 1.10.3 + + cosmiconfig@8.3.6(typescript@5.9.3): + dependencies: + import-fresh: 3.3.1 + js-yaml: 4.1.1 + parse-json: 5.2.0 + path-type: 4.0.0 + optionalDependencies: + typescript: 5.9.3 + + cosmjs-types@0.10.1: {} + + cosmjs-types@0.9.0: {} + + cp-file@7.0.0: + dependencies: + graceful-fs: 4.2.11 + make-dir: 3.1.0 + nested-error-stacks: 2.1.1 + p-event: 4.2.0 + + cpy@8.1.2: + dependencies: + arrify: 2.0.1 + cp-file: 7.0.0 + globby: 9.2.0 + has-glob: 1.0.0 + junk: 3.1.0 + nested-error-stacks: 2.1.1 + p-all: 2.1.0 + p-filter: 2.1.0 + p-map: 3.0.0 + transitivePeerDependencies: + - supports-color + + create-ecdh@4.0.4: + dependencies: + bn.js: 4.12.3 + elliptic: 6.6.1 + + create-hash@1.2.0: + dependencies: + cipher-base: 1.0.7 + inherits: 2.0.4 + md5.js: 1.3.5 + ripemd160: 2.0.3 + sha.js: 2.4.12 + + create-hmac@1.1.7: + dependencies: + cipher-base: 1.0.7 + create-hash: 1.2.0 + inherits: 2.0.4 + ripemd160: 2.0.3 + safe-buffer: 5.2.1 + sha.js: 2.4.12 + + create-jest@29.7.0(@types/node@22.19.19)(babel-plugin-macros@3.1.0): + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@22.19.19)(babel-plugin-macros@3.1.0) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + cross-fetch@3.2.0(encoding@0.1.13): + dependencies: + node-fetch: 2.7.0(encoding@0.1.13) + transitivePeerDependencies: + - encoding + + cross-spawn@6.0.6: + dependencies: + nice-try: 1.0.5 + path-key: 2.0.1 + semver: 5.7.2 + shebang-command: 1.2.0 + which: 1.3.1 + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + crossws@0.3.5: + dependencies: + uncrypto: 0.1.3 + + crypto-browserify@3.12.1: + dependencies: + browserify-cipher: 1.0.1 + browserify-sign: 4.2.5 + create-ecdh: 4.0.4 + create-hash: 1.2.0 + create-hmac: 1.1.7 + diffie-hellman: 5.0.3 + hash-base: 3.0.5 + inherits: 2.0.4 + pbkdf2: 3.1.5 + public-encrypt: 4.0.3 + randombytes: 2.1.0 + randomfill: 1.0.4 + + crypto-js@4.2.0: {} + + css-declaration-sorter@6.4.1(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + + css-declaration-sorter@7.4.0(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + + css-loader@3.6.0(webpack@4.47.0): + dependencies: + camelcase: 5.3.1 + cssesc: 3.0.0 + icss-utils: 4.1.1 + loader-utils: 1.4.2 + normalize-path: 3.0.0 + postcss: 7.0.39 + postcss-modules-extract-imports: 2.0.0 + postcss-modules-local-by-default: 3.0.3 + postcss-modules-scope: 2.2.0 + postcss-modules-values: 3.0.0 + postcss-value-parser: 4.2.0 + schema-utils: 2.7.1 + semver: 6.3.1 + webpack: 4.47.0 + + css-loader@5.2.7(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)): + dependencies: + icss-utils: 5.1.0(postcss@8.5.14) + loader-utils: 2.0.4 + postcss: 8.5.14 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.14) + postcss-modules-local-by-default: 4.2.0(postcss@8.5.14) + postcss-modules-scope: 3.2.1(postcss@8.5.14) + postcss-modules-values: 4.0.0(postcss@8.5.14) + postcss-value-parser: 4.2.0 + schema-utils: 3.3.0 + semver: 7.8.0 + webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + + css-loader@6.11.0(webpack@5.106.2): + dependencies: + icss-utils: 5.1.0(postcss@8.5.14) + postcss: 8.5.14 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.14) + postcss-modules-local-by-default: 4.2.0(postcss@8.5.14) + postcss-modules-scope: 3.2.1(postcss@8.5.14) + postcss-modules-values: 4.0.0(postcss@8.5.14) + postcss-value-parser: 4.2.0 + semver: 7.8.0 + optionalDependencies: + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + + css-minimizer-webpack-plugin@3.4.1(webpack@5.106.2): + dependencies: + cssnano: 5.1.15(postcss@8.5.14) + jest-worker: 27.5.1 + postcss: 8.5.14 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + source-map: 0.6.1 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + + css-minimizer-webpack-plugin@5.0.1(webpack@5.106.2): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + cssnano: 6.1.2(postcss@8.5.14) + jest-worker: 29.7.0 + postcss: 8.5.14 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) + + css-select@4.3.0: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 4.3.1 + domutils: 2.8.0 + nth-check: 2.1.1 + + css-select@5.2.2: + dependencies: + boolbase: 1.0.0 + css-what: 6.2.2 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-tree@1.1.3: + dependencies: + mdn-data: 2.0.14 + source-map: 0.6.1 + + css-tree@2.2.1: + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.2.1 + + css-tree@2.3.1: + dependencies: + mdn-data: 2.0.30 + source-map-js: 1.2.1 + + css-tree@3.2.1: + dependencies: + mdn-data: 2.27.1 + source-map-js: 1.2.1 + + css-vendor@2.0.8: + dependencies: + '@babel/runtime': 7.29.2 + is-in-browser: 1.1.3 + + css-what@6.2.2: {} + + css.escape@1.5.1: {} + + cssesc@3.0.0: {} + + cssnano-preset-default@5.2.14(postcss@8.5.14): + dependencies: + css-declaration-sorter: 6.4.1(postcss@8.5.14) + cssnano-utils: 3.1.0(postcss@8.5.14) + postcss: 8.5.14 + postcss-calc: 8.2.4(postcss@8.5.14) + postcss-colormin: 5.3.1(postcss@8.5.14) + postcss-convert-values: 5.1.3(postcss@8.5.14) + postcss-discard-comments: 5.1.2(postcss@8.5.14) + postcss-discard-duplicates: 5.1.0(postcss@8.5.14) + postcss-discard-empty: 5.1.1(postcss@8.5.14) + postcss-discard-overridden: 5.1.0(postcss@8.5.14) + postcss-merge-longhand: 5.1.7(postcss@8.5.14) + postcss-merge-rules: 5.1.4(postcss@8.5.14) + postcss-minify-font-values: 5.1.0(postcss@8.5.14) + postcss-minify-gradients: 5.1.1(postcss@8.5.14) + postcss-minify-params: 5.1.4(postcss@8.5.14) + postcss-minify-selectors: 5.2.1(postcss@8.5.14) + postcss-normalize-charset: 5.1.0(postcss@8.5.14) + postcss-normalize-display-values: 5.1.0(postcss@8.5.14) + postcss-normalize-positions: 5.1.1(postcss@8.5.14) + postcss-normalize-repeat-style: 5.1.1(postcss@8.5.14) + postcss-normalize-string: 5.1.0(postcss@8.5.14) + postcss-normalize-timing-functions: 5.1.0(postcss@8.5.14) + postcss-normalize-unicode: 5.1.1(postcss@8.5.14) + postcss-normalize-url: 5.1.0(postcss@8.5.14) + postcss-normalize-whitespace: 5.1.1(postcss@8.5.14) + postcss-ordered-values: 5.1.3(postcss@8.5.14) + postcss-reduce-initial: 5.1.2(postcss@8.5.14) + postcss-reduce-transforms: 5.1.0(postcss@8.5.14) + postcss-svgo: 5.1.0(postcss@8.5.14) + postcss-unique-selectors: 5.1.1(postcss@8.5.14) + + cssnano-preset-default@6.1.2(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + css-declaration-sorter: 7.4.0(postcss@8.5.14) + cssnano-utils: 4.0.2(postcss@8.5.14) + postcss: 8.5.14 + postcss-calc: 9.0.1(postcss@8.5.14) + postcss-colormin: 6.1.0(postcss@8.5.14) + postcss-convert-values: 6.1.0(postcss@8.5.14) + postcss-discard-comments: 6.0.2(postcss@8.5.14) + postcss-discard-duplicates: 6.0.3(postcss@8.5.14) + postcss-discard-empty: 6.0.3(postcss@8.5.14) + postcss-discard-overridden: 6.0.2(postcss@8.5.14) + postcss-merge-longhand: 6.0.5(postcss@8.5.14) + postcss-merge-rules: 6.1.1(postcss@8.5.14) + postcss-minify-font-values: 6.1.0(postcss@8.5.14) + postcss-minify-gradients: 6.0.3(postcss@8.5.14) + postcss-minify-params: 6.1.0(postcss@8.5.14) + postcss-minify-selectors: 6.0.4(postcss@8.5.14) + postcss-normalize-charset: 6.0.2(postcss@8.5.14) + postcss-normalize-display-values: 6.0.2(postcss@8.5.14) + postcss-normalize-positions: 6.0.2(postcss@8.5.14) + postcss-normalize-repeat-style: 6.0.2(postcss@8.5.14) + postcss-normalize-string: 6.0.2(postcss@8.5.14) + postcss-normalize-timing-functions: 6.0.2(postcss@8.5.14) + postcss-normalize-unicode: 6.1.0(postcss@8.5.14) + postcss-normalize-url: 6.0.2(postcss@8.5.14) + postcss-normalize-whitespace: 6.0.2(postcss@8.5.14) + postcss-ordered-values: 6.0.2(postcss@8.5.14) + postcss-reduce-initial: 6.1.0(postcss@8.5.14) + postcss-reduce-transforms: 6.0.2(postcss@8.5.14) + postcss-svgo: 6.0.3(postcss@8.5.14) + postcss-unique-selectors: 6.0.4(postcss@8.5.14) + + cssnano-utils@3.1.0(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + + cssnano-utils@4.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + + cssnano@5.1.15(postcss@8.5.14): + dependencies: + cssnano-preset-default: 5.2.14(postcss@8.5.14) + lilconfig: 2.1.0 + postcss: 8.5.14 + yaml: 1.10.3 + + cssnano@6.1.2(postcss@8.5.14): + dependencies: + cssnano-preset-default: 6.1.2(postcss@8.5.14) + lilconfig: 3.1.3 + postcss: 8.5.14 + + csso@4.2.0: + dependencies: + css-tree: 1.1.3 + + csso@5.0.5: + dependencies: + css-tree: 2.2.1 + + cssom@0.3.8: {} + + cssom@0.4.4: {} + + cssstyle@2.3.0: + dependencies: + cssom: 0.3.8 + + cssstyle@6.2.0: + dependencies: + '@asamuzakjp/css-color': 5.1.11 + '@csstools/css-syntax-patches-for-csstree': 1.1.4(css-tree@3.2.1) + css-tree: 3.2.1 + lru-cache: 11.3.6 + + csstype@3.2.3: {} + + currently-unhandled@0.4.1: + dependencies: + array-find-index: 1.0.2 + optional: true + + cyclist@1.0.2: {} + + d3-array@2.12.1: + dependencies: + internmap: 1.0.1 + + d3-array@3.2.4: + dependencies: + internmap: 2.0.3 + + d3-color@3.1.0: {} + + d3-delaunay@6.0.4: + dependencies: + delaunator: 5.1.0 + + d3-ease@3.0.1: {} + + d3-format@1.4.5: {} + + d3-interpolate@3.0.1: + dependencies: + d3-color: 3.1.0 + + d3-path@3.1.0: {} + + d3-scale-chromatic@3.1.0: + dependencies: + d3-color: 3.1.0 + d3-interpolate: 3.0.1 + + d3-scale@4.0.2: + dependencies: + d3-array: 3.2.4 + d3-format: 1.4.5 + d3-interpolate: 3.0.1 + d3-time: 3.1.0 + d3-time-format: 3.0.0 + + d3-shape@3.2.0: + dependencies: + d3-path: 3.1.0 + + d3-time-format@3.0.0: + dependencies: + d3-time: 2.1.1 + + d3-time@1.1.0: {} + + d3-time@2.1.1: + dependencies: + d3-array: 2.12.1 + + d3-time@3.1.0: + dependencies: + d3-array: 3.2.4 + + d3-timer@3.0.1: {} + + damerau-levenshtein@1.0.8: {} + + dargs@7.0.0: {} + + data-urls@2.0.0: + dependencies: + abab: 2.0.6 + whatwg-mimetype: 2.3.0 + whatwg-url: 8.7.0 + + data-urls@7.0.0(@noble/hashes@1.8.0): + dependencies: + whatwg-mimetype: 5.0.0 + whatwg-url: 16.0.1(@noble/hashes@1.8.0) + transitivePeerDependencies: + - '@noble/hashes' + + data-view-buffer@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-length@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + data-view-byte-offset@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-data-view: 1.0.2 + + date-fns@2.30.0: + dependencies: + '@babel/runtime': 7.29.2 + + date-fns@4.1.0: {} + + dateformat@3.0.3: {} + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@3.2.7: + dependencies: + ms: 2.1.3 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + decamelize-keys@1.1.1: + dependencies: + decamelize: 1.2.0 + map-obj: 1.0.1 + + decamelize@1.2.0: {} + + decimal.js-light@2.5.1: {} + + decimal.js@10.6.0: {} + + decode-named-character-reference@1.3.0: + dependencies: + character-entities: 2.0.2 + + decode-uri-component@0.2.2: {} + + dedent@0.7.0: {} + + dedent@1.7.2(babel-plugin-macros@3.1.0): + optionalDependencies: + babel-plugin-macros: 3.1.0 + + deep-equal@2.2.3: + dependencies: + array-buffer-byte-length: 1.0.2 + call-bind: 1.0.9 + es-get-iterator: 1.1.3 + get-intrinsic: 1.3.0 + is-arguments: 1.2.0 + is-array-buffer: 3.0.5 + is-date-object: 1.1.0 + is-regex: 1.2.1 + is-shared-array-buffer: 1.0.4 + isarray: 2.0.5 + object-is: 1.1.6 + object-keys: 1.1.1 + object.assign: 4.1.7 + regexp.prototype.flags: 1.5.4 + side-channel: 1.1.0 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.20 + + deep-is@0.1.4: {} + + deep-object-diff@1.1.9: {} + + deepmerge@4.3.1: {} + + default-browser-id@1.0.4: + dependencies: + bplist-parser: 0.1.1 + meow: 3.7.0 + untildify: 2.1.0 + optional: true + + default-gateway@6.0.3: + dependencies: + execa: 5.1.1 + + defaults@1.0.4: + dependencies: + clone: 1.0.4 + + define-data-property@1.1.4: + dependencies: + es-define-property: 1.0.1 + es-errors: 1.3.0 + gopd: 1.2.0 + + define-lazy-prop@2.0.0: {} + + define-properties@1.2.1: + dependencies: + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 + object-keys: 1.1.1 + + define-property@0.2.5: + dependencies: + is-descriptor: 0.1.8 + + define-property@1.0.0: + dependencies: + is-descriptor: 1.0.4 + + define-property@2.0.2: + dependencies: + is-descriptor: 1.0.4 + isobject: 3.0.1 + + defu@6.1.7: {} + + del@4.1.1: + dependencies: + '@types/glob': 7.2.0 + globby: 6.1.0 + is-path-cwd: 2.2.0 + is-path-in-cwd: 2.1.0 + p-map: 2.1.0 + pify: 4.0.1 + rimraf: 2.7.1 + + delaunator@5.1.0: + dependencies: + robust-predicates: 3.0.3 + + delay@4.4.1: {} + + delayed-stream@1.0.0: {} + + delegates@1.0.0: {} + + depd@1.1.2: {} + + depd@2.0.0: {} + + deprecation@2.3.1: {} + + dequal@2.0.3: {} + + des.js@1.1.0: + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + + destr@2.0.5: {} + + destroy@1.2.0: {} + + detab@2.0.4: + dependencies: + repeat-string: 1.6.1 + + detect-indent@5.0.0: {} + + detect-libc@2.1.2: {} + + detect-newline@3.1.0: {} + + detect-node@2.1.0: {} + + detect-package-manager@2.0.1: + dependencies: + execa: 5.1.1 + + detect-port@1.6.1: + dependencies: + address: 1.2.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + diff-sequences@27.5.1: {} + + diff-sequences@29.6.3: {} + + diffie-hellman@5.0.3: + dependencies: + bn.js: 4.12.3 + miller-rabin: 4.0.1 + randombytes: 2.1.0 + + dir-glob@2.2.2: + dependencies: + path-type: 3.0.0 + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + dns-packet@5.6.1: + dependencies: + '@leichtgewicht/ip-codec': 2.0.5 + + doctrine@2.1.0: + dependencies: + esutils: 2.0.3 + + doctrine@3.0.0: + dependencies: + esutils: 2.0.3 + + dom-accessibility-api@0.5.16: {} + + dom-accessibility-api@0.6.3: {} + + dom-converter@0.2.0: + dependencies: + utila: 0.4.0 + + dom-helpers@5.2.1: + dependencies: + '@babel/runtime': 7.29.2 + csstype: 3.2.3 + + dom-serializer@1.4.1: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + entities: 2.2.0 + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + dom-walk@0.1.2: {} + + domain-browser@1.2.0: {} + + domelementtype@2.3.0: {} + + domexception@2.0.1: + dependencies: + webidl-conversions: 5.0.0 + + domhandler@4.3.1: + dependencies: + domelementtype: 2.3.0 + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + dompurify@3.4.3: + optionalDependencies: + '@types/trusted-types': 2.0.7 + + domutils@2.8.0: + dependencies: + dom-serializer: 1.4.1 + domelementtype: 2.3.0 + domhandler: 4.3.1 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dot-case@3.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.8.1 + + dot-prop@5.3.0: + dependencies: + is-obj: 2.0.0 + + dotenv-defaults@2.0.2: + dependencies: + dotenv: 8.6.0 + + dotenv-expand@10.0.0: {} + + dotenv-expand@5.1.0: {} + + dotenv-webpack@7.1.1(webpack@5.106.2): + dependencies: + dotenv-defaults: 2.0.2 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + + dotenv-webpack@8.1.1(webpack@5.106.2): + dependencies: + dotenv-defaults: 2.0.2 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) + + dotenv@16.3.2: {} + + dotenv@8.6.0: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + duplexer@0.1.2: {} + + duplexify@3.7.1: + dependencies: + end-of-stream: 1.4.5 + inherits: 2.0.4 + readable-stream: 2.3.8 + stream-shift: 1.0.3 + + duplexify@4.1.3: + dependencies: + end-of-stream: 1.4.5 + inherits: 2.0.4 + readable-stream: 3.6.2 + stream-shift: 1.0.3 + + eastasianwidth@0.2.0: {} + + ee-first@1.1.1: {} + + ejs@3.1.10: + dependencies: + jake: 10.9.4 + + electron-to-chromium@1.5.354: {} + + elliptic@6.6.1: + dependencies: + bn.js: 4.12.3 + brorand: 1.1.0 + hash.js: 1.1.7 + hmac-drbg: 1.0.1 + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + emittery@0.13.1: {} + + emittery@0.8.1: {} + + emoji-regex@8.0.0: {} + + emoji-regex@9.2.2: {} + + emojis-list@3.0.0: {} + + encodeurl@2.0.0: {} + + encoding@0.1.13: + dependencies: + iconv-lite: 0.6.3 + optional: true + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + + endent@2.1.0: + dependencies: + dedent: 0.7.0 + fast-json-parse: 1.0.3 + objectorarray: 1.0.5 + + enhanced-resolve@4.5.0: + dependencies: + graceful-fs: 4.2.11 + memory-fs: 0.5.0 + tapable: 1.1.3 + + enhanced-resolve@5.21.3: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.3 + + enquirer@2.3.6: + dependencies: + ansi-colors: 4.1.3 + + entities@2.2.0: {} + + entities@4.5.0: {} + + entities@8.0.0: {} + + env-paths@2.2.1: {} + + envinfo@7.21.0: {} + + envinfo@7.8.1: {} + + err-code@2.0.3: {} + + errno@0.1.8: + dependencies: + prr: 1.0.1 + + error-ex@1.3.4: + dependencies: + is-arrayish: 0.2.1 + + error-stack-parser@2.1.4: + dependencies: + stackframe: 1.3.4 + + es-abstract@1.24.2: + dependencies: + array-buffer-byte-length: 1.0.2 + arraybuffer.prototype.slice: 1.0.4 + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 + data-view-buffer: 1.0.2 + data-view-byte-length: 1.0.2 + data-view-byte-offset: 1.0.1 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + es-set-tostringtag: 2.1.0 + es-to-primitive: 1.3.0 + function.prototype.name: 1.1.8 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + get-symbol-description: 1.1.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.3 + internal-slot: 1.1.0 + is-array-buffer: 3.0.5 + is-callable: 1.2.7 + is-data-view: 1.0.2 + is-negative-zero: 2.0.3 + is-regex: 1.2.1 + is-set: 2.0.3 + is-shared-array-buffer: 1.0.4 + is-string: 1.1.1 + is-typed-array: 1.1.15 + is-weakref: 1.1.1 + math-intrinsics: 1.1.0 + object-inspect: 1.13.4 + object-keys: 1.1.1 + object.assign: 4.1.7 + own-keys: 1.0.1 + regexp.prototype.flags: 1.5.4 + safe-array-concat: 1.1.4 + safe-push-apply: 1.0.0 + safe-regex-test: 1.1.0 + set-proto: 1.0.0 + stop-iteration-iterator: 1.1.0 + string.prototype.trim: 1.2.10 + string.prototype.trimend: 1.0.9 + string.prototype.trimstart: 1.0.8 + typed-array-buffer: 1.0.3 + typed-array-byte-length: 1.0.3 + typed-array-byte-offset: 1.0.4 + typed-array-length: 1.0.7 + unbox-primitive: 1.1.0 + which-typed-array: 1.1.20 + + es-array-method-boxes-properly@1.0.0: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-get-iterator@1.1.3: + dependencies: + call-bind: 1.0.9 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + is-arguments: 1.2.0 + is-map: 2.0.3 + is-set: 2.0.3 + is-string: 1.1.1 + isarray: 2.0.5 + stop-iteration-iterator: 1.1.0 + + es-iterator-helpers@1.3.2: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-set-tostringtag: 2.1.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + globalthis: 1.0.4 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + has-proto: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + iterator.prototype: 1.1.5 + math-intrinsics: 1.1.0 + + es-module-lexer@2.1.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + es-set-tostringtag@2.1.0: + dependencies: + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + has-tostringtag: 1.0.2 + hasown: 2.0.3 + + es-shim-unscopables@1.1.0: + dependencies: + hasown: 2.0.3 + + es-to-primitive@1.3.0: + dependencies: + is-callable: 1.2.7 + is-date-object: 1.1.0 + is-symbol: 1.1.1 + + es5-shim@4.6.7: {} + + es6-shim@0.35.8: {} + + esbuild-register@3.6.0(esbuild@0.25.12): + dependencies: + debug: 4.4.3 + esbuild: 0.25.12 + transitivePeerDependencies: + - supports-color + + esbuild@0.25.12: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.12 + '@esbuild/android-arm': 0.25.12 + '@esbuild/android-arm64': 0.25.12 + '@esbuild/android-x64': 0.25.12 + '@esbuild/darwin-arm64': 0.25.12 + '@esbuild/darwin-x64': 0.25.12 + '@esbuild/freebsd-arm64': 0.25.12 + '@esbuild/freebsd-x64': 0.25.12 + '@esbuild/linux-arm': 0.25.12 + '@esbuild/linux-arm64': 0.25.12 + '@esbuild/linux-ia32': 0.25.12 + '@esbuild/linux-loong64': 0.25.12 + '@esbuild/linux-mips64el': 0.25.12 + '@esbuild/linux-ppc64': 0.25.12 + '@esbuild/linux-riscv64': 0.25.12 + '@esbuild/linux-s390x': 0.25.12 + '@esbuild/linux-x64': 0.25.12 + '@esbuild/netbsd-arm64': 0.25.12 + '@esbuild/netbsd-x64': 0.25.12 + '@esbuild/openbsd-arm64': 0.25.12 + '@esbuild/openbsd-x64': 0.25.12 + '@esbuild/openharmony-arm64': 0.25.12 + '@esbuild/sunos-x64': 0.25.12 + '@esbuild/win32-arm64': 0.25.12 + '@esbuild/win32-ia32': 0.25.12 + '@esbuild/win32-x64': 0.25.12 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + escape-string-regexp@1.0.5: {} + + escape-string-regexp@2.0.0: {} + + escape-string-regexp@4.0.0: {} + + escodegen@2.1.0: + dependencies: + esprima: 4.0.1 + estraverse: 5.3.0 + esutils: 2.0.3 + optionalDependencies: + source-map: 0.6.1 + + eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint@9.39.4): + dependencies: + confusing-browser-globals: 1.0.11 + eslint: 9.39.4 + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4) + object.assign: 4.1.7 + object.entries: 1.1.9 + semver: 6.3.1 + + eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4))(eslint@9.39.4): + dependencies: + confusing-browser-globals: 1.0.11 + eslint: 9.39.4 + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4) + object.assign: 4.1.7 + object.entries: 1.1.9 + semver: 6.3.1 + + eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1): + dependencies: + confusing-browser-globals: 1.0.11 + eslint: 8.57.1 + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1) + object.assign: 4.1.7 + object.entries: 1.1.9 + semver: 6.3.1 + + eslint-config-airbnb-typescript@16.2.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint@9.39.4): + dependencies: + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5) + '@typescript-eslint/parser': 5.62.0(eslint@9.39.4)(typescript@4.9.5) + eslint: 9.39.4 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint@9.39.4) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4) + + eslint-config-airbnb-typescript@16.2.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3))(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4))(eslint@9.39.4): + dependencies: + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/parser': 5.62.0(eslint@9.39.4)(typescript@5.9.3) + eslint: 9.39.4 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4))(eslint@9.39.4) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4) + + eslint-config-airbnb-typescript@16.2.0(@typescript-eslint/eslint-plugin@8.59.4(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3))(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1): + dependencies: + '@typescript-eslint/eslint-plugin': 8.59.4(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) + '@typescript-eslint/parser': 8.59.4(eslint@8.57.1)(typescript@5.9.3) + eslint: 8.57.1 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1) + + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4))(eslint-plugin-react-hooks@4.6.2(eslint@9.39.4))(eslint-plugin-react@7.37.5(eslint@9.39.4))(eslint@9.39.4): + dependencies: + eslint: 9.39.4 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint@9.39.4) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.4) + eslint-plugin-react: 7.37.5(eslint@9.39.4) + eslint-plugin-react-hooks: 4.6.2(eslint@9.39.4) + object.assign: 4.1.7 + object.entries: 1.1.9 + + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4))(eslint-plugin-react-hooks@5.2.0(eslint@9.39.4))(eslint-plugin-react@7.37.5(eslint@9.39.4))(eslint@9.39.4): + dependencies: + eslint: 9.39.4 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint@9.39.4) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.4) + eslint-plugin-react: 7.37.5(eslint@9.39.4) + eslint-plugin-react-hooks: 5.2.0(eslint@9.39.4) + object.assign: 4.1.7 + object.entries: 1.1.9 + + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4))(eslint-plugin-react-hooks@4.6.2(eslint@9.39.4))(eslint-plugin-react@7.37.5(eslint@9.39.4))(eslint@9.39.4): + dependencies: + eslint: 9.39.4 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4))(eslint@9.39.4) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.4) + eslint-plugin-react: 7.37.5(eslint@9.39.4) + eslint-plugin-react-hooks: 4.6.2(eslint@9.39.4) + object.assign: 4.1.7 + object.entries: 1.1.9 + + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.1))(eslint-plugin-react@7.37.5(eslint@8.57.1))(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1) + eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) + eslint-plugin-react: 7.37.5(eslint@8.57.1) + eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) + object.assign: 4.1.7 + object.entries: 1.1.9 + + eslint-config-next@15.0.3(eslint@9.39.4)(typescript@5.9.3): + dependencies: + '@next/eslint-plugin-next': 15.0.3 + '@rushstack/eslint-patch': 1.16.1 + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) + '@typescript-eslint/parser': 5.62.0(eslint@9.39.4)(typescript@5.9.3) + eslint: 9.39.4 + eslint-import-resolver-node: 0.3.10 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.4) + eslint-plugin-react: 7.37.5(eslint@9.39.4) + eslint-plugin-react-hooks: 5.2.0(eslint@9.39.4) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - eslint-import-resolver-webpack + - eslint-plugin-import-x + - supports-color + + eslint-config-prettier@8.10.2(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + + eslint-config-prettier@8.10.2(eslint@9.39.4): + dependencies: + eslint: 9.39.4 + + eslint-import-resolver-node@0.3.10: + dependencies: + debug: 3.2.7 + is-core-module: 2.16.2 + resolve: 2.0.0-next.6 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-root-import@1.0.4(babel-plugin-root-import@5.1.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)): + dependencies: + babel-plugin-root-import: 5.1.0 + eslint-import-resolver-node: 0.3.10 + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4) + json5: 2.2.3 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-root-import@1.0.4(babel-plugin-root-import@6.6.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)): + dependencies: + babel-plugin-root-import: 6.6.0 + eslint-import-resolver-node: 0.3.10 + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4) + json5: 2.2.3 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-root-import@1.0.4(babel-plugin-root-import@6.6.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)): + dependencies: + babel-plugin-root-import: 6.6.0 + eslint-import-resolver-node: 0.3.10 + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4) + json5: 2.2.3 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-root-import@1.0.4(babel-plugin-root-import@6.6.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)): + dependencies: + babel-plugin-root-import: 6.6.0 + eslint-import-resolver-node: 0.3.10 + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1) + json5: 2.2.3 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4): + dependencies: + '@nolyfill/is-core-module': 1.0.39 + debug: 4.4.3 + eslint: 9.39.4 + get-tsconfig: 4.14.0 + is-bun-module: 2.0.0 + stable-hash: 0.0.5 + tinyglobby: 0.2.16 + unrs-resolver: 1.11.1 + optionalDependencies: + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.1(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint-import-resolver-node@0.3.10)(eslint@9.39.4): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 5.62.0(eslint@9.39.4)(typescript@4.9.5) + eslint: 9.39.4 + eslint-import-resolver-node: 0.3.10 + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.1(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 5.62.0(eslint@9.39.4)(typescript@5.9.3) + eslint: 9.39.4 + eslint-import-resolver-node: 0.3.10 + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4) + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint@8.57.1): + dependencies: + debug: 3.2.7 + optionalDependencies: + '@typescript-eslint/parser': 8.59.4(eslint@8.57.1)(typescript@5.9.3) + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.10 + transitivePeerDependencies: + - supports-color + + eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.39.4 + eslint-import-resolver-node: 0.3.10 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint-import-resolver-node@0.3.10)(eslint@9.39.4) + hasown: 2.0.3 + is-core-module: 2.16.2 + is-glob: 4.0.3 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 5.62.0(eslint@9.39.4)(typescript@4.9.5) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.39.4 + eslint-import-resolver-node: 0.3.10 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4) + hasown: 2.0.3 + is-core-module: 2.16.2 + is-glob: 4.0.3 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 5.62.0(eslint@9.39.4)(typescript@5.9.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 9.39.4 + eslint-import-resolver-node: 0.3.10 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4) + hasown: 2.0.3 + is-core-module: 2.16.2 + is-glob: 4.0.3 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 5.62.0(eslint@9.39.4)(typescript@5.9.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7 + doctrine: 2.1.0 + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.10 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint@8.57.1) + hasown: 2.0.3 + is-core-module: 2.16.2 + is-glob: 4.0.3 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 8.59.4(eslint@8.57.1)(typescript@5.9.3) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-jest@26.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(jest@27.5.1)(typescript@4.9.5): + dependencies: + '@typescript-eslint/utils': 5.62.0(eslint@9.39.4)(typescript@4.9.5) + eslint: 9.39.4 + optionalDependencies: + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5) + jest: 27.5.1 + transitivePeerDependencies: + - supports-color + - typescript + + eslint-plugin-jest@26.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3): + dependencies: + '@typescript-eslint/utils': 5.62.0(eslint@9.39.4)(typescript@5.9.3) + eslint: 9.39.4 + optionalDependencies: + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)(typescript@5.9.3) + transitivePeerDependencies: + - supports-color + - typescript + + eslint-plugin-jest@26.9.0(@typescript-eslint/eslint-plugin@8.59.4(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(jest@29.7.0(@types/node@22.19.19)(babel-plugin-macros@3.1.0))(typescript@5.9.3): + dependencies: + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@5.9.3) + eslint: 8.57.1 + optionalDependencies: + '@typescript-eslint/eslint-plugin': 8.59.4(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1)(typescript@5.9.3) + jest: 29.7.0(@types/node@22.19.19)(babel-plugin-macros@3.1.0) + transitivePeerDependencies: + - supports-color + - typescript + + eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1): + dependencies: + aria-query: 5.3.2 + array-includes: 3.1.9 + array.prototype.flatmap: 1.3.3 + ast-types-flow: 0.0.8 + axe-core: 4.11.4 + axobject-query: 4.1.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 8.57.1 + hasown: 2.0.3 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + safe-regex-test: 1.1.0 + string.prototype.includes: 2.0.1 + + eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4): + dependencies: + aria-query: 5.3.2 + array-includes: 3.1.9 + array.prototype.flatmap: 1.3.3 + ast-types-flow: 0.0.8 + axe-core: 4.11.4 + axobject-query: 4.1.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 9.39.4 + hasown: 2.0.3 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + safe-regex-test: 1.1.0 + string.prototype.includes: 2.0.1 + + eslint-plugin-prettier@4.2.5(eslint-config-prettier@8.10.2(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8): + dependencies: + eslint: 8.57.1 + prettier: 2.8.8 + prettier-linter-helpers: 1.0.1 + optionalDependencies: + eslint-config-prettier: 8.10.2(eslint@8.57.1) + + eslint-plugin-prettier@4.2.5(eslint-config-prettier@8.10.2(eslint@9.39.4))(eslint@9.39.4)(prettier@2.8.8): + dependencies: + eslint: 9.39.4 + prettier: 2.8.8 + prettier-linter-helpers: 1.0.1 + optionalDependencies: + eslint-config-prettier: 8.10.2(eslint@9.39.4) + + eslint-plugin-react-hooks@4.6.2(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + + eslint-plugin-react-hooks@4.6.2(eslint@9.39.4): + dependencies: + eslint: 9.39.4 + + eslint-plugin-react-hooks@5.2.0(eslint@9.39.4): + dependencies: + eslint: 9.39.4 + + eslint-plugin-react@7.37.5(eslint@8.57.1): + dependencies: + array-includes: 3.1.9 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.3.2 + eslint: 8.57.1 + estraverse: 5.3.0 + hasown: 2.0.3 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.5 + object.entries: 1.1.9 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.6 + semver: 6.3.1 + string.prototype.matchall: 4.0.12 + string.prototype.repeat: 1.0.0 + + eslint-plugin-react@7.37.5(eslint@9.39.4): + dependencies: + array-includes: 3.1.9 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.3.2 + eslint: 9.39.4 + estraverse: 5.3.0 + hasown: 2.0.3 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.5 + object.entries: 1.1.9 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.6 + semver: 6.3.1 + string.prototype.matchall: 4.0.12 + string.prototype.repeat: 1.0.0 + + eslint-plugin-storybook@0.5.13(eslint@9.39.4)(typescript@4.9.5): + dependencies: + '@storybook/csf': 0.0.1 + '@typescript-eslint/experimental-utils': 5.62.0(eslint@9.39.4)(typescript@4.9.5) + eslint: 9.39.4 + requireindex: 1.2.0 + transitivePeerDependencies: + - supports-color + - typescript + + eslint-plugin-storybook@0.5.13(eslint@9.39.4)(typescript@5.9.3): + dependencies: + '@storybook/csf': 0.0.1 + '@typescript-eslint/experimental-utils': 5.62.0(eslint@9.39.4)(typescript@5.9.3) + eslint: 9.39.4 + requireindex: 1.2.0 + transitivePeerDependencies: + - supports-color + - typescript + + eslint-scope@4.0.3: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + eslint-scope@5.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + eslint-scope@7.2.2: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-scope@8.4.0: + dependencies: + esrecurse: 4.3.0 + estraverse: 5.3.0 + + eslint-visitor-keys@3.4.3: {} + + eslint-visitor-keys@4.2.1: {} + + eslint-visitor-keys@5.0.1: {} + + eslint@8.57.1: + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) + '@eslint-community/regexpp': 4.12.2 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.1 + '@humanwhocodes/config-array': 0.13.0 + '@humanwhocodes/module-importer': 1.0.1 + '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.3.1 + ajv: 6.15.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + doctrine: 3.0.0 + escape-string-regexp: 4.0.0 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 + espree: 9.6.1 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + find-up: 5.0.0 + glob-parent: 6.0.2 + globals: 13.24.0 + graphemer: 1.4.0 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + is-path-inside: 3.0.3 + js-yaml: 4.1.1 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + strip-ansi: 6.0.1 + text-table: 0.2.0 + transitivePeerDependencies: + - supports-color + + eslint@9.39.4: + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@9.39.4) + '@eslint-community/regexpp': 4.12.2 + '@eslint/config-array': 0.21.2 + '@eslint/config-helpers': 0.4.2 + '@eslint/core': 0.17.0 + '@eslint/eslintrc': 3.3.5 + '@eslint/js': 9.39.4 + '@eslint/plugin-kit': 0.4.1 + '@humanfs/node': 0.16.8 + '@humanwhocodes/module-importer': 1.0.1 + '@humanwhocodes/retry': 0.4.3 + '@types/estree': 1.0.9 + ajv: 6.15.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3 + escape-string-regexp: 4.0.0 + eslint-scope: 8.4.0 + eslint-visitor-keys: 4.2.1 + espree: 10.4.0 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 8.0.0 + find-up: 5.0.0 + glob-parent: 6.0.2 + ignore: 5.3.2 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + json-stable-stringify-without-jsonify: 1.0.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + transitivePeerDependencies: + - supports-color + + espree@10.4.0: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + eslint-visitor-keys: 4.2.1 + + espree@9.6.1: + dependencies: + acorn: 8.16.0 + acorn-jsx: 5.3.2(acorn@8.16.0) + eslint-visitor-keys: 3.4.3 + + esprima@4.0.1: {} + + esquery@1.7.0: + dependencies: + estraverse: 5.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@4.3.0: {} + + estraverse@5.3.0: {} + + estree-to-babel@3.2.1: + dependencies: + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + c8: 7.14.0 + transitivePeerDependencies: + - supports-color + + estree-util-is-identifier-name@3.0.0: {} + + esutils@2.0.3: {} + + etag@1.8.1: {} + + eventemitter3@4.0.7: {} + + events@3.3.0: {} + + evp_bytestokey@1.0.3: + dependencies: + md5.js: 1.3.5 + safe-buffer: 5.2.1 + + exec-sh@0.3.6: {} + + execa@1.0.0: + dependencies: + cross-spawn: 6.0.6 + get-stream: 4.1.0 + is-stream: 1.1.0 + npm-run-path: 2.0.2 + p-finally: 1.0.0 + signal-exit: 3.0.7 + strip-eof: 1.0.0 + + execa@5.0.0: + dependencies: + cross-spawn: 7.0.6 + 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.7 + strip-final-newline: 2.0.0 + + execa@5.1.1: + dependencies: + cross-spawn: 7.0.6 + get-stream: 6.0.1 + human-signals: 2.1.0 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + + exit@0.1.2: {} + + expand-brackets@2.1.4: + dependencies: + debug: 2.6.9 + define-property: 0.2.5 + extend-shallow: 2.0.1 + posix-character-classes: 0.1.1 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + expect@27.5.1: + dependencies: + '@jest/types': 27.5.1 + jest-get-type: 27.5.1 + jest-matcher-utils: 27.5.1 + jest-message-util: 27.5.1 + + expect@29.7.0: + dependencies: + '@jest/expect-utils': 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + + exponential-backoff@3.1.3: {} + + express@4.22.2: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.5 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.0.7 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.2 + fresh: 0.5.2 + http-errors: 2.0.1 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.13 + proxy-addr: 2.0.7 + qs: 6.15.1 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.2 + serve-static: 1.16.3 + setprototypeof: 1.2.0 + statuses: 2.0.2 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + extend-shallow@2.0.1: + dependencies: + is-extendable: 0.1.1 + + extend-shallow@3.0.2: + dependencies: + assign-symbols: 1.0.0 + is-extendable: 1.0.1 + + extend@3.0.2: {} + + extglob@2.0.4: + dependencies: + array-unique: 0.3.2 + define-property: 1.0.0 + expand-brackets: 2.1.4 + extend-shallow: 2.0.1 + fragment-cache: 0.2.1 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + fast-deep-equal@3.1.3: {} + + fast-diff@1.3.0: {} + + fast-equals@5.4.0: {} + + fast-glob@2.2.7: + dependencies: + '@mrmlnc/readdir-enhanced': 2.2.1 + '@nodelib/fs.stat': 1.1.3 + glob-parent: 3.1.0 + is-glob: 4.0.3 + merge2: 1.4.1 + micromatch: 3.1.10 + transitivePeerDependencies: + - supports-color + + fast-glob@3.3.1: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-json-parse@1.0.3: {} + + fast-json-stable-stringify@2.1.0: {} + + fast-levenshtein@2.0.6: {} + + fast-redact@3.5.0: {} + + fast-uri@3.1.2: {} + + fastest-levenshtein@1.0.16: {} + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + favicons-webpack-plugin@5.0.2(favicons@7.2.0)(webpack@5.106.2): + dependencies: + '@types/favicons': 5.5.0 + favicons: 7.2.0 + find-root: 1.1.0 + parse-author: 2.0.0 + parse5: 6.0.1 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + optionalDependencies: + html-webpack-plugin: 5.6.7(webpack@5.106.2) + transitivePeerDependencies: + - '@rspack/core' + + favicons@7.2.0: + dependencies: + escape-html: 1.0.3 + sharp: 0.33.5 + xml2js: 0.6.2 + + faye-websocket@0.11.4: + dependencies: + websocket-driver: 0.7.4 + + fb-watchman@2.0.2: + dependencies: + bser: 2.1.1 + + fdir@6.5.0(picomatch@4.0.4): + optionalDependencies: + picomatch: 4.0.4 + + fetch-retry@5.0.6: {} + + figgy-pudding@3.5.2: {} + + figures@3.2.0: + dependencies: + escape-string-regexp: 1.0.5 + + file-entry-cache@6.0.1: + dependencies: + flat-cache: 3.2.0 + + file-entry-cache@8.0.0: + dependencies: + flat-cache: 4.0.1 + + file-loader@6.2.0(webpack@4.47.0): + dependencies: + loader-utils: 2.0.4 + schema-utils: 3.3.0 + webpack: 4.47.0 + + file-loader@6.2.0(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)): + dependencies: + loader-utils: 2.0.4 + schema-utils: 3.3.0 + webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + + file-loader@6.2.0(webpack@5.106.2): + dependencies: + loader-utils: 2.0.4 + schema-utils: 3.3.0 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + + file-system-cache@1.1.0: + dependencies: + fs-extra: 10.1.0 + ramda: 0.28.0 + + file-uri-to-path@1.0.0: {} + + filelist@1.0.6: + dependencies: + minimatch: 5.1.9 + + fill-range@4.0.0: + dependencies: + extend-shallow: 2.0.1 + is-number: 3.0.0 + repeat-string: 1.6.1 + to-regex-range: 2.1.1 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@1.3.2: + dependencies: + debug: 2.6.9 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + find-cache-dir@2.1.0: + dependencies: + commondir: 1.0.1 + make-dir: 2.1.0 + pkg-dir: 3.0.0 + + find-cache-dir@3.3.2: + dependencies: + commondir: 1.0.1 + make-dir: 3.1.0 + pkg-dir: 4.2.0 + + find-cache-dir@4.0.0: + dependencies: + common-path-prefix: 3.0.0 + pkg-dir: 7.0.0 + + find-root@1.1.0: {} + + find-up@1.1.2: + dependencies: + path-exists: 2.1.0 + pinkie-promise: 2.0.1 + optional: true + + find-up@2.1.0: + dependencies: + locate-path: 2.0.0 + + find-up@3.0.0: + dependencies: + locate-path: 3.0.0 + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + find-up@5.0.0: + dependencies: + locate-path: 6.0.0 + path-exists: 4.0.0 + + find-up@6.3.0: + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + + flat-cache@3.2.0: + dependencies: + flatted: 3.4.2 + keyv: 4.5.4 + rimraf: 3.0.2 + + flat-cache@4.0.1: + dependencies: + flatted: 3.4.2 + keyv: 4.5.4 + + flat@5.0.2: {} + + flatted@3.4.2: {} + + flush-write-stream@1.1.1: + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + + focus-lock@0.8.1: + dependencies: + tslib: 1.14.1 + + follow-redirects@1.16.0: {} + + for-each@0.3.5: + dependencies: + is-callable: 1.2.7 + + for-in@1.0.2: {} + + foreground-child@2.0.0: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 3.0.7 + + foreground-child@3.3.1: + dependencies: + cross-spawn: 7.0.6 + signal-exit: 4.1.0 + + fork-ts-checker-webpack-plugin@4.1.6(eslint@9.39.4)(typescript@4.9.5)(webpack@4.47.0): + dependencies: + '@babel/code-frame': 7.29.0 + chalk: 2.4.2 + micromatch: 3.1.10 + minimatch: 3.1.5 + semver: 5.7.2 + tapable: 1.1.3 + typescript: 4.9.5 + webpack: 4.47.0 + worker-rpc: 0.1.1 + optionalDependencies: + eslint: 9.39.4 + transitivePeerDependencies: + - supports-color + + fork-ts-checker-webpack-plugin@6.5.3(eslint@9.39.4)(typescript@4.9.5)(webpack@4.47.0): + dependencies: + '@babel/code-frame': 7.29.0 + '@types/json-schema': 7.0.15 + chalk: 4.1.2 + chokidar: 3.6.0 + cosmiconfig: 6.0.0 + deepmerge: 4.3.1 + fs-extra: 9.1.0 + glob: 7.2.3 + memfs: 3.5.3 + minimatch: 3.1.5 + schema-utils: 2.7.0 + semver: 7.8.0 + tapable: 1.1.3 + typescript: 4.9.5 + webpack: 4.47.0 + optionalDependencies: + eslint: 9.39.4 + + fork-ts-checker-webpack-plugin@6.5.3(eslint@9.39.4)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)): + dependencies: + '@babel/code-frame': 7.29.0 + '@types/json-schema': 7.0.15 + chalk: 4.1.2 + chokidar: 3.6.0 + cosmiconfig: 6.0.0 + deepmerge: 4.3.1 + fs-extra: 9.1.0 + glob: 7.2.3 + memfs: 3.5.3 + minimatch: 3.1.5 + schema-utils: 2.7.0 + semver: 7.8.0 + tapable: 1.1.3 + typescript: 4.9.5 + webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + optionalDependencies: + eslint: 9.39.4 + + fork-ts-checker-webpack-plugin@7.3.0(typescript@5.9.3)(webpack@5.106.2): + dependencies: + '@babel/code-frame': 7.29.0 + chalk: 4.1.2 + chokidar: 3.6.0 + cosmiconfig: 7.1.0 + deepmerge: 4.3.1 + fs-extra: 10.1.0 + memfs: 3.5.3 + minimatch: 3.1.5 + node-abort-controller: 3.1.1 + schema-utils: 3.3.0 + semver: 7.8.0 + tapable: 2.3.3 + typescript: 5.9.3 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + + fork-ts-checker-webpack-plugin@8.0.0(typescript@4.9.5)(webpack@5.106.2): + dependencies: + '@babel/code-frame': 7.29.0 + chalk: 4.1.2 + chokidar: 3.6.0 + cosmiconfig: 7.1.0 + deepmerge: 4.3.1 + fs-extra: 10.1.0 + memfs: 3.5.3 + minimatch: 3.1.5 + node-abort-controller: 3.1.1 + schema-utils: 3.3.0 + semver: 7.8.0 + tapable: 2.3.3 + typescript: 4.9.5 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) + + form-data@3.0.4: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.3 + mime-types: 2.1.35 + + form-data@4.0.5: + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + es-set-tostringtag: 2.1.0 + hasown: 2.0.3 + mime-types: 2.1.35 + + forwarded@0.2.0: {} + + fragment-cache@0.2.1: + dependencies: + map-cache: 0.2.2 + + fresh@0.5.2: {} + + from2@2.3.0: + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + + fs-constants@1.0.0: {} + + fs-extra@10.1.0: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.1 + universalify: 2.0.1 + + fs-extra@11.3.5: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.1 + universalify: 2.0.1 + + fs-extra@9.1.0: + dependencies: + at-least-node: 1.0.0 + graceful-fs: 4.2.11 + jsonfile: 6.2.1 + universalify: 2.0.1 + + fs-minipass@2.1.0: + dependencies: + minipass: 3.3.6 + + fs-minipass@3.0.3: + dependencies: + minipass: 7.1.3 + + fs-monkey@1.1.0: {} + + fs-write-stream-atomic@1.0.10: + dependencies: + graceful-fs: 4.2.11 + iferr: 0.1.5 + imurmurhash: 0.1.4 + readable-stream: 2.3.8 + + fs.realpath@1.0.0: {} + + fsevents@1.2.13: + dependencies: + bindings: 1.5.0 + nan: 2.27.0 + optional: true + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + function.prototype.name@1.1.8: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + functions-have-names: 1.2.3 + hasown: 2.0.3 + is-callable: 1.2.7 + + functions-have-names@1.2.3: {} + + gauge@3.0.2: + dependencies: + aproba: 2.1.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + object-assign: 4.1.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + + gauge@4.0.4: + dependencies: + aproba: 2.1.0 + color-support: 1.1.3 + console-control-strings: 1.1.0 + has-unicode: 2.0.1 + signal-exit: 3.0.7 + string-width: 4.2.3 + strip-ansi: 6.0.1 + wide-align: 1.1.5 + + generator-function@2.0.1: {} + + gensync@1.0.0-beta.2: {} + + get-caller-file@2.0.5: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.3 + math-intrinsics: 1.1.0 + + get-package-type@0.1.0: {} + + get-pkg-repo@4.2.1: + dependencies: + '@hutson/parse-repository-url': 3.0.2 + hosted-git-info: 4.1.0 + through2: 2.0.5 + yargs: 16.2.0 + + get-port@5.1.1: {} + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + get-stdin@4.0.1: + optional: true + + get-stream@4.1.0: + dependencies: + pump: 3.0.4 + + get-stream@6.0.0: {} + + get-stream@6.0.1: {} + + get-symbol-description@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + + get-tsconfig@4.14.0: + dependencies: + resolve-pkg-maps: 1.0.0 + + get-value@2.0.6: {} + + git-raw-commits@3.0.0: + dependencies: + dargs: 7.0.0 + meow: 8.1.2 + split2: 3.2.2 + + git-remote-origin-url@2.0.0: + dependencies: + gitconfiglocal: 1.0.0 + pify: 2.3.0 + + git-semver-tags@5.0.1: + dependencies: + meow: 8.1.2 + semver: 7.8.0 + + git-up@7.0.0: + dependencies: + is-ssh: 1.4.1 + parse-url: 8.1.0 + + git-url-parse@13.1.0: + dependencies: + git-up: 7.0.0 + + gitconfiglocal@1.0.0: + dependencies: + ini: 1.3.8 + + github-slugger@1.5.0: {} + + glob-parent@3.1.0: + dependencies: + is-glob: 3.1.0 + path-dirname: 1.0.2 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob-promise@3.4.0(glob@7.2.3): + dependencies: + '@types/glob': 9.0.0 + glob: 7.2.3 + + glob-to-regexp@0.3.0: {} + + glob-to-regexp@0.4.1: {} + + glob@10.5.0: + dependencies: + foreground-child: 3.3.1 + jackspeak: 3.4.3 + minimatch: 9.0.9 + minipass: 7.1.3 + package-json-from-dist: 1.0.1 + path-scurry: 1.11.1 + + glob@7.1.4: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.5 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@7.2.3: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 3.1.5 + once: 1.4.0 + path-is-absolute: 1.0.1 + + glob@8.1.0: + dependencies: + fs.realpath: 1.0.0 + inflight: 1.0.6 + inherits: 2.0.4 + minimatch: 5.1.9 + once: 1.4.0 + + glob@9.3.5: + dependencies: + fs.realpath: 1.0.0 + minimatch: 8.0.7 + minipass: 4.2.8 + path-scurry: 1.11.1 + + global@4.4.0: + dependencies: + min-document: 2.19.2 + process: 0.11.10 + + globals@13.24.0: + dependencies: + type-fest: 0.20.2 + + globals@14.0.0: {} + + globalthis@1.0.4: + dependencies: + define-properties: 1.2.1 + gopd: 1.2.0 + + globby@11.1.0: + dependencies: + array-union: 2.1.0 + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 3.0.0 + + globby@13.2.2: + dependencies: + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 4.0.0 + + globby@6.1.0: + dependencies: + array-union: 1.0.2 + glob: 7.2.3 + object-assign: 4.1.1 + pify: 2.3.0 + pinkie-promise: 2.0.1 + + globby@9.2.0: + dependencies: + '@types/glob': 7.2.0 + array-union: 1.0.2 + dir-glob: 2.2.2 + fast-glob: 2.2.7 + glob: 7.2.3 + ignore: 4.0.6 + pify: 4.0.1 + slash: 2.0.0 + transitivePeerDependencies: + - supports-color + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + graphemer@1.4.0: {} + + h3@1.15.11: + dependencies: + cookie-es: 1.2.3 + crossws: 0.3.5 + defu: 6.1.7 + destr: 2.0.5 + iron-webcrypto: 1.2.1 + node-mock-http: 1.0.4 + radix3: 1.1.2 + ufo: 1.6.4 + uncrypto: 0.1.3 + + handle-thing@2.0.1: {} + + handlebars@4.7.9: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.19.3 + + hard-rejection@2.1.0: {} + + has-bigints@1.1.0: {} + + has-flag@3.0.0: {} + + has-flag@4.0.0: {} + + has-glob@1.0.0: + dependencies: + is-glob: 3.1.0 + + has-property-descriptors@1.0.2: + dependencies: + es-define-property: 1.0.1 + + has-proto@1.2.0: + dependencies: + dunder-proto: 1.0.1 + + has-symbols@1.1.0: {} + + has-tostringtag@1.0.2: + dependencies: + has-symbols: 1.1.0 + + has-unicode@2.0.1: {} + + has-value@0.3.1: + dependencies: + get-value: 2.0.6 + has-values: 0.1.4 + isobject: 2.1.0 + + has-value@1.0.0: + dependencies: + get-value: 2.0.6 + has-values: 1.0.0 + isobject: 3.0.1 + + has-values@0.1.4: {} + + has-values@1.0.0: + dependencies: + is-number: 3.0.0 + kind-of: 4.0.0 + + hash-base@3.0.5: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + + hash-base@3.1.2: + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + safe-buffer: 5.2.1 + to-buffer: 1.2.2 + + hash-wasm@4.12.0: {} + + hash.js@1.1.7: + dependencies: + inherits: 2.0.4 + minimalistic-assert: 1.0.1 + + hasown@2.0.3: + dependencies: + function-bind: 1.1.2 + + hast-to-hyperscript@9.0.1: + dependencies: + '@types/unist': 2.0.11 + comma-separated-tokens: 1.0.8 + property-information: 5.6.0 + space-separated-tokens: 1.1.5 + style-to-object: 0.3.0 + unist-util-is: 4.1.0 + web-namespaces: 1.1.4 + + hast-util-from-parse5@6.0.1: + dependencies: + '@types/parse5': 5.0.3 + hastscript: 6.0.0 + property-information: 5.6.0 + vfile: 4.2.1 + vfile-location: 3.2.0 + web-namespaces: 1.1.4 + + hast-util-parse-selector@2.2.5: {} + + hast-util-raw@6.0.1: + dependencies: + '@types/hast': 2.3.10 + hast-util-from-parse5: 6.0.1 + hast-util-to-parse5: 6.0.0 + html-void-elements: 1.0.5 + parse5: 6.0.1 + unist-util-position: 3.1.0 + vfile: 4.2.1 + web-namespaces: 1.1.4 + xtend: 4.0.2 + zwitch: 1.0.5 + + hast-util-to-jsx-runtime@2.3.6: + dependencies: + '@types/estree': 1.0.9 + '@types/hast': 3.0.4 + '@types/unist': 3.0.3 + comma-separated-tokens: 2.0.3 + devlop: 1.1.0 + estree-util-is-identifier-name: 3.0.0 + hast-util-whitespace: 3.0.0 + mdast-util-mdx-expression: 2.0.1 + mdast-util-mdx-jsx: 3.2.0 + mdast-util-mdxjs-esm: 2.0.1 + property-information: 7.1.0 + space-separated-tokens: 2.0.2 + style-to-js: 1.1.21 + unist-util-position: 5.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + hast-util-to-parse5@6.0.0: + dependencies: + hast-to-hyperscript: 9.0.1 + property-information: 5.6.0 + web-namespaces: 1.1.4 + xtend: 4.0.2 + zwitch: 1.0.5 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.4 + + hastscript@6.0.0: + dependencies: + '@types/hast': 2.3.10 + comma-separated-tokens: 1.0.8 + hast-util-parse-selector: 2.2.5 + property-information: 5.6.0 + space-separated-tokens: 1.1.5 + + he@1.2.0: {} + + hex-rgb@4.3.0: {} + + highlight-words@2.0.0: {} + + hmac-drbg@1.0.1: + dependencies: + hash.js: 1.1.7 + minimalistic-assert: 1.0.1 + minimalistic-crypto-utils: 1.0.1 + + hoist-non-react-statics@3.3.2: + dependencies: + react-is: 16.13.1 + + hosted-git-info@2.8.9: {} + + hosted-git-info@3.0.8: + dependencies: + lru-cache: 6.0.0 + + hosted-git-info@4.1.0: + dependencies: + lru-cache: 6.0.0 + + hosted-git-info@6.1.3: + dependencies: + lru-cache: 7.18.3 + + hpack.js@2.1.6: + dependencies: + inherits: 2.0.4 + obuf: 1.1.2 + readable-stream: 2.3.8 + wbuf: 1.7.3 + + html-encoding-sniffer@2.0.1: + dependencies: + whatwg-encoding: 1.0.5 + + html-encoding-sniffer@6.0.0(@noble/hashes@1.8.0): + dependencies: + '@exodus/bytes': 1.15.0(@noble/hashes@1.8.0) + transitivePeerDependencies: + - '@noble/hashes' + + html-entities@2.6.0: {} + + html-escaper@2.0.2: {} + + html-minifier-terser@5.1.1: + dependencies: + camel-case: 4.1.2 + clean-css: 4.2.4 + commander: 4.1.1 + he: 1.2.0 + param-case: 3.0.4 + relateurl: 0.2.7 + terser: 4.8.1 + + html-minifier-terser@6.1.0: + dependencies: + camel-case: 4.1.2 + clean-css: 5.3.3 + commander: 8.3.0 + he: 1.2.0 + param-case: 3.0.4 + relateurl: 0.2.7 + terser: 5.47.1 + + html-parse-stringify@3.0.1: + dependencies: + void-elements: 3.1.0 + + html-tags@3.3.1: {} + + html-url-attributes@3.0.1: {} + + html-void-elements@1.0.5: {} + + html-webpack-plugin@4.5.2(webpack@4.47.0): + dependencies: + '@types/html-minifier-terser': 5.1.2 + '@types/tapable': 1.0.12 + '@types/webpack': 4.41.40 + html-minifier-terser: 5.1.1 + loader-utils: 1.4.2 + lodash: 4.18.1 + pretty-error: 2.1.2 + tapable: 1.1.3 + util.promisify: 1.0.0 + webpack: 4.47.0 + + html-webpack-plugin@5.6.7(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)): + dependencies: + '@types/html-minifier-terser': 6.1.0 + html-minifier-terser: 6.1.0 + lodash: 4.18.1 + pretty-error: 4.0.0 + tapable: 2.3.3 + optionalDependencies: + webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + + html-webpack-plugin@5.6.7(webpack@5.106.2): + dependencies: + '@types/html-minifier-terser': 6.1.0 + html-minifier-terser: 6.1.0 + lodash: 4.18.1 + pretty-error: 4.0.0 + tapable: 2.3.3 + optionalDependencies: + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + + htmlparser2@6.1.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 4.3.1 + domutils: 2.8.0 + entities: 2.2.0 + + http-cache-semantics@4.2.0: {} + + http-deceiver@1.2.7: {} + + http-errors@1.8.1: + dependencies: + depd: 1.1.2 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 1.5.0 + toidentifier: 1.0.1 + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + http-parser-js@0.5.10: {} + + http-proxy-agent@4.0.1: + dependencies: + '@tootallnate/once': 1.1.2 + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + http-proxy-agent@5.0.0: + dependencies: + '@tootallnate/once': 2.0.1 + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + http-proxy-middleware@2.0.9(@types/express@4.17.25): + dependencies: + '@types/http-proxy': 1.17.17 + http-proxy: 1.18.1 + is-glob: 4.0.3 + is-plain-obj: 3.0.0 + micromatch: 4.0.8 + optionalDependencies: + '@types/express': 4.17.25 + transitivePeerDependencies: + - debug + + http-proxy@1.18.1: + dependencies: + eventemitter3: 4.0.7 + follow-redirects: 1.16.0 + requires-port: 1.0.0 + transitivePeerDependencies: + - debug + + https-browserify@1.0.0: {} + + https-proxy-agent@5.0.1: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + human-signals@2.1.0: {} + + humanize-ms@1.2.1: + dependencies: + ms: 2.1.3 + + hyphenate-style-name@1.1.0: {} + + i18next-resources-to-backend@1.2.1: + dependencies: + '@babel/runtime': 7.29.2 + + i18next@24.2.3(typescript@5.9.3): + dependencies: + '@babel/runtime': 7.29.2 + optionalDependencies: + typescript: 5.9.3 + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + iconv-lite@0.6.3: + dependencies: + safer-buffer: 2.1.2 + optional: true + + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + + icss-utils@4.1.1: + dependencies: + postcss: 7.0.39 + + icss-utils@5.1.0(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + + idb-keyval@6.2.2: {} + + ieee754@1.2.1: {} + + iferr@0.1.5: {} + + ignore-walk@5.0.1: + dependencies: + minimatch: 5.1.9 + + ignore-walk@6.0.5: + dependencies: + minimatch: 9.0.9 + + ignore@4.0.6: {} + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + immediate@3.0.6: {} + + immer@10.2.0: {} + + import-fresh@3.3.1: + dependencies: + parent-module: 1.0.1 + resolve-from: 4.0.0 + + import-local@3.1.0: + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + + import-local@3.2.0: + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + + imurmurhash@0.1.4: {} + + indent-string@2.1.0: + dependencies: + repeating: 2.0.1 + optional: true + + indent-string@4.0.0: {} + + infer-owner@1.0.4: {} + + inflight@1.0.6: + dependencies: + once: 1.4.0 + wrappy: 1.0.2 + + inherits@2.0.3: {} + + inherits@2.0.4: {} + + ini@1.3.8: {} + + init-package-json@5.0.0: + dependencies: + npm-package-arg: 10.1.0 + promzard: 1.0.2 + read: 2.1.0 + read-package-json: 6.0.4 + semver: 7.8.0 + validate-npm-package-license: 3.0.4 + validate-npm-package-name: 5.0.0 + + inline-style-parser@0.1.1: {} + + inline-style-parser@0.2.7: {} + + inquirer@8.2.7(@types/node@22.19.19): + dependencies: + '@inquirer/external-editor': 1.0.3(@types/node@22.19.19) + ansi-escapes: 4.3.2 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-width: 3.0.0 + figures: 3.2.0 + lodash: 4.18.1 + mute-stream: 0.0.8 + ora: 5.4.1 + run-async: 2.4.1 + rxjs: 7.8.2 + string-width: 4.2.3 + strip-ansi: 6.0.1 + through: 2.3.8 + wrap-ansi: 6.2.0 + transitivePeerDependencies: + - '@types/node' + + internal-slot@1.1.0: + dependencies: + es-errors: 1.3.0 + hasown: 2.0.3 + side-channel: 1.1.0 + + internmap@1.0.1: {} + + internmap@2.0.3: {} + + interpret@2.2.0: {} + + interpret@3.1.1: {} + + ip-address@10.2.0: {} + + ip@2.0.1: {} + + ipaddr.js@1.9.1: {} + + ipaddr.js@2.4.0: {} + + iron-webcrypto@1.2.1: {} + + is-absolute-url@3.0.3: {} + + is-accessor-descriptor@1.0.2: + dependencies: + hasown: 2.0.3 + + is-alphabetical@1.0.4: {} + + is-alphabetical@2.0.1: {} + + is-alphanumerical@1.0.4: + dependencies: + is-alphabetical: 1.0.4 + is-decimal: 1.0.4 + + is-alphanumerical@2.0.1: + dependencies: + is-alphabetical: 2.0.1 + is-decimal: 2.0.1 + + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-array-buffer@3.0.5: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-arrayish@0.2.1: {} + + is-arrayish@0.3.4: {} + + is-async-function@2.1.1: + dependencies: + async-function: 1.0.0 + call-bound: 1.0.4 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-bigint@1.1.0: + dependencies: + has-bigints: 1.1.0 + + is-binary-path@1.0.1: + dependencies: + binary-extensions: 1.13.1 + optional: true + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-boolean-object@1.2.2: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-buffer@1.1.6: {} + + is-buffer@2.0.5: {} + + is-bun-module@2.0.0: + dependencies: + semver: 7.8.0 + + is-callable@1.2.7: {} + + is-ci@2.0.0: + dependencies: + ci-info: 2.0.0 + + is-ci@3.0.1: + dependencies: + ci-info: 3.9.0 + + is-core-module@2.16.2: + dependencies: + hasown: 2.0.3 + + is-data-descriptor@1.0.1: + dependencies: + hasown: 2.0.3 + + is-data-view@1.0.2: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + is-typed-array: 1.1.15 + + is-date-object@1.1.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-decimal@1.0.4: {} + + is-decimal@2.0.1: {} + + is-descriptor@0.1.8: + dependencies: + is-accessor-descriptor: 1.0.2 + is-data-descriptor: 1.0.1 + + is-descriptor@1.0.4: + dependencies: + is-accessor-descriptor: 1.0.2 + is-data-descriptor: 1.0.1 + + is-docker@2.2.1: {} + + is-dom@1.1.0: + dependencies: + is-object: 1.0.2 + is-window: 1.0.2 + + is-extendable@0.1.1: {} + + is-extendable@1.0.1: + dependencies: + is-plain-object: 2.0.4 + + is-extglob@2.1.1: {} + + is-finalizationregistry@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-finite@1.1.0: + optional: true + + is-fullwidth-code-point@3.0.0: {} + + is-function@1.0.2: {} + + is-generator-fn@2.1.0: {} + + is-generator-function@1.1.2: + dependencies: + call-bound: 1.0.4 + generator-function: 2.0.1 + get-proto: 1.0.1 + has-tostringtag: 1.0.2 + safe-regex-test: 1.1.0 + + is-glob@3.1.0: + dependencies: + is-extglob: 2.1.1 + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-hexadecimal@1.0.4: {} + + is-hexadecimal@2.0.1: {} + + is-in-browser@1.1.3: {} + + is-interactive@1.0.0: {} + + is-lambda@1.0.1: {} + + is-map@2.0.3: {} + + is-negative-zero@2.0.3: {} + + is-number-object@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-number@3.0.0: + dependencies: + kind-of: 3.2.2 + + is-number@7.0.0: {} + + is-obj@2.0.0: {} + + is-object@1.0.2: {} + + is-path-cwd@2.2.0: {} + + is-path-in-cwd@2.1.0: + dependencies: + is-path-inside: 2.1.0 + + is-path-inside@2.1.0: + dependencies: + path-is-inside: 1.0.2 + + is-path-inside@3.0.3: {} + + is-plain-obj@1.1.0: {} + + is-plain-obj@2.1.0: {} + + is-plain-obj@3.0.0: {} + + is-plain-obj@4.1.0: {} + + is-plain-object@2.0.4: + dependencies: + isobject: 3.0.1 + + is-plain-object@5.0.0: {} + + is-potential-custom-element-name@1.0.1: {} + + is-regex@1.2.1: + dependencies: + call-bound: 1.0.4 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + hasown: 2.0.3 + + is-set@2.0.3: {} + + is-shared-array-buffer@1.0.4: + dependencies: + call-bound: 1.0.4 + + is-ssh@1.4.1: + dependencies: + protocols: 2.0.2 + + is-stream@1.1.0: {} + + is-stream@2.0.0: {} + + is-stream@2.0.1: {} + + is-string@1.1.1: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + + is-symbol@1.1.1: + dependencies: + call-bound: 1.0.4 + has-symbols: 1.1.0 + safe-regex-test: 1.1.0 + + is-text-path@1.0.1: + dependencies: + text-extensions: 1.9.0 + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.20 + + is-typedarray@1.0.0: {} + + is-unicode-supported@0.1.0: {} + + is-utf8@0.2.1: + optional: true + + is-weakmap@2.0.2: {} + + is-weakref@1.1.1: + dependencies: + call-bound: 1.0.4 + + is-weakset@2.0.4: + dependencies: + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + + is-whitespace-character@1.0.4: {} + + is-window@1.0.2: {} + + is-windows@1.0.2: {} + + is-word-character@1.0.4: {} + + is-wsl@1.1.0: {} + + is-wsl@2.2.0: + dependencies: + is-docker: 2.2.1 + + isarray@1.0.0: {} + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + isobject@2.1.0: + dependencies: + isarray: 1.0.0 + + isobject@3.0.1: {} + + isobject@4.0.0: {} + + isomorphic-dompurify@2.36.0(@noble/hashes@1.8.0): + dependencies: + dompurify: 3.4.3 + jsdom: 28.1.0(@noble/hashes@1.8.0) + transitivePeerDependencies: + - '@noble/hashes' + - canvas + - supports-color + + isomorphic-unfetch@3.1.0(encoding@0.1.13): + dependencies: + node-fetch: 2.7.0(encoding@0.1.13) + unfetch: 4.2.0 + transitivePeerDependencies: + - encoding + + isomorphic-ws@4.0.1(ws@7.5.10): + dependencies: + ws: 7.5.10 + + istanbul-lib-coverage@3.2.2: {} + + istanbul-lib-instrument@5.2.1: + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.3 + '@istanbuljs/schema': 0.1.6 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + + istanbul-lib-instrument@6.0.3: + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.3 + '@istanbuljs/schema': 0.1.6 + istanbul-lib-coverage: 3.2.2 + semver: 7.8.0 + transitivePeerDependencies: + - supports-color + + istanbul-lib-report@3.0.1: + dependencies: + istanbul-lib-coverage: 3.2.2 + make-dir: 4.0.0 + supports-color: 7.2.0 + + istanbul-lib-source-maps@4.0.1: + dependencies: + debug: 4.4.3 + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + + istanbul-reports@3.2.0: + dependencies: + html-escaper: 2.0.2 + istanbul-lib-report: 3.0.1 + + iterate-iterator@1.0.2: {} + + iterate-value@1.0.2: + dependencies: + es-get-iterator: 1.1.3 + iterate-iterator: 1.0.2 + + iterator.prototype@1.1.5: + dependencies: + define-data-property: 1.1.4 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + has-symbols: 1.1.0 + set-function-name: 2.0.2 + + jackspeak@3.4.3: + dependencies: + '@isaacs/cliui': 8.0.2 + optionalDependencies: + '@pkgjs/parseargs': 0.11.0 + + jake@10.9.4: + dependencies: + async: 3.2.6 + filelist: 1.0.6 + picocolors: 1.1.1 + + jest-changed-files@27.5.1: + dependencies: + '@jest/types': 27.5.1 + execa: 5.1.1 + throat: 6.0.2 + + jest-changed-files@29.7.0: + dependencies: + execa: 5.1.1 + jest-util: 29.7.0 + p-limit: 3.1.0 + + jest-circus@27.5.1: + dependencies: + '@jest/environment': 27.5.1 + '@jest/test-result': 27.5.1 + '@jest/types': 27.5.1 + '@types/node': 22.19.19 + chalk: 4.1.2 + co: 4.6.0 + dedent: 0.7.0 + expect: 27.5.1 + is-generator-fn: 2.1.0 + jest-each: 27.5.1 + jest-matcher-utils: 27.5.1 + jest-message-util: 27.5.1 + jest-runtime: 27.5.1 + jest-snapshot: 27.5.1 + jest-util: 27.5.1 + pretty-format: 27.5.1 + slash: 3.0.0 + stack-utils: 2.0.6 + throat: 6.0.2 + transitivePeerDependencies: + - supports-color + + jest-circus@29.7.0(babel-plugin-macros@3.1.0): + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.19.19 + chalk: 4.1.2 + co: 4.6.0 + dedent: 1.7.2(babel-plugin-macros@3.1.0) + is-generator-fn: 2.1.0 + jest-each: 29.7.0 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + p-limit: 3.1.0 + pretty-format: 29.7.0 + pure-rand: 6.1.0 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-cli@27.5.1: + dependencies: + '@jest/core': 27.5.1 + '@jest/test-result': 27.5.1 + '@jest/types': 27.5.1 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + import-local: 3.2.0 + jest-config: 27.5.1 + jest-util: 27.5.1 + jest-validate: 27.5.1 + prompts: 2.4.2 + yargs: 16.2.0 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - ts-node + - utf-8-validate + + jest-cli@29.7.0(@types/node@22.19.19)(babel-plugin-macros@3.1.0): + dependencies: + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@22.19.19)(babel-plugin-macros@3.1.0) + exit: 0.1.2 + import-local: 3.2.0 + jest-config: 29.7.0(@types/node@22.19.19)(babel-plugin-macros@3.1.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + jest-config@27.5.1: + dependencies: + '@babel/core': 7.29.0 + '@jest/test-sequencer': 27.5.1 + '@jest/types': 27.5.1 + babel-jest: 27.5.1(@babel/core@7.29.0) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 27.5.1 + jest-environment-jsdom: 27.5.1 + jest-environment-node: 27.5.1 + jest-get-type: 27.5.1 + jest-jasmine2: 27.5.1 + jest-regex-util: 27.5.1 + jest-resolve: 27.5.1 + jest-runner: 27.5.1 + jest-util: 27.5.1 + jest-validate: 27.5.1 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 27.5.1 + slash: 3.0.0 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - utf-8-validate + + jest-config@29.7.0(@types/node@22.19.19)(babel-plugin-macros@3.1.0): + dependencies: + '@babel/core': 7.29.0 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.29.0) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0(babel-plugin-macros@3.1.0) + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 22.19.19 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + + jest-diff@27.5.1: + dependencies: + chalk: 4.1.2 + diff-sequences: 27.5.1 + jest-get-type: 27.5.1 + pretty-format: 27.5.1 + + jest-diff@29.7.0: + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-docblock@27.5.1: + dependencies: + detect-newline: 3.1.0 + + jest-docblock@29.7.0: + dependencies: + detect-newline: 3.1.0 + + jest-each@27.5.1: + dependencies: + '@jest/types': 27.5.1 + chalk: 4.1.2 + jest-get-type: 27.5.1 + jest-util: 27.5.1 + pretty-format: 27.5.1 + + jest-each@29.7.0: + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + jest-get-type: 29.6.3 + jest-util: 29.7.0 + pretty-format: 29.7.0 + + jest-environment-jsdom@27.5.1: + dependencies: + '@jest/environment': 27.5.1 + '@jest/fake-timers': 27.5.1 + '@jest/types': 27.5.1 + '@types/node': 22.19.19 + jest-mock: 27.5.1 + jest-util: 27.5.1 + jsdom: 16.7.0 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - utf-8-validate + + jest-environment-node@27.5.1: + dependencies: + '@jest/environment': 27.5.1 + '@jest/fake-timers': 27.5.1 + '@jest/types': 27.5.1 + '@types/node': 22.19.19 + jest-mock: 27.5.1 + jest-util: 27.5.1 + + jest-environment-node@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.19.19 + jest-mock: 29.7.0 + jest-util: 29.7.0 + + jest-get-type@27.5.1: {} + + jest-get-type@29.6.3: {} + + jest-haste-map@26.6.2: + dependencies: + '@jest/types': 26.6.2 + '@types/graceful-fs': 4.1.9 + '@types/node': 22.19.19 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 26.0.0 + jest-serializer: 26.6.2 + jest-util: 26.6.2 + jest-worker: 26.6.2 + micromatch: 4.0.8 + sane: 4.1.0 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + transitivePeerDependencies: + - supports-color + + jest-haste-map@27.5.1: + dependencies: + '@jest/types': 27.5.1 + '@types/graceful-fs': 4.1.9 + '@types/node': 22.19.19 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 27.5.1 + jest-serializer: 27.5.1 + jest-util: 27.5.1 + jest-worker: 27.5.1 + micromatch: 4.0.8 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + + jest-haste-map@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 22.19.19 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + jest-worker: 29.7.0 + micromatch: 4.0.8 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + + jest-jasmine2@27.5.1: + dependencies: + '@jest/environment': 27.5.1 + '@jest/source-map': 27.5.1 + '@jest/test-result': 27.5.1 + '@jest/types': 27.5.1 + '@types/node': 22.19.19 + chalk: 4.1.2 + co: 4.6.0 + expect: 27.5.1 + is-generator-fn: 2.1.0 + jest-each: 27.5.1 + jest-matcher-utils: 27.5.1 + jest-message-util: 27.5.1 + jest-runtime: 27.5.1 + jest-snapshot: 27.5.1 + jest-util: 27.5.1 + pretty-format: 27.5.1 + throat: 6.0.2 + transitivePeerDependencies: + - supports-color + + jest-leak-detector@27.5.1: + dependencies: + jest-get-type: 27.5.1 + pretty-format: 27.5.1 + + jest-leak-detector@29.7.0: + dependencies: + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-matcher-utils@27.5.1: + dependencies: + chalk: 4.1.2 + jest-diff: 27.5.1 + jest-get-type: 27.5.1 + pretty-format: 27.5.1 + + jest-matcher-utils@29.7.0: + dependencies: + chalk: 4.1.2 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + + jest-message-util@27.5.1: + dependencies: + '@babel/code-frame': 7.29.0 + '@jest/types': 27.5.1 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + pretty-format: 27.5.1 + slash: 3.0.0 + stack-utils: 2.0.6 + + jest-message-util@29.7.0: + dependencies: + '@babel/code-frame': 7.29.0 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + stack-utils: 2.0.6 + + jest-mock@27.5.1: + dependencies: + '@jest/types': 27.5.1 + '@types/node': 22.19.19 + + jest-mock@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 22.19.19 + jest-util: 29.7.0 + + jest-pnp-resolver@1.2.3(jest-resolve@27.5.1): + optionalDependencies: + jest-resolve: 27.5.1 + + jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): + optionalDependencies: + jest-resolve: 29.7.0 + + jest-regex-util@26.0.0: {} + + jest-regex-util@27.5.1: {} + + jest-regex-util@29.6.3: {} + + jest-resolve-dependencies@27.5.1: + dependencies: + '@jest/types': 27.5.1 + jest-regex-util: 27.5.1 + jest-snapshot: 27.5.1 + transitivePeerDependencies: + - supports-color + + jest-resolve-dependencies@29.7.0: + dependencies: + jest-regex-util: 29.6.3 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + + jest-resolve@27.5.1: + dependencies: + '@jest/types': 27.5.1 + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 27.5.1 + jest-pnp-resolver: 1.2.3(jest-resolve@27.5.1) + jest-util: 27.5.1 + jest-validate: 27.5.1 + resolve: 1.22.12 + resolve.exports: 1.1.1 + slash: 3.0.0 + + jest-resolve@29.7.0: + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + resolve: 1.22.12 + resolve.exports: 2.0.3 + slash: 3.0.0 + + jest-runner@27.5.1: + dependencies: + '@jest/console': 27.5.1 + '@jest/environment': 27.5.1 + '@jest/test-result': 27.5.1 + '@jest/transform': 27.5.1 + '@jest/types': 27.5.1 + '@types/node': 22.19.19 + chalk: 4.1.2 + emittery: 0.8.1 + graceful-fs: 4.2.11 + jest-docblock: 27.5.1 + jest-environment-jsdom: 27.5.1 + jest-environment-node: 27.5.1 + jest-haste-map: 27.5.1 + jest-leak-detector: 27.5.1 + jest-message-util: 27.5.1 + jest-resolve: 27.5.1 + jest-runtime: 27.5.1 + jest-util: 27.5.1 + jest-worker: 27.5.1 + source-map-support: 0.5.21 + throat: 6.0.2 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - utf-8-validate + + jest-runner@29.7.0: + dependencies: + '@jest/console': 29.7.0 + '@jest/environment': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.19.19 + chalk: 4.1.2 + emittery: 0.13.1 + graceful-fs: 4.2.11 + jest-docblock: 29.7.0 + jest-environment-node: 29.7.0 + jest-haste-map: 29.7.0 + jest-leak-detector: 29.7.0 + jest-message-util: 29.7.0 + jest-resolve: 29.7.0 + jest-runtime: 29.7.0 + jest-util: 29.7.0 + jest-watcher: 29.7.0 + jest-worker: 29.7.0 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + + jest-runtime@27.5.1: + dependencies: + '@jest/environment': 27.5.1 + '@jest/fake-timers': 27.5.1 + '@jest/globals': 27.5.1 + '@jest/source-map': 27.5.1 + '@jest/test-result': 27.5.1 + '@jest/transform': 27.5.1 + '@jest/types': 27.5.1 + chalk: 4.1.2 + cjs-module-lexer: 1.4.3 + collect-v8-coverage: 1.0.3 + execa: 5.1.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-haste-map: 27.5.1 + jest-message-util: 27.5.1 + jest-mock: 27.5.1 + jest-regex-util: 27.5.1 + jest-resolve: 27.5.1 + jest-snapshot: 27.5.1 + jest-util: 27.5.1 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + + jest-runtime@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/globals': 29.7.0 + '@jest/source-map': 29.6.3 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.19.19 + chalk: 4.1.2 + cjs-module-lexer: 1.4.3 + collect-v8-coverage: 1.0.3 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + + jest-serializer@26.6.2: + dependencies: + '@types/node': 22.19.19 + graceful-fs: 4.2.11 + + jest-serializer@27.5.1: + dependencies: + '@types/node': 22.19.19 + graceful-fs: 4.2.11 + + jest-snapshot@27.5.1: + dependencies: + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/traverse': 7.29.0 + '@babel/types': 7.29.0 + '@jest/transform': 27.5.1 + '@jest/types': 27.5.1 + '@types/babel__traverse': 7.28.0 + '@types/prettier': 2.7.3 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0) + chalk: 4.1.2 + expect: 27.5.1 + graceful-fs: 4.2.11 + jest-diff: 27.5.1 + jest-get-type: 27.5.1 + jest-haste-map: 27.5.1 + jest-matcher-utils: 27.5.1 + jest-message-util: 27.5.1 + jest-util: 27.5.1 + natural-compare: 1.4.0 + pretty-format: 27.5.1 + semver: 7.8.0 + transitivePeerDependencies: + - supports-color + + jest-snapshot@29.7.0: + dependencies: + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/types': 7.29.0 + '@jest/expect-utils': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0) + chalk: 4.1.2 + expect: 29.7.0 + graceful-fs: 4.2.11 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + natural-compare: 1.4.0 + pretty-format: 29.7.0 + semver: 7.8.0 + transitivePeerDependencies: + - supports-color + + jest-util@26.6.2: + dependencies: + '@jest/types': 26.6.2 + '@types/node': 22.19.19 + chalk: 4.1.2 + graceful-fs: 4.2.11 + is-ci: 2.0.0 + micromatch: 4.0.8 + + jest-util@27.5.1: + dependencies: + '@jest/types': 27.5.1 + '@types/node': 22.19.19 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.2 + + jest-util@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 22.19.19 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.2 + + jest-validate@27.5.1: + dependencies: + '@jest/types': 27.5.1 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 27.5.1 + leven: 3.1.0 + pretty-format: 27.5.1 + + jest-validate@29.7.0: + dependencies: + '@jest/types': 29.6.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.6.3 + leven: 3.1.0 + pretty-format: 29.7.0 + + jest-watcher@27.5.1: + dependencies: + '@jest/test-result': 27.5.1 + '@jest/types': 27.5.1 + '@types/node': 22.19.19 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + jest-util: 27.5.1 + string-length: 4.0.2 + + jest-watcher@29.7.0: + dependencies: + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 22.19.19 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 29.7.0 + string-length: 4.0.2 + + jest-worker@26.6.2: + dependencies: + '@types/node': 22.19.19 + merge-stream: 2.0.0 + supports-color: 7.2.0 + + jest-worker@27.5.1: + dependencies: + '@types/node': 22.19.19 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jest-worker@29.7.0: + dependencies: + '@types/node': 22.19.19 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + jest@27.5.1: + dependencies: + '@jest/core': 27.5.1 + import-local: 3.2.0 + jest-cli: 27.5.1 + transitivePeerDependencies: + - bufferutil + - canvas + - supports-color + - ts-node + - utf-8-validate + + jest@29.7.0(@types/node@22.19.19)(babel-plugin-macros@3.1.0): + dependencies: + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0) + '@jest/types': 29.6.3 + import-local: 3.2.0 + jest-cli: 29.7.0(@types/node@22.19.19)(babel-plugin-macros@3.1.0) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + + joi@17.13.3: + dependencies: + '@hapi/hoek': 9.3.0 + '@hapi/topo': 5.1.0 + '@sideway/address': 4.1.5 + '@sideway/formula': 3.0.1 + '@sideway/pinpoint': 2.0.0 + + js-sha3@0.8.0: {} + + js-string-escape@1.0.1: {} + + js-tokens@4.0.0: {} + + js-yaml@3.14.2: + dependencies: + argparse: 1.0.10 + esprima: 4.0.1 + + js-yaml@4.1.0: + dependencies: + argparse: 2.0.1 + + js-yaml@4.1.1: + dependencies: + argparse: 2.0.1 + + jsdoc-type-pratt-parser@4.8.0: {} + + jsdom@16.7.0: + dependencies: + abab: 2.0.6 + acorn: 8.16.0 + acorn-globals: 6.0.0 + cssom: 0.4.4 + cssstyle: 2.3.0 + data-urls: 2.0.0 + decimal.js: 10.6.0 + domexception: 2.0.1 + escodegen: 2.1.0 + form-data: 3.0.4 + html-encoding-sniffer: 2.0.1 + http-proxy-agent: 4.0.1 + https-proxy-agent: 5.0.1 + is-potential-custom-element-name: 1.0.1 + nwsapi: 2.2.23 + parse5: 6.0.1 + saxes: 5.0.1 + symbol-tree: 3.2.4 + tough-cookie: 4.1.4 + w3c-hr-time: 1.0.2 + w3c-xmlserializer: 2.0.0 + webidl-conversions: 6.1.0 + whatwg-encoding: 1.0.5 + whatwg-mimetype: 2.3.0 + whatwg-url: 8.7.0 + ws: 7.5.10 + xml-name-validator: 3.0.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + jsdom@28.1.0(@noble/hashes@1.8.0): + dependencies: + '@acemir/cssom': 0.9.31 + '@asamuzakjp/dom-selector': 6.8.1 + '@bramus/specificity': 2.4.2 + '@exodus/bytes': 1.15.0(@noble/hashes@1.8.0) + cssstyle: 6.2.0 + data-urls: 7.0.0(@noble/hashes@1.8.0) + decimal.js: 10.6.0 + html-encoding-sniffer: 6.0.0(@noble/hashes@1.8.0) + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + is-potential-custom-element-name: 1.0.1 + parse5: 8.0.1 + saxes: 6.0.0 + symbol-tree: 3.2.4 + tough-cookie: 6.0.1 + undici: 7.25.0 + w3c-xmlserializer: 5.0.0 + webidl-conversions: 8.0.1 + whatwg-mimetype: 5.0.0 + whatwg-url: 16.0.1(@noble/hashes@1.8.0) + xml-name-validator: 5.0.0 + transitivePeerDependencies: + - '@noble/hashes' + - supports-color + + jsesc@3.1.0: {} + + json-buffer@3.0.1: {} + + json-parse-better-errors@1.0.2: {} + + json-parse-even-better-errors@2.3.1: {} + + json-parse-even-better-errors@3.0.2: {} + + json-schema-traverse@0.4.1: {} + + json-schema-traverse@1.0.0: {} + + json-stable-stringify-without-jsonify@1.0.1: {} + + json-stringify-safe@5.0.1: {} + + json5@1.0.2: + dependencies: + minimist: 1.2.8 + + json5@2.2.3: {} + + jsonc-parser@3.2.0: {} + + jsonfile@6.2.1: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + + jsonparse@1.3.1: {} + + jss-plugin-camel-case@10.10.0: + dependencies: + '@babel/runtime': 7.29.2 + hyphenate-style-name: 1.1.0 + jss: 10.10.0 + + jss-plugin-default-unit@10.10.0: + dependencies: + '@babel/runtime': 7.29.2 + jss: 10.10.0 + + jss-plugin-global@10.10.0: + dependencies: + '@babel/runtime': 7.29.2 + jss: 10.10.0 + + jss-plugin-nested@10.10.0: + dependencies: + '@babel/runtime': 7.29.2 + jss: 10.10.0 + tiny-warning: 1.0.3 + + jss-plugin-props-sort@10.10.0: + dependencies: + '@babel/runtime': 7.29.2 + jss: 10.10.0 + + jss-plugin-rule-value-function@10.10.0: + dependencies: + '@babel/runtime': 7.29.2 + jss: 10.10.0 + tiny-warning: 1.0.3 + + jss-plugin-vendor-prefixer@10.10.0: + dependencies: + '@babel/runtime': 7.29.2 + css-vendor: 2.0.8 + jss: 10.10.0 + + jss@10.10.0: + dependencies: + '@babel/runtime': 7.29.2 + csstype: 3.2.3 + is-in-browser: 1.1.3 + tiny-warning: 1.0.3 + + jsx-ast-utils@3.3.5: + dependencies: + array-includes: 3.1.9 + array.prototype.flat: 1.3.3 + object.assign: 4.1.7 + object.values: 1.2.1 + + junk@3.1.0: {} + + keyv@4.5.4: + dependencies: + json-buffer: 3.0.1 + + keyvaluestorage-interface@1.0.0: {} + + kind-of@3.2.2: + dependencies: + is-buffer: 1.1.6 + + kind-of@4.0.0: + dependencies: + is-buffer: 1.1.6 + + kind-of@6.0.3: {} + + kleur@3.0.3: {} + + klona@2.0.6: {} + + language-subtag-registry@0.3.23: {} + + language-tags@1.0.9: + dependencies: + language-subtag-registry: 0.3.23 + + launch-editor@2.13.2: + dependencies: + picocolors: 1.1.1 + shell-quote: 1.8.3 + + lazy-universal-dotenv@3.0.1: + dependencies: + '@babel/runtime': 7.29.2 + app-root-dir: 1.0.2 + core-js: 3.49.0 + dotenv: 8.6.0 + dotenv-expand: 5.1.0 + + lefthook-darwin-arm64@1.13.6: + optional: true + + lefthook-darwin-x64@1.13.6: + optional: true + + lefthook-freebsd-arm64@1.13.6: + optional: true + + lefthook-freebsd-x64@1.13.6: + optional: true + + lefthook-linux-arm64@1.13.6: + optional: true + + lefthook-linux-x64@1.13.6: + optional: true + + lefthook-openbsd-arm64@1.13.6: + optional: true + + lefthook-openbsd-x64@1.13.6: + optional: true + + lefthook-windows-arm64@1.13.6: + optional: true + + lefthook-windows-x64@1.13.6: + optional: true + + lefthook@1.13.6: + optionalDependencies: + lefthook-darwin-arm64: 1.13.6 + lefthook-darwin-x64: 1.13.6 + lefthook-freebsd-arm64: 1.13.6 + lefthook-freebsd-x64: 1.13.6 + lefthook-linux-arm64: 1.13.6 + lefthook-linux-x64: 1.13.6 + lefthook-openbsd-arm64: 1.13.6 + lefthook-openbsd-x64: 1.13.6 + lefthook-windows-arm64: 1.13.6 + lefthook-windows-x64: 1.13.6 + + lerna@7.4.2(@types/node@22.19.19)(encoding@0.1.13): + dependencies: + '@lerna/child-process': 7.4.2 + '@lerna/create': 7.4.2(@types/node@22.19.19)(encoding@0.1.13)(typescript@5.9.3) + '@npmcli/run-script': 6.0.2 + '@nx/devkit': 16.10.0(nx@16.10.0) + '@octokit/plugin-enterprise-rest': 6.0.1 + '@octokit/rest': 19.0.11(encoding@0.1.13) + byte-size: 8.1.1 + chalk: 4.1.0 + clone-deep: 4.0.1 + cmd-shim: 6.0.1 + columnify: 1.6.0 + conventional-changelog-angular: 7.0.0 + conventional-changelog-core: 5.0.1 + conventional-recommended-bump: 7.0.1 + cosmiconfig: 8.3.6(typescript@5.9.3) + dedent: 0.7.0 + envinfo: 7.8.1 + execa: 5.0.0 + fs-extra: 11.3.5 + get-port: 5.1.1 + get-stream: 6.0.0 + git-url-parse: 13.1.0 + glob-parent: 5.1.2 + globby: 11.1.0 + graceful-fs: 4.2.11 + has-unicode: 2.0.1 + import-local: 3.1.0 + ini: 1.3.8 + init-package-json: 5.0.0 + inquirer: 8.2.7(@types/node@22.19.19) + is-ci: 3.0.1 + is-stream: 2.0.0 + jest-diff: 29.7.0 + js-yaml: 4.1.0 + libnpmaccess: 7.0.2 + libnpmpublish: 7.3.0 + load-json-file: 6.2.0 + lodash: 4.18.1 + make-dir: 4.0.0 + minimatch: 3.0.5 + multimatch: 5.0.0 + node-fetch: 2.6.7(encoding@0.1.13) + npm-package-arg: 8.1.1 + npm-packlist: 5.1.1 + npm-registry-fetch: 14.0.5 + npmlog: 6.0.2 + nx: 16.10.0 + p-map: 4.0.0 + p-map-series: 2.1.0 + p-pipe: 3.1.0 + p-queue: 6.6.2 + p-reduce: 2.1.0 + p-waterfall: 2.1.1 + pacote: 15.2.0 + pify: 5.0.0 + read-cmd-shim: 4.0.0 + read-package-json: 6.0.4 + resolve-from: 5.0.0 + rimraf: 4.4.1 + semver: 7.8.0 + signal-exit: 3.0.7 + slash: 3.0.0 + ssri: 9.0.1 + strong-log-transformer: 2.1.0 + tar: 6.1.11 + temp-dir: 1.0.0 + typescript: 5.9.3 + upath: 2.0.1 + uuid: 9.0.1 + validate-npm-package-license: 3.0.4 + validate-npm-package-name: 5.0.0 + write-file-atomic: 5.0.1 + write-pkg: 4.0.0 + yargs: 16.2.0 + yargs-parser: 20.2.4 + transitivePeerDependencies: + - '@swc-node/register' + - '@swc/core' + - '@types/node' + - bluebird + - debug + - encoding + - supports-color + + leven@3.1.0: {} + + levn@0.4.1: + dependencies: + prelude-ls: 1.2.1 + type-check: 0.4.0 + + libnpmaccess@7.0.2: + dependencies: + npm-package-arg: 10.1.0 + npm-registry-fetch: 14.0.5 + transitivePeerDependencies: + - supports-color + + libnpmpublish@7.3.0: + dependencies: + ci-info: 3.9.0 + normalize-package-data: 5.0.0 + npm-package-arg: 10.1.0 + npm-registry-fetch: 14.0.5 + proc-log: 3.0.0 + semver: 7.8.0 + sigstore: 1.9.0 + ssri: 10.0.6 + transitivePeerDependencies: + - supports-color + + libsodium-sumo@0.7.16: {} + + libsodium-wrappers-sumo@0.7.16: + dependencies: + libsodium-sumo: 0.7.16 + + libsodium-wrappers@0.7.16: + dependencies: + libsodium: 0.7.16 + + libsodium@0.7.16: {} + + lie@3.1.1: + dependencies: + immediate: 3.0.6 + + lilconfig@2.1.0: {} + + lilconfig@3.1.3: {} + + lines-and-columns@1.2.4: {} + + lines-and-columns@2.0.4: {} + + load-json-file@1.1.0: + dependencies: + graceful-fs: 4.2.11 + parse-json: 2.2.0 + pify: 2.3.0 + pinkie-promise: 2.0.1 + strip-bom: 2.0.0 + optional: true + + load-json-file@4.0.0: + dependencies: + graceful-fs: 4.2.11 + parse-json: 4.0.0 + pify: 3.0.0 + strip-bom: 3.0.0 + + load-json-file@6.2.0: + dependencies: + graceful-fs: 4.2.11 + parse-json: 5.2.0 + strip-bom: 4.0.0 + type-fest: 0.6.0 + + loader-runner@2.4.0: {} + + loader-runner@4.3.2: {} + + loader-utils@1.4.2: + dependencies: + big.js: 5.2.2 + emojis-list: 3.0.0 + json5: 1.0.2 + + loader-utils@2.0.4: + dependencies: + big.js: 5.2.2 + emojis-list: 3.0.0 + json5: 2.2.3 + + localforage@1.10.0: + dependencies: + lie: 3.1.1 + + locate-path@2.0.0: + dependencies: + p-locate: 2.0.0 + path-exists: 3.0.0 + + locate-path@3.0.0: + dependencies: + p-locate: 3.0.0 + path-exists: 3.0.0 + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + locate-path@6.0.0: + dependencies: + p-locate: 5.0.0 + + locate-path@7.2.0: + dependencies: + p-locate: 6.0.0 + + lodash-es@4.18.1: {} + + lodash.debounce@4.0.8: {} + + lodash.ismatch@4.4.0: {} + + lodash.memoize@4.1.2: {} + + lodash.merge@4.6.2: {} + + lodash.padend@4.6.1: {} + + lodash.trimstart@4.5.1: {} + + lodash.uniq@4.5.0: {} + + lodash.words@4.2.0: {} + + lodash@4.18.1: {} + + log-symbols@4.1.0: + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + + long@4.0.0: {} + + longest-streak@3.1.0: {} + + loose-envify@1.4.0: + dependencies: + js-tokens: 4.0.0 + + lossless-json@4.3.0: {} + + loud-rejection@1.6.0: + dependencies: + currently-unhandled: 0.4.1 + signal-exit: 3.0.7 + optional: true + + loupe@3.2.1: {} + + lower-case@2.0.2: + dependencies: + tslib: 2.8.1 + + lru-cache@10.4.3: {} + + lru-cache@11.3.6: {} + + lru-cache@5.1.1: + dependencies: + yallist: 3.1.1 + + lru-cache@6.0.0: + dependencies: + yallist: 4.0.0 + + lru-cache@7.18.3: {} + + lucide-react@0.453.0(react@19.2.6): + dependencies: + react: 19.2.6 + + lz-string@1.5.0: {} + + make-dir@2.1.0: + dependencies: + pify: 4.0.1 + semver: 5.7.2 + + make-dir@3.1.0: + dependencies: + semver: 6.3.1 + + make-dir@4.0.0: + dependencies: + semver: 7.8.0 + + make-error@1.3.6: {} + + make-fetch-happen@10.2.1: + dependencies: + agentkeepalive: 4.6.0 + cacache: 16.1.3 + http-cache-semantics: 4.2.0 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + is-lambda: 1.0.1 + lru-cache: 7.18.3 + minipass: 3.3.6 + minipass-collect: 1.0.2 + minipass-fetch: 2.1.2 + minipass-flush: 1.0.7 + minipass-pipeline: 1.2.4 + negotiator: 0.6.4 + promise-retry: 2.0.1 + socks-proxy-agent: 7.0.0 + ssri: 9.0.1 + transitivePeerDependencies: + - bluebird + - supports-color + + make-fetch-happen@11.1.1: + dependencies: + agentkeepalive: 4.6.0 + cacache: 17.1.4 + http-cache-semantics: 4.2.0 + http-proxy-agent: 5.0.0 + https-proxy-agent: 5.0.1 + is-lambda: 1.0.1 + lru-cache: 7.18.3 + minipass: 5.0.0 + minipass-fetch: 3.0.5 + minipass-flush: 1.0.7 + minipass-pipeline: 1.2.4 + negotiator: 0.6.4 + promise-retry: 2.0.1 + socks-proxy-agent: 7.0.0 + ssri: 10.0.6 + transitivePeerDependencies: + - supports-color + + makeerror@1.0.12: + dependencies: + tmpl: 1.0.5 + + map-age-cleaner@0.1.3: + dependencies: + p-defer: 1.0.0 + + map-cache@0.2.2: {} + + map-obj@1.0.1: {} + + map-obj@4.3.0: {} + + map-or-similar@1.5.0: {} + + map-visit@1.0.0: + dependencies: + object-visit: 1.0.1 + + markdown-escapes@1.0.4: {} + + material-react-table@3.2.1(010425a9628d654b3c54ea7b922081d1): + dependencies: + '@emotion/react': 11.14.0(@types/react@19.2.14)(react@19.2.6) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@mui/icons-material': 5.18.0(@mui/material@6.5.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@mui/material': 6.5.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mui/x-date-pickers': 7.29.4(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@mui/material@6.5.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mui/system@6.5.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(date-fns@4.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@tanstack/match-sorter-utils': 8.19.4 + '@tanstack/react-table': 8.20.6(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@tanstack/react-virtual': 3.11.2(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + highlight-words: 2.0.0 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + + math-intrinsics@1.1.0: {} + + md5.js@1.3.5: + dependencies: + hash-base: 3.1.2 + inherits: 2.0.4 + safe-buffer: 5.2.1 + + mdast-squeeze-paragraphs@4.0.0: + dependencies: + unist-util-remove: 2.1.0 + + mdast-util-definitions@4.0.0: + dependencies: + unist-util-visit: 2.0.3 + + mdast-util-from-markdown@2.0.3: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + mdast-util-to-string: 4.0.0 + micromark: 4.0.2 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-decode-string: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + unist-util-stringify-position: 4.0.0 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-expression@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-mdx-jsx@3.2.0: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + ccount: 2.0.1 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + parse-entities: 4.0.2 + stringify-entities: 4.0.4 + unist-util-stringify-position: 4.0.0 + vfile-message: 4.0.3 + transitivePeerDependencies: + - supports-color + + mdast-util-mdxjs-esm@2.0.1: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + devlop: 1.1.0 + mdast-util-from-markdown: 2.0.3 + mdast-util-to-markdown: 2.1.2 + transitivePeerDependencies: + - supports-color + + mdast-util-phrasing@4.1.0: + dependencies: + '@types/mdast': 4.0.4 + unist-util-is: 6.0.1 + + mdast-util-to-hast@10.0.1: + dependencies: + '@types/mdast': 3.0.15 + '@types/unist': 2.0.11 + mdast-util-definitions: 4.0.0 + mdurl: 1.0.1 + unist-builder: 2.0.3 + unist-util-generated: 1.1.6 + unist-util-position: 3.1.0 + unist-util-visit: 2.0.3 + + mdast-util-to-hast@13.2.1: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.3.1 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + + mdast-util-to-markdown@2.1.2: + dependencies: + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + longest-streak: 3.1.0 + mdast-util-phrasing: 4.1.0 + mdast-util-to-string: 4.0.0 + micromark-util-classify-character: 2.0.1 + micromark-util-decode-string: 2.0.1 + unist-util-visit: 5.1.0 + zwitch: 2.0.4 + + mdast-util-to-string@1.1.0: {} + + mdast-util-to-string@4.0.0: + dependencies: + '@types/mdast': 4.0.4 + + mdn-data@2.0.14: {} + + mdn-data@2.0.28: {} + + mdn-data@2.0.30: {} + + mdn-data@2.27.1: {} + + mdurl@1.0.1: {} + + media-query-parser@2.0.2: + dependencies: + '@babel/runtime': 7.29.2 + + media-typer@0.3.0: {} + + mem@8.1.1: + dependencies: + map-age-cleaner: 0.1.3 + mimic-fn: 3.1.0 + + memfs@3.5.3: + dependencies: + fs-monkey: 1.1.0 + + memoizerific@1.11.3: + dependencies: + map-or-similar: 1.5.0 + + memory-fs@0.4.1: + dependencies: + errno: 0.1.8 + readable-stream: 2.3.8 + + memory-fs@0.5.0: + dependencies: + errno: 0.1.8 + readable-stream: 2.3.8 + + memorystream@0.3.1: {} + + meow@3.7.0: + dependencies: + camelcase-keys: 2.1.0 + decamelize: 1.2.0 + loud-rejection: 1.6.0 + map-obj: 1.0.1 + minimist: 1.2.8 + normalize-package-data: 2.5.0 + object-assign: 4.1.1 + read-pkg-up: 1.0.1 + redent: 1.0.0 + trim-newlines: 1.0.0 + optional: true + + meow@8.1.2: + dependencies: + '@types/minimist': 1.2.5 + camelcase-keys: 6.2.2 + decamelize-keys: 1.1.1 + hard-rejection: 2.1.0 + minimist-options: 4.1.0 + normalize-package-data: 3.0.3 + read-pkg-up: 7.0.1 + redent: 3.0.0 + trim-newlines: 3.0.1 + type-fest: 0.18.1 + yargs-parser: 20.2.9 + + merge-descriptors@1.0.3: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + methods@1.1.2: {} + + microevent.ts@0.1.1: {} + + micromark-core-commonmark@2.0.3: + dependencies: + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-factory-destination: 2.0.1 + micromark-factory-label: 2.0.1 + micromark-factory-space: 2.0.1 + micromark-factory-title: 2.0.1 + micromark-factory-whitespace: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-classify-character: 2.0.1 + micromark-util-html-tag-name: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-destination@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-label@2.0.1: + dependencies: + devlop: 1.1.0 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-space@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-types: 2.0.2 + + micromark-factory-title@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-factory-whitespace@2.0.1: + dependencies: + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-chunked@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-classify-character@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-combine-extensions@2.0.1: + dependencies: + micromark-util-chunked: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-decode-numeric-character-reference@2.0.2: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-decode-string@2.0.1: + dependencies: + decode-named-character-reference: 1.3.0 + micromark-util-character: 2.1.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-symbol: 2.0.1 + + micromark-util-encode@2.0.1: {} + + micromark-util-html-tag-name@2.0.1: {} + + micromark-util-normalize-identifier@2.0.1: + dependencies: + micromark-util-symbol: 2.0.1 + + micromark-util-resolve-all@2.0.1: + dependencies: + micromark-util-types: 2.0.2 + + micromark-util-sanitize-uri@2.0.1: + dependencies: + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 + + micromark-util-subtokenize@2.1.0: + dependencies: + devlop: 1.1.0 + micromark-util-chunked: 2.0.1 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + + micromark-util-symbol@2.0.1: {} + + micromark-util-types@2.0.2: {} + + micromark@4.0.2: + dependencies: + '@types/debug': 4.1.13 + debug: 4.4.3 + decode-named-character-reference: 1.3.0 + devlop: 1.1.0 + micromark-core-commonmark: 2.0.3 + micromark-factory-space: 2.0.1 + micromark-util-character: 2.1.1 + micromark-util-chunked: 2.0.1 + micromark-util-combine-extensions: 2.0.1 + micromark-util-decode-numeric-character-reference: 2.0.2 + micromark-util-encode: 2.0.1 + micromark-util-normalize-identifier: 2.0.1 + micromark-util-resolve-all: 2.0.1 + micromark-util-sanitize-uri: 2.0.1 + micromark-util-subtokenize: 2.1.0 + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.2 + transitivePeerDependencies: + - supports-color + + micromatch@3.1.10: + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + braces: 2.3.2 + define-property: 2.0.2 + extend-shallow: 3.0.2 + extglob: 2.0.4 + fragment-cache: 0.2.1 + kind-of: 6.0.3 + nanomatch: 1.2.13 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + + miller-rabin@4.0.1: + dependencies: + bn.js: 4.12.3 + brorand: 1.1.0 + + mime-db@1.52.0: {} + + mime-db@1.54.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime@1.6.0: {} + + mime@2.6.0: {} + + mimic-fn@2.1.0: {} + + mimic-fn@3.1.0: {} + + min-document@2.19.2: + dependencies: + dom-walk: 0.1.2 + + min-indent@1.0.1: {} + + mini-css-extract-plugin@2.10.2(webpack@5.106.2): + dependencies: + schema-utils: 4.3.3 + tapable: 2.3.3 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + + minimalistic-assert@1.0.1: {} + + minimalistic-crypto-utils@1.0.1: {} + + minimatch@10.2.5: + dependencies: + brace-expansion: 5.0.6 + + minimatch@3.0.5: + dependencies: + brace-expansion: 1.1.14 + + minimatch@3.1.5: + dependencies: + brace-expansion: 1.1.14 + + minimatch@5.1.9: + dependencies: + brace-expansion: 2.1.0 + + minimatch@8.0.7: + dependencies: + brace-expansion: 2.1.0 + + minimatch@9.0.9: + dependencies: + brace-expansion: 2.1.0 + + minimist-options@4.1.0: + dependencies: + arrify: 1.0.1 + is-plain-obj: 1.1.0 + kind-of: 6.0.3 + + minimist@1.2.8: {} + + minipass-collect@1.0.2: + dependencies: + minipass: 3.3.6 + + minipass-fetch@2.1.2: + dependencies: + minipass: 3.3.6 + minipass-sized: 1.0.3 + minizlib: 2.1.2 + optionalDependencies: + encoding: 0.1.13 + + minipass-fetch@3.0.5: + dependencies: + minipass: 7.1.3 + minipass-sized: 1.0.3 + minizlib: 2.1.2 + optionalDependencies: + encoding: 0.1.13 + + minipass-flush@1.0.7: + dependencies: + minipass: 3.3.6 + + minipass-json-stream@1.0.2: + dependencies: + jsonparse: 1.3.1 + minipass: 3.3.6 + + minipass-pipeline@1.2.4: + dependencies: + minipass: 3.3.6 + + minipass-sized@1.0.3: + dependencies: + minipass: 3.3.6 + + minipass@3.3.6: + dependencies: + yallist: 4.0.0 + + minipass@4.2.8: {} + + minipass@5.0.0: {} + + minipass@7.1.3: {} + + minizlib@2.1.2: + dependencies: + minipass: 3.3.6 + yallist: 4.0.0 + + mississippi@3.0.0: + dependencies: + concat-stream: 1.6.2 + duplexify: 3.7.1 + end-of-stream: 1.4.5 + flush-write-stream: 1.1.1 + from2: 2.3.0 + parallel-transform: 1.2.0 + pump: 3.0.4 + pumpify: 1.5.1 + stream-each: 1.2.3 + through2: 2.0.5 + + mixin-deep@1.3.2: + dependencies: + for-in: 1.0.2 + is-extendable: 1.0.1 + + mkdirp@0.5.6: + dependencies: + minimist: 1.2.8 + + mkdirp@1.0.4: {} + + mobx@6.15.3: {} + + modern-ahocorasick@1.1.0: {} + + modify-values@1.0.1: {} + + move-concurrently@1.0.1: + dependencies: + aproba: 1.2.0 + copy-concurrently: 1.0.5 + fs-write-stream-atomic: 1.0.10 + mkdirp: 0.5.6 + rimraf: 2.7.1 + run-queue: 1.0.3 + + ms@2.0.0: {} + + ms@2.1.3: {} + + multicast-dns@7.2.5: + dependencies: + dns-packet: 5.6.1 + thunky: 1.1.0 + + multimatch@5.0.0: + dependencies: + '@types/minimatch': 3.0.5 + array-differ: 3.0.0 + array-union: 2.1.0 + arrify: 2.0.1 + minimatch: 3.1.5 + + mute-stream@0.0.8: {} + + mute-stream@1.0.0: {} + + nan@2.27.0: {} + + nanoclone@0.2.1: {} + + nanoid@3.3.12: {} + + nanomatch@1.2.13: + dependencies: + arr-diff: 4.0.0 + array-unique: 0.3.2 + define-property: 2.0.2 + extend-shallow: 3.0.2 + fragment-cache: 0.2.1 + is-windows: 1.0.2 + kind-of: 6.0.3 + object.pick: 1.3.0 + regex-not: 1.0.2 + snapdragon: 0.8.2 + to-regex: 3.0.2 + transitivePeerDependencies: + - supports-color + + napi-postinstall@0.3.4: {} + + natural-compare-lite@1.4.0: {} + + natural-compare@1.4.0: {} + + negotiator@0.6.3: {} + + negotiator@0.6.4: {} + + neo-async@2.6.2: {} + + nested-error-stacks@2.1.1: {} + + next@14.2.35(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + dependencies: + '@next/env': 14.2.35 + '@swc/helpers': 0.5.5 + busboy: 1.6.0 + caniuse-lite: 1.0.30001792 + graceful-fs: 4.2.11 + postcss: 8.4.31 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + styled-jsx: 5.1.1(babel-plugin-macros@3.1.0)(react@19.2.6) + optionalDependencies: + '@next/swc-darwin-arm64': 14.2.33 + '@next/swc-darwin-x64': 14.2.33 + '@next/swc-linux-arm64-gnu': 14.2.33 + '@next/swc-linux-arm64-musl': 14.2.33 + '@next/swc-linux-x64-gnu': 14.2.33 + '@next/swc-linux-x64-musl': 14.2.33 + '@next/swc-win32-arm64-msvc': 14.2.33 + '@next/swc-win32-ia32-msvc': 14.2.33 + '@next/swc-win32-x64-msvc': 14.2.33 + transitivePeerDependencies: + - '@babel/core' + - babel-plugin-macros + + nice-try@1.0.5: {} + + no-case@3.0.4: + dependencies: + lower-case: 2.0.2 + tslib: 2.8.1 + + nock@13.5.4: + dependencies: + debug: 4.4.3 + json-stringify-safe: 5.0.1 + propagate: 2.0.1 + transitivePeerDependencies: + - supports-color + + node-abort-controller@3.1.1: {} + + node-addon-api@3.2.1: {} + + node-dir@0.1.17: + dependencies: + minimatch: 3.1.5 + + node-exports-info@1.6.0: + dependencies: + array.prototype.flatmap: 1.3.3 + es-errors: 1.3.0 + object.entries: 1.1.9 + semver: 6.3.1 + + node-fetch-native@1.6.7: {} + + node-fetch@2.6.7(encoding@0.1.13): + dependencies: + whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 + + node-fetch@2.7.0(encoding@0.1.13): + dependencies: + whatwg-url: 5.0.0 + optionalDependencies: + encoding: 0.1.13 + + node-forge@1.4.0: {} + + node-gyp-build@4.8.4: {} + + node-gyp@9.4.1: + dependencies: + env-paths: 2.2.1 + exponential-backoff: 3.1.3 + glob: 7.2.3 + graceful-fs: 4.2.11 + make-fetch-happen: 10.2.1 + nopt: 6.0.0 + npmlog: 6.0.2 + rimraf: 3.0.2 + semver: 7.8.0 + tar: 6.2.1 + which: 2.0.2 + transitivePeerDependencies: + - bluebird + - supports-color + + node-int64@0.4.0: {} + + node-libs-browser@2.2.1: + dependencies: + assert: 1.5.1 + browserify-zlib: 0.2.0 + buffer: 4.9.2 + console-browserify: 1.2.0 + constants-browserify: 1.0.0 + crypto-browserify: 3.12.1 + domain-browser: 1.2.0 + events: 3.3.0 + https-browserify: 1.0.0 + os-browserify: 0.3.0 + path-browserify: 0.0.1 + process: 0.11.10 + punycode: 1.4.1 + querystring-es3: 0.2.1 + readable-stream: 2.3.8 + stream-browserify: 2.0.2 + stream-http: 2.8.3 + string_decoder: 1.3.0 + timers-browserify: 2.0.12 + tty-browserify: 0.0.0 + url: 0.11.4 + util: 0.11.1 + vm-browserify: 1.1.2 + + node-machine-id@1.1.12: {} + + node-mock-http@1.0.4: {} + + node-releases@2.0.44: {} + + nopt@6.0.0: + dependencies: + abbrev: 1.1.1 + + normalize-package-data@2.5.0: + dependencies: + hosted-git-info: 2.8.9 + resolve: 1.22.12 + semver: 5.7.2 + validate-npm-package-license: 3.0.4 + + normalize-package-data@3.0.3: + dependencies: + hosted-git-info: 4.1.0 + is-core-module: 2.16.2 + semver: 7.8.0 + validate-npm-package-license: 3.0.4 + + normalize-package-data@5.0.0: + dependencies: + hosted-git-info: 6.1.3 + is-core-module: 2.16.2 + semver: 7.8.0 + validate-npm-package-license: 3.0.4 + + normalize-path@2.1.1: + dependencies: + remove-trailing-separator: 1.1.0 + + normalize-path@3.0.0: {} + + normalize-range@0.1.2: {} + + normalize-url@6.1.0: {} + + notistack@2.0.8(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + dependencies: + '@mui/material': 5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + clsx: 1.2.1 + hoist-non-react-statics: 3.3.2 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + optionalDependencies: + '@emotion/react': 11.14.0(@types/react@19.2.14)(react@19.2.6) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + + npm-bundled@1.1.2: + dependencies: + npm-normalize-package-bin: 1.0.1 + + npm-bundled@3.0.1: + dependencies: + npm-normalize-package-bin: 3.0.1 + + npm-install-checks@6.3.0: + dependencies: + semver: 7.8.0 + + npm-normalize-package-bin@1.0.1: {} + + npm-normalize-package-bin@3.0.1: {} + + npm-package-arg@10.1.0: + dependencies: + hosted-git-info: 6.1.3 + proc-log: 3.0.0 + semver: 7.8.0 + validate-npm-package-name: 5.0.0 + + npm-package-arg@8.1.1: + dependencies: + hosted-git-info: 3.0.8 + semver: 7.8.0 + validate-npm-package-name: 3.0.0 + + npm-packlist@5.1.1: + dependencies: + glob: 8.1.0 + ignore-walk: 5.0.1 + npm-bundled: 1.1.2 + npm-normalize-package-bin: 1.0.1 + + npm-packlist@7.0.4: + dependencies: + ignore-walk: 6.0.5 + + npm-pick-manifest@8.0.2: + dependencies: + npm-install-checks: 6.3.0 + npm-normalize-package-bin: 3.0.1 + npm-package-arg: 10.1.0 + semver: 7.8.0 + + npm-registry-fetch@14.0.5: + dependencies: + make-fetch-happen: 11.1.1 + minipass: 5.0.0 + minipass-fetch: 3.0.5 + minipass-json-stream: 1.0.2 + minizlib: 2.1.2 + npm-package-arg: 10.1.0 + proc-log: 3.0.0 + transitivePeerDependencies: + - supports-color + + npm-run-all@4.1.5: + dependencies: + ansi-styles: 3.2.1 + chalk: 2.4.2 + cross-spawn: 6.0.6 + memorystream: 0.3.1 + minimatch: 3.1.5 + pidtree: 0.3.1 + read-pkg: 3.0.0 + shell-quote: 1.8.3 + string.prototype.padend: 3.1.6 + + npm-run-path@2.0.2: + dependencies: + path-key: 2.0.1 + + npm-run-path@4.0.1: + dependencies: + path-key: 3.1.1 + + npmlog@5.0.1: + dependencies: + are-we-there-yet: 2.0.0 + console-control-strings: 1.1.0 + gauge: 3.0.2 + set-blocking: 2.0.0 + + npmlog@6.0.2: + dependencies: + are-we-there-yet: 3.0.1 + console-control-strings: 1.1.0 + gauge: 4.0.4 + set-blocking: 2.0.0 + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + num2fraction@1.2.2: {} + + nwsapi@2.2.23: {} + + nx@16.10.0: + dependencies: + '@nrwl/tao': 16.10.0 + '@parcel/watcher': 2.0.4 + '@yarnpkg/lockfile': 1.1.0 + '@yarnpkg/parsers': 3.0.0-rc.46 + '@zkochan/js-yaml': 0.0.6 + axios: 1.16.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.6.1 + cliui: 8.0.1 + dotenv: 16.3.2 + dotenv-expand: 10.0.0 + enquirer: 2.3.6 + figures: 3.2.0 + flat: 5.0.2 + fs-extra: 11.3.5 + glob: 7.1.4 + ignore: 5.3.2 + jest-diff: 29.7.0 + js-yaml: 4.1.0 + jsonc-parser: 3.2.0 + lines-and-columns: 2.0.4 + minimatch: 3.0.5 + node-machine-id: 1.1.12 + npm-run-path: 4.0.1 + open: 8.4.2 + semver: 7.5.3 + string-width: 4.2.3 + strong-log-transformer: 2.1.0 + tar-stream: 2.2.0 + tmp: 0.2.5 + tsconfig-paths: 4.2.0 + tslib: 2.8.1 + v8-compile-cache: 2.3.0 + yargs: 17.7.2 + yargs-parser: 21.1.1 + optionalDependencies: + '@nx/nx-darwin-arm64': 16.10.0 + '@nx/nx-darwin-x64': 16.10.0 + '@nx/nx-freebsd-x64': 16.10.0 + '@nx/nx-linux-arm-gnueabihf': 16.10.0 + '@nx/nx-linux-arm64-gnu': 16.10.0 + '@nx/nx-linux-arm64-musl': 16.10.0 + '@nx/nx-linux-x64-gnu': 16.10.0 + '@nx/nx-linux-x64-musl': 16.10.0 + '@nx/nx-win32-arm64-msvc': 16.10.0 + '@nx/nx-win32-x64-msvc': 16.10.0 + transitivePeerDependencies: + - debug + + object-assign@4.1.1: {} + + object-copy@0.1.0: + dependencies: + copy-descriptor: 0.1.1 + define-property: 0.2.5 + kind-of: 3.2.2 + + object-inspect@1.13.4: {} + + object-is@1.1.6: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + + object-keys@1.1.1: {} + + object-visit@1.0.1: + dependencies: + isobject: 3.0.1 + + object.assign@4.1.7: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + has-symbols: 1.1.0 + object-keys: 1.1.1 + + object.entries@1.1.9: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + object.fromentries@2.0.8: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.1 + + object.getownpropertydescriptors@2.1.9: + dependencies: + array.prototype.reduce: 1.0.8 + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.1 + gopd: 1.2.0 + safe-array-concat: 1.1.4 + + object.groupby@1.0.3: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + + object.pick@1.3.0: + dependencies: + isobject: 3.0.1 + + object.values@1.2.1: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + objectorarray@1.0.5: {} + + obuf@1.1.2: {} + + ofetch@1.5.1: + dependencies: + destr: 2.0.5 + node-fetch-native: 1.6.7 + ufo: 1.6.4 + + on-exit-leak-free@0.2.0: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + on-headers@1.1.0: {} + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@5.1.2: + dependencies: + mimic-fn: 2.1.0 + + open@7.4.2: + dependencies: + is-docker: 2.2.1 + is-wsl: 2.2.0 + + open@8.4.2: + dependencies: + define-lazy-prop: 2.0.0 + is-docker: 2.2.1 + is-wsl: 2.2.0 + + openapi-fetch@0.13.8: + dependencies: + openapi-typescript-helpers: 0.0.15 + + openapi-typescript-helpers@0.0.15: {} + + optionator@0.9.4: + dependencies: + deep-is: 0.1.4 + 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@5.4.1: + dependencies: + bl: 4.1.0 + chalk: 4.1.2 + cli-cursor: 3.1.0 + cli-spinners: 2.9.2 + is-interactive: 1.0.0 + is-unicode-supported: 0.1.0 + log-symbols: 4.1.0 + strip-ansi: 6.0.1 + wcwidth: 1.0.1 + + os-browserify@0.3.0: {} + + os-homedir@1.0.2: + optional: true + + own-keys@1.0.1: + dependencies: + get-intrinsic: 1.3.0 + object-keys: 1.1.1 + safe-push-apply: 1.0.0 + + p-all@2.1.0: + dependencies: + p-map: 2.1.0 + + p-defer@1.0.0: {} + + p-event@4.2.0: + dependencies: + p-timeout: 3.2.0 + + p-filter@2.1.0: + dependencies: + p-map: 2.1.0 + + p-finally@1.0.0: {} + + p-limit@1.3.0: + dependencies: + p-try: 1.0.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-limit@3.1.0: + dependencies: + yocto-queue: 0.1.0 + + p-limit@4.0.0: + dependencies: + yocto-queue: 1.2.2 + + p-locate@2.0.0: + dependencies: + p-limit: 1.3.0 + + p-locate@3.0.0: + dependencies: + p-limit: 2.3.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-locate@5.0.0: + dependencies: + p-limit: 3.1.0 + + p-locate@6.0.0: + dependencies: + p-limit: 4.0.0 + + p-map-series@2.1.0: {} + + p-map@2.1.0: {} + + p-map@3.0.0: + dependencies: + aggregate-error: 3.1.0 + + p-map@4.0.0: + dependencies: + aggregate-error: 3.1.0 + + p-pipe@3.1.0: {} + + p-queue@6.6.2: + dependencies: + eventemitter3: 4.0.7 + p-timeout: 3.2.0 + + p-reduce@2.1.0: {} + + p-retry@4.6.2: + dependencies: + '@types/retry': 0.12.0 + retry: 0.13.1 + + p-timeout@3.2.0: + dependencies: + p-finally: 1.0.0 + + p-try@1.0.0: {} + + p-try@2.2.0: {} + + p-waterfall@2.1.1: + dependencies: + p-reduce: 2.1.0 + + package-json-from-dist@1.0.1: {} + + pacote@15.2.0: + dependencies: + '@npmcli/git': 4.1.0 + '@npmcli/installed-package-contents': 2.1.0 + '@npmcli/promise-spawn': 6.0.2 + '@npmcli/run-script': 6.0.2 + cacache: 17.1.4 + fs-minipass: 3.0.3 + minipass: 5.0.0 + npm-package-arg: 10.1.0 + npm-packlist: 7.0.4 + npm-pick-manifest: 8.0.2 + npm-registry-fetch: 14.0.5 + proc-log: 3.0.0 + promise-retry: 2.0.1 + read-package-json: 6.0.4 + read-package-json-fast: 3.0.2 + sigstore: 1.9.0 + ssri: 10.0.6 + tar: 6.1.11 + transitivePeerDependencies: + - bluebird + - supports-color + + pako@1.0.11: {} + + pako@2.1.0: {} + + parallel-transform@1.2.0: + dependencies: + cyclist: 1.0.2 + inherits: 2.0.4 + readable-stream: 2.3.8 + + param-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.8.1 + + parent-module@1.0.1: + dependencies: + callsites: 3.1.0 + + parse-asn1@5.1.9: + dependencies: + asn1.js: 4.10.1 + browserify-aes: 1.2.0 + evp_bytestokey: 1.0.3 + pbkdf2: 3.1.5 + safe-buffer: 5.2.1 + + parse-author@2.0.0: + dependencies: + author-regex: 1.0.0 + + parse-entities@2.0.0: + dependencies: + character-entities: 1.2.4 + character-entities-legacy: 1.1.4 + character-reference-invalid: 1.1.4 + is-alphanumerical: 1.0.4 + is-decimal: 1.0.4 + is-hexadecimal: 1.0.4 + + parse-entities@4.0.2: + dependencies: + '@types/unist': 2.0.11 + character-entities-legacy: 3.0.0 + character-reference-invalid: 2.0.1 + decode-named-character-reference: 1.3.0 + is-alphanumerical: 2.0.1 + is-decimal: 2.0.1 + is-hexadecimal: 2.0.1 + + parse-json@2.2.0: + dependencies: + error-ex: 1.3.4 + optional: true + + parse-json@4.0.0: + dependencies: + error-ex: 1.3.4 + json-parse-better-errors: 1.0.2 + + parse-json@5.2.0: + dependencies: + '@babel/code-frame': 7.29.0 + error-ex: 1.3.4 + json-parse-even-better-errors: 2.3.1 + lines-and-columns: 1.2.4 + + parse-path@7.1.0: + dependencies: + protocols: 2.0.2 + + parse-url@8.1.0: + dependencies: + parse-path: 7.1.0 + + parse5@6.0.1: {} + + parse5@8.0.1: + dependencies: + entities: 8.0.0 + + parseurl@1.3.3: {} + + pascal-case@3.1.2: + dependencies: + no-case: 3.0.4 + tslib: 2.8.1 + + pascalcase@0.1.1: {} + + path-browserify@0.0.1: {} + + path-browserify@1.0.1: {} + + path-dirname@1.0.2: {} + + path-exists@2.1.0: + dependencies: + pinkie-promise: 2.0.1 + optional: true + + path-exists@3.0.0: {} + + path-exists@4.0.0: {} + + path-exists@5.0.0: {} + + path-is-absolute@1.0.1: {} + + path-is-inside@1.0.2: {} + + path-key@2.0.1: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-scurry@1.11.1: + dependencies: + lru-cache: 10.4.3 + minipass: 7.1.3 + + path-to-regexp@0.1.13: {} + + path-type@1.1.0: + dependencies: + graceful-fs: 4.2.11 + pify: 2.3.0 + pinkie-promise: 2.0.1 + optional: true + + path-type@3.0.0: + dependencies: + pify: 3.0.0 + + path-type@4.0.0: {} + + pbkdf2@3.1.5: + dependencies: + create-hash: 1.2.0 + create-hmac: 1.1.7 + ripemd160: 2.0.3 + safe-buffer: 5.2.1 + sha.js: 2.4.12 + to-buffer: 1.2.2 + + picocolors@0.2.1: {} + + picocolors@1.1.1: {} + + picomatch@2.3.2: {} + + picomatch@4.0.4: {} + + pidtree@0.3.1: {} + + pify@2.3.0: {} + + pify@3.0.0: {} + + pify@4.0.1: {} + + pify@5.0.0: {} + + pinkie-promise@2.0.1: + dependencies: + pinkie: 2.0.4 + + pinkie@2.0.4: {} + + pino-abstract-transport@0.5.0: + dependencies: + duplexify: 4.1.3 + split2: 4.2.0 + + pino-std-serializers@4.0.0: {} + + pino@7.11.0: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 0.2.0 + pino-abstract-transport: 0.5.0 + pino-std-serializers: 4.0.0 + process-warning: 1.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.1.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 2.8.0 + thread-stream: 0.15.2 + + pirates@4.0.7: {} + + pkg-dir@3.0.0: + dependencies: + find-up: 3.0.0 + + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + + pkg-dir@5.0.0: + dependencies: + find-up: 5.0.0 + + pkg-dir@7.0.0: + dependencies: + find-up: 6.3.0 + + pnp-webpack-plugin@1.6.4(typescript@4.9.5): + dependencies: + ts-pnp: 1.2.0(typescript@4.9.5) + transitivePeerDependencies: + - typescript + + polished@4.3.1: + dependencies: + '@babel/runtime': 7.29.2 + + posix-character-classes@0.1.1: {} + + possible-typed-array-names@1.1.0: {} + + postcss-calc@8.2.4(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-selector-parser: 6.1.2 + postcss-value-parser: 4.2.0 + + postcss-calc@9.0.1(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-selector-parser: 6.1.2 + postcss-value-parser: 4.2.0 + + postcss-colormin@5.3.1(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + colord: 2.9.3 + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-colormin@6.1.0(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + colord: 2.9.3 + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-convert-values@5.1.3(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-convert-values@6.1.0(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-discard-comments@5.1.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + + postcss-discard-comments@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + + postcss-discard-duplicates@5.1.0(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + + postcss-discard-duplicates@6.0.3(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + + postcss-discard-empty@5.1.1(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + + postcss-discard-empty@6.0.3(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + + postcss-discard-overridden@5.1.0(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + + postcss-discard-overridden@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + + postcss-flexbugs-fixes@4.2.1: + dependencies: + postcss: 7.0.39 + + postcss-loader@4.3.0(postcss@7.0.39)(webpack@4.47.0): + dependencies: + cosmiconfig: 7.1.0 + klona: 2.0.6 + loader-utils: 2.0.4 + postcss: 7.0.39 + schema-utils: 3.3.0 + semver: 7.8.0 + webpack: 4.47.0 + + postcss-merge-longhand@5.1.7(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + stylehacks: 5.1.1(postcss@8.5.14) + + postcss-merge-longhand@6.0.5(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + stylehacks: 6.1.1(postcss@8.5.14) + + postcss-merge-rules@5.1.4(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + cssnano-utils: 3.1.0(postcss@8.5.14) + postcss: 8.5.14 + postcss-selector-parser: 6.1.2 + + postcss-merge-rules@6.1.1(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + cssnano-utils: 4.0.2(postcss@8.5.14) + postcss: 8.5.14 + postcss-selector-parser: 6.1.2 + + postcss-minify-font-values@5.1.0(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-minify-font-values@6.1.0(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-minify-gradients@5.1.1(postcss@8.5.14): + dependencies: + colord: 2.9.3 + cssnano-utils: 3.1.0(postcss@8.5.14) + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-minify-gradients@6.0.3(postcss@8.5.14): + dependencies: + colord: 2.9.3 + cssnano-utils: 4.0.2(postcss@8.5.14) + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-minify-params@5.1.4(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + cssnano-utils: 3.1.0(postcss@8.5.14) + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-minify-params@6.1.0(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + cssnano-utils: 4.0.2(postcss@8.5.14) + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-minify-selectors@5.2.1(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-selector-parser: 6.1.2 + + postcss-minify-selectors@6.0.4(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-selector-parser: 6.1.2 + + postcss-modules-extract-imports@2.0.0: + dependencies: + postcss: 7.0.39 + + postcss-modules-extract-imports@3.1.0(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + + postcss-modules-local-by-default@3.0.3: + dependencies: + icss-utils: 4.1.1 + postcss: 7.0.39 + postcss-selector-parser: 6.1.2 + postcss-value-parser: 4.2.0 + + postcss-modules-local-by-default@4.2.0(postcss@8.5.14): + dependencies: + icss-utils: 5.1.0(postcss@8.5.14) + postcss: 8.5.14 + postcss-selector-parser: 7.1.1 + postcss-value-parser: 4.2.0 + + postcss-modules-scope@2.2.0: + dependencies: + postcss: 7.0.39 + postcss-selector-parser: 6.1.2 + + postcss-modules-scope@3.2.1(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-selector-parser: 7.1.1 + + postcss-modules-values@3.0.0: + dependencies: + icss-utils: 4.1.1 + postcss: 7.0.39 + + postcss-modules-values@4.0.0(postcss@8.5.14): + dependencies: + icss-utils: 5.1.0(postcss@8.5.14) + postcss: 8.5.14 + + postcss-normalize-charset@5.1.0(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + + postcss-normalize-charset@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + + postcss-normalize-display-values@5.1.0(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-normalize-display-values@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-normalize-positions@5.1.1(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-normalize-positions@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-normalize-repeat-style@5.1.1(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-normalize-repeat-style@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-normalize-string@5.1.0(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-normalize-string@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-normalize-timing-functions@5.1.0(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-normalize-timing-functions@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-normalize-unicode@5.1.1(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-normalize-unicode@6.1.0(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-normalize-url@5.1.0(postcss@8.5.14): + dependencies: + normalize-url: 6.1.0 + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-normalize-url@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-normalize-whitespace@5.1.1(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-normalize-whitespace@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-ordered-values@5.1.3(postcss@8.5.14): + dependencies: + cssnano-utils: 3.1.0(postcss@8.5.14) + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-ordered-values@6.0.2(postcss@8.5.14): + dependencies: + cssnano-utils: 4.0.2(postcss@8.5.14) + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-reduce-initial@5.1.2(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + postcss: 8.5.14 + + postcss-reduce-initial@6.1.0(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + postcss: 8.5.14 + + postcss-reduce-transforms@5.1.0(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-reduce-transforms@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + + postcss-selector-parser@6.1.2: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-selector-parser@7.1.1: + dependencies: + cssesc: 3.0.0 + util-deprecate: 1.0.2 + + postcss-svgo@5.1.0(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + svgo: 2.8.2 + + postcss-svgo@6.0.3(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + svgo: 3.3.3 + + postcss-unique-selectors@5.1.1(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-selector-parser: 6.1.2 + + postcss-unique-selectors@6.0.4(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-selector-parser: 6.1.2 + + postcss-value-parser@4.2.0: {} + + postcss@7.0.39: + dependencies: + picocolors: 0.2.1 + source-map: 0.6.1 + + postcss@8.4.31: + dependencies: + nanoid: 3.3.12 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + postcss@8.5.14: + dependencies: + nanoid: 3.3.12 + picocolors: 1.1.1 + source-map-js: 1.2.1 + + prelude-ls@1.2.1: {} + + prettier-linter-helpers@1.0.1: + dependencies: + fast-diff: 1.3.0 + + prettier@2.3.0: {} + + prettier@2.8.8: {} + + pretty-error@2.1.2: + dependencies: + lodash: 4.18.1 + renderkid: 2.0.7 + + pretty-error@4.0.0: + dependencies: + lodash: 4.18.1 + renderkid: 3.0.0 + + pretty-format@27.5.1: + dependencies: + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 17.0.2 + + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + + pretty-hrtime@1.0.3: {} + + proc-log@3.0.0: {} + + process-nextick-args@2.0.1: {} + + process-warning@1.0.0: {} + + process@0.11.10: {} + + promise-inflight@1.0.1(bluebird@3.7.2): + optionalDependencies: + bluebird: 3.7.2 + + promise-retry@2.0.1: + dependencies: + err-code: 2.0.3 + retry: 0.12.0 + + promise.allsettled@1.0.7: + dependencies: + array.prototype.map: 1.0.8 + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + get-intrinsic: 1.3.0 + iterate-value: 1.0.2 + + promise.prototype.finally@3.1.8: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + set-function-name: 2.0.2 + + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + + promzard@1.0.2: + dependencies: + read: 3.0.1 + + prop-types@15.8.1: + dependencies: + loose-envify: 1.4.0 + object-assign: 4.1.1 + react-is: 16.13.1 + + propagate@2.0.1: {} + + property-expr@2.0.6: {} + + property-information@5.6.0: + dependencies: + xtend: 4.0.2 + + property-information@7.1.0: {} + + protobufjs@6.10.3: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.5 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.1 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.1 + '@types/long': 4.0.2 + '@types/node': 13.13.52 + long: 4.0.0 + + protobufjs@6.11.6: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.5 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.1 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.1 + '@types/long': 4.0.2 + '@types/node': 22.19.19 + long: 4.0.0 + + protocols@2.0.2: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + proxy-from-env@2.1.0: {} + + prr@1.0.1: {} + + psl@1.15.0: + dependencies: + punycode: 2.3.1 + + public-encrypt@4.0.3: + dependencies: + bn.js: 4.12.3 + browserify-rsa: 4.1.1 + create-hash: 1.2.0 + parse-asn1: 5.1.9 + randombytes: 2.1.0 + safe-buffer: 5.2.1 + + pump@2.0.1: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + + pump@3.0.4: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + + pumpify@1.5.1: + dependencies: + duplexify: 3.7.1 + inherits: 2.0.4 + pump: 2.0.1 + + punycode@1.4.1: {} + + punycode@2.3.1: {} + + pure-rand@6.1.0: {} + + qr.js@0.0.0: {} + + qrcode.react@1.0.1(react@19.2.6): + dependencies: + loose-envify: 1.4.0 + prop-types: 15.8.1 + qr.js: 0.0.0 + react: 19.2.6 + + qrcode.react@4.2.0(react@19.2.6): + dependencies: + react: 19.2.6 + + qs@6.15.1: + dependencies: + side-channel: 1.1.0 + + querystring-es3@0.2.1: {} + + querystringify@2.2.0: {} + + queue-microtask@1.2.3: {} + + quick-format-unescaped@4.0.4: {} + + quick-lru@4.0.1: {} + + radix3@1.1.2: {} + + rainbow-sprinkles@0.17.3(@vanilla-extract/css@1.20.1(babel-plugin-macros@3.1.0))(@vanilla-extract/dynamic@2.1.5): + dependencies: + '@vanilla-extract/css': 1.20.1(babel-plugin-macros@3.1.0) + '@vanilla-extract/dynamic': 2.1.5 + + ramda@0.26.1: {} + + ramda@0.28.0: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + randomfill@1.0.4: + dependencies: + randombytes: 2.1.0 + safe-buffer: 5.2.1 + + range-parser@1.2.1: {} + + raw-body@2.5.3: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + raw-loader@4.0.2(webpack@4.47.0): + dependencies: + loader-utils: 2.0.4 + schema-utils: 3.3.0 + webpack: 4.47.0 + + react-aria@3.48.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + dependencies: + '@internationalized/date': 3.12.1 + '@internationalized/number': 3.6.6 + '@internationalized/string': 3.2.8 + '@react-types/shared': 3.34.0(react@19.2.6) + '@swc/helpers': 0.5.21 + aria-hidden: 1.2.6 + clsx: 2.1.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-stately: 3.46.0(react@19.2.6) + use-sync-external-store: 1.6.0(react@19.2.6) + + react-docgen-typescript@2.4.0(typescript@4.9.5): + dependencies: + typescript: 4.9.5 + + react-docgen@5.4.3: + dependencies: + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/runtime': 7.29.2 + ast-types: 0.14.2 + commander: 2.20.3 + doctrine: 3.0.0 + estree-to-babel: 3.2.1 + neo-async: 2.6.2 + node-dir: 0.1.17 + strip-indent: 3.0.0 + transitivePeerDependencies: + - supports-color + + react-dom@19.2.6(react@19.2.6): + dependencies: + react: 19.2.6 + scheduler: 0.27.0 + + react-element-to-jsx-string@14.3.4(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + dependencies: + '@base2/pretty-print-object': 1.0.1 + is-plain-object: 5.0.0 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-is: 17.0.2 + + react-error-boundary@3.1.4(react@19.2.6): + dependencies: + '@babel/runtime': 7.29.2 + react: 19.2.6 + + react-hook-form@7.75.0(react@19.2.6): + dependencies: + react: 19.2.6 + + react-i18next@15.7.4(i18next@24.2.3(typescript@5.9.3))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@5.9.3): + dependencies: + '@babel/runtime': 7.29.2 + html-parse-stringify: 3.0.1 + i18next: 24.2.3(typescript@5.9.3) + react: 19.2.6 + optionalDependencies: + react-dom: 19.2.6(react@19.2.6) + typescript: 5.9.3 + + react-inspector@5.1.1(react@19.2.6): + dependencies: + '@babel/runtime': 7.29.2 + is-dom: 1.1.0 + prop-types: 15.8.1 + react: 19.2.6 + + react-is@16.13.1: {} + + react-is@17.0.2: {} + + react-is@18.3.1: {} + + react-is@19.2.6: {} + + react-markdown@9.1.0(@types/react@19.2.14)(react@19.2.6): + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + '@types/react': 19.2.14 + devlop: 1.1.0 + hast-util-to-jsx-runtime: 2.3.6 + html-url-attributes: 3.0.1 + mdast-util-to-hast: 13.2.1 + react: 19.2.6 + remark-parse: 11.0.0 + remark-rehype: 11.1.2 + unified: 11.0.5 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + transitivePeerDependencies: + - supports-color + + react-merge-refs@1.1.0: {} + + react-random-avatars@1.3.1(react@19.2.6): + dependencies: + react: 19.2.6 + + react-refresh-typescript@2.0.12(react-refresh@0.10.0)(typescript@5.9.3): + dependencies: + react-refresh: 0.10.0 + typescript: 5.9.3 + + react-refresh@0.10.0: {} + + react-refresh@0.11.0: {} + + react-router-dom@6.30.3(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + dependencies: + '@remix-run/router': 1.23.2 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-router: 6.30.3(react@19.2.6) + + react-router@6.30.3(react@19.2.6): + dependencies: + '@remix-run/router': 1.23.2 + react: 19.2.6 + + react-smooth@4.0.4(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + dependencies: + fast-equals: 5.4.0 + prop-types: 15.8.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-transition-group: 4.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + + react-stately@3.46.0(react@19.2.6): + dependencies: + '@internationalized/date': 3.12.1 + '@internationalized/number': 3.6.6 + '@internationalized/string': 3.2.8 + '@react-types/shared': 3.34.0(react@19.2.6) + '@swc/helpers': 0.5.21 + react: 19.2.6 + use-sync-external-store: 1.6.0(react@19.2.6) + + react-transition-group@4.4.5(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + dependencies: + '@babel/runtime': 7.29.2 + dom-helpers: 5.2.1 + loose-envify: 1.4.0 + prop-types: 15.8.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + + react-world-flags@1.6.0(react@19.2.6): + dependencies: + react: 19.2.6 + svg-country-flags: 1.2.10 + svgo: 3.3.3 + world-countries: 5.1.0 + + react@19.2.6: {} + + read-cmd-shim@4.0.0: {} + + read-package-json-fast@3.0.2: + dependencies: + json-parse-even-better-errors: 3.0.2 + npm-normalize-package-bin: 3.0.1 + + read-package-json@6.0.4: + dependencies: + glob: 10.5.0 + json-parse-even-better-errors: 3.0.2 + normalize-package-data: 5.0.0 + npm-normalize-package-bin: 3.0.1 + + read-pkg-up@1.0.1: + dependencies: + find-up: 1.1.2 + read-pkg: 1.1.0 + optional: true + + read-pkg-up@3.0.0: + dependencies: + find-up: 2.1.0 + read-pkg: 3.0.0 + + read-pkg-up@7.0.1: + dependencies: + find-up: 4.1.0 + read-pkg: 5.2.0 + type-fest: 0.8.1 + + read-pkg@1.1.0: + dependencies: + load-json-file: 1.1.0 + normalize-package-data: 2.5.0 + path-type: 1.1.0 + optional: true + + read-pkg@3.0.0: + dependencies: + load-json-file: 4.0.0 + normalize-package-data: 2.5.0 + path-type: 3.0.0 + + read-pkg@5.2.0: + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 2.5.0 + parse-json: 5.2.0 + type-fest: 0.6.0 + + read@2.1.0: + dependencies: + mute-stream: 1.0.0 + + read@3.0.1: + dependencies: + mute-stream: 1.0.0 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdirp@2.2.1: + dependencies: + graceful-fs: 4.2.11 + micromatch: 3.1.10 + readable-stream: 2.3.8 + transitivePeerDependencies: + - supports-color + optional: true + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.2 + + readdirp@5.0.0: {} + + readonly-date@1.0.0: {} + + real-require@0.1.0: {} + + recast@0.23.11: + dependencies: + ast-types: 0.16.1 + esprima: 4.0.1 + source-map: 0.6.1 + tiny-invariant: 1.3.3 + tslib: 2.8.1 + + recharts-scale@0.4.5: + dependencies: + decimal.js-light: 2.5.1 + + recharts@2.15.4(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + dependencies: + clsx: 2.1.1 + eventemitter3: 4.0.7 + lodash: 4.18.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-is: 18.3.1 + react-smooth: 4.0.4(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + recharts-scale: 0.4.5 + tiny-invariant: 1.3.3 + victory-vendor: 36.9.2 + + rechoir@0.7.1: + dependencies: + resolve: 1.22.12 + + rechoir@0.8.0: + dependencies: + resolve: 1.22.12 + + redent@1.0.0: + dependencies: + indent-string: 2.1.0 + strip-indent: 1.0.1 + optional: true + + redent@3.0.0: + dependencies: + indent-string: 4.0.0 + strip-indent: 3.0.0 + + redeyed@2.1.1: + dependencies: + esprima: 4.0.1 + + reflect.getprototypeof@1.0.10: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + get-proto: 1.0.1 + which-builtin-type: 1.2.1 + + regenerate-unicode-properties@10.2.2: + dependencies: + regenerate: 1.4.2 + + regenerate@1.4.2: {} + + regenerator-runtime@0.13.11: {} + + regex-not@1.0.2: + dependencies: + extend-shallow: 3.0.2 + safe-regex: 1.1.0 + + regexp.prototype.flags@1.5.4: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-errors: 1.3.0 + get-proto: 1.0.1 + gopd: 1.2.0 + set-function-name: 2.0.2 + + regexpu-core@6.4.0: + dependencies: + regenerate: 1.4.2 + regenerate-unicode-properties: 10.2.2 + regjsgen: 0.8.0 + regjsparser: 0.13.1 + unicode-match-property-ecmascript: 2.0.0 + unicode-match-property-value-ecmascript: 2.2.1 + + regjsgen@0.8.0: {} + + regjsparser@0.13.1: + dependencies: + jsesc: 3.1.0 + + relateurl@0.2.7: {} + + remark-external-links@8.0.0: + dependencies: + extend: 3.0.2 + is-absolute-url: 3.0.3 + mdast-util-definitions: 4.0.0 + space-separated-tokens: 1.1.5 + unist-util-visit: 2.0.3 + + remark-footnotes@2.0.0: {} + + remark-mdx@1.6.22: + dependencies: + '@babel/core': 7.12.9 + '@babel/helper-plugin-utils': 7.10.4 + '@babel/plugin-proposal-object-rest-spread': 7.12.1(@babel/core@7.12.9) + '@babel/plugin-syntax-jsx': 7.12.1(@babel/core@7.12.9) + '@mdx-js/util': 1.6.22 + is-alphabetical: 1.0.4 + remark-parse: 8.0.3 + unified: 9.2.0 + transitivePeerDependencies: + - supports-color + + remark-parse@11.0.0: + dependencies: + '@types/mdast': 4.0.4 + mdast-util-from-markdown: 2.0.3 + micromark-util-types: 2.0.2 + unified: 11.0.5 + transitivePeerDependencies: + - supports-color + + remark-parse@8.0.3: + dependencies: + ccount: 1.1.0 + collapse-white-space: 1.0.6 + is-alphabetical: 1.0.4 + is-decimal: 1.0.4 + is-whitespace-character: 1.0.4 + is-word-character: 1.0.4 + markdown-escapes: 1.0.4 + parse-entities: 2.0.0 + repeat-string: 1.6.1 + state-toggle: 1.0.3 + trim: 0.0.1 + trim-trailing-lines: 1.1.4 + unherit: 1.1.3 + unist-util-remove-position: 2.0.1 + vfile-location: 3.2.0 + xtend: 4.0.2 + + remark-rehype@11.1.2: + dependencies: + '@types/hast': 3.0.4 + '@types/mdast': 4.0.4 + mdast-util-to-hast: 13.2.1 + unified: 11.0.5 + vfile: 6.0.3 + + remark-slug@6.1.0: + dependencies: + github-slugger: 1.5.0 + mdast-util-to-string: 1.1.0 + unist-util-visit: 2.0.3 + + remark-squeeze-paragraphs@4.0.0: + dependencies: + mdast-squeeze-paragraphs: 4.0.0 + + remove-accents@0.5.0: {} + + remove-trailing-separator@1.1.0: {} + + renderkid@2.0.7: + dependencies: + css-select: 4.3.0 + dom-converter: 0.2.0 + htmlparser2: 6.1.0 + lodash: 4.18.1 + strip-ansi: 3.0.1 + + renderkid@3.0.0: + dependencies: + css-select: 4.3.0 + dom-converter: 0.2.0 + htmlparser2: 6.1.0 + lodash: 4.18.1 + strip-ansi: 6.0.1 + + repeat-element@1.1.4: {} + + repeat-string@1.6.1: {} + + repeating@2.0.1: + dependencies: + is-finite: 1.1.0 + optional: true + + require-directory@2.1.1: {} + + require-from-string@2.0.2: {} + + requireindex@1.2.0: {} + + requires-port@1.0.0: {} + + resolve-cwd@3.0.0: + dependencies: + resolve-from: 5.0.0 + + resolve-from@4.0.0: {} + + resolve-from@5.0.0: {} + + resolve-pkg-maps@1.0.0: {} + + resolve-url@0.2.1: {} + + resolve.exports@1.1.1: {} + + resolve.exports@2.0.3: {} + + resolve@1.22.12: + dependencies: + es-errors: 1.3.0 + is-core-module: 2.16.2 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + resolve@2.0.0-next.6: + dependencies: + es-errors: 1.3.0 + is-core-module: 2.16.2 + node-exports-info: 1.6.0 + object-keys: 1.1.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + restore-cursor@3.1.0: + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + + ret@0.1.15: {} + + retry@0.12.0: {} + + retry@0.13.1: {} + + reusify@1.1.0: {} + + rgb-hex@3.0.0: {} + + rimraf@2.7.1: + dependencies: + glob: 7.2.3 + + rimraf@3.0.2: + dependencies: + glob: 7.2.3 + + rimraf@4.4.1: + dependencies: + glob: 9.3.5 + + ripemd160@2.0.3: + dependencies: + hash-base: 3.1.2 + inherits: 2.0.4 + + robust-predicates@3.0.3: {} + + rsvp@4.8.5: {} + + run-async@2.4.1: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + run-queue@1.0.3: + dependencies: + aproba: 1.2.0 + + rxjs@7.8.2: + dependencies: + tslib: 2.8.1 + + safe-array-concat@1.1.4: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + get-intrinsic: 1.3.0 + has-symbols: 1.1.0 + isarray: 2.0.5 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safe-push-apply@1.0.0: + dependencies: + es-errors: 1.3.0 + isarray: 2.0.5 + + safe-regex-test@1.1.0: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-regex: 1.2.1 + + safe-regex@1.1.0: + dependencies: + ret: 0.1.15 + + safe-stable-stringify@2.5.0: {} + + safer-buffer@2.1.2: {} + + sane@4.1.0: + dependencies: + '@cnakazawa/watch': 1.0.4 + anymatch: 2.0.0 + capture-exit: 2.0.0 + exec-sh: 0.3.6 + execa: 1.0.0 + fb-watchman: 2.0.2 + micromatch: 3.1.10 + minimist: 1.2.8 + walker: 1.0.8 + transitivePeerDependencies: + - supports-color + + sax@1.6.0: {} + + saxes@5.0.1: + dependencies: + xmlchars: 2.2.0 + + saxes@6.0.0: + dependencies: + xmlchars: 2.2.0 + + scheduler@0.27.0: {} + + schema-utils@1.0.0: + dependencies: + ajv: 6.15.0 + ajv-errors: 1.0.1(ajv@6.15.0) + ajv-keywords: 3.5.2(ajv@6.15.0) + + schema-utils@2.7.0: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 6.15.0 + ajv-keywords: 3.5.2(ajv@6.15.0) + + schema-utils@2.7.1: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 6.15.0 + ajv-keywords: 3.5.2(ajv@6.15.0) + + schema-utils@3.3.0: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 6.15.0 + ajv-keywords: 3.5.2(ajv@6.15.0) + + schema-utils@4.3.3: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.20.0 + ajv-formats: 2.1.1(ajv@8.20.0) + ajv-keywords: 5.1.0(ajv@8.20.0) + + select-hose@2.0.0: {} + + selfsigned@2.4.1: + dependencies: + '@types/node-forge': 1.3.14 + node-forge: 1.4.0 + + semver@5.7.2: {} + + semver@6.3.1: {} + + semver@7.5.3: + dependencies: + lru-cache: 6.0.0 + + semver@7.8.0: {} + + send@0.19.2: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.1 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serialize-javascript@4.0.0: + dependencies: + randombytes: 2.1.0 + + serialize-javascript@5.0.1: + dependencies: + randombytes: 2.1.0 + + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + + serve-favicon@2.5.1: + dependencies: + etag: 1.8.1 + fresh: 0.5.2 + ms: 2.1.3 + parseurl: 1.3.3 + safe-buffer: 5.2.1 + + serve-index@1.9.2: + dependencies: + accepts: 1.3.8 + batch: 0.6.1 + debug: 2.6.9 + escape-html: 1.0.3 + http-errors: 1.8.1 + mime-types: 2.1.35 + parseurl: 1.3.3 + transitivePeerDependencies: + - supports-color + + serve-static@1.16.3: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.2 + transitivePeerDependencies: + - supports-color + + set-blocking@2.0.0: {} + + set-function-length@1.2.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-property-descriptors: 1.0.2 + + set-function-name@2.0.2: + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + set-proto@1.0.0: + dependencies: + dunder-proto: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + + set-value@2.0.1: + dependencies: + extend-shallow: 2.0.1 + is-extendable: 0.1.1 + is-plain-object: 2.0.4 + split-string: 3.1.0 + + setimmediate@1.0.5: {} + + setprototypeof@1.2.0: {} + + sha.js@2.4.12: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + to-buffer: 1.2.2 + + shallow-clone@3.0.1: + dependencies: + kind-of: 6.0.3 + + sharp@0.33.5: + dependencies: + color: 4.2.3 + detect-libc: 2.1.2 + semver: 7.8.0 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.33.5 + '@img/sharp-darwin-x64': 0.33.5 + '@img/sharp-libvips-darwin-arm64': 1.0.4 + '@img/sharp-libvips-darwin-x64': 1.0.4 + '@img/sharp-libvips-linux-arm': 1.0.5 + '@img/sharp-libvips-linux-arm64': 1.0.4 + '@img/sharp-libvips-linux-s390x': 1.0.4 + '@img/sharp-libvips-linux-x64': 1.0.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.0.4 + '@img/sharp-libvips-linuxmusl-x64': 1.0.4 + '@img/sharp-linux-arm': 0.33.5 + '@img/sharp-linux-arm64': 0.33.5 + '@img/sharp-linux-s390x': 0.33.5 + '@img/sharp-linux-x64': 0.33.5 + '@img/sharp-linuxmusl-arm64': 0.33.5 + '@img/sharp-linuxmusl-x64': 0.33.5 + '@img/sharp-wasm32': 0.33.5 + '@img/sharp-win32-ia32': 0.33.5 + '@img/sharp-win32-x64': 0.33.5 + + shebang-command@1.2.0: + dependencies: + shebang-regex: 1.0.0 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@1.0.0: {} + + shebang-regex@3.0.0: {} + + shell-quote@1.8.3: {} + + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + signal-exit@3.0.7: {} + + signal-exit@4.1.0: {} + + sigstore@1.9.0: + dependencies: + '@sigstore/bundle': 1.1.0 + '@sigstore/protobuf-specs': 0.2.1 + '@sigstore/sign': 1.0.0 + '@sigstore/tuf': 1.0.3 + make-fetch-happen: 11.1.1 + transitivePeerDependencies: + - supports-color + + simple-swizzle@0.2.4: + dependencies: + is-arrayish: 0.3.4 + + sisteransi@1.0.5: {} + + slash@1.0.0: {} + + slash@2.0.0: {} + + slash@3.0.0: {} + + slash@4.0.0: {} + + smart-buffer@4.2.0: {} + + snapdragon-node@2.1.1: + dependencies: + define-property: 1.0.0 + isobject: 3.0.1 + snapdragon-util: 3.0.1 + + snapdragon-util@3.0.1: + dependencies: + kind-of: 3.2.2 + + snapdragon@0.8.2: + dependencies: + base: 0.11.2 + debug: 2.6.9 + define-property: 0.2.5 + extend-shallow: 2.0.1 + map-cache: 0.2.2 + source-map: 0.5.7 + source-map-resolve: 0.5.3 + use: 3.1.1 + transitivePeerDependencies: + - supports-color + + sockjs@0.3.24: + dependencies: + faye-websocket: 0.11.4 + uuid: 8.3.2 + websocket-driver: 0.7.4 + + socks-proxy-agent@7.0.0: + dependencies: + agent-base: 6.0.2 + debug: 4.4.3 + socks: 2.8.9 + transitivePeerDependencies: + - supports-color + + socks@2.8.9: + dependencies: + ip-address: 10.2.0 + smart-buffer: 4.2.0 + + sonic-boom@2.8.0: + dependencies: + atomic-sleep: 1.0.0 + + sort-keys@2.0.0: + dependencies: + is-plain-obj: 1.1.0 + + source-list-map@2.0.1: {} + + source-map-js@1.2.1: {} + + source-map-resolve@0.5.3: + dependencies: + atob: 2.1.2 + decode-uri-component: 0.2.2 + resolve-url: 0.2.1 + source-map-url: 0.4.1 + urix: 0.1.0 + + source-map-support@0.5.13: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map-url@0.4.1: {} + + source-map@0.5.7: {} + + source-map@0.6.1: {} + + source-map@0.7.6: {} + + space-separated-tokens@1.1.5: {} + + space-separated-tokens@2.0.2: {} + + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.23 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.23 + + spdx-license-ids@3.0.23: {} + + spdy-transport@3.0.0: + dependencies: + debug: 4.4.3 + detect-node: 2.1.0 + hpack.js: 2.1.6 + obuf: 1.1.2 + readable-stream: 3.6.2 + wbuf: 1.7.3 + transitivePeerDependencies: + - supports-color + + spdy@4.0.2: + dependencies: + debug: 4.4.3 + handle-thing: 2.0.1 + http-deceiver: 1.2.7 + select-hose: 2.0.0 + spdy-transport: 3.0.0 + transitivePeerDependencies: + - supports-color + + split-string@3.1.0: + dependencies: + extend-shallow: 3.0.2 + + split2@3.2.2: + dependencies: + readable-stream: 3.6.2 + + split2@4.2.0: {} + + split@1.0.1: + dependencies: + through: 2.3.8 + + sprintf-js@1.0.3: {} + + ssri@10.0.6: + dependencies: + minipass: 7.1.3 + + ssri@6.0.2: + dependencies: + figgy-pudding: 3.5.2 + + ssri@8.0.1: + dependencies: + minipass: 3.3.6 + + ssri@9.0.1: + dependencies: + minipass: 3.3.6 + + stable-hash@0.0.5: {} + + stable@0.1.8: {} + + stack-utils@2.0.6: + dependencies: + escape-string-regexp: 2.0.0 + + stackframe@1.3.4: {} + + starknet@8.9.2: + dependencies: + '@noble/curves': 1.7.0 + '@noble/hashes': 1.6.1 + '@scure/base': 1.2.6 + '@scure/starknet': 1.1.0 + '@starknet-io/starknet-types-08': '@starknet-io/types-js@0.8.4' + '@starknet-io/starknet-types-09': '@starknet-io/types-js@0.9.2' + abi-wan-kanabi: 2.2.4 + lossless-json: 4.3.0 + pako: 2.1.0 + ts-mixer: 6.0.4 + + state-toggle@1.0.3: {} + + static-extend@0.1.2: + dependencies: + define-property: 0.2.5 + object-copy: 0.1.0 + + statuses@1.5.0: {} + + statuses@2.0.2: {} + + stop-iteration-iterator@1.1.0: + dependencies: + es-errors: 1.3.0 + internal-slot: 1.1.0 + + store2@2.14.4: {} + + storybook@8.6.18(prettier@2.8.8): + dependencies: + '@storybook/core': 8.6.18(prettier@2.8.8)(storybook@8.6.18(prettier@2.8.8)) + optionalDependencies: + prettier: 2.8.8 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + stream-browserify@2.0.2: + dependencies: + inherits: 2.0.4 + readable-stream: 2.3.8 + + stream-each@1.2.3: + dependencies: + end-of-stream: 1.4.5 + stream-shift: 1.0.3 + + stream-http@2.8.3: + dependencies: + builtin-status-codes: 3.0.0 + inherits: 2.0.4 + readable-stream: 2.3.8 + to-arraybuffer: 1.0.1 + xtend: 4.0.2 + + stream-shift@1.0.3: {} + + streamsearch@1.1.0: {} + + string-length@4.0.2: + dependencies: + char-regex: 1.0.2 + strip-ansi: 6.0.1 + + string-to-color@2.2.2: + dependencies: + colornames: 1.1.1 + hex-rgb: 4.3.0 + lodash.padend: 4.6.1 + lodash.trimstart: 4.5.1 + lodash.words: 4.2.0 + rgb-hex: 3.0.0 + + string-width@4.2.3: + dependencies: + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 + + string-width@5.1.2: + dependencies: + eastasianwidth: 0.2.0 + emoji-regex: 9.2.2 + strip-ansi: 7.2.0 + + string.prototype.includes@2.0.1: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + + string.prototype.matchall@4.0.12: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-intrinsic: 1.3.0 + gopd: 1.2.0 + has-symbols: 1.1.0 + internal-slot: 1.1.0 + regexp.prototype.flags: 1.5.4 + set-function-name: 2.0.2 + side-channel: 1.1.0 + + string.prototype.padend@3.1.6: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.1 + + string.prototype.padstart@3.1.7: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.1 + + string.prototype.repeat@1.0.0: + dependencies: + define-properties: 1.2.1 + es-abstract: 1.24.2 + + string.prototype.trim@1.2.10: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-data-property: 1.1.4 + define-properties: 1.2.1 + es-abstract: 1.24.2 + es-object-atoms: 1.1.1 + has-property-descriptors: 1.0.2 + + string.prototype.trimend@1.0.9: + dependencies: + call-bind: 1.0.9 + call-bound: 1.0.4 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string.prototype.trimstart@1.0.8: + dependencies: + call-bind: 1.0.9 + define-properties: 1.2.1 + es-object-atoms: 1.1.1 + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + + strip-ansi@3.0.1: + dependencies: + ansi-regex: 2.1.1 + + strip-ansi@6.0.1: + dependencies: + ansi-regex: 5.0.1 + + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.2.2 + + strip-bom@2.0.0: + dependencies: + is-utf8: 0.2.1 + optional: true + + strip-bom@3.0.0: {} + + strip-bom@4.0.0: {} + + strip-eof@1.0.0: {} + + strip-final-newline@2.0.0: {} + + strip-indent@1.0.1: + dependencies: + get-stdin: 4.0.1 + optional: true + + strip-indent@3.0.0: + dependencies: + min-indent: 1.0.1 + + strip-json-comments@3.1.1: {} + + strong-log-transformer@2.1.0: + dependencies: + duplexer: 0.1.2 + minimist: 1.2.8 + through: 2.3.8 + + style-loader@1.3.0(webpack@4.47.0): + dependencies: + loader-utils: 2.0.4 + schema-utils: 2.7.1 + webpack: 4.47.0 + + style-loader@2.0.0(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)): + dependencies: + loader-utils: 2.0.4 + schema-utils: 3.3.0 + webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + + style-loader@3.3.4(webpack@5.106.2): + dependencies: + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + + style-to-js@1.1.21: + dependencies: + style-to-object: 1.0.14 + + style-to-object@0.3.0: + dependencies: + inline-style-parser: 0.1.1 + + style-to-object@1.0.14: + dependencies: + inline-style-parser: 0.2.7 + + styled-jsx@5.1.1(babel-plugin-macros@3.1.0)(react@19.2.6): + dependencies: + client-only: 0.0.1 + react: 19.2.6 + optionalDependencies: + babel-plugin-macros: 3.1.0 + + stylehacks@5.1.1(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + postcss: 8.5.14 + postcss-selector-parser: 6.1.2 + + stylehacks@6.1.1(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + postcss: 8.5.14 + postcss-selector-parser: 6.1.2 + + stylis@4.2.0: {} + + supports-color@5.5.0: + dependencies: + has-flag: 3.0.0 + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-hyperlinks@2.3.0: + dependencies: + has-flag: 4.0.0 + supports-color: 7.2.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + svg-country-flags@1.2.10: {} + + svg-parser@2.0.4: {} + + svgo@2.8.2: + dependencies: + commander: 7.2.0 + css-select: 4.3.0 + css-tree: 1.1.3 + csso: 4.2.0 + picocolors: 1.1.1 + sax: 1.6.0 + stable: 0.1.8 + + svgo@3.3.3: + dependencies: + commander: 7.2.0 + css-select: 5.2.2 + css-tree: 2.3.1 + css-what: 6.2.2 + csso: 5.0.5 + picocolors: 1.1.1 + sax: 1.6.0 + + symbol-observable@2.0.3: {} + + symbol-tree@3.2.4: {} + + symbol.prototype.description@1.0.7: + dependencies: + call-bind: 1.0.9 + es-errors: 1.3.0 + es-object-atoms: 1.1.1 + get-symbol-description: 1.1.0 + gopd: 1.2.0 + has-symbols: 1.1.0 + object.getownpropertydescriptors: 2.1.9 + + synchronous-promise@2.0.17: {} + + tabbable@6.4.0: {} + + tapable@1.1.3: {} + + tapable@2.3.3: {} + + tar-stream@2.2.0: + dependencies: + bl: 4.1.0 + end-of-stream: 1.4.5 + fs-constants: 1.0.0 + inherits: 2.0.4 + readable-stream: 3.6.2 + + tar@6.1.11: + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 3.3.6 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + + tar@6.2.1: + dependencies: + chownr: 2.0.0 + fs-minipass: 2.1.0 + minipass: 5.0.0 + minizlib: 2.1.2 + mkdirp: 1.0.4 + yallist: 4.0.0 + + telejson@6.0.8: + dependencies: + '@types/is-function': 1.0.3 + global: 4.4.0 + is-function: 1.0.2 + is-regex: 1.2.1 + is-symbol: 1.1.1 + isobject: 4.0.0 + lodash: 4.18.1 + memoizerific: 1.11.3 + + temp-dir@1.0.0: {} + + terminal-link@2.1.1: + dependencies: + ansi-escapes: 4.3.2 + supports-hyperlinks: 2.3.0 + + terser-webpack-plugin@1.4.6(webpack@4.47.0): + dependencies: + cacache: 12.0.4 + find-cache-dir: 2.1.0 + is-wsl: 1.1.0 + schema-utils: 1.0.0 + serialize-javascript: 4.0.0 + source-map: 0.6.1 + terser: 4.8.1 + webpack: 4.47.0 + webpack-sources: 1.4.3 + worker-farm: 1.7.0 + + terser-webpack-plugin@4.2.3(webpack@4.47.0): + dependencies: + cacache: 15.3.0 + find-cache-dir: 3.3.2 + jest-worker: 26.6.2 + p-limit: 3.1.0 + schema-utils: 3.3.0 + serialize-javascript: 5.0.1 + source-map: 0.6.1 + terser: 5.47.1 + webpack: 4.47.0 + webpack-sources: 1.4.3 + transitivePeerDependencies: + - bluebird + + terser-webpack-plugin@5.6.0(esbuild@0.25.12)(postcss@8.5.14)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + terser: 5.47.1 + webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + optionalDependencies: + esbuild: 0.25.12 + postcss: 8.5.14 + + terser-webpack-plugin@5.6.0(postcss@8.5.14)(webpack@5.106.2): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + terser: 5.47.1 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + optionalDependencies: + postcss: 8.5.14 + + terser-webpack-plugin@5.6.0(webpack@5.106.2): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + terser: 5.47.1 + webpack: 5.106.2(webpack-cli@4.10.0) + + terser@4.8.1: + dependencies: + acorn: 8.16.0 + commander: 2.20.3 + source-map: 0.6.1 + source-map-support: 0.5.21 + + terser@5.47.1: + dependencies: + '@jridgewell/source-map': 0.3.11 + acorn: 8.16.0 + commander: 2.20.3 + source-map-support: 0.5.21 + + test-exclude@6.0.0: + dependencies: + '@istanbuljs/schema': 0.1.6 + glob: 7.2.3 + minimatch: 3.1.5 + + text-extensions@1.9.0: {} + + text-table@0.2.0: {} + + thread-loader@3.0.4(webpack@5.106.2): + dependencies: + json-parse-better-errors: 1.0.2 + loader-runner: 4.3.2 + loader-utils: 2.0.4 + neo-async: 2.6.2 + schema-utils: 3.3.0 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + + thread-loader@4.0.4(webpack@5.106.2): + dependencies: + json-parse-better-errors: 1.0.2 + loader-runner: 4.3.2 + neo-async: 2.6.2 + schema-utils: 4.3.3 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) + + thread-stream@0.15.2: + dependencies: + real-require: 0.1.0 + + throat@6.0.2: {} + + through2@2.0.5: + dependencies: + readable-stream: 2.3.8 + xtend: 4.0.2 + + through@2.3.8: {} + + thunky@1.1.0: {} + + timers-browserify@2.0.12: + dependencies: + setimmediate: 1.0.5 + + tiny-invariant@1.3.3: {} + + tiny-secp256k1@1.1.7: + dependencies: + bindings: 1.5.0 + bn.js: 4.12.3 + create-hmac: 1.1.7 + elliptic: 6.6.1 + nan: 2.27.0 + + tiny-warning@1.0.3: {} + + tinyglobby@0.2.16: + dependencies: + fdir: 6.5.0(picomatch@4.0.4) + picomatch: 4.0.4 + + tinyrainbow@1.2.0: {} + + tldts-core@7.0.30: {} + + tldts@7.0.30: + dependencies: + tldts-core: 7.0.30 + + tmp@0.2.5: {} + + tmpl@1.0.5: {} + + to-arraybuffer@1.0.1: {} + + to-buffer@1.2.2: + dependencies: + isarray: 2.0.5 + safe-buffer: 5.2.1 + typed-array-buffer: 1.0.3 + + to-object-path@0.3.0: + dependencies: + kind-of: 3.2.2 + + to-regex-range@2.1.1: + dependencies: + is-number: 3.0.0 + repeat-string: 1.6.1 + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + to-regex@3.0.2: + dependencies: + define-property: 2.0.2 + extend-shallow: 3.0.2 + regex-not: 1.0.2 + safe-regex: 1.1.0 + + toggle-selection@1.0.6: {} + + toidentifier@1.0.1: {} + + toposort@2.0.2: {} + + tough-cookie@4.1.4: + dependencies: + psl: 1.15.0 + punycode: 2.3.1 + universalify: 0.2.0 + url-parse: 1.5.10 + + tough-cookie@6.0.1: + dependencies: + tldts: 7.0.30 + + tr46@0.0.3: {} + + tr46@2.1.0: + dependencies: + punycode: 2.3.1 + + tr46@6.0.0: + dependencies: + punycode: 2.3.1 + + trim-lines@3.0.1: {} + + trim-newlines@1.0.0: + optional: true + + trim-newlines@3.0.1: {} + + trim-trailing-lines@1.1.4: {} + + trim@0.0.1: {} + + trough@1.0.5: {} + + trough@2.2.0: {} + + ts-api-utils@2.5.0(typescript@5.9.3): + dependencies: + typescript: 5.9.3 + + ts-dedent@2.2.0: {} + + ts-jest@27.1.5(@babel/core@7.29.0)(@types/jest@27.5.2)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5): + dependencies: + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + jest: 27.5.1 + jest-util: 27.5.1 + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.8.0 + typescript: 4.9.5 + yargs-parser: 20.2.9 + optionalDependencies: + '@babel/core': 7.29.0 + '@types/jest': 27.5.2 + babel-jest: 27.5.1(@babel/core@7.29.0) + esbuild: 0.25.12 + + ts-jest@29.4.9(@babel/core@7.29.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.19.19)(babel-plugin-macros@3.1.0))(typescript@5.9.3): + dependencies: + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + handlebars: 4.7.9 + jest: 29.7.0(@types/node@22.19.19)(babel-plugin-macros@3.1.0) + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.8.0 + type-fest: 4.41.0 + typescript: 5.9.3 + yargs-parser: 21.1.1 + optionalDependencies: + '@babel/core': 7.29.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.29.0) + jest-util: 29.7.0 + + ts-loader@9.5.7(typescript@4.9.5)(webpack@5.106.2): + dependencies: + chalk: 4.1.2 + enhanced-resolve: 5.21.3 + micromatch: 4.0.8 + semver: 7.8.0 + source-map: 0.7.6 + typescript: 4.9.5 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) + + ts-loader@9.5.7(typescript@5.9.3)(webpack@5.106.2): + dependencies: + chalk: 4.1.2 + enhanced-resolve: 5.21.3 + micromatch: 4.0.8 + semver: 7.8.0 + source-map: 0.7.6 + typescript: 5.9.3 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + + ts-mixer@6.0.4: {} + + ts-pnp@1.2.0(typescript@4.9.5): + optionalDependencies: + typescript: 4.9.5 + + tsconfig-paths-webpack-plugin@3.5.2: + dependencies: + chalk: 4.1.2 + enhanced-resolve: 5.21.3 + tsconfig-paths: 3.15.0 + + tsconfig-paths-webpack-plugin@4.2.0: + dependencies: + chalk: 4.1.2 + enhanced-resolve: 5.21.3 + tapable: 2.3.3 + tsconfig-paths: 4.2.0 + + tsconfig-paths@3.15.0: + dependencies: + '@types/json5': 0.0.29 + json5: 1.0.2 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tsconfig-paths@4.2.0: + dependencies: + json5: 2.2.3 + minimist: 1.2.8 + strip-bom: 3.0.0 + + tslib@1.14.1: {} + + tslib@2.8.1: {} + + tslog@3.3.3: + dependencies: + source-map-support: 0.5.21 + + tsutils@3.21.0(typescript@4.9.5): + dependencies: + tslib: 1.14.1 + typescript: 4.9.5 + + tsutils@3.21.0(typescript@5.9.3): + dependencies: + tslib: 1.14.1 + typescript: 5.9.3 + + tty-browserify@0.0.0: {} + + tuf-js@1.1.7: + dependencies: + '@tufjs/models': 1.0.4 + debug: 4.4.3 + make-fetch-happen: 11.1.1 + transitivePeerDependencies: + - supports-color + + tweetnacl-util@0.15.1: {} + + tweetnacl@1.0.3: {} + + type-check@0.4.0: + dependencies: + prelude-ls: 1.2.1 + + type-detect@4.0.8: {} + + type-fest@0.18.1: {} + + type-fest@0.20.2: {} + + type-fest@0.21.3: {} + + type-fest@0.4.1: {} + + type-fest@0.6.0: {} + + type-fest@0.8.1: {} + + type-fest@4.41.0: {} + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + typed-array-buffer@1.0.3: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + is-typed-array: 1.1.15 + + typed-array-byte-length@1.0.3: + dependencies: + call-bind: 1.0.9 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + + typed-array-byte-offset@1.0.4: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + for-each: 0.3.5 + gopd: 1.2.0 + has-proto: 1.2.0 + is-typed-array: 1.1.15 + reflect.getprototypeof: 1.0.10 + + typed-array-length@1.0.7: + dependencies: + call-bind: 1.0.9 + for-each: 0.3.5 + gopd: 1.2.0 + is-typed-array: 1.1.15 + possible-typed-array-names: 1.1.0 + reflect.getprototypeof: 1.0.10 + + typedarray-to-buffer@3.1.5: + dependencies: + is-typedarray: 1.0.0 + + typedarray@0.0.6: {} + + typeforce@1.18.0: {} + + typescript@4.9.5: {} + + typescript@5.9.3: {} + + ufo@1.6.4: {} + + uglify-js@3.19.3: + optional: true + + unbox-primitive@1.1.0: + dependencies: + call-bound: 1.0.4 + has-bigints: 1.1.0 + has-symbols: 1.1.0 + which-boxed-primitive: 1.1.1 + + uncrypto@0.1.3: {} + + undici-types@6.21.0: {} + + undici@7.25.0: {} + + unfetch@4.2.0: {} + + unherit@1.1.3: + dependencies: + inherits: 2.0.4 + xtend: 4.0.2 + + unicode-canonical-property-names-ecmascript@2.0.1: {} + + unicode-match-property-ecmascript@2.0.0: + dependencies: + unicode-canonical-property-names-ecmascript: 2.0.1 + unicode-property-aliases-ecmascript: 2.2.0 + + unicode-match-property-value-ecmascript@2.2.1: {} + + unicode-property-aliases-ecmascript@2.2.0: {} + + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unified@9.2.0: + dependencies: + '@types/unist': 2.0.11 + bail: 1.0.5 + extend: 3.0.2 + is-buffer: 2.0.5 + is-plain-obj: 2.1.0 + trough: 1.0.5 + vfile: 4.2.1 + + union-value@1.0.1: + dependencies: + arr-union: 3.1.0 + get-value: 2.0.6 + is-extendable: 0.1.1 + set-value: 2.0.1 + + unique-filename@1.1.1: + dependencies: + unique-slug: 2.0.2 + + unique-filename@2.0.1: + dependencies: + unique-slug: 3.0.0 + + unique-filename@3.0.0: + dependencies: + unique-slug: 4.0.0 + + unique-slug@2.0.2: + dependencies: + imurmurhash: 0.1.4 + + unique-slug@3.0.0: + dependencies: + imurmurhash: 0.1.4 + + unique-slug@4.0.0: + dependencies: + imurmurhash: 0.1.4 + + unist-builder@2.0.3: {} + + unist-util-generated@1.1.6: {} + + unist-util-is@4.1.0: {} + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@3.1.0: {} + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-remove-position@2.0.1: + dependencies: + unist-util-visit: 2.0.3 + + unist-util-remove@2.1.0: + dependencies: + unist-util-is: 4.1.0 + + unist-util-stringify-position@2.0.3: + dependencies: + '@types/unist': 2.0.11 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@3.1.1: + dependencies: + '@types/unist': 2.0.11 + unist-util-is: 4.1.0 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@2.0.3: + dependencies: + '@types/unist': 2.0.11 + unist-util-is: 4.1.0 + unist-util-visit-parents: 3.1.1 + + unist-util-visit@5.1.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + universal-user-agent@6.0.1: {} + + universalify@0.2.0: {} + + universalify@2.0.1: {} + + unpipe@1.0.0: {} + + unrs-resolver@1.11.1: + dependencies: + napi-postinstall: 0.3.4 + optionalDependencies: + '@unrs/resolver-binding-android-arm-eabi': 1.11.1 + '@unrs/resolver-binding-android-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-arm64': 1.11.1 + '@unrs/resolver-binding-darwin-x64': 1.11.1 + '@unrs/resolver-binding-freebsd-x64': 1.11.1 + '@unrs/resolver-binding-linux-arm-gnueabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm-musleabihf': 1.11.1 + '@unrs/resolver-binding-linux-arm64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-arm64-musl': 1.11.1 + '@unrs/resolver-binding-linux-ppc64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-riscv64-musl': 1.11.1 + '@unrs/resolver-binding-linux-s390x-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-gnu': 1.11.1 + '@unrs/resolver-binding-linux-x64-musl': 1.11.1 + '@unrs/resolver-binding-wasm32-wasi': 1.11.1 + '@unrs/resolver-binding-win32-arm64-msvc': 1.11.1 + '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 + '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 + + unset-value@1.0.0: + dependencies: + has-value: 0.3.1 + isobject: 3.0.1 + + unstorage@1.17.5(idb-keyval@6.2.2): + dependencies: + anymatch: 3.1.3 + chokidar: 5.0.0 + destr: 2.0.5 + h3: 1.15.11 + lru-cache: 11.3.6 + node-fetch-native: 1.6.7 + ofetch: 1.5.1 + ufo: 1.6.4 + optionalDependencies: + idb-keyval: 6.2.2 + + untildify@2.1.0: + dependencies: + os-homedir: 1.0.2 + optional: true + + upath@1.2.0: + optional: true + + upath@2.0.1: {} + + update-browserslist-db@1.2.3(browserslist@4.28.2): + dependencies: + browserslist: 4.28.2 + escalade: 3.2.0 + picocolors: 1.1.1 + + uri-js@4.4.1: + dependencies: + punycode: 2.3.1 + + urix@0.1.0: {} + + url-loader@4.1.1(file-loader@6.2.0(webpack@4.47.0))(webpack@4.47.0): + dependencies: + loader-utils: 2.0.4 + mime-types: 2.1.35 + schema-utils: 3.3.0 + webpack: 4.47.0 + optionalDependencies: + file-loader: 6.2.0(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + + url-loader@4.1.1(file-loader@6.2.0(webpack@5.106.2))(webpack@5.106.2): + dependencies: + loader-utils: 2.0.4 + mime-types: 2.1.35 + schema-utils: 3.3.0 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + optionalDependencies: + file-loader: 6.2.0(webpack@5.106.2) + + url-parse@1.5.10: + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + + url@0.11.4: + dependencies: + punycode: 1.4.1 + qs: 6.15.1 + + use-clipboard-copy@0.2.0(react@19.2.6): + dependencies: + clipboard-copy: 3.2.0 + react: 19.2.6 + + use-sync-external-store@1.6.0(react@19.2.6): + dependencies: + react: 19.2.6 + + use@3.1.1: {} + + util-deprecate@1.0.2: {} + + util.promisify@1.0.0: + dependencies: + define-properties: 1.2.1 + object.getownpropertydescriptors: 2.1.9 + + util@0.10.4: + dependencies: + inherits: 2.0.3 + + util@0.11.1: + dependencies: + inherits: 2.0.3 + + util@0.12.5: + dependencies: + inherits: 2.0.4 + is-arguments: 1.2.0 + is-generator-function: 1.1.2 + is-typed-array: 1.1.15 + which-typed-array: 1.1.20 + + utila@0.4.0: {} + + utility-types@3.11.0: {} + + utils-merge@1.0.1: {} + + uuid-browser@3.1.0: {} + + uuid@11.1.1: {} + + uuid@3.4.0: {} + + uuid@8.3.2: {} + + uuid@9.0.1: {} + + v8-compile-cache@2.3.0: {} + + v8-to-istanbul@8.1.1: + dependencies: + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 1.9.0 + source-map: 0.7.6 + + v8-to-istanbul@9.3.0: + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + '@types/istanbul-lib-coverage': 2.0.6 + convert-source-map: 2.0.0 + + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + + validate-npm-package-name@3.0.0: + dependencies: + builtins: 1.0.3 + + validate-npm-package-name@5.0.0: + dependencies: + builtins: 5.1.0 + + vary@1.1.2: {} + + vfile-location@3.2.0: {} + + vfile-message@2.0.4: + dependencies: + '@types/unist': 2.0.11 + unist-util-stringify-position: 2.0.3 + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@4.2.1: + dependencies: + '@types/unist': 2.0.11 + is-buffer: 2.0.5 + unist-util-stringify-position: 2.0.3 + vfile-message: 2.0.4 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + + victory-vendor@36.9.2: + dependencies: + '@types/d3-array': 3.2.2 + '@types/d3-ease': 3.0.2 + '@types/d3-interpolate': 3.0.4 + '@types/d3-scale': 4.0.9 + '@types/d3-shape': 3.1.8 + '@types/d3-time': 3.0.4 + '@types/d3-timer': 3.0.2 + d3-array: 3.2.4 + d3-ease: 3.0.1 + d3-interpolate: 3.0.1 + d3-scale: 4.0.2 + d3-shape: 3.2.0 + d3-time: 3.1.0 + d3-timer: 3.0.1 + + vm-browserify@1.1.2: {} + + void-elements@3.1.0: {} + + w3c-hr-time@1.0.2: + dependencies: + browser-process-hrtime: 1.0.0 + + w3c-xmlserializer@2.0.0: + dependencies: + xml-name-validator: 3.0.0 + + w3c-xmlserializer@5.0.0: + dependencies: + xml-name-validator: 5.0.0 + + walker@1.0.8: + dependencies: + makeerror: 1.0.12 + + watchpack-chokidar2@2.0.1: + dependencies: + chokidar: 2.1.8 + transitivePeerDependencies: + - supports-color + optional: true + + watchpack@1.7.5: + dependencies: + graceful-fs: 4.2.11 + neo-async: 2.6.2 + optionalDependencies: + chokidar: 3.6.0 + watchpack-chokidar2: 2.0.1 + transitivePeerDependencies: + - supports-color + + watchpack@2.5.1: + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + + wbuf@1.7.3: + dependencies: + minimalistic-assert: 1.0.1 + + wcwidth@1.0.1: + dependencies: + defaults: 1.0.4 + + web-namespaces@1.1.4: {} + + webidl-conversions@3.0.1: {} + + webidl-conversions@5.0.0: {} + + webidl-conversions@6.1.0: {} + + webidl-conversions@8.0.1: {} + + webpack-cli@4.10.0(webpack-dev-server@4.15.2)(webpack@5.106.2): + dependencies: + '@discoveryjs/json-ext': 0.5.7 + '@webpack-cli/configtest': 1.2.0(webpack-cli@4.10.0)(webpack@5.106.2) + '@webpack-cli/info': 1.5.0(webpack-cli@4.10.0) + '@webpack-cli/serve': 1.7.0(webpack-cli@4.10.0)(webpack-dev-server@4.15.2) + colorette: 2.0.20 + commander: 7.2.0 + cross-spawn: 7.0.6 + fastest-levenshtein: 1.0.16 + import-local: 3.2.0 + interpret: 2.2.0 + rechoir: 0.7.1 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack-merge: 5.10.0 + optionalDependencies: + webpack-dev-server: 4.15.2(webpack-cli@4.10.0)(webpack@5.106.2) + + webpack-cli@5.1.4(webpack-dev-server@4.15.2)(webpack@5.106.2): + dependencies: + '@discoveryjs/json-ext': 0.5.7 + '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4)(webpack@5.106.2) + '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4)(webpack@5.106.2) + '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4)(webpack-dev-server@4.15.2)(webpack@5.106.2) + colorette: 2.0.20 + commander: 10.0.1 + cross-spawn: 7.0.6 + envinfo: 7.21.0 + fastest-levenshtein: 1.0.16 + import-local: 3.2.0 + interpret: 3.1.1 + rechoir: 0.8.0 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) + webpack-merge: 5.10.0 + optionalDependencies: + webpack-dev-server: 4.15.2(webpack-cli@5.1.4)(webpack@5.106.2) + + webpack-dev-middleware@3.7.3(webpack@4.47.0): + dependencies: + memory-fs: 0.4.1 + mime: 2.6.0 + mkdirp: 0.5.6 + range-parser: 1.2.1 + webpack: 4.47.0 + webpack-log: 2.0.0 + + webpack-dev-middleware@4.3.0(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)): + dependencies: + colorette: 1.4.0 + mem: 8.1.1 + memfs: 3.5.3 + mime-types: 2.1.35 + range-parser: 1.2.1 + schema-utils: 3.3.0 + webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + + webpack-dev-middleware@5.3.4(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)): + dependencies: + colorette: 2.0.20 + memfs: 3.5.3 + mime-types: 2.1.35 + range-parser: 1.2.1 + schema-utils: 4.3.3 + webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + optional: true + + webpack-dev-middleware@5.3.4(webpack@5.106.2): + dependencies: + colorette: 2.0.20 + memfs: 3.5.3 + mime-types: 2.1.35 + range-parser: 1.2.1 + schema-utils: 4.3.3 + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + + webpack-dev-server@4.15.2(webpack-cli@4.10.0)(webpack@5.106.2): + dependencies: + '@types/bonjour': 3.5.13 + '@types/connect-history-api-fallback': 1.5.4 + '@types/express': 4.17.25 + '@types/serve-index': 1.9.4 + '@types/serve-static': 1.15.10 + '@types/sockjs': 0.3.36 + '@types/ws': 8.18.1 + ansi-html-community: 0.0.8 + bonjour-service: 1.3.0 + chokidar: 3.6.0 + colorette: 2.0.20 + compression: 1.8.1 + connect-history-api-fallback: 2.0.0 + default-gateway: 6.0.3 + express: 4.22.2 + graceful-fs: 4.2.11 + html-entities: 2.6.0 + http-proxy-middleware: 2.0.9(@types/express@4.17.25) + ipaddr.js: 2.4.0 + launch-editor: 2.13.2 + open: 8.4.2 + p-retry: 4.6.2 + rimraf: 3.0.2 + schema-utils: 4.3.3 + selfsigned: 2.4.1 + serve-index: 1.9.2 + sockjs: 0.3.24 + spdy: 4.0.2 + webpack-dev-middleware: 5.3.4(webpack@5.106.2) + ws: 8.20.1 + optionalDependencies: + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.106.2) + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - utf-8-validate + + webpack-dev-server@4.15.2(webpack-cli@5.1.4)(webpack@5.106.2): + dependencies: + '@types/bonjour': 3.5.13 + '@types/connect-history-api-fallback': 1.5.4 + '@types/express': 4.17.25 + '@types/serve-index': 1.9.4 + '@types/serve-static': 1.15.10 + '@types/sockjs': 0.3.36 + '@types/ws': 8.18.1 + ansi-html-community: 0.0.8 + bonjour-service: 1.3.0 + chokidar: 3.6.0 + colorette: 2.0.20 + compression: 1.8.1 + connect-history-api-fallback: 2.0.0 + default-gateway: 6.0.3 + express: 4.22.2 + graceful-fs: 4.2.11 + html-entities: 2.6.0 + http-proxy-middleware: 2.0.9(@types/express@4.17.25) + ipaddr.js: 2.4.0 + launch-editor: 2.13.2 + open: 8.4.2 + p-retry: 4.6.2 + rimraf: 3.0.2 + schema-utils: 4.3.3 + selfsigned: 2.4.1 + serve-index: 1.9.2 + sockjs: 0.3.24 + spdy: 4.0.2 + webpack-dev-middleware: 5.3.4(webpack@5.106.2) + ws: 8.20.1 + optionalDependencies: + webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.106.2) + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - utf-8-validate + + webpack-dev-server@4.15.2(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)): + dependencies: + '@types/bonjour': 3.5.13 + '@types/connect-history-api-fallback': 1.5.4 + '@types/express': 4.17.25 + '@types/serve-index': 1.9.4 + '@types/serve-static': 1.15.10 + '@types/sockjs': 0.3.36 + '@types/ws': 8.18.1 + ansi-html-community: 0.0.8 + bonjour-service: 1.3.0 + chokidar: 3.6.0 + colorette: 2.0.20 + compression: 1.8.1 + connect-history-api-fallback: 2.0.0 + default-gateway: 6.0.3 + express: 4.22.2 + graceful-fs: 4.2.11 + html-entities: 2.6.0 + http-proxy-middleware: 2.0.9(@types/express@4.17.25) + ipaddr.js: 2.4.0 + launch-editor: 2.13.2 + open: 8.4.2 + p-retry: 4.6.2 + rimraf: 3.0.2 + schema-utils: 4.3.3 + selfsigned: 2.4.1 + serve-index: 1.9.2 + sockjs: 0.3.24 + spdy: 4.0.2 + webpack-dev-middleware: 5.3.4(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + ws: 8.20.1 + optionalDependencies: + webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - utf-8-validate + optional: true + + webpack-favicons@1.5.43: + dependencies: + favicons: 7.2.0 + + webpack-filter-warnings-plugin@1.2.1(webpack@4.47.0): + dependencies: + webpack: 4.47.0 + + webpack-hot-middleware@2.26.1: + dependencies: + ansi-html-community: 0.0.8 + html-entities: 2.6.0 + strip-ansi: 6.0.1 + + webpack-log@2.0.0: + dependencies: + ansi-colors: 3.2.4 + uuid: 3.4.0 + + webpack-merge@5.10.0: + dependencies: + clone-deep: 4.0.1 + flat: 5.0.2 + wildcard: 2.0.1 + + webpack-sources@1.4.3: + dependencies: + source-list-map: 2.0.1 + source-map: 0.6.1 + + webpack-sources@3.4.1: {} + + webpack-virtual-modules@0.2.2: + dependencies: + debug: 3.2.7 + transitivePeerDependencies: + - supports-color + + webpack-virtual-modules@0.4.6: {} + + webpack@4.47.0: + dependencies: + '@webassemblyjs/ast': 1.9.0 + '@webassemblyjs/helper-module-context': 1.9.0 + '@webassemblyjs/wasm-edit': 1.9.0 + '@webassemblyjs/wasm-parser': 1.9.0 + acorn: 6.4.2 + ajv: 6.15.0 + ajv-keywords: 3.5.2(ajv@6.15.0) + chrome-trace-event: 1.0.4 + enhanced-resolve: 4.5.0 + eslint-scope: 4.0.3 + json-parse-better-errors: 1.0.2 + loader-runner: 2.4.0 + loader-utils: 1.4.2 + memory-fs: 0.4.1 + micromatch: 3.1.10 + mkdirp: 0.5.6 + neo-async: 2.6.2 + node-libs-browser: 2.2.1 + schema-utils: 1.0.0 + tapable: 1.1.3 + terser-webpack-plugin: 1.4.6(webpack@4.47.0) + watchpack: 1.7.5 + webpack-sources: 1.4.3 + transitivePeerDependencies: + - supports-color + + webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14): + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.9 + '@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.16.0 + acorn-import-phases: 1.0.4(acorn@8.16.0) + browserslist: 4.28.2 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.21.3 + es-module-lexer: 2.1.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + loader-runner: 4.3.2 + mime-db: 1.54.0 + neo-async: 2.6.2 + schema-utils: 4.3.3 + tapable: 2.3.3 + terser-webpack-plugin: 5.6.0(esbuild@0.25.12)(postcss@8.5.14)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + watchpack: 2.5.1 + webpack-sources: 3.4.1 + transitivePeerDependencies: + - '@minify-html/node' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - esbuild + - html-minifier-terser + - lightningcss + - postcss + - uglify-js + + webpack@5.106.2(postcss@8.5.14)(webpack-cli@4.10.0): + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.9 + '@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.16.0 + acorn-import-phases: 1.0.4(acorn@8.16.0) + browserslist: 4.28.2 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.21.3 + es-module-lexer: 2.1.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + loader-runner: 4.3.2 + mime-db: 1.54.0 + neo-async: 2.6.2 + schema-utils: 4.3.3 + tapable: 2.3.3 + terser-webpack-plugin: 5.6.0(postcss@8.5.14)(webpack@5.106.2) + watchpack: 2.5.1 + webpack-sources: 3.4.1 + optionalDependencies: + webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.106.2) + transitivePeerDependencies: + - '@minify-html/node' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - esbuild + - html-minifier-terser + - lightningcss + - postcss + - uglify-js + + webpack@5.106.2(postcss@8.5.14)(webpack-cli@5.1.4): + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.9 + '@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.16.0 + acorn-import-phases: 1.0.4(acorn@8.16.0) + browserslist: 4.28.2 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.21.3 + es-module-lexer: 2.1.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + loader-runner: 4.3.2 + mime-db: 1.54.0 + neo-async: 2.6.2 + schema-utils: 4.3.3 + tapable: 2.3.3 + terser-webpack-plugin: 5.6.0(postcss@8.5.14)(webpack@5.106.2) + watchpack: 2.5.1 + webpack-sources: 3.4.1 + optionalDependencies: + webpack-cli: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.106.2) + transitivePeerDependencies: + - '@minify-html/node' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - esbuild + - html-minifier-terser + - lightningcss + - postcss + - uglify-js + + webpack@5.106.2(webpack-cli@4.10.0): + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.9 + '@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.16.0 + acorn-import-phases: 1.0.4(acorn@8.16.0) + browserslist: 4.28.2 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.21.3 + es-module-lexer: 2.1.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + loader-runner: 4.3.2 + mime-db: 1.54.0 + neo-async: 2.6.2 + schema-utils: 4.3.3 + tapable: 2.3.3 + terser-webpack-plugin: 5.6.0(webpack@5.106.2) + watchpack: 2.5.1 + webpack-sources: 3.4.1 + optionalDependencies: + webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.106.2) + transitivePeerDependencies: + - '@minify-html/node' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - esbuild + - html-minifier-terser + - lightningcss + - postcss + - uglify-js + + websocket-driver@0.7.4: + dependencies: + http-parser-js: 0.5.10 + safe-buffer: 5.2.1 + websocket-extensions: 0.1.4 + + websocket-extensions@0.1.4: {} + + whatwg-encoding@1.0.5: + dependencies: + iconv-lite: 0.4.24 + + whatwg-mimetype@2.3.0: {} + + whatwg-mimetype@5.0.0: {} + + whatwg-url@16.0.1(@noble/hashes@1.8.0): + dependencies: + '@exodus/bytes': 1.15.0(@noble/hashes@1.8.0) + tr46: 6.0.0 + webidl-conversions: 8.0.1 + transitivePeerDependencies: + - '@noble/hashes' + + whatwg-url@5.0.0: + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + + whatwg-url@8.7.0: + dependencies: + lodash: 4.18.1 + tr46: 2.1.0 + webidl-conversions: 6.1.0 + + which-boxed-primitive@1.1.1: + dependencies: + is-bigint: 1.1.0 + is-boolean-object: 1.2.2 + is-number-object: 1.1.1 + is-string: 1.1.1 + is-symbol: 1.1.1 + + which-builtin-type@1.2.1: + dependencies: + call-bound: 1.0.4 + function.prototype.name: 1.1.8 + has-tostringtag: 1.0.2 + is-async-function: 2.1.1 + is-date-object: 1.1.0 + is-finalizationregistry: 1.1.1 + is-generator-function: 1.1.2 + is-regex: 1.2.1 + is-weakref: 1.1.1 + isarray: 2.0.5 + which-boxed-primitive: 1.1.1 + which-collection: 1.0.2 + which-typed-array: 1.1.20 + + which-collection@1.0.2: + dependencies: + is-map: 2.0.3 + is-set: 2.0.3 + is-weakmap: 2.0.2 + is-weakset: 2.0.4 + + which-typed-array@1.1.20: + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.9 + call-bound: 1.0.4 + for-each: 0.3.5 + get-proto: 1.0.1 + gopd: 1.2.0 + has-tostringtag: 1.0.2 + + which@1.3.1: + dependencies: + isexe: 2.0.0 + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + which@3.0.1: + dependencies: + isexe: 2.0.0 + + wide-align@1.1.5: + dependencies: + string-width: 4.2.3 + + widest-line@3.1.0: + dependencies: + string-width: 4.2.3 + + wif@2.0.6: + dependencies: + bs58check: 2.1.2 + + wildcard@2.0.1: {} + + word-wrap@1.2.5: {} + + wordwrap@1.0.0: {} + + worker-farm@1.7.0: + dependencies: + errno: 0.1.8 + + worker-rpc@0.1.1: + dependencies: + microevent.ts: 0.1.1 + + world-countries@5.1.0: {} + + wrap-ansi@6.2.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@7.0.0: + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + + wrap-ansi@8.1.0: + dependencies: + ansi-styles: 6.2.3 + string-width: 5.1.2 + strip-ansi: 7.2.0 + + wrappy@1.0.2: {} + + write-file-atomic@2.4.3: + dependencies: + graceful-fs: 4.2.11 + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + + write-file-atomic@3.0.3: + dependencies: + imurmurhash: 0.1.4 + is-typedarray: 1.0.0 + signal-exit: 3.0.7 + typedarray-to-buffer: 3.1.5 + + write-file-atomic@4.0.2: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + + write-file-atomic@5.0.1: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 4.1.0 + + write-json-file@3.2.0: + dependencies: + detect-indent: 5.0.0 + graceful-fs: 4.2.11 + make-dir: 2.1.0 + pify: 4.0.1 + sort-keys: 2.0.0 + write-file-atomic: 2.4.3 + + write-pkg@4.0.0: + dependencies: + sort-keys: 2.0.0 + type-fest: 0.4.1 + write-json-file: 3.2.0 + + ws@7.5.10: {} + + ws@8.20.1: {} + + x-default-browser@0.4.0: + optionalDependencies: + default-browser-id: 1.0.4 + + xml-name-validator@3.0.0: {} + + xml-name-validator@5.0.0: {} + + xml2js@0.6.2: + dependencies: + sax: 1.6.0 + xmlbuilder: 11.0.1 + + xmlbuilder@11.0.1: {} + + xmlchars@2.2.0: {} + + xstream@11.14.0: + dependencies: + globalthis: 1.0.4 + symbol-observable: 2.0.3 + + xtend@4.0.2: {} + + y18n@4.0.3: {} + + y18n@5.0.8: {} + + yallist@3.1.1: {} + + yallist@4.0.0: {} + + yaml@1.10.3: {} + + yargs-parser@20.2.4: {} + + yargs-parser@20.2.9: {} + + yargs-parser@21.1.1: {} + + yargs@16.2.0: + dependencies: + cliui: 7.0.4 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 20.2.9 + + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + + yocto-queue@0.1.0: {} + + yocto-queue@1.2.2: {} + + yup@0.32.11: + dependencies: + '@babel/runtime': 7.29.2 + '@types/lodash': 4.17.24 + lodash: 4.18.1 + lodash-es: 4.18.1 + nanoclone: 0.2.1 + property-expr: 2.0.6 + toposort: 2.0.2 + + zod@3.25.76: {} + + zustand@4.5.7(@types/react@19.2.14)(immer@10.2.0)(react@19.2.6): + dependencies: + use-sync-external-store: 1.6.0(react@19.2.6) + optionalDependencies: + '@types/react': 19.2.14 + immer: 10.2.0 + react: 19.2.6 + + zwitch@1.0.5: {} + + zwitch@2.0.4: {} + + zxcvbn@4.4.2: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml new file mode 100644 index 0000000000..0dff613df8 --- /dev/null +++ b/pnpm-workspace.yaml @@ -0,0 +1,244 @@ +packages: + - 'ts-packages/*' + - 'nym-wallet' + - 'explorer-v2' + - 'types' + - 'sdk/typescript/packages/mix-fetch/internal-dev' + - 'sdk/typescript/packages/react-components' + - 'sdk/typescript/packages/mui-theme' + +allowBuilds: + '@biomejs/biome': true + '@parcel/watcher': true + '@swc/core': true + core-js: true + core-js-pure: true + es5-ext: true + esbuild: true + fsevents: true + lefthook: true + lmdb: true + msgpackr-extract: true + nx: true + protobufjs: true + sharp: true + tiny-secp256k1: true + unrs-resolver: true + +catalog: + # babel + "@babel/core": "^7.22.10" + "@babel/helper-simple-access": "^7.25.9" + "@babel/runtime": "^7.29.2" + "@babel/plugin-transform-async-to-generator": "^7.22.5" + "@babel/preset-env": "^7.22.10" + "@babel/preset-react": "^7.14.5" + "@babel/preset-typescript": "^7.22.5" + + # emotion + "@emotion/cache": "^11.14.0" + "@emotion/hash": "^0.9.2" + "@emotion/is-prop-valid": "^1.4.0" + "@emotion/memoize": "^0.9.0" + "@emotion/react": "^11.13.5" + "@emotion/serialize": "^1.3.3" + "@emotion/sheet": "^1.4.0" + "@emotion/styled": "^11.13.5" + "@emotion/unitless": "^0.10.0" + "@emotion/use-insertion-effect-with-fallbacks": "^1.2.0" + "@emotion/utils": "^1.4.2" + "@emotion/weak-memoize": "^0.4.0" + + # mui + "@mui/base": "5.0.0-beta.40" + "@mui/icons-material": "^5.2.0" + "@mui/lab": "5.0.0-alpha.170" + "@mui/material": "^5.2.2" + "@mui/private-theming": "^5.17.1" + "@mui/styles": "^5.18.0" + "@mui/system": "^5.18.0" + "@mui/utils": "^5.7.0" + "@mui/x-tree-view": "^7.11.1" + + # tanstack + "@tanstack/react-query": "^5.64.2" + "@tanstack/query-core": "^5.64.2" + + # tauri + "@tauri-apps/api": "^2.10.1" + "@tauri-apps/cli": "^2.10.1" + "@tauri-apps/plugin-clipboard-manager": "^2.3.2" + "@tauri-apps/plugin-opener": "^2.5.3" + "@tauri-apps/plugin-process": "^2.3.1" + "@tauri-apps/plugin-updater": "^2.10.1" + "@tauri-apps/tauri-forage": "^1.0.0-beta.2" + + # types + "@types/big.js": "^6.1.6" + "@types/bs58": "^4.0.1" + "@types/flat": "^5.0.2" + "@types/jest": "^29.5.14" + "@types/lodash": "^4.17.21" + "@types/minimatch": "5.1.2" + "@types/qrcode.react": "^1.0.2" + "@types/react": "^19.2.14" + "@types/react-dom": "^19.2.3" + "@types/semver": "^7.3.8" + "@types/uuid": "^8.3.4" + "@types/ws": "^8.18.1" + "@types/zxcvbn": "^4.4.1" + + # react ecosystem + "@popperjs/core": "^2.11.8" + "hoist-non-react-statics": "^3.3.2" + "prop-types": "^15.8.1" + "react": "^19.2.6" + "react-dom": "^19.2.6" + "react-error-boundary": "^3.1.3" + "react-hook-form": "^7.14.2" + "react-is": "^19.2.6" + "react-refresh": "^0.10.0" + "react-refresh-typescript": "^2.0.2" + "react-smooth": "^4.0.4" + "react-transition-group": "^4.4.5" + "scheduler": "^0.27.0" + "stylis": "^4.2.0" + + # react router + "@remix-run/router": "^1.23.2" + "react-router": "^6.30.3" + "react-router-dom": "6" + "tiny-invariant": "^1.3.3" + + # storybook + "@storybook/addon-docs": "^6.5.8" + "@storybook/addon-actions": "^6.5.8" + "@storybook/addon-essentials": "^6.5.8" + "@storybook/addon-interactions": "^6.5.8" + "@storybook/addon-links": "^6.5.8" + "@storybook/builder-webpack5": "^6.5.8" + "@storybook/manager-webpack5": "^6.5.8" + "@storybook/react": "^6.5.15" + "@storybook/testing-library": "^0.0.9" + + # testing + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.4" + "@testing-library/dom": "^10.4.1" + "@testing-library/jest-dom": "^6.9.1" + "@testing-library/react": "^16.3.2" + + # crypto / cosmjs + "@cosmjs/cosmwasm-stargate": "^0.32.4" + "@cosmjs/math": "^0.32.4" + "@cosmjs/stargate": "^0.32.4" + "axios": "^1.16.0" + "long": "^4.0.0" + "base-x": "^3.0.11" + "base64-js": "^1.5.1" + "bech32": "^1.1.4" + "bn.js": "^5.2.3" + "bs58": "^4.0.1" + "buffer": "^6.0.3" + "ieee754": "^1.2.1" + "safe-buffer": "^5.2.1" + "tweetnacl": "^1.0.3" + "tweetnacl-util": "^0.15.1" + + # d3 / recharts + "d3-array": "^3.2.4" + "d3-color": "^3.1.0" + "d3-format": "^1.4.5" + "d3-interpolate": "^3.0.1" + "d3-path": "^3.1.0" + "d3-scale": "^4.0.2" + "d3-shape": "^3.2.0" + "d3-time": "^3.1.0" + "d3-time-format": "^3.0.0" + "decimal.js-light": "^2.5.1" + "eventemitter3": "^4.0.7" + "fast-equals": "^5.4.0" + "internmap": "^2.0.3" + "ramda": "^0.28.0" + "recharts": "^2.1.13" + "recharts-scale": "^0.4.5" + "victory-vendor": "^36.9.2" + + # typescript-eslint (v5 line — nym-wallet pins v8 separately) + "@typescript-eslint/eslint-plugin": "^5.13.0" + "@typescript-eslint/parser": "^5.13.0" + + # webpack helpers + "@svgr/webpack": "^6.1.1" + "babel-loader": "^8.3.0" + "clean-webpack-plugin": "^4.0.0" + "css-loader": "^6.8.1" + "css-minimizer-webpack-plugin": "^3.0.2" + "dotenv-webpack": "^7.0.3" + "favicons": "^7.0.2" + "favicons-webpack-plugin": "^5.0.2" + "file-loader": "^6.2.0" + "fork-ts-checker-webpack-plugin": "^7.2.1" + "html-webpack-plugin": "^5.5.3" + "mini-css-extract-plugin": "^2.7.6" + "style-loader": "^3.3.3" + "thread-loader": "^3.0.4" + "ts-loader": "^9.4.4" + "tsconfig-paths-webpack-plugin": "^3.5.2" + "url-loader": "^4.1.1" + "webpack": "^5.88.2" + "webpack-cli": "^4.8.0" + "webpack-dev-server": "^4.15.1" + "webpack-favicons": "^1.3.8" + "webpack-merge": "^5.9.0" + + # eslint ecosystem + "eslint": "^9.26.0" + "eslint-config-airbnb": "^19.0.4" + "eslint-config-airbnb-typescript": "^16.1.0" + "eslint-config-prettier": "^8.5.0" + "eslint-import-resolver-root-import": "^1.0.4" + "eslint-plugin-import": "^2.25.4" + "eslint-plugin-jest": "^26.1.1" + "eslint-plugin-jsx-a11y": "^6.5.1" + "eslint-plugin-prettier": "^4.0.0" + "eslint-plugin-react": "^7.29.2" + "eslint-plugin-react-hooks": "^4.3.0" + "eslint-plugin-storybook": "^0.5.12" + + # test + "jest": "^27.1.0" + "ts-jest": "^27.0.5" + + # misc shared + "@hookform/resolvers": "^2.8.0" + "big.js": "^6.2.1" + "clipboard-copy": "^3.2.0" + "clsx": "^1.1.1" + "colornames": "^1.1.1" + "date-fns": "^2.28.0" + "dom-helpers": "^5.2.1" + "flat": "^5.0.2" + "glob": "^10.5.0" + "hex-rgb": "^4.3.0" + "joi": "^17.11.0" + "localforage": "^1.10.0" + "lodash": "^4.17.21" + "lodash.padend": "^4.6.1" + "lodash.trimstart": "^4.5.1" + "lodash.words": "^4.2.0" + "nanoclone": "^0.2.1" + "notistack": "^2.0.3" + "npm-run-all": "^4.1.5" + "prettier": "^2.8.7" + "property-expr": "^2.0.6" + "qr.js": "0.0.0" + "rgb-hex": "^3.0.0" + "rimraf": "^3.0.2" + "semver": "^6.3.0" + "string-to-color": "^2.2.2" + "toposort": "^2.0.2" + "tslib": "^2.8.1" + "use-clipboard-copy": "^0.2.0" + "uuid": "^8.3.2" + "yup": "^0.32.9" + "zxcvbn": "^4.4.2" diff --git a/sdk/typescript/codegen/contract-clients/internal-dev/package.json b/sdk/typescript/codegen/contract-clients/internal-dev/package.json index e41a628208..5667258f5f 100644 --- a/sdk/typescript/codegen/contract-clients/internal-dev/package.json +++ b/sdk/typescript/codegen/contract-clients/internal-dev/package.json @@ -7,7 +7,7 @@ "test": "echo \"Error: no test specified\" && exit 1" }, "dependencies": { - "@nymproject/contract-clients": "file:.." + "@nymproject/contract-clients": "workspace:*" }, "author": "", "license": "ISC" diff --git a/sdk/typescript/codegen/contract-clients/package.json b/sdk/typescript/codegen/contract-clients/package.json index 3be66eff66..cdbc4c0870 100644 --- a/sdk/typescript/codegen/contract-clients/package.json +++ b/sdk/typescript/codegen/contract-clients/package.json @@ -15,12 +15,12 @@ "docs:generate:prod": "typedoc --basePath ./docs/tsdoc/nymproject/contract-clients/", "docs:prod:build": "scripts/build-prod-docs-collect.sh", "docs:serve": "reload -b -d ./docs -p 3000", - "docs:watch": "nodemon --ext ts --watch './src/**/*' --watch './typedoc.json' --exec \"yarn docs:generate\"" + "docs:watch": "nodemon --ext ts --watch './src/**/*' --watch './typedoc.json' --exec \"pnpm docs:generate\"" }, "devDependencies": { "@cosmwasm/ts-codegen": "^1.13.3", "nodemon": "3.0.1", - "npm-run-all": "^4.1.5", + "npm-run-all": "catalog:", "reload": "^3.2.1", "typedoc": "^0.24.8", "typescript": "^4.6.2" diff --git a/sdk/typescript/codegen/contract-clients/scripts/build-prod-docs-collect.sh b/sdk/typescript/codegen/contract-clients/scripts/build-prod-docs-collect.sh index 17382f7fec..94305ddae4 100755 --- a/sdk/typescript/codegen/contract-clients/scripts/build-prod-docs-collect.sh +++ b/sdk/typescript/codegen/contract-clients/scripts/build-prod-docs-collect.sh @@ -7,7 +7,7 @@ set -o pipefail rm -rf ../../../../dist/ts/docs/tsdoc/nymproject/contract-clients || true # run the build -yarn docs:generate:prod +pnpm docs:generate:prod # move the output outside of the yarn/npm workspaces mkdir -p ../../../../dist/ts/docs/tsdoc/nymproject diff --git a/sdk/typescript/examples/chat-app/parcel/package.json b/sdk/typescript/examples/chat-app/parcel/package.json index 7a4d2a2751..2d69b3f320 100644 --- a/sdk/typescript/examples/chat-app/parcel/package.json +++ b/sdk/typescript/examples/chat-app/parcel/package.json @@ -20,22 +20,22 @@ "devDependencies": { "@types/jest": "^27.0.1", "@types/node": "^16.7.13", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", + "@typescript-eslint/eslint-plugin": "catalog:", + "@typescript-eslint/parser": "catalog:", "eslint": "^8.10.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^16.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", - "jest": "^27.1.0", - "mini-css-extract-plugin": "^2.2.2", - "npm-run-all": "^4.1.5", - "prettier": "^2.8.7", - "ts-jest": "^27.0.5", + "eslint-config-airbnb": "catalog:", + "eslint-config-airbnb-typescript": "catalog:", + "eslint-config-prettier": "catalog:", + "eslint-import-resolver-root-import": "catalog:", + "eslint-plugin-import": "catalog:", + "eslint-plugin-jest": "catalog:", + "eslint-plugin-jsx-a11y": "catalog:", + "eslint-plugin-prettier": "catalog:", + "jest": "catalog:", + "mini-css-extract-plugin": "catalog:", + "npm-run-all": "catalog:", + "prettier": "catalog:", + "ts-jest": "catalog:", "typescript": "^4.6.2" }, "private": false, diff --git a/sdk/typescript/examples/chat-app/plain-html/package.json b/sdk/typescript/examples/chat-app/plain-html/package.json index c6fe9695b5..00adf27b73 100644 --- a/sdk/typescript/examples/chat-app/plain-html/package.json +++ b/sdk/typescript/examples/chat-app/plain-html/package.json @@ -19,47 +19,47 @@ "@nymproject/sdk": ">=1.4.1-rc1 || ^1" }, "devDependencies": { - "@babel/core": "^7.15.0", - "@babel/plugin-transform-async-to-generator": "^7.14.5", - "@babel/preset-env": "^7.15.0", - "@babel/preset-typescript": "^7.15.0", + "@babel/core": "catalog:", + "@babel/plugin-transform-async-to-generator": "catalog:", + "@babel/preset-env": "catalog:", + "@babel/preset-typescript": "catalog:", "@types/jest": "^27.0.1", "@types/node": "^16.7.13", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", - "babel-loader": "^8.3.0", + "@typescript-eslint/eslint-plugin": "catalog:", + "@typescript-eslint/parser": "catalog:", + "babel-loader": "catalog:", "babel-plugin-root-import": "^5.1.0", - "clean-webpack-plugin": "^4.0.0", - "css-loader": "^6.7.3", + "clean-webpack-plugin": "catalog:", + "css-loader": "catalog:", "css-minimizer-webpack-plugin": "^3.0.2", - "dotenv-webpack": "^7.0.3", + "dotenv-webpack": "catalog:", "eslint": "^8.10.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^16.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", - "file-loader": "^6.2.0", - "fork-ts-checker-webpack-plugin": "^7.2.1", - "html-webpack-plugin": "^5.3.2", - "jest": "^27.1.0", - "mini-css-extract-plugin": "^2.2.2", - "npm-run-all": "^4.1.5", - "prettier": "^2.8.7", - "style-loader": "^3.3.1", + "eslint-config-airbnb": "catalog:", + "eslint-config-airbnb-typescript": "catalog:", + "eslint-config-prettier": "catalog:", + "eslint-import-resolver-root-import": "catalog:", + "eslint-plugin-import": "catalog:", + "eslint-plugin-jest": "catalog:", + "eslint-plugin-jsx-a11y": "catalog:", + "eslint-plugin-prettier": "catalog:", + "file-loader": "catalog:", + "fork-ts-checker-webpack-plugin": "catalog:", + "html-webpack-plugin": "catalog:", + "jest": "catalog:", + "mini-css-extract-plugin": "catalog:", + "npm-run-all": "catalog:", + "prettier": "catalog:", + "style-loader": "catalog:", "thread-loader": "^3.0.4", - "ts-jest": "^27.0.5", - "ts-loader": "^9.4.2", - "tsconfig-paths-webpack-plugin": "^3.5.2", + "ts-jest": "catalog:", + "ts-loader": "catalog:", + "tsconfig-paths-webpack-plugin": "catalog:", "typescript": "^4.6.2", - "url-loader": "^4.1.1", - "webpack": "^5.75.0", - "webpack-cli": "^4.8.0", - "webpack-dev-server": "^4.5.0", - "webpack-merge": "^5.8.0" + "url-loader": "catalog:", + "webpack": "catalog:", + "webpack-cli": "catalog:", + "webpack-dev-server": "catalog:", + "webpack-merge": "catalog:" }, "private": false } diff --git a/sdk/typescript/examples/chat-app/react-webpack-with-theme-example/package.json b/sdk/typescript/examples/chat-app/react-webpack-with-theme-example/package.json index 0ba3cc677d..6c08c6ce7d 100644 --- a/sdk/typescript/examples/chat-app/react-webpack-with-theme-example/package.json +++ b/sdk/typescript/examples/chat-app/react-webpack-with-theme-example/package.json @@ -16,78 +16,78 @@ "tsc:watch": "tsc --watch" }, "dependencies": { - "@mui/icons-material": "^5.5.0", + "@mui/icons-material": "catalog:", "@mui/lab": "^5.0.0-alpha.72", "@mui/material": "^5.0.1", "@mui/styles": "^5.0.1", "@nymproject/sdk": ">=1.4.1-rc1 || ^1", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "react": "catalog:", + "react-dom": "catalog:", "react-dropzone": "^14.2.3", "react-mui-dropzone": "^4.0.6", "use-clipboard-copy": "^0.2.0" }, "devDependencies": { - "@babel/core": "^7.15.0", - "@babel/plugin-transform-async-to-generator": "^7.14.5", - "@babel/preset-env": "^7.15.0", - "@babel/preset-react": "^7.14.5", - "@babel/preset-typescript": "^7.15.0", + "@babel/core": "catalog:", + "@babel/plugin-transform-async-to-generator": "catalog:", + "@babel/preset-env": "catalog:", + "@babel/preset-react": "catalog:", + "@babel/preset-typescript": "catalog:", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.4", - "@svgr/webpack": "^6.1.1", + "@svgr/webpack": "catalog:", "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^12.0.0", "@types/jest": "^27.0.1", "@types/node": "^16.7.13", - "@types/react": "^18.0.26", - "@types/react-dom": "^18.0.10", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", - "babel-loader": "^8.3.0", + "@types/react": "catalog:", + "@types/react-dom": "catalog:", + "@typescript-eslint/eslint-plugin": "catalog:", + "@typescript-eslint/parser": "catalog:", + "babel-loader": "catalog:", "babel-plugin-root-import": "^5.1.0", - "clean-webpack-plugin": "^4.0.0", - "css-loader": "^6.7.3", + "clean-webpack-plugin": "catalog:", + "css-loader": "catalog:", "css-minimizer-webpack-plugin": "^3.0.2", - "dotenv-webpack": "^7.0.3", + "dotenv-webpack": "catalog:", "eslint": "^8.10.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^16.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-react": "^7.29.2", - "eslint-plugin-react-hooks": "^4.3.0", - "favicons": "^7.0.2", - "favicons-webpack-plugin": "^5.0.2", - "file-loader": "^6.2.0", - "fork-ts-checker-webpack-plugin": "^7.2.1", - "html-webpack-plugin": "^5.3.2", - "jest": "^27.1.0", - "mini-css-extract-plugin": "^2.2.2", - "npm-run-all": "^4.1.5", - "prettier": "^2.8.7", + "eslint-config-airbnb": "catalog:", + "eslint-config-airbnb-typescript": "catalog:", + "eslint-config-prettier": "catalog:", + "eslint-import-resolver-root-import": "catalog:", + "eslint-plugin-import": "catalog:", + "eslint-plugin-jest": "catalog:", + "eslint-plugin-jsx-a11y": "catalog:", + "eslint-plugin-prettier": "catalog:", + "eslint-plugin-react": "catalog:", + "eslint-plugin-react-hooks": "catalog:", + "favicons": "catalog:", + "favicons-webpack-plugin": "catalog:", + "file-loader": "catalog:", + "fork-ts-checker-webpack-plugin": "catalog:", + "html-webpack-plugin": "catalog:", + "jest": "catalog:", + "mini-css-extract-plugin": "catalog:", + "npm-run-all": "catalog:", + "prettier": "catalog:", "react-refresh-typescript": "^2.0.3", - "style-loader": "^3.3.1", + "style-loader": "catalog:", "thread-loader": "^3.0.4", - "ts-jest": "^27.0.5", - "ts-loader": "^9.4.2", - "tsconfig-paths-webpack-plugin": "^3.5.2", + "ts-jest": "catalog:", + "ts-loader": "catalog:", + "tsconfig-paths-webpack-plugin": "catalog:", "typescript": "^4.6.2", - "url-loader": "^4.1.1", - "webpack": "^5.75.0", - "webpack-cli": "^4.8.0", - "webpack-dev-server": "^4.5.0", - "webpack-favicons": "^1.3.8", - "webpack-merge": "^5.8.0" + "url-loader": "catalog:", + "webpack": "catalog:", + "webpack-cli": "catalog:", + "webpack-dev-server": "catalog:", + "webpack-favicons": "catalog:", + "webpack-merge": "catalog:" }, "private": false, "overrides": { - "@types/react": "^18.0.26", - "@types/react-dom": "^18.0.10", - "react": "^18.2.0", - "react-dom": "^18.2.0" + "@types/react": "^19.2.14", + "@types/react-dom": "^19.2.3", + "react": "^19.2.6", + "react-dom": "^19.2.6" } } diff --git a/sdk/typescript/examples/chrome-extension/README.md b/sdk/typescript/examples/chrome-extension/README.md deleted file mode 100644 index 8d7359e8c3..0000000000 --- a/sdk/typescript/examples/chrome-extension/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# Nym Chrome Extension Example - -This is an example of how Nym can be used within the context of a Chrome extension. - -## Running the example - -1. Copy a build of the Nym TypeScript SDK (ESM version) into `./sdk`. -2. Navigate to `chrome://extensions` in Google Chrome. -3. Enable "Developer mode" (top right of the page). -4. Click on "Load unpacked" (top left of the page). -5. Load this extension folder. - -## How does it work? - -The Nym Mixnet Client runs a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) that wraps -a WASM library that builds and encrypts Sphinx packets in the browser to send over the Nym mixnet: - -![Sphinx packet](../docs/worker.svg) - -The WASM code encrypts each layer of the Sphinx packet in the browser, before sending the Sphinx packet over a websocket to the ingress gateway: - -![Sphinx packet](../docs/sphinx.svg) diff --git a/sdk/typescript/examples/chrome-extension/manifest.json b/sdk/typescript/examples/chrome-extension/manifest.json deleted file mode 100644 index 5f83d5c014..0000000000 --- a/sdk/typescript/examples/chrome-extension/manifest.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "Nym Chrome Extension Example", - "description": "An example demonstrating how to integrate the Nym TypeScript SDK in the context of a Google Chrome browser extension.", - "version": "1.0", - "manifest_version": 3, - "icons": { - "48": "icon.png" - }, - "content_security_policy": { - "extension_pages": "script-src 'self' 'wasm-unsafe-eval'; object-src 'self';" - }, - "action": { - "default_title": "Nym Chrome Extension Example", - "default_icon": "icon.png", - "default_popup": "popup.html" - } -} diff --git a/sdk/typescript/examples/chrome-extension/package.json b/sdk/typescript/examples/chrome-extension/package.json deleted file mode 100644 index 8fd5a619af..0000000000 --- a/sdk/typescript/examples/chrome-extension/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "@nymproject/sdk-example-chrome-extension", - "version": "1.0.5", - "description": "This is an example of how Nym can be used within the context of a Chrome extension.", - "license": "ISC", - "author": "", - "main": "index.js", - "scripts": { - "build": "webpack" - }, - "dependencies": { - "@nymproject/sdk": ">=1.4.1-rc1 || ^1" - }, - "devDependencies": { - "clean-webpack-plugin": "^4.0.0", - "copy-webpack-plugin": "^11.0.0", - "webpack": "^5.88.1", - "webpack-cli": "^5.1.4" - }, - "private": false -} diff --git a/sdk/typescript/examples/chrome-extension/popup.css b/sdk/typescript/examples/chrome-extension/popup.css deleted file mode 100644 index 491c7dc3c7..0000000000 --- a/sdk/typescript/examples/chrome-extension/popup.css +++ /dev/null @@ -1,8 +0,0 @@ -body { - width: 800px; - min-height: 400px; -} - -#editdialog input { - width: 100%; -} \ No newline at end of file diff --git a/sdk/typescript/examples/chrome-extension/popup.html b/sdk/typescript/examples/chrome-extension/popup.html deleted file mode 100644 index 9245988b60..0000000000 --- a/sdk/typescript/examples/chrome-extension/popup.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - -

-

-

-

-

Send messages from your browser, through the mixnet, and to the recipient using the "send" button.

-

- Sent messages show in blue, received messages - show in green. -

-
-

-
-

- - diff --git a/sdk/typescript/examples/chrome-extension/src/dom-utils.js b/sdk/typescript/examples/chrome-extension/src/dom-utils.js deleted file mode 100644 index 322606c241..0000000000 --- a/sdk/typescript/examples/chrome-extension/src/dom-utils.js +++ /dev/null @@ -1,66 +0,0 @@ -// dom-utils.js -// Contains utility functionality to help manipulate the DOM elements necessary to demonstrate the Nym example. - -/** - * Create a Sphinx packet and send it to the mixnet through the gateway node. - * - * Message and recipient are taken from the values in the user interface. - * - * @param {Client} nymClient the nym client to use for message sending - */ -async function sendMessageTo(nym) { - const message = document.getElementById('message').value; - const recipient = document.getElementById('recipient').value; - await nym.client.send({ - payload: { - message, - mimeType: 'text/plain' - }, - recipient - }); - displaySend(message); -} - -/** - * Display messages that have been sent up the websocket. Colours them blue. - * - * @param {string} message - */ -function displaySend(message) { - const timestamp = new Date().toISOString().substr(11, 12); - const sendDiv = document.createElement('div'); - const paragraph = document.createElement('p'); - paragraph.setAttribute('style', 'color: blue'); - const paragraphContent = document.createTextNode(`${timestamp} sent >>> ${message}`); - paragraph.appendChild(paragraphContent); - sendDiv.appendChild(paragraph); - document.getElementById('output')?.appendChild(sendDiv); -} - -/** - * Display received text messages in the browser. Colour them green. - * - * @param {string} message - */ -function displayReceived(message) { - const content = message; - const timestamp = new Date().toLocaleTimeString(); - const receivedDiv = document.createElement('div'); - const paragraph = document.createElement('p'); - paragraph.setAttribute('style', 'color: green'); - const paragraphContent = document.createTextNode(`${timestamp} received >>> ${content}`); - paragraph.appendChild(paragraphContent); - receivedDiv.appendChild(paragraph); - document.getElementById('output')?.appendChild(receivedDiv); -} - -/** - * Display the nymClient's sender address in the user interface - * - * @param {Client} nymClient - */ -function displaySenderAddress(address) { - document.getElementById('sender').value = address; -} - -export { sendMessageTo, displaySend, displayReceived , displaySenderAddress } \ No newline at end of file diff --git a/sdk/typescript/examples/chrome-extension/src/main.js b/sdk/typescript/examples/chrome-extension/src/main.js deleted file mode 100644 index 5ead4f6c67..0000000000 --- a/sdk/typescript/examples/chrome-extension/src/main.js +++ /dev/null @@ -1,53 +0,0 @@ -// main.js -// Simple example of how to load Nym's TypeScript SDK and bind it to a DOM. -// Look at dom-utils.js for the DOM utility functionality referenced here. - -// Import the Nym mixnet ESM module. -import { createNymMixnetClient } from '@nymproject/sdk'; - -// Import the DOM utility functionality. -import { displaySenderAddress, displayReceived, sendMessageTo } from './dom-utils.js'; - -async function main() { - // Initialize the Nym mixnet client. - let nymClient = await createNymMixnetClient(); - if (!nymClient) { - console.error('Oh no! Could not create client'); - return; - } - - const nymApiUrl = 'https://validator.nymtech.net/api'; - const preferredGatewayIdentityKey = 'E3mvZTHQCdBvhfr178Swx9g4QG3kkRUun7YnToLMcMbM'; - - // subscribe to connect event, so that we can show the client's address - nymClient.events.subscribeToConnected((e) => { - if (e.args.address) { - displaySenderAddress(e.args.address); - } - }); - - // subscribe to message received events and show any string messages received - nymClient.events.subscribeToTextMessageReceivedEvent((e) => { - displayReceived(e.args.payload); - }); - - const sendButton = document.querySelector('#send-button'); - if (sendButton) { - sendButton.onclick = function () { - if (nymClient) { - sendMessageTo(nymClient); - } - }; - } - - nymClient.events.subscribeToRawMessageReceivedEvent((e) => console.log('Received: ', e.args.payload)); - await nymClient.client.start({ - clientId: 'My awesome client', - nymApiUrl, - preferredGatewayIdentityKey, - }); -} - -window.addEventListener('DOMContentLoaded', () => { - main(); -}); diff --git a/sdk/typescript/examples/chrome-extension/tsconfig.json b/sdk/typescript/examples/chrome-extension/tsconfig.json deleted file mode 100644 index 704db85a1c..0000000000 --- a/sdk/typescript/examples/chrome-extension/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "dist", - "declaration": false, - "declarationMap": false - }, - "exclude": ["node_modules", "dist"] -} diff --git a/sdk/typescript/examples/chrome-extension/webpack.config.js b/sdk/typescript/examples/chrome-extension/webpack.config.js deleted file mode 100644 index d1c7c473c7..0000000000 --- a/sdk/typescript/examples/chrome-extension/webpack.config.js +++ /dev/null @@ -1,25 +0,0 @@ -// Webpack configuration for the Chrome extension example - -const path = require('path'); -const CopyWebpackPlugin = require('copy-webpack-plugin'); -const { CleanWebpackPlugin } = require('clean-webpack-plugin'); - -module.exports = { - mode: 'production', - entry: { - main: './src/main.js', - }, - output: { - path: path.resolve(__dirname, 'dist'), - }, - plugins: [ - new CleanWebpackPlugin(), - new CopyWebpackPlugin({ - patterns: [ - 'manifest.json', - 'popup.html', - { from: path.resolve(__dirname, '../../../../assets/favicon/favicon.png'), to: 'icon.png' }, - ], - }), - ], -}; diff --git a/sdk/typescript/examples/firefox-extension/.gitignore b/sdk/typescript/examples/firefox-extension/.gitignore deleted file mode 100644 index 6e8096e78b..0000000000 --- a/sdk/typescript/examples/firefox-extension/.gitignore +++ /dev/null @@ -1 +0,0 @@ -sdk/index.js \ No newline at end of file diff --git a/sdk/typescript/examples/firefox-extension/README.md b/sdk/typescript/examples/firefox-extension/README.md deleted file mode 100644 index 27678813c6..0000000000 --- a/sdk/typescript/examples/firefox-extension/README.md +++ /dev/null @@ -1,35 +0,0 @@ -# Nym Firefox Extension Example - -This is an example of how Nym can be used within the context of a Mozilla Firefox extension. - -## Running the example - -First, build the Nym SDK: - -From the SDK directory `sdk/typescript/packages/sdk` run: - -```js -npm run build:local -``` - -Then, from the example directory `sdk/typescript/examples/firefox-extension` run: - -```js -npm install -npm run build -``` - -## Workers - -Firefox browser extensions cannot run inline web workers. In order to overcome this limitation, the Nym Firefox Extension Example imports workers from the SDK and uses Webpack's `worker-loader` to allow the worker's to be bundled inline into the extension. In order for webpack to include the workers in the build, they are imported as modules in the `src/index.js` file: - -## How does it work? - -The Nym Mixnet Client runs a [Web Worker](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) that wraps -a WASM library that builds and encrypts Sphinx packets in the browser to send over the Nym mixnet: - -![Sphinx packet](../docs/worker.svg) - -The WASM code encrypts each layer of the Sphinx packet in the browser, before sending the Sphinx packet over a websocket to the ingress gateway: - -![Sphinx packet](../docs/sphinx.svg) diff --git a/sdk/typescript/examples/firefox-extension/manifest.json b/sdk/typescript/examples/firefox-extension/manifest.json deleted file mode 100644 index 5829265a88..0000000000 --- a/sdk/typescript/examples/firefox-extension/manifest.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "manifest_version": 3, - "name": "Nym Firefox Extension Example", - "version": "1.0", - "description": "An example demonstrating how to integrate the Nym TypeScript SDK in the context of a Mozilla Firefox browser extension.", - "icons": { - "48": "icon.png" - }, - "permissions": [], - "content_security_policy": { - "extension_pages": "script-src 'self' 'wasm-unsafe-eval';" - }, - "background": { - "scripts": ["background.js"] - }, - "action": { - "default_icon": { - "32": "icon.png" - }, - "default_title": "Nym Firefox Extension Example", - "default_popup": "popup.html" - } -} diff --git a/sdk/typescript/examples/firefox-extension/package.json b/sdk/typescript/examples/firefox-extension/package.json deleted file mode 100644 index 36974a7856..0000000000 --- a/sdk/typescript/examples/firefox-extension/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "@nymproject/sdk-example-firefox-extension", - "version": "1.0.5", - "description": "This is an example of how Nym can be used within the context of a Firefox extension.", - "license": "ISC", - "author": "", - "main": "index.js", - "scripts": { - "build": "yarn webpack" - }, - "dependencies": { - "@nymproject/sdk": ">=1.4.1-rc1 || ^1" - }, - "devDependencies": { - "copy-webpack-plugin": "^11.0.0", - "webpack": "^5.88.1", - "webpack-cli": "^5.1.4", - "worker-loader": "^3.0.8" - }, - "private": false -} diff --git a/sdk/typescript/examples/firefox-extension/popup.css b/sdk/typescript/examples/firefox-extension/popup.css deleted file mode 100644 index 491c7dc3c7..0000000000 --- a/sdk/typescript/examples/firefox-extension/popup.css +++ /dev/null @@ -1,8 +0,0 @@ -body { - width: 800px; - min-height: 400px; -} - -#editdialog input { - width: 100%; -} \ No newline at end of file diff --git a/sdk/typescript/examples/firefox-extension/popup.html b/sdk/typescript/examples/firefox-extension/popup.html deleted file mode 100644 index 976e0c54f4..0000000000 --- a/sdk/typescript/examples/firefox-extension/popup.html +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - - - -

-

-

-

-

Send messages from your browser, through the mixnet, and to the recipient using the "send" button.

-

- Sent messages show in blue, received messages - show in green. -

-
-

-
-

- - diff --git a/sdk/typescript/examples/firefox-extension/src/background.js b/sdk/typescript/examples/firefox-extension/src/background.js deleted file mode 100644 index c0a6ce8a35..0000000000 --- a/sdk/typescript/examples/firefox-extension/src/background.js +++ /dev/null @@ -1,107 +0,0 @@ -// main.js -// Simple example of how to load Nym's TypeScript SDK and bind it to a DOM. -// Look at dom-utils.js for the DOM utility functionality referenced here. - -// Import the Nym mixnet ESM module. -// Import The web workers for the Nym mixnet ESM module.These are required for to run the Nym mixnet client. - -import { createNymMixnetClient } from '../../../packages/sdk/dist/full-fat/index.js'; -import '../../../packages/sdk/dist/full-fat/web-worker-0.js'; -import '../../../packages/sdk/dist/full-fat/web-worker-1.js'; - -const backgroundState = { - isReady: false, - address: '', - recipient: '', - messageLog: [], -}; - -async function initBackground() { - // Initialize the Nym mixnet client. - let nymClient = await createNymMixnetClient().catch((err) => { - console.log(err); - }); - if (!nymClient) { - console.error('Oh no! Could not create client'); - return; - } - const nymApiUrl = 'https://validator.nymtech.net/api'; - const preferredGatewayIdentityKey = 'E3mvZTHQCdBvhfr178Swx9g4QG3kkRUun7YnToLMcMbM'; - - // subscribe to connect event, so that we can show the client's address - nymClient.events.subscribeToConnected((e) => { - if (e.args.address) { - backgroundState.address = e.args.address; - browser.runtime.sendMessage({ - type: 'displaySenderAddress', - message: backgroundState.address, - }); - } - }); - - // subscribe to message received events and show any string messages received - nymClient.events.subscribeToTextMessageReceivedEvent((e) => { - backgroundState.messageLog.push({ - type: 'received', - message: e.args.payload, - }); - browser.runtime.sendMessage({ - type: 'displayReceived', - message: e.args.payload, - }); - }); - - nymClient.events.subscribeToRawMessageReceivedEvent((e) => console.log('Received: ', e.args.payload)); - await nymClient.client.start({ - clientId: 'My awesome client', - nymApiUrl, - preferredGatewayIdentityKey, - }); - browser.runtime.onMessage.addListener(async (data) => { - switch (data.type) { - case 'nymClientSendMessage': - if (nymClient) { - await nymClient.client.send({ - payload: { - message: data.message, - mimeType: 'text/plain', - }, - recipient: data.recipient, - }); - backgroundState.messageLog.push({ - type: 'sent', - message: data.message, - }); - break; - } - } - }); - backgroundState.isReady = true; -} - -window.addEventListener('DOMContentLoaded', () => { - browser.runtime.onMessage.addListener((data) => { - switch (data.type) { - case 'popupReady': - if (backgroundState.isReady) { - browser.runtime.sendMessage({ - type: 'displaySenderAddress', - message: backgroundState.address, - }); - browser.runtime.sendMessage({ - type: 'displayMessageLog', - message: backgroundState.messageLog, - }); - browser.runtime.sendMessage({ - type: 'updateRecipient', - message: backgroundState.recipient, - }); - } else { - initBackground(); - } - break; - case 'updateRecipient': - backgroundState.recipient = data.message; - } - }); -}); diff --git a/sdk/typescript/examples/firefox-extension/src/background.ts b/sdk/typescript/examples/firefox-extension/src/background.ts deleted file mode 100644 index 6d15c9ce9f..0000000000 --- a/sdk/typescript/examples/firefox-extension/src/background.ts +++ /dev/null @@ -1,114 +0,0 @@ -// main.js -// Simple example of how to load Nym's TypeScript SDK and bind it to a DOM. -// Look at dom-utils.js for the DOM utility functionality referenced here. - -// Import the Nym mixnet ESM module. -// Import The web workers for the Nym mixnet ESM module.These are required for to run the Nym mixnet client. - -import { createNymMixnetClient } from '../../../packages/sdk/dist/full-fat/index.js'; -import '../../../packages/sdk/dist/full-fat/web-worker-0.js'; -import '../../../packages/sdk/dist/full-fat/web-worker-1.js'; - -export type BackgroundState = { - isReady: boolean; - address: string; - recipient: string; - messageLog: { type: string; message: string }[]; -}; - -const backgroundState: BackgroundState = { - isReady: false, - address: '', - recipient: '', - messageLog: [], -}; - -async function initBackground() { - // Initialize the Nym mixnet client. - let nymClient = await createNymMixnetClient().catch((err) => { - console.log(err); - }); - if (!nymClient) { - console.error('Oh no! Could not create client'); - return; - } - const nymApiUrl = 'https://validator.nymtech.net/api'; - const preferredGatewayIdentityKey = 'E3mvZTHQCdBvhfr178Swx9g4QG3kkRUun7YnToLMcMbM'; - - // subscribe to connect event, so that we can show the client's address - nymClient.events.subscribeToConnected((e) => { - if (e.args.address) { - backgroundState.address = e.args.address; - browser.runtime.sendMessage({ - type: 'displaySenderAddress', - message: backgroundState.address, - }); - } - }); - - // subscribe to message received events and show any string messages received - nymClient.events.subscribeToTextMessageReceivedEvent((e) => { - backgroundState.messageLog.push({ - type: 'received', - message: e.args.payload, - }); - browser.runtime.sendMessage({ - type: 'displayReceived', - message: e.args.payload, - }); - }); - - nymClient.events.subscribeToRawMessageReceivedEvent((e) => console.log('Received: ', e.args.payload)); - await nymClient.client.start({ - clientId: 'My awesome client', - nymApiUrl, - preferredGatewayIdentityKey, - }); - browser.runtime.onMessage.addListener(async (data) => { - switch (data.type) { - case 'nymClientSendMessage': - if (nymClient) { - await nymClient.client.send({ - payload: { - message: data.message, - mimeType: 'text/plain', - }, - recipient: data.recipient, - }); - backgroundState.messageLog.push({ - type: 'sent', - message: data.message, - }); - break; - } - } - }); - backgroundState.isReady = true; -} - -window.addEventListener('DOMContentLoaded', () => { - browser.runtime.onMessage.addListener((data) => { - switch (data.type) { - case 'popupReady': - if (backgroundState.isReady) { - browser.runtime.sendMessage({ - type: 'displaySenderAddress', - message: backgroundState.address, - }); - browser.runtime.sendMessage({ - type: 'displayMessageLog', - message: backgroundState.messageLog, - }); - browser.runtime.sendMessage({ - type: 'updateRecipient', - message: backgroundState.recipient, - }); - } else { - initBackground(); - } - break; - case 'updateRecipient': - backgroundState.recipient = data.message; - } - }); -}); diff --git a/sdk/typescript/examples/firefox-extension/src/dom-utils.js b/sdk/typescript/examples/firefox-extension/src/dom-utils.js deleted file mode 100644 index 859dcdac2c..0000000000 --- a/sdk/typescript/examples/firefox-extension/src/dom-utils.js +++ /dev/null @@ -1,74 +0,0 @@ -// dom-utils.js -// Contains utility functionality to help manipulate the DOM elements necessary to demonstrate the Nym example. - -/** - * Create a Sphinx packet and send it to the mixnet through the gateway node. - * - * Message and recipient are taken from the values in the user interface. - * - * @param {Client} nymClient the nym client to use for message sending - */ -async function sendMessageTo() { - const message = document.getElementById('message').value; - const recipient = document.getElementById('recipient').value; - browser.runtime.sendMessage({ - type: 'nymClientSendMessage', - message, - recipient, - }); - displaySend(message); -} - -/** - * Display messages that have been sent up the websocket. Colours them blue. - * - * @param {string} message - */ -function displaySend(message) { - const timestamp = new Date().toISOString().substr(11, 12); - const sendDiv = document.createElement('div'); - const paragraph = document.createElement('p'); - paragraph.setAttribute('style', 'color: blue'); - const paragraphContent = document.createTextNode(`${timestamp} sent >>> ${message}`); - paragraph.appendChild(paragraphContent); - sendDiv.appendChild(paragraph); - document.getElementById('output')?.appendChild(sendDiv); -} - -/** - * Display received text messages in the browser. Colour them green. - * - * @param {string} message - */ -function displayReceived(message) { - const content = message; - const timestamp = new Date().toLocaleTimeString(); - const receivedDiv = document.createElement('div'); - const paragraph = document.createElement('p'); - paragraph.setAttribute('style', 'color: green'); - const paragraphContent = document.createTextNode(`${timestamp} received >>> ${content}`); - paragraph.appendChild(paragraphContent); - receivedDiv.appendChild(paragraph); - document.getElementById('output')?.appendChild(receivedDiv); -} - -/** - * Display the nymClient's sender address in the user interface - * - * @param {Client} nymClient - */ -function displaySenderAddress(address) { - document.getElementById('sender').value = address; -} - -function displayMessageLog(messageLog) { - for (let i = 0; i < messageLog.length; i++) { - if (messageLog[i].type === 'sent') { - displaySend(messageLog[i].message); - } else if (messageLog[i].type === 'received') { - displayReceived(messageLog[i].message); - } - } -} - -export { sendMessageTo, displaySend, displayReceived, displaySenderAddress, displayMessageLog }; diff --git a/sdk/typescript/examples/firefox-extension/src/dom-utils.ts b/sdk/typescript/examples/firefox-extension/src/dom-utils.ts deleted file mode 100644 index 89b21bc0c5..0000000000 --- a/sdk/typescript/examples/firefox-extension/src/dom-utils.ts +++ /dev/null @@ -1,35 +0,0 @@ -// dom-utils.js -// Contains utility functionality to help manipulate the DOM elements necessary to demonstrate the Nym example. - -import { BackgroundState } from './background'; -import { displayReceived, displaySend, displaySenderAddress } from '../../shared/dom-utils'; - -/** - * Create a Sphinx packet and send it to the mixnet through the gateway node. - * - * Message and recipient are taken from the values in the user interface. - * - * @param {Client} nymClient the nym client to use for message sending - */ -async function sendMessageTo() { - const message = (document.getElementById('message') as HTMLFormElement).value; - const recipient = (document.getElementById('recipient') as HTMLFormElement).value; - browser.runtime.sendMessage({ - type: 'nymClientSendMessage', - message, - recipient, - }); - displaySend(message); -} - -function displayMessageLog(messageLog: BackgroundState['messageLog']) { - for (let i = 0; i < messageLog.length; i++) { - if (messageLog[i].type === 'sent') { - displaySend(messageLog[i].message); - } else if (messageLog[i].type === 'received') { - displayReceived(messageLog[i].message); - } - } -} - -export { sendMessageTo, displaySend, displayReceived, displaySenderAddress, displayMessageLog }; diff --git a/sdk/typescript/examples/firefox-extension/src/popup.js b/sdk/typescript/examples/firefox-extension/src/popup.js deleted file mode 100644 index 8126f21827..0000000000 --- a/sdk/typescript/examples/firefox-extension/src/popup.js +++ /dev/null @@ -1,40 +0,0 @@ -// Import the DOM utility functionality. -import { displaySenderAddress, displayReceived, sendMessageTo, displayMessageLog } from './dom-utils.js'; - -window.addEventListener('DOMContentLoaded', () => { - const sendButton = document.querySelector('#send-button'); - if (sendButton) { - sendButton.onclick = function () { - sendMessageTo(); - }; - } - const recipient = document.getElementById('recipient'); - recipient.onchange = () => { - browser.runtime.sendMessage({ - type: 'updateRecipient', - message: recipient.value, - }); - }; - browser.runtime.onMessage.addListener((data) => { - switch (data.type) { - case 'displaySenderAddress': - displaySenderAddress(data.message); - break; - case 'displayReceived': - displayReceived(data.message); - break; - case 'sendMessageTo': - sendMessageTo(data.message); - break; - case 'displayMessageLog': - displayMessageLog(data.message); - break; - case 'updateRecipient': - recipient.value = data.message; - } - }); - browser.runtime.sendMessage({ - type: 'popupReady', - message: '', - }); -}); diff --git a/sdk/typescript/examples/firefox-extension/src/popup.ts b/sdk/typescript/examples/firefox-extension/src/popup.ts deleted file mode 100644 index 9c20100bd8..0000000000 --- a/sdk/typescript/examples/firefox-extension/src/popup.ts +++ /dev/null @@ -1,40 +0,0 @@ -// Import the DOM utility functionality. -import { displaySenderAddress, displayReceived, sendMessageTo, displayMessageLog } from './dom-utils'; - -window.addEventListener('DOMContentLoaded', () => { - const sendButton = document.querySelector('#send-button') as HTMLButtonElement; - if (sendButton) { - sendButton.onclick = function () { - sendMessageTo(); - }; - } - const recipient = document.getElementById('recipient') as HTMLFormElement; - recipient.onchange = () => { - browser.runtime.sendMessage({ - type: 'updateRecipient', - message: recipient.value, - }); - }; - browser.runtime.onMessage.addListener((data) => { - switch (data.type) { - case 'displaySenderAddress': - displaySenderAddress(data.message); - break; - case 'displayReceived': - displayReceived(data.message); - break; - // case 'sendMessageTo': - // sendMessageTo(data.message); - // break; - case 'displayMessageLog': - displayMessageLog(data.message); - break; - case 'updateRecipient': - recipient.value = data.message; - } - }); - browser.runtime.sendMessage({ - type: 'popupReady', - message: '', - }); -}); diff --git a/sdk/typescript/examples/firefox-extension/tsconfig.json b/sdk/typescript/examples/firefox-extension/tsconfig.json deleted file mode 100644 index efe834e509..0000000000 --- a/sdk/typescript/examples/firefox-extension/tsconfig.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "extends": "../../tsconfig.json", - "compilerOptions": { - "outDir": "./dist", - "declaration": false, - "declarationMap": false - }, - "exclude": ["node_modules", "dist"] -} diff --git a/sdk/typescript/examples/firefox-extension/webpack.config.js b/sdk/typescript/examples/firefox-extension/webpack.config.js deleted file mode 100644 index 26bd5d679c..0000000000 --- a/sdk/typescript/examples/firefox-extension/webpack.config.js +++ /dev/null @@ -1,38 +0,0 @@ -// Webpack configuration for the Firefox extension example - -const path = require('path'); -const CopyWebpackPlugin = require('copy-webpack-plugin'); -const { CleanWebpackPlugin } = require('clean-webpack-plugin'); - -module.exports = { - mode: 'production', - entry: { - background: './src/background.js', - popup: './src/popup.js', - }, - output: { - path: path.resolve(__dirname, 'dist'), - }, - plugins: [ - new CleanWebpackPlugin(), - new CopyWebpackPlugin({ - patterns: [ - 'manifest.json', - 'popup.html', - { from: path.resolve(__dirname, '../../../../assets/favicon/favicon.png'), to: 'icon.png' }, - ], - }), - ], - module: { - rules: [ - { - test: /web-worker.*\.js$/, - loader: 'worker-loader', - options: { - filename: '[name].js', - inline: 'fallback', - }, - }, - ], - }, -}; diff --git a/sdk/typescript/examples/node-tester/parcel/README.md b/sdk/typescript/examples/node-tester/parcel/README.md deleted file mode 100644 index 6669b8f164..0000000000 --- a/sdk/typescript/examples/node-tester/parcel/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# Nym Node Tester - Parcel bundler - -This is an example of using the Nym Mixnet node tester. - -You can use this example as a seed for a new project. - -## Running the example - -Try out the node tester app by running: - -``` -npm install -npm start -``` diff --git a/sdk/typescript/examples/node-tester/parcel/package.json b/sdk/typescript/examples/node-tester/parcel/package.json deleted file mode 100644 index e344d7ba1a..0000000000 --- a/sdk/typescript/examples/node-tester/parcel/package.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "@nymproject/sdk-example-node-tester-plain-html-parcel", - "version": "1.0.5", - "description": "An example project that uses WASM and plain HTML bundled with Parcel v2", - "license": "Apache-2.0", - "scripts": { - "build": "npx parcel build", - "build:serve": "npx serve dist", - "lint": "eslint src", - "lint:fix": "eslint src --fix", - "start": "npx parcel", - "test": "jest", - "test:watch": "jest --watch", - "tsc": "tsc", - "tsc:watch": "tsc --watch" - }, - "dependencies": { - "@nymproject/sdk": ">=1.4.1-rc1 || ^1" - }, - "devDependencies": { - "@types/jest": "^27.0.1", - "@types/node": "^16.7.13", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", - "eslint": "^8.10.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^16.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", - "jest": "^27.1.0", - "mini-css-extract-plugin": "^2.2.2", - "npm-run-all": "^4.1.5", - "prettier": "^2.8.7", - "ts-jest": "^27.0.5", - "typescript": "^4.6.2" - }, - "private": false, - "browserslist": "> 0.5%, last 2 versions, not dead", - "source": "src/index.html" -} diff --git a/sdk/typescript/examples/node-tester/parcel/src/index.html b/sdk/typescript/examples/node-tester/parcel/src/index.html deleted file mode 100644 index acd8174db6..0000000000 --- a/sdk/typescript/examples/node-tester/parcel/src/index.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - Nym Node Tester Demo - - - -

- -

-

- - - - -

- -

Test a mixnode by entering the mixnode id above and click the Test button

- -
-

-

-

- - - diff --git a/sdk/typescript/examples/node-tester/parcel/src/index.ts b/sdk/typescript/examples/node-tester/parcel/src/index.ts deleted file mode 100644 index 350be6e469..0000000000 --- a/sdk/typescript/examples/node-tester/parcel/src/index.ts +++ /dev/null @@ -1,118 +0,0 @@ -import { createNodeTesterClient, NodeTester } from '@nymproject/sdk'; - -let nodeTester: NodeTester | null = null; - -/** - * Display messages that have been sent up the websocket. Colours them blue. - * - * @param {string} message - */ -function displayOutput(message: string, color?: string) { - const timestamp = new Date().toISOString().substr(11, 12); - - const sendDiv = document.createElement('div'); - const paragraph = document.createElement('p'); - paragraph.setAttribute('style', `color: ${color || 'blue'}`); - const paragraphContent = document.createTextNode(`${timestamp} >>> ${message}`); - paragraph.appendChild(paragraphContent); - - sendDiv.appendChild(paragraph); - document.getElementById('output')?.appendChild(sendDiv); -} - -/** - * The main entry point - */ -async function main() { - nodeTester = await createNodeTesterClient(); - - // add node tester to the Window globally, so that it can be used from the dev tools console - (window as any).nodeTester = nodeTester; - - if (!nodeTester) { - console.error('Oh no! Could not the node test'); - return; - } - - const nymApiUrl = 'https://validator.nymtech.net/api'; - const nodeTesterId = new Date().toISOString(); // make a new tester id for each session - await nodeTester.tester.init(nymApiUrl, nodeTesterId); - - const mixnodes = await (await fetch(`${nymApiUrl}/v1/mixnodes/active`)).json(); - - const exampleMixnodeIdentityKey = mixnodes[0].bond_information.mix_node.identity_key; - - const testButton: HTMLButtonElement = document.querySelector('#test-button') as HTMLButtonElement; - const reconnectButton: HTMLButtonElement = document.querySelector('#reconnect-button') as HTMLButtonElement; - const disconnectButton: HTMLButtonElement = document.querySelector('#disconnect-button') as HTMLButtonElement; - const terminateButton: HTMLButtonElement = document.querySelector('#terminate-button') as HTMLButtonElement; - - const mixnodeIdInput = document.getElementById('mixnodeId') as HTMLFormElement; - - mixnodeIdInput.value = exampleMixnodeIdentityKey; - - reconnectButton.onclick = async function () { - try { - await nodeTester?.tester.reconnectToGateway(); - } catch (e: any) { - console.error('Error', e); - displayOutput(`ERROR: ${e.message}`, 'red'); - } - }; - - disconnectButton.onclick = async function () { - try { - await nodeTester?.tester.disconnectFromGateway(); - } catch (e: any) { - console.error('Error', e); - displayOutput(`ERROR: ${e.message}`, 'red'); - } - }; - - terminateButton.onclick = async function () { - try { - await nodeTester?.terminate(); - } catch (e: any) { - console.error('Error', e); - displayOutput(`ERROR: ${e.message}`, 'red'); - } - }; - - if (testButton) { - testButton.onclick = async function () { - console.log('clicked'); - - const mixnodeId = mixnodeIdInput.value; - if (!nodeTester) { - displayOutput('ERROR: The node tester is not defined'); - console.error('The node tester is not defined'); - return; - } - if (!mixnodeId) { - displayOutput('ERROR: No mix id specified'); - console.error('No mix id specified'); - return; - } - - if (nodeTester && mixnodeId) { - displayOutput('Starting test...'); - try { - const response = await nodeTester.tester.startTest(mixnodeId); - displayOutput('Done!'); - if (response) { - displayOutput(JSON.stringify(response, null, 2), 'green'); - } - } catch (e: any) { - console.error('Error', e); - displayOutput(`ERROR: ${e.message}`, 'red'); - } - } - }; - } -} - -// wait for the html to load -window.addEventListener('DOMContentLoaded', () => { - // let's do this! - main(); -}); diff --git a/sdk/typescript/examples/node-tester/parcel/tsconfig.json b/sdk/typescript/examples/node-tester/parcel/tsconfig.json deleted file mode 100644 index 5403eafc03..0000000000 --- a/sdk/typescript/examples/node-tester/parcel/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "../../../tsconfig.json", - "compilerOptions": { - "outDir": "./dist" - }, - "include": ["src/**/*.ts", "src/**/*.tsx"], - "exclude": ["node_modules", "build", "dist"] -} diff --git a/sdk/typescript/examples/node-tester/plain-html/README.md b/sdk/typescript/examples/node-tester/plain-html/README.md deleted file mode 100644 index 7a613f68a2..0000000000 --- a/sdk/typescript/examples/node-tester/plain-html/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# Nym Node Tester - HTML - -This is an example of using the Nym Mixnet node tester. - -You can use this example as a seed for a new project. - -## Running the example - -Try out the node tester app by running: - -``` -npm install -npm start -``` diff --git a/sdk/typescript/examples/node-tester/plain-html/package.json b/sdk/typescript/examples/node-tester/plain-html/package.json deleted file mode 100644 index 06c9b27c24..0000000000 --- a/sdk/typescript/examples/node-tester/plain-html/package.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "name": "@nymproject/sdk-example-node-tester-plain-html", - "version": "1.0.5", - "description": "An example project that uses WASM node tester and plain HTML", - "license": "Apache-2.0", - "scripts": { - "build": "webpack build --progress --config webpack.prod.js", - "build:dev": "webpack build --progress", - "build:serve": "npx serve dist", - "lint": "eslint src", - "lint:fix": "eslint src --fix", - "start": "webpack serve --progress --port 3000", - "test": "jest", - "test:watch": "jest --watch", - "tsc": "tsc", - "tsc:watch": "tsc --watch" - }, - "dependencies": { - "@nymproject/sdk": ">=1.4.1-rc1 || ^1" - }, - "devDependencies": { - "@babel/core": "^7.15.0", - "@babel/plugin-transform-async-to-generator": "^7.14.5", - "@babel/preset-env": "^7.15.0", - "@babel/preset-typescript": "^7.15.0", - "@types/jest": "^27.0.1", - "@types/node": "^16.7.13", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", - "babel-loader": "^8.3.0", - "babel-plugin-root-import": "^5.1.0", - "clean-webpack-plugin": "^4.0.0", - "css-loader": "^6.7.3", - "css-minimizer-webpack-plugin": "^3.0.2", - "dotenv-webpack": "^7.0.3", - "eslint": "^8.10.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^16.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", - "file-loader": "^6.2.0", - "fork-ts-checker-webpack-plugin": "^7.2.1", - "html-webpack-plugin": "^5.3.2", - "jest": "^27.1.0", - "mini-css-extract-plugin": "^2.2.2", - "npm-run-all": "^4.1.5", - "prettier": "^2.8.7", - "style-loader": "^3.3.1", - "thread-loader": "^3.0.4", - "ts-jest": "^27.0.5", - "ts-loader": "^9.4.2", - "tsconfig-paths-webpack-plugin": "^3.5.2", - "typescript": "^4.6.2", - "url-loader": "^4.1.1", - "webpack": "^5.75.0", - "webpack-cli": "^4.8.0", - "webpack-dev-server": "^4.5.0", - "webpack-merge": "^5.8.0" - }, - "private": false -} diff --git a/sdk/typescript/examples/node-tester/plain-html/src/index.html b/sdk/typescript/examples/node-tester/plain-html/src/index.html deleted file mode 100644 index fc536c636c..0000000000 --- a/sdk/typescript/examples/node-tester/plain-html/src/index.html +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - Nym Node Tester Demo - - - -

- -

-

- - - - -

- -

Test a mixnode by entering the mixnode id above and click the Test button

- -
-

-

-

- - - diff --git a/sdk/typescript/examples/node-tester/plain-html/src/index.ts b/sdk/typescript/examples/node-tester/plain-html/src/index.ts deleted file mode 100644 index a2946ba079..0000000000 --- a/sdk/typescript/examples/node-tester/plain-html/src/index.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { createNodeTesterClient, NodeTester } from '@nymproject/sdk'; - -let nodeTester: NodeTester | null = null; - -/** - * Display messages that have been sent up the websocket. Colours them blue. - * - * @param {string} message - */ -function displayOutput(message: string, color?: string) { - const timestamp = new Date().toISOString().substr(11, 12); - - const sendDiv = document.createElement('div'); - const paragraph = document.createElement('p'); - paragraph.setAttribute('style', `color: ${color || 'blue'}`); - const paragraphContent = document.createTextNode(`${timestamp} >>> ${message}`); - paragraph.appendChild(paragraphContent); - - sendDiv.appendChild(paragraph); - document.getElementById('output')?.appendChild(sendDiv); -} - -/** - * The main entry point - */ -async function main() { - nodeTester = await createNodeTesterClient(); - - // add node tester to the Window globally, so that it can be used from the dev tools console - (window as any).nodeTester = nodeTester; - - if (!nodeTester) { - console.error('Oh no! Could not the node test'); - return; - } - - const nymApiUrl = 'https://validator.nymtech.net/api'; - const nodeTesterId = new Date().toISOString(); // make a new tester id for each session - await nodeTester.tester.init(nymApiUrl, nodeTesterId); - - const mixnodes = await (await fetch(`${nymApiUrl}/v1/mixnodes/active`)).json(); - - const exampleMixnodeIdentityKey = mixnodes[0].bond_information.mix_node.identity_key; - - const sendButton: HTMLButtonElement = document.querySelector('#send-button') as HTMLButtonElement; - const reconnectButton: HTMLButtonElement = document.querySelector('#reconnect-button') as HTMLButtonElement; - const disconnectButton: HTMLButtonElement = document.querySelector('#disconnect-button') as HTMLButtonElement; - const terminateButton: HTMLButtonElement = document.querySelector('#terminate-button') as HTMLButtonElement; - - const mixnodeIdInput = document.getElementById('mixnodeId') as HTMLFormElement; - - mixnodeIdInput.value = exampleMixnodeIdentityKey; - - reconnectButton.onclick = async function () { - try { - await nodeTester?.tester.reconnectToGateway(); - } catch (e: any) { - console.error('Error', e); - displayOutput(`ERROR: ${e.message}`, 'red'); - } - }; - - disconnectButton.onclick = async function () { - try { - await nodeTester?.tester.disconnectFromGateway(); - } catch (e: any) { - console.error('Error', e); - displayOutput(`ERROR: ${e.message}`, 'red'); - } - }; - - terminateButton.onclick = async function () { - try { - await nodeTester?.terminate(); - } catch (e: any) { - console.error('Error', e); - displayOutput(`ERROR: ${e.message}`, 'red'); - } - }; - - if (sendButton) { - sendButton.onclick = async function () { - const mixnodeId = mixnodeIdInput.value; - if (!nodeTester) { - displayOutput('ERROR: The node tester is not defined'); - console.error('The node tester is not defined'); - return; - } - if (!mixnodeId) { - displayOutput('ERROR: No mix id specified'); - console.error('No mix id specified'); - return; - } - - if (nodeTester && mixnodeId) { - displayOutput('Starting test...'); - try { - const response = await nodeTester.tester.startTest(mixnodeId); - displayOutput('Done!'); - if (response) { - displayOutput(JSON.stringify(response, null, 2), 'green'); - } - } catch (e: any) { - console.error('Error', e); - displayOutput(`ERROR: ${e.message}`, 'red'); - } - } - }; - } -} - -// wait for the html to load -window.addEventListener('DOMContentLoaded', () => { - // let's do this! - main(); -}); diff --git a/sdk/typescript/examples/node-tester/plain-html/tsconfig.json b/sdk/typescript/examples/node-tester/plain-html/tsconfig.json deleted file mode 100644 index 5403eafc03..0000000000 --- a/sdk/typescript/examples/node-tester/plain-html/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "../../../tsconfig.json", - "compilerOptions": { - "outDir": "./dist" - }, - "include": ["src/**/*.ts", "src/**/*.tsx"], - "exclude": ["node_modules", "build", "dist"] -} diff --git a/sdk/typescript/examples/node-tester/plain-html/tsconfig.prod.json b/sdk/typescript/examples/node-tester/plain-html/tsconfig.prod.json deleted file mode 100644 index cd04ae7aed..0000000000 --- a/sdk/typescript/examples/node-tester/plain-html/tsconfig.prod.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "../../../tsconfig.json", - "compilerOptions": { - "jsx": "react-jsx", - "outDir": "./dist", - "declaration": false - }, - "include": ["src/**/*.ts", "src/**/*.tsx"], - "exclude": ["node_modules", "build", "dist", "**/*.stories.*", "**/*.test.*", "**/*.spec.*"] -} diff --git a/sdk/typescript/examples/node-tester/plain-html/webpack.common.js b/sdk/typescript/examples/node-tester/plain-html/webpack.common.js deleted file mode 100644 index ae6ef6dc8e..0000000000 --- a/sdk/typescript/examples/node-tester/plain-html/webpack.common.js +++ /dev/null @@ -1,30 +0,0 @@ -const path = require('path'); -const { mergeWithRules } = require('webpack-merge'); -const { webpackCommon } = require('../../.webpack/webpack.base'); - -module.exports = mergeWithRules({ - module: { - rules: { - test: 'match', - use: 'replace', - }, - }, -})( - webpackCommon(__dirname, [ - { - inject: true, - filename: 'index.html', - template: path.resolve(__dirname, 'src/index.html'), - chunks: ['index'], - }, - ]), - { - entry: { - index: path.resolve(__dirname, 'src/index.ts'), - }, - output: { - path: path.resolve(__dirname, 'dist'), - publicPath: '/', - }, - }, -); diff --git a/sdk/typescript/examples/node-tester/plain-html/webpack.config.js b/sdk/typescript/examples/node-tester/plain-html/webpack.config.js deleted file mode 100644 index 8c7288de81..0000000000 --- a/sdk/typescript/examples/node-tester/plain-html/webpack.config.js +++ /dev/null @@ -1,67 +0,0 @@ -const { mergeWithRules } = require('webpack-merge'); -const webpack = require('webpack'); -const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); -const ReactRefreshTypeScript = require('react-refresh-typescript'); -const commonConfig = require('./webpack.common'); - -module.exports = mergeWithRules({ - module: { - rules: { - test: 'match', - use: 'replace', - }, - }, -})(commonConfig, { - mode: 'development', - devtool: 'inline-source-map', - module: { - rules: [ - { - test: /\.tsx?$/, - use: 'ts-loader', - exclude: /node_modules/, - options: { - getCustomTransformers: () => ({ - before: [ReactRefreshTypeScript()], - }), - // `ts-loader` does not work with HMR unless `transpileOnly` is used. - // If you need type checking, `ForkTsCheckerWebpackPlugin` is an alternative. - transpileOnly: true, - }, - }, - ], - }, - plugins: [ - new ReactRefreshWebpackPlugin(), - - // this can be included automatically by the dev server, however build mode fails if missing - new webpack.HotModuleReplacementPlugin(), - ], - - target: 'web', - - devServer: { - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - }, - historyApiFallback: true, - }, - - // recommended for faster rebuild - optimization: { - runtimeChunk: true, - removeAvailableModules: false, - removeEmptyChunks: false, - splitChunks: false, - }, - - cache: { - type: 'filesystem', - buildDependencies: { - // restart on config change - config: ['./webpack.config.js'], - }, - }, -}); diff --git a/sdk/typescript/examples/node-tester/plain-html/webpack.prod.js b/sdk/typescript/examples/node-tester/plain-html/webpack.prod.js deleted file mode 100644 index c92239179a..0000000000 --- a/sdk/typescript/examples/node-tester/plain-html/webpack.prod.js +++ /dev/null @@ -1,42 +0,0 @@ -const { mergeWithRules } = require('webpack-merge'); -const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); -const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const commonConfig = require('./webpack.common'); - -module.exports = mergeWithRules({ - module: { - rules: { - test: 'match', - use: 'replace', - }, - }, -})(commonConfig, { - mode: 'production', - - // TODO: no source maps, add back - devtool: false, - - module: { - rules: [ - { - test: /\.css$/, - use: [MiniCssExtractPlugin.loader, 'css-loader'], - }, - ], - }, - optimization: { - minimizer: ['...', new CssMinimizerPlugin()], - splitChunks: { - chunks: 'all', - }, - }, - plugins: [ - new MiniCssExtractPlugin({ - filename: '[name].[contenthash].css', - }), - ], - output: { - pathinfo: false, - filename: '[name].[contenthash].js', - }, -}); diff --git a/sdk/typescript/examples/node-tester/react/README.md b/sdk/typescript/examples/node-tester/react/README.md deleted file mode 100644 index 13d4a79db3..0000000000 --- a/sdk/typescript/examples/node-tester/react/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# Nym Node Tester - React - -This is an example of using the Nym Mixnet node tester. - -You can use this example as a seed for a new project. - -## Running the example - -Try out the node tester app by running: - -``` -npm install -npm start -``` diff --git a/sdk/typescript/examples/node-tester/react/index.html b/sdk/typescript/examples/node-tester/react/index.html deleted file mode 100644 index 193ccdcbd1..0000000000 --- a/sdk/typescript/examples/node-tester/react/index.html +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - Nym Node Tester Example - - -
- - - diff --git a/sdk/typescript/examples/node-tester/react/package.json b/sdk/typescript/examples/node-tester/react/package.json deleted file mode 100644 index 2320367bc5..0000000000 --- a/sdk/typescript/examples/node-tester/react/package.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "name": "@nymproject/sdk-example-node-tester-react", - "version": "1.0.5", - "description": "An example project that uses WASM node tester and React", - "license": "Apache-2.0", - "scripts": { - "start": "parcel index.html" - }, - "dependencies": { - "@emotion/react": "^11.11.1", - "@emotion/styled": "^11.11.0", - "@mui/icons-material": "^5.14.0", - "@mui/material": "^5.14.0", - "@nymproject/sdk": ">=1.4.1-rc1 || ^1", - "parcel": "^2.9.3", - "react": "^18.2.0", - "react-dom": "^18.2.0" - }, - "private": false -} diff --git a/sdk/typescript/examples/node-tester/react/src/App.tsx b/sdk/typescript/examples/node-tester/react/src/App.tsx deleted file mode 100644 index eb0bd1927a..0000000000 --- a/sdk/typescript/examples/node-tester/react/src/App.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import React, { useState } from 'react'; -import { - Button, - Card, - CardActions, - CardContent, - CardHeader, - CircularProgress, - Grid, - List, - ListItem, - ListItemText, - TextField, - Typography, -} from '@mui/material'; -import { NodeTestResultResponse } from '@nymproject/sdk'; -import { ScoreIndicator } from 'src/components/ScoreIndicator'; -import { useNodeTesterClient } from 'src/hooks/useNodeTesterClient'; -import { BasicPageLayout } from 'src/layouts'; -import { TestStatusLabel } from 'src/components/TestStatusLabel'; -import Icon from '../../../../../../assets/appicon/appicon.png'; - -export const App = () => { - const { testState, error, testNode, disconnectFromGateway, reconnectToGateway } = useNodeTesterClient(); - const [mixnodeIdentity, setMixnodeIdentity] = useState(''); - const [results, setResults] = React.useState(); - - console.log({ testState, error, testNode }); - - const handleTestNode = async () => { - setResults(undefined); - try { - const result = await testNode(mixnodeIdentity); - setResults(result); - } catch (e) { - console.error(e); - } - }; - - return ( - - - Nym Mixnode Testnet Node Tester} - action={} - avatar={} - /> - - - - - - - - - - - - - - - - - - - - - - - - { - setMixnodeIdentity(e.target.value); - }} - fullWidth - /> - - - - - - - - - - - - - - - ); -}; diff --git a/sdk/typescript/examples/node-tester/react/src/components/ScoreIndicator.tsx b/sdk/typescript/examples/node-tester/react/src/components/ScoreIndicator.tsx deleted file mode 100644 index 6527edeb48..0000000000 --- a/sdk/typescript/examples/node-tester/react/src/components/ScoreIndicator.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import React from 'react'; -import { Box, CircularProgress, CircularProgressProps, Stack, Typography } from '@mui/material'; - -const getPerformanceDescriptionAndColor = (score: number) => { - const res: { description: string; color: CircularProgressProps['color'] } = { description: '', color: 'warning' }; - - if (score >= 90) { - res.description = 'Reliable node'; - res.color = 'success'; - } - - if (score >= 75 && score < 90) { - res.description = 'Average node'; - res.color = 'warning'; - } - - if (score > 0 && score < 75) { - res.description = 'Unreliable node'; - res.color = 'error'; - } - - return res; -}; - -export const ScoreIndicator = ({ score }) => { - const { color } = getPerformanceDescriptionAndColor(score); - return ( - - - - - - {Math.round(score)}% - - Performance Score - - - ); -}; diff --git a/sdk/typescript/examples/node-tester/react/src/components/TestStatusLabel.tsx b/sdk/typescript/examples/node-tester/react/src/components/TestStatusLabel.tsx deleted file mode 100644 index 558677fce7..0000000000 --- a/sdk/typescript/examples/node-tester/react/src/components/TestStatusLabel.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react'; -import { Chip } from '@mui/material'; -import { HourglassTop, ErrorOutline, CheckCircleOutline, WarningAmber } from '@mui/icons-material'; -import { TestState } from 'src/hooks/useNodeTesterClient'; - -const getColor = (state: TestState) => { - switch (state) { - case 'Connecting': - return 'warning'; - case 'Error': - return 'error'; - case 'Ready': - return 'success'; - default: - return 'warning'; - } -}; - -const getIcon = (state: TestState) => { - switch (state) { - case 'Connecting': - return ; - case 'Error': - return ; - case 'Ready': - return ; - default: - return ; - } -}; - -export const TestStatusLabel = ({ state }: { state: TestState }) => ( - -); diff --git a/sdk/typescript/examples/node-tester/react/src/hooks/useNodeTesterClient.ts b/sdk/typescript/examples/node-tester/react/src/hooks/useNodeTesterClient.ts deleted file mode 100644 index fcd6f92937..0000000000 --- a/sdk/typescript/examples/node-tester/react/src/hooks/useNodeTesterClient.ts +++ /dev/null @@ -1,71 +0,0 @@ -import { useState, useEffect } from 'react'; -import { createNodeTesterClient, NodeTester } from '@nymproject/sdk'; - -export type TestState = 'Ready' | 'Connecting' | 'Disconnected' | 'Disconnecting' | 'Error' | 'Testing' | 'Stopped'; - -export const useNodeTesterClient = () => { - const [client, setClient] = useState(); - const [error, setError] = useState(); - const [testState, setTestState] = useState('Disconnected'); - - const createClient = async () => { - setTestState('Connecting'); - try { - const validator = 'https://validator.nymtech.net/api'; - const nodeTesterClient = await createNodeTesterClient(); - - await nodeTesterClient.tester.init(validator); - setClient(nodeTesterClient); - } catch (e) { - console.log(e); - setError('Failed to load node tester client, please try again'); - } finally { - setTestState('Ready'); - } - }; - - useEffect(() => { - createClient(); - }, []); - - const testNode = !client - ? undefined - : async (mixnodeIdentity: string) => { - try { - setTestState('Testing'); - const result = await client.tester.startTest(mixnodeIdentity); - setTestState('Ready'); - return result; - } catch (e) { - console.log(e); - setError('Failed to test node, please try again'); - setTestState('Error'); - } - }; - - const disconnectFromGateway = !client - ? undefined - : async () => { - setTestState('Disconnecting'); - await client.tester.disconnectFromGateway(); - setTestState('Disconnected'); - }; - - const reconnectToGateway = !client - ? undefined - : async () => { - setTestState('Connecting'); - await client.tester.reconnectToGateway(); - setTestState('Ready'); - }; - - const terminateWorker = !client - ? undefined - : async () => { - setTestState('Disconnecting'); - await client.terminate(); - setTestState('Disconnected'); - }; - - return { testNode, disconnectFromGateway, reconnectToGateway, terminateWorker, testState, error }; -}; diff --git a/sdk/typescript/examples/node-tester/react/src/index.tsx b/sdk/typescript/examples/node-tester/react/src/index.tsx deleted file mode 100644 index 77d3da3be1..0000000000 --- a/sdk/typescript/examples/node-tester/react/src/index.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; -import { createRoot } from 'react-dom/client'; -import { App } from './App'; -import { NymThemeProvider } from './theme/theme'; - -const rootDOMElem = document.getElementById('root'); -if (!rootDOMElem) throw new Error('Root element not found'); - -const root = createRoot(rootDOMElem); -root.render( - - - , -); diff --git a/sdk/typescript/examples/node-tester/react/src/layouts/index.tsx b/sdk/typescript/examples/node-tester/react/src/layouts/index.tsx deleted file mode 100644 index 1a38d6a350..0000000000 --- a/sdk/typescript/examples/node-tester/react/src/layouts/index.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import React from 'react'; -import { Container } from '@mui/material'; - -export const BasicPageLayout = ({ children }: { children: React.ReactNode }) => ( - {children} -); diff --git a/sdk/typescript/examples/node-tester/react/src/theme/theme.tsx b/sdk/typescript/examples/node-tester/react/src/theme/theme.tsx deleted file mode 100644 index 3f5d35fdf9..0000000000 --- a/sdk/typescript/examples/node-tester/react/src/theme/theme.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import * as React from 'react'; -import { createTheme, ThemeProvider } from '@mui/material/styles'; -import { CssBaseline } from '@mui/material'; - -export const NymThemeProvider = ({ children }: { children: React.ReactNode }) => { - const theme = createTheme({ - palette: { - mode: 'dark', - primary: { - main: '#FB6E4E', - }, - success: { - main: '#21D073', - }, - background: { - default: '#1D2125', - paper: '#292E34', - }, - }, - }); - - return ( - - - {children} - - ); -}; diff --git a/sdk/typescript/examples/node-tester/react/src/typesDefs.ts b/sdk/typescript/examples/node-tester/react/src/typesDefs.ts deleted file mode 100644 index dd84df40a4..0000000000 --- a/sdk/typescript/examples/node-tester/react/src/typesDefs.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module '*.png' { - const content: any; - export default content; -} diff --git a/sdk/typescript/examples/node-tester/react/tsconfig.json b/sdk/typescript/examples/node-tester/react/tsconfig.json deleted file mode 100644 index 272e623d99..0000000000 --- a/sdk/typescript/examples/node-tester/react/tsconfig.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "compilerOptions": { - "jsx": "react", - "baseUrl": ".", - "paths": { - "react": ["node_modules/react"], - "react-dom": ["node_modules/react-dom"] - }, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true - }, - "include": ["src"], - "paths": { - "@assets/*": ["../../../../../../assets"] - } -} diff --git a/sdk/typescript/examples/react/mui-theme/README.md b/sdk/typescript/examples/react/mui-theme/README.md index a95d916957..6a385b95c0 100644 --- a/sdk/typescript/examples/react/mui-theme/README.md +++ b/sdk/typescript/examples/react/mui-theme/README.md @@ -7,15 +7,15 @@ You can use this example as a seed for a new project. Remember to build the dependency packages from the root of this repo by running: ``` -yarn -yarn build +pnpm i +pnpm build ``` If you need to make changes to the dependency packages, you can run `yarn watch` in that package to watch for chagnes and build them. This project will pick up the changes in the built package and hot-reload / recompile. ## Features -### Yarn workspaces +### pnpm workspaces Packages from `ts-packages` are shared using Yarn workspaces. Make sure you add you new project to [package.json](../../package.json) to use the shared packages. diff --git a/sdk/typescript/examples/react/mui-theme/package.json b/sdk/typescript/examples/react/mui-theme/package.json index 67b8d345ea..2482b6e800 100644 --- a/sdk/typescript/examples/react/mui-theme/package.json +++ b/sdk/typescript/examples/react/mui-theme/package.json @@ -4,70 +4,70 @@ "version": "1.0.0", "license": "Apache-2.0", "dependencies": { - "react": "^18.2.0", - "react-dom": "^18.2.0", + "react": "catalog:", + "react-dom": "catalog:", "@mui/material": "^5.0.1", "@mui/styles": "^5.0.1", - "@mui/icons-material": "^5.5.0", + "@mui/icons-material": "catalog:", "@mui/lab": "^5.0.0-alpha.72", - "@nymproject/mui-theme": "^1.0.0", - "@nymproject/react": "^1.0.0" + "@nymproject/mui-theme": "workspace:*", + "@nymproject/react": "workspace:*" }, "devDependencies": { - "@babel/core": "^7.15.0", - "@babel/plugin-transform-async-to-generator": "^7.14.5", - "@babel/preset-env": "^7.15.0", - "@babel/preset-react": "^7.14.5", - "@babel/preset-typescript": "^7.15.0", - "@nymproject/eslint-config-react-typescript": "^1.0.0", - "@nymproject/webpack": "^1.0.0", + "@babel/core": "catalog:", + "@babel/plugin-transform-async-to-generator": "catalog:", + "@babel/preset-env": "catalog:", + "@babel/preset-react": "catalog:", + "@babel/preset-typescript": "catalog:", + "@nymproject/eslint-config-react-typescript": "workspace:*", + "@nymproject/webpack": "workspace:*", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.4", - "@svgr/webpack": "^6.1.1", + "@svgr/webpack": "catalog:", "@testing-library/jest-dom": "^5.14.1", "@testing-library/react": "^12.0.0", "@types/jest": "^27.0.1", "@types/node": "^16.7.13", - "@types/react": "^18.0.26", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", - "babel-loader": "^8.3.0", + "@types/react": "catalog:", + "@typescript-eslint/eslint-plugin": "catalog:", + "@typescript-eslint/parser": "catalog:", + "babel-loader": "catalog:", "babel-plugin-root-import": "^5.1.0", - "clean-webpack-plugin": "^4.0.0", - "css-loader": "^6.7.3", + "clean-webpack-plugin": "catalog:", + "css-loader": "catalog:", "css-minimizer-webpack-plugin": "^3.0.2", - "dotenv-webpack": "^7.0.3", + "dotenv-webpack": "catalog:", "eslint": "^8.10.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^16.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-react": "^7.29.2", - "eslint-plugin-react-hooks": "^4.3.0", - "favicons": "^7.0.2", - "favicons-webpack-plugin": "^5.0.2", - "file-loader": "^6.2.0", - "fork-ts-checker-webpack-plugin": "^7.2.1", - "html-webpack-plugin": "^5.3.2", - "jest": "^27.1.0", - "mini-css-extract-plugin": "^2.2.2", - "prettier": "^2.8.7", + "eslint-config-airbnb": "catalog:", + "eslint-config-airbnb-typescript": "catalog:", + "eslint-config-prettier": "catalog:", + "eslint-import-resolver-root-import": "catalog:", + "eslint-plugin-import": "catalog:", + "eslint-plugin-jest": "catalog:", + "eslint-plugin-jsx-a11y": "catalog:", + "eslint-plugin-prettier": "catalog:", + "eslint-plugin-react": "catalog:", + "eslint-plugin-react-hooks": "catalog:", + "favicons": "catalog:", + "favicons-webpack-plugin": "catalog:", + "file-loader": "catalog:", + "fork-ts-checker-webpack-plugin": "catalog:", + "html-webpack-plugin": "catalog:", + "jest": "catalog:", + "mini-css-extract-plugin": "catalog:", + "prettier": "catalog:", "react-refresh-typescript": "^2.0.3", - "style-loader": "^3.3.1", + "style-loader": "catalog:", "thread-loader": "^3.0.4", - "ts-jest": "^27.0.5", - "ts-loader": "^9.4.2", - "tsconfig-paths-webpack-plugin": "^3.5.2", + "ts-jest": "catalog:", + "ts-loader": "catalog:", + "tsconfig-paths-webpack-plugin": "catalog:", "typescript": "^4.6.2", - "url-loader": "^4.1.1", - "webpack": "^5.75.0", - "webpack-cli": "^4.8.0", - "webpack-dev-server": "^4.5.0", - "webpack-favicons": "^1.3.8", - "webpack-merge": "^5.8.0" + "url-loader": "catalog:", + "webpack": "catalog:", + "webpack-cli": "catalog:", + "webpack-dev-server": "catalog:", + "webpack-favicons": "catalog:", + "webpack-merge": "catalog:" }, "scripts": { "start": "webpack serve --progress --port 3000", diff --git a/sdk/typescript/examples/react/sdk-react/package.json b/sdk/typescript/examples/react/sdk-react/package.json index 1c4a84f5ce..d67a430f77 100644 --- a/sdk/typescript/examples/react/sdk-react/package.json +++ b/sdk/typescript/examples/react/sdk-react/package.json @@ -11,22 +11,22 @@ "devDependencies": { "@types/jest": "^27.0.1", "@types/node": "^16.7.13", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", + "@typescript-eslint/eslint-plugin": "catalog:", + "@typescript-eslint/parser": "catalog:", "eslint": "^8.10.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^16.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", - "jest": "^27.1.0", - "mini-css-extract-plugin": "^2.2.2", - "npm-run-all": "^4.1.5", - "prettier": "^2.8.7", - "ts-jest": "^27.0.5", + "eslint-config-airbnb": "catalog:", + "eslint-config-airbnb-typescript": "catalog:", + "eslint-config-prettier": "catalog:", + "eslint-import-resolver-root-import": "catalog:", + "eslint-plugin-import": "catalog:", + "eslint-plugin-jest": "catalog:", + "eslint-plugin-jsx-a11y": "catalog:", + "eslint-plugin-prettier": "catalog:", + "jest": "catalog:", + "mini-css-extract-plugin": "catalog:", + "npm-run-all": "catalog:", + "prettier": "catalog:", + "ts-jest": "catalog:", "typescript": "^4.6.2" }, "scripts": { diff --git a/sdk/typescript/packages/dom-utils/README.md b/sdk/typescript/packages/dom-utils/README.md deleted file mode 100644 index 2cbde69fe2..0000000000 --- a/sdk/typescript/packages/dom-utils/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Nym DOM Utils - -This package manipulates the DOM without any frameworks. - -## Usage - -TODO diff --git a/sdk/typescript/packages/dom-utils/index.ts b/sdk/typescript/packages/dom-utils/index.ts deleted file mode 100644 index cc7d70c6b3..0000000000 --- a/sdk/typescript/packages/dom-utils/index.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { NymMixnetClient, MimeTypes } from '@nymproject/sdk'; - -/** - * Create a Sphinx packet and send it to the mixnet through the gateway node. - * - * Message and recipient are taken from the values in the user interface. - * - * @param {Client} nymClient the nym client to use for message sending - */ -export async function sendMessageTo(nym: NymMixnetClient) { - const message = (document.getElementById('message') as HTMLFormElement).value; - const recipient = (document.getElementById('recipient') as HTMLFormElement).value; - - await nym.client.send({ payload: { message, mimeType: MimeTypes.TextPlain }, recipient }); - createChatEntry({message, sendOrReceive: "SEND"}); -} - -const createISOTimeStamp = () => new Date().toISOString().substring(11, 12); - -const createChatEntry = ({message, sendOrReceive}: {message: string, sendOrReceive: "SEND" | "RECEIVE"}) => { - const timestamp = createISOTimeStamp(); - - const sendDiv = document.createElement('div'); - const paragraph = document.createElement('p'); - paragraph.setAttribute('style', `color: ${sendOrReceive === "SEND" ? "blue" : "green"}`); - const paragraphContent = document.createTextNode(`${timestamp} sent >>> ${message}`); - paragraph.appendChild(paragraphContent); - - sendDiv.appendChild(paragraph); - document.getElementById('output')?.appendChild(sendDiv); - -/** - * Display messages that have been sent up the websocket. Colours them blue. - * - * @param {string} message - */ - -function displaySend(message: string) { - createChatEntry({message, sendOrReceive: "SEND"}); - return undefined -} - -/** - * Display received text messages in the browser. Colour them green. - * - * @param {string} message - */ - -export function displayReceived(message: string) { - return createChatEntry({message, sendOrReceive: "RECEIVE"}); - return undefined -} - -/** - * Display the nymClient's sender address in the user interface - * - * @param {Client} nymClient - */ -export function displaySenderAddress(address: string) { - (document.getElementById('sender') as HTMLFormElement).value = address; -} diff --git a/sdk/typescript/packages/mix-fetch-node/package.json b/sdk/typescript/packages/mix-fetch-node/package.json index f6cee944f7..2089653d40 100644 --- a/sdk/typescript/packages/mix-fetch-node/package.json +++ b/sdk/typescript/packages/mix-fetch-node/package.json @@ -19,11 +19,11 @@ "docs:generate:prod": "typedoc --basePath ./docs/tsdoc/nymproject/sdk/", "docs:prod:build": "scripts/build-prod-docs-collect.sh", "docs:serve": "reload -b -d ./docs -p 3000", - "docs:watch": "nodemon --ext ts --watch './src/**/*' --watch './typedoc.json' --exec \"yarn docs:generate\"", + "docs:watch": "nodemon --ext ts --watch './src/**/*' --watch './typedoc.json' --exec \"pnpm docs:generate\"", "lint": "eslint src", "lint:fix": "eslint src --fix", "start": "tsc -w", - "start:dev": "nodemon --watch src -e ts,json --exec 'yarn build:dev:esm'", + "start:dev": "nodemon --watch src -e ts,json --exec 'pnpm build:dev:esm'", "test": "node --experimental-fetch --experimental-vm-modules node_modules/jest/bin/jest.js -c=jest.config.mjs --no-cache", "tsc": "tsc --noEmit true" }, @@ -42,30 +42,32 @@ "@rollup/plugin-wasm": "^6.1.1", "@types/jest": "^27.0.1", "@types/node": "^16.7.13", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", + "@types/ws": "catalog:", + "@typescript-eslint/eslint-plugin": "catalog:", + "@typescript-eslint/parser": "catalog:", "eslint": "^8.10.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^16.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", + "eslint-config-airbnb": "catalog:", + "eslint-config-airbnb-typescript": "catalog:", + "eslint-config-prettier": "catalog:", + "eslint-import-resolver-root-import": "catalog:", + "eslint-plugin-import": "catalog:", + "eslint-plugin-jest": "catalog:", + "eslint-plugin-jsx-a11y": "catalog:", + "eslint-plugin-prettier": "catalog:", "jest": "^29.5.0", "nodemon": "^2.0.21", "reload": "^3.2.1", - "rimraf": "^3.0.2", + "rimraf": "catalog:", "rollup": "^3.9.1", "rollup-plugin-base64": "^1.0.1", "rollup-plugin-modify": "^3.0.0", "rollup-plugin-web-worker-loader": "^1.6.1", "ts-jest": "^29.1.0", - "ts-loader": "^9.4.2", + "ts-loader": "catalog:", + "tslib": "catalog:", "typedoc": "^0.24.8", "typescript": "^4.8.4" }, "private": false, "types": "./dist/cjs/index.d.ts" -} \ No newline at end of file +} diff --git a/sdk/typescript/packages/mix-fetch/internal-dev/README.md b/sdk/typescript/packages/mix-fetch/internal-dev/README.md index 3ef80f55ea..3ade7784ec 100644 --- a/sdk/typescript/packages/mix-fetch/internal-dev/README.md +++ b/sdk/typescript/packages/mix-fetch/internal-dev/README.md @@ -7,7 +7,7 @@ This project is for use by Nym developers only. Use at your own risk! From the root of this repository run: ``` -yarn +pnpm i make sdk-wasm-build ``` @@ -20,25 +20,25 @@ cd sdk/typescript/packages/mix-fetch You can run in watch mode: ``` -yarn start +pnpm start ``` Or do a single build: ``` -yarn build:dev:esm-no-inline +pnpm build:dev:esm-no-inline ``` Then, in another terminal: ``` cd sdk/typescript/packages/mix-fetch/internal-dev/parcel -yarn && yarn start +pnpm i && pnpm start ``` If you have trouble with changes not propagating: ``` -rm -rf node_modules && yarn && yarn start +rm -rf node_modules && pnpm i && pnpm start ``` diff --git a/sdk/typescript/packages/mix-fetch/internal-dev/package.json b/sdk/typescript/packages/mix-fetch/internal-dev/package.json index 61aa61669f..e64aaf611a 100644 --- a/sdk/typescript/packages/mix-fetch/internal-dev/package.json +++ b/sdk/typescript/packages/mix-fetch/internal-dev/package.json @@ -11,48 +11,48 @@ "@nymproject/mix-fetch": ">=1.4.2-rc.0 || ^1" }, "devDependencies": { - "@babel/core": "^7.22.10", - "@babel/plugin-transform-async-to-generator": "^7.22.5", - "@babel/preset-env": "^7.22.10", - "@babel/preset-typescript": "^7.22.5", + "@babel/core": "catalog:", + "@babel/plugin-transform-async-to-generator": "catalog:", + "@babel/preset-env": "catalog:", + "@babel/preset-typescript": "catalog:", "@types/jest": "^27.0.1", "@types/node": "^16.7.13", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", + "@typescript-eslint/eslint-plugin": "catalog:", + "@typescript-eslint/parser": "catalog:", "babel-loader": "^9.1.3", "babel-plugin-root-import": "^6.6.0", - "clean-webpack-plugin": "^4.0.0", + "clean-webpack-plugin": "catalog:", "copy-webpack-plugin": "^11.0.0", - "css-loader": "^6.8.1", + "css-loader": "catalog:", "css-minimizer-webpack-plugin": "^5.0.1", "dotenv-webpack": "^8.0.1", - "eslint": "^9.26.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^16.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", - "file-loader": "^6.2.0", + "eslint": "catalog:", + "eslint-config-airbnb": "catalog:", + "eslint-config-airbnb-typescript": "catalog:", + "eslint-config-prettier": "catalog:", + "eslint-import-resolver-root-import": "catalog:", + "eslint-plugin-import": "catalog:", + "eslint-plugin-jest": "catalog:", + "eslint-plugin-jsx-a11y": "catalog:", + "eslint-plugin-prettier": "catalog:", + "file-loader": "catalog:", "fork-ts-checker-webpack-plugin": "^8.0.0", - "html-webpack-plugin": "^5.5.3", - "jest": "^27.1.0", - "mini-css-extract-plugin": "^2.7.6", - "npm-run-all": "^4.1.5", - "prettier": "^2.8.7", - "style-loader": "^3.3.3", + "html-webpack-plugin": "catalog:", + "jest": "catalog:", + "mini-css-extract-plugin": "catalog:", + "npm-run-all": "catalog:", + "prettier": "catalog:", + "style-loader": "catalog:", "thread-loader": "^4.0.2", - "ts-jest": "^27.0.5", - "ts-loader": "^9.4.4", + "ts-jest": "catalog:", + "ts-loader": "catalog:", "tsconfig-paths-webpack-plugin": "^4.1.0", "typescript": "^4.6.2", - "url-loader": "^4.1.1", - "webpack": "^5.88.2", + "url-loader": "catalog:", + "webpack": "catalog:", "webpack-cli": "^5.1.4", - "webpack-dev-server": "^4.15.1", - "webpack-merge": "^5.9.0" + "webpack-dev-server": "catalog:", + "webpack-merge": "catalog:" }, "private": false -} \ No newline at end of file +} diff --git a/sdk/typescript/packages/mix-fetch/package.json b/sdk/typescript/packages/mix-fetch/package.json index 87ccdb52ed..12235ba862 100644 --- a/sdk/typescript/packages/mix-fetch/package.json +++ b/sdk/typescript/packages/mix-fetch/package.json @@ -24,12 +24,12 @@ "docs:generate:prod": "typedoc --basePath ./docs/tsdoc/nymproject/sdk/", "docs:prod:build": "scripts/build-prod-docs-collect.sh", "docs:serve": "reload -b -d ./docs -p 3000", - "docs:watch": "nodemon --ext ts --watch './src/**/*' --watch './typedoc.json' --exec \"yarn docs:generate\"", + "docs:watch": "nodemon --ext ts --watch './src/**/*' --watch './typedoc.json' --exec \"pnpm docs:generate\"", "lint": "eslint src", "lint:fix": "eslint src --fix", "prebuild": "node scripts/showDependencyLocation.cjs", "start": "tsc -w", - "start:dev": "nodemon --watch src -e ts,json --exec 'yarn build:dev:esm'", + "start:dev": "nodemon --watch src -e ts,json --exec 'pnpm build:dev:esm'", "test": "node --experimental-vm-modules --no-warnings node_modules/jest/bin/jest.js -c=jest.config.mjs --no-cache", "tsc": "tsc --noEmit true" }, @@ -38,12 +38,12 @@ "comlink": "^4.3.1" }, "devDependencies": { - "@babel/core": "^7.15.0", - "@babel/plugin-transform-async-to-generator": "^7.14.5", - "@babel/preset-env": "^7.15.0", - "@babel/preset-react": "^7.14.5", - "@babel/preset-typescript": "^7.15.0", - "@nymproject/eslint-config-react-typescript": "^1.0.0", + "@babel/core": "catalog:", + "@babel/plugin-transform-async-to-generator": "catalog:", + "@babel/preset-env": "catalog:", + "@babel/preset-react": "catalog:", + "@babel/preset-typescript": "catalog:", + "@nymproject/eslint-config-react-typescript": "workspace:*", "@rollup/plugin-commonjs": "^24.0.1", "@rollup/plugin-inject": "^5.0.3", "@rollup/plugin-json": "^6.0.0", @@ -54,32 +54,33 @@ "@rollup/plugin-wasm": "^6.1.1", "@types/jest": "^27.0.1", "@types/node": "^16.7.13", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", + "@typescript-eslint/eslint-plugin": "catalog:", + "@typescript-eslint/parser": "catalog:", "eslint": "^8.10.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^16.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-react": "^7.29.2", - "eslint-plugin-react-hooks": "^4.3.0", + "eslint-config-airbnb": "catalog:", + "eslint-config-airbnb-typescript": "catalog:", + "eslint-config-prettier": "catalog:", + "eslint-import-resolver-root-import": "catalog:", + "eslint-plugin-import": "catalog:", + "eslint-plugin-jest": "catalog:", + "eslint-plugin-jsx-a11y": "catalog:", + "eslint-plugin-prettier": "catalog:", + "eslint-plugin-react": "catalog:", + "eslint-plugin-react-hooks": "catalog:", "jest": "^29.5.0", "nodemon": "^2.0.21", "reload": "^3.2.1", - "rimraf": "^3.0.2", + "rimraf": "catalog:", "rollup": "^3.9.1", "rollup-plugin-base64": "^1.0.1", "rollup-plugin-web-worker-loader": "^1.6.1", "ts-jest": "^29.1.0", - "ts-loader": "^9.4.2", + "ts-loader": "catalog:", + "tslib": "catalog:", "typedoc": "^0.24.8", "typescript": "^4.8.4" }, "private": false, "type": "module", "types": "./dist/esm/index.d.ts" -} \ No newline at end of file +} diff --git a/sdk/typescript/packages/mix-fetch/scripts/build-prod-docs-collect.sh b/sdk/typescript/packages/mix-fetch/scripts/build-prod-docs-collect.sh index f672185300..ce75d65fff 100755 --- a/sdk/typescript/packages/mix-fetch/scripts/build-prod-docs-collect.sh +++ b/sdk/typescript/packages/mix-fetch/scripts/build-prod-docs-collect.sh @@ -7,7 +7,7 @@ set -o pipefail rm -rf ../../../../dist/ts/docs/tsdoc/nymproject/mix-fetch || true # run the build -yarn docs:generate:prod +pnpm docs:generate:prod # move the output outside of the yarn/npm workspaces mkdir -p ../../../../dist/ts/docs/tsdoc/nymproject diff --git a/sdk/typescript/packages/mui-theme/README.md b/sdk/typescript/packages/mui-theme/README.md index 50e2fb5077..7b205436ae 100644 --- a/sdk/typescript/packages/mui-theme/README.md +++ b/sdk/typescript/packages/mui-theme/README.md @@ -51,8 +51,8 @@ export const Content: FCWithChildren = () => { The best way to make changes to the theme is to: -1. Run this package in watch mode with `yarn watch` -2. Run Storybook from [react-components](../react-components/README.md) with `yarn storybook` +1. Run this package in watch mode with `pnpm watch` +2. Run Storybook from [react-components](../react-components/README.md) with `pnpm storybook` 3. Make sure the component you are changing is included in the [playground](../react-components/src/playground/index.tsx) 4. Watch for changes in the [Playground story](../react-components/src/stories/Playground.stories.tsx) @@ -63,8 +63,8 @@ Also remember to check light mode and dark mode! This package should be built from the root of the repository as follows: ``` -yarn -yarn build +pnpm i +pnpm build ``` ## Publishing diff --git a/sdk/typescript/packages/mui-theme/package.json b/sdk/typescript/packages/mui-theme/package.json index 8adf23aa0d..4b4a97aa5c 100644 --- a/sdk/typescript/packages/mui-theme/package.json +++ b/sdk/typescript/packages/mui-theme/package.json @@ -5,33 +5,33 @@ "main": "dist/index.js", "types": "dist/index.d.ts", "peerDependencies": { - "react": "^18.2.0", - "react-dom": "^18.2.0", + "react": "catalog:", + "react-dom": "catalog:", "@mui/material": "^5.2.2", "@mui/styles": "^5.2.2" }, "devDependencies": { - "@nymproject/eslint-config-react-typescript": "^1.0.0", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", - "eslint": "^9.26.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^16.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-react": "^7.29.2", - "eslint-plugin-react-hooks": "^4.3.0", - "prettier": "^2.8.7", - "typescript": "^4.6.2", - "ts-jest": "^27.0.5", - "jest": "^27.1.0", + "@nymproject/eslint-config-react-typescript": "workspace:*", + "@types/react": "catalog:", + "@typescript-eslint/eslint-plugin": "catalog:", + "@typescript-eslint/parser": "catalog:", "babel-plugin-root-import": "^5.1.0", - "@types/react": "^18.0.26", - "rimraf": "^3.0.2" + "eslint": "catalog:", + "eslint-config-airbnb": "catalog:", + "eslint-config-airbnb-typescript": "catalog:", + "eslint-config-prettier": "catalog:", + "eslint-import-resolver-root-import": "catalog:", + "eslint-plugin-import": "catalog:", + "eslint-plugin-jest": "catalog:", + "eslint-plugin-jsx-a11y": "catalog:", + "eslint-plugin-prettier": "catalog:", + "eslint-plugin-react": "catalog:", + "eslint-plugin-react-hooks": "catalog:", + "jest": "catalog:", + "prettier": "catalog:", + "rimraf": "catalog:", + "ts-jest": "catalog:", + "typescript": "^4.6.2" }, "scripts": { "clean": "rimraf dist", diff --git a/sdk/typescript/packages/node-tester/.babelrc b/sdk/typescript/packages/node-tester/.babelrc deleted file mode 100644 index 0ef5ffc214..0000000000 --- a/sdk/typescript/packages/node-tester/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@babel/env"] -} diff --git a/sdk/typescript/packages/node-tester/.gitignore b/sdk/typescript/packages/node-tester/.gitignore deleted file mode 100644 index d0b3e5e3ff..0000000000 --- a/sdk/typescript/packages/node-tester/.gitignore +++ /dev/null @@ -1 +0,0 @@ -src/worker.js diff --git a/sdk/typescript/packages/node-tester/README-CommonJS-full-fat.md b/sdk/typescript/packages/node-tester/README-CommonJS-full-fat.md deleted file mode 100644 index cc17ad4fb3..0000000000 --- a/sdk/typescript/packages/node-tester/README-CommonJS-full-fat.md +++ /dev/null @@ -1,7 +0,0 @@ -# Nym Node Tester - -This package provides a WASM library to test if a Nym node can process packets. - -## Usage - -TODO diff --git a/sdk/typescript/packages/node-tester/README-CommonJS.md b/sdk/typescript/packages/node-tester/README-CommonJS.md deleted file mode 100644 index cc17ad4fb3..0000000000 --- a/sdk/typescript/packages/node-tester/README-CommonJS.md +++ /dev/null @@ -1,7 +0,0 @@ -# Nym Node Tester - -This package provides a WASM library to test if a Nym node can process packets. - -## Usage - -TODO diff --git a/sdk/typescript/packages/node-tester/README-full-fat.md b/sdk/typescript/packages/node-tester/README-full-fat.md deleted file mode 100644 index cc17ad4fb3..0000000000 --- a/sdk/typescript/packages/node-tester/README-full-fat.md +++ /dev/null @@ -1,7 +0,0 @@ -# Nym Node Tester - -This package provides a WASM library to test if a Nym node can process packets. - -## Usage - -TODO diff --git a/sdk/typescript/packages/node-tester/README.md b/sdk/typescript/packages/node-tester/README.md deleted file mode 100644 index cc17ad4fb3..0000000000 --- a/sdk/typescript/packages/node-tester/README.md +++ /dev/null @@ -1,7 +0,0 @@ -# Nym Node Tester - -This package provides a WASM library to test if a Nym node can process packets. - -## Usage - -TODO diff --git a/sdk/typescript/packages/node-tester/jest.config.mjs b/sdk/typescript/packages/node-tester/jest.config.mjs deleted file mode 100644 index ed5b112c72..0000000000 --- a/sdk/typescript/packages/node-tester/jest.config.mjs +++ /dev/null @@ -1,15 +0,0 @@ -import preset from 'ts-jest/presets/index.js' - -/** @type {import('ts-jest').JestConfigWithTsJest} */ -export default { - ...preset.defaults, - transform: { - '^.+\\.(ts|tsx)$': [ - 'ts-jest', - { - tsconfig: 'tsconfig.jest.json', - useESM: true, - }, - ], - }, -} diff --git a/sdk/typescript/packages/node-tester/package.json b/sdk/typescript/packages/node-tester/package.json deleted file mode 100644 index 4ca5b2fedf..0000000000 --- a/sdk/typescript/packages/node-tester/package.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "name": "@nymproject/node-tester", - "version": "1.3.1", - "description": "This package provides a tester that can send test packets to mixnode that is part of the Nym Mixnet.", - "license": "Apache-2.0", - "author": "Nym Technologies SA", - "files": [ - "dist/esm/worker.js", - "dist/cjs/worker.js", - "dist/**/*" - ], - "main": "dist/cjs/index.js", - "browser": "dist/esm/index.js", - "scripts": { - "build": "scripts/build-prod.sh", - "build:dev": "scripts/build.sh", - "build:dev:esm": "scripts/build-dev-esm.sh", - "build:worker": "rollup -c rollup-worker.config.mjs", - "clean": "rimraf dist", - "lint": "eslint src", - "lint:fix": "eslint src --fix", - "start": "tsc -w", - "start:dev": "nodemon --watch src -e ts,json --exec 'yarn build:dev:esm'", - "test": "node --experimental-vm-modules --no-warnings node_modules/jest/bin/jest.js -c=jest.config.mjs --no-cache", - "tsc": "tsc --noEmit true" - }, - "dependencies": { - "@nymproject/nym-node-tester-wasm": ">=1.3.1-rc.0 || ^1", - "comlink": "^4.3.1" - }, - "devDependencies": { - "@babel/core": "^7.15.0", - "@babel/plugin-transform-async-to-generator": "^7.14.5", - "@babel/preset-env": "^7.15.0", - "@babel/preset-react": "^7.14.5", - "@babel/preset-typescript": "^7.15.0", - "@nymproject/eslint-config-react-typescript": "^1.0.0", - "@rollup/plugin-commonjs": "^24.0.1", - "@rollup/plugin-inject": "^5.0.3", - "@rollup/plugin-json": "^6.0.0", - "@rollup/plugin-node-resolve": "^15.0.1", - "@rollup/plugin-replace": "^5.0.2", - "@rollup/plugin-terser": "^0.2.1", - "@rollup/plugin-typescript": "^10.0.1", - "@rollup/plugin-wasm": "^6.1.1", - "@types/jest": "^27.0.1", - "@types/node": "^16.7.13", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", - "eslint": "^8.10.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^16.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-react": "^7.29.2", - "eslint-plugin-react-hooks": "^4.3.0", - "jest": "^29.5.0", - "nodemon": "^2.0.21", - "rimraf": "^3.0.2", - "rollup": "^3.9.1", - "rollup-plugin-base64": "^1.0.1", - "rollup-plugin-web-worker-loader": "^1.6.1", - "ts-jest": "^29.1.0", - "ts-loader": "^9.4.2", - "typescript": "^4.8.4" - }, - "private": false, - "type": "module", - "types": "./dist/esm/index.d.ts" -} diff --git a/sdk/typescript/packages/node-tester/rollup-cjs-full-fat.config.mjs b/sdk/typescript/packages/node-tester/rollup-cjs-full-fat.config.mjs deleted file mode 100644 index d4c6e39e99..0000000000 --- a/sdk/typescript/packages/node-tester/rollup-cjs-full-fat.config.mjs +++ /dev/null @@ -1,8 +0,0 @@ -import { getConfig } from './rollup/cjs.mjs'; - -export default { - ...getConfig({ - inline: true, - outputDir: 'dist/cjs-full-fat', - }), -}; diff --git a/sdk/typescript/packages/node-tester/rollup-cjs.config.mjs b/sdk/typescript/packages/node-tester/rollup-cjs.config.mjs deleted file mode 100644 index a12e5bdb7a..0000000000 --- a/sdk/typescript/packages/node-tester/rollup-cjs.config.mjs +++ /dev/null @@ -1,5 +0,0 @@ -import { getConfig } from './rollup/cjs.mjs'; - -export default { - ...getConfig({ inline: false }), -}; diff --git a/sdk/typescript/packages/node-tester/rollup-esm-full-fat.config.mjs b/sdk/typescript/packages/node-tester/rollup-esm-full-fat.config.mjs deleted file mode 100644 index ea80b1997b..0000000000 --- a/sdk/typescript/packages/node-tester/rollup-esm-full-fat.config.mjs +++ /dev/null @@ -1,8 +0,0 @@ -import { getConfig } from './rollup/esm.mjs'; - -export default { - ...getConfig({ - inline: true, - outputDir: 'dist/esm-full-fat', - }), -}; diff --git a/sdk/typescript/packages/node-tester/rollup-esm.config.mjs b/sdk/typescript/packages/node-tester/rollup-esm.config.mjs deleted file mode 100644 index fe7b0082bb..0000000000 --- a/sdk/typescript/packages/node-tester/rollup-esm.config.mjs +++ /dev/null @@ -1,8 +0,0 @@ -import { getConfig } from './rollup/esm.mjs'; - -export default { - ...getConfig({ - // by default, the web worker will not be inlined, in local development mode it will be - inline: process.env.MIX_FETCH_DEV_MODE === 'true', - }), -}; diff --git a/sdk/typescript/packages/node-tester/rollup-worker.config.mjs b/sdk/typescript/packages/node-tester/rollup-worker.config.mjs deleted file mode 100644 index b34376618c..0000000000 --- a/sdk/typescript/packages/node-tester/rollup-worker.config.mjs +++ /dev/null @@ -1,28 +0,0 @@ -import typescript from '@rollup/plugin-typescript'; -import resolve from '@rollup/plugin-node-resolve'; -import { wasm } from '@rollup/plugin-wasm'; -import replace from '@rollup/plugin-replace'; - -const extensions = [ - '.js', '.jsx', '.ts', '.tsx', -]; - -export default { - input: 'src/worker.ts', - output: { - dir: 'dist', - format: 'cjs', - }, - plugins: [ - resolve({ extensions }), - // this is some nasty monkey patching that removes the WASM URL (because it is handled by the `wasm` plugin) - replace({ - values: { 'input = new URL(\'mix_fetch_wasm_bg.wasm\', import.meta.url);': 'input = undefined;' }, - delimiters: ['', ''], - preventAssignment: true, - }), - // force the wasm plugin to embed the wasm bundle - this means no downstream bundlers have to worry about handling it - wasm({ maxFileSize: 10000000, targetEnv: 'browser' }), - typescript({ compilerOptions: { declaration: false, target: 'es5' } }), - ], -}; diff --git a/sdk/typescript/packages/node-tester/rollup/cjs.mjs b/sdk/typescript/packages/node-tester/rollup/cjs.mjs deleted file mode 100644 index 18c6f5e8c0..0000000000 --- a/sdk/typescript/packages/node-tester/rollup/cjs.mjs +++ /dev/null @@ -1,30 +0,0 @@ -import typescript from '@rollup/plugin-typescript'; -import resolve from '@rollup/plugin-node-resolve'; -import { wasm } from '@rollup/plugin-wasm'; -import webWorkerLoader from 'rollup-plugin-web-worker-loader'; - -const extensions = ['.js', '.jsx', '.ts', '.tsx']; - -/** - * Gets the config for bundling the package as a CommonJS module. - * - * @param opts Options: - * `{ inline: boolean }` - set inline to true to inline the web worker in the main bundle - * `{ outputDir: string }` - override the destination - */ -export const getConfig = (opts) => ({ - input: 'src/index.ts', - output: { - dir: opts.outputDir || 'dist/cjs', - format: 'cjs', - }, - plugins: [ - webWorkerLoader({ targetPlatform: 'browser', inline: opts.inline }), // the inline param is used here - resolve({ extensions }), - wasm({ maxFileSize: 10000000, targetEnv: 'browser' }), - typescript({ - compilerOptions: { outDir: opts.outputDir || 'dist/cjs', target: 'es5' }, - exclude: ['worker.ts'], - }), - ], -}); diff --git a/sdk/typescript/packages/node-tester/rollup/esm.mjs b/sdk/typescript/packages/node-tester/rollup/esm.mjs deleted file mode 100644 index b47cf1ac05..0000000000 --- a/sdk/typescript/packages/node-tester/rollup/esm.mjs +++ /dev/null @@ -1,28 +0,0 @@ -import typescript from '@rollup/plugin-typescript'; -import resolve from '@rollup/plugin-node-resolve'; -import webWorkerLoader from 'rollup-plugin-web-worker-loader'; - -const extensions = ['.js', '.jsx', '.ts', '.tsx']; - -/** - * Gets the config for bundling the package as an ES Module. - * - * @param opts Options: - * `{ inline: boolean }` - set inline to true to inline the web worker in the main bundle - * `{ outputDir: string }` - override the destination * - */ -export const getConfig = (opts) => ({ - input: 'src/index.ts', - output: { - dir: opts.outputDir || 'dist/esm', - format: 'es', - }, - plugins: [ - webWorkerLoader({ targetPlatform: 'browser', inline: opts.inline }), // the inline param is used here - resolve({ extensions }), - typescript({ - exclude: ['worker.ts'], - compilerOptions: { outDir: opts.outputDir || 'dist/esm' }, - }), - ], -}); diff --git a/sdk/typescript/packages/node-tester/scripts/build-dev-esm.sh b/sdk/typescript/packages/node-tester/scripts/build-dev-esm.sh deleted file mode 100755 index 26970fc4e6..0000000000 --- a/sdk/typescript/packages/node-tester/scripts/build-dev-esm.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -#------------------------------------------------------- -# WEB WORKER (node-tester WASM) -#------------------------------------------------------- -# The web worker needs to be bundled because the WASM bundle needs to be loaded synchronously and all dependencies -# must be included in the worker script (because it is not loaded as an ES Module) - -# build the worker -rollup -c rollup-worker.config.mjs - -# move it next to the Typescript `src/index.ts` so it can be inlined by rollup -cp dist/worker.js src/worker.js -rm dist/worker.js - -#------------------------------------------------------- -# ESM -#------------------------------------------------------- - -# build the SDK as a ESM bundle -rollup -c rollup-esm.config.mjs - -#------------------------------------------------------- -# CLEAN UP -#------------------------------------------------------- - -rm -rf dist/esm/worker - - diff --git a/sdk/typescript/packages/node-tester/scripts/build-prod.sh b/sdk/typescript/packages/node-tester/scripts/build-prod.sh deleted file mode 100755 index 74a173acc8..0000000000 --- a/sdk/typescript/packages/node-tester/scripts/build-prod.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -rm -rf dist || true -rm -rf ../../../../dist/ts/sdk/node-tester || true - -# run the build -scripts/build.sh -node scripts/buildPackageJson.mjs - -# move the output outside of the yarn/npm workspaces -mkdir -p ../../../../dist/ts/sdk -mv dist ../../../../dist/ts/sdk -mv ../../../../dist/ts/sdk/dist ../../../../dist/ts/sdk/node-tester - -echo "Output can be found in:" -realpath ../../../../dist/ts/sdk/node-tester diff --git a/sdk/typescript/packages/node-tester/scripts/build.sh b/sdk/typescript/packages/node-tester/scripts/build.sh deleted file mode 100755 index 64ed2e4381..0000000000 --- a/sdk/typescript/packages/node-tester/scripts/build.sh +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -rm -rf dist || true - -#------------------------------------------------------- -# WEB WORKER (mix-fetch WASM) -#------------------------------------------------------- -# The web worker needs to be bundled because the WASM bundle needs to be loaded synchronously and all dependencies -# must be included in the worker script (because it is not loaded as an ES Module) - -# build the worker -rollup -c rollup-worker.config.mjs - -# move it next to the Typescript `src/index.ts` so it can be inlined by rollup -rm -f src/worker.js -mv dist/worker.js src/worker.js - -#------------------------------------------------------- -# ESM -#------------------------------------------------------- - -# build the SDK as a ESM bundle -rollup -c rollup-esm.config.mjs - -#------------------------------------------------------- -# COMMON JS -#------------------------------------------------------- -# Some old build systems cannot fully handle ESM or ES2021, so build -# a CommonJS bundle targeting ES5 - -# build the SDK as a CommonJS bundle -rollup -c rollup-cjs.config.mjs - -#------------------------------------------------------- -# ESM (full-fat) -#------------------------------------------------------- - -# build the SDK as a ESM bundle (with worker inlined as a blob) -rollup -c rollup-esm-full-fat.config.mjs - -#------------------------------------------------------- -# COMMON JS (full-fat) -#------------------------------------------------------- -# Some old build systems cannot fully handle ESM or ES2021, so build -# a CommonJS bundle targeting ES5 - -# build the SDK as a CommonJS bundle (with worker inlined as a blob) -rollup -c rollup-cjs-full-fat.config.mjs - -#------------------------------------------------------- -# CLEAN UP -#------------------------------------------------------- - -rm -rf dist/cjs/worker -rm -rf dist/esm/worker -rm -rf dist/cjs-full-fat/worker -rm -rf dist/esm-full-fat/worker - -# copy README -cp README.md dist/esm -cp README-CommonJS.md dist/cjs/README.md -cp README-CommonJS-full-fat.md dist/cjs-full-fat/README.md -cp README-full-fat.md dist/esm-full-fat/README.md - - diff --git a/sdk/typescript/packages/node-tester/scripts/buildPackageJson.mjs b/sdk/typescript/packages/node-tester/scripts/buildPackageJson.mjs deleted file mode 100644 index 3fc5a7b5b2..0000000000 --- a/sdk/typescript/packages/node-tester/scripts/buildPackageJson.mjs +++ /dev/null @@ -1,29 +0,0 @@ -import * as fs from 'fs'; - -// parse the package.json from the SDK, so we can keep fields like the name and version -const json = JSON.parse(fs.readFileSync('package.json').toString()); - -// defaults (NB: these are in the output file locations) -const browser = 'index.js'; -const main = 'index.js'; -const types = 'index.d.ts'; - -const getPackageJson = (type, suffix) => ({ - name: `${json.name}${suffix ? `-${suffix}` : ''}`, - version: json.version, - license: json.license, - author: json.author, - type, - browser, - main, - types, -}); - -fs.writeFileSync('dist/cjs/package.json', JSON.stringify(getPackageJson('commonjs', 'commonjs'), null, 2)); -fs.writeFileSync('dist/esm/package.json', JSON.stringify(getPackageJson('module'), null, 2)); - -fs.writeFileSync( - 'dist/cjs-full-fat/package.json', - JSON.stringify(getPackageJson('commonjs', 'commonjs-full-fat'), null, 2), -); -fs.writeFileSync('dist/esm-full-fat/package.json', JSON.stringify(getPackageJson('module', 'full-fat'), null, 2)); diff --git a/sdk/typescript/packages/node-tester/scripts/publish.sh b/sdk/typescript/packages/node-tester/scripts/publish.sh deleted file mode 100755 index f08bcf3068..0000000000 --- a/sdk/typescript/packages/node-tester/scripts/publish.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -yarn -yarn build -cd ../../../../dist/ts/sdk/node-tester - -cd cjs -echo "Publishing CommonJS package to NPM.." -npm publish --access=public -cd .. - -cd esm -echo "Publishing ESM package to NPM.." -npm publish --access=public -cd .. diff --git a/sdk/typescript/packages/node-tester/src/index.ts b/sdk/typescript/packages/node-tester/src/index.ts deleted file mode 100644 index 230ed9490a..0000000000 --- a/sdk/typescript/packages/node-tester/src/index.ts +++ /dev/null @@ -1,52 +0,0 @@ -import InlineWasmWebWorker from 'web-worker:./worker'; -import * as Comlink from 'comlink'; -import { INodeTesterWorkerAsync, NodeTester, NodeTesterEventKinds } from './types'; - -/** - * Client for the Nym node tester. - */ -export const createNodeTesterClient = async (): Promise => { - // eslint-disable-next-line @typescript-eslint/no-use-before-define - const worker = await createWorker(); - - // let comlink handle interop with the web worker - const tester = Comlink.wrap(worker); - - // expose the method to terminate the worker - const terminate = async () => { - worker.terminate(); - }; - - return { tester, terminate }; -}; - -/** - * Async method to create a web worker that runs the Nym node tester client on another thread. It will only return once the worker - * has passed back a `Loaded` event to the calling thread. - * - * @return The instance of the web worker. - */ - -const createWorker = async () => - new Promise((resolve, reject) => { - // rollup will inline the built worker script, so that when the SDK is used in - // other projects, they will not need to mess around trying to bundle it - // however, it will make this SDK bundle bigger because of Base64 inline data - const worker = new InlineWasmWebWorker(); - - worker.addEventListener('error', reject); - worker.addEventListener( - 'message', - (msg) => { - worker.removeEventListener('error', reject); - if (msg.data?.kind === NodeTesterEventKinds.Loaded) { - resolve(worker); - } else { - reject(msg); - } - }, - { once: true }, - ); - }); - -export * from './types'; diff --git a/sdk/typescript/packages/node-tester/src/types.ts b/sdk/typescript/packages/node-tester/src/types.ts deleted file mode 100644 index 5bf1afb4d1..0000000000 --- a/sdk/typescript/packages/node-tester/src/types.ts +++ /dev/null @@ -1,35 +0,0 @@ -export interface INodeTesterWorkerAsync { - init: (validatorUrl: string, nodeTesterId?: string) => Promise; - reconnectToGateway: () => Promise; - disconnectFromGateway: () => Promise; - startTest: (mixnodeIdentityKey: string) => Promise; -} - -export interface INodeTesterWorkerDisposableAsync { - terminate: () => Promise; -} - -export interface NodeTester extends INodeTesterWorkerDisposableAsync { - tester: INodeTesterWorkerAsync; -} - -export enum NodeTesterEventKinds { - Loaded = 'Loaded', - Connected = 'Connected', -} - -export interface NodeTesterLoadedEvent { - kind: NodeTesterEventKinds.Loaded; - args: { - loaded: true; - }; -} - -export type NodeTestResultResponse = { - score: number; - sentPackets: number; - receivedPackets: number; - receivedAcks: number; - duplicatePackets: number; - duplicateAcks: number; -}; diff --git a/sdk/typescript/packages/node-tester/src/worker.js b/sdk/typescript/packages/node-tester/src/worker.js new file mode 100644 index 0000000000..31edb483a1 --- /dev/null +++ b/sdk/typescript/packages/node-tester/src/worker.js @@ -0,0 +1,2011 @@ +'use strict'; + +var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null; +/****************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */ +/* global Reflect, Promise, SuppressedError, Symbol, Iterator */ + + +function __awaiter(thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +} + +function __generator(thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype); + return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (g && (g = 0, op[0] && (_ = 0)), _) try { + if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [op[0] & 2, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } +} + +typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) { + var e = new Error(message); + return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; +}; + +/** + * @license + * Copyright 2019 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ +const proxyMarker = Symbol("Comlink.proxy"); +const createEndpoint = Symbol("Comlink.endpoint"); +const releaseProxy = Symbol("Comlink.releaseProxy"); +const finalizer = Symbol("Comlink.finalizer"); +const throwMarker = Symbol("Comlink.thrown"); +const isObject = (val) => (typeof val === "object" && val !== null) || typeof val === "function"; +/** + * Internal transfer handle to handle objects marked to proxy. + */ +const proxyTransferHandler = { + canHandle: (val) => isObject(val) && val[proxyMarker], + serialize(obj) { + const { port1, port2 } = new MessageChannel(); + expose(obj, port1); + return [port2, [port2]]; + }, + deserialize(port) { + port.start(); + return wrap(port); + }, +}; +/** + * Internal transfer handler to handle thrown exceptions. + */ +const throwTransferHandler = { + canHandle: (value) => isObject(value) && throwMarker in value, + serialize({ value }) { + let serialized; + if (value instanceof Error) { + serialized = { + isError: true, + value: { + message: value.message, + name: value.name, + stack: value.stack, + }, + }; + } + else { + serialized = { isError: false, value }; + } + return [serialized, []]; + }, + deserialize(serialized) { + if (serialized.isError) { + throw Object.assign(new Error(serialized.value.message), serialized.value); + } + throw serialized.value; + }, +}; +/** + * Allows customizing the serialization of certain values. + */ +const transferHandlers = new Map([ + ["proxy", proxyTransferHandler], + ["throw", throwTransferHandler], +]); +function isAllowedOrigin(allowedOrigins, origin) { + for (const allowedOrigin of allowedOrigins) { + if (origin === allowedOrigin || allowedOrigin === "*") { + return true; + } + if (allowedOrigin instanceof RegExp && allowedOrigin.test(origin)) { + return true; + } + } + return false; +} +function expose(obj, ep = globalThis, allowedOrigins = ["*"]) { + ep.addEventListener("message", function callback(ev) { + if (!ev || !ev.data) { + return; + } + if (!isAllowedOrigin(allowedOrigins, ev.origin)) { + console.warn(`Invalid origin '${ev.origin}' for comlink proxy`); + return; + } + const { id, type, path } = Object.assign({ path: [] }, ev.data); + const argumentList = (ev.data.argumentList || []).map(fromWireValue); + let returnValue; + try { + const parent = path.slice(0, -1).reduce((obj, prop) => obj[prop], obj); + const rawValue = path.reduce((obj, prop) => obj[prop], obj); + switch (type) { + case "GET" /* MessageType.GET */: + { + returnValue = rawValue; + } + break; + case "SET" /* MessageType.SET */: + { + parent[path.slice(-1)[0]] = fromWireValue(ev.data.value); + returnValue = true; + } + break; + case "APPLY" /* MessageType.APPLY */: + { + returnValue = rawValue.apply(parent, argumentList); + } + break; + case "CONSTRUCT" /* MessageType.CONSTRUCT */: + { + const value = new rawValue(...argumentList); + returnValue = proxy(value); + } + break; + case "ENDPOINT" /* MessageType.ENDPOINT */: + { + const { port1, port2 } = new MessageChannel(); + expose(obj, port2); + returnValue = transfer(port1, [port1]); + } + break; + case "RELEASE" /* MessageType.RELEASE */: + { + returnValue = undefined; + } + break; + default: + return; + } + } + catch (value) { + returnValue = { value, [throwMarker]: 0 }; + } + Promise.resolve(returnValue) + .catch((value) => { + return { value, [throwMarker]: 0 }; + }) + .then((returnValue) => { + const [wireValue, transferables] = toWireValue(returnValue); + ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables); + if (type === "RELEASE" /* MessageType.RELEASE */) { + // detach and deactive after sending release response above. + ep.removeEventListener("message", callback); + closeEndPoint(ep); + if (finalizer in obj && typeof obj[finalizer] === "function") { + obj[finalizer](); + } + } + }) + .catch((error) => { + // Send Serialization Error To Caller + const [wireValue, transferables] = toWireValue({ + value: new TypeError("Unserializable return value"), + [throwMarker]: 0, + }); + ep.postMessage(Object.assign(Object.assign({}, wireValue), { id }), transferables); + }); + }); + if (ep.start) { + ep.start(); + } +} +function isMessagePort(endpoint) { + return endpoint.constructor.name === "MessagePort"; +} +function closeEndPoint(endpoint) { + if (isMessagePort(endpoint)) + endpoint.close(); +} +function wrap(ep, target) { + const pendingListeners = new Map(); + ep.addEventListener("message", function handleMessage(ev) { + const { data } = ev; + if (!data || !data.id) { + return; + } + const resolver = pendingListeners.get(data.id); + if (!resolver) { + return; + } + try { + resolver(data); + } + finally { + pendingListeners.delete(data.id); + } + }); + return createProxy(ep, pendingListeners, [], target); +} +function throwIfProxyReleased(isReleased) { + if (isReleased) { + throw new Error("Proxy has been released and is not useable"); + } +} +function releaseEndpoint(ep) { + return requestResponseMessage(ep, new Map(), { + type: "RELEASE" /* MessageType.RELEASE */, + }).then(() => { + closeEndPoint(ep); + }); +} +const proxyCounter = new WeakMap(); +const proxyFinalizers = "FinalizationRegistry" in globalThis && + new FinalizationRegistry((ep) => { + const newCount = (proxyCounter.get(ep) || 0) - 1; + proxyCounter.set(ep, newCount); + if (newCount === 0) { + releaseEndpoint(ep); + } + }); +function registerProxy(proxy, ep) { + const newCount = (proxyCounter.get(ep) || 0) + 1; + proxyCounter.set(ep, newCount); + if (proxyFinalizers) { + proxyFinalizers.register(proxy, ep, proxy); + } +} +function unregisterProxy(proxy) { + if (proxyFinalizers) { + proxyFinalizers.unregister(proxy); + } +} +function createProxy(ep, pendingListeners, path = [], target = function () { }) { + let isProxyReleased = false; + const proxy = new Proxy(target, { + get(_target, prop) { + throwIfProxyReleased(isProxyReleased); + if (prop === releaseProxy) { + return () => { + unregisterProxy(proxy); + releaseEndpoint(ep); + pendingListeners.clear(); + isProxyReleased = true; + }; + } + if (prop === "then") { + if (path.length === 0) { + return { then: () => proxy }; + } + const r = requestResponseMessage(ep, pendingListeners, { + type: "GET" /* MessageType.GET */, + path: path.map((p) => p.toString()), + }).then(fromWireValue); + return r.then.bind(r); + } + return createProxy(ep, pendingListeners, [...path, prop]); + }, + set(_target, prop, rawValue) { + throwIfProxyReleased(isProxyReleased); + // FIXME: ES6 Proxy Handler `set` methods are supposed to return a + // boolean. To show good will, we return true asynchronously ¯\_(ツ)_/¯ + const [value, transferables] = toWireValue(rawValue); + return requestResponseMessage(ep, pendingListeners, { + type: "SET" /* MessageType.SET */, + path: [...path, prop].map((p) => p.toString()), + value, + }, transferables).then(fromWireValue); + }, + apply(_target, _thisArg, rawArgumentList) { + throwIfProxyReleased(isProxyReleased); + const last = path[path.length - 1]; + if (last === createEndpoint) { + return requestResponseMessage(ep, pendingListeners, { + type: "ENDPOINT" /* MessageType.ENDPOINT */, + }).then(fromWireValue); + } + // We just pretend that `bind()` didn’t happen. + if (last === "bind") { + return createProxy(ep, pendingListeners, path.slice(0, -1)); + } + const [argumentList, transferables] = processArguments(rawArgumentList); + return requestResponseMessage(ep, pendingListeners, { + type: "APPLY" /* MessageType.APPLY */, + path: path.map((p) => p.toString()), + argumentList, + }, transferables).then(fromWireValue); + }, + construct(_target, rawArgumentList) { + throwIfProxyReleased(isProxyReleased); + const [argumentList, transferables] = processArguments(rawArgumentList); + return requestResponseMessage(ep, pendingListeners, { + type: "CONSTRUCT" /* MessageType.CONSTRUCT */, + path: path.map((p) => p.toString()), + argumentList, + }, transferables).then(fromWireValue); + }, + }); + registerProxy(proxy, ep); + return proxy; +} +function myFlat(arr) { + return Array.prototype.concat.apply([], arr); +} +function processArguments(argumentList) { + const processed = argumentList.map(toWireValue); + return [processed.map((v) => v[0]), myFlat(processed.map((v) => v[1]))]; +} +const transferCache = new WeakMap(); +function transfer(obj, transfers) { + transferCache.set(obj, transfers); + return obj; +} +function proxy(obj) { + return Object.assign(obj, { [proxyMarker]: true }); +} +function toWireValue(value) { + for (const [name, handler] of transferHandlers) { + if (handler.canHandle(value)) { + const [serializedValue, transferables] = handler.serialize(value); + return [ + { + type: "HANDLER" /* WireValueType.HANDLER */, + name, + value: serializedValue, + }, + transferables, + ]; + } + } + return [ + { + type: "RAW" /* WireValueType.RAW */, + value, + }, + transferCache.get(value) || [], + ]; +} +function fromWireValue(value) { + switch (value.type) { + case "HANDLER" /* WireValueType.HANDLER */: + return transferHandlers.get(value.name).deserialize(value.value); + case "RAW" /* WireValueType.RAW */: + return value.value; + } +} +function requestResponseMessage(ep, pendingListeners, msg, transfers) { + return new Promise((resolve) => { + const id = generateUUID(); + pendingListeners.set(id, resolve); + if (ep.start) { + ep.start(); + } + ep.postMessage(Object.assign({ id }, msg), transfers); + }); +} +function generateUUID() { + return new Array(4) + .fill(0) + .map(() => Math.floor(Math.random() * Number.MAX_SAFE_INTEGER).toString(16)) + .join("-"); +} + +function _loadWasmModule (sync, filepath, src, imports) { + function _instantiateOrCompile(source, imports, stream) { + var instantiateFunc = stream ? WebAssembly.instantiateStreaming : WebAssembly.instantiate; + var compileFunc = stream ? WebAssembly.compileStreaming : WebAssembly.compile; + + if (imports) { + return instantiateFunc(source, imports) + } else { + return compileFunc(source) + } + } + + +var buf = null; +if (filepath) { + +return _instantiateOrCompile(fetch(filepath), imports, true); + +} + + +var raw = globalThis.atob(src); +var rawLength = raw.length; +buf = new Uint8Array(new ArrayBuffer(rawLength)); +for(var i = 0; i < rawLength; i++) { + buf[i] = raw.charCodeAt(i); +} + + + + if(sync) { + var mod = new WebAssembly.Module(buf); + return imports ? new WebAssembly.Instance(mod, imports) : mod + } else { + return _instantiateOrCompile(buf, imports, false) + } +} + +function wasmBytes(imports){return _loadWasmModule(0, null, 'AGFzbQEAAAABiwl1YAJ/fwF/YAJ/fwBgAX8AYAN/f38AYAF/AX9gA39/fwF/YAR/f39/AGAFf39/f38AYAR/f39/AX9gAW8Bb2AGf39/f39/AGABbwF/YAV/f39/fwF/YAABf2AHf39/f39/fwBgAABgAm9vAGACf34AYAABb2ACf28AYAN/f38Bb2AGf39/f39/AX9gA39/fwF+YAJ/fgF/YAV/f39+fwBgAn9/AX5gAn9/AW9gAX8Bb2ACb28Bb2AHf39/f39/fwF/YAt/f39/f39/f39/fwF/YAN/f34AYAJvbwF/YAFvAGACb38AYAh/f39/f39/fwBgBH9/fn4AYAR/fn9/AGADf35/AGABbwF8YAJvfwFvYANvf38Bb2ADb39/AGADb29vAW9gA39/fgF/YAF/AXxgFH9/f39/f39/f39/f39/f39/f39/AX9gBH9/f34AYAJ/fABgAX8BfmAAAn9/YAN/f28AYAN/f28Bb2AEb39/fwFvYARvf39vAGAEf3x/fwF/YAV/f35/fwBgE39/f39/f39/f39/f39/f39/f38Bf2AFf35+fn4AYAF/AX1gBH9+fn8AYAF+AX9gA39/fABgAX8Cf39gBH9/f38Bb2AMf39/f39/f39/f39/AX9gDX9/f39/f39/f39/f38Bf2AJf39/f39/f39/AX9gCH9/f39/f39/AX9gCn9/f39/f39/f38AYAF+AW9gA29vbwBgAXwBb2ADb29/AW9gBW9/f39/AGAEb29/fwFvYAVvf39vbwBgA29vfwBgA29/bwBgCH9+f39/f39/AX9gA35+fwF/YAd/f39+f39/AX9gCX9/f39/f39/fwBgDX9/f39/f39/f39/f38AYAt/f39/f39/f39/fwBgBH9/fn8Bf2AJf39/f39/fn5+AGADf35/AX9gF39/f39/f39/f39/f39/f39/f39/f39/AX9gA39+fgBgAn5/AGAPf39/f39/f39/f39/f39/AX9gA35/fwF+YAR/f35/AGAGf39/f35/AGAFf35/fn8AYAABfGAGfn9/f39/AX5gAX4BfmADf39vAn9/YAV/f3x/fwBgBH98f38AYAV/f31/fwBgBH99f38AYAR/f29vAGAGf39/f358AW9gAXwBf2AQf39/f39/f39/f39/f39/fwF/YBZ/f39/f39/f39/f39/f39/f39/f39/AX9gCn9/f39/f39/f38Bf2A3f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/fwF/YB5/f39/f39/f39/f39/f39/f39/f39/f39/f39/f38Bf2Alf39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/fwF/YEx/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/f39/AX9gB39/f35+fn4Bf2AIf39/f39/f34AYAd/f39+f39/AALsNLYBA3diZxVfX3diaW5kZ2VuX3N0cmluZ19uZXcAGgN3YmcVX193YmluZGdlbl9zdHJpbmdfZ2V0ABMDd2JnF19fd2JpbmRnZW5faXNfdW5kZWZpbmVkAAsDd2JnDV9fd2JpbmRnZW5faW4AIAN3YmcUX193YmluZGdlbl9pc19vYmplY3QACwN3YmcUX193YmluZGdlbl9pc19zdHJpbmcACwN3YmcWX193YmluZGdlbl9ib29sZWFuX2dldAALA3diZxhfX3diZ19ub2RldGVzdHJlc3VsdF9uZXcAGwN3YmcXX193Ymdfbnltbm9kZXRlc3Rlcl9uZXcAGwN3YmceX193Ymdfbnltbm9kZXRlc3RlcmJ1aWxkZXJfbmV3ABsDd2JnFF9fd2JpbmRnZW5fZXJyb3JfbmV3ABoDd2JnF19fd2JnX2NsaWVudHN0b3JhZ2VfbmV3ABsDd2JnFF9fd2JpbmRnZW5faXNfYmlnaW50AAsDd2JnGl9fd2JpbmRnZW5fYmlnaW50X2Zyb21fdTY0AEYDd2JnE19fd2JpbmRnZW5fanN2YWxfZXEAIAN3YmcUX193YmluZGdlbl9hc19udW1iZXIAJwN3YmcSX193YmluZGdlbl9pc19udWxsAAsDd2JnGV9fd2JpbmRnZW5fanN2YWxfbG9vc2VfZXEAIAN3YmcVX193YmluZGdlbl9udW1iZXJfZ2V0ABMDd2JnJF9fd2JnX2dldHdpdGhyZWZrZXlfMWRjMzYxYmQxMDA1M2JmZQAcA3diZxpfX3diZ19zZXRfM2YxZDBiOTg0ZWQyNzJlZABHA3diZx1fX3diZ19TdHJpbmdfOGYwZWIzOWE0YTRjMmY2NgATA3diZxVfX3diaW5kZ2VuX251bWJlcl9uZXcASAN3YmcSX193YmluZGdlbl9jYl9kcm9wAAsDd2JnHV9fd2JnX2NvbW1pdF9hNTRlZGNlNjVmMzg1OGYyACEDd2JnHV9fd2JnX1dpbmRvd180MTU1OTAxOTAzM2VkZTk0AAkDd2JnKF9fd2JnX1dvcmtlckdsb2JhbFNjb3BlX2QzMjRiZmZiZWFlZjlmM2EACQN3YmcdX193YmdfZ2xvYmFsX2Y1YzI5MjZlNTdiYTQ1N2YACQN3YmcgX193YmdfaW5kZXhlZERCXzU0ZjAxNDMwYjFlMTk0ZTgACwN3YmciX193YmdfcGVyZm9ybWFuY2VfN2ZlMDkyOGYzYWIwNTllNQAJA3diZyFfX3diZ19zZXRUaW1lb3V0XzQyMzcwY2IzMDUxYjhjMmMASQN3YmcaX193Ymdfbm93X2UxMTYzYzY3MTE1ZmY4NzQAJwN3YmccX193YmdfZmV0Y2hfMTFiZmY4Mjk5ZDBlY2QyYgAJA3diZyNfX3diZ19jbGVhclRpbWVvdXRfMGI1M2QzOTFjMWI5NGRkYQAJA3diZyFfX3diZ19zZXRUaW1lb3V0XzczY2U4ZGYxMmRlNGYyZjIAKAN3YmcaX193YmdfbG9nXzZkOTE1NTM4MTZmM2M2ZTMAAQN3YmcbX193Ymdfd2Fybl9hZjZhYjA5NDcyZGYxOWY1AAEDd2JnHF9fd2JnX2Vycm9yXzliNmM4YzAxNDI3Zjk4MzYAAQN3YmclX193YmdfcXVldWVNaWNyb3Rhc2tfOTdkOTJiNGZjYzhhNjFjNQAhA3diZyVfX3diZ19xdWV1ZU1pY3JvdGFza19kMzIxOWRlZjgyNTUyNDg1AAkDd2JnFl9fd2JpbmRnZW5faXNfZnVuY3Rpb24ACwN3YmcgX193YmdfaW5kZXhlZERCX2IxZjQ5MjgwMjgyMDQ2ZjgACwN3YmcgX193YmdfaW5kZXhlZERCX2Y2YjQ3YjBkYzMzM2ZkMmYACwN3YmccX193YmdfZmV0Y2hfNTA5MDk2NTMzMDcxYzY1NwAcA3diZypfX3diZ19pbnN0YW5jZW9mX1Jlc3BvbnNlX2YyY2MyMGQ5ZjdkZmQ2NDQACwN3YmciX193YmdfYXJyYXlCdWZmZXJfZDFiNDRjNDM5MGRiNDIyZgAJA3diZxpfX3diZ191cmxfYWUxMGMzNGNhMjA5NjgxZAATA3diZxtfX3diZ190ZXh0Xzc4MDViZWE1MGRlMmFmNDkACQN3YmcdX193Ymdfc3RhdHVzX2Y2MzYwMzM2Y2E2ODZiZjAACwN3YmceX193YmdfaGVhZGVyc185Y2I1MWNmZDJhYzc4MGE0AAkDd2JnGl9fd2JnX25ld18wMThkY2MyZDZjOGMyZjZhABIDd2JnHV9fd2JnX2FwcGVuZF84YzdkZDhkNjQxYTVmMDFiAEoDd2JnKF9fd2JnX25ld3dpdGhzdHJhbmRpbml0XzA2YzUzNWUwYTg2N2M2MzUANAN3YmcoX193YmdfY3JlYXRlT2JqZWN0U3RvcmVfZTU2NjQ1OWY3MTYxZjgyZgApA3diZyJfX3diZ190cmFuc2FjdGlvbl9iYWJjNDIzOTM2OTQ2YTM3ADUDd2JnLV9fd2JnX2luc3RhbmNlb2ZfSWRiRGF0YWJhc2VfYTNlZjAwOWNhMDAwNTlmOQALA3diZyJfX3diZ19wb3N0TWVzc2FnZV84M2E4ZDU4ZDNmY2I2YzEzABADd2JnHV9fd2JnX3RhcmdldF8wYTYyZDlkNzlhMmExZWRlAAsDd2JnIV9fd2JnX2xvd2VyQm91bmRfMTg3MmQxOWY1YmNmODNjNgAoA3diZyFfX3diZ191cHBlckJvdW5kXzc2YTAwODE0ZTgxZjY4OTEAKAN3YmccX193YmdfYm91bmRfZjJhZmMzNzY2ZDQ1NDVjZgBLA3diZyFfX3diZ19vbGRWZXJzaW9uX2U4MzM3ODExZTUyODYxYzYAJwN3YmchX193YmdfcmVhZHlTdGF0ZV80MDEzY2ZkZjRmMjJhZmIwAAsDd2JnIV9fd2JnX3NldG9uZXJyb3JfZDdlMzA1NmNjNmU1NjA4NQAQA3diZyNfX3diZ19zZXRvbnN1Y2Nlc3NfYWZhNDY0ZWU3NzdhMzk2ZAAQA3diZxxfX3diZ19lcnJvcl9mZjRkZGFhYmRmYzVkYmIzAAsDd2JnHV9fd2JnX3Jlc3VsdF9mMjlhZmFiZGYyYzA1ODI2AAkDd2JnLF9fd2JnX2luc3RhbmNlb2ZfSWRiUmVxdWVzdF80ODEzYzNmMjA3NjY2YWE0AAsDd2JnJF9fd2JnX2Rpc3BhdGNoRXZlbnRfOWUyNTlkN2MxZDYwM2RmYgAgA3diZydfX3diZ19hZGRFdmVudExpc3RlbmVyXzkwZTU1M2ZkY2UyNTQ0MjEANgN3YmcqX193YmdfcmVtb3ZlRXZlbnRMaXN0ZW5lcl8wNTZkZmU4YzNkNmM1OGY5ADYDd2JnJ19fd2JnX2FkZEV2ZW50TGlzdGVuZXJfODRhZTNlYWM2ZTE1NDgwYQBMA3diZyFfX3diZ19zZXRvbmFib3J0XzNiZjRkYjY2MTRmYTk4ZTkAEAN3YmchX193Ymdfc2V0b25lcnJvcl9iMGQ5ZDcyM2I4ZmRkYmJiABADd2JnIl9fd2JnX29iamVjdFN0b3JlXzIxODc4ZDQ2ZDI1YjY0YjYAKQN3YmckX193Ymdfc2V0b25jb21wbGV0ZV80ZDE5ZGYwZGFkYjdjNGQ0ABADd2JnHF9fd2JnX2Fib3J0Xzk5ZmM2NDRlMmM3OWM5ZmIAIQN3YmcpX193Ymdfc2V0b251cGdyYWRlbmVlZGVkX2ZjZjdjZTRmMmViMGNiNWYAEAN3YmchX193YmdfcmVhZHlTdGF0ZV83ZWY2ZTYzYzM0OTg5OWVkAAsDd2JnG19fd2JnX3NlbmRfMDI5MzE3OWJhMDc0ZmZiNAAqA3diZyRfX3diZ19zZXRiaW5hcnlUeXBlXzkyZmExZmZkODczYjMyN2MAIgN3YmcbX193Ymdfc2VuZF9mYzBjMjA0ZThhMTc1N2Y0ACoDd2JnGl9fd2JnX25ld185MmM1NGZjNzQ1NzRlZjU1ABoDd2JnHF9fd2JnX2Nsb3NlXzI4OTNiN2QwNTZhMDYyN2QAIQN3YmcbX193YmdfbmFtZV9mMmQyNzA5OGJmZDg0M2U3ABMDd2JnHl9fd2JnX21lc3NhZ2VfNWM1ZDkxOTIwNGQ0MjQwMAATA3diZy5fX3diZ19pbnN0YW5jZW9mX0RvbUV4Y2VwdGlvbl9lZDFjY2I3YWFmMzkwMzRjAAsDd2JnK19fd2JnX25ld3dpdGhldmVudGluaXRkaWN0XzUwMmRiZmExYjNkMmZjYmMANAN3YmcbX193YmdfY29kZV9mNGVjMWU2ZTJlMWIwNDE3AAsDd2JnHV9fd2JnX3JlYXNvbl80OWYxY2VkZThiY2YyM2RkABMDd2JnH19fd2JnX3dhc0NsZWFuXzYwNWI0ZmQ2NmQ0NDM1NGEACwN3YmcbX193YmdfZGF0YV80MzJkOWMzZGYyNjMwOTQyAAkDd2JnIl9fd2JnX3RyYW5zYWN0aW9uXzdkNDUyNDc1ZWYzYzNjMzMACQN3YmcaX193YmdfcHV0XzA2NmZhYTMxYTZhODhmNWIAKwN3YmccX193YmdfY291bnRfOWRiZWRlZTRkMjQ3NGZmOAAcA3diZxpfX3diZ19nZXRfOGRhMDNmODFmNmExMTExZQAcA3diZxtfX3diZ19vcGVuX2UwYzBiMjk5M2ViNTk2ZTEANQN3YmccX193YmdfYWJvcnRfNDEwZWM0N2E2NGFjNjExNwAQA3diZxpfX3diZ19uZXdfZTI1ZTVhYWIwOWZmNDVkYgASA3diZxxfX3diZ19hYm9ydF83NzVlZjFkMTdmYzY1ODY4ACEDd2JnHV9fd2JnX3NpZ25hbF9hYWY5YWQ3NDExOWYyMGE0AAkDd2JnIF9fd2JnX3NldG1ldGhvZF8zYzUyODBmZTVkODkwODQyACoDd2JnIF9fd2JnX3NldHNpZ25hbF83NWIyMWVmM2E4MWRlOTA1ABADd2JnJV9fd2JnX3NldGNyZWRlbnRpYWxzX2MzYTIyZjFjZDEwNWEyYzYAIgN3YmchX193Ymdfc2V0aGVhZGVyc184MzRjMGJkYjZhODk0OWFkABADd2JnHl9fd2JnX3NldGJvZHlfNTkyM2I3OGE5NWVlZGYyOQAQA3diZx5fX3diZ19zZXRtb2RlXzVkYzMwMGI4NjUwNDRiNjUAIgN3YmcgX193Ymdfc2V0cmVhc29uX2QyOWFjMDQwMmVlZWI4MWEAKgN3YmceX193Ymdfc2V0Y29kZV8xNTYwNjA0NjVhMmY4Zjc5ACIDd2JnHl9fd2JnX3NldG9uY2VfMGNiODBhZWEyNjMwM2EzNQAiA3diZyRfX3diZ19nZXR3aXRocmVma2V5XzY1NTBiMmMwOTNkMmViMTgAHAN3YmcdX193YmdfU3RyaW5nX2VlY2M0YTExOTg3MTI3ZDYAEwN3YmcdX193YmdfY3J5cHRvXzU3NGU3OGFkOGIxM2I2NWYACQN3YmceX193YmdfcHJvY2Vzc19kYzBmYmFjYzdjMWMwNmY3AAkDd2JnH19fd2JnX3ZlcnNpb25zX2MwMWRmZDQ3MjJhODgxNjUACQN3YmcbX193Ymdfbm9kZV85MDVkM2UyNTFlZGZmOGEyAAkDd2JnHl9fd2JnX3JlcXVpcmVfNjBjYzc0N2E2YmM1MjE1YQASA3diZx9fX3diZ19tc0NyeXB0b19hNjFhZWIzNWEyNGMxMzI5AAkDd2JnJV9fd2JnX3JhbmRvbUZpbGxTeW5jX2FjMDk4OGFiYTMyNTQyOTAAEAN3YmcmX193YmdfZ2V0UmFuZG9tVmFsdWVzX2I4ZjVkYmQ1ZjM5OTVhOWUAEAN3YmcaX193YmdfbmV3XzVlMGJlNzM1MjFiYzhjMTcAEgN3YmcaX193YmdfbmV3Xzc4ZmViMTA4YjY0NzI3MTMAEgN3YmcaX193YmdfbmV3XzQwNWUyMmYzOTA1NzZjZTIAEgN3YmcgX193YmdfbmV3bm9hcmdzXzEwNWVkNDcxNDc1YWFmNTAAGgN3YmcaX193YmdfbmV3X2ExMjAwMmE3ZjkxYzc1YmUACQN3YmcdX193YmdfYnVmZmVyXzYwOWNjM2VlZTUxZWQxNTgACQN3YmcxX193YmdfbmV3d2l0aGJ5dGVvZmZzZXRhbmRsZW5ndGhfZDk3ZTYzN2ViZTE0NWE5YQApA3diZx1fX3diZ19sZW5ndGhfYTQ0NjE5M2RjMjJjMTJmOAALA3diZyRfX3diZ19uZXd3aXRobGVuZ3RoX2EzODE2MzRlOTBjMjc2ZDQAGwN3YmcaX193Ymdfc2V0XzY1NTk1YmRkODY4YjMwMDkATQN3YmcfX193Ymdfc3ViYXJyYXlfYWE5MDY1ZmE5ZGM1ZGY5NgApA3diZxtfX3diZ19kb25lXzc2OWU1ZWRlNGIzMWM2N2IACwN3YmccX193YmdfdmFsdWVfY2QxZmZhN2IxYWI3OTRmMQAJA3diZydfX3diZ19pbnN0YW5jZW9mX0Vycm9yXzRkNTQxMTNiMjJkMjAzMDYACwN3YmcsX193YmdfaW5zdGFuY2VvZl9VaW50OEFycmF5XzE3MTU2YmNmMTE4MDg2YTkACwN3YmctX193YmdfaW5zdGFuY2VvZl9BcnJheUJ1ZmZlcl9lMTQ1ODU0MzJlMzczN2ZjAAsDd2JnGl9fd2JnX3NldF84ZmM2YmY4YTViMTA3MWQxACsDd2JnG19fd2JnX25ldzBfZjc4OGEyMzk3YzdjYTkyOQASA3diZx5fX3diZ19nZXRUaW1lXzQ2MjY3YjFjMjQ4NzdlMzAAJwN3YmcaX193YmdfZ2V0X2I5YjkzMDQ3ZmUzY2Y0NWIAKAN3YmcaX193Ymdfc2V0XzM3ODM3MDIzZjNkNzQwZTgATgN3YmcdX193YmdfbGVuZ3RoX2UyZDJhNDkxMzJjMWIyNTYACwN3YmceX193YmdfaXNBcnJheV9hMWVhYjdlMGQwNjczOTFiAAsDd2JnGl9fd2JnX25ld19jNjhkNzIwOWJlNzQ3Mzc5ABoDd2JnG19fd2JnX25hbWVfMGIzMjdkNTY5ZjAwZWJlZQAJA3diZx5fX3diZ19tZXNzYWdlXzk3YTJhZjliODlkNjkzYTMACQN3YmcfX193YmdfdG9TdHJpbmdfYzgxM2JiZDM0ZDA2MzgzOQAJA3diZyRfX3diZ19pc1NhZmVJbnRlZ2VyXzM0M2UyYmVlZWVjZTFiYjAACwN3YmceX193YmdfZW50cmllc18zMjY1ZDQxNThiMzNlNWRjAAkDd2JnH19fd2JnX3RvU3RyaW5nXzUyODU1OTc5NjA2NzZiN2IACQN3YmcfX193YmdfaXRlcmF0b3JfOWEyNGM4OGRmODYwZGM2NQASA3diZzJfX3diZ19zdGF0aWNfYWNjZXNzb3JfR0xPQkFMX1RISVNfNTY1NzhiZTdlOWY4MzJiMAANA3diZxtfX3diZ19jYWxsXzY3MmE0ZDIxNjM0ZDRhMjQAHAN3YmcrX193Ymdfc3RhdGljX2FjY2Vzc29yX1NFTEZfMzdjNWQ0MThlNGJmNTgxOQANA3diZy1fX3diZ19zdGF0aWNfYWNjZXNzb3JfR0xPQkFMXzg4YTkwMmQxM2E1NTdkMDcADQN3YmctX193Ymdfc3RhdGljX2FjY2Vzc29yX1dJTkRPV181ZGUzNzA0M2E5MWE5YzQwAA0Dd2JnGl9fd2JnX25ld18yM2EyNjY1ZmFjODNjNjExABoDd2JnG19fd2JnX3RoZW5fNDRiNzM5NDZkMmZiM2U3ZAAcA3diZxtfX3diZ190aGVuXzQ4YjQwNjc0OTg3OGE1MzEAKwN3YmcdX193YmdfcmVqZWN0X2IzZmNmOTkwNjMxODZmZjcACQN3YmceX193YmdfcmVzb2x2ZV80ODUxNzg1YzljNWY1NzNkAAkDd2JnG19fd2JnX2NhbGxfN2NjY2RkNjllMDc5MWFlMgArA3diZxtfX3diZ19uZXh0XzI1ZmVhZGZjMDkxM2ZlYTkACQN3YmcbX193YmdfbmV4dF82NTc0ZTFhOGE2MmQxMDU1AAkDd2JnGl9fd2JnX2dldF82N2IyYmE2MmZjMzBkZTEyABwDd2JnGl9fd2JnX2hhc19hNWVhOTExN2YyNThhMGVjACADd2JnIF9fd2JnX3N0cmluZ2lmeV9mN2VkNjk4NzkzNWI0YTI0AAkDd2JnHF9fd2JpbmRnZW5fYmlnaW50X2dldF9hc19pNjQAEwN3YmcRX193YmluZGdlbl9tZW1vcnkAEgN3YmcQX193YmluZGdlbl90aHJvdwABA3diZxdfX3diaW5kZ2VuX2RlYnVnX3N0cmluZwATA3diZx5fX3diaW5kZ2VuX2Nsb3N1cmVfd3JhcHBlcjE4NDYAFAN3YmceX193YmluZGdlbl9jbG9zdXJlX3dyYXBwZXIyODc2ABQDd2JnHl9fd2JpbmRnZW5fY2xvc3VyZV93cmFwcGVyMjg3NwAUA3diZx5fX3diaW5kZ2VuX2Nsb3N1cmVfd3JhcHBlcjU2NzEAFAN3YmceX193YmluZGdlbl9jbG9zdXJlX3dyYXBwZXI2MDk2ABQDd2JnHl9fd2JpbmRnZW5fY2xvc3VyZV93cmFwcGVyNjE5OQAUA3diZx5fX3diaW5kZ2VuX2Nsb3N1cmVfd3JhcHBlcjYyMDEAFAN3YmceX193YmluZGdlbl9jbG9zdXJlX3dyYXBwZXI2MjAzABQDd2JnHl9fd2JpbmRnZW5fY2xvc3VyZV93cmFwcGVyNjIwNQAUA3diZx5fX3diaW5kZ2VuX2Nsb3N1cmVfd3JhcHBlcjYyNjMAFAN3YmcfX193YmluZGdlbl9pbml0X2V4dGVybnJlZl90YWJsZQAPA7UlsyUDAwMDAwAfEQMBAQMBAwEHAwMYAwMDFQQDAwMDAwMDAQMHAQAADgMAAQMGAQYDBAEDAwMGCgQBAwMKAAMDAAMDAwEABAMDAAEAAQMDAwMDAwADBQMBFQADAwMDAwMDAQEHBAMDAQMDAk8DA1ABAwAIAAAAAwgdAwMDAwIBAAADAQADAQABUQMAAAMEAwUDAQMAAAMDAwEDAFIEAwMBAQMBAgEFBQADAwIBAQEDAwECAQEDBQMDAQBTBAEAAQUDAgEBAwMDNwADAAMBAAEBAgIDAAADAgICAgICAgICAQEDAwEEBAcBBAECAwIDBwACBgYCBgAEAwEBAAEAAAAAAQMDAwMBAwoBAQABBAIDNxUDCAEAAgIjAAEAAQAAAwMBAQICAgICAAMAAAIDAQIBAwABAQMEAwIBIwEAAgMBBQIGAAAFBQIDAwMDAAMKCgoAAgICBgEOAAMDBgMFAQEIAwMDAwECAwUBAwAkAAUCAAEBAwAFAQUDBQUGAAAMDA4BAQMCAgEBA1QCAAMDGAAYGAAAAwgGBgoKAQMBAgMDAAMDGBgEFRgEAAUBBAAABgEAAAADAQMFDgMDAQEAAwMZGREAAwoOAgEODgMCAgMBAQgBAQMBBgEGBwEBBwEBAQMAGQgCAwMFAAADAQEAAQAAAAIDAAAAVQ4DAQEAAQMZAAEBAAAPBQAODgMDAwIDAwMBBgEDAwNWJQEBAAAEAQEBAQEDBAIDAwMDAQMBBgEDAwMBAQIAAQEBBgABAQEBByYAAgAKAAADAwEBAQEDBAADAwIBAQU4AwMBAAMCAwAAAQEAAgcBHQEDAQEDAwIDAwQEAQEBFwADAwYAAAMAAAAKAwEAAQEOBgMAIwIEBAMOAQ4AAAADAwMEAQMBAwoGAQMHAQIDGQEDBgIBAQEBBgADAAIAAAAAAAADAQcBAQAEAwEDAAMBAQEBAwYAAQYBAQAGAQEBAQEBAQEDAwMBAwQBAQQGAwACAQERBgEKAAoAAQEDAQEDAQEBAwEBBxcKBQEAAAMADAYBAwIAAAAjJgIGAQAHDQECAQABAAECABgAAAEBAQMDAQADAAUDAAIBAQ0ABAAHBAEYAAMDAAIDBAMDAQQBBAMDAAMDAQMBAQEAAlcDDAMDAgAAAAEAACUBAAAAAAAAAQEAAgEBAAYDAAIBAwAMAAYAAAIAAgABAwYNAwEDAQEDAQMHAAAEAwMBBgYDAQoAAgABAwQABgMAAwMAAQAAAAADAAEAAC8vAAEvAwIGBgMCAwMDAQQEAQYGBAUDAgANAwECAwECBwEAAQUADgEKAwABBQABAAAAAQMCAAUCBQAAAAMDBwABAQEAAQACBgMBAAEBAAMBBAECAQEBAQMBAQABAQUAAQMCAQEBAQEBAAAAAVgKAQEBAQEBAQEBAQEBBQEAAQEBAQEKWQIGAgQFBQUHEVoDAAAABAIBCggEAQMHOQMBAAABAAEDBgADAAECAQMDAAEBAQABAQMADiYAFwEABQEIAwMBAwEDAwACAQAAAgAAAAoKCgAAAgABAAAAAQYEB1sGAwEBAgAAAxEEAwYBAQEBAQEBAQEBAQEBAQMDBgABCAgIAAMDBgMBBAEBAAUDAwACAQEAAAIBAAICAgICAAQREQAGBAMEHgEDAQEBAAMBAQMNAAEAAQEAMAAABgMFAwMHAQMDAQIHAQAFAQIDAgQDAgIAAgIDAQADHQIBBR8EAAEDCgQAAToBAQYFBAEBCAIELAYBCA4IAQECAQEBAQEMAQECAwMDAQAMBgEDAQECAgICBAEAAQMDBAEBAQIBAQQGAQIAAQEAAAQAAAAEAQAAAQEBAQEAAwMDAQIAAQABAQAxAAABAgEABAACAQMDAwMDAwMDAwgGAwABAQEXAgMAAAAAAQQCDAEDAAUBAQEBAgEBAQcEAAEHAQICAAEDAAEfBgIBAgEBBQAGAQECBgEBAQEBAwEAAQABXAMHBgAAAAECCAMDAwIBAwIBAwEDAC0ABAYAAgMHAgYBAQMEAAEBAgYBAAMBAwMGDAICAgEAAQIAAgEIAgQEAwAEAAADAQAEAgICAQICAgICAgICBAcCXQEBAQElAQEBAgYBAAMFBQEBAgEDAAICAQICBwEBAQEBAAIDAgAFAQQBAAIBAQEDAQEBAQEAAAAAAAAGAwAAAAABAQMBAwIDAwE6AgEDAwAAAAICAAgCAAEDAAQBBwMBAgEDAQEBAAICAAADAQMAAAMDAgECAwIBBgECAgICBgAAAgIBBAIEBAgCAgMAAwEEAgIEAQA7AQUAAgcBCgYsDQIAA14CBQAAAwMDAQIABQMAAQEBAgUCBQYBAAAAAAYGAwAAAAMBAwEBAwICAgEBAAYAAiYCAgICAgYBBgAKAwEBAQMAAQAAAAEDAQAAAQcHAwYCAAACAwABBwECAQEBAAICAQABAAMFAwEBAgIDAgEEAAICAQEBAQUCAgECAQEEAgEBAQECAQECAhEGAQEBAQEBAwEBAgIDBgECAAMAAwEDBAIBAgQEBAEBAAECBQAAAAAGAQYCAAUAAgIDAgEBBQMFAAIAAxcBAQEBAAUGBgYFBwICAgICBAcDAQECAgACBAcBAAQCBQABAAIFPDwBAgEBAQEDAwEAAgEBBgIBAgIBAAECBwcHBwcBBAICBQICBgYBAQEGAAABAAoBAAACAgEBBwcAAAQBAQQDAQEAAwMBAgAABgYCAQMEAgABAAYCAgABAgEBASQGAQMBAQMCAQACAgQBAQMABgYAAQAAAgECAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAQMDAwMBAgQDAwICBAQ9Al8CAQIEAgABAQMCAgMHJAIBAQADABEBAAAAAgEAAAAEBAAAAAAAAAACAQAABgYDAAEBAgICMQIBAQIBAQMBAwQCAwMBAw8EAQMBAgIBAAACAQEAAAICAAEAAAABAwIAAAIAAAAAAGACAgABAAACBgICAgEDAgIBAQ0CAgICAgIAAgAAAAAEBAQCAgICAAACAAAGAgUCBQUAAAECBAAEBAABAgIDAwMAAAQCDQIABA8BAQQCAQIBBAQEBAQCAgYAAgIEAgEAAA8CAgAKIwFhAQMPBQICAgICAgECDQICAgINAwECAgECBwAHAQERAQEAAAICAgIBAQECAQIDAAcHBwMCAQAAAAEDAAACAQAAAQECAQEAAQoHAAAAAQEDAAAHAAEAAgEDAwMCAwIBAwMCAgQHAwMCAgIDAgICAgIHAgMHAQcEAwMBAgcHAwEBBQUFBQICAgIAAQECDQMCAgICAAAAAgIABAAAAAAABAICAgUAAAADAgAAAgICAwEBAQAGBgcEBAcBBAICAgAAAAARAQEAAwMDBgEBBgMCAgIBAgIBBAECAQIBBgYAAwEGDQUEAgICAgICAgECBAIBAgIEBAIBAgQEAgYIAgECAQYCAQEBBAABAQECAQECAQEBAQEBAQEBAwICAgICAgACAgECAAABAAAAAAEAAQEAAgICAgMAAQUCAAIDAgIBAQEAAgIBAgIDAQACAQYfAgQBDQECAAwBAgAHBwcHBwcCAQMCAgIBAQECAgEBAQEBAQEBAQEBAQEBAgEAAAIBAAEBAQABAQAAAQEBAgEBAgQDAAEAAAIAAQIBAQEEAAEBAQEGAAcGAgIBAgIAAQEDOwABAgIBAgICAAADAQEBAQEAAAIAAA8BDwIPBAAAAQECAAMDBQQBAAAAAAMCAA8CAg8CAgICAgICAgICAgICAgICAgICAgEABgICAgQEAgIBAAAEBAQtMAAAAQAEAAIBAgAEAgIBAgAAAQEAAAAAAAAAAAQAAAAAAAYGAQANCAEABAICAgICAQYEAgICAgICAQICAgICAgICAgICBAECAiUAAgEHAQQCAgIABAIAAQICAgICAgICAgICAgICAgIDBQIBAgIBLQBiBAACAgQAAAMCJCQDAAYCAgMDAwMDAwICBgEBAgICAgEBBAICBAICAQEBAAQEPh8fAwMBAgICAgIBAQIFAgACAgIEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAQEBAQEBAQEBAQIBAgIBAQEBBAEBAQEBAQUBBAMCAQECAhcAAAEBAgIEAgECAQZjAgIEAgICAg0CAgICAi0CAgICAgICAQICAgEBFwMDAAICAgICAgICAgICAgICAgICAgICAgICAgEwAQEBAQEBAQEBAQEGAQACBAQEAQIBBAIGAQEBAQEBAQEBAwMBAQEBPz8CAgICAgECAAICAgEAAQIEBAEABAACAgM+FQECAgIIAgICAgMCAgICFhYGAgIAAhYWAgIFAAEBAQEHZAw4ZgIIBAICAgIBAgICAgICAgICAgICAAMCBAQAAgICAgICAwMDAQAAAAICAgIDAwYAAQBoAgACAgICAgICAgEBAQEWDQAEAgIAAgIGAQECAgECFhYBAQEWAQEBAQQBAAAABgIEBQABAgQCAgECAAQGAQAABAAEAAAIAAQCAAAEAAACBAAEAQAEAQACAAMEAABpAgICAgICAgICAgICAgICAgICAQECAQIBAgECAgEBAQEBAQEBAQEAAQMDAQEBAQECAQECAQEBAQEBAQEBAQEBAQAAAQQBAQQBAQEBAQIBAQEBAQADAwEBAQEBAQEBAQEBAQEBAQEBAQEBAQEDAQEBAQEBAQEBAAABAgIBAQEBAQEBAAEBAQEBAQEBAAEBAQEBAQEBAQEEAQEBAQEBAQEBAQEBAAEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQECAQEAAAEBAQEBAAEBAQEBAQEBAgAAAAEBAQEBAQEBAQEAAQEBAQEBAAEAAQEBAQAAAAAACQkCAgICAgIDAgIGAgEDAgIAAwIBAQAAAgMEAgICAgIDAAAEBEBAAgICAgICAgICAgICAgICAgUCAgICAgICAgIDAgMCAgICAgQDBgMCBAIFAwACAgIFAAUAAAAAAAAFAAICAQEBAgEBAQEBAQIBAgEABQECAgICAgACAgMFAAQ9ajMzMwICAAICAQECAQYGAwIBAgYGBgYGBgUBBAAEAwACAwMDBgYDBAcNDQ0aGgIAAgECAgEAAQECAgECAAECAggBAQEBBAMAAQMAAQMBAQAAAQEBAAIBAQEBAAEBAgEBAQABAgACAgEBDwEBAQEBAQEDAwEAAQABAQEAAQECAQIBAQEBAgEABgYAAQEBAQEBAQEBAAEBAQECAgECAQEAAAQbGxsCAgIEBAMCAgMCAQEBAQEDAgQAAwQAAAINAAMAAA8AAAAAAAAAAAQEAQECBAAACAAEAAMEBAQEAQAEBAMEBA0EBQACAwAEBBISAgICAgECAgICAgICAgIAAgICAgIAAgICAAAAAgICAgICAgEAAAICAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAABAAAAAAAAAAIAAAAAAAAAAAAAAAAAAgIAAAAAAAAAAAACAAIAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAACAAAAAAAAAAIAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAIAAAQCBAAAAAAAAAAAAAIAAAAAAgAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAABAAAAAAAAAgQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAABAAACAgIAAAAAAAAAAwIAAAAAAAAAAAAAAAIAAgAAAAAAAAAAAAAAAAAAAAAABgAABAQAAAMBAAIDAgAAAAAAAAAAAAADAQAAAAMAAAICAQACAwEAAAABDw8AAAAAAAABAAUAAAAAAAQAAAEBAAECAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAgAAAAAAAAAAAAAAAAAAADEAAAAAAgABAAAAAAAAAAEAAAAAAAABAAIAAAAAAAEBAQEBAAECAQEBAQAXAgQEAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMABAEEBAAAAAIAAAQAAQEBAQAEBAQABAAEAAAAAgIEBAQEBAQEBAQEAgQEAg8EAgIZDRcEBAQPAAAEGQMCAREMHR4eDBUMHUEuHgwMCBUFCAUGBgMBawMeAwcDAS4IFQwMDAwMDANsbR0uCgcICANubx5BHh0OOUIdQwVEcEIHcQMMBgYDAwUIDBUDDEMuCAcHBgYKBgYHRQUFBQUVAQMGBwEGRURyCAMGAQFzAwoGCgoHBwUDBw4MCAUFBQAAdAAGBgYGBwAGAyYHBgcHDAUDBgYHAwQLAnABvhO+E28AgAEFAwEAGgYJAX8BQYCAwAALB+A6qAEGbWVtb3J5AgAnX193YmdfZ2V0X25vZGV0ZXN0cmVzdWx0X2R1cGxpY2F0ZV9hY2tzALoTKl9fd2JnX2dldF9ub2RldGVzdHJlc3VsdF9kdXBsaWNhdGVfcGFja2V0cwC7EyZfX3diZ19nZXRfbm9kZXRlc3RyZXN1bHRfcmVjZWl2ZWRfYWNrcwC8EylfX3diZ19nZXRfbm9kZXRlc3RyZXN1bHRfcmVjZWl2ZWRfcGFja2V0cwC9EyVfX3diZ19nZXRfbm9kZXRlc3RyZXN1bHRfc2VudF9wYWNrZXRzAL4TGV9fd2JnX25vZGV0ZXN0cmVzdWx0X2ZyZWUA2hQnX193Ymdfc2V0X25vZGV0ZXN0cmVzdWx0X2R1cGxpY2F0ZV9hY2tzAN0VKl9fd2JnX3NldF9ub2RldGVzdHJlc3VsdF9kdXBsaWNhdGVfcGFja2V0cwDeFSZfX3diZ19zZXRfbm9kZXRlc3RyZXN1bHRfcmVjZWl2ZWRfYWNrcwDfFSlfX3diZ19zZXRfbm9kZXRlc3RyZXN1bHRfcmVjZWl2ZWRfcGFja2V0cwDgFSVfX3diZ19zZXRfbm9kZXRlc3RyZXN1bHRfc2VudF9wYWNrZXRzAOEVGm5vZGV0ZXN0cmVzdWx0X2xvZ19kZXRhaWxzAMUXFG5vZGV0ZXN0cmVzdWx0X3Njb3JlAPwWGF9fd2JnX255bW5vZGV0ZXN0ZXJfZnJlZQCgFR9fX3diZ19ueW1ub2RldGVzdGVyYnVpbGRlcl9mcmVlALsSJW55bW5vZGV0ZXN0ZXJfZGlzY29ubmVjdF9mcm9tX2dhdGV3YXkAjSARbnltbm9kZXRlc3Rlcl9uZXcA6x0ibnltbm9kZXRlc3Rlcl9yZWNvbm5lY3RfdG9fZ2F0ZXdheQCOIBdueW1ub2RldGVzdGVyX3Rlc3Rfbm9kZQD6GxhueW1ub2RldGVzdGVyYnVpbGRlcl9uZXcA7B0hbnltbm9kZXRlc3RlcmJ1aWxkZXJfc2V0dXBfY2xpZW50AI8gGF9fd2JnX2NsaWVudHN0b3JhZ2VfZnJlZQDYDBFjbGllbnRzdG9yYWdlX25ldwCQHhdjbGllbnRzdG9yYWdlX25ld19hc3luYwCRHh1jbGllbnRzdG9yYWdlX25ld191bmVuY3J5cHRlZACYHx9fX3diZ19hY2tub3dsZWRnZW1lbnRzd2FzbV9mcmVlAMARG19fd2JnX2NvdmVydHJhZmZpY3dhc21fZnJlZQDAERRfX3diZ19kZWJ1Z3dhc21fZnJlZQDuDxdfX3diZ19mb3JnZXRtZXdhc21fZnJlZQDcECBfX3diZ19nYXRld2F5Y29ubmVjdGlvbndhc21fZnJlZQCMETNfX3diZ19nZXRfYWNrbm93bGVkZ2VtZW50c3dhc21fYWNrX3dhaXRfYWRkaXRpb25fbXMAhhkyX193YmdfZ2V0X2Fja25vd2xlZGdlbWVudHN3YXNtX2Fja193YWl0X211bHRpcGxpZXIA2RkzX193YmdfZ2V0X2Fja25vd2xlZGdlbWVudHN3YXNtX2F2ZXJhZ2VfYWNrX2RlbGF5X21zAIcZPF9fd2JnX2dldF9jb3ZlcnRyYWZmaWN3YXNtX2Rpc2FibGVfbG9vcF9jb3Zlcl90cmFmZmljX3N0cmVhbQCIGSRfX3diZ19nZXRfZGVidWd3YXNtX2Fja25vd2xlZGdlbWVudHMAkhAhX193YmdfZ2V0X2RlYnVnd2FzbV9jb3Zlcl90cmFmZmljAJMQHV9fd2JnX2dldF9kZWJ1Z3dhc21fZm9yZ2V0X21lAPsRJl9fd2JnX2dldF9kZWJ1Z3dhc21fZ2F0ZXdheV9jb25uZWN0aW9uAM8XH19fd2JnX2dldF9kZWJ1Z3dhc21fcmVtZW1iZXJfbWUA0BcfX193YmdfZ2V0X2RlYnVnd2FzbV9yZXBseV9zdXJicwDDECNfX3diZ19nZXRfZGVidWd3YXNtX3N0YXRzX3JlcG9ydGluZwDnBxxfX3diZ19nZXRfZGVidWd3YXNtX3RvcG9sb2d5ANIOG19fd2JnX2dldF9kZWJ1Z3dhc21fdHJhZmZpYwDTDh1fX3diZ19nZXRfZm9yZ2V0bWV3YXNtX2NsaWVudACJGRxfX3diZ19nZXRfZm9yZ2V0bWV3YXNtX3N0YXRzAIoZO19fd2JnX2dldF9nYXRld2F5Y29ubmVjdGlvbndhc21fZ2F0ZXdheV9yZXNwb25zZV90aW1lb3V0X21zAIsZQF9fd2JnX2dldF9yZXBseXN1cmJzd2FzbV9tYXhpbXVtX2FsbG93ZWRfcmVwbHlfc3VyYl9yZXF1ZXN0X3NpemUAjBkxX193YmdfZ2V0X3JlcGx5c3VyYnN3YXNtX21heGltdW1fcmVwbHlfa2V5X2FnZV9tcwCNGUJfX3diZ19nZXRfcmVwbHlzdXJic3dhc21fbWF4aW11bV9yZXBseV9zdXJiX2Ryb3Bfd2FpdGluZ19wZXJpb2RfbXMAjhlHX193YmdfZ2V0X3JlcGx5c3VyYnN3YXNtX21heGltdW1fcmVwbHlfc3VyYl9yZXJlcXVlc3Rfd2FpdGluZ19wZXJpb2RfbXMAjxk9X193YmdfZ2V0X3JlcGx5c3VyYnN3YXNtX21heGltdW1fcmVwbHlfc3VyYl9zdG9yYWdlX3RocmVzaG9sZACQGTdfX3diZ19nZXRfcmVwbHlzdXJic3dhc21fbWF4aW11bV9yZXBseV9zdXJic19yZXJlcXVlc3RzAJEZOF9fd2JnX2dldF9yZXBseXN1cmJzd2FzbV9taW5pbXVtX3JlcGx5X3N1cmJfcmVxdWVzdF9zaXplAIcZPF9fd2JnX2dldF9yZXBseXN1cmJzd2FzbV9taW5pbXVtX3JlcGx5X3N1cmJfdGhyZXNob2xkX2J1ZmZlcgCSGSZfX3diZ19nZXRfcmVwbHlzdXJic3dhc21fc3VyYl9taXhfaG9wcwDRFy1fX3diZ19nZXRfc3RhdHNyZXBvcnRpbmd3YXNtX3Byb3ZpZGVyX2FkZHJlc3MArBopX193YmdfZ2V0X3RvcG9sb2d5d2FzbV9kaXNhYmxlX3JlZnJlc2hpbmcAkxkwX193YmdfZ2V0X3RvcG9sb2d5d2FzbV9pZ25vcmVfaW5ncmVzc19lcG9jaF9yb2xlAJQZMl9fd2JnX2dldF90b3BvbG9neXdhc21fbWluaW11bV9nYXRld2F5X3BlcmZvcm1hbmNlAJUZMl9fd2JnX2dldF90b3BvbG9neXdhc21fbWluaW11bV9taXhub2RlX3BlcmZvcm1hbmNlAJYZLF9fd2JnX2dldF90b3BvbG9neXdhc21fdXNlX2V4dGVuZGVkX3RvcG9sb2d5AJcZJl9fd2JnX2dldF90cmFmZmljd2FzbV9kaXNhYmxlX21peF9ob3BzAJgZN19fd2JnX2dldF90cmFmZmljd2FzbV9tYXhpbXVtX251bWJlcl9vZl9yZXRyYW5zbWlzc2lvbnMA0hcuX193YmdfZ2V0X3RyYWZmaWN3YXNtX3VzZV9leHRlbmRlZF9wYWNrZXRfc2l6ZQCZGS5fX3diZ19nZXRfdHJhZmZpY3dhc21fdXNlX2xlZ2FjeV9zcGhpbnhfZm9ybWF0AJoZIF9fd2JnX2dldF90cmFmZmljd2FzbV91c2Vfb3V0Zm94AJsZGV9fd2JnX3JlbWVtYmVybWV3YXNtX2ZyZWUAjREZX193YmdfcmVwbHlzdXJic3dhc21fZnJlZQDdEDNfX3diZ19zZXRfYWNrbm93bGVkZ2VtZW50c3dhc21fYWNrX3dhaXRfYWRkaXRpb25fbXMAgxoyX193Ymdfc2V0X2Fja25vd2xlZGdlbWVudHN3YXNtX2Fja193YWl0X211bHRpcGxpZXIAhBozX193Ymdfc2V0X2Fja25vd2xlZGdlbWVudHN3YXNtX2F2ZXJhZ2VfYWNrX2RlbGF5X21zAIUaPF9fd2JnX3NldF9jb3ZlcnRyYWZmaWN3YXNtX2Rpc2FibGVfbG9vcF9jb3Zlcl90cmFmZmljX3N0cmVhbQCcGSRfX3diZ19zZXRfZGVidWd3YXNtX2Fja25vd2xlZGdlbWVudHMA1BIhX193Ymdfc2V0X2RlYnVnd2FzbV9jb3Zlcl90cmFmZmljANUSHV9fd2JnX3NldF9kZWJ1Z3dhc21fZm9yZ2V0X21lAMERJl9fd2JnX3NldF9kZWJ1Z3dhc21fZ2F0ZXdheV9jb25uZWN0aW9uAOQYH19fd2JnX3NldF9kZWJ1Z3dhc21fcmVtZW1iZXJfbWUA5RgfX193Ymdfc2V0X2RlYnVnd2FzbV9yZXBseV9zdXJicwCUEiNfX3diZ19zZXRfZGVidWd3YXNtX3N0YXRzX3JlcG9ydGluZwC/DhxfX3diZ19zZXRfZGVidWd3YXNtX3RvcG9sb2d5AKkQG19fd2JnX3NldF9kZWJ1Z3dhc21fdHJhZmZpYwDvDx1fX3diZ19zZXRfZm9yZ2V0bWV3YXNtX2NsaWVudACdGRxfX3diZ19zZXRfZm9yZ2V0bWV3YXNtX3N0YXRzAJ4ZO19fd2JnX3NldF9nYXRld2F5Y29ubmVjdGlvbndhc21fZ2F0ZXdheV9yZXNwb25zZV90aW1lb3V0X21zAIYaQF9fd2JnX3NldF9yZXBseXN1cmJzd2FzbV9tYXhpbXVtX2FsbG93ZWRfcmVwbHlfc3VyYl9yZXF1ZXN0X3NpemUAhxoxX193Ymdfc2V0X3JlcGx5c3VyYnN3YXNtX21heGltdW1fcmVwbHlfa2V5X2FnZV9tcwCIGkJfX3diZ19zZXRfcmVwbHlzdXJic3dhc21fbWF4aW11bV9yZXBseV9zdXJiX2Ryb3Bfd2FpdGluZ19wZXJpb2RfbXMAiRpHX193Ymdfc2V0X3JlcGx5c3VyYnN3YXNtX21heGltdW1fcmVwbHlfc3VyYl9yZXJlcXVlc3Rfd2FpdGluZ19wZXJpb2RfbXMAiho9X193Ymdfc2V0X3JlcGx5c3VyYnN3YXNtX21heGltdW1fcmVwbHlfc3VyYl9zdG9yYWdlX3RocmVzaG9sZACLGjdfX3diZ19zZXRfcmVwbHlzdXJic3dhc21fbWF4aW11bV9yZXBseV9zdXJic19yZXJlcXVlc3RzAIwaOF9fd2JnX3NldF9yZXBseXN1cmJzd2FzbV9taW5pbXVtX3JlcGx5X3N1cmJfcmVxdWVzdF9zaXplAIUaPF9fd2JnX3NldF9yZXBseXN1cmJzd2FzbV9taW5pbXVtX3JlcGx5X3N1cmJfdGhyZXNob2xkX2J1ZmZlcgCNGiZfX3diZ19zZXRfcmVwbHlzdXJic3dhc21fc3VyYl9taXhfaG9wcwCMGC1fX3diZ19zZXRfc3RhdHNyZXBvcnRpbmd3YXNtX3Byb3ZpZGVyX2FkZHJlc3MAkQ0pX193Ymdfc2V0X3RvcG9sb2d5d2FzbV9kaXNhYmxlX3JlZnJlc2hpbmcAnxkwX193Ymdfc2V0X3RvcG9sb2d5d2FzbV9pZ25vcmVfaW5ncmVzc19lcG9jaF9yb2xlAKAZMl9fd2JnX3NldF90b3BvbG9neXdhc21fbWluaW11bV9nYXRld2F5X3BlcmZvcm1hbmNlAI4aMl9fd2JnX3NldF90b3BvbG9neXdhc21fbWluaW11bV9taXhub2RlX3BlcmZvcm1hbmNlAI8aLF9fd2JnX3NldF90b3BvbG9neXdhc21fdXNlX2V4dGVuZGVkX3RvcG9sb2d5AKEZJl9fd2JnX3NldF90cmFmZmljd2FzbV9kaXNhYmxlX21peF9ob3BzAKIZN19fd2JnX3NldF90cmFmZmljd2FzbV9tYXhpbXVtX251bWJlcl9vZl9yZXRyYW5zbWlzc2lvbnMA0xcuX193Ymdfc2V0X3RyYWZmaWN3YXNtX3VzZV9leHRlbmRlZF9wYWNrZXRfc2l6ZQCjGS5fX3diZ19zZXRfdHJhZmZpY3dhc21fdXNlX2xlZ2FjeV9zcGhpbnhfZm9ybWF0AKQZIF9fd2JnX3NldF90cmFmZmljd2FzbV91c2Vfb3V0Zm94AKUZHV9fd2JnX3N0YXRzcmVwb3J0aW5nd2FzbV9mcmVlAPAPF19fd2JnX3RvcG9sb2d5d2FzbV9mcmVlAN4QFl9fd2JnX3RyYWZmaWN3YXNtX2ZyZWUA3xAMZGVmYXVsdERlYnVnANcgDWRlZmF1bHRfZGVidWcA3BQMbm9Db3ZlckRlYnVnANggDm5vX2NvdmVyX2RlYnVnAPwSHl9fd2JnX2dldF9yZW1lbWJlcm1ld2FzbV9zdGF0cwCJGSRfX3diZ19nZXRfc3RhdHNyZXBvcnRpbmd3YXNtX2VuYWJsZWQAiBkvX193YmdfZ2V0X3RvcG9sb2d5d2FzbV9pZ25vcmVfZWdyZXNzX2Vwb2NoX3JvbGUAiBkzX193YmdfZ2V0X3RyYWZmaWN3YXNtX2RldGVybWluaXN0aWNfcm91dGVfc2VsZWN0aW9uAIgZPl9fd2JnX2dldF90cmFmZmljd2FzbV9kaXNhYmxlX21haW5fcG9pc3Nvbl9wYWNrZXRfZGlzdHJpYnV0aW9uAJQZHl9fd2JnX3NldF9yZW1lbWJlcm1ld2FzbV9zdGF0cwCdGSRfX3diZ19zZXRfc3RhdHNyZXBvcnRpbmd3YXNtX2VuYWJsZWQAnBkvX193Ymdfc2V0X3RvcG9sb2d5d2FzbV9pZ25vcmVfZWdyZXNzX2Vwb2NoX3JvbGUAnBkzX193Ymdfc2V0X3RyYWZmaWN3YXNtX2RldGVybWluaXN0aWNfcm91dGVfc2VsZWN0aW9uAJwZPl9fd2JnX3NldF90cmFmZmljd2FzbV9kaXNhYmxlX21haW5fcG9pc3Nvbl9wYWNrZXRfZGlzdHJpYnV0aW9uAKAZO19fd2JnX3NldF9jb3ZlcnRyYWZmaWN3YXNtX2NvdmVyX3RyYWZmaWNfcHJpbWFyeV9zaXplX3JhdGlvAIQaPl9fd2JnX3NldF9jb3ZlcnRyYWZmaWN3YXNtX2xvb3BfY292ZXJfdHJhZmZpY19hdmVyYWdlX2RlbGF5X21zAIUaOF9fd2JnX3NldF9yZXBseXN1cmJzd2FzbV9tYXhpbXVtX3JlcGx5X3N1cmJfcmVxdWVzdF9zaXplAIMaPV9fd2JnX3NldF9yZXBseXN1cmJzd2FzbV9taW5pbXVtX3JlcGx5X3N1cmJfc3RvcmFnZV90aHJlc2hvbGQAhhoyX193Ymdfc2V0X3N0YXRzcmVwb3J0aW5nd2FzbV9yZXBvcnRpbmdfaW50ZXJ2YWxfbXMAhRo8X193Ymdfc2V0X3RvcG9sb2d5d2FzbV9tYXhfc3RhcnR1cF9nYXRld2F5X3dhaXRpbmdfcGVyaW9kX21zAI0aL19fd2JnX3NldF90b3BvbG9neXdhc21fdG9wb2xvZ3lfcmVmcmVzaF9yYXRlX21zAIYaNV9fd2JnX3NldF90b3BvbG9neXdhc21fdG9wb2xvZ3lfcmVzb2x1dGlvbl90aW1lb3V0X21zAIsaLV9fd2JnX3NldF90cmFmZmljd2FzbV9hdmVyYWdlX3BhY2tldF9kZWxheV9tcwCNGjZfX3diZ19zZXRfdHJhZmZpY3dhc21fbWVzc2FnZV9zZW5kaW5nX2F2ZXJhZ2VfZGVsYXlfbXMAhRo+X193YmdfZ2V0X2NvdmVydHJhZmZpY3dhc21fbG9vcF9jb3Zlcl90cmFmZmljX2F2ZXJhZ2VfZGVsYXlfbXMAhxk4X193YmdfZ2V0X3JlcGx5c3VyYnN3YXNtX21heGltdW1fcmVwbHlfc3VyYl9yZXF1ZXN0X3NpemUAhhk9X193YmdfZ2V0X3JlcGx5c3VyYnN3YXNtX21pbmltdW1fcmVwbHlfc3VyYl9zdG9yYWdlX3RocmVzaG9sZACLGTJfX3diZ19nZXRfc3RhdHNyZXBvcnRpbmd3YXNtX3JlcG9ydGluZ19pbnRlcnZhbF9tcwCHGTxfX3diZ19nZXRfdG9wb2xvZ3l3YXNtX21heF9zdGFydHVwX2dhdGV3YXlfd2FpdGluZ19wZXJpb2RfbXMAkhkvX193YmdfZ2V0X3RvcG9sb2d5d2FzbV90b3BvbG9neV9yZWZyZXNoX3JhdGVfbXMAixk1X193YmdfZ2V0X3RvcG9sb2d5d2FzbV90b3BvbG9neV9yZXNvbHV0aW9uX3RpbWVvdXRfbXMAkBktX193YmdfZ2V0X3RyYWZmaWN3YXNtX2F2ZXJhZ2VfcGFja2V0X2RlbGF5X21zAJIZNl9fd2JnX2dldF90cmFmZmljd2FzbV9tZXNzYWdlX3NlbmRpbmdfYXZlcmFnZV9kZWxheV9tcwCHGTtfX3diZ19nZXRfY292ZXJ0cmFmZmljd2FzbV9jb3Zlcl90cmFmZmljX3ByaW1hcnlfc2l6ZV9yYXRpbwDZGRZjdXJyZW50TmV0d29ya1RvcG9sb2d5AJkfF3Rhc2tfd29ya2VyX2VudHJ5X3BvaW50AK0aHV9fd2JnX2Fub255bW91c3NlbmRlcnRhZ19mcmVlAMsRDnNldF9wYW5pY19ob29rAMslCGFsbG9jYXRlAMUYCmRlYWxsb2NhdGUAkhMTaW50ZXJmYWNlX3ZlcnNpb25fOADLJRFyZXF1aXJlc19pdGVyYXRvcgDLJRFfX3diaW5kZ2VuX21hbGxvYwCiFhJfX3diaW5kZ2VuX3JlYWxsb2MA+hcUX193YmluZGdlbl9leG5fc3RvcmUA5h4XX19leHRlcm5yZWZfdGFibGVfYWxsb2MAxiUTX193YmluZGdlbl9leHBvcnRfNAEBE19fd2JpbmRnZW5fZXhwb3J0XzUBAA9fX3diaW5kZ2VuX2ZyZWUA5x4ZX19leHRlcm5yZWZfdGFibGVfZGVhbGxvYwChFiljbG9zdXJlMzc2X2V4dGVybnJlZl9zaGltX211bHRpdmFsdWVfc2hpbQDLGRljbG9zdXJlNTc4X2V4dGVybnJlZl9zaGltAO0eel9keW5fY29yZV9fb3BzX19mdW5jdGlvbl9fRm5NdXRfX19fX091dHB1dF9fX1JfYXNfd2FzbV9iaW5kZ2VuX19jbG9zdXJlX19XYXNtQ2xvc3VyZV9fX2Rlc2NyaWJlX19pbnZva2VfX2g1ZjA3MjE0YzVlYTllMmMyALYbel9keW5fY29yZV9fb3BzX19mdW5jdGlvbl9fRm5NdXRfX19fX091dHB1dF9fX1JfYXNfd2FzbV9iaW5kZ2VuX19jbG9zdXJlX19XYXNtQ2xvc3VyZV9fX2Rlc2NyaWJlX19pbnZva2VfX2gxNDkzYWRhNmVhNmRiYWI3AL4bel9keW5fY29yZV9fb3BzX19mdW5jdGlvbl9fRm5NdXRfX19fX091dHB1dF9fX1JfYXNfd2FzbV9iaW5kZ2VuX19jbG9zdXJlX19XYXNtQ2xvc3VyZV9fX2Rlc2NyaWJlX19pbnZva2VfX2hmY2Q5M2UyODBhY2IyOWJlAMIbGmNsb3N1cmUxNjgwX2V4dGVybnJlZl9zaGltAO4eel9keW5fY29yZV9fb3BzX19mdW5jdGlvbl9fRm5NdXRfX19fX091dHB1dF9fX1JfYXNfd2FzbV9iaW5kZ2VuX19jbG9zdXJlX19XYXNtQ2xvc3VyZV9fX2Rlc2NyaWJlX19pbnZva2VfX2g3OTY2ZDIxOTE5ZDMwZGNmAMMbGmNsb3N1cmUxNjk0X2V4dGVybnJlZl9zaGltAO8eGmNsb3N1cmUyMzg1X2V4dGVybnJlZl9zaGltAJ0bEF9fd2JpbmRnZW5fc3RhcnQAtQEJmicIAEEBC5oCnBuGAqoN4wbQH58HiyCbE7sJtAfrCvMBmx+aJekGwh6nEZAf+QSzAt0D2AeNHKAfuxbQJfoe+R6+F7kFwBfHA70XowW/F64EvBffBLsXgAPYGPUO2Rj0DtUYvA7aGPYO1xi9DtYYqg7ZIKIepgjDEecgnx+HFsQe3BLSG5MhlQqUIZIKlSG7DMIhoR/jG/AL+Q7UCLMP4QacE/gWjReVIu4j2hKKDO0S+xn6DJ8f2SCbH6Ef7yOOHKIf7yPQJawh+SHyIaYW0BnRAdAZ1AHQGdMBnxXbAp8V1AKfFdwChB/WFMUCgx/WFMgC1xSQAoIf2SCiHqYI7SD7GfsM2SDvI5Acox/QJagf8SODJPMjhCSJJIok/SP/I/QjiCTyI4Uk+yP6I4ckuSS6JIAkyST1I/Yj9yOCJIYk+SPRJLwhgSSoH/wj+CPSG5sfgCHbGLIIsBqQCf8YpQS7FYcC1BubAtkgoh6mCPEg/hnQAvsaxgHbGN0F2SCiHqYI8iDoF+8jkhymH9Al8yDDF9Ibyw/8IPgU/iPZ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BCADKALEByEKIAMoArwHIQsgAy0AwAchESADKAK0ByETIAMtALgHIR0gAygC2AchGyADQZICaiIlIAktAAA6AAAgA0HqAWoiCSAILQAAOgAAIANBgANqIgggDikDADcDACADIAMvAdACOwGQAiADIAMvAcQJOwHoASADIAMpA/gENwP4AiAPIB06AJwBIA8gEzYCmAEgDyAROgCkASAPIAs2AqABIA8gAy8BkAI7AJ0BIA9BnwFqICUtAAA6AAAgDyAKNgKoASAPIAMvAegBOwClASAPQacBaiAJLQAAOgAAIA8gAykD+AI3AqwBIA9BtAFqIAgpAwA3AgAgD0EAOgCwBCAPIAY2AqgEIA8gGzYCvAELIANBsAdqIBogAhCJAiADLQCwByILQTFGDQIgA0HSAmogAy0Aswc6AAAgA0HOCWogA0G7B2otAAA6AAAgA0HKCWogA0HDB2otAAA6AAAgAyADLwCxBzsB0AIgAyADLwC5BzsBzAkgAyADLwDBBzsByAkgAygCtAchBiADLQC4ByEIIAMoArwHIQkgAy0AwAchCiADKALEByEOIANB6ANqIANB0AdqKQMANwMAIAMgAykDyAc3A+ADIAMpA9gHISogA0H4BGogA0HgB2pBOPwKAAAgGhD+GgwPCwJAAkBB2MrmACgCAEEBSw0AQYTC5gAtAAAiCEEBa0ECTwRAIAhFDQFB/MHmABC5CkH/AXEiCEUNAQtB/MHmACgCACAIENUVRQ0AQfzB5gAoAgAiCCgCICIJRQ0MIAgoAighCiAIKAIkIQ4gCCgCHCELIANBADYCiAUgAyAKNgKEBSADIA42AoAFIAMgCTYC/AQgAyALNgL4BCADQbjcwwA2AoADIANBADYCwAcgA0EBNgK0ByADQcDdwwA2ArAHIANCBDcCuAcgAyADQbAHajYC/AIgAyADQfgEajYC+AIgA0GoAWogCEEcaiADQfgCahD9HSADQdgCaiADQbABaigCADYCACADIAMpAqgBNwPQAkH8weYAKAIAIANB0AJqIggQ9xdB4NDmAC0AAA0BQdDQ5gAoAgBBBEkNASADQQQ2AuADIANB/MHmACgCACILKQIUNwLkAyADQShqEMYZIAMoAigiCSADQeADaiADKAIsIgooAgwRAABFDQEgA0HoBWogA0HoA2ooAgA2AgAgAyADKQLgAzcD4AUgCyAJIAogA0HgBWogCBD3CQwBC0Hg0OYALQAADQBB0NDmACgCAEEESQ0AIANBBDYCkAIgA0H8weYAKAIAIgkpAhQ3ApQCIANBIGoQxhkgAygCICIKIANBkAJqIAMoAiQiDigCDBEAAEUNAEH8weYAKAIAIggoAiAiC0UNDCAIKAIoIREgCCgCJCETIAgoAhwhHSADQQA2AogFIAMgETYChAUgAyATNgKABSADIAs2AvwEIAMgHTYC+AQgA0G43MMANgLoAyADQQA2AsAHIANBATYCtAcgA0HA3cMANgKwByADQgQ3ArgHIAMgA0GwB2o2AuQDIAMgA0H4BGo2AuADIANB+AJqIgsgCEEcaiADQeADahD9HSADQegFaiADQZgCaigCADYCACADIAMpApACNwPgBSAJIAogDiADQeAFaiALEPcJCyAGKALgAiIIRQRAQRohCwwPCyADQbAHaiAIQQhqIAYoAswCQQhqEM4IIAMoArAHQQFGBEAgA0HSAmoiBiADQbsHai0AADoAACADQeoBaiILIANBwwdqLQAAOgAAIANBgAVqIhEgA0HQB2opAwA3AwAgAyADLwC5BzsB0AIgAyADLwDBBzsB6AEgAyADKQPIBzcD+AQgAy0AuAchCCADKAK8ByEJIAMtAMAHIQogAygCxAchDiADKQPYByEqIANBzglqIAYtAAA6AAAgA0HKCWogCy0AADoAACADQegDaiARKQMANwMAIAMgAy8B0AI7AcwJIAMgAy8B6AE7AcgJIAMgAykD+AQ3A+ADQREhCwwPCyADQdICaiIJIANBuwdqLQAAOgAAIANB6gFqIgggA0HDB2otAAA6AAAgA0GABWoiDiADQdAHaikDADcDACADIAMvALkHOwHQAiADIAMvAMEHOwHoASADIAMpA8gHNwP4BCADKALEByEKIAMoArwHIQsgAy0AwAchESADKAK0ByETIAMtALgHIR0gAygC2AchGyADQfoCaiIlIAktAAA6AAAgA0GqAWoiCSAILQAAOgAAIANB6AVqIgggDikDADcDACADIAMvAdACOwH4AiADIAMvAegBOwGoASADIAMpA/gENwPgBSAPIB06AJwBIA8gEzYCmAEgDyAROgCkASAPIAs2AqABIA8gAy8B+AI7AJ0BIA9BnwFqICUtAAA6AAAgDyAKNgKoASAPIAMvAagBOwClASAPQacBaiAJLQAAOgAAIA8gAykD4AU3AqwBIA9BtAFqIAgpAwA3AgAgD0EAOgCwBCAPIAY2AqgEIA8gGzYCvAELIANBsAdqIBogAhCJAiADLQCwByILQTFGDQMgA0HSAmogAy0Aswc6AAAgA0HOCWogA0G7B2otAAA6AAAgA0HKCWogA0HDB2otAAA6AAAgAyADLwCxBzsB0AIgAyADLwC5BzsBzAkgAyADLwDBBzsByAkgAygCtAchBiADLQC4ByEIIAMoArwHIQkgAy0AwAchCiADKALEByEOIANB6ANqIANB0AdqKQMANwMAIAMgAykDyAc3A+ADIAMpA9gHISogA0H4BGogA0HgB2pBOPwKAAAgGhD+GgwNCyAXQQM6AABBBAwDC0HAxOYAKAIAIgYoAiAiC0UNCSAGKAIoIQggBigCJCEJIAYoAhwhCiADQQA2AogFIAMgCDYChAUgAyAJNgKABSADIAs2AvwEIAMgCjYC+AQgA0G43MMANgKAAyADQQA2AsAHIANBATYCtAcgA0Hk48MANgKwByADQgQ3ArgHIAMgA0GwB2o2AvwCIAMgA0H4BGo2AvgCIANBkAJqIgsgBkEcaiADQfgCahD9HUHAxOYAKAIAIAsQ9xdB4NDmAC0AAA0AQdDQ5gAoAgBBBEkNACADQQQ2AuADIANBwMTmACgCACIGKQIUNwLkAyADQRBqEMYZIAMoAhAiESADQeADaiADKAIUIggoAgwRAABFDQAgA0HoBWogA0HoA2ooAgA2AgAgAyADKQLgAzcD4AUgBiARIAggA0HgBWogCxD3CQsgDygCiAEiCygC4AIiBkUEQEEqIQsMGAsgBiAGKAIAIghBAWo2AgAgCEEASA0SIAsoAuACLQAIQQFGBH8gDy0AjgEFQQALQQFxDBELIBdBAzoAAEEDCyEGIBwgBjoAACAUQTE6AABBBgwWC0Hg28MAQSJBhNzDABC5EQALQeDbwwBBIkGE3MMAELkRAAtB4NvDAEEiQdjcwwAQuREAC0Hg28MAQSJB2NzDABC5EQALQeDbwwBBIkGY3cMAELkRAAtB4NvDAEEiQZjdwwAQuREAC0Hg28MAQSJBvOPDABC5EQALQeDbwwBBIkG848MAELkRAAsgF0EBOgAAIBxBAToAACAZELIWIAtBMEcNACAPKAKIASIGLQDqAkEBRwRAQSkhCwwNCyAGKALgAiIGBEBBACELIAYtAAhBAUYEQCAPLQCOASELCyAGIAYoAgAiCEEBajYCACAIQQBIDQggC0EBcQwHC0Hs48MAENIgAAsgA0HCCWogA0HSAmotAAA6AAAgA0G+CWogA0HOCWotAAA6AAAgA0G6CWogA0HKCWotAAA6AAAgA0GwCWogA0HoA2opAwA3AwAgAyADLwHQAjsBwAkgAyADLwHMCTsBvAkgAyADLwHICTsBuAkgAyADKQPgAzcDqAkgA0HwCGogA0H4BGpBOPwKAAAMCwsgCEECRwRAQSchCwwJCyAGKALMAiEIIANBsAdqIg4gBkHQAGpBwAH8CgAAIANBGGogD0GYAWogBkGUAmogCEEIaiAOIAYtABggCUEBcRCDCSAPIAMpAxg3ApwBCyADQbAHaiAPQZwBaiIKIAIQtR5BAyADLQCwByIOQQJGDQEaIANBigFqIAMtALMHOgAAIANBzglqIgsgA0G7B2otAAA6AAAgA0HoA2oiESADQcgHaikCADcDACADQfADaiITIANB0AdqLwEAOwEAIAMgAy8AsQc7AYgBIAMgAy8AuQc7AcwJIAMgAykCwAc3A+ADIAMoArQHIQYgAy0AuAchCCADKAK8ByEJIAoQ/hUgDkEBcQRAIANBvglqIAstAAA6AAAgAyADLwHMCTsBvAlBKCELDAgLIA9BAToAmAEgCiADLwGIATsAACAPIAg6AKMBIA8gBjYAnwEgDyADLwHMCTsApAEgDyAJNgCnASAPIAMpA+ADNwCrASAKQQJqIANBigFqLQAAOgAAIA9BpgFqIANBzglqLQAAOgAAIA9BswFqIBEpAwA3AAAgD0G7AWogEy8BADsAACAPQQA6AJ0CIA8gDygCkAE2ApgCCyADQbAHaiAPQcABaiIRIAIQgwIgAy0AsAciC0ExRw0BQQQLIQYgHCAGOgAAIBRBMToAAEEHDAgLIANBqgFqIhMgAy0Aswc6AAAgA0HSAmoiFyADQbsHai0AADoAACADQeoBaiIaIANBwwdqLQAAOgAAIAMgAy8AsQc7AagBIAMgAy8AuQc7AdACIAMgAy8AwQc7AegBIAMoArQHIQYgAy0AuAchCCADKAK8ByEJIAMtAMAHIQogAygCxAchDiADQYADaiIdIANB0AdqKQMANwMAIAMgAykDyAc3A/gCIAMpA9gHISogA0H4BGoiGyADQeAHakE4/AoAACAREIAXIAtBMEcEQCADQcIJaiATLQAAOgAAIANBvglqIBctAAA6AAAgA0G6CWogGi0AADoAACADQbAJaiAdKQMANwMAIAMgAy8BqAE7AcAJIAMgAy8B0AI7AbwJIAMgAy8B6AE7AbgJIAMgAykD+AI3A6gJIANB8AhqIBtBOPwKAAAMBAsgA0HrBWogA0HqAWotAAA6AAAgA0H4BWogA0GAA2opAwA3AwAgAyAIOgDgBSADIAMvAdACOwDhBSADIAo6AOgFIAMgCTYC5AUgAyADLwHoATsA6QUgAyAONgLsBSADIAMpA/gCNwPwBSADIANB0gJqLQAAOgDjBQJAAkAgCEEBRwRAIAhBBkYNASADQbsHaiADQeoBai0AADoAACADQcgHaiADQYADaikDADcDACADIAg6ALAHIAMgAy8B0AI7ALEHIAMgCjoAuAcgAyAJNgK0ByADIAMvAegBOwC5ByADIA42ArwHIAMgAykD+AI3A8AHIAMgA0HSAmotAAA6ALMHIANBkAJqIANBsAdqIgsQ4AMgA0G+CWogA0GXAmotAAA6AAAgAyADLwCVAjsBvAkgAy0AlAIhCCADKAKQAiEGIAMoApgCIQkgCxDpFUEmIQsMBgsgAy0A4wUhCSADLQDiBSEIIAMtAOEFIREgA0HgBWoQ6RUgA0GwB2ogGSgCACARIAgQ4gEgAy0AsAciC0EwRwRAIANBwglqIAMtALMHOgAAIANBvglqIANBuwdqLQAAOgAAIANBuglqIANBwwdqLQAAOgAAIAMgAy8AsQc7AcAJIAMgAy8AuQc7AbwJIAMgAy8AwQc7AbgJIAMoArQHIQYgAy0AuAchCCADKAK8ByEJIAMtAMAHIQogAygCxAchDiADQbAJaiADQdAHaikDADcDACADIAMpA8gHNwOoCSADKQPYByEqIANB8AhqIANB4AdqQTj8CgAADAYLIBkoAgAgCToA6gIgGSgCACILLQDqAkUNASAPQQA6AJgBIANBsAdqIgkgD0GcAWpBIfwKAAACf0EsQQQQhCEiBgRAIAZCgYCAgBA3AgAgBkEIaiAJQSH8CgAAIAYMAQtBBEEsEOEjAAshCQJAIA8oApABIgooAuACIgZFDQAgBiAGKAIAIg5BAWs2AgAgDkEBRw0AIApB4AJqEP4RCyAZKAIAIAk2AuACIBkoAgAhCwwBCyADQb4JaiADQeoBai0AADoAACADIAMvAegBOwG8CUEPIQsgCSEGIAohCCAOIQkMBAsgCyAIOgDpAiALIBE6AOgCIA8tAJgBBEAgD0GcAWoQrhoLIA9BgAI7AZgBIBkQhhYgDygCiAEoAuACIgZFDQIgBiAGKAIAIghBAWo2AgAgCEEASA0BQQALIQhBMCELDAULAAtB/OPDABDSIAALIA9BnAFqEK4aCyAPQQA6AJgBCyAcQQE6AAAgGRCGFgsgFCALOgAAIBQgAy8BwAk7AAEgFCAIOgAIIBQgBjYCBCAUIAMvAbwJOwAJIBQgCjoAECAUIAk2AgwgFCADLwG4CTsAESAUIA42AhQgFEEDaiADQcIJai0AADoAACAUQQtqIANBvglqLQAAOgAAIBRBE2ogA0G6CWotAAA6AAAgFCAqNwMoIBRBIGogA0GwCWopAwA3AAAgFCADKQOoCTcAGCAUQTBqIANB8AhqQTj8CgAAQQELOgCPASADQfgAahDiDSADQdAJaiQAIAQtAJgXIhFBMUcNAkEDDDQLIAxB8AZqIARBwAVqQaAE/AoAAAsgDEHwBmohAwJAAkACQAJAAkACQAJAAkACQAJAAkACQCAMLQDfB0EBaw4HDTkBAx8LCgALIAwoAtgHIggoApACIgZBAkkgBkEGcUECRnINASAMIAitNwPgBwsgBEHgCWogDEHgB2oQ3AkgBC0A4AkiEUExRgRAQQMhFQw8CyAEQfYOaiIJIAQtAOMJOgAAIARB8g5qIg8gBEHrCWotAAA6AAAgBEHuDmoiFCAEQfMJai0AADoAACAEIAQvAOEJOwH0DiAEIAQvAOkJOwHwDiAEIAQvAPEJOwHsDiAEKALkCSEIIAQtAOgJIQogBCgC7AkhBiAELQDwCSEOIAQoAvQJIQsgBEHgDmoiEyAEQYAKaikDADcDACAEIAQpA/gJNwPYDiAEKQOICiEqIARBoA5qIhcgBEGQCmpBOPwKAAAgEUEwRwRAIARBvhFqIAktAAA6AAAgBEG6EWogDy0AADoAACAEQbYRaiAULQAAOgAAIARBqBFqIBMpAwA3AwAgBCAELwH0DjsBvBEgBCAELwHwDjsBuBEgBCAELwHsDjsBtBEgBCAEKQPYDjcDoBEgBEHoEGogF0E4/AoAAAw6CyAMKALYByEICyAMQQA6AMwKIAwgCDYCyAogDEHgB2ohESAMQcwKaiEKDAELIAxB4AdqIREgDEHMCmohCgJAIAwtAMwKQQFrDgMGNgIACyAMKALICiEICyAIKAKQAiIGQQJJIAZBBnFBAkZyDQFBDiEIDBkLIAxBkAhqIQ4CQCAMLQCQCEEBaw4FCTQDDw0ACyAMKAKICCEIDAELIAxBADoAkAggDCAINgKICCAMQYeAgIB4NgLgByAMQZAIaiEOCyAMQQE6AJIIIAwgCDYCjAggDEGUCGogEUEo/AoAACAIKAKQAkECTwRAIAxBADoAkQgMDAsgDEEAOgDECiAMIAg2ApAKCyAEQZgXaiAMQcAIaiIJIAIQ0wQgBC0AmBciBkExRgRAQQMhFQwRCyAEQZgUaiIIIARBmBdqQQFyQecA/AoAACAJEMwZIAZBMEcEQCAEQeAJakEBciAIQecA/AoAACAEIAY6AOAJDBILIAxBAToAkQggDCgCjAghCAwKC0GkmcIAELUXAAsgDEHgB2ohHSAMQekHaiEaAkAgDC0A6QdBAWsOBAUvKSoACyAMLQDqByEKIAwoAuQHIQgMGAsgDEHgB2ohHSAMQeQHaiEaAkACQAJAAkAgDC0A5AdBAWsOBAMxAgEACyAMLQDlByERIAwoAuAHIQgMHAsgDEHoB2ohGSAMQYwLaiEcAkAgDC0AjAtBAWsOAwcwHgALIAwoAogLIQgMHAsgDEHoB2ohGSAMQYwLaiEcAkAgDC0AjAtBAWsOAwcvHwALIAwoAogLIQgMHQtBkJHCABC1FwALIARBvhFqIAQtAJsXOgAAIARBuhFqIARBoxdqLQAAOgAAIARBthFqIARBqxdqLQAAOgAAIAQgBC8AmRc7AbwRIAQgBC8AoRc7AbgRIAQgBC8AqRc7AbQRIAQoApwXIQggBC0AoBchCiAEKAKkFyEGIAQtAKgXIQ4gBCgCrBchCyAEQagRaiAEQbgXaikDADcDACAEIAQpA7AXNwOgESAEKQPAFyEqIARB6BBqIARByBdqQTj8CgAAIA8Q2iAMLwtBvKHCABC1FwALQdilwgAQtRcAC0Hkp8IAELUXAAtB4JHCABC1FwALQaCSwgAQtRcAC0EBIQgMBQsCQEEBIAgoApACIgZBAmsgBkEBTRsOAwACBAILIAxBADoAkgggBEGYF2oiBiAMQZQIakEo/AoAACAEQbAVaiIJIAYQngUgBEHIFWogCEGUAmogCRCHFyAMQawIaiAEQeAVaigCADYCACAMQaQIaiAEQdgVaikCADcCACAMQZwIaiAEQdAVaikCADcCACAMIAQpAsgVNwKUCAsgBEGYF2ogDEGUCGoiCSACEKUJIAQoApgXIgZBkICAgHhHDQFBBCEVDAQLIARBJzoA4AkMBAsgBEGQFWoiCyAEQawXaigCADYCACAEQYgVaiIIIARBpBdqKQIANwMAIAQgBCkCnBc3A4AVIAkQkx4gBkGPgICAeEcEQCAEQawVaiALKAIANgIAIARBpBVqIAgpAwA3AgAgBCAEKQOAFTcCnBUgBCAGNgKYFSAEQeAJaiAEQZgVahC1EgwECyAEQbAVaiAMKAKMCCIGKQMgIAYoAigQnw8gDCAMQaAIajYCmAggDEGwCGogBEHAFWopAwA3AwAgDEGoCGogBEG4FWopAwA3AwAgDCAEKQOwFTcDoAhBACEIDAELIARBDjoA4AkMAgsDQCAIRQRAIAxBADoAlAggDEEAOgCdCSAMIAxBuAhqNgKkCSAMIAxBlAhqNgKgCSAMIAwoAowINgKYCSAMIAxBmAhqNgK4CEEBIQgMAQsgBEGYF2ogDEGgCWogAhDxASAELQCYFyIGQTRGBEBBBSEVDAILIARBsBZqIARBmBdqQQFyQecA/AoAACAMQcAIahCgGwJAAkACQAJAQQEgBkExayAGQTBNG0H/AXFBAWsOAgIAAQsgBEEANgKoFyAEQQE2ApwXIARBvJzCADYCmBcgBEIENwKgFyAEQZgXakHopcIAEPcYAAsgBEErOgDIFQwBCyAGQTBHBEAgBCAGOgDIFSAEQcgVakEBciAEQbAWakHnAPwKAAAMAQsgBEGwF2ogBEHPFmopAAA3AwAgBEGoF2ogBEHHFmopAAA3AwAgBEGgF2ogBEG/FmopAAA3AwAgBCAEKQC3FiIqNwOYFyAqp0H/AXFBBEcEQCAEQegVaiAEQbcWaiIGQRhqKQAANwMAIARB4BVqIAZBEGopAAA3AwAgBEHYFWogBkEIaikAADcDACAEQTA6AMgVIAQgBikAADcD0BUMAQsgBEGYF2oQ6RVBACEIDAELCwJAIAwtAJEIRQ0AIARBmBdqIgYgDCgCjAgQywYgBC0AmBciCUEwRg0AIARB4AlqQQFyIAZBAXJB5wD8CgAAIAQgCToA4AkgBEHIFWoQ8BogDEGgCGoQ9BYMAgsgBEHgCWogBEHIFWpB6AD8CgAAIAxBoAhqEPQWDAILIA4gFToAAAwCCyAMLQCSCARAIAxBlAhqEKEICwsgDEEAOgCSCCAELQDhCSEGIAQtAOAJIQggBEGgEmoiCSAEQeAJakECckEm/AoAACAEQeARaiIPIARBiApqQcAA/AoAACAOQQE6AAAgCEExRg0AIARBiBNqIgogCUEm/AoAACAEQcgSaiIJIA9BwAD8CgAAIBEQphEgCEEwRg0BIARBsBNqIApBJvwKAAAgBEHWE2ogCUHAAPwKAAAMAgsgCkEDOgAAQQQhFQwgCyAEQdgRaiAEQaYTaikAADcDACAEQdARaiAEQZ4TaikAADcDACAEQcgRaiAEQZYTaikAADcDACAEIAQpAI4TIio3A8ARAkACQAJAICqnQf8BcUEFaw4CAQACCyAEQeoJaiAEQZoTaigAADYAACAEIAQpAJITNwDiCSAEIAQpAOAJNwOwEyAEIARB5glqKQAANwG2E0EPIQgMAgsgBC0AwREhBiAEQcARahDpFUEwIQgMAQsgBEH4CWogBEGOE2oiCUEYaikAADcDACAEQfAJaiAJQRBqKQAANwMAIARB6AlqIAlBCGopAAA3AwAgBCAJKQAANwPgCSAEQcgVaiAEQeAJaiIJEOADIARBohdqIARB0BVqKAIANgAAIAQgBCkCyBU3AJoXIAQgBCkAmBc3A7ATIAQgBEGeF2opAAA3AbYTIAkQ6RVBJiEICyAEQfgOaiIJIARBsBNqQeYA/AoAACAMQQE6AMwKIAwgBjoA8QYgDCAIOgDwBiAMQfIGaiAJQeYA/AoAACAREJQeIAwtAPAGQTBGDQEgDCAMNQLYBzcD4AcLIARB4AlqIAxB4AdqENwJIAQtAOAJIhFBMUcNAUEFIRUMHQsgDEEBOgDcByAMIAwtAPEGOgDdBwwBCyAEQbYQaiIJIAQtAOMJOgAAIARBshBqIg8gBEHrCWotAAA6AAAgBEGuEGoiFCAEQfMJai0AADoAACAEIAQvAOEJOwG0ECAEIAQvAOkJOwGwECAEIAQvAPEJOwGsECAEKALkCSEIIAQtAOgJIQogBCgC7AkhBiAELQDwCSEOIAQoAvQJIQsgBEGgEGoiEyAEQYAKaikDADcDACAEIAQpA/gJNwOYECAEKQOICiEqIARB4A9qIhcgBEGQCmpBOPwKAAAgEUEwRwRAIARBvhFqIAktAAA6AAAgBEG6EWogDy0AADoAACAEQbYRaiAULQAAOgAAIARBqBFqIBMpAwA3AwAgBCAELwG0EDsBvBEgBCAELwGwEDsBuBEgBCAELwGsEDsBtBEgBCAEKQOYEDcDoBEgBEHoEGogF0E4/AoAACADEJUeDBoLIAxBADoA3AcLIAMQlR4gDCAMLQDcByIJIAwtAN0HIghBAktxIgo6AN4HIAhBBEshBiAJIAhBA0txIRECQCAKDQACQEHYyuYAKAIAQQNLDQBBqMTmABDuGkH/AXEiCkUNAEGoxOYAKAIAIAoQ1RVFDQAgBEEANgKoFyAEQajE5gAoAgAiCigCICIONgKsFyAEIAopAiQ3AqAXIAQgDjYCnBcgBCAKKAIcNgKYFyAEQeAJaiIIIARBmBdqIg8QhxEgBEHIFWoiFCAIQfyhwgAQqBQgBEH0hsIANgKgFCAEQQA2AvAJIARBATYC5AkgBEHUosIANgLgCSAEQgQ3AugJIAQgCDYCnBQgBCAUNgKYFCAEQbATaiAKQRxqIARBmBRqEP0dIARB0BJqIARBuBNqKAIANgIAIAQgBCkCsBM3A8gSQajE5gAoAgAgBEHIEmoiCBD3F0Hg0OYALQAADQFB0NDmACgCAEECSQ0BIARBAjYCsBYgBEGoxOYAKAIAIgopAhQ3ArQWIARBiAFqEMYZIAQoAogBIg4gBEGwFmogBCgCjAEiCygCDBEAAEUNASAEQaAXaiAEQbgWaigCADYCACAEIAQpArAWNwOYFyAKIA4gCyAPIAgQ9wkMAQtB4NDmAC0AAA0AQdDQ5gAoAgBBAkkNACAEQQI2ArgQIARBqMTmACgCACIOKQIUNwK8ECAEQYABahDGGSAEKAKAASILIARBuBBqIAQoAoQBIg8oAgwRAABFDQAgBEEANgKoFyAEQajE5gAoAgAiCigCICIINgKsFyAEIAopAiQ3AqAXIAQgCDYCnBcgBCAKKAIcNgKYFyAEQeAJaiIIIARBmBdqIhQQhxEgBEHIFWoiEyAIQfyhwgAQqBQgBEH0hsIANgK4FiAEQQA2AvAJIARBATYC5AkgBEHUosIANgLgCSAEQgQ3AugJIAQgCDYCtBYgBCATNgKwFiAEQZgUaiIIIApBHGogBEGwFmoQ/R0gBEGgF2ogBEHAEGooAgA2AgAgBCAEKQK4EDcDmBcgDiALIA8gFCAIEPcJCyAGIAlxIQgCQCARDQACQEHYyuYAKAIAQQNLDQBBzMTmABDuGkH/AXEiCkUNAEHMxOYAKAIAIAoQ1RVFDQAgBEEANgKoFyAEQczE5gAoAgAiCigCICIGNgKsFyAEIAopAiQ3AqAXIAQgBjYCnBcgBCAKKAIcNgKYFyAEQeAJaiIJIARBmBdqIg8QhxEgBEHIFWoiFCAJQdyiwgAQqBQgBEH0hsIANgKgFCAEQQA2AvAJIARBATYC5AkgBEG0o8IANgLgCSAEQgQ3AugJIAQgCTYCnBQgBCAUNgKYFCAEQbATaiAKQRxqIARBmBRqEP0dIARB0BJqIARBuBNqKAIANgIAIAQgBCkCsBM3A8gSQczE5gAoAgAgBEHIEmoiCRD3F0Hg0OYALQAADQFB0NDmACgCAEECSQ0BIARBAjYCsBYgBEHMxOYAKAIAIgopAhQ3ArQWIARB+ABqEMYZIAQoAngiBiAEQbAWaiAEKAJ8Ig4oAgwRAABFDQEgBEGgF2ogBEG4FmooAgA2AgAgBCAEKQKwFjcDmBcgCiAGIA4gDyAJEPcJDAELQeDQ5gAtAAANAEHQ0OYAKAIAQQJJDQAgBEECNgLEECAEQczE5gAoAgAiBikCFDcCyBAgBEHwAGoQxhkgBCgCcCIOIARBxBBqIAQoAnQiCygCDBEAAEUNACAEQQA2AqgXIARBzMTmACgCACIKKAIgIgk2AqwXIAQgCikCJDcCoBcgBCAJNgKcFyAEIAooAhw2ApgXIARB4AlqIgkgBEGYF2oiDxCHESAEQcgVaiIUIAlB3KLCABCoFCAEQfSGwgA2ArgWIARBADYC8AkgBEEBNgLkCSAEQbSjwgA2AuAJIARCBDcC6AkgBCAJNgK0FiAEIBQ2ArAWIARBmBRqIgkgCkEcaiAEQbAWahD9HSAEQaAXaiAEQcwQaigCADYCACAEIAQpAsQQNwOYFyAGIA4gCyAPIAkQ9wkLAkAgCA0AAkBB2MrmACgCAEEDSw0AQbTE5gAQ7hpB/wFxIglFDQBBtMTmACgCACAJENUVRQ0AIARBADYCqBcgBEG0xOYAKAIAIgkoAiAiCjYCrBcgBCAJKQIkNwKgFyAEIAo2ApwXIAQgCSgCHDYCmBcgBEHgCWoiCCAEQZgXaiIPEIcRIARByBVqIhQgCEG8o8IAEKgUIARB9IbCADYCoBQgBEEANgLwCSAEQQE2AuQJIARBmKTCADYC4AkgBEIENwLoCSAEIAg2ApwUIAQgFDYCmBQgBEGwE2ogCUEcaiAEQZgUahD9HSAEQdASaiAEQbgTaigCADYCACAEIAQpArATNwPIEkG0xOYAKAIAIARByBJqIgkQ9xdB4NDmAC0AAA0BQdDQ5gAoAgBBAkkNASAEQQI2ArAWIARBtMTmACgCACIIKQIUNwK0FiAEQegAahDGGSAEKAJoIgogBEGwFmogBCgCbCIGKAIMEQAARQ0BIARBoBdqIARBuBZqKAIANgIAIAQgBCkCsBY3A5gXIAggCiAGIA8gCRD3CQwBC0Hg0OYALQAADQBB0NDmACgCAEECSQ0AIARBAjYC0BAgBEG0xOYAKAIAIgopAhQ3AtQQIARB4ABqEMYZIAQoAmAiBiAEQdAQaiAEKAJkIg4oAgwRAABFDQAgBEEANgKoFyAEQbTE5gAoAgAiCSgCICILNgKsFyAEIAkpAiQ3AqAXIAQgCzYCnBcgBCAJKAIcNgKYFyAEQeAJaiIIIARBmBdqIg8QhxEgBEHIFWoiFCAIQbyjwgAQqBQgBEH0hsIANgK4FiAEQQA2AvAJIARBATYC5AkgBEGYpMIANgLgCSAEQgQ3AugJIAQgCDYCtBYgBCAUNgKwFiAEQZgUaiIIIAlBHGogBEGwFmoQ/R0gBEGgF2ogBEHYEGooAgA2AgAgBCAEKQLQEDcDmBcgCiAGIA4gDyAIEPcJCyAMKALYByIILQDqAgRAQdjK5gAoAgBBAUsNCUHAxOYAEO4aQf8BcSIJRQ0JQcDE5gAoAgAgCRDVFUUNCSAEQQA2AqgXIARBwMTmACgCACIJKAIgIgg2AqwXIAQgCSkCJDcCoBcgBCAINgKcFyAEIAkoAhw2ApgXIARB4AlqIgggBEGYF2oiDxCHESAEQcgVaiIUIAhBoKTCABCoFCAEQfSGwgA2AqAUIARBADYC8AkgBEEBNgLkCSAEQcikwgA2AuAJIARCBDcC6AkgBCAINgKcFCAEIBQ2ApgUIARBsBNqIAlBHGogBEGYFGoQ/R0gBEHQEmogBEG4E2ooAgA2AgAgBCAEKQKwEzcDyBJBwMTmACgCACAEQcgSaiIJEPcXQeDQ5gAtAAANCkHQ0OYAKAIAQQRJDQogBEEENgKwFiAEQcDE5gAoAgAiCCkCFDcCtBYgBEEgahDGGSAEKAIgIhQgBEGwFmogBCgCJCIRKAIMEQAARQ0KIARBoBdqIARBuBZqKAIANgIAIAQgBCkCsBY3A5gXIAggFCARIA8gCRD3CQwKCyAMQeAHaiEdIAgoAuACDQEgDEEAOgDpByAMIAg2AuQHIAwgDC0A3gciCjoA6gcgDEHpB2ohGgsgDCAINgLgByAMQQA6AOgHIAgoApACIhFBAkkgEUEGcUECRnJFBEBBDiERDBULQdDQ5gAoAgBBA00NDiAEQcynwgA2AuAJIARCATcC7AkgBEEBNgK0EyAEQQE2AuQJIAQgCkF/c0EBcToAsBUgBCAEQbATajYC6AkgBCAEQbAVajYCsBMgBEHUp8IANgLYFSAEQRo2AtQVIARB6JrCADYC0BUgBEEaNgLMFSAEQeiawgA2AsgVIARB4AlqQQQgBEHIFWoQwwogHSgCACIIKAKQAiERDA4LIAwgEToA5QcgDEEAOgDkByAMIAg2AuAHIAxB5AdqIRoLIAgoApACIgpBAkkgCkEGcUECRnJFBEBBDiERDAsLAkACQEHYyuYAKAIAQQFLDQBB5MHmABDuGkH/AXEiCkUNAEHkweYAKAIAIAoQ1RVFDQAgBEEANgKoFyAEQeTB5gAoAgAiCigCICIGNgKsFyAEIAopAiQ3AqAXIAQgBjYCnBcgBCAKKAIcNgKYFyAEQeAJaiIJIARBmBdqIg8QhxEgBEHIFWoiFCAJQdyQwgAQqBQgBEH0hsIANgKgFCAEQQA2AvAJIARBATYC5AkgBEGIkcIANgLgCSAEQgQ3AugJIAQgCTYCnBQgBCAUNgKYFCAEQbATaiAKQRxqIARBmBRqEP0dIARB0BJqIARBuBNqKAIANgIAIAQgBCkCsBM3A8gSQeTB5gAoAgAgBEHIEmoiCRD3F0Hg0OYALQAADQFB0NDmACgCAEEESQ0BIARBBDYCsBYgBEHkweYAKAIAIgopAhQ3ArQWIARB2ABqEMYZIAQoAlgiBiAEQbAWaiAEKAJcIg4oAgwRAABFDQEgBEGgF2ogBEG4FmooAgA2AgAgBCAEKQKwFjcDmBcgCiAGIA4gDyAJEPcJDAELQeDQ5gAtAAANAEHQ0OYAKAIAQQRJDQAgBEEENgKgEiAEQeTB5gAoAgAiBikCFDcCpBIgBEHQAGoQxhkgBCgCUCIOIARBoBJqIAQoAlQiCygCDBEAAEUNACAEQQA2AqgXIARB5MHmACgCACIKKAIgIgk2AqwXIAQgCikCJDcCoBcgBCAJNgKcFyAEIAooAhw2ApgXIARB4AlqIgkgBEGYF2oiDxCHESAEQcgVaiIUIAlB3JDCABCoFCAEQfSGwgA2ArgWIARBADYC8AkgBEEBNgLkCSAEQYiRwgA2AuAJIARCBDcC6AkgBCAJNgK0FiAEIBQ2ArAWIARBmBRqIgkgCkEcaiAEQbAWahD9HSAEQaAXaiAEQagSaigCADYCACAEIAQpAqASNwOYFyAGIA4gCyAPIAkQ9wkLIAxBADoAjAsgDCAINgKICyAMQegHaiEZIAxBjAtqIRwgEUEBcQ0CCwJAAkBB2MrmACgCAEEBSw0AQfDB5gAQ7hpB/wFxIglFDQBB8MHmACgCACAJENUVRQ0AIARBADYC2BUgBEHwweYAKAIAIgkoAiAiCjYC3BUgBCAJKQIkNwLQFSAEIAo2AswVIAQgCSgCHDYCyBUgBEHgCWoiDyAEQcgVaiIUEIcRIARBsBZqIhEgD0GwkcIAEKgUIARB9IbCADYCuBMgBEEANgLwCSAEQQE2AuQJIARB2JHCADYC4AkgBEIENwLoCSAEIA82ArQTIAQgETYCsBMgBEHgEWogCUEcaiAEQbATahD9HSAEQZATaiAEQegRaigCADYCACAEIAQpAuARNwOIE0HwweYAKAIAIARBiBNqIgkQ9xdB4NDmAC0AAA0BQdDQ5gAoAgBBBEkNASAEQQQ2ApgUIARB8MHmACgCACIPKQIUNwKcFCAEQcgAahDGGSAEKAJIIgogBEGYFGogBCgCTCIGKAIMEQAARQ0BIARB0BVqIARBoBRqKAIANgIAIAQgBCkCmBQ3A8gVIA8gCiAGIBQgCRD3CQwBC0Hg0OYALQAADQBB0NDmACgCAEEESQ0AIARBBDYCyBIgBEHwweYAKAIAIgopAhQ3AswSIARBQGsQxhkgBCgCQCIGIARByBJqIAQoAkQiDigCDBEAAEUNACAEQQA2AtgVIARB8MHmACgCACIJKAIgIgs2AtwVIAQgCSkCJDcC0BUgBCALNgLMFSAEIAkoAhw2AsgVIARB4AlqIg8gBEHIFWoiFBCHESAEQbAWaiIRIA9BsJHCABCoFCAEQfSGwgA2AqAUIARBADYC8AkgBEEBNgLkCSAEQdiRwgA2AuAJIARCBDcC6AkgBCAPNgKcFCAEIBE2ApgUIARBsBNqIg8gCUEcaiAEQZgUahD9HSAEQdAVaiAEQdASaigCADYCACAEIAQpAsgSNwPIFSAKIAYgDiAUIA8Q9wkLIAgoAuACRQRAQRohEQwJCyAEQZgXaiIGIAgoAswCQQhqEM8NIARB4AlqIAYgCCgC4AJBCGogCC0AGBC5BiAEKALgCUEBRgRAIARB4hFqIgggBEHrCWotAAA6AAAgBEGKE2oiCSAEQfMJai0AADoAACAEQbgWaiIPIARBgApqKQMANwMAIAQgBC8A6Qk7AeARIAQgBC8A8Qk7AYgTIAQgBCkD+Ak3A7AWIAQtAOgJIQogBCgC7AkhBiAELQDwCSEOIAQoAvQJIQsgBCkDiAohKiAEQaoZaiAILQAAOgAAIARBphlqIAktAAA6AAAgBEGYGWogDykDADcDACAEIAQvAeAROwGoGSAEIAQvAYgTOwGkGSAEIAQpA7AWNwOQGUERIREMCQsgBEHiEWoiBiAEQesJai0AADoAACAEQYoTaiIJIARB8wlqLQAAOgAAIARBuBZqIg4gBEGACmopAwA3AwAgBCAELwDpCTsB4BEgBCAELwDxCTsBiBMgBCAEKQP4CTcDsBYgBCgC9AkhCiAEKALsCSELIAQtAPAJIQ8gBCgC5AkhFCAELQDoCSERIAQoAogKIRMgBEGaFGoiFyAGLQAAOgAAIARBshNqIgYgCS0AADoAACAEQdAVaiIJIA4pAwA3AwAgBCAELwHgETsBmBQgBCAELwGIEzsBsBMgBCAEKQOwFjcDyBUgDCAROgDsByAMIBQ2AugHIAwgDzoA9AcgDCALNgLwByAMIAQvAZgUOwDtByAMQe8HaiAXLQAAOgAAIAwgCjYC+AcgDCAELwGwEzsA9QcgDEH3B2ogBi0AADoAACAMIAQpA8gVNwL8ByAMQYQIaiAJKQMANwIAIAxBADoAgAsgDCAINgL4CiAMIBM2AowICyAEQeAJaiAZIAIQgQIgBC0A4AkiEUExRg0CIARBrhlqIAQtAOMJOgAAIARBqhlqIARB6wlqLQAAOgAAIARBphlqIARB8wlqLQAAOgAAIAQgBC8A4Qk7AawZIAQgBC8A6Qk7AagZIAQgBC8A8Qk7AaQZIAQoAuQJIQggBC0A6AkhCiAEKALsCSEGIAQtAPAJIQ4gBCgC9AkhCyAEQZgZaiAEQYAKaikDADcDACAEIAQpA/gJNwOQGSAEKQOICiEqIARB2BhqIARBkApqQTj8CgAAIBkQ8RoMBwsCQAJAQdjK5gAoAgBBAUsNAEH8weYAEO4aQf8BcSIJRQ0AQfzB5gAoAgAgCRDVFUUNACAEQQA2AqgXIARB/MHmACgCACIJKAIgIgo2AqwXIAQgCSkCJDcCoBcgBCAKNgKcFyAEIAkoAhw2ApgXIARB4AlqIg8gBEGYF2oiFBCHESAEQcgVaiIRIA9B8JHCABCoFCAEQfSGwgA2AqAUIARBADYC8AkgBEEBNgLkCSAEQZiSwgA2AuAJIARCBDcC6AkgBCAPNgKcFCAEIBE2ApgUIARByBJqIAlBHGogBEGYFGoQ/R0gBEHoEWogBEHQEmooAgA2AgAgBCAEKQLIEjcD4BFB/MHmACgCACAEQeARaiIJEPcXQeDQ5gAtAAANAUHQ0OYAKAIAQQRJDQEgBEEENgKwFiAEQfzB5gAoAgAiDykCFDcCtBYgBEE4ahDGGSAEKAI4IgogBEGwFmogBCgCPCIGKAIMEQAARQ0BIARBoBdqIARBuBZqKAIANgIAIAQgBCkCsBY3A5gXIA8gCiAGIBQgCRD3CQwBC0Hg0OYALQAADQBB0NDmACgCAEEESQ0AIARBBDYCsBMgBEH8weYAKAIAIgopAhQ3ArQTIARBMGoQxhkgBCgCMCIGIARBsBNqIAQoAjQiDigCDBEAAEUNACAEQQA2AqgXIARB/MHmACgCACIJKAIgIgs2AqwXIAQgCSkCJDcCoBcgBCALNgKcFyAEIAkoAhw2ApgXIARB4AlqIg8gBEGYF2oiFBCHESAEQcgVaiIRIA9B8JHCABCoFCAEQfSGwgA2ArgWIARBADYC8AkgBEEBNgLkCSAEQZiSwgA2AuAJIARCBDcC6AkgBCAPNgK0FiAEIBE2ArAWIARBmBRqIg8gCUEcaiAEQbAWahD9HSAEQaAXaiAEQbgTaigCADYCACAEIAQpArATNwOYFyAKIAYgDiAUIA8Q9wkLIAgoAuACIglFBEBBGiERDAcLIARB4AlqIAlBCGogCCgCzAJBCGoQzgggBCgC4AlBAUYEQCAEQcoSaiIIIARB6wlqLQAAOgAAIARB4hFqIgkgBEHzCWotAAA6AAAgBEHQFWoiDyAEQYAKaikDADcDACAEIAQvAOkJOwHIEiAEIAQvAPEJOwHgESAEIAQpA/gJNwPIFSAELQDoCSEKIAQoAuwJIQYgBC0A8AkhDiAEKAL0CSELIAQpA4gKISogBEGqGWogCC0AADoAACAEQaYZaiAJLQAAOgAAIARBmBlqIA8pAwA3AwAgBCAELwHIEjsBqBkgBCAELwHgETsBpBkgBCAEKQPIFTcDkBlBESERDAcLIARByhJqIgYgBEHrCWotAAA6AAAgBEHiEWoiCSAEQfMJai0AADoAACAEQdAVaiIOIARBgApqKQMANwMAIAQgBC8A6Qk7AcgSIAQgBC8A8Qk7AeARIAQgBCkD+Ak3A8gVIAQoAvQJIQogBCgC7AkhCyAELQDwCSEPIAQoAuQJIRQgBC0A6AkhESAEKAKICiETIARBshZqIhcgBi0AADoAACAEQZoUaiIGIAktAAA6AAAgBEGgF2oiCSAOKQMANwMAIAQgBC8ByBI7AbAWIAQgBC8B4BE7AZgUIAQgBCkDyBU3A5gXIAwgEToA7AcgDCAUNgLoByAMIA86APQHIAwgCzYC8AcgDCAELwGwFjsA7QcgDEHvB2ogFy0AADoAACAMIAo2AvgHIAwgBC8BmBQ7APUHIAxB9wdqIAYtAAA6AAAgDCAEKQOYFzcC/AcgDEGECGogCSkDADcCACAMQQA6AIALIAwgCDYC+AogDCATNgKMCAsgBEHgCWogGSACEIECIAQtAOAJIhFBMUYNAyAEQa4ZaiAELQDjCToAACAEQaoZaiAEQesJai0AADoAACAEQaYZaiAEQfMJai0AADoAACAEIAQvAOEJOwGsGSAEIAQvAOkJOwGoGSAEIAQvAPEJOwGkGSAEKALkCSEIIAQtAOgJIQogBCgC7AkhBiAELQDwCSEOIAQoAvQJIQsgBEGYGWogBEGACmopAwA3AwAgBCAEKQP4CTcDkBkgBCkDiAohKiAEQdgYaiAEQZAKakE4/AoAACAZEPEaDAULIBxBAzoAAEEEDAMLQeDQ5gAtAAANAEHQ0OYAKAIAQQRJDQAgBEEENgLcECAEQcDE5gAoAgAiDykCFDcC4BAgBEEYahDGGSAEKAIYIhQgBEHcEGogBCgCHCIRKAIMEQAARQ0AIARBADYCqBcgBEHAxOYAKAIAIgkoAiAiCjYCrBcgBCAJKQIkNwKgFyAEIAo2ApwXIAQgCSgCHDYCmBcgBEHgCWoiCCAEQZgXaiIWEIcRIARByBVqIhMgCEGgpMIAEKgUIARB9IbCADYCuBYgBEEANgLwCSAEQQE2AuQJIARByKTCADYC4AkgBEIENwLoCSAEIAg2ArQWIAQgEzYCsBYgBEGYFGoiCCAJQRxqIARBsBZqEP0dIARBoBdqIARB5BBqKAIANgIAIAQgBCkC3BA3A5gXIA8gFCARIBYgCBD3CQsgDCgC2AciCSgC4AIiCEUEQEEqIREMDwsgCCAIKAIAIgpBAWo2AgAgCkEASA0MIAkoAuACLQAIQQFGBH8gDC0A3gcFQQALQQFxIQoMBAsgHEEDOgAAQQMLIQYgGiAGOgAAQQYhFQwOCyAcQQE6AAAgGRCWHgsgGkEBOgAAIB0QzRkgEUEwRwRAIARBvhFqIARBrhlqLQAAOgAAIARBuhFqIARBqhlqLQAAOgAAIARBthFqIARBphlqLQAAOgAAIARBqBFqIARBmBlqKQMANwMAIAQgBC8BrBk7AbwRIAQgBC8BqBk7AbgRIAQgBC8BpBk7AbQRIAQgBCkDkBk3A6ARIARB6BBqIARB2BhqQTj8CgAADAsLIAwoAtgHIggtAOoCQQFHBEBBKSERDAsLIAgoAuACIggEQEEAIQkgCC0ACEEBRgRAIAwtAN4HIQkLIAggCCgCACIKQQFqNgIAIApBAEgNCSAJQQFxIQoMAQtB0KTCABDSIAALQTAhEQwJCyARQQJHBEBBJyERDAULIAgoAswCIQYgBEHgCWoiCSAIQdAAakHAAfwKAAAgBEEoaiAMQegHaiAIQZQCaiAGQQhqIAkgCC0AGCAKQQFxEIMJIAwgBCkDKDcC7AcLIARB4AlqIAxB7AdqIgkgAhC1HkEDIAQtAOAJIg5BAkYNARogBEGiEmogBC0A4wk6AAAgBEHCEWoiDyAEQesJai0AADoAACAEQbgWaiILIARB+AlqKQIANwMAIARBwBZqIhQgBEGACmovAQA7AQAgBCAELwDhCTsBoBIgBCAELwDpCTsBwBEgBCAEKQLwCTcDsBYgBCgC5AkhCCAELQDoCSEKIAQoAuwJIQYgCRD+FSAOQQFxBEAgBEHSGGogDy0AADoAACAEIAQvAcAROwHQGEEoIREMBAsgDEEBOgDoByAJIAQvAaASOwAAIAwgCjoA8wcgDCAINgDvByAMIAQvAcAROwD0ByAMIAY2APcHIAwgBCkDsBY3APsHIAlBAmogBEGiEmotAAA6AAAgDEH2B2ogBEHCEWotAAA6AAAgDEGDCGogCykDADcAACAMQYsIaiAULwEAOwAAIAxBADoA7QggDCAMKALgBzYC6AgLIARB4AlqIAxBkAhqIgkgAhCNAiAELQDgCSIRQTFHDQFBBAshBiAaIAY6AABBByEVDAcLIARByhJqIg8gBC0A4wk6AAAgBEHiEWoiFCAEQesJai0AADoAACAEQYoTaiIWIARB8wlqLQAAOgAAIAQgBC8A4Qk7AcgSIAQgBC8A6Qk7AeARIAQgBC8A8Qk7AYgTIAQoAuQJIQggBC0A6AkhCiAEKALsCSEGIAQtAPAJIQ4gBCgC9AkhCyAEQaAUaiITIARBgApqKQMANwMAIAQgBCkD+Ak3A5gUIAQpA4gKISogBEGYF2oiFyAEQZAKakE4/AoAACAJEKAbAkAgEUEwRwRAIARB1hhqIA8tAAA6AAAgBEHSGGogFC0AADoAACAEQc4YaiAWLQAAOgAAIARBwBhqIBMpAwA3AwAgBCAELwHIEjsB1BggBCAELwHgETsB0BggBCAELwGIEzsBzBggBCAEKQOYFDcDuBggBEGAGGogF0E4/AoAAAwBCyAEQdMVaiAEQYoTai0AADoAACAEQeAVaiAEQaAUaikDADcDACAEIAo6AMgVIAQgBC8B4BE7AMkVIAQgDjoA0BUgBCAGNgLMFSAEIAQvAYgTOwDRFSAEIAs2AtQVIAQgBCkDmBQ3A9gVIAQgBEHiEWotAAA6AMsVAkACQCAKQQFHBEAgCkEGRg0BIARB6wlqIARBihNqLQAAOgAAIARB+AlqIARBoBRqKQMANwMAIAQgCjoA4AkgBCAELwHgETsA4QkgBCAOOgDoCSAEIAY2AuQJIAQgBC8BiBM7AOkJIAQgCzYC7AkgBCAEKQOYFDcD8AkgBCAEQeIRai0AADoA4wkgBEGwE2ogBEHgCWoiCRDgAyAEQdIYaiAEQbcTai0AADoAACAEIAQvALUTOwHQGCAELQC0EyEKIAQoArATIQggBCgCuBMhBiAJEOkVQSYhEQwDCyAELQDLFSEPIAQtAMoVIQggBC0AyRUhCSAEQcgVahDpFSAEQeAJaiAdKAIAIAkgCBDiASAELQDgCSIRQTBHBEAgBEHWGGogBC0A4wk6AAAgBEHSGGogBEHrCWotAAA6AAAgBEHOGGogBEHzCWotAAA6AAAgBCAELwDhCTsB1BggBCAELwDpCTsB0BggBCAELwDxCTsBzBggBCgC5AkhCCAELQDoCSEKIAQoAuwJIQYgBC0A8AkhDiAEKAL0CSELIARBwBhqIARBgApqKQMANwMAIAQgBCkD+Ak3A7gYIAQpA4gKISogBEGAGGogBEGQCmpBOPwKAAAMAwsgHSgCACAPOgDqAiAdKAIAIhEtAOoCRQ0BIAxBADoA6AcgBEHgCWoiDyAMQewHakEh/AoAACAPEM4ZIQ8gDCgC4AdB4AJqEPAeIAwoAuAHIA82AuACIAwoAuAHIREMAQsgBEHSGGogBEGKE2otAAA6AAAgBCAELwGIEzsB0BhBDyERIAYhCCAOIQogCyEGDAELIBEgCDoA6QIgESAJOgDoAiAMLQDoBwRAIAxB7AdqEK4aCyAMQQA6AOgHQTAhEQwCCyAMQewHahCuGgsgDEEAOgDoBwsgGkEBOgAAIB0Q/xUgEUEwRwRAIARBvhFqIARB1hhqLQAAOgAAIARBuhFqIARB0hhqLQAAOgAAIARBthFqIARBzhhqLQAAOgAAIARBqBFqIARBwBhqKQMANwMAIAQgBC8B1Bg7AbwRIAQgBC8B0Bg7AbgRIAQgBC8BzBg7AbQRIAQgBCkDuBg3A6ARIARB6BBqIARBgBhqQTj8CgAADAMLIAwoAtgHKALgAiIIRQ0BIAggCCgCACIJQQFqNgIAIAlBAEgNAEEwIRFBACEKDAILAAtB4KTCABDSIAALIAxBAToA3wcgAxCzFQsgDC0A7AYEQCAVEIUECyAMQYACOwHsBiAVEJ0VIAxBiAJqIQkgEUEwRwRAIARBywVqIARBuhFqLQAAOgAAIARB0wVqIARBthFqLQAAOgAAIAQgEToAwAUgBCAELwG8ETsAwQUgBCAKOgDIBSAEIAg2AsQFIAQgBC8BuBE7AMkFIAQgDjoA0AUgBCAGNgLMBSAEIAQvAbQROwDRBSAEIAs2AtQFIAQgBEG+EWotAAA6AMMFIARB4AVqIARBqBFqKQMANwMAIAQgKjcD6AUgBCAEKQOgETcD2AUgBEHwBWogBEHoEGpBOPwKAAACQAJAQdjK5gAoAgBBA0sNAEGIv+YAEO4aQf8BcSIGRQ0AQYi/5gAoAgAgBhDVFUUNACAEQQA2AqgXIARBiL/mACgCACIGKAIgIgg2AqwXIAQgBikCJDcCoBcgBCAINgKcFyAEIAYoAhw2ApgXIARB4AlqIgggBEGYF2oiDhCHESAEQcgVaiIKIAhBrInCABCoFCAEQfSGwgA2ArgTIARBAjYC5AkgBEHkicIANgLgCSAEQgI3AuwJIARBAjYCvBYgBEEDNgK0FiAEIAk2ArAWIAQgCDYCtBMgBCAKNgKwEyAEIARBsBZqNgLoCSAEIARBwAVqNgK4FiAEQfgOaiAGQRxqIARBsBNqEP0dIARB0BJqIARBgA9qKAIANgIAIAQgBCkC+A43A8gSQYi/5gAoAgAgBEHIEmoiBhD3F0Hg0OYALQAADQFB0NDmACgCAEECSQ0BIARBAjYCmBQgBEGIv+YAKAIAIggpAhQ3ApwUIARBEGoQxhkgBCgCECIKIARBmBRqIAQoAhQiCygCDBEAAEUNASAEQaAXaiAEQaAUaigCADYCACAEIAQpApgUNwOYFyAIIAogCyAOIAYQ9wkMAQtB4NDmAC0AAA0AQdDQ5gAoAgBBAkkNACAEQQI2AvgOIARBiL/mACgCACIOKQIUNwL8DiAEQQhqEMYZIAQoAggiCiAEQfgOaiAEKAIMIgsoAgwRAABFDQAgBEEANgKoFyAEQYi/5gAoAgAiBigCICIINgKsFyAEIAYpAiQ3AqAXIAQgCDYCnBcgBCAGKAIcNgKYFyAEQeAJaiIIIARBmBdqIgMQhxEgBEHIFWoiDyAIQayJwgAQqBQgBEH0hsIANgKgFCAEQQI2AuQJIARB5InCADYC4AkgBEICNwLsCSAEQQI2ArwWIARBAzYCtBYgBCAJNgKwFiAEIAg2ApwUIAQgDzYCmBQgBCAEQbAWajYC6AkgBCAEQcAFajYCuBYgBEGwE2oiCCAGQRxqIARBmBRqEP0dIARBoBdqIARBgA9qKAIANgIAIAQgBCkC+A43A5gXIA4gCiALIAMgCBD3CQsgBEHgCWoiBiAJQcAB/AoAACAEQZgXakEEciAGEJ8QQQAiCEUEQCAGIARBwAVqQegA/AoAAAtB6ABBCBCfGyIGIARB4AlqQegA/AoAACAEQb4FaiAELQCbFzoAACAEIAY2AqgXIAQgBC8AmRc7AbwFIAQoApwXIRUgBC0AoBchCSAEQeQEaiAEQaEXakHXAPwKAAAMAwsgBCAINgLQAiAEIAo6ANQCIApBAXFFBEAgBEG+BWogDEHTA2otAAA6AAAgBCAMLwDRAzsBvAUgDC0A0AMhESAMKQPIAyEqIAwoAtQDIRUgDC0A2AMhCSAEQeQEaiAMQdkDakHXAPwKAAAgBEHYAmogDEGwBGpBiAL8CgAADAULIARB4AlqIgYgCUHAAfwKAAAgBEHABWogBhCfECAEIAQoAMUFNgLkBCAEIARByAVqKAAANgDnBCAEKALABSEVIAQtAMQFIQkgBEHQAmoQ7RlBOAwDCyAMIBU6AN8HQQQLIQYgFiAGOgAAIBBCAzcDAEEEDAMLQQcLIREgDEHIA2oQuhFCAiEqCyAMQbwGahDuGSAQIBE6AAggECAqNwMAIBAgCToAECAQIBU2AgwgECAELwG8BTsACSAQQQtqIARBvgVqLQAAOgAAIBBBEWogBEHkBGpB1wD8CgAAIBBB6ABqIARB2AJqQYgC/AoAACAQIAg2AvACQQELOgDABiAEQbAZaiQAQQYgBykDwCQiLkIDUQ0FGiAHKQOgJSErIAcpA5glISogBykDkCUhLCAHKAKMJSEEIAcoAoglIQ8gBygChCUhCCAHKAKAJSELIAcoAvwkIQ4gBygC+CQhCiAHKAL0JCEUIAcoAvAkIQkgBykD6CQhLSAHKQPgJCEwIAcpA9gkIS8gBygC1CQhAyAHKALQJCEWIAcoAswkIQYgBy8ByiQhESAHLQDJJCETIActAMgkIRAgB0G4LGogB0GoJWpBiAL8CgAAIAcoArAnIRkgDBD6FCAuQgJRBEAgDUHMBGoQ8yEgDUGEBWoQlRwMBwsgB0HAGmogB0G4LGpBiAL8CgAAIAdByBxqIA1ByBBqQcAB/AoAACAHQfQ0aiANQYwFaikCADcCACAHIA0pAoQFNwLsNCANKAK8BCEMIAdBqDRqIA1BwARqQcQA/AoAAAwCCyAWQQM6AABBBQwECyANQQA6ALUEIA0oArAEIQMgDSgCrAQhFiANKAKoBCEGQTchEAwECyAHIAw2AqQYIAdBqBhqIAdBqDRqQdQA/AoAACAHIBk2AvwYIAdBgBlqIAdByBxqQcAB/AoAACANICs3A+AHIA0gKjcD2AcgDSAsNwPQByANIAQ2AswHIA0gDzYCyAcgDSAINgLEByANIAs2AsAHIA0gDjYCvAcgDSAKNgK4ByANIBQ2ArQHIA0gCTYCsAcgDSAtNwOoByANIDA3A6AHIA0gLzcDmAcgDSADNgKUByANIBY2ApAHIA0gBjYCjAcgDSAROwGKByANIBM6AIkHIA0gEDoAiAcgDSAuNwOAByANQegHaiAHQcAaakGIAvwKAAAgDUG8BGoiECIGQZwCahCdJSAGIAdBpBhqQZwC/AoAACANQQA6APgGIA0gEDYC7AYgDSANKALcASIWNgLoBiANQfgGaiEGIA1B6AZqIQMLQeAAQQQQhCEiDEUEQEEEQeAAEOEjAAsgDEEAOgBcIAwgEDYCBCAMIBY2AgAgB0EYaiIQQZTTwwA2AgQgECAMNgIAIAcoAhghDCANIAcoAhw2AvQGIA0gDDYC8AYLIAdBwCRqIhAgDUHwBmoiFiACELUeIActAMAkIgxBwgBHBEAgB0GIHmogEEEBckHnAPwKAAAgFhD+FSAMQcEARiIWBH9BPwVB6ABBCBCfGyIGIAw6AAAgBkEBaiAHQYgeakHnAPwKAABBFAshECANQQE6APgGIAMQgxwgDUG8BGohDCAWRQRAIAwQ8xYgDUGAB2oQlx5BlIzCACEWDAMLIAdBwDBqIAxBrAL8CgAAIAdB9DJqIA1BjAJqKAIANgIAIAcgDSkChAI3AuwyIA0pA4AHIS4gDS0AiAchECANLQCJByETIA0vAYoHIREgDSgCjAchBiANKAKQByEWIA0oApQHIQMgDSkDmAchLyANKQOgByEwIA0pA6gHIS0gDSgCsAchCSANKAK0ByEUIA0oArgHIQogDSgCvAchDiANKALAByELIA0oAsQHIQggDSgCyAchDyANKALMByEEIA0pA9AHISwgDSkD2AchKiANKQPgByErIA0pA+gHITEgB0HALmogDUHwB2pBgAL8CgAAIA1BqARqEPMhIA1BADYAtQQgDUH4AWoQ2yAMBQsgBkEDOgAAQQcLIQYgJCAGOgAADAQLIA0tALUEBEAgDUGoBGoQ8yELIA1BADoAtQQgDSgCkAJBAkYEQCANLQC4BEUNASANQZQCahCVHAwBCyANLQC3BARAIA1B2AJqEJUcCyANLQC2BEUNACANQaACahDzIQsgDUEAOgC4BCANQQA7AbYEIA1BhAJqELYSCyANQfgBahDbIEIDIS4CQAJAQQMgDSgC4AEiDEGAgICAeHMgDEEAThtBAmsOAgABAgsgDS0AuQRFDQEgDUHkAWoQ8yEMAQsgDS0AuwQEQCANQeABahDzIQsgDS0AugRFDQAgDUHsAWoQlRwLIA1BADoAuwQgDUEAOwC5BCANQQE6ALQEIC5CBFENACAHQZALaiAHQcAuakG4BPwKAAAgIhDVBgwDC0EECyEGICEgBjoAAAsgHkIENwMAQQQMAwsgIUEBOgAACyAHQbABaiAHQZALakG4BPwKAAAgEhD3DQJAIC5CA1EEQCAQQf8BcSAPrSAErUIghoQhMyAtQiCIIC2nQTAhECAIIQQgCyEPIA4hCCAvITIgCSESIBQhDiAwIS0hCachFCArITEgCiELIBatIAOtQiCGhCEvIAYhAyATQf8BcUEIdHIgEUEQdHIhFgwBCyAHQegFaiAHQbABakG4BPwKAAAgLCEzICohLCArISogMCEyIAohEgsgDS0AOwRAIA1BLGoQ2yALIA1BADoAOwsgDUEgahCVHCAeIDE3A2ggHiAqNwNgIB4gLDcDWCAeIDM3A1AgHiAENgJMIB4gDzYCSCAeIAg2AkQgHiALNgJAIB4gDjYCPCAeIBI2AjggHiAUNgI0IB4gCTYCMCAeIC03AyggHiAyNwMgIB4gLzcDGCAeIAM2AhQgHiAWNgIQIB4gBjYCDCAeIBE7AQogHiATOgAJIB4gEDoACCAeIC43AwAgHkHwAGogB0HoBWpBuAT8CgAAQQELOgA5IAdBgDVqJAAgBSkDoCgiK0IEUg0BIB9BAzoAAEEECyEBICYgAToAACAAQQQ2AgBBBAw8CyANEPMRIAUpA5ApISogBSkDiCkhLCAFKAKEKSEPIAUoAoApIQkgBSgC/CghEyAFKAL4KCEWIAUoAvQoIREgBSgC8CghGSAFKALsKCEhIAUoAugoIRwgBSgC5CghJCAFKALgKCEeIAUoAtwoIR0gBSgC2CghGiAFKALUKCEVIAUoAtAoIQQgBSgCzCghECAFKALIKCEHIAUoAsQoIQogBSgCwCghFCAFKAK8KCEGIAUoArgoIQsgBSgCtCghCCAFKAKwKCEDIAUoAqwoIQwgBSgCqCghDiAFQcAfaiAFQZgpakGwBPwKAAAgH0EBOgAAIA0Q9BogK0IDUQRAICMpAwBCA1EEQCAjEIEYCyAEIRcgECEiIAchBCAKIRAgFCEHIAYhCiALIRQgCCEGIAkhHyADIQsgDCEIIA8hEiAsISogDiEDQQQhDkIDISsMAQsgBUHwI2ogBUHAH2pBsAT8CgAAICxCIIinIRIgLKchHyAjKQMAQgNRBEAgIxCBGAsgGiEXIBUhIiAdIRUgHiEaICQhHSAcIR4gISEkIBkhHCARISEgFiEZIBMhESAJIRYgDyETC0EAIglFBEAgBUGAAmogBUHwI2pBsAT8CgAACyAmQQE6AAAgBUGwBmogBUGAAmpBsAT8CgAAICMQgBYgK0IDUQRAICpCIIinISMgKqchJgw4CyABICo3A5gTIAEgEjYClBMgASAfNgKQEyABIBM2AowTIAEgFjYCiBMgASARNgKEEyABIBk2AoATIAEgITYC/BIgASAcNgL4EiABICQ2AvQSIAEgHjYC8BIgASAdNgLsEiABIBo2AugSIAEgFTYC5BIgASAXNgLgEiABICI2AtwSIAEgBDYC2BIgASAQNgLUEiABIAc2AtASIAEgCjYCzBIgASAUNgLIEiABIAY2AsQSIAEgCzYCwBIgASAINgK8EiABIAM2ArgSIAEgDDYCtBIgASAONgKwEiABICs3A6gSIAFBoBNqIAVBsAZqQbAE/AoAACABKAKYFUECRg0BIAFBgQI7AaYbIAFB8BhqIAVBqAhqQZwC/AoAACABQZQbaiAFQdwKaigCADYCACABIAUpAtQKNwKMGyAFQagBahD4CyAFKAKoASEIIAEgBSgCrAE2ApgbIAVBoAFqEPgLIAUoAqABIQogASAFKAKkATYCnBsgAUHAEWoiCxCsIiESIAFBAToApRsgASASNgKgGyABQaAbaiIDELcZIRIgBSAINgLsCiAFIAo2AugKIAUgEjYC5AogAUGgCmogAUHMGWoiCEHAAfwKAAAgCxCsIiESAkAgASkDqBJCAlIEQCAFQfAKaiIIIAFBqBJqQfAC/AoAACAFQaAoaiIUIAFBkAVqQfAC/AoAACABQQI2ApAFIAFB4AtqIQogBUHkCmohCyADELcZIQMCQAJAAkAgCC0A6gIEQCAIKAKQAkECRw0BIAgoAuACIgxFDQIgCkG4BGogCEHIAPwKAAAgCiAIKQK8AjcCnAUgCkGkBWogCEHEAmooAgA2AgAgCCgCyAIhECAKIAhB0ABqQcAB/AoAACAIKALMAiEHIApBqAVqIAhBkAJqQSz8CgAAIApBAToA1gUgCiAHNgKUBSAKIBA2ApAFIAogDDYCgAUgCiALKQIANwKEBSAKQYwFaiALQQhqKAIANgIAIAgvAegCIQsgCkHAAWogFEHwAvwKAAAgCiALOwHUBSAKQQA2ArQEIAogEjYCsAQgCiADNgKYBSAIQdACahCMHCAIKALkAgRAIAhB5AJqEPQZCyAIQcgAahC3FSAIQdwCahD6GAwDC0Hgr8MAQSRBhLDDABCcFQALQZSwwwBBMEHEsMMAEJwVAAtB1LDDAEErQYCxwwAQnBUACwwBCyAFQaAoaiAIQcAB/AoAACABQQA6AKcbQYCAgIB4IQogASgCuBkiCEGAgICAeEcEQCAFQfwjaiABQcQZaigCADYCACAFIAg2AvAjIAUgASkCvBk3AvQjIAVBADYCyB8gBUKAgICAEDcCwB8gBUH8s8IANgLkFCAFQqCAgIAONwLoFCAFIAVBwB9qNgLgFCAFQfAjaiIIIAVB4BRqEOYfDT0gBSkCxB8hKyAFKALAHyEKIAgQ8yELIAVBADYC+CMgBUKAgICAEDcC8CMgBUH8s8IANgLkFCAFQqCAgIAONwLoFCAFIAVB8CNqNgLgFCABQYAZaiAFQeAUaiIDEJsfDTwgBUHoDWogBUH4I2ooAgA2AgAgBSAFKQLwIzcD4A0gBUH4DWogBUGgKGoiC0HAAfwKAAAgBSArNwPwDSAFIAo2AuwNIAtBAToARCALQQo2AkAgC0EANgI4IAtCBTcDMCALQQA2AiggC0KsAjcDICALQQA6ABggC0KAtIkTNwMQIAtCADcDACAFQQA6ALgoIAMgC0HIAPwKAAAgAUGMG2oQlBohFCABQQA6AKYbIAEoAsgZIQwgCyABQZAFakHwAvwKAAAgAUEAOgClGyABQQI2ApAFIAEoAqAbIRAQ4xMhByABQeALaiIIIAVB4A1qIgopAgA3ApwFIAhBpAVqIApBCGooAgA2AgAgCCAKQRhqQcAB/AoAACAIQbgEaiADQcgA/AoAACAIIBQ2ApQFIAggBzYCkAUgCEEAOgDWBSAIQQQ2AqgFIAggDDYCgAUgCCAFQeQKaiIDKQIANwKEBSAIQYwFaiADQQhqKAIANgIAIAhBwAFqIAtB8AL8CgAAIAhBADoA1AUgCEEANgK0BCAIIBI2ArAEIAggEDYCmAUgCigCDEGAgICAeEcEQCAKQQxqEPMhCwsgAUEAOgDVGyABIAFB4AtqIgo2AtAbIAFBsBtqIRQgAUHVG2ohEgsgAUEAOgDUGwJAQdjK5gAoAgBBAksNAEGcxOYAEO4aQf8BcSIIRQ0AQZzE5gAoAgAgCBDVFUUNAEGcxOYAKAIAIQggBUEANgLwFCAFIAgoAiAiCzYC9BQgBSAIKQIkNwLoFCAFIAs2AuQUIAUgCCgCHDYC4BQgBUGgKGoiAyAFQeAUaiIMEIcRIAVBgAJqIhAgA0G8ocIAEKgUIAUgCjYC2B4gBUHwI2oiCyAMEIcRIAVBwB9qIgwgC0G8ocIAEKgUIAVB3KHCADYCtCggBUHMocIANgKoKCAFIApBnAVqNgKwGyAFIAVBsBtqNgKwKCAFIAw2AqwoIAUgBUHYHmo2AqQoIAUgEDYCoCggCyAIQRxqIAMQ+R0gFCAIIAsQpxcgAUEBOgDUGwwECyAFQQI2AqgoIAVBnMTmACgCACIINgK4KEHg0OYALQAARQ0BDAILIAVBADYCsCggBUEBNgKkKCAFQaiqwgA2AqAoIAVCBDcCqCggBUGgKGpBsKrCABD3GAALIAVBADYCgCQgBSAIKAIgIgs2AoQkIAUgCCkCJDcC+CMgBSALNgL0IyAFIAgoAhw2AvAjIAVB4BRqIgMgBUHwI2oiDBCHESAFQbAbaiIQIANBvKHCABCoFCAFIAo2AvAdIAVBwB9qIgsgDBCHESAFQYACaiIMIAtBvKHCABCoFCAFQdyhwgA2AvQUIAVBzKHCADYC6BQgBSAKQZwFajYC2B4gBSAFQdgeajYC8BQgBSAMNgLsFCAFIAVB8B1qNgLkFCAFIBA2AuAUIAsgCEEcaiADEPkdIAVBoChqIAsQ1QcLIAFBAToA1BsgFCAFKQOgKDcDACAUQQhqIAVBqChqKQMANwMAIBRBEGogBUGwKGopAwA3AwAgFEEYaiAFQbgoaikDADcDAAsgAUHYG2ohCyABKAK4G0ECRg0BIAFBADoA1BsgAUEAOgDnHCABIAo2AuAcIAsgFCkDADcDACALQQhqIBRBCGopAwA3AwAgC0EQaiAUQRBqKQMANwMAIAtBGGogFEEYaikDADcDAAtBACEIQQAhBkEAIQ5BACEKQgAhKkEAIRhBACEHIwBBkAprIgMkACABQdgbaiILKAIIQQJHBEAgC0EIaiALEO4TCyAFQaAoaiEPAkBB4NDmAC0AAA0AIAsoAhgiBEUNACADQQI2ArwIIANBsNHCADYCuAggA0IBNwLECCADQQU2AoQGIAMgBCkCDDcC0AcgAyADQYAGajYCwAggAyADQdAHajYCgAYgCyADQbgIahCFBQsgC0EgaiEMIAMgCzYCfCALAn8CQAJAAkACfwJAAkACQAJ/AkACQAJAAkACQAJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIAstAI8BQQFrDgcMOAEDHgsKAAsgCygCiAEiBCgCqAUiBkECSSAGQQZxQQJGcg0BIAsgBK03A5ABCyADQbgIaiALQZABahDeCSADLQC4CCIEQTFGBEAgD0ExOgAAQQMMOgsgA0HSAWoiECADLQC7CDoAACADQc4BaiIRIANBwwhqLQAAOgAAIANBygFqIhYgA0HLCGotAAA6AAAgAyADLwC5CDsB0AEgAyADLwDBCDsBzAEgAyADLwDJCDsByAEgAygCvAghDiADLQDACCEIIAMoAsQIIQYgAy0AyAghCSADKALMCCEKIANBwAFqIhMgA0HYCGopAwA3AwAgAyADKQPQCDcDuAEgAykD4AghKiADQYABaiIVIANB6AhqQTj8CgAAIARBMEcEQCADQYIDaiAQLQAAOgAAIANBwgNqIBEtAAA6AAAgA0GGCmogFi0AADoAACADQfAGaiATKQMANwMAIAMgAy8B0AE7AYADIAMgAy8BzAE7AcADIAMgAy8ByAE7AYQKIAMgAykDuAE3A+gGIANBuAhqIBVBOPwKAAAMOQsgCygCiAEhBAsgC0EAOgD8AyALIAQ2AvgDIAtBkAFqIQ4gC0H8A2ohCAwBCyALQZABaiEOIAtB/ANqIQgCQCALLQD8A0EBaw4DBjUCAAsgCygC+AMhBAsgBCgCqAUiBkECSSAGQQZxQQJGcg0BQQ4hBAwYCyALQcABaiEJAkAgCy0AwAFBAWsOBQgzAw4MAAsgCygCuAEhBAwBCyALQQA6AMABIAsgBDYCuAEgC0GHgICAeDYCkAEgC0HAAWohCQsgC0EBOgDCASALIAQ2ArwBIAtBxAFqIA5BKPwKAAAgBCgCqAVBAk8EQCALQQA6AMEBDAsLIAtBADoA9AMgCyAENgLAAwsgA0HQB2ogC0HwAWoiBCACEKwCIAMtANAHIgZBMUYEQEEDIQQMEAsgA0HRBGoiECADQdAHakEBckHnAPwKAAAgBBDMGSAGQTBHBEAgA0G4CGpBAXIgEEHnAPwKAAAgAyAGOgC4CAwRCyALQQE6AMEBIAsoArwBIQQMCQtB8MHCABC1FwALIAtBkAFqIQwgC0GZAWohGAJAIAstAJkBQQFrDgQELicoAAsgCy0AmgEhCCALKAKUASEEDBcLIAtBkAFqIQwgC0GUAWohGAJAAkACQAJAIAstAJQBQQFrDgQDMAIBAAsgCy0AlQEhDiALKAKQASEEDBsLIAtBmAFqIQcgC0G8BGohEAJAIAstALwEQQFrDgMGLx0ACyALKAK4BCEEDBsLIAtBmAFqIQcgC0G8BGohEAJAIAstALwEQQFrDgMGLh4ACyALKAK4BCEEDBwLQdDAwgAQtRcAC0GQxcIAELUXAAtB/MjCABC1FwALQezJwgAQtRcAC0GQwcIAELUXAAtB0MHCABC1FwALQQEhBAwFCwJAQQEgBCgCqAUiBkECayAGQQFNGw4DAAIEAgsgC0EAOgDCASADQdAHaiIGIAtBxAFqQSj8CgAAIANB6AVqIgogBhCeBSADQYAGaiAEQawFaiAKEIcXIAtB3AFqIANBmAZqKAIANgIAIAtB1AFqIANBkAZqKQIANwIAIAtBzAFqIANBiAZqKQIANwIAIAsgAykCgAY3AsQBCyADQdAHaiALQcQBaiIEIAIQpQkgAygC0AciBkGQgICAeEcNAUEEIQQMBAsgA0EnOgC4CAwECyADQcgFaiIKIANB5AdqKAIANgIAIANBwAVqIhAgA0HcB2opAgA3AwAgAyADKQLUBzcDuAUgBBCTHiAGQY+AgIB4RwRAIANB5AVqIAooAgA2AgAgA0HcBWogECkDADcCACADIAMpA7gFNwLUBSADIAY2AtAFIANBuAhqIANB0AVqELUSDAQLIANB6AVqIAsoArwBIgYpA9gEIAYoAuAEEJ8PIAsgC0HQAWo2AsgBIAtB4AFqIANB+AVqKQMANwMAIAtB2AFqIANB8AVqKQMANwMAIAsgAykD6AU3A9ABQQAhBAwBCyADQQ46ALgIDAILA0AgBEUEQCALQQA6AMQBIAtBADoAzQIgCyALQegBajYC1AIgCyALQcQBajYC0AIgCyALKAK8ATYCyAIgCyALQcgBajYC6AFBASEEDAELIANB0AdqIAtB0AJqIAIQ9AEgAy0A0AciBkE0RgRAQQUhBAwCCyADQegGaiADQdAHakEBckHnAPwKAAAgC0HwAWoQoBsCQAJAAkACQEEBIAZBMWsgBkEwTRtB/wFxQQFrDgICAAELIANBADYC4AcgA0EBNgLUByADQbDEwgA2AtAHIANCBDcC2AcgA0HQB2pBjMnCABD3GAALIANBKzoAgAYMAQsgBkEwRwRAIAMgBjoAgAYgA0GABmpBAXIgA0HoBmpB5wD8CgAADAELIANB6AdqIANBhwdqKQAANwMAIANB4AdqIANB/wZqKQAANwMAIANB2AdqIANB9wZqKQAANwMAIAMgAykA7wYiKjcD0AcgKqdB/wFxQQRHBEAgA0GgBmogA0HvBmoiBkEYaikAADcDACADQZgGaiAGQRBqKQAANwMAIANBkAZqIAZBCGopAAA3AwAgA0EwOgCABiADIAYpAAA3A4gGDAELIANB0AdqEOkVQQAhBAwBCwsCQCALLQDBAUUNACADQdAHaiIGIAsoArwBEP4GIAMtANAHIgRBMEYNACADQbgIakEBciAGQQFyQecA/AoAACADIAQ6ALgIIANBgAZqEPgaIAtB0AFqEPQWDAILIANBuAhqIANBgAZqQegA/AoAACALQdABahD0FgwCCyAJIAQ6AAAMAgsgCy0AwgEEQCALQcQBahChCAsLIAtBADoAwgEgAy0AuQghBiADLQC4CCEEIANB2AJqIhAgA0G4CGpBAnJBJvwKAAAgA0GYAmoiESADQeAIakHAAPwKAAAgCUEBOgAAIARBMUYNACADQcADaiIIIBBBJvwKAAAgA0GAA2oiECARQcAA/AoAACAOEKYRIARBMEYNASADQegDaiAIQSb8CgAAIANBjgRqIBBBwAD8CgAADAILIAhBAzoAACAPQTE6AABBBAwfCyADQZACaiADQd4DaikAADcDACADQYgCaiADQdYDaikAADcDACADQYACaiADQc4DaikAADcDACADIAMpAMYDIio3A/gBAkACQAJAICqnQf8BcUEFaw4CAQACCyADQcIIaiADQdIDaigAADYAACADIAMpAMoDNwC6CCADIAMpALgINwPoAyADIANBvghqKQAANwHuA0EPIQQMAgsgAy0A+QEhBiADQfgBahDpFUEwIQQMAQsgA0HQCGogA0HGA2oiCEEYaikAADcDACADQcgIaiAIQRBqKQAANwMAIANBwAhqIAhBCGopAAA3AwAgAyAIKQAANwO4CCADQYAGaiADQbgIaiIIEOADIANB2gdqIANBiAZqKAIANgAAIAMgAykCgAY3ANIHIAMgAykA0Ac3A+gDIAMgA0HWB2opAAA3Ae4DIAgQ6RVBJiEECyADQdAHaiIIIANB6ANqQeYA/AoAACALQQE6APwDIAsgBjoAISALIAQ6ACAgC0EiaiAIQeYA/AoAACAOEJQeIAstACBBMEYNASALIAs1AogBNwOQAQsgA0G4CGogC0GQAWoQ3gkgAy0AuAgiBEExRw0BIA9BMToAAEEFDBwLIAtBAToAjAEgCyALLQAhOgCNAQwBCyADQd4BaiIQIAMtALsIOgAAIANB2gFqIhEgA0HDCGotAAA6AAAgA0HWAWoiFiADQcsIai0AADoAACADIAMvALkIOwHcASADIAMvAMEIOwHYASADIAMvAMkIOwHUASADKAK8CCEOIAMtAMAIIQggAygCxAghBiADLQDICCEJIAMoAswIIQogA0HgAmoiEyADQdgIaikDADcDACADIAMpA9AINwPYAiADKQPgCCEqIANB0QRqIhUgA0HoCGpBOPwKAAAgBEEwRwRAIANBggNqIBAtAAA6AAAgA0HCA2ogES0AADoAACADQYYKaiAWLQAAOgAAIANB8AZqIBMpAwA3AwAgAyADLwHcATsBgAMgAyADLwHYATsBwAMgAyADLwHUATsBhAogAyADKQPYAjcD6AYgA0G4CGogFUE4/AoAACAMEKQeDBoLIAtBADoAjAELIAwQpB4gCyALLQCMASIEIAstAI0BIg5BAktxIgg6AI4BIA5BBEshBiAEIA5BA0txIQ4CQCAIDQACQEHYyuYAKAIAQQNLDQBBqMTmABDuGkH/AXEiCEUNAEEAIQlBqMTmACgCACAIENUVRQ0AQajE5gAoAgAiCEEcaiEKIAgoAiAiDARAIAgoAighGCAIKAIkIRAgCCgCHCEJIANBADYCyAggAyAYNgLECCADIBA2AsAIIAMgDDYCvAgLIAMgCTYCuAggA0GABmoiDCADQbgIaiIYQaDFwgAQqRQgA0HAwMIANgKIAyADQQE2ArwIIANB+MXCADYCuAggA0IENwLACCADIBg2AoQDIAMgDDYCgAMgA0EANgLICCADQZgCaiAKIANBgANqEP0dIANByANqIANBoAJqKAIANgIAIAMgAykCmAI3A8ADQajE5gAoAgAgA0HAA2oiDBD3F0Hg0OYALQAADQFB0NDmACgCAEECSQ0BIANBAjYC6AMgA0GoxOYAKAIAIggpAhQ3AuwDIANB8ABqEMYZIAMoAnAiCSADQegDaiADKAJ0IgooAgwRAABFDQEgA0HwBmogA0HwA2ooAgA2AgAgAyADKQLoAzcD6AYgCCAJIAogA0HoBmogDBD3CQwBC0Hg0OYALQAADQBB0NDmACgCAEECSQ0AIANBAjYC4AEgA0GoxOYAKAIAIgkpAhQ3AuQBIANB6ABqEMYZIAMoAmgiCiADQeABaiADKAJsIgwoAgwRAABFDQBBqMTmACgCACIIQRxqIRAgCCgCICIRBEAgCCgCKCEWIAgoAiQhEyAIKAIcIRggA0EANgLICCADIBY2AsQIIAMgEzYCwAggAyARNgK8CAsgAyAYNgK4CCADQYAGaiIYIANBuAhqIhFBoMXCABCpFCADQcDAwgA2AvADIANBADYCyAggA0EBNgK8CCADQfjFwgA2ArgIIANCBDcCwAggAyARNgLsAyADIBg2AugDIANBgANqIhggECADQegDahD9HSADQfAGaiADQegBaigCADYCACADIAMpAuABNwPoBiAJIAogDCADQegGaiAYEPcJCyAEIAZxIQQCQCAODQACQEHYyuYAKAIAQQNLDQBBzMTmABDuGkH/AXEiCEUNAEEAIQZBzMTmACgCACAIENUVRQ0AQczE5gAoAgAiCEEcaiEJIAgoAiAiCgRAIAgoAighDCAIKAIkIRggCCgCHCEGIANBADYCyAggAyAMNgLECCADIBg2AsAIIAMgCjYCvAgLIAMgBjYCuAggA0GABmoiDCADQbgIaiIYQYDGwgAQqRQgA0HAwMIANgKIAyADQQE2ArwIIANB2MbCADYCuAgg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NgK4CCADQYAGaiIHIANBuAhqIhFBjMDCABCpFCADQcDAwgA2AvADIANBADYCyAggA0EBNgK8CCADQbjAwgA2ArgIIANCBDcCwAggAyARNgLsAyADIAc2AugDIANBgANqIgcgECADQegDahD9HSADQfAGaiADQdgFaigCADYCACADIAMpAtAFNwPoBiAGIAkgCiADQegGaiAHEPcJCyALQQA6ALwEIAsgBDYCuAQgC0GYAWohByALQbwEaiEQIA5BAXENAgsCQAJAQdjK5gAoAgBBAUsNAEHwweYAEO4aQf8BcSIORQ0AQQAhCEHwweYAKAIAIA4Q1RVFDQBB8MHmACgCACIOQRxqIQYgDigCICIJBEAgDigCKCEKIA4oAiQhESAOKAIcIQggA0EANgLICCADIAo2AsQIIAMgETYCwAggAyAJNgK8CAsgAyAINgK4CCADQYAGaiIRIANBuAhqIhZB4MDCABCpFCADQcDAwgA2AqACIANBATYCvAggA0GIwcIANgK4CCADQgQ3AsAIIAMgFjYCnAIgAyARNgKYAiADQQA2AsgIIANB+AFqIAYgA0GYAmoQ/R0gA0HwBWogA0GAAmooAgA2AgAgAyADKQL4ATcD6AVB8MHmACgCACADQegFaiIREPcXQeDQ5gAtAAANAUHQ0OYAKAIAQQRJDQEgA0EENgKAAyADQfDB5gAoAgAiDikCFDcChAMgA0EwahDGGSADKAIwIgggA0GAA2ogAygCNCIGKAIMEQAARQ0BIANB8ANqIANBiANqKAIANgIAIAMgAykCgAM3A+gDIA4gCCAGIANB6ANqIBEQ9wkMAQtB4NDmAC0AAA0AQdDQ5gAoAgBBBEkNACADQQQ2AsADIANB8MHmACgCACIIKQIUNwLEAyADQShqEMYZIAMoAigiBiADQcADaiADKAIsIgkoAgwRAABFDQBB8MHmACgCACIOQRxqIRFBACEKIA4oAiAiFgRAIA4oAighEyAOKAIkIRUgDigCHCEKIANBADYCyAggAyATNgLECCADIBU2AsAIIAMgFjYCvAgLIAMgCjYCuAggA0GABmoiFiADQbgIaiITQeDAwgAQqRQgA0HAwMIANgKIAyADQQA2AsgIIANBATYCvAggA0GIwcIANgK4CCADQgQ3AsAIIAMgEzYChAMgAyAWNgKAAyADQZgCaiIWIBEgA0GAA2oQ/R0gA0HwA2ogA0HIA2ooAgA2AgAgAyADKQLAAzcD6AMgCCAGIAkgA0HoA2ogFhD3CQsgBCgCgAVFBEBBGiEEDAkLIANB6AZqIgYgBCgClAVBCGoQzw0gA0G4CGogBiAEKAKABUEIaiAELQDQBBC5BiADKAK4CEEBRgRAIANB+gFqIgQgA0HDCGotAAA6AAAgA0GGCmoiDiADQcsIai0AADoAACADQYgGaiIRIANB2AhqKQMANwMAIAMgAy8AwQg7AfgBIAMgAy8AyQg7AYQKIAMgAykD0Ag3A4AGIAMtAMAIIQggAygCxAghBiADLQDICCEJIAMoAswIIQogAykD4AghKiADQY4KaiAELQAAOgAAIANBigpqIA4tAAA6AAAgA0HwA2ogESkDADcDACADIAMvAfgBOwGMCiADIAMvAYQKOwGICiADIAMpA4AGNwPoA0ERIQQMCQsgA0H6AWoiBiADQcMIai0AADoAACADQYYKaiIJIANBywhqLQAAOgAAIANBiAZqIgggA0HYCGopAwA3AwAgAyADLwDBCDsB+AEgAyADLwDJCDsBhAogAyADKQPQCDcDgAYgAygCzAghDiADKALECCEKIAMtAMgIIREgAygCvAghFiADLQDACCETIAMoAuAIIRUgA0GaAmoiFyAGLQAAOgAAIANB6gVqIgYgCS0AADoAACADQYgDaiIJIAgpAwA3AwAgAyADLwH4ATsBmAIgAyADLwGECjsB6AUgAyADKQOABjcDgAMgCyATOgCcASALIBY2ApgBIAsgEToApAEgCyAKNgKgASALIAMvAZgCOwCdASALQZ8BaiAXLQAAOgAAIAsgDjYCqAEgCyADLwHoBTsApQEgC0GnAWogBi0AADoAACALIAMpA4ADNwKsASALQbQBaiAJKQMANwIAIAtBADoAsAQgCyAENgKoBCALIBU2ArwBCyADQbgIaiAHIAIQggIgAy0AuAgiBEExRg0CIANB+gFqIAMtALsIOgAAIANBjgpqIANBwwhqLQAAOgAAIANBigpqIANBywhqLQAAOgAAIAMgAy8AuQg7AfgBIAMgAy8AwQg7AYwKIAMgAy8AyQg7AYgKIAMoArwIIQ4gAy0AwAghCCADKALECCEGIAMtAMgIIQkgAygCzAghCiADQfADaiADQdgIaikDADcDACADIAMpA9AINwPoAyADKQPgCCEqIANBgAZqIANB6AhqQTj8CgAAIAcQ8RoMBwsCQAJAQdjK5gAoAgBBAUsNAEH8weYAEO4aQf8BcSIORQ0AQQAhCEH8weYAKAIAIA4Q1RVFDQBB/MHmACgCACIOQRxqIQYgDigCICIJBEAgDigCKCEKIA4oAiQhESAOKAIcIQggA0EANgLICCADIAo2AsQIIAMgETYCwAggAyAJNgK8CAsgAyAINgK4CCADQYAGaiIOIANBuAhqIhFBoMHCABCpFCADQcDAwgA2AogDIANBATYCvAggA0HIwcIANgK4CCADQgQ3AsAIIAMgETYChAMgAyAONgKAAyADQQA2AsgIIANBwANqIAYgA0GAA2oQ/R0gA0GAAmogA0HIA2ooAgA2AgAgAyADKQLAAzcD+AFB/MHmACgCACADQfgBaiIOEPcXQeDQ5gAtAAANAUHQ0OYAKAIAQQRJDQEgA0EENgLoAyADQfzB5gAoAgAiESkCFDcC7AMgA0EgahDGGSADKAIgIgggA0HoA2ogAygCJCIGKAIMEQAARQ0BIANB8AZqIANB8ANqKAIANgIAIAMgAykC6AM3A+gGIBEgCCAGIANB6AZqIA4Q9wkMAQtB4NDmAC0AAA0AQdDQ5gAoAgBBBEkNACADQQQ2ApgCIANB/MHmACgCACIIKQIUNwKcAiADQRhqEMYZIAMoAhgiBiADQZgCaiADKAIcIgkoAgwRAABFDQBB/MHmACgCACIOQRxqIRFBACEKIA4oAiAiFgRAIA4oAighEyAOKAIkIRUgDigCHCEKIANBADYCyAggAyATNgLECCADIBU2AsAIIAMgFjYCvAgLIAMgCjYCuAggA0GABmoiDiADQbgIaiIWQaDBwgAQqRQgA0HAwMIANgLwAyADQQA2AsgIIANBATYCvAggA0HIwcIANgK4CCADQgQ3AsAIIAMgFjYC7AMgAyAONgLoAyADQYADaiIOIBEgA0HoA2oQ/R0gA0HwBmogA0GgAmooAgA2AgAgAyADKQKYAjcD6AYgCCAGIAkgA0HoBmogDhD3CQsgBCgCgAUiDkUEQEEaIQQMBwsgA0G4CGogDkEIaiAEKAKUBUEIahDOCCADKAK4CEEBRgRAIANB+gFqIgQgA0HDCGotAAA6AAAgA0HqBWoiDiADQcsIai0AADoAACADQYgGaiIRIANB2AhqKQMANwMAIAMgAy8AwQg7AfgBIAMgAy8AyQg7AegFIAMgAykD0Ag3A4AGIAMtAMAIIQggAygCxAghBiADLQDICCEJIAMoAswIIQogAykD4AghKiADQY4KaiAELQAAOgAAIANBigpqIA4tAAA6AAAgA0HwA2ogESkDADcDACADIAMvAfgBOwGMCiADIAMvAegFOwGICiADIAMpA4AGNwPoA0ERIQQMBwsgA0H6AWoiBiADQcMIai0AADoAACADQeoFaiIJIANBywhqLQAAOgAAIANBiAZqIgggA0HYCGopAwA3AwAgAyADLwDBCDsB+AEgAyADLwDJCDsB6AUgAyADKQPQCDcDgAYgAygCzAghDiADKALECCEKIAMtAMgIIREgAygCvAghFiADLQDACCETIAMoAuAIIRUgA0GCA2oiFyAGLQAAOgAAIANBwgNqIgYgCS0AADoAACADQfAGaiIJIAgpAwA3AwAgAyADLwH4ATsBgAMgAyADLwHoBTsBwAMgAyADKQOABjcD6AYgCyATOgCcASALIBY2ApgBIAsgEToApAEgCyAKNgKgASALIAMvAYADOwCdASALQZ8BaiAXLQAAOgAAIAsgDjYCqAEgCyADLwHAAzsApQEgC0GnAWogBi0AADoAACALIAMpA+gGNwKsASALQbQBaiAJKQMANwIAIAtBADoAsAQgCyAENgKoBCALIBU2ArwBCyADQbgIaiAHIAIQggIgAy0AuAgiBEExRg0DIANB+gFqIAMtALsIOgAAIANBjgpqIANBwwhqLQAAOgAAIANBigpqIANBywhqLQAAOgAAIAMgAy8AuQg7AfgBIAMgAy8AwQg7AYwKIAMgAy8AyQg7AYgKIAMoArwIIQ4gAy0AwAghCCADKALECCEGIAMtAMgIIQkgAygCzAghCiADQfADaiADQdgIaikDADcDACADIAMpA9AINwPoAyADKQPgCCEqIANBgAZqIANB6AhqQTj8CgAAIAcQ8RoMBQsgEEEDOgAAQQQMAwtB4NDmAC0AAA0AQdDQ5gAoAgBBBEkNACADQQQ2ApgCIANBwMTmACgCACIEKQIUNwKcAiADEMYZIAMoAgAiDCADQZgCaiADKAIEIggoAgwRAABFDQBBwMTmACgCACIOQRxqIQlBACEGIA4oAiAiCgRAIA4oAighGCAOKAIkIRAgDigCHCEGIANBADYCyAggAyAYNgLECCADIBA2AsAIIAMgCjYCvAgLIAMgBjYCuAggA0GABmoiDiADQbgIaiIYQcTHwgAQqRQgA0HAwMIANgLwAyADQQA2AsgIIANBATYCvAggA0Hsx8IANgK4CCADQgQ3AsAIIAMgGDYC7AMgAyAONgLoAyADQYADaiIOIAkgA0HoA2oQ/R0gA0HwBmogA0GgAmooAgA2AgAgAyADKQKYAjcD6AYgBCAMIAggA0HoBmogDhD3CQsgCygCiAEiBCgCgAUiDkUEQEEqIQQMDwsgDiAOKAIAIghBAWo2AgAgCEEASA0MIAQoAoAFLQAIQQFGBH8gCy0AjgEFQQALQQFxDAsLIBBBAzoAAEEDCyEGIBggBjoAACAPQTE6AABBBgwNCyAQQQE6AAAgBxCWHgsgGEEBOgAAIAwQzRkgBEEwRwRAIANBggNqIANB+gFqLQAAOgAAIANBwgNqIANBjgpqLQAAOgAAIANBhgpqIANBigpqLQAAOgAAIANB8AZqIANB8ANqKQMANwMAIAMgAy8B+AE7AYADIAMgAy8BjAo7AcADIAMgAy8BiAo7AYQKIAMgAykD6AM3A+gGIANBuAhqIANBgAZqQTj8CgAADAsLIAsoAogBIgQtANYFQQFHBEBBKSEEDAsLIAQoAoAFIg4EQEEAIQQgDi0ACEEBRgRAIAstAI4BIQQLIA4gDigCACIIQQFqNgIAIAhBAEgNCSAEQQFxDAgLQfTHwgAQ0iAACyAOQQJHBEBBJyEEDAULIAQoApQFIQYgA0G4CGoiCSAEQcAB/AoAACADQRBqIAtBmAFqIARBrAVqIAZBCGogCSAELQDQBCAIQQFxEIMJIAsgAykDEDcCnAELIANBuAhqIAtBnAFqIgQgAhC1HkEDIAMtALgIIglBAkYNARogA0GCCmogAy0Auwg6AAAgA0H+CWoiECADQcMIai0AADoAACADQYgDaiIKIANB0AhqKQIANwMAIANBkANqIgcgA0HYCGovAQA7AQAgAyADLwC5CDsBgAogAyADLwDBCDsB/AkgAyADKQLICDcDgAMgAygCvAghDiADLQDACCEIIAMoAsQIIQYgBBD+FSAJQQFxBEAgA0HqBWogEC0AADoAACADIAMvAfwJOwHoBUEoIQQMBAsgC0EBOgCYASAEIAMvAYAKOwAAIAsgCDoAowEgCyAONgCfASALIAMvAfwJOwCkASALIAY2AKcBIAsgAykDgAM3AKsBIARBAmogA0GCCmotAAA6AAAgC0GmAWogA0H+CWotAAA6AAAgC0GzAWogCikDADcAACALQbsBaiAHLwEAOwAAIAtBADoAnQIgCyALKAKQATYCmAILIANBuAhqIAtBwAFqIhAgAhCPAiADLQC4CCIEQTFHDQFBBAshBiAYIAY6AAAgD0ExOgAAQQcMBwsgA0GOCmoiByADLQC7CDoAACADQYoKaiIRIANBwwhqLQAAOgAAIANBhgpqIhYgA0HLCGotAAA6AAAgAyADLwC5CDsBjAogAyADLwDBCDsBiAogAyADLwDJCDsBhAogAygCvAghDiADLQDACCEIIAMoAsQIIQYgAy0AyAghCSADKALMCCEKIANByANqIhMgA0HYCGopAwA3AwAgAyADKQPQCDcDwAMgAykD4AghKiADQegGaiIVIANB6AhqQTj8CgAAIBAQoBsCQCAEQTBHBEAgA0H6AWogBy0AADoAACADQeoFaiARLQAAOgAAIANB0gVqIBYtAAA6AAAgA0GgAmogEykDADcDACADIAMvAYwKOwH4ASADIAMvAYgKOwHoBSADIAMvAYQKOwHQBSADIAMpA8ADNwOYAiADQYAGaiAVQTj8CgAADAELIANB8wNqIANBhgpqLQAAOgAAIANBgARqIANByANqKQMANwMAIAMgCDoA6AMgAyADLwGICjsA6QMgAyAJOgDwAyADIAY2AuwDIAMgAy8BhAo7APEDIAMgCjYC9AMgAyADKQPAAzcD+AMgAyADQYoKai0AADoA6wMCQAJAIAhBAUcEQCAIQQZGDQEgA0HDCGogA0GGCmotAAA6AAAgA0HQCGogA0HIA2opAwA3AwAgAyAIOgC4CCADIAMvAYgKOwC5CCADIAk6AMAIIAMgBjYCvAggAyADLwGECjsAwQggAyAKNgLECCADIAMpA8ADNwPICCADIANBigpqLQAAOgC7CCADQYAGaiADQbgIaiIEEOADIANB6gVqIANBhwZqLQAAOgAAIAMgAy8AhQY7AegFIAMtAIQGIQggAygCgAYhDiADKAKIBiEGIAQQ6RVBJiEEDAMLIAMtAOsDIQggAy0A6gMhDiADLQDpAyEQIANB6ANqEOkVIANBuAhqIAwoAgAgECAOEOABIAMtALgIIgRBMEcEQCADQfoBaiADLQC7CDoAACADQeoFaiADQcMIai0AADoAACADQdIFaiADQcsIai0AADoAACADIAMvALkIOwH4ASADIAMvAMEIOwHoBSADIAMvAMkIOwHQBSADKAK8CCEOIAMtAMAIIQggAygCxAghBiADLQDICCEJIAMoAswIIQogA0GgAmogA0HYCGopAwA3AwAgAyADKQPQCDcDmAIgAykD4AghKiADQYAGaiADQegIakE4/AoAAAwDCyAMKAIAIAg6ANYFIAwoAgAiBC0A1gVFDQEgC0EAOgCYASADQbgIaiIGIAtBnAFqQSH8CgAAQSxBBBCfGyIEQoGAgIAQNwIAIARBCGogBkEh/AoAAAJAIAsoApABIgYoAoAFIghFDQAgCCAIKAIAIglBAWs2AgAgCUEBRw0AIAZBgAVqEP4RCyAMKAIAIAQ2AoAFIAwoAgAhBAwBCyADQeoFaiADQYYKai0AADoAACADIAMvAYQKOwHoBUEPIQQgBiEOIAkhCCAKIQYMAQsgBCAOOgDVBSAEIBA6ANQFIAstAJgBBEAgC0GcAWoQrhoLIAtBADoAmAFBMCEEDAILIAtBnAFqEK4aCyALQQA6AJgBCyAYQQE6AAAgDBD/FSAEQTBHBEAgA0GCA2ogA0H6AWotAAA6AAAgA0HCA2ogA0HqBWotAAA6AAAgA0GGCmogA0HSBWotAAA6AAAgA0HwBmogA0GgAmopAwA3AwAgAyADLwH4ATsBgAMgAyADLwHoBTsBwAMgAyADLwHQBTsBhAogAyADKQOYAjcD6AYgA0G4CGogA0GABmpBOPwKAAAMBAsgCygCiAEoAoAFIg5FDQIgDiAOKAIAIghBAWo2AgAgCEEASA0BQQALIQhBMCEEDAILAAtBhMjCABDSIAALIA8gBDoAACAPIAMvAYADOwABIA8gCDoACCAPIA42AgQgDyADLwHAAzsACSAPIAk6ABAgDyAGNgIMIA8gAy8BhAo7ABEgDyAKNgIUIA9BA2ogA0GCA2otAAA6AAAgD0ELaiADQcIDai0AADoAACAPQRNqIANBhgpqLQAAOgAAIA8gKjcDKCAPQSBqIANB8AZqKQMANwAAIA8gAykD6AY3ABggD0EwaiADQbgIakE4/AoAAEEBCzoAjwEgA0H8AGoQ3g0gA0GQCmokACAFLQCgKCIDQTFHDQpBAwwbCyABQQA6AMccIAEgCjYCwBwgAUHHHGohDAsgASgCwBwiCigCqAUiCEECSSAIQQZxQQJGcg0BIAEgCq03A8gcCyAFQaAoaiABQcgcahDdCSAFLQCgKCIDQTFGBEBBAyECDBgLIANBMEcEQCAFLwChKCAFLQCjKEEQdHIhICAFLwCxKCAFQbMoai0AAEEQdHIhGCAFLwCpKCAFQasoai0AAEEQdHIhCSAFKAKEKSEjIAUoAoApISYgBSgC/CghEiAFKAL4KCEfIAUoAvQoIRMgBSgC8CghFiAFKALsKCERIAUoAugoIRkgBSgC5CghISAFKALgKCEcIAUoAtwoISQgBSgC2CghHiAFKALUKCEdIAUoAtAoIRogBSgCzCghFSAFKALIKCEXIAUoAsQoISIgBSgCwCghBCAFKAK8KCEQIAUoArgoIQcgBSgCtCghCiAFLQCwKCEPIAUoAqwoIQYgBS0AqCghDiAFKAKkKCEIDB8LIAEoAsAcIQoLIAFBADoAtB8gASAKNgKwHyABQcgcaiEQIAFBtB9qIQgLIAooAqgFIgdBAkkgB0EGcUECRnJFBEBBDiEKDAILIAFBADoA+BwgASAKNgLwHCABQYeAgIB4NgLIHAsgBUGgKGoiAyAQIAIQqQIgBS0AoCgiCkExRg0FIAUtAKEoIQcgBUGAAmoiCCADQQJyQSb8CgAAIAVBwB9qIgMgBUHIKGpBwAD8CgAAIBAQphEgCkEwRwRAIAVB4BRqIAhBJvwKAAAgBUGGFWogA0HAAPwKAAAMAQsgBUHIG2ogBUGeAmopAAA3AwAgBUHAG2ogBUGWAmopAAA3AwAgBUG4G2ogBUGOAmopAAA3AwAgBSAFKQCGAiIrNwOwGwJAAkACQCArp0H/AXFBBWsOAgEAAgsgBUGqKGogBUGSAmooAAA2AAAgBSAFKQCKAjcAoiggBSAFKQCgKDcD4BQgBSAFQaYoaikAADcB5hRBDyEKDAILIAUtALEbIQcgBUGwG2oQ6RVBMCEKDAELIAVBuChqIAVBhgJqIghBGGopAAA3AwAgBUGwKGogCEEQaikAADcDACAFQagoaiAIQQhqKQAANwMAIAUgCCkAADcDoCggBUHwHWogBUGgKGoiCBDgAyAFQeIeaiAFQfgdaigCADYAACAFIAUpAvAdNwDaHiAFIAUpANgeNwPgFCAFIAVB3h5qKQAANwHmFCAIEOkVQSYhCgsgBUHwI2oiCCAFQeAUakHmAPwKAAAgAUEBOgC0HyABIAc6ANkbIAEgCjoA2BsgAUHaG2ogCEHmAPwKAAAgEBCUHiABLQDYG0EwRg0BIAEgATUCwBw3A8gcCyAFQaAoaiABQcgcahDdCSAFLQCgKCIDQTFHDQFBBSECDBILIAFBAToAxBwgASABLQDZGzoAxRwMAwsgA0EwRwRAIAUvAKEoIAUtAKMoQRB0ciEgIAUvALEoIAVBsyhqLQAAQRB0ciEYIAUvAKkoIAVBqyhqLQAAQRB0ciEJIAUoAoQpISMgBSgCgCkhJiAFKAL8KCESIAUoAvgoIR8gBSgC9CghEyAFKALwKCEWIAUoAuwoIREgBSgC6CghGSAFKALkKCEhIAUoAuAoIRwgBSgC3CghJCAFKALYKCEeIAUoAtQoIR0gBSgC0CghGiAFKALMKCEVIAUoAsgoIRcgBSgCxCghIiAFKALAKCEEIAUoArwoIRAgBSgCuCghByAFKAK0KCEKIAUtALAoIQ8gBSgCrCghBiAFLQCoKCEOIAUoAqQoIQggCxCVHgwYCyABQQA6AMQcDAILIAVBqyhqLQAAIQwgBUGzKGotAAAhCSAFKAKEKSEjIAUoAoApISYgBSgC/CghEiAFKAL4KCEfIAUoAvQoIRMgBSgC8CghFiAFKALsKCERIAUoAugoIRkgBSgC5CghISAFKALgKCEcIAUoAtwoISQgBSgC2CghHiAFKALUKCEdIAUoAtAoIRogBSgCzCghFSAFKALIKCEXIAUoAsQoISIgBSgCwCghBCAFKAK8KCEQIAUoArgoIQcgBSgCtCghCiAFLQCwKCEPIAUoAqwoIQYgBS0AqCghDiAFKAKkKCEIIAUvAKkoIAUvALEoIAUvAKEoIAUtAKMoIAsQ4SBBEHRyISAgCUEQdHIhGCAMQRB0ciEJDBcLIAhBAzoAAEEEIQIMDgsgCxCVHiABIAEtAMQcIgogAS0AxRwiA0ECS3EiBzoAxhwgA0EESyEIIAogA0EDS3EhEAJAIAcNAAJAQdjK5gAoAgBBA0sNAEGoxOYAEO4aQf8BcSIHRQ0AQajE5gAoAgAgBxDVFUUNACAFQQA2AvAUIAVBqMTmACgCACIHKAIgIh82AvQUIAUgBykCJDcC6BQgBSAfNgLkFCAFIAcoAhw2AuAUIAVBoChqIgMgBUHgFGoiDRCHESAFQcAfaiIbIANB/KHCABCoFCAFQfSGwgA2ArgbIAVBADYCsCggBUEBNgKkKCAFQdSiwgA2AqAoIAVCBDcCqCggBSADNgK0GyAFIBs2ArAbIAVB2B5qIAdBHGogBUGwG2oQ/R0gBUH4HWogBUHgHmooAgA2AgAgBSAFKQLYHjcD8B1BqMTmACgCACAFQfAdaiIDEPcXQeDQ5gAtAAANAUHQ0OYAKAIAQQJJDQEgBUECNgKAAiAFQajE5gAoAgAiBykCFDcChAIgBUGYAWoQxhkgBSgCmAEiHyAFQYACaiAFKAKcASITKAIMEQAARQ0BIAVB6BRqIAVBiAJqKAIANgIAIAUgBSkCgAI3A+AUIAcgHyATIA0gAxD3CQwBC0Hg0OYALQAADQBB0NDmACgCAEECSQ0AIAVBAjYC8BogBUGoxOYAKAIAIh8pAhQ3AvQaIAVBkAFqEMYZIAUoApABIhMgBUHwGmogBSgClAEiFigCDBEAAEUNACAFQQA2AvAUIAVBqMTmACgCACIHKAIgIhE2AvQUIAUgBykCJDcC6BQgBSARNgLkFCAFIAcoAhw2AuAUIAVBoChqIgMgBUHgFGoiDRCHESAFQcAfaiIbIANB/KHCABCoFCAFQfSGwgA2AogCIAVBADYCsCggBUEBNgKkKCAFQdSiwgA2AqAoIAVCBDcCqCggBSADNgKEAiAFIBs2AoACIAVBsBtqIgMgB0EcaiAFQYACahD9HSAFQegUaiAFQfgaaigCADYCACAFIAUpAvAaNwPgFCAfIBMgFiANIAMQ9wkLIAggCnEhAwJAIBANAAJAQdjK5gAoAgBBA0sNAEHMxOYAEO4aQf8BcSIHRQ0AQczE5gAoAgAgBxDVFUUNACAFQQA2AvAUIAVBzMTmACgCACIHKAIgIgg2AvQUIAUgBykCJDcC6BQgBSAINgLkFCAFIAcoAhw2AuAUIAVBoChqIgogBUHgFGoiDRCHESAFQcAfaiIbIApB3KLCABCoFCAFQfSGwgA2ArgbIAVBADYCsCggBUEBNgKkKCAFQbSjwgA2AqAoIAVCBDcCqCggBSAKNgK0GyAFIBs2ArAbIAVB2B5qIAdBHGogBUGwG2oQ/R0gBUH4HWogBUHgHmooAgA2AgAgBSAFKQLYHjcD8B1BzMTmACgCACAFQfAdaiIKEPcXQeDQ5gAtAAANAUHQ0OYAKAIAQQJJDQEgBUECNgKAAiAFQczE5gAoAgAiBykCFDcChAIgBUGIAWoQxhkgBSgCiAEiCCAFQYACaiAFKAKMASIfKAIMEQAARQ0BIAVB6BRqIAVBiAJqKAIANgIAIAUgBSkCgAI3A+AUIAcgCCAfIA0gChD3CQwBC0Hg0OYALQAADQBB0NDmACgCAEECSQ0AIAVBAjYCmBsgBUHMxOYAKAIAIggpAhQ3ApwbIAVBgAFqEMYZIAUoAoABIh8gBUGYG2ogBSgChAEiEygCDBEAAEUNACAFQQA2AvAUIAVBzMTmACgCACIHKAIgIhY2AvQUIAUgBykCJDcC6BQgBSAWNgLkFCAFIAcoAhw2AuAUIAVBoChqIgogBUHgFGoiDRCHESAFQcAfaiIbIApB3KLCABCoFCAFQfSGwgA2AogCIAVBADYCsCggBUEBNgKkKCAFQbSjwgA2AqAoIAVCBDcCqCggBSAKNgKEAiAFIBs2AoACIAVBsBtqIgogB0EcaiAFQYACahD9HSAFQegUaiAFQaAbaigCADYCACAFIAUpApgbNwPgFCAIIB8gEyANIAoQ9wkLAkAgAw0AAkBB2MrmACgCAEEDSw0AQbTE5gAQ7hpB/wFxIgpFDQBBtMTmACgCACAKENUVRQ0AIAVBADYC8BQgBUG0xOYAKAIAIgooAiAiBzYC9BQgBSAKKQIkNwLoFCAFIAc2AuQUIAUgCigCHDYC4BQgBUGgKGoiAyAFQeAUaiINEIcRIAVBwB9qIhsgA0G8o8IAEKgUIAVB9IbCADYCuBsgBUEANgKwKCAFQQE2AqQoIAVBmKTCADYCoCggBUIENwKoKCAFIAM2ArQbIAUgGzYCsBsgBUHYHmogCkEcaiAFQbAbahD9HSAFQfgdaiAFQeAeaigCADYCACAFIAUpAtgeNwPwHUG0xOYAKAIAIAVB8B1qIgoQ9xdB4NDmAC0AAA0BQdDQ5gAoAgBBAkkNASAFQQI2AoACIAVBtMTmACgCACIDKQIUNwKEAiAFQfgAahDGGSAFKAJ4IgcgBUGAAmogBSgCfCIIKAIMEQAARQ0BIAVB6BRqIAVBiAJqKAIANgIAIAUgBSkCgAI3A+AUIAMgByAIIA0gChD3CQwBC0Hg0OYALQAADQBB0NDmACgCAEECSQ0AIAVBAjYCoBwgBUG0xOYAKAIAIgcpAhQ3AqQcIAVB8ABqEMYZIAUoAnAiCCAFQaAcaiAFKAJ0Ih8oAgwRAABFDQAgBUEANgLwFCAFQbTE5gAoAgAiCigCICITNgL0FCAFIAopAiQ3AugUIAUgEzYC5BQgBSAKKAIcNgLgFCAFQaAoaiIDIAVB4BRqIg0QhxEgBUHAH2oiGyADQbyjwgAQqBQgBUH0hsIANgKIAiAFQQA2ArAoIAVBATYCpCggBUGYpMIANgKgKCAFQgQ3AqgoIAUgAzYChAIgBSAbNgKAAiAFQbAbaiIDIApBHGogBUGAAmoQ/R0gBUHoFGogBUGoHGooAgA2AgAgBSAFKQKgHDcD4BQgByAIIB8gDSADEPcJCyABKALAHCIKLQDWBQRAQdjK5gAoAgBBAUsNBEHAxOYAEO4aQf8BcSIIRQ0EQcDE5gAoAgAgCBDVFUUNBCAFQQA2AvAUIAVBwMTmACgCACIIKAIgIgo2AvQUIAUgCCkCJDcC6BQgBSAKNgLkFCAFIAgoAhw2AuAUIAVBoChqIhIgBUHgFGoiAxCHESAFQcAfaiINIBJBoKTCABCoFCAFQfSGwgA2ArgbIAVBADYCsCggBUEBNgKkKCAFQcikwgA2AqAoIAVCBDcCqCggBSASNgK0GyAFIA02ArAbIAVB2B5qIAhBHGogBUGwG2oQ/R0gBUH4HWogBUHgHmooAgA2AgAgBSAFKQLYHjcD8B1BwMTmACgCACAFQfAdaiIIEPcXQeDQ5gAtAAANBUHQ0OYAKAIAQQRJDQUgBUEENgKAAiAFQcDE5gAoAgAiEikCFDcChAIgBUHgAGoQxhkgBSgCYCIKIAVBgAJqIAUoAmQiECgCDBEAAEUNBSAFQegUaiAFQYgCaigCADYCACAFIAUpAoACNwPgFCASIAogECADIAgQ9wkMBQsgCigCgAUNASABQQA6ANEcIAEgCjYCzBwgASABLQDGHCIHOgDSHCABQcgcaiENIAFB0RxqIRsLIAEgCjYCyBwgAUEAOgDQHCAKKAKoBSIQQQJJIBBBBnFBAkZyRQRAQQ4hAwwQC0HQ0OYAKAIAQQNNDQUgBUHMp8IANgKgKCAFQgE3AqwoIAVBATYChAIgBUEBNgKkKCAFIAdBf3NBAXE6ANgeIAUgBUGAAmo2AqgoIAUgBUHYHmo2AoACIAVB1KfCADYC8BQgBUEaNgLsFCAFQeiawgA2AugUIAVBGjYC5BQgBUHomsIANgLgFCAFQaAoakEEIAVB4BRqEMMKIA0oAgAiCigCqAUhEAwFCyABIBA6AM0cIAFBADoAzBwgASAKNgLIHAsgBUGgKGogAUHIHGoiCSACEN8BIAUtAKAoIgNBMUcNAkEGIQIMCgtB4NDmAC0AAA0AQdDQ5gAoAgBBBEkNACAFQQQ2AtgcIAVBwMTmACgCACIKKQIUNwLcHCAFQdgAahDGGSAFKAJYIhAgBUHYHGogBSgCXCIHKAIMEQAARQ0AIAVBADYC8BQgBUHAxOYAKAIAIggoAiAiEjYC9BQgBSAIKQIkNwLoFCAFIBI2AuQUIAUgCCgCHDYC4BQgBUGgKGoiEiAFQeAUaiIDEIcRIAVBwB9qIg0gEkGgpMIAEKgUIAVB9IbCADYCiAIgBUEANgKwKCAFQQE2AqQoIAVByKTCADYCoCggBUIENwKoKCAFIBI2AoQCIAUgDTYCgAIgBUGwG2oiEiAIQRxqIAVBgAJqEP0dIAVB6BRqIAVB4BxqKAIANgIAIAUgBSkC2Bw3A+AUIAogECAHIAMgEhD3CQsgASgCwBwiEigCgAUiCEUEQEEqIQMMEAsgCCAIKAIAIg5BAWo2AgAgDkEASA0NQQAhCiASKAKABS0ACEEBRgRAIAEtAMYcIQoLIApBAXEMDAsgBUGrKGotAAAhDSAFQbMoai0AACEYIAUoAoQpISMgBSgCgCkhJiAFKAL8KCESIAUoAvgoIR8gBSgC9CghEyAFKALwKCEWIAUoAuwoIREgBSgC6CghGSAFKALkKCEhIAUoAuAoIRwgBSgC3CghJCAFKALYKCEeIAUoAtQoIR0gBSgC0CghGiAFKALMKCEVIAUoAsgoIRcgBSgCxCghIiAFKALAKCEEIAUoArwoIRAgBSgCuCghByAFKAK0KCEKIAUtALAoIQ8gBSgCrCghBiAFLQCoKCEOIAUoAqQoIQggBS8AqSghGyAFLwCxKCElIAUvAKEoISAgBS0AoyghJyAJEM0ZIANBMEcEQCAgICdBEHRyISAgJSAYQRB0ciEYIBsgDUEQdHIhCQwPCyABKALAHCISLQDWBUEBRwRAQSkhAwwPCyASKAKABSIIBEBBACESIAgtAAhBAUYEQCABLQDGHCESCyAIIAgoAgAiCkEBajYCACAKQQBIDQ0gEkEBcQwMC0HQpMIAENIgAAsgEEECRwRAQSchAwwFCyAKKAKUBSEGIAVBoChqIgkgCkHAAfwKAAAgBUHoAGogAUHQHGogCkGsBWogBkEIaiAJIAotANAEIAdBAXEQgwkgASAFKQNoNwLUHAsgBUGgKGogAUHUHGoiCiACELUeQQMgBS0AoCgiEEECRg0BGiAFQbIbaiAFLQCjKDoAACAFQcgfaiITIAVBuChqKQIANwMAIAVB0B9qIhYgBUHAKGovAQA7AQAgBSAFLwChKDsBsBsgBSAFKQKwKDcDwB8gBUGrKGotAAAhByAFKAKkKCEIIAUtAKgoIQ4gBSgCrCghBiAFLwCpKCEfIAoQ/hUgHyAHQRB0ciEJIBBBAXEEQEEoIQMMBAsgASAJOwHcHCABQQE6ANAcIAogBS8BsBs7AAAgASAGNgDfHCABIA46ANscIAEgCDYA1xwgASAFKQPAHzcA4xwgAUHeHGogCUEQdjoAACAKQQJqIAVBshtqLQAAOgAAIAFB6xxqIBMpAwA3AAAgAUHzHGogFi8BADsAACABQQA6ANUdIAEgASgCyBw2AtAdCyAFQaAoaiABQfgcaiIJIAIQjgIgBS0AoCgiA0ExRw0BQQQLIQEgGyABOgAAQQchAgwDCyAFQasoai0AACEgIAVBsyhqLQAAIRggBSgChCkhIyAFKAKAKSEmIAUoAvwoIRIgBSgC+CghHyAFKAL0KCETIAUoAvAoIRYgBSgC7CghESAFKALoKCEZIAUoAuQoISEgBSgC4CghHCAFKALcKCEkIAUoAtgoIR4gBSgC1CghHSAFKALQKCEaIAUoAswoIRUgBSgCyCghFyAFKALEKCEiIAUoAsAoIQQgBSgCvCghECAFKAK4KCEHIAUoArQoIQogBS0AsCghDyAFKAKsKCEGIAUtAKgoIQ4gBSgCpCghCCAFLwCpKCAFLwCxKCAFLwChKCEoIAUtAKMoISkgCRCgGyAYQRB0ciEYICBBEHRyIQkCQCADQTBHBEAgKCApQRB0ciEgDAELIAUgGDsA6RQgBUHrFGogGEEQdjoAACAFICI2AvwUIAUgBDYC+BQgBSAQNgL0FCAFIAc2AvAUIAUgCjYC7BQgBSAPOgDoFCAFIAY2AuQUIAUgDjoA4BQgBSAJOwDhFCAFIAlBEHY6AOMUIA5BAUcEQCAOQQZGBEBBDyEDIBghCSAGIQggDyEOIAohBgwCCyAFIBg7AKkoIAVBqyhqIBhBEHY6AAAgBSAiNgK8KCAFIAQ2ArgoIAUgEDYCtCggBSAHNgKwKCAFIAo2AqwoIAUgDzoAqCggBSAGNgKkKCAFIA46AKAoIAUgCTsAoSggBSAJQRB2OgCjKCAFQYACaiAFQaAoaiIDEOADIAUvAIUCIAVBhwJqLQAAQRB0ciEJIAUoAogCIQYgBS0AhAIhDiAFKAKAAiEIIAMQ6RVBJiEDDAELIAVB4BRqEOkVIAVBoChqIA0oAgAgCUEBcSAJQf///wdxIhJBCHYiChDgASAFLQCgKCIDQTBGDQIgBS8AoSggBS0AoyhBEHRyISAgBS8AsSggBUGzKGotAABBEHRyIRggBS8AqSggBUGrKGotAABBEHRyIQkgBSgChCkhIyAFKAKAKSEmIAUoAvwoIRIgBSgC+CghHyAFKAL0KCETIAUoAvAoIRYgBSgC7CghESAFKALoKCEZIAUoAuQoISEgBSgC4CghHCAFKALcKCEkIAUoAtgoIR4gBSgC1CghHSAFKALQKCEaIAUoAswoIRUgBSgCyCghFyAFKALEKCEiIAUoAsAoIQQgBSgCvCghECAFKAK4KCEHIAUoArQoIQogBS0AsCghDyAFKAKsKCEGIAUtAKgoIQ4gBSgCpCghCAsgAUHUHGoQrhoLIAFBADoA0BwMBAsgDSgCACASQRB2OgDWBSANKAIAIhItANYFRQ0CIAFBADoA0BwgBUGgKGoiEiABQdQcakEh/AoAACASEM4ZIRIgASgCyBxBgAVqEPAeIAEoAsgcIBI2AoAFIAEoAsgcIRIMAgsgDCACOgAAQQQLIQEgEiABOgAAIABBBDYCAEEFDBgLIBIgCjoA1QUgEiAJOgDUBSABLQDQHARAIAFB1BxqEK4aCyABQQA6ANAcQTAhAwsgG0EBOgAAIA0Q/xUgA0EwRw0DIAEoAsAcKAKABSIIRQ0CIAggCCgCACISQQFqNgIAIBJBAEgNAUEACyEOQTAhAwwCCwALQeCkwgAQ0iAACyAMQQE6AAAgCxCzFQsgAS0A1BsEQCAUEIUECyABQYACOwHUGyAUEJ4VIANBMEcEQCAPQf8BcSAYQQh0ciEUIA5B/wFxIAlBCHRyIQsgIEEIdCADciEDQQchDgwOCyABIA46ANQXIAEgCDYC0BcgDkEBcUUNBiABQQA6AMAeIAEgAUHgC2oiEjYCuB4gAUGwG2ohFyABQcAeaiELCyABIBI2ArweAkACQEHYyuYAKAIAQQJLDQBB7MPmABDuGkH/AXEiCkUNAEHsw+YAKAIAIAoQ1RVFDQAgBUEANgKAJCAFQezD5gAoAgAiCigCICISNgKEJCAFIAopAiQ3AvgjIAUgEjYC9CMgBSAKKAIcNgLwIyAFQaAoaiISIAVB8CNqIg8QhxEgBUHAH2oiGCASQfSewgAQqBQgBUH0hsIANgK4GyAFQQA2ArAoIAVBATYCpCggBUHEn8IANgKgKCAFQgQ3AqgoIAUgEjYCtBsgBSAYNgKwGyAFQfAdaiAKQRxqIAVBsBtqEP0dIAVB4BxqIAVB+B1qKAIANgIAIAUgBSkC8B03A9gcQezD5gAoAgAgBUHYHGoiChD3F0Hg0OYALQAADQFB0NDmACgCAEEDSQ0BIAVBAzYCgAIgBUHsw+YAKAIAIhIpAhQ3AoQCIAVB0ABqEMYZIAUoAlAiGCAFQYACaiAFKAJUIhAoAgwRAABFDQEgBUH4I2ogBUGIAmooAgA2AgAgBSAFKQKAAjcD8CMgEiAYIBAgDyAKEPcJDAELQeDQ5gAtAAANAEHQ0OYAKAIAQQNJDQAgBUEDNgLQHSAFQezD5gAoAgAiDykCFDcC1B0gBUHIAGoQxhkgBSgCSCIQIAVB0B1qIAUoAkwiBygCDBEAAEUNACAFQQA2AoAkIAVB7MPmACgCACIKKAIgIgg2AoQkIAUgCikCJDcC+CMgBSAINgL0IyAFIAooAhw2AvAjIAVBoChqIhIgBUHwI2oiGBCHESAFQcAfaiIVIBJB9J7CABCoFCAFQfSGwgA2AogCIAVBADYCsCggBUEBNgKkKCAFQcSfwgA2AqAoIAVCBDcCqCggBSASNgKEAiAFIBU2AoACIAVBsBtqIhIgCkEcaiAFQYACahD9HSAFQfgjaiAFQdgdaigCADYCACAFIAUpAtAdNwPwIyAPIBAgByAYIBIQ9wkLQQAhDyABKAK8HiIKKAKoBSISQQJJIBJBBnFBAkZyRQRAQQ4hFQwECyAKLQDWBUEBRwRAQSIhFQwECyAKKAKABSISRQRAQRohFQwECyASLQAIQQFHBEBBFCEVDAQLIBIoAgBBAUcEQEEVIRUMBAsgBUGgKGohBAJ/IwBBIGsiBiQAIBJBCGoiCS0AAEEBRgRAIAZBIGokACAJQQFqDAELIAZBADYCGCAGQQE2AgwgBkGQg8gANgIIIAZCBDcCECAGQQhqQZiDyAAQ9xgACyISIQkjAEHgAGsiBiQAIAYQnxY2AgQgBkEIakEQQZD1xwAQqAsgBkEEaiIKIAYoAgwiDyAGKAIQIhQQjh8gBiAJNgIsIAYgCUEgajYCOCAGIAlBEGoiCTYCNCAGIAk2AjAgBkEUaiIJIAZBLGoiDhDHIyAOIA8gFCAGKAIYIAYoAhxBIBDyCQJAAkAgBigCLEGAgICAeEcEQCAGQShqIAZBNGooAgAiDzYCACAGIAYpAiw3AyAgDiAGKAIkIA8QmwsgBi0ALEEBRg0BIAQgBikALTcAACAEQRhqIAZBxQBqKQAANwAAIARBEGogBkE9aikAADcAACAEQQhqIAZBNWopAAA3AAAgBEEoaiAGQRBqKAIANgIAIAQgBikCCDcCICAGQSBqEPMhIAkQphQgCRDzISAGKAIEIgkgCSgCAEEBayIJNgIAIAlFBEAgChDNGAsgBkHgAGokAAwCC0HI9McAQSEgBkHQAGpB4PXHAEGg9ccAEKkOAAsgBkHYAGogBkE4aigCADYCACAGIAYpAjA3A1BB6fTHAEElIAZB0ABqQdD1xwBBsPXHABCpDgALIBdBGGogBUG4KGopAgA3AgAgF0EQaiAFQbAoaikCADcCACAXQQhqIAVBqChqKQIANwIAIBcgBSkCoCg3AgAgBUHoHWoiDyAFQcgoaigCADYCACAFIAUpAsAoNwPgHSMAQTBrIgkkACMAQcAeayIGJAAgBhDVCyAGIBdBIBC3AiAGQYAPaiIOIAZBgA/8CgAAIAZBgB5qEMQZIAZBoB5qIA4QjBIgBkGYHmoiCiAGQbgeaikAADcDACAGQZAeaiIUIAZBsB5qKQAANwMAIAZBiB5qIgwgBkGoHmopAAA3AwAgBiAGKQCgHjcDgB4gBkGYEGoQ4B4gCUEEaiIOQRhqIAopAwA3AAAgDkEQaiAUKQMANwAAIA5BCGogDCkDADcAACAOIAYpA4AeNwAAIAZBwB5qJAAgCUEkakEgQQBBAUEBEKILIAkoAighDiAJKAIkQQFGBEAgDiAJKAIsQfCGyAAQ9hsACyAJKAIsIgYgCSkABDcAACAFQcABaiIKQSA2AgggCiAGNgIEIAogDjYCACAGQRhqIAlBHGopAAA3AAAgBkEQaiAJQRRqKQAANwAAIAZBCGogCUEMaikAADcAACAJQTBqJAAgBUH4I2ogDygCADYCACAFQYQkaiAFQcgBaigCADYCACAFIAUpA+AdNwPwIyAFIAUpAsABNwL8IyMAQTBrIgokACAKQSRqIhRB7MPDABDuECAKIBQ2AhggCkEYaiEGIwBBEGsiDiQAAkACQAJAAkAgBUHwI2oiGCIJKAIAIg9BH3UgD0H/////B2txQQFrDgIBAgALIA5BCGogBkGUx8MAQQpBAhDtBiAOKAIIIQYgDi0ADCIPQQNGDQIgDiAPOgAEIA4gBjYCACAOQZ7HwwBBCSAJELANIgYNAiAOQafHwwBBEiAJQQxqELANIgYNAiAOKAIAIA4tAAQQpBAhBgwCCyAOQQhqIAZBucfDAEEIQQIQ7QYgDigCCCEGIA4tAAwiD0EDRg0BIA4gDzoABCAOIAY2AgAgDkHBx8MAQQYgCUEEahCxDCIGDQEgDkHHx8MAQQUgCUEFahCxDCIGDQEgDigCACAOLQAEEKQQIQYMAQsgDkEIaiAGQczHwwBBCkEBEO0GIA4oAgghBiAOLQAMIg9BA0YNACAOIA86AAQgDiAGNgIAIAlBBGohDCMAQRBrIg8kAAJAIA5B1sfDAEEMEOMOIgYNACAPQQhqIhAiBiAOKAIAIgkQnSAgBhC8FSIGDQACfyAJIQYCQAJAAkACQAJAAkAgDC0AAEEBaw4FAQIDBAUACyAGQfTHwwBBAxCFFgwFCyAGQffHwwBBBhCFFgwECyAGQf3HwwBBBBCFFgwDCyAGQYHIwwBBBhCFFgwCCyAGQYfIwwBBBhCFFgwBCyAGQY3IwwBBBxCFFgsiBg0AIA9BBDoACCAQELwVIQYLIA9BEGokACAGDQAgDigCACAOLQAEEKQQIQYLIA5BEGokAAJAAkAgBiIJBEAgFBDzIQwBCyAKKAIoIQkgCigCJCIGQYCAgIB4Rg0AIAogCigCLCIMNgIUIAogCTYCECAKIAY2AgwgCkEYaiEPIwBBMGsiBiQAIAYQnxY2AgwgBkEgaiIOELgeIAZBDGoiECAOQRAQjh8gBkEYaiIHIAZBKGopAAA3AwAgBiAGKQAgNwMQIA5BEEEAQQFBARCiCyAGKAIkIQ4CQCAGKAIgQQFHBEAgBigCKCIUIAYpAxA3AAAgFEEIaiAHKQMANwAAIA9BEDYCCCAPIBQ2AgQgDyAONgIAIAYoAgwiDiAOKAIAQQFrIg42AgAgDkUEQCAQEM0YCyAGQTBqJAAMAQsgDiAGKAIoQdz2xwAQ9hsACyAKQSRqIQYgCigCICEUAkACQAJAIAooAhwiDgRAIBRBEEYNASAUDQILQQAhDgsgBiASIAkgDCAOEOcNDAELIAZBgICAgHg2AgAgBkECOgAECyAKLQAoIQYCfyAKKAIkIglBgICAgHhGBEAgBCAGOgAJIARBADoACCAPEPMhQQEMAQsgBCAKKAApNgANIARBEGogCkEsaigAADYAACAEQRxqIApBIGooAgA2AgAgBCAKKQIYNwIUIAQgBjoADCAEIAk2AgggBEGGgICAeDYCBEEACyEGIApBDGoQ8yEgBCAGNgIAIApBMGokAAwBCyAKIAk2AiRBsMzDAEErIApBJGpBoMzDAEGEx8MAEKkOAAsgBSgCoChBAUYEQCAFLwDBKCAFQcMoai0AAEEQdHIhDyAFLwCxKCAFQbMoai0AAEEQdHIhFCAFLwCpKCAFQasoai0AAEEQdHIhBCAFKQPIKCErIAUoAsQoISIgBS0AwCghDCAFKAK8KCEQIAUoArgoIQcgBSgCtCghCiAFLQCwKCEOIAUoAqwoIQYgBS0AqCghCSAYEKMbQREhFQwCCyAFLwDBKCAFQcMoai0AAEEQdHIhCSAFLwCxKCAFQbMoai0AAEEQdHIhCCAFLwCpKCAFQasoai0AAEEQdHIhDiAFKALIKCESIAUoAsQoIQMgBS0AwCghDyAFKAK8KCEUIAUoArgoIQwgBSgCtCghGCAFLQCwKCEQIAUoAqwoIQcgBS0AqCghESAFKAKkKCEWIAVB8CNqIgoQoxsCQAJAQdjK5gAoAgBBAksNAEH4w+YAEO4aQf8BcSIGRQ0AQfjD5gAoAgAgBhDVFUUNACAFQQA2AoAkIAVB+MPmACgCACIGKAIgIgQ2AoQkIAUgBikCJDcC+CMgBSAENgL0IyAFIAYoAhw2AvAjIAVBoChqIgQgChCHESAFQcAfaiITIARBzJ/CABCoFCAFQfSGwgA2ArgbIAVBADYCsCggBUEBNgKkKCAFQZygwgA2AqAoIAVCBDcCqCggBSAENgK0GyAFIBM2ArAbIAVB8B1qIAZBHGogBUGwG2oQ/R0gBUHgHGogBUH4HWooAgA2AgAgBSAFKQLwHTcD2BxB+MPmACgCACAFQdgcaiIGEPcXQeDQ5gAtAAANAUHQ0OYAKAIAQQNJDQEgBUEDNgKAAiAFQfjD5gAoAgAiBCkCFDcChAIgBUFAaxDGGSAFKAJAIhMgBUGAAmogBSgCRCIVKAIMEQAARQ0BIAVB+CNqIAVBiAJqKAIANgIAIAUgBSkCgAI3A/AjIAQgEyAVIAogBhD3CQwBC0Hg0OYALQAADQBB0NDmACgCAEEDSQ0AIAVBAzYC8BogBUH4w+YAKAIAIgQpAhQ3AvQaIAVBOGoQxhkgBSgCOCITIAVB8BpqIAUoAjwiFSgCDBEAAEUNACAFQQA2AoAkIAVB+MPmACgCACIGKAIgIgo2AoQkIAUgBikCJDcC+CMgBSAKNgL0IyAFIAYoAhw2AvAjIAVBoChqIgogBUHwI2oiGRCHESAFQcAfaiIcIApBzJ/CABCoFCAFQfSGwgA2AogCIAVBADYCsCggBUEBNgKkKCAFQZygwgA2AqAoIAVCBDcCqCggBSAKNgKEAiAFIBw2AoACIAVBsBtqIgogBkEcaiAFQYACahD9HSAFQfgjaiAFQfgaaigCADYCACAFIAUpAvAaNwPwIyAEIBMgFSAZIAoQ9wkLIAEgCTsA7RsgASAIOwDdGyABIA47ANUbIAFBADoAgBwgASASNgL0GyABIAM2AvAbIAEgDzoA7BsgASAUNgLoGyABIAw2AuQbIAEgGDYC4BsgASAQOgDcGyABIAc2AtgbIAEgEToA1BsgASAWNgLQGyABQe8baiAJQRB2OgAAIAFB3xtqIAhBEHY6AAAgAUHXG2ogDkEQdjoAACABIAEoArweNgL4GwsgBUGgKGogAUHQG2oiBiACEJQDIAUtAKAoIhVBMUYNASAFQasoai0AACEUIAVBsyhqLQAAIQkgBUHDKGotAAAhAyAFKAKEKSEjIAUoAoApISYgBSgC/CghEiAFKAL4KCEfIAUoAvQoIRMgBSgC8CghFiAFKALsKCERIAUoAugoIRkgBSgC5CghISAFKALgKCEcIAUoAtwoISQgBSgC2CghHiAFKALUKCEdIAUoAtAoIRogBSkDyCghKyAFKALEKCEiIAUtAMAoIQwgBSgCvCghECAFKAK4KCEHIAUoArQoIQogBS0AsCghDiAFKAKsKCEIIAUtAKgoIRggBSgCpCghDSAFLwCpKCAFLwCxKCAFLwDBKCAFLwChKCEbIAUtAKMoISUgBhC3EiADQRB0ciEPIAlBEHRyIQQgFEEQdHIhICAVQTBHBEAgGyAlQRB0ciEDIAQhFCAgIQQgGCEJIAghBiANIQgMAQtBDyEVIA4hCSAKIQYCfwJAAkAgGEECaw4FAQAAAAMACyAFIA87ALkoIAVBuyhqIA9BEHY6AAAgBSAEOwCpKCAFQasoaiAEQRB2OgAAIAUgIjYCvCggBSAMOgC4KCAFIBA2ArQoIAUgBzYCsCggBSAKNgKsKCAFIA46AKgoIAUgCDYCpCggBSAYOgCgKCAFICA7AKEoIAUgIEEQdjoAoyggBUHwI2ogBUGgKGoiGBDgAyAFLwD1IyAFQfcjai0AAEEQdHIhBCAFKAL4IyEGIAUtAPQjIQkgBSgC8CMhCCAYEOkVQSYMAQsgBSAEOwCdGyAFQZ8baiAEQRB2OgAAIAUgDzsAqRwgBUGrHGogD0EQdjoAACAFIA46AJwbIAUgCDYCmBsgBSAKNgKgGyAFIAw6AKgcIAUgEDYCpBwgBSAHNgKgHCAFQaAoaiENIAUoApwbISUgBSgCqBwhGyMAQSBrIhgkACAYQRRqISAjAEEgayIVJAAgFUETaiAQIBsQ/wwgFS0AFCEbAkAgFS0AE0EBRgRAICBBgICAgHg2AgAgICAbOgAEDAELIBVBD2ogFUEcaigAADYAACAVIBUpABU3AAggFSAbOgAHICAgFyAlIAogFUEHahC6DwsgFUEgaiQAIBgtABghFQJAIBgoAhQiIEGAgICAeEYEQCANIBU6AAEgDUEAOgAADAELIBhBEGoiGyAYQRxqKAAANgAAIBggGCgAGTYADSAYIBU6AAwgGCAgNgIIIBgoAgwhICAbKAIAIRsjAEEQayIVJAAgFUEANgIMIBUgGzYCCCAVICA2AgQgGEEUaiAVQQRqEK8NIBVBEGokAEEBISACQCAYLQAUQQFGBEAgDSAYKAIYNgIEDAELIA0gGC0AFToAAUEUISALIA0gIDoAACAYQQhqEPMhCyAYQSBqJAACQCAFLQCgKEEURgRAIAUtAKEoIRIgDRCdHiASDQECQAJAQdjK5gAoAgBBAksNAEGExOYAEO4aQf8BcSIGRQ0AQYTE5gAoAgAgBhDVFUUNACAFQQA2AoAkIAVBhMTmACgCACIGKAIgIgk2AoQkIAUgBikCJDcC+CMgBSAJNgL0IyAFIAYoAhw2AvAjIA0gBUHwI2oiCRCHESAFQcAfaiIIIA1BtKDCABCoFCAFQfSGwgA2ArgbIAVBADYCsCggBUEBNgKkKCAFQeigwgA2AqAoIAVCBDcCqCggBSANNgK0GyAFIAg2ArAbIAVB8B1qIAZBHGogBUGwG2oQ/R0gBUHgHGogBUH4HWooAgA2AgAgBSAFKQLwHTcD2BxBhMTmACgCACAFQdgcaiIGEPcXQeDQ5gAtAAANAUHQ0OYAKAIAQQNJDQEgBUEDNgKAAiAFQYTE5gAoAgAiCCkCFDcChAIgBUEwahDGGSAFKAIwIg4gBUGAAmogBSgCNCIKKAIMEQAARQ0BIAVB+CNqIAVBiAJqKAIANgIAIAUgBSkCgAI3A/AjIAggDiAKIAkgBhD3CQwBC0Hg0OYALQAADQBB0NDmACgCAEEDSQ0AIAVBAzYC2B4gBUGExOYAKAIAIggpAhQ3AtweIAVBKGoQxhkgBSgCKCIOIAVB2B5qIAUoAiwiCigCDBEAAEUNACAFQQA2AoAkIAVBhMTmACgCACIGKAIgIgk2AoQkIAUgBikCJDcC+CMgBSAJNgL0IyAFIAYoAhw2AvAjIAVBoChqIgkgBUHwI2oiBBCHESAFQcAfaiISIAlBtKDCABCoFCAFQfSGwgA2AogCIAVBADYCsCggBUEBNgKkKCAFQeigwgA2AqAoIAVCBDcCqCggBSAJNgKEAiAFIBI2AoACIAVBsBtqIgkgBkEcaiAFQYACahD9HSAFQfgjaiAFQeAeaigCADYCACAFIAUpAtgeNwPwIyAIIA4gCiAEIAkQ9wkLIAVB4BRqIBcQpxUgBUG5KGogF0EYaikAADcAACAFQbEoaiAXQRBqKQAANwAAIAVBqShqIBdBCGopAAA3AAAgBSAXKQAANwChKEEAIQ8gBUEAOgCgKCAFQaAoahDOGSESIAEoArweQYAFahDwHiABKAK8HiASNgKABSAFLwHwFCAFQfIUai0AAEEQdHIhFCAFLwHoFCAFQeoUai0AAEEQdHIhBCAFLwHgFCAFLQDiFEEQdHIhAyAFKADjFCEIIAUtAOcUIQkgBSgA6xQhBiAFLQDvFCEOIAUoAPMUIQogBSgA9xQhByAFKAD7FCEQIAUtAP8UIQwgBUGgHGoQ8yEgBUGYG2oQ8yFBMCEVDAULIAVBoChqEJ0eCyAFQaAcahDzISAFQZgbahDzIUETCyEVCyAXEKMYIA9BCHQhDwwBCyALQQM6AAAgAEEENgIAQQYMDQsgC0EBOgAAIBcQpBsgFUEwRwRAIA5B/wFxIBRBCHRyIRQgCUH/AXEgBEEIdHIhCyAPIAxB/wFxciEEIANBCHQgFXIhAyArQiCIpyEVICunIRcMBwsgASAUOwHIGyABIAQ7AcAbIAEgAzsBuBsgASAMOgDXGyABIBA2ANMbIAEgBzYAzxsgASAKNgDLGyABIA46AMcbIAEgBjYAwxsgASAJOgC/GyABIAg2ALsbIAFByhtqIBRBEHY6AAAgAUHCG2ogBEEQdjoAACABQbobaiADQRB2OgAAIAVBoChqIgggAUGgCmpBwAH8CgAAIAVBIGohCSABQeQXaiEOIAFBuBtqIQoCQEHgAUEEEIQhIgYEQCAGIAo2AgQgBiAONgIAIAZBCGogCEHAAfwKAAAgBkEAOgDcASAJQbTTwwA2AgQgCSAGNgIADAELQQRB4AEQ4SMACyABIAUpAyA3A7AbCyAFQaAoaiABQbAbaiIDIAIQtR4gBS0AoCgiDkHCAEYEQCAAQQQ2AgBBBwwMCyAFKAKEKSEjIAUoAoApISYgBSgC/CghEiAFKAL4KCEfIAUoAvQoIRMgBSgC8CghFiAFKALsKCERIAUoAugoIRkgBSgC5CghISAFKALgKCEcIAUoAtwoISQgBSgC2CghHiAFKALUKCEdIAUoAtAoIRogBSgCzCghFSAFKALIKCEXIAUoAsQoISIgBSgCwCghBCAFKAK8KCEQIAUoArgoIQcgBSgCtCghCiAFKAKwKCEUIAUoAqwoIQYgBSgCqCghCyAFKAKkKCEIIAUvAKEoIQwgBS0AoyghCSADEP4VIA5BwQBHBEAgAUG4G2oQ4iAgDCAJQRB0ckEIdCAOciEDQQQMBwsgAUG4G2oQ4iALIAFBADoA7EsgASABQeALaiISNgLoSyABQbAbaiEOIAFB7MsAaiEMCyASLQDWBUEBRwRAQSIhAwwDCyASQZAFahCuJCIqIBIpA8gEWQ0BIAVBoChqIBJBuARqICoQuQsgBS0AoCgiA0EwRwRAIAUvAKEoIAUtAKMoQRB0ciECIAUoAoQpISMgBSgCgCkhJiAFKAL8KCESIAUoAvgoIR8gBSgC9CghEyAFKALwKCEWIAUoAuwoIREgBSgC6CghGSAFKALkKCEhIAUoAuAoIRwgBSgC3CghJCAFKALYKCEeIAUoAtQoIR0gBSgC0CghGiAFKALMKCEVIAUoAsgoIRcgBSgCxCghIiAFKALAKCEEIAUoArwoIRAgBSgCuCghByAFKAK0KCEKIAUoArAoIRQgBSgCrCghBiAFKAKoKCELIAUoAqQoIQgMAwsCQAJAQdjK5gAoAgBBAksNAEHgw+YAEO4aQf8BcSIGRQ0AQeDD5gAoAgAgBhDVFUUNACAFQQA2AvAUIAVB4MPmACgCACIGKAIgIgk2AvQUIAUgBikCJDcC6BQgBSAJNgLkFCAFIAYoAhw2AuAUIAVBoChqIgkgBUHgFGoiCBCHESAFQfAjaiIKIAlBmJ3CABCoFCAFQfSGwgA2AogCIAVBADYCsCggBUEBNgKkKCAFQZSewgA2AqAoIAVCBDcCqCggBSAJNgKEAiAFIAo2AoACIAVB2B5qIAZBHGogBUGAAmoQ/R0gBUH4HWogBUHgHmooAgA2AgAgBSAFKQLYHjcD8B1B4MPmACgCACAFQfAdaiIGEPcXQeDQ5gAtAAANAUHQ0OYAKAIAQQNJDQEgBUEDNgLAHyAFQeDD5gAoAgAiCSkCFDcCxB8gBUEYahDGGSAFKAIYIgogBUHAH2ogBSgCHCILKAIMEQAARQ0BIAVB6BRqIAVByB9qKAIANgIAIAUgBSkCwB83A+AUIAkgCiALIAggBhD3CQwBC0Hg0OYALQAADQBB0NDmACgCAEEDSQ0AIAVBAzYCsBsgBUHgw+YAKAIAIggpAhQ3ArQbIAVBEGoQxhkgBSgCECIKIAVBsBtqIAUoAhQiCygCDBEAAEUNACAFQQA2AvAUIAVB4MPmACgCACIGKAIgIgk2AvQUIAUgBikCJDcC6BQgBSAJNgLkFCAFIAYoAhw2AuAUIAVBoChqIgkgBUHgFGoiBBCHESAFQfAjaiIDIAlBmJ3CABCoFCAFQfSGwgA2AsgfIAVBADYCsCggBUEBNgKkKCAFQZSewgA2AqAoIAVCBDcCqCggBSAJNgLEHyAFIAM2AsAfIAVBgAJqIgkgBkEcaiAFQcAfahD9HSAFQegUaiAFQbgbaigCADYCACAFIAUpArAbNwPgFCAIIAogCyAEIAkQ9wkLIAFBADoAtCkgASASNgKoKQsgBUGgKGogDiACELcBIAUtAKAoIgNBMUcEQCAFKAKEKSEjIAUoAoApISYgBSgC/CghEiAFKAL4KCEfIAUoAvQoIRMgBSgC8CghFiAFKALsKCERIAUoAugoIRkgBSgC5CghISAFKALgKCEcIAUoAtwoISQgBSgC2CghHiAFKALUKCEdIAUoAtAoIRogBSgCzCghFSAFKALIKCEXIAUoAsQoISIgBSgCwCghBCAFKAK8KCEQIAUoArgoIQcgBSgCtCghCiAFKAKwKCEUIAUoAqwoIQYgBSgCqCghCyAFKAKkKCEIIAUvAKEoIQIgBS0AoyghCSAOELgSIANBMEYNASACIAlBEHRyIQIMAgsgDEEDOgAAIABBBDYCAEEIDAgLQTAhAwsgDEEBOgAAIA4Qnh4gA0EwRwRAIAJBCHQgA3IhAwwBCyAFQaAoaiABQeALaiIIEP4GIAUtAKAoIgJBMEcEQCAFLQCjKEEYdCAFLwChKEEIdHIgAnIhAyAFKAKEKSEjIAUoAoApISYgBSgC/CghEiAFKAL4KCEfIAUoAvQoIRMgBSgC8CghFiAFKALsKCERIAUoAugoIRkgBSgC5CghISAFKALgKCEcIAUoAtwoISQgBSgC2CghHiAFKALUKCEdIAUoAtAoIRogBSgCzCghFSAFKALIKCEXIAUoAsQoISIgBSgCwCghBCAFKAK8KCEQIAUoArgoIQcgBSgCtCghCiAFKAKwKCEUIAUoAqwoIQYgBSgCqCghCyAFKAKkKCEIDAELIAVBoChqIAFBgAhqQYAC/AoAACAFQeAUaiIOIAFBoApqQcAB/AoAACMAQRBrIgIkACACIAFBjBtqIg8iBhCUGiIKNgIIIAVBvA9qIgsiCSAKQQhqQcAB/AoAACAJIAYQlRoiBikAKDcAgAMgCUGIA2ogBkEwaikAADcAACAJQZADaiAGQThqKQAANwAAIAlBmANqIAZBQGspAAA3AAAgAiAGNgIMIAlBwAFqIA5BwAH8CgAAIAYgBigCACIGQQFrNgIAIAZBAUYEQCACQQxqELcUCyACKAIIIgYgBigCACIGQQFrNgIAIAZBAUYEQCACQQhqEOAUCyACQRBqJAAgDxCWGiEOIAVB4BJqIAVBoChqIgZBgAL8CgAAIwBBIGsiCSQAIwBBIGsiAiQAIAJBgYCAgHg2AgAgCUEYaiIKIAIQnxMiBDYCBCAKIAQ2AgAgAkEgaiQAIAlBDGoQ0R8gCSkDGCEqQSRBBBCfGyICQoCAgIAYNwIQIAIgKjcCCCACQoGAgIAQNwIAIAIgCSkCDDcCGCACQSBqIAlBFGooAgA2AgAgAiACKAIAIgpBAWo2AgAgCkEASARAAAsgBUEIaiIKIAI2AgQgCiACNgIAIAlBIGokACAFKAIMIQkgBSgCCCEKIA8QlRohBCAPEJYaIRIgASkDmBshKiABQcARahCsIiEDIwBBEGsiAiQAIAJBoKHTABDZFiACKQMAISsgAikDCCEsIAZBCGpB+KTTACkDADcDACAGQfCk0wApAwA3AwAgBiAsNwMYIAYgKzcDECACQRBqJAAgBSAKNgLUKCAFICo3AswoIAUgEjYCxCggBSAENgLAKCAFQQA6AJgpIAUgAzYCyChBiAJBCBCfGyICIAZBgAH8CgAAIAJBADoAgAIgAkGgssMAEPIMQQxBBBCfGyIfQQA6AAggH0KBgICAEDcCAEHgBUEIEJ8bIhJBwJaxAjYCKCASQgA3AyAgEkHAlrECNgIYIBJCADcDECASQQA6AAggEkKBgICAEDcDACASQSxqIAVB3BJqQYQC/AoAACASQQE2ArACIBJBtAJqIAtBoAP8CgAAIBJBAToA2gUgEkGAAjsB2AUgEiAONgLUBSAGIAhB4AX8CgAAIAVB4BRqIgIQgg8gBUGAFWogBUGgKGoiBkHgBfwKAAAgBUGoKGogAkGABvwKAABBkAZBEBCfGyImQoGAgIAQNwMAICZBCGogBkGIBvwKAAAjAEEgayICJAAgAkEIahCCDyACIAk2AhxBIEEEEJ8bIiNCgYCAgBA3AgAgIyACKQIINwIIICNBEGogAkEQaikCADcCACAjQRhqIAJBGGopAgA3AgAgAkEgaiQAIAEoAqQSIRMgASgCoBIhFiABKAKcEiERIAEoApgSIRkgASgClBIhISABKAKQEiEcIAEoAowSISQgASgCiBIhHiABKAKEEiEdIAEoAoASIRogASgC/BEhFSABKAL4ESEXIAEoAvQRISIgASgC8BEhBCABKALsESEQIAEoAugRIQcgASgC5BEhCiABKALgESEUIAEoAtwRIQYgASgC2BEhCyABKALUESEIIAEoAtARIQMgASgCzBEhDCABKALIESEOIAEoAsQRIQkgASgCwBEhAiABQdAXahDtGSABLQClGwRAIAFBoBtqEPoYCyABQQA6AKUbIA8QthIgAS0AphsEQCABQcgZahDtGQsgAS0ApxsEQCABQbgZahCVHAsgAUGAGWoQ8yEgAUEAOwGmGyABKAKYFUECRgRAIAFBmBVqEPMWCyABQeQXahDyGSABQdgXahDzISABQYAKahCVHCABQYwKahCVHCABQZAFahCcDQwFC0EHCyEOIAFB0BdqEO0ZCyABQeALahD0EiABLQClGwRAIAFBoBtqEPoYCyABQQA6AKUbIAFBnBtqEO8dIAFBmBtqEO8dIAFBjBtqELYSIAEtAKYbBEAgAUHIGWoQ7RkLIAEtAKcbBEAgAUG4GWoQlRwLIAFBgBlqEPMhIAFBADsBphsgASgCmBVBAkcNACABQZgVahDzFgsgAUHkF2oQ8hkLIAFB2BdqEPMhIAFBwBFqEN8HIAFBkAVqEPsYQQMhAgsgAEEANgJ4IAAgIzYCdCAAICY2AnAgACASNgJsIAAgHzYCaCAAIBM2AmQgACAWNgJgIAAgETYCXCAAIBk2AlggACAhNgJUIAAgHDYCUCAAICQ2AkwgACAeNgJIIAAgHTYCRCAAIBo2AkAgACAVNgI8IAAgFzYCOCAAICI2AjQgACAENgIwIAAgEDYCLCAAIAc2AiggACAKNgIkIAAgFDYCICAAIAY2AhwgACALNgIYIAAgCDYCFCAAIAM2AhAgACAMNgIMIAAgDjYCCCAAIAk2AgQgACACNgIAQQELOgCkGyAFQbAuaiQADwtBpLTCAEE3IAVBgAJqQZS0wgBB3LTCABCpDgAL4eICAkp/J34jAEHw8gBrIgMkAAJAAkAgAQJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAn8CQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACfwJAAkACQAJAAkACQCABLQCEDkEBaw4GDhQBBRNbAAsgASABKAL4DSIENgL8DSAELQDWBUUEQEEiIQoMYQsgBCgCgAVFBEBBGiEKDGELAkAgBCgCwAFBAkcNACAELQDQBEUNAEEbIQoMYQsgBEGQBWooAgAiBCAELQAgIghBASAIGzoAIAJAIAgNACAEIAQoAgAiCEEBajYCACAEIQUgCEEATg0AAAsgBUUNDCABIAU2AoAOAkACQEHYyuYAKAIAQQNLDQBBxMLmABDuGkH/AXEiBEUNAEHEwuYAKAIAIAQQ1RVFDQAgA0EANgLgLCADQcTC5gAoAgAiBCgCICIGNgLkLCADIAQpAiQ3AtgsIAMgBjYC1CwgAyAEKAIcNgLQLCADQYACaiIFIANB0CxqIggQhxEgA0GIzgBqIhogBUGwksIAEKgUIANB9IbCADYC8GEgA0EANgKQAiADQQE2AoQCIANBjJPCADYCgAIgA0IENwKIAiADIAU2AuxhIAMgGjYC6GEgA0HwwwBqIARBHGogA0Ho4QBqEP0dIANB8NoAaiADQfjDAGooAgA2AgAgAyADKQLwQzcD6FpBxMLmACgCACADQejaAGoiBBD3F0Hg0OYALQAADQFB0NDmACgCAEECSQ0BIANBAjYC+BIgA0HEwuYAKAIAIgUpAhQ3AvwSIANB0AFqEMYZIAMoAtABIgYgA0H4EmogAygC1AEiGigCDBEAAEUNASADQdgsaiADQYATaigCADYCACADIAMpAvgSNwPQLCAFIAYgGiAIIAQQ9wkMAQtB4NDmAC0AAA0AQdDQ5gAoAgBBAkkNACADQQI2AugBIANBxMLmACgCACIGKQIUNwLsASADQcgBahDGGSADKALIASIIIANB6AFqIAMoAswBIhEoAgwRAABFDQAgA0EANgLgLCADQcTC5gAoAgAiBCgCICINNgLkLCADIAQpAiQ3AtgsIAMgDTYC1CwgAyAEKAIcNgLQLCADQYACaiIFIANB0CxqIhoQhxEgA0GIzgBqIhYgBUGwksIAEKgUIANB9IbCADYCgBMgA0EANgKQAiADQQE2AoQCIANBjJPCADYCgAIgA0IENwKIAiADIAU2AvwSIAMgFjYC+BIgA0Ho4QBqIgUgBEEcaiADQfgSahD9HSADQdgsaiADQfABaigCADYCACADIAMpAugBNwPQLCAGIAggESAaIAUQ9wkLIAEoAvwNIgQtANAEQQFGBEBBISEKIAQtANQFDQQMVgsCQAJAQdjK5gAoAgBBAksNAEG4wuYAEO4aQf8BcSIERQ0AQbjC5gAoAgAgBBDVFUUNACADQQA2AuAsIANBuMLmACgCACIEKAIgIgU2AuQsIAMgBCkCJDcC2CwgAyAFNgLULCADIAQoAhw2AtAsIANBgAJqIgUgA0HQLGoiBhCHESADQYjOAGoiDSAFQZSTwgAQqBQgA0H0hsIANgLwYSADQQA2ApACIANBATYChAIgA0GMlMIANgKAAiADQgQ3AogCIAMgBTYC7GEgAyANNgLoYSADQfDDAGogBEEcaiADQejhAGoQ/R0gA0Hw2gBqIANB+MMAaigCADYCACADIAMpAvBDNwPoWkG4wuYAKAIAIANB6NoAaiIEEPcXQeDQ5gAtAAANAUHQ0OYAKAIAQQNJDQEgA0EDNgL4EiADQbjC5gAoAgAiBSkCFDcC/BIgA0HAAWoQxhkgAygCwAEiDSADQfgSaiADKALEASIJKAIMEQAARQ0BIANB2CxqIANBgBNqKAIANgIAIAMgAykC+BI3A9AsIAUgDSAJIAYgBBD3CQwBC0Hg0OYALQAADQBB0NDmACgCAEEDSQ0AIANBAzYC9AEgA0G4wuYAKAIAIgYpAhQ3AvgBIANBuAFqEMYZIAMoArgBIg0gA0H0AWogAygCvAEiCSgCDBEAAEUNACADQQA2AuAsIANBuMLmACgCACIEKAIgIgU2AuQsIAMgBCkCJDcC2CwgAyAFNgLULCADIAQoAhw2AtAsIANBgAJqIgUgA0HQLGoiCBCHESADQYjOAGoiDiAFQZSTwgAQqBQgA0H0hsIANgKAEyADQQA2ApACIANBATYChAIgA0GMlMIANgKAAiADQgQ3AogCIAMgBTYC/BIgAyAONgL4EiADQejhAGoiBSAEQRxqIANB+BJqEP0dIANB2CxqIANB/AFqKAIANgIAIAMgAykC9AE3A9AsIAYgDSAJIAggBRD3CQsgAUEAOgD4ECABIAEoAvwNIgo2AvAQIAFBiA5qIRkgAUH4EGohFAwBCyABQYgOaiEZIAFB+BBqIRQCQCABLQD4EEEBaw4DFRMCAAsgASgC8BAhCgsgASAKNgL0ECABQQA6ALgOIAEgCjYCsA4gAUGFgICAeDYCiA4LIANBgAJqIBkgAhCpAiADLQCAAiIKQTFGDQsgA0Hw4QBqIgIgA0GgAmopAwA3AwAgAyADKQOYAjcD6GEgAykDkAIhVSADKQOIAiFPIAMoAoQCIQ0gAy0AgwIhESADLQCCAiEGIAMtAIECIRMgA0HQLGoiBCADQagCakHAAPwKAAAgGRCmESAKQTBHBEAgA0GYPmogBEHAAPwKAAAgA0GQPmogAikDADcDACADIAMpA+hhNwOIPgwOCyADQaDOAGoiAiADQfDhAGopAwA3AwAgAyBVNwOQTiADIAMpA+hhNwOYTiADIE83A4hOAkACQCBPp0H/AXFBA2sOBAEODgAOCyBPQiCIpyENQQ8hCiBVIU8MDgsgA0GIzgBqIgQQ6RUCQAJAQdjK5gAoAgBBAksNAEGQxOYAEO4aQf8BcSICRQ0AQZDE5gAoAgAgAhDVFUUNACADQQA2AphOIANBkMTmACgCACICKAIgIgU2ApxOIAMgAikCJDcCkE4gAyAFNgKMTiADIAIoAhw2AohOIANBgAJqIgUgBBCHESADQfgSaiIJIAVBgKHCABCoFCADQfSGwgA2AvBaIANBADYCkAIgA0EBNgKEAiADQbShwgA2AoACIANCBDcCiAIgAyAFNgLsWiADIAk2AuhaIANBhMEAaiACQRxqIANB6NoAahD9HSADQeA+aiADQYzBAGooAgA2AgAgAyADKQKEQTcD2D5BkMTmACgCACADQdg+aiICEPcXQeDQ5gAtAAANAUHQ0OYAKAIAQQNJDQEgA0EDNgLwQyADQZDE5gAoAgAiBSkCFDcC9EMgA0GwAWoQxhkgAygCsAEiCSADQfDDAGogAygCtAEiBigCDBEAAEUNASADQZDOAGogA0H4wwBqKAIANgIAIAMgAykC8EM3A4hOIAUgCSAGIAQgAhD3CQwBC0Hg0OYALQAADQBB0NDmACgCAEEDSQ0AIANBAzYC4G0gA0GQxOYAKAIAIgUpAhQ3AuRtIANBqAFqEMYZIAMoAqgBIgYgA0Hg7QBqIAMoAqwBIhMoAgwRAABFDQAgA0EANgKYTiADQZDE5gAoAgAiAigCICIRNgKcTiADIAIpAiQ3ApBOIAMgETYCjE4gAyACKAIcNgKITiADQYACaiIEIANBiM4AaiIJEIcRIANB+BJqIgggBEGAocIAEKgUIANB9IbCADYC+EMgA0EANgKQAiADQQE2AoQCIANBtKHCADYCgAIgA0IENwKIAiADIAQ2AvRDIAMgCDYC8EMgA0Ho2gBqIgQgAkEcaiADQfDDAGoQ/R0gA0GQzgBqIANB6O0AaigCADYCACADIAMpAuBtNwOITiAFIAYgEyAJIAQQ9wkLIAEoAvQQQZAFaiBVEJkSQTAhCgwNCyAELQDVBSIGQQJJBEBBASETDFILIAQQrxshCiADQdAsaiIEIAEoAvwNQcAB/AoAACADQYACaiIFIAQQpxUgAUGIDmoiKiAFQeAQ/AoAACABQQA7AfgeIAEgCjYC9B4gAUEBNgLoHiABQfgeaiExQQEMAQsgAUGIDmohKiABQfgeaiExAkAgAS0A+B5BAWsOBQYPAgdNAAsgAS0A+R4hEyABKAL0HiEKIAEoAugeCyEGIAEgCjYC7B4gAUEAOgCSHyABIBM6AJEfIAEgCjYCjB8gASAGNgKIHyABIAY2AvAeIAEgKikDADcDqA4gAUGwDmogKkEIaikDADcDACABQbgOaiAqQRBqKQMANwMAIAFBwA5qICpBGGopAwA3AwAgAUGAH2ohBSABQZIfaiEmDAELIAFBgB9qIQUgAUGSH2ohJgJAIAEtAJIfQQFrDgMRDQIACyABKAKIHyEGIAEtAJEfIRMgASgCjB8hCgsgASATOgCQHyADQQA2AoBeIANCgICAgBA3AvhdIANB/LPCADYC9EMgA0KggICADjcC+EMgAyADQfjdAGo2AvBDIAFBkB9qIANB8MMAahD3FQ0OIANBkOEAaiADQYDeAGooAgA2AgAgAyADKQL4XTcDiGFB8ABBBBCEISIERQRAQQRB8AAQ4SMACyAEQQA6AGwgBCAGNgIQIAQgCkHgAmo2AgwgBCADQYjhAGoiCCkCADcCACAEQQhqIAhBCGooAgA2AgAgA0GgAWoiCEGo1sgANgIEIAggBDYCACADKAKgASEKIAEgAygCpAE2AoQfIAEgCjYCgB8MAQsgBSgCACEKCyADQfDDAGoiBCAKIAIgBSgCBCgCDBEDACADLQD0RkEGRg0HIANB0CxqIgggBEGQA/wKAAAgBRD+FQJAAkAgAy0A1C9BBUYEQCADQejaAGogCBCEFgwBCyADQejaAGogA0HQLGpBkAP8CgAAIAMtAOxdIgRBBUcNAQsgAykD+FohVSADKQPwWiFPIAMoAuxaIQ0gAy0A61ohESADLQDqWiEGIAMtAOlaIRMgAy0A6FohCiADQbjwAGogA0GA2wBqQdAA/AoAAAwZCyAEQQRGBEBBAyEKDBkLIAMtAOhaIQogAykD4CwhVSADKQPYLCFPIAMoAtQsIQ0gAy0A0ywhESADLQDSLCEGIAMtANEsIRMgA0G48ABqIANB6CxqQdAA/AoAACADQeDtAGogA0G4LWpBnAL8CgAAIAMgA0HcL2ooAAA2AIdyIAMgAykA1S83A4ByDBkLQaSuwgAQtRcACyABQYAfaiEmIAFBxChqIQQCQAJAAkACQAJAIAEtAMQoQQFrDgUCDAEDBAALIAEoArAoIQYgASgCwCghCgwcCyABQcgoaiEaIAFBoDBqIRECQAJAAkAgAS0AoDBBAWsOAwINAQALIAEoApwwIQYgASkDyCghTyABKAKYMCEKDB4LIAFB0ChqIRYgAUHwKGohBQJAAkACQAJAIAEtAPAoQQFrDgYUDwIkAwEACyABKALkKCEGIAEpA9AoIU8gASgC4CghCgwhCyABKAL8KCEKDCULIAEoAvwoIQYgASgC+CghCgwgCyABQfgoaiEgIAFBlDBqIR8CQAJAAkAgAS0AlDBBAWsOAwEOAgALIAEoAvgvIQoMIwtB0LLCABC1FwALIAFBiC9qIRQgAUHIL2ohDgJAAkAgAS0AyC9BAWsOAxMNAAELIAEoAsQvIRcgASgCwC8hBwwYCyABKQO4LyFZQQEMIgtBiLDCABC1FwALQeivwgAQtRcACyABQcgoaiEXIAFBtDBqIQ0CQAJAAkAgAS0AtDBBAWsOAwILAQALIAEoArAwIRMgASgCrDAhCiABKAKoMCEGDCkLIAFB0ChqIQUgAUH4KGohFAJAAkACQAJAIAEtAPgoQQFrDgYUDQIvAwEACyABKALoKCETIAEoAuQoIQogASkD0CghTyABKALgKCEGDCwLIAEoApwpIQYgASgCmCkhCgwxCyABKAKEKSEGIAEoAoApIQoMKwsgAUGAKWohDiABQaQwaiEaAkACQAJAIAEtAKQwQQFrDgMBDAIACyABKALkLyEGIAEoAuAvIQoMLgtB0LLCABC1FwALIAFBmC9qIRkgAUHcL2ohGwJAAkAgAS0A3C9BAWsOAxMLAAELIAEoAtQvIRAgASgC0C8hFQwXCyABKQPILyFaIAEoAtgvIR1BASEGDC4LQZiwwgAQtRcACyABQdgoaiEUIAFBsDBqIRECQAJAAkAgAS0AsDBBAWsOAwIKAQALIAEoAqwwIQYgASkD2CghTyABKAKoMCEKDDULIAFB4ChqIRUgAUGAKWohDQJAAkACQAJAIAEtAIApQQFrDgYVDAI7AwEACyABKAL0KCEGIAEpA+AoIU8gASgC8CghCgw4CyABKAKkKSEGIAEoAqApIQoMPQsgASgCjCkhBiABKAKIKSEKDDcLIAFBiClqIR0gAUGkMGohBwJAAkACQCABLQCkMEEBaw4DAQsCAAsgASgCiDAhCgw6C0HQssIAELUXAAsgAUGYL2ohDCABQdgvaiEJAkACQCABLQDYL0EBaw4DFAoAAQsgASgC1C8hEiABKALQLyEPDBcLIAEpA8gvIVtBASEKDDoLQcivwgAQtRcACwJAQdjK5gAoAgBBAUsNAEGIwuYAEO4aQf8BcSIBRQ0AQYjC5gAoAgAgARDVFUUNACADQQA2AuAsIANBiMLmACgCACIBKAIgIgI2AuQsIAMgASkCJDcC2CwgAyACNgLULCADIAEoAhw2AtAsIANBgAJqIgIgA0HQLGoiBBCHESADQYjOAGoiBSACQZSUwgAQqBQgA0H0hsIANgLwYSADQQA2ApACIANBATYChAIgA0HYlMIANgKAAiADQgQ3AogCIAMgAjYC7GEgAyAFNgLoYSADQfDDAGogAUEcaiADQejhAGoQ/R0gA0Hw2gBqIANB+MMAaigCADYCACADIAMpAvBDNwPoWkGIwuYAKAIAIANB6NoAaiIBEPcXAkBB4NDmAC0AAA0AQdDQ5gAoAgBBBEkNACADQQQ2AvgSIANBiMLmACgCACICKQIUNwL8EiADQRBqEMYZIAMoAhAiBSADQfgSaiADKAIUIgYoAgwRAABFDQAgA0HYLGogA0GAE2ooAgA2AgAgAyADKQL4EjcD0CwgAiAFIAYgBCABEPcJC0EwIQoMVAtBMCEKQeDQ5gAtAAANU0HQ0OYAKAIAQQRJDVMgA0EENgLcASADQYjC5gAoAgAiBikCFDcC4AEgA0EIahDGGSADKAIIIhMgA0HcAWogAygCDCIRKAIMEQAARQ1TIANBADYC4CwgA0GIwuYAKAIAIgEoAiAiDTYC5CwgAyABKQIkNwLYLCADIA02AtQsIAMgASgCHDYC0CwgA0GAAmoiAiADQdAsaiIEEIcRIANBiM4AaiIFIAJBlJTCABCoFCADQfSGwgA2AoATIANBADYCkAIgA0EBNgKEAiADQdiUwgA2AoACIANCBDcCiAIgAyACNgL8EiADIAU2AvgSIANB6OEAaiICIAFBHGogA0H4EmoQ/R0gA0HYLGogA0HkAWooAgA2AgAgAyADKQLcATcD0CwgBiATIBEgBCACEPcJDFMLQeCUwgAQtRcACyAUQQM6AAAgAEExOgAAQQMMUgsgA0GYAmogAikDADcDACADQZACaiADQZjOAGopAwA3AwAgA0GIAmogA0GQzgBqKQMANwMAIAMgAykDiE43A4ACIANB+BJqIANBgAJqIgIQ4AMgAykC/BIhTyADKAL4EiENIAIQ6RVBJiEKCyAUQQE6AAAgGRCYHgxEC0EDIQogJkEDOgAADEALIAFBiA5qIQYgAUHwHWohEyABLQDwHUEBaw4DCwBFAQsACyABKALsHSEKDEILQfCgwgAQtRcAC0GktMIAQTcgA0GI4QBqQZS0wgBB3LTCABCpDgALQdivwgAQtRcAC0GsscIAELUXAAtB7LHCABC1FwALQfyxwgAQtRcAC0HAssIAELUXAAtBqLDCABC1FwALQeywwgAQtRcAC0HEmcIAELUXAAtBAgwKC0ECIQYMFwtBAiEKDCMLQQQhBAsgA0HA3wBqIgggA0G48ABqQdAA/AoAACADQdg+aiIaIANB4O0AakGcAvwKAAAgAyADKACHcjYAt3IgAyADKQOAcjcDsHIgJkEBOgAAIANBoMMAaiIWIAhB0AD8CgAAIANBhMEAaiAaQZwC/AoAACADIAMoALdyNgD/QCADIAMpA7ByNwP4QCAFEJkeIARBBEYEQCADQYjOAGogFkHQAPwKAAAMMAsgASBVNwPYDiABIE83A9AOIAEgDTYCzA4gASAROgDLDiABIAY6AMoOIAEgEzoAyQ4gASAKOgDIDiABQeAOaiADQaDDAGpB0AD8CgAAIAFBsA9qIANBhMEAakGcAvwKAAAgASAEOgDMESABIAMpA/hANwDNESABQdQRaiADKAD/QDYAACABIAEpA6ARNwPoESABKALwHiIGIAEoApgRaiIEIAZPBEAgASkDyA4hTyABIAQ2AuQRIAEgBjYC4BEgASBPNwPYESADQdgsaiABQbAOaikDADcDACADQeAsaiABQbgOaikDADcDACADQegsaiABQcAOaikDADcDACADIAEpA6gONwPQLCABKALsHiEKIANB8DJqIAFByA5qQZAD/AoAACADQfDDAGoiBCADQdAsakGwCfwKAAAgBSAEQbAJ/AoAACABQQA6AMQoIAEgCjYCwCggASAGNgKwKCABQYAfaiEmIAFBxChqIQQMAQtBtK7CABCuFwALIAEgCjYCtCggASAGNgK4KCABICYpAwA3A6AfIAFBqB9qICZBCGopAwA3AwAgAUGwH2ogJkEQaikDADcDACABQbgfaiAmQRhqKQMANwMAIAFBwB9qIAFBoCVqQZAD/AoAACABIAo2AtQiIAFBADoAoDAgASABQdAiaiIGNgKcMCABIAo2ApgwIAFBADYC0CIgASABKQOYIiJPNwPgIiABIAEoAsAiNgK8KCABIE83A9giIAEgTzcDyCggAUGgMGohESABQcgoaiEaCyABQQA6APAoIAEgBjYC5CggASBPNwPQKCABIApB4AJqIgo2AuAoIAFB8ChqIQUgAUHQKGohFgsgASAGNgLsKCABIE83A9goIAEgCjYC6ChB2ABBCBCEISIGRQRAQQhB2AAQ4SMACyAGQQA6AFQgBiAKNgJQIAYgTzcDACADQZgBaiINQYjVyAA2AgQgDSAGNgIAIAMoApgBIQogASADKAKcASIGNgL8KCABIAo2AvgoCyADQdAsaiAKIAIgBigCDBEDACADKAL8LkGCgICAeEYEQEEDIQoMBQsgA0Ho2gBqIgYgA0HQLGpBuAL8CgAAIAFB+ChqEP4VAkACQCADKAKUXUGBgICAeEYEQCADQeDtAGogBhCEFgwBCyADQeDtAGogA0Ho2gBqQbgC/AoAACADKAKMcCINQYGAgIB4Rw0BCyADLwDhbSADLQDjbUEQdHIhCiADKQPAbiFYIAMpA7huIU0gAykDsG4hTiADKQOobiFQIAMpA6BuIVEgAykDmG4hUiADKQOQbiFTIAMpA4huIVYgAykDgG4hVyADKQP4bSFVIAMpA/BtIVQgAykD6G0hTyADKALkbSETIAMtAOBtIQYMCAsgDUGAgICAeEcEQCADKQOQcCFZIAMtAOBtIQYgAykDyFshWCADKQPAWyFNIAMpA7hbIU4gAykDsFsh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uC1qQfgL/AoAACADQeDhAGogA0HEOWooAgA2AgAgA0HY4QBqIANBvDlqKQIANwMAIAMgAykCtDk3A9BhIANByPIAahCEIyABQcgoahCEI0EQdHIhCgsgDRCbHgsgAUHQImoQ7h0gAUHAH2oQ0RsgAUEBOgDEKCABQfMRaiAKQRB2OgAAIAEgCjsA8REgASBYNwPQEiABIE03A8gSIAEgTjcDwBIgASBQNwO4EiABIFE3A7ASIAEgUjcDqBIgASBTNwOgEiABIFY3A5gSIAEgVzcDkBIgASBVNwOIEiABIFQ3A4ASIAEgTzcD+BEgASATNgL0ESABIAY6APARIAFB2BJqIANB6OEAakH4C/wKAAAgASARNgLQHiABIAMpA9BhNwLUHiABQdweaiADQdjhAGopAwA3AgAgAUHkHmogA0Hg4QBqKAIANgIAICYQ6xAgAUHwEWohBCABKALQHiIZQYCAgIB4RwRAIANBiM4AaiAEQeAM/AoAACADQYDOAGogAUHUHmoiBEEQaigCADYCACADQfjNAGogBEEIaikCADcDACADIAQpAgA3A/BNIAEpA+ARIU8gASgC3BEhDSABLQDbESERIAEtANoRIQYgAS0A2REhEyABLQDYESEKIAEpA+gRIVUMBAsgJiAEQegA/AoAAEHQ0OYAKAIABEAgA0EANgLgLCADQQE2AtQsIANBmK/CADYC0CwgA0IENwLYLCADQaCvwgA2AvhaIANBGDYC9FogA0Gwr8IANgLwWiADQRg2AuxaIANBsK/CADYC6FogA0HQLGpBASADQejaAGoQwwoLIAFBADoAhCAgASABKQPYETcD6B8gASABKALsHjYCgCAgAUHwH2ogAUHgEWopAwA3AwALIANB0CxqIAFB6B9qIgQgAhCGCCADLQDQLCIKQQ9GBEBBBSEKDAELIAMpA+AsIVUgAykD2CwhTyADKALULCENIAMtANMsIREgAy0A0iwhBiADLQDRLCETIANBoM0AaiIFIANB6CxqQdAA/AoAACAEEIccIApBDkcEQCADQYjOAGogBUHQAPwKAAAgAUGAH2oQ2wYMAgsgASkDkB8hVSABKQOIHyFPIAEoAoQfIQ0gAS0Agx8hESABLQCCHyEGIAEtAIEfIRMgAS0AgB8hCiADQYjOAGogAUGYH2pB0AD8CgAADAELIDEgCjoAACAA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IAMgBCAIQRhsajYChAkgA0HcCmogA0H4CGoQ3SAgASAFQQhqNgKABCABQQA6APwDIAEgAUHQA2o2AvgDIAFBhYCAgHg2AuADIAEgAygC3Ao2AtgDIAEgAygC4AoiBDYC1AMgASAENgLQAyABIAQgAygC5ApBHGxqNgLcAwsgA0H4CGohBSMAQfAAayIEJAAgAUHgA2oiCCgCACEJIAhBhYCAgHg2AgACQAJAIAlBhYCAgHhGDQAgBEEUaiAIQQxqKQIANwIAIARBHGogCEEUaigCADYCACAEIAk2AgggBCAIKQIENwIMIARBPGogCCACIARBCGoQvAoCQAJAIAQoAjwiCUHx////B2oOAgIBAAsgBSAEKQJANwIEIAVBFGogBEHQAGooAgA2AgAgBUEMaiAEQcgAaikCADcCAAsgBSAJNgIADAELIAhBGGohCyAEQUBrIQkgBEHcAGohByAEQShqIQogBEEkaiEQAkACQAJAAkACQANAIARBPGoiFiALEO0KIARBIGogFhCPECAEKAIgQQFGBEAgBSAQKQIANwIAIAVBEGogEEEQaikCADcCACAFQQhqIBBBCGopAgA3AgAMBwsCQAJAAkAgBCgCJCIWQfv///8Hag4CAgABCyAEQTxqIAhBIGogAhCVICAEKAI8IglB8f///wdqDgIFBwYLIAcgCikCADcCACAHQQhqIApBCGopAgA3AgAgB0EQaiAKQRBqKAIANgIAIAQgFjYCWCAEQTxqIAggAiAEQdgAahC8CiAEKAI8IhZB8f///wdqDgIBAwILCyAEQTxqIAhBIGogAhCVIAJAAkACQCAEKAI8IglB8f///wdqDgIAAgELIAVBj4CAgHg2AgAMBwsgBSAEKQJANwIEIAVBFGogBEHQAGooAgA2AgAgBUEMaiAEQcgAaikCADcCAAsgBSAJNgIADAULIAUgCSkCADcCBCAFQRRqIAlBEGooAgA2AgAgBUEMaiAJQQhqKQIANwIACyAFIBY2AgAMAwsgBUGQgICAeDYCAAwCCyAFIAQpAkA3AgQgBUEUaiAEQdAAaigCADYCACAFQQxqIARByABqKQIANwIACyAFIAk2AgALIARB8ABqJAAgAygC+AgiBEGQgICAeEYEQCATQQM6AABBBAwFCyADQaAJaiIJIANBjAlqKAIANgIAIANBmAlqIgcgA0GE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NgLcAiADIAc2AtgCIAMgBDYC1AIgAyAGNgLQAiADQezVxgA2AogFIANBADYCyAMgA0EBNgK8AyADQZzdxgA2ArgDIANCBDcCwAMgAyADQbgDajYChAUgAyADQdACajYCgAUgA0HABGogAkEcaiADQYAFahD9HSADQagEaiADQcgEaigCADYCACADIAMpAsAENwOgBEHcxeYAKAIAIANBoARqIgIQ9xdB4NDmAC0AAA0BQdDQ5gAoAgBBBUkNASADQQU2ApAFIANB3MXmACgCACIEKQIUNwKUBSADQegAahDGGSADKAJoIgUgA0GQBWogAygCbCIHKAIMEQAARQ0BIANB2ARqIANBmAVqKAIANgIAIAMgAykCkAU3A9AEIAQgBSAHIANB0ARqIAIQ9wkMAQtB4NDmAC0AAA0AQdDQ5gAoAgBBBUkNACADQQU2AvABIANB3MXmACgCACIEKQIUNwL0ASADQeAAahDGGSADKAJgIgUgA0HwAWogAygCZCIHKAIMEQAARQ0AQdzF5gAoAgAiAigCICIGRQ0SIAIoAighCCACKAIkIQkgAigCHCEKIANBADYC4AIgAyAINgLcAiADIAk2AtgCIAMgBjYC1AIgAyAKNgLQAiADQezVxgA2ApgFIANBADYCyAMgA0EBNgK8AyADQZzdxgA2ArgDIANCBDcCwAMgAyADQbgDajYClAUgAyADQdACajYCkAUgA0GABWoiBiACQRxqIANBkAVqEP0dIANB2ARqIANB+AFqKAIANgIAIAMgAykC8AE3A9AEIAQgBSAHIANB0ARqIAYQ9wkLIAMoArwBIgIgAygCtAFGBEAgA0G0AWpBpN3GABD5EwsgAygCuAEgAkEMbGoiBCAPNwIEIAQgCzYCACADIAJBAWo2ArwBDBkLAkACQEHYyuYAKAIADQBB+MTmAC0AACIEQQFrQQJPBEAgBEUNAUHwxOYAELkKQf8BcSIERQ0BC0HwxOYAKAIAIAQQ1RVFDQBB8MTmACgCACICKAIgIgRFDRMgAigCKCEFIAIoAiQhByACKAIcIQYgA0EANgLgAiADIAU2AtwCIAMgBzYC2AIgAyAENgLUAiADIAY2AtACIANB7NXGADYCiAUgA0EANgLIAyADQQE2ArwDIANB5N3GADYCuAMgA0IENwLAAyADIANBuANqNgKEBSADIANB0AJqNgKABSADQcAEaiACQRxqIANBgAVqEP0dIANBqARqIANByARqKAIANgIAIAMgAykCwAQ3A6AEQfDE5gAoAgAgA0GgBGoiAhD3F0Hg0OYALQAADQFB0NDmACgCAEEFSQ0BIANBBTYCkAUgA0HwxOYAKAIAIgQpAhQ3ApQFIANB2ABqEMYZIAMoAlgiBSADQZAFaiADKAJcIgcoAgwRAABFDQEgA0HYBGogA0GYBWooAgA2AgAgAyADKQKQBTcD0AQgBCAFIAcgA0HQBGogAhD3CQwBC0Hg0OYALQAADQBB0NDmACgCAEEFSQ0AIANBBTYC5AEgA0HwxOYAKAIAIgQpAhQ3AugBIANB0ABqEMYZIAMoAlAiBSADQeQBaiADKAJUIgcoAgwRAABFDQBB8MTmACgCACICKAIgIgZFDRMgAigCKCEIIAIoAiQhCSACKAIcIQogA0EANgLgAiADIAg2AtwCIAMgCTYC2AIgAyAGNgLUAiADIAo2AtACIANB7NXGADYCmAUgA0EANgLIAyADQQE2ArwDIANB5N3GADYCuAMgA0IENwLAAyADIANBuANqNgKUBSADIANB0AJqNgKQBSADQYAFaiIGIAJBHGogA0GQBWoQ/R0gA0HYBGogA0HsAWooAgA2AgAgAyADKQLkATcD0AQgBCAFIAcgA0HQBGogBhD3CQsgAygCvAEiAiADKAK0AUYEQCADQbQBakHs3cYAEPkTCyADKAK4ASACQQxsaiIEIA83AgQgBCALNgIAIAMgAkEBajYCvAEMGAsCQEHYyuYAKAIADQBB8MXmAC0AACIEQQFrQQJPBEAgBEUNAUHoxeYAELkKQf8BcSIERQ0BC0HoxeYAKAIAIAQQ1RVFDQBB6MXmACgCACICKAIgIgRFDRMgAigCKCEFIAIoAiQhByACKAIcIQYgA0EANgLgAiADIAU2AtwCIAMgBzYC2AIgAyAENgLUAiADIAY2AtACIANB7NXGADYCiAUgA0EANgLIAyADQQE2ArwDIANBoN7GADYCuAMgA0IENwLAAyADIANBuANqNgKEBSADIANB0AJqNgKABSADQcAEaiACQRxqIANBgAVqEP0dIANBqARqIANByARqKAIANgIAIAMgAykCwAQ3A6AEQejF5gAoAgAgA0GgBGoiAhD3F0Hg0OYALQAADRdB0NDmACgCAEEFSQ0XIANBBTYCkAUgA0HoxeYAKAIAIgQpAhQ3ApQFIANBqAFqEMYZIAMoAqgBIgUgA0GQBWogAygCrAEiBygCDBEAAEUNFyADQdgEaiADQZgFaigCADYCACADIAMpApAFNwPQBCAEIAUgByADQdAEaiACEPcJDBcLQeDQ5gAtAAANFkHQ0OYAKAIAQQVJDRYgA0EFNgLYASADQejF5gAoAgAiBCkCFDcC3AEgA0GgAWoQxhkgAygCoAEiBSADQdgBaiADKAKkASIHKAIMEQAARQ0WQejF5gAoAgAiAigCICIGRQ0TIAIoAighCCACKAIkIQkgAigCHCEKIANBADYC4AIgAyAINgLcAiADIAk2AtgCIAMgBjYC1AIgAyAKNgLQAiADQezVxgA2ApgFIANBADYCyAMgA0EBNgK8AyADQaDexgA2ArgDIANCBDcCwAMgAyADQbgDajYClAUgAyADQdACajYCkAUgA0GABWoiBiACQRxqIANBkAVqEP0dIANB2ARqIANB4AFqKAIANgIAIAMgAykC2AE3A9AEIAQgBSAHIANB0ARqIAYQ9wkMFgtBiMXmACgCACICKAIgIgRFDRMgAigCKCEFIAIoAiQhByACKAIcIQYgA0EANgLgAiADIAU2AtwCIAMgBzYC2AIgAyAENgLUAiADIAY2AtACIANB7NXGADYCiAUgA0EANgLIAyADQQE2ArwDIANB3N7GADYCuAMgA0IENwLAAyADIANBuANqNgKEBSADIANB0AJqNgKABSADQcAEaiACQRxqIANBgAVqEP0dIANBqARqIANByARqKAIANgIAIAMgAykCwAQ3A6AEQYjF5gAoAgAgA0GgBGoiAhD3F0Hg0OYALQAADQBB0NDmACgCAEEFSQ0AIANBBTYCkAUgA0GIxeYAKAIAIgQpAhQ3ApQFIANByABqEMYZIAMoAkgiBSADQZAFaiADKAJMIgcoAgwRAABFDQAgA0HYBGogA0GYBWooAgA2AgAgAyADKQKQBTcD0AQgBCAFIAcgA0HQBGogAhD3CQsgAygCyAEiAiADKALAAUYEQCADQcABakHk3sYAEPkTCyADKALEASACQQxsaiIEIA83AgQgBCALNgIAIAMgAkEBajYCyAEMFQtB6NnGABC0FwALQfjZxgAQtBcAC0GI2sYAELQXAAtBmNrGABC0FwALQfzUxgBBIkGo2sYAELkRAAtB/NTGAEEiQajaxgAQuREAC0H81MYAQSJBoNvGABC5EQALQfzUxgBBIkGg28YAELkRAAtB/NTGAEEiQeTbxgAQuREAC0H81MYAQSJB5NvGABC5EQALQfzUxgBBIkGo3MYAELkRAAtB/NTGAEEiQajcxgAQuREAC0H81MYAQSJB7NzGABC5EQALQfzUxgBBIkHs3MYAELkRAAtB/NTGAEEiQbTdxgAQuREAC0H81MYAQSJBtN3GABC5EQALQfzUxgBBIkH83cYAELkRAAtB/NTGAEEiQfzdxgAQuREAC0H81MYAQSJBuN7GABC5EQALQfzUxgBBIkG43sYAELkRAAsgAygCyAEiAiADKALAAUYEQCADQcABakGo3sYAEPkTCyADKALEASACQQxsaiIEIA83AgQgBCALNgIAIAMgAkEBajYCyAELIAMoAuwEIgQgAygC9ARHDQALCyADQegEahDsDwJAAkACQAJAAkACQAJAAkACQAJAAkAgAygCvAEiC0UNAAJAAkBB2MrmACgCAA0AQfzF5gAtAAAiAkEBa0ECTwRAIAJFDQFB9MXmABC5CkH/AXEiAkUNAQtB9MXmACgCACACENUVRQ0AQfTF5gAoAgAiAigCICIERQ0DIAIoAiQhBSACKAIcIQcgAyACKAIoNgLcAiADIAU2AtgCIAMgBDYC1AIgAyAHNgLQAiADQezVxgA2ApgFIANBADYC4AIgA0ECNgK8AyADQbTYxgA2ArgDIANCATcCxAMgA0EKNgKkBCADIAMoArwBNgKsBCADIANBuANqNgKUBSADIANB0AJqNgKQBSADIANBoARqNgLAAyADIANBrARqNgKgBCADQYAFaiACQRxqIANBkAVqEP0dIANByARqIANBiAVqKAIANgIAIAMgAykCgAU3A8AEQfTF5gAoAgAgA0HABGoiAhD3F0Hg0OYALQAADQFB0NDmACgCAEEFSQ0BIANBBTYC0AQgA0H0xeYAKAIAIgQpAhQ3AtQEIANBOGoQxhkgAygCOCIFIANB0ARqIAMoAjwiBygCDBEAAEUNASADQfAEaiADQdgEaigCADYCACADIAMpAtAENwPoBCAEIAUgByADQegEaiACEPcJDAELQeDQ5gAtAAANAEHQ0OYAKAIAQQVJDQAgA0EFNgKsAiADQfTF5gAoAgAiBCkCFDcCsAIgA0EwahDGGSADKAIwIgUgA0GsAmogAygCNCIHKAIMEQAARQ0AQfTF5gAoAgAiAigCICIGRQ0DIAIoAighCCACKAIkIQkgAigCHCEKIANBADYC4AIgAyAINgLcAiADIAk2AtgCIAMgBjYC1AIgAyAKNgLQAiADQezVxgA2AtgEIANBAjYCvAMgA0G02MYANgK4AyADQgE3AsQDIANBCjYChAUgAyADKAK8ATYCwAQgAyADQbgDajYC1AQgAyADQdACajYC0AQgAyADQYAFajYCwAMgAyADQcAEajYCgAUgA0GQBWoiBiACQRxqIANB0ARqEP0dIANB8ARqIANBtAJqKAIANgIAIAMgAykCrAI3A+gEIAQgBSAHIANB6ARqIAYQ9wkLIANBwANqIANBvAFqKAIANgIAIAMgAykCtAE3A7gDIANB0AJqIQUjAEGwAWsiAiQAIAJBGGogAUEIaiADQbgDaiIHEJEOAkACQAJAAkACQCACKAIYQYCAgIB4RwRAIAJBMGogAkEgaikCADcDACACIAIpAhg3AyggARDCJUUNAQJAQdjK5gAoAgBBA0sNAEGwweYALQAAIgRBAWtBAk8EQCAERQ0BQajB5gAQuQpB/wFxIgRFDQELQajB5gAoAgAgBBDVFUUNAEGoweYAKAIAIgQoAiAiBkUNAyAEKAIoIQggBCgCJCEJIAQoAhwhCiACQQA2AnggAiAINgJ0IAIgCTYCcCACIAY2AmwgAiAKNgJoIAJB7NXGADYCZCACQQA2AowBIAJBATYCgAEgAkGA2MYANgJ8IAJCBDcChAEgAiACQfwAajYCYCACIAJB6ABqNgJcIAJBxABqIARBHGogAkHcAGoQ/R0gAkFAayACQcwAaigCADYCACACIAIpAkQ3AzhBqMHmACgCACACQThqIgQQ9xdB4NDmAC0AAA0FQdDQ5gAoAgBBAkkNBSACQQI2ApQBIAJBqMHmACgCACIGKQIUNwKYASACQRBqEMYZIAIoAhAiCCACQZQBaiACKAIUIgkoAgwRAABFDQUgAkGoAWogAkGcAWooAgA2AgAgAiACKQKUATcDoAEgBiAIIAkgAkGgAWogBBD3CQwFC0Hg0OYALQAADQRB0NDmACgCAEECSQ0EIAJBAjYCUCACQajB5gAoAgAiBikCFDcCVCACQQhqEMYZIAIoAggiCCACQdAAaiACKAIMIgkoAgwRAABFDQRBqMHmACgCACIEKAIgIgpFDQMgBCgCKCEMIAQoAiQhDSAEKAIcIQ4gAkEANgJ4IAIgDDYCdCACIA02AnAgAiAKNgJsIAIgDjYCaCACQezVxgA2ApwBIAJBADYCjAEgAkEBNgKAASACQYDYxgA2AnwgAkIENwKEASACIAJB/ABqNgKYASACIAJB6ABqNgKUASACQdwAaiIKIARBHGogAkGUAWoQ/R0gAkGoAWogAkHYAGooAgA2AgAgAiACKQJQNwOgASAGIAggCSACQaABaiAKEPcJDAQLIAVBMDoAAAwECyACQQE2AoABIAJBnNfGADYCfCACQgE3AogBIAJBpwY2AmwgAiACQegAajYChAEgAiACQShqNgJoIAJB/ABqQaTXxgAQ9xgAC0H81MYAQSJBtNfGABC5EQALQfzUxgBBIkG018YAELkRAAsgBUEvOgAAIAJBKGoiBBCPFyAEEPYgCyACQbABaiQAIAMtANACQTBGDQAgByAFQegA/AoAAAJAAkBB2MrmACgCAEEESw0AQZzF5gAtAAAiBEEBa0ECTwRAIARFDQFBlMXmABC5CkH/AXEiBEUNAQtBlMXmACgCACAEENUVRQ0AQZTF5gAoAgAiASgCICICRQ0FIAEoAiQhBCABKAIcIQsgAyABKAIoNgLcBCADIAQ2AtgEIAMgAjYC1AQgAyALNgLQBCADQezVxgA2AsgEIANBADYC4AQgA0EBNgLsBCADQfjYxgA2AugEIANCATcC9AQgA0ECNgKwBCADIANB6ARqNgLEBCADIANB0ARqNgLABCADIANBrARqNgLwBCADIANBuANqNgKsBCADQaAEaiICIAFBHGogA0HABGoQ/R1BlMXmACgCACACEPcXQeDQ5gAtAAANAUHQ0OYAKAIARQ0BIANBATYCgAUgA0GUxeYAKAIAIgEpAhQ3AoQFIANBKGoQxhkgAygCKCIEIANBgAVqIAMoAiwiCygCDBEAAEUNASADQZgFaiADQYgFaigCADYCACADIAMpAoAFNwOQBSABIAQgCyADQZAFaiACEPcJDAELQeDQ5gAtAAANAEHQ0OYAKAIARQ0AIANBATYCuAIgA0GUxeYAKAIAIgIpAhQ3ArwCIANBIGoQxhkgAygCICIEIANBuAJqIAMoAiQiCygCDBEAAEUNAEGUxeYAKAIAIgEoAiAiBUUNBSABKAIoIQcgASgCJCEGIAEoAhwhCCADQQA2AuAEIAMgBzYC3AQgAyAGNgLYBCADIAU2AtQEIAMgCDYC0AQgA0Hs1cYANgKIBSADQQE2AuwEIANB+NjGADYC6AQgA0IBNwL0BCADQQI2AqQEIAMgA0HoBGo2AoQFIAMgA0HQBGo2AoAFIAMgA0GgBGo2AvAEIAMgA0G4A2o2AqAEIANBwARqIgUgAUEcaiADQYAFahD9HSADQZgFaiADQcACaigCADYCACADIAMpArgCNwOQBSACIAQgCyADQZAFaiAFEPcJCyAAIANBuANqQegA/AoAACADQcABaiIAEI8XIAAQ9iAMCgsgAygCyAEEQAJAAkBB2MrmACgCAA0AQajF5gAtAAAiAkEBa0ECTwRAIAJFDQFBoMXmABC5CkH/AXEiAkUNAQtBoMXmACgCACACENUVRQ0AQaDF5gAoAgAiAigCICIERQ0HIAIoAiQhBSACKAIcIQcgAyACKAIoNgLcAiADIAU2AtgCIAMgBDYC1AIgAyAHNgLQAiADQezVxgA2ApgFIANBADYC4AIgA0ECNgK8AyADQaDZxgA2ArgDIANCATcCxAMgA0EKNgKkBCADIAMoAsgBNgKsBCADIANBuANqNgKUBSADIANB0AJqNgKQBSADIANBoARqNgLAAyADIANBrARqNgKgBCADQYAFaiACQRxqIANBkAVqEP0dIANByARqIANBiAVqKAIANgIAIAMgAykCgAU3A8AEQaDF5gAoAgAgA0HABGoiAhD3F0Hg0OYALQAADQFB0NDmACgCAEEFSQ0BIANBBTYC0AQgA0GgxeYAKAIAIgQpAhQ3AtQEIANBGGoQxhkgAygCGCIFIANB0ARqIAMoAhwiBygCDBEAAEUNASADQfAEaiADQdgEaigCADYCACADIAMpAtAENwPoBCAEIAUgByADQegEaiACEPcJDAELQeDQ5gAtAAANAEHQ0OYAKAIAQQVJDQAgA0EFNgLEAiADQaDF5gAoAgAiBCkCFDcCyAIgA0EQahDGGSADKAIQIgUgA0HEAmogAygCFCIHKAIMEQAARQ0AQaDF5gAoAgAiAigCICIGRQ0HIAIoAighCCACKAIkIQkgAigCHCEKIANBADYC4AIgAyAINgLcAiADIAk2AtgCIAMgBjYC1AIgAyAKNgLQAiADQezVxgA2AtgEIANBAjYCvAMgA0Gg2cYANgK4AyADQgE3AsQDIANBCjYChAUgAyADKALIATYCwAQgAyADQbgDajYC1AQgAyADQdACajYC0AQgAyADQYAFajYCwAMgAyADQcAEajYCgAUgA0GQBWoiBiACQRxqIANB0ARqEP0dIANB8ARqIANBzAJqKAIANgIAIAMgAykCxAI3A+gEIAQgBSAHIANB6ARqIAYQ9wkLIANBwANqIANByAFqKAIANgIAIAMgAykCwAE3A7gDIANB0AJqIQQjAEGwAWsiAiQAIAJBGGogAUEEaiADQbgDahCRDgJAAkACQAJAAkAgAigCGEGAgICAeEcEQCACQTBqIAJBIGopAgA3AwAgAiACKQIYNwMoIAEQwiVFDQECQEHYyuYAKAIAQQNLDQBBpMHmAC0AACIBQQFrQQJPBEAgAUUNAUGcweYAELkKQf8BcSIBRQ0BC0GcweYAKAIAIAEQ1RVFDQBBnMHmACgCACIBKAIgIgVFDQMgASgCKCEHIAEoAiQhBiABKAIcIQggAkEANgJ4IAIgBzYCdCACIAY2AnAgAiAFNgJsIAIgCDYCaCACQezVxgA2AmQgAkEANgKMASACQQE2AoABIAJB5NXGADYCfCACQgQ3AoQBIAIgAkH8AGo2AmAgAiACQegAajYCXCACQcQAaiABQRxqIAJB3ABqEP0dIAJBQGsgAkHMAGooAgA2AgAgAiACKQJENwM4QZzB5gAoAgAgAkE4aiIBEPcXQeDQ5gAtAAANBUHQ0OYAKAIAQQJJDQUgAkECNgKUASACQZzB5gAoAgAiBSkCFDcCmAEgAkEQahDGGSACKAIQIgcgAkGUAWogAigCFCIGKAIMEQAARQ0FIAJBqAFqIAJBnAFqKAIANgIAIAIgAikClAE3A6ABIAUgByAGIAJBoAFqIAEQ9wkMBQtB4NDmAC0AAA0EQdDQ5gAoAgBBAkkNBCACQQI2AlAgAkGcweYAKAIAIgUpAhQ3AlQgAkEIahDGGSACKAIIIgcgAkHQAGogAigCDCIGKAIMEQAARQ0EQZzB5gAoAgAiASgCICIIRQ0DIAEoAighCSABKAIkIQogASgCHCEMIAJBADYCeCACIAk2AnQgAiAKNgJwIAIgCDYCbCACIAw2AmggAkHs1cYANgKcASACQQA2AowBIAJBATYCgAEgAkHk1cYANgJ8IAJCBDcChAEgAiACQfwAajYCmAEgAiACQegAajYClAEgAkHcAGoiCCABQRxqIAJBlAFqEP0dIAJBqAFqIAJB2ABqKAIANgIAIAIgAikCUDcDoAEgBSAHIAYgAkGgAWogCBD3CQwECyAEQTA6AAAMBAsgAkEBNgKAASACQeTUxgA2AnwgAkIBNwKIASACQacGNgJsIAIgAkHoAGo2AoQBIAIgAkEoajYCaCACQfwAakHs1MYAEPcYAAtB/NTGAEEiQaDVxgAQuREAC0H81MYAQSJBoNXGABC5EQALIARBLzoAACACQShqIgEQjxcgARD2IAsgAkGwAWokACADLQDQAkEwRgRAIABBMDoAAAwKCyADQbgDaiADQdACakHoAPwKAAACQAJAQdjK5gAoAgBBBEsNAEHMxeYALQAAIgJBAWtBAk8EQCACRQ0BQcTF5gAQuQpB/wFxIgJFDQELQcTF5gAoAgAgAhDVFUUNAEHExeYAKAIAIgEoAiAiAkUNCSABKAIkIQQgASgCHCEFIAMgASgCKDYC3AQgAyAENgLYBCADIAI2AtQEIAMgBTYC0AQgA0Hs1cYANgLIBCADQQA2AuAEIANBATYC7AQgA0Hg2cYANgLoBCADQgE3AvQEIANBAjYCsAQgAyADQegEajYCxAQgAyADQdAEajYCwAQgAyADQawEajYC8AQgAyADQbgDajYCrAQgA0GgBGoiAiABQRxqIANBwARqEP0dQcTF5gAoAgAgAhD3F0Hg0OYALQAADQFB0NDmACgCAEUNASADQQE2AoAFIANBxMXmACgCACIBKQIUNwKEBSADQQhqEMYZIAMoAggiBCADQYAFaiADKAIMIgUoAgwRAABFDQEgA0GYBWogA0GIBWooAgA2AgAgAyADKQKABTcDkAUgASAEIAUgA0GQBWogAhD3CQwBC0Hg0OYALQAADQBB0NDmACgCAEUNACADQQE2ArQEIANBxMXmACgCACICKQIUNwK4BCADEMYZIAMoAgAiBCADQbQEaiADKAIEIgUoAgwRAABFDQBBxMXmACgCACIBKAIgIgdFDQkgASgCKCEGIAEoAiQhCCABKAIcIQkgA0EANgLgBCADIAY2AtwEIAMgCDYC2AQgAyAHNgLUBCADIAk2AtAEIANB7NXGADYCiAUgA0EBNgLsBCADQeDZxgA2AugEIANCATcC9AQgA0ECNgKkBCADIANB6ARqNgKEBSADIANB0ARqNgKABSADIANBoARqNgLwBCADIANBuANqNgKgBCADQcAEaiIHIAFBHGogA0GABWoQ/R0gA0GYBWogA0G8BGooAgA2AgAgAyADKQK0BDcDkAUgAiAEIAUgA0GQBWogBxD3CQsgACADQbgDakHoAPwKAAAgCw0KIANBtAFqIgAQjxcgABD2IAwKCyAAQTA6AAAgA0HAAWoiABCPFyAAEPYgDAgLQfzUxgBBIkGI2MYAELkRAAtB/NTGAEEiQYjYxgAQuREAC0H81MYAQSJBxNjGABC5EQALQfzUxgBBIkHE2MYAELkRAAtB/NTGAEEiQYDZxgAQuREAC0H81MYAQSJBgNnGABC5EQALQfzUxgBBIkGw2cYAELkRAAtB/NTGAEEiQbDZxgAQuREACyALDQAgA0G0AWoiABCPFyAAEPYgCyADQaAFaiQAC5NlAjJ/BH4jAEHQBWsiAiQAIAAoAgQiBgRAIAAoAgAoAghBCGohBANAIAYoApgEIARGDQALIAYoAqAEISMLIAAoAgBBDGogASgCACIkEMAIIAJBlANqISogAkGwA2ohKyACQaQDaiEbIAJBnANqISwgAkGYA2ohFyACQYgDaiIBQQRyIRQgAkGQA2ohFiACQagDaiEtIAFBAXIhJSACQYwDaiEuIAJBoANqIS9BACEBAkACfwJAAkADQAJAIAJB0ABqIAAoAgBBCGoQ9QsCfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAn8CQAJAAkACQAJAAkACQAJAAkAgAigCUCIEBEAgBEECaw0BDB8LIAIoAlQiBSgCAEUEQCACIAVBCGsiBDYCiAMgBCAEKAIAIgRBAWs2AgAgBEEBRw0gIAJBiANqEOUODCALIAAgBRCPDSIaLQC0BCAaQQA6ALQERQ0jIBpBADoAtQQgAiAaQQhqNgJgIAJB9PvDADYCXCACQQA2AmwgBUEIaiEYIAIgAkHcAGoiBDYCaCACIAQ2AmQCQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIAUtALACQQFrDgQUCQEIAAsgGCAFKAKoAkHEAGpBwAH8CgAAAkACQEHYyuYAKAIADQBBtL/mAC0AACIJQQFrQQJPBEAgCUUNAUGsv+YAELkKQf8BcSIJRQ0BC0Gsv+YAKAIAIAkQ1RVFDQBBrL/mACgCACIHKAIgIglFDRAgBygCJCEGIAcoAhwhBCACIAcoAig2AtQEIAIgBjYC0AQgAiAJNgLMBCACIAQ2AsgEIAJB9PzDADYCmAUgAkEANgLYBCACQQI2AowDIAJB1P7DADYCiAMgAkIBNwKUAyACQQM2AsQFIAIgGDYCwAUgAiACQYgDajYClAUgAiACQcgEajYCkAUgAiACQcAFajYCkAMgAkH4AWogB0EcaiACQZAFahD9HSACQeABaiACQYACaigCADYCACACIAIpAvgBNwPYAUGsv+YAKAIAIAJB2AFqIgcQ9xdB4NDmAC0AAA0BQdDQ5gAoAgBBBUkNASACQQU2AoABIAJBrL/mACgCACIJKQIUNwKEASACQcgAahDGGSACKAJIIgYgAkGAAWogAigCTCIEKAIMEQAARQ0BIAJBoAJqIAJBiAFqKAIANgIAIAIgAikCgAE3A5gCIAkgBiAEIAJBmAJqIAcQ9wkMAQtB4NDmAC0AAA0AQdDQ5gAoAgBBBUkNACACQQU2AnQgAkGsv+YAKAIAIgcpAhQ3AnggAkFAaxDGGSACKAJAIgkgAkH0AGogAigCRCIGKAIMEQAARQ0AQay/5gAoAgAiCigCICIERQ0QIAooAighECAKKAIkIREgCigCHCETIAJBADYC2AQgAiAQNgLUBCACIBE2AtAEIAIgBDYCzAQgAiATNgLIBCACQfT8wwA2AogBIAJBAjYCjAMgAkHU/sMANgKIAyACQgE3ApQDIAJBAzYC/AEgAiAYNgL4ASACIAJBiANqNgKEASACIAJByARqNgKAASACIAJB+AFqNgKQAyACQZAFaiIEIApBHGogAkGAAWoQ/R0gAkGgAmogAkH8AGooAgA2AgAgAiACKQJ0NwOYAiAHIAkgBiACQZgCaiAEEPcJCyAFQQA6AMwCIAUgBSgCqAIiCTYCuAIgBUHMAmohDiAFQbgCaiEiDAELIAVBuAJqISIgBUHMAmohDgJAIAUtAMwCQQFrDgQFCAIVAAsgIigCACEJCyAFIAk2ArwCIAJBiANqIgYgCRCGEiACKAKIA0GAgICAeEYEQCAFKAK8AiIEKAJAIRAgBiAEQcQAakHAAfwKAAAgAkEANgKYBSACQoCAgIAQNwKQBSACQez/wwA2AoQBIAJCoICAgA43AogBIAIgAkGQBWo2AoABIAYgAkGAAWoQqg0NDyACKQKUBSE1IAIoApAFIQ9BMSEIDBYLIAUgAikCiAM3AsACIAVByAJqIBYoAgA2AgAgBUHAAmohCgJAAkBB2MrmACgCAA0AQby+5gAtAAAiCEEBa0ECTwRAIAhFDQFBtL7mABC5CkH/AXEiCEUNAQtBtL7mACgCACAIENUVRQ0AQbS+5gAoAgAiBigCICIERQ0RIAYoAiQhESAGKAIcIRMgAiAGKAIoNgKcBSACIBE2ApgFIAIgBDYClAUgAiATNgKQBSACQQA2AqAFIAJBiANqIgQgBSgCvAJBxABqQcAB/AoAACACQQM2AoQBIAJB3PzDADYCgAEgAkICNwKMASACQfT8wwA2AvQCIAJBvAI2AuQBIAIgCjYC4AEgAkEDNgLcASACIAJB2AFqNgKIASACIAJBgAFqNgLwAiACIAJBkAVqNgLsAiACIAQ2AtgBIAJB4AJqIAZBHGoiECACQewCahD9HSACQcgBaiACQegCaigCADYCACACIAIpAuACNwPAAUG0vuYAKAIAIAJBwAFqIgcQ9xdB4NDmAC0AAA0BQdDQ5gAoAgBBBUkNASACQQU2ArQFIAJBtL7mACgCACIJKQIUNwK4BSACQThqEMYZIAIoAjgiBiACQbQFaiACKAI8IgQoAgwRAABFDQEgAkHIBWogAkG8BWooAgA2AgAgAiACKQK0BTcDwAUgCSAGIAQgAkHABWogBxD3CQwBC0Hg0OYALQAADQBB0NDmACgCAEEFSQ0AIAJBBTYCzAEgAkG0vuYAKAIAIgcpAhQ3AtABIAJBMGoQxhkgAigCMCIQIAJBzAFqIAIoAjQiESgCDBEAAEUNAEG0vuYAKAIAIgsoAiAiE0UNESALKAIoIQkgCygCJCEGIAsoAhwhBCACQQA2AqAFIAIgCTYCnAUgAiAGNgKYBSACIBM2ApQFIAIgBDYCkAUgAkGIA2oiBCAFKAK8AkHEAGpBwAH8CgAAIAJBAzYChAEgAkHc/MMANgKAASACQgI3AowBIAJB9PzDADYCvAUgAkG8AjYC5AEgAiAKNgLgASACQQM2AtwBIAIgAkHYAWo2AogBIAIgAkGAAWo2ArgFIAIgAkGQBWo2ArQFIAIgBDYC2AEgAkHsAmoiBCALQRxqIh0gAkG0BWoQ/R0gAkHIBWogAkHUAWooAgA2AgAgAiACKQLMATcDwAUgByAQIBEgAkHABWogBBD3CQsgBUEAOgDYAiAFIAUoAsgCIgk2AtQCIAUgBSgCxAIiCDYC0AIMAQsgBS0A2AJBAXENASAFKALUAiEJIAUoAtACIQgLIAJBiANqIAggCRD9ByACKAKIAyIPDQIgAkGAAWoiBCAuQST8CgAAIAQQgxkgAkHwAWogAkGoBWopAwAiNjcDACACQegBaiACQaAFaikDACI3NwMAIAVBAToA2AIgAkGAAmogAkGYBWopAwAiNDcDACACQYgCaiA3NwMAIAJBkAJqIDY3AwAgAkHQBGogNDcDACACQdgEaiA3NwMAIAJB4ARqIDY3AwAgAiACKQOQBSI1NwP4ASACIDU3A8gEQRohCAwUC0Hc/8MAELUXAAtBhP3DABC1FwALIAJB4AFqIBtBCGopAAAiNDcDACACQZACaiIJIBtBGGopAAA3AwAgAkGIAmoiBiAbQRBqKQAANwMAIAJBgAJqIgQgNDcDACACIBspAAAiNDcD2AEgAiA0NwP4ASACKQKMAyE3IAIpApQDITQgBSACKQKcAzcC6AIgBSA0NwLgAiAFIDc3AtgCIAUgDzYC1AIgBUKAgICAMDcDoANBACEZIAVBADYCmAMgBUKAgICAgAE3ApADIAUgAikD+AE3AvACIAVB+AJqIAQpAwA3AgAgBUGAA2ogBikDADcCACAFQYgDaiAJKQMANwIAQQMhJkEADA8LAkAgBS0A8AJBAWsOAwUBABMLAkACQCAFLQDsAkEBaw4DBQIBAAsgBSgCvAIhCQwUCyAFQcACaiEOIAUtAMgCQQFrDgQMAAIWAQsACyAOKAIAIQkMEgsgBSgCxAIhCQwSC0HkgcQAELUXAAtB1IHEABC1FwALQQIgACgCBA0hGiAAQQE6AAhBAAwhC0GE/MMAQSJBrP7DABC5EQALQYT8wwBBIkGs/sMAELkRAAtBlIDEAEE3IAJB2AFqQYSAxABBzIDEABCpDgALQYT8wwBBIkGo/MMAELkRAAtBhPzDAEEiQaj8wwAQuREAC0Hk/sMAELUXAAtB9IHEABC1FwALQQELIQkDQAJAAkACQAJAAkACQCAJRQRAIBkgJk8NASAFIBlBAWo2AqADIAJBgAFqQgFBABCfDyAFIAVBqANqNgKcAyAFQQA6APQDIAUgBUGQA2o2AuQDIAUgBUHUAmo2AuADIAUgBUGcA2o2AsgDIAVBADoA0AIgBSAFQcgDajYCxAMgBSAFQdACajYCwAMgBUG4A2ogAkGQAWopAwA3AwAgBUGwA2ogAkGIAWopAwA3AwAgBSACKQOAATcDqANBASEJDAcLIAJBiANqIScgBUHAA2ohCSACQeQAaiEeQQAhCiMAQdADayIDJAACQBCoIEH/AXEiBEECRiAEQQFxckUEQCAeEK0iQcMAIQcMAQtBAhDpGCEwIAkoAgQiDUE0aiEoIA1BMGohBiANQSBqISkgDUEIaiExIANB4AJqQQFyITIgA0GYAWohHyADQZQBaiEgIANBtAFqISEgCSgCACEcQQEhCUEAIQcDQAJAAkACQAJAAkACQAJAAkACQAJ/AkACQCANAn8CQAJAAkACQCAHIAcgMGoiBE0EQCAcLQAAIQcgBEEBcUUEQCAHQQFxDRJBASEKIA0oAgAoAgAgHhC7Cw0SIBwgHC0AAEEBcjoAAEHAACEHDBQLIAdBAnENEQJAAkACQCANLQAsQQFrDgQGAAIFAQsAC0EDQQEQhCEiBEUNAiAEQQM6AAIgBEGBBDsAACANQQM2AiggDSAENgIkIA1BAzYCICAxEMAYIA0oAhghBCADQZABaiApEK8OIA1BgoCAgHg2AjAgDSAENgJIICggAykCkAE3AgAgKEEIaiAfKAIANgIACyADQbABaiELIwBBIGsiCCQAAkACQAJAAkAgBigCAEGFgICAeEYNACAIQQhqIQojAEEwayIMJAAgDEEYaiAGKAIYIgcgHhCADQJAAkACQAJAAkAgDCgCGCIEQfH///8Hag4CAAIBCyAGKAIAIQQgBkGFgICAeDYCACAEQYWAgIB4Rg0CIAxBDGogBkEMaikCADcCACAMQRRqIAZBFGooAgA2AgAgDCAENgIAIAwgBikCBDcCBCAMQRhqIAcgDBCcCiAMKAIYIgRBj4CAgHhHBEAgCiAMKQIcNwIEIApBFGogDEEsaigCADYCACAKQQxqIAxBJGopAgA3AgAgCiAENgIADAQLIApBj4CAgHg2AgAMAwsgCiAMKQIcNwIEIApBFGogDEEsaigCADYCACAKQQxqIAxBJGopAgA3AgALIAogBDYCAAwBC0Gg+sMAQRxBvPrDABC5EQALIAxBMGokACAIKAIIIgRB8f///wdqDgIAAgELIAhBCGogBigCGBDXJAJAAkACQCAIKAIIIgRB8f///wdqDgIAAgELIAtBj4CAgHg2AgAMBAsgCyAIKQIMNwIEIAtBFGogCEEcaigCADYCACALQQxqIAhBFGopAgA3AgALIAsgBDYCAAwCCyALIAgpAgw3AgQgC0EUaiAIQRxqKAIANgIAIAtBDGogCEEUaikCADcCAAsgCyAENgIACyAIQSBqJABBAyADKAKwASIIQZCAgIB4Rg0FGiADQYgBaiILICFBEGoiCigCADYCACADQYABaiIHICFBCGoiBCkCADcDACADICEpAgA3A3ggBigCAEGFgICAeEcEQCAGEL0NCyAIQY+AgIB4RwRAICEgAykDeDcCACAKIAsoAgA2AgAgBCAHKQMANwIAIAMgCDYCsAEgA0HgAmogA0GwAWoQ2xIMCAsgDSANKAIYIgc2AjAMBAtBiPDDABCuFwALQQFBAxDhIwALIAYoAgAhBwwBC0Go8MMAELUXAAsgA0GwAWogByAeENgIIAMoArABQQNHDQFBBAs6ACwMAwsgA0GoAWogA0HIAWooAgA2AgAgA0GgAWogA0HAAWopAgA3AwAgHyADQbgBaikCADcDACADIAMpArABIjQ3A5ABIDSnIgRBAkcEQCAEQQFxBEAgA0HYAmogIEEQaikCADcDACADQdACaiAgQQhqKQIANwMAIAMgICkCADcDyAIgA0HgAmogA0HIAmoQ2xIMAgsCQCADKAKUAUGDgICAeEYEQCADQdgBaiAfQQhqKAIAIgQ2AgAgAyAfKQIANwPQAQJAAkAgDSgCKCAERgRAIAMoAtQBIA0oAiQgBBCaE0UNAQsCQEHYyuYAKAIAQQNLDQBB4L7mAC0AACIHQQFrQQJPBEAgB0UNAUHYvuYAELkKQf8BcSIHRQ0BC0HYvuYAKAIAIAcQ1RVFDQBB2L7mACgCACIIKAIgIgtFDQogCCgCKCEKIAgoAiQhByAIKAIcIQQgA0EANgLEAiADIAo2AsACIAMgBzYCvAIgAyALNgK4AiADIAQ2ArQCIANBqPHDADYCyAMgA0EANgLAASADQQE2ArQBIANBoPHDADYCsAEgA0IENwK4ASADIANBsAFqNgLEAyADIANBtAJqNgLAAyADQagCaiILIAhBHGogA0HAA2oQ/R0jAEEwayIIJABB2L7mACgCACALEPcXAkBB4NDmAC0AAA0AQdDQ5gAoAgBBAkkNACAIQQI2AhQgCEHYvuYAKAIAIgopAhQ3AhggCEEIahDGGSAIKAIIIgcgCEEUaiAIKAIMIgQoAgwRAABFDQAgCEEoaiAIQRxqKAIANgIAIAggCCkCFDcDICAKIAcgBCAIQSBqIAsQ9wkLIAhBMGokAAwCC0Hg0OYALQAADQFB0NDmACgCAEECSQ0BIANBAjYChAIgA0HYvuYAKAIAIhUpAhQ3AogCIANBCGoQxhkgAygCCCIMIANBhAJqIAMoAgwiCCgCDBEAAEUNAUHYvuYAKAIAIhIoAiAiC0UNCiASKAIoIQogEigCJCEHIBIoAhwhBCADQQA2AsQCIAMgCjYCwAIgAyAHNgK8AiADIAs2ArgCIAMgBDYCtAIgA0Go8cMANgKwAiADQQA2AsABIANBATYCtAEgA0Gg8cMANgKwASADQgQ3ArgBIAMgA0GwAWo2AqwCIAMgA0G0Amo2AqgCIANBnAJqIgQgEkEcaiADQagCahD9HSADQcgDaiADQYwCaigCADYCACADIAMpAoQCNwPAAyAVIAwgCCADQcADaiAEEPcJDAELIANBsAFqIgwQwBggDSkDCCE0IA0oAhAhBCMAQRBrIgokACAKIAwgNCAEEMwNIAopAwAhNCADQeABaiIIIgdBACAKKAIIIgQgBEGAlOvcA0YiBBs2AgggB0IAIDQgBBs3AwAgCkEQaiQAAkACQEHYyuYAKAIADQBB1L7mAC0AACIEQQNPBH9BzL7mABC5CkH/AXEFIAQLQf8BcSIERQ0AQcy+5gAoAgAgBBDVFUUNAEHMvuYAKAIAIhUoAiAiC0UNDCAVKAIoIQogFSgCJCEHIBUoAhwhBCADQQA2AsQCIAMgCjYCwAIgAyAHNgK8AiADIAs2ArgCIAMgBDYCtAIgA0Go8cMANgLIAyADQQE2ArQBIANB3PHDADYCsAEgA0IBNwK8ASADQQs2AqACIAMgDDYCxAMgAyADQbQCajYCwAMgAyADQZwCajYCuAEgAyAINgKcAiADQagCaiILIBVBHGogA0HAA2oQ/R0jAEEwayIIJABBzL7mACgCACALEPcXAkBB4NDmAC0AAA0AQdDQ5gAoAgBBBUkNACAIQQU2AhQgCEHMvuYAKAIAIgopAhQ3AhggCEEIahDGGSAIKAIIIgcgCEEUaiAIKAIMIgQoAgwRAABFDQAgCEEoaiAIQRxqKAIANgIAIAggCCkCFDcDICAKIAcgBCAIQSBqIAsQ9wkLIAhBMGokAAwBC0Hg0OYALQAADQBB0NDmACgCAEEFSQ0AIANBBTYC8AEgA0HMvuYAKAIAIhUpAhQ3AvQBIAMQxhkgAygCACIMIANB8AFqIAMoAgQiCCgCDBEAAEUNAEHMvuYAKAIAIhIoAiAiC0UNDCASKAIoIQogEigCJCEHIBIoAhwhBCADQQA2AsQCIAMgCjYCwAIgAyAHNgK8AiADIAs2ArgCIAMgBDYCtAIgA0Go8cMANgKwAiADQQE2ArQBIANB3PHDADYCsAEgA0IBNwK8ASADQQs2AoACIAMgA0GwAWo2AqwCIAMgA0G0Amo2AqgCIAMgA0H8AWo2ArgBIAMgA0HgAWo2AvwBIANBnAJqIgQgEkEcaiADQagCahD9HSADQcgDaiADQfgBaigCADYCACADIAMpAvABNwPAAyAVIAwgCCADQcADaiAEEPcJCyADKALoASEHIAMpA+ABITQgDSgCHCILKAIIIgogCygCAEYEQCALQeTxwwAQ/BMLIAsoAgQgCkEEdGoiBCAHNgIIIAQgNDcDACALIApBAWo2AggLIANB0AFqEPMhDAELAkACQEHYyuYAKAIAQQNLDQBByL7mAC0AACIHQQFrQQJPBEAgB0UNAUHAvuYAELkKQf8BcSIHRQ0BC0HAvuYAKAIAIAcQ1RVFDQBBwL7mACgCACIIKAIgIgtFDQwgCCgCKCEKIAgoAiQhByAIKAIcIQQgA0EANgLEAiADIAo2AsACIAMgBzYCvAIgAyALNgK4AiADIAQ2ArQCIANBqPHDADYCyAMgA0EANgLAASADQQE2ArQBIANBrPLDADYCsAEgA0IENwK4ASADIANBsAFqNgLEAyADIANBtAJqNgLAAyADQagCaiILIAhBHGogA0HAA2oQ/R0jAEEwayIIJABBwL7mACgCACALEPcXAkBB4NDmAC0AAA0AQdDQ5gAoAgBBAkkNACAIQQI2AhQgCEHAvuYAKAIAIgopAhQ3AhggCEEIahDGGSAIKAIIIgcgCEEUaiAIKAIMIgQoAgwRAABFDQAgCEEoaiAIQRxqKAIANgIAIAggCCkCFDcDICAKIAcgBCAIQSBqIAsQ9wkLIAhBMGokAAwBC0Hg0OYALQAADQBB0NDmACgCAEECSQ0AIANBAjYCkAIgA0HAvuYAKAIAIhUpAhQ3ApQCIANBEGoQxhkgAygCECIMIANBkAJqIAMoAhQiCCgCDBEAAEUNAEHAvuYAKAIAIhIoAiAiC0UNDCASKAIoIQogEigCJCEHIBIoAhwhBCADQQA2AsQCIAMgCjYCwAIgAyAHNgK8AiADIAs2ArgCIAMgBDYCtAIgA0Go8cMANgKwAiADQQA2AsABIANBATYCtAEgA0Gs8sMANgKwASADQgQ3ArgBIAMgA0GwAWo2AqwCIAMgA0G0Amo2AqgCIANBnAJqIgQgEkEcaiADQagCahD9HSADQcgDaiADQZgCaigCADYCACADIAMpApACNwPAAyAVIAwgCCADQcADaiAEEPcJCyAgEL0NCyADQT86AOACQT8MAgsgA0EbOgDgAgsgAy0A4AILIQcgKRDzISADQRlqIDJB3wD8CgAAIA1BAToALCAHQf8BcUHAAEcNAQtBASEKDAcLICdBAWogA0EZakHfAPwKAAAgHCAcLQAAQQJyOgAADAgLQbjwwwBBIkHc8MMAELkRAAtBuPDDAEEiQdzwwwAQuREAC0G48MMAQSJBuPHDABC5EQALQbjwwwBBIkG48cMAELkRAAtBuPDDAEEiQfTxwwAQuREAC0G48MMAQSJB9PHDABC5EQALQQEhByAJQQAhCQ0AC0HDAEHCACAKGyEHCyAnIAc6AAAgA0HQA2okACACLQCIAyIIQcMARgRAIA5BBDoAAEEBIQ5BAwwbCyACQd4CaiIEICVBAmotAAA6AAAgAiAlLwAAOwHcAiACKAKMAyEPIAIpA5ADITUgAigCmAMhECACKAKcAyETIAIoAqADIREgAigCpAMhHSACQZgCaiAtQcAA/AoAACAFQcgDahC2FgJAAkACQAJAAkBBASAIQUBqIAhBP00bQf8BcUEBaw4CAgABCyACQQA2ApgDIAJBATYCjAMgAkGU/sMANgKIAyACQgQ3ApADIAJBiANqQZz+wwAQ9xgACwJAQdjK5gAoAgBBA0sNAEGwvuYALQAAIhlBAWtBAk8EQCAZRQ0BQai+5gAQuQpB/wFxIhlFDQELQai+5gAoAgAgGRDVFUUNAEGovuYAKAIAIgcoAiAiCUUNByAHKAIoIQYgBygCJCEEIAcoAhwhDyACQQA2AqAFIAIgBjYCnAUgAiAENgKYBSACIAk2ApQFIAIgDzYCkAUgAkH0/MMANgK8BSACQQA2ApgDIAJBATYCjAMgAkHU/cMANgKIAyACQgQ3ApADIAIgAkGIA2o2ArgFIAIgAkGQBWo2ArQFIAJB7AJqIAdBHGogAkG0BWoQ/R0gAkHoAmogAkH0AmooAgA2AgAgAiACKQLsAjcD4AJBqL7mACgCACACQeACaiIHEPcXQeDQ5gAtAAANAkHQ0OYAKAIAQQJJDQIgAkECNgLABSACQai+5gAoAgAiCSkCFDcCxAUgAkEoahDGGSACKAIoIgYgAkHABWogAigCLCIEKAIMEQAARQ0CIAJB4AFqIAJByAVqKAIANgIAIAIgAikCwAU3A9gBIAkgBiAEIAJB2AFqIAcQ9wkMAgtB4NDmAC0AAA0BQdDQ5gAoAgBBAkkNASACQQI2AvgCIAJBqL7mACgCACIHKQIUNwL8AiACQSBqEMYZIAIoAiAiCSACQfgCaiACKAIkIgYoAgwRAABFDQFBqL7mACgCACIKKAIgIg9FDQcgCigCKCEQIAooAiQhESAKKAIcIRMgAkEANgKgBSACIBA2ApwFIAIgETYCmAUgAiAPNgKUBSACIBM2ApAFIAJB9PzDADYCyAUgAkEANgKYAyACQQE2AowDIAJB1P3DADYCiAMgAkIENwKQAyACIAJBiANqNgLEBSACIAJBkAVqNgLABSACQbQFaiIEIApBHGogAkHABWoQ/R0gAkHgAWogAkGAA2ooAgA2AgAgAiACKQL4AjcD2AEgByAJIAYgAkHYAWogBBD3CQwBCyAIQT9HDQELIAVBqANqEPQWIAUoAqQDISYgBSgCoAMhGQwGCyACQY4FaiAELQAAOgAAIAIgAi8B3AI7AYwFIAJByARqIAJBmAJqQcAA/AoAACAFQagDahD0FgwBCyAFKAKYAyIKDQEgAkGIA2oiBCAFKAK8AkHEAGpBwAH8CgAAIAJBgAFqIAQQnxAgAigCgAEhDyACKQKEASE1QR4hCAsgBUGQA2pBCEEQEK4OIAVB1AJqEK4NDAYLIAIgBSgCkAM2ApADIAIgBSgClAMiBDYCiAMgAiAENgKMAyACIAQgCkEEdGo2ApQDIAJBgAFqIQdCACE1QgAhNiMAQRBrIgskACACQYgDaiIEKAIIIQkgBCgCACEGAkACQAJAIAQoAgQiCCAEKAIMIgRGDQADQAJAAn4CQCAIKQMAIjQgNnwiNiA0WgRAIDUgCEEIajUCACI3fCI0IDVUDQEgNAwCCwwFCyA2IDYgNUKAlOvcA4AiNHwiNlYNASA1IDRCgJTr3AN+fSA3fAshNSAEIAhBEGoiCEcNAQwCCwsMAQsgCyAGNgIMIAsgCTYCCCALQQhqQQhBEBCuDiA2IDYgNUKAlOvcA4AiN3wiNFYNACAHIDQ3AwAgByA1IDdCgJTr3AN+fT4CCCALQRBqJAAMAQtBkPDEAEEkQbTwxAAQuREACyAFKAK8AiERIAI1AogBIAIpA4ABIAVB1AJqEK4NIAVBwAJqEPMhQoCU69wDfnwgCq2AIjQgNEKAlOvcA4AiNUKAlOvcA359pyEQQT8hCAwEC0GE/MMAQSJBlP3DABC5EQALQYT8wwBBIkGU/cMAELkRAAtBACEJDAALAAsgAkHuAmogAkGOBWotAAA6AAAgAiACLwGMBTsB7AIgAkGAAWogAkHIBGpBwAD8CgAAIA5BAToAAAwBCyAFQcACahDzISACQe4CaiACQY4Fai0AADoAACACIAIvAYwFOwHsAiACQYABaiACQcgEakHAAPwKAABBASEOIAVBAToAzAJBAyAIQcAARg0RGgsgBSAIOgDIASAFIAIvAewCOwDJASAFIB02AuQBIAUgETYC4AEgBSATNgLcASAFIBA2AtgBIAUgNTcD0AEgBSAPNgLMASAFQcsBaiACQe4Cai0AADoAACAFQegBaiACQYABakHAAPwKAAAgIhDgEyAFLQDIAUE/Rw0FIAUgBUHQAWoiBCkDADcD+AIgBUGIA2ogBEEQaikDADcDACAFQYADaiAEQQhqKQMANwMAIAVB+AJqIQcCQAJAQdjK5gAoAgBBAUsNAEHAv+YALQAAIg5BAWtBAk8EQCAORQ0BQbi/5gAQuQpB/wFxIg5FDQELQbi/5gAoAgAgDhDVFUUNAEG4v+YAKAIAIgkoAiAiBkUNCiAJKAIkIQ8gCSgCHCEEIAIgCSgCKDYC1AQgAiAPNgLQBCACIAY2AswEIAIgBDYCyAQgAkH0/MMANgLgASACQQA2AtgEIAJBAjYCjAMgAkGI/8MANgKIAyACQgI3ApQDIAJBCzYCpAIgAiAHNgKgAiACQQM2ApwCIAIgGDYCmAIgAiACQYgDajYC3AEgAiACQcgEajYC2AEgAiACQZgCajYCkAMgAkHABWoiByAJQRxqIAJB2AFqEP0dQbi/5gAoAgAgBxD3F0Hg0OYALQAADQFB0NDmACgCAEEESQ0BIAJBBDYC+AEgAkG4v+YAKAIAIgkpAhQ3AvwBIAJBCGoQxhkgAigCCCIGIAJB+AFqIAIoAgwiBCgCDBEAAEUNASACQZgFaiACQYACaigCADYCACACIAIpAvgBNwOQBSAJIAYgBCACQZAFaiAHEPcJDAELQeDQ5gAtAAANAEHQ0OYAKAIAQQRJDQAgAkEENgLABSACQbi/5gAoAgAiCSkCFDcCxAUgAhDGGSACKAIAIg8gAkHABWogAigCBCIGKAIMEQAARQ0AQbi/5gAoAgAiCigCICIQRQ0KIAooAighESAKKAIkIRMgCigCHCEdIAJBADYC2AQgAiARNgLUBCACIBM2AtAEIAIgEDYCzAQgAiAdNgLIBCACQfT8wwA2AoACIAJBAjYCjAMgAkGI/8MANgKIAyACQgI3ApQDIAJBCzYCpAIgAiAHNgKgAiACQQM2ApwCIAIgGDYCmAIgAiACQYgDajYC/AEgAiACQcgEajYC+AEgAiACQZgCajYCkAMgAkHYAWoiBCAKQRxqIAJB+AFqEP0dIAJBmAVqIAJByAVqKAIANgIAIAIgAikCwAU3A5AFIAkgDyAGIAJBkAVqIAQQ9wkLIAUoAqwCKAIAIQQgBUEAOgDwAiAFIARBCGo2ArgCCyAFQQA6AOwCIAUgBSgCuAIiCTYCvAILIAVBADoAyAIgBSAJNgLAAiAFQcACaiEOCyAFIAk2AsQCCyACQYgDaiAJQQEQuBkgBUHkAmogLykCADcCACAFQdwCaiAXKQIANwIAIAVB1AJqIBYpAgA3AgAgBSACKQKIAzcCzAILIAVBzAJqIgQgAkHkAGoQ2gNB/wFxIgZBAkYNASAEEJIOIAUoAtACIgQEQCAFKALUAiAEKAIMEQIACyAGQQFxRQ0CQYSCxABBKEGsgsQAEJwVAAsgAkGIA2ogBUHIAWpB4AD8CgAAAkACQEHYyuYAKAIAQQNLDQBBzL/mAC0AACIJQQFrQQJPBEAgCUUNAUHEv+YAELkKQf8BcSIJRQ0BC0HEv+YAKAIAIAkQ1RVFDQBBxL/mACgCACIJKAIgIgZFDQYgCSgCJCEEIAkoAhwhDyACIAkoAig2AqQCIAIgBDYCoAIgAiAGNgKcAiACIA82ApgCIAJB9PzDADYCyAUgAkEANgKoAiACQQI2AswEIAJBvP/DADYCyAQgAkICNwLUBCACQb0CNgKcBSACQQM2ApQFIAIgGDYCkAUgAiACQcgEajYCxAUgAiACQZgCajYCwAUgAiACQZAFajYC0AQgAiACQYgDajYCmAUgAkG0BWogCUEcaiACQcAFahD9HSACQYADaiACQbwFaigCADYCACACIAIpArQFNwP4AkHEv+YAKAIAIAJB+AJqIgcQ9xdB4NDmAC0AAA0BQdDQ5gAoAgBBAkkNASACQQI2AtgBIAJBxL/mACgCACIJKQIUNwLcASACQRhqEMYZIAIoAhgiBiACQdgBaiACKAIcIgQoAgwRAABFDQEgAkGAAmogAkHgAWooAgA2AgAgAiACKQLYATcD+AEgCSAGIAQgAkH4AWogBxD3CQwBC0Hg0OYALQAADQBB0NDmACgCAEECSQ0AIAJBAjYCtAUgAkHEv+YAKAIAIgkpAhQ3ArgFIAJBEGoQxhkgAigCECIGIAJBtAVqIAIoAhQiDygCDBEAAEUNAEHEv+YAKAIAIgcoAiAiBEUNBiAHKAIoIRAgBygCJCERIAcoAhwhEyACQQA2AqgCIAIgEDYCpAIgAiARNgKgAiACIAQ2ApwCIAIgEzYCmAIgAkH0/MMANgLgASACQQI2AswEIAJBvP/DADYCyAQgAkICNwLUBCACQb0CNgKcBSACQQM2ApQFIAIgGDYCkAUgAiACQcgEajYC3AEgAiACQZgCajYC2AEgAiACQZAFajYC0AQgAiACQYgDajYCmAUgAkHABWoiBCAHQRxqIAJB2AFqEP0dIAJBgAJqIAJBvAVqKAIANgIAIAIgAikCtAU3A/gBIAkgBiAPIAJB+AFqIAQQ9wkLAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQEEEIAItAIgDIgRBBmsgBEEFTRtB/wFxDjcAAQYCAw8PGhoaBAUGBgYGGgcICRoaGhoPGhoPGhoKGhoPDw8PGhoaGhoPDwsMDQ4PDw8aGhAQGgsgFBDKGgwZCyAUEPMhAkACQAJAAkACQAJAAkACQAJAAkACQEEOIAIoApgDIgYtAAAiBEEOayAEQQ5JG0H/AXFBAWsOGgAiAQIiIiIDBAUGIiIHIiIiIiIiIiIICSIKIgsgBkEEahDzIQwhCwJAAkACQAJAAkACQAJAIAYtAAgOEycBAicnJycnJycnAycnBCcFJwYACyAGQQxqEPMhDCYLIAZBDGoQtRUMJQsgBkEMahC1FQwkC0EGIAYoAgwiBEELayAEQQpNGyIEQQVLDSEgBEECRw0jIAYoAhBBAEgNIyAGQRBqEPMhDCMLIAZBEGoQ2xAMIgsgBkEMahDzIQwhCyAGLQAnQQNHDSAgBigCDEUNICAGQQxqEP4VDCALIAZBBGoQmA8MHwsgBkEEahCDGQweCyAGQQRqEPMhIAZBEGoQmA8MHQsgBkEEahDzIQwcCyAGQQRqEPMhDBsLAkACQAJAAkACQAJAAkACQAJAIAQODQECAyMEBQYHCCMjIyMACyAGQQRqEPMhDCILIAZBCGoQiwMMIQsCQAJAAkACQAJAQQYgBi0ACCIEQQZrIARBBkkbQf8BcQ4GJQElAgMEAAsgBkEIahCKGAwkCyAGQRBqEIsDDCMLIAZBEGoQ2xAMIgsgBkEMahDzIQwhCyAGQQxqEIwfDCALIAZBBGoQ/hUMHwsgBigCCA0eIAZBDGoQ8yEMHgsgBkEIahDbEAwdCyAGQQhqEIoYDBwLAkACQAJAAkACQAJAAkACQAJAQQcgBi0ACCIEQQZrIARBBU0bQf8BcQ4PAAECJCQkAwQFBiQkJAcIJAsgBkEMahDKGgwjCyAGQQxqEPgSDCILIAZBDGoQ+BIMIQsgBkEQahDbEAwgCyAGQQhqEIoYDB8LIAZBDGoQmAQMHgsgBkEMahDzIQwdCyAGQRBqENsQDBwLIAZBDGoQ8yEMGwsgBigCBA0aIAYoAghFDRogBkEIahD+FQwaCyAGQQRqEPMhIAZBEGoQ8yEMGQsgBkEEahDzIQwYCyAGKAIEQQBIDRcgBkEEahDzIQwXCyACKAKMAw0XIAIoApADRQ0XDBULIAJBiANqEIoYDBYLIBQQmAQMFQsCQAJAAkACQAJAAkACQAJAQQogAigCjAMiBEGAgICAeHMgBEEAThsOEBwCAxwcHAEBHBwEHAUcBgcACyACKAKQA0GAgICAeEYNGwsgFhDzIQwaCyACKAKQA0HAAUEEEJ8gDBkLIAIoApADQcABQQQQnyAMGAsgFBDSIwwXC0EBIAIoApADdEH7AHENFiAqEPMhDBYLIBYQ+hEMFQsgFhChFQwUCyAUEP4VDBMLIAIoAowDDRIgAigCkAMNEAwSCyACKAKMAyIEEPMhIARBEEEEEJ8gDBELIBQQmA8MEAsgFBDzISAXEP4VDA8LIBQQ8yEgFxDKGgwOCyAUEPMhIBcQ8yEgGxDzISArEMoaDA0LICwQ8yEgAigCjAMNDCACKAKQAw0KDAwLIBQQ8yEgFxDzIQwLCyAUEPMhDAoLIBYQiwMMCQsgBUEDOgDwAiAFQQM6AOwCIAVBBDoAyAJBASEOQQQMCQsgBUEBOgDIAiAOELAYIAVBAToA8AIgBUEBOgDsAiAFKAK8AiEHIBcgBUGIA2opAwA3AwAgFiAFQYADaikDADcDACACIAUpA/gCNwOIAyAHKAIcIgYgBygCFEYEQCMAQRBrIgkkACAJQQhqIAdBFGoiBCAEKAIAQQFBCEEYEKAHIAkoAggiBEGBgICAeEcEQCAEIAkoAgxBzP/DABD2GwALIAlBEGokAAsgBygCGCAGQRhsaiIEIAIpA4gDNwMAIARBEGogFykDADcDACAEQQhqIBYpAwA3AwAgByAGQQFqNgIcIAdBARCTF0EAIQ5BAQwIC0GE/MMAQSJB9P7DABC5EQALQYT8wwBBIkH0/sMAELkRAAtBhPzDAEEiQZj/wwAQuREAC0GE/MMAQSJBmP/DABC5EQALIAZBDGoQ+hEMAQsgFhD+FQwBCyAGQegAQQgQnyALQQAhDkEBCyEEIAUgBDoAsAIgAUEBaiIBRQ0CIA5FDQMgGi0AtQQhBCAAIBoQ5A4aIAEgI0cgMyAEQQBHaiIzQQFNcQ0BCwsgJCgCBCAkKAIAKAIIEQIAQQIMAgtBsPvDABCuFwALIBoQuQxBAQsgAkHQBWokAA8LQYf7wwBBFkGg+8MAEJwVAAvrLQEqfiAAIAApAzgiJSAAKQMYIikgASkAMCIbfHwiFyABKQA4Ihx8IBdC+cL4m5Gjs/DbAIVCIIkiF0KPkouH2tiC2NoAfSIgICWFQiiJIhh8Ih8gF4VCMIkiCCAgfCIdIBiFQgGJIhYgACkDMCImIAApAxAiKiABKQAgIhd8fCIYIAEpACgiIHwgAiAYhULr+obav7X2wR+FQiCJIiFCq/DT9K/uvLc8fCIeICaFQiiJIhp8IgUgASkAYCICfHwiIiABKQBoIhh8IBYgIiAAKQMoIicgACkDCCIrIAEpABAiI3x8IhkgASkAGCIkfCAZQp/Y+dnCkdqCm3+FQiCJIhlCxbHV2aevlMzEAH0iBiAnhUIoiSIDfCIKIBmFQjCJIgSFQiCJIg0gACkDICIoIAApAwAiLCABKQAAIiJ8fCIJIAEpAAgiGXwgACkDQCAJhULRhZrv+s+Uh9EAhUIgiSIJQoiS853/zPmE6gB8IgcgKIVCKIkiC3wiDyAJhUIwiSIJIAd8Igd8IgyFQiiJIg58IhAgASkASCIWfCAFICGFQjCJIgUgHnwiEiAahUIBiSIaIAogASkAUCIhfHwiCiABKQBYIh58IBogHSAJIAqFQiCJIgp8Ih2FQiiJIhp8IgkgCoVCMIkiCiAdfCIRIBqFQgGJIhN8IhQgASkAeCIdfCATIBQgByALhUIBiSIHIB8gASkAcCIafHwiHyAdfCAFIB+FQiCJIh8gBCAGfCIFfCIGIAeFQiiJIgR8IgcgH4VCMIkiC4VCIIkiFCADIAWFQgGJIgUgDyABKQBAIh98fCIDIBZ8IAUgAyAIhUIgiSIIIBJ8IgOFQiiJIgV8Ig8gCIVCMIkiCCADfCIDfCIShUIoiSITfCIVIB58IA0gEIVCMIkiDSAMfCIMIA6FQgGJIg4gByAYfHwiByAbfCAHIAiFQiCJIgggEXwiByAOhUIoiSIOfCIQIAiFQjCJIgggB3wiByAOhUIBiSIOfCIRIBx8IA4gESADIAWFQgGJIgUgCSAXfHwiAyAffCAFIAMgDYVCIIkiAyAGIAt8IgZ8Ig2FQiiJIgV8IgkgA4VCMIkiA4VCIIkiCyAEIAaFQgGJIgYgDyAafHwiBCAhfCAGIAQgCoVCIIkiCiAMfCIEhUIoiSIGfCIPIAqFQjCJIgogBHwiBHwiDIVCKIkiDnwiESAgfCATIBIgFCAVhUIwiSISfCIThUIBiSIUIAkgInx8IgkgI3wgCSAKhUIgiSIKIAd8IgkgFIVCKIkiB3wiFCAKhUIwiSIKIAl8IgkgB4VCAYkiB3wiFSAjfCAHIBUgBCAGhUIBiSIGIBAgIHx8IgQgJHwgBiAEIBKFQiCJIgYgAyANfCIDfCIEhUIoiSINfCIQIAaFQjCJIgaFQiCJIhIgAyAFhUIBiSIFIA8gGXx8IgMgAnwgBSADIAiFQiCJIgggE3wiA4VCKIkiBXwiDyAIhUIwiSIIIAN8IgN8IhOFQiiJIgd8IhUgHHwgCyARhUIwiSILIAx8IgwgDoVCAYkiDiAQIB18fCIQIBh8IAggEIVCIIkiCCAJfCIJIA6FQiiJIg58IhAgCIVCMIkiCCAJfCIJIA6FQgGJIg58IhEgGXwgDiARIAMgBYVCAYkiBSACIBR8fCIDICJ8IAUgAyALhUIgiSIDIAQgBnwiBnwiBIVCKIkiBXwiCyADhUIwiSIDhUIgiSIRIAYgDYVCAYkiBiAPIB58fCINIB98IAYgCiANhUIgiSIKIAx8Ig2FQiiJIgZ8Ig8gCoVCMIkiCiANfCINfCIMhUIoiSIOfCIUIBh8IAcgEiAVhUIwiSIHIBN8IhKFQgGJIhMgCyAkfHwiCyAbfCAKIAuFQiCJIgogCXwiCSAThUIoiSILfCITIAqFQjCJIgogCXwiCSALhUIBiSILfCIVIAJ8IAsgFSAGIA2FQgGJIgYgECAWfHwiDSAXfCAGIAcgDYVCIIkiDSADIAR8IgN8IgSFQiiJIgZ8IgcgDYVCMIkiDYVCIIkiECADIAWFQgGJIgUgDyAhfHwiAyAafCAFIAMgCIVCIIkiCCASfCIDhUIoiSIFfCIPIAiFQjCJIgggA3wiA3wiEoVCKIkiC3wiFSAXfCAOIAwgESAUhUIwiSIMfCIOhUIBiSIRIAcgHnx8IgcgGnwgByAIhUIgiSIIIAl8IgkgEYVCKIkiB3wiESAIhUIwiSIIIAl8IgkgB4VCAYkiB3wiFCAifCAHIBQgAyAFhUIBiSIFIBMgJHx8IgMgGXwgBSADIAyFQiCJIgMgBCANfCIEfCINhUIoiSIFfCIMIAOFQjCJIgOFQiCJIhMgBCAGhUIBiSIGIA8gHHx8IgQgFnwgBiAEIAqFQiCJIgogDnwiBIVCKIkiBnwiDyAKhUIwiSIKIAR8IgR8Ig6FQiiJIgd8IhQgI3wgCyAQIBWFQjCJIgsgEnwiEIVCAYkiEiAMICB8fCIMICF8IAogDIVCIIkiCiAJfCIJIBKFQiiJIgx8IhIgCoVCMIkiCiAJfCIJIAyFQgGJIgx8IhUgF3wgDCAVIAQgBoVCAYkiBiARIB18fCIEIB98IAYgBCALhUIgiSIEIAMgDXwiA3wiDYVCKIkiBnwiCyAEhUIwiSIEhUIgiSIRIAMgBYVCAYkiBSAPICN8fCIDIBt8IAUgAyAIhUIgiSIIIBB8IgOFQiiJIgV8Ig8gCIVCMIkiCCADfCIDfCIQhUIoiSIMfCIVIBt8IAcgEyAUhUIwiSIHIA58Ig6FQgGJIhMgCyAhfHwiCyAdfCAIIAuFQiCJIgggCXwiCSAThUIoiSILfCITIAiFQjCJIgggCXwiCSALhUIBiSILfCIUIB98IAsgFCADIAWFQgGJIgUgEiAgfHwiAyAcfCAFIAMgB4VCIIkiAyAEIA18IgR8Ig2FQiiJIgV8IgcgA4VCMIkiA4VCIIkiEiAEIAaFQgGJIgYgDyAWfHwiBCAifCAGIAQgCoVCIIkiCiAOfCIEhUIoiSIGfCIPIAqFQjCJIgogBHwiBHwiDoVCKIkiC3wiFCAifCAMIBEgFYVCMIkiDCAQfCIQhUIBiSIRIAcgHnx8IgcgAnwgByAKhUIgiSIKIAl8IgkgEYVCKIkiB3wiESAKhUIwiSIKIAl8IgkgB4VCAYkiB3wiFSAefCAHIBUgBCAGhUIBiSIGIBMgJHx8IgQgGHwgBiAEIAyFQiCJIgQgAyANfCIDfCINhUIoiSIGfCIMIASFQjCJIgSFQiCJIhMgAyAFhUIBiSIFIA8gGnx8IgMgGXwgBSADIAiFQiCJIgggEHwiA4VCKIkiBXwiDyAIhUIwiSIIIAN8IgN8IhCFQiiJIgd8IhUgHXwgCyASIBSFQjCJIgsgDnwiDoVCAYkiEiAMIB98fCIMICR8IAggDIVCIIkiCCAJfCIJIBKFQiiJIgx8IhIgCIVCMIkiCCAJfCIJIAyFQgGJIgx8IhQgGnwgDCAUIAMgBYVCAYkiBSARIBt8fCIDICF8IAUgAyALhUIgiSIDIAQgDXwiBHwiDYVCKIkiBXwiCyADhUIwiSIDhUIgiSIRIAQgBoVCAYkiBiAPICN8fCIEIAJ8IAYgBCAKhUIgiSIKIA58IgSFQiiJIgZ8Ig8gCoVCMIkiCiAEfCIEfCIOhUIoiSIMfCIUIBp8IAcgEyAVhUIwiSIHIBB8IhCFQgGJIhMgCyAcfHwiCyAgfCAKIAuFQiCJIgogCXwiCSAThUIoiSILfCITIAqFQjCJIgogCXwiCSALhUIBiSILfCIVIBh8IAsgFSAEIAaFQgGJIgYgEiAZfHwiBCAWfCAGIAQgB4VCIIkiBCADIA18IgN8Ig2FQiiJIgZ8IgcgBIVCMIkiBIVCIIkiEiADIAWFQgGJIgUgDyAXfHwiAyAYfCAFIAMgCIVCIIkiCCAQfCIDhUIoiSIFfCIPIAiFQjCJIgggA3wiA3wiEIVCKIkiC3wiFSAWfCAMIBEgFIVCMIkiDCAOfCIOhUIBiSIRIAcgF3x8IgcgIXwgByAIhUIgiSIIIAl8IgkgEYVCKIkiB3wiESAIhUIwiSIIIAl8IgkgB4VCAYkiB3wiFCAjfCAHIBQgAyAFhUIBiSIFIBMgGXx8IgMgHXwgBSADIAyFQiCJIgMgBCANfCIEfCINhUIoiSIFfCIMIAOFQjCJIgOFQiCJIhMgBCAGhUIBiSIGIAIgD3x8IgQgIHwgBiAEIAqFQiCJIgogDnwiBIVCKIkiBnwiDyAKhUIwiSIKIAR8IgR8Ig6FQiiJIgd8IhQgAnwgCyASIBWFQjCJIgsgEHwiEIVCAYkiEiAMIBt8fCIMICR8IAogDIVCIIkiCiAJfCIJIBKFQiiJIgx8IhIgCoVCMIkiCiAJfCIJIAyFQgGJIgx8IhUgGXwgDCAVIAQgBoVCAYkiBiARIB98fCIEIB58IAYgBCALhUIgiSIEIAMgDXwiA3wiDYVCKIkiBnwiCyAEhUIwiSIEhUIgiSIRIAMgBYVCAYkiBSAPICJ8fCIDIBx8IAUgAyAIhUIgiSIIIBB8IgOFQiiJIgV8Ig8gCIVCMIkiCCADfCIDfCIQhUIoiSIMfCIVIB98IAcgEyAUhUIwiSIHIA58Ig6FQgGJIhMgCyAkfHwiCyAWfCAIIAuFQiCJIgggCXwiCSAThUIoiSILfCITIAiFQjCJIgggCXwiCSALhUIBiSILfCIUIBt8IAsgFCADIAWFQgGJIgUgEiAcfHwiAyAafCAFIAMgB4VCIIkiAyAEIA18IgR8Ig2FQiiJIgV8IgcgA4VCMIkiA4VCIIkiEiAEIAaFQgGJIgYgDyAYfHwiBCAefCAGIAQgCoVCIIkiCiAOfCIEhUIoiSIGfCIPIAqFQjCJIgogBHwiBHwiDoVCKIkiC3wiFCAefCAMIBEgFYVCMIkiDCAQfCIQhUIBiSIRIAcgHXx8IgcgF3wgByAKhUIgiSIKIAl8IgkgEYVCKIkiB3wiESAKhUIwiSIKIAl8IgkgB4VCAYkiB3wiFSAkfCAHIBUgBCAGhUIBiSIGIBMgI3x8IgQgIXwgBiAEIAyFQiCJIgQgAyANfCIDfCINhUIoiSIGfCIMIASFQjCJIgSFQiCJIhMgAyAFhUIBiSIFIA8gIHx8IgMgInwgBSADIAiFQiCJIgggEHwiA4VCKIkiBXwiDyAIhUIwiSIIIAN8IgN8IhCFQiiJIgd8IhUgGXwgCyASIBSFQjCJIgsgDnwiDoVCAYkiEiAMICJ8fCIMIB98IAggDIVCIIkiCCAJfCIJIBKFQiiJIgx8IhIgCIVCMIkiCCAJfCIJIAyFQgGJIgx8IhQgF3wgDCAUIAMgBYVCAYkiBSARIBp8fCIDIBZ8IAUgAyALhUIgiSIDIAQgDXwiBHwiDYVCKIkiBXwiCyADhUIwiSIDhUIgiSIRIAQgBoVCAYkiBiAPIBt8fCIEIB18IAYgBCAKhUIgiSIKIA58IgSFQiiJIgZ8Ig8gCoVCMIkiCiAEfCIEfCIOhUIoiSIMfCIUIBx8IAcgEyAVhUIwiSIHIBB8IhCFQgGJIhMgCyAYfHwiCyAcfCAKIAuFQiCJIgogCXwiCSAThUIoiSILfCITIAqFQjCJIgogCXwiCSALhUIBiSILfCIVIBt8IAsgFSAEIAaFQgGJIgYgEiAhfHwiBCAgfCAGIAQgB4VCIIkiBCADIA18IgN8Ig2FQiiJIgZ8IgcgBIVCMIkiBIVCIIkiEiADIAWFQgGJIgUgAiAPfHwiAyAjfCAFIAMgCIVCIIkiCCAQfCIDhUIoiSIFfCIPIAiFQjCJIgggA3wiA3wiEIVCKIkiC3wiFSAkfCAMIBEgFIVCMIkiDCAOfCIOhUIBiSIRIAcgGXx8IgcgIHwgByAIhUIgiSIIIAl8IgkgEYVCKIkiB3wiESAIhUIwiSIIIAl8IgkgB4VCAYkiB3wiFCACfCAHIBQgAyAFhUIBiSIFIBMgH3x8IgMgF3wgBSADIAyFQiCJIgMgBCANfCIEfCINhUIoiSIFfCIMIAOFQjCJIgOFQiCJIhMgBCAGhUIBiSIGIA8gIXx8IgQgI3wgBiAEIAqFQiCJIgogDnwiBIVCKIkiBnwiDyAKhUIwiSIKIAR8IgR8Ig6FQiiJIgd8IhQgF3wgCyASIBWFQjCJIgsgEHwiEIVCAYkiEiAMIBZ8fCIMIBp8IAogDIVCIIkiCiAJfCIJIBKFQiiJIgx8IhIgCoVCMIkiCiAJfCIJIAyFQgGJIgx8IhUgIHwgDCAVIAQgBoVCAYkiBiARIBh8fCIEICJ8IAYgBCALhUIgiSIEIAMgDXwiA3wiDYVCKIkiBnwiCyAEhUIwiSIEhUIgiSIRIAMgBYVCAYkiBSAPIB18fCIDIB58IAUgAyAIhUIgiSIIIBB8IgOFQiiJIgV8Ig8gCIVCMIkiCCADfCIDfCIQhUIoiSIMfCIVIAJ8IAcgEyAUhUIwiSIHIA58Ig6FQgGJIhMgCyAbfHwiCyAcfCAIIAuFQiCJIgggCXwiCSAThUIoiSILfCITIAiFQjCJIgggCXwiCSALhUIBiSILfCIUIBh8IAsgFCADIAWFQgGJIgUgEiAjfHwiAyAkfCAFIAMgB4VCIIkiAyAEIA18IgR8Ig2FQiiJIgV8IgcgA4VCMIkiA4VCIIkiEiAEIAaFQgGJIgYgDyAifHwiBCAZfCAGIAQgCoVCIIkiCiAOfCIEhUIoiSIGfCIPIAqFQjCJIgogBHwiBHwiDoVCKIkiC3wiFCAWfCAMIBEgFYVCMIkiDCAQfCIQhUIBiSIRIAcgIXx8IgcgHnwgByAKhUIgiSIKIAl8IgkgEYVCKIkiB3wiESAKhUIwiSIKIAl8IgkgB4VCAYkiB3wiFSAdfCAHIBUgHSAEIAaFQgGJIgYgEyAafHwiBHwgBiAEIAyFQiCJIh0gAyANfCIDfCIEhUIoiSIGfCINIB2FQjCJIh2FQiCJIgwgFiADIAWFQgGJIgUgDyAffHwiA3wgBSADIAiFQiCJIhYgEHwiCIVCKIkiBXwiAyAWhUIwiSIWIAh8Igh8Ig+FQiiJIgd8IhAgHnwgGyALIBIgFIVCMIkiHiAOfCILhUIBiSIOIA0gGHx8Ihh8IBYgGIVCIIkiGyAJfCIYIA6FQiiJIhZ8Ig0gG4VCMIkiGyAYfCIYIBaFQgGJIhZ8IgkgHHwgFiAJIAUgCIVCAYkiHCARIBd8fCIXIB98IBwgFyAehUIgiSIXIAQgHXwiFnwiHoVCKIkiHHwiHSAXhUIwiSIXhUIgiSIfICEgBiAWhUIBiSIWIAMgGnx8Ihp8IBYgCiAahUIgiSIhIAt8IhqFQiiJIhZ8IgggIYVCMIkiISAafCIafCIFhUIoiSIGfCIDICqFIAIgHCAXIB58IhyFQgGJIhcgCCAZfHwiGXwgFyAZIBuFQiCJIgIgDCAQhUIwiSIbIA98Ihl8Ih6FQiiJIhd8IgggAoVCMIkiAiAefCIehTcDECAAICMgByAZhUIBiSIZIB0gInx8IiJ8IBkgGCAhICKFQiCJIhh8IiOFQiiJIiJ8IhkgGIVCMIkiGCAjfCIjICkgJCAWIBqFQgGJIhYgDSAgfHwiIHwgHCAbICCFQiCJIht8IhwgFoVCKIkiIHwiJIWFNwMYIAAgGyAkhUIwiSIbIBx8IhwgGSArhYU3AwggACADIB+FQjCJIiQgBXwiGSAIICyFhTcDACAAICcgFyAehUIBiYUgJIU3AyggACAlIAYgGYVCAYmFIAKFNwM4IAAgJiAiICOFQgGJhSAbhTcDMCAAICggHCAghUIBiYUgGIU3AyAL/C0BKn4gACAAKQM4IhggACkDMCIeIAApA7gCIiQgACkDmAIiKHx8Ihl8IBlC+cL4m5Gjs/DbAIVCIIkiGUKPkouH2tiC2NoAfSIgICSFQiiJIhZ8Ih8gGYVCMIkiByAgfCIaIBaFQgGJIhUgACkDYCIZIAApAygiICAAKQMgIhYgACkDsAIiJSAAKQOQAiIpfHwiIXwgASAhhULr+obav7X2wR+FQiCJIiJCq/DT9K/uvLc8fCIbICWFQiiJIhd8IgR8fCIcIAApA2giAXwgFSAcIAApAxgiISAAKQMQIiMgACkDqAIiJiAAKQOIAiIqfHwiHXwgHUKf2PnZwpHagpt/hUIgiSIdQsWx1dmnr5TMxAB9IgkgJoVCKIkiAnwiBSAdhUIwiSIDhUIgiSINIAApAwgiHCAAKQMAIh0gACkDoAIiJyAAKQOAAiIrfHwiCHwgACkDgAMgCIVC0YWa7/rPlIfRAIVCIIkiCEKIkvOd/8z5hOoAfCIGICeFQiiJIgt8IgogCIVCMIkiCCAGfCIGfCIOhUIoiSIMfCIQIAApA0giFXwgFyAEICKFQjCJIgQgG3wiEYVCAYkiFyAAKQNQIiIgBXx8IgUgACkDWCIbfCAXIBogBSAIhUIgiSIXfCIahUIoiSIFfCIIIBeFQjCJIhMgGnwiDyAFhUIBiSIFfCISIAApA3giGnwgBSASIBogBiALhUIBiSIGIB8gACkDcCIXfHwiH3wgBCAfhUIgiSIfIAMgCXwiBHwiCSAGhUIoiSIDfCIGIB+FQjCJIguFQiCJIhIgAiAEhUIBiSIEIAApA0AiHyAKfHwiAiAVfCAEIAIgB4VCIIkiByARfCIEhUIoiSICfCIKIAeFQjCJIgcgBHwiBHwiEYVCKIkiBXwiFCAbfCANIBCFQjCJIg0gDnwiDiAMhUIBiSIMIAEgBnx8IgYgHnwgBiAHhUIgiSIHIA98IgYgDIVCKIkiDHwiECAHhUIwiSIHIAZ8IgYgDIVCAYkiDHwiDyAYfCAMIA8gAiAEhUIBiSIEIAggFnx8IgIgH3wgBCACIA2FQiCJIgIgCSALfCIJfCINhUIoiSIEfCIIIAKFQjCJIgKFQiCJIgsgAyAJhUIBiSIJIAogF3x8IgMgInwgCSADIBOFQiCJIgMgDnwiCoVCKIkiCXwiDiADhUIwiSIDIAp8Igp8IhOFQiiJIgx8Ig8gIHwgBSARIBIgFIVCMIkiBXwiEYVCAYkiEiAIIB18fCIIICN8IAMgCIVCIIkiAyAGfCIIIBKFQiiJIgZ8IhIgA4VCMIkiAyAIfCIIIAaFQgGJIgZ8IhQgI3wgBiAUIAkgCoVCAYkiCSAQICB8fCIKICF8IAkgBSAKhUIgiSIFIAIgDXwiAnwiDYVCKIkiCXwiCiAFhUIwiSIFhUIgiSIQIAIgBIVCAYkiBCAOIBx8fCICIBl8IAQgAiAHhUIgiSIHIBF8IgKFQiiJIgR8Ig4gB4VCMIkiByACfCICfCIRhUIoiSIGfCIUIBh8IAwgCyAPhUIwiSILIBN8IgyFQgGJIhMgCiAafHwiCiABfCAHIAqFQiCJIgcgCHwiCCAThUIoiSIKfCITIAeFQjCJIgcgCHwiCCAKhUIBiSIKfCIPIBx8IAogDyACIASFQgGJIgQgEiAZfHwiAiAdfCAEIAIgC4VCIIkiAiAFIA18IgV8Ig2FQiiJIgR8IgsgAoVCMIkiAoVCIIkiDyAFIAmFQgGJIgkgDiAbfHwiBSAffCAJIAMgBYVCIIkiBSAMfCIDhUIoiSIJfCIOIAWFQjCJIgUgA3wiA3wiDIVCKIkiCnwiEiABfCAGIBAgFIVCMIkiBiARfCIQhUIBiSIRIAsgIXx8IgsgHnwgBSALhUIgiSIFIAh8IgggEYVCKIkiC3wiESAFhUIwiSIFIAh8IgggC4VCAYkiC3wiFCAZfCALIBQgAyAJhUIBiSIJIBMgFXx8IgMgFnwgCSADIAaFQiCJIgMgAiANfCICfCINhUIoiSIJfCIGIAOFQjCJIgOFQiCJIhMgAiAEhUIBiSIEIA4gInx8IgIgF3wgBCACIAeFQiCJIgcgEHwiAoVCKIkiBHwiDiAHhUIwiSIHIAJ8IgJ8IhCFQiiJIgt8IhQgFnwgCiAPIBKFQjCJIgogDHwiDIVCAYkiDyAGIBt8fCIGIBd8IAYgB4VCIIkiByAIfCIIIA+FQiiJIgZ8Ig8gB4VCMIkiByAIfCIIIAaFQgGJIgZ8IhIgHXwgBiASIAIgBIVCAYkiBCARICF8fCICIBx8IAQgAiAKhUIgiSICIAMgDXwiA3wiDYVCKIkiBHwiCiAChUIwiSIChUIgiSIRIAMgCYVCAYkiCSAOIBh8fCIDIBV8IAkgAyAFhUIgiSIFIAx8IgOFQiiJIgl8Ig4gBYVCMIkiBSADfCIDfCIMhUIoiSIGfCISICN8IAsgEyAUhUIwiSILIBB8IhCFQgGJIhMgCiAgfHwiCiAifCAFIAqFQiCJIgUgCHwiCCAThUIoiSIKfCITIAWFQjCJIgUgCHwiCCAKhUIBiSIKfCIUIBZ8IAogFCADIAmFQgGJIgkgDyAafHwiAyAffCAJIAMgC4VCIIkiAyACIA18IgJ8Ig2FQiiJIgl8IgsgA4VCMIkiA4VCIIkiDyACIASFQgGJIgQgDiAjfHwiAiAefCAEIAIgB4VCIIkiByAQfCIChUIoiSIEfCIOIAeFQjCJIgcgAnwiAnwiEIVCKIkiCnwiFCAefCAGIBEgEoVCMIkiBiAMfCIMhUIBiSIRIAsgInx8IgsgGnwgByALhUIgiSIHIAh8IgggEYVCKIkiC3wiESAHhUIwiSIHIAh8IgggC4VCAYkiC3wiEiAffCALIBIgAiAEhUIBiSIEIBMgIHx8IgIgGHwgBCACIAaFQiCJIgIgAyANfCIDfCINhUIoiSIEfCIGIAKFQjCJIgKFQiCJIhMgAyAJhUIBiSIJIA4gFXx8IgMgHXwgCSADIAWFQiCJIgUgDHwiA4VCKIkiCXwiDiAFhUIwiSIFIAN8IgN8IgyFQiiJIgt8IhIgHXwgCiAPIBSFQjCJIgogEHwiEIVCAYkiDyAGIBt8fCIGIBl8IAUgBoVCIIkiBSAIfCIIIA+FQiiJIgZ8Ig8gBYVCMIkiBSAIfCIIIAaFQgGJIgZ8IhQgG3wgBiAUIAMgCYVCAYkiCSARICF8fCIDIAF8IAkgAyAKhUIgiSIDIAIgDXwiAnwiDYVCKIkiCXwiCiADhUIwiSIDhUIgiSIRIAIgBIVCAYkiBCAOIBd8fCICIBx8IAQgAiAHhUIgiSIHIBB8IgKFQiiJIgR8Ig4gB4VCMIkiByACfCICfCIQhUIoiSIGfCIUIBp8IAsgEiAThUIwiSILIAx8IgyFQgGJIhMgCiAffHwiCiAhfCAHIAqFQiCJIgcgCHwiCCAThUIoiSIKfCITIAeFQjCJIgcgCHwiCCAKhUIBiSIKfCISIBd8IAogEiACIASFQgGJIgQgDyAefHwiAiAifCAEIAIgC4VCIIkiAiADIA18IgN8Ig2FQiiJIgR8IgsgAoVCMIkiAoVCIIkiDyADIAmFQgGJIgkgDiAjfHwiAyAZfCAJIAMgBYVCIIkiBSAMfCIDhUIoiSIJfCIOIAWFQjCJIgUgA3wiA3wiDIVCKIkiCnwiEiAXfCAGIBEgFIVCMIkiBiAQfCIQhUIBiSIRIAsgGHx8IgsgIHwgBSALhUIgiSIFIAh8IgggEYVCKIkiC3wiESAFhUIwiSIFIAh8IgggC4VCAYkiC3wiFCABfCALIBQgAyAJhUIBiSIJIBMgHHx8IgMgFXwgCSADIAaFQiCJIgMgAiANfCICfCINhUIoiSIJfCIGIAOFQjCJIgOFQiCJIhMgAiAEhUIBiSIEIA4gFnx8IgIgAXwgBCACIAeFQiCJIgcgEHwiAoVCKIkiBHwiDiAHhUIwiSIHIAJ8IgJ8IhCFQiiJIgt8IhQgFXwgCiAPIBKFQjCJIgogDHwiDIVCAYkiDyAGIBZ8fCIGICJ8IAYgB4VCIIkiByAIfCIIIA+FQiiJIgZ8Ig8gB4VCMIkiByAIfCIIIAaFQgGJIgZ8IhIgI3wgBiASIAIgBIVCAYkiBCARIBx8fCICIBp8IAQgAiAKhUIgiSICIAMgDXwiA3wiDYVCKIkiBHwiCiAChUIwiSIChUIgiSIRIAMgCYVCAYkiCSAOIBl8fCIDICB8IAkgAyAFhUIgiSIFIAx8IgOFQiiJIgl8Ig4gBYVCMIkiBSADfCIDfCIMhUIoiSIGfCISIBl8IAsgEyAUhUIwiSILIBB8IhCFQgGJIhMgCiAefHwiCiAhfCAFIAqFQiCJIgUgCHwiCCAThUIoiSIKfCITIAWFQjCJIgUgCHwiCCAKhUIBiSIKfCIUIBx8IAogFCADIAmFQgGJIgkgDyAffHwiAyAbfCAJIAMgC4VCIIkiAyACIA18IgJ8Ig2FQiiJIgl8IgsgA4VCMIkiA4VCIIkiDyACIASFQgGJIgQgDiAdfHwiAiAYfCAEIAIgB4VCIIkiByAQfCIChUIoiSIEfCIOIAeFQjCJIgcgAnwiAnwiEIVCKIkiCnwiFCAffCAGIBEgEoVCMIkiBiAMfCIMhUIBiSIRIAsgIXx8IgsgFXwgByALhUIgiSIHIAh8IgggEYVCKIkiC3wiESAHhUIwiSIHIAh8IgggC4VCAYkiC3wiEiAefCALIBIgAiAEhUIBiSIEIBMgGHx8IgIgF3wgBCACIAaFQiCJIgIgAyANfCIDfCINhUIoiSIEfCIGIAKFQjCJIgKFQiCJIhMgAyAJhUIBiSIJIAEgDnx8IgMgG3wgCSADIAWFQiCJIgUgDHwiA4VCKIkiCXwiDiAFhUIwiSIFIAN8IgN8IgyFQiiJIgt8IhIgG3wgCiAPIBSFQjCJIgogEHwiEIVCAYkiDyAGIBp8fCIGIBZ8IAUgBoVCIIkiBSAIfCIIIA+FQiiJIgZ8Ig8gBYVCMIkiBSAIfCIIIAaFQgGJIgZ8IhQgIXwgBiAUIAMgCYVCAYkiCSARICN8fCIDICJ8IAkgAyAKhUIgiSIDIAIgDXwiAnwiDYVCKIkiCXwiCiADhUIwiSIDhUIgiSIRIAIgBIVCAYkiBCAOICB8fCICIB18IAQgAiAHhUIgiSIHIBB8IgKFQiiJIgR8Ig4gB4VCMIkiByACfCICfCIQhUIoiSIGfCIUIBx8IAsgEiAThUIwiSILIAx8IgyFQgGJIhMgCiAdfHwiCiAffCAHIAqFQiCJIgcgCHwiCCAThUIoiSIKfCITIAeFQjCJIgcgCHwiCCAKhUIBiSIKfCISIBZ8IAogEiACIASFQgGJIgQgDyAXfHwiAiAVfCAEIAIgC4VCIIkiAiADIA18IgN8Ig2FQiiJIgR8IgsgAoVCMIkiAoVCIIkiDyADIAmFQgGJIgkgDiAefHwiAyAafCAJIAMgBYVCIIkiBSAMfCIDhUIoiSIJfCIOIAWFQjCJIgUgA3wiA3wiDIVCKIkiCnwiEiAYfCAGIBEgFIVCMIkiBiAQfCIQhUIBiSIRIAEgC3x8IgsgGHwgBSALhUIgiSIFIAh8IgggEYVCKIkiC3wiESAFhUIwiSIFIAh8IgggC4VCAYkiC3wiFCAefCALIBQgAyAJhUIBiSIJIBMgInx8IgMgIHwgCSADIAaFQiCJIgMgAiANfCICfCINhUIoiSIJfCIGIAOFQjCJIgOFQiCJIhMgAiAEhUIBiSIEIA4gGXx8IgIgI3wgBCACIAeFQiCJIgcgEHwiAoVCKIkiBHwiDiAHhUIwiSIHIAJ8IgJ8IhCFQiiJIgt8IhQgIXwgCiAPIBKFQjCJIgogDHwiDIVCAYkiDyAGIBx8fCIGICB8IAYgB4VCIIkiByAIfCIIIA+FQiiJIgZ8Ig8gB4VCMIkiByAIfCIIIAaFQgGJIgZ8IhIgGXwgBiASIAIgBIVCAYkiBCARIB98fCICIBZ8IAQgAiAKhUIgiSICIAMgDXwiA3wiDYVCKIkiBHwiCiAChUIwiSIChUIgiSIRIAMgCYVCAYkiCSAOICJ8fCIDICN8IAkgAyAFhUIgiSIFIAx8IgOFQiiJIgl8Ig4gBYVCMIkiBSADfCIDfCIMhUIoiSIGfCISIBZ8IAsgEyAUhUIwiSILIBB8IhCFQgGJIhMgCiAVfHwiCiAXfCAFIAqFQiCJIgUgCHwiCCAThUIoiSIKfCITIAWFQjCJIgUgCHwiCCAKhUIBiSIKfCIUICB8IAogFCADIAmFQgGJIgkgASAPfHwiAyAdfCAJIAMgC4VCIIkiAyACIA18IgJ8Ig2FQiiJIgl8IgsgA4VCMIkiA4VCIIkiDyACIASFQgGJIgQgDiAafHwiAiAbfCAEIAIgB4VCIIkiByAQfCIChUIoiSIEfCIOIAeFQjCJIgcgAnwiAnwiEIVCKIkiCnwiFCAZfCAGIBEgEoVCMIkiBiAMfCIMhUIBiSIRIAsgHnx8IgsgGHwgByALhUIgiSIHIAh8IgggEYVCKIkiC3wiESAHhUIwiSIHIAh8IgggC4VCAYkiC3wiEiABfCALIBIgAiAEhUIBiSIEIBMgI3x8IgIgIXwgBCACIAaFQiCJIgIgAyANfCIDfCINhUIoiSIEfCIGIAKFQjCJIgKFQiCJIhMgAyAJhUIBiSIJIA4gHXx8IgMgHHwgCSADIAWFQiCJIgUgDHwiA4VCKIkiCXwiDiAFhUIwiSIFIAN8IgN8IgyFQiiJIgt8IhIgFXwgCiAPIBSFQjCJIgogEHwiEIVCAYkiDyAGICJ8fCIGIBt8IAUgBoVCIIkiBSAIfCIIIA+FQiiJIgZ8Ig8gBYVCMIkiBSAIfCIIIAaFQgGJIgZ8IhQgGnwgBiAUIBogAyAJhUIBiSIJIBEgF3x8IgN8IAkgAyAKhUIgiSIaIAIgDXwiAnwiA4VCKIkiCXwiDSAahUIwiSIahUIgiSIKIBUgAiAEhUIBiSIEIA4gH3x8IgJ8IAQgAiAHhUIgiSIVIBB8IgeFQiiJIgR8IgIgFYVCMIkiFSAHfCIHfCIOhUIoiSIGfCIQIBt8IB4gCyASIBOFQjCJIhsgDHwiC4VCAYkiDCABIA18fCIBfCABIBWFQiCJIgEgCHwiHiAMhUIoiSIVfCINIAGFQjCJIgEgHnwiHiAVhUIBiSIVfCIIIBh8IBUgCCAEIAeFQgGJIhggDyAWfHwiFiAffCAYIBYgG4VCIIkiFiADIBp8IhV8IhuFQiiJIhh8IhogFoVCMIkiFoVCIIkiHyAiIAkgFYVCAYkiFSACIBd8fCIXfCAVIAUgF4VCIIkiIiALfCIXhUIoiSIVfCIHICKFQjCJIiIgF3wiF3wiBIVCKIkiCXwiAiAphSAZIBggFiAbfCIYhUIBiSIWIAcgHHx8Ihx8IBYgASAchUIgiSIBIAogEIVCMIkiGSAOfCIcfCIbhUIoiSIWfCIHIAGFQjCJIgEgG3wiG4U3A5ACIAAgIyAGIByFQgGJIhwgGiAdfHwiHXwgHCAeIB0gIoVCIIkiHnwiI4VCKIkiHHwiHSAehUIwiSIeICN8IiMgKCAhIBUgF4VCAYkiFSANICB8fCIgfCAYIBkgIIVCIIkiGXwiGCAVhUIoiSIgfCIhhYU3A5gCIAAgGCAZICGFQjCJIhh8IhkgHSAqhYU3A4gCIAAgAiAfhUIwiSIhIAR8Ih0gByArhYU3A4ACIAAgJiAWIBuFQgGJhSAhhTcDqAIgACAkIAkgHYVCAYmFIAGFNwO4AiAAICUgHCAjhUIBiYUgGIU3A7ACIAAgJyAZICCFQgGJhSAehTcDoAIL3jkBJ38jAEGgA2siAyQAIANBCGpBAEHAAPwLACAAKAIcISQgACgCGCElIAAoAhQhICAAKAIQISEgACgCDCEmIAAoAgghJyAAKAIEISIgACgCACEjAkAgAgRAIAEgAkEGdGohKCADQcgAaiEpA0AgA0KAgICAwAA3AnggAyABNgJsIANBwAA2AnAgAyABQUBrIgE2AnQgA0HIAGogA0EIaiApIANB7ABqEPgMIAMoAmgiDyADKAJkIgJLBEAgAygCYEEERw0DIA8gAmshESACQQJ0Ig8gAygCSGohAiADKAJQIA9qIQ8DQCACIA8oAAAiEEEYdCAQQYD+A3FBCHRyIBBBCHZBgP4DcSAQQRh2cnI2AgAgAkEEaiECIA9BBGohDyARQQFrIhENAAsLIAMoAkQhAiADKAJAIQ8gAygCPCEQIAMoAjghESADKAI0IRMgAygCMCEUIAMoAiwhFSADKAIoIRYgAygCJCEXIAMoAiAhGCADKAIcIRkgAygCGCEaIAMoAhQhGyADKAIQIRwgAygCDCEdIAMoAgghHiADICc2ApADIAMgJjYClAMgAyAlNgKYAyADICQ2ApwDIAMgIDYCeCADICE2AnQgAyAiNgJwIAMgIzYCbCADIB5BmN+olARqIgQ2AlQgAyAdQZGJ3YkHaiIFNgJQIAMgHEGxiPzRBGsiBjYCTCADIBtB28iosgFrIgc2AkggA0GAA2oiEiADQZADaiIMIANB7ABqIg0gA0HIAGoiDhCwCCADIAY2AowBIAMgBzYCiAEgAyAENgKEASADIAU2AoABIAMoAoADIQQgAygChAMhBSADKAKIAyEGIAMoAowDIQcgAyAgNgJ4IAMgITYCdCADICI2AnAgAyAjNgJsIAMgBzYCVCADIAY2AlAgAyAFNgJMIAMgBDYCSCAMIA0gDiADQYABahCwCCADKAKQAyEIIAMoApQDIQkgAygCmAMhCiADKAKcAyELIAMgBzYCnAMgAyAGNgKYAyADIAU2ApQDIAMgBDYCkAMgAyALNgJ4IAMgCjYCdCADIAk2AnAgAyAINgJsIAMgGkHbhNvKA2oiBDYCVCADIBlB8aPEzwVqIgU2AlAgAyAYQdz6ge4GayIGNgJMIAMgF0Grwo6nBWsiBzYCSCASIAwgDSAOELAIIAMgBjYCnAEgAyAHNgKYASADIAQ2ApQBIAMgBTYCkAEgAygCgAMhBCADKAKEAyEFIAMoAogDIQYgAygCjAMhByADIAs2AnggAyAKNgJ0IAMgCTYCcCADIAg2AmwgAyAHNgJUIAMgBjYCUCADIAU2AkwgAyAENgJIIAwgDSAOIANBkAFqELAIIAMoApADIQggAygClAMhCSADKAKYAyEKIAMoApwDIQsgAyAHNgKcAyADIAY2ApgDIAMgBTYClAMgAyAENgKQAyADIAs2AnggAyAKNgJ0IAMgCTYCcCADIAg2AmwgAyAWQeiq4b8CayIENgJUIAMgFUGBto2UAWoiBTYCUCADIBRBvovGoQJqIgY2AkwgAyATQcP7sagFaiIHNgJIIBIgDCANIA4QsAggAyAGNgKsASADIAc2AqgBIAMgBDYCpAEgAyAFNgKgASADKAKAAyEEIAMoAoQDIQUgAygCiAMhBiADKAKMAyEHIAMgCzYCeCADIAo2AnQgAyAJNgJwIAMgCDYCbCADIAc2AlQgAyAGNgJQIAMgBTYCTCADIAQ2AkggDCANIA4gA0GgAWoQsAggAygCkAMhCCADKAKUAyEJIAMoApgDIQogAygCnAMhCyADIAc2ApwDIAMgBjYCmAMgAyAFNgKUAyADIAQ2ApADIAMgCzYCeCADIAo2AnQgAyAJNgJwIAMgCDYCbCADIBFB9Lr5lQdqIgQ2AlQgAyAQQYKchfkHayIFNgJQIAMgD0HZ8o+hBmsiBjYCTCADIAJBjJ2Q8wNrIgc2AkggEiAMIA0gDhCwCCADIAY2ArwBIAMgBzYCuAEgAyAENgK0ASADIAU2ArABIAMoAoADIQQgAygChAMhBSADKAKIAyEGIAMoAowDIQcgAyALNgJ4IAMgCjYCdCADIAk2AnAgAyAINgJsIAMgBzYCVCADIAY2AlAgAyAFNgJMIAMgBDYCSCAMIA0gDiADQbABahCwCCADKAKQAyEIIAMoApQDIQkgAygCmAMhCiADKAKcAyELIAMgHjYCjAMgAyAdNgKIAyADIBw2AoQDIAMgGzYCgAMgAyAaNgKcAyADIBk2ApgDIAMgGDYClAMgAyAXNgKQAyADIBY2AnggAyAVNgJ0IAMgFDYCcCADIBM2AmwgAyARNgJUIAMgEDYCUCADIA82AkwgAyACNgJIIANB8AJqIh8gEiAMIA0gDhDmByADKALwAiEbIAMoAvQCIRwgAygC+AIhHSADKAL8AiEeIAMgBzYCnAMgAyAGNgKYAyADIAU2ApQDIAMgBDYCkAMgAyALNgJ4IAMgCjYCdCADIAk2AnAgAyAINgJsIAMgHkG/rJLbAWsiBDYCVCADIB1B+vCGggFrIgU2AlAgAyAcQca7hv4AaiIGNgJMIAMgG0HMw7KgAmoiBzYCSCASIAwgDSAOELAIIAMgBjYCzAEgAyAHNgLIASADIAQ2AsQBIAMgBTYCwAEgAygCgAMhBCADKAKEAyEFIAMoAogDIQYgAygCjAMhByADIAs2AnggAyAKNgJ0IAMgCTYCcCADIAg2AmwgAyAHNgJUIAMgBjYCUCADIAU2AkwgAyAENgJIIAwgDSAOIANBwAFqELAIIAMoApADIQggAygClAMhCSADKAKYAyEKIAMoApwDIQsgAyAaNgKMAyADIBk2AogDIAMgGDYChAMgAyAXNgKAAyADIBY2ApwDIAMgFTYCmAMgAyAUNgKUAyADIBM2ApADIAMgETYCeCADIBA2AnQgAyAPNgJwIAMgAjYCbCADIB42AlQgAyAdNgJQIAMgHDYCTCADIBs2AkggHyASIAwgDSAOEOYHIAMoAvACIRcgAygC9AIhGCADKAL4AiEZIAMoAvwCIRogAyAHNgKcAyADIAY2ApgDIAMgBTYClAMgAyAENgKQAyADIAs2AnggAyAKNgJ0IAMgCTYCcCADIAg2AmwgAyAaQe/YpO8CaiIENgJUIAMgGUGqidLTBGoiBTYCUCADIBhB3NPC5QVqIgY2AkwgAyAXQdqR5rcHaiIHNgJIIBIgDCANIA4QsAggAyAGNgLcASADIAc2AtgBIAMgBDYC1AEgAyAFNgLQASADKAKAAyEEIAMoAoQDIQUgAygCiAMhBiADKAKMAyEHIAMgCzYCeCADIAo2AnQgAyAJNgJwIAMgCDYCbCADIAc2AlQgAyAGNgJQIAMgBTYCTCADIAQ2AkggDCANIA4gA0HQAWoQsAggAygCkAMhCCADKAKUAyEJIAMoApgDIQogAygCnAMhCyADIBY2AowDIAMgFTYCiAMgAyAUNgKEAyADIBM2AoADIAMgETYCnAMgAyAQNgKYAyADIA82ApQDIAMgAjYCkAMgAyAeNgJ4IAMgHTYCdCADIBw2AnAgAyAbNgJsIAMgGjYCVCADIBk2AlAgAyAYNgJMIAMgFzYCSCAfIBIgDCANIA4Q5gcgAygC8AIhEyADKAL0AiEUIAMoAvgCIRUgAygC/AIhFiADIAc2ApwDIAMgBjYCmAMgAyAFNgKUAyADIAQ2ApADIAMgCzYCeCADIAo2AnQgAyAJNgJwIAMgCDYCbCADIBZBrt2GvgZrIgQ2AlQgAyAVQZPzuL4FayIFNgJQIAMgFEG4sPP/BGsiBjYCTCADIBNBuYCahQRrIgc2AkggEiAMIA0gDhCwCCADIAY2AuwBIAMgBzYC6AEgAyAENgLkASADIAU2AuABIAMoAoADIQQgAygChAMhBSADKAKIAyEGIAMoAowDIQcgAyALNgJ4IAMgCjYCdCADIAk2AnAgAyAINgJsIAMgBzYCVCADIAY2AlAgAyAFNgJMIAMgBDYCSCAMIA0gDiADQeABahCwCCADKAKQAyEIIAMoApQDIQkgAygCmAMhCiADKAKcAyELIAMgETYCjAMgAyAQNgKIAyADIA82AoQDIAMgAjYCgAMgAyAeNgKcAyADIB02ApgDIAMgHDYClAMgAyAbNgKQAyADIBo2AnggAyAZNgJ0IAMgGDYCcCADIBc2AmwgAyAWNgJUIAMgFTYCUCADIBQ2AkwgAyATNgJIIB8gEiAMIA0gDhDmByADKALwAiECIAMoAvQCIQ8gAygC+AIhECADKAL8AiERIAMgBzYCnAMgAyAGNgKYAyADIAU2ApQDIAMgBDYCkAMgAyALNgJ4IAMgCjYCdCADIAk2AnAgAyAINgJsIAMgEUGN6P/IA2siBDYCVCADIBBBud3h0gJrIgU2AlAgAyAPQdHGqTZqIgY2AkwgAyACQefSpKEBaiIHNgJIIBIgDCANIA4QsAggAyAGNgL8ASADIAc2AvgBIAMgBDYC9AEgAyAFNgLwASADKAKAAyEEIAMoAoQDIQUgAygCiAMhBiADKAKMAyEHIAMgCzYCeCADIAo2AnQgAyAJNgJwIAMgCDYCbCADIAc2AlQgAyAGNgJQIAMgBTYCTCADIAQ2AkggDCANIA4gA0HwAWoQsAggAygCkAMhCCADKAKUAyEJIAMoApgDIQogAygCnAMhCyADIB42AowDIAMgHTYCiAMgAyAcNgKEAyADIBs2AoADIAMgGjYCnAMgAyAZNgKYAyADIBg2ApQDIAMgFzYCkAMgAyAWNgJ4IAMgFTYCdCADIBQ2AnAgAyATNgJsIAMgETYCVCADIBA2AlAgAyAPNgJMIAMgAjYCSCAfIBIgDCANIA4Q5gcgAygC8AIhGyADKAL0AiEcIAMoAvgCIR0gAygC/AIhHiADIAc2ApwDIAMgBjYCmAMgAyAFNgKUAyADIAQ2ApADIAMgCzYCeCADIAo2AnQgAyAJNgJwIAMgCDYCbCADIB5BhZXcvQJqIgQ2AlQgAyAdQbjC7PACaiIFNgJQIAMgHEH827HpBGoiBjYCTCADIBtBk5rgmQVqIgc2AkggEiAMIA0gDhCwCCADIAY2AowCIAMgBzYCiAIgAyAENgKEAiADIAU2AoACIAMoAoADIQQgAygChAMhBSADKAKIAyEGIAMoAowDIQcgAyALNgJ4IAMgCjYCdCADIAk2AnAgAyAINgJsIAMgBzYCVCADIAY2AlAgAyAFNgJMIAMgBDYCSCAMIA0gDiADQYACahCwCCADKAKQAyEIIAMoApQDIQkgAygCmAMhCiADKAKcAyELIAMgGjYCjAMgAyAZNgKIAyADIBg2AoQDIAMgFzYCgAMgAyAWNgKcAyADIBU2ApgDIAMgFDYClAMgAyATNgKQAyADIBE2AnggAyAQNgJ0IAMgDzYCcCADIAI2AmwgAyAeNgJUIAMgHTYCUCADIBw2AkwgAyAbNgJIIB8gEiAMIA0gDhDmByADKALwAiEXIAMoAvQCIRggAygC+AIhGSADKAL8AiEaIAMgBzYCnAMgAyAGNgKYAyADIAU2ApQDIAMgBDYCkAMgAyALNgJ4IAMgCjYCdCADIAk2AnAgAyAINgJsIAMgGkHU5qmoBmoiBDYCVCADIBlBu5WoswdqIgU2AlAgAyAYQdLt9PEHayIGNgJMIAMgF0H7prfsBmsiBzYCSCASIAwgDSAOELAIIAMgBjYCnAIgAyAHNgKYAiADIAQ2ApQCIAMgBTYCkAIgAygCgAMhBCADKAKEAyEFIAMoAogDIQYgAygCjAMhByADIAs2AnggAyAKNgJ0IAMgCTYCcCADIAg2AmwgAyAHNgJUIAMgBjYCUCADIAU2AkwgAyAENgJIIAwgDSAOIANBkAJqELAIIAMoApADIQggAygClAMhCSADKAKYAyEKIAMoApwDIQsgAyAWNgKMAyADIBU2AogDIAMgFDYChAMgAyATNgKAAyADIBE2ApwDIAMgEDYCmAMgAyAPNgKUAyADIAI2ApADIAMgHjYCeCADIB02AnQgAyAcNgJwIAMgGzYCbCADIBo2AlQgAyAZNgJQIAMgGDYCTCADIBc2AkggHyASIAwgDSAOEOYHIAMoAvACIRMgAygC9AIhFCADKAL4AiEVIAMoAvwCIRYgAyAHNgKcAyADIAY2ApgDIAMgBTYClAMgAyAENgKQAyADIAs2AnggAyAKNgJ0IAMgCTYCcCADIAg2AmwgAyAWQd+ugOoFayIENgJUIAMgFUG1s5a/BWsiBTYCUCADIBRBkOnR7QNrIgY2AkwgAyATQd3czsQDayIHNgJIIBIgDCANIA4QsAggAyAGNgKsAiADIAc2AqgCIAMgBDYCpAIgAyAFNgKgAiADKAKAAyEEIAMoAoQDIQUgAygCiAMhBiADKAKMAyEHIAMgCzYCeCADIAo2AnQgAyAJNgJwIAMgCDYCbCADIAc2AlQgAyAGNgJQIAMgBTYCTCADIAQ2AkggDCANIA4gA0GgAmoQsAggAygCkAMhCCADKAKUAyEJIAMoApgDIQogAygCnAMhCyADIBE2AowDIAMgEDYCiAMgAyAPNgKEAyADIAI2AoADIAMgHjYCnAMgAyAdNgKYAyADIBw2ApQDIAMgGzYCkAMgAyAaNgJ4IAMgGTYCdCADIBg2AnAgAyAXNgJsIAMgFjYCVCADIBU2AlAgAyAUNgJMIAMgEzYCSCAfIBIgDCANIA4Q5gcgAygC8AIhAiADKAL0AiEPIAMoAvgCIRAgAygC/AIhESADIAc2ApwDIAMgBjYCmAMgAyAFNgKUAyADIAQ2ApADIAMgCzYCeCADIAo2AnQgAyAJNgJwIAMgCDYCbCADIBFB56+08wJrIgQ2AlQgAyAQQdzzm8sCayIFNgJQIAMgD0H7lMffAGsiBjYCTCADIAJB8MCqgwFqIgc2AkggEiAMIA0gDhCwCCADIAY2ArwCIAMgBzYCuAIgAyAENgK0AiADIAU2ArACIAMoAoADIQQgAygChAMhBSADKAKIAyEGIAMoAowDIQcgAyALNgJ4IAMgCjYCdCADIAk2AnAgAyAINgJsIAMgBzYCVCADIAY2AlAgAyAFNgJMIAMgBDYCSCAMIA0gDiADQbACahCwCCADKAKQAyEIIAMoApQDIQkgAygCmAMhCiADKAKcAyELIAMgHjYCjAMgAyAdNgKIAyADIBw2AoQDIAMgGzYCgAMgAyAaNgKcAyADIBk2ApgDIAMgGDYClAMgAyAXNgKQAyADIBY2AnggAyAVNgJ0IAMgFDYCcCADIBM2AmwgAyARNgJUIAMgEDYCUCADIA82AkwgAyACNgJIIB8gEiAMIA0gDhDmByADKALwAiEbIAMoAvQCIRwgAygC+AIhHSADKAL8AiEeIAMgBzYCnAMgAyAGNgKYAyADIAU2ApQDIAMgBDYCkAMgAyALNgJ4IAMgCjYCdCADIAk2AnAgAyAINgJsIAMgHkGWgpPNAWoiBDYCVCADIB1BiNjd8QFqIgU2AlAgAyAcQczuoboCaiIGNgJMIAMgG0G1+cKlA2oiBzYCSCASIAwgDSAOELAIIAMgBjYCzAIgAyAHNgLIAiADIAQ2AsQCIAMgBTYCwAIgAygCgAMhBCADKAKEAyEFIAMoAogDIQYgAygCjAMhByADIAs2AnggAyAKNgJ0IAMgCTYCcCADIAg2AmwgAyAHNgJUIAMgBjYCUCADIAU2AkwgAyAENgJIIAwgDSAOIANBwAJqELAIIAMoApADIQggAygClAMhCSADKAKYAyEKIAMoApwDIQsgAyAaNgKMAyADIBk2AogDIAMgGDYChAMgAyAXNgKAAyADIBY2ApwDIAMgFTYCmAMgAyAUNgKUAyADIBM2ApADIAMgETYCeCADIBA2AnQgAyAPNgJwIAMgAjYCbCADIB42AlQgAyAdNgJQIAMgHDYCTCADIBs2AkggHyASIAwgDSAOEOYHIAMoAvACIRcgAygC9AIhGCADKAL4AiEZIAMoAvwCIRogAyAHNgKcAyADIAY2ApgDIAMgBTYClAMgAyAENgKQAyADIAs2AnggAyAKNgJ0IAMgCTYCcCADIAg2AmwgAyAaQbOZ8MgDaiIENgJUIAMgGUHK1OL2BGoiBTYCUCADIBhBz5Tz3AVqIgY2AkwgAyAXQfPfucEGaiIHNgJIIBIgDCANIA4QsAggAyAGNgLcAiADIAc2AtgCIAMgBDYC1AIgAyAFNgLQAiADKAKAAyEEIAMoAoQDIQUgAygCiAMhBiADKAKMAyEHIAMgCzYCeCADIAo2AnQgAyAJNgJwIAMgCDYCbCADIAc2AlQgAyAGNgJQIAMgBTYCTCADIAQ2AkggDCANIA4gA0HQAmoQsAggAygCkAMhCCADKAKUAyEJIAMoApgDIQogAygCnAMhCyADIBY2AowDIAMgFTYCiAMgAyAUNgKEAyADIBM2AoADIAMgETYCnAMgAyAQNgKYAyADIA82ApQDIAMgAjYCkAMgAyAeNgJ4IAMgHTYCdCADIBw2AnAgAyAbNgJsIAMgGjYCVCADIBk2AlAgAyAYNgJMIAMgFzYCSCAfIBIgDCANIA4Q5gcgAygC8AIhEyADKAL0AiEUIAMoAvgCIRUgAygC/AIhFiADIAc2ApwDIAMgBjYCmAMgAyAFNgKUAyADIAQ2ApADIAMgCzYCeCADIAo2AnQgAyAJNgJwIAMgCDYCbCADIBZB7oW+pAdqIgQ2AlQgAyAVQe/GlcUHaiIFNgJQIAMgFEHsj97ZB2siBjYCTCADIBNB+PvjmQdrIgc2AkggEiAMIA0gDhCwCCADIAY2AuwCIAMgBzYC6AIgAyAENgLkAiADIAU2AuACIAMoAoADIQQgAygChAMhBSADKAKIAyEGIAMoAowDIQcgAyALNgJ4IAMgCjYCdCADIAk2AnAgAyAINgJsIAMgBzYCVCADIAY2AlAgAyAFNgJMIAMgBDYCSCAMIA0gDiADQeACahCwCCADKAKQAyEIIAMoApQDIQkgAygCmAMhCiADKAKcAyELIAMgETYCjAMgAyAQNgKIAyADIA82AoQDIAMgAjYCgAMgAyAeNgKcAyADIB02ApgDIAMgHDYClAMgAyAbNgKQAyADIBo2AnggAyAZNgJ0IAMgGDYCcCADIBc2AmwgAyAWNgJUIAMgFTYCUCADIBQ2AkwgAyATNgJIIB8gEiAMIA0gDhDmByADKALwAiECIAMoAvQCIQ8gAygC+AIhECADKAL8AiERIAMgBzYCnAMgAyAGNgKYAyADIAU2ApQDIAMgBDYCkAMgAyALNgJ4IAMgCjYCdCADIAk2AnAgAyAINgJsIAMgEUGGgIT6BmsiETYCVCADIBBBlaa+3QVrIhA2AlAgAyAPQYm4mYgEayIPNgJMIAMgAkGOjrrMA2siAjYCSCAfIAwgDSAOELAIIAMgDzYCjAMgAyACNgKIAyADIBE2AoQDIAMgEDYCgAMgAygC8AIhAiADKAL0AiEPIAMoAvgCIRAgAygC/AIhESADIAs2AnggAyAKNgJ0IAMgCTYCcCADIAg2AmwgAyARNgJUIAMgEDYCUCADIA82AkwgAyACNgJIIBEgJGohJCAQICVqISUgDyAmaiEmIAIgJ2ohJyAMIA0gDiASELAIIAMoApwDICBqISAgAygCmAMgIWohISADKAKUAyAiaiEiIAMoApADICNqISMgASAoRw0ACwsgACAkNgIcIAAgJTYCGCAAICA2AhQgACAhNgIQIAAgJjYCDCAAICc2AgggACAiNgIEIAAgIzYCACADQaADaiQADwtB0NfhAEErIANByABqQcDX4QBB/NfhABCpDgALmogBARV/IwBB4ABrIgMkAEHMp98AIQcCQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCABKAIAIg9BAWsOBBYAAgMBCyABKAIYIQ8gASgCFCENIAEoAgwhBSABKAIEIQQCQCABKAIIIgxBA0YEQEEAIQEDQCABQQNGDQIgASAEaiECIAFBrKbfAGohByABQQFqIQFBIEEAIAItAAAiAkHBAGtB/wFxQRpJGyACckH/AXFBIEEAIActAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFGDQALQQAhAQNAIAFBA0YNBiABIARqIQIgAUGvpt8AaiEHIAFBAWohAUEgQQAgAi0AACICQcEAa0H/AXFBGkkbIAJyQf8BcUEgQQAgBy0AACIGQcEAa0H/AXFBGkkbIAZyQf8BcUYNAAsLIAxBBEYEQEEAIQEDQCABQQRGDRYgASAEaiECIAFBsqbfAGohBiABQQFqIQFBIEEAIAItAAAiAkHBAGtB/wFxQRpJGyACckH/AXFBIEEAIAYtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFGDQALCyAMQQZGBEBBACEBA0AgAUEGRg0VIAEgBGohAiABQbam3wBqIQYgAUEBaiEBQSBBACACLQAAIgJBwQBrQf8BcUEaSRsgAnJB/wFxQSBBACAGLQAAIgZBwQBrQf8BcUEaSRsgBnJB/wFxRg0AC0EAIQEDQCABQQZGDRQgASAEaiECIAFBvKbfAGohBiABQQFqIQFBIEEAIAItAAAiAkHBAGtB/wFxQRpJGyACckH/AXFBIEEAIAYtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFGDQALCyAMQQVGBEBBACEBA0AgAUEFRg0HIAEgBGohAiABQcKm3wBqIQYgAUEBaiEBQSBBACACLQAAIgJBwQBrQf8BcUEaSRsgAnJB/wFxQSBBACAGLQAAIgZBwQBrQf8BcUEaSRsgBnJB/wFxRg0ACwsgDEELRgRAQQAhAQNAIAFBC0YNEiABIARqIQIgAUHHpt8AaiEGIAFBAWohAUEgQQAgAi0AACICQcEAa0H/AXFBGkkbIAJyQf8BcUEgQQAgBi0AACIGQcEAa0H/AXFBGkkbIAZyQf8BcUYNAAsLIAxBDUYEQEEAIQEDQCABQQ1GDQggASAEaiECIAFB0qbfAGohBiABQQFqIQFBIEEAIAItAAAiAkHBAGtB/wFxQRpJGyACckH/AXFBIEEAIAYtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFGDQALQQAhAQNAIAFBDUYNCSABIARqIQIgAUHfpt8AaiEGIAFBAWohAUEgQQAgAi0AACICQcEAa0H/AXFBGkkbIAJyQf8BcUEgQQAgBi0AACIGQcEAa0H/AXFBGkkbIAZyQf8BcUYNAAsLIAxBB0YEQEEAIQEDQCABQQdGDQogASAEaiECIAFB7KbfAGohBiABQQFqIQFBIEEAIAItAAAiAkHBAGtB/wFxQRpJGyACckH/AXFBIEEAIAYtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFGDQALCyAMQQZGBEBBACEBA0AgAUEGRg0LIAEgBGohAiABQfOm3wBqIQYgAUEBaiEBQSBBACACLQAAIgJBwQBrQf8BcUEaSRsgAnJB/wFxQSBBACAGLQAAIgZBwQBrQf8BcUEaSRsgBnJB/wFxRg0AC0EAIQEDQCABQQZGDQwgASAEaiECIAFB+abfAGohBiABQQFqIQFBIEEAIAItAAAiAkHBAGtB/wFxQRpJGyACckH/AXFBIEEAIAYtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFGDQALCyAMQQlGBEBBACEBA0AgAUEJRg0NIAEgBGohAiABQf+m3wBqIQYgAUEBaiEBQSBBACACLQAAIgJBwQBrQf8BcUEaSRsgAnJB/wFxQSBBACAGLQAAIgZBwQBrQf8BcUEaSRsgBnJB/wFxRg0ACwsgDEEORgRAQQAhAQNAIAFBDkYNDiABIARqIQIgAUGIp98AaiEGIAFBAWohAUEgQQAgAi0AACICQcEAa0H/AXFBGkkbIAJyQf8BcUEgQQAgBi0AACIGQcEAa0H/AXFBGkkbIAZyQf8BcUYNAAsLIAxBB0YEQEEAIQEDQCABQQdGDQ8gASAEaiECIAFBlqffAGohBiABQQFqIQFBIEEAIAItAAAiAkHBAGtB/wFxQRpJGyACckH/AXFBIEEAIAYtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFGDQALCyAMQQtGBEBBACEBA0AgAUELRg0QIAEgBGohAiABQZ2n3wBqIQYgAUEBaiEBQSBBACACLQAAIgJBwQBrQf8BcUEaSRsgAnJB/wFxQSBBACAGLQAAIgZBwQBrQf8BcUEaSRsgBnJB/wFxRg0ACwsgDEEERgRAQQAhAQNAIAFBBEYNESABIARqIQIgAUGop98AaiEGIAFBAWohAUEgQQAgAi0AACICQcEAa0H/AXFBGkkbIAJyQf8BcUEgQQAgBi0AACIGQcEAa0H/AXFBGkkbIAZyQf8BcUYNAAsLIANByABqIgEgBCAMEJUEIANBJGogARDmCyADQRBqIANBLmovAQA7AQAgAyAFNgIcIAMgAy8BJDsBICADIAMpASY3AwhBASEBDBoLAkAgD0UEQEEDIQQMAQsgDSAPQQV0aiEHIA0hAgNAIAIoAgAhDAJAIAIoAgQiAUEHRgRAIAJBIGohBUEAIQEDQCABQQdGDQIgASAMaiEEIAFB0KXfAGohBiABQQFqIQFBIEEAIAQtAAAiBEHBAGtB/wFxQRpJGyAEckH/AXFBIEEAIAYtAAAiBEHBAGtB/wFxQRpJGyAEckH/AXFGDQALQQchAQsgAigCCCEEIANByABqIgIgDCABEJUEIANBLGogAhDmCyADIAQ2AihBAiEBDBsLIANByABqIAJBEGoQkQUgAy0ATCEEIAMoAkgiAUEHRwRAIANBOGogA0HcAGooAAA2AAAgA0ExaiADQdUAaikAADcAACADIAMpAE03ACkMGwsgBSICIAdHDQALCyADIAQ6AB0gA0EAOgAcDBQLIAEoAgQhByABKAIIIQ8MFAsgASgCCCEPIAEoAgQhByADIAEoAgwiDSABKAIQIgFBHGxqNgIwIAMgATYCLCADIA02AiggAyANNgIkIANByABqIANBJGoQ2wkgAygCUCEEIAMoAkwhBiADKAJIIgFBB0cEQCAAIAMpAlQ3AgwgAEEUaiADQdwAaigCADYCACAAIAQ2AgggACAGNgIEIAAgATYCAAwZC0ECIQUMEwtBAyEFIAEoAgghDyABKAIEIQcgAyABKAIMIg0gASgCECIBQQN0ajYCMCADIAE2AiwgAyANNgIoIAMgDTYCJCADQcgAaiEOIwBB0ABrIhQkACAUQQc2AhQgFEFAayADQSRqIgFBCGopAgA3AwAgFCABKQIANwM4IBQgFEEUajYCSCAUQSxqIRIjAEEgayIWJAAgFEE4aiIIKAIIIQogCCgCACENIBYgCCgCDDYCBCAIKAIQIQEgFiAIQRBqNgIcIBYgATYCGCAWIBZBBGo2AhQgFkEIaiEQIA0hBiAWQRRqIQsjAEEwayIVJAACQCAIKAIEIgQgCCgCDCIMRg0AA0AgCCAEQQhqIgE2AgQgFSAEKAIAIhEgBEEEaigCACIEQRxsajYCLCAVIAQ2AiggFSARNgIkIBUgETYCICAVQQhqIBVBIGoQ2wkgFSgCECETIBUoAgwhESAVKAIIIgRBB0cEQCALKAIEIgEQwxogASATNgIIIAEgETYCBCABIAQ2AgAgASAVKQIUNwIMIAFBFGogFUEcaigCADYCAEEBIQkMAgsgBiARNgIAIAZBBGogEzYCACAGQQhqIQYgASIEIAxHDQALCyAQIAY2AgggECANNgIEIBAgCTYCACAVQTBqJAAgFigCECEBIwBBEGsiDCQAIAhBADYCCCAIKAIMIQYgCCgCBCELIAhBBDYCACAMQoCAgIDAADcCCCAMQQhqQQRBCBCuDiAIQQQ2AgwgCEEENgIEIAYgC0cEQCAGIAtrQQN2IQQDQCALEPEUIAtBCGohCyAEQQFrIgQNAAsLIAxBEGokACASIAEgDWtBA3Y2AgggEiANNgIEIBIgCjYCACMAQRBrIgYkACAIKAIMIgEgCCgCBCINRwRAIAEgDWtBA3YhAQNAIA0Q8RQgDUEIaiENIAFBAWsiAQ0ACwsgBiAIKAIANgIMIAYgCCgCCDYCCCAGQQhqQQRBCBCuDiAGQRBqJAAgFkEgaiQAIBRBCGogEkGYtd8AEIoQIBQgFCgCDCINNgI8IBQgFCgCCCIBNgI4AkAgFCgCFEEHRwRAIA4gFCkCFDcCACAOQRBqIBRBJGopAgA3AgAgDkEIaiAUQRxqKQIANwIAIAgQ7xQMAQsgDiANNgIIIA4gATYCBCAOQQc2AgALIBRB0ABqJAAgAygCUCEEIAMoAkwhBiADKAJIIgFBB0YNEiAAIAMpAlQ3AgwgAEEUaiADQdwAaigCADYCACAAIAQ2AgggACAGNgIEIAAgATYCAAwXCyAPBEAgDSgCCCEGIANBJGoiAiANKAIAIA0oAgQQlQQgA0HQAGoiASACEOYLIANBIGogAS8BADsBACADIAY2AhwgAyADKQFSNwMIIAMgA0HYAGopAQA3AQ5BAiEBDBYLQQEhBSADQQE6ABwgAy8BHCECDBELIANByABqIQggDSEBIwBBMGsiCiQAAkACQCAPRQRAQQIhEUEDIQ5BAyETDAELIAEgD0EFdGohDEEDIRNBAiERQQMhDgNAIAEoAgAhCwJAAkAgASgCBCIJQQdGBEBBACECA0AgAkEHRg0CIAIgC2ohBSACQdCl3wBqIQcgAkEBaiECQSBBACAFLQAAIgVBwQBrQf8BcUEaSRsgBXJB/wFxQSBBACAHLQAAIgVBwQBrQf8BcUEaSRsgBXJB/wFxRg0ACwsCQAJAIAlBBEYEQEEAIQIDQCACQQRGDQIgAiALaiEFIAJB4aXfAGohByACQQFqIQJBIEEAIAUtAAAiBUHBAGtB/wFxQRpJGyAFckH/AXFBIEEAIActAAAiBUHBAGtB/wFxQRpJGyAFckH/AXFGDQALCyAJQQ5GBEBBACECA0AgAkEORg0DIAIgC2ohBSACQdan3wBqIQcgAkEBaiECQSBBACAFLQAAIgVBwQBrQf8BcUEaSRsgBXJB/wFxQSBBACAHLQAAIgVBwQBrQf8BcUEaSRsgBXJB/wFxRg0AC0EOIQkLIAEoAgghAiAKQQxqIgEgCyAJEJUEIAhBCGogARDmCyAIIAI2AgQgCEECNgIADAYLIAEoAhAhCyABKAIUIglBCUYEQEEAIQ5BACECA0AgAkEJRg0EIAIgC2ohBSACQayo3wBqIQcgAkEBaiECQSBBACAFLQAAIgVBwQBrQf8BcUEaSRsgBXJB/wFxQSBBACAHLQAAIgVBwQBrQf8BcUEaSRsgBXJB/wFxRg0ACwsgCUEERgRAQQAhAgNAIAJBBEYEQEEBIQ4MBQsgAiALaiEFIAJB6qXfAGohByACQQFqIQJBIEEAIAUtAAAiBUHBAGtB/wFxQRpJGyAFckH/AXFBIEEAIActAAAiBUHBAGtB/wFxQRpJGyAFckH/AXFGDQALCyAJQQVGBEBBACECA0AgAkEFRgRAQQIhDgwFCyACIAtqIQUgAkHlpd8AaiEHIAJBAWohAkEgQQAgBS0AACIFQcEAa0H/AXFBGkkbIAVyQf8BcUEgQQAgBy0AACIFQcEAa0H/AXFBGkkbIAVyQf8BcUYNAAtBBSEJCyABKAIYIQIgCkEkaiIBIAsgCRCVBCAKQRRqIAEQ5gsgCEENaiAKQRlqKQAANwAAIAhBFGogCkEgaigAADYAACAKIAI2AhAgCCAKKQARNwAFIAggAjoABCAIQQI2AgAMBQsgASgCECELIAEoAhQiCUEFRgRAQQAhEUEAIQIDQCACQQVGDQMgAiALaiEFIAJBo6bfAGohByACQQFqIQJBIEEAIAUtAAAiBUHBAGtB/wFxQRpJGyAFckH/AXFBIEEAIActAAAiBUHBAGtB/wFxQRpJGyAFckH/AXFGDQALCyAJQQRGBEBBACECA0AgAkEERgRAQQEhEQwECyACIAtqIQUgAkGopt8AaiEHIAJBAWohAkEgQQAgBS0AACIFQcEAa0H/AXFBGkkbIAVyQf8BcUEgQQAgBy0AACIFQcEAa0H/AXFBGkkbIAVyQf8BcUYNAAtBBCEJCyABKAIYIQIgCkEkaiIBIAsgCRCVBCAKQRRqIAEQ5gsgCEENaiAKQRlqKQAANwAAIAhBFGogCkEgaigAADYAACAKIAI2AhAgCCAKKQARNwAFIAggAjoABCAIQQI2AgAMBAsgCkEMaiABQRBqEJEFIAotABAhEyAKKAIMIgJBB0YNACAIIAopABE3AAUgCEEUaiAKQSBqKAAANgAAIAhBDWogCkEZaikAADcAACAIIBM6AAQgCCACNgIADAMLIAFBIGoiASAMRw0ACwsgCCAOOgAGIAggEzoABSAIIBE6AAQgCEEHNgIACyAKQTBqJAAgAyADLwFMOwEkIAMgA0HOAGotAAA6ACYgAygCSCIBQQdHBEAgA0EhaiADQdEAai0AADoAACADIAMvAE87AB8gAyADKQFSNwMIIAMgA0HYAGopAQA3AQ4gAyADLwEkOwEcIAMgAy0AJjoAHgwMCyADIAMvASQ7AB0gAyADLQAmOgAfIANBBToAHAwLCyADQcgAaiANIA8QrgYgAy0ATCEEAkAgAygCSCIBQQdHBEAgA0EhaiADQdEAai0AADoAACADIAMoAE02AB0gAyADKQFSNwMIIAMgA0HYAGopAQA3AQ4MAQsgAyAEOgAdQQchBAsgAyAEOgAcDAoLIANByABqIA0gDxCuBiADLQBMIQQCQCADKAJIIgFBB0cEQCADQSFqIANB0QBqLQAAOgAAIAMgAygATTYAHSADIAMpAVI3AwggAyADQdgAaikBADcBDgwBCyADIAQ6AB1BCCEECyADIAQ6ABwMCQsgA0HIAGogDSAPEK4GIAMtAEwhBAJAIAMoAkgiAUEHRwRAIANBIWogA0HRAGotAAA6AAAgAyADKABNNgAdIAMgAykBUjcDCCADIANB2ABqKQEANwEODAELIAMgBDoAHUEJIQQLIAMgBDoAHAwICyADQcgAaiEIIA0hASMAQTBrIgokAAJAAkAgD0UEQEECIQdBAiEJDAELIAEgD0EFdGohDEECIQlBAiEHA0AgASgCACELAkACQAJAIAEoAgQiBUEERgRAQQAhAgNAIAJBBEYNAiACIAtqIQYgAkHpp98AaiEEIAJBAWohAkEgQQAgBi0AACIGQcEAa0H/AXFBGkkbIAZyQf8BcUEgQQAgBC0AACIGQcEAa0H/AXFBGkkbIAZyQf8BcUYNAAsLIAVBDkYEQEEAIQIDQCACQQ5GDQMgAiALaiEGIAJB1qffAGohBCACQQFqIQJBIEEAIAYtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFBIEEAIAQtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFGDQALQQ4hBQsgASgCCCECIApBDGoiASALIAUQlQQgCEEIaiABEOYLIAggAjYCBCAIQQI2AgAMBQsgASgCECEFIAEoAhQiAkEFRgRAQQAhCUEAIQIDQCACQQVGDQMgAiAFaiEGIAJB16XfAGohBCACQQFqIQJBIEEAIAYtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFBIEEAIAQtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFGDQALQQAhAgNAIAJBBUYEQEEBIQkMBAsgAiAFaiEGIAJB3KXfAGohBCACQQFqIQJBIEEAIAYtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFBIEEAIAQtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFGDQALQQUhAgsgASgCGCEGIApBJGoiASAFIAIQlQQgCkEUaiABEOYLIAhBDWogCkEZaikAADcAACAIQRRqIApBIGooAAA2AAAgCiAGNgIQIAggCikAETcABSAIIAY6AAQgCEECNgIADAQLIAEoAhAhCyABKAIUIgVBBUYEQEEAIQdBACECA0AgAkEFRg0CIAIgC2ohBiACQaOm3wBqIQQgAkEBaiECQSBBACAGLQAAIgZBwQBrQf8BcUEaSRsgBnJB/wFxQSBBACAELQAAIgZBwQBrQf8BcUEaSRsgBnJB/wFxRg0ACwsgBUEERgRAQQAhAgNAIAJBBEYEQEEBIQcMAwsgAiALaiEGIAJBqKbfAGohBCACQQFqIQJBIEEAIAYtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFBIEEAIAQtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFGDQALQQQhBQsgASgCGCECIApBJGoiASALIAUQlQQgCkEUaiABEOYLIAhBDWogCkEZaikAADcAACAIQRRqIApBIGooAAA2AAAgCiACNgIQIAggCikAETcABSAIIAI6AAQgCEECNgIADAMLIAFBIGoiASAMRw0ACwsgCCAHOgAFIAggCToABCAIQQc2AgALIApBMGokACADLQBNIQQgAy0ATCEGAn8gAygCSCIBQQdHBEAgAyADKAFONgEeIAMgAykBUjcDCCADIANB2ABqKQEANwEOIAYMAQsgAyAEOgAeIAYhBEEKCyECIAMgBDoAHSADIAI6ABwMBwsgA0HIAGogDSAPEK4GIAMtAEwhBAJAIAMoAkgiAUEHRwRAIANBIWogA0HRAGotAAA6AAAgAyADKABNNgAdIAMgAykBUjcDCCADIANB2ABqKQEANwEODAELIAMgBDoAHUELIQQLIAMgBDoAHAwGCyADQcgAaiESIA0hASMAQTBrIggkAAJAAkAgD0UEQEEKIQcMAQsgASAPQQV0aiEKA0AgASICKAIAIQwCQCACKAIEIgRBBkYEQCACQSBqIQFBACEEA0AgBEEGRg0CIAQgDGohBSAEQbWo3wBqIQcgBEEBaiEEQSBBACAFLQAAIgVBwQBrQf8BcUEaSRsgBXJB/wFxQSBBACAHLQAAIgVBwQBrQf8BcUEaSRsgBXJB/wFxRg0AC0EGIQQLIAIoAgghAiAIQQxqIgEgDCAEEJUEIBJBCGogARDmCyASIAI2AgQgEkECNgIADAMLIAIoAhAhEQJAIAIoAhQiE0EBRgRAQQAhB0EAIQRBACEFA0AgBQ0CIAQgEWohDCAEQZim3wBqIQtBASEFIARBAWohBEEgQQAgDC0AACIMQcEAa0H/AXFBGkkbIAxyQf8BcUEgQQAgCy0AACIMQcEAa0H/AXFBGkkbIAxyQf8BcUYNAAtBACEEQQAhBQNAQQEhByAFDQIgBCARaiEHIARBmabfAGohDEEBIQUgBEEBaiEEQSBBACAHLQAAIgdBwQBrQf8BcUEaSRsgB3JB/wFxQSBBACAMLQAAIgdBwQBrQf8BcUEaSRsgB3JB/wFxRg0AC0EAIQRBACEFA0AgBQRAQQIhBwwDCyAEIBFqIQcgBEGapt8AaiEMQQEhBSAEQQFqIQRBIEEAIActAAAiB0HBAGtB/wFxQRpJGyAHckH/AXFBIEEAIAwtAAAiB0HBAGtB/wFxQRpJGyAHckH/AXFGDQALQQAhBEEAIQUDQCAFBEBBAyEHDAMLIAQgEWohByAEQZum3wBqIQxBASEFIARBAWohBEEgQQAgBy0AACIHQcEAa0H/AXFBGkkbIAdyQf8BcUEgQQAgDC0AACIHQcEAa0H/AXFBGkkbIAdyQf8BcUYNAAtBACEEQQAhBQNAIAUEQEEEIQcMAwsgBCARaiEHIARBnKbfAGohDEEBIQUgBEEBaiEEQSBBACAHLQAAIgdBwQBrQf8BcUEaSRsgB3JB/wFxQSBBACAMLQAAIgdBwQBrQf8BcUEaSRsgB3JB/wFxRg0AC0EAIQRBACEFA0AgBQRAQQUhBwwDCyAEIBFqIQcgBEGdpt8AaiEMQQEhBSAEQQFqIQRBIEEAIActAAAiB0HBAGtB/wFxQRpJGyAHckH/AXFBIEEAIAwtAAAiB0HBAGtB/wFxQRpJGyAHckH/AXFGDQALQQAhBEEAIQUDQCAFBEBBBiEHDAMLIAQgEWohByAEQZ6m3wBqIQxBASEFIARBAWohBEEgQQAgBy0AACIHQcEAa0H/AXFBGkkbIAdyQf8BcUEgQQAgDC0AACIHQcEAa0H/AXFBGkkbIAdyQf8BcUYNAAtBACEEQQAhBQNAIAUEQEEHIQcMAwsgBCARaiEHIARBn6bfAGohDEEBIQUgBEEBaiEEQSBBACAHLQAAIgdBwQBrQf8BcUEaSRsgB3JB/wFxQSBBACAMLQAAIgdBwQBrQf8BcUEaSRsgB3JB/wFxRg0AC0EAIQRBACEFA0AgBQRAQQghBwwDCyAEIBFqIQcgBEGgpt8AaiEMQQEhBSAEQQFqIQRBIEEAIActAAAiB0HBAGtB/wFxQRpJGyAHckH/AXFBIEEAIAwtAAAiB0HBAGtB/wFxQRpJGyAHckH/AXFGDQALCyATQQJGBEBBACEEA0AgBEECRgRAQQkhBwwDCyAEIBFqIQUgBEGhpt8AaiEHIARBAWohBEEgQQAgBS0AACIFQcEAa0H/AXFBGkkbIAVyQf8BcUEgQQAgBy0AACIFQcEAa0H/AXFBGkkbIAVyQf8BcUYNAAtBAiETCyACKAIYIQIgCEEkaiIBIBEgExCVBCAIQRRqIAEQ5gsgEkENaiAIQRlqKQAANwAAIBJBFGogCEEgaigAADYAACAIIAI2AhAgEiAIKQARNwAFIBIgAjoABCASQQI2AgAMAwsgASAKRw0ACwsgEkEHNgIAIBIgBzoABAsgCEEwaiQAIAMtAEwhBAJAIAMoAkgiAUEHRwRAIANBIWogA0HRAGotAAA6AAAgAyADKABNNgAdIAMgAykBUjcDCCADIANB2ABqKQEANwEODAELIAMgBDoAHUEMIQQLIAMgBDoAHAwFCyADQcgAaiEIIA0hASMAQTBrIgokAAJAAkAgD0UEQEECIQ5BBCEHDAELIAEgD0EFdGohDEECIQ5BBCEHA0AgASgCACELAkACQAJAIAEoAgQiBUEJRgRAQQAhAgNAIAJBCUYNAiACIAtqIQYgAkGMpt8AaiEEIAJBAWohAkEgQQAgBi0AACIGQcEAa0H/AXFBGkkbIAZyQf8BcUEgQQAgBC0AACIGQcEAa0H/AXFBGkkbIAZyQf8BcUYNAAsLIAVBBEYEQEEAIQIDQCACQQRGDQMgAiALaiEGIAJBzKXfAGohBCACQQFqIQJBIEEAIAYtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFBIEEAIAQtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFGDQALQQQhBQsgASgCCCECIApBDGoiASALIAUQlQQgCEEIaiABEOYLIAggAjYCBCAIQQI2AgAMBQsgASgCECELIAEoAhQiBUEGRgRAQQAhB0EAIQIDQCACQQZGDQMgAiALaiEGIAJB+abfAGohBCACQQFqIQJBIEEAIAYtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFBIEEAIAQtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFGDQALCyAFQQtGBEBBACECA0AgAkELRgRAQQEhBwwECyACIAtqIQYgAkGsp98AaiEEIAJBAWohAkEgQQAgBi0AACIGQcEAa0H/AXFBGkkbIAZyQf8BcUEgQQAgBC0AACIGQcEAa0H/AXFBGkkbIAZyQf8BcUYNAAtBACECA0AgAkELRgRAQQIhBwwECyACIAtqIQYgAkG3p98AaiEEIAJBAWohAkEgQQAgBi0AACIGQcEAa0H/AXFBGkkbIAZyQf8BcUEgQQAgBC0AACIGQcEAa0H/AXFBGkkbIAZyQf8BcUYNAAsLIAVBCkYEQEEAIQIDQCACQQpGBEBBAyEHDAQLIAIgC2ohBiACQcKn3wBqIQQgAkEBaiECQSBBACAGLQAAIgZBwQBrQf8BcUEaSRsgBnJB/wFxQSBBACAELQAAIgZBwQBrQf8BcUEaSRsgBnJB/wFxRg0AC0EKIQULIAEoAhghAiAKQSRqIgEgCyAFEJUEIApBFGogARDmCyAIQQ1qIApBGWopAAA3AAAgCEEUaiAKQSBqKAAANgAAIAogAjYCECAIIAopABE3AAUgCCACOgAEIAhBAjYCAAwECyAKQQxqIAFBEGoQ0QYgCi0AECEOIAooAgwiAkEHRg0AIAggCikAETcABSAIQRRqIApBIGooAAA2AAAgCEENaiAKQRlqKQAANwAAIAggDjoABCAIIAI2AgAMAwsgAUEgaiIBIAxHDQALCyAIIAc6AAUgCCAOOgAEIAhBBzYCAAsgCkEwaiQAIAMtAE0hBCADLQBMIQYCfyADKAJIIgFBB0cEQCADIAMoAU42AR4gAyADKQFSNwMIIAMgA0HYAGopAQA3AQ4gBgwBCyADIAQ6AB4gBiEEQQ0LIQIgAyAEOgAdIAMgAjoAHAwECyADQcgAaiEIIA0hASMAQTBrIgokAAJAAkAgD0UEQEECIRNBBCEOQQIhEgwBCyABIA9BBXRqIQxBAiESQQIhE0EEIQ4DQCABKAIAIQsCQAJAAkACQCABKAIEIglBBEYEQEEAIQIDQCACQQRGDQIgAiALaiEFIAJB4aXfAGohByACQQFqIQJBIEEAIAUtAAAiBUHBAGtB/wFxQRpJGyAFckH/AXFBIEEAIActAAAiBUHBAGtB/wFxQRpJGyAFckH/AXFGDQALCyAJQQtGBEBBACECA0AgAkELRg0DIAIgC2ohBSACQfqn3wBqIQcgAkEBaiECQSBBACAFLQAAIgVBwQBrQf8BcUEaSRsgBXJB/wFxQSBBACAHLQAAIgVBwQBrQf8BcUEaSRsgBXJB/wFxRg0ACwsgCUEORgRAQQAhAgNAIAJBDkYNBCACIAtqIQUgAkHWp98AaiEHIAJBAWohAkEgQQAgBS0AACIFQcEAa0H/AXFBGkkbIAVyQf8BcUEgQQAgBy0AACIFQcEAa0H/AXFBGkkbIAVyQf8BcUYNAAtBDiEJCyABKAIIIQIgCkEMaiIBIAsgCRCVBCAIQQhqIAEQ5gsgCCACNgIEIAhBAjYCAAwGCyABKAIQIQsgASgCFCIJQQVGBEBBACEOQQAhAgNAIAJBBUYNBCACIAtqIQUgAkHlpd8AaiEHIAJBAWohAkEgQQAgBS0AACIFQcEAa0H/AXFBGkkbIAVyQf8BcUEgQQAgBy0AACIFQcEAa0H/AXFBGkkbIAVyQf8BcUYNAAsLIAlBBEYEQEEAIQIDQCACQQRGBEBBASEODAULIAIgC2ohBSACQeql3wBqIQcgAkEBaiECQSBBACAFLQAAIgVBwQBrQf8BcUEaSRsgBXJB/wFxQSBBACAHLQAAIgVBwQBrQf8BcUEaSRsgBXJB/wFxRg0ACwsgCUEGRgRAQQAhAgNAIAJBBkYEQEECIQ4MBQsgAiALaiEFIAJB7qXfAGohByACQQFqIQJBIEEAIAUtAAAiBUHBAGtB/wFxQRpJGyAFckH/AXFBIEEAIActAAAiBUHBAGtB/wFxQRpJGyAFckH/AXFGDQALQQAhAgNAIAJBBkYEQEEDIQ4MBQsgAiALaiEFIAJB9KXfAGohByACQQFqIQJBIEEAIAUtAAAiBUHBAGtB/wFxQRpJGyAFckH/AXFBIEEAIActAAAiBUHBAGtB/wFxQRpJGyAFckH/AXFGDQALQQYhCQsgASgCGCECIApBJGoiASALIAkQlQQgCkEUaiABEOYLIAhBDWogCkEZaikAADcAACAIQRRqIApBIGooAAA2AAAgCiACNgIQIAggCikAETcABSAIIAI6AAQgCEECNgIADAULIAEoAhAhCyABKAIUIglBBUYEQEEAIRJBACECA0AgAkEFRg0DIAIgC2ohBSACQaOm3wBqIQcgAkEBaiECQSBBACAFLQAAIgVBwQBrQf8BcUEaSRsgBXJB/wFxQSBBACAHLQAAIgVBwQBrQf8BcUEaSRsgBXJB/wFxRg0ACwsgCUEERgRAQQAhAgNAIAJBBEYEQEEBIRIMBAsgAiALaiEFIAJBqKbfAGohByACQQFqIQJBIEEAIAUtAAAiBUHBAGtB/wFxQRpJGyAFckH/AXFBIEEAIActAAAiBUHBAGtB/wFxQRpJGyAFckH/AXFGDQALQQQhCQsgASgCGCECIApBJGoiASALIAkQlQQgCkEUaiABEOYLIAhBDWogCkEZaikAADcAACAIQRRqIApBIGooAAA2AAAgCiACNgIQIAggCikAETcABSAIIAI6AAQgCEECNgIADAQLIAEoAhAhCyABKAIUIglBBUYEQEEAIRNBACECA0AgAkEFRg0CIAIgC2ohBSACQaOm3wBqIQcgAkEBaiECQSBBACAFLQAAIgVBwQBrQf8BcUEaSRsgBXJB/wFxQSBBACAHLQAAIgVBwQBrQf8BcUEaSRsgBXJB/wFxRg0ACwsgCUEERgRAQQAhAgNAIAJBBEYEQEEBIRMMAwsgAiALaiEFIAJBqKbfAGohByACQQFqIQJBIEEAIAUtAAAiBUHBAGtB/wFxQRpJGyAFckH/AXFBIEEAIActAAAiBUHBAGtB/wFxQRpJGyAFckH/AXFGDQALQQQhCQsgASgCGCECIApBJGoiASALIAkQlQQgCkEUaiABEOYLIAhBDWogCkEZaikAADcAACAIQRRqIApBIGooAAA2AAAgCiACNgIQIAggCikAETcABSAIIAI6AAQgCEECNgIADAMLIAFBIGoiASAMRw0ACwsgCCAOOgAGIAggEzoABSAIIBI6AAQgCEEHNgIACyAKQTBqJAAgAyADLwFMOwEkIAMgA0HOAGotAAA6ACYgAygCSCIBQQdHBEAgA0EhaiADQdEAai0AADoAACADIAMvAE87AB8gAyADKQFSNwMIIAMgA0HYAGopAQA3AQ4gAyADLwEkOwEcIAMgAy0AJjoAHgwECyADIAMvASQ7AB0gAyADLQAmOgAfIANBDjoAHAwDCyADQcgAaiEIIA0hASMAQTBrIgokAAJAAkAgD0UEQEEDIQdBAyEJDAELIAEgD0EFdGohDEEDIQlBAyEHA0AgASgCACELAkACQCABKAIEIgVBB0YEQEEAIQIDQCACQQdGDQIgAiALaiEGIAJB0KXfAGohBCACQQFqIQJBIEEAIAYtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFBIEEAIAQtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFGDQALCwJAIAVBBEYEQEEAIQIDQCACQQRGDQIgAiALaiEGIAJB4aXfAGohBCACQQFqIQJBIEEAIAYtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFBIEEAIAQtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFGDQALQQQhBQsgASgCCCECIApBDGoiASALIAUQlQQgCEEIaiABEOYLIAggAjYCBCAIQQI2AgAMBQsgASgCECELIAEoAhQiBUEDRgRAQQAhB0EAIQIDQCACQQNGDQMgAiALaiEGIAJBlabfAGohBCACQQFqIQJBIEEAIAYtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFBIEEAIAQtAAAiBkHBAGtB/wFxQRpJGyAGckH/AXFGDQALCyAFQQZGBEBBACECA0AgAkEGRgRAQQEhBwwECyACIAtqIQYgAkHupd8AaiEEIAJBAWohAkEgQQAgBi0AACIGQcEAa0H/AXFBGkkbIAZyQf8BcUEgQQAgBC0AACIGQcEAa0H/AXFBGkkbIAZyQf8BcUYNAAtBACECA0AgAkEGRgRAQQIhBwwECyACIAtqIQYgAkH0pd8AaiEEIAJBAWohAkEgQQAgBi0AACIGQcEAa0H/AXFBGkkbIAZyQf8BcUEgQQAgBC0AACIGQcEAa0H/AXFBGkkbIAZyQf8BcUYNAAtBBiEFCyABKAIYIQIgCkEkaiIBIAsgBRCVBCAKQRRqIAEQ5gsgCEENaiAKQRlqKQAANwAAIAhBFGogCkEgaigAADYAACAKIAI2AhAgCCAKKQARNwAFIAggAjoABCAIQQI2AgAMBAsgCkEMaiABQRBqEJEFIAotABAhCSAKKAIMIgJBB0YNACAIIAopABE3AAUgCEEUaiAKQSBqKAAANgAAIAhBDWogCkEZaikAADcAACAIIAk6AAQgCCACNgIADAMLIAFBIGoiASAMRw0ACwsgCCAHOgAFIAggCToABCAIQQc2AgALIApBMGokACADLQBNIQQgAy0ATCEGAn8gAygCSCIBQQdHBEAgAyADKAFONgEeIAMgAykBUjcDCCADIANB2ABqKQEANwEOIAYMAQsgAyAEOgAeIAYhBEEPCyECIAMgBDoAHSADIAI6ABwMAgsgA0HIAGohECANIQEjAEEwayIJJAACQAJAIA9FBEBBAiERQQMhDkEDIRNBAiESQQIhCgwBCyABIA9BBXRqIQtBAyETQQIhCkECIRJBAiERQQMhDgNAIAEoAgAhCAJAAkAgASgCBCIHQQdGBEBBACECA0AgAkEHRg0CIAIgCGohBCACQdCl3wBqIQUgAkEBaiECQSBBACAELQAAIgRBwQBrQf8BcUEaSRsgBHJB/wFxQSBBACAFLQAAIgRBwQBrQf8BcUEaSRsgBHJB/wFxRg0ACwsCQAJAAkACQCAHQQRHIgxFBEBBACECA0AgAkEERg0CIAIgCGohBCACQeGl3wBqIQUgAkEBaiECQSBBACAELQAAIgRBwQBrQf8BcUEaSRsgBHJB/wFxQSBBACAFLQAAIgRBwQBrQf8BcUEaSRsgBHJB/wFxRg0ACwsgB0EFRgRAQQAhAgNAIAJBBUYNAyACIAhqIQQgAkHNp98AaiEFIAJBAWohAkEgQQAgBC0AACIEQcEAa0H/AXFBGkkbIARyQf8BcUEgQQAgBS0AACIEQcEAa0H/AXFBGkkbIARyQf8BcUYNAAsLIAxFBEBBACECA0AgAkEERg0EIAIgCGohBCACQdKn3wBqIQUgAkEBaiECQSBBACAELQAAIgRBwQBrQf8BcUEaSRsgBHJB/wFxQSBBACAFLQAAIgRBwQBrQf8BcUEaSRsgBHJB/wFxRg0AC0EAIQIDQCACQQRGDQUgAiAIaiEEIAJBzKXfAGohBSACQQFqIQJBIEEAIAQtAAAiBEHBAGtB/wFxQRpJGyAEckH/AXFBIEEAIAUtAAAiBEHBAGtB/wFxQRpJGyAEckH/AXFGDQALQQQhBwsgASgCCCECIAlBDGoiASAIIAcQlQQgEEEIaiABEOYLIBAgAjYCBCAQQQI2AgAMCAsgASgCECEMIAEoAhQiB0EERgRAQQAhDkEAIQIDQCACQQRGDQYgAiAMaiEEIAJBmajfAGohBSACQQFqIQJBIEEAIAQtAAAiBEHBAGtB/wFxQRpJGyAEckH/AXFBIEEAIAUtAAAiBEHBAGtB/wFxQRpJGyAEckH/AXFGDQALCyAHQQdGBEBBACECA0AgAkEHRgRAQQEhDgwHCyACIAxqIQQgAkGdqN8AaiEFIAJBAWohAkEgQQAgBC0AACIEQcEAa0H/AXFBGkkbIARyQf8BcUEgQQAgBS0AACIEQcEAa0H/AXFBGkkbIARyQf8BcUYNAAsLIAdBCEYEQEEAIQIDQCACQQhGBEBBAiEODAcLIAIgDGohBCACQaSo3wBqIQUgAkEBaiECQSBBACAELQAAIgRBwQBrQf8BcUEaSRsgBHJB/wFxQSBBACAFLQAAIgRBwQBrQf8BcUEaSRsgBHJB/wFxRg0AC0EIIQcLIAEoAhghAiAJQSRqIgEgDCAHEJUEIAlBFGogARDmCyAQQQ1qIAlBGWopAAA3AAAgEEEUaiAJQSBqKAAANgAAIAkgAjYCECAQIAkpABE3AAUgECACOgAEIBBBAjYCAAwHCyABKAIQIQcgASgCFCICQQhGBEBBACEKQQAhAgNAIAJBCEYNBSACIAdqIQQgAkG7qN8AaiEFIAJBAWohAkEgQQAgBC0AACIEQcEAa0H/AXFBGkkbIARyQf8BcUEgQQAgBS0AACIEQcEAa0H/AXFBGkkbIARyQf8BcUYNAAtBACECA0AgAkEIRgRAQQEhCgwGCyACIAdqIQQgAkHDqN8AaiEFIAJBAWohAkEgQQAgBC0AACIEQcEAa0H/AXFBGkkbIARyQf8BcUEgQQAgBS0AACIEQcEAa0H/AXFBGkkbIARyQf8BcUYNAAtBCCECCyABKAIYIQQgCUEkaiIBIAcgAhCVBCAJQRRqIAEQ5gsgEEENaiAJQRlqKQAANwAAIBBBFGogCUEgaigAADYAACAJIAQ2AhAgECAJKQARNwAFIBAgBDoABCAQQQI2AgAMBgsgASgCECEHIAEoAhQiAkEIRgRAQQAhEkEAIQIDQCACQQhGDQQgAiAHaiEEIAJBiajfAGohBSACQQFqIQJBIEEAIAQtAAAiBEHBAGtB/wFxQRpJGyAEckH/AXFBIEEAIAUtAAAiBEHBAGtB/wFxQRpJGyAEckH/AXFGDQALQQAhAgNAIAJBCEYEQEEBIRIMBQsgAiAHaiEEIAJBkajfAGohBSACQQFqIQJBIEEAIAQtAAAiBEHBAGtB/wFxQRpJGyAEckH/AXFBIEEAIAUtAAAiBEHBAGtB/wFxQRpJGyAEckH/AXFGDQALQQghAgsgASgCGCEEIAlBJGoiASAHIAIQlQQgCUEUaiABEOYLIBBBDWogCUEZaikAADcAACAQQRRqIAlBIGooAAA2AAAgCSAENgIQIBAgCSkAETcABSAQIAQ6AAQgEEECNgIADAULIAlBDGogAUEQahDRBiAJLQAQIREgCSgCDCICQQdGDQEgECAJKQARNwAFIBBBFGogCUEgaigAADYAACAQQQ1qIAlBGWopAAA3AAAgECAROgAEIBAgAjYCAAwECyAJQQxqIAFBEGoQkQUgCS0AECETIAkoAgwiAkEHRg0AIBAgCSkAETcABSAQQRRqIAlBIGooAAA2AAAgEEENaiAJQRlqKQAANwAAIBAgEzoABCAQIAI2AgAMAwsgAUEgaiIBIAtHDQALCyAQIA46AAggECATOgAHIBAgEToABiAQIBI6AAUgECAKOgAEIBBBBzYCAAsgCUEwaiQAIANBKGoiBCADQdAAai0AADoAACADIAMoAkw2AiQgAygCSCIBQQdHBEAgA0EgaiAELQAAOgAAIAMgAy0AUToAISADIAMpAVI3AwggAyADQdgAaikBADcBDiADIAMoAiQ2AhwMAgsgA0EhaiAELQAAOgAAIAMgAygCJDYAHSADQRA6ABwMAQsCQAJAAkAgD0UEQEECIQdBAyEFDAELIA0gD0EFdGohDEEDIQVBAiEHIA0hAgNAIAIoAgAhCwJAAkAgAigCBCIJQQRGBEBBACEBA0AgAUEERg0CIAEgC2ohBCABQcyl3wBqIQYgAUEBaiEBQSBBACAELQAAIgRBwQBrQf8BcUEaSRsgBHJB/wFxQSBBACAGLQAAIgRBwQBrQf8BcUEaSRsgBHJB/wFxRg0ACwsCQCAJQQdGBEBBACEBA0AgAUEHRg0CIAEgC2ohBCABQdCl3wBqIQYgAUEBaiEBQSBBACAELQAAIgRBwQBrQf8BcUEaSRsgBHJB/wFxQSBBACAGLQAAIgRBwQBrQf8BcUEaSRsgBHJB/wFxRg0AC0EHIQkLIAIoAgghBSADQcgAaiIBIAsgCRCVBCADQSxqIAEQ5gsgAyAFNgIoQQIhAQwFCyADQcgAaiACQRBqEJEFIAMtAEwhBSADKAJIIgFBB0YNASADQThqIANB3ABqKAAANgAAIANBMWogA0HVAGopAAA3AAAgAyADKQBNNwApDAQLIANByABqIAJBEGoQ0QYgAy0ATCEHIAMoAkgiAUEHRg0AIANBOGogA0HcAGooAAA2AAAgA0ExaiADQdUAaikAADcAACADIAMpAE03ACkgByEFDAMLIAJBIGoiAiAMRw0ACwsgAyAFOgAeQQYhBUEHIQEMAQsgAyADKAEqNgEeIAMgAykBLjcDCCADIANBNGopAQA3AQ4gAy0AKSEHCyADIAc6AB0gAyAFOgAcCyABQQdHDQgMAwsCQAJAIA9FBEBBAyEEDAELIA0gD0EFdGohByANIQIDQCACKAIAIQwCQCACKAIEIgFBB0YEQCACQSBqIQVBACEBA0AgAUEHRg0CIAEgDGohBCABQdCl3wBqIQYgAUEBaiEBQSBBACAELQAAIgRBwQBrQf8BcUEaSRsgBHJB/wFxQSBBACAGLQAAIgRBwQBrQf8BcUEaSRsgBHJB/wFxRg0AC0EHIQELIAIoAgghBCADQcgAaiICIAwgARCVBCADQSxqIAIQ5gsgAyAENgIoQQIhAQwDCyADQcgAaiACQRBqEJEFIAMtAEwhBCADKAJIIgFBB0cEQCADQThqIANB3ABqKAAANgAAIANBMWogA0HVAGopAAA3AAAgAyADKQBNNwApDAMLIAUiAiAHRw0ACwsgAyAEOgAdIANBBDoAHAwDCyADQSFqIANBLWotAAA6AAAgAyADKAApNgAdIAMgAykBLjcDCCADIANBNGopAQA3AQ4gAyAEOgAcDAcLAn8gDwRAIA0gD0EFdGohCyANIQIDQCACKAIAIQwCQCACKAIEIgFBBUYEQCACQSBqIQdBACEBA0AgAUEFRg0CIAEgDGohBiABQeSn3wBqIQQgAUEBaiEBQSBBACAGLQAAIgZBwQBrQf8BcUEaSRsgBnJB/wFxQSBBACAELQAAIgZBwQBrQf8BcUEaSRsgBnJB/wFxRg0AC0EFIQELIAIoAgghBSADQcgAaiICIAwgARCVBCADQSxqIAIQ5gsgAyAFNgIoQQIMAwsgA0HIAGogAigCECIEIAIoAhQiBhDRAwJAAkAgAygCSA0AIAMoAkwhDkEBIREgAygCUCIBIQkCQAJAAkACQAJAAkACQCABDgIGAAELQYACIQlBACEBQQEhBSAOLQAAQStrDgMFAQUBCyAOLQAAQStGBEAgAUEBayEFIA5BAWohDiABQQZJDQEMAgsgASIFQQVPDQELQQAhAUEAIQkDQCAOLQAAQTBrIgxBCUsEQEGAAiEJDAULIA5BAWohDiAJQQpsIAxqIQkgBUEBayIFDQALDAELQQAhCQNAIAVFDQEgCUH//wNxQQpsIgFBEHYgDi0AAEEwayIMQQlLcg0CIA5BAWohDiAFQQFrIQUgAUH//wNxIAxB//8DcWoiCUH//wNxIAlGDQALQYAEIQlBACEBDAILIAlBEHQhASAJQf//A3FFIRFBgAghCQwBC0GAAkGABCAMQQlLGyEJQQAhAQsgASAJciARciIBQQFxDQAgAUH//wNLDQELIAIoAhghBSADQTxqIgEgBCAGEJUEIANB0ABqIAEQ5gsgA0EyaiADQdYAaikBADcBACADQTpqIANB3gBqLwEAOwEAIAMgBTYCTCADIAMpAU43ASpBAgwDCyAHIgIgC0cNAAsgA0EDOgAcIAMgAUEQdjsBHgwDCyADQQU2AjAgA0Hkp98ANgIsIAMgBTYCKEEECyEBIAMgAygBKjYBHiADIAMpAS43AwggAyADQTRqKQEANwEOIAMgBTsBHAwGCwJAIA9FBEBBAyEFQQIhBwwBCyANIA9BBXRqIQxBAyEFQQIhByANIQIDQCACKAIAIQsCQAJAIAIoAgQiCUEHRgRAQQAhAQNAIAFBB0YNAiABIAtqIQQgAUHQpd8AaiEGIAFBAWohAUEgQQAgBC0AACIEQcEAa0H/AXFBGkkbIARyQf8BcUEgQQAgBi0AACIEQcEAa0H/AXFBGkkbIARyQf8BcUYNAAsLAkAgCUEERgRAQQAhAQNAIAFBBEYNAiABIAtqIQQgAUHhpd8AaiEGIAFBAWohAUEgQQAgBC0AACIEQcEAa0H/AXFBGkkbIARyQf8BcUEgQQAgBi0AACIEQcEAa0H/AXFBGkkbIARyQf8BcUYNAAtBBCEJCyACKAIIIQUgA0HIAGoiASALIAkQlQQgA0EsaiABEOYLIAMgBTYCKAwHCyACKAIQIQsgAigCFCIBQQJGBEBBACEHQQAhAQNAIAFBAkYNAyABIAtqIQQgAUGFqN8AaiEGIAFBAWohAUEgQQAgBC0AACIEQcEAa0H/AXFBGkkbIARyQf8BcUEgQQAgBi0AACIEQcEAa0H/AXFBGkkbIARyQf8BcUYNAAtBACEBA0AgAUECRgRAQQEhBwwECyABIAtqIQQgAUGHqN8AaiEGIAFBAWohAUEgQQAgBC0AACIEQcEAa0H/AXFBGkkbIARyQf8BcUEgQQAgBi0AACIEQcEAa0H/AXFBGkkbIARyQf8BcUYNAAtBAiEBCyACKAIYIQUgA0E8aiICIAsgARCVBCADQdAAaiACEOYLIANBMWogA0HVAGopAAA3AAAgA0E4aiADQdwAaigAADYAACADIAU2AkwgAyADKQBNNwApDAYLIANByABqIAJBEGoQkQUgAy0ATCEFIAMoAkgiAUEHRg0AIANBOGogA0HcAGooAAA2AAAgA0ExaiADQdUAaikAADcAACADIAMpAE03ACkMBgsgAkEgaiICIAxHDQALCyADIAU6AB4gAyAHOgAdIANBAjoAHAsgAygBHiEHIAMvARwhAkEBIQUgD0UNACANIA9BBXRBBBCfIAsgACAENgIUIAAgBjYCECAAIA82AgwgACAHNgIIIAAgAjsBBiAAIAU7AQQgAEEHNgIADAQLQQIhAQsgAyADKAEqNgEeIAMgAykBLjcDCCADIANBNGopAQA3AQ4gAyADLQApOgAdIAMgBToAHAwBCyADQSFqIANBLWotAAA6AAAgAyADKAApNgAdIAMgAykBLjcDCCADIANBNGopAQA3AQ4gAyAEOgAcCyAAIAMpAwg3AQogAEEQaiADKQEONwEAIAMvARwhAiAAIAMoAR42AQYgACACOwEEIAAgATYCACAPRQ0AIA0gD0EFdEEEEJ8gCyADQeAAaiQAC5EuAhd/I34jAEGgBGsiAiQAIABBEGohFiAAQSBqIRcgACkDICIhQgN8ISogIUICfCExICFCAXwhK0H0yoHZBiEHQbLaiMsHIQZB7siBmQMhCEHl8MGLBiEJQQYhGEHl8MGLBiEMQe7IgZkDIQ1BstqIywchCkH0yoHZBiEOQeXwwYsGIQ9B7siBmQMhEEGy2ojLByELQfTKgdkGIRFB5fDBiwYhEkHuyIGZAyETQbLaiMsHIRRB9MqB2QYhFSAAKQMYIiIhLyAAKQMQIhkhMiAiIh0hIyAZIiAhJyAAKQMIIhwhJCAAKQMAIhshMCAcIhohKCAbIiUhKSAAKQMoIh8hLCAfIh4hLQNAIAIgJTcDwAEgAiAaNwPIASACIAc2AtwCIAIgBjYC2AIgAiAINgLUAiACIAk2AtACIAJBkAJqIgUgAkHQAmoiAyACQcABaiIEEK0VIAIoApgCIQYgAigCnAIhCCACKAKQAiEJIAIoApQCIQcgAiAwNwPAASACICQ3A8gBIAIgDjYC3AIgAiAKNgLYAiACIA02AtQCIAIgDDYC0AIgBSADIAQQrRUgAigCmAIhDCACKAKcAiENIAIoApACIQogAigClAIhDiACIBs3A8ABIAIgHDcDyAEgAiARNgLcAiACIAs2AtgCIAIgEDYC1AIgAiAPNgLQAiAFIAMgBBCtFSACKAKYAiEPIAIoApwCIRAgAigCkAIhCyACKAKUAiERIAIgKTcDwAEgAiAoNwPIASACIBU2AtwCIAIgFDYC2AIgAiATNgLUAiACIBI2AtACIAUgAyAEEK0VIAIoApgCIRIgAigCnAIhEyACKAKQAiEUIAIoApQCIRUgAiAJrSAHrUIghoQgIYUiIUIgiKdBEHetQiCGICGnQRB3rYQiJjcDwAEgAiAGrSAIrUIghoQgH4UiH0IgiKdBEHetQiCGIB+nQRB3rYQiLjcDyAEgAiAdNwPYAiACICA3A9ACIAUgAyAEEK0VIAIpA5ACIR0gAikDmAIhICACIAqtIA6tQiCGhCArhSIfQiCIp0EQd61CIIYgH6dBEHethCIrNwPAASACIAytIA2tQiCGhCAshSIfQiCIp0EQd61CIIYgH6dBEHethCIsNwPIASACIC83A9gCIAIgMjcD0AIgBSADIAQQrRUgAikDkAIhHyACKQOYAiEhIAIgC60gEa1CIIaEIDGFIi9CIIinQRB3rUIghiAvp0EQd62EIi83A8ABIAIgD60gEK1CIIaEIB6FIh5CIIinQRB3rUIghiAep0EQd62EIjI3A8gBIAIgIjcD2AIgAiAZNwPQAiAFIAMgBBCtFSACKQOQAiEeIAIpA5gCISIgAiAUrSAVrUIghoQgKoUiGUIgiKdBEHetQiCGIBmnQRB3rYQiKjcDwAEgAiASrSATrUIghoQgLYUiGUIgiKdBEHetQiCGIBmnQRB3rYQiLTcDyAEgAiAjNwPYAiACICc3A9ACIAUgAyAEEK0VIAIpA5ACIRkgAikDmAIhIyACIBogIIUiGkIgiKdBDHetQiCGIBqnQQx3rYQiJzcDyAEgAiAdICWFIhpCIIinQQx3rUIghiAap0EMd62EIjE3A8ABIAIgCDYC3AIgAiAGNgLYAiACIAc2AtQCIAIgCTYC0AIgBSADIAQQrRUgAigCkAIhBiACKAKUAiEIIAIoApgCIQkgAigCnAIhByACICEgJIUiGkIgiKdBDHetQiCGIBqnQQx3rYQiJDcDyAEgAiAfIDCFIhpCIIinQQx3rUIghiAap0EMd62EIjA3A8ABIAIgDTYC3AIgAiAMNgLYAiACIA42AtQCIAIgCjYC0AIgBSADIAQQrRUgAigCkAIhDCACKAKUAiENIAIoApgCIQogAigCnAIhDiACIBwgIoUiGkIgiKdBDHetQiCGIBqnQQx3rYQiMzcDyAEgAiAbIB6FIhpCIIinQQx3rUIghiAap0EMd62EIhs3A8ABIAIgEDYC3AIgAiAPNgLYAiACIBE2AtQCIAIgCzYC0AIgBSADIAQQrRUgAigCkAIhDyACKAKUAiEQIAIoApgCIQsgAigCnAIhESACICMgKIUiGkIgiKdBDHetQiCGIBqnQQx3rYQiKDcDyAEgAiAZICmFIhpCIIinQQx3rUIghiAap0EMd62EIik3A8ABIAIgEzYC3AIgAiASNgLYAiACIBU2AtQCIAIgFDYC0AIgBSADIAQQrRUgAigCkAIhEiACKAKUAiETIAIoApgCIRQgAigCnAIhFSACIAmtIAetQiCGhCAuhSIaQiCIp0EId60iLkIghiAap0EId60iNIQ3A8gBIAIgBq0gCK1CIIaEICaFIhpCIIinQQh3rSImQiCGIBqnQQh3rSI1hDcDwAEgAiAgNwPYAiACIB03A9ACIAUgAyAEEK0VIAIpA5gCIR0gAikDkAIhICACIAqtIA6tQiCGhCAshSIaQiCIp0EId60iLEIghiAap0EId60iNoQ3A8gBIAIgDK0gDa1CIIaEICuFIhpCIIinQQh3rSIrQiCGIBqnQQh3rSI3hDcDwAEgAiAhNwPYAiACIB83A9ACIAUgAyAEEK0VIAIpA5gCIRogAikDkAIhJSACIAutIBGtQiCGhCAyhSIcQiCIp0EId60iH0IghiAcp0EId60iIYQ3A8gBIAIgD60gEK1CIIaEIC+FIhxCIIinQQh3rSIvQiCGIBynQQh3rSIyhDcDwAEgAiAiNwPYAiACIB43A9ACIAUgAyAEEK0VIAIpA5gCIR4gAikDkAIhIiACIBStIBWtQiCGhCAthSIcQiCIp0EId60iLUIghiAcp0EId60iOIQ3A8gBIAIgEq0gE61CIIaEICqFIhxCIIinQQh3rSIqQiCGIBynQQh3rSI5hDcDwAEgAiAjNwPYAiACIBk3A9ACIAUgAyAEEK0VIAIpA5gCIRkgAikDkAIhHCACIB0gJ4UiI0IgiKdBB3etICAgMYUiJ6dBB3etQiCGhCIxNwPIASACICdCIIinQQd3rSAjp0EHd61CIIaEIiM3A8ABIAIgBzYC3AIgAiAJNgLYAiACIAg2AtQCIAIgBjYC0AIgBSADIAQQrRUgAigCmAIhBiACKAKcAiEIIAIoApACIQkgAigClAIhByACIBogJIUiJ0IgiKdBB3etICUgMIUiJKdBB3etQiCGhCIwNwPIASACICRCIIinQQd3rSAnp0EHd61CIIaEIic3A8ABIAIgDjYC3AIgAiAKNgLYAiACIA02AtQCIAIgDDYC0AIgBSADIAQQrRUgAigCmAIhDCACKAKcAiENIAIoApACIQogAigClAIhDiACIB4gM4UiJEIgiKdBB3etIBsgIoUiG6dBB3etQiCGhCIzNwPIASACIBtCIIinQQd3rSAkp0EHd61CIIaEIiQ3A8ABIAIgETYC3AIgAiALNgLYAiACIBA2AtQCIAIgDzYC0AIgBSADIAQQrRUgAigCmAIhDyACKAKcAiEQIAIoApACIQsgAigClAIhESACIBkgKIUiG0IgiKdBB3etIBwgKYUiKKdBB3etQiCGhCIpNwPIASACIChCIIinQQd3rSAbp0EHd61CIIaEIig3A8ABIAIgFTYC3AIgAiAUNgLYAiACIBM2AtQCIAIgEjYC0AIgBSADIAQQrRUgAigCmAIhEiACKAKcAiETIAIoApACIRQgAigClAIhFSACIAmtIAetQiCGhCA1QiCGIC6EhSIbQiCIp0EQd61CIIYgG6dBEHethCIuNwPAASACIAatIAitQiCGhCA0QiCGICaEhSIbQiCIp0EQd61CIIYgG6dBEHethCImNwPIASACICA3A9gCIAIgHTcD0AIgBSADIAQQrRUgAikDmAIhHSACKQOQAiEgIAIgCq0gDq1CIIaEIDdCIIYgLISFIhtCIIinQRB3rUIghiAbp0EQd62EIiw3A8ABIAIgDK0gDa1CIIaEIDZCIIYgK4SFIhtCIIinQRB3rUIghiAbp0EQd62EIis3A8gBIAIgJTcD2AIgAiAaNwPQAiAFIAMgBBCtFSACKQOYAiEaIAIpA5ACISUgAiALrSARrUIghoQgMkIghiAfhIUiG0IgiKdBEHetQiCGIBunQRB3rYQiHzcDwAEgAiAPrSAQrUIghoQgIUIghiAvhIUiG0IgiKdBEHetQiCGIBunQRB3rYQiITcDyAEgAiAiNwPYAiACIB43A9ACIAUgAyAEEK0VIAIpA5gCIR4gAikDkAIhIiACIBStIBWtQiCGhCA5QiCGIC2EhSIbQiCIp0EQd61CIIYgG6dBEHethCItNwPAASACIBKtIBOtQiCGhCA4QiCGICqEhSIbQiCIp0EQd61CIIYgG6dBEHethCIqNwPIASACIBw3A9gCIAIgGTcD0AIgBSADIAQQrRUgAikDmAIhHCACKQOQAiEbIAIgICAjhSIZQiCIp0EMd61CIIYgGadBDHethCIjNwPAASACIB0gMYUiGUIgiKdBDHetQiCGIBmnQQx3rYQiNDcDyAEgAiAINgLcAiACIAY2AtgCIAIgBzYC1AIgAiAJNgLQAiAFIAMgBBCtFSACKAKQAiEJIAIoApQCIQggAigCmAIhBiACKAKcAiEHIAIgJSAnhSIZQiCIp0EMd61CIIYgGadBDHethCInNwPAASACIBogMIUiGUIgiKdBDHetQiCGIBmnQQx3rYQiMDcDyAEgAiANNgLcAiACIAw2AtgCIAIgDjYC1AIgAiAKNgLQAiAFIAMgBBCtFSACKAKQAiEMIAIoApQCIQ0gAigCmAIhCiACKAKcAiEOIAIgIiAkhSIZQiCIp0EMd61CIIYgGadBDHethCI1NwPAASACIB4gM4UiGUIgiKdBDHetQiCGIBmnQQx3rYQiMzcDyAEgAiAQNgLcAiACIA82AtgCIAIgETYC1AIgAiALNgLQAiAFIAMgBBCtFSACKAKQAiEPIAIoApQCIRAgAigCmAIhCyACKAKcAiERIAIgGyAohSIZQiCIp0EMd61CIIYgGadBDHethCIoNwPAASACIBwgKYUiGUIgiKdBDHetQiCGIBmnQQx3rYQiKTcDyAEgAiATNgLcAiACIBI2AtgCIAIgFTYC1AIgAiAUNgLQAiAFIAMgBBCtFSACKAKQAiESIAIoApQCIRMgAigCmAIhFCACKAKcAiEVIAIgBq0gB61CIIaEICaFIhlCIIinQQh3rSIkQiCGIBmnQQh3rSImhDcDyAEgAiAJrSAIrUIghoQgLoUiGUIgiKdBCHetIjFCIIYgGadBCHetIi6ENwPAASACIB03A9gCIAIgIDcD0AIgBSADIAQQrRUgAikDkAIhHSACKQOYAiEgIAIgCq0gDq1CIIaEICuFIhlCIIinQQh3rSIrQiCGIBmnQQh3rSI2hDcDyAEgAiAMrSANrUIghoQgLIUiGUIgiKdBCHetIjdCIIYgGadBCHetIiyENwPAASACIBo3A9gCIAIgJTcD0AIgBSADIAQQrRUgAikDkAIhLyACKQOYAiEyIAIgC60gEa1CIIaEICGFIhpCIIinQQh3rSIlQiCGIBqnQQh3rSIahDcDyAEgAiAPrSAQrUIghoQgH4UiGUIgiKdBCHetIjhCIIYgGadBCHetIjmENwPAASACIB43A9gCIAIgIjcD0AIgBSADIAQQrRUgAikDkAIhIiACKQOYAiEZIAIgFK0gFa1CIIaEICqFIh5CIIinQQh3rSIqQiCGIB6nQQh3rSI6hDcDyAEgAiASrSATrUIghoQgLYUiHkIgiKdBCHetIjtCIIYgHqdBCHetIi2ENwPAASACIBw3A9gCIAIgGzcD0AIgLkIghiAkhCEfICZCIIYgMYQhISAsQiCGICuEISwgNkIghiA3hCErIDlCIIYgJYQhHiAaQiCGIDiEITEgLUIghiAqhCEtIDpCIIYgO4QhKiAdICOFIiVCIIinQQd3rSAgIDSFIhynQQd3rUIghoQhGiAcQiCIp0EHd60gJadBB3etQiCGhCElICcgL4UiHEIgiKdBB3etIDAgMoUiG6dBB3etQiCGhCEkIBtCIIinQQd3rSAcp0EHd61CIIaEITAgIiA1hSIbQiCIp0EHd60gGSAzhSIjp0EHd61CIIaEIRwgI0IgiKdBB3etIBunQQd3rUIghoQhGyAFIAMgBBCtFSACKQOQAiIjICiFIiZCIIinQQd3rSACKQOYAiInICmFIimnQQd3rUIghoQhKCApQiCIp0EHd60gJqdBB3etQiCGhCEpIBhBAWsiGA0ACyAAKQMoIS4gACkDICEmIAIgFTYCPCACIBQ2AjggAiATNgI0IAIgEjYCMCACIBE2AiwgAiALNgIoIAIgEDYCJCACIA82AiAgAiAONgIcIAIgCjYCGCACIA02AhQgAiAMNgIQIAIgBzYCDCACIAY2AgggAiAINgIEIAIgCTYCACACICg3A3ggAiApNwNwIAIgHDcDaCACIBs3A2AgAiAkNwNYIAIgMDcDUCACIBo3A0ggAiAlNwNAIAIgIzcDuAEgAiAnNwOwASACICI3A6gBIAIgGTcDoAEgAiAvNwOYASACIDI3A5ABIAIgHTcDiAEgAiAgNwOAASACIC03A/gBIAIgKjcD8AEgAiAeNwPoASACIDE3A+ABIAIgLDcD2AEgAiArNwPQASACIB83A8gBIAIgITcDwAEgAkGIAmoiDCAWQQhqKQMANwMAIAIgFikDADcDgAIgAkGYAmogF0EIaikDADcDACAXKQMAIR0gACAmQgR8IiBCIIg+AiQgACAgPgIgIAIgLjcDyAIgAiAuNwO4AiACIC43A6gCIAIgHTcDkAIgAiAmQgN8Ih0+AsACIAIgHUIgiD4CxAIgAiAmQgJ8Ih0+ArACIAIgHUIgiD4CtAIgAiAmQgF8Ih0+AqACIAIgHUIgiD4CpAIgAkGYA2oiBiACIAJBQGsiByAHIAJBgAFqIgcQ7BMgAyAGIAcgBBCgECAGIAMgBCACQYACahCxEiADIAYgBSADELASAkAgAigClAMiCSACKAKQAyIGSwRAIAIoAvgCIAZBBHQiCCACKAKAAyIHQQR0amohDSACKALoAiAIIAcgAigC8AIiCmpBBHRqaiEOIAkgBmshCSACKAKIAyAIaiEPIAIoAuACIAYgB2ogCmpqQQR0IgYgAigC0AJqIQogAigC2AIgBmohEEEAIQhBACEGA0AgAkHYA2ogBiAKaiIHQQhqKQIANwMAIAJB6ANqIAYgEGoiC0EIaikCADcDACACQfgDaiAGIA5qIhFBCGopAgA3AwAgAkGIBGogBiANaiISQQhqKQIANwMAIAJBmARqIAYgD2oiE0EIaikCADcDACACIAcpAgA3A9ADIAIgCykCADcD4AMgAiARKQIANwPwAyACIBIpAgA3A4AEIAIgEykCADcDkAQgAkKy2ojLx66ZkOsANwLYAiACQuXwwYvmjZmQMzcC0AIgAkGYA2oiBCACQdADaiACQdACaiIDEK0VIAhBgAJGDQIgASAIaiIHIAIpApgDNwAAIAdBCGogAikCoAM3AAAgAkHYAmoiCyAAQQhqKQIANwMAIAIgACkCADcD0AIgBCACQeADaiADEK0VIAdBGGogAikCoAM3AAAgB0EQaiACKQKYAzcAACALIAwpAwA3AwAgAiACKQOAAjcD0AIgBCACQfADaiADEK0VIAdBKGogAikCoAM3AAAgB0EgaiACKQKYAzcAACADIAJBgARqIAJBkARqEK0VIAdBOGogAikC2AI3AAAgB0EwaiACKQLQAjcAACAIQUBrIQggBkEQaiEGIAlBAWsiCQ0ACwsgAkGgBGokAA8LQYDA4QAQ0iAAC+8qAh1/A34jAEGgCmsiAyQAAkACQAJAAkACQCABKQMAIiBQRQRAIAEpAwgiIlBFBEAgASkDECIhUEUEQCAgQn+FICFaBEAgICAiWgRAIAEsABohEyABLgEYIQEgAyAgPgIAIANBAUECICBCgICAgBBUIgUbNgKgASADQQAgIEIgiKcgBRs2AgQgA0EIakEAQZgB/AsAIAMgIj4CpAEgA0EBQQIgIkKAgICAEFQiBRs2AsQCIANBACAiQiCIpyAFGzYCqAEgA0GsAWpBAEGYAfwLACADICE+AsgCIANBAUECICFCgICAgBBUIgUbNgLoAyADQQAgIUIgiKcgBRs2AswCIANB0AJqQQBBmAH8CwAgA0HwA2pBAEGcAfwLACADQQE2AuwDIANBATYCjAUgAawgICAhfEIBfXl9QsKawegEfkKAoc2gtAJ8QiCIpyIFwSEQAkAgAUEATgRAIAMgARCvBBogA0GkAWogARCvBBogA0HIAmogARCvBBoMAQsgA0HsA2pBACABa8EQrwQaCwJAIBBBAEgEQCADQQAgEGtB//8DcSIBELUCIANBpAFqIAEQtQIgA0HIAmogARC1AgwBCyADQewDaiAFQf//AXEQtQILIANB/AhqIANBpAH8CgAAAkACQAJAAkAgAygC6AMiCCADKAKcCiIBIAEgCEkbIgVBKE0EQCAFRQRAQQAhBQwECyAFQQFxIQwgBUEBRw0BDAILDAkLIAVBPnEhCyADQfwIaiEBIANByAJqIQYDQCABIAYoAgAiCiABKAIAaiIJIARBAXFqIg82AgAgAUEEaiIEIAZBBGooAgAiEiAEKAIAaiIEIAkgCkkgCSAPS3JqIgk2AgAgBCASSSAEIAlLciEEIAZBCGohBiABQQhqIQEgCyAHQQJqIgdHDQALCyAMBH8gB0ECdCIBIANB/AhqaiIJIAQgA0HIAmogAWooAgAiByAJKAIAaiIBaiIJNgIAIAEgB0kgASAJS3IFIAQLQQFxRQ0AIAVBKEYNASADQfwIaiAFQQJ0akEBNgIAIAVBAWohBQsgAyAFNgKcCiAFIAMoAowFIg8gBSAPSxsiAUEpSQRAIAFBAnQhAQJAAkACfwJAA0AgAUUNASABQQRrIgEgA0HsA2pqKAIAIgUgASADQfwIamooAgAiCUYNAAsgBSAJSyAFIAlJawwBC0F/QQAgARsLIBNOBEAgAygCoAEiBEEpTw0CAkAgBEUEQEEAIQQMAQsgBEECdCIJQQRrIgFBAnZBAWoiB0EDcSEFAkAgAUEMSQRAIAMhAUIAISAMAQsgB0H8////B3EhBiADIQFCACEgA0AgASABNQIAQgp+ICB8IiA+AgAgAUEEaiIHIAc1AgBCCn4gIEIgiHwiID4CACABQQhqIgcgBzUCAEIKfiAgQiCIfCIgPgIAIAFBDGoiByAHNQIAQgp+ICBCIIh8IiE+AgAgIUIgiCEgIAFBEGohASAGQQRrIgYNAAsLIAUEQCAFQQJ0IQYDQCABIAE1AgBCCn4gIHwiIT4CACABQQRqIQEgIUIgiCEgIAZBBGsiBg0ACwsgIUKAgICAEFQNACAEQShGDQ8gAyAJaiAgPgIAIARBAWohBAsgAyAENgKgASADKALEAiIFQSlPDQpBACEJIAMCf0EAIAVFDQAaIAVBAnQiDEEEayIBQQJ2QQFqIgtBA3EhBwJAIAFBDEkEQCADQaQBaiEBQgAhIAwBCyALQfz///8HcSEGIANBpAFqIQFCACEgA0AgASABNQIAQgp+ICB8IiA+AgAgAUEEaiILIAs1AgBCCn4gIEIgiHwiID4CACABQQhqIgsgCzUCAEIKfiAgQiCIfCIgPgIAIAFBDGoiCyALNQIAQgp+ICBCIIh8IiE+AgAgIUIgiCEgIAFBEGohASAGQQRrIgYNAAsLIAcEQCAHQQJ0IQYDQCABIAE1AgBCCn4gIHwiIT4CACABQQRqIQEgIUIgiCEgIAZBBGsiBg0ACwsgBSAhQoCAgIAQVA0AGiAFQShGDQ8gA0GkAWogDGogID4CACAFQQFqCzYCxAIgCARAIAhBAnQiCUEEayIBQQJ2QQFqIgdBA3EhBQJAIAFBDEkEQCADQcgCaiEBQgAhIAwBCyAHQfz///8HcSEGIANByAJqIQFCACEgA0AgASABNQIAQgp+ICB8IiA+AgAgAUEEaiIHIAc1AgBCCn4gIEIgiHwiID4CACABQQhqIgcgBzUCAEIKfiAgQiCIfCIgPgIAIAFBDGoiByAHNQIAQgp+ICBCIIh8IiE+AgAgIUIgiCEgIAFBEGohASAGQQRrIgYNAAsLIAUEQCAFQQJ0IQYDQCABIAE1AgBCCn4gIHwiIT4CACABQQRqIQEgIUIgiCEgIAZBBGsiBg0ACwsgIUKAgICAEFQEQCADIAgiCTYC6AMMAwsgCEEoRg0PIANByAJqIAlqICA+AgAgCEEBaiEJCyADIAk2AugDDAELIBBBAWohECADKAKgASEEIAghCQsgA0GQBWoiASADQewDaiIFQaQB/AoAACABQQEQrwQhFCADQbQGaiIBIAVBpAH8CgAAIAFBAhCvBCEVIANB2AdqIgEgBUGkAfwKAAACQAJAAkACQAJAAkACQCABQQMQrwQiGCgCoAEiEiAEIAQgEkkbIgVBKE0EQCADQYwFaiEZIANBsAZqIRogA0HUB2ohGyAUKAKgASEWIBUoAqABIRdBACEMA0AgDCELIAVBAnQhAQJ/AkACQAJAA0AgAUUNASABIBtqIQggAUEEayIBIANqKAIAIgcgCCgCACIIRg0ACyAHIAhJDQEMAgsgAUUNAQsgBCEFQQAMAQsgBQRAQQEhBEEAIQcgBUEBRwRAIAVBPnEhDCADIgFB2AdqIQYDQCABIAEoAgAiCiAGKAIAQX9zaiIIIARBAXFqIg42AgAgAUEEaiIEIAQoAgAiDSAGQQRqKAIAQX9zaiIEIAggCkkgCCAOS3JqIgg2AgAgBCANSSAEIAhLciEEIAZBCGohBiABQQhqIQEgDCAHQQJqIgdHDQALCyAFQQFxBH8gAyAHQQJ0IgFqIgggCCgCACIIIAEgGGooAgBBf3NqIgEgBGoiBDYCACABIAhJIAEgBEtyBSAEC0EBcUUNFAsgAyAFNgKgAUEICyEKIBcgBSAFIBdJGyIIQSlPDRMgCEECdCEBAkACQAJAA0AgAUUNASABIBpqIQQgAUEEayIBIANqKAIAIgcgBCgCACIERg0ACyAEIAdNDQEgBSEIDAILIAFFDQAgBSEIDAELIAgEQEEBIQRBACEHIAhBAUcEQCAIQT5xIQwgAyIBQbQGaiEGA0AgASABKAIAIg4gBigCAEF/c2oiBSAEQQFxaiINNgIAIAFBBGoiBCAEKAIAIhEgBkEEaigCAEF/c2oiBCAFIA5JIAUgDUtyaiIFNgIAIAQgEUkgBCAFS3IhBCAGQQhqIQYgAUEIaiEBIAwgB0ECaiIHRw0ACwsgCEEBcQR/IAMgB0ECdCIBaiIFIAUoAgAiBSABIBVqKAIAQX9zaiIBIARqIgQ2AgAgASAFSSABIARLcgUgBAtBAXFFDRQLIAMgCDYCoAEgCkEEciEKCyAWIAggCCAWSRsiBUEpTw0RIAVBAnQhAQJAAkACQANAIAFFDQEgASAZaiEEIAFBBGsiASADaigCACIHIAQoAgAiBEYNAAsgBCAHTQ0BIAghBQwCCyABRQ0AIAghBQwBCyAFBEBBASEEQQAhByAFQQFHBEAgBUE+cSEMIAMiAUGQBWohBgNAIAEgASgCACIOIAYoAgBBf3NqIgggBEEBcWoiDTYCACABQQRqIgQgBCgCACIRIAZBBGooAgBBf3NqIgQgCCAOSSAIIA1LcmoiCDYCACAEIBFJIAQgCEtyIQQgBkEIaiEGIAFBCGohASAMIAdBAmoiB0cNAAsLIAVBAXEEfyADIAdBAnQiAWoiCCAIKAIAIgggASAUaigCAEF/c2oiASAEaiIENgIAIAEgCEkgASAES3IFIAQLQQFxRQ0UCyADIAU2AqABIApBAmohCgsgDyAFIAUgD0kbIghBKU8NEyAIQQJ0IQECQAJAAkADQCABRQ0BIAFBBGsiASADaigCACIEIAEgA0HsA2pqKAIAIgdGDQALIAQgB08NASAFIQgMAgsgAUUNACAFIQgMAQsgCARAQQEhBEEAIQcgCEEBRwRAIAhBPnEhDCADIgFB7ANqIQYDQCABIAEoAgAiDiAGKAIAQX9zaiIFIARBAXFqIg02AgAgAUEEaiIEIAQoAgAiESAGQQRqKAIAQX9zaiIEIAUgDkkgBSANS3JqIgU2AgAgBCARSSAEIAVLciEEIAZBCGohBiABQQhqIQEgDCAHQQJqIgdHDQALCyAIQQFxBH8gAyAHQQJ0IgFqIgUgBSgCACIFIANB7ANqIAFqKAIAQX9zaiIBIARqIgQ2AgAgASAFSSABIARLcgUgBAtBAXFFDRQLIAMgCDYCoAEgCkEBaiEKCyALQRFGDQYgAiALaiIOIApBMGo6AAAgAygCxAIiBSAIIAUgCEsbIgFBKU8NFCALQQFqIQwgAUECdCEBAn8CQANAIAFFDQEgAUEEayIBIANqKAIAIgQgASADQaQBamooAgAiB0YNAAsgBCAHSyAEIAdJawwBC0F/QQAgARsLIANB/AhqIANBpAH8CgAAIAkgAygCnAoiASABIAlJGyIKQShLDQUCQCAKRQRAQQAhCgwBC0EAIQRBACEHIApBAUcEQCAKQT5xIRwgA0H8CGohASADQcgCaiEGA0AgASAGKAIAIh0gASgCAGoiDSAEQQFxaiIeNgIAIAFBBGoiBCAGQQRqKAIAIh8gBCgCAGoiBCANIB1JIA0gHktyaiINNgIAIAQgH0kgBCANS3IhBCAGQQhqIQYgAUEIaiEBIBwgB0ECaiIHRw0ACwsgCkEBcQR/IAdBAnQiASADQfwIamoiByAEIANByAJqIAFqKAIAIgYgBygCAGoiAWoiBDYCACABIAZJIAEgBEtyBSAEC0EBcUUNACAKQShGDRYgA0H8CGogCkECdGpBATYCACAKQQFqIQoLIAMgCjYCnAogCiAPIAogD0sbIgFBKU8NFCABQQJ0IQEgE04iBgJ/AkADQCABRQ0BIAFBBGsiASADQewDamooAgAiBCABIANB/AhqaigCACIHRg0ACyAEIAdLIAQgB0lrDAELQX9BACABGwsgE04iAXFFBEAgAQ0FIAYNBCADQQEQrwQaIA8gAygCoAEiASABIA9JGyIBQSlPDRUgAUECdCEBIANBBGshBSADQegDaiEIA0AgAUUNBCABIAhqIQkgASAFaiABQQRrIQEoAgAiBCAJKAIAIglGDQALIAQgCU8NBAwFC0EAIQcgAwJ/QQAgCEUNABogCEECdCILQQRrIgFBAnZBAWoiBkEDcSEEAkAgAUEMSQRAIAMhAUIAISEMAQsgBkH8////B3EhBiADIQFCACEhA0AgASABNQIAQgp+ICF8IiA+AgAgAUEEaiIKIAo1AgBCCn4gIEIgiHwiID4CACABQQhqIgogCjUCAEIKfiAgQiCIfCIgPgIAIAFBDGoiCiAKNQIAQgp+ICBCIIh8IiA+AgAgIEIgiCEhIAFBEGohASAGQQRrIgYNAAsLIAQEQCAEQQJ0IQYDQCABIAE1AgBCCn4gIXwiID4CACABQQRqIQEgIEIgiCEhIAZBBGsiBg0ACwsgCCAgQoCAgIAQVA0AGiAIQShGDRYgAyALaiAhPgIAIAhBAWoLIgQ2AqABAkAgBUUNACAFQQJ0IgdBBGsiAUECdkEBaiILQQNxIQgCQCABQQxJBEAgA0GkAWohAUIAISAMAQsgC0H8////B3EhBiADQaQBaiEBQgAhIANAIAEgATUCAEIKfiAgfCIgPgIAIAFBBGoiCyALNQIAQgp+ICBCIIh8IiA+AgAgAUEIaiILIAs1AgBCCn4gIEIgiHwiID4CACABQQxqIgsgCzUCAEIKfiAgQiCIfCIhPgIAICFCIIghICABQRBqIQEgBkEEayIGDQALCyAIBEAgCEECdCEGA0AgASABNQIAQgp+ICB8IiE+AgAgAUEEaiEBICFCIIghICAGQQRrIgYNAAsLICFCgICAgBBUBEAgBSEHDAELIAVBKEYNFiADQaQBaiAHaiAgPgIAIAVBAWohBwsgAyAHNgLEAgJAIAlFBEBBACEJDAELIAlBAnQiCEEEayIBQQJ2QQFqIgdBA3EhBQJAIAFBDEkEQCADQcgCaiEBQgAhIAwBCyAHQfz///8HcSEGIANByAJqIQFCACEgA0AgASABNQIAQgp+ICB8IiA+AgAgAUEEaiIHIAc1AgBCCn4gIEIgiHwiID4CACABQQhqIgcgBzUCAEIKfiAgQiCIfCIgPgIAIAFBDGoiByAHNQIAQgp+ICBCIIh8IiE+AgAgIUIgiCEgIAFBEGohASAGQQRrIgYNAAsLIAUEQCAFQQJ0IQYDQCABIAE1AgBCCn4gIHwiIT4CACABQQRqIQEgIUIgiCEgIAZBBGsiBg0ACwsgIUKAgICAEFQNACAJQShGDRYgA0HIAmogCGogID4CACAJQQFqIQkLIAMgCTYC6AMgEiAEIAQgEkkbIgVBKUkNAAsLDA8LIAENAQsgAiAMaiEIQQAhBkF/IQECQAJAA0AgASALRg0BIAFBAWohASAGIA5qIAZBAWsiBSEGLQAAQTlGDQALIAUgC2oiASACakEBaiIIIAgtAABBAWo6AAAgAUECaiIBIAxNDQEgASAMIAxBpIXlABCbFQALIAJBMToAACALBEAgAkEBakEwIAv8CwALIAxBEU8NBCAIQTA6AAAgEEEBaiEQIAtBAmohDAwBCyAFQX9GDQAgBUF/cyIBRQ0AIAUgDmpBAmpBMCAB/AsACyAMQRFLDQMgACAQOwEIIAAgDDYCBCAAIAI2AgAgA0GgCmokAA8LQQAgCkEoQciC5QAQmxUAC0ERQRFBhJblABCMEAALIAxBEUGUluUAEIwQAAtBACAMQRFBpJblABCbFQALQQAgBEEoQciC5QAQmxUACwwJCwwJC0GUk+UAQTdBtJblABCcFQALQdyT5QBBNkHEluUAEJwVAAtB6JHlAEEcQeSV5QAQnBUAC0G4keUAQR1B1JXlABCcFQALQYiQ5QBBHEHEleUAEJwVAAtBACAFQShByILlABCbFQALQauC5QBBGkHIguUAEJwVAAtBACAIQShByILlABCbFQALQQAgAUEoQciC5QAQmxUAC0EoQShByILlABCMEAALwiwCG34GfyMAQbAGayIdJAAgHSABQTBqIiAQ1QEgHSAdKQMAIhdCAYYiAiACQtWqgYCAgMCAxgB8IgogAlStQgF9IgIgAiACIB0pAwgiGEIBhiAXQj+IhCIHfCICVq18IAJC///Piuv//9UefSIEIAJUrXxCAX1CP4ciAiACIB0pAxAiGUIBhiAYQj+IhCIGfCICIAZUrXwgAkKk7MO1j9S0mOcAfSIDIAJUrXxCAX1CP4ciAiACIB0pAxgiGkIBhiAZQj+IhCIFfCICIAVUrXwgAkK/pZScz/DSu+QAfSIPIAJUrXxCAX1CP4ciAiACIB0pAyAiG0IBhiAaQj+IhCILfCICIAtUrXwgAkLX2a6a5PbpjcsAfSIOIAJUrXxCAX1CP4ciAiACIB0pAygiHEIBhiAbQj+IhCIMfCICIAxUrXwgAkKazf/Lo73EgBp9IgggAlStfEIBfSINgyANQn+FIhEgCoOEIgJCAYYiCiAKQtWqgYCAgMCAxgB8IhAgClStQgF9IgogCiAEIBGDIAcgDYOEIgRCAYYgAkI/iIQiCXwiAiAKVK18IAJC///Piuv//9UefSIKIAJUrXxCAX1CP4ciAiACIAMgEYMgBiANg4QiA0IBhiAEQj+IhCIGfCICIAZUrXwgAkKk7MO1j9S0mOcAfSIHIAJUrXxCAX1CP4ciAiACIA8gEYMgBSANg4QiBEIBhiADQj+IhCIFfCICIAVUrXwgAkK/pZScz/DSu+QAfSIPIAJUrXxCAX1CP4ciAiACIA4gEYMgCyANg4QiA0IBhiAEQj+IhCISfCICIBJUrXwgAkLX2a6a5PbpjcsAfSIOIAJUrXxCAX1CP4ciAiACIAggEYMgDCANg4RCAYYgA0I/iIQiC3wiAiALVK18IAJCms3/y6O9xIAafSIIIAJUrXxCAX0iDYMgDUJ/hSIRIBCDhCICQgGGIgxC1aqBgICAwIDGAHwiECAMVK1CAX0iBCAEIAogEYMgCSANg4QiA0IBhiACQj+IhCIJfCICIARUrXwgAkL//8+K6///1R59IgogAlStfEIBfUI/hyICIAIgByARgyAGIA2DhCIEQgGGIANCP4iEIgZ8IgIgBlStfCACQqTsw7WP1LSY5wB9IgcgAlStfEIBfUI/hyICIAIgDyARgyAFIA2DhCIDQgGGIARCP4iEIgV8IgIgBVStfCACQr+llJzP8NK75AB9Ig8gAlStfEIBfUI/hyICIAIgDiARgyANIBKDhCIEQgGGIANCP4iEIg58IgIgDlStfCACQtfZrprk9umNywB9IgMgAlStfEIBfUI/hyICIAIgCCARgyALIA2DhEIBhiAEQj+IhCIEfCICIARUrXwgAiACQprN/8ujvcSAGn0iAlatfEIBfSILQn+FIgggAoMgBCALg4Q3A1ggHSADIAiDIAsgDoOENwNQIB0gCCAPgyAFIAuDhDcDSCAdIAcgCIMgBiALg4Q3A0AgHSAIIAqDIAkgC4OENwM4IB0gCyAMgyAIIBCDhDcDMCAdQeAAaiIeICAgAUHgAGoiIRDKASAdQZABaiAhENUBIB0gHSkDkAEiAkIBhiIDIANC1aqBgICAwIDGAHwiCiADVK1CAX0iAyADIB0pA5gBIgRCAYYgAkI/iIQiDnwiAiADVK18IAJC///Piuv//9UefSIHIAJUrXxCAX1CP4ciAiACIB0pA6ABIgNCAYYgBEI/iIQiBnwiAiAGVK18IAJCpOzDtY/UtJjnAH0iCCACVK18QgF9Qj+HIgIgAiAdKQOoASIEQgGGIANCP4iEIgV8IgIgBVStfCACQr+llJzP8NK75AB9Ig8gAlStfEIBfUI/hyICIAIgHSkDsAEiA0IBhiAEQj+IhCILfCICIAtUrXwgAkLX2a6a5PbpjcsAfSIQIAJUrXxCAX1CP4ciAiACIB0pA7gBQgGGIANCP4iEIgx8IgIgDFStfCACQprN/8ujvcSAGn0iCSACVK18QgF9Ig2DIA1Cf4UiESAKg4QiAkIBhiIDIANC1aqBgICAwIDGAHwiCiADVK1CAX0iAyADIAcgEYMgDSAOg4QiBEIBhiACQj+IhCIOfCICIANUrXwgAkL//8+K6///1R59IgcgAlStfEIBfUI/hyICIAIgCCARgyAGIA2DhCIDQgGGIARCP4iEIgZ8IgIgBlStfCACQqTsw7WP1LSY5wB9IgggAlStfEIBfUI/hyICIAIgDyARgyAFIA2DhCIEQgGGIANCP4iEIgV8IgIgBVStfCACQr+llJzP8NK75AB9Ig8gAlStfEIBfUI/hyICIAIgECARgyALIA2DhCIDQgGGIARCP4iEIhJ8IgIgElStfCACQtfZrprk9umNywB9IhAgAlStfEIBfUI/hyICIAIgCSARgyAMIA2DhEIBhiADQj+IhCILfCICIAtUrXwgAkKazf/Lo73EgBp9IgkgAlStfEIBfSIUgyAUQn+FIhUgCoOEIhZCAYYiAiACQtWqgYCAgMCAxgB8IgogAlStQgF9IgIgAiACIAcgFYMgDiAUg4QiDEIBhiAWQj+IhCIHfCICVq18IAJC///Piuv//9UefSIDIAJUrXxCAX1CP4ciAiACIAggFYMgBiAUg4QiE0IBhiAMQj+IhCIGfCICIAZUrXwgAkKk7MO1j9S0mOcAfSIEIAJUrXxCAX1CP4ciAiACIA8gFYMgBSAUg4QiDUIBhiATQj+IhCIFfCICIAVUrXwgAkK/pZScz/DSu+QAfSIPIAJUrXxCAX1CP4ciAiACIBAgFYMgEiAUg4QiEUIBhiANQj+IhCISfCICIBJUrXwgAkLX2a6a5PbpjcsAfSIOIAJUrXxCAX1CP4ciAiACIAkgFYMgCyAUg4QiCEIBhiARQj+IhCILfCICIAtUrXwgAkKazf/Lo73EgBp9IhAgAlStfEIBfSIUgyAUQn+FIhUgCoOEIgIgFnwiFiAWQtWqgYCAgMCAxgB8IgkgFlStQgF9IgogCiADIBWDIAcgFIOEIgMgDHwiByACIBZWrXwiDHwiAiAKVK18IAJC///Piuv//9UefSIKIAJUrXxCAX1CP4ciAiACIAQgFYMgBiAUg4QiBCATfCIGIAMgB1atIAcgDFatfHwiE3wiAiATVK18IAJCpOzDtY/UtJjnAH0iByACVK18QgF9Qj+HIgIgAiAPIBWDIAUgFIOEIgMgDXwiBSAEIAZWrSAGIBNWrXx8IgZ8IgIgBlStfCACQr+llJzP8NK75AB9Ig8gAlStfEIBfUI/hyICIAIgDiAVgyASIBSDhCIEIBF8Ig4gAyAFVq0gBSAGVq18fCIFfCICIAVUrXwgAkLX2a6a5PbpjcsAfSIDIAJUrXxCAX1CP4ciAiACIBAgFYMgCyAUg4QgCHwgBCAOVq0gBSAOVK18fCIEfCICIARUrXwgAiACQprN/8ujvcSAGn0iAlatfEIBfSIQgyAJIBBCf4UiCYOEIgs3A/AEIB0gCSAKgyAMIBCDhCIVNwP4BCAdIAcgCYMgECATg4QiDTcDgAUgHSAJIA+DIAYgEIOEIhI3A4gFIB0gAyAJgyAFIBCDhCIWNwOQBSAdIAIgCYMgBCAQg4QiETcDmAUgHUHAAWogHUHwBGoiIiAdQTBqIh8QygEgHSALIBd8IgZC1aqBgICAwIDGAHwiCiAGVK1CAX0iAiACIAIgFSAYfCIDIAYgC1StfCIQfCICVq18IAJC///Piuv//9UefSIHIAJUrXxCAX1CP4ciAiACIA0gGXwiBCADIBVUrSADIBBWrXx8IgV8IgIgBVStfCACQqTsw7WP1LSY5wB9Ig8gAlStfEIBfUI/hyICIAIgEiAafCIDIAQgDVStIAQgBVatfHwiDnwiAiAOVK18IAJCv6WUnM/w0rvkAH0iBCACVK18QgF9Qj+HIgIgAiAWIBt8IgkgAyASVK0gAyAOVq18fCIIfCICIAhUrXwgAkLX2a6a5PbpjcsAfSIDIAJUrXxCAX1CP4ciAiACIBEgHHwgCSAWVK0gCCAJVK18fCIJfCICIAlUrXwgAiACQprN/8ujvcSAGn0iAlatfEIBfSITQn+FIgwgAoMgCSATg4Q3A5gCIB0gAyAMgyAIIBODhDcDkAIgHSAEIAyDIA4gE4OENwOIAiAdIAwgD4MgBSATg4Q3A4ACIB0gByAMgyAQIBODhDcD+AEgHSAGIBODIAogDIOENwPwASAdQcAEaiAeIB8QygEgHSAXQgBCq9X+////v/+5fyALIAtCAYYiAiACQtWqgYCAgMCAxgB8IgogAlStQgF9IgIgAiACIBVCAYYgC0I/iIQiB3wiAlatfCACQv//z4rr///VHn0iAyACVK18QgF9Qj+HIgIgAiANQgGGIBVCP4iEIgV8IgIgBVStfCACQqTsw7WP1LSY5wB9IgQgAlStfEIBfUI/hyICIAIgEkIBhiANQj+IhCIOfCICIA5UrXwgAkK/pZScz/DSu+QAfSIPIAJUrXxCAX1CP4ciAiACIBZCAYYgEkI/iIQiC3wiAiALVK18IAJC19mumuT26Y3LAH0iCCACVK18QgF9Qj+HIgIgAiARQgGGIBZCP4iEIgZ8IgIgBlStfCACQprN/8ujvcSAGn0iECACVK18QgF9IhSDIBRCf4UiEyAKg4QiAnwiDCAMQtWqgYCAgMCAxgB8IgkgDFStQgF9IgogCiADIBODIAcgFIOEIgMgFXwiByACIAxWrXwiDHwiAiAKVK18IAJC///Piuv//9UefSIKIAJUrXxCAX1CP4ciAiACIAQgE4MgBSAUg4QiBCANfCIFIAMgB1atIAcgDFatfHwiDXwiAiANVK18IAJCpOzDtY/UtJjnAH0iByACVK18QgF9Qj+HIgIgAiAPIBODIA4gFIOEIgMgEnwiDiAEIAVWrSAFIA1WrXx8IhJ8IgIgElStfCACQr+llJzP8NK75AB9Ig8gAlStfEIBfUI/hyICIAIgCCATgyALIBSDhCIEIBZ8IgggAyAOVq0gDiASVq18fCIFfCICIAVUrXwgAkLX2a6a5PbpjcsAfSIDIAJUrXxCAX1CP4ciAiACIBAgE4MgBiAUg4QgEXwgBCAIVq0gBSAIVK18fCIQfCICIBBUrXwgAiACQprN/8ujvcSAGn0iAlatfEIBfSIIgyAJIAhCf4UiCYOEIgR9IAIgCYMgCCAQg4QiDiADIAmDIAUgCIOEIhEgCSAPgyAIIBKDhCISIAcgCYMgCCANg4QiBiAJIAqDIAggDIOEIgUgBISEhISEUCIeGyICfCIWQtWqgYCAgMCAxgB8IgggFlStQgF9IgogCiAYQgBCACAEQqvV/v///7//uX9WrX0iByAFfSIEQv//z4rr///VHnwiAyAeGyIPfCIJIAIgFlatfCILfCICIApUrXwgAkL//8+K6///1R59IhAgAlStfEIBfUI/hyICIAIgGUIAIAMgBFStIAcgBSAHVq19fEI/hyIFIAZ9IgRCpOzDtY/UtJjnAHwiAyAeGyIHfCIKIAkgD1StIAkgC1atfHwiE3wiAiATVK18IAJCpOzDtY/UtJjnAH0iCSACVK18QgF9Qj+HIgIgAiAaQgAgAyAEVK0gBSAFIAZUrX18Qj+HIgUgEn0iD0K/pZScz/DSu+QAfCIEIB4bIgN8IgwgByAKVq0gCiATVq18fCINfCICIA1UrXwgAkK/pZScz/DSu+QAfSIKIAJUrXxCAX1CP4ciAiACIBtCACAEIA9UrSAFIAUgElStfXxCP4ciBiARfSIHQtfZrprk9umNywB8Ig8gHhsiBHwiBSADIAxWrSAMIA1WrXx8Igx8IgIgDFStfCACQtfZrprk9umNywB9IgMgAlStfEIBfUI/hyICIAIgHEIAIAcgD1atIAYgBiARVK19fEI/hyAOfUKazf/Lo73EgBp8IB4bfCAEIAVWrSAFIAxWrXx8IgR8IgIgBFStfCACIAJCms3/y6O9xIAafSICVq18QgF9IgdCf4UiDyACgyAEIAeDhDcDyAIgHSADIA+DIAcgDIOENwPAAiAdIAogD4MgByANg4Q3A7gCIB0gCSAPgyAHIBODhDcDsAIgHSAPIBCDIAcgC4OENwOoAiAdIAcgFoMgCCAPg4Q3A6ACIB1B0AJqIB1BoAJqIh4gHUHwAWoQygEgHSkD+AIhDiAdKQPoASEIIB0pA/ACIRIgHSkD4AEhECAdKQPoAiELIB0pA9gBIQkgHSkD4AIhDCAdKQPQASEEIB0pA9ACIQcgHSkDwAEhAyAdKQPYAiEGIB0pA8gBIQIgHUGAA2oiHyABICAQygEgHUGwA2ogHiAfEMoBIB0gAyAHfCINQtWqgYCAgMCAxgB8IgogDVStQgF9Ig8gDyACIAZ8IgMgByANVq18IgV8IgIgD1StfCACQv//z4rr///VHn0iByACVK18QgF9Qj+HIgIgAiAEIAx8IgQgAyAGVK0gAyAFVq18fCIRfCICIBFUrXwgAkKk7MO1j9S0mOcAfSIPIAJUrXxCAX1CP4ciAiACIAkgC3wiAyAEIAxUrSAEIBFWrXx8IgZ8IgIgBlStfCACQr+llJzP8NK75AB9IgQgAlStfEIBfUI/hyICIAIgECASfCIJIAMgC1StIAMgBlatfHwiEHwiAiAQVK18IAJC19mumuT26Y3LAH0iAyACVK18QgF9Qj+HIgIgAiAIIA58IAkgElStIAkgEFatfHwiCXwiAiAJVK18IAIgAkKazf/Lo73EgBp9IgJWrXxCAX0iDkJ/hSIIIAKDIAkgDoOENwO4BCAdIAMgCIMgDiAQg4Q3A7AEIB0gBCAIgyAGIA6DhDcDqAQgHSAIIA+DIA4gEYOENwOgBCAdIAcgCIMgBSAOg4Q3A5gEIB0gDSAOgyAIIAqDhDcDkAQgHSAdKQOwAyICQgGGIgZC1aqBgICAwIDGAHwiECAGVK1CAX0iBCAEIB0pA7gDIgNCAYYgAkI/iIQiCXwiAiAEVK18IAJC///Piuv//9UefSIKIAJUrXxCAX1CP4ciAiACIB0pA8ADIgRCAYYgA0I/iIQiBXwiAiAFVK18IAJCpOzDtY/UtJjnAH0iByACVK18QgF9Qj+HIgIgAiAdKQPIAyIDQgGGIARCP4iEIg58IgIgDlStfCACQr+llJzP8NK75AB9Ig8gAlStfEIBfUI/hyICIAIgHSkD0AMiBEIBhiADQj+IhCIIfCICIAhUrXwgAkLX2a6a5PbpjcsAfSIDIAJUrXxCAX1CP4ciAiACIB0pA9gDQgGGIARCP4iEIgR8IgIgBFStfCACIAJCms3/y6O9xIAafSICVq18QgF9IgtCf4UiDCACgyAEIAuDhDcDiAQgHSADIAyDIAggC4OENwOABCAdIAwgD4MgCyAOg4Q3A/gDIB0gByAMgyAFIAuDhDcD8AMgHSAKIAyDIAkgC4OENwPoAyAdIAYgC4MgDCAQg4Q3A+ADICJBAEEw/AsAIB1B0AVqQQBBMPwLACAdQaAFakHwjN4AQTD8CgAAIB1BgAZqIgFBAEEw/AsAIAAgHUHgA2ogHUHwBGogISABEP0KEM8VIB1BsAZqJAALwisCI34PfyMAQdAAayImJAACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCABKAIEIi2tIgMgAigCACIurSILfiIGIAIoAgQiL60iCCABKAIAIjCtIgx+fCIXIAZaBEAgAigCCCIxrSIFIAx+IgYgAyAIfnwiCSAGVA0BIAEoAggiMq0iByALfiIGIAl8Ig8gBlQNAiACKAIMIjOtIgQgDH4iCSADIAV+fCIGIAlUDQMgBiAGIAcgCH58IgZWDQQgBiABKAIMIjStIgogC34iBnwiEyAGVA0FIAI1AhAiBiAMfiIOIAMgBH58IgkgDlQNPiAJIAkgBSAHfnwiCVYNPiAJIAkgCCAKfnwiCVYNPiAJIAE1AhAiCSALfiIOfCIUIA5UDT4gAyAGfiIOIAQgB358IgMgDlQNBiADIAMgBSAKfnwiA1YNByADIAggCX4iA3wiHCADVA0IIAYgB34iAyAEIAp+fCIIIANUDQkgBSAJfiIDIAh8Ih0gA1QNCiAEIAl+IgMgBiAKfnwiHiADVA0LIAEoAhgiJ60iAyACKAIUIiitIhF+IgUgAigCGCIprSIIIAEoAhQiKq0iEH58Ih8gBVQNDCACKAIcIiutIgUgEH4iByADIAh+fCIEIAdUDQ0gBCABKAIcIiytIgcgEX4iBHwiICAEVA0OIAIoAiAiAq0iGCAQfiIKIAMgBX58IgQgClQNDyAEIAQgByAIfnwiBFYNECAEIAEoAiAiAa0iGSARfiIEfCIWIARUDREgAyAYfiIDIAUgB358IgQgA1QNEiAIIBl+IgMgBHwiGiADVA0TIAUgGX4iAyAHIBh+fCIbIANUDRQgKiAqIDBqIipLDRUgJyAnIC1qIidLDRYgLCAsIDJqIixLDRcgASABIDRqIgFLDRggKCAoIC5qIihLDRkgKSApIC9qIilLDRogKyArIDFqIitLDRsgAiACIDNqIgJLDRwgJ60iAyAorSIHfiIFICmtIgggKq0iBH58IiEgBVQNHSArrSIFIAR+IgogAyAIfnwiDiAKVA0eIA4gLK0iCiAHfiIOfCIiIA5UDR8gAq0iDiAEfiISIAMgBX58Ig0gElQNICANIA0gCCAKfnwiDVYNISANIAGtIg0gB34iEnwiIyASVA0iIAMgDn4iFSAEIAZ+fCISIBVUDSMgEiASIAUgCn58IhJWDSQgCCANfiIVIBJ8IhIgFVQNJSASIBIgByAJfnwiElYNJiAKIA5+IhUgAyAGfnwiAyAVVA0nIAUgDX4iFSADfCIDIBVUDSggAyAIIAl+fCIVIANUDSkgDSAOfiIIIAYgCn58IgMgCFQNKiADIAUgCX58IiQgA1QNKyAGIA1+IgMgCSAOfnwiDiADVA0sIAsgDH4iCkKb/NGSAX5C/////wGDIgNC7afX5wF+IgsgCnwiCCALVA0/IAhCHYgiCCAXfCILIAhUDS0gCyALIANC0rHMBH58IgtWDS4gCyALQpv80ZIBfkL/////AYMiC0Ltp9fnAX4iCHwiDCAIVA0/IA8gDEIdiHwiCCAPVA0vIAggCCADQpbrnO8BfnwiCFYNMCAIIAggC0LSscwEfnwiCFYNMSAIIAhCm/zRkgF+Qv////8BgyIIQu2n1+cBfiIMfCIFIAxUDT8gEyAFQh2IfCIMIBNUDUAgDCAMIANCxfrO7wF+fCIMVg1AIAwgDCALQpbrnO8BfnwiDFYNQCAMIAwgCELSscwEfnwiDFYNQCAMIAxCm/zRkgF+Qv////8BgyIMQu2n1+cBfiIFfCINIAVUDT8gFCANQh2IfCIFIBRUDUEgBSAFIANCzQJ+fCIFVg1BIAUgBSALQsX6zu8BfnwiBVYNQSAFIAUgCEKW65zvAX58IgVWDUEgBSAFIAxC0rHMBH58IgVWDUEgBSAFQpv80ZIBfkL/////AYMiBULtp9fnAX4iDXwiJSANVA0/IBwgECARfn0iDSAlQh2IIhEgCn18IAQgB358IgcgEVQNQiAHIAcgC0LNAn58IgdWDUIgByAHIAhCxfrO7wF+fCIHVg1CIAcgByAMQpbrnO8BfnwiB1YNQiAHIAcgBULSscwEfnwiB1YNQiAHIAdCm/zRkgF+Qv////8BgyIHQu2n1+cBfiIEfCIKIARUDT8gHSAffSIRIBd9ICF8IhAgCkIdiHwiBCAQVA1DIAQgBCAIQs0CfnwiBFYNQyAEIAQgDELF+s7vAX58IgRWDUMgBCAEIAVCluuc7wF+fCIEVg1DIAQgBCAHQtKxzAR+fCIEVg1DIAQgBEKb/NGSAX5C/////wGDIgRC7afX5wF+Igp8IhAgClQNPyAeICB9IhcgEEIdiCIQIA99fCAifCIKIBBUDUQgCiAKIAxCzQJ+fCIKVg1EIAogCiAFQsX6zu8BfnwiClYNRCAKIAogB0KW65zvAX58IgpWDUQgCiAKIARC0rHMBH58IgpWDUQgCiAKQpv80ZIBfkL/////AYMiCkLtp9fnAX4iD3wiECAPVA0/IBBCHYgiDyAGIAl+fCATIBZ8fSAjfCIGIA9UDUUgBiAGIANCFIZ8IgZWDUUgBiAGIAVCzQJ+fCIGVg1FIAYgBiAHQsX6zu8BfnwiBlYNRSAGIAYgBEKW65zvAX58IgZWDUUgBiAGIApC0rHMBH58IgZWDUUgBiAGQpv80ZIBfkL/////AYMiBkLtp9fnAX4iCXwiAyAJVA0/IBIgFCAafH0iDyADQh2IfCIJIA9UDUYgCSAJIAtCFIZ8IglWDUYgCSAJIAdCzQJ+fCIJVg1GIAkgCSAEQsX6zu8BfnwiCVYNRiAJIAkgCkKW65zvAX58IglWDUYgCSAJIAZC0rHMBH58IglWDUYgFSANIBt8fSILIAlCHYh8IgMgC1QNRyADIAMgCEIUhnwiA1YNRyADIAMgBELNAn58IgNWDUcgAyADIApCxfrO7wF+fCIDVg1HIAMgAyAGQpbrnO8BfnwiA1YNRyAkIBggGX4iDSARfH0iCCADQh2IfCILIAhUDUggCyALIAxCFIZ8IgtWDUggCyALIApCzQJ+fCILVg1IIAsgCyAGQsX6zu8BfnwiC1YNSCALQh2IIgwgDiAXfXwiCCAMVA1JIAggCCAFQhSGfCIIVg1JIAggCCAGQs0CfnwiCFYNSSAIQh2IIgUgFnwiDCAFVA0yIAwgDCAHQhSGfCIMVg0zIAxCHYgiByAafCIFIAdUDTQgBSAFIARCFIZ8IgVWDTUgBUIdiCIEIBt8IgcgBFQNNiAHIAcgCkIUhnwiB1YNNyAHQh2IIgogDXwiBCAKVA04IAQgBkIUhnwiBiAEVA05ICYgB6dB/////wFxNgJEICYgBadB/////wFxNgJAICYgDKdB/////wFxNgI8ICYgCKdB/////wFxNgI4ICYgC6dB/////wFxNgI0ICYgA6dB/////wFxNgIwICYgCadB/////wFxNgIsICYgBkIdiD4CTCAmIAanQf////8BcTYCSCAmQQhqICZBLGoiMUH84OEAEN0HICYoAhwiASAmKAIIIilqIiogAUkNOiAmKAIgIgIgJigCDCIraiIsIAJJDTsgJigCJCInICYoAhAiLWoiLiAnSQ08ICYoAigiKCAmKAIUIi9qIjAgKEkNPSAtrSIHQtfu/KEBfiArrSIMQoGvy8sBfnwgL60iBEK9/rWsAX58ICY1AhgiBkKXttDwAX58IAGtIhNChKnAXn58IhggKa0iCUKSuv7aAH4iC30gKq0iCkKOkb78AH58Ig4gDELX7vyhAX4gCUKBr8vLAX58IAdCvf61rAF+fCAEQpe20PABfnwgBkKSuv7aAH58IhkgCULm2bGCAX5C/v///wGDIgNCzQJ+fCAMQpK6/toAfiAJQpe20PABfnwiDSADQtKxzAR+fCADQu2n1+cBfiALfEIdiHwiCEKb/NGSAX5C/////wGDIgtCxfrO7wF+fCAMQpe20PABfiAJQr3+tawBfnwgB0KSuv7aAH58Ig8gA0KW65zvAX58IAtC0rHMBH58IAtC7afX5wF+IAh8Qh2IfCIFQpv80ZIBfkL/////AYMiCEKW65zvAX58IAxCvf61rAF+IAlC1+78oQF+fCAHQpe20PABfnwgBEKSuv7aAH58IhAgA0LF+s7vAX58IAtCluuc7wF+fCAIQtKxzAR+fCAIQu2n1+cBfiAFfEIdiHwiDEKb/NGSAX5C/////wGDIglC0rHMBH58IAlC7afX5wF+IAx8Qh2IfCIFQpv80ZIBfkL/////AYMiDELtp9fnAX4gBXxCHYh8IgUgDlQNQiAFIAUgC0LNAn58IgVWDUIgBSAFIAhCxfrO7wF+fCIFVg1CIAUgBSAJQpbrnO8BfnwiBVYNQiAFIAUgDELSscwEfnwiBVYNQiAFIAVCm/zRkgF+Qv////8BgyIFQu2n1+cBfiIOfCIRIA5UDT8gBELX7vyhAX4gB0KBr8vLAX58IAZCvf61rAF+fCATQsPxxJh+fnwgAq0iFEKEqcBefnwiFyAKQtTEi9gDfiANfSAsrSIOQo6RvvwAfnx8Ig0gEUIdiHwiByANVA1DIAcgByAIQs0CfnwiB1YNQyAHIAcgCULF+s7vAX58IgdWDUMgByAHIAxCluuc7wF+fCIHVg1DIAcgByAFQtKxzAR+fCIHVg1DIAcgB0Kb/NGSAX5C/////wGDIgdC7afX5wF+Ig18IhYgDVQNPyAGQtfu/KEBfiAEQoGvy8sBfnwgE0Li5Z6Pfn58IBRCw/HEmH5+fCAnrSIRQoSpwF5+fCIaIApC25iXnQN+IA99IA5C1MSL2AN+fCAurSINQo6RvvwAfnx8Ig8gFkIdiHwiBCAPVA1EIAQgBCAJQs0CfnwiBFYNRCAEIAQgDELF+s7vAX58IgRWDUQgBCAEIAVCluuc7wF+fCIEVg1EIAQgBCAHQtKxzAR+fCIEVg1EIAQgBEKb/NGSAX5C/////wGDIgRC7afX5wF+Ig98IhYgD1QNPyAGQoGvy8sBfiAQfSAKQsT3kKIBfnwgDkLbmJedA358IA1C1MSL2AN+fCAwrSIPQo6RvvwAfnwgFEKemuHwAX4gE0LtiBR+fCARQr2Ou+cBfnwgKK0iE0L81r8hfnwiG30iEiAWQh2IfCIQIBJUDUUgECADQhSGfCIDIBBUDUUgAyADIAxCzQJ+fCIDVg1FIAMgAyAFQsX6zu8BfnwiA1YNRSADIAMgB0KW65zvAX58IgNWDUUgAyADIARC0rHMBH58IgNWDUUgAyADQpv80ZIBfkL/////AYMiA0Ltp9fnAX4iEHwiFiAQVA0/IAZCjpG+/AB+IBl9IApCga/LywF+fCAOQsT3kKIBfnwgDULbmJedA358IBFCnprh8AF+IBRC7YgUfnwgE0K9jrvnAX58IhR9IA9C1MSL2AN+fCIQIBZCHYh8IgogEFQNRiAKIAtCFIZ8IgsgClQNRiALIAsgBULNAn58IgtWDUYgCyALIAdCxfrO7wF+fCILVg1GIAsgCyAEQpbrnO8BfnwiC1YNRiALIAsgA0LSscwEfnwiC1YNRiAGQtTEi9gDfiAYfSAOQoGvy8sBfnwgDULE95CiAX58IBNCnprh8AF+IBFC7YgUfnwiDn0gD0LbmJedA358IhEgC0IdiHwiCiARVA1HIAogCEIUhnwiCCAKVA1HIAggCCAHQs0CfnwiCFYNRyAIIAggBELF+s7vAX58IghWDUcgCCAIIANCluuc7wF+fCIIVg1HIAZC25iXnQN+IBcgE0LtiBR+IhN8fSANQoGvy8sBfnwgD0LE95CiAX58Ig0gCEIdiHwiCiANVA1IIAogCUIUhnwiCSAKVA1IIAkgCSAEQs0CfnwiCVYNSCAJIAkgA0LF+s7vAX58IglWDUggBkLE95CiAX4gGn0gD0KBr8vLAX58IgogCUIdiHwiBiAKVA1JIAYgBiAMQhSGfCIGVg1JIAYgBiADQs0CfnwiBlYNSSAmIAanQf////8BcTYCOCAmIAmnQf////8BcTYCNCAmIAinQf////8BcTYCMCAmIAunQf////8BcTYCLCAmIAVCFIYgG3wgBkIdiHwiBqdB/////wFxNgI8ICYgB0IUhiAUfCAGQh2IfCIGp0H/////AXE2AkAgJiAEQhSGIA58IAZCHYh8IganQf////8BcTYCRCAmIANCFIYgE3wgBkIdiHwiBkIdiD4CTCAmIAanQf////8BcTYCSCAAIDFB/ODhABDdByAmQdAAaiQADwtBtNzhABCuFwALQcTc4QAQrhcAC0HE3OEAEK4XAAtB1NzhABCuFwALQdTc4QAQrhcAC0HU3OEAEK4XAAtB9NzhABCuFwALQfTc4QAQrhcAC0H03OEAEK4XAAtBhN3hABCuFwALQYTd4QAQrhcAC0GU3eEAEK4XAAtBpN3hABCuFwALQbTd4QAQrhcAC0G03eEAEK4XAAtBxN3hABCuFwALQcTd4QAQrhcAC0HE3eEAEK4XAAtB1N3hABCuFwALQdTd4QAQrhcAC0Hk3eEAEK4XAAtB9N3hABCuFwALQYTe4QAQrhcAC0GU3uEAEK4XAAtBpN7hABCuFwALQbTe4QAQrhcAC0HE3uEAEK4XAAtB1N7hABCuFwALQeTe4QAQrhcAC0H03uEAEK4XAAtBhN/hABCuFwALQZTf4QAQrhcAC0Gk3+EAEK4XAAtBpN/hABCuFwALQbTf4QAQrhcAC0HE3+EAEK4XAAtBxN/hABCuFwALQcTf4QAQrhcAC0HU3+EAEK4XAAtB5N/hABCuFwALQeTf4QAQrhcAC0H03+EAEK4XAAtBhODhABCuFwALQZTg4QAQrhcAC0Gk4OEAEK4XAAtBoOHhABCuFwALQaDh4QAQrhcAC0Gw4eEAEK4XAAtBsOHhABCuFwALQbDh4QAQrhcAC0Hg4uEAEK4XAAtB4OLhABCuFwALQfDi4QAQrhcAC0Hw4uEAEK4XAAtBgOPhABCuFwALQYDj4QAQrhcAC0GQ4+EAEK4XAAtBkOPhABCuFwALQfTd4QAQrhcAC0GE3uEAEK4XAAtBlN7hABCuFwALQaTe4QAQrhcAC0Hk3OEAEK4XAAtBoOPhABCuFwALQcDh4QAQrhcAC0HQ4eEAEK4XAAtB4OHhABCuFwALQfDh4QAQrhcAC0GA4uEAEK4XAAtBkOLhABCuFwALQaDi4QAQrhcAC0Gw4uEAEK4XAAtBwOLhABCuFwALQdDi4QAQrhcAC5gqAhJ/BH4jAEHABGsiAiQAIAIgARD9ASACQSBqIgQgAiABEPIBIAJBQGsiESACEP0BIAJB4ABqIhAgERD9ASACQYABaiISIBAgAhDyASACIBAgERDyASACQaABaiITIBIgERDyASACQcABaiIJIBAQ/QEgAkHgAWoiCCASIBAQ8gEgAkGAAmoiCiACIBIQ8gEgAkGgAmoiDiATEP0BIAJBoARqIg8gBCAOEPIBIAJBOGogAkG4BGoiCykDADcDACACQTBqIAJBsARqIgwpAwA3AwBBCCEDIAJBKGogAkGoBGoiDSkDADcDACACIAIpA6AENwMgIAJBwAJqIgYgCCAJEPIBIAJB4AJqIgUgBCAOEPIBIAJBgANqIgcgBSAJEPIBIAJBoANqIgQgBSAIEPIBIAggByASEPIBIAJBwANqIgUgByAOEPIBIBIgBCAOEPIBIAJB4ANqIAggChDyASACQYAEaiAFIBMQ8gEgEyAFIA4Q8gEgDyAKIBMQ8gEgAkGYAmogCykDADcDACACQZACaiAMKQMANwMAIAJBiAJqIA0pAwA3AwAgAiACKQOgBDcDgAIgDyARIAoQ8gEgAkHYAGogCykDADcDACACQdAAaiAMKQMANwMAIAJByABqIA0pAwA3AwAgAiACKQOgBDcDQCAPIAYgERDyASACQdgCaiALKQMANwMAIAJB0AJqIAwpAwA3AwAgAkHIAmogDSkDADcDACACIAIpA6AENwPAAiAPIA4gBhDyASACQbgCaiALKQMANwMAIAJBsAJqIAwpAwA3AwAgAkGoAmogDSkDADcDACACIAIpA6AENwOgAiAPIAIgDhDyASACQRhqIgYgCykDADcDACACQRBqIgcgDCkDADcDACACQQhqIgUgDSkDADcDACACIAIpA6AENwMAIA8gECACEPIBIAJB+ABqIAspAwA3AwAgAkHwAGogDCkDADcDACACQegAaiANKQMANwMAIAIgAikDoAQ3A2AgDyAJIBAQ8gEgAkHYAWogCykDADcDACACQdABaiAMKQMANwMAIAJByAFqIA0pAwA3AwAgAiACKQOgBDcDwAEDQCACQaAEaiIEIAIQ/QEgBiALKQMANwMAIAcgDCkDADcDACAFIA0pAwA3AwAgAiACKQOgBDcDACADQQFrIgMNAAsgBCACIAJBoAJqEPIBIAJBGGoiCCACQbgEaiIJKQMANwMAIAJBEGoiCiACQbAEaiIGKQMANwMAIAJBCGoiByACQagEaiIFKQMANwMAIAIgAikDoAQ3AwBBCSEDA0AgAkGgBGoiBCACEP0BIAggCSkDADcDACAKIAYpAwA3AwAgByAFKQMANwMAIAIgAikDoAQ3AwAgA0EBayIDDQALIAQgAiACQUBrEPIBIAJBGGoiCCACQbgEaiIJKQMANwMAIAJBEGoiCiACQbAEaiIGKQMANwMAIAJBCGoiByACQagEaiIFKQMANwMAIAIgAikDoAQ3AwBBCSEDA0AgAkGgBGoiBCACEP0BIAggCSkDADcDACAKIAYpAwA3AwAgByAFKQMANwMAIAIgAikDoAQ3AwAgA0EBayIDDQALIAQgAiACQYACahDyASACQRhqIgggAkG4BGoiCSkDADcDACACQRBqIgogAkGwBGoiBikDADcDACACQQhqIgcgAkGoBGoiBSkDADcDACACIAIpA6AENwMAQQkhAwNAIAJBoARqIgQgAhD9ASAIIAkpAwA3AwAgCiAGKQMANwMAIAcgBSkDADcDACACIAIpA6AENwMAIANBAWsiAw0ACyAEIAIgAkGAAmoQ8gEgAkEYaiIIIAJBuARqIgkpAwA3AwAgAkEQaiIKIAJBsARqIgYpAwA3AwAgAkEIaiIHIAJBqARqIgUpAwA3AwAgAiACKQOgBDcDAEEHIQMDQCACQaAEaiIEIAIQ/QEgCCAJKQMANwMAIAogBikDADcDACAHIAUpAwA3AwAgAiACKQOgBDcDACADQQFrIgMNAAsgBCACIAJB4ANqEPIBIAJBGGoiCCACQbgEaiIJKQMANwMAIAJBEGoiCiACQbAEaiIGKQMANwMAIAJBCGoiByACQagEaiIFKQMANwMAIAIgAikDoAQ3AwBBByEDA0AgAkGgBGoiBCACEP0BIAggCSkDADcDACAKIAYpAwA3AwAgByAFKQMANwMAIAIgAikDoAQ3AwAgA0EBayIDDQALIAQgAiACQYAEahDyASACQRhqIgggAkG4BGoiCSkDADcDACACQRBqIgogAkGwBGoiBikDADcDACACQQhqIgcgAkGoBGoiBSkDADcDACACIAIpA6AENwMAQQohAwNAIAJBoARqIgQgAhD9ASAIIAkpAwA3AwAgCiAGKQMANwMAIAcgBSkDADcDACACIAIpA6AENwMAIANBAWsiAw0ACyAEIAIgAkGgAWoQ8gEgAkEYaiIIIAJBuARqIgkpAwA3AwAgAkEQaiIKIAJBsARqIgYpAwA3AwAgAkEIaiIHIAJBqARqIgUpAwA3AwAgAiACKQOgBDcDAEEJIQMDQCACQaAEaiIEIAIQ/QEgCCAJKQMANwMAIAogBikDADcDACAHIAUpAwA3AwAgAiACKQOgBDcDACADQQFrIgMNAAsgBCACIAJBwANqEPIBIAJBGGoiCCACQbgEaiIJKQMANwMAIAJBEGoiCiACQbAEaiIGKQMANwMAQQghAyACQQhqIgcgAkGoBGoiBSkDADcDACACIAIpA6AENwMAA0AgAkGgBGoiBCACEP0BIAggCSkDADcDACAKIAYpAwA3AwAgByAFKQMANwMAIAIgAikDoAQ3AwAgA0EBayIDDQALIAQgAiACQeACahDyASACQRhqIgggAkG4BGoiCSkDADcDACACQRBqIgogAkGwBGoiBikDADcDAEEIIQMgAkEIaiIHIAJBqARqIgUpAwA3AwAgAiACKQOgBDcDAANAIAJBoARqIgQgAhD9ASAIIAkpAwA3AwAgCiAGKQMANwMAIAcgBSkDADcDACACIAIpA6AENwMAIANBAWsiAw0ACyAEIAIgARDyASACQRhqIgggAkG4BGoiCSkDADcDACACQRBqIgogAkGwBGoiBikDADcDACACQQhqIgcgAkGoBGoiBSkDADcDACACIAIpA6AENwMAQQ4hAwNAIAJBoARqIgQgAhD9ASAIIAkpAwA3AwAgCiAGKQMANwMAIAcgBSkDADcDACACIAIpA6AENwMAIANBAWsiAw0ACyAEIAIgAkGgA2oQ8gEgAkEYaiIIIAJBuARqIgkpAwA3AwAgAkEQaiIKIAJBsARqIgYpAwA3AwAgAkEIaiIHIAJBqARqIgUpAwA3AwAgAiACKQOgBDcDAEEKIQMDQCACQaAEaiIEIAIQ/QEgCCAJKQMANwMAIAogBikDADcDACAHIAUpAwA3AwAgAiACKQOgBDcDACADQQFrIgMNAAsgBCACIAJB4AJqEPIBIAJBGGoiCCACQbgEaiIJKQMANwMAIAJBEGoiCiACQbAEaiIGKQMANwMAIAJBCGoiByACQagEaiIFKQMANwMAIAIgAikDoAQ3AwBBDyEDA0AgAkGgBGoiBCACEP0BIAggCSkDADcDACAKIAYpAwA3AwAgByAFKQMANwMAIAIgAikDoAQ3AwAgA0EBayIDDQALIAQgAiACQeABahDyASACQRhqIgggAkG4BGoiCSkDADcDACACQRBqIgogAkGwBGoiBikDADcDACACQQhqIgcgAkGoBGoiBSkDADcDACACIAIpA6AENwMAQQohAwNAIAJBoARqIgQgAhD9ASAIIAkpAwA3AwAgCiAGKQMANwMAIAcgBSkDADcDACACIAIpA6AENwMAIANBAWsiAw0ACyAEIAIgAkHgAGoQ8gEgAkEYaiIIIAJBuARqIgkpAwA3AwAgAkEQaiIKIAJBsARqIgYpAwA3AwBBCCEDIAJBCGoiByACQagEaiIFKQMANwMAIAIgAikDoAQ3AwADQCACQaAEaiIEIAIQ/QEgCCAJKQMANwMAIAogBikDADcDACAHIAUpAwA3AwAgAiACKQOgBDcDACADQQFrIgMNAAsgBCACIAJBgAFqEPIBIAJBGGoiCCACQbgEaiIJKQMANwMAQRAhAyACQRBqIgogAkGwBGoiBikDADcDACACQQhqIgcgAkGoBGoiBSkDADcDACACIAIpA6AENwMAA0AgAkGgBGoiBCACEP0BIAggCSkDADcDACAKIAYpAwA3AwAgByAFKQMANwMAIAIgAikDoAQ3AwAgA0EBayIDDQALIAQgAiACQcACahDyASACQRhqIgggAkG4BGoiCSkDADcDACACQRBqIgogAkGwBGoiBikDADcDAEEIIQMgAkEIaiIHIAJBqARqIgUpAwA3AwAgAiACKQOgBDcDAANAIAJBoARqIgQgAhD9ASAIIAkpAwA3AwAgCiAGKQMANwMAIAcgBSkDADcDACACIAIpA6AENwMAIANBAWsiAw0ACyAEIAIgAkHAAWoQ8gEgAkEYaiIIIAJBuARqIgkpAwA3AwAgAkEQaiIKIAJBsARqIgYpAwA3AwAgAkEIaiIHIAJBqARqIgUpAwA3AwAgAiACKQOgBDcDAEEHIQMDQCACQaAEaiIEIAIQ/QEgCCAJKQMANwMAIAogBikDADcDACAHIAUpAwA3AwAgAiACKQOgBDcDACADQQFrIgMNAAsgBCACIAJBgANqEPIBIAJBGGoiCCACQbgEaiIJKQMANwMAIAJBEGoiCiACQbAEaiIGKQMANwMAIAJBCGoiByACQagEaiIFKQMANwMAIAIgAikDoAQ3AwBBCSEDA0AgAkGgBGoiBCACEP0BIAggCSkDADcDACAKIAYpAwA3AwAgByAFKQMANwMAIAIgAikDoAQ3AwAgA0EBayIDDQALIAQgAiACQcABahDyASACQRhqIgggAkG4BGoiCSkDADcDACACQRBqIgogAkGwBGoiBikDADcDAEEIIQMgAkEIaiIHIAJBqARqIgUpAwA3AwAgAiACKQOgBDcDAANAIAJBoARqIgQgAhD9ASAIIAkpAwA3AwAgCiAGKQMANwMAIAcgBSkDADcDACACIAIpA6AENwMAIANBAWsiAw0ACyAEIAIgAkHAAmoQ8gEgAkEYaiIIIAJBuARqIgkpAwA3AwAgAkEQaiIKIAJBsARqIgYpAwA3AwBBCCEDIAJBCGoiByACQagEaiIFKQMANwMAIAIgAikDoAQ3AwADQCACQaAEaiIEIAIQ/QEgCCAJKQMANwMAIAogBikDADcDACAHIAUpAwA3AwAgAiACKQOgBDcDACADQQFrIgMNAAsgBCACIAJBwAFqEPIBIAJBGGoiCCACQbgEaiIJKQMANwMAIAJBEGoiCiACQbAEaiIGKQMANwMAQQghAyACQQhqIgcgAkGoBGoiBSkDADcDACACIAIpA6AENwMAA0AgAkGgBGoiBCACEP0BIAggCSkDADcDACAKIAYpAwA3AwAgByAFKQMANwMAIAIgAikDoAQ3AwAgA0EBayIDDQALIAQgAiACQcABahDyASACQRhqIgggAkG4BGoiCSkDADcDACACQRBqIgogAkGwBGoiBikDADcDAEEIIQMgAkEIaiIHIAJBqARqIgUpAwA3AwAgAiACKQOgBDcDAANAIAJBoARqIgQgAhD9ASAIIAkpAwA3AwAgCiAGKQMANwMAIAcgBSkDADcDACACIAIpA6AENwMAIANBAWsiAw0ACyAEIAIgAkHAAWoQ8gEgAkEYaiIIIAJBuARqIgkpAwA3AwAgAkEQaiIKIAJBsARqIgYpAwA3AwBBCCEDIAJBCGoiByACQagEaiIFKQMANwMAIAIgAikDoAQ3AwADQCACQaAEaiIEIAIQ/QEgCCAJKQMANwMAIAogBikDADcDACAHIAUpAwA3AwAgAiACKQOgBDcDACADQQFrIgMNAAsgBCACIAJBwAJqEPIBIAJBGGoiCCACQbgEaiIJKQMANwMAIAJBEGoiCiACQbAEaiIGKQMANwMAQQghAyACQQhqIgcgAkGoBGoiBSkDADcDACACIAIpA6AENwMAA0AgAkGgBGoiBCACEP0BIAggCSkDADcDACAKIAYpAwA3AwAgByAFKQMANwMAIAIgAikDoAQ3AwAgA0EBayIDDQALIAQgAiACQcABahDyASACQRhqIgggAkG4BGoiCSkDADcDACACQRBqIgogAkGwBGoiBikDADcDAEEIIQMgAkEIaiIHIAJBqARqIgUpAwA3AwAgAiACKQOgBDcDAANAIAJBoARqIgQgAhD9ASAIIAkpAwA3AwAgCiAGKQMANwMAIAcgBSkDADcDACACIAIpA6AENwMAIANBAWsiAw0ACyAEIAIgAkHAAWoQ8gEgAkEYaiIIIAJBuARqIgkpAwA3AwAgAkEQaiIKIAJBsARqIgYpAwA3AwAgAkEIaiIHIAJBqARqIgUpAwA3AwAgAiACKQOgBDcDAEEFIQMDQCACQaAEaiIEIAIQ/QEgCCAJKQMANwMAIAogBikDADcDACAHIAUpAwA3AwAgAiACKQOgBDcDACADQQFrIgMNAAsgBCACIAJBIGoQ8gEgAkEYaiIIIAJBuARqIgkpAwA3AwAgAkEQaiIKIAJBsARqIgYpAwA3AwAgAkEIaiIHIAJBqARqIgUpAwA3AwAgAiACKQOgBDcDAEEFIQMDQCACQaAEaiIEIAIQ/QEgCCAJKQMANwMAIAogBikDADcDACAHIAUpAwA3AwAgAiACKQOgBDcDACADQQFrIgMNAAsgBCACIAJBIGoQ8gEgAkEYaiACQbgEaiIGKQMAIhU3AwAgAkEQaiACQbAEaiIHKQMAIhY3AwAgAkEIaiACQagEaiIFKQMAIhc3AwAgAiACKQOgBCIUNwMAIABBGGogFTcDACAAQRBqIBY3AwAgAEEIaiAXNwMAIAAgFDcDACAGQgA3AwAgB0IANwMAIAVCADcDACACQgA3A6AEIAAgBCkDACABKQMAhSIUQgAgFH2EQgBZELkeIAQpAwggASkDCIUiFEIAIBR9hEIAWRC5HnEQuR4gBCkDECABKQMQhSIUQgAgFH2EQgBZELkecRC5HiAEKQMYIAEpAxiFIhRCACAUfYRCAFkQuR5xELkeQX9zQQFxELkeOgAgIAJBwARqJAALtSQCG38DfiMAQcAGayIHJAACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgASkDACIgUEUEQCABKQMIIiFQDQEgASkDECIiUA0CICIgIEJ/hVYNAyAgICFUDQQgAS4BGCEBIAcgID4CDCAHQQFBAiAgQoCAgIAQVCIFGzYCrAEgB0EAICBCIIinIAUbNgIQIAdBFGpBAEGYAfwLACAHQbQBakEAQZwB/AsAIAdBATYCsAEgB0EBNgLQAiABrCAgQgF9eX1CwprB6AR+QoChzaC0AnxCIIinIgXBIQ8CQCABQQBOBEAgB0EMaiABEK8EGgwBCyAHQbABakEAIAFrwRCvBBoLAkAgD0EASARAIAdBDGpBACAPa0H//wNxELUCDAELIAdBsAFqIAVB//8BcRC1AgsgB0GcBWogB0GwAWpBpAH8CgAAIAMiBkEKTwRAIAdBlAVqIQgDQCAHKAK8BiIBQSlPDRACQCABRQ0AAn8gAUECdCIBQQRrIgVFBEBCACEgIAdBnAVqIAFqDAELIAEgCGohASAFQQJ2QQFqQf7///8HcSEJQgAhIANAIAFBBGoiCiAKNQIAICBCIIaEIiBCgJTr3AOAIiE+AgAgASABNQIAICAgIUKAlOvcA359QiCGhCIgQoCU69wDgCIhPgIAICAgIUKAlOvcA359ISAgAUEIayEBIAlBAmsiCQ0ACyAgQiCGISAgAUEIagsgBUEEcQ0AQQRrIgEgICABNQIAhEKAlOvcA4A+AgALIAZBCWsiBkEJSw0ACwsgBkECdCgC1JZlQQF0IgVFDQUgBygCvAYiAUEpTw0OIAEEfyAFrSEgAn8gAUECdCIBQQRrIgVFBEBCACEhIAdBnAVqIAFqDAELIAEgB2pBlAVqIQEgBUECdkEBakH+////B3EhCUIAISEDQCABQQRqIgggCDUCACAhQiCGhCIhICCAIiI+AgAgASABNQIAICEgICAifn1CIIaEIiEgIIAiIj4CACAhICAgIn59ISEgAUEIayEBIAlBAmsiCQ0ACyAhQiCGISEgAUEIagshASAFQQRxRQRAIAFBBGsiASAhIAE1AgCEICCAPgIACyAHKAK8BgVBAAshAQJAAkACQCAHKAKsASIFIAEgASAFSRsiCEEoTQRAIAhFBEBBACEIDAQLIAhBAXEhCyAIQQFHDQFBACEGQQAhCgwCCwwQCyAIQT5xIQ1BACEGIAdBnAVqIQEgB0EMaiEJQQAhCgNAIAEgCSgCACIOIAEoAgBqIgwgBkEBcWoiEzYCACABQQRqIgYgCUEEaigCACIVIAYoAgBqIgYgDCAOSSAMIBNLcmoiDDYCACAGIBVJIAYgDEtyIQYgCUEIaiEJIAFBCGohASANIApBAmoiCkcNAAsLIAsEfyAKQQJ0IgEgB0GcBWpqIgogBiAHQQxqIAFqKAIAIgYgCigCAGoiAWoiCjYCACABIAZJIAEgCktyBSAGC0EBcUUNACAIQShGDRAgB0GcBWogCEECdGpBATYCACAIQQFqIQgLIAcgCDYCvAYgBygC0AIiDCAIIAggDEkbIgFBKU8NDiABQQJ0IQECQAJAA0AgAUUNASABQQRrIgEgB0GcBWpqKAIAIgggASAHQbABamooAgAiBkYNAAsgBiAITQ0BDAgLIAENBwsgD0EBaiEPDAcLQYiQ5QBBHEGklOUAEJwVAAtBuJHlAEEdQbSU5QAQnBUAC0HokeUAQRxBxJTlABCcFQALQdyT5QBBNkG0leUAEJwVAAtBlJPlAEE3QaSV5QAQnBUAC0GQguUAQRtByILlABCcFQALIAVFBEBBACEFIAdBADYCrAEMAQsgBUECdCIGQQRrIgFBAnZBAWoiCkEDcSEIAkAgAUEMSQRAIAdBDGohAUIAISAMAQsgCkH8////B3EhCSAHQQxqIQFCACEgA0AgASABNQIAQgp+ICB8IiA+AgAgAUEEaiIKIAo1AgBCCn4gIEIgiHwiID4CACABQQhqIgogCjUCAEIKfiAgQiCIfCIgPgIAIAFBDGoiCiAKNQIAQgp+ICBCIIh8IiE+AgAgIUIgiCEgIAFBEGohASAJQQRrIgkNAAsLIAgEQCAIQQJ0IQkDQCABIAE1AgBCCn4gIHwiIT4CACABQQRqIQEgIUIgiCEgIAlBBGsiCQ0ACwsgIUKAgICAEFoEQCAFQShGDQkgB0EMaiAGaiAgPgIAIAVBAWohBQsgByAFNgKsAQtBACELQQEhCCAPwSIBIATBIgZIIhsNASAPIARrwSADIAEgBmsgA0kbIgpFDQEgB0HUAmogB0GwAWpBpAH8CgAAQQEhEyAHQdQCakEBEK8EIRUgB0H4A2oiASAHQbABaiIEQaQB/AoAACABQQIQrwQhFiAHQZwFaiIBIARBpAH8CgAAIAdBrAFqIRwgB0HQAmohHSAHQfQDaiEeIAdBmAVqIR8gAUEDEK8EIRcgFSgCoAEhGCAWKAKgASEZIBcoAqABIRpBACENAkACQANAIAVBKU8NCyAFQQJ0IQRBACEBA0AgASAERg0DIAdBDGogAWogAUEEaiEBKAIARQ0ACyAaIAUgBSAaSRsiBEEpTw0MIARBAnQhAQJ/AkACQANAIAFFDQEgASAfaiEIIAFBBGsiASAHQQxqaigCACIGIAgoAgAiCEYNAAsgBiAITw0BQQAMAgsgAUUNAEEADAELQQEhBkEAIQUgBEEBRwRAIARBPnEhDiAHQQxqIQEgB0GcBWohCQNAIAEgASgCACIQIAkoAgBBf3NqIgggBkEBcWoiETYCACABQQRqIgYgBigCACISIAlBBGooAgBBf3NqIgYgCCAQSSAIIBFLcmoiCDYCACAGIBJJIAYgCEtyIQYgCUEIaiEJIAFBCGohASAOIAVBAmoiBUcNAAsLIARBAXEEfyAFQQJ0IgEgB0EMamoiBSAFKAIAIgUgASAXaigCAEF/c2oiASAGaiIINgIAIAEgBUkgASAIS3IFIAYLQQFxRQ0OIAcgBDYCrAEgBCEFQQgLIQ4gGSAFIAUgGUkbIgRBKU8NDCAEQQJ0IQECQAJAAkADQCABRQ0BIAEgHmohCCABQQRrIgEgB0EMamooAgAiBiAIKAIAIghGDQALIAYgCE8NASAFIQQMAgsgAUUNACAFIQQMAQsgBARAQQEhBkEAIQUgBEEBRwRAIARBPnEhECAHQQxqIQEgB0H4A2ohCQNAIAEgASgCACIRIAkoAgBBf3NqIgggBkEBcWoiEjYCACABQQRqIgYgBigCACIUIAlBBGooAgBBf3NqIgYgCCARSSAIIBJLcmoiCDYCACAGIBRJIAYgCEtyIQYgCUEIaiEJIAFBCGohASAQIAVBAmoiBUcNAAsLIARBAXEEfyAFQQJ0IgEgB0EMamoiBSAFKAIAIgUgASAWaigCAEF/c2oiASAGaiIINgIAIAEgBUkgASAIS3IFIAYLQQFxRQ0PCyAHIAQ2AqwBIA5BBHIhDgsgGCAEIAQgGEkbIghBKU8NCCAIQQJ0IQECQAJAAkADQCABRQ0BIAEgHWohBSABQQRrIgEgB0EMamooAgAiBiAFKAIAIgVGDQALIAUgBk0NASAEIQgMAgsgAUUNACAEIQgMAQsgCARAQQEhBkEAIQUgCEEBRwRAIAhBPnEhECAHQQxqIQEgB0HUAmohCQNAIAEgASgCACIRIAkoAgBBf3NqIgQgBkEBcWoiEjYCACABQQRqIgYgBigCACIUIAlBBGooAgBBf3NqIgYgBCARSSAEIBJLcmoiBDYCACAGIBRJIAQgBklyIQYgCUEIaiEJIAFBCGohASAQIAVBAmoiBUcNAAsLIAhBAXEEfyAFQQJ0IgEgB0EMamoiBCAEKAIAIgQgASAVaigCAEF/c2oiASAGaiIFNgIAIAEgBEkgASAFS3IFIAYLQQFxRQ0PCyAHIAg2AqwBIA5BAmohDgsgDCAIIAggDEkbIgVBKU8NCyAFQQJ0IQECQAJAAkADQCABRQ0BIAEgHGohBCABQQRrIgEgB0EMamooAgAiBiAEKAIAIgRGDQALIAQgBk0NASAIIQUMAgsgAUUNACAIIQUMAQsgBQRAQQEhBkEAIQggBUEBRwRAIAVBPnEhECAHQQxqIQEgB0GwAWohCQNAIAEgASgCACIRIAkoAgBBf3NqIgQgBkEBcWoiEjYCACABQQRqIgYgBigCACIUIAlBBGooAgBBf3NqIgYgBCARSSAEIBJLcmoiBDYCACAGIBRJIAQgBklyIQYgCUEIaiEJIAFBCGohASAQIAhBAmoiCEcNAAsLIAVBAXEEfyAIQQJ0IgEgB0EMamoiBCAEKAIAIgQgB0GwAWogAWooAgBBf3NqIgEgBmoiCDYCACABIARJIAEgCEtyBSAGC0EBcUUNDwsgByAFNgKsASAOQQFqIQ4LIAMgDU0NASACIA1qIA5BMGo6AAAgBUEpTw0LAkAgBUUEQEEAIQUMAQsgBUECdCIIQQRrIgFBAnZBAWoiBkEDcSEEAkAgAUEMSQRAIAdBDGohAUIAISAMAQsgBkH8////B3EhCSAHQQxqIQFCACEgA0AgASABNQIAQgp+ICB8IiA+AgAgAUEEaiIGIAY1AgBCCn4gIEIgiHwiID4CACABQQhqIgYgBjUCAEIKfiAgQiCIfCIgPgIAIAFBDGoiBiAGNQIAQgp+ICBCIIh8IiE+AgAgIUIgiCEgIAFBEGohASAJQQRrIgkNAAsLIAQEQCAEQQJ0IQkDQCABIAE1AgBCCn4gIHwiIT4CACABQQRqIQEgIUIgiCEgIAlBBGsiCQ0ACwsgIUKAgICAEFQNACAFQShGDQsgB0EMaiAIaiAgPgIAIAVBAWohBQsgByAFNgKsASANQQFqIQ0gEyAKIBNLIgFqIRMgAQ0AC0EAIQgMBAsgDSADQYSV5QAQjBAACyADIApJDQACQCAKIA1GDQAgCiANayIBRQ0AIAIgDWpBMCAB/AsACyAAIA87AQggACAKNgIEDAMLIA0gCiADQZSV5QAQmxUAC0EAIQoLAn8CQAJAAkAgDEUNACAMQQJ0IgZBBGsiAUECdkEBaiILQQNxIQQCQCABQQxJBEAgB0GwAWohAUIAISAMAQsgC0H8////B3EhCSAHQbABaiEBQgAhIANAIAEgATUCAEIFfiAgfCIgPgIAIAFBBGoiCyALNQIAQgV+ICBCIIh8IiA+AgAgAUEIaiILIAs1AgBCBX4gIEIgiHwiID4CACABQQxqIgsgCzUCAEIFfiAgQiCIfCIhPgIAICFCIIghICABQRBqIQEgCUEEayIJDQALCyAEBEAgBEECdCEJA0AgASABNQIAQgV+ICB8IiE+AgAgAUEEaiEBICFCIIghICAJQQRrIgkNAAsLICFCgICAgBBUBEAgDCELDAELIAxBKEYNCCAHQbABaiAGaiAgPgIAIAxBAWohCwsgByALNgLQAiALIAUgBSALSRsiAUEpTw0GIAFBAnQhASAHQQhqIQYgB0GsAWohDAJAAkACfwJAA0AgAUUNASABIAxqIQUgASAGaiABQQRrIQEoAgAiBCAFKAIAIgVGDQALIAQgBUsgBCAFSWsMAQtBf0EAIAEbC0H/AXEOAgABAwtBACAIDQMaIAMgCkEBayIBSwRAIAEgAmotAABBAXENAQwDCyABIANB1JTlABCMEAALIAMgCkkNACACIApqIQVBACEBAkACQANAIAEgCmpFDQEgAUEBayIBIAVqIgQtAABBOUYNAAsgBCAELQAAQQFqOgAAIAEgCmpBAWoiBSAKTQ0BIAUgCiAKQaSF5QAQmxUACwJAIAgEQEExIQEMAQsgAkExOgAAQTAhASAKQQFrIgRFIARFcg0AIAJBAWpBMCAE/AsACyAPQQFqIQ8gGyADIApNcg0CIAUgAToAACAKQQFqIQoMAgsgAUF/Rg0BIAFBf3MiAUUNASAEQQFqQTAgAfwLAAwBC0EAIAogA0HklOUAEJsVAAsgAyAKSQ0CIAoLIQEgACAPOwEIIAAgATYCBAsgACACNgIAIAdBwAZqJAAPC0EAIAogA0H0lOUAEJsVAAtBACAIQShByILlABCbFQALQQAgAUEoQciC5QAQmxUAC0EoQShByILlABCMEAALQQAgBUEoQciC5QAQmxUAC0EAIARBKEHIguUAEJsVAAtBq4LlAEEaQciC5QAQnBUAC8evAQIefwN+IwBBsBBrIgckACABAn8CQAJAAkACfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgAS0A1AdBAWsOAwUKAQALIAEoAtAHIQUgAUEwaiIaIAFBMPwKAAAgAUEAOgBkIAEgBTYCYCABQeQAaiEbDAELIAFBMGohGiABQeQAaiEbAkAgAS0AZEEBaw4EAwkCBgALIAEoAmAhBQsgB0HIAWoiICAaQTD8CgAAIAdB+AFqIRcjAEGQBGsiCyQAIAsQvRkgC0GwAmoiBEGk9sIAQRAQlhECQAJAAkAgCy0AwAJBAkcEQCALQfAAaiIKIAtBwAJqKAIANgIAIAtB6ABqIhEgC0G4AmoiDykCADcDACALIAspArACNwNgIAtBiARqIhJBzPbCACkCADcDACALQcT2wgApAgA3A4AEIAQgCyALQYAEaiIQIAtB4ABqIhMQ6Q4gBBCqHiALQdAAaiIUQdT2wgBBHBD1ESAEIAsoAlQgCygCWBCWESALLQDAAkECRg0BIAogC0HAAmooAgA2AgAgESAPKQIANwMAIAsgCykCsAI3A2AgEkGI98IAKQIANwMAIAtBgPfCACkCADcDgAQgBCALIBAgExDpDiAEEKoeIBQQ8yEgC0HEAGohDiMAQRBrIggkACAFKAIYIQYgBSgCFCEJAkACQAJAIAUoAiAiA0UNACADIAZPBEAgAyAGRg0BDAILIAMgCWosAABBv39MDQELAkAgAyAJaiAGIANrQZOjyQBBAxC+IEUEQCAOQYCAgIB4NgIADAELIAhBCGohFSAFKAIYIQMgBSgCFCEJAkACQAJAIAUoAiAiBkUNACADIAZNBEAgAyAGRg0BDAILIAYgCWosAABBv39MDQELQQEhDQJAAkACQCAGIAlqIAMgBmtBnNjVAEEDEO0aRQ0AIAZBfEsNASAFKAIwIgwgBkEDaiIGTQ0AAkAgAyAGTQRAIAMgBkYNAQwECyAGIAlqLAAAQUBIDQMLAkAgAyAMTQRAIAMgDEcNBAwBCyAJIAxqLAAAQb9/TA0DCyAGIAlqIQ0gDCAGayEWCyAVIBY2AgQgFSANNgIADAMLQZTd1QAQrhcACyAJIAMgBiAMQbTe1QAQlB8ACyAJIAMgBiADQdTe1QAQlB8AC0EAIQMgCCgCDCEGIAgoAgghDANAAkAgAyAMaiENAkAgBiADayIVQQdNBEAgAyAGRg0CQQAhCQNAIAkgDWotAABBwABGDQIgFSAJQQFqIglHDQALDAILIAhBwAAgDSAVELgHIAgoAgBBAXFFDQEgCCgCBCEJCwJAIAMgCWoiAyAGTw0AIAMgDGotAABBwABHDQAgDkHQoMkAIAwgAxDvCAwDCyAGIANBAWoiA08NAQsLIA5BgICAgHg2AgALIAhBEGokAAwBCyAJIAYgAyAGQZijyQAQlB8ACyALKAJEQYCAgIB4RwRAIAtB2ABqIAtBzABqKAIAIgM2AgAgCyALKQJENwNQIAQgCygCVCADEJYRIAstAMACQQJGDQMgCiALQcACaigCADYCACARIA8pAgA3AwAgCyALKQKwAjcDYCASQaj3wgApAgA3AwAgC0Gg98IAKQIANwOABCAEIAsgECATEOkOIAQQqh4gFBDzIQsgCiAFQRBqENYPIAtBnAFqIAVBPGopAgA3AgAgC0GkAWogBUHEAGotAAA6AAAgCyAFKQI0NwKUASALIAUpAig3AogBIAsgBSkCIDcCgAEgCyAFKAIwNgKQASALIAUoAhw2AnwgCyAFKQIINwJoIAsgBSkCADcCYCALQbACaiERIAVByABqIwBB0ANrIgMkACADQcABaiALQeAAaiIOEPoGQcTcyQAoAgAhBEHA3MkAKAIAIQZBvNzJAC0AACEFAkAgAygCwAFBAkYEQEIDISEgAygCxAEhCCAERSAFQQpJcg0BIAYgBEEBEJ8gDAELQcjcyQApAgAhISADQYgCahC9GSADQbsDakG/3MkALQAAOgAAIAMgBToAuAMgAyAhNwLEAyADIAQ2AsADIAMgBjYCvAMgA0G93MkALwAAOwC5AyADQcgCaiADQcABakHIAPwKAAAgA0EBOgDMAyADQYCU69wDNgKYAyADQQA2AqADIANBBDYCtAMgAykDiAIhISADKAKQAiEIIANBBGogA0GUAmpBvAH8CgAACygCACIEIAQoAgAiBkEBajYCAAJAIAZBAE4EQCARIAg2AgggESAhNwMAIBEgBDYCyAEgEUEMaiADQQRqQbwB/AoAACADQdADaiQADAELAAsjAEHQAGsiBCQAIwBBEGsiDyQAIwBBQGoiBSQAIAUQnxYiAzYCLCADQQhqIQYCQAJAAn8CQAJ/AkACfwJAAn8CQAJ/AkACQAJAAn8gAygCiAIiCUHAAE8EQCADQZACaiAGEJ4WIAMoAgghFkEBDAELIAYgCUECdGooAgAhFiADIAlBAWoiCDYCiAIgCUE/Rw0BIANBkAJqIAYQnhZBAAsiCEEDaiEJIAhBAnIhCiAGIAhBAnRqIggoAgQhDCAIKAIAIRgMAQsgBiAIQQJ0aigCACEYIAMgCUECaiIINgKIAgJ/IAlBPk8EQCADQZACaiAGEJ4WIAMoAgghDEEBDAELIAYgCEECdGooAgAhDCADIAlBA2oiCjYCiAIgCUE9Rw0CIANBkAJqIAYQnhZBAAsiCkEBaiEJCyAGIApBAnRqKAIAIQogAyAJNgKIAiAGIAlBAnRqKAIAIRIgAyAJQQFqIgg2AogCIAlBAmoMAQsgBiAKQQJ0aigCACEKIAMgCUEEaiINNgKIAgJ/IAhBPkYEQCADQZACaiAGEJ4WIAMoAgghEkEBDAELIAYgDUECdGooAgAhEiADIAlBBWoiCDYCiAIgCUE7SQ0CIANBkAJqIAYQnhZBAAsiCEEBagshCSAGIAhBAnRqKAIAIRkgAyAJNgKIAiAGIAlBAnRqKAIAIRAgAyAJQQFqIgg2AogCIAlBAmoMAQsgBiAIQQJ0aigCACEZIAMgCUEGaiIINgKIAgJ/IA1BPkYEQCADQZACaiAGEJ4WIAMoAgghEEEBDAELIAYgCEECdGooAgAhECADIAlBB2oiDTYCiAIgCUE5SQ0CIANBkAJqIAYQnhZBAAsiCEEBagshCSAGIAhBAnRqKAIAIRwgAyAJNgKIAiAGIAlBAnRqKAIAIRQgAyAJQQFqIgg2AogCIAlBAmoMAQsgBiANQQJ0aigCACEcIAMgCUEIaiINNgKIAgJ/IAhBPkYEQCADQZACaiAGEJ4WIAMoAgghFEEBDAELIAYgDUECdGooAgAhFCADIAlBCWoiCDYCiAIgCUE3SQ0CIANBkAJqIAYQnhZBAAsiCEEBagshCSAGIAhBAnRqKAIAIR0gAyAJNgKIAiAGIAlBAnRqKAIAIRMgAyAJQQFqIgg2AogCIAlBAmoMAQsgBiAIQQJ0aigCACEdIAMgCUEKaiIINgKIAgJ/IA1BPkYEQCADQZACaiAGEJ4WIAMoAgghE0EBDAELIAYgCEECdGooAgAhEyADIAlBC2oiDTYCiAIgCUE1SQ0CIANBkAJqIAYQnhZBAAsiCEEBagshCSAGIAhBAnRqKAIAIR4gAyAJNgKIAiAGIAlBAnRqKAIAIRUgAyAJQQFqIgg2AogCIAlBAmoMAQsgBiANQQJ0aigCACEeIAMgCUEMaiINNgKIAgJ/IAhBPkYEQCADQZACaiAGEJ4WIAMoAgghFUEBDAELIAYgDUECdGooAgAhFSADIAlBDWoiCDYCiAIgCUEzSQ0CIANBkAJqIAYQnhZBAAsiCEEBagshCSAGIAhBAnRqKAIAIR8gAyAJNgKIAiAGIAlBAnRqKAIAIQ0gAyAJQQFqIgg2AogCDAELIAYgCEECdGooAgAhHyADIAlBDmoiCDYCiAIgDUE+RgRAIANBkAJqIAYQnhZBASEIIANBATYCiAIgAygCCCENDAELIAYgCEECdGooAgAhDSADIAlBD2oiCDYCiAIgCUExSQ0AIANBkAJqIAYQnhZBACEICyAGIAhBAnRqKAIAIQYgAyAIQQFqNgKIAiAFIA06AA4gBSAfOgANIAUgFToADCAFIB46AAsgBSATOgAKIAUgHToACSAFIBQ6AAggBSAcOgAHIAUgEDoABiAFIBk6AAUgBSASOgAEIAUgCjoAAyAFIAw6AAIgBSAYOgABIAUgFjoAACAFIAY6AA8gAyADKAIAQQFrIgM2AgAgA0UEQCAFQSxqEM0YCyAFQRBqIgYgBSgACTYACSAGIAUoAAA2AAAgBiAFLQAHOgAHIAZBDGogBUEMaigAADYAACAGQQRqIAVBBGovAAA7AAAgBiAFLQAIQT9xQYABcjoACCAGIAUtAAZBD3FBwAByOgAGIAVBADYCKCAFQoCAgIAQNwIgIAVBkInVADYCMCAFQqCAgIAONwI0IAUgBUEgajYCLCMAQTBrIg0kACANQQxqIRJBACEJQQAhCEEAIQwjAEHQAGsiAyQAIANCmICAgMAENwIkIANCk4CAgPACNwIcIANCjoCAgKACNwIUIANCiYCAgNABNwIMIANBLGpBAEEk/AsAQQghCgJAAkACQAJAA0ACQCAJIApJBEBBECAIIAhBEE0bIRADQCAIIBBGDQIgCUEkTw0EIANBLGogCWoiEyAGIAhqLQAAIhRBBHZBuIvVAGotAAA6AAAgCUEjRg0FIBNBAWogFEEPcUG4i9UAai0AADoAACAIQQFqIQggCUECaiIJIApJDQALCyAMQQRGBEAgEiADQSxqQST8CgAAIANB0ABqJAAMBgsgCkEkTw0EIANBLGogCmpBLToAACADQQRqIAxBAWoiDEEDdGoiCSgCBCEKIAkoAgAhCQwBCwsgEEEQQeiL1QAQjBAACyAJQSRB+IvVABCMEAALQSRBJEGIjNUAEIwQAAsgCkEkQdiL1QAQjBAACyAFQSxqIBJBJBDoHiANQTBqJAAEQEG4idUAQTcgBUE/akGoidUAQfCJ1QAQqQ4ACyAPQQRqIgMgBSkCIDcCACADQQhqIAVBKGooAgA2AgAgBUFAayQAIA9BATYCACMAQRBrIgMkACADQQRqQQNBAEEBQQEQogsgAygCCCEGIAMoAgRBAUYEQCAGIAMoAgxBqIvVABD2GwALIAMoAgwiBUECakGmi9UALQAAOgAAIAVBpIvVAC8AADsAACAEQUBrIghBAzYCCCAIIAU2AgQgCCAGNgIAIANBEGokACAEQQE6AEwgBEE4aiAPQQhqKQMANwMAIAQgDykDADcDMCAEICBBMPwKAAAgD0EQaiQAIAtBgARqIQ8jAEEgayINJAAgDUHcw8MAEO4QIA1BEGoiA0EAOgAMIANCAjcCBCADQbTi3wA2AgAgDSANNgIMIwBBIGsiDCQAAkACQAJAAkAgDUEMaiIGKAIMIgNBf0cEQCAGQQA6ABAgBiADQQFqNgIMIAxBGGoiAyAGQYHEwwBBARD2HSADELwVIgMNBCAMQQE6AAQgDCAGNgIAIAghAyMAQRBrIgYkACAMKAIAIgUoAgBBntzJAEGc3MkAIAwtAARBAUYiCBtBAUECIAgbEI8fIAYgBSAFKAIMIAUoAgQgBSgCCBCgGAJAIAYtAABBBEcEQCAGIAYpAwA3AwggBkEIahDpFiEDDAELIAxBAjoABCAGIAVBlMTDAEEHEIERIAYtAABBBEcEQCAGIAYpAwA3AwggBkEIahDpFiEDDAELIAUoAgBBn9zJAEECEI8fIwBBEGsiCCQAIAggBSADKAIEIAMoAggQgRFBACEDIAgtAABBBEcEQCAIIAgpAwA3AwggCEEIahDpFiEDCyAIQRBqJAAgAw0AIAVBAToAEEEAIQMLIAZBEGokACADDQQgBEEwaiEDIwBBEGsiBSQAIAwoAgAiCCgCAEGe3MkAQZzcyQAgDC0ABEEBRiIGG0EBQQIgBhsQjx8gBSAIIAgoAgwgCCgCBCAIKAIIEKAYAkAgBS0AAEEERwRAIAUgBSkDADcDCCAFQQhqEOkWIQMMAQsgDEECOgAEIAUgCEGbxMMAQQIQgREgBS0AAEEERwRAIAUgBSkDADcDCCAFQQhqEOkWIQMMAQsgCCgCAEGf3MkAQQIQjx8jAEFAaiIJJAACfwJAAkACQAJAIAMoAgBBAWsOAgECAAsgCUEIaiESIAlBEGohCgJAAkACQAJAAkACQAJAAkACQCADKQMIIiNCP4ciISAjhSAhfSIhQpDOAFoEQEEUIQMDQCAhIiJCkM4AgCEhIAMiBkUNCSADQQRrIgMgCmogIiAhQpDOAH59pyIQQf//A3FB5ABuIhNBAXQvAITjSjsAACAGQQJrIANJDQIgBiAKakECayAQIBNB5ABsa0H//wNxQQF0LwCE40o7AAAgIkL/wdcvVg0ACyAiQr+EPVgNAyADRQ0IDAILQRQhAyAhQuMAVg0BICFCClQNBQwDC0HM5MoAEK4XAAsgCiADQQJrIgNqICGnIgYgBkH//wNxQeQAbiIGQeQAbGtB//8DcUEBdC8AhONKOwAAIAatISELICFCClQNASADQQJPDQAMBAsgCiADQQJrIgNqICGnQQF0LwCE40o7AAAMAgsgA0UNAgsgCiADQQFrIgNqICGnQTByOgAACyAjQgBTBEAgA0UNASAKIANBAWsiA2pBLToAAAsgA0EUSw0AIBJBFCADazYCBCASIAMgCmo2AgAMAQtBzOTKABC0FwALIAgoAgAgCSgCCCAJKAIMEI8fDAILIAlBOGogCCADKAIIIAMoAgwQgRFBACAJLQA4QQRGDQIaIAkgCSkDODcDECAJQRBqEOkWDAILIAgoAgBBpJDKAEEEEI8fC0EACyEDIAlBQGskACADDQAgCEEBOgAQQQAhAwsgBUEQaiQAIAMNBCAEQcwAaiEDIwBBEGsiBiQAIAwoAgAiBSgCAEGe3MkAQZzcyQAgDC0ABEEBRiIIG0EBQQIgCBsQjx8gBiAFIAUoAgwgBSgCBCAFKAIIEKAYAkAgBi0AAEEERwRAIAYgBikDADcDCCAGQQhqEOkWIQMMAQsgDEECOgAEIAYgBUGdxMMAQQYQgREgBi0AAEEERwRAIAYgBikDADcDCCAGQQhqEOkWIQMMAQsgBSgCAEGf3MkAQQIQjx8jAEEQayIIJAAgCCAFIAMtAABBAnQiAygChNpJIAMoApzZSRCBEUEAIQMgCC0AAEEERwRAIAggCCkDADcDCCAIQQhqEOkWIQMLIAhBEGokACADDQAgBUEBOgAQQQAhAwsgBkEQaiQAIAMNBCMAQRBrIhIkAAJAIAxBo8TDAEEGELgLIgMNACASQQhqIhQiAyAMKAIAIgYQniAgAxC8FSIDDQAjAEEgayIJJAACQAJAAkACQCAGKAIMIgNBf0cEQCAEKQMAIAQoAhwgBkEAOgAQIAYgA0EBajYCDCAJQRhqIgMgBkGYnMMAEPMdIAMQvBUiAw0EIAlBAToABCAJIAY2AgBBgICAgHhHBEAjAEEQayIFJAAgCSgCACIDKAIAIgpBmM7eAEGZzt4AIAktAARBAUYiCBtBAUECIAgbEI0fIAMoAgwiCARAIAMoAgghECADKAIEIRMDQCAKIBMgEBCNHyAIQQFrIggNAAsLIARBHGohCCAJQQI6AAQgBSADQaSXwwBBBBCBEQJ/IAUtAABBBEcEQCAFIAUpAwA3AwggBUEIahDpFgwBCyADKAIAQZvO3gBBAhCNHwJAIAgoAgBBgICAgHhHBEAgBSADIAgoAgQgCCgCCBCBESAFLQAAQQRGDQEgBSAFKQMANwMIIAVBCGoQ6RYMAgsgAygCAEGEzt4AQQQQjR8LIANBAToAEEEACyEDIAVBEGokACADDQULIAkgBEEQajYCGCAJQRhqIQUjAEEQayIQJAACQCAJQaiXwwBBBBC4CyIDDQAgEEEIaiIVIgMgCSgCACITEJ4gIAMQvBUiAw0AIAUoAgAhAyMAQUBqIgokACAKQQhqIAMQqSEgCigCDCEFIAooAgghCCAKQQE6ABwjAEEgayIDJAAgA0EIaiAFEM0bQeyTygAQqAsgA0EUaiAKQRxqIhYgCCAFIAMoAgwgAygCEBDFCCADLQAUQQFGBEAgAyADLQAVOgAfQZyUygBBKyADQR9qQYyUygBB/JPKABCpDgALIApBEGoiBSADKQIINwIAIAVBCGogA0EQaigCADYCACADQSBqJAAgFiAKKAIUIgMgCigCGCIFENEDAkACQAJAIAooAhxFBEAgCigCECEIIAWtISEMAQsgCikCICEhIAooAhAiCEGAgICAeEcNASADIQggBSEDCyAIQYCAgIB4Rg0BIAogAzYCICAKIAg2AhwgCiAhpyIFNgIkIApBMGogEyADIAUQgRFBACEDIAotADBBBEcEQCAKIAopAzA3AzggCkE4ahDpFiEDCyAKQRxqEPMhDAELIAogITcCKCAKIAU2AiQgCiADNgIgIAogCDYCHCMAQTBrIgUkACAFQQA2AhwgBUKAgICAEDcCFCAFQYCRygA2AiQgBUKggICADjcCKCAFIAVBFGo2AiAgCkEcaiIIIAVBIGoQ0SAEQEGokcoAQTcgBUEIakGYkcoAQeCRygAQqQ4ACyAFQRBqIAVBHGooAgA2AgAgBSAFKQIUNwMIIAVBCGoQ+QEhAyAIEPMhIAVBMGokAAsgCkFAayQAIAMNACATQQE6ABAgEEEEOgAIIBUQvBUhAwsgEEEQaiQAIAMNBFBFBEAjAEEQayIIJAAgCSgCACIKKAIAQZ7cyQBBnNzJACAJLQAEQQFGIgMbQQFBAiADGxCPHyAIIAogCigCDCAKKAIEIAooAggQoBgCQCAILQAAQQRHBEAgCCAIKQMANwMIIAhBCGoQ6RYhAwwBCyAJQQI6AAQgCCAKQcKWwwBBBhCBESAILQAAQQRHBEAgCCAIKQMANwMIIAhBCGoQ6RYhAwwBCyAKKAIAQZ/cyQBBAhCPHwJAIAQoAgBFBEAgCigCAEGI3MkAQQQQjx8MAQsCfyMAQUBqIgUkAAJAAkAgBEEIaikDACIhQgBZBEAgBUEYakETQQBBAUEBEKILIAUoAhwhAyAFKAIYQQFGDQIgBUEANgI4IAUgBSgCIDYCNCAFIAM2AjAMAQsgBUEYakEUQQBBAUEBEKILIAUoAhwhAyAFKAIYQQFGDQEgBUEANgI4IAUgBSgCIDYCNCAFIAM2AjAgBUEwakEBEKoaIAUoAjQgBSgCOGpBLToAACAFQQE2AjgLIAUgISAhQj+HIiKFICJ9IAVBGGoiEEETEI8IIAVBMGoiAyAFKAIAIhMgEyAFKAIEahCyEiAFQRBqIAVBOGooAgAiEzYCACAFIAUpAjA3AwggAyAKIAUoAgwgExCBEUEAIQMgBS0AMEEERwRAIAUgBSkDMDcDGCAQEOkWIQMLIAVBCGoQ8yEgBUFAayQAIAMMAQsgAyAFKAIgQbS0yQAQ9hsACyIDDQELIApBAToAEEEAIQMLIAhBEGokACADDQULIwBBEGsiCCQAIAkoAgAiBSgCACIKQZjO3gBBmc7eACAJLQAEQQFGIgMbQQFBAiADGxCNHyAFKAIMIgMEQCAFKAIIIRAgBSgCBCETA0AgCiATIBAQjR8gA0EBayIDDQALCyAEQShqIQMgCUECOgAEIAggBUGsl8MAQQUQgRECfyAILQAAQQRHBEAgCCAIKQMANwMIIAhBCGoQ6RYMAQsgBSgCAEGbzt4AQQIQjR8gBSgCAEGAzt4AQfvN3gAgAy0AACIDG0EEQQUgAxsQjR8gBUEBOgAQQQALIQMgCEEQaiQAIAMNBCAJLQAERQRAQQAhAwwFCyAJKAIAIgMoAgwiBUUNASADIAVBAWsiBTYCDCADLQAQRQ0CIAlBEGogA0GEnMMAEPMdIAktABBBBEcEQCAJIAkpAxA3AwgMBAsgCUEYaiADIAUgAygCBCADKAIIEKAYIAktABhBBEYNAiAJIAkpAxg3AwgMAwtBiJzDABCuFwALQfSbwwAQtBcACyAJQQhqIANBhZzDABDzHQsgCUEIahC8FSEDCyAJQSBqJAAgAw0AIAZBAToAECASQQQ6AAggFBC8FSEDCyASQRBqJAAgAw0EIAwtAARFBEBBACEDDAULIAwoAgAiAygCDCIGRQ0BIAMgBkEBayIGNgIMIAMtABBFDQIgDEEQaiADQfjMwwBBARD2HSAMLQAQQQRHBEAgDCAMKQMQNwMIDAQLIAxBGGogAyAGIAMoAgQgAygCCBCgGCAMLQAYQQRGDQIgDCAMKQMYNwMIDAMLQfzMwwAQrhcAC0HozMMAELQXAAsgDEEIaiADQfzDwwBBARD2HQsgDEEIahC8FSEDCyAMQSBqJAACQAJAIAMiBQRAIA0Q8yEMAQsgDSgCBCEFIA0oAgAiA0GAgICAeEYNACAPIA0oAgg2AgggDyAFNgIEIA8gAzYCACAEQUBrEPMhIAQoAjBBAUYEQCAEQTRqEPMhCyAEQRxqEJUcIARBEGoQ8yEgDUEgaiQADAELIA0gBTYCDEGwzMMAQSsgDUEMakGgzMMAQYTEwwAQqQ4ACyAEQdAAaiQAIA4gESAPEIkKIBEgC0HAAPwKAAAjAEFAaiIPJAACQCAOKQMAQgNRBEAgFyAOQdAB/AoAACARELkVDAELIA8gEUHAAPwKAAAjAEHAAWsiCiQAIApBADYCCCAKQRRqIgNBADYCACADIA8pAiw3AgggAyAPKAIgNgIcIAMgDygCJCIENgIYIAMgBDYCFCADQRBqIA9BNGooAgA2AgAgAyAEIA8oAihBNGxqNgIgIA8oAhwiBARAIA8oAhggBEECdEECEJ8gCyAKQThqIAMQ0wcgCigCOCIEQQJHBEAgCkG0AWohFSAKQcwAaiENIApBPGohFANAIApB8ABqIA1BEGooAgA2AgAgCkHoAGogDUEIaikCADcDACAKIA0pAgA3A2ACQAJAAkAgBEEBcQRAIApBgAFqIBRBCGopAgA3AwAgCiAUKQIANwN4IwBBIGsiBiQAIApB+ABqIQVBACEIAkACQCAOEIAGBEAgBkEDOgAaDAELIA4gBRDQA0H//wNxIgkgDi8BOHEhAwJAAkADQCAOKAIcIQwDQCADIQRBACEDIAQgDE8NAAsgDigCGCAEQQJ0aiIMLwEAIgNB//8DRwRAIAQgDi8BOCIRIAwvAQIiDHFrIBFxIAhJDQICQCAJIAxHDQAgDigCKCIMIANNDQQgBSgCAEUgDigCJCADQTRsaiIMKAIgIhFBAEdGDQAgDEEgaiEMIBEEQCAMIAUQ7xhFDQEgBkECOgAaIAYgAzYCCCAGIAQ2AgQgBiAONgIADAYLIAwtAAQgBS0ABEcNACAGQQI6ABogBiADNgIIIAYgBDYCBCAGIA42AgAMBgsgBEEBaiEDIAhBAWohCAwBCwsgBiAJOwEYIAYgBDYCFCAGIA42AgAgBiAFKQIINwIMIAYgBSkCADcCBCAGIAhB/wNLIA4pAwBCAlJxOgAaDAMLIAYgCTsBGCAGIAQ2AhQgBiAONgIAIAYgBSkCCDcCDCAGIAUpAgA3AgQgBiAIQf8DSyAOKQMAQgJScToAGgwCCyADIAxBuJzUABCMEAALIAUoAgAiA0UNACAFQQxqIAUoAgQgBSgCCCADKAIQEQMACyAGLQAaQQNGBEBByJ3UAEEXIAZBH2pB+JvUAEHgndQAEKkOAAsgCkGMAWoiAyAGKQIANwIAIANBGGogBkEYaigCADYCACADQRBqIAZBEGopAgA3AgAgA0EIaiAGQQhqKQIANwIAIAZBIGokACAKLQCmAUECRg0BIwBBEGsiEiQAIApB4ABqIQRBACETIwBBMGsiESQAIAMoAgAhECARQQhqIANBDGopAgA3AwAgESADKQIENwMAAkACQAJAAkAgECgCKCIIQf//AU0EQCADLQAaIRYgAygCFCEMIAMvARghBiARQSxqIgUgBEEQaigCADYCACARQSRqIgkgBEEIaikCADcCACARIAQpAgA3AhwgEEEgaiIEKAIAIAhGBEAgBEGondQAEJUUCyAQKAIkIAhBNGxqIgQgESkCFDcCBCAEQQA2AgAgBCADQQRqIgMpAgA3AiAgBCAGOwEwIARBDGogEUEcaikCADcCACAEQRRqIAkpAgA3AgAgBEEcaiAFKAIANgIAIARBKGogA0EIaikCADcCACAQIAhBAWo2AiggECgCHCEYIBAoAhghGSAIIQQgDCEDA0AgAyEJQQAhAyAJIBhPDQAgGSAJQQJ0aiIDLwEAIgVB//8DRg0CIBNBAWoiE0UNBCADIAQ7AQAgAy8BAiADIAY7AQIgCUEBaiEDIQYgBSEEDAALAAsgBEEMaiAEKAIEIAQoAgggBCgCACgCEBEDACARKAIAIgMEQCARQQxqIBEoAgQgESgCCCADKAIQEQMACyASQQA2AgAMAQsgAyAGOwECIAMgBDsBAAJAIBZBAXMgE0GAAUlxDQAgECkDAEIAUg0AIBBCATcDAAsgEiAINgIIIBIgDDYCBCASIBA2AgALIBFBMGokAAwBC0HQoNQAEK4XAAsgEigCAEUEQEHIndQAQRcgEkEPakH4m9QAQfCg1AAQqQ4ACyAKQQhqIgMgEikCADcCACADQQhqIBJBCGooAgA2AgAgEkEQaiQADAMLIAooAghFDQECQAJAIApBCGoiAygCCCIFIAMoAgAiAygCKCIESQRAIANBLGohBiADKAIkIAVBNGxqIgQoAgBBAUYEQCAEKAIIIQkgAygCNCIIIAMoAixGBEAgBkGYnNQAEPoTCyADKAIwIAhBJGxqIgYgBTYCDCAGQQA2AgggBiAJNgIEIAZBATYCACAGIA0pAgA3AhAgBkEYaiANQQhqKQIANwIAIAZBIGogDUEQaigCADYCACADIAhBAWoiBjYCNCAIIAlJDQIgBCAINgIIIARBATYCACADKAIwIAlBJGxqIgMgCDYCDCADQQE2AggMAwsgAygCNCIIIAMoAixGBEAgBkGInNQAEPoTCyADKAIwIAhBJGxqIgYgBTYCDCAGQQA2AgggBiAFNgIEIAZBADYCACAGIA0pAgA3AhAgBkEYaiANQQhqKQIANwIAIAZBIGogDUEQaigCADYCACAEIAg2AgggBCAINgIEIARBATYCACADIAhBAWo2AjQMAgsgBSAEQZCh1AAQjBAACyAJIAZBqJzUABCMEAALDAILIApBEGogCkGUAWooAgA2AgAgCiAKKQKMATcDCCAKQagBaiEFAkACQCAKQYwBaiIDKAIIIgQgAygCACIGKAIoIgNJBEAgBigCJCAEQTRsaiIIKAIAQQFGBEAgBiAIKAIEENcCIAYoAighAwsgAyAETQ0BIAYoAiQgBEE0bGoiAykCDCEhIAMgDSkCADcCDCAFICE3AgAgA0EUaiIEKQIAISEgBCANQQhqKQIANwIAIAVBCGogITcCACADQRxqIgMoAgAhBCADIA1BEGooAgA2AgAgBUEQaiAENgIADAILIAQgA0HInNQAEIwQAAsgBCADQdic1AAQjBAACyAVIAooAqwBIAooArABIAooAqgBKAIQEQMADAELIApBADYCuAEgCkEBNgKsASAKQZSs1AA2AqgBIApCBDcCsAEgCkGoAWpBnKzUABD3GAALIApBOGogCkEUahDTByAKKAI4IgRBAkcNAAsLIApBFGohBiMAQTBrIgQkAANAIARBCGoiAyAGENMHIAQoAgggAygCACIIQQJHBEACQCAIRQ0AIAMoAgQiCEUNACADQRBqIAMoAgggAygCDCAIKAIQEQMACyADQSBqIAMoAhggAygCHCADKAIUKAIQEQMAC0ECRw0ACyAGQQA2AhAgBEEwaiQAIwBBEGsiBiQAIApBKGoiBSgCDCIIIAUoAgQiBGtBNG4hAyAEIAhHBEADQCAEQSBqKAIAIggEQCAEQSxqIARBJGooAgAgBEEoaigCACAIKAIQEQMACyAEQRhqIARBEGooAgAgBEEUaigCACAEQQxqKAIAKAIQEQMAIARBNGohBCADQQFrIgMNAAsLIAYgBSgCADYCDCAGIAUoAgg2AgggBkEIahDhIiAGQRBqJAAgCkEcaiIDEI8TIAMQ9SAgCkHAAWokACAXIA5B0AH8CgAACyAPQUBrJAAgC0GQBGokAAwDC0GI+cIAQSsgC0GABGpBtPnCAEG09sIAEKkOAAtBiPnCAEErIAtBgARqQbT5wgBB8PbCABCpDgALQYj5wgBBKyALQYAEakG0+cIAQZD3wgAQqQ4ACyABQegAaiIIIBdB0AH8CgAAIAFBADoAyAcgAUHIB2ohCQwFCyABQegAaiEIIAFByAdqIQkgAS0AyAdBAWsOAwIGBQQLQbD3wgAQtRcAC0H09MIAELUXAAtB2IXDABC1FwALIAFB2AFqIQMgAUG0A2ohBgJAAkAgAS0AtANBAWsOAwAEAQ8LQeiFwwAQtRcACyABQagDaiEIIAFBsANqIQQCQAJAIAEtALADQQFrDgMBBBEACyAIKAIAIQUMDwtBpIXDABC1FwALIAFBuAJqIAhB0AH8CgAAQgMhISABKALAAiEFIAEpA7gCIiJCA1ENCSAHQZQFaiABQfQAakG8AfwKAAAgByAFNgKQBSAHICI3A4gFIAdB0AZqIgMgAUGABGogB0GIBWoQhgkgAUGIBGogA0HAA/wKAAALIAFBiARqIQwCQAJAAkAgAS0AxAdBAWsOAwEDAgALIAFBADoAxQcgAUHQBWoiBCAMQcgB/AoAACABEJYfNgKYByABQZgHaiEGQbOCwwAhBUEHIQMCQAJAAkACQAJAAkACQAJAAkACQAJAIAEtAIAHQQFrDgoAAQIDBAUGBwgJCgtBuoLDACEFQQMhAwwJC0G9gsMAIQVBBCEDDAgLQcGCwwAhBUEDIQMMBwtBxILDACEFQQYhAwwGC0HKgsMAIQVBBCEDDAULQc6CwwAhBUEFIQMMBAtB04LDACEFDAMLQdqCwwAhBUEFIQMMAgsgB0G4AWogAUGBB2oQ7BggBygCvAEhAyAHKAK4ASEFDAELIAdBwAFqIAFBhAdqENoiIAcoAsQBIQMgBygCwAEhBQsgBiAFIAMQ3h8gB0GwAWoQhxIgBygCtAEhBQJAIAcoArABQQFxRQ0AIAdBqAFqIAUQyAsgBygCrAEhBSAHKAKoASIDRQ0AQgMhISADIAUQtSAhBQwKCyABIAU2ApwHIAFBAToAxQcgB0HADWogBBCPGyAHQZAMaiAHQcgNaikCADcDACAHIAcpAsANNwOIDCABQZwHaiELA0AgB0GgAWogB0GIDGoQzQcCQCAHKAKgASIFBEAgBygCpAEhCgJAIAUoAgAEQCAFKAIIIQQgBSgCBCEDDAELQQYhBEHE+cIAIQMCQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIAUtAARBAWsOUAABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVGR0hJSktMTU5PUAtBDiEEQcr5wgAhAwxPC0EPIQRB2PnCACEDDE4LQQ8hBEHn+cIAIQMMTQtBDSEEQfb5wgAhAwxMC0EgIQRBg/rCACEDDEsLQRwhBEGj+sIAIQMMSgtBHCEEQb/6wgAhAwxJC0EbIQRB2/rCACEDDEgLQR0hBEH2+sIAIQMMRwtBFiEEQZP7wgAhAwxGC0EeIQRBqfvCACEDDEULQR0hBEHH+8IAIQMMRAtBAyEEQeT7wgAhAwxDC0EFIQRB5/vCACEDDEILQQchBEHs+8IAIQMMQQtBDSEEQfP7wgAhAwxAC0ENIQRBgPzCACEDDD8LQQwhBEGN/MIAIQMMPgtBESEEQZn8wgAhAww9C0EKIQRBqvzCACEDDDwLQRMhBEG0/MIAIQMMOwtBECEEQcf8wgAhAww6C0EQIQRB1/zCACEDDDkLQQ4hBEHn/MIAIQMMOAtBECEEQfX8wgAhAww3C0ENIQRBhf3CACEDDDYLQRchBEGS/cIAIQMMNQtBIyEEQan9wgAhAww0C0EMIQRBzP3CACEDDDMLQdj9wgAhAwwyC0EDIQRB3v3CACEDDDELQQQhBEHh/cIAIQMMMAtBBCEEQeX9wgAhAwwvC0Hp/cIAIQMMLgtBByEEQe/9wgAhAwwtC0EJIQRB9v3CACEDDCwLQQQhBEH//cIAIQMMKwtBBCEEQYP+wgAhAwwqC0EIIQRBh/7CACEDDCkLQREhBEGP/sIAIQMMKAtBDSEEQaD+wgAhAwwnC0EIIQRBrf7CACEDDCYLQRMhBEG1/sIAIQMMJQtBDSEEQcj+wgAhAwwkC0EEIQRB1f7CACEDDCMLQQghBEHZ/sIAIQMMIgtBDCEEQeH+wgAhAwwhC0Ht/sIAIQMMIAtB8/7CACEDDB8LQRIhBEH5/sIAIQMMHgtBEyEEQYv/wgAhAwwdC0EPIQRBnv/CACEDDBwLQRshBEGt/8IAIQMMGwtBBSEEQcj/wgAhAwwaC0EHIQRBzf/CACEDDBkLQQ8hBEHU/8IAIQMMGAtBByEEQeP/wgAhAwwXC0ELIQRB6v/CACEDDBYLQRQhBEH1/8IAIQMMFQtBGCEEQYmAwwAhAwwUC0ERIQRBoYDDACEDDBMLQRYhBEGygMMAIQMMEgtBFSEEQciAwwAhAwwRC0HdgMMAIQMMEAtBCiEEQeOAwwAhAwwPC0EZIQRB7YDDACEDDA4LQQIhBEGGgcMAIQMMDQtBByEEQYiBwwAhAwwMC0ERIQRBj4HDACEDDAsLQQohBEGggcMAIQMMCgtBByEEQaqBwwAhAwwJC0EZIQRBsYHDACEDDAgLQQQhBEHKgcMAIQMMBwtBAyEEQc6BwwAhAwwGC0EHIQRB0YHDACEDDAULQRAhBEHYgcMAIQMMBAtBFiEEQeiBwwAhAwwDC0EWIQRB/oHDACEDDAILQQ8hBEGUgsMAIQMMAQtBECEEQaOCwwAhAwsgB0GYAWogChDpDyAHKAKYASIFDQFBABDHFSEFDAsLIAFBADoAxQcgByABKAKcBzYCiAwgBiAHQYgMaiIDEN8fIAMQ7R0gAS0AlAdFBEAgBhC6IAsgASgC/AYiA0EERwRAIAYgAxC5IAsgASgC6AZBAUcNBiABQewGaiIDEOgUDQYgB0GAAWogAxD8DSAHKAKEASEFIAcoAoABQQFxDQogByAFNgKIDCAGIAdBiAxqIgMQ5RkgAxDtHQwGCyAHQZABaiALIAMgBCAFIAcoApwBEJgUIAcoApABQQFxRQ0AIAdBiAFqIAcoApQBEMgLIAcoAogBIgNFDQALIAMgBygCjAEQtSAhBQwIC0Hsg8MAELUXAAsgAUG4B2ohBSABQcAHaiEGAkAgAS0AwAdBAWsOAwIBBQALIAUoAgAhAwwDCwALQaSFwwAQtRcACyAHQYgMahDcDiAHKAKMDCEFIAcoAogMDQMgB0HIDWogB0GYDGopAgAiITcDACAHIAcpApAMIiI3A8ANIAEgBTYCoAcgASAiNwKkByABQawHaiAhNwIAIAFBoAdqIQMgASgC4AYiBEGAlOvcA0cEQCADIAEpA9gGIAQQwAcLIAcgAxDPIjYCiAwgBiAHQYgMaiIDEOYZIAMQ7R0gB0H4AGogASgCpAYgASgCqAYgBhD8ECAHKAJ8IQUCQCAHKAJ4QQFxRQ0AIAdB8ABqIAUQyAsgBygCdCEFIAcoAnAiA0UNACADIAUQtSAhBQwDCyABIAU2ArQHIAFBtAdqEPoKIQMgAUEAOgDAByABIAM2ArgHIAFBwAdqIQYgAUG4B2ohBQsgASADEKIGNgK8BwsgB0HoAGogAUG8B2oiAyACEJ4LAkAgBygCaCILQQJHBEAgBygCbCEEIAMQyxoCfyALQQFxBEAgB0HgAGogBBDICyAHKAJkIgQgBygCYCIDDQEaCyMAQRBrIgMkACADIAQ2AgwgA0EMahC2ICELIAdB2ABqIgogBDYCBCAKIAtBAXM2AgAgA0EQaiQAQQAhAyAHKAJcIgQgBygCWEEBcUUNABogByAENgKIDBDeEyEDIAdBiAxqEO0dQcCDwwALIQQgBkEBOgAAIAUQ+RogAwRAIAcgBDYC9AwgByADNgLwDCAHQQA2AsgNIAdCgICAgBA3AsANIAdB0PfCADYCjAwgB0KggICADjcCkAwgByAHQcANajYCiAwgB0HwDGogB0GIDGoQix8NAiAHQYgPaiAHQcgNaigCACIGNgIAIAcgBykCwA03A4APAkACQCAGQSRGBEAgBygChA9B/oTDAEEkEJoTRQ0BCyAHQYAPahDzIQwBCyAHQYAPahDzISAHQdAAaiIDQbjOygA2AgQgA0EBNgIAIAcoAlQhBCAHKAJQIQMgB0HwDGoQ/hULQQEgBCADIAQQyhUhBSABQbQHahDtHQwDCyAHIAQ2AuwKIAdBiAxqIgMQyxUgB0HwCmogAyAHQewKaiIGEOIiEOwHIAdBgA9qIgUgBhDuEiAHKAKIDyELIAcoAoQPIQogB0EANgLIDSAHQQA2AsANIAdBADYC0A0gAyAHQcANaiAKIAsQ5QwgB0G4C2ohCwJAIAMoAgBBAkcEQCALIANByAD8CgAADAELQfyDwwBBCRDYIwALIAUQ8yEgByAGEOMiNgKADCADIAdBgAxqEP8HIAMtAAQiBkEDRgRAQYWEwwBBEBDYIwALIAdByABqIgUgBjoABCAFIAMoAgA2AgAgB0FAayEDIAcoAkghBgJAIActAEwiBUECRwRAIAMgBjYCACADIAVBAXE6AAQMAQtBlYTDAEEYENgjAAsgBygCQCEDIAcgBy0ARDoAnBAgByADNgKYECAHQcwNaiEFA0AgB0E4aiAHQZgQahDXFSAHKAI4IgNBAkcEQCAHIAMgBygCPEGthMMAQR4Q4hs2AoQMIAdBMGogB0GEDGoQ8RMgB0HQD2ogBygCMCAHKAI0QcuEwwBBEhDiGxDuFiAHKALUDyEDIAcoAtgPIQsjAEEQayIGJAAgBkEEaiIKIAMgCxCEHiAHQYgMaiIDIAoQnAggBkEQaiQAIAMoAgBBgICAgHhGBEBB3YTDAEEhENgjAAsgB0HADWoiBiADKQIANwIAIAZBEGogA0EQaikCADcCACAGQQhqIANBCGopAgA3AgAgB0H4DGogB0HIDWooAgA2AgAgByAHKQLADTcD8AwgB0GID2ogBUEIaigCADYCACAHIAUpAgA3A4APIAMgB0HwCmoiA0HIAPwKAAAgBiAHQYgMaiAHQfAMaiILIAdBgA9qIgoQxAUgAyAGQcgA/AoAACAKEPMhIAsQ8yEgB0HQD2oQ8yEgB0GEDGoQ7R0MAQsLIAdBmBBqEO0dIAdBiAxqIgYgB0HwCmpByAD8CgAAIAdB8AxqIQMgBi0ACSEFIAYtAAghCwJAIAYpAwAiIUIDUQRAIAMgBToACSADIAs6AAggA0IDNwMAIARBhAFJDQEgBBChFgwBCyADIAU6AAkgAyALOgAIIAMgITcDACADQQpqIAZBCmpBPvwKAAAgAyAENgJICyAHQcANaiAHQbgLakHIAPwKAAAgB0GYDmogAUGwB2ooAgA2AgAgB0GQDmogAUGoB2opAgA3AgAgByABKQKgBzcCiA4CQAJAAkAgBykD8AxCA1EEQCAHLQD5DCEFIActAPgMIQMgB0HQDWoQ8yEgB0GIDmoQ0hkMAQsgB0GAD2oiBCAHQfAMakHQAPwKAAAgB0HQD2oiBiAHQbgLakHIAPwKAAAgB0GoEGogAUGgB2oiA0EQaigCADYCACAHQaAQaiADQQhqKQIANwMAIAcgAykCADcDmBAgB0GIDGogBCAGIAdBmBBqEL0PIAcpA4gMIiFCA1INASAHLQCRDCEFIActAJAMIQMLQgMhIUEBIAUgAyAFEKEOIQUMAQsgBygCkAwhBSAHQaAOaiAHQZQMakHcAPwKAAALIAdBgAxqEO0dIAFBtAdqEO0dDAQLIAFBAzoAwAcgAUEDOgDEBwwFC0H498IAQTcgB0HQD2pB6PfCAEGw+MIAEKkOAAsgAUGgB2oQ0hkLQgMhISABLQDFB0UNACABQZwHahDtHQsgAUEAOgDFByABQZgHahDtHSABQdAFahC+ECABQQE6AMQHICFCBFENASAHQZAKaiAHQaAOakHcAPwKAAAgDBCtFAsgAUGABGoQ+RkgAUEBOgDIByAIEJYPICFCA1INARCtICAHQYAFaiAHQdwDaikCADcDACAHIAcpAtQDNwP4BCAHKALQAyEDIAdBtARqIAdB5ANqQcQA/AoAAAwJCyAJQQM6AABBAwwGCyAHIAU2AtADIAcgITcDyAMgB0HUA2ogB0GQCmpB3AD8CgAAIAcpA6gEISIgASAFNgJ4IAEgITcDcCABIAcpApAKNwJ8IAFBhAFqIAdBmApqKQIANwIAIAFBjAFqIAdBoApqQcQA/AoAACABICI3A9ABIAEgAS8BtAE7AWggAUHYAWoiAyABQfAAakHoAPwKAAAgAUEAOgC0AyABQbQDaiEGCyABQcACaiADQegA/AoAACAHQShqIAFBiANqELARIAcoAiwhBQJAIAcoAihBAXFFDQAgB0EgaiAFEMgLIAcoAiQhBSAHKAIgIghFDQBBACEEIAggBRCsICEFDAMLIAFBADoAsAMgASAFNgKoAyABQbADaiEEIAFBqANqIQgLIAEgBRCiBjYCrAMLIAdBGGogAUGsA2oiCSACEJ4LIAcoAhgiAkECRg0BIAcoAhwhBSAJEMsaAn8gAkEBcQRAIAdBEGogBRDICyAHKAIUIgUgBygCECIGDQEaCyAHQQhqIAUQhh9BACEGIAcoAgwiAiAHKAIIQQFxRQ0AGiAHIAI2AogFEN4TIQYgB0GIBWoQ7R1BwIPDAAshAiAEQQE6AAAgCBD5GiAGBEAgBiACEKwgIQVBACEEDAELIAcgAjYC8AwgByAHQfAMaiIGEKclNgKADyAHQcANaiAHQYAPaiICEKglQfiFwwAQqAsgAiAHKALEDSAHQcgNaiIEKAIAEI0SIAdBqA5qIAQoAgA2AgAgByAHKQLADTcDoA4gB0GIBWogB0GgDmoQ2gkgBygCiAUhBCAHKAKMBSEFIAcpApAFISEgAhDtHSAGEO0dCyABQcACahD3EyABQQE6ALQDIAMQ/xkgBARAIAcgITcC3AYgByAFNgLYBiAHIAQ2AtQGDAMLEK0gIAcoAtAGIgNBIUYNAiAHQZAMaiIBIAdB3AZqKQIANwMAIAcgBykC1AY3A4gMIAdBtARqIAdB5AZqQcQA/AoAACAHQYAFaiABKQMANwMAIAcgBykDiAw3A/gEDAMLIARBAzoAACAGQQM6AABBBAshASAbIAE6AAAgAEICNwMAQQMMAwsgB0HQA2oiAiAHQdwGaiIDKQIANwMAIAcgBykC1AY3A8gDIAEvAWgiBEHIAUYEQCAHQZAFaiACKQMANwMAIAcgBykDyAM3A4gFIAdB0AZqIQsjAEHABGsiCCQAIAdBiAVqIhIoAgQhASASKAIIIQIjAEEQayINJAAgDUEANgIMIA0gAjYCCCANIAE2AgQgCEGAAmohESMAQeACayIKJAAgCkEEaiIGIA1BBGoQoRggCkHAAWohCUEAIQNBACEMQgAhISMAQfAGayIEJAAgBCAGELEOAkACQAJAAkACQAJAAkACQAJAAkACfwJAAkACQAJAAkACQAJAAkACQAJ/AkACQAJ/IAQtAABBAUYEQCAEKAIEDAELIAQtAAFBAUYEQCAELQACIgFB2wBGDQIgAUH7AEYNAyAGIARB7wZqQeTnwgAQ+AMhAQwXCyAEQQU2ApADIAYgBEGQA2oQyBYLIQEgCUEDNgIAIAkgATYCBAwWCyAGLQAYIgFFDQMgBiABQQFrIgE6ABggAUH/AXFFBEAgBEEYNgKQAyAGIARBkANqEMgWDAILIAYQtxogBEEBOgDIBCAEIAY2AsQEIARBkANqIQIjAEEQayIBJAAgAUEEaiAEQcQEaiIFEIIFAkAgAS0ABEEBRgRAIAIgASgCCDYCBCACQYGAgIB4NgIADAELIAEtAAVFBEAgAkGAgICAeDYCAAwBCyABQQRqIAUoAgAQ3gUgASgCCCEFIAEoAgQiDkGAgICAeEcEQCACIAEoAgw2AgggAiAFNgIEIAIgDjYCAAwBCyACQYGAgIB4NgIAIAIgBTYCBAsgAUEQaiQAIAQoApADIgFBgYCAgHhGBEAgBCgClAMhAQwRCyABQYCAgIB4Rg0EIAQoApQDIQIgBCAEKAKYAzYCuAYgBCACNgK0BiAEIAE2ArAGIARBkANqIQIjAEEQayIBJAAgASAEQcQEaiIOEIIFAkAgAS0AAEEBRgRAIAIgASgCBDYCBCACQQQ2AgAMAQsgAS0AAUUEQCACQQM2AgAMAQsgASAOKAIAEOQFIAEoAgBBA0cEQCACIAEpAwA3AwAgAkEIaiABQQhqKQMANwMADAELIAIgASgCBDYCBCACQQQ2AgALIAFBEGokACAEKAKUAyEBIAQoApADIgVBBEYNDyAFQQNGDQUgBCAEKQOYAyIhNwPIBiAEIAE2AsQGIAQgBTYCwAYjAEHgAGsiAyQAIAMgDhCCBQJAIAMtAABBAUYEQCACQYKAgIB4NgJQIAIgAygCBDYCAAwBCyADLQABRQRAIAJBgYCAgHg2AlAMAQsgAyAOKAIAEIMLIAMoAlBBgYCAgHhHBEAgAiADQeAA/AoAAAwBCyACQYKAgIB4NgJQIAIgAygCADYCAAsgA0HgAGokACAEKAKQAyECIAQoAuADIgNBgoCAgHhGBEAgAiEBDA8LIARB4AVqIg8gBEGQA2oiDkEEckHMAPwKAAAgBEHYBGoiECAEQewDaigCADYCACAEIAQpAuQDNwPQBCADQYGAgIB4Rg0GIARB4ARqQQRyIA9BzAD8CgAAIARBvAVqIBAoAgA2AgAgBCADNgKwBSAEIAI2AuAEIAQgBCkD0AQ3ArQFIwBBIGsiAiQAIAIgBEHEBGoiAxCCBQJAIAItAABBAUYEQCAOIAIoAgQ2AgQgDkEMNgIADAELIAItAAFFBEAgDkELNgIADAELIAIgAygCABCSByACKAIAQQtHBEAgDiACKQIANwIAIA5BGGogAkEYaikCADcCACAOQRBqIAJBEGopAgA3AgAgDkEIaiACQQhqKQIANwIADAELIA4gAigCBDYCBCAOQQw2AgALIAJBIGokACAEKAKUAyEDIAQoApADIgxBDEYEfyADBSAEQdAFaiICIARBqANqKQIANwMAIARByAVqIg4gBEGgA2opAgA3AwAgBCAEKQKYAzcDwAUgDEELRwRAIARBmAJqIAIpAwA3AwAgBEGQAmogDikDADcDACAEQaABaiAEQbgGaigCADYCACAEIAQpA8AFNwOIAiAEIAQpArAGNwOYASAEQagBaiAEQeAEakHgAPwKAAAMEwtBA0GI4cIAQdDfwgAQgQ8LIQEgBEHgBGoQpR4MDgsgBi0AGCIBRQ0GIAYgAUEBayIBOgAYIAFB/wFxDQEgBEEYNgKQAyAGIARBkANqEMgWCyEBIAlBAzYCACAJIAE2AgQMEwsgBhC3GiAEQQE6AMAEIAQgBjYCvAQgBEGAgICAeDYCxAQgBEEDNgLQBCAEQYGAgIB4NgKwBSAEQQs2AsAFIARBtAVqIRAgBEHgBGpBBHIhEyAEQeQDaiEMIARBkANqQQRyIRcgBEHIBWohBSAEQZgDaiEOA0AgBEGQA2ohAiMAQSBrIgEkACABQRRqIARBvARqIgMQowQCQCABLQAUQQFGBEAgAiABKAIYNgIEIAJBAToAAAwBCyABLQAVRQRAIAJBgAo7AQAMAQsgAygCACIDKAIUIg9Bf0cEQCADQQA2AgggAyAPQQFqNgIUIAFBFGogA0EMaiADEJIFIAEoAhghAwJAIAEoAhRBAkcEQCABQQxqIQ8CfwJAAkACQAJAAkAgASgCHEECaw4GAQQEAwIABAsgA0Gc3skAQQcQmhMNA0EADAQLIAMvAABB6cgBRw0CQQEMAwsgA0Gj3skAQQYQmhMNAUECDAILIANBqd7JAEEFEJoTDQBBAwwBC0EECyEDIA9BADoAACAPIAM6AAEgAS0ADEEBRw0BIAEoAhAhAwsgAkEBOgAAIAIgAzYCBAwCCyACIAEtAA06AAEgAkEAOgAADAELQdSdyQAQrhcACyABQSBqJAAgBC0AkANBAUYEQCAEKAKUAyECDAkLAkACQAJAAkACQAJAIAQtAJEDQQFrDgUCAwQABQELIARBvARqEN8bIgJFDQUMDQsgBCgCxARBgICAgHhHBEBB1ODCAEEHEJ8RIQJBAQwOCyAEQZADaiEPIwBBEGsiASQAQYCAgIB4IQMCQCAEQbwEaigCACIUEO0IIgINACABQQRqIBQQ3gUgASgCCCECIAEoAgQiA0GAgICAeEYNACAPIAEoAgw2AggLIA8gAzYCACAPIAI2AgQgAUEQaiQAIAQoApQDIQIgBCgCkAMiAUGAgICAeEYNDCAEKAKYAyEDIAQoAsQEQYCAgIB4RwRAIARBxARqEPMhCyAEIAM2AswEIAQgAjYCyAQgBCABNgLEBAwECyAEKALQBEEDRwRAQdvgwgBBAhCfESECQQEMDQsgBEGQA2ohAQJAIARBvARqKAIAIgIQ7QgiAwRAIAFBAzYCACABIAM2AgQMAQsgASACEOQFCyAEKAKUAyECIAQoApADIgFBA0YNCyAEKQOYAyEhIAQoAtAEQQNHBEAgBEHQBGoQkRwLIAQgITcD2AQgBCACNgLUBCAEIAE2AtAEDAMLIAQoArAFQYGAgIB4RwRAQd3gwgBBBhCfESECQQEMDAsgBEGQA2ohAQJAIARBvARqKAIAIgIQ7QgiAwRAIAFBgYCAgHg2AlAgASADNgIADAELIAEgAhCDCwsgBCgCkAMhAiAEKALgAyIBQYGAgIB4Rg0KIARB4AVqIBdBzAD8CgAAIARByAZqIgMgDEEIaigCADYCACAEIAwpAgA3A8AGIAQoArAFQYGAgIB4RwRAIARB4ARqEKUeCyAEIAI2AuAEIBMgBEHgBWpBzAD8CgAAIBAgBCkDwAY3AgAgEEEIaiADKAIANgIAIAQgATYCsAUMAgsgBCgCwAVBC0cEQEHj4MIAQQUQnxEhAkEBDAsLIARBkANqIQECQCAEQbwEaigCACICEO0IIgMEQCABQQs2AgAgASADNgIEDAELIAEgAhCSBwsgBCgClAMhAiAEKAKQAyIBQQtGDQkgBEHwBWoiAyAOQRBqKQIANwMAIARB6AVqIg8gDkEIaikCADcDACAEIA4pAgA3A+AFIAQoAsAFQQtHBEAgBEHABWoQ0BoLIAUgBCkD4AU3AgAgBUEIaiAPKQMANwIAIAVBEGogAykDADcCACAEIAI2AsQFIAQgATYCwAUMAQsLAkAgBCgCxARBgICAgHhGIg5FBEAgBEG4BmogBEHMBGooAgA2AgAgBCAEKQLEBDcDsAYMAQsgBEGQA2pB1ODCAEEHEOYcIAQoApQDIQIgBCgCkAMiAUGAgICAeEYEQEEBIQFBASEDDAsLIAQgBCgCmAM2ArgGIAQgAjYCtAYgBCABNgKwBgsCQCAEKALQBEEDRiIDRQRAIARByAZqIARB2ARqKQMANwMAIAQgBCkD0AQ3A8AGDAELQdvgwgBBAhCeESEBIARBkANqIgJBAzYCACACIAE2AgQgBCgClAMhAiAEKAKQAyIBQQNGBEBBASEBDAgLIAQgBCkDmAM3A8gGIAQgAjYCxAYgBCABNgLABgsCQCAEKAKwBUGBgICAeEYiAUUEQCAEQZADaiAEQeAEakHgAPwKAAAMAQsgBEGAgICAeDYC4AMLAkAgBCgCwAUiDEELRwRAIARB2AZqIAVBCGopAgA3AwAgBEHgBmogBUEQaikCADcDACAEIAUpAgA3A9AGIAQoAsQFIQIMAQsgBEHgBWpBCjYCACAEKALkBSECIAQoAuAFIgxBC0YNBiAEQeAGaiAEQfgFaikCADcDACAEQdgGaiAEQfAFaikCADcDACAEIAQpAugFNwPQBgsgBEGoAmogBEG4BmooAgA2AgAgBCAEKQOwBjcDoAIgBCgCwAYhBSAEKALEBiEBIAQpA8gGISEgBEGwAmogBEGQA2pB4AD8CgAADAoLQfTmwgAQtBcAC0EDIQVBAEGI4cIAQdDfwgAQgQ8hAQwMC0EBQYjhwgBB0N/CABCBDyEBDAkLQQJBiOHCAEHQ38IAEIEPIQEMBwtBhOfCABC0FwALIARBkANqEKUeIARBwAZqEJEcCyAEQbAGahDzIQwCC0EBCyEBQQEhA0EBIQ4LIAQoAsAFQQtHBEAgBEHABWoQ0BoLIAQoArAFQYGAgIB4RyABcQRAIARB4ARqEKUeC0EDIQUgBCgC0ARBA0cgA3EEQCAEQdAEahCRHAsgBCgCxARBgICAgHhHIA5xBEAgBEHEBGoQ8yELIAIhAQsCQCAGLQAYIgNB/wFHBEAgBiADQQFqOgAYIAYQkQchAyAEQbADaiAEQdgGaikDADcDACAEQbgDaiAEQeAGaikDADcDACAEIAI2AqQDIAQgDDYCoAMgBCAhNwOYAyAEIAE2ApQDIAQgBCkD0AY3A6gDIAQgBTYCkAMgBEHAA2ogBEGwAmpB4AD8CgAAIARBqARqIARBqAJqKAIANgIAIAQgAzYCsAQgBCAEKQOgAjcDoAQgBUEDRwRAIAMNAiAEIARBmANqQZgB/AoAAAwICyADRQ0GIARBsARqEJcODAYLQYTnwgAQrhcACyAEQZADahDPGkEDIQUgAyEBDAULIARBwAZqEJEcCyAEQbAGahDzIQtBAyEFCwJAIAYtABgiAkH/AUcEQCAGIAJBAWo6ABggBhDXBCECIARBsANqIARBkAJqKQMANwMAIARBuANqIARBmAJqKQMANwMAIAQgAzYCpAMgBCAMNgKgAyAEICE3A5gDIAQgATYClAMgBCAEKQOIAjcDqAMgBCAFNgKQAyAEQcADaiAEQagBakHgAPwKAAAgBEGoBGogBEGgAWooAgA2AgAgBCACNgKwBCAEIAQpA5gBNwOgBAJAIAVBA0cEQCACDQEgBCAEQZgDakGYAfwKAAAMBQsgAg0CDAMLIARBkANqEM8aQQMhBSACIQEMAwtB9ObCABCuFwALIARBsARqEJcOC0EDIQULIAVBA0YNACAJQQhqIARBmAH8CgAAIAkgATYCBCAJIAU2AgAMAQsgBiABEMMkIQEgCUEDNgIAIAkgATYCBAsgBEHwBmokAAJAIAooAsABQQNGBEAgESAJQaAB/AoAAAwBCyAKQSBqIgEgCkHAAWpBoAH8CgAAIApBBGoQiAwiAgRAIBFBAzYCACARIAI2AgQgARDPGgwBCyARIApBwAFqQaAB/AoAAAsgCkEEahDzISAKQeACaiQAIA1BEGokAAJAAkACQCAIKAKAAkEDRgRAIAgoAoQCIQIjAEHQAGsiAyQAIwBBEGsiBCQAIAQgAjYCDCMAQTBrIgEkACABIARBDGo2AgAgAUGFDjYCFCABIAE2AhAgAUIBNwIkIAFBATYCHCABQYyL1QA2AhggASABQRBqNgIgIAFBBGoiBiABQRhqEO4EIAZBlIvVABCVJSABQTBqJAACQAJAAkAgAigCAA4CAAECCyACKAIIIgFFDQEgAigCBCABQQEQnyAMAQsgAkEEahDTEgsgAkEUQQQQnyAgBEEQaiQAIANBFzYCACADEM8QIQEgCEHoAGoiAiADQdAA/AoAACACIAE2AlAgA0HQAGokAAwBCyAIQeAAaiAIQYACakGgAfwKAAAgCCgCYCIBQQNHDQELIAhBCGoiASAIQegAakHYAPwKAAAgC0EIaiABQdgA/AoAACALQgE3AwAMAQsgCEEEaiIDIAhB4ABqQQRyQdwA/AoAACAIQYAEaiAIQcABakHAAPwKAAAgCCABNgKgAyAIQaADaiICQQRyIANB3AD8CgAAIwBBgAFrIgMkACADQQhqIQQjAEHQAGsiASQAIAJBkAFqIgkiBigCBCEFAkACQAJAAkACQCAGKAIIIgZBA0YEQCAFQaSL1QBBAxCaE0UNAQsgASAGQQBBAUEBEKILIAEoAgQhDCABKAIAQQFGDQIgASgCCCEKIAYEQCAKIAUgBvwKAAALIAFBA0EAQQFBARCiCyABKAIEIQUgASgCAEEBRg0DIAEoAggiDkECakGmi9UALQAAOgAAIA5BpIvVAC8AADsAACABQQM2AhggASAONgIUIAEgBTYCECABIAY2AgwgASAKNgIIIAEgDDYCBCABQR02AgAgARDQECEGIAQgAUHQAPwKAAAgBCAGNgJQDAELIARBITYCAAsgAUHQAGokAAwCCyAMIAEoAghBqIvVABD2GwALIAUgASgCCEGoi9UAEPYbAAsCQCADKAIIIgFBIUcEQCALQQxqIARBBHJB1AD8CgAAIAtCATcDACALIAE2AgggCRDzISACEJEcIAIoAoABQYCAgIB4RwRAIAJBMGoQ3RMLIAIoAhBBCkYNASACQRBqEK0eDAELAkAgAigCEEEKRwRAIANB+ABqIAJBEGoiAUEYaikCADcDACADQfAAaiABQRBqKQIANwMAIANB6ABqIAFBCGopAgA3AwAgAyABKQIANwNgIwBB0ABrIgUkACMAQTBrIgEkACABIANB4ABqIgQ2AgAgAUGEDjYCFCABIAE2AhAgAUIBNwIkIAFBATYCHCABQYyL1QA2AhggASABQRBqNgIgIAFBBGoiBiABQRhqEO4EIAZBlIvVABCVJSABQTBqJAAgBUEcaiAEQRhqKQIANwIAIAVBFGogBEEQaikCADcCACAFQQxqIARBCGopAgA3AgAgBUECNgIAIAUgBCkCADcCBCAFEM8QIQEgC0EIaiIEIAVB0AD8CgAAIAQgATYCUAwBCyALQQhqIQEgAigCgAFBgICAgHhHBEAgASACQTBqQeAA/AoAACALQgA3AwAgCRDzISACEJEcDAILIwBB0ABrIgUkACAFQRs2AgAgBRDQECEEIAEgBUHQAPwKAAAgASAENgJQCyAFQdAAaiQAIAtCATcDACAJEPMhIAIQkRwgAigCgAFBgICAgHhGDQAgAkEwahDdEwsgA0GAAWokAAsgEhDTGyAIQcAEaiQAIAdBgAVqIAdB5AZqKQIANwMAIAcgBykC3AY3A/gEIAcpA9AGISEgBygC2AYhAyAHQbQEaiAHQewGakHEAPwKAAAgBykDsAchIgwCCyMAQdAAayIBJAAgAUEKNgIAIAEgBDsBBCABENAQIQIgB0HQBmoiBCABQdAA/AoAACAEIAI2AlAgAUHQAGokACAHQYAFaiADKQIANwMAIAcgBykC1AY3A/gEIAcoAtAGIQMgB0G0BGogB0HkBmpBxAD8CgAAIAdByANqENMbC0IBISELIBtBAToAACAaENwYIAAgAzYCCCAAICE3AwAgACAHKQP4BDcCDCAAQRRqIAdBgAVqKQMANwIAIABBHGogB0G0BGpBxAD8CgAAIAAgIjcDYEEBCzoA1AcgB0GwEGokAAvvJwINfwJ+IwBBgAprIgMkAAJAAkAgAQJ/AkACfwJ/AkACQAJAAkACQAJAAkACQAJ/AkACQAJAAkACQAJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJ/AkACQAJAAkACQAJAAkACfwJAAkAgAS0AxAdBAWsOAw8OAQALIANBCGoiBCABQcAHaigCADYCACADIAEpArgHNwMAIAMgASkDmAc3AsAGIANBBTYCjAkgA0EFNgKECSADQZjSwwA2AoAJIAMgA0HABmo2AogJIANCAjcCnAJBAiELIANBAjYClAIgA0Gk0sMANgKQAiADIANBgAlqNgKYAiABQaAHaiADQZACahDuBCABQbQHaiAEKAIANgIAIAEgAykDACIRNwKsByABKAKoByEEIAEoAqQHIQcgEadBgICAgHhGBH9BAAUgASgCtAchBiABKAKwBwshBSABQYACOwEcIAFBAjYCGCABIAQ2AhQgASAHNgIQIAEgBjYCBCABIAU2AgAgAUEcaiEKQQEMAQsgAUEcaiEKAkAgAS0AHEEBaw4EDw0CAwALIAEoAgQhBiABKAIAIQUgASgCGCELIAEoAhQhBCABKAIQIQcgAS0AHQshCCABIAY2AgwgASAFNgIIQQEhBSADQdQFaiAIQQFxEKoQIAMgCzYC5AUgAyAENgLQBSADIAc2AswFIANBgAlqIANBzAVqEJ4NAkAgAygCgAlBAUYEQCADQZwDaiADQZAJaikDADcCACADIAMpA4gJNwKUAyADQcgGaiADQZgDaikCADcDACADQdAGaiADQaADaigCADYCACADIAMpApADNwPABgwBCyADQcAGaiADQYAJakEEckHEAPwKAABBACEFCyABIAU2AiAgAUEkaiADQcAGakHEAPwKAAALIAMgAUEgaiIENgLMBSADQYAJaiIHIANBzAVqKAIAIAIQrBBBAyADKAKACSIFQRJGDS4aIAMpA4gJIRAgAygChAkhBiAEEMgHIAVBEUYNASADIBA3A4gJIAMgBjYChAkgAyAFNgKACSADQZQCaiAHEKENQQMhAiADLQCgAiEGIAMtAJwCIQcgAy0AmAIhBSADLQCUAiEEDC8LIAFBKGohDyABQagCaiELAkAgAS0AqAJBAWsOBQcKAwgJAAsgASgCMCEHIAEoAiwhBSABKAIoIQQMAQsgASAGNgIgIAFBADoAqAIgASAENgIoIAEgASgCDCIHNgIwIAEgASgCCCIFNgIsIAFBqAJqIQsgAUEoaiEPCyABQQA6AIQEIAEgBDYCgAQgASAHNgI8IAEgBTYCOCABIAQ2AjQgAUGwAmohDiABQYQEaiENDAELIAFBsAJqIQ4gAUGEBGohDQJAIAEtAIQEQQFrDgMLBwIACyABKAKABCEEC0G8i8QA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EPMhIAMoAswFQQJHDQFBBiEEDBALIANBgAlqQSpBAEEBQQEQogsgAygChAkhAiADKAKACUEBRw0BDBoLIANBwAZqIgIgA0HMBWpB9AD8CgAAIANBgAlqIAcgBSACEOEEIAMoAowJIQUgAykChAkhECADKAKACSICQQJGBEBBBCEEQQMhAiAFIQYMEAsgAygCkAkhBiADQbgHaiADQZQJakHoAPwKAAAgAyAFNgKIBCADIBA3A4AEIBCnIQQgAykChAQhEAwPCyADKAKICSIEQf+KxABBKvwKAAAgA0EqNgKICSADIAQ2AoQJIAMgAjYCgAkgBEEqENQkIANBgAlqEPMhQQIhAkEFIQQgAygCzAVBAkYNDiADQagGahDzIQwNCyABQQA6ALwCIAEgBTYCuAIgASAHNgK0AiABIAQ2ArACIAFBsAJqIQggAUG8AmohDQsgCCgCACEJIAcEQCADQYAJaiIMQSdBAEEBQQEQogsgAygChAkhBiADKAKACUEBRg0YIAMoAogJIgRB6InEAEEn/AoAACADQSc2AogJIAMgBDYChAkgAyAGNgKACSAEQScQ1CQgDBDzISAMEOcIIAMoApAJIQYgAykCiAkhECADKAKECSEEIAMoAoAJIgxBAkcNAgwJCyADQYAJaiIEQSxBAEEBQQEQogsgAygChAkhBiADKAKACUEBRg0XIAMoAogJIgVBj4rEAEEs/AoAACADQSw2AogJIAMgBTYChAkgAyAGNgKACSAFQSwQ1CQgBBDzISABQQA6AJAGIAFBAjYCnAUgASAJNgKYBQsgA0GACWogAUHAAmoiBSACEPUBIAMoAoAJIgRBCEcNBEEEDAILIANBtAhqIANBlAlqQcgA/AoAACADIAY2ArAIIAMgEDcCqAggAyAENgKkCCADIAw2AqAIIANBgAlqIAcgBSADQaAIahDCCCADKAKMCSEGIAMpAoQJIRAgAygCgAkiBEECRgRAQQQhBAwHCyADQcAGaiIFIANBkAlqQewA/AoAACABIAY2AswCIAEgEDcCxAIgASAENgLAAiABQdACaiAFQewA/AoAACADQYAJaiABQcACahClBiADKAKMCSEGIAMpAoQJIRAgAygCgAkiBEECRgRAQQQhBAwGCyADQYAEaiIFIANBkAlqQeQA/AoAACABIAY2AqgGIAEgEDcDoAYgASAENgKcBiABIAk2ApgGIAFBrAZqIAVB5AD8CgAAIAFBADoAkAcLIANBgAlqIAFBwANqIgUgAhD1ASADKAKACSIEQQhHDQFBAwshASANIAE6AAAMAgsgAygCjAkhBiADKQKECSEQIAUQ6hUgBEEHRw0CIAEoAtACIQYgASkDyAIhECABKALEAiEEIAEoAsACIQIgA0HMBWogAUHUAmpB6AD8CgAAIAFBAToAvAIgAkEERg0BDAULIAMoAowJIQYgAykChAkhECAFEOoVQQMgBEEHRw0DGkECDAMLQQUMCwsgAUGcA2oQoxgLQQMLIQIgDUEBOgAACyADQbgHaiADQcwFakHoAPwKAAAgCBCLGAwCC0EDIQILIAFBAToArAMLIAtBAToAACAPELIUIAJBA0cNAQsgAyAGNgKgAiADIBA3ApgCIAMgBDYClAJBAyECIAEoAiAiBUGEAUkNASAFEKEWDAELIANBpAJqIANBuAdqQegA/AoAACADIAY2AqACIAMgEDcCmAIgAyAENgKUAiADIAEoAiA2AowDCyAQQiCIpyEHIBCnIQUMAwtBAwshASALIAE6AABBBAshASAKIAE6AAAgAEECNgIAQQMMAQsgA0GGAWoiDiADQZcCai0AADoAACADQYIBaiIJIANBmwJqLQAAOgAAIANB/gBqIgwgA0GfAmotAAA6AAAgA0H6AGoiCCADQaMCai0AADoAACADIAMvAJUCOwGEASADIAMvAJkCOwGAASADIAMvAJ0COwF8IAMgAy8AoQI7AXggAy0ApAIhCiADQfYAaiADQacCai0AADoAACADIAMvAKUCOwF0IANBDGogA0GoAmpB6AD8CgAAQQEhCyABQQE6ABwgARDrFQJAIAJBA0YEQCADQYoCaiAOLQAAOgAAIANBhgJqIAktAAA6AAAgA0GCAmogDC0AADoAACADQf4BaiAILQAAOgAAIAMgAy8BhAE7AYgCIAMgAy8BgAE7AYQCIAMgAy8BfDsBgAIgAyADLwF4OwH8ASABQawHaiIKEOYNIAoQlRwgAUGgB2oQ8yFBPSEIIAYhCgwBCyADQf4BaiADQfYAai0AADoAACADIAMvAXQ7AfwBIANBlAFqIANBDGpB6AD8CgAAIANBjgJqIANBhgFqLQAAOgAAIANBigJqIANBggFqLQAAOgAAIANBhgJqIANB/gBq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BkEQahDWDyAGKQIoIRMgBikCICEVIAUgBikCNDcC/AEgBUGEAmogBkE8aikCADcCACAFQYwCaiAGQcQAai0AADoAACAGKQIAIRQgBikCCCEWIAYoAjAhCCAFIAYoAhw2AuQBIAUgCDYC+AEgBSAVNwPoASAFIBM3A/ABIAUgFjcD0AEgBSAUNwPIAQJAAkBB2MrmACgCAA0AQZjH5gAtAAAiBkEBa0ECTwRAIAZFDQFBkMfmABC5CkH/AXEiBkUNAQtBkMfmACgCACAGENUVRQ0AQZDH5gAoAgAiBigCICIIRQ0KIAYoAiQhCSAGKAIcIQsgAyAGKAIoNgKEASADIAk2AoABIAMgCDYCfCADIAs2AnggA0EANgKIASADIAcvAQBByAFrQf//A3FB5ABJOgBUIANBAzYC1AEgA0GswcUANgLQASADQgI3AtwBIANBATYCdCADQdMANgJsIAMgBzYCaCADIANB6ABqNgLYASADIANB1ABqNgJwIANBxMHFADYCZCADIANB0AFqNgJgIAMgA0H4AGo2AlwgA0HIAGogBkEcaiADQdwAahD9HSADQUBrIANB0ABqKAIANgIAIAMgAykCSDcDOEGQx+YAKAIAIANBOGoiBhD3F0Hg0OYALQAADQFB0NDmACgCAEEFSQ0BIANBBTYCsAIgA0GQx+YAKAIAIgcpAhQ3ArQCIANBIGoQxhkgAygCICIIIANBsAJqIAMoAiQiCSgCDBEAAEUNASADQcgCaiADQbgCaigCADYCACADIAMpArACNwPAAiAHIAggCSADQcACaiAGEPcJDAELQeDQ5gAtAAANAEHQ0OYAKAIAQQVJDQAgA0EFNgI4IANBkMfmACgCACIIKQIUNwI8IANBGGoQxhkgAygCGCIJIANBOGogAygCHCILKAIMEQAARQ0AQZDH5gAoAgAiBigCICINRQ0KIAYoAighDiAGKAIkIRAgBigCHCERIANBADYCiAEgAyAONgKEASADIBA2AoABIAMgDTYCfCADIBE2AnggAyAHLwEAQcgBa0H//wNxQeQASToASCADQQM2AtQBIANBrMHFADYC0AEgA0ICNwLcASADQQE2AnQgA0HTADYCbCADIAc2AmggAyADQegAajYC2AEgAyADQcgAajYCcCADQcTBxQA2ArgCIAMgA0HQAWo2ArQCIAMgA0H4AGo2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A0GQBmogBUIAIAxCABCWDiADQeAGaiAFQgAgDUIAEJYOIANBsAdqIAVCACAIQgAQlg4gA0GACGogBUIAIAdCABCWDiADQdAIaiAFQgAgBkIAEJYOIANB0AVqIAEpAyAiBUIAIARCABCWDiADQaAGaiAFQgAgDEIAEJYOIANB8AZqIAVCACANQgAQlg4gA0HAB2ogBUIAIAhCABCWDiADQZAIaiAFQgAgB0IAEJYOIANB4AhqIAVCACAGQgAQlg4gA0HgBWogASkDKCIFQgAgBEIAEJYOIANBsAZqIAVCACAMQgAQlg4gA0GAB2ogBUIAIA1CABCWDiADQdAHaiAFQgAgCEIAEJYOIANBoAhqIAVCACAHQgAQlg4gA0HwCGogBUIAIAZCABCWDiADQbAEaiADKQPABCIFQv3/8//P///5iX9+IgRCAEKr1f7///+//7l/QgAQlg4gA0GgBGogBEIAQv//z4rr///VHkIAEJYOIANBsANqIARCAEKk7MO1j9S0mOcAQgAQlg4gA0HAAmogBEIAQr+llJzP8NK75ABCABCWDiADQdABaiAEQgBC19mumuT26Y3LAEIAEJYOIANB4ABqIARCAEKazf/Lo73EgBpCABCWDiADQZAEaiADKQO4BCAFIAMpA7AEIgR8IARUrXwiDSADKQOgBHwiBSADKQOgBSIIIAMpA9AEIgcgAykDyAR8IgZ8Igl8IgxC/f/z/8////mJf34iBEIAQqvV/v///7//uX9CABCWDiADQYAEaiAEQgBC///Piuv//9UeQgAQlg4gA0HwA2ogBEIAQqTsw7WP1LSY5wBCABCWDiADQeADaiAEQgBCv6WUnM/w0rvkAEIAEJYOIANB0ANqIARCAELX2a6a5PbpjcsAQgAQlg4gA0HAA2ogBEIAQprN/8ujvcSAGkIAEJYOIANBoANqIAUgDFatIAMpA6gEIAUgDVStfHwiCiADKQOwA3wiBSADKQPwBSILIAMpA9gEIAYgB1StfCIOIAMpA+AEfCIPfCINIAMpA6gFIAggCVatfHwiCCADKQOwBXwiEHwiByADKQOABHwiBiADKQOYBCADKQOQBCIEIAx8IARUrXx8IgxC/f/z/8////mJf34iBEIAQqvV/v///7//uX9CABCWDiADQZADaiAEQgBC///Piuv//9UeQgAQlg4gA0GAA2og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ACAMQgAQlg4gA0HQB2ogBUIAIAhCABCWDiADQaAIaiAFQgAgB0IAEJYOIANB8AhqIAVCACAGQgAQlg4gA0GwBGogAykDwAQiBUL9//P/z///+Yl/fiIEQgBCq9X+////v/+5f0IAEJYOIANBoARqIARCAEL//8+K6///1R5CABCWDiADQbADaiAEQgBCpOzDtY/UtJjnAEIAEJYOIANBwAJqIARCAEK/pZScz/DSu+QAQgAQlg4gA0HQAWogBEIAQtfZrprk9umNywBCABCWDiADQeAAaiAEQgBCms3/y6O9xIAaQgAQlg4gA0GQBGogAykDuAQgBSADKQOwBCIEfCAEVK18IgwgAykDoAR8IgUgAykDoAUiCCADKQPQBCIHIAMpA8gEfCIGfCIJfCINQv3/8//P///5iX9+IgRCAEKr1f7///+//7l/QgAQlg4gA0GABGogBEIAQv//z4rr///VHkIAEJYOIANB8ANqIARCAEKk7MO1j9S0mOcAQgAQlg4gA0HgA2ogBEIAQr+llJzP8NK75ABCABCWDiADQdADaiAEQgBC19mumuT26Y3LAEIAEJYOIANBwANqIARCAEKazf/Lo73EgBpCABCWDiADQaADaiAFIA1WrSADKQOoBCAFIAxUrXx8IgogAykDsAN8IgUgAykD8AUiCyADKQPYBCAGIAdUrXwiDiADKQPgBHwiD3wiDCADKQOoBSAIIAlWrXx8IgggAykDsAV8IhB8IgcgAykDgAR8IgYgAykDmAQgAykDkAQiBCANfCAEVK18fCINQv3/8//P///5iX9+IgRCAEKr1f7///+//7l/QgAQlg4gA0GQA2ogBEIAQv//z4rr///VHkIAEJYOIANBgANqIARCAEKk7MO1j9S0mOcAQgAQlg4gA0HwAmogBEIAQr+llJzP8NK75ABCABCWDiADQeACaiAEQgBC19mumuT26Y3LAEIAEJYOIANB0AJqIARCAEKazf/Lo73EgBpCABCWDiADQbACaiAGIA1WrSADKQOIBCAGIAdUrXx8IhEgAykD8AN8IgYgBSAHVq0gAykDuAMgBSAKVK18fCISIAMpA8ACfCIFIAMpA+gEIA4gD1atfCIPIAMpA/AEfCIHIAMpA8AGfCIJIAggDFStIAMpA/gFIAsgDFatfHx8IgwgAykDgAZ8IgogAykDuAUgCCAQ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ICIJIANBQGsgAygCJCILKAIMEQAARQ0AQZDH5gAoAgAiBigCICIMRQ0KIAYoAighDSAGKAIkIQ8gBigCHCEQIANBADYCkAEgAyANNgKMASADIA82AogBIAMgDDYChAEgAyAQNgKAASADIAcvAQBByAFrQf//A3FB5ABJOgBQIANBAzYC3AEgA0GswcUANgLYASADQgI3AuQBIANBATYCfCADQdMANgJ0IAMgBzYCcCADIANB8ABqNgLgASADIANB0ABqNgJ4IANBxMHFADYCyAIgAyADQdgBajYCxAIgAyADQYABajYCwAIgA0HkAGoiByAGQRxqIANBwAJqEP0dIANB2AJqIANByABqKAIANgIAIAMgAykCQDcD0AIgCCAJIAsgA0HQAmogBxD3CQsgBUGIAWohBwJAAkBB2MrmACgCAA0AQaTH5gAtAAAiBkEBa0ECTwRAIAZFDQFBnMfmABC5CkH/AXEiBkUNAQtBnMfmACgCACAGENUVRQ0AQZzH5gAoAgAiBigCICIIRQ0MIAYoAiQhCSAGKAIcIQsgAyAGKAIoNgKMASADIAk2AogBIAMgCDYChAEgAyALNgKAASADQcTBxQA2AsgCIANBADYCkAEgA0EBNgLcASADQfDBxQA2AtgBIANCATcC5AEgA0HUADYCYCADIAc2AlwgAyADQdgBajYCxAIgAyADQYABajYCwAIgAyADQdwAajYC4AEgA0HkAGogBkEcaiADQcACahD9HSADQdgAaiADQewAaigCADYCACADIAMpAmQ3A1BBnMfmACgCACADQdAAaiIGEPcXQeDQ5gAtAAANAUHQ0OYAKAIAQQVJDQEgA0EFNgLQAiADQZzH5gAoAgAiCCkCFDcC1AIgA0EYahDGGSADKAIYIgkgA0HQAmogAygCHCILKAIMEQAARQ0BIANB+ABqIANB2AJqKAIANgIAIAMgAykC0AI3A3AgCCAJIAsgA0HwAGogBhD3CQwBC0Hg0OYALQAADQBB0NDmACgCAEEFSQ0AIANBBTYCZCADQZzH5gAoAgAiCCkCFDcCaCADQRBqEMYZIAMoAhAiCSADQeQAaiADKAIUIgsoAgwRAABFDQBBnMfmACgCACIGKAIgIgxFDQwgBigCKCENIAYoAiQhDyAGKAIcIRAgA0EANgKQASADIA02AowBIAMgDzYCiAEgAyAM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QAJAAkACQAJAAkACQAJAAkACQAJAAn8CQAJAAkACQAJAIAEtABFBAWsOBAIHAQQACyABQQA6ABAgASgCCCEEIAEoAgwhBSABKAIAIQcgASgCBCEGIANBuAxqQYGChAg2AgAgA0GwDGpCgYKEiJCgwIABNwMAIANCgYKEiJCgwIABNwOoDCADQShqIAQgA0GoDGogBSAHIAYQ6A4gASADKQMoNwIUCyADQagMaiABQRRqIgQgAhC1HiADKQOoDCIWQgRSDQEgAEGBgICAeDYCrAJBAwwcC0G41cIAELUXAAsgA0EwaiIFIANBsAxqQdwA/AoAACADKAKMDSEHIAQQ/hUgFkIDUQRAIANBuAhqIAVB3AD8CgAAQYCAgIB4IQIMGgsgASAWNwMYIAFBIGogA0EwakHcAPwKAAAgAUEAOwGgASABIAc2AnwgAUGhAWohFCABQRhqIRJBAAwBCyABQRhqIRIgAUGhAWohFAJAIAEtAKEBQQFrDgQFAwkCAAsgAS0AoAELIQUgAUEAOgCiASADQZABaiASQegA/AoAAAJAQdjK5gAoAgBBAUsNAEGEx+YAEO4aQf8BcSIERQ0AQYTH5gAoAgAgBBDVFUUNACADQagMaiIEQYTH5gAoAgAiB0EcahD4HSABQYABaiAHIAQQpxcgAUEBOgCiAQwHCyADQQI2ArAMIANBhMfmACgCACIENgLADEHg0OYALQAARQ0EDAULIAFBqAFqIQQgAUGbA2ohByABLQCbA0EBaw4EAQAMCQgLAAtBkNPCABC1FwALQezRwgAQtRcACyADQYgGaiIHIARBHGoQ+B0gA0GoDGogBxDVBwsgAUEBOgCiASABIAMpA6gMNwOAASABQYgBaiADQbAMaikDADcDACABQZABaiADQbgMaikDADcDACABQZgBaiADQcAMaikDADcDAAsgA0H4AWoiBCADQZABakHoAPwKAAAgASgCiAFBAkYNASABQQA6AKIBIANB+ANqIAFBiAFqKQMANwMAIANBgARqIAFBkAFqKQMANwMAIANBiARqIAFBmAFqKQMANwMAIAMgASkDgAE3A/ADIANBkARqIARB8gH8CgAAIAFBqAFqIANB8ANqQZIC/AoAACABQQA6ALsDIAEgBToAugMLQQAhByMAQdAEayIEJAAgAUGoAWoiBSgCCEECRwRAIAVBCGog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aigCADYCACADQfAPaiABQaQBaigCADYCACADQfwPaiABQbABaigCADYCACADQYgQaiABQbwBaigCADYCACADQZQQaiABQcgBaigCADYCACADIAEpApABNwLcDyADIAEpApwBNwPoDyADIAEpAqgBNwL0DyADIAEpArQBNwOAECADIAEpAsABNwKMECADQdgPaiABQYwBaigCADYCACADIAI2AswLIAMgASkChAE3A9APIANBhAtqIgYgA0HQD2oiAkHIAPwKAAAgA0HQDWoiBSAEELoZIANBADYCzBMgA0KAgICAwAA3AsQTIAIgBSAGIANBxBNqEMQOIAUgAiABKALkASABKALoARCcGiADQdALaiIEIAUgAygClAcgBygCABCcGiACIAQQsxAgA0HCE2ogAy0A0w86AAAgAyADLwDRDzsBwBMgAy0A0A8hAiADKALUDyEEIAMpA9gPIRUgAy0A4A8hByADQekSaiADQeEPakHXAPwKAAAgA0HQEWogA0G4EGpBkwH8CgAAIAMoAswRIQUgAy0AyxEhBiADQZAHahDjICABQeABahDjICABEPsUIAFBQGsQ8yEgAUH4AGoQ8yEgAUGAAjsB3AEgBkECRg0CDAcLQbCNwgAQtRcAC0HgqsIAELUXAAsgAEEENgIAQQMMDAsgAUGEAWoQkxILIAEQ+xQLIAFBQGsQ8yEgAS0A3AFFDQAgAUH4AGoQ8yELIAFBgAI7AdwBQQEhBgsgARDXDyAGQQFxBEAgA0GABWogA0HCE2otAAA6AAAgAyADLwHAEzsB/gQgA0GnBGogA0HpEmpB1wD8CgAAQQQMAgsgA0EgaiADQdARakGTAfwKAAAgA0GOAmogA0HCE2otAAA6AAAgAyADLwHAEzsBjAIgA0G1AWogA0HpEmpB1wD8CgAACyABQQA6AJIHIANB+AdqIAFB4ARqKAIANgIAIAMgASkC2AQ3A/AHIAFBADoAkQcgA0HYC2ogAUHIBGooAgA2AgAgAyABKQLABDcD0AsgAyACOgDQDyADIAMvAYwCOwDRDyADIANBjgJqLQAAOgDTDyADIAc6AOAPIAMgFTcD2A8gAyAENgLUDyADQeEPaiADQbUBakHXAPwKAAAgA0G4EGogA0EgakGTAfwKAAAgAyAFNgLMESADQQA6AMsRIANB0A1qIQpCACEWIwBBkAJr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IAYQ6A4gASADKQMoNwIUCyADQfADaiABQRRqIgQgAhC1HiADKQPwAyIWQgRSDQEgAEECNgIAQQMMHAtBuNXCABC1FwALIANBMGoiBSADQfgDakHcAPwKAAAgAygC1AQhByAEEP4VIBZCA1EEQCADQeQGaiAFQdwA/AoAAEEBIQIMGgsgASAWNwMYIAFBIGogA0EwakHcAPwKAAAgAUEAOwGgASABIAc2AnwgAUGhAWohFCABQRhqIRJBAAwBCyABQRhqIRIgAUGhAWohFAJAIAEtAKEBQQFrDgQFAwkCAAsgAS0AoAELIQUgAUEAOgCiASADQZABaiASQegA/AoAAAJAQdjK5gAoAgBBAUsNAEGEx+YAEO4aQf8BcSIERQ0AQYTH5gAoAgAgBBDVFUUNACADQYAJaiIEQYTH5gAoAgAiB0EcahD4HSABQYABaiAHIAQQpxcgAUEBOgCiAQwHCyADQQI2AogJIANBhMfmACgCACIENgKYCUHg0OYALQAARQ0EDAULIAFBqAFqIQQgAUGbA2ohByABLQCbA0EBaw4EAQAMCQgLAAtBkNPCABC1FwALQezRwgAQtRcACyADQYgGaiIHIARBHGoQ+B0gA0GACWogBxDVBwsgAUEBOgCiASABIAMpA4AJNwOAASABQYgBaiADQYgJaikDADcDACABQZABaiADQZAJaikDADcDACABQZgBaiADQZgJaikDADcDAAsgA0H4AWoiBCADQZABakHoAPwKAAAgASgCiAFBAkYNASABQQA6AKIBIANB+ANqIAFBiAFqKQMANwMAIANBgARqIAFBkAFqKQMANwMAIANBiARqIAFBmAFqKQMANwMAIAMgASkDgAE3A/ADIANBkARqIARB8gH8CgAAIAFBqAFqIANB8ANqQZIC/AoAACABQQA6ALsDIAEgBToAugMLQQAhByMAQfACayIEJAAgAUGoAWoiBSgCCEECRwRAIAVBCGogBRDuEwsgA0GACWohEAJAQeDQ5gAtAAANACAFKAIYIgZFDQAgBEECNgK0ASAEQbDRwgA2ArABIARCATcCvAEgBEEFNgK0AiAEIAYpAgw3AlggBCAEQbACajYCuAEgBCAEQdgAajYCsAIgBSAEQbABahCFBQsgBUEgaiEGIAQgBTYCJCAFAn8CQAJAAkACQAJAAkACQAJAAkACQAJAIAUtAJMCQQFrDgQHAAUCAQsACyAFQYACOwGUAiAFIAUvAWQ7AZACIAVBiAFqIgsgBhC2CSAFQQE6AJQCIAVByAFqIg4gBSgCcBCwDyAFQZACaiEIAkACQEHYyuYAKAIADQBBkMfmABDuGkH/AXEiCUUNAEGQx+YAKAIAIAkQ1RVFDQBBkMfmACgCACIJQRxqIQogCSgCICIMBEAgCSgCKCENIAkoAiQhDyAJKAIcIQcgBEEANgLAASAEIA02ArwBIAQgDzYCuAEgBCAMNgK0AQsgBCAHNgKwASAEQdgAaiIHIARBsAFqIglB/MnCABCpFCAEIAgvAQBByAFrQf//A3FB5ABJOgBEIARBwMDCADYCVCAEQQM2ArQBIARBoMrCADYCsAEgBEICNwK8ASAEQQE2ArwCIARB0wA2ArQCIAQgCDYCsAIgBCAJNgJQIAQgBzYCTCAEIARBsAJqNgK4ASAEIARBxABqNgK4AiAEQThqIAogBEHMAGoQ/R0gBEEwaiAEQUBrKAIANgIAIAQgBCkCODcDKEGQx+YAKAIAIARBKGoiBxD3F0Hg0OYALQAADQFB0NDmACgCAEEFSQ0BIARBBTYClAIgBEGQx+YAKAIAIggpAhQ3ApgCIARBGGoQxhkgBCgCGCIJIARBlAJqIAQoAhwiCigCDBEAAEUNASAEQagCaiAEQZwCaigCADYCACAEIAQpApQCNwOgAiAIIAkgCiAEQaACaiAHEPcJDAELQeDQ5gAtAAANAEHQ0OYAKAIAQQVJDQAgBEEFNgIoIARBkMfmACgCACIKKQIUNwIsIARBEGoQxhkgBCgCECIMIARBKGogBCgCFCINKAIMEQAARQ0AQZDH5gAoAgAiCUEcaiEPIAkoAiAiEQRAIAkoAighEyAJKAIkIRUgCSgCHCEHIARBADYCwAEgBCATNgK8ASAEIBU2ArgBIAQgETYCtAELIAQgBzYCsAEgBEHYAGoiByAEQbABaiIJQfzJwgAQqRQgBCAILwEAQcgBa0H//wNxQeQASToAOCAEQcDAwgA2ApwCIARBAzYCtAEgBEGgysIANgKwASAEQgI3ArwBIARBATYCvAIgBEHTADYCtAIgBCAINgKwAiAEIAk2ApgCIAQgBzYClAIgBCAEQbACajYCuAEgBCAEQThqNgK4AiAEQcwAaiIHIA8gBEGUAmoQ/R0gBEGoAmogBEEwaigCADYCACAEIAQpAig3A6ACIAogDCANIARBoAJqIAcQ9wkLAkACQEHYyuYAKAIADQBBnMfmABDuGkH/AXEiCEUNAEEAIQdBnMfmACgCACAIENUVRQ0AQZzH5gAoAgAiCEEcaiEJIAgoAiAiCgRAIAgoAighDCAIKAIkIQ0gCCgCHCEHIARBADYCwAEgBCAMNgK8ASAEIA02ArgBIAQgCjYCtAELIAQgBzYCsAEgBEHYAGoiByAEQbABaiIIQbjKwgAQqRQgBEHAwMIANgKcAiAEQQE2ArQBIARB1MrCADYCsAEgBEIBNwK8ASAEQdQANgJIIAQgCzYCRCAEIAg2ApgCIAQgBzYClAIgBCAEQcQAajYCuAEgBEHMAGogCSAEQZQCahD9HSAEQUBrIARB1ABqKAIANgIAIAQgBCkCTDcDOEGcx+YAKAIAIARBOGoiBxD3F0Hg0OYALQAADQFB0NDmACgCAEEFSQ0BIARBBTYCoAIgBEGcx+YAKAIAIggpAhQ3AqQCIARBCGoQxhkgBCgCCCIJIARBoAJqIAQoAgwiCigCDBEAAEUNASAEQbgCaiAEQagCaigCADYCACAEIAQpAqACNwOwAiAIIAkgCiAEQbACaiAHEPcJDAELQeDQ5gAtAAANAEHQ0OYAKAIAQQVJDQAgBEEFNgJMIARBnMfmACgCACIJKQIUNwJQIAQQxhkgBCgCACIKIARBzABqIAQoAgQiDCgCDBEAAEUNAEEAIQdBnMfmACgCACIIQRxqIQ0gCCgCICIPBEAgCCgCKCERIAgoAiQhEyAIKAIcIQcgBEEANgLAASAEIBE2ArwBIAQgEzYCuAEgBCAPNgK0AQsgBCAHNgKwASAEQdgAaiIHIARBsAFqIghBuMrCABCpFCAEQcDAwgA2AqgCIARBATYCtAEgBEHUysIANgKwASAEQgE3ArwBIARB1AA2AjwgBCALNgI4IAQgCDYCpAIgBCAHNgKgAiAEIARBOGo2ArgBIARBlAJqIgcgDSAEQaACahD9HSAEQbgCaiAEQdQAaigCADYCACAEIAQpAkw3A7ACIAkgCiAMIARBsAJqIAcQ9wkLAkAgBS0AkgINACAEQbACaiAGEM0GIAQoArACQQFHDQAgBCkDuAJQDQILIAUvAWQiB0HIAWtB//8DcUHkAEkNAiAHQZQDRg0EIAVBADoAlQIgBUGYAmogBkHoAPwKAAAgBUEAOgD0AwsgBEGwAWogBUGYAmoiByACEMcFIAQoArABQYGAgIB4Rw0GIBBBAjYCAEEEDAgLIARBuAFqIA5ByAD8CgAAIAUvAZACIQIgBUEAOgCUAiAEQdgAaiIHIAtBwAD8CgAAQcAAQQgQnxsiCCAHQcAA/AoAACAEIAI7AYQCIAQgCDYCgAIgBEKBgICA4AE3A7ABDAYLIAVBADoAlQIgBUGYAmogBkHoAPwKAAAgBUEAOgD0AwsgBEGwAWogBUGYAmoiCCACEJcFIAQoArABRQ0CIBBBAjYCAEEDDAULIARBuAFqIA5ByAD8CgAAIARCgYCAgLABNwOwAQwDC0HcysIAELUXAAsgBCkCvAEhFiAEKAK4ASECIAQoArQBIQcgCBD8GSAEQdgAaiAFQcgBakHIAPwKAAAgBCAFQZACajYCpAEgBCAFQYgBaiIINgKgASAHRQRAIAQpAlghFiAEKQJgIRcgBEHIAWogBUHYAWpBOPwKAAAgBEGwAmoiByAIELYJQcAAQQgQnxsiCCAHQcAA/AoAACAEIAI2AoQCIAQgCDYCgAIgBCAXNwPAASAEIBY3A7gBIARCgYCAgIABNwOwASAEIAUvAZACOwGIAgwCCyAEQegAahDzISAEIBY3ArgCIAQgAjYCtAIgBCAHNgKwAiAEQbABaiAIIARBsAJqEJECDAELIARBuAJqIgggBEG4AWoiCSgCADYCACAEIAQpArABNwOwAiAHEPwZIAVBiAFqIQIgBCgCsAJBgICAgHhHBEAgBEGoAWogCCgCADYCACAEIAQpA7ACNwKgASAEQdgAaiIHIAVByAFqQcgA/AoAACAFLwGQAiEIIAVBADoAlAIgBEGwAmoiCSACQcAA/AoAAEHAAEEIEJ8bIgIgCUHAAPwKAAAgBEGwAWpBBHIgB0HUAPwKAAAgBCAIOwGMAiAEIAI2AogCIARBATYCsAEMAQsgBEGwAmoQ+hogCSAFQcgBakHIAPwKAAAgBS8BkAIhByAFQQA6AJQCIARB2ABqIgggAkHAAPwKAABBwABBCBCfGyICIAhBwAD8CgAAIAQgBzsBhAIgBCACNgKAAiAEQoGAgIDQATcDsAELIAUtAJQCBEAgBUGIAWoQuRULIAVBADoAlAIgBS0AlQIEQCAGEI4QCyAQIARBsAFqQeAA/AoAAEEBCzoAkwIgBEEkahDeDSAEQfACaiQAIAMoAoAJIgJBAkcNCUEDDA4LIAFBqAFqIgQgA0H4AWpB8gH8CgAAIAFBADoAmwMgASAFOgCaAyABQZsDaiEHCyABQYACOwGcAyABIAEvAewBOwGYAyABQZACaiIIIAQQtgkgAUEBOgCcAyABQdACaiIQIAEoAvgBELAPIAFBmANqIQUCQAJAQdjK5gAoAgANAEGQx+YAEO4aQf8BcSIGRQ0AQZDH5gAoAgAgBhDVFUUNAEGQx+YAKAIAIgZBHGohCyAGKAIgIg4EQCAGKAIoIQogBigCJCEMIAYoAhwhCSADQQA2ArgIIAMgCjYCtAggAyAMNgKwCCADIA42AqwICyADIAk2AqgIIANBgApqIgYgA0GoCGoiCUGg0sIAEKoUIAMgBS8BAEHIAWtB//8DcUHkAEk6ANMHIANB3NLCADYCiAggA0EDNgKsCCADQcTSwgA2AqgIIANCAjcCtAggA0EBNgLsByADQdMANgLkByADIAU2AuAHIAMgCTYChAggAyAGNgKACCADIANB4AdqNgKwCCADIANB0wdqNgLoByADQfAHaiALIANBgAhqEP0dIANByAdqIANB+AdqKAIANgIAIAMgAykC8Ac3A8AHQZDH5gAoAgAgA0HAB2oiBRD3F0Hg0OYALQAADQFB0NDmACgCAEEFSQ0BIANBBTYC5AkgA0GQx+YAKAIAIgYpAhQ3AugJIANBIGoQxhkgAygCICIJIANB5AlqIAMoAiQiCygCDBEAAEUNASADQfgJaiADQewJaigCADYCACADIAMpAuQJNwPwCSAGIAkgCyADQfAJaiAFEPcJDAELQeDQ5gAtAAANAEHQ0OYAKAIAQQVJDQAgA0EFNgLUByADQZDH5gAoAgAiCykCFDcC2AcgA0EYahDGGSADKAIYIg4gA0HUB2ogAygCHCIKKAIMEQAARQ0AQZDH5gAoAgAiBkEcaiEMIAYoAiAiDQRAIAYoAighDyAGKAIkIREgBigCHCEJIANBADYCuAggAyAPNgK0CCADIBE2ArAIIAMgDTYCrAgLIAMgCTYCqAggA0GACmoiBiADQagIaiIJQaDSwgAQqhQgAyAFLwEAQcgBa0H//wNxQeQASToA8AcgA0Hc0sIANgLsCSADQQM2AqwIIANBxNLCADYCqAggA0ICNwK0CCADQQE2AuwHIANB0wA2AuQHIAMgBTYC4AcgAyAJNgLoCSADIAY2AuQJIAMgA0HgB2o2ArAIIAMgA0HwB2o2AugHIANBgAhqIgUgDCADQeQJahD9HSADQfgJaiADQdwHaigCADYCACADIAMpAtQHNwPwCSALIA4gCiADQfAJaiAFEPcJCwJAAkBB2MrmACgCAA0AQZzH5gAQ7hpB/wFxIgZFDQBBACEFQZzH5gAoAgAgBhDVFUUNAEGcx+YAKAIAIgZBHGohCSAGKAIgIgsEQCAGKAIoIQ4gBigCJCEKIAYoAhwhBSADQQA2ArgIIAMgDjYCtAggAyAKNgKwCCADIAs2AqwICyADIAU2AqgIIANBgApqIgUgA0GoCGoiBkHs0sIAEKoUIANB3NLCADYC7AkgA0EBNgKsCCADQYjTwgA2AqgIIANCATcCtAggA0HUADYCxAcgAyAINgLAByADIAY2AugJIAMgBTYC5AkgAyADQcAHajYCsAggA0GACGogCSADQeQJahD9HSADQfgHaiADQYgIaigCADYCACADIAMpAoAINwPwB0Gcx+YAKAIAIANB8AdqIgUQ9xdB4NDmAC0AAA0BQdDQ5gAoAgBBBUkNASADQQU2AvAJIANBnMfmACgCACIGKQIUNwL0CSADQRBqEMYZIAMoAhAiCSADQfAJaiADKAIUIgsoAgwRAABFDQEgA0HoB2ogA0H4CWooAgA2AgAgAyADKQLwCTcD4AcgBiAJIAsgA0HgB2ogBRD3CQwBC0Hg0OYALQAADQBB0NDmACgCAEEFSQ0AIANBBTYCjAggA0Gcx+YAKAIAIgkpAhQ3ApAIIANBCGoQxhkgAygCCCILIANBjAhqIAMoAgwiDigCDBEAAEUNAEEAIQVBnMfmACgCACIGQRxqIQogBigCICIMBEAgBigCKCENIAYoAiQhDyAGKAIcIQUgA0EANgK4CCADIA02ArQIIAMgDzYCsAggAyAMNgKsCAsgAyAFNgKoCCADQYAKaiIFIANBqAhqIgZB7NLCABCqFCADQdzSwgA2AvgJIANBATYCrAggA0GI08IANgKoCCADQgE3ArQIIANB1AA2AoQIIAMgCDYCgAggAyAGNgL0CSADIAU2AvAJIAMgA0GACGo2ArAIIANB5AlqIgUgCiADQfAJahD9HSADQegHaiADQZQIaigCADYCACADIAMpAowINwPgByAJIAsgDiADQeAHaiAFEPcJCwJAIAEtAJoDDQAgA0GACmogBBDNBiADKAKACkEBRw0AIAMpA4gKUA0CCyABLwHsASIFQcgBa0H//wNxQeQASQ0CIAVBlANGDQQgAUEAOgCdAyABQaADaiAEQegA/AoAACABQQA6APwECyADQagIaiABQaADaiIFIAIQyAUgAygCqAhBgYCAgHhHDQVBBCECDAkLIANBiAlqIBBByAD8CgAAIAEvAZgDIQIgAUEAOgCcAyADQagIaiIFIAhBwAD8CgAAQcAAQQgQnxsiBiAFQcAA/AoAACADIAI7AdQJIAMgBjYC0AkgA0KBgICA4AE3A4AJDAYLIAFBADoAnQMgAUGgA2ogBEHoAPwKAAAgAUEAOgD8BAsgA0GoCGogAUGgA2oiBiACEJgFIAMoAqgIRQ0BQQMhAgwGCyADQYgJaiAQQcgA/AoAACADQoGAgICwATcDgAkMAwsgAykCtAghFiADKAKwCCECIAMoAqwIIQUgBhD8GSADQagIaiABQdACakHIAPwKAAAgAyABQZgDajYC9AggAyABQZACaiIGNgLwCCAFRQRAIAMpAqgIIRYgAykCsAghFyADQZgJaiABQeACakE4/AoAACADQYAKaiIFIAYQtglBwABBCBCfGyIGIAVBwAD8CgAAIAMgAjYC1AkgAyAGNgLQCSADIBc3A5AJIAMgFjcDiAkgA0KBgICAgAE3A4AJIAMgAS8BmAM7AdgJDAMLIANBuAhqEPMhIAMgFjcCoAggAyACNgKcCCADIAU2ApgIIANBgAlqIAYgA0GYCGoQkQIMAgsgA0GICmoiBiADQbAIaigCADYCACADIAMpAqgINwOACiAFEPwZIAFBkAJqIQIgAygCgApBgICAgHhHBEAgA0H4CGogBigCADYCACADIAMpA4AKNwLwCCADQagIaiIFIAFB0AJqQcgA/AoAACABLwGYAyEGIAFBADoAnAMgA0GACmoiCCACQcAA/AoAAEHAAEEIEJ8bIgIgCEHAAPwKAAAgA0GACWpBBHIgBUHUAPwKAAAgAyAGOwHcCSADIAI2AtgJIANBATYCgAkMAgsgA0GACmoQthMgA0GICWogAUHQAmpByAD8CgAAIAEvAZgDIQUgAUEAOgCcAyADQagIaiIGIAJBwAD8CgAAQcAAQQgQnxsiAiAGQcAA/AoAACADIAU7AdQJIAMgAjYC0AkgA0KBgICA0AE3A4AJDAELIANB5AZqIANBgAlqQQRyQdwA/AoAACAFEOkgDAELIAEtAJwDBEAgAUGQAmoQuRULIAFBADoAnAMgAS0AnQMEQCAEEI4QCyADKAKACSECIANBiAZqIgUgA0GACWpBBHJB3AD8CgAAIAdBAToAACACQQJGDQIgA0HkBmogBUHcAPwKAAAgBBCrFAsgAS0AogEEQCABQYABahCGBAsgAUEAOgCiASABQQE6AKEBIBIQ9hMMAwsgByACOgAAC0EECyEBIBQgAToAACAAQQI2AgBBBAwBCyAAIAI2AgAgAEEEaiADQeQGakHcAPwKAABBAQs6ABEgA0HACmokAAuwHAIBfxd+IwBBkAdrIgIkACACQcAEaiABKQMIIgNCACABKQMAIgRCABCWDiACQdAEaiABKQMQIglCACAEQgAQlg4gAkHgBGogASkDGCIKQgAgBEIAEJYOIAJB8ARqIAEpAyAiCEIAIARCABCWDiACQYAFaiABKQMoIgVCACAEQgAQlg4gAkGgBWogCUIAIANCABCWDiACQbAFaiAKQgAgA0IAEJYOIAJBwAVqIAhCACADQgAQlg4gAkHQBWogBUIAIANCABCWDiACQfAFaiAKQgAgCUIAEJYOIAJBgAZqIAhCACAJQgAQlg4gAkGQBmogBUIAIAlCABCWDiACQbAGaiAIQgAgCkIAEJYOIAJBwAZqIAVCACAKQgAQlg4gAkHgBmogBUIAIAhCABCWDiACQZAFaiAEQgAgBEIAEJYOIAJB4AVqIANCACADQgAQlg4gAkGgBmogCUIAIAlCABCWDiACQdAGaiAKQgAgCkIAEJYOIAJB8AZqIAhCACAIQgAQlg4gAkGAB2ogBUIAIAVCABCWDiACQbAEaiACKQOQBSIKQv3/8//P///5iX9+IgNCAEKr1f7///+//7l/QgAQlg4gAkGgBGogA0IAQv//z4rr///VHkIAEJYOIAJBkARqIANCAEKk7MO1j9S0mOcAQgAQlg4gAkGABGogA0IAQr+llJzP8NK75ABCABCWDiACQfADaiADQgBC19mumuT26Y3LAEIAEJYOIAJB4ANqIANCAEKazf/Lo73EgBpCABCWDiACQdADaiACKQOYBSIGIAIpA8AEIgVCAYZ8IgQgAikDoAR8IgkgAikDuAQgAikDsAQiAyAKQn2DfCADVK18fCIKQv3/8//P///5iX9+IgNCAEKr1f7///+//7l/QgAQlg4gAkHAA2ogA0IAQv//z4rr///VHkIAEJYOIAJB0AJqIANCAEKk7MO1j9S0mOcAQgAQlg4gAkHgAWogA0IAQr+llJzP8NK75ABCABCWDiACQfAAaiADQgBC19mumuT26Y3LAEIAEJYOIAIgA0IAQprN/8ujvcSAGkIAEJYOIAJBsANqIAIpA8ADIgwgAikD4AUiCyACKQPQBCINIAIpA8gEfCIIQgGGIAVCP4iEfCIFIAQgBlStfCIGIAIpA5AEfCIHIAkgClatIAIpA6gEIAQgCVatfHx8Ig58IgQgAikD2AMgAikD0AMiAyAKfCADVK18fCIJQv3/8//P///5iX9+IgNCAEKr1f7///+//7l/QgAQlg4gAkGgA2ogA0IAQv//z4rr///VHkIAEJYOIAJBkANqIANCAEKk7MO1j9S0mOcAQgAQlg4gAkGAA2ogA0IAQr+llJzP8NK75ABCABCWDiACQfACaiADQgBC19mumuT26Y3LAEIAEJYOIAJB4AJqIANCAEKazf/Lo73EgBpCABCWDiACQcACaiACKQOgAyIPIAUgBlatIAIpA+gFIAUgC1StfHwiECACKQPYBCAIIA1UrXwiDSACKQPgBHwiCiACKQOgBXwiBUIBhiAIQj+IhHwiCCACKQOABHwiCyAHIA5WrSACKQOYBCAGIAdWrXx8fCIGIAIpA9ACfCIHIAQgCVatIAIpA8gDIAQgDFStfHx8Igx8IgQgAikDuAMgAikDsAMiAyAJfCADVK18fCIJQv3/8//P///5iX9+IgNCAEKr1f7///+//7l/QgAQlg4gAkGwAmogA0IAQv//z4rr///VHkIAEJYOIAJBoAJqIANCAEKk7MO1j9S0mOcAQgAQlg4gAkGQAmogA0IAQr+llJzP8NK75ABCABCWDiACQYACaiADQgBC19mumuT26Y3LAEIAEJYOIAJB8AFqIANCAEKazf/Lo73EgBpCABCWDiACQdABaiACKQOwAiITIAcgDFatIAIpA9gCIAYgB1atfHwiDiACKQPgAXwiByAGIAtUrSACKQOIBCAIIAtWrXx8IhQgAikD8AN8IgYgCCAQVK0iECACKQOgBnwiCCACKQPoBCAKIA1UrXwiESACKQPwBHwiCyACKQOwBXwiDCACKQOoBSAFIApUrXx8IgpCAYYgBUI/iIR8IhJ8IhV8IgUgAikDkAN8Ig0gBCAJVq0gAikDqAMgBCAPVK18fHwiF3wiBCACKQPIAiACKQPAAiIDIAl8IANUrXx8IglC/f/z/8////mJf34iA0IAQqvV/v///7//uX9CABCWDiACQcABaiADQgBC///Piuv//9UeQgAQlg4gAkGwAWogA0IAQqTsw7WP1LSY5wBCABCWDiACQaABaiADQgBCv6WUnM/w0rvkAEIAEJYOIAJBkAFqIANCAELX2a6a5PbpjcsAQgAQlg4gAkGAAWogA0IAQprN/8ujvcSAGkIAEJYOIAJB4ABqIAIpA8ABIhYgBSAHVK0gAikD6AEgByAOVK18fCIYIAIpA3B8IgcgBiAVVq0gAikD+AMgBiAUVK18fCIUIAIpA+ADfCIGIAggElatIAIpA6gGIAggEFStfHwiECACKQP4BCALIBFUrXwiESACKQOABXwiCCACKQPABXwiDiAKIAxUrSACKQO4BSALIAxWrXx8fCILIAIpA/AFfCIMQgGGIApCP4iEfCISfCIVfCIKIAIpA4ADfCIPIA0gF1atIAIpA5gDIAUgDVatfHx8IgUgAikDoAJ8Ig0gBCAJVq0gAikDuAIgBCATVK18fHwiF3wiBCACKQPYASACKQPQASIDIAl8IANUrXx8IglC/f/z/8////mJf34iA0IAQqvV/v///7//uX9CABCWDiACQdAAaiADQgBC///Piuv//9UeQgAQlg4gAkFAayADQgBCpOzDtY/UtJjnAEIAEJYOIAJBMGogA0IAQr+llJzP8NK75ABCABCWDiACQSBqIANCAELX2a6a5PbpjcsAQgAQlg4gAkEQaiADQgBCms3/y6O9xIAaQgAQlg4gACACKQNQIhkgECASVq0iEiACKQPQBnwiAyACKQOIBSAIIBFUrXwiESACKQPQBXwiECALIA5UrSACKQPIBSAIIA5WrXx8fCIIIAIpA4AGfCIOIAIpA/gFIAsgDFatfHwiC0IBhiAMQj+IhHwiDCAGIBVWrSACKQPoAyAGIBRUrXx8fCIGIAIpAwB8IhMgByAKVq0gAikDeCAHIBhUrXx8fCIHIAIpA/ACfCIUIAUgD1StIAIpA4gDIAogD1atfHx8IgogAikDkAJ8Ig8gDSAXVq0gAikDqAIgBSANVq18fHwiBSACKQOwAXwiDSAEIAlWrSACKQPIASAEIBZUrXx8fCIVfCIEIAIpA2ggCSACKQNgIgl8IAlUrXx8IglC1aqBgICAwIDGAHwiFyAJVK1CAX0iFiAWIAMgDFatIAIpA9gGIAMgElStfHwiEiAIIBBUrSACKQPYBSAQIBFUrXx8IhEgAikDkAZ8IgMgCyAOVK0gAikDiAYgCCAOVq18fHwiCCACKQOwBnwiDkIBhiALQj+IhHwiCyAGIAxUrXwiDCAHIBNUrSACKQMIIAYgE1atfHx8IgYgAikD4AJ8IhAgCiAUVK0gAikD+AIgByAUVq18fHwiByACKQOAAnwiEyAFIA9UrSACKQOYAiAKIA9WrXx8fCIPIAIpA6ABfCIUIA0gFVatIAIpA7gBIAUgDVatfHx8IgUgAikDQHwiDSAEIAlWrSACKQNYIAQgGVStfHx8Igp8IgQgClStfCAEQv//z4rr///VHn0iFSAEVK18QgF9Qj+HIhYgFiALIAxWrSAGIAxUrXwiGCACKQPwBiIZIAMgCFatIAIpA5gGIAMgEVStfHwiESACKQPABnwiAyACKQO4BiAIIA5WrXx8IgRCAYYgDkI/iIR8IgwgCyASVK18IhJ8IgsgByAQVK0gAikD6AIgBiAQVq18fHwiBiACKQPwAXwiDiAPIBNUrSACKQOIAiAHIBNWrXx8fCIHIAIpA5ABfCIQIAUgFFStIAIpA6gBIA8gFFatfHx8Ig8gAikDMHwiEyAKIA1UrSACKQNIIAUgDVatfHx8Igh8IgUgCFStfCAFQqTsw7WP1LSY5wB9IhQgBVStfEIBfUI/hyINIA0gCyAYVK0gBiALVK18IhYgDCASVq0gAikD+AYgDCAZVK18fCISIAMgBFatIAIpA8gGIAMgEVStfHwiESACKQPgBnwiA0IBhiAEQj+IhHwiGHwiBCAHIA5UrSACKQP4ASAGIA5WrXx8fCIGIAIpA4ABfCILIA8gEFStIAIpA5gBIAcgEFatfHx8IgcgAikDIHwiDCAIIBNUrSACKQM4IA8gE1atfHx8IgV8Ig0gBVStfCANQr+llJzP8NK75AB9Ig4gDVStfEIBfUI/hyIPIA8gBCAWVK0gBCAGVq18IhAgAikDgAciEyACKQPoBiADIBFUrXwiEUIBhiADQj+IhHwiAyASIBhWrXwiEnwiBCAHIAtUrSACKQOIASAGIAtWrXx8fCILIAIpAxB8Ig0gBSAMVK0gAikDKCAHIAxWrXx8fCIGfCIHIAZUrXwgB0LX2a6a5PbpjcsAfSIMIAdUrXxCAX1CP4ciDyAPIAQgEFStIAQgC1atfCADIBJWrSACKQOIByADIBNUrXx8IBFCP4h8fCAGIA1UrSACKQMYIAsgDVatfHx8Igd8IgMgB1StfCADQprN/8ujvcSAGn0iCyADVK18QgF9IgNCf4UiBCALgyADIAeDhDcDKCAAIAQgDIMgAyAGg4Q3AyAgACAEIA6DIAMgBYOENwMYIAAgBCAUgyADIAiDhDcDECAAIAQgFYMgAyAKg4Q3AwggACAEIBeDIAMgCYOENwMAIAJBkAdqJAALsWcCHH8EfiMAQfAFayIDJAACQCABAn8CQAJAAkACQAJAAkACfwJAAkACQAJAAkACQAJAAkACQAJAAn8CQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIAEtAOgEQQFrDgQJCwEKAAsgAUG0AmoiEiABQbQC/AoAACABQQA6ALwFIAEgEjYC8AQgAUG8BWohHiABQfAEaiEbDAELIAFB8ARqIRsgAUG8BWohHgJAIAEtALwFQQFrDgYECgIFBgcACyAbKAIAIRILIAEgEjYC9AQgAUH4BGohBSMAQRBrIggkAAJAIBItAJECRQRAIAVBgICAgHg2AgAMAQsgCEEEakEQQdSUxAAQqAsgEigCyAEgCCgCCCAIQQxqIgQoAgAQjA8gBUEIaiAEKAIANgIAIAUgCCkCBDcCAAsgCEEQaiQAIAEoAvQEIQQCfyABKAL4BEGAgICAeEcEQCADIAUQrw4gASgC9AQMAQsgA0GAgICAeDYCACAECyERIANB3AJqIAQoAswBQcAB/AoAACADQbQEaiAEQYgCaikCADcCACADQawEaiAEQYACaikCADcCACADQaQEaiAEQfgBaikCADcCACADQdgCaiADQQhqKAIANgIAIAMgBCkC8AE3ApwEIAMgAykCADcD0AIgAUHABWoiEiADQdACakHsAfwKAAAgAUEAOgDMByABIBE2AqwHIAFBzAdqIQoMAQsgAUHABWohEiABQcwHaiEKAkAgAS0AzAdBAWsOAwwIEgALIAEoAqwHIRELIAMgEkHsAfwKAABB0NDmACgCAEEESw0JDA8LQeyFxAAQtRcACyABQcAFaiESIAFB7AVqIQoCQCABLQDsBUEBaw4DCgURAAsgASgC6AUhEQwPCyABQcAFaiESIAFB+AVqIQoCQCABLQD4BUEBaw4DCgQWAAsgASgC2AUhEQwQCyABQcAFaiESIAFB7AVqIQoCQCABLQDsBUEBaw4DCgMXAAsgASgC6AUhEQwVC0H8hcQAELUXAAsgAUHsBGohEiABQcQFaiEeAkACQCABLQDEBUEBaw4DBAIBAAsgASgC+AQhGwweCyABQZQFaiERIAFBwAVqIQogAS0AwAVBAWsOAwgAHwELAAsgASgCoAUhGwwcC0HchcQAELUXAAsgA0EBNgKUBSADQcCExAA2ApAFIANCATcCnAUgA0EFNgK8BSADQccANgLEBSADQcWHxAA2AsAFIAMgA0G4BWo2ApgFIAMgA0HABWo2ArgFIANByITEADYC2AUgA0E0NgLUBSADQdiExAA2AtAFIANBNDYCzAUgA0HYhMQANgLIBSADQZAFakEFIANByAVqEMMKDAULQZyFxAAQtRcAC0HMhcQAELUXAAtBnIXEABC1FwALQcyFxAAQtRcAC0G8hcQAELUXAAsgA0HgBWohFCMAQYACayIPJAAgD0FAayIEIANBDGpBwAH8CgAAIA9BIGogBBCnFSAPQdgAaiADQeQBaikAADcDACAPQdAAaiADQdwBaikAADcDACAPQcgAaiADQdQBaikAADcDACAPIAMpAMwBNwNAIA8gBBCnFQJAIAMoAgAiCEGAgICAeEcEQCADKAIIIQUgAygCBCEHIA9B5ABqIA9BOGopAgA3AgAgD0HcAGogD0EwaikCADcCACAPQdQAaiAPQShqKQIANwIAIA9BgAFqIA9BCGopAgA3AgAgD0GIAWogD0EQaikCADcCACAPQZABaiAPQRhqKQIANwIAIA8gDykCIDcCTCAPIA8pAgA3AnggDyAFIAdqNgKkASAPIAg2AqABIA8gBzYCnAEgDyAHNgKYASAPQSA2AnQgD0IBNwJsIA9BIDYCSCAPQgE3AkAjAEEwayIWJAAgBCgCWCEIAkACQAJAAkACQAJAAkAgBCgCACIFQQJHBEAgBCgCLCEHIAhFDQRBASEQIAVBAXFFDQEgB0UNAiAEKAIIIAQoAgRrIgUgBCgCNCAEKAIwa2oiCSAFTyEQDAMLIAhFDQUgBCgCZCAEKAJcayEQDAYLIAdFDQEgBCgCNCAEKAIwayEJDAELIAQoAgggBCgCBGshCQsgEEUNASAEKAJkIAQoAlxrIAlqIhAgCU8NAwwBCwJAIAVBAXEEQCAHDQEgBCgCCCAEKAIEayEQDAQLIAdFDQIgBCgCNCAEKAIwayEQDAMLIAQoAjQgBCgCMGsiBSAEKAIIIAQoAgRraiIQIAVPDQILIBZBADYCKCAWQQE2AhwgFkHg98cANgIYIBZCBDcCICAWQRhqQZD7xwAQ9xgACwsgFkEYaiAQQQBBAUEBEKILIBYoAhwhBQJAIBYoAhhBAUcEQCAWQRRqIghBADYCACAWIBYoAiA2AhAgFiAFNgIMIBZBDGohCyMAQSBrIgwkACAEKAJYIQcCQAJAAkACQAJAAkACQCAEKAIAIgVBAkcEQCAEKAIsIQYgB0UNBEEBIQkgBUEBcUUNASAGRQ0CIAQoAgggBCgCBGsiBSAEKAI0IAQoAjBraiIHIAVPIQkMAwsgB0UNBSAEKAJkIAQoAlxrIQkMBgtBACEHIAZFDQEgBCgCNCAEKAIwayEHDAELIAQoAgggBCgCBGshBwsgCUUNASAEKAJkIAQoAlxrIAdqIgkgB08NAwwBCwJAIAVBAXEEQCAGDQEgBCgCCCAEKAIEayEJDAQLIAZFDQIgBCgCNCAEKAIwayEJDAMLIAQoAjQgBCgCMGsiBSAEKAIIIAQoAgRraiIJIAVPDQILIAxBADYCGCAMQQE2AgwgDEHg98cANgIIIAxCBDcCECAMQQhqQZD7xwAQ9xgAC0EAIQkLIAsgCRCqGiAMIAspAgRCIIk3AgwgDCALQQhqNgIIIAxBCGohDSMAQRBrIgskACAEKAIAQQJHBEAjAEHQAGsiCSQAIAQoAgBBAUYEQCAJIARBBGpBKPwKAAAgCSgCACIQIAkoAgQiB0cEfyANKAIIIQUgDSgCBCEGA0AgBSAGaiAJIBBqQQhqLQAAOgAAIAZBAWohBiAHIBBBAWoiEEcNAAsgDSAGNgIEIAkgBzYCAEEABSAQCxoLIAQoAixBAUYEQCAJQShqIARBMGpBKPwKAAAgCSgCKCIQIAkoAiwiB0cEfyANKAIIIQUgDSgCBCEGA0AgBSAGaiAJIBBqQTBqLQAAOgAAIAZBAWohBiAHIBBBAWoiEEcNAAsgDSAGNgIEIAkgBzYCKEEABSAQCxoLIAlB0ABqJAALAkAgBCgCWARAIAtBCGogBEHYAGoiBEEIaikCADcDACALIAQpAgA3AwAgCyANEMkPDAELIA0oAgAgDSgCBDYCAAsgC0EQaiQAIAxBIGokACAUQQhqIAgoAgA2AgAgFCAWKQIMNwIAIBZBMGokAAwBCyAFIBYoAiBBkPvHABD2GwALDAELIA9B1ABqIA9BKGopAgA3AgAgD0HcAGogD0EwaikCADcCACAPQeQAaiAPQThqKQIANwIAIA9BgAFqIA9BCGopAgA3AgAgD0GIAWogD0EQaikCADcCACAPQZABaiAPQRhqKQIANwIAIA9BIDYCSCAPQgE3AkAgDyAPKQIgNwJMIA9BIDYCdCAPQgE3AmwgDyAPKQIANwJ4IBQgD0FAa0GQ+8cAEPoHCyAPQYACaiQAIANBAToA7AUgA0EDIBEtAJACQQFqIBEtAJECGzoA7QUgESgCxAEhBSADQZAFaiAUEJ0JIAMoApAFQYCAgIB4Rg0FIANB0AVqIANBmAVqKAIAIgQ2AgAgAyADKQKQBSIfNwPIBSABQYCAgIB4NgKwByABIB83ArQHIAFBvAdqIAQ2AgAgASAFNgLIBwsgA0GQBWogAUGwB2oiBSACEKUJIAMoApAFIgRBkICAgHhGDQMgA0HQBGogA0GkBWooAgA2AgAgA0HIBGogA0GcBWopAgA3AwAgAyADKQKUBTcDwAQgBSgCAEGFgICAeEcEQCAFEMcPCyAEQY+AgIB4RwRAIANBnAVqIANByARqKQMANwIAIANBpAVqIANB0ARqKAIANgIAIAMgBDYCkAUgAyADKQPABDcClAUgA0GQBWoQqBAgCkEBOgAAIBIQhRlBhYCAgHgMCwsgAUEBOgDMByASEIUZIAFBADoA7AUgASABKAL0BCIRNgLoBSABQcAFaiESIAFB7AVqIQoLIANBADoA1AUgAyARNgLIBSADQZAFaiIEIANByAVqELwSIBIgBEEo/AoAAAsgA0HIBWogEiACEMwGAkACQCADKALIBSIEQQNGBEAgCkEDOgAADAELIAMpAtAFIR8gAygCzAUhESASEPQWAkACQCAEQQJGBEBBi4CAgHghEQwBCyAEQQFxRQ0BCyAKQQE6AAAMEAsgAyARNgLgBSADIB83AuQFIB+nIQsjAEHgAGsiDCQAAkAgH0IgiKciBEH8AEcgBEHgAEdxRQRAIAxBLGoiFCALQSAQ1A8gDC0ALEEBRwRAIAxBIGoiByAMQcUAaikAADcDACAMQRhqIgggDEE9aikAADcDACAMQRBqIgUgDEE1aikAADcDACAMIAwpAC03AwggC0EgaiEGQgAhHyMAQRBrIg0kAAJAAkACQAJAAkAgBEEgayIEQcAARwRAIARB3ABGDQEgFEKAgICA+ICAgIB/NwIADAMLIA1BBGpBwABBAEEBQQEQogsgDSgCCCESIA0oAgRBAUYNA0HAACEJIA0oAgwiECAGQcAA/AoAAEGAgICAeCELDAELIA1BBGoiBEHQAEEAQQFBARCiCyANKAIIIRIgDSgCBEEBRg0CIA0oAgwiECAGQdAA/AoAACAEQQxBAEEBQQEQogsgDSgCCCELIA0oAgRBAUcEQCANKAIMIgRBCGogBkHYAGooAAA2AAAgBCAGKQBQNwAAIAStQoCAgIDAAYQhH0HQACEJDAELIAsgDSgCDEGo/ccAEPYbAAsgFCAfNwIQIBQgCzYCDCAUIAk2AgggFCAQNgIEIBQgEjYCAAsgDUEQaiQADAELIBIgDSgCDEGo/ccAEPYbAAsgDEHYAGoiCyAMQThqKAIANgIAIAwgDCkCMDcDUCAMKAIsIgRBgICAgHhGBEAgAyAMKQNQNwIEIANBgICAgHg2AgAgA0EMaiALKAIANgIADAMLIAwpAjwhICADIAwpA1A3AgQgA0EMaiALKAIANgIAIANBMGogBykDADcAACADQShqIAgpAwA3AAAgA0EgaiAFKQMANwAAIAMgDCkDCDcAGCADICA3AhAgAyAENgIADAILIAxB2ABqIAxBOGopAgA3AwAgDCAMKQIwNwNQQaD7xwBBKyAMQdAAakHM+8cAQZD6xwAQqQ4ACyADQoCAgID4gICAgH83AgALIAxB4ABqJAAgA0HgBWoQ8yEgAygCACEFIAMoAgQhESADKQIIIR8gA0HABGogA0EQakEo/AoAACAKQQE6AAAgBUGBgICAeEcNAQtBBCESDAwLIANB6ARqIgQgA0HABGpBKPwKAAAgBUGAgICAeEYNDSABIB83AowFIAEgETYCiAUgASAFNgKEBSABQZQFaiAEQSj8CgAAIAEoAvQEIQsgASgC/ARBACABKAL4BEGAgICAeEcbIQcgASgCgAUhCCMAQZABayIGJAAgBkEIaiIFIAtB0AFqIAFBnAVqIhwQpBEgBkHcAGoiBCAHIAggBUEgQSAQ8gkCQAJAAkAgBigCXEGAgICAeEcEQCAGQTBqIAZB5ABqKAIANgIAIAYgBikCXDcDKAJAIAstAJECRQRAIAQgBigCLCAGKAIwELcIQQEhCiAGLQBcQQFGDQMgBkHQAGogBkH1AGopAAA3AwAgBkHIAGogBkHtAGopAAA3AwAgBkFAayAGQeUAaikAADcDACAGIAYpAF03AzgMAQsgBkHcAGogBigCLCAGKAIwEJsLIAYtAFxBAUYNAyAGQdAAaiAGQfUAaikAADcDACAGQcgAaiAGQe0AaikAADcDACAGQUBrIAZB5QBqKQAANwMAIAYgBikAXTcDOEEAIQoLAkAgCy0AkgJBAkYNACALQZICahDnGCALQZMCaiEEIAstAJICRQRAIAQQoxgMAQsgBBDBHwsgCyAKOgCSAiALIAYpAzg3AJMCIAtBmwJqIAZBQGspAwA3AAAgC0GjAmogBkHIAGopAwA3AAAgC0GrAmogBkHQAGopAwA3AAAgBkEoahDzISAGQZABaiQADAMLQfySxABBISAGQYABakGwl8QAQaCTxAAQqQ4ACyAGQYgBaiAGQegAaigCADYCACAGIAYpAmA3A4ABQbCTxABBJSAGQYABakGgl8QAQdiTxAAQqQ4ACyAGQYgBaiAGQegAaigCADYCACAGIAYpAmA3A4ABQbCTxABBJSAGQYABakGgl8QAQeiTxAAQqQ4ACyABKAL0BCENIAFBhAVqIQcjAEGQAmsiDiQAAkACQAJAIA0tAJICQQJHBEAgDS0AkQJBAUYgBygCDCIEQYCAgIB4RnENASAOQbgBaiEIIAcoAgQhFCAHKAIIIQUgBygCEEEAIARBgICAgHhHGyEEIAcoAhQhCyMAQSBrIgwkAAJAAkAgDUGSAmoiBy0AAEEBRgRAAkAgBARAIAtBEEYNASALDQMLQQAhBAsgB0EBaiELIwBBoAZrIgkkACAJQQhqELgeIAlBGGogBUEAQQFBARCiCyAJKAIcIQYCQCAJKAIYQQFHBEAgCSgCICEQIAUEQCAQIBQgBfwKAAALIAlBqANqIgcgCxCaAyAJQRhqIgsQ4R4gCUGQBmogBCAJQQhqIAQbIgQpAAgiIEI4hiAgQoD+A4NCKIaEICBCgID8B4NCGIYgIEKAgID4D4NCCIaEhCAgQgiIQoCAgPgPgyAgQhiIQoCA/AeDhCAgQiiIQoD+A4MgIEI4iISEhDcDACAJIAQpAAA3A4gGIAlCADcDmAYgCxC4HiAJQShqIAdB+AL8CgAAIAlBADoAoAMgCyAQIAUQswYgCxCcFiAIIAU2AgggCCAQNgIEIAggBjYCACAJQaAGaiQADAELIAYgCSgCIEHc9scAEPYbAAsMAgsgDEETaiAEIAsQ/wwgDC0AFCEEIAwtABNBAUYEQCAIQYCAgIB4NgIAIAggBDoABAwCCyAMQQ9qIAxBHGooAAA2AAAgDCAMKQAVNwAIIAwgBDoAByAIIAdBAWogFCAFIAxBB2oQug8MAQsgCEGAgICAeDYCACAIQQI6AAQLIAxBIGokACAOLQC8ASEIIA4oArgBIgVBgICAgHhGBEAgAyAIOgAEIANBgoCAgHg2AgAMBAsgDkEUaiIEIA5BwAFqKAAANgAAIA4gDigAvQE2ABEgDiAIOgAQIA4gBTYCDCAOKAIQIQggDkG4AWoiBQJ/IAQoAgBBwABHBEAgBUEBNgIEQQEMAQsgBUEBaiIEIAgpAAA3AAAgBCAIKQAgNwAgIARBGGogCEEYaikAADcAACAEQRBqIAhBEGopAAA3AAAgBEEIaiAIQQhqKQAANwAAIARBKGogCEEoaikAADcAACAEQTBqIAhBMGopAAA3AAAgBEE4aiAIQThqKQAANwAAQQALOgAAIA4tALgBQQFGBEAgDkHgAGogDkHEAWopAgA3AwAgDiAOKQK8ASIgNwNYAkAgIKcNACAOKAJcRQ0AIA5B2ABqQQRyEP4VCyADQYOAgIB4NgIAIA5BDGoQ8yEMBAsgDkEaaiAOLQC7AToAACAOIA4vALkBOwEYIA4oArwBIQQgDikCwAEhICAOQdgAaiIPIA5ByAFqQTH8CgAAIA4gIDcAHyAOIAQ2ABsgDkEnaiAPQTH8CgAAIA5B8ABqIgggHEEYaikAADcDACAOQegAaiIFIBxBEGopAAA3AwAgDkHgAGoiBCAcQQhqKQAANwMAIA4gHCkAADcDWCAOQcQBaiAPEKcVIAggDUGIAmopAAA3AwAgBSANQYACaikAADcDACAEIA1B+AFqKQAANwMAIA4gDSkA8AE3A1ggDkGYAWogDxCnFSAOQfgBaiAOQaABaikCADcCACAOQYACaiAOQagBaikCADcCACAOQYgCaiAOQbABaikCADcCACAOQSA2AuwBIA5CATcC5AEgDkEgNgLAASAOQgE3ArgBIA4gDikCmAE3AvABIA5BjAFqIhYgDkG4AWoiERDkISANKAIARQ0CIA1BBGohCCMAQRBrIhIkACASQQhqIBYQqSEgEigCCCEFIBIoAgwhBCMAQdABayIXJAAgF0HMAGohCUEAIQ0jAEHQAWsiCiQAIApBCGogDkEYahCbDSAKQaABaiAKQUBrKQAANwMAIApBmAFqIApBOGopAAA3AwBBCCEQIApBkAFqIApBMGopAAA3AwAgCiAKKQAoNwOIASMAQSBrIhQkACAKQYgBaiIMLAAfQQBOELkeIQsgFCAMEOUBQQEhBgNAIA0gFGotAAAgDCANai0AAHMiB0EAIAdrcsBBAE4QuR4gBnEhBiANQQFqIg1BIEcNAAsgCkGvAWoiByAGELkeIAtxELkeOgAgIAdBGGogDEEYaikAADcAACAHQRBqIAxBEGopAAA3AAAgB0EIaiAMQQhqKQAANwAAIAcgDCkAADcAACAUQSBqJABBASEHAn8gCi0AzwFBAUcEQCAKQQE2AkggCiAKQcgAahCZFSAKKAIAIRRBoNLhACEGQQQMAQsgCkHqAGogCkGxAWotAAA6AAAgCkH9AGoiCyAKQccBaikAADcAACAKQfgAaiIHIApBwgFqKQAANwMAIAogCi8ArwE7AWggCiAKKQC6ASIgNwNwIAooALIBIRQgCigAtgEhBiAJQTlqIAspAAA3AAAgCUE0aiAHKQMANwIAIAkgIDcCLCAKQeAAaiAKQSBqKQAANwMAIApB2ABqIApBGGopAAA3AwAgCkHQAGogCkEQaikAADcDACAKIAopAAg3A0ggCUEBaiAKQcgAakEj/AoAAEEAIQdBKCEQQSQLIAlqIBQ2AgAgCSAQaiAGNgIAIAkgBzoAACAKQdABaiQAAkAgFy0ATEEBRgRAIBcpAlAhICARQQE2AgAgESAgNwIEDAELIBdBkgFqIBctAE86AAAgFyAXLwBNOwGQASAXKQJQISAgF0EUaiIJIBdB2ABqQTX8CgAAIBcgIDcAkwEgF0GbAWogCUE1/AoAACAXQcwAaiEMIwBB4AprIhMkACATQeADaiINQQBBwAD8CwAgE0H4B2oiECAXQZABaiIUQRhqKQAANwMAIBNB8AdqIgYgFEEQaikAADcDACATQdAJaiILIAhBEGopAgA3AwAgE0HYCWoiByAIQRhqKQIANwMAIBMgFEEIaikAADcD6AcgEyAUKQAANwPgByATIAgpAgA3A8AJIBMgCEEIaikCADcDyAkgE0GAAmoiCkGA1+EAQcAA/AoAACATQdgCaiATKQPoBzcDACATQeACaiAGKQMANwMAIBNB6AJqIBApAwA3AwAgE0H4AmogEykDyAk3AwAgE0GAA2ogCykDADcDACATQYgDaiAHKQMANwMAIBNCADcDyAIgE0IANwPAAiATIBMpA+AHNwPQAiATIBMpA8AJNwPwAiATQZADaiANQcAA/AoAACATQcAAOgDQAyATIAhBwAH8CgAAIBNBwAFqIBRBwAD8CgAAIBNB0AJqIQsCQAJAAkACQEGAASATLQDQAyIHayIIIARNBEAgBwRAIAgEQCAHIAtqIAUgCPwKAAALIBMpA8ACIiAgEykDyAIiH4NCf1ENAyATICBCAXwiIDcDwAIgEyAfICBQrXw3A8gCIAogC0EBENMjIAUgCGohBSAEIAhrIQQLIARBgAFPBEAgEykDwAIiISAEQQd2IgetfCIiICFUIgggEykDyAIiHyAIrXwiICAfVCAhICJYG0EBRg0EIBMgIjcDwAIgEyAgNwPIAiAKIAUgBxDTIwsgBEH/AHEiCEUNASALIAUgBEGAf3FqIAj8CgAADAELIAQEQCAHIAtqIAUgBPwKAAALIAQgB2ohCAsgEyAIOgDQAyATQeADaiATQeAD/AoAACATQeAHaiIZIApB4AH8CgAAIBNBwAdqIgQgGRDmAyAZIBNBgARqQaAB/AoAACMAQdAAayIIJAAgCCAZQSj8CgAAIAgQjgYgE0HACWoiByAIQSj8CgAAIAdBKGogGUEoakEo/AoAACAHQdAAaiAZQdAAakEo/AoAACAIQShqIgUgGUH4AGpBKPwKAAAgBRCOBiAHQfgAaiAFQSj8CgAAIAhB0ABqJABBACEGIwBBgBRrIhUkACAVQQhqIARBBRCpBiAVQYgCaiATQcAFakEIEKkGQf8BIQUDQCAFIgQgFUEIamotAAAgBEVyRQRAIARBAWshBSAVQYgCaiAEai0AAEUNAQsLIBVBiARqIwBBgA9rIhAkACAQQeANaiAHEIEMA0AgBiAQaiAQQeANaiIIQaAB/AoAACAGQaABaiIGQYAKRw0ACyAQQegMaiAHQShqQSj8CgAAIBBBkA1qIAdB0ABqQSj8CgAAIBBBwAxqIgUgB0Eo/AoAACAIIAUQpQcgEEGACmogCBCODEEAIQYDQCAQQeANaiIFIBBBgApqIAYgEGoiBxCwBSAQQcAMaiIIIAUQjgwgEEGgC2oiBSAIEIEMIAdBoAFqIAVBoAH8CgAAIAZBoAFqIgZB4AhHDQALIBBBgAr8CgAAIBBBgA9qJAAgFUGIDmpBAEEo/AsAIBVBsA5qQYjy4QBBKPwKAAAgFUHYDmpBiPLhAEEo/AoAAAJAAkACQAJAAkACQAJAA0AgFUGAD2ogFUGIDmoQpQcCQAJAAkAgFUEIaiAEaiwAACIGQQBKIAZBAEhrQf8BcQ4CAgABCyAGQQF2IQUgFUHAEWoiCyAVQYAPaiIHEI4MIAZBEE8NBCAVQeASaiIIIBVBiARqIAVBoAFsakGgAfwKAAAgFUGgEGoiBSALIAgQsAUgByAFQaAB/AoAAAwBCyAVQcARaiIKIBVBgA9qIggQjgwgBkGAf0YNBUEAIAZrIgXAQQF2IQcgBUH/AXFBEE8NBCAVQeASaiINIBVBiARqIAdBoAFsakGgAfwKAAAjAEGQA2siGCQAIBhBmAJqIgcgCkEoaiIFQSj8CgAAIAcgChDwEyAYIAdBKPwKAAAgByAFQSj8CgAAIAcgChDxAyAYQShqIgUgB0Eo/AoAACAYQdAAaiIQIBggDUEoahDmASAYQfgAaiIGIAUgDRDmASAYQaABaiILIApB+ABqIA1B+ABqEOYBIBhByAFqIgUgCkHQAGogDUHQAGoQ5gEgGEHwAWoiCiAFQSj8CgAAIAogBRDwEyAHIBBBKPwKAAAgByAGEPEDIBVBoBBqIg0gB0Eo/AoAACAYQcACaiIHIBBBKPwKAAAgByAGEPATIBhB6AJqIgUgCkEo/AoAACAFIAsQ8QMgCiALEPATIA1BKGogB0Eo/AoAACANQdAAaiAFQSj8CgAAIA1B+ABqIApBKPwKAAAgGEGQA2okACAIIA1BoAH8CgAACwJAAkACQAJAIBVBiAJqIARqLAAAIghBAEogCEEASGtB/wFxDgICAAELIAhBAXYhBSAVQeASaiILIBVBgA9qIgcQjgwgCEEASA0IIBVBoBBqIgggBUH4AGxB6PLhAGpB+AD8CgAAIBVBwBFqIgUgCyAIEMAFIAcgBUGgAfwKAAAMAQsgFUHgEmoiGCAVQYAPaiIHEI4MIAhBgH9GDQFBACAIa8BBAXYhBSAIQQBKDQggFUGgEGoiDSAFQfgAbEHo8uEAakH4APwKAAAjAEHwAmsiGiQAIBpB+AFqIh0gGEEoaiIFQSj8CgAAIB0gGBDwEyAaQQhqIgggHUEo/AoAACAdIAVBKPwKAAAgHSAYEPEDIBpBMGoiBSAdQSj8CgAAIBpB2ABqIhAgCCANQShqEOYBIBpBgAFqIgYgBSANEOYBIBpBqAFqIgsgGEH4AGogDUHQAGoQ5gEgGkHQAWoiCiAYQdAAaiIFQSj8CgAAIAogBRDwEyAdIBBBKPwKAAAgHSAGEPEDIBVBwBFqIg0gHUEo/AoAACAaQaACaiIIIBBBKPwKAAAgCCAGEPATIBpByAJqIgUgCkEo/AoAACAFIAsQ8QMgCiALEPATIA1BKGogCEEo/AoAACANQdAAaiAFQSj8CgAAIA1B+ABqIApBKPwKAAAgGkHwAmokACAHIA1BoAH8CgAACyAVQeASaiIFIBVBgA9qEK0PIBVBiA5qIAVB+AD8CgAAIARFDQIgBEEBayEEDAELC0H4ruIAELEXAAsjAEGAAWsiBiQAIBkgFUGIDmoiCyALQdAAaiIIEOYBIAZBCGoiBSALQShqIgQgCBDmASAGQTBqIgcgCBCKAiAZQdAAaiAHENMFIAcgCyAEEOYBIBlBKGogBUEo/AoAACAZQfgAaiAHQSj8CgAAIAZBgAFqJAAgFUGAFGokAAwFCyAFQQhB2J/kABCMEAALIAdBCEHYn+QAEIwQAAtB6K7iABCxFwALIAVBwABB6J/kABCMEAALIAVBwABB6J/kABCMEAALIAwgGRCPCiATQeAKaiQADAILQcTW4QAQrhcAC0HE1uEAEK4XAAsgESAMIBRBIBCaEwR/IBdBAzYCFCAXQQhqIAkQmRUgESAXKQMINwIEQQEFQQALNgIACyAXQdABaiQAIBYQ8yEgEkEQaiQAIAMgDigCuAFBAUYEfyAOKAK8ASEEIA4gDigCwAE2AlwgDiAENgJYIAQEQCAPEP4VC0GDgICAeAVBjICAgHgLNgIAIA5BDGoQ8yEMAwtBiJTEAEEbQbSUxAAQuREACyADQYGAgIB4NgIADAELQcSUxAAQ0iAACyAOQZACaiQAIAMoAgAiEUGMgICAeEcEQCADKQIEIR8MDQsgASgC9AQhDSMAQeABayIJJAAgCUHQAGoiCCANQYgCaikAADcDACAJQcgAaiIFIA1BgAJqKQAANwMAIAlBQGsiBCANQfgBaikAADcDACAJIA0pAPABNwM4IAlBlAFqIAlBOGoiFBCnFSAIIBxBGGopAAA3AwAgBSAcQRBqKQAANwMAIAQgHEEIaikAADcDACAJIBwpAAA3AzggCUEYaiAUEKcVIAlByAFqIAlBIGopAgA3AgAgCUHQAWogCUEoaikCADcCACAJQdgBaiAJQTBqKQIANwIAIAlBIDYCvAEgCUIBNwK0ASAJQSA2ApABIAlCATcCiAEgCSAJKQIYNwLAASAJQQxqIgYgCUGIAWoQ5CEgDSgCzAFBwAFqIRAjAEHQAmsiDCQAIAxBiAJqIBBBGGoiCCkAADcDACAMQYACaiAQQRBqIgUpAAA3AwAgDEH4AWogEEEIaiIEKQAANwMAIAwgECkAADcD8AEgDEGQAmoiCyAMQfABahCTAyAMQRBqIgcgCxCgFiALEIcgIAxB2AFqIAQpAAA3AgAgDEHgAWogBSkAADcCACAMQegBaiAIKQAANwIAIAwgECkAADcC0AEgDEEIaiAGEKkhIBQgByAMKAIIIAwoAgwQnhAgBxC5IyAGEPMhIAxB0AJqJAACQAJAAkACfyANLQCRAkUEQCAJQYCAgIB4NgJ4QQAMAQsgCRCfFjYChAEjAEEQayIIJAAgCEEEaiIEEN8eIAlBhAFqIgUgBEEMEI4fIAlBGGoiBEEIaiAIQQxqKAAANgAAIAQgCCkABDcAACAIQRBqJAAgCUGIAWpBDEEAQQFBARCiCyAJKAKMASEHIAkoAogBQQFGDQEgCSgCkAEiCCAJKQAYNwAAIAhBCGogCUEgaigAADYAACAJQQw2AoABIAkgCDYCfCAJIAc2AnggCSgChAEiBCAEKAIAQQFrIgQ2AgAgBEUEQCAFEM0YCyAIQQAgB0GAgICAeEcbCyEFIA0tAJICQQJGDQEgCUGIAWoiBCAJQThqEKIlIAlBGGogDUGSAmogBEHAACAFQQwQrgogCS0AHCEFAkAgCSgCGCIEQYCAgIB4RgRAIAMgBToACCADQYKAgIB4NgIEIAlB+ABqEJUcDAELIAMgCSgAHTYABSADQQhqIAlBIGooAAA2AAAgA0EUaiAJQYABaigCADYCACADIAkpAng3AgwgAyAFOgAECyADIAQ2AgAgCUHgAWokAAwCCyAHIAkoApABQZyYxAAQ9hsAC0GIlMQAQRtBpJTEABC5EQALIAMpAgghHyADKAIEIREgAygCACIEQYCAgIB4Rg0MIAMpAhAhICABQQA6APgFIAEgIDcD0AUgASAfNwPIBSABIBE2AsQFIAEgBDYCwAUgASABKAL0BCIRNgLYBSABQcAFaiESIAFB+AVqIQoLIANBoAVqIBJBEGopAgA3AwAgA0GYBWogEkEIaikCADcDACADIBIpAgA3A5AFQdDQ5gAoAgBBBEsNAgwDC0EDIRIgCkEDOgAADAkLIAMgAygClAU2AsAFDBgLIANBATYCBCADQcCExAA2AgAgA0IBNwIMIANBBTYCvAUgA0HJADYCxAUgA0H8hsQANgLABSADIANBuAVqNgIIIAMgA0HABWo2ArgFIANByITEADYC2AUgA0E0NgLUBSADQdiExAA2AtAFIANBNDYCzAUgA0HYhMQANgLIBSADQQUgA0HIBWoQwwoLIANB4AVqIQsjAEEgayIUJAACQAJAAkAgA0GQBWoiBigCDCIIQYCAgIB4RwRAIAYoAhQhBSAGKAIQIQcgFCAGKAIEIgQgBigCCGo2AhwgFCAENgIYIBQgBSAHajYCFCAUIAg2AhAgFCAHNgIMIBQgBzYCCCALIBRBCGpBkPvHABC/CAwBCyAGKAIEIQQgFEEIaiAGKAIIIgdBAEEBQQEQogsgFCgCDCEIIBQoAghBAUYNASAUKAIQIQUgBwRAIAUgBCAH/AoAAAsgCyAHNgIIIAsgBTYCBCALIAg2AgALIAYQ8yEgFEEgaiQADAELIAggFCgCEEGo/ccAEPYbAAsgA0EBOgDsBSADQQMgES0AkAJBAWogES0AkQIbOgDtBSARKALEASEFIAMgCxCdCSADKAIAQYCAgIB4Rg0EIANB0AVqIANBCGooAgAiBDYCACADIAMpAgAiHzcDyAUgAUGAgICAeDYC3AUgASAfNwLgBSABQegFaiAENgIAIAEgBTYC9AULIAMgAUHcBWoiBSACEKUJIAMoAgAiBEGQgICAeEYNBCADQdAEaiADQRRqKAIANgIAIANByARqIANBDGopAgA3AwAgAyADKQIENwPABCAFKAIAQYWAgIB4RwRAIAUQxw8LIARBj4CAgHhHBEAgA0EMaiADQcgEaikDADcCACADQRRqIANB0ARqKAIANgIAIAMgBDYCACADIAMpA8AENwIEIAMQqBAgCkEBOgAAIBIQtxZBhYCAgHghEQwHCyABQQE6APgFIBIQtxYgAUEAOgDsBSABIAEoAvQEIhE2AugFIAFBwAVqIRIgAUHsBWohCgsgA0EAOgCcBSADIBE2ApAFIAMgA0GQBWoQvBIgEiADQSj8CgAACyADQZAFaiASIAIQzAYgAygCkAUiBEEDRgRAIApBAzoAAEEGIRIMBAsgAykCmAUhHyADKAKUBSERIBIQ9BYCQCAEQQJGBEBBi4CAgHghEQwBCyAEQQFxDQAgAyARNgLIBSADIB83AswFIB+nIQUgA0HABGoiBCAfQiCIp0EBRgR/IAQgBS0AAEEBRjoABEGMgICAeAVBh4CAgHgLNgIAIANByAVqEPMhIAMpAsQEIR8gAygCwAQhEQsgCkEBOgAAQQYhEgJAIBFB9P///wdqDgIABAULIB+nQQFxRQRAQYmAgIB4IREMBQsgAUGEBWoQ8yEgAUGQBWoQlRxBjICAgHgLIREgAUH4BGoQlRwgAUEBOgC8BQwGCyADIAMoAgQ2AsAFDBELIApBAzoAAEEFIRILIB4gEjoAAAwCCyABQYQFahDzISABQZAFahCVHAsgAUH4BGoQlRwgAUEBOgC8BSARQY2AgIB4Rw0BCyAAQQI6AABBAwwLCyAbENEOIAFBADoAxAUgASABQbQCaiIbNgL4BCABIB83AvAEIAEgETYC7AQgAUHEBWohHiABQewEaiESCyABIBIpAgAiHzcC/AQgAUGEBWogEkEIaiIEKAIANgIAQYyAgIB4IB+nQYyAgIB4Rg0CGiABIBIpAgA3AogFIAFBkAVqIAQoAgA2AgAgA0EANgLYAiADQoCAgIAQNwLQAiADQYyGxAA2AgQgA0KggICADjcCCCADIANB0AJqNgIAIAFBiAVqIAMQkQYNBiADQcgEaiADQdgCaigCACIENgIAIAMgAykC0AIiIDcDwAQgAUGcBWogBDYCACABICA3ApQFIAFBADoAwAUgASAbNgKgBSABQcAFaiEKIAFBlAVqIRELIANBnAVqIBFBCGooAgA2AgAgAyARKQIANwKUBSADQYCAgIB4NgKQBSAbKALEASEFIAMgA0GQBWoQnQkgAygCAEGAgICAeEYNBiADQfAEaiADQQhqKAIAIgQ2AgAgAyADKQIAIh83A+gEIAFBgICAgHg2AqQFIAEgHzcCqAUgAUGwBWogBDYCACABIAU2ArwFCyADIAFBpAVqIgQgAhClCSADKAIAIgJBkICAgHhGDQIgA0HgAmogA0EUaigCADYCACADQdgCaiADQQxqKQIANwMAIAMgAykCBDcD0AIgBCgCAEGFgICAeEcEQCAEEMcPCyACQY+AgIB4Rg0BIANBDGogA0HYAmopAwA3AgAgA0EUaiADQeACaigCADYCACADIAI2AgAgAyADKQPQAjcCBCADEKgQIAFBAToAwAUgERCxGCABQYgFahCWHEGFgICAeAshESAeQQE6AAAMBQsgAUEBOgDABSARELEYIAFBAToAxAUgASgCiAUiEUGNgICAeEYNASABKQKMBSEfDAQLIApBAzoAACAeQQM6AAALIABBAjoAAEEEDAMLQbSGxABBNyADQZAFakGkhsQAQeyGxAAQqQ4ACyADIAMoAgQ2AsgFQZyIxABBKyADQcgFakGMiMQAQayFxAAQqQ4ACyASEIMXIAACfyARQYyAgIB4RwRAIAFBtAJqEP0TQQEMAQsgAyABQbQCakG0AvwKAAAgAy0AkgIiAUECRgRAQfiTxAAQ0iAACyADQdACaiICIAE6AAAgAiADKQCTAjcAASACQQlqIANBmwJqKQAANwAAIAJBEWogA0GjAmopAAA3AAAgAkEZaiADQasCaikAADcAACADQdABaiIBEKMYIAEQoxggARCjGCADQc4CaiADQdICai0AADoAACADQcACaiADQecCaikAADcDACADQcgCaiADQe8Cai8AADsBACADIAMvANACOwHMAiADIAMpAN8CNwO4AiADKADTAiERIAMpANcCIR9BAAs6AAAgACADLwHMAjsAASAAIB83AgggACARNgIEIAAgAykDuAI3AhAgAEEDaiADQc4Cai0AADoAACAA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IANBuwxqIAwoAgA2AAAgAyADKQPgAzcAswwgA0GkCmogB0HPAPwKAABBNCECDAsLIAAgCDoA3AMgACAFNgLYAyAAIAQ2AtQDIABB3QNqIANB8wNqQcMA/AoAACADQSBqIBUQjBcgAygCICEFIAAgAygCJDYCtAQgACAFNgKwBAsgA0HwC2ogAEGwBGoiByABELUeQQQgAygC8AsiCUECRg0BGiADLQCADCEIIAMoAvwLIQUgAygC+AshBCADKAL0CyEGIANBtgRqIgsgA0GBDGpBzwD8CgAAIAcQ/hUgCUEBcQRAIANBpApqIAtBzwD8CgAAQTQhAgwJCyAAIAg6AMgEIAAgBTYCxAQgACAENgLABCAAQckEaiADQbYEakE//AoAACAHQQhqIANB/QRqKAAANgAAIAcgAykA9QQ3AAAgA0EYaiAVEIsXIAMoAhghBSAAIAMoAhw2AowFIAAgBTYCiAULIANB8AtqIABBiAVqIgcgARC1HiADKALwCyIBQQJHDQFBBQshBiACIAY6AABBAiEBDAELIAMtAIAMIQggAygC/AshBSADKAL4CyEEIAMoAvQLIQYgA0GFBWoiAiADQYEMakHPAPwKAAAgBxD+FQJAAn8gAUEBcQRAIANBpApqIAJBzwD8CgAAQTQMAQsgA0GJC2ogA0GFBWpBzwD8CgAAIAMgCDoAiAsgAyAFNgKECyADIAQ2AoALIANBgAtqIgEgAEHABGoiBhDFCQ0BIANBzwI2AqwIIANBzwI2AqQIIAMgBjYCoAggAyABNgKoCCADQgI3AvwLIANBAjYC9AsgA0GMjcQANgLwCyADIANBoAhqNgL4CyADQaQKaiIBIANB8AtqEO4EIAMoAqgKIAMoAqwKENUkIAEQ8yEgA0HIC2oiBhCPGCAGEMAhQTgLIQIgAEGwBGoiARCPGCABEMAhDAYLIANB6AtqIgUgA0HMBWooAAA2AgAgAyADKQDEBTcD4AsgACgCnAQhASADQYQMaiAAQegDaigCADYCACADQZAMaiAAQfQDaigCADYCACADQZwMaiAAQYAEaigCADYCACADQagMaiAAQYwEaigCADYCACADQbQMaiAAQZgEaigCADYCACADIAApAuADNwL8CyADIAApAuwDNwOIDCADIAApAvgDNwKUDCADIAApAoQENwOgDCADIAApApAENwKs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ASgCBCABKAIIakEvOgAAIAEgBEEBajYCCCAMQQhqIQ1BACEEIAMgAyACIghqayELA0ACQCADIAQiAkYEQCADIQIMAQsCfyACIAhqIgQsAAAiB0EATgRAIAdB/wFxIQcgBEEBagwBCyAELQABQT9xIQkgB0EfcSEKIAdBX00EQCAKQQZ0IAlyIQcgBEECagwBCyAELQACQT9xIAlBBnRyIQkgB0FwSQRAIAkgCkEMdHIhByAEQQNqDAELIApBEnRBgIDwAHEgBC0AA0E/cSAJQQZ0cnIhByAEQQRqCyALaiEEIAdBL0YNAQsLIA0gAyACazYCBCANIAIgCGo2AgAgASAMKAIIIgEgASAMKAIMahDGEiAMQSRqEPMhCyAAIAY2AgQgACAFNgIAIAxBMGokAAupFwITfhF/IwAiFiAWQYAQa0FAcSIWJAAgFkGACGogAUGACPwKAAAgFkGACGoiASACEJoPIBYgAUGACPwKAAAgASAWQYAI/AoAAEEAIQIDQCAWQYAIaiACaiIBIAFBOGoiFykDACIFIAFBGGoiGCkDACIHfCAHQgGGQv7///8fgyAFQv////8Pg358IgcgAUH4AGoiGSkDAIVCIIkiBCABQdgAaiIaKQMAIgh8IARC/////w+DIAhCAYZC/v///x+DfnwiCCAFhUIoiSIFIAd8IAVC/////w+DIAdCAYZC/v///x+DfnwiByAEhUIwiSIEIAFBKGoiGykDACIDIAFBCGoiHCkDACIGfCAGQgGGQv7///8fgyADQv////8Pg358IgYgAUHoAGoiHSkDAIVCIIkiCyABQcgAaiIeKQMAIgx8IAtC/////w+DIAxCAYZC/v///x+DfnwiDCADhUIoiSIDIAZ8IANC/////w+DIAZCAYZC/v///x+DfnwiBiALhUIwiSILIAx8IAtC/////w+DIAxCAYZC/v///x+DfnwiDCADhUIBiSIDIAFBIGoiHykDACIPIAEpAwAiCnwgCkIBhkL+////H4MgD0L/////D4N+fCIKIAFB4ABqIiApAwCFQiCJIhAgAUFAayIhKQMAIhN8IBBC/////w+DIBNCAYZC/v///x+DfnwiEyAPhUIoiSIPIAp8IA9C/////w+DIApCAYZC/v///x+DfnwiCnwgA0L/////D4MgCkIBhkL+////H4N+fCIJhUIgiSIUIAFBMGoiIikDACIRIAFBEGoiIykDACINfCANQgGGQv7///8fgyARQv////8Pg358Ig0gAUHwAGoiJCkDAIVCIIkiEiABQdAAaiIBKQMAIg58IBJC/////w+DIA5CAYZC/v///x+DfnwiDiARhUIoiSIRIA18IBFC/////w+DIA1CAYZC/v///x+DfnwiDSAShUIwiSISIA58IBJC/////w+DIA5CAYZC/v///x+DfnwiDnwgFEL/////D4MgDkIBhkL+////H4N+fCIVIAOFQiiJIgMgCXwgA0L/////D4MgCUIBhkL+////H4N+fCIJNwMAIBkgCSAUhUIwiSIJNwMAIAEgCSAVfCAJQv////8PgyAVQgGGQv7///8fg358Igk3AwAgGyADIAmFQgGJNwMAICAgDiARhUIBiSIDIAZ8IANC/////w+DIAZCAYZC/v///x+DfnwiBiAKIBCFQjCJIgqFQiCJIhAgBCAIfCAEQv////8PgyAIQgGGQv7///8fg358IgR8IBBCAYZC/v///x+DIARC/////w+DfnwiCCADhUIoiSIDIAZ8IANC/////w+DIAZCAYZC/v///x+DfnwiCSAQhUIwiSIGNwMAIBwgCTcDACAaIAYgCHwgBkL/////D4MgCEIBhkL+////H4N+fCIINwMAICIgAyAIhUIBiTcDACAdIAQgBYVCAYkiBSANfCAFQv////8PgyANQgGGQv7///8fg358IgQgC4VCIIkiCCAKIBN8IApC/////w+DIBNCAYZC/v///x+DfnwiA3wgCEL/////D4MgA0IBhkL+////H4N+fCIGIAWFQiiJIgUgBHwgBUL/////D4MgBEIBhkL+////H4N+fCILIAiFQjCJIgQ3AwAgIyALNwMAICEgBCAGfCAEQv////8PgyAGQgGGQv7///8fg358IgQ3AwAgFyAEIAWFQgGJNwMAICQgByADIA+FQgGJIgV8IAdC/////w+DIAVCAYZC/v///x+DfnwiByAShUIgiSIEIAx8IARC/////w+DIAxCAYZC/v///x+DfnwiCCAFhUIoiSIFIAd8IAVC/////w+DIAdCAYZC/v///x+DfnwiAyAEhUIwiSIHNwMAIBggAzcDACAeIAcgCHwgB0L/////D4MgCEIBhkL+////H4N+fCIHNwMAIB8gBSAHhUIBiTcDACACQYABaiICQYAIRw0AC0GAfyECA0AgFkGACGoiJSACaiIBQYABaiIXIAFBiARqIhgpAwAiBSABQYgCaiIZKQMAIgd8IAdCAYZC/v///x+DIAVC/////w+DfnwiByABQYgIaiIaKQMAhUIgiSIEIAFBiAZqIhspAwAiCHwgBEL/////D4MgCEIBhkL+////H4N+fCIIIAWFQiiJIgUgB3wgBUL/////D4MgB0IBhkL+////H4N+fCIHIASFQjCJIgQgAUGIA2oiHCkDACIDIAFBiAFqIh0pAwAiBnwgBkIBhkL+////H4MgA0L/////D4N+fCIGIAFBiAdqIh4pAwCFQiCJIgsgAUGIBWoiHykDACIMfCALQv////8PgyAMQgGGQv7///8fg358IgwgA4VCKIkiAyAGfCADQv////8PgyAGQgGGQv7///8fg358IgYgC4VCMIkiCyAMfCALQv////8PgyAMQgGGQv7///8fg358IgwgA4VCAYkiAyABQYADaiIgKQMAIg8gFykDACIKfCAKQgGGQv7///8fgyAPQv////8Pg358IgogAUGAB2oiFykDAIVCIIkiECABQYAFaiIhKQMAIhN8IBBC/////w+DIBNCAYZC/v///x+DfnwiEyAPhUIoiSIPIAp8IA9C/////w+DIApCAYZC/v///x+DfnwiCnwgA0L/////D4MgCkIBhkL+////H4N+fCIJhUIgiSIUIAFBgARqIiIpAwAiESABQYACaiIjKQMAIg18IA1CAYZC/v///x+DIBFC/////w+DfnwiDSABQYAIaiIkKQMAhUIgiSISIAFBgAZqIgEpAwAiDnwgEkL/////D4MgDkIBhkL+////H4N+fCIOIBGFQiiJIhEgDXwgEUL/////D4MgDUIBhkL+////H4N+fCINIBKFQjCJIhIgDnwgEkL/////D4MgDkIBhkL+////H4N+fCIOfCAUQv////8PgyAOQgGGQv7///8fg358IhUgA4VCKIkiAyAJfCADQv////8PgyAJQgGGQv7///8fg358Igk3AwAgGiAJIBSFQjCJIgk3AwAgASAJIBV8IAlC/////w+DIBVCAYZC/v///x+DfnwiCTcDACAcIAMgCYVCAYk3AwAgFyAOIBGFQgGJIgMgBnwgA0L/////D4MgBkIBhkL+////H4N+fCIGIAogEIVCMIkiCoVCIIkiECAEIAh8IARC/////w+DIAhCAYZC/v///x+DfnwiBHwgEEIBhkL+////H4MgBEL/////D4N+fCIIIAOFQiiJIgMgBnwgA0L/////D4MgBkIBhkL+////H4N+fCIJIBCFQjCJIgY3AwAgHSAJNwMAIBsgBiAIfCAGQv////8PgyAIQgGGQv7///8fg358Igg3AwAgIiADIAiFQgGJNwMAIB4gBCAFhUIBiSIFIA18IAVC/////w+DIA1CAYZC/v///x+DfnwiBCALhUIgiSIIIAogE3wgCkL/////D4MgE0IBhkL+////H4N+fCIDfCAIQv////8PgyADQgGGQv7///8fg358IgYgBYVCKIkiBSAEfCAFQv////8PgyAEQgGGQv7///8fg358IgsgCIVCMIkiBDcDACAjIAs3AwAgISAEIAZ8IARC/////w+DIAZCAYZC/v///x+DfnwiBDcDACAYIAQgBYVCAYk3AwAgJCAHIAMgD4VCAYkiBXwgB0L/////D4MgBUIBhkL+////H4N+fCIHIBKFQiCJIgQgDHwgBEL/////D4MgDEIBhkL+////H4N+fCIIIAWFQiiJIgUgB3wgBUL/////D4MgB0IBhkL+////H4N+fCIDIASFQjCJIgc3AwAgGSADNwMAIB8gByAIfCAHQv////8PgyAIQgGGQv7///8fg358Igc3AwAgICAFIAeFQgGJNwMAIAJBEGoiAg0ACyAlIBYQmg8gACAlQYAI/AoAACQAC4AdAQR/IwBB0ABrIgIkAAJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkBBCiAAKAIAIgNBIWsgA0EgTRtBAWsOJwECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJwALIAIgAEEEajYCKCACQRA2AjwgAiACQShqNgI4IAEoAgAgASgCBCACQgE3AhQgAkEBNgIMIAJB0PzJADYCCCACIAJBOGo2AhAgAkEIahCpBAwnCyMAQTBrIgQkAAJ/AkACQAJAAkAgAEEEaiIAKAIAIgNB/f///wdqIgVBACADIAVPG0EBaw4DAQIDAAsjAEEwayID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AUGIrMMANgLoAiABQQE2AsACIAFB8K7DADYCvAIgAUIBNwLIAiABQQI2ApQCIAEgAzYC5AIgASACNgLgAiABIAFBkAJqNgLEAiABIAFBiAFqNgKQAiABQdQCaiICIAcgAUHgAmoQ/R0gAUHwAGogAUH8AWooAgA2AgAgASABKQL0ATcDaCAEIAUgBiABQegAaiACEPcJCyAAIAFBiAFqQegA/AoAAAwBCyAAQTA6AAALIAFB8AJqJAALkhcCAX8PfiMAQcAEayICJAAgAkGwBGogASkDACIFQv3/8//P///5iX9+IgNCAEKr1f7///+//7l/QgAQlg4gAkGgBGogA0IAQv//z4rr///VHkIAEJYOIAJBkARqIANCAEKk7MO1j9S0mOcAQgAQlg4gAkGABGogA0IAQr+llJzP8NK75ABCABCWDiACQfADaiADQgBC19mumuT26Y3LAEIAEJYOIAJB4ANqIANCAEKazf/Lo73EgBpCABCWDiACQdADaiACKQOgBCIJIAEpAwh8IgQgAikDuAQgBSACKQOwBCIDfCADVK18fCIFQv3/8//P///5iX9+IgNCAEKr1f7///+//7l/QgAQlg4gAkHAA2ogA0IAQv//z4rr///VHkIAEJYOIAJB0AJqIANCAEKk7MO1j9S0mOcAQgAQlg4gAkHgAWogA0IAQr+llJzP8NK75ABCABCWDiACQfAAaiADQgBC19mumuT26Y3LAEIAEJYOIAIgA0IAQprN/8ujvcSAGkIAEJYOIAJBsANqIAIpA8ADIgcgAikDkAQiCCABKQMQfCIKIAQgBVatIAIpA6gEIAQgCVStfHx8IgZ8IgQgAikD2AMgAikD0AMiAyAFfCADVK18fCIFQv3/8//P///5iX9+IgNCAEKr1f7///+//7l/QgAQlg4gAkGgA2ogA0IAQv//z4rr///VHkIAEJYOIAJBkANqIANCAEKk7MO1j9S0mOcAQgAQlg4gAkGAA2ogA0IAQr+llJzP8NK75ABCABCWDiACQfACaiADQgBC19mumuT26Y3LAEIAEJYOIAJB4AJqIANCAEKazf/Lo73EgBpCABCWDiACQcACaiACKQOgAyILIAIpA4AEIgwgASkDGHwiCSAGIApUrSACKQOYBCAIIApWrXx8fCIKIAIpA9ACfCIIIAQgBVatIAIpA8gDIAQgB1StfHx8Ig98IgQgAikDuAMgAikDsAMiAyAFfCADVK18fCIFQv3/8//P///5iX9+IgNCAEKr1f7///+//7l/QgAQlg4gAkGwAmogA0IAQv//z4rr///VHkIAEJYOIAJBoAJqIANCAEKk7MO1j9S0mOcAQgAQlg4gAkGQAmogA0IAQr+llJzP8NK75ABCABCWDiACQYACaiADQgBC19mumuT26Y3LAEIAEJYOIAJB8AFqIANCAEKazf/Lo73EgBpCABCWDiACQdABaiACKQOwAiINIAIpA/ADIg4gASkDIHwiByAJIApWrSACKQOIBCAJIAxUrXx8fCIJIAIpA+ABfCIGIAggD1atIAIpA9gCIAggClStfHx8IgogAikDkAN8IgggBCAFVq0gAikDqAMgBCALVK18fHwiD3wiBCACKQPIAiACKQPAAiIDIAV8IANUrXx8IgVC/f/z/8////mJf34iA0IAQqvV/v///7//uX9CABCWDiACQcABaiADQgBC///Piuv//9UeQgAQlg4gAkGwAWogA0IAQqTsw7WP1LSY5wBCABCWDiACQaABaiADQgBCv6WUnM/w0rvkAEIAEJYOIAJBkAFqIANCAELX2a6a5PbpjcsAQgAQlg4gAkGAAWogA0IAQprN/8ujvcSAGkIAEJYOIAJB4ABqIAIpA8ABIhAgAikD4AMiESABKQMofCILIAcgCVatIAIpA/gDIAcgDlStfHx8IgcgAikDcHwiDCAGIApWrSACKQPoASAGIAlUrXx8fCIJIAIpA4ADfCIGIAggD1atIAIpA5gDIAggClStfHx8IgogAikDoAJ8IgggBCAFVq0gAikDuAIgBCANVK18fHwiD3wiBCACKQPYASACKQPQASIDIAV8IANUrXx8IgVC/f/z/8////mJf34iA0IAQqvV/v///7//uX9CABCWDiACQdAAaiADQgBC///Piuv//9UeQgAQlg4gAkFAayADQgBCpOzDtY/UtJjnAEIAEJYOIAJBMGogA0IAQr+llJzP8NK75ABCABCWDiACQSBqIANCAELX2a6a5PbpjcsAQgAQlg4gAkEQaiADQgBCms3/y6O9xIAaQgAQlg4gACACKQNQIg0gByALVK0gAikD6AMgCyARVK18fCIOIAIpAwB8IgsgCSAMVK0gAikDeCAHIAxWrXx8fCIHIAIpA/ACfCIM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EQALQbjwwwBBIkGE98MAELkRAAtBuPDDAEEiQYT3wwAQuREAC0G48MMAQSJBgPjDABC5EQALQbjwwwBBIkGA+MMAELkRAAsgACABQYgBakHoAPwKAAAMAQsgAEEwOgAACyABQeACaiQAC6spAhZ/BH4jAEGgB2siAyQAIAECfwJAAkACfwJAAkACQCABLQAUQQFrDgMEAAIBCwALIAEoAgAhBSABKAIEIQggASgCCCEJQRhBBBCEISIERQRAQQRBGBDhIwALIARBADoAFCAEIAk2AgggBCAINgIEIAQgBTYCACADQazXwwA2AgQgAyAENgIAIAMoAgAhCiABQazXwwA2AhAgASAKNgIMQazXwwAMAQsgASgCDCEKIAEoAhALIQQgA0HYAmogCiACIAQoAgwRAwAgAy0A2AIiCkHCAEcNASAAQQI2AgBBAwwCC0GE08MAELUXAAsgA0GqBGoiDSADLQDbAjoAACADQaYEaiIOIAMtAN8COgAAIANBogRqIg8gA0HjAmotAAA6AAAgA0GeBGoiECADQecCai0AADoAACADIAMvANkCOwGoBCADIAMvAN0COwGkBCADIAMvAOECOwGgBCADIAMvAOUCOwGcBCADLQDcAiECIAMtAOACIQQgAy0A5AIhBSADQZoEaiIRIANB6wJqLQAAOgAAIANBlgRqIhIgA0HvAmotAAA6AAAgA0GSBGoiEyADQfMCai0AADoAACADQY4EaiIUIANB9wJqLQAAOgAAIAMgAy8A6QI7AZgEIAMgAy8A7QI7AZQEIAMgAy8A8QI7AZAEIAMgAy8A9QI7AYwEIAMtAOgCIQcgAy0A7AIhCCADLQDwAiEJIAMtAPQCIQYgA0GKBGoiFSADQfsCai0AADoAACADIAMvAPkCOwGIBCADLQD4AiELIANB3ANqIhYgA0H8AmpBLPwKAAAgA0HQA2oiFyADQbgDaikDADcDACADQcgDaiIYIANBsANqKQMANwMAIAMgAykDqAM3A8ADIAFBDGoQ/hUCfyAKQcEARwRAIANBngdqIA0tAAA6AAAgA0GaB2ogDi0AADoAACADQZYHaiAPLQAAOgAAIANBkgdqIBAtAAA6AAAgA0GOB2ogES0AADoAACADIAMvAagEOwGcByADIAMvAaQEOwGYByADIAMvAaAEOwGUByADIAMvAZwEOwGQByAD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QZIHaiANLQAAOgAAIANBjgdqIA4tAAA6AAAgA0GKB2ogDy0AADoAACADIAMvASg7AZgHIAMgAy8BJDsBlAcgAyADLwEgOwGQByADIAMvARw7AYwHIAMgAy8BGDsBiAcgA0GGB2ogEC0AADoAACADQYIHaiARLQAAOgAAIANB/gZqIBItAAA6AAAgAyADLwEUOwGEByADIAMvARA7AYAHIAMgAy8BDDsB/AYgBSEHIAQhBSACIQQgASELIAohAkE/IQpBAQwBCyADQf4GaiADQdMAai0AADoAACADIAMvAFE7AfwGIAMtAFAhCyADQbgGaiADQdQAakHEAPwKAAAgA0H4BGogA0GYAWpBwAH8CgAAIANBngdqIANBKmotAAA6AAAgA0GaB2ogA0Emai0AADoAACADQZYHaiADQSJqLQAAOgAAIANBkgdqIANBHmotAAA6AAAgA0GOB2ogA0Eaai0AADoAACADIAMvASg7AZwHIAMgAy8BJDsBmAcgAyADLwEgOwGUByADIAMvARw7AZAHIAMgAy8BGDsBjAcgA0GKB2ogA0EWai0AADoAACADQYYHaiADQRJqLQAAOgAAIANBggdqIANBDmotAAA6AAAgAyADLwEUOwGIByADIAMvARA7AYQHIAMgAy8BDDsBgAcgCCEHIAkhCCAGIQkgASEGQQALIQEgACAKOgAIIAAgDDYCBCAAIAE2AgAgACADLwGcBzsACSAAQQtqIANBngdqLQAAOgAAIAAgAjoADCAAIAMvAZgHOwANIABBD2ogA0GaB2otAAA6AAAgACAEOgAQIAAgAy8BlAc7ABEgAEETaiADQZYHai0AADoAACAAIAU6ABQgAEEXaiADQZIHai0AADoAACAAIAMvAZAHOwAVIAAgBzoAGCAAQRtqIANBjgdqLQAAOgAAIAAgAy8BjAc7ABkgACAIOgAcIABBH2ogA0GKB2otAAA6AAAgACADLwGIBzsAHSAAIAk6ACAgAEEjaiADQYYHai0AADoAACAAIAMvAYQHOwAhIAAgBjoAJCAAQSdqIANBggdqLQAAOgAAIAAgAy8BgAc7ACUgACALOgAoIABBK2ogA0H+BmotAAA6AAAgACADLwH8BjsAKSAAQSxqIANBuAZqQcQA/AoAACAAQfAAaiADQfgEakHAAfwKAABBAQs6ABQgA0GgB2okAAvj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BSADQcwAahCnFyABQQE6ADcMBwsgA0ECNgIoIANBvMbmACgCACIFNgI4QeDQ5gAtAAANBSAFKAIgIgRFDQ8gBSgCKCEGIAUoAiQhByAFKAIcIQggA0EANgJcIAMgBjYCWCADIAc2AlQgAyAINgJMIAMgBDYCUCAEQQFGDQ8gA0EBNgJwIAMgBjYCbCADIAc2AmggAyAINgJgIAMgBDYCZCADIAE2AnQgBEECTQ0PIANBAjYCiAEgAyAGNgKEASADIAc2AoABIAMgCDYCeCADIAQ2AnwgAyABQQhqNgKMASAEQQNGDQ8gA0EDNgKgASADIAY2ApwBIAMgBzYCmAEgAyAENgKUASADIAg2ApABIANB9KvFADYCtAIgA0GErMUANgKoAiADQYSsxQA2ApwCIANB9KvFADYCkAIgAyABQTRqNgKMAiADIAVBHGo2AkggA0EENgJEIAMgAUE1ajYCsAIgAyADQZABajYCrAIgAyADQYwBajYCpAIgAyADQfgAajYCoAIgAyADQfQAajYCmAIgAyADQeAAajYClAIgAyADQcwAajYCiAIgAyADQYgCajYCQCADQSBqIANBQGsQ1QcMBQsgAUHiAGohCCABQThqIQkgAS0AYkEBaw4DAgABCAsACyABKAJYIQQgASgCXAwJC0HEr8UAELUXAAtBtK7FABC1FwALIAFBAToANyABIAMpAyA3AxAgAUEYaiADQShqKQMANwMAIAFBIGogA0EwaikDADcDACABQShqIANBOGopAwA3AwALIAEtADUhBCABKAIMIQUgASgCCCEGIAEoAgQhByABKAIAIQggAS0ANCEJIAEoAjAhCyABKAIYQQJGDQEgAUEAOgA3IAFBADoAggEgASAEOgCBASABIAk6AIABIAEgCzYCaCABIAU2AmQgASAGNgJgIAEgBzYCXCABIAg2AlggASABKQMQNwM4IAFBQGsgAUEYaikDADcDACABQcgAaiABQSBqKQMANwMAIAFB0ABqIAFBKGopAwA3AwALIANBiAJqIQsjAEGgAWsiBCQAIAFBOGoiBSgCCEECRwRAIAVBCGogBRDuEwsCQEHg0OYALQAADQAgBSgCGCIGRQ0AIARBAjYCLCAEQfzHxQA2AiggBEIBNwI0IARBBTYCJCAEIAYpAgw3ApQBIAQgBEEgajYCMCAEIARBlAFqNgIg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ByASIAkQ7QIMAQsgAEECNgIAIAAgBzoABCABEPMhCyAGQZABaiQAC8gSAgF/D34jAEHABGsiASQAIAFBsARqIAApAwAiBEL9//P/z///+Yl/fiICQgBCq9X+////v/+5f0IAEJYOIAFBoARqIAJCAEL//8+K6///1R5CABCWDiABQZAEaiACQgBCpOzDtY/UtJjnAEIAEJYOIAFBgARqIAJCAEK/pZScz/DSu+QAQgAQlg4gAUHwA2ogAkIAQtfZrprk9umNywBCABCWDiABQeADaiACQgBCms3/y6O9xIAaQgAQlg4gAUHQA2ogASkDoAQiBiAAKQMIfCIDIAEpA7gEIAQgASkDsAQiAnwgAlStfHwiBEL9//P/z///+Yl/fiICQgBCq9X+////v/+5f0IAEJYOIAFBwANqIAJCAEL//8+K6///1R5CABCWDiABQdACaiACQgBCpOzDtY/UtJjnAEIAEJYOIAFB4AFqIAJCAEK/pZScz/DSu+QAQgAQlg4gAUHwAGogAkIAQtfZrprk9umNywBCABCWDiABIAJCAEKazf/Lo73EgBpCABCWDiABQbADaiABKQPAAyIIIAEpA5AEIgcgACkDEHwiBSADIARWrSABKQOoBCADIAZUrXx8fCIJfCIDIAEpA9gDIAEpA9ADIgIgBHwgAlStfHwiBEL9//P/z///+Yl/fiICQgBCq9X+////v/+5f0IAEJYOIAFBoANqIAJCAEL//8+K6///1R5CABCWDiABQZADaiACQgBCpOzDtY/UtJjnAEIAEJYOIAFBgANqIAJCAEK/pZScz/DSu+QAQgAQlg4gAUHwAmogAkIAQtfZrprk9umNywBCABCWDiABQeACaiACQgBCms3/y6O9xIAaQgAQlg4gAUHAAmogASkDoAMiCyABKQOABCIKIAApAxh8IgYgBSAJVq0gASkDmAQgBSAHVK18fHwiBSABKQPQAnwiByADIARWrSABKQPIAyADIAhUrXx8fCIMfCIDIAEpA7gDIAEpA7ADIgIgBHwgAlStfHwiBEL9//P/z///+Yl/fiICQgBCq9X+////v/+5f0IAEJYOIAFBsAJqIAJCAEL//8+K6///1R5CABCWDiABQaACaiACQgBCpOzDtY/UtJjnAEIAEJYOIAFBkAJqIAJCAEK/pZScz/DSu+QAQgAQlg4gAUGA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ACIBKAIgIgZFDQcgASgCKCEJIAEoAiQhCiABKAIcIQcgA0EANgLAASADIAk2ArwBIAMgCjYCuAEgAyAGNgK0ASADIAc2ArABIANBvJzKADYC6AEgAyABQRxqNgKsASADQQE2AqgBIANBADYC2AEgA0EBNgLMASADQbCoygA2AsgBIANCBDcC0AEgAyADQcgBajYC5AEgAyADQbABajYC4AEgAyADQeABajYCpAEgA0HwAGogA0GgAWooAgA2AgAgAyADKQKYATcDaCACIAQgBSADQegAaiADQaQBahD3CQwJCyAIIARBlKPKABCMEAALIAMgBDoAyAFBlKvKAEErIANByAFqQYSrygBB6KXKABCpDgALQcCbygBBIkH4pcoAELkRAAtBwJvKAEEiQfilygAQuREAC0HAm8oAQSJB9KbKABC5EQALQcCbygBBIkH0psoAELkRAAtBwJvKAEEiQdSnygAQuREAC0HAm8oAQSJB1KfKABC5EQALIAYgBCAJEMICQf8BcSIBQQpGBEAgA0HIAWogBSAKEJYRAkAgAy0A2AFBAkYEQCADQYgBakEAOgAAIANCADcDgAEgA0EBNgJ8IANB5K7KADYCeAwBCyADQYgBaiADQdgBaigCADYCACADQYABaiADQdABaikCADcDACADIAMpAsgBNwN4CyADQbgBakHspsoAKQIANwMAIANB5KbKACkCADcDsAEgA0HIAWogAiADQbABaiADQfgAahDpDiADLQDYAUECRwRAIANB1AFqIAMoAswBIAMoAtABIAMoAsgBKAIQEQMACyAIKQIUIREgA0EYaiAIEPgPIAAgAykDGDcCCCAAIBE3AgAMAgsgAyABOgDIAUGUq8oAQSsgA0HIAWpBhKvKAEHUpsoAEKkOAAsgAEEANgIIIAAgCCkCFDcCAAsgA0HwAWokAAvEEAINfwF+IwBB4A5rIgMkACABAn8CfgJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgAS0AMEEBaw4FCQUBBBIACyABIAEoAgw2AhQgASABKQIAIhA3AhggAUEgaiABQQhqIgUoAgA2AgAgAUE0aiEKIAEoAhAhBCAQp0GAgICAeEYNBSABIAEpAgA3AiQgAUEAOgBQIAEgBDYCNCABQSxqIAUoAgAiBzYCACABIAc2Ajwg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Qez0wwAQ9xgAC0HQ0OYAKAIAQQVPBEAgA0EANgKoAiADQQE2ApwCIANB+PLDADYCmAIgA0IENwKgAiADQYDzwwA2AsABIANBGjYCvAEgA0GQ88MANgK4ASADQRo2ArQBIANBkPPDADYCsAEgA0GYAmpBBSADQbABahDDCgtBHiEBQdDQ5gAoAgBBBEkNAiADQQA2AqgCIANBATYCnAIgA0HU88MANgKYAiADQgQ3AqACIANB3PPDADYCwAEgA0EaNgK8ASADQZDzwwA2ArgBIANBGjYCtAEgA0GQ88MANgKwASADQZgCakEEIANBsAFqEMMKDAILQSshAQwBCyAMIAMpA0A3AgAgDEEIaiAGKQMANwIAIAxBEGogBSkDADcCACADIAE2AlwgA0GYAmoiBSADQdwAahCVECADLQCYAiIBQTBHBEAgA0GoA2ogBUEBckEn/AoAACADQbABaiADQcACakHAAPwKAAAMAQsgA0GIAWogC0EQaikCADcDACADQYABaiALQQhqKQIANwMAIAMgCykCACIVNwN4AkACQAJAAkACQAJAQQUgFaciAUGAgICAeHMgAUEAThsOAgABAgsgA0GgA2ogCkEIaigCADYCACADIAopAgA3A5gDIANBmAJqIANBmANqEPAVAn8gAy0AmAJBCEYEQCADIAMoApwCNgKwASADQbABahC1FUEfDAELIANBxwNqIANBsAJqKQMANwAAIANBvwNqIANBqAJqKQMANwAAIANBtwNqIANBoAJqKQMANwAAIAMgAykDmAI3AK8DQTALIQEgAygCeEGCgICAeEgNBSADQfgAahC9DQwFCyADQZgBaiIFIApBCGooAgA2AgAgAyAKKQIANwOQAQJAIAQoAigiBigC4AIiAQRAIANBnAFqIANBkAFqIAFBCGoQvAIgAygCnAFBgICAgHhGDQEgBCgCKCEFQQxBBBCEISIBRQ0EIAEgAykCnAE3AgAgAUEIaiADQaQBaigCADYCACADQQE2AqACIAMgATYCnAIgA0EBNgKYAiADQbABaiIGIAVB0AJqIANBmAJqIgEQugEgAy0AsAFBMEYNASABIAZB6AD8CgAAQdDQ5gAoAgBBAUsEQCADQQE2AqwDIANBhPTDADYCqAMgA0IBNwK0AyADQQI2AqwBIAMgA0GoAWo2ArADIAMgATYCqAEgA0GM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NgK4ASADQRo2ArQBIANBiMXDADYCsAEgA0GYAmpBBCADQbABahDDCgwGC0ErIQQMBQsgDCADKQNANwIAIAxBCGogBykDADcCACAMQRBqIAYpAwA3AgAgAyAENgJcIANBmAJqIgYgA0HcAGoQlRAgAy0AmAIiBEEwRwRAIANBqANqIAZBAXJBJ/wKAAAgA0GwAWogA0HAAmpBwAD8CgAADAULIANBiAFqIAtBEGopAgA3AwAgA0GAAWogC0EIaikCADcDACADIAspAgAiFTcDeAJAAkACQEEFIBWnIgRBgICAgHhzIARBAE4bDgIAAQILIANBoANqIApBCGooAgA2AgAgAyAKKQIANwOYAyADQZgCaiADQZgDahDwFQJ/IAMtAJgCQQhGBEAgAyADKAKcAjYCsAEgA0GwAWoQtRVBHwwBCyADQccDaiADQbACaikDADcAACADQb8DaiADQagCaikDADcAACADQbcDaiADQaACaikDADcAACADIAMpA5gCNwCvA0EwCyEEIAMoAnhBgoCAgHhIDQYgA0H4AGoQvQ0MBgsgA0GYAWoiBiAKQQhqKAIANgIAIAMgCikCADcDkAECQCAFKAIoIgcoAoAFIgQEQCADQZwBaiADQZABaiAEQQhqELwCIAMoApwBQYCAgIB4Rg0BIAUoAighBhCtGyIEQQhqIANBpAFqKAIANgIAIAQgAykCnAE3AgAgA0EBNgKgAiADIAQ2ApwCIANBATYCmAIgA0GwAWoiByAGQYQFaiADQZgCaiIEELoBIAMtALABQTBGDQEgBCAHQegA/AoAAEHQ0OYAKAIAQQFLBEAgA0EBNgKsAyADQfzFwwA2AqgDIANCATcCtAMgA0ECNgKsASADIANBqAFqNgKwAyADIAQ2AqgBIANBhMbDADYClAMgA0EaNgKQAyADQYjFwwA2AowDIANBGjYCiAMgA0GIxcMANgKEAyADQagDakECIANBhANqEMMKCyADQZgCahDhAwwBCxCtGyIEQQhqIAYoAgA2AgAgBCADKQOQATcCACADQQE2AqACIAMgBDYCnAIgA0EBNgKYAiADQbABaiIGIAdBhAVqIANBmAJqIgQQugEgAy0AsAFBMEYNACAEIAZB6AD8CgAAQdDQ5gAoAgBBAUsEQCADQQE2AqwDIANB/MXDADYCqAMgA0IBNwK0AyADQQI2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1IXCACEHIAFB1IXCADYCCCABQd0AaiEIIAFBCGohCkENCyEEIAFBAToAXCADIAU2AjAgAyAENgK8AyADIAc2ArgDIAMgBjYCtAMgA0EBNgKwAyADQegAaiADQbADahC0DyADKAJoBEAgA0FAayADQfgAaikDACINNwIAIANBqAFqIA03AwAgAyADKQNwIg03AjggAyANNwOgASADQZADaiADQaABahCkFgwTCyADQTRqIgsgA0HoAGoiDEEEckE0/AoAACABQRRqIgYgC0E0/AoAACAMIAYgByAEEKoRIANBuAFqIgQgA0H0AGooAgA2AgAgAyADKQJsNwOwASADKAJoIgZBDkcEQCADQcwBaiAEKAIANgIAIAMgBjYCwAEgAyADKQOwATcCxAEgA0GQA2ogA0HAAWoQpBYMEgsgASADKQOwATcCSCABQdAAaiAEKAIANgIAIAFBADoAXCADIAU2ArgDIAMgCTYCtAMgAyABQcgAajYCsAMgA0HoAGogA0GwA2oQtQgCQAJAIAMoAmhFBEAgASADKQNwNwNoIAFBADYCYCABQfAAaiADQfgAaikDADcDAAwBCyABQeAAaiIEIAMpA2giDTcDACAEQRBqIgUgA0H4AGopAwA3AwAgBEEIaiIGIANB8ABqKQMANwMAIA2nDQELIANB2AFqIAFB8ABqKQMANwMAIAMgASkDaDcD0AEgA0HQAWohBAwRCyABIAQpAwA3A3ggAUGIAWogBSkDADcDACABQYABaiAGKQMANwMACyADIAFB+ABqNgKwAyADQegAaiADQbADaigCACACEKcQQQMgAygCaCIEQQ9GDQ0aIAMpA3AhDSADKAJsIQUgAUH8AGoQzhIgBEEORwRAIAMgDTcD6AEgAyAFNgLkASADIAQ2AuABIANB4AFqIQQMEAsgAyAFNgLAAyADQcADahDtHSADQbwCaiABQRRqQTT8CgAAIAFB4ABqIgUgA0H0AWpB/AD8CgAAIAFBADoA3AEgAUHcAWohBgwHC0Gog8IAELUXAAtB9IXCABC1FwALIAFB4ABqIQUgAUHcAWohBgJAAkAgAS0A3AFBAWsOAwACAQYLQaiOwgAQtRcACyABQaQBaiEJAkACQCABLQCkAUEBaw4DBQIBAAsgASgClAEMBgsgAUGgAWohByABLQCgAUEBaw4DAgAHAQsACyAB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QayxxAAQtQsMFQsgAiAAQQRqNgIMIAFBvdbEAEEOQd7ExABBByACQQxqQayxxAAQtQsMFAsgAUHL1sQAQR4Q6B4MEwsgAUHp1sQAQR4Q6B4MEgsgAUGH18QAQScQ6B4MEQsgAUGu18QAQRMQ6B4MEAsgAUHB18QAQQ0Q6B4MDwsgAiAAQQRqNgIMIAFBztfEAEEWQeTXxABBByACQQxqQayxxAAQtQsMDgsgAiAAQQRqNgIMIAFB/NfEAEEQQYzYxABBAiAAQRBqQezXxABBpNTEAEEIIAJBDGpBrLHEABCCCwwNCyACIABBEGo2AgwgAUGg2MQAQRlBudjEAEEJIABBBGpBkNjEAEG6xcQAQQYgAkEMakH0zsQAEIILDAwLIAIgAEEoajYCDCABQcLYxABBEUHRscQAQQMgAEEEakHYxsQAQYzYxABBAiAAQRBqQdjGxABBiLnEAEEEIABBHGpBkNjEAEG6xcQAQQYgAkEMakH0zsQAEPgJDAsLIAIgAEEEajYCDCABQdPYxABBGEHuscQAQQogAEEUakHYxsQAQbrFxABBBiACQQxqQdjPxAAQggsMCgsgAiAAQRxqNgIMIAFB69jEAEERQe6xxABBCiAAQQRqQdjGxABB/NjEAEEMIABBEGpB2MbEAEG6xcQAQQYgAkEMakGgyMQAELsKDAkLIAIgAEEEajYCDCABQYjZxABBEkGa2cQAQQkgAkEMakGsscQAELULDAgLIAIgAEEEajYCDCABQaPZxABBEUHuscQAQQogAkEMakGsscQAELULDAcLIAIgAEEEajYCDCABQbTZxABBFEHuscQAQQogAkEMakGsscQAELULDAYLIAFByNnEAEETEOgeDAULIAFB29nEAEETEOgeDAQLIAIgAEEIajYCDCABQYDaxABBFUG6xcQAQQYgAkEMakHw2cQAELULDAMLIAIgAEEIajYCDCABQZXaxABBGEG6xcQAQQYgAkEMakHw2cQAELULDAILIAIgAEEBajYCDCABQcDaxABBF0G6xcQAQQYgAkEMakGw2sQAELULDAELIAIgADYCDCABQejaxABBDiACQQxqQdjaxAAQpQgLIAJBEGokAAvZDQIBfxB+IwBBoANrIgIkACACQYACaiABKQMIIgNCACABKQMAIgRCABCWDiACQZACaiABKQMQIgVCACAEQgAQlg4gAkGgAmogASkDGCIGQgAgBEIAEJYOIAJBwAJqIAVCACADQgAQlg4gAkHQAmogBkIAIANCABCWDiACQfACaiAGQgAgBUIAEJYOIAJBsAJqIARCACAEQgAQlg4gAkHgAmogA0IAIANCABCWDiACQYADaiAFQgAgBUIAEJYOIAJBkANqIAZCACAGQgAQlg4gAkHwAWogAikDsAIiBkL/////b34iA0IAQoGAgIBwQgAQlg4gAkHgAWogA0IAQv63+f+vgOne0wBCABCWDiACQdABaiADQgBChbCHzYCB9pwzQgAQlg4gAkHAAWogA0IAQsj69cyy6un28wBCABCWDiACQbABaiACKQO4AiIJIAIpA4ACIgdCAYZ8IgQgAikD4AF8IgUgAikD+AEgAikD8AEiAyAGQn2DfCADVK18fCIGQv////9vfiIDQgBCgYCAgHBCABCWDiACQaABaiADQgBC/rf5/6+A6d7TAEIAEJYOIAJB0ABqIANCAEKFsIfNgIH2nDNCABCWDiACIANCAELI+vXMsurp9vMAQgAQlg4gAkGQAWogAikDoAEiDiACKQPgAiILIAIpA5ACIgwgAikDiAJ8IghCAYYgB0I/iIR8IgcgBCAJVK18IgkgAikD0AF8IgogBSAGVq0gAikD6AEgBCAFVq18fHwiDXwiBCACKQO4ASACKQOwASIDIAZ8IANUrXx8IgVC/////29+IgNCAEKBgICAcEIAEJYOIAJBgAFqIANCAEL+t/n/r4Dp3tMAQgAQlg4gAkHwAGogA0IAQoWwh82AgfacM0IAEJYOIAJB4ABqIANCAELI+vXMsurp9vMAQgAQlg4gAkFAayACKQOAASIRIAcgCVatIAIpA+gCIAcgC1StfHwiDyACKQOYAiAIIAxUrXwiDCACKQOgAnwiBiACKQPAAnwiB0IBhiAIQj+IhHwiCCACKQPAAXwiCyAKIA1WrSACKQPYASAJIApWrXx8fCIJIAIpA1B8IgogBCAFVq0gAikDqAEgBCAOVK18fHwiDXwiBCACKQOYASACKQOQASIDIAV8IANUrXx8IgVC/////29+IgNCAEKBgICAcEIAEJYOIAJBMGogA0IAQv63+f+vgOne0wBCABCWDiACQSBqIANCAEKFsIfNgIH2nDNCABCWDiACQRBqIANCAELI+vXMsurp9vMAQgAQ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6AUMBgsgA0H4A2oiByADQZQFaigCADYCACADQfADaiIJIANBjAVqKQIANwMAIAMgAykChAU3A+gDIAUQkx4gBEGPgICAeEcEQCADQZQEaiAHKAIANgIAIANBjARqIAkpAwA3AgAgAyADKQPoAzcChAQgAyAENgKABCADQegFaiADQYAEahC1EgwGCyABQQA6AL0BIAEgASgCVDYCuAELIANBgAVqIAFB4ABqIgQgAhCPAiADLQCABUExRw0BQQULIQEgBiABOgAADAULIANBmARqIgUgA0GABWoiAkHoAPwKAAAgBBCgGyABLQBZRQ0BIAIgASgCVBD+BiADLQCABSIEQTBGDQEgA0HoBWpBAXIgAkEBckHnAPwKAAAgAyAEOgDoBSAFEPgaDAILIANBDjoA6AUMAQsgA0HoBWogA0GYBGpB6AD8CgAADAELIAEtAFoEQCABQdwAahChCAsLIAFBADoAWiADLQDoBSEEIANBKWoiAiADQegFakEBckHnAPwKAAAgBkEBOgAAIARBMUYNACADQZABaiIGIAJB5wD8CgAAIAgQtxIgBEEwRg0BIANBgAJqIAZBJ/wKAAAgA0GnAmogA0G3AWpBwAD8CgAADAILIABBMToAAEEDDAILIANBIGogA0GvAWopAAA3AwAgA0EYaiADQacBaikAADcDACADQRBqIANBnwFqKQAANwMAIAMgAykAlwEiCjcDCAJAIAqnQf8BcSICBEAgAkEGRwRAIANBgAZqIANBlwFqIgFBGGopAAA3AwAgA0H4BWogAUEQaikAADcDACADQfAFaiABQQhqKQAANwMAIAMgASkAADcD6AUgA0GYBGogA0HoBWoiARDgAyADQYsFaiADQaAEaigCADYAACADIAMpApgENwCDBSADIAMpAIAFNwOAAiADIANBhwVqKQAANwCHAiABEOkVQSYhBAwDCyADQfMFaiADQaMBaigAADYAACADIAMpAJsBNwDrBSADIAMpAOgFNwOAAiADIANB7wVqKQAANwCHAkEPIQYMAQsgAyADLQAJIgI6APcBIAMgAykDECIKNwP4ASADQegFaiIIIAEoApQDIAMtAAoiBSADLQALIgcQ4AFBMCEGIAMtAOgFIgRBMEcEQCADQYACaiAIQQFyQecA/AoAACADLQAIQQZGDQIgA0EIahDpFQwCCyABKAKUAyACOgDWBSABKAKUA0GQBWogChCbByABKAKUAyIBIAc6ANUFIAEgBToA1AVB0NDmACgCAEEESQ0AIANBAjYC7AUgA0HcyMIANgLoBSADQgI3AvQFIANBBDYCpAQgA0EBNgKcBCADIANBmARqNgLwBSADIANB+AFqNgKgBCADIANB9wFqNgKYBCADQezIwgA2ApAFIANBGjYCjAUgA0HcwsIANgKIBSADQRo2AoQFIANB3MLCADYCgAUgA0HoBWpBBCADQYAFahDDCgsgAy0ACEEGRwRAIANBCGoQ6RULIAYhBAsgACAEOgAAIABBAWogA0GAAmpB5wD8CgAAQQELOgCYAyADQdAGaiQAC6gOAgR/AX4jAEGwBGsiAyQAIAECfwJAAn8CQAJAAkACQAJAIAEtAF1BAWsOAwIAAwELAAsgASABKAJYIgU2AiBBJyEEIAUoApACQQJGDQIMBAtB+N3DABC1FwALQQEMAQsgASAFQZQCajYCJCADQQhqIAUpAyAgBSgCKBCfDyABQRBqIANBGGopAwA3AwAgAUEIaiADQRBqKQMANwMAIAEgAykDCDcDACABIAE2AihBAAshBANAIARFBEAgAUEAOgBcIANBJGoiBCABKAIgQdwCahDSJCABKAIkIQUgAUEsaiIGIARBJPwKAAAgASAFNgJUIAEgAUEoajYCUCABIAY2AhwgASABQdwAajYCGEEBIQQMAQsgA0GgAmogAUEYaiACEI0GIAMoAqACIgVBB0YEQCAAQTE6AABBAwwDCyADQdgAaiADQbQCaikCADcDACADQdAAaiADQawCaikCADcDACADIAMpAqQCNwNIIAFBMGoQ5hQgASgCQCIEBEAgASgCRCAEKAIMEQIAC0ErIQQCQAJAAkACQEECIAVBA2sgBUECTRtBAWsOAwMCAAELIANBADYCsAIgA0EBNgKkAiADQajgwwA2AqACIANCBDcCqAIgA0GgAmpBsODDABD3GAALQdDQ5gAoAgBBBU8EQCADQQA2ArACIANBATYCpAIgA0G83sMANgKgAiADQgQ3AqgCIANBxN7DADYCyAEgA0EaNgLEASADQdTewwA2AsABIANBGjYCvAEgA0HU3sMANgK4ASADQaACakEFIANBuAFqEMMKC0EeIQRB0NDmACgCAEEESQ0BIANBADYCsAIgA0EBNgKkAiADQZjfwwA2AqACIANCBDcCqAIgA0Gg38MANgLIASADQRo2AsQBIANB1N7DADYCwAEgA0EaNgK8ASADQdTewwA2ArgBIANBoAJqQQQgA0G4AWoQwwoMAQsgA0HwAGogA0HQAGopAwA3AgAgA0H4AGogA0HYAGopAwA3AgAgAyAFNgJkIAMgAykDSDcCaCADQaACaiIFIANB5ABqEJUQIAMtAKACIgRBMEcEQCADQYkEaiAFQQFyQSf8CgAAIANByANqIANByAJqQcAA/AoAAAwBCyADQZABaiADQbQCaikCADcDACADQYgBaiADQawCaikCADcDACADIAMpAqQCIgc3A4ABAkACQAJAAkACQAJAQQUgB6ciBEGAgICAeHMgBEEAThsOAgABAgsgA0HAA2ogA0GMAWooAgA2AgAgAyADKQKEATcDuAMgA0GgAmogA0G4A2oQ8BUCfyADLQCgAkEIRgRAIAMgAygCpAI2ArgBIANBuAFqELUVQR8MAQsgA0GoBGogA0G4AmopAwA3AAAgA0GgBGogA0GwAmopAwA3AAAgA0GYBGogA0GoAmopAwA3AAAgAyADKQOgAjcAkARBMAshBCADKAKAAUGCgICAeEgNBSADQYABahC9DQwFCyADQaABaiADQYwBaigCADYCACADIAMpAoQBNwOYAQJAIAEoAiAiBSgC4AIiBARAIANBpAFqIANBmAFqIARBCGoQvAIgAygCpAFBgICAgHhGDQEgASgCICEFQQxBBBCEISIERQ0EIAQgAykCpAE3AgAgBEEIaiADQawBaigCADYCACADQQE2AqgCIAMgBDYCpAIgA0EBNgKgAiADQbgBaiIGIAVB0AJqIANBoAJqIgQQugEgAy0AuAFBMEYNASAEIAZB6AD8CgAAQdDQ5gAoAgBBAUsEQCADQQE2ApADIANByN/DADYCjAMgA0IBNwKYAyADQQI2ArQBIAMgA0GwAWo2ApQDIAMgBDYCsAEgA0HQ38MANgK0AyADQRo2ArADIANB1N7DADYCrAMgA0EaNgKoAyADQdTewwA2AqQDIANBjANqQQIgA0GkA2oQwwoLIANBoAJqEIQDDAELQQxBBBCEISIERQ0CIAQgAykDmAE3AgAgBEEIaiADQaABaigCADYCACADQQE2AqgCIAMgBDYCpAIgA0EBNgKgAiADQbgBaiIGIAVB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eDYCACANIAQ2AgQMDwsgCC0AGCIERQ0GIAggBEEBayIEOgAYIARB/wFxRQRAIANBGDYC0AEgCCADQdABahDIFgwCCyAIELcaIANBAToA3AIgAyAINgLYAiADQdABaiIGIANB2AJqIgcQ0w0gAygC1AEhBAJAAkAgAygC0AEiE0ECRg0AIAYgBxDKDCADKALQASIHQYGAgIB4RgRAIAMoAtQBIQQMAQtBgICAgHghBgJAAkAgB0GAgICAeEcEQCADKALUASEGIAMgAygC2AEiETYC7AIgAyAGNgLoAiADIAc2AuQCIANB0AFqIANB2AJqEMoMIAMoAtABIgpBgYCAgHhHDQEgAygC1AEhBAwCC0EBQfS7xQBB0LfFABCBDyEEDAMLAkACQCAKQYCAgIB4RwRAIAMoAtQBIQsgAyADKALYATYC+AIgAyALNgL0AiADIAo2AvACIANB0AFqIANB2AJqEMoMIAMoAtABIgpBgYCAgHhHDQEgAygC1AEhBAwCC0ECQfS7xQBB0LfFABCBDyEEDAILAkACQCAKQYCAgIB4RwRAIAMoAtQBIQsgAyADKALYATYCiAMgAyALNgKEAyADIAo2AoADIANB0AFqIANB2AJqEMoMIAMoAtABIgpBgYCAgHhHDQEgAygC1AEhBAwCC0EDQfS7xQBB0LfFABCBDyEEDAILAkACQCAKQYCAgIB4RwRAIAMoAtQBIQsgAyADKALYATYCmAMgAyALNgKUAyADIAo2ApADIANB0AFqIANB2AJqEMoMIAMoAtABIgpBgYCAgHhHDQEgAygC1AEhBAwCC0EEQfS7xQBB0LfFABCBDyEEDAILAn8CQCAKQYCAgIB4RwRAIAMoAtQBIQsgAyADKALYATYCqAMgAyALNgKkAyADIAo2AqADIANB0AFqIANB2AJqEMoMIAMoAtABIgpBgYCAgHhHDQEgAygC1AEMAgtBBUH0u8UAQdC3xQAQgQ8hBAwCCyAKQYCAgIB4RwRAIARBACATQQFxGyELIAMoAtgBIQ4gAygC1AEhEiADQYgBaiADQfgCaigCADYCACADQfgAaiADQYgDaigCADYCACADQegAaiADQZgDaigCADYCACADQdgAaiADQagDaigCADYCACADIAMpAvACNwOAASADIAMpAoADNwNwIAMgAykCkAM3A2AgAyADKQKgAzcD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AkEUaiADQTRqKQIANwIAIAJBDGogA0EsaikCADcCACACQRxqIAkoAgA2AgAgA0EIaikDACELIAMpAwAhDCACIAY7ATAgAiAMNwIgIAJBKGogCzcCACAAIAFBAWo2AiggACgCHCEJIAAoAhghCgNAIAchBEEAIQcgBCAJTw0AIAogBEECdGoiBy8BACICQf//A0YNAiAFQQFqIgVFDQcgByABOwEAIAcvAQIgByAGOwECIARBAWohByEGIAIhAQwACwALIANBHGogAygCFCADKAIYIAMoAhAoAhARAwAgAygCACIARQ0GIANBDGogAygCBCADKAIIIAAoAhARAwAMBgsgByAGOwECIAcgATsBAAJAIAhBf3MgBUGAAUlxDQAgACkDAEIAUg0AIABCATcDAAtBACEEDAYLIAAoAighBSADQQhqIAFBCGopAgA3AwAgAyABKQIANwMAIANBIGogAkEQaiIBKAIANgIAIANBGGogAkEIaiIEKQIANwMAIAMgAikCADcDEAJAIAVB//8BTQRAIANBPGoiCCABKAIANgIAIANBNGogBCkCADcCACADIAIpAgA3AiwgAEEgaiIBKAIAIAVGBEAgAUGU1MoAEJUUCyAAKAIkIAVBNGxqIgEgAykCJDcCBEEAIQQgAUEANgIAIAFBDGogA0EsaikCADcCACABQRRqIANBNGopAgA3AgAgAUEcaiAIKAIANgIAIANBCGopAwAhCyADKQMAIQwgASAGOwEwIAEgDDcCICABQShqIAs3AgAgACAFQQFqNgIoIAcgACgCHCIBTw0BIAAoAhggB0ECdGoiACAGOwECIAAgBTsBAAwHCyADQRxqIAMoAhQgAygCGCADKAIQKAIQEQMAIAMoAgAiAEUNBSADQQxqIAMoAgQgAygCCCAAKAIQEQMADAULIAcgAUHE08oAEIwQAAsgBCAIQaTTygAQjBAACyAEIAhBtNPKABCMEAALIAggAkGU08oAEIwQAAtBzNTKABCuFwALQQIhBAsgA0FAayQAIAQLxw0CB38BfiMAQaAGayIDJAAgAQJ/AkACQAJAAkACQAJAAkACQAJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgAS0AmANBAWsOAwYCAQALIAEgASgCkAMiBDYClAMgAUEoaiIHIAFBKPwKAAAgAUEAOgBYIAEgBDYC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KAIAQQVPBEAgA0EANgKwAiADQQE2AqQCIANB0JrCADYCoAIgA0IENwKoAiADQdiawgA2AsgBIANBGjYCxAEgA0HomsIANgLAASADQRo2ArwBIANB6JrCADYCuAEgA0GgAmpBBSADQbgBahDDCgtBHiEEQdDQ5gAoAgBBBEkNASADQQA2ArACIANBATYCpAIgA0Gsm8IANgKgAiADQgQ3AqgCIANBtJvCADYCyAEgA0EaNgLEASADQeiawgA2AsABIANBGjYCvAEgA0HomsIANgK4ASADQaACakEEIANBuAFqEMMKDAELIANB8ABqIAcpAwA3AgAgA0H4AGogBikDADcCACADIAU2AmQgAyADKQNINwJoIANBoAJqIgUgA0HkAGoQlRAgAy0AoAIiBEEwRwRAIANBiQRqIAVBAXJBJ/wKAAAgA0HIA2ogA0HIAmpBwAD8CgAADAELIANBkAFqIANBtAJqKQIANwMAIANBiAFqIANBrAJqKQIANwMAIAMgAykCpAIiCDcDgAECQAJAAkBBBSAIpyIEQYCAgIB4cyAEQQBOGw4CAAECCyADQcADaiADQYwBaigCADYCACADIAMpAoQBNwO4AyADQaACaiADQbgDahDwFQJ/IAMtAKACQQhGBEAgAyADKAKkAjYCuAEgA0G4AWoQtRVBHwwBCyADQagEaiADQbgCaikDADcAACADQaAEaiADQbACaikDADcAACADQZgEaiADQagCaikDADcAACADIAMpA6ACNwCQBEEwCyEEIAMoAoABQYKAgIB4SA0CIANBgAFqEL0NDAILIANBoAFqIANBjAFqKAIANgIAIAMgAykChAE3A5gBAkAgASgCICIFKALgAiIEBEAgA0GkAWogA0GYAWogBEEIahC8AiADKAKkAUGAgICAeEYNASABKAIgIQVBDEEEEJ8bIgRBCGogA0GsAWooAgA2AgAgBCADKQKkATcCACADQQE2AqgCIAMgBDYCpAIgA0EBNgKgAiADQbgBaiIGIAVB0AJqIANBoAJqIgQQugEgAy0AuAFBMEYNASAEIAZB6AD8CgAAQdDQ5gAoAgBBAUsEQCADQQE2ApADIANB3JvCADYCjAMgA0IBNwKYAyADQQI2ArQBIAMgA0GwAWo2ApQDIAMgBDYCsAEgA0Hkm8IANgK0AyADQRo2ArADIANB6JrCADYCrAMgA0EaNgKoAyADQeiawgA2AqQDIANBjANqQQIgA0GkA2oQwwoLIANBoAJqEOEJDAELQQxBBBCfGyIEQQhqIANBoAFqKAIANgIAIAQgAykDmAE3AgAgA0EBNgKoAiADIAQ2AqQCIANBATYCoAIgA0G4AWoiBiAFQdACaiADQaACaiIEELoBIAMtALgBQTBGDQAgBCAGQegA/AoAAEHQ0OYAKAIAQQFLBEAgA0EBNgKQAyADQdybwgA2AowDIANCATcCmAMgA0ECNgKoASADIANBpAFqNgKUAyADIAQ2AqQBIANB9JvCADYCtAMgA0EaNgKwAyADQeiawgA2AqwDIANBGjYCqAMgA0HomsIANgKkAyADQYwDakECIANBpANqEMMKCyADQaACahDhCQsgAygCgAEhBAsgBEGCgICAeE4EQCADQYABahC9DQtBACEEDAELCyABEPQWCyAAIAQ6AAAgAEEBaiADQYkEakEn/AoAACAAQShqIANByANqQcAA/AoAAEEBCzoAXSADQbAEaiQAC+sNAgV/AX4jAEGwBGsiAyQAIAECfwJAAn8CQAJAAkACQAJAIAEtAF1BAWsOAwIAAwELAAsgASABKAJYIgU2AiBBJyEEIAUoAqgFQQJGDQIMBAtBjJrCABC1FwALQQEMAQsgASAFQawFajYCJCADQQhqIAUpA9gEIAUoAuAEEJ8PIAFBEGogA0EYaikDADcDACABQQhqIANBEGopAwA3AwAgASADKQMINwMAIAEgATYCKEEACyEEA0AgBEUEQCABQQA6AFwgA0EkaiIEIAEoAiBBmAVqENIkIAEoAiQhBSABQSxqIgYgBEEk/AoAACABIAU2AlQgASABQShqNgJQIAEgBjYCHCABIAFB3ABqNgIYQQEhBAwBCyADQaACaiABQRhqIAIQ+QUgAygCoAIiBUEHRgRAIABBMToAAEEDDAMLIANB2ABqIgYgA0G0AmopAgA3AwAgA0HQAGoiByADQawCaikCADcDACADIAMpAqQCNwNIIAFBLGoQrxpBKyEEAkACQAJAAkBBAiAFQQNrIAVBAk0bQQFrDgMDAgABCyADQQA2ArACIANBATYCpAIgA0G8nMIANgKgAiADQgQ3AqgCIANBoAJqQcScwgAQ9xgAC0HQ0OYAKAIAQQVPBEAgA0EANgKwAiADQQE2AqQCIANB0JrCADYCoAIgA0IENwKoAiADQdiawgA2AsgBIANBGjYCxAEgA0HomsIANgLAASADQRo2ArwBIANB6JrCADYCuAEgA0GgAmpBBSADQbgBahDDCgtBHiEEQdDQ5gAoAgBBBEkNASADQQA2ArACIANBATYCpAIgA0Gsm8IANgKgAiADQgQ3AqgCIANBtJvCADYCyAEgA0EaNgLEASADQeiawgA2AsABIANBGjYCvAEgA0HomsIANgK4ASADQaACakEEIANBuAFqEMMKDAELIANB8ABqIAcpAwA3AgAgA0H4AGogBikDADcCACADIAU2AmQgAyADKQNINwJoIANBoAJqIgUgA0HkAGoQlRAgAy0AoAIiBEEwRwRAIANBiQRqIAVBAXJBJ/wKAAAgA0HIA2ogA0HIAmpBwAD8CgAADAELIANBkAFqIANBtAJqKQIANwMAIANBiAFqIANBrAJqKQIANwMAIAMgAykCpAIiCDcDgAECQAJAAkBBBSAIpyIEQYCAgIB4cyAEQQBOGw4CAAECCyADQcADaiADQYwBaigCADYCACADIAMpAoQBNwO4AyADQaACaiADQbgDahDwFQJ/IAMtAKACQQhGBEAgAyADKAKkAjYCuAEgA0G4AWoQtRVBHwwBCyADQagEaiADQbgCaikDADcAACADQaAEaiADQbACaikDADcAACADQZgEaiADQagCaikDADcAACADIAMpA6ACNwCQBEEwCyEEIAMoAoABQYKAgIB4SA0CIANBgAFqEL0NDAILIANBoAFqIANBjAFqKAIANgIAIAMgAykChAE3A5gBAkAgASgCICIFKAKABSIEBEAgA0GkAWogA0GYAWogBEEIahC8AiADKAKkAUGAgICAeEYNASABKAIgIQVBDEEEEJ8bIgRBCGogA0GsAWooAgA2AgAgBCADKQKkATcCACADQQE2AqgCIAMgBDYCpAIgA0EBNgKgAiADQbgBaiIGIAVBhAVqIANBoAJqIgQQugEgAy0AuAFBMEYNASAEIAZB6AD8CgAAQdDQ5gAoAgBBAUsEQCADQQE2ApADIANB3JvCADYCjAMgA0IBNwKYAyADQQI2ArQBIAMgA0GwAWo2ApQDIAMgBDYCsAEgA0Hkm8IANgK0AyADQRo2ArADIANB6JrCADYCrAMgA0EaNgKoAyADQeiawgA2AqQDIANBjANqQQIgA0GkA2oQwwoLIANBoAJqEOEJDAELQQxBBBCfGyIEQQhqIANBoAFqKAIANgIAIAQgAykDmAE3AgAgA0EBNgKoAiADIAQ2AqQCIANBATYCoAIgA0G4AWoiBiAFQYQFaiADQaACaiIEELoBIAMtALgBQTBGDQAgBCAGQegA/AoAAEHQ0OYAKAIAQQFLBEAgA0EBNgKQAyADQdybwgA2AowDIANCATcCmAMgA0ECNgKoASADIANBpAFqNgKUAyADIAQ2AqQBIANB9JvCADYCtAMgA0EaNgKwAyADQeiawgA2AqwDIANBGjYCqAMgA0HomsIANgKkAyADQYwDakECIANBpANqEMMKCyADQaACahDhCQsgAygCgAEhBAsgBEGCgICAeE4EQCADQYABahC9DQtBACEEDAELCyABEPQWCyAAIAQ6AAAgAEEBaiADQYkEakEn/AoAACAAQShqIANByANqQcAA/AoAAEEBCzoAXSADQbAEaiQAC+sNAgV/AX4jAEGwBGsiAyQAIAECfwJAAn8CQAJAAkACQAJAIAEtAF1BAWsOAwIAAwELAAsgASABKAJYIgU2AiBBJyEEIAUoAqgFQQJGDQIMBAtBgMLCABC1FwALQQEMAQsgASAFQawFajYCJCADQQhqIAUpA9gEIAUoAuAEEJ8PIAFBEGogA0EYaikDADcDACABQQhqIANBEGopAwA3AwAgASADKQMINwMAIAEgATYCKEEACyEEA0AgBEUEQCABQQA6AFwgA0EkaiIEIAEoAiBBmAVqENIkIAEoAiQhBSABQSxqIgYgBEEk/AoAACABIAU2AlQgASABQShqNgJQIAEgBjYCHCABIAFB3ABqNgIYQQEhBAwBCyADQaACaiABQRhqIAIQ+QUgAygCoAIiBUEHRgRAIABBMToAAEEDDAMLIANB2ABqIgYgA0G0AmopAgA3AwAgA0HQAGoiByADQawCaikCADcDACADIAMpAqQCNwNIIAFBLGoQrxpBKyEEAkACQAJAAkBBAiAFQQNrIAVBAk0bQQFrDgMDAgABCyADQQA2ArACIANBATYCpAIgA0GwxMIANgKgAiADQgQ3AqgCIANBoAJqQbjEwgAQ9xgAC0HQ0OYAKAIAQQVPBEAgA0EANgKwAiADQQE2AqQCIANBxMLCADYCoAIgA0IENwKoAiADQczCwgA2AsgBIANBGjYCxAEgA0HcwsIANgLAASADQRo2ArwBIANB3MLCADYCuAEgA0GgAmpBBSADQbgBahDDCgtBHiEEQdDQ5gAoAgBBBEkNASADQQA2ArACIANBATYCpAIgA0Ggw8IANgKgAiADQgQ3AqgCIANBqMPCADYCyAEgA0EaNgLEASADQdzCwgA2AsABIANBGjYCvAEgA0HcwsIANgK4ASADQaACakEEIANBuAFqEMMKDAELIANB8ABqIAcpAwA3AgAgA0H4AGogBikDADcCACADIAU2AmQgAyADKQNINwJoIANBoAJqIgUgA0HkAGoQlRAgAy0AoAIiBEEwRwRAIANBiQRqIAVBAXJBJ/wKAAAgA0HIA2ogA0HIAmpBwAD8CgAADAELIANBkAFqIANBtAJqKQIANwMAIANBiAFqIANBrAJqKQIANwMAIAMgAykCpAIiCDcDgAECQAJAAkBBBSAIpyIEQYCAgIB4cyAEQQBOGw4CAAECCyADQcADaiADQYwBaigCADYCACADIAMpAoQBNwO4AyADQaACaiADQbgDahDwFQJ/IAMtAKACQQhGBEAgAyADKAKkAjYCuAEgA0G4AWoQtRVBHwwBCyADQagEaiADQbgCaikDADcAACADQaAEaiADQbACaikDADcAACADQZgEaiADQagCaikDADcAACADIAMpA6ACNwCQBEEwCyEEIAMoAoABQYKAgIB4SA0CIANBgAFqEL0NDAILIANBoAFqIANBjAFqKAIANgIAIAMgAykChAE3A5gBAkAgASgCICIFKAKABSIEBEAgA0GkAWogA0GYAWogBEEIahC8AiADKAKkAUGAgICAeEYNASABKAIgIQVBDEEEEJ8bIgRBCGogA0GsAWooAgA2AgAgBCADKQKkATcCACADQQE2AqgCIAMgBDYCpAIgA0EBNgKgAiADQbgBaiIGIAVBhAVqIANBoAJqIgQQugEgAy0AuAFBMEYNASAEIAZB6AD8CgAAQdDQ5gAoAgBBAUsEQCADQQE2ApADIANB0MPCADYCjAMgA0IBNwKYAyADQQI2ArQBIAMgA0GwAWo2ApQDIAMgBDYCsAEgA0HYw8IANgK0AyADQRo2ArADIANB3MLCADYCrAMgA0EaNgKoAyADQdzCwgA2AqQDIANBjANqQQIgA0GkA2oQwwoLIANBoAJqEMADDAELQQxB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IAUoAkQgCEEUbGoiBkEINgIEIAZB/MrCADYCACAGIAQpAiA3AgggBkEQaiAEQShqKAIANgIAIAUgCEEBaiIGNgJICyAEQQhqIAlB8MzCACAFKAJEIAYQrBYgBCgCCCEGIAUgBCgCDCIINgI0IAUgBjYCMAsgBEEgaiAGIAIgCCgCDBEDACAFAn8gBCgCIEECRgRAIAdBAjYCAEEDDAELIAcgBEEgakHgAPwKAAAgBUEwahD+FSAFQUBrEOggQQELOgBMIARBEGoQ3g0gBEGQAWokAAwCCyAEQYgBaiAEQSxqKAIANgIAIAQgBCkCJDcDgAFB8M3CAEErIARBgAFqQeDNwgBBmMzCABCpDgALQYjNwgAQtRcACyADKALAASICQQJHDQMgAEECNgIAQQMMBwsgAUEAOgBsIAEgBDYCXCABIAU2AlggASALNwNIIAEgDDcDQCABQewAaiEFIAFBQGshBgsgASkDSCELIAEpA0AhDCABKAJYIQgCQCABKAJcIgkEQEEUQQQQnxshBCADQcwAaiIHEMgNIANBwAFqIAkgBxC7GCADKALAAUEBRg0FIANBEGogA0HMAWooAgAiCTYCACADIAMpAsQBIg03AwggBEEPNgIEIARB1NjCADYCACAEIA03AgggBEEQaiAJNgIAIAFBATYCaCABIAQ2AmQgAUEBNgJgIAcQ9iAMAQsgAUEANgJoIAFCgICAgMAANwNgCwJAIAynRQRAIAEoAmghBAwBCyADIAs3AwggA0HAAWogA0EIahD6FiABKAJoIgcgASgCYEYEQCABQeAAakHk2MIAEI4UCyABKAJkIAdBFGxqIgRBCDYCBCAEQdjWwgA2AgAgBCADKQLAATcCCCAEQRBqIANByAFqKAIANgIAIAEgB0EBaiIENgJoCyADIAhBnNnCACABKAJkIAQQrBYgAygCACEEIAFB6NXCADYCVCABIAQ2AlBB6NXCAAshByADQcABaiAEIAIgBygCDBEDACADKALAASICQQJHDQEgBUEDOgAAIABBAjYCAEEEDAQLIANB5ABqIANBwAFqQQRyQdwA/AoAACAFEOwgDAILIANB5ABqIANBwAFqQQRyQdwA/AoAACABQdAAahD+FSABQeAAahDoICABQQE6AGwgBhDOGgwBCyADQRBqIANBzAFqKAIANgIAIAMgAykCxAE3AwhB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ARDtDCADQcgBaiIEQbDTwgBBLPwKAAAgA0EgaiAGIAQQghYCQAJAQdjK5gAoAgBBAUsNAEG0x+YAEO4aQf8BcSIERQ0AQbTH5gAoAgAgBBDVFUUNAEG0x+YAKAIAIgtBHGohCiALKAIgIgcEQCALKAIoIQYgCygCJCEEIAsoAhwhCCADQQA2AtgBIAMgBjYC1AEgAyAENgLQASADIAc2AswBCyADIAg2AsgBIANBzABqIgYgA0HIAWoiBEHc08IAEKoUIANB3NLCADYCxAEgA0EBNgLMASADQYzUwgA2AsgBIANCATcC1AEgA0HjADYCiAEgAyAENgLAASADIAY2ArwBIAMgA0GEAWo2AtABIAMgA0EgajYChAEgA0GcAWogCiADQbwBahD9HSADQZgBaiADQaQBaigCADYCACADIAMpApwBNwOQAUG0x+YAKAIAIANBkAFqIgoQ9xdB4NDmAC0AAA0BQdDQ5gAoAgBBBEkNASADQQQ2AvQBIANBtMfmACgCACIHKQIUNwL4ASADQRhqEMYZIAMoAhgiBiADQfQBaiADKAIcIgQoAgwRAABFDQEgA0GIAmogA0H8AWooAgA2AgAgAyADKQL0ATcDgAIgByAGIAQgA0GAAmogChD3CQwBC0Hg0OYALQAADQBB0NDmACgCAEEESQ0AIANBBDYCeCADQbTH5gAoAgAiCSkCFDcCfCADQRBqEMYZIAMoAhAiDCADQfgAaiADKAIUIgsoAgwRAABFDQBBtMfmACgCACIXQRxqIQogFygCICIHBEAgFygCKCEGIBcoAiQhBCAXKAIcIQggA0EANgLYASADIAY2AtQBIAMgBDYC0AEgAyAHNgLMAQsgAyAINgLIASADQcwAaiIGIANByAFqIgRB3NPCABCqFCADQdzSwgA2AvwBIANBATYCzAEgA0GM1MIANgLIASADQgE3AtQBIANB4wA2AqABIAMgBDYC+AEgAyAGNgL0ASADIANBnAFqNgLQASADIANBIGo2ApwBIANBvAFqIgQgCiADQfQBahD9HSADQYgCaiADQYABaigCADYCACADIAMpAng3A4ACIAkgDCALIANBgAJqIAQQ9wkLIANByAFqIANBIGoiBBD4DSADQYQBaiAEELIHIAMtANABIQQgAygCiAEhByADKAKEASEGAkACQAJAIAMoAsgBIAMoAswB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CCADKQIUNwIAIAhBCGogA0EcaigCADYCAAsgA0HgAGokAAwBCyAEIAMoAlhBuN/HABD2GwALIAEtABgiA0H/AUYNAyABIANBAWo6ABggARCUByEDIAJBMGogAkEgaikDADcDACACIAM2AjggAiACKQMYIg03AyggDadBlYCAgHhHBEAgA0UEQCACQRBqIAJBIGopAwA3AwAgAiACKQMYNwMIDAYLIAJBlYCAgHg2AgggAiADNgIMIAJBKGoQxA0MBQsgAiACKAIsNgIMIAJBlYCAgHg2AgggA0UNBCACQThqEJcODAQLIAJBGGogAUEBELYjIAIpAxhCA1EEQCAAIAIoAiA2AgQgAEGVgICAeDYCAAwICyACQTBqIAJBIGopAwA3AwAgAiACKQMYNwMoIAJBCGogAkEoahCIFSACKAIIQZWAgIB4RgRAIAEgAigCDBChJSEBIABBlYCAgHg2AgAgACABNgIEDAgLIAAgAikDCDcDACAAQQhqIAJBEGopAwA3AwAMBwtB7PHHABCuFwALQfzxxwAQtBcAC0H88ccAEK4XAAsgAigCCEGVgICAeEYNACAAIAIpAwg3AwAgAEEIaiACQRBqKQMANwMADAMLIAEgAigCDBChJSEBIABBlYCAgHg2AgAgACABNgIEDAILIABBlYCAgHg2AgAgACADNgIEDAELIAAgAigCIDYCBCAAQZWAgIB4NgIACyACQUBrJAALgwsCCn8BfiAERQRAIABBADYCPCAAIAM2AjggACACNgI0IAAgATYCMCAAQQA6AA4gAEGBAjsBDCAAIAI2AgggAEIANwMADwtBASEMQQEhCQJAAkACQAJAAkACQAJAAkAgBEEBRwRAQQEhBUEBIQcDQCAGIAtqIgkgBE8NAiAHIQgCQCADIAVqLQAAIgcgAyAJai0AACIFSQRAIAYgCGpBAWoiByALayEMQQAhBgwBCyAFIAdHBEBBASEMIAhBAWohB0EAIQYgCCELDAELQQAgBkEBaiIHIAcgDEYiBRshBiAHQQAgBRsgCGohBwsgBiAHaiIFIARJDQALQQEhBUEBIQdBACEGQQEhCQNAIAYgCmoiDSAETw0DIAchCAJAIAMgBWotAAAiByADIA1qLQAAIgVLBEAgBiAIakEBaiIHIAprIQlBACEGDAELIAUgB0cEQEEBIQkgCEEBaiEHQQAh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AWoiATYCFCABIARHDQALCyADQQM2AkQgA0EgaiAHENQQIANBxABqIAMoAiAgAygCJBDyFCEBDAoLQQgLNgJEIAMgBxDUECADQcQAaiADKAIAIAMoAgQQ8hQhAQwICyADQRE2AkQgA0EIaiAHENQQIANBxABqIAMoAgggAygCDBDyFCEBDAcLIAJBOkcEQCADQQY2AkQgA0EYaiAHENQQIANBxABqIAMoAhggAygCHBDyFCEBDAcLIAFBf0YNByAAIAFBAWoiATYCFAtBASEJIAEgBEkNAwwECwJAIAMgCEH/AXEiAEHbAEcEfyAAQfsARw0BQQMFQQILNgJEIANBMGogBxDUECADQcQAaiADKAIwIAMoAjQQ8hQhAQwFC0Ggm8kAQShByJvJABCcFQALQQAhAQwDCyAAIAFBAWoiATYCFCABIARHDQALCyADQQU2AkQgA0EoaiAHENQQIANBxABqIAMoAiggAygCLBDyFCEBCyADQdAAaiQAIAEPC0HUnckAEK4XAAurDAIKfwF+IwBBwANrIgMkACABAn8CQAJAAn8CQAJAAkACfwJAAkACQCABLQANQQFrDgQEAAIGAQsACyABQQA6AAwgAUEANgIEIAEgASgCCCIENgIAIANBCGogBEEAIAQQxBEgAygCCCEEIAFB/KzFADYCFCABIAQ2AhBB/KzFAAwBCyABKAIQIQQgASgCFAshBSADQbgBaiAEIAIgBSgCDBEDACADKAK4ASIJQQJHDQEgAEECNgIAQQMMBgtB5K/FABC1FwALIAMoArwBIQogA0EQaiIMIANBwAFqQcgA/AoAACADKAKUAiEHIAMoApACIQUgAygCjAIhBCADKAKIAiEIIAFBEGoQ/hUgCUEBcQRAIANB6AJqIAxByAD8CgAAQQEhAgwECyABQSBqIANBEGpByAD8CgAAIAEgBTYCGCABIAQ2AhQgASAINgIQIAFBAToADAJAIAUgB0cEQCABKAIEIgRBf0YNASABIARBAWoiBTYCBEEADAMLIANB6AJqIANBEGpByAD8CgAAQQAhAgwDC0H0r8UAEK4XAAsgASgCbCELIAEoAmghBkEBCyEEA0ACQAJAIARFBEAgAyABKAIAIAUgBBDEESADKAIAIQZB/KzFACELIAFB/KzFADYCbCABIAY2AmgMAQsgA0G4AWogBiACIAsoAgwRAwAgAygCuAEiCUECRgRAIABBAjYCAEEEDAYLIAMoArwBIQogA0GgAmoiDCADQcABakHIAPwKAAAgAykDmAIhDSADKAKUAiEHIAMoApACIQUgAygCjAIhBCADKAKIAiEIIAFB6ABqEP4VIAlBAXEEQCADQegCaiAMQcgA/AoAAAwCCyADQdgAaiIJIANBoAJqQcgA/AoAACADIA03A7ABIAMgBzYCrAEgAyAFNgKoASADIAQ2AqQBIAMgCDYCoAEgA0GgAWohBwJAAkACQCABQSBqIgogCRDFCUUEQCADQcgBaiABKAIAEJgYIgJBEGoQ1g8gA0H0AWogAkE8aikCADcCACADQfwBaiACQcQAai0AADoAACADIAIpAjQ3AuwBIAMgAikCKDcC4AEgAyACKQIgNwLYASADIAIoAjA2AugBIAMgAigCHDYC1AEgAyACKQIINwLAASADIAIpAgA3ArgBIANBtANqQRtBAEEBQQEQogsgAygCuAMhCCADKAK0A0EBRg0BIAMoArwDIgRBF2pB96zFACgAADYAACAEQRBqQfCsxQApAAA3AAAgBEEIakHorMUAKQAANwAAIARB4KzFACkAADcAACADQegCaiADQbgBakHIAPwKAAAgAygCqAEiBgRAIAMoAqQBIQUDQCAFEN4ZIAVBoAJqIQUgBkEBayIGDQALCyAHQRBBoAIQrg5BGyEFQREhCgwFCyADQbgBaiAHEOsDIAMoArwBIQggAygCwAEiBCABKAIQIAEoAhgiBWtLBEAgAUEQaiAFIARBEEGgAhDMFCABKAIYIQULIARBoAJsIgkEQCABKAIUIAVBoAJsaiAIIAn8CgAACyABIAEoAhggBGo2AhggA0EANgLAASADQbgBakEQQaACEK4OIAEoAhggAygCrAFJBEAgASgCBCIEQX9GDQIgASAEQQFqNgIEIAMoAqgBIgUEQCADKAKkASEEA0AgBBDeGSAEQaACaiEEIAVBAWsiBQ0ACwsgB0EQQaACEK4OIAEoAgQhBQwDCyADKAKoASIFBEAgAygCpAEhBANAIAQQ3hkgBEGgAmohBCAFQQFrIgUNAAsLIAdBEEGgAhCuDiABKAIYIQUgASgCFCEEIAEoAhAhCCADQegCaiAKQcgA/AoAAEEAIQIgAUEAOgAMDAcLIAggAygCvANBrLbFABD2GwALQZSw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BEGsBWogBhCHFyABQcwAaiADQcgBaigCADYCACABQcQAaiADQcABaikCADcCACABQTxqIANBuAFqKQIANwIAIAEgAykCsAE3AjQLIANBgANqIAFBNGoiBSACEKUJIAMoAoADIgRBkICAgHhHDQEgAEExOgAAQQQMBgsgA0EnOgDoAwwDCyADQfgAaiIGIANBlANqKAIANgIAIANB8ABqIgcgA0GMA2opAgA3AwAgAyADKQKEAzcDaCAFEJMeIARBj4CAgHhHBEAgA0GUAWogBigCADYCACADQYwBaiAHKQMANwIAIAMgAykDaDcChAEgAyAENgKAASADQegDaiADQYABahC1EgwDCyADQZgBaiABKAIsIgQpA9gEIAQoAuAEEJ8PIAEgAUFAazYCOCABQdAAaiADQagBaikDADcDACABQcgAaiADQaABaikDADcDACABIAMpA5gBNwNAQQAhBAwBCyADQQ46AOgDDAELA0AgBEUEQCABQQA6ADQgAUEAOgC9ASABIAFB2ABqNgLEASABIAFBNGo2AsABIAEgASgCLDYCuAEgASABQThqNgJYQQEhBAwBCyADQYADaiABQcABaiACEPQBIAMtAIADIgRBNEYEQCAAQTE6AABBBQwECyADQZkCaiADQYADakEBckHnAPwKAAAgAUHgAGoQoBsCQAJAAkACQEEBIARBMWsgBEEwTRtB/wFxQQFrDgICAAELIANBADYCkAMgA0EBNgKEAyADQbycwgA2AoADIANCBDcCiAMgA0GAA2pB6KXCABD3GAALIANBKzoAsAEMAQsgBEEwRwRAIAMgBDoAsAEgA0GwAWpBAXIgA0GZAmpB5wD8CgAADAELIANBmANqIANBuAJqKQAANwMAIANBkANqIANBsAJqKQAANwMAIANBiANqIANBqAJqKQAANwMAIAMgAykAoAIiCDcDgAMgCKdB/wFxQQRHBEAgA0HQAWogA0GgAmoiAkEYaikAADcDACADQcgBaiACQRBqKQAANwMAIANBwAFqIAJBCGopAAA3AwAgA0EwOgCwASADIAIpAAA3A7gBDAELIANBgANqEOkVQQAhBAwBCwsCQCABLQAxRQ0AIANBgANqIgQgASgCLBD+BiADLQCAAyICQTBGDQAgA0HoA2pBAXIgBEEBckHnAPwKAAAgAyACOgDoAyADQbABahDw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AkACQAJAAkACQCABLQCEAkEBaw4DBAIBAAsgASABKALQASIENgLUASAEKAKoBSIFQQJGDRAgBUEBSwRAQSchBAwSCyABQdgBaiIFIARBqAVqIgRBLPwKAAAgBEEFNgIAIAEoAtgBQQJJBEAgA0GkAWogBUEs/AoAACABIANBCGpBygH8CgAAIAFBADoAygEgAUHKAWohBgwFC0HIxMIAQShB8MTCABCcFQALIAFBygFqIQYgAS0AygFBAWsOAwEABAMLAAtByL/CABC1FwALQYDFwgAQtRcACyABQegAaiABQZwBakEs/AoAACABQQE6AMkBIAEgASgCjAE2ApQBIAFBAToAyAEgAyABKAKQASIINgK8AiADQagDaiABQZQBahCtHyADLQCoAyIEQTJGDQggA0GmA2oiByADLQCrAzoAACADIAMvAKkDOwGkAyADKAKsAyEFIANBwAJqIANBsANqQeAA/AoAACABIAQ6AAAgASADLwGkAzsAASABQQNqIActAAA6AAAgASAFNgIEIAFBCGoiByADQcACakHgAPwKAAACQCAEQTBrDgIGAAILIAFBADoAyAEgCBDYFw0IIAFBADoAyQEgASABKAKUATYCmAELIANBqANqIAFBmAFqIgQgAhD7HiADLQCoAyICQTJGDQMgA0H2BGogAy0AqwM6AAAgAyADLwCpAzsB9AQgAygCrAMhBSADQZAEaiADQbADakHgAPwKAAAgBBD4GEEdIQQgAkEwaw4CAggBCyADQd4FaiABQQFqIgJBAmotAAA6AAAgAyACLwAAOwHcBSADQfgEaiAHQeAA/AoAAAwHCyADQd4FaiADQfYEai0AADoAACADIAMvAfQEOwHcBSADQfgEaiADQZAEakHgAPwKAAAMBAsgA0HYAmoiAiABQYgBaigCADYCACADQdACaiIEIAFBgAFqKQIANwMAIANByAJqIgYgAUH4AGopAgA3AwAgAyABKQJwNwPAAiADQagDaiADQcACaiAFEMUQIAMoAqgDIgVFDQIgA0H4BGogA0GsA2pBOPwKAAAgAUEAOgDIASABQQA6AMkBQTAhBAwGCyAGQQM6AAAgAEExOgAAQQMMCAsgA0EANgK4AyADQQE2AqwDIANBsL/CADYCqAMgA0IENwKwAyADQagDakG4v8IAEPcYAAsgAiADQcQDaikCADcD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BCACQgY3AlQgAkEGNgJMIAJBmJvUADYCSCACIAJBFGo2AlAgAkHIAGoQqQQMBgsgAUHIm9QAQRcQ6B4MBQsgAiAAQQRqNgJEIAJBnAw2AkwgAiACQcQAajYCSCABKAIAIAEoAgQgAkIBNwIgIAJBATYCGCACQeib1AA2AhQgAiACQcgAajYCHCACQRRqEKkEDAQLIAIgADYCRCACQZ0MNgJMIAIgAkHEAGo2AkggASgCACABKAIEIAJCATcCICACQQE2AhggAkHwm9QANgIUIAIgAkHIAGo2AhwgAkEUahCpBAwDCyACIABBBGo2AkQgAkGvCzYCTCACIAJBxABqNgJIIAEoAgAgASgCBCACQgE3AiAgAkEBNgIYIAJB8JvUADYCFCACIAJByABqNgIcIAJBFGoQqQQMAgsgAiAAQQRqNgJEIAJBngw2AkwgAiACQcQAajYCSCABKAIAIAEoAgQgAkIBNwIgIAJBATYCGCACQfCb1AA2AhQgAiACQcgAajYCHCACQRRqEKkEDAELIAIgAEEEajYCRCACQZ8MNgJMIAIgAkHEAGo2AkggASgCACABKAIEIAJCATcCICACQQE2AhggAkHwm9QANgIUIAIgAkHIAGo2AhwgAkEUahCpBAsgAkHgAGokAAvwFAEDfyMAQTBrIgMkAAJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQEECIAAtAAAiAkEwayACQS9NG0H/AXFBAWsOEAECAwQFBgcICQoLDA0ODxAACyADIABBCGo2AhQgA0H/AjYCCCADIANBFGo2AgQgASgCACABKAIEIANCATcCJCADQQE2AhwgA0Gs28QANgIYIAMgA0EEajYCICADQRhqEKkEDBALIAMgAEEEajYCFCADQYADNgIIIAMgA0EUajYCBCABKAIAIAEoAgQgA0IBNwIkIANBATYCHCADQeDbxAA2AhggAyADQQRqNgIgIANBGGoQqQQMDwsgAyAANgIUIANB8gE2AgggAyADQRRqNgIEIAEoAgAgASgCBCADQgE3AiQgA0EBNgIcIANBiNzEADYCGCADIANBBGo2AiAgA0EYahCpBAwOCyADIABBCGo2AhQgA0GBAzYCCCADIANBFGo2AgQgASgCACABKAIEIANCATcCJCADQQE2AhwgA0Gs3MQANgIYIAMgA0EEajYCICADQRhqEKkEDA0LIAMgAEEEajYCFCADQYIDNgIIIAMgA0EUajYCBCABKAIAIAEoAgQgA0IBNwIkIANBATYCHCADQazcxAA2AhggAyADQQRqNgIgIANBGGoQqQQMDAsgAyAAQQRqNgIUIANB8AE2AgggAyADQRRqNgIEIAEoAgAgASgCBCADQgE3AiQgA0EBNgIcIANB3NzEADYCGCADIANBBGo2AiAgA0EYahCpBAwLCyADIABBBGo2AhQgA0GDAzYCCCADIANBFGo2AgQgASgCACABKAIEIANCATcCJCADQQE2AhwgA0GM3cQANgIYIAMgA0EEajYCICADQRhqEKkEDAoLIAMgAEEEajYCACADIABBEGo2AhQgA0GEAzYCECADQRA2AgggAyADQRRqNgIMIAMgAzYCBCABKAIAIAEoAgQgA0ICNwIkIANBAjYCHCADQazdxAA2AhggAyADQQRqNgIgIANBGGoQqQQMCQsgAUG83cQAQSkQ6B4MCAsgAyAAQQRqNgIUIANBEDYCCCADIANBFGo2AgQgASgCACABKAIEIANCATcCJCADQQI2AhwgA0Gc3sQANgIYIAMgA0EEajYCICADQRhqEKkEDAcLIAMgAEEEajYCFCADQRA2AgggAyADQRRqNgIEIAEoAgAgASgCBCADQgE3AiQgA0ECNgIcIANBtN7EADYCGCADIANBBGo2AiAgA0EYahCpBAwGCyADIABBGGo2AgAgAyAAQQRqNgIUIANBhQM2AhAgA0EQNgIIIAMgA0EUajYCDCADIAM2AgQgASgCACABKAIEIANCAjcCJCADQQI2AhwgA0Hs3sQANgIYIAMgA0EEajYCICADQRhqEKkEDAULIAMgAEEEajYCACADIABBEGo2AhQgA0GGAzYCECADQRA2AgggAyADQRRqNgIMIAMgAzYCBCABKAIAIAEoAgQgA0ICNwIkIANBAjYCHCADQaTfxAA2AhggAyADQQRqNgIgIANBGGoQqQQMBAsjAEEwayICJAACfwJAAkACQAJAAkACQAJAIABBBGoiACgCAEEBaw4GAQIDBAUGAAsgAiAAQQRqNgIMIAJBiwQ2AhQgAiACQQxqNgIQIAEoAgAgASgCBCACQgE3AiQgAkEBNgIcIAJBuIDFADYCGCACIAJBEGo2AiAgAkEYahCpBAwGCyACIABB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QQE2AhggAkG0pMgANgIUIAIgAkHIAGo2AhwgAkEUahCpBAwDCyACIABBBGo2AkQgAkG0BTYCTCACIAJBxABqNgJIIAEoAgAgASgCBCACQgE3AiAgAkEBNgIYIAJB/KTIADYCFCACIAJByABqNgIcIAJBFGoQqQQMAgsgAiAAQQRqNgJEIAJBuwc2AkwgAiACQcQAajYCSCABKAIAIAEoAgQgAkIBNwIgIAJBATYCGCACQailyAA2AhQgAiACQcgAajYCHCACQRRqEKkEDAELIAIgAEEEajYCRCACQRA2AkwgAiACQcQAajYCSCABKAIAIAEoAgQgAkIBNwIgIAJBATYCGCACQbClyAA2AhQgAiACQcgAajYCHCACQRRqEKkECyACQeAAaiQAC4ULAgx/BH4jAEGQAmsiAyQAAkACQAJAAkAgACkDkAEiD0L/////////H1gEQCAPUA0BIANCgAggD3qGIhE3AwACQAJAIAApA4ABIhAgACkDkAEiEloEQCAQIBJ9IhBC/////////x9WDQEgEEIKhiISIAAxAIgBhCAAMQCJAUIGhnwiECASWg0CQfD44AAQrhcAC0Hw+OAAELQXAAtB8PjgABCwFwALIBAgEVYNAiACrSARIBB9WA0BIAMgD0IKhjcD8AEgAyACNgIMIANBBDYCFCADQcD34AA2AhAgA0IDNwIcIANBCjYClAEgA0EGNgKMASADQQY2AoQBIAMgA0GAAWo2AhggAyADQQxqNgKQASADIAM2AogBIAMgA0HwAWo2AoABIANBEGpB4PfgABD3GAALQej24AAQsBcACyAAQSBqIQ4CQAJAAkACQAJAAkAgAC0AiAEgAC0AiQFBBnRqIgQEQCAEQYAISw0JIA4gASACQYAIIARrIgQgAiAESRsiBhCxByEHIAIgBmsiAkUNASADQcgBaiIJIABB6ABqKQMANwMAIANB0AFqIgwgAEHwAGopAwA3AwAgA0HYAWoiBSAAQfgAaikDADcDACADIAApA2A3A8ABIAAtAIgBIQggACkDgAEhDyAALQCKASEKIAAtAIkBIQsgA0GAAWoiBCAHQcAA/AoAACADIAogC0VyQQJyOgDpASADIA83A+ABIAMgCDoA6AEgA0EQaiIIIAQQug0gACAAKQOAARD0BCAAQZgBaiAIQYD54AAQ6gogACkDgAEiD0J/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BSALNgIADAILQQRBoAMQ4SMACyAFIAQ2AgwgBSADNgIIIAUgBjYCBCAFQQo2AgALIAhBkAdqJAAgB0EIaiICIAdBIGooAgA2AgAgByAHKQIYNwMAIAcoAhQiA0EKRwRAIAcoAiQhCCAKIAcpAwA3AgggCiAINgIUIAogAzYCBCAKQQk2AgAgCkEQaiACKAIANgIADAQLIAogBykDADcCBCAKQQg2AgAgCkEMaiACKAIANgIADAMLIApCiYCAgMABNwIADAILIAMgBygCHEG0rdMAEPYbAAsgCiAHKQMANwIEIApBCTYCACAKQRRqIAMoAgA2AgAgCkEMaiACKQMANwIACyANEPMhIAdBQGskACAPQRBqIQIgDygCHEEJRgRAIA9BkAFqIgMgD0EwaigCADYCACAPQZwBaiACQQhqKAIANgIAIBcgDykCIDcCBCAXQQo2AgAgF0EMaiAPQShqKQIANwIAIA8gAikCADcClAEgF0EUaiADKQMANwIAIBdBHGogD0GYAWopAwA3AgAMAgsgD0HIAGoiAyAPQRxqQSz8CgAAIA9B/ABqIAJBCGooAgA2AgAgDyACKQIANwJ0IBcgA0E4/AoAAAwBCyAXQQk2AgALIA9BoAFqJAAgEUGYAWoiAiAoKQIANwMAIBFBoAFqIgggLCkCADcDACARQagBaiIGIC0pAgA3AwAgESARKQK0ATcDkAEgESgCsAEiA0EKRgRAIBkgESkDkAE3AgQgGUEHNgIAIBlBHGogBikDADcCACAZQRRqIAgpAwA3AgAgGUEMaiACKQMANwIADAELIBFBmAJqIBFB5AFqKAIANgIAIBFBkAJqIBFB3AFqKQIANwMAIBFB8AFqIAIpAwA3AwAgEUH4AWogEUGgAWopAwA3AwAgEUGAAmogEUGoAWopAwA3AwAgESARKQLUATcDiAIgESARKQOQATcD6AEgEUEKNgKwASADQQlGBEAgGSARQbABakEk/AoAAAwBCyARQYgBaiARQZQCaikCADcCACARIBEpAowCNwKAASARQbABahDeCyARQdwAaiARQegBakEk/AoAACARIAM2AlggEUEsaiICIBFB2ABqQSz8CgAAIBFBhAFqEPcgIwBBEGsiHSQAIB1BBGoiJCEDIwBB0ABrIggkAAJAAkACQAJAAkACQAJAQQEgAigCACIGQQZrIAZB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BEAgASgCKCAFRw0BCyAAIAMgBGoiATYCCCABIARPIQILIABBfyADIARqIgEgASAESRs2AgBBBAwKCyAAQoCAgIAQNwIADAgLIARBACAEQQJHGwsiBSACaiIDIAMgBUkbIQQgAyAFTyEFDAULQQEhBQJAIANBAXEEQCABKAI0IAEoAjBrIQIgBEECRw0BIAIiBCEDDAYLIARBACAEQQJHGyIEIQMMBQtBfyACIARqIgMgAiADSxshBCACIANNIQUMBAsgAS0AQCEFIANBAkYNASABLQA8IQIgBUECRwRAQX8gBQJ/IANBAXEEQCABKAI0IAEoAjBrIgMgAkECRg0BGkF/QX8gAiADaiIEIAMgBEsbIgEgBWoiAiABIAJLGyEBIAMgBE0gBCAFaiICIARPcSEEDAULIAJBACACQQJHGwsiA2oiAiACIANJGyEBIAIgA08hBAwDC0EBIQQCQCADQQFxBEAgASgCNCABKAIwayEDIAJBAkcNASADIgEhAgwECyACQQAgAkECRxsiASECDAMLQX8gAiADaiICIAIgA0kbIQEgAiADTyEEDAILQQEhBSACQQAgAkECRxsiBCEDDAILQQEhBCAFQQAgBUECRxsiASECCyAAIAQ2AgQgACABNgIADAELIAAgBSABKAIkIgJFIAEoAiggAkZycSABKAIQIAEoAghrQQAgASgCBBsiBSABKAIgIAEoAhhrQQAgASgCFBtqIgEgBU9xIAEgA2oiAiADT3E2AgQgAEF/IARBfyABIAEgBUkbaiIBIAEgBEkbNgIAC0EICyAAaiACNgIAC/4HAQV/IwBB0ABrIgIkACACIAE2AhACQAJAIAEQtCVBAUcEQCACQRBqIAJBFGpB6OnDABCrBCEDIABBgICAgHg2AgAgACADNgIEIAFBhAFJDQEgARChFgwBCyACQRRqIgMgAUHA9cQAQQMQkBogAkGAgICAeDYCKCACQYCAgIB4NgI0IAJBQGsgAxCFBwJAAkACQCACLQBARQRAQQAhAQNAAkACQAJAAkACQAJAAkACQAJAIAItAEFBAWsOBAIDAAQBCyACQQhqIAJBFGoQvhUMBwsgAUEBcQ0DIAIoAhQgAkEANgIURQ0NIAJBQGsgAigCGBC0FiACLQBABEAgAigCRCEBIABBgICAgHg2AgAgACABNgIEDAoLIAItAEEhBkEBIQEMBgsgAigCKEGAgICAeEYNBEH76MMAQQoQkREhASAAQYCAgIB4NgIAIAAgATYCBAwICyACKAI0QYCAgIB4Rg0CQYXpwwBBBRCRESEBIABBgICAgHg2AgAgACABNgIEDAcLQQEhAyABQQFxRQRAQfTowwBBBxCQESEBIABBgICAgHg2AgAgACABNgIEDAgLIAIoAigiAUGAgICAeEYhAyABQYCAgIB4RgRAQfvowwBBChCQESEBIABBgICAgHg2AgAgACABNgIEDAgLIAJByABqIAJBMGoiASgCADYCACACIAIpAig3A0AgAigCNCIEQYCAgIB4RgRAQYXpwwBBBRCQESEBIABBgICAgHg2AgAgACABNgIEIAJBQGsQ8yEMCAsgACACKQIoNwIAIAAgBjoAGCAAIAIpAjg3AhAgACAENgIMIABBCGogASgCADYCAAwIC0H06MMAQQcQkREhASAAQYCAgIB4NgIAIAAgATYCBAwFCyACKAIUIAJBADYCFARAIAJBQGsgAigCGBCFCiACKAJEIQMgAigCQCIEQYCAgIB4RgRAIABBgICAgHg2AgAgACADNgIEDAYLIAIoAkghBSACQTRqEJUcIAIgBTYCPCACIAM2AjggAiAENgI0DAILDAgLIAIoAhQgAkEANgIUBEAgAkFAayACKAIYEIUKIAIoAkQhAyACKAJAIgRBgICAgHhGBEAgAEGAgICAeDYCACAAIAM2AgQMBQsgAigCSCEFIAJBKGoQlRwgAiAFNgIwIAIgAzYCLCACIAQ2AigMAQsMBwsgAkFAayACQRRqEIUHIAItAEBFDQALCyACKAJEIQEgAEGAgICAeDYCACAAIAE2AgQLQQEhAwsgAigCNEGAgICAeEcEQCACQTRqEPMhCyADIAIoAihBgICAgHhHcUUNACACQShqEPMhCyACQRRqEMsXCyACQdAAaiQADwtBiOjEAEExENgjAAuLCAINfwR+IwBBMGsiByQAIAEQ9AICQAJAIAEoAhQiCyACSwRAIAEoAhAiDCACQQN0aiIDKAIEIQQgAyABKAIYNgIEIAMoAgAhBSADQQA2AgACQCAFQQFGBEAgASACNgIYIAQgASgCCCIDTw0BIAEoAgQiCSAEQQV0aiICKQMAIRIgAkEIaiIFKAIAIQ0gASADQQFrIgY2AgggB0EQaiIOIAJBFGoo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IAFBIGoiBCADKQMoIgk3AwAgBEEIaiIGIANBMGopAwA3AwAgCadBDkYNASADQUBrIAYpAwA3AwAgAyAEKQMANwM4IANBgAFqIANBOGoQrQ4MAwtBpNHDABC1FwALIAEgASkCJDcCjAEgAUGUAWogAUEsaigCADYCACADIAc2AhwgA0EDOgAYIAMgAUGMAWoiBjYCJCADIANBGGoQiAkCQAJAIAMoAgBFBEAgASADKQMINwMQIAFBADYCCCABQRhqIANBEGopAwA3AwAMAQsgAUEIaiIEIAMpAwAiCTcDACAEQRBqIgggA0EQaikDADcDACAEQQhqIANBCGopAwA3AwAgCacNAQsgA0FAayABQRhqKQMANwMAIAMgASkDEDcDOCADQYABaiADQThqEK0OIAYQyhcMAgsgASAEKQMANwNoIAFB+ABqIAgpAwA3AwAgAUHwAGogBEEIaikDADcDAAsgA0E4aiABQegAaiACEKcQIAMoAjgiAkEPRgRAIABBCDYCAEEDDAULIAMoAkQhByADKAJAIQQgAygCPCEFIAFB7ABqEKUQAkAgAkEORwRAIAMgBzYCRCADIAQ2AkAgAyAFNgI8IAMgAjYCOCADQYABaiADQThqEK0ODAELIAMgBDYCiAEgAyAFNgKEASADQQc2AoABCyABQYwBahDKFyABQZgBahDvECABKAKIASICQYMBSw0CDAMLIAUQ7xALIAcoAgAiAkGDAU0NAQsgAhChFgsgACADKQKAATcCACAAQQhqIANBiAFqKQIANwIAQQELOgDMASADQZABaiQAC90IAQh/IwBBMGsiBCQAIAEoAgAhByABQQA2AgACQAJAAkACQAJAAkACQAJAIAdFBEAgASgCCCEHIAFBADYCCAJAAkACQAJAAkAgB0EBcUUEQCABKAIUIgIgASgCGEYNAiABIAJBAWo2AhQgASgCHCIHQX9GDQcgASAHQQFqNgIcDAELIAEoAgwiAkUNASABKAIQIQcLIAFBCGohAwJAIAItAAAiBUHbAGsOAwIAAwALIAEtACgNAwwKCyAAQQg2AgAMCwsgBEEgaiEIQQAhAkEAIQUgAygCACEGIANBADYCAAJAAkACQAJAAkAgBkEBcUUEQCADKAIMIgYgAygCEEYNAiADIAZBAWo2AgwgAygCFCICQX9GDQQgAyACQQFqNgIUDAEL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G0H/AXEODwABAggICAwOAwoICAgMBAgLIABBDGoQyhoPCyAAQQxqEPgSDwsgAEEMahD4Eg8LIABBDGoQmAQPCwwFCyAAKAIEDQIgACgCCEUNAiAAQQhqEP4VDwsgAEEEahDzIQwECyAAKAIEQQBIDQAgAEEEahDzIQsPCyAAQQRqIQAMAwsgAEEMaiEADAILIABBEGohAAwBCyAAQRBqENsQDwsgABDzIQ8LAkACQAJAAkAgAEEIaiIALQAADgQAAQMCAwsgAEEEahCYBAwCCyAAQQhqEOQGDAELIABBCGoQiQMLC5UHAgZ/AX4jAEGQA2siAyQAIAECfwJAAkACQAJAAkAgAS0AmANBAWsOAwMAAgELAAsgASABKAKQAyIENgKUAyABQShqIAFBKPwKAAAgAUEAOgBYIAEgBDYCUAsgA0GYAWogAUEoaiIEIAIQlAMgAy0AmAEiAkExRw0BIABBMToAAEEDDAILQYClwgAQtRcACyADQegAaiIFIANBmAFqQQFyQSf8CgAAIANBKGoiBiADQcABakHAAPwKAAAgBBC3EgJAIAJBMEcEQCADQagCaiAFQSf8CgAAIANBzwJqIAZBwAD8CgAADAELIANBIGogA0GHAWopAAA3AwAgA0EYaiADQf8AaikAADcDACADQRBqIANB9wBqKQAANwMAIAMgAykAbyIJNwMIAkAgCadB/wFxIgIEQCACQQZHBEAgA0GwAWogA0HvAGoiAUEYaikAADcDACADQagBaiABQRBqKQAANwMAIANBoAFqIAFBCGopAAA3AwAgAyABKQAANwOYASADQYQCaiADQZgBaiIBEOADIANBnwJqIANBjAJqKAIANgAAIAMgAykChAI3AJcCIAMgAykAlAI3A6gCIAMgA0GbAmopAAA3AK8CIAEQ6RVBJiECDAMLIANBowFqIANB+wBqKAAANgAAIAMgAykAczcAmwEgAyADKQCYATcDqAIgAyADQZ8BaikAADcArwJBDyEEDAELIAMgAy0ACSIFOgCPASADIAMpAxAiCTcDkAEgA0GYAWoiBiABKAKUAyADLQAKIgcgAy0ACyIIEOABQTAhBCADLQCYASICQTBHBEAgA0GoAmogBkEBckHnAPwKAAAgAy0ACEEGRg0CIANBCGoQ6RUMAgsgASgClAMgBToA1gUgASgClANBkAVqIAkQ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DAsLIAIgAEEEajYCDCABQezmyABBHEGI58gAQQkgAEEIakHM5sgAQZHnyABBBiACQQxqQdzmyAAQggsMCgsgAiAAQQhqNgIMIAFBuOfIAEEYQdDnyABBAyAAQQRqQZjnyABB0+fIAEEGIAJBDGpBqOfIABCCCwwJCyACIABBCGo2AgwgAUHZ58gAQR1BiOfIAEEJIABBDGpBzObIAEH258gAQQggAEEEakGY58gAQdPnyABBBiACQQxqQajnyAAQuwoMCAsgAiAAQRRqNgIMIAFB/ufIAEEcQdPnyABBBiAAQQRqQZjnyABBmujIAEEGIABBCGpBmOfIAEGg6MgAQQ4gAEEMakGY58gAQa7oyABBByAAQRBqQZjnyABBxubIAEEGIAJBDGpBoObIABDJCQwHCyABQbXoyABBHBDoHgwGCyABQdHoyABBIhDoHgwFCyABQfPoyABBIhDoHgwECyABQZXpyABBFxDoHgwDCyABQazpyABBIxDoHgwCCyABQc/pyABBKBDoHgwBCyABQffpyABBDxDoHgsgAkEQaiQAC8kFAQd/IwBBEGsiBiQAIAFBGGohCCABKAIYIQICQAJAAkACQAJAAkACQEF/An8CQCABKAIAIgVBA0cEQCACRQ0EIAEtABQhBCAFQQJGDQUgAS0AECECIARBAkYNAyAFQQFxRQ0BIAEoAgggASgCBGsiAyACQQJGDQIaQX9BfyACIANqIgEgASADSRsiAiAEaiIFIAIgBUsbIQIgASADTyABIAEgBGoiAU1xIQcMCAsgAgRAIAAgCBDkGgwJCyAAQQA2AgggAEKAgICAEDcCAAwICyACQQAgAkECRxsLIgMgBGoiASABIANJGyECIAEgA08hBwwFC0EBIQcCQCAFQQFxBEAgASgCCCABKAIEayEDIAJBAkcNASADIgIhAQwGCyACQQAgAkECRxsiAiEBDAULQX8gAiADaiIBIAEgA0kbIQIgASADTyEHDAQLIAEtABQhAiAFQQJGDQEgAS0AECEDIAJBAkcEQEF/IAICfyAFQQFxBEAgASgCCCABKAIEayIEIANBAkYNARpBf0F/IAMgBGoiASABIARJGyIDIAJqIgUgAyAFSxshAyABIARPIAEgASACaiIBTXEhBAwFCyADQQAgA0ECRxsLIgRqIgEgASAESRshAyABIARPIQQMAwtB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QCADQQA6AIECCyALQQFxRQ0AIANBADoAggILQZWDwgAMAQtBvOnKAAstAABBAUYNACADKAJ4IQICQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCADKAJsQQFrDhEBAgMEBQYHCAkKCwwNDg8REAALIANBADYCsAEgAigCAEEBRwRAIANB64DCADYCBAwWCyADKAJIIgFFBEAgA0EBIAIoAggiASABQQFNGyIBNgJICyADKAJQIgJBCmtBeE8NE0ECIQIgA0ECNgJQDBMLIAMgAkEBEOgCDRMMFQsgAyACQQAQ6AJFDRQMEgsgGCgCACIBIBsoAgBGBH8gHiAYIBsQ1gogGCgCAAUgAQtBBDYCACADIAMoAmhBBGo2AmggAyACQQFBAEEAQQAQzAFFDRMMEQsgAigCAEEERwRAIANBxYHCADYCBAwSC0G86coAIQEgAxDbDkUNEyACLQAIRQRAIANBxYLCAEEBQQBBABClDUUNFCADQQA2ArABIAMQ2w4NDwwUCyADKAKwAUUNDQwOCyADIAJBARCHBkUNEQwPCyADIAJBABCHBkUNEAwOCyADIAJBARDcBEUNDwwNCyADIAJBABDcBEUNDgwMCyADIAJBARDGC0UNDQwLCyADIAJBABDGC0UNDAwKCyADIAJBARCTCUUNCwwJCyADIAJBABCTCUUNCgwICyADIAJBARDcB0UNCQwHCyADIAJBABDcB0UNCAwGCyADIAJBARDjDEUNBwwFCyADQYGCwgA2AgQMBQsgAyACQQAQ4wxFDQUMAwsgA0EBNgKwAQsgAxC/A0UNBCADQQI2AmwgAygClAEiASADKAKMAUYNAQNAIAMgAUEIayICNgKUASABQQRrKAIAIQEgAigCACICBEAgAkEIayICIAIoAgBBCBCfIAsgAQRAIAFBCGsiASABKAIAQQgQnyALIAMoApQBIgEgAygCjAFHDQALDAELAkAgAyADKAJUIgVBAEgEf0H/////BwUgBSACQQF0Sw0BQdAACzYCVAsgAygCXEUEQCADQQI2AlwLIANBgQI7AawBIANCADcCpAEgA0F/NgKYASABQQFHBEBBvOnKACEBAn8gAygCLCADKAIwQQVqTQRAQbzpygAgAxC/A0UNARoLQZWDwgALLQAABH9BvOnKAAUg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ayISKAIAQYCAgIB4RwRAIAtBLGogEhDWDwwBCyALQYCAgIB4NgIsCyALQagCaiALQTRqKAIANgIAIAsgCykCLDcDoAIgDUGOAmsvAQAhHyANQZACay8BACEcIAspAgwhKiALKAIIIRgLIAtBLGoiICANQeQBa0HAAfwKAAAgC0EgaiIdIA1BJGsiEkEYaikCADcDACALQRhqIh4gEkEQaikCADcDACALQRBqIiEgEkEIaikCADcDACALIBIpAgA3AwggDUEEayISLwAAISIgEkECai0AACESIA5BCGogDUGIAmsiDUEIaikBADcBACAOQRBqIA1BEGopAQA3AQAgDkEYaiANQRhqKQEANwEAIA0pAQAhLSALQZgCaiIjIAtBqAJqKAIANgIAIA4gLTcBACALIAspA6ACNwOQAiAaaiINQaQCayAqNwIAIA1BqAJrIBg2AgAgDUGsAmsgGzYCACANQYwCayAZOwEAIA1BjgJrIB87AQAgDUGQAmsgHDsBACANQZwCayIYIAspA5ACNwIAIBhBCGogIygCADYCACANQYoCayALQe4BakEi/AoAACANQegBayAXNgIAIA1B5AFrICBBwAH8CgAAIClCAX0iKiApgyEpIA1BBGsiGEECaiASOgAAIBggIjsBACANQSRrIg1BGGogHSkDADcCACANQRBqIB4pAwA3AgAgDUEIaiAhKQMANwIAIA0gCykDCDcCACAGQQFrIgYNAAsLIAwgCTYCDCAMIBAoAgg2AgggC0GwAmokACAVQQhqIAxBCGopAgA3AgAgFSAMKQIANwIACyAMQRBqJAAgFSAsNwMYIBUgKzcDECAKQShqIBNByAH8CgAAIBMgAhCGBiMAQcAFayIGJAAgBkEQaiIIIBNBqAL8CgAAIAZBuAJqIhEgFSAGKAJQIgkgCBDJBAJAIAYoArgCQYKAgIB4SA0AIBEQ/CIgBigCxAJBgICAgHhGDQAgBkHEAmoQ8yELIwBBMGsiCCQAIAhBIGpB/IvUABDZFiAIQQhqIgtBwIfUACkDADcDACAIQRhqIgwgCCkDKDcDACAIQRBqIg0gCCkDIDcDACAIQbiH1AApAwA3AwAgCCAJEKEFGiAGQbgCaiIRQRhqIAwpAwA3AwAgEUEQaiANKQMANwMAIBFBCGogCykDADcDACARIAgpAwA3AwAgCEEwaiQA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KAIANgIADAQLIA9BmAVqIgYgD0GQAmopAwA3AwAgDyAPKQOIAjcDkAUgD0G8BGogIEEk/AoAACAPQeAEaiAiQTD8CgAAIA8oApwEIgMgDygClARGBEAjAEEQayICJAAgAkEIaiAPQZQEaiIHIAcoAgBBAUEIQegAEKAHIAIoAggiB0GBgICAeEcEQCAHIAIoAgxBhKXDABD2GwALIAJBEGokAAsgDygCmAQgA0HoAGxqIgIgDykDkAU3AwAgAiAENgIQIAJBCGogBikDADcDACACQRRqIA9BvARqQST8CgAAIAJBOGogD0HgBGpBMPwKAAAgDyADQQFqNgKcBCAPKAKkBCECIA8oAqwEIQQMAAsACyAIIA8oApACQfSkwwAQ9hsACyAPQZQEaiIAEKwOIAAQ9CALIA9BIGoQyxMgD0FAaxDLEyAPQeAAahDLEyAPQYABahDLEyAPQaABahDLEyAPQcABahDLEyAPEIwTIA9BoAVqJAALyQkCHn8CfiMAQcAFayICJAAgASgCBCEWIAIgASgCCCIOQQhBgANBoKHDABCREiAOQYADbCEXIAJBEGohDyACQaQFaiEQIAJBmAVqIRggAkHsAmohESACKAIEIRIgAkEYaiEZIAIoAgAiGiENAkADQCANRSAKIBdGckUEQCACQfgCaiEHQQAhBiMAQbABayIDJAAgCiAWaiIFQRBqIgEoAgQhGyADQQhqIAEoAggiC0EAQQRB2AAQogsgAygCDCEBAkACQCADKAIIQQFHBEAgAygCECEMAkAgAUUNACALQdgAbCEcIANB0ABqIRMgA0HsAGohHSADQZABaiIUQQhqIR4gASEIA0AgBiAcRg0BIB0gBiAbaiIEQRBqENYPIBQgBEE0aikCADcCACAeIARBPGopAgA3AgAgFEEQaiAEQcQAai0AADoAACADIARBKGopAgA3AoQBIAMgBEEgaikCADcCfCADIARBMGooAgA2AowBIAMgBEEcaigBADYCeCADIAQoAgA2AlwgAyAEQQxqKAIANgJoIAMgBEEEaikCADcCYAJAIARByABqIgkoAgBBgICAgHhHBEAgA0GkAWogCRD5BgwBCyADQYCAgIB4NgKkAQsgBEHUAGooAgAiBCAEKAIAIglBAWo2AgAgCUEASA0DIANBCGoiCSADQdwAakHIAPwKAAAgE0EIaiAD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IAEgAmpBAWstAABB3QBGDQELIABBgwg7AQAMAQsCQCACQQFrIgVFDQAgASwAAUG/f0wNACADQQhqIAFBAWogAkECaxCtAiAAAn8gAy0ACEEBRgRAIAAgAy0ACToAAUEDDAELIAAgA0EJaiIBKQAANwABIABBCWogAUEIaikAADcAAEECCzoAAAwBCyABIAJBASAFQeDh1QAQlB8ACyADQdAAaiQAC70FAQF/IwBBMGsiAiQAAn8CQAJAAkACQAJAAkACQAJAIAAtAABBAWsOBwECAwQFBgcACyACIABBBGo2AhQgAkGODjYCCCACIAJBFGo2AgQgASgCACABKAIEIAJCATcCJCACQQE2AhwgAkGM294ANgIYIAIgAkEEajYCICACQRhqEKkEDAcLIAFBlNveAEETEOgeDAYLIAIgAEEEajYCFCACQY4ONgIIIAIgAkEUajYCBCABKAIAIAEoAgQgAkIBNwIkIAJBATYCHCACQcDb3gA2AhggAiACQQRqNgIgIAJBGGoQqQQMBQsgAiAAQQRqNgIUIAJBjg42AgggAiACQRRqNgIEIAEoAgAgASgCBCACQgE3AiQgAkEBNgIcIAJB4NveADYCGCACIAJBBGo2AiAgAkEYahCpBAwECyACIABBCGo2AgAgAiAAQQRqNgIUIAJBjw82AhAgAkHJCTYCCCACIAJBFGo2AgwgAiACNgIEIAEoAgAgASgCBCACQgI3AiQgAkECNgIcIAJBjNzeADYCGCACIAJBBGo2AiAgAkEYahCpBAwDCyACIABBBGo2AhQgAkHJCTYCCCACIAJBFGo2AgQgASgCACABKAIEIAJCATcCJCACQQE2AhwgAkG03N4ANgIYIAIgAkEEajYCICACQRhqEKkEDAILIAIgAEEEajYCACACIABBDGo2AhQgAkHJCTYCECACQY4ONgIIIAIgAjYCDCACIAJBFGo2AgQgASgCACABKAIEIAJCAjcCJCACQQI2AhwgAkHc3N4ANgIYIAIgAkEEajYCICACQRhqEKkEDAELIAIgAEEBajYCFCACQYYKNgIIIAIgAkEUajYCBCABKAIAIAEoAgQgAkIBNwIkIAJBATYCHCACQYTd3gA2AhggAiACQQRqNgIgIAJBGGoQqQQLIAJBMGokAAvCBgECfyMAQRBrIgIkAAJ/AkACQAJAAkACQAJAAkAC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/gODIAtCOIiEhIQ3AAAgA0EIaiIDQcAARw0ACyAFQUBrIgEgAkHAAPwKAAAgBSABQcAA/AoAACMAQTBrIggkACAIQQxqIQkgBSEBQQAhBCMAQbABayICJAAgAkEEakEAQcAA/AsAA0AgAkEEaiAEQQJ0aiIKKAIAIQYgASEDQQAhBwNAIAMtAAAgB3QgBnIhBiADQQFqIQMgB0EIaiIHQSBHDQALIAogBjYCACABQQRqIQEgBEEBaiIEQRBHDQALIAIgAigCBCIBQf////8BcTYCRCACIAIoAggiA0EDdCABQR12ckH/////AXE2AkggAiACKAIMIgFBBnQgA0EadnJB/////wFxNgJMIAIgAigCECIDQQl0IAFBF3ZyQf////8BcTYCUCACIAIoAhQiAUEMdCADQRR2ckH/////AXE2AlQgAiACKAIYIgNBD3QgAUERdnJB/////wFxNgJYIAIgAigCHCIBQRJ0IANBDnZyQf////8BcTYCXCACIAIoAiAiA0EVdCABQQt2ckH/////AXE2AmAgAiACKAIkIgRBGHQgA0EIdnJB/////wFxNgJkIAIgAigCQCIDQQ12NgKIASACIAIoAigiAUECdkH/////AXE2AmwgAiABQRt0IARBBXZyQf////8BcTYCaCACIAIoAiwiBEEBdCABQR92ckH/////AXE2AnAgAiACKAIwIgFBBHQgBEEcdnJB/////wFxNgJ0IAIgAigCNCIEQQd0IAFBGXZyQf////8BcTYCeCACIAIoAjgiAUEKdCAEQRZ2ckH/////AXE2AnwgAiACKAI8IgRBDXQgAUETdnJB/////wFxNgKAASACIANBEHQgBEEQdnJB/////wFxNgKEASACQYwBaiIBIAJBxABqIgQiA0HY4OEAEM8BIAMgAUEk/AoAACABIgMgAkHoAGoiAUG04OEAEM8BIAEgA0Ek/AoAACAJIAEgBBDnCyACQbABaiQAIAAgCRDgBSAIQTBqJAAgBUHAAmokAA8LQdTW4QAQsBcAC0Hk1uEAELAXAAvmBQEDfyMAQSBrIgMkACAAAn8CQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIAEOKAIBAQEBAQEBAQMFAQEEAQEBAQEBAQEBAQEBAQEBAQEBAQEIAQEBAQcACyABQdwARg0FCyACQQFxRSABQf8F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IANBBzoAQCADQUBrIAEgAhDaDQwLCyAEQfQARg0JIARB+wBGDQILIARBMGtB/wFxQQpJDQULIANBCjYCQCADQQhqIABBDGoQ1BAgA0FAayADKAIIIAMoAgwQ8hQMCAsgA0ELOgBAIANBQGsgASACENoNDAcLIAAgBUEBajYCFCAAQdenyABBBBDXCSIEDQcgA0EAOwFAIANBQGsgASACENoNDAYLIAAgBUEBajYCFCADQUBrIABBABDrBCADKQNAQgNRDQIgA0EYaiADQcgAaikDADcDACADIAMpA0A3AxAgA0EQaiABIAIQ0w8MBQsgAEEANgIIIAAgBUEBajYCFCADQTRqIABBDGogABCSBSADKAI4IQQgAygCNEECRg0FIAMgAygCPDYCSCADIAQ2AkQgA0EFOgBAIANBQGsgASACENoNDAQLIANBQGsgAEEBEOsEIAMpA0BCA1INAQsgAygCSCEEDAMLIANBKGogA0HIAGopAwA3AwAgAyADKQNANwMgIANBIGogASACENMPDAELIAAgBUEBajYCFCAAQdSnyABBAxDXCSIEDQEgA0GAAjsBQCADQUBrIAEgAhDaDQsgABCbDyEECyADQdAAaiQAIAQL9wQBA38jAEHQAGsiAyQAAkACfwJAAkACQAJAAkACQAJAAkAgACgCFCIFIAAoAhBJBEACQCAAKAIMIAVqLQAAIgRB5QBNBEAgBEEiRg0GIARBLUYNBSAEQdsARw0BIANBCjoAQCADQUBrIAEgAhDaDQwLCyAEQfMATQRAIARB5gBGDQQgBEHuAEcNASAAIAVBAWo2AhQgAEGFm8kAQQMQ1wkiBA0MIANBBzoAQCADQUBrIAEgAhDaDQwLCyAEQfQARg0JIARB+wBGDQILIARBMGtB/wFxQQpJDQULIANBCjYCQCADQQhqIABBDGoQ1BAgA0FAayADKAIIIAMoAgwQ8hQMCAsgA0ELOgBAIANBQGsgASACENoNDAcLIAAgBUEBajYCFCAAQYubyQBBBBDXCSIEDQcgA0EAOwFAIANBQGsgASACENoNDAYLIAAgBUEBajYCFCADQUBrIABBABDsBCADKQNAQgNRDQIgA0EYaiADQcgAaikDADcDACADIAMpA0A3AxAgA0EQaiABIAIQ0w8MBQsgAEEANgIIIAAgBUEBajYCFCADQTRqIABBDGog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AgsACyABKAIAIQVBEEEEEIQhIgZFBEBBBEEQEOEjAAsgBkEAOgAMIAYgBTYCACADQQhqIgVBtNTDADYCBCAFIAY2AgAgAygCCCEEIAFBtNTDADYCCCABIAQ2AgRBtNTDAAshBSADQRBqIAQgAiAFKAIMEQMAIAMtABAiBEHCAEcNASAAQcIAOgAAQQMMAgtB5NTDABC1FwALIAMvASIhDSADLQAhIQkgAykAGSERIAMtABghDiADLQAXIQYgAy0AFiEPIAMtABUhCiADLQAUIQIgAy0AEyELIAMtABIhBSADLQARIQwgA0H8AGoiByADQSRqQdQA/AoAACABQQRqEP4VAkACQCAEQcEARwRAIANB3AFqIAdB1AD8CgAADAELIAMgCToA2AEgAyARNwPQASADQRBqQRFBAEEBQQEQogsgAygCFCEIIAMoAhBBAUcEQCADKAIYIgFBCGpBpNTDACkAADcAACABQZzUwwApAAA3AAAgAUEQakGs1MMALQAAOgAAIANBETYCHCADIAE2AhggAyAINgIUIANBADYCEAJ/IAxBAXFFBEBBPiEEQQAhASADKQAVIRFBACEHQQAMAQsgEachCCADKQDRASERIANBFGoQ8yFBwQAhBCAOIQEgBiEHIAohECAFIQwgDwshCkEAIQ1BACEJDAILIAggAygCGEGk2cMAEPYbAAsgDyEHIAIhECALIQIgBiEBIAUhCyAOIQgLIAAgDTsBEiAAIAk6ABEgACARNwAJIAAgCDoACCAAIAE6AAcgACAHOgAGIAAgCjoABSAAIBA6AAQgACACOgADIAAgCzoAAiAAIAw6AAEgACAEOgAAIABBFGogA0HcAWpB1AD8CgAAQQELOgAMIANBsAJqJAALiwUBAX8jAEEwayICJAACfwJAAkACQAJAAkACQAJAAkACQAJAAkACQCAAKAIAQQFrDgsBAgMEBQYHCAkKCwALIABBBGogARC1IwwLCyACIABBBGo2AgwgAkG2BzYCFCACIAJBDGo2AhAgASgCACABKAIEIAJCATcCJCACQQE2AhwgAkGMidMANgIYIAIgAkEQajYCICACQRhqEKkEDAoLIABBBGogARCyAgwJCyACIABBBGo2AgwgAkHhCTYCFCACIAJBDGo2AhAgASgCACABKAIEIAJCATcCJCACQQI2AhwgAkHAidMANgIY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QTpHDQAgBEEQaiABEO8CIAQtABANAgsCQCAHBEAgASAHQQFrNgIEIAEgBkEBajYCACAGLQAAQTpGDQELIAEgBzYCBCABIAY2AgAMAwsgBEEQNgIYIARCgYCAgMAANwIQIARBAToAHCAEIARBEGogARDpAiAELwECIQwgBC8BACINQQFHBEAgASAHNgIEIAEgBjYCACANQQFxRQ0DCyAIIAw7AQAgBUEBaiEFIAhBAmohCCAKQQJrIgoNAAsgAyEFDAELIAMgBU0NAkEBIQkgAiAFQQF0aiAEKAARIgFBCHQgAUGA/gNxQQh2cjsBACAFQQFqIgYgA08NASACIAZBAXRqIAFBCHZBgP7/B3EgAUEYdnI7AQAgBUECaiEFCyAAIAk6AAQgACAFNgIAIARBIGokAA8LIAYgA0Gs/+QAEIwQAAsgBSADQZz/5AAQjBAAC60HAyh/BX4CfCABKAKoBSEFIAEoArAFIQYgASgCuAUhByABKALABSEIIAEoApgEIQkgASgCoAQhCiABKAKoBCELIAEoArAEIQwgASgCuAQhDSABKALABCEOIAEoAtAEIQ8gASgC2AQhECABKALgBCERIAEoAugEIRIgASgC8AQhEyABKAL4BCEUIAEoAgghFSABKAIQIRYgASgCGCEXIAEoAiAhGCABKALoAyEZIAEoAvADIRogASgCiAQhGyABKAKQBCEcIAErA6AFIS8gAS8BzAQhHSABKALIBCEeIAEpA4AFISsgASkDiAUhLCABKQOQBSEtIAEoApgFIR8gAS8BnAUhICABKQMAIS4gAS0AKSEhIAEtACghIiABLQAuISMgAS0AKiEkIAEtACwhJSABLQArISYgASsD+AMhMCABLQCABCEnIABBOGohAyMAQcADayICJAAgAUEwaiIELQC0AyEoAkACQCAEKAIQQQFxBH8gAiAEQRRqQaAD/AoAACACQQA2AqgDIAJCgICAgBA3AqADIAJBiKXEADYCsAMgAkKggICADjcCtAMgAiACQaADajYCrAMgAiACQawDahDwBg0BIAIpAqQDISogAigCoAMFQYCAgIB4CyEpIAMgKDoAECADICo3AgQgAyApNgIAIAMgBCgCAEHoB2wgBCgCCEHAhD1uajYCDCACQcADaiQADAELQbClxABBNyACQb8DakGgpcQAQeilxAAQqQ4ACyAA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BEHlAE0EQCAEQSJGDQYgBEEtRg0FIARB2wBHDQEgA0EKOgAwIANBMGogASACENoNDAsLIARB8wBNBEAgBEHmAEYNBCAEQe4ARw0BIAAQxBogAEHEzcoAQQMQugkiAA0MIANBBzoAMCADQTBqIAEgAhDaDQwLCyAEQfQARg0JIARB+wBGDQILIARBMGtB/wFxQQpJDQULIANBCjYCMCAAIANBMGoQyBYMCAsgA0ELOgAwIANBMGogASACENoNDAcLIAAQxBogAEHKzcoAQQQQugkiAA0HIANBADsBMCADQTBqIAEgAhDaDQwGCyAAEMQaIANBMGogAEEAELYjIAMpAzBCA1ENAiADQQhqIANBOGopAwA3AwAgAyADKQMwNwMAIAMgASACENMPDAULIAAQxBogAEEANgIIIANBJGogAEEMaiAAEJ0GIAMoAighACADKAIkQQJGDQUgAyADKAIsNgI4IAMgADYCNCADQQU6ADAgA0EwaiABIAIQ2g0MBAsgA0EwaiAAQQEQtiMgAykDMEIDUg0BCyADKAI4IQAMAwsgA0EYaiADQThqKQMANwMAIAMgAykDMDcDECADQRBqIAEgAhDTDwwBCyAAEMQaIABBx83KAEEDELoJIgANASADQYACOwEwIANBMGogASACENoNCxChJSEACyADQUBrJAAgAAuyBAIFfwR+IwBBgAFrIgIkACACQRhqQgA3AwAgAkEQakIANwMAIAJBCGpCADcDACACQgA3AwAgAkE4akIANwMAIAJBMGpCADcDACACQShqQgA3AwAgAkIANwMgAkAgASkDICIHQv//////////A1gEQCAHQv////////8/Vg0BIAFBKGoiBCABLQBoIgNqIgVBgAE6AAAgA60iCEI7hiAHQgmGIgkgCEIDhoQiCEKA/gODQiiGhCAIQoCA/AeDQhiGIAhCgICA+A+DQgiGhIQgB0IBhkKAgID4D4MgB0IPiEKAgPwHg4QgB0IfiEKA/gODIAlCOIiEhIQhBwJAAkAgA0E/Rg0AIANBP3MiBgRAIAVBAWpBACAG/AsACyADQThxQThGDQAgASAHNwNgIAEgBEEBEL4BDAELIAEgBEEBEL4BIAJBQGsiA0EAQTj8CwAgAiAHNwB4IAEgA0EBEL4BC0EAIQMgAUEAOgBoA0AgAkEgaiADaiABIANqKAIAIgRB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QQxqIAooAgAQhAkgBC0ADEUEQCAFIAQpAA03AAIgBUGAAjsBACAFQRpqIARBJWopAAA3AAAgBUESaiAEQR1qKQAANwAAIAVBCmogBEEVaikAADcAAAwBCyAFIAQoAhA2AgQgBUEBOgAACyAEQTBqJAACfwJAIAMtAJABQQFGBEAgAygClAEhBAwBCyADQbgCaiIEIANBoAFqKQIANwMAIANBwAJqIgUgA0GoAWopAgA3AwAgA0HIAmoiEiADQbABai8BADsBACADIAMpApgBNwOwAgJ/AkAgAy0AkQFBAXEEQCADKAKUASEHIAMvAZIBIQogA0GEAmogEi8BADsBACADQfwBaiAFKQMANwEAIANB9AFqIAQpAwA3AQAgAyADKQOwAjcB7AEgAyAHNgHoASADIAo7AeYBIANBkAFqIQUjAEHgAGsiBCQAIARBPGogA0GIAmoiChCCBQJAIAQtADxBAUYEQCAFIAQoAkA2AgQgBUEBOgAADAELIAQtAD1FBEAgBUEAOwEADAELIARBPGogCigCABD7CCAELQA8RQRAIAUgBC8APTsAAiAFQQRqIAQtAD86AAAgBEEwaiAEQdQAaikCACIcNwMAIARBCGoiCiAEQcwAaikCADcDACAEQRBqIg8gHDcDACAEQRhqIhUgBEHcAGotAAA6AAAgBCAEKQJENwMAIAUgBCgCQDYABSAFQYACOwEAIAUgBCkDADcACSAFQRFqIAopAwA3AAAgBUEZaiAPKQMANwAAIAVBIWogFS0AADoAAAwBCyAEKAJAIQogBUEBOgAAIAUgCjYCBAsgBEHgAGokACADLQCQAUUNASADKAKUAQwCC0EAQcTtxABBzO3EABCBDyEEDAILIANBuAJqIgQgA0GgAWopAgA3AwAgA0HAAmoiBSADQagBaikCADcDACADQcgCaiIKIANBsAFqLwEAOwEAIAMgAykCmAE3A7ACIAMtAJEBQQFxBEAgAygClAEhEiADLwGSASEHIANB4ABqIAovAQA7AQAgA0HYAGogBSkDADcDACADQdAAaiAEKQMANwMAIANBigFqIANB6AFqLQAAOgAAIANB8ABqIANB9QFqKQAANwMAIANB+ABqIANB/QFqKQAANwMAIANBgAFqIANBhQJqLQAAOgAAIAMgAykDsAI3A0ggAyADLwHmATsBiAEgAyADKQDtATcDaCADKADpASEEQQAMAwtBAUHE7cQAQcztxAAQgQ8LIQQgA0HmAWoiBRCjGCAFEKMYC0EBCyEKIAYtABgiBUH/AUYNBCAGIAVBAWo6ABggBhDXBCEFIANBoAFqIANB8ABqKQMANwIAIANBqAFqIANB+ABqKQMANwIAIANBsAFqIANBgAFqLQAAOgAAIANBvwFqIANB0ABqKQMANwAAIANBxwFqIANB2ABqKQMANwAAIANBzwFqIANB4ABqLwEAOwAAIAMgCjoAkAEgAyAENgKUASADIBI2ALMBIAMgBzsAsQEgAyADLwGIATsAkQEgAyADQYoBai0AADoAkwEgAyADKQNoNwKYASADIAMpA0g3ALcBIAMgBTYC1AECQCAKRQRAIAVFDQEgA0GQAWpBAXIiBBCjGCAEEKMYIAQQoxggBSEEDAsLIAVFDQogA0HUAWoQlw4MCgsgA0HGAGogA0GKAWotAAA6AAAgAyADLwGIATsBRAwLCyAGLQAYIgRFDQIgBiAEQQFrIgQ6ABggBEH/AXENASADQRg2ApABIAYgA0GQAWoQyBYLIQQgDUEBOgAADAsLIAYQtxogAyAGNgLcAUEBIRIgA0EBOgDgASADQQA6AOYBIANB5wFqIQUgA0GQAWoiBCADQdwBahDJCiADLQCQAUUEQCADQe4BaiEPIANBmAFqIQogBEEBciEVA0ACQAJAAkACQAJAAkACQAJAIAMtAJEBQQFrDgMCAAMBCyADQdwBahDfGyIERQ0GDA0LIAMtAOYBDQIgA0GQAWohBAJAIANB3AFqKAIAIhMQ7QgiFwRAIARBAToAACAEIBc2AgQMAQsgBCATEIQJCyADLQCQAQ0LIANBrgJqIgQgFUECai0AADoAACADQbgCaiITIApBCGopAgA3AwAgA0HAAmoiFyAKQRBqKQIANwMAIANByAJqIhogCkEYai0AADoAACADIBUvAAA7AawCIAMgCikCADcDsAIgAygClAEhGyADLQDmAQRAIAUQoxggBRCjGAsgBSADLwGsAjsAACAPIAMpA7ACNwAAIAVBAmogBC0AADoAACAPQQhqIBMpAwA3AAAgD0EQaiAXKQMANwAAIA9BGGogGi0AADoAACADQQE6AOYBIAMgGzYA6gEMBQsgBw0CIANBkAFqIQcCQCADQdwBaigCACITEO0IIgQEQCAHQQE6AAAgByAENgIEDAELIwBBQGoiBCQAIARBHGogExD7CEEBIRMCQCAELQAcQQFGBEAgBCgCICEXDAELIAcgBC8AHTsAASAHQQNqIAQtAB86AAAgBEEIaiAEQSxqKQIAIhw3AwAgBEEQaiAEQTRqKQIAIh03AwAgBEEYaiAEQTxqLQAAIhM6AAAgBCAEKQIkIh43AwAgBCgCICEXIAdBIGogEzoAACAHQRhqIB03AgAgB0EQaiAcNwIAIAcgHjcCCEEAIRMLIAcgFzYCBCAHIBM6AAAgBEFAayQACyADLQCQAQ0KIANBqgJqIBVBAmotAAA6AAAgA0HAAmogCkEQaikCACIcNwMAIANBkAJqIApBCGopAgA3AwAgA0GYAmogHDcDACADQaACaiAKQRhqLQAAOgAAIAMgFS8AADsBqAIgAyAKKQIANwOIAiADKAKUASEZQQEhBwwECyADLQDmASIKRQRAQY7txABBCxCeESEEDAMLIANBqAFqIAVBGGopAAA3AwAgA0GgAWogBUEQaikAADcDACADQZgBaiAFQQhqKQAANwMAIAMgBSkAADcDkAEgB0UEQEGZ7cQAQQoQnhEhBCADQZABaiIHEKMYIAcQoxgMAwsgA0GLA2ogA0GqAmotAAA6AAAgA0HYAmogA0GQAmopAwA3AwAgA0HgAmogA0GYAmopAwA3AwAgA0HoAmogA0GgAmotAAA6AAAgA0GOAWogBUECai0AADoAACADIAMvAagCOwCJAyADIAMpA4gCNwPQAiADIAUvAAA7AYwBIAMoAJMBIQQgA0GIA2ogA0GGAmotAAA6AAAgA0GAA2ogA0H+AWopAAA3AwAgA0H4AmogA0H2AWopAAA3AwAgAyADKQDuATcD8AJBACEHDAsLQY7txABBCxCfESEEDAkLQZntxABBChCfESEEDAgLIApBAXMhEgwHCyADQZABaiADQdwBahDJCiADLQCQAUUNAAsLIAMoApQBIQQMBAtBhPHEABC0FwALQfTwxAAQrhcAC0H08MQAELQXAAsgAygClAEhBAsCQCASRQ0AQQEhByADLQDmAUEBcUUNACAFEKMYIAUQoxgMAQtBASEHCyAGLQAYIgVB/wFGDQEgBiAFQQFqOgAYIAYQkQchBSADQaABaiADQfgCaikDADcCACADQagBaiADQYADaikDADcCACAD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CDcDKCACQQI2AjwgAkG0k+YANgI4IAJCAjcCRCAANQIEIQYgAiACQShqrUKAgICA4ACENwMYIAIgBkKAgICA0LMChDcDECACIAJBEGo2AkAgASgCACIEIAEoAgQiBSACQThqEKkERQ0BDAILIAJBAjYCPCACQdiT5gA2AjggAkIBNwJEIAIgADUCBEKAgICA0LMChDcDECACIAJBEGo2AkAgASgCACIEIAEoAgQiBSACQThqEKkEDQELAkAgACgCCCgCACIDRQ0AIANBCkkEQCACIAM2AgwgAiAAKAIMNgIIAkACQCABLQALQRBxBEAgAS8BDiEBDAELIAAoAhAoAgAiAUH//wNLDQELQQEhAyACQQE2AiQgAkHwk+YANgIgIAJBATYCFCACQeiT5gA2AhAgAkECNgIcIAIgAa1CIIY3AzAgAiACQQhqrUKAgICA0LMChDcDKCACIAJBKGo2AhggBCAFIAJBEGoQqQQNAwwCCyACQQA2AkggAkEBNgI8IAJBqJTmADYCOCACQgQ3AkAgAkE4akGwlOYAEPcYAAtBACADQQlBwJTmABCbFQALIAJBATYCPCACQdic5QA2AjggAkIBNwJEIAIgADUCFEKAgICA0LMChDcDECACIAJBEGo2AkAgBCAFIAJBOGoQqQQhAwsgAkHQAGokACADC+IDAQN/IwBBkARrIgMkACABAn8CQAJAAkACQAJAAkACQAJAIAEtAIQCQQFrDgMEAAIBCwALIAEgASgC0AEiBDYC1AEgBCgCkAIiBUECRg0EIAVBAUsEQEEnIQIMBgsgAUHYAWoiBSAEQZACaiIEQSz8CgAAIARBBTYCACABKALYAUECTw0BIANBpAFqIAVBLPwKAAAgASADQQhqQcoB/AoAACABQQA6AMoBCyADQdgBaiABIAIQ/AIgAy0A2AEiAkExRgRAIABBMToAAEEDDAYLIANB6QJqIgQgA0HYAWpBAXJBP/wKAAAgA0HAAmoiBSADQZgCakEo/AoAACABELcXIAJBMEcEQCADQagDaiAFQSj8CgAAIANB0QNqIARBP/wKAAAgASgC2AFBAkkNBSABQdgBahCvCwwFCyABKALYAUEBTQ0CIAFB2AFqEK8LDAILQayewgBBKEHUnsIAEJwVAAtB5J7CABC1FwALQTxBBBCfGyICIANB7AJqQTz8CgAAIAEo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HwwDCyACKAIAQZngxwBBARCPHyADQQE6ABAgAyACNgIMIANBDGpBruDHAEEEQePhxwBBGRDbCyICDQMgAy0AEEUNAiADKAIMKAIAQZjgxwBBARCPHwwCCyACKAIAQZngxwBBARCPHyADQQE6ABAgAyACNgIMIANBDGoiBEGu4McAQQRB/OHHAEEQENsLIgINAiAEQYzixwBBCiABQQRqELANIgINAiAEQZbixwBBBSABQRBqELANIgINAiADLQAQRQ0BIAMoAgwoAgBBmODHAEEBEI8fDAELIAIoAgBBmeDHAEEBEI8fIANBAToAECADIAI2AgwgA0EMakGu4McAQQRBm+LHAEERENsLIgINASADLQAQRQ0AIAMoAgwoAgBBmODHAEEBEI8fC0EAIQILIANBMGokACACBEAgDBDzIQwCCyAGKAIMIQIgBigCCCIDQYCAgIB4Rg0BIAAgBigCEDYCDCAAIAI2AgggACADNgIEIABBgICAgHg2AgACQAJAAkACQAJAAkACQAJAIAEoAgAiAEEfdSAAQf////8Ha3EOCAABAgMEBQcGBwsgARDzISABQQxqEPMhIAFBGGoQ8yEMBgsgASgCBCIAQYgCahDzISAAQZQCahDzISAAQagCQQgQnyAMBQsgAUEEahDzIQwECyABQQRqEPMhIAFBEGoQ8yEMAwsgAUEEahDzISABQRBqEPMhDAILIAFBBGoQ8yEgAUEQahDzIQwBCyABQQRqEPMhIAFBEGoQ8yELIAZBIGokAA8LIAMgBigCHEGE+ccAEPYbAAsgBiACNgIUQdT5xwBBKyAGQRRqQcT5xwBBlPnHABCpDgAL6wMBAn8jAEEwayICJAACfwJAAkACQAJAAkACQAJAAkACQAJAQQYgACgCACIDQfv///8HaiADQYSAgIB4TRtBAWsOCQIDAAQFBgcICQELAAsgAUGUs9QAQRoQ6B4MCAsgAUGus9QAQSUQ6B4MBwsgAkHuDDYCECACIABBBGo2AhQgAiACQRRqNgIMIAEoAgAgASgCBCACQgE3AiQgAkEBNgIcIAJB4LPUADYCGCACIAJBDGo2AiAgAkEYahCpBAwGCyACQe8MNgIQIAIgAEEEajYCFCACIAJBFGo2AgwgASgCACABKAIEIAJCATcCJCACQQE2AhwgAkGAtNQANgIYIAIgAkEMajYCICAC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CyAEQQA2AgggBCAANgIEIAEgAigCEBEEAARAIARBAjYCCAsjAEEgayICJAAgBEEEaiIBKAIAIgMoAgAhACADIAEoAgQ2AgAgAiAAQQNxIgE2AgQCQAJAIAFBAUYEQCAAQQFrIgAEQANAIAAoAgQgACgCACEDIABBADYCACADRQ0DIABBAToACCACIAM2AgggAyADKAIAIgBBAWs2AgAgAEEBRgRAIAJBCGoQ6hALIgANAAsLIAJBIGokAAwCCyACQQA2AghBACACQQRqQfyv5AAgAkEIakGQsOQAEPEWAAtBgLDkABDSIAALCyAEQRBqJAAL9gMBBH8jAEHAAmsiAyQAIAECfwJAAkACfwJAAkACQCABLQAUQQFrDgMEAQACCyABKAIMIQQgASgCEAwCCwALIAEoAgAhBSABKAIEIAEoAggQjB4hBkGAAkEIEIQhIgRFBEBBCEGAAhDhIwALIARBADoA+QEgBCAFNgL0ASAEIAY2AvABIARBFTYC7AEgBEGC1cMANgLoASADQfTZwwA2AgQgAyAENgIAIAMoAgAhBCABQfTZwwA2AhAgASAENgIMQfTZwwALIQUgA0HwAGogBCACIAUoAgwRAwAgAy0AcCICQcIARw0BIABBwgA6AABBAwwCC0Hc18MAELUXAAsgA0HxAWoiBCADQfAAakEBckHPAPwKAAAgA0HoAWoiBSADQdABaikDADcDACADQeABaiIGIANByAFqKQMANwMAIAMgAykDwAE3A9gBIAFBDGoQ/hUCQCACQcEARwRAIANBIWogBEHPAPwKAAAgA0EYaiAFKQMANwMAIANBEGogBikDADcDACADIAMpA9gBNwMIDAELIANBJGogA0H0AWpBzAD8CgAACyAAIAI6AAAgAEEBaiADQSFqQc8A/AoAACAAQeAAaiADQRhqKQMANwMAIABB2ABqIANBEGopAwA3AwAgACADKQMINwNQQQELOgAUIANBwAJqJAAL2wQBBn8jAEHQAGsiAiQAAkACQCABKQMAQgNRDQAgAkEsakGAAUEAQQFBARCiCyACKAIwIQQgAigCLEEBRg0BIAJBADYCICACIAIoAjQ2AhwgAiAENgIYIAJBGGpBjPjIAEEEEI8fIAIoAhwhBCACKAIYIgNBgICAgHhHBEAgAiACKAIgNgIUIAIgBDYCECACIAM2AgxBcCEE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QQ5qIAQQlBUiBCAEQQJNGyIIaiIEIAhJDQIgBCAEIAFBj84AS0EEIAJB/wFxIgIgAkEETRtqIgJB/wFxaiIFTQ0DQYib3wAQrhcAC0H4mt8AEK4XAAtB+JrfABCuFwALQfia3wAQrhcACyAAIAU2AgAgACABrSAHrUL/AYNCMIZCgICAgICAgIABQgAgAUGPzgBLG4QgBq1CD4NCKIaEIAKtQv8Bg0IghoSENwIEIANBIGokAAuXAwELfgJAAkACQAJAIAEpAwgiAiABKQMAIgpCGoh8IgMgAloEQCABKQMoIgQgASkDICILQhqIfCICIARUDQQgASkDECIFIANCGYh8IgQgBVQNASABKQMwIgYgAkIZiHwiBSAGVA0CIAEpAxgiByAEQhqIfCIGIAdUDQQgASkDOCIIIAVCGoh8IgcgCFQNBCABKQNAIgkgB0IZiHwiCCAJVA0DIAEpA0giDCAIQhqIfCIJIAxUDQQgACAJp0H///8PcTYCJCAAIAinQf///x9xNgIgIAAgB6dB////D3E2AhwgACAFp0H///8fcTYCGCAAIAanQf///w9xNgIMIAAgBKdB////H3E2AgggACACQv///w+DIAtC////H4MgBkIZiHwiAkIaiHw+AhQgACACp0H///8fcTYCECAAIANC////D4MgCUIZiEITfiAKQv///x+DfCIDQhqIfD4CBCAAIAOnQf///x9xNgIADwsMAwtB6OvhABCuFwALQejr4QAQrhcAC0Ho6+EAEK4XAAtB2OvhABCuFwALDgAgACABQYjg5AAQ+iUL3RACC38DfiMAQdACayIEJAACQCACQRFPBEAgBEHoAWohCSMAQSBrIggkACAIQQ9qIQsjAEHQAGsiAyQAIAMgAUEQajYCGCADIAE2AhQgA0EANgIsIANCADcCPCADIANBLGo2AjQgAyADQRRqNgI4IAMgA0EcajYCMCADQcQAaiADQThqEKgaAkACQAJAQRAgAygCTCIHIAdBEE8bQRAgAygCSBsiDARAA0BBECEHQQAhBSAGQRBHBEAgAyAGQQFqIgcgA0EcaiIFajYCMCAFIAZqIQULIANBEGogA0EUahDSFSAFIAMtABE6AAAgAygCLCIGQX9GDQMgAyAGQQFqIgU2AiwgByEGIAxBAWsiDA0ADAILAAsgAygCLCEFC0EAIQYCQCAF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ASAAQQM2AgAgACABNgIEDAELIAJBAjYCECAAIAIpAxA3AwAgAEEIaiACQRhqKQMANwMACyACEPgKCyACQTBqJAALlQMCAX8ZfiMAQdAAayICJAAgATEABiEDIAExAAUhBCABMQAEIQUgATEACSEGIAExAAghByABMQAHIQggATEADCEJIAExAAshCiABMQAKIQsgATEADyEMIAExAA4hDSABMQANIQ4gATEAFiEPIAExABUhECABMQAUIREgATEAGSESIAExABghEyABMQAXIRQgATEAHCEVIAExABshFiABMQAaIRcgATEAHyEYIAExAB4hGSABMQAdIRogATUAACEbIAIgATUAEDcDKCACIBs3AwAgAiAYQhKGQoCA8A+DIBlCCoYgGkIChoSENwNIIAIgFkIMhiAXQgSGhCAVQhSGhDcDQCACIBNCDYYgFEIFhoQgEkIVhoQ3AzggAiAQQg+GIBFCB4aEIA9CF4aENwMwIAIgDUIKhiAOQgKGhCAMQhKGhDcDICACIApCC4YgC0IDhoQgCUIThoQ3AxggAiAHQg2GIAhCBYaEIAZCFYaENwMQIAIgBEIOhiAFQgaGhCADQhaGhDcDCCAAIAIQ0wUgAkHQAGokAAusAwEDfwJAAkACQEEBIAAoAgAiAUECayABQQFNGw4CAAECCyAAKAIEIgEQhAYgAUE0ahDtHSABKAIAIgIgAigCAEEBayICNgIAIAJFBEAgARC+FAsgAEEEaiABQThqIgMQgg0CQCABKAI4IgBFDQAgACAAKAIAIgBBAWs2AgAgAEEBRw0AIAMQ7BILIAFBBGoQuh4gAUEQahC6HiABQRxqELoeIAFBKGoQuh4QmSAPCyAAKAIgIgEgASgCACICQQFrNgIAIABBCGohASACQQFGBEAgAEEgahCvCQsCQCABKAIAIgJBhYCAgHhGDQACQAJAAkACQAJAAkBBBSACQYCAgIB4cyACQQBOGw4FAAECAwQFCyAAQQxqIQEMBAsgAEEMaiEBDAMLIABBDGohAQwCCyAAQQxqIQEMAQsgACgCDEGCgICAeEgNASAAQQxqIQELIAEQ8yELIABBJGoiARCgICAAKAIkIgIgAigCACICQQFrNgIAIAJBAUYEQCABEOQCCyAAQShqIgEQpyAgACgCKCIAIAAoAgAiAEEBazYCACAAQQFHDQAgARD3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AC0AEEEBaw4ECwADBQELAAsgBygCACECCyAAIAI2AgwMAQsgACgCDCECCyADIAJBARC4GSAAQSxqIANBGGopAgA3AgAgAEEkaiADQRBqKQIANwIAIABBHGogA0EIaikCADcCACAAIAMpAgA3AhQLIABBFGoiAiABENoDQf8BcSIBQQJGDQIgAhDyGkEBIQIgAUEBcUUNA0GsnsIAQShB1LbCABCcFQALQbS2wgAQtRcAC0GktsIAELUXAAtBAyECIAVBAzoAACAGQQQ6AABBACEBDAELIAZBAToAACAHEP8bIAVBAToAACAEKAIAIQEgBBCAHAsgACACOgA4IANBIGokACABDwtBxLbCABC1FwALjgMBC38jAEEgayIDJAACQCACEMkXBEAgAEEHNgIADAELQQMQ6RghBSABKAIEIghBJGohCiAIQShqIQsgASgCACEEQQYhCUEAIQECQANAIAEgBWohBgJAAkADQCABQQNGDQQgBkEDbiEMAkACQAJAAkACQCAFIAEgBWoiDU0EQCAELQAAIQcgDSAMQX1sakEBaw4CAgMBC0HkxsMAEK4XAAsgB0EBcQ0CIAggAhD1CA0FIABBAzYCACAEIAQtAABBAXI6AAAMCQsgB0ECcQ0BIAogAhCiIA0EIABBBDYCACAEIAQtAABBAnI6AAAMCAsgB0EEcUUNAQsgAUEBaiEBIAZBAWohBgwBCwsgA0EEaiALKAIAKAIAIAIQ2AggAygCBEEDRw0BCyABQQFqIQFBByEJDAELCyAAIAMpAgQ3AgAgAEEYaiADQRxqKAIANgIAIABBEGogA0EUaikCADcCACAAQQhqIANBDGopAgA3AgAgBCAELQAAQQRyOgAADAELIAAgCTYCAAsgA0EgaiQAC7ANAhV/BX4jAEHwBGsiByQAAkACfwJAAkACQAJAAkACQAJAIAEtAEhBAWsOAwUBAAILAkAgAS0AREEBaw4DCAEEAAsgASgCDCEDIAEoAgghBQwCCwALIAFBADoARCABIAEoAgQiAzYCDCABIAEoAgAiBTYCCAsgASADNgIQIAUoAgAhAyABQQA6AEAgASADQQhqNgIUCyAHQbgCaiABQRRqIAIQwAYgBygCuAIiEUUNASAHKALAAiAHKAK8AiESIAEtAEBBA0YEQCABQRhqELYYCyABKAIQIgMpAwAhGyAHQdgE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AgMBC0Hs9MMAEK4XAAsgCEEBcQ0EIAYgAhD1CEUNAgwDCyAIQQJxDQMgBigCJCgCACACELsLDQIgAEEENgIAIAQgBC0AAEECcjoAAAwFCyAIQQRxDQIgA0EEaiAGKAIoKAIAIAIQ2AggAygCBEEDRg0BIAAgAykCBDcCACAAQRhqIANBHGooAgA2AgAgAEEQaiADQRRqKQIANwIAIABBCGogA0EMaikCADcCACAEIAQtAABBBHI6AAAMBAsgAEEDNgIAIAQgBC0AAEEBcjoAAAwDC0EBIQkLIAFBAWohASAHQQFqIgdBA0cNAAsgAEEHQQYgCRs2AgALIANBIGokAAvbAwELfyMAQYABayIBJAACQAJAAkACQAJAAkACQAJAIAAoAgAiAkHQ/f//A00EQCAAKAIEIgNB8P///wFLDQEgACgCCCIEQfD///8DSw0CIAAoAgwiBUHw////AUsNAyAAKAIQIgZB8P///wNLDQQgACgCFCIHQfD///8BSw0FIAAoAhgiCEHw////A0sNBiAAKAIcIglB8P///wFLDQcgACgCICIKQfD///8DSw0IIAAoAiQiC0Hw////AU0EQCABQfD///8BIAtrrTcDUCABQfD///8DIAprrTcDSCABQfD///8BIAlrrTcDQCABQfD///8DIAhrrTcDOCABQfD///8BIAdrrTcDMCABQfD///8DIAZrrTcDKCABQfD///8BIAVrrTcDICABQfD///8DIARrrTcDGCABQfD///8BIANrrTcDECABQdD9//8DIAJrrTcDCCABQdgAaiICIAFBCGoQ0wUgACACQSj8CgAAIAFBgAFqJAAPC0HI6+EAELQXAAtBuOrhABC0FwALQcjq4QAQtBcAC0HY6uEAELQXAAtB6OrhABC0FwALQfjq4QAQtBcAC0GI6+EAELQXAAtBmOvhABC0FwALQajr4QAQtBcAC0G46+EAELQXAAu6HAETfyMAQdAAayILJAAgC0EEaiIDIAIQ7QxBACECIAsoAgRBAkcEQCALQUBrIREjAEFAaiIIJABBASADKAIIIgdBgICAgHhzIAdBAE4bIQwgA0EYaiESIAMoAgwiDiADKAIQQQR0aiEVIAhBPWohEyAIQTFqIRACQAJAAkACQANAQQUhA0GPzcoAIQZBASEUQQIhDUGIzcoAIQdBByEJQQEhDwJAAkAgDEEBaw4CAAMBCwJ/IA4gFUYEQEECIQ8gCEEkagwBCyAOKAIMIQMgDigCCCEEIA4oAgQhByAOKAIAIQUgCEEIaiASEL4YIAgoAgwhAiAIKAIIIQYCQAJAAkAgBSAHSw0AAkAgBUUNACACIAVNBEAgAiAFRw0CDAELIAUgBmosAABBv39MDQELAkAgB0UNACACIAdNBEAgAiAHRg0BDAILIAYgB2osAABBv39MDQELIAggEhC+GCAIKAIEIQIgCCgCACEJIAMgBEkNCCAERQ0CIAIgBEsNASACIARHDQgMAgsgBiACIAUgB0GUzcoAEJQfAAsgBCAJaiwAAEG/f0wNBgsCQCADRQ0AIAIgA00EQCACIANGDQEMBwsgAyAJaiwAAEG/f0wNBgsgBSAGaiECQQAhDyAHIAVrIgVBB0YEQCACQYjNygBBBxCaE0UhDwsgDkEQaiEOIAhBAToAJCADIARrIQogBCAJaiEEIAhBIGoLIA86AAAgCC0AJCIPQQJGDQJBASENIAgtACAhFCACIQcgBSEJIAQhBiAKIQMLIBBBADsAACATQQA7AAAgEEECakEAOgAAIBNBAmpBADoAACAIIA86ADAgCCAJNgIsIAggBzYCKCAIIBQ6ADwgCCADNgI4IAggBjYCNCAIQShqQb2eygBBBxClC0UEQCANIQwgAyEKIAYhBCAJIQUgByECDAELCyAIIBApAAA3AxAgCCAQQQdqKQAANwAXIBFBCGogCEEbaigAADYAACARIAgpABM3AAAMAQsgEUECOgAICyAIQUBrJAAMAQsgCSACIAQgA0GkzcoAEJQfAAsgCygCRCEEIAsoAkBBACALLQBIQQJHGyECCyACQbieygAgAhshCkEAIQUjAEEgayIGJAAgBkEeakEAOwAAIAZBFmpCADcAACAGQgA3AA4Cf0EAIARBBSACGyIJRQ0AGkF+IQMgCUECayEHAkADQCAFIApqIgwtAAAiBEEJayICQRdLQQEgAnRBm4CABHFFckUEQCADQQFrIQMgB0EBayEHIAkgBUEBaiIFRw0BDAILCwJAIARB3wBGIARBLWsiAkENTUEAQQEgAnRBg8AAcRtyDQAgBEHBAGtB/wFxQRpPBEAgBEHhAGtB/wFxQRpJIARBMGtB/wFxQQpJcg0BDAILIARBIHIhBAsgBiAEOgANQQEhAgJAIAlBAWsgBUYNACADIAlqIQogBUF/cyAJaiEEIAZBDmohCUEAIQUDQCAFQQFqIQICQAJAAkAgBSAMaiINQQFqLQAAIgNBLWsiCEENTUEAQQEgCHRBg8AAcRsgA0HfAEZyDQAgA0EJayIIQRdLQQEgCHRBm4CABHFFckUEQCAFIApGDQUgByAFayEDIA1BAmohBQNAIAUtAABBCWsiBEEXS0EBIAR0QZuAgARxRXINByAFQQFqIQUgA0EBayIDDQALIAJBFEkNBUEAIAJBE0H4n8sAEJsVAAsgA0HBAGtB/wFxQRpPBEAgA0HhAGtB/wFxQRpJDQFBACAFQRJGIANBOmtB/wFxQfYBSXINBxoMAgsgBUESRg0FIAJBEk0EQCADQSByIQMMAwsgBUEBakETQaigywAQjBAACyAFQRJGDQQLIAJBE0kNACAFQQFqQRNBmKDLABCMEAALIAUgCWogAzoAACACIQUgBEEBayIEDQALIAJBAWohAgsgBkEMaiEJQQAhBEHkASEDA0ACQAJAIAIgA0EBdiIKIAQiB2oiBEEDdCIFKAKogUsiDEYEQCAFQaSBywBqKAIAQQFrIQwgAiEFA0AgBUUNAyAFIAlqIQ0gBSAMaiAFQQFrIQUtAAAiCCANLQAAIg1GDQALIAggDUsNAQwCCyACIAxPDQELIAchBAsgAyAKayIDQQFLDQALAkACfyACIARBA3QiAygCqIFLIgVHBEAgAiAFSSACIAVLawwBCyADQaSBywBqKAIAQQFrIQcgBkEMaiEJA0AgAkUNAiACIAlqIQMgAiAHaiACQQFrIQItAAAiBSADLQAAIgNGDQALIAMgBUkgAyAFS2sLIgINASAEIAJBf0ZqIQQLIARB4wFNBEAgBEECdCgC9JVLDAILQeQBQeQBQYigywAQjBAAC0EACyEDIAZBIGokAEGw78oAKAIAIQdBAyEFIAtBQGshCQJAAn8Cf0Gw78oAIAEoAgQiBCABKAIIIgJB8JnKAEEDEO0aDQAaQQIhBUG478oAIAQgAkHzmcoAQQIQ7RoNABogAyAHIAMbIAQgAkH1mcoAQQIQ7RpFDQEaQbTvygALIAIgBUkNASAEIAVqIQQgAiAFayECKAIACyEGIAQhBUEAIQFBACEEQQAhByMAQaABayIDJAACQAJAAkAgA0HQAGoCfwJAAkACQAJ/AkACQAJAIAZB6I/LAEYgBkHQk8sARnJFIAZBzI/LAEdxRQRAIANB/ABqIgEgBhDuCCADQQk6AJQBIAMgBjYCkAEgA0EwaiABIAIQ0AQCfyADKAIwQQFxBEBBfyADKAI0IgRBAWtndkEAIARBAk8bIgRBf0YNAyADQSBqIAEgAhC+BCADKAIkIgcgBEEBaiIBIAEgB0sbIAEgAygCIEEBcRsMAQsgA0EoaiADQfwAaiACEL4EIAMoAihBAXFFDQMgAygCLAshBEEAIQEgA0E4aiAEQQBBAUEBEKILIAMoAjwhBCADKAI4QQFGDQogAygCQCEHIANB/ABqDAgLIAZBxO/KAEYNAiAGQZySywBHBEACQAJAQQAgBWtBA3EiBEEIciACSw0AIAQEQANAIAEgBWosAABBAEgNAyAEIAFBAWoiAUcNAAsLIAJBCGshCiAEIQEDQCABIAVqIgRBBGooAgBBgIGChHhxIgwgBCgCAEGAgYKEeHEiBHIEQCAEaEEDdiAMaEEDdkEEaiAEGyIEIAEgBGoiAU0NA0H8u8sAEK4XAAsgAUF3TQRAIAFBCGoiASAKTQ0BDAILC0GMvMsAEK4XAAsgASACSQRAA0AgASAFaiwAAEEASA0CIAIgAUEBaiIBRw0ACwsgAiEBCyABDAQLAn8CQANAIAIgBCIBIAJGDQIaIARBAWoiBEUNASABIAVqLAAAIgpBAE4EQCAKQf8BcSIKQRtLQQEgCnRBgICDwABxRXINAQsLIAEMAQtB6LbLABCuFwALDAMLQeigywAQrhcAC0GYn8sAENIgAAsgBSACEL0CCyIBIAJHBEAgA0HgAGoiBCAGEO4IIANBCToAeCADIAY2AnQgASACTQRAIANBGGogBCACIAFrIgoQ0ARBACEEAkAgAygCGEEBcUUNACADKAIcIgwgAWoiBiAMSQ0AQX8gBkEBa2d2QQAgBkECTxsiB0F/Rg0DQQEhBCAHQQFqIQcLIANBEGogA0HgAGogChC+BCADKAIQIAMoAhQiCiABaiIGIApPcSEKAkAgBARAIAYgByAGIAdJGyAHIAobIQYMAQsgCkUNBAsgA0E4aiAGQQBBAUEBEKILIAMoAjwhBCADKAI4QQFHDQQMBwtBqJ/LABC0FwALIAlBADoADCAJIAI2AgggCSAFNgIEIAlBgICAgHg2AgAMBAtB6KDLABCuFwALQbifywAQ0iAACyADKAJAIQcgAQRAIAcgBSAB/AoAAAsgA0HgAGoLIgZBGGooAgA2AgAgA0HIAGogBkEQaikCADcDACADQUBrIAZBCGopAgA3AwAgAyAGKQIANwM4IAMgBzYCWCADIAQ2AlQgAyABNgJcIANBmAFqIANBOGogASAFaiACIAFrIANB1ABqEM8MAkAgAygCmAEiBCABaiIBIARPBEAgAy0AnQEhByADLQCcASEEQQAhBgNAIAYgB3IhBgJAIARBAXEEQCABIAJNDQFB2J/LABC0FwALIAkgAykCVDcCACAJIAZBAXE6AAwgCUEIaiADQdwAaigCADYCAAwECyADQQhqIANBOGogAiABayIHEL4EIAMoAghBAXFFDQIgAygCDCIKIAMoAlQgAygCXCIMa0sEQCMAQRBrIgQkACAEQQhqIANB1ABqIAwgCkEBQQEQoAcgBCgCCCIKQYGAgIB4RwRAIAogBCgCDEHAqMsAEPYbAAsgBEEQaiQACyADQZgBaiADQThqIAEgBWogByADQdQAahDPDCADLQCdASEHIAMtAJwBIQQgAygCmAEiCiABaiIBIApPDQALC0HIn8sAEK4XAAtB6J/LABDSIAALIANBoAFqJAAMAQsgBCADKAJAQfigywAQ9hsACyALQThqIAtByABqKAIANgIAIAsgCykCQDcDMCMAQRBrIgEkAAJAAkACQCALQTBqIgIoAgBBgICAgHhHBEAgACACKQIANwIAIABBCGogAkEIaigCADYCAAwBCyACKAIEIQMgAUEEaiACKAIIIgJBAEEBQQEQogsgASgCCCEEIAEoAgRBAUYNASABKAIMIQUgAgRAIAUgAyAC/AoAAAsgACACNgIIIAAgBTYCBCAAIAQ2AgALIAFBEGokAAwBCyAEIAEoAgxBrITeABD2GwALAkAgCygCBEECRg0AIAstABwEQCALQSBqEPMhCyALKAIMQQBIDQAgC0EMahCpIgsgC0HQAGokAA8LIAUgAiACQeCZygAQmxUAC80FAQN/IwBBQGoiAiQAIwBBEGsiAyQAIAICfwJAAkACQAJAAkACQEEFIAAoAgAiBEGAgICAeHMgBEEAThtBAWsOBQEBAQIDAAsgAiAAKQIINwIEDAQLIANBBGogACgCCCAAKAIMENEDIAMoAgRBAUYNAiACIAMpAgg3AgQMAwsgACgCBEGBgICAeEcEQCACIAApAgg3AgQMAwsgAkIBNwIEDAILIANBBGogACgCBCAAKAIIENEDIAMoAgQNACACIAMpAgg3AgQMAQtBjICAgHgMAQtBj4CAgHgLNgIAIANBEGokAAJAIAIoAgAiA0GPgICAeEYEQCACIAIpAgQ3AhggAkH0BzYCJCACIAJBGGo2AiAgASgCACABKAIEIAJCATcCNCACQQE2AiwgAkGEw9QANgIoIAIgAkEgajYCMCACQShqEKkEIQEMAQsCfwJAAkACQEEFIAAoAgAiBEGAgICAeHMgBEEAThtBBGsOAgABAgsgACgCDEEAIAAoAgRBgYCAgHhHGwwCC0EBQQIgACgCCCIEQYCABEkbQQAgBEH+AE8bQQJ0KAKww1QgBGogAC0AE0ECdEEEcWoMAQsgACgCDAshACACQQo2AiQgAiAANgIYIAIgAkEYajYCICABKAIAIAEoAgQgAkIBNwI0IAJBAjYCLCACQaDD1AA2AiggAiACQSBqNgIwIAJBKGoQqQQhAUEGIANB+////wdqIANBhICAgHhNGyIAQQhNBEBBASAAdEG7A3ENASAAQQJGBEAgAkEEahDTEgwCCyACIQACQAJAAkACQAJAAkBBBSADQYCAgIB4cyADQQBOGw4FAAECAwQFCyACQQRqIQAMBAsgAkEEaiEADAMLIAJBBGohAAwCCyACQQRqIQAMAQsgAigCBEGCgICAeEgNAiACQQRqIQALIAAQ8yEMAQsgAkEEahCWHAsgAkFAayQAIAELowMBAn8jAEEwayICJAACfwJAAkACQAJAAkACQAJAAkACQAJAAkACQEEGIAAoAgAiA0GAgICAeHMgA0EAThtBAWsOCwECAwQFBgcICQoLAAsgAiAAQQRqNgIAIAIgAEEIajYCFCACQaIHNgIQIAJBogc2AgggAiACQRRqNgIMIAIgAjYCBCABKAIAIAEoAgQgAkICNwIkIAJBAjYCHCACQbCAyAA2AhggAiACQQRqNgIgIAJBGGoQqQQMCwsgAUHAgMgAQTwQ6B4MCgsgAEEEaiABEIgUDAkLIAFB/IDIAEEaEOgeDAgLIAFBloHIAEEZEOgeDAcLIAFBloHIAEEZEOgeDAYLIAIgADYCFCACQRA2AgggAiACQRRqNgIEIAEoAgAgASgCBCACQgE3AiQgAkEBNgIcIAJBxIHIADYCGCACIAJBBGo2AiAgAkEYahCpBAwFCyABQcyByABBIBDoHgwECyABQeyByABBGhDoHgwDCyABQeyByABBGhDoHgwCCyABQYaCyABBERDoHgwBCyABQZeCyABBKRDoHgsgAkEwaiQAC4wDAQN/IwBBEGsiAiQAAkACQAJAAkACQAJAIAEtAABBAWsOAwECAwALQRAhBCACQQRqQRBBAEEBQQEQogsgAigCCCEDIAIoAgRBAUYNBCACKAIMIgFBCGpBhKHKACkAADcAACABQfygygApAAA3AAAMAwtBEyEEIAJBBGpBE0EAQQFBARCiCyACKAIIIQMgAigCBEEBRg0DIAIoAgwiAUEPakGbocoAKAAANgAAIAFBCGpBlKHKACkAADcAACABQYyhygApAAA3AAAMAgtBECEEIAJBBGpBEEEAQQFBARCiCyACKAIIIQMgAigCBEEBRg0CIAIoAgwiAUEIakGnocoAKQAANwAAIAFBn6HKACkAADcAAAwBC0EKIQQgAkEEakEKQQBBAUEBEKILIAIoAgghAyACKAIEQQFGDQEgAigCDCIBQQhqQbehygAvAAA7AAAgAUGvocoAKQAANwAACyAAIAQ2AgggACABNgIEIAAgAzYCACACQRBqJAAPCyADIAIoAgxBrLzKABD2GwAL2goCDn4GfyMAQdAEayIRJAAjAEGwAmsiECQAIBBBCGoiEyABQcABaiISENUBIBBB8ABqIhQgEkEwaiIVENUBIBAgECkDcCIEIBApAwh8IgdC1aqBgICAwIDGAHwiCiAHVK1CAX0iAiACIAIgECkDeCIFIBApAxB8IgMgBCAHVq18Igl8IgRWrXwgBEL//8+K6///1R59Ig0gBFStfEIBfUI/hyIGIAYgECkDgAEiCCAQKQMYfCICIAMgBVStIAMgCVatfHwiBHwiAyAEVK18IANCpOzDtY/UtJjnAH0iDiADVK18QgF9Qj+HIgYgBiAQKQOIASILIBApAyB8IgMgAiAIVK0gAiAEVq18fCIFfCICIAVUrXwgAkK/pZScz/DSu+QAfSIPIAJUrXxCAX1CP4ciCCAIIBApA5ABIgwgECkDKHwiAiADIAtUrSADIAVWrXx8IgZ8IgMgBlStfCADQtfZrprk9umNywB9IgsgA1StfEIBfUI/hyIDIAMgECkD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DCIFRQRAIAQgA2shBEEAIQUMAwsCQCACKAIYIgggBU0EQCAFIAhHDQEMAwsgBSAHaiwAAEG/f0oNAgsgByAIQQAgBUGs19UAEJQfAAsgAigCGCEFIAIoAhQhBwsgBSAEIANraiIEIAVPDQBBhMvVABCuFwALIAEgBBClGiABIAcgBSAHahDGEiABQQhqIgMoAgAhBCABQQEQpRogASgCBCADKAIAakEjOgAAIAMgBEEBajYCACAGQQhqEPYHGiABIAYoAgggBigCDBD9BCAAQQE2AgggACAFNgIMIABBGGogAygCADYCACAAIAEpAgA3AhAgACACKQI0NwI0IABBPGogAkE8aikCADcCACAAQcQAaiACQcQAai0AADoAACAAIAIoAjA2AjAgACACKQIANwIAIAAgAikCIDcCICAAIAIpAig3AiggACACKAIcNgIcIAZBEGokAAvSAgEFfyMAQZACayIEJAAgBEExNgIEA0AgBEEQaiACakEAOgAAIAJBAmoiAkGAAkcNAAtBACECAkADQCABIAJqKAIAIgNBgAFPDQEgBEEQaiIGIANBAXRqIgMgBToAASADQQE6AAAgBUEBaiEFIAJBBGoiAkGAAUcNAAsgAEGEAWogBkGAAvwKAAAgACABQYAB/AoAACAAQTE2AoABIARBkAJqJAAPCyMAQUBqIgAkACAAQQJBA0EEIANBgIAESRsgA0GAEEkbNgIIIAAgAzYCBCAAQQE2AgwgAEEDNgIkIABBtJ3lADYCICAAQQM2AhQgAEGcneUANgIQIABBAzYCHCAAIABBDGqtQoCAgICgAYQ3AzggACAAQQRqrUKAgICAkLQChDcDMCAAIABBCGqtQoCAgICgAYQ3AyggACAAQShqNgIYIABBEGpB3NvgABD3GAALoAMBAn8jAEEgayIHJAACQCAAKAIAIgggASACIAAoAgQoAgwiAREFAARAQQEhAgwBCwJAIAAtAApBgAFxRQRAQQEhAiAIQY385ABBASABEQUADQIgAyAAIAQoAgwRAABFDQEMAgsgCEGO/OQAQQIgAREFAARAQQEhAgwCC0EBIQIgB0EBOgAPIAdBlPzkADYCFCAHIAApAgA3AgAgByAAKQIINwIYIAcgB0EPajYCCCAHIAc2AhAgAyAHQRBqIAQoAgwRAAANASAHKAIQQYv85ABBAiAHKAIU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QcAAIAJrIQVCASACrYYiCEIBiCEKIAhCAX0hCyAIpyEGQQAhAQNAIANBiAJqIAFBA3ZB+P///wFxaiIHKQMAIAFBP3EiBK2IIQgCQCAEIAVPBH4gBykDCEHAACAEa62GIAiEBSAICyALgyAJfCIIQgGDUEUEQCADQQhqIAFqIAinIAZBACAIIApaIgQbazoAACAErSEJIAEgAmoiAUGAAkkNAgwBCyABQQFqIgFBgAJHDQELCyAAIANBCGpBgAL8CgAAIANBsAJqJAAPC0Gw2uEAELIXAAuuAwEEfyMAQcAFayIDJAACQAJAAkACfwJAAkACQCABLQAMQQFrDgMEAQACCyABKAIEIQQgASgCCAwCCwALIAEoAgAhBUHY1cMAQRgQjB4hBkGAAkEIEIQhIgRFBEBBCEGAAhDhIwALIARBADoA+QEgBCAFNgL0ASAEIAY2AvABIARBBDYC7AEgBEGt1MMANgLoASADQcTZwwA2AgQgAyAENgIAIAMoAgAhBCABQcTZwwA2AgggASAENgIEQcTZwwALIQUgA0HwAWogBCACIAUoAgwRAwBBAyEEIAMoAvABIgJBA0cNASAAQQM2AgAMAgtBvNbDABC1FwALIANB1ARqIANB8AFqQQRyQewA/AoAACADQdgDaiADQeACakH4APwKAAAgAUEEahD+FQJAIAJBAkYEQCADQYgBaiADQdgEakHoAPwKAAAMAQsgA0GEAWogA0HUBGpB7AD8CgAAIANBCGogA0HYA2pB+AD8CgAACyAAIAI2AgAgAEEEaiADQYQBakHsAPwKAAAgAEHwAGogA0EIakH4APwKAABBASEECyABIAQ6AAwgA0HABWokAAuMBAEIfyMAQeAAayIEJAACQAJAAkAgASkDAEIDUgRAIARBCGogAkEIaiIKKQIANwMAIAQgAikCADcDACAEQTBqIANBCGooAgA2AgAgBCADKQIANwMoIARB0ABqIgMgBEEoahDaCSAEQRRqIQUgAygCCCEHIAMoAgQhCAJAAkADQCAGIAdGDQEgBiAIai0AACIJQR9LIAlB/wBHcSELIAZBAWohBiAJQQlGIAtyDQALIAVBAjoAECADQQxqIAggByADKAIAKAIQEQMADAELIAVBADoAECAFIAMpAgA3AgAgBUEIaiADQQhqKQIANwIACyAELQAkQQJHDQFBACAE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IAEQpRgLIAEgAjYCDCABIAQ2AgggASADNgIEIAEgAzYCAAwCCyABKAIQBEAgASgCFCICIAEoAhxHBEBBASEEIAEgAkEBajYCFCACLQAAIQEMBAsgAUEQaiIBEKUYIAFBADYCAAtBACEEDAILQQEhBCABIANBAWo2AgQgAy0AACEBDAELQQAhBAwBCwsgACABOgABIAAgBDoAACANQRBqJAALlgMBAn9BCCECAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAQRUgASgCACIDQYCAgIB4cyADQQBOG0EBaw4VAQIDBAUGBwgJCgsMDQ4PFBQQERITAAsgACABLQAEOgABQQAhAgwTCyAAIAExAAQ3AwhBASECDBILIAAgATMBBDcDCEEBIQIMEQsgACABNQIENwMIQQEhAgwQCyAAIAEpAwg3AwhBASECDA8LIAAgATAABDcDCEECIQIMDgsgACABMgEENwMIQQIhAgwNCyAAIAE0AgQ3AwhBAiECDAwLIAAgASkDCDcDCEECIQIMCwsgACABKgIEuzkDCEEDIQIMCgsgACABKwMIOQMIQQMhAgwJCyAAIAEoAgQ2AgRBBCECDAgLIAAgASkDCDcCBEEFIQIMBwsgACABKQIENwIEQQUhAgwGCyAAIAEpAwg3AgRBBiECDAULIAAgASkCBDcCBEEGIQIMBAtBByECDAMLQQkhAgwCC0EKIQIMAQtBCyECCyAAIAI6AAALtAMBA38CQAJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAQQQgAS0AACIEQQZrIARBBU0bQf8BcUEBaw44AQIMAxMTExMTBAUGBgYGExMHCBMTExMTExMTExMJExMTExMTExMTExMTEwoLDA0TExMTEw4PEBEACyABQQRqIQJBsPLFACEDDBILIAFBEGohAkG48cUAIQMMEQsgAUEEaiECQezyxQAhAwwQC0GY9cUADA4LIAFBBGohAkHc9MUAIQMMDgsgAUEEaiECQcjvxQAhAwwNCyABKAIIIQMgASgCBCECDAwLIAFBBGohAkGg9MUAIQMMCwsgAUEEaiECQcDwxQAhAwwKCyABKAIUIQMgASgCECECDAkLIAFBEGohAkGw8sUAIQMMCAsgAUEoaiECQbDyxQAhAwwHCyABQQRq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QAJAAkACQAJAIAFBAkwEQAJAIAFBFWoOCgUDAwYDAwcDAwgACyABQQlqDgoIAgIJAgIKAgILAQsCQCABQQNrDgoMAgINAgIOAgIPAAsgAUEPaw4KDwEBEAEBEQEBEgELIAFBaEYNAQsgAkEPNgIUIAIgAkEMajYCECACQgE3AiQgAkECNgIcIAJBiLLIADYCGCACIAJBEGo2AiAgACACQRhqEO4EDBELIABCgICAgIh9NwIADBALIABCgICAgLh9NwIADA8LIABCgICAgOh9NwIADA4LIABCgICAgJh+NwIADA0LIABCgICAgMh+NwIADAwLIABCgICAgPh+NwIADAsLIABCgICAgKh/NwIADAoLIABCgICAgFg3AgAMCQsgAEKAgICACDcCAAwICyAAQoCAgIA4NwIADAcLIABCgICAgOgANwIADAYLIABCgICAgJgBNwIADAULIABCgICAgMgBNwIADAQLIABCgICAgPgBNwIADAMLIABCgICAgKgCNwIADAILIABCgICAgNgCNwIADAELIABCgICAgIgDNwIACyACQTBqJAALwgIBCn8jAEHQAGsiAiQAIAEoAgQhAyACQQhqIAEoAggiBkEAQQRByAAQogsgAigCDCEEIAIoAghBAUcEQCACKAIQIQcCQCAERQ0AIAZByABsIQEgAkEYaiEKIAJBPGoiCEEIaiELIAchBSAEIQkDQCABRQ0BIAogA0EQahDWDyAIIAMpAjQ3AgAgCyADQTxqKQIANwIAIAhBEGogA0HEAGotAAA6AAAgAiADKQIoNwIwIAIgAykCIDcCKCACIAMoAjA2AjggAiADKAEcNgIkIAIgAykCCDcCECACIAMpAgA3AgggBSACQQhqQcgA/AoAACAFQcgAaiEFIAFByABrIQEgA0HIAGohAyAJQQFrIgkNAAsLIAAgBjYCCCAAIAc2AgQgACAENgIAIAJB0ABqJAAPCyAEIAIoAhBBvMrKABD2GwALrgUBB38jAEHQAGsiBSQAAkACQAJAIAEoAiAiAkUNACABKAIUIQQCQCABKAIYIgMgAk0EQCACIANGDQEMBAsgAiAEaiwAAEG/f0wNAwsgAkEERw0AIAQoAABB4ti9kwZHDQAgBSABEKMHIAUoAgAgBSgCBEHMrNQAQQQQviBFDQACQAJAIANBBU0EQCADQQVGDQEMAgsg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aiEBIAMgAmshAgwDC0HE29UAEK4XAAsCQCAFQX9HBEAgBUEBaiECIAEoAhghAyABKAIUIQYgBSABKAIMIgRPDQECQCACIANPBEAgAiADRg0BDAMLIAIgBmosAABBQEgNAgsCQCADIARNBEAgAyAERw0DDAELIAQgBmosAABBv39MDQILIAIgBmohASAEIAJrIQIMAwtB1NvVABCuFwALIAYgAyACIARBtN7VABCUHwALIAQgAyACIANB1N7VABCUHwALIAAgAjYCBCAAIAE2AgALDAAgAEHY3t8AENEmC9UCAgR/AX4jAEFAaiIEJABBASEGAkAgAygCAEEBRgRAIAMoAgQiBSADKAIIIgMoAghBAWtBeHFqQQhqIAIgAygCHBEZACEIIAUgBSgCACIHQQFqNgIAIAdBAE4NAQALQQAhBiADKAIEIgUgAiADKAIIIgMoAhwRGQAhCAsgACABNgIYIAAgAzYCECAAIAU2AgwgACAGNgIIIAAgCDcDAEHg0OYALQAARQRAIAEoAgghBSACKAIUEKURIQMgASgCFCEGIAEoAhghByACKAIUIQIgBCABKQIMNwIgIARBADoALCAEIAI2AiggBEECNgIMIARBsMvhADYCCCAEQgI3AhQgBEGMEjYCPCAEQfQHNgI0IAQgBEEwajYCECAEIARBKGo2AjggBCAEQSBqNgIwIABBwcrhACAGIAMbQQ0gByADG0EFIAVrIARBCGoQiwULIARBQGskAAu4AwEJfyMAQdAAayIDJAAgA0EgaiACEO8bIAMgAygCJCIHNgIsIAMgAygCICICNgIoIANBGGogA0EoahCsHSADQUBrIAEgAygCGCADKAIcENkbIAACfwJAAkAgAygCQEUEQCADKAJEIQEMAQsgA0E4aiIKIANByABqIgsoAgA2AgAgAyADKQJANwMwIAIgB0YNAQNAAkAgAyACNgJAIANBEGohCCMAQRBrIgEkACADQTBqIgQoAgghBSABQQhqIAQoAgAgA0FAaygCAC0AABCjHEEBIQYgASgCDCEJAkACQCABKAIIQQFxRQRAIARBBGogBSAJEMsgIAVBf0YNASAEIAVBAWo2AghBACEGCyAIIAk2AgQgCCAGNgIAIAFBEGokAAwBC0H0sMQAEK4XAAsgAygCEEEBcQ0AIAcgAkEBaiICRw0BDAMLCyADKAIU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NgIAIAAgAikCCDcCACACQUBrJAAMAgsgAkEANgIwIAJBATYCJCACQYy50wA2AiAgAkIENwIoIAJBIGpBnLzTABD3GAALIAQgAigCKEGcvNMAEPYbAAsLIAVBMGokAA8LIANBADYCKCADQQE2AhwgA0GMudMANgIYIANCBDcCICADQRhqQZy80wAQ9xgAC6UCAQN/AkACQCABKAIAQQFGBEAgAUEEaiECDAELIAEoAggEQCABQQxqIQIMAQsgASgCGCECIAEoAhQhAwJAAkAgASgCMCIBRQ0AIAEgAk8EQCABIAJGDQEMAgsgASADaiwAAEG/f0wNAQsgASADaiEDDAILIAMgAiABIAJB1N7VABCUHwALIAEoAhghAyABKAIUIQQCQCACKAIAIgIgASgCMCIBSQ0AAkAgAUUNACABIANPBEAgASADRw0CDAELIAEgBGosAABBv39MDQELAkAgAkUNACACIANPBEAgAiADRw0CDAELIAIgBGosAABBv39MDQELIAEgBGohAwwBCyAEIAMgASACQbTe1QAQlB8ACyACIAFrIQEgACABNgIEIAAgAzYCAAuaAgICfwF+IwBB0AFrIgMkACAAAn8gAkEgRwRAIABBATYCBEEBDAELIANBIGogAUEYaikAADcDACADQRhqIAFBEGoiAikAADcDACADQRBqIAFBCGopAAA3AwAgAyABKQAANwMIIANBLGoiBCADQQhqENYLIAMoAixFBEAgA0EANgIsIAMgBBDtFiAAIAMpAwA3AgggAEEANgIEQQEMAQsgACADKQI0NwIoIABBMGogA0E8aigCADYCACADKAIwIQQgAEE0aiADQUBrQZAB/AoAACAAIAEpAAg3AAwgAEEUaiACKQAANwAAIABBHGogAUEYaikAADcAACABKQAAIQUgACAENgIkIAAgBTcCBEEACzYCACADQdABaiQAC8cCAgZ/AX4jAEHAAmsiAyQAIANB+ABqIgIgARCKAiADIAIQ0wUgAiABQShqIgUQigIgA0EoaiACENMFIANBmAJqIQYjAEHQAGsiAiQAIAIgAUHQAGoQigICQAJAA0AgAiAEaiIHKQMAIghCAFMNASAHIAhCAYY3AwAgBEEIaiIEQdAARw0ACyAGIAIQ0wUgAkHQAGokAAwBC0H46+EAEK4XAAsgA0HQAGoiAiABQSj8CgAA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w8cAELULDAMLIAIgAEEEajYCDCABQfTHxwBBCyACQQxqQczExwAQpQgMAgsgAiAAQQRqNgIMIAFBkMjHAEEXQdDCxwBBBiACQQxqQYDIxwAQtQsMAQsgAiAANgIMIAFBp8jHAEEGQdDCxwBBBiACQQxqQYzExwAQtQsLIAJBEGokAAv+AQECfyMAQYAfayIDJAAgAxDiHgJAIAJBwABNBEAgAkUNASADIAEgAvwKAAAMAQsgA0FAayIEENULIAQgASACELcCIANBwA9qIgEgBEGAD/wKAAAgA0HAHmoQxBkgA0HgHmogARCMEiADQdgeaiIBIANB+B5qKQAANwMAIANB0B5qIgIgA0HwHmopAAA3AwAgA0HIHmoiBCADQegeaikAADcDACADIAMpAOAeNwPAHiADQdgQahDgHiADQRhqIAEpAwA3AwAgA0EQaiACKQMANwMAIANBCGogBCkDADcDACADIAMpA8AeNwMACyAAIANBwAD8CgAAIANBgB9qJAALjgICA38CfiMAQeAAayICJAAgACgCACEAAkACQANAQQEgACgCQCIDQQhrIANBB00bIgRBEUcEQAJAQQEhAyAEQQFHBEAgACABELUFDQUgAkEIaiAAEO4MIAIoAghBAUcNBCACQThqIAJBIGopAwAiBTcDACACQTBqIAJBGGopAwAiBjcDACACIAIpAxA3AyggBSAGhFBFDQEMBAsgACABELIFIQMMBAsFIAAoAgBBCGohAAwBCwsgAkGACzYCRCACIAJBKGo2AkAgASgCACABKAIEIAJCATcCVCACQQE2AkwgAkG038oANgJIIAIgAkFAazYCUCACQcgAahCpBA0BC0EAIQMLIAJB4ABqJAAgAwueAgAgAgRAIABBAEEAEO8MCyABKAIAQQpHBEACQAJ/QQAgABDbDkUNABogABC6Cw0BQQAgAEGjgsIAQQFBAEEBEKUNRQ0AGiAAKAJoIgIgACgCZEYEfyAAQeAAaiAAQegAaiAAQeQAahDWCiAAKAJoBSACC0EQNgIAIAAgACgCaEEEajYCaCAAIAFBAEEAQQFBABDMAQsPCyAAKAJoIgIgACgCZEYEfyAAQeAAaiAAQegAaiAAQeQAahDWCiAAKAJoBSACC0EPNgIAIAAgACgCaEEEajYCaCAAIAFBAEEAQQFBARDMAQ8LIAAgACgCiAFB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mAJBCBCEISIDRQRAQQhBmAIQ4SMACyADQQA6AJECIAMgBTYCjAIgAyAGNgKIAiADQRU2AoQCIANBgtXDADYCgAIgBEG02sMANgIEIAQgAzYCACAEKAIAIQMgAUG02sMANgIQIAEgAzYCDEG02sMACyEFIARB8ABqIAMgAiAFKAIMEQMAIAQtAHAiAkHCAEcNASAAQcIAOgAAQQMMAgtByNXDABC1FwALIAQtAHEhAyAEQdoBaiIFIARB8ABqQQJyQeYA/AoAACABQQxqEP4VIAJBwQBHBEAgBEEKaiAFQeYA/AoAAAsgACADOgABIAAgAjoAACAAQQJqIARBCmpB5gD8CgAAQQELOgAUIARBwAJqJAALDAAgAEHUhMUAENomCxIAIAAgASACQShB5MjTABDHJgsSACAAIAEgAkEwQbjJ0wAQxyYLkgMBBn8jAEHQAGsiAiQAIAJByABqIAFBOGopAgA3AwAgAkFAayABQTBqKQIANwMAIAJBOGoiBiABQShqKQIANwMAIAIgASkCIDcDMCMAQRBrIgQkACAEQQRqIAJBMGoiB0EgEPYMIAQoAgwiA0EgRwRAQSAgA0H0w+AAENMgAAsgAkEMaiIDQQA6AAAgAyAEKAIIIgUpAAA3AAEgA0EJaiAFQQhqKQAANwAAIANBEWogBUEQaikAADcAACADQRlqIAVBGGopAAA3AAAgBEEEahDzISAEQRBqJAAgAi0ADEEBRgRAIAYgAkEYaigCADYCACACIAIpAhA3AzBBlInUAEErIAdBhInUAEGQh9QAEKkOAAsgACACKQANNwAAIABBGGogAkElaikAADcAACAAQRBqIAJBHWopAAA3AAAgAEEIaiACQRVqKQAANwAAIABBOGogAUGcAmopAAA3AAAgAEEwaiABQZQCaikAADcAACAAQShqIAFBjAJqKQAANwAAIAAgASkAhAI3ACAgAkHQAGokAAsMACAAQdDx1AAQ2iYL7QECAX8EfiMAQaADayICJAAgAkHQAWogARCNCiAAAn4gAi0AmANBAUcEQCACQRBqIAJB2AFqKQMAIgM3AwAgAkEYaiACQeABaikDACIENwMAIAJBIGogAkHoAWopAwAiBTcDACACQR02AtABIAIgAikD0AEiBjcDCCAAQSBqIAU3AwAgAEEYaiAENwMAIABBEGogAzcDACAAIAY3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IAUgATYCBAwFC0Ho0coAELQXAAsgARDEGiACIAE2AhwgAkEBOgAgIAJBMGogAkEcahDODEGAgICAeCEHAkACfwJAAkACQAJAAkACQCACKAIwIgZBgICAgHhrDgICAAELIAIoAjQhBAwGCyACIAIpAjQiCzcCKCACIAY2AiQgAiACQRxqEM4MIAIoAgAiCEGAgICAeGsOAgMBAgtBACACQT9qQfjRygAQgQ8hBAwECyACKAIEDAILIAtCIIinIQkgAikCBCEKIAunIQQgBiEHDAILQQEgAkE/akH40coAEIEPCyEEIAJBJGoQ8yELIAEtABgiBkH/AUYNBCABIAZBAWo6ABggAiABENoEIgY2AhggAiAKNwIQIAIgCDYCDCACIAk2AgggAiAENgIEIAIgBzYCACAHQYCAgIB4RwRAIAZFDQMgAhDgGSAGIQQMAgsgBkUNASACQRhqEL8VDAELIAEgAkE/akH40coAEJoEIQQLIAEgBBChJSEBIAVBgICAgHg2AgAgBSABNgIEDAELIAUgAkEIaiIBKQIANwIIIAVBEGogAUEIaikCADcCACAFIAQ2AgQgBSAHNgIACyACQUBrJAAMAQtB6NHKABCuFwALAkAgAygCOEGAgICAeEYEQCAAIAMpAjg3AgAgAEEQaiADQcgAaikCADcCACAAQQhqIANBQGspAgA3AgAMAQsgA0EwaiADQcgAaiIBKQIANwMAIANBKGogA0FAayIEKQIANwMAIAMgAykCODcDICADQQRqEIgMIgcEQCAAQYCAgIB4NgIAIAAgBzYCBCADQSBqEOAZDAELIAAgAykCODcCACAAQRBqIAEpAgA3AgAgAEEIaiAEKQIANwIACyADQQRqEPMhIANB0ABqJAAL+AECAX8CfiMAQUBqIgIkAAJAIAApAwgiAyAAKQMQIgSEUARAIAJBBjYCHCACIAA2AhggASgCACEAIAEoAgQhASACQgE3AjQgAkEBNgIsIAJB5ObKADYCKAwBCyADQn9SBEAgAiADQgF8NwMIIARCf1IEQCACIARCAXw3AxAgAkEGNgIkIAJBBjYCHCACIAJBEGo2AiAgAiACQQhqNgIYIAEoAgAhACABKAIEIQEgAkICNwI0IAJBAjYCLCACQZznygA2AigMAgtB/ObKABCuFwALQezmygAQrhcACyACIAJBGGo2AjAg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QR53IARBE3dzIARBCndzamoiATYCBCAAIAkgByADKAIIaiAIIAYgBSAIc3FzaiAGQRp3IAZBFXdzIAZBB3dzaiIDajYCCCAAIAFBHncgAUETd3MgAUEKd3MgASACIARzcSACIARxc2ogA2o2AgALvwIBA38jAEEwayIAJAACQAJAQcTL5gAoAgBFBEBB3MvmACgCACEBQdzL5gBBADYCACABRQ0BIABBGGogARECACAAQRBqIgEgAEEkaikCADcDACAAIAApAhw3AwggACgCGCECQcTL5gAoAgANAkHIy+YAIAI2AgBBxMvmAEEBNgIAQczL5gAgACkDCDcCAEHUy+YAIAEpAwA3AgALIABBMGokAEHIy+YADwsgAEEANgIoIABBATYCHCAAQdCu5AA2AhggAEIENwIgIABBGGpB2K7kABD3GAALIABBKGogASkDADcCACAAIAApAwg3AiAgACACNgIcIABBATYCGCAAQRhqIgEoAgAEQCABQQRqQQRBBBCuDgsgAEEANgIoIABBATYCHCAAQfiu5AA2AhggAEIENwIgIAFBgK/kABD3GAALFQAgACABIAJB7O3CAEH4ucMAEJMmC/MBAQd/IwBBMGsiAiQAIAIgASgCADYCFCACIAEoAgQiAzYCDCACIAM2AhAgAiADIAEoAggiBGoiBTYCGEEAIQEgAkEANgIsQRAgBCAEQRBPGyEHA0AgASAHRwRAIAUhBiADIAVHBEAgAy0AACEIIANBAWohBgsgAkEcaiABaiAIOgAAIAIgAUEBaiIBNgIsIAYhAwwBCwsgAiADNgIQAkAgBEEQTwRAIAMgBUYEQCAAIAIpAhw3AAEgAEEBOgAAIABBCWogAkEkaikCADcAAAwCCyACIANBAWo2AhALIABBADoAAAsgAkEMahClGCACQTBqJAALFQAgACABIAJBiLrDAEGE9sIAEJMmC4MEAwZ/AX4BbyMAQSBrIgMkACADQQhqIQIjAEEQayIFJAAgBSABQQhqEKgcIAUoAgQhBAJAIAUoAgAiBkEORwRAIAIgBSkDCDcDCCACIAQ2AgQgAiAGNgIADAELIAUgASgCBBCoHCAFKAIEIQYgBSgCACIHQQ5HBEAgAiAFKQMINwMIIAIgBjYCBCACIAc2AgAgBEGEAUkNASAEEKEWDAELIAIgBjYCCCACIAQ2AgQgAkEONgIACyAFQRBqJAAgAykCDCEIAkACQAJAIAMoAggiAkEORwRAIAAgAygCFDYCFCAAIAg3AgwgACACNgIIDAELIAEoAgAgAyAIQiCIpyIGNgIIIAMgCKciBTYCHCMAQRBrIgIkAEEIaigCACUBIANBCGooAgAlASADQRxqKAIAJQEQXSEJEI0LIgQgCSYBIAQhByACQQhqEOwZQQEhBCADAn8gAigCCEEBcQRAIAIoAgwMAQtBACEEIAcLNgIEIAMgBDYCACACQRBqJAAgAygCBCECIAMoAgAgCEKAgICAwBBaBEAgBhChFgsgBUGEAU8EQCAFEKEWC0EBcQRAIABBCGogAhC2DwwBCyAAIAI2AgggAEEANgIEIABB9wI2AgAgASgCCCIAQYQBSQ0CDAELIABBADYCACABKAIIIgBBgwFNDQELIAAQoRYLIANBIGokAAv+AQEGfyMAQSBrIgIkACABKAIkIgNBAk0EfyABQQRqBSABKAIEIQMgASgCCAshBQJAAkAgA0UNACADQQR0IQYDQAJAIAJBCGogBSgCAEEIahDyDyACKAIMIgRBADoAACAEKAIIIQEgBEEQNgIIQQMhB0EMIQMCQAJAQQEgAUEOayABQQ1NG0EBaw4CAAIBCyAELQAMIQcgAiAEKQANNwMQIAIgBEEUaigAADYAFyABIgNBDkcNAQsgBUEQaiEFIAZBEGsiBg0BDAILCyAAIAc6AAQgACACKQMQNwAFIABBDGogAigAFzYAAAwBC0EOIQMLIAAgAzYCACACQSBqJAALiAICAn8CfiMAQdAAayIDJAACQAJAAkAgAkEgRgRAIANBGGogASABQRBqIgIQ0gYgAy0AGEUNAiADQRBqIgQgA0EhaikAADcDACADIAMpABk3AwggA0E/aiACIAFBIGoQ0gYgAy0AP0UNAyADQShqIAMpAEAiBTcDACADQTBqIANByABqKQAAIgY3AwAgACADKQMINwABIABBCWogBCkDADcAACAAQRFqIAU3AAAgAEEZaiAGNwAAIABBADoAAAwBCyAAQSA2AgwgACACNgIIIABBBjoABCAAQQE6AAALIANB0ABqJAAPC0GM9McAQSpBuPTHABC5EQALQYz0xwBBKkG49McAELkRAAvzAQECfyMAQSBrIgIkAAJAAkACQAJAAkACQCAALQAAQQFrDgMCAwEA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BARAIAAoAgQgBCgCDBECAAsgACABNgIEIAAgAjYCAAsgAEEAIAAoAggiASABQQFGIgEbNgIIIAENACAAKAIAIQEgAEEANgIAIAFFDQEgACgCBCAAQQA2AgggASgCBBECAAsgA0EQaiQADwtBqLXkABDSIAAL0AECAn8BfiMAQRBrIgEkAAJAAkACQCACrSADrX4iBkIgiKcNACAGpyICQQdqIgQgAkkNACADQQhqIgUgBEF4cSIEaiICIAVJIAJB+P///wdLcg0AIAIEfyACQQgQhCEFQQgLIgUNASACENwaIAAgASkDCDcCBCAAQQA2AgAMAgsQ1BMgACABKQMANwIEIABBADYCAAwBCyAAQQA2AgwgACADQQFrIgI2AgQgACAEIAVqNgIAIAAgAiADQQN2QQdsIAJBCEkbNgIICyABQRBqJAAL8gECAX8EfiMAQaABayIEJAAgBEEkaiADIAEgAhDdDAJAIAQtACRBAUYEQCAEQQtqIARBMGooAgAiATYAACAEIAQpAigiBTcAAyAAQQxqIAE2AAAgACAFNwAEIABBAjYCAAwBCyAEQRhqIARBPWopAAAiBTcDACAEQRBqIARBNWopAAAiBjcDACAEQQhqIARBLWopAAAiBzcDACAEIAQpACUiCDcDACAEQZgBaiAFNwIAIARBkAFqIAY3AgAgBEGIAWogBzcCACAEIAg3AoABIARBJGoiASADQdwA/AoAACAAIAFB/AD8CgAACyAEQaABaiQAC58EAQZ/IwBBMGsiBCQAIAEoAgAhBQJAIAEtABAiA0ECRwRAIAVFDQEgASgCDCABKAIEayIFIANqIgMgBU8NASAEQQA2AiggBEEBNgIcIARBwNvTADYCGCAEQgQ3AiAgBEEYaiACEPcYAAsgBUUEQEEAIQMMAQsgASgCDCABKAIEayEDCyAEQRhqIANBAEEBQQEQogsgBCgCHCEDIAQoAhhBAUcEQCAEQRRqIghBADYCACAEIAQoAiA2AhAgBCADNgIMIARBDGohBiMAQSBrIgMkACABKAIAIQcCQCABLQAQIgVBAkcEQCAHRQ0BIAEoAgwgASgCBGsiByAFaiIFIAdPDQEgA0EANgIYIANBATYCDCADQcDb0wA2AgggA0IENwIQIANBCGogAhD3GAALIAdFBEBBACEFDAELIAEoAgwgASgCBGshBQsg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CwwBCyABKQMIIgNCgAF8QoACWgRAIAJBAjoACCACIAM3AxAgACACQQhqIAJBH2pBjKnIABDbDTYCBEEBDAILCyAAIAM8AAFBAAs6AAAgAkEgaiQACxMAIAAgAUG8qMgAQeivyAAQ2CYLEwAgACABQcicyQBBoN3JABDYJgvDAgECfyMAQSBrIgIkACACQRRqIAEQowQCQCACLQAUQQFGBEAgACACKAIYNgIEIABBAToAAAwBCyACLQAVRQRAIABBgAg7AQAMAQsgASgCACIBKAIUIgNBf0cEQCABQQA2AgggASADQQFqNgIUIAJBFGogAUEMaiABEJIFIAIoAhghAQJAIAIoAhRBAkcEQCACQQxqIQMCfwJAAkACQAJAIAIoAhxBBGsOBAADAwEDCyABKAAAQePekasGRw0BQQAMAwsgAUH83ckAQQcQmhMNAUEBDAILIAEoAABB5MLRiwZHDQBBAgwBC0EDCyEBIANBADoAACADIAE6AAEgAi0ADEEBRw0BIAIoAhAhAQsgAEEBOgAAIAAgATYCBAwCCyAAIAItAA06AAEgAEEAOgAADAELQdSdyQAQrhcACyACQSBqJAALwwEBBH8jAEEwayIDJAACQCABIAJGBEAMAQsgAyABLQAAOgAMQSAgAiABayIFIAVBIE8bIgZBfyAGGyEEQQEhAgJAA0AgAiAGRg0BIANBDGogAmogASACai0AADoAACACQQFqIgINAAtB5LHVABCuFwALIAVBIEkNACAAIAMpAgw3AAAgAEEYaiADQSRqKQIANwAAIABBEGogA0EcaikCADcAACAAQQhqIANBFGopAgA3AAAgA0EwaiQADwsgBEEgEOkQAAvNAQEJfyAAIAAoAgRBGHYiAyAAKAIAQRh2IgVJQQJ0aiICIABBDEEIIAAtAA8gAC0AC0kiBhtqIgQgACADIAVPQQJ0aiIDIABBCEEMIAYbaiIALQADIAMtAANJIgUbIAQoAgAiB0EYdiACKAIAIghBGHZJIgIbIgYtAAMhCSAAIAMgBCACGyAFGyIELQADIQogASAHIAggAhs2AgAgASAEIAYgCSAKSyICGygCADYCBCABIAYgBCACGygCADYCCCABIAMgACAFGygCADYCDAvbAQIEfwN+IwBBIGsiAiQAIAEvATghAyACIAFBGGoQpwwgAigCBCEEIAIoAgAh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AUEADAQLIAUpAABCweSd++bNzLTkAFENAQsgBiAFIAlBlPXEAEEDENwKNgIEQQEMAgsgBkECOgABC0EACzoAACADQSBqEPMhDAELIANBEGogA0EvakGY6sMAEKsEIQUgBkEBOgAAIAYgBTYCBAsgAUGEAU8EQCABEKEWCyADQTBqJAACQCAHLQAIQQFGBEAgBygCDCEBIAhBAzoAACAIIAE2AgQgAkGEAUkNASACEKEWDAELIActAAkhASAIIAI2AgQgCCABOgAACyAHQRBqJAAgBCgCHCEBAkACQAJAAkACQAJAAkACQAJAIAQtABhBAWsOAwIDAAELIAAgATYCBEEBIQIMBwsgBCABEL0WQQEhAiAEKAIAQQFxDQVBACECIABBADoAAQwGCyAEQQhqIAEQvRZBASECIAQoAghBAXENAyAAQQE6AAEMAQsgBEEQaiABEL0WQQEhAiAEKAIQQQFxDQEgAEECOgABC0EAIQIMAwsgACAEKAIUNgIEDAILIAAgBCgCDDYCBAwBCyAAIAQoAgQ2AgQLIAAgAjoAACAEQSBqJAAL2gEBAn8jAEEwayIBJAAgACgCCEECRwRAIABBCGogABDuEwsCQEHg0OYALQAADQAgACgCGCICRQ0AIAFBAjYCDCABQfzHxQA2AgggAUIBNwIUIAFBBTYCJCABIAIpAgw3AiggASABQSBqNgIQIAEgAUEoajYCICAAIAFBCGoQiQULIAEgADYCCAJAAkACQCAALQCTAg4FAAICAQECCyAAQSBqEN4MDAELIABBmAJqEJMaIABB2AFqEPMhIABBiAFqELkVIABBADoAlAILIAFBCGoQ5Q0gAUEwaiQAC+QBAwF/AX4BfCMAQSBrIgIkACAAAn8CQAJAAkACQCABKAIAQQFrDgIBAgALIAErAwghBCACQQM6AAggAiAEOQMQIAAgAkEIaiACQR9qQfivyAAQ2g02AgRBAQwDCyABKQMIIgNCgIAEWgRAIAJBAToACCACIAM3AxAgACACQQhqIAJBH2pB7KjIABDbDTYCBEEBDAMLDAELIAEpAwgiA0KAgARaBEAgAkECOgAIIAIgAzcDECAAIAJBCGogAkEfakHsqMgAENsNNgIEQQEMAgsLIAAgAz0BAkEACzsBACACQSBqJAALEwAgACABQdyoyABBqLDIABDWJgsTACAAIAFB/KjIAEGYsMgAENYmCxMAIAAgAUHMqMgAQYiwyAAQ1yYLEwAgACABQdicyQBBgN3JABDWJgsTACAAIAFB6JzJAEGQ3ckAENcmC7ACAQV/AkACQCAAKAIIIgNBgZTr3ANGIAEoAggiBEGBlOvcA0ZyRQRAIANBgJTr3ANHIARBgJTr3ANHcw0CIANBgJTr3ANGIARBgJTr3ANGcg0BIAAoAiQgASgCJEcNAiAAKAIgIAEoAiBHDQIjAEEgayICJAAgAiAAQRBqEL4DIAJBEGogAUEQahC+AwJAIAIoAgAgAigCEEcNACACLwEEIAIvARRHDQAgAikCGCACKQIIhUL/////8+fPD4NQIQULIAJBIGokACAFRQ0CIAAoAiggASgCKEcgAyAER3INAiAAKQMAIAEpAwBSDQIgACgCLCABKAIsRg0BDAILIANBgZTr3ANHIARBgZTr3ANHcg0BCyAAKAJAIAEoAkBHDQAgACgCRCABKAJERiEGCyAGC+IBAQJ/IwBBIGsiAiQAIAJBCGoiAyABQcik5ABBBRDKGQJAIAAoAgAiAEEATgRAIAIgADYCECADQeCk5ABBCCACQRBqQdCk5AAQtwcaDAELIAIgABDWFSACKAIAIgEEQCACKAIEIQMgAiABNgIUIAIgAzYCGCACIAA2AhwgAkEIaiIAQZSl5ABBDSACQRxqQYSl5AAQtwcaIABB+KTkAEELIAJBFGpB6KTkABC3BxoMAQsgAiAANgIUIAJBCGpBoaXkAEEMIAJBFGpBhKXkABC3BxoLIAJBCGoQjRAgAkEgaiQAC6cEAgV/AX4jAEEQayIDJAACfyAAKAIAQQJHBEAjAEFAaiICJABBASEEAkACQAJ/AkAgACgCAEEBRgRAIAIgAEEEajYCCCABKAIIIAIgATYCFCACQoCAgICAyNAHNwIMIAJBCGqtQoCAgICwsQKEIQdBgICABHENASACIAc3AxggAkIBNwIwIAJBATYCKCACQdTb5AA2AiQgAiACQRhqNgIsIAJBDGpB4N/kACACQSRqEKkEDAILIAEgACgCECAAKAIUEOgeDQMMAgsgAiAHNwMYIAJBATYCOCACQdzb5AA2AjQgAkEBNgIwIAJBATYCKCACQdTb5AA2AiQgAiACQRhqNgIsIAJBDGpB4N/kACACQSRqEKkECyIFQQAgAigCDCIGG0UEQCAFDQIgBkUNAUGY3OQAQTcgAkE/akGI3OQAQdDc5AAQqQ4ACyABQfTb5ABBFBDoHg0BCyABIAAoAhggACgCHBDoHiEECyACQUBrJAAgBAwBCwJAAkACQCAAKAIkIgJFDQAgACgCICEAA0AgA0EEaiAAIAIQ0QMCQCADKAIEQQFGBEAgAy0ADSEEIAMtAAwhBSADKAIIIQZBzLfkAEEDIAEQ4yNFDQEMBQsgAygCCCADKAIMIAEQ4yMNBAwCCyAFQQFxRQ0BIAIgBCAGaiIESQ0CIAAgBGohACACIARrIgINAAsLQQAMAgsgBCACIAJB0LfkABCbFQALQQELIANBEGokAAvzAQEDfyMAQSBrIgIkAAJAAkACQCAALQAAIgNBAk8EQCADQQNrDQEMAwsgAEECOgAAIAEoAgAgAUEANgIABEAgA0EBRwRAQbzU5gAtAAAhAUG81OYAQQE6AAAgAiABOgAHIAFBAUcNAyACQgA3AhQgAkKBgICAwAA3AgwgAkHswOQANgIIIAJBB2pBhMHkACACQQhqQfTA5AAQ7xYACxCqFwALQZjB5AAQ0iAACyACQQA2AhggAkEBNgIMIAJBxMDkADYCCCACQgQ3AhAgAkEIakGIweQAEPcYAAtBvNTmAEEAOgAAIABBAzoAAAsgAkEgaiQAC+kBAQF/IwBBEGsiFyQAIAAoAgAgASACIAAoAgQoAgwRBQAhASAXQQA6AA0gFyABOgAMIBcgADYCCCAXQQhqIAMgBCAFIAYQtwcgByAIIAkgChC3ByALIAwgDSAOELcHIA8gECARIBIQtwcgEyAUIBUgFhC3ByEBIBctAA0iAiAXLQAMIgNyIQACQCADQQFxIAJBAUdyDQAgASgCACIALQAKQYABcUUEQCAAKAIAQbX85ABBAiAAKAIEKAIMEQUAIQAMAQsgACgCAEG0/OQAQQEgACgCBCgCDBEFACEACyAXQRBqJAAgAEEBcQuUBAEHfyMAQSBrIgckACAHQRhqIQgCQEEkQQQQhCEiBgRAIAZBADoAIiAGQQA7ASAgBkEAOgAcIAZBADYCFCAGQQA6ABAgBkEANgIIIAZCgoCAgBA3AgAgCCAGNgIEIAggBjYCAAwBC0EEQSQQ4SMACyAHKAIcIQkgBygCGCEKIAdBEGohCAJAQZgBQQgQhCEiBgRAIAZBADoAkAEgBkEAOgCMASAGQQA2AoQBIAZBADoAgAEgBkEANgJ4IAZBADoAcCAGQTE6AAggBkKCgICAEDcCACAIIAY2AgQgCCAGNgIADAELQQhBmAEQ4SMACyAHKAIUIQsgBygCECEMIAdBCGohCAJAAkBBzABBBBCEISIGBEAgBkEBNgIIIAZCgYCAgBA3AgAgBkEMaiABQTz8CgAAIAZBADYCSCAGIAYoAgAiAUEBajYCACABQQBIDQEgCCAGNgIEIAggBjYCAAwCC0EEQcwAEOEjCwALIAcoAgwhBiAHKAIIIQhBtAFBBBCEISIBRQRAQQRBtAEQ4SMACyABQQA6ALABIAEgBTYCICABIAg2AhwgASAMNgIUIAEgBDYCECABIAM2AgwgASACKQIANwIAIAEgCTYCGCABQQhqIAJBCGooAgA2AgAgAUGQ0sYAEPIMIAAgCjYCKCAAIAs2AiQgACAGNgIgIABBhYCAgHg2AgggAEEANgIAIAdBIGokAAuwBwEFfyMAQdAAayIDJAAgA0EIaiABENkLAkAgAygCCEGVgICAeEcEQCADQTBqIANBEGopAwA3AwAgAyADKQMINwMoIAEoAgBBlYCAgHhHBEAgARDFDQsgASADQRhqIgIpAwA3AwAgAUEIaiACQQhqKQMANwMAIANBQGsiASADQShqELcbIANBOGohBiMAQUBqIgQkAAJAAkACQAJAAkACQAJAAkACQEEVIAEoAgAiAkGAgICAeHMgAkEAThtBAWsODwEAAAIAAAAAAAAAAwQFBgALIARBMGogAUEIaikDADcDACAEIAEpAwA3AyggBEEoaiAEQT9qQaTXxwAQvBghASAGQQE6AAAgBiABNgIEDAcLIAEtAARBAEchBQwFCyABKQMIQgBSIQUMBAsgBEEQaiABQQxqKAIAIgI2AgAgBCABKQIENwMIQQEhASACQQ9GBEAgBCgCDEHs48cAQQ8QmhNBAEchAQsgBkEAOgAAIAYgAToAASAEQQhqEPMhDAQLQQEhBSABKAIIQQ9HDQIgASgCBEHs48cAQQ8QmhNBAEchBQwCCyAEQSBqIAFBDGooAgA2AgAgBCABKQIENwMYQQEhBQJAIARBGGoiAigCCEEPRw0AIAIoAgQiAS0AAEHhAEcNACABLQABQfYARw0AIAEtAAJB4QBHDQAgAS0AA0HpAEcNACABLQAEQewARw0AIAEtAAVB4QBHDQAgAS0ABkHiAEcNACABLQAHQewARw0AIAEtAAhB5QBHDQAgAS0ACUHfAEcNACABLQAKQfQARw0AIAEtAAtB7wBHDQAgAS0ADEH0AEcNACABLQANQeEARw0AIAEtAA5B7ABHIQULIAZBADoAACAGIAU6AAEgAhDzIQwCC0EBIQUgASgCCEEPRw0AIAEoAgQiAi0AAEHhAEcNACACLQABQfYARw0AIAItAAJB4QBHDQAgAi0AA0HpAEcNACACLQAEQewARw0AIAItAAVB4QBHDQAgAi0ABkHiAEcNACACLQAHQewARw0AIAItAAhB5QBHDQAgAi0ACUHfAEcNACACLQAKQfQARw0AIAItAAtB7wBHDQAgAi0ADEH0AEcNACACLQANQeEARw0AIAItAA5B7ABHIQULIAZBADoAACAGIAU6AAEgARDBDQsgBEFAayQAQQEhAQJAIAMtADhBAUYEQCAAIAMoAjw2AgQMAQsgACADLQA5OgABQQAhAQsgACABOgAADAELIABBgAQ7AQALIANB0ABqJAALEwAgACABQaPvxwBBlNfHABCXJgvbBwIFfwF+IwBB0ABrIgMkACADQQhqIAEQ2QsCQCADKAIIQZWAgIB4RwRAIANBMGogA0EQaikDADcDACADIAMpAwg3AyggASgCAEGVgICAeEcEQCABEMUNCyABIANBGGoiAikDADcDACABQQhqIAJBCGopAwA3AwAgA0FAayIBIANBKGoQtxsgA0E4aiEEIwBBQGoiBSQAAkACQAJAAkACQAJAAkACQAJAQRUgASgCACICQYCAgIB4cyACQQBOG0EBaw4PAQAAAgAAAAAAAAADBAUGAAsgBUEwaiABQQhqKQMANwMAIAUgASkDADcDKCAFQShqIAVBP2pBlNjHABC8GCEBIARBAToAACAEIAE2AgQMBwsgBEEAOgAAIARBAUECIAEtAAQiAkEBRhtBACACGzoAAQwFCyAEQQA6AAAgBEEAQQFBAiABKQMIIgdCAVEbIAdQGzoAAQwECyAFQRBqIAFBDGooAgAiAjYCACAFIAEpAgQ3AwggBCAFKAIMIAIQpxMgBUEIahDzIQwECyAEIAEoAgQgASgCCBCnEwwCCyAFQSBqIAFBDGooAgA2AgAgBSABKQIENwMYIAVBGGoiAigCBCEBAn8CQCAC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QAJAAkACQAJAAkACQAJAAkBBFSABKAIAIgJBgICAgHhzIAJBAE4bQQFrDg8BAAACAAAAAAAAAAMEBQYACyAFQTBqIAFBCGopAwA3AwAgBSABKQMANwMoIAVBKGogBUE/akGk2McAELwYIQEgBEEBOgAAIAQgATYCBAwHCyAEQQA6AAAgBEEBQQIgAS0ABCICQQFGG0EAIAIbOgABDAULIARBADoAACAEQQBBAUECIAEpAwgiBkIBURsgBlAbOgABDAQLIAVBEGogAUEMaigCACICNgIAIAUgASkCBDcDCCAEIAUoAgwgAhCKFCAFQQhqEPMhDAQLIAQgASgCBCABKAIIEIoUDAILIAVBIGogAUEMaigCADYCACAFIAEpAgQ3AxggBUEYaiICKAIEIQECfwJAAkACQCACKAIIQQhrDgIAAQILIAEtAABB8gBHDQEgAS0AAUHlAEcNASABLQACQfEARw0BIAEtAANB9QBHDQEgAS0ABEHpAEcNASABLQAFQfIARw0BIAEtAAZB5QBHDQEgAS0AB0HkAEcNAUEADAILIAEtAABB4QBHDQAgAS0AAUH2AEcNACABLQACQeEARw0AIAEtAANB6QBHDQAgAS0ABEHsAEcNACABLQAFQeEARw0AIAEtAAZB4gBHDQAgAS0AB0HsAEcNACABLQAIQeUARw0AQQEMAQtBAgshASAEQQA6AAAgBCABOgABIAIQ8yEMAgsgASgCBCECAn8CQAJAAkAgASgCCEEIaw4CAAECCyACLQAAQfIARw0BIAItAAFB5QBHDQEgAi0AAkHxAEcNASACLQADQfUARw0BIAItAARB6QBHDQEgAi0ABUHyAEcNASACLQAGQeUARw0BIAItAAdB5ABHDQFBAAwCCyACLQAAQeEARw0AIAItAAFB9gBHDQAgAi0AAkHhAEcNACACLQADQekARw0AIAItAARB7ABHDQAgAi0ABUHhAEcNACACLQAGQeIARw0AIAItAAdB7ABHDQAgAi0ACEHlAEcNAEEBDAELQQILIQIgBEEAOgAAIAQgAjoAAQsgARDBDQsgBUFAayQAQQEhAQJAIAMtADhBAUYEQCAAIAMoAjw2AgQMAQsgACADLQA5OgABQQAhAQsgACABOgAADAELIABBgAY7AQALIANB0ABqJAAL1AUBBX8jAEHQAGsiAiQAIAJBCGog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DQEgAi0AA0H0AEcNASACLQAEQfUARw0BIAItAAVB8wBHDQFBAQwCCyACLQAAQeIARw0AIAItAAFB4QBHDQAgAi0AAkHuAEcNACACLQADQeQARw0AIAItAARB9wBHDQAgAi0ABUHpAEcNACACLQAGQeQARw0AIAItAAdB9ABHDQAgAi0ACEHoAEcNACACLQAJQd8ARw0AIAItAApB8gBHDQAgAi0AC0HlAEcNACACLQAMQe0ARw0AIAItAA1B4QBHDQAgAi0ADkHpAEcNACACLQAPQe4ARw0AIAItABBB6QBHDQAgAi0AEUHuAEcNACACLQASQecARw0AQQIMAQtBAwshAiAEQQA6AAAgBCACOgABCyABEMENCyAFQUBrJABBASEBAkAgAy0AOEEBRgRAIAAgAygCPDYCBAwBCyAAIAMtADk6AAFBACEBCyAAIAE6AAAMAQsgAEGACDsBAAsgA0HQAGokAAuICAEFfyMAQdAAayIDJAAgA0EIaiABENkLAkAgAygCCEGVgICAeEcEQCADQTBqIANBEGopAwA3AwAgAyADKQMINwMoIAEoAgBBlYCAgHhHBEAgARDFDQsgASADQRhqIgIpAwA3AwAgAUEIaiACQQhqKQMANwMAIANBQGsiASADQShqELcbIANBOGohBiMAQUBqIgQkAAJAAkACQAJAAkACQAJAAkACQEEVIAEoAgAiAkGAgICAeHMgAkEAThtBAWsODwEAAAIAAAAAAAAAAwQFBgALIARBMGogAUEIaikDADcDACAEIAEpAwA3AyggBEEoaiAEQT9qQYTYxwAQvBghASAGQQE6AAAgBiABNgIEDAcLIAEtAARBAEchBQwFCyABKQMIQgBSIQUMBAsgBEEQaiABQQxqKAIAIgI2AgAgBCABKQIENwMIQQEhASACQRNGBEAgBCgCDEH/48cAQRMQmhNBAEchAQsgBkEAOgAAIAYgAToAASAEQQhqEPMhDAQLQQEhBSABKAIIQRNHDQIgASgCBEH/48cAQRMQmhNBAEchBQwCCyAEQSBqIAFBDGooAgA2AgAgBCABKQIENwMYQQEhBQJAIARBGGoiAigCCEETRw0AIAIoAgQiAS0AAEHyAEcNACABLQABQeUARw0AIAEtAAJB7QBHDQAgAS0AA0HhAEcNACABLQAEQekARw0AIAEtAAVB7gBHDQAgAS0ABkHpAEcNACABLQAHQe4ARw0AIAEtAAhB5wBHDQAgAS0ACUHfAEcNACABLQAKQeIARw0AIAEtAAtB4QBHDQAgAS0ADEHuAEcNACABLQANQeQARw0AIAEtAA5B9wBHDQAgAS0AD0HpAEcNACABLQAQQeQARw0AIAEtABFB9ABHDQAgAS0AEkHoAEchBQsgBkEAOgAAIAYgBToAASACEPMhDAILQQEhBSABKAIIQRNHDQAgASgCBCICLQAAQfIARw0AIAItAAFB5QBHDQAgAi0AAkHtAEcNACACLQADQeEARw0AIAItAARB6QBHDQAgAi0ABUHuAEcNACACLQAGQekARw0AIAItAAdB7gBHDQAgAi0ACEHnAEcNACACLQAJQd8ARw0AIAItAApB4gBHDQAgAi0AC0HhAEcNACACLQAMQe4ARw0AIAItAA1B5ABHDQAgAi0ADkH3AEcNACACLQAPQekARw0AIAItABBB5ABHDQAgAi0AEUH0AEcNACACLQASQegARyEFCyAGQQA6AAAgBiAFOgABIAEQwQ0LIARBQGskAEEBIQECQCADLQA4QQFGBEAgACADKAI8NgIEDAELIAAgAy0AOToAAUEAIQELIAAgAToAAAwBCyAAQYAEOwEACyADQdAAaiQAC/UIAgV/AX4jAEHQAGsiAyQAIANBCGogARDZCwJAIAMoAghBlYCAgHhHBEAgA0EwaiADQRBqKQMANwMAIAMgAykDCDcDKCABKAIAQZWAgIB4RwRAIAEQxQ0LIAEgA0EYaiICKQMANwMAIAFBCGogAkEIaikDADcDACADQUBrIgEgA0EoahC3GyADQThqIQQjAEFAaiIFJAACQAJAAkACQAJAAkACQAJAAkBBFSABKAIAIgJBgICAgHhzIAJBAE4bQQFrDg8BAAACAAAAAAAAAAMEBQYACyAFQTBqIAFBCGopAwA3AwAgBSABKQMANwMoIAVBKGogBUE/akG018cAELwYIQEgBEEBOgAAIAQgATYCBAwHCyAEQQA6AAAgBEEBQQIgAS0ABCICQQFGG0EAIAIbOgABDAULIARBADoAACAEQQBBAUECIAEpAwgiB0IBURsgB1AbOgABDAQLIAVBEGogAUEMaigCACICNgIAIAUgASkCBDcDCCAEIAUoAgwgAhCoEyAFQQhqEPMhDAQLIAQgASgCBCAB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OwAAIAJBAmogBCAFQeQAbGtBAXQvANDkXzsAACACQQRrIQIgAUH/wdcvSyADIQENAQwCCwtB3LzgABC0FwALIAJBBGohAgsCQCADQeMATQRAIAMhAQwBCyACQQJrIgIgAyADQf//A3FB5ABuIgFB5ABsa0H//wNxQQF0LwDQ5F87AAALAkAgAUEKTwRAIAJBAmsgAUEBdC8A0ORfOwAADAELIAJBAWsgAUEwcjoAAAsLpwEBAn8jAEEgayIDJAAgAyACIAJBIGogACAAQSBqEIQVIAMgATYCGCADIAFBIGo2AhwgAygCECECIAMoAhQhACADQRhqEKQgIgQgACACayIAIAAgBEsbIgAEQCADKAIAIAJqIQQgAygCCCACaiECA0AgBCABLQAAIAItAABzOgAAIARBAWohBCACQQFqIQIgAUEBaiEBIABBAWsiAA0ACwsgA0EgaiQAC+0BAQJ/IwBBMGsiAiQAAkAgACkDAEL///////////8Ag0KAgICAgICA+P8AWgRAIAJB8gc2AhQgAiAANgIQIAEoAgAgASgCBCACQgE3AiQgAkEBNgIcIAJBzLPkADYCGCACIAJBEGo2AiAgAkEYahCpBCEDDAELIAJBADoADCACIAE2AghBASEDIAJBATYCHCACQcyz5AA2AhggAkIBNwIkIAJB8gc2AhQgAiAANgIQIAIgAkEQajYCICACQQhqIAJBGGoQ7xENACACLQAMRQRAIAFB1LPkAEECEOgeDQELQQAhAwsgAkEwaiQAIAMLOwAgACABQeDlyABBkefIAEH27MgAQd7syABBqOfIAEH258gAQZjnyABBwezIAEHJ7MgAQa3syAAQ3CULOwAgACABQeDg0wBBiOHTAEGO4dMAQfDg0wBBnN/TAEHA4NMAQZTg0wBBuODTAEHI4NMAQaTg0wAQ3CUL1AECA38BfgJAAkAgACAAQYz7lAFrIgFKBEAgAUHwxcCuAWoiACABSA0BIABB/////wNLDQIgAEECdEEDciIAIABBsfUIbiIAQbH1CGxrQQNyrULhtrMBfiIEpyIBQYTbzQVuIgJBz/0DaiACQQNBDyABQcfP47N9SyIBIARCIIinIABB5ABsampBwIQ9ayIAQeQAbxsgAHEiA0VqQTxqIAEbQf//A3EgAEEKdEEAQYAEIAMbcnIPC0HMmN8AELQXAAtB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QQEQogsgAygCLCEEIAMoAihBAUYNASADQRhqIghBADYCACADIAMoAjA2AhQgAyAENgIQIA0gBWsiBCADQRBqIgooAgAgCigCCCIJa0sEQCMAQRBrIgckACAHQQhqIAogCSAEQQFBARCgByAHKAIIIglBgYCAgHhHBEAgCSAHKAIMQdCZygAQ9hsACyAHQRBqJAALIAooAgghByAFIA1HBEAgCigCBCENA0AgByANaiAFLQAAOgAAIAVBAWohBSAHQQFqIQcgBEEBayIEDQALCyAKIAc2AgggC0EIaiAIKAIANgIAIAsgAykCEDcCACADQUBrJAAMAgsgA0EANgI4IANBATYCLCADQeD3xwA2AiggA0IENwIwIANBKGpBsIPIABD3GAALIAQgAygCMEGwg8gAEPYbAAsgBikCDCEhIAYoAgghBEGAgICAeAshByAGQQA2AkggBkKAgICAEDcCQCAGQZy5xAA2AgwgBkKggICADjcCECAGIAZBQGsiBTYCCCARQdwAaiAGQQhqIgoQqg0NASAGQShqIAZByABqIgMoAgA2AgAgBiAGKQJANwMgIAZBADYCSCAGQoCAgIAQNwJAIAZBnLnEADYCDCAGQqCAgIAONwIQIAYgBTYCCCARKAIUIBEoAhggChDjIw0BIAZBOGogAygCADYCACAGIAYpAkA3AzBBgICAgHghAyARKAJIQYCAgIB4RwRAIAZBADYCSCAGQoCAgIAQNwJAIAZBnLnEADYCDCAGQqCAgIAONwIQIAYgBTYCCCARQcgAaiAKEOYfDQIgBikCRCEiIAYoAkAhAwsgDiAGKQMgNwIAIA4gIjcCNCAOIAM2AjAgDiAhNwIoIA4gBDYCJCAOICA3AhwgDiAHNgIYIA4gBikDMDcCDCAOIBEpApwCNwI8IA5BCGogBkEoaigCADYCACAOQcQAaiARQaQCaikCADcCACAOQRRqIAZBOGooAgA2AgAgBkHQAGokAAwCCyAGQQA2AhggBkEBNgIMIAZBvLfEADYCCCAGQgQ3AhAgBkEIakHEt8QAEPcYAAtBxLnEAEE3IAZBzwBqQbS5xABB/LnEABCpDgALIBQgHSAOEOYVIBQoAgAhAyABQYzWwwA2AlggASADNgJUQYzWwwALIQQgFEEIaiADIAIgBCgCDBEDACAULQAIQcIARw0BIABBwgA6AABB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DAELIAItABVFBEAgAEGABjsBAAwBCyABKAIAIgEQtxogAUEANgIIIAJBFGogAUEMaiABEJIFIAIoAhghAQJAIAIoAhRBAkcEQCACQQxqIAEgAigCHBD+EyACLQAMQQFHDQEgAigCECEBCyAAQQE6AAAgACABNgIEDAELIAAgAi0ADToAASAAQQA6AAALIAJBIGokAAvIAQEBfyMAQSBrIgIkACACQRRqIAEQowQCQCACLQAUQQFGBEAgACACKAIYNgIEIABBAToAAAwBCyACLQAVRQRAIABBgA47AQAMAQsgASgCACIBELcaIAFBADYCCCACQRRqIAFBDGogARCSBSACKAIYIQECQCACKAIUQQJHBEAgAkEMaiABIAIoAhwQugwgAi0ADEEBRw0BIAIoAhAhAQsgAEEBOgAAIAAgATYCBAwBCyAAIAItAA06AAEgAEEAOgAACyACQSBqJAALxwIBA38jAEEgayICJAAgAkEUaiABEKMEAkAgAi0AFEEBRgRAIAAgAigCGDYCBCAAQQE6AAAMAQsgAi0AFUUEQCAAQYAKOwEADAELIAEoAgAiARC3GiABQQA2AgggAkEUaiABQQxqIAEQkgUgAigCGCEBAkAgAigCFEECRwRAIAJBDGohAwJ/AkACQAJAAkACQCACKAIcIgRBC2sOBwIDBAQEBAEACyAEQQZHDQMgAUGM6sUAQQYQmhMNA0EADAQLIAFBkurFAEEREJoTDQJBAQwDCyABQaPqxQBBCxCaEw0BQQIMAgsgAUGu6sUAQQwQmhMNAEEDDAELQQQLIQEgA0EAOgAAIAMgAToAASACLQAMQQFHDQEgAigCECEBCyAAQQE6AAAgACABNgIEDAELIAAgAi0ADToAASAAQQA6AAALIAJBIGokAAuuAgECfyMAQSBrIgIkACACQRRqIAEQowQCQCACLQAUQQFGBEAgACACKAIYNgIEIABBAToAAAwBCyACLQAVRQRAIABBgAg7AQAMAQsgASgCACIBELcaIAFBADYCCCACQRRqIAFBDGogARCSBSACKAIYIQECQCACKAIUQQJHBEAgAkEMaiEDAn8CQAJAAkACQCACKAIcQQdrDgIBAAMLIAEpAABC6N7No+et2LblAFINAUEADAMLIAFB4+nFAEEHEJoTDQFBAQwCCyABKQAAQvfmzfuF7pu59ABSDQBBAgwBC0EDCyEBIANBADoAACADIAE6AAEgAi0ADEEBRw0BIAIoAhAhAQsgAEEBOgAAIAAgATYCBAwBCyAAIAItAA06AAEgAEEAOgAACyACQSBqJAALwAIBAn8jAEEgayICJAAgAkEUaiABEKMEAkAgAi0AFEEBRgRAIAAgAigCGDYCBCAAQQE6AAAMAQsgAi0AFUUEQCAAQYAKOwEADAELIAEoAgAiARC3GiABQQA2AgggAkEUaiABQQxqIAEQkgUgAigCGCEBAkAgAigCFEECRwRAIAJBDGohAwJ/AkACQAJAAkACQCACKAIcQQVrDgQBBAADBAsgAUH35cUAQQcQmhMNAUEADAQLIAFB/uXFAEEFEJoTDQJBAQwDCyABQYPmxQBBBxCaEw0BQQIMAgsgASkAAELl8KWj96uauPIAUg0AQQMMAQtBBAshASADQQA6AAAgAyABOgABIAItAAxBAUcNASACKAIQIQELIABBAToAACAAIAE2AgQMAQsgACACLQANOgABIABBADoAAAsgAkEgaiQAC5YCAQJ/IwBBIGsiAiQAIAJBFGogARCjBAJAIAItABRBAUYEQCAAIAIoAhg2AgQgAEEBOgAADAELIAItABVFBEAgAEGABjsBAAwBCyABKAIAIgEQtxogAUEANgIIIAJBFGogAUEMaiABEJIFIAIoAhghAQJAIAIoAhRBAkcEQCACQQxqIQMCfwJAAkACQCACKAIcQQVrDgQBAgIAAgsgASkAAELtytGLxqyYuuEAUg0BQQAMAgsgAUHc6sUAQQUQmhMNAEEBDAELQQILIQEgA0EAOgAAIAMgAToAASACLQAMQQFHDQEgAigCECEBCyAAQQE6AAAgACABNgIEDAELIAAgAi0ADToAASAAQQA6AAALIAJBIGokAAvxAgEDfyMAQSBrIgIkACACQRRqIAEQowQCQCACLQAUQQFGBEAgACACKAIYNgIEIABBAToAAAwBCyACLQAVRQRAIABBgA47AQAMAQsgASgCACIBELcaIAFBADYCCCACQRRqIAFBDGogARCSBSACKAIYIQECQCACKAIUQQJHBEAgAkEMaiEDAn8CQAJAAkACQAJAAkACQCACKAIcIgRBDGsOCQQGBgYDBgECBQALIARBAkcNBSABLwAAQenIAUcNBUEADAYLIAFBjObFAEESEJoTDQRBAQwF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AgQiAigCDCIIBEAgCiAINgIEIAIoAgBBgICAgHhHDQEgCCgCACIFQYCAgIB4Rg0CIAhBgICAgHg2AgAgCCkCBCELIAIoAgBBgICAgHhHBEAgAhCPFyACEPYgCyACQRBBBBCfICAHIAs3AgQgByAFNgIADAMLIAIgCigCAEcEQCAHQYGAgIB4NgIADAMLIAdBgICAgHg2AgAMAgtBhN/GAEEpQbDfxgAQnBUAC0HA38YAQSlB7N/GABCcFQALIAQoAgQiBUEfdSAFQf////8Ha3EiBUECRg0ACwJAIAVBAUYEQCAJQYCAgIB4NgIADAELIAkgBCkCBDcCACAJQQhqIARBDGooAgA2AgALIARBEGokACADKAIEQYCAgIB4Rg0BIAAgAykCBDcCACAGIAYoAhBBAWs2AhAgAEEIaiADQQxqKAIANgIADAILIABBgICAgHg2AgAMAQsgACAGKAIQBH9BgYCAgHgFAkAgASgCACIARQ0AIAAgACgCACIAQQFrNgIAIABBAUcNACABEOESCyABQQA2AgBBgICAgHgLNgIACyADQRBqJAAL0AECA38BfiMAQSBrIgIkACACIAEQjwcgAigCBCEBAkAgAigCACIDQYCAgIB4RgRAIABBgICAgHg2AgAgACABNgIEDAELIAIgASACKAIIIgQQ0QMgAigCAEEBRgRAIAIgAikCBCIFNwIMIAIgBDYCCCACIAE2AgQgAiADNgIAIAJBgYCAgHg2AhQgAiAFNwIYIAJBFGoQ3BYhASACEPMhIABBgICAgHg2AgAgACABNgIEDAELIAAgBDYCCCAAIAE2AgQgACADNgIACyACQSBqJAALzwEBAn8jAEEQayICJAACfwJAAkACQAJAQQIgACgCACIDQYCAgIB4cyADQQBOG0EBaw4DAQIDAAsgAiAAQQRqNgIMIAFBuLDKAEEXIAJBDGpBqLDKABClCAwDCyACIABBBGo2AgwgAUHPsMoAQRkgAkEMakGosMoAEKUIDAILIAIgADYCDCABQfiwygBBBSAAQQxqQYypygAgAkEMakHosMoAEJgGDAELIAIgAEEEajYCDCABQf2wygBBByACQQxqQeiwygAQpQgLIAJBEGokAAuxAQEFfyMAQRBrIgMkACADQQRqIAJBAEEBQQEQogsgAygCCCEFIAMoAgRBAUcEQCADKAIMIQQgAgRAIAQgASAC/AoAAAsgAgRAIAQhASACIQYDQCABQSBBACABLQAAIgdBwQBrQf8BcUEaSRsgB3I6AAAgAUEBaiEBIAZBAWsiBg0ACwsgACACNgIIIAAgBDYCBCAAIAU2AgAgA0EQaiQADwsgBSADKAIMQayI0wAQ9hsAC8IBAgF+A38gASgCGCIFBH8CQCABKQMAIgJQRQRAIAEoAhAhAwwBCyABKAIQIQMgASgCCCEEA0AgA0EgayEDIAQpAwAgBEEIaiEEQoCBgoSIkKDAgH+DIgJCgIGChIiQoMCAf1ENAAsgASADNgIQIAEgBDYCCCACQoCBgoSIkKDAgH+FIQILIAEgBUEBazYCGCABIAJCAX0gAoM3AwAgAyACeqdBAXZBPHFrIgNBBGsFQQALIQQgACADNgIEIAAgBDYCAAuwAQEDfwJAAkAgAS0ANEUEQAwBCyABKAIYIQIgASgCFCEEIAEoAiwiAyABKAIoIgFJDQECQCABRQ0AIAEgAk8EQCABIAJHDQMMAQsgASAEaiwAAEG/f0wNAgsCQCADRQ0AIAIgA00EQCACIANGDQEMAwsgAyAEaiwAAEG/f0wNAgsgASAEaiECIAMgAWshAQsgACABNgIEIAAgAjYCAA8LIAQgAiABIANBtN7VABCUHwALtgEBBH8CQAJAAkAgAkF3TQRAIAJBCGohBSACQQ9qIQMgACACQQJ0aiEGQSAhAAJAA0AgA0EIayIEIAJJDQMgASAETQ0EIAMgBUkNBSABIANNDQEgACAGaiIEQRxqIARBBGsoAgA2AgAgA0EBayEDIABBBGsiAA0ACw8LIAMgAUGAxOEAEIwQAAtBwMPhABCuFwALQdDD4QAQrhcACyADQQhrIAFB4MPhABCMEAALQfDD4QAQrhcAC6YEAQx/IwBBMGsiACQAIABBEGoiChCxCCIFQRBqIgcoAgA2AgAgAEEIaiILIAVBCGoiCCkCADcDACAHQQA2AgAgCEIANwIAIAAgBSkCADcDACAFQoCAgIDAADcCACMAQRBrIgkkAAJAAkAgACgCDCICIAAoAggiAUYEQCACIQEgACgCACIDIAJGBEDQb0GAASACIAJBgAFNGyIB/A8BIgNBf0YNAgJAIAAoAhAiBkUEQCAAIAM2AhAMAQsgBiACIAZqIgRNBEAgAyAERg0BDAQLQeit5AAQrhcACyAJQQhqIQYjAEEQayIDJAACf0GBgICAeCAAKAIAIAAoAggiBGsgAU8NABogA0EIaiAAIAQgAUEEELoIQYGAgIB4IAMoAggiBEGBgICAeEYNABogAygCDCEBIAQLIQQgBiABNgIEIAYgBDYCACADQRBqJAAgCSgCCEGBgICAeEcNAiAAKAIAIQMgACgCCCEBCyABIANPDQEgACgCBCABQQJ0aiACQQFqNgIAIAAgAUEBaiIBNgIICyABIAJNDQAgACAAKAIEIAJBAnRqKAIANgIMIAAoAhAiASACaiICIAFPDQFB+K3kABCuFwALAAsgCUEQaiQAIABBKGogBygCADYCACAAQSBqIAgpAgA3AwAgACAFKQIANwMYIAUgACkDADcCACAIIAspAwA3AgAgByAKKAIANgIAIABBGGpBBEEEEK4OIABBMGokACACC0AAIAAgAUGkqcMAQauqwwBBw6rDAEHQqMMAQfCowwBBs6rDAEH4qcMAQeipwwBBm6rDAEGIqsMAQdipwwAQjCYLtgECA38BfiMAQSBrIgIkAAJAIAEEQCABQQhrIgMoAgBBAUcNASACQRhqIgQgAUEQaikDADcDACACQRBqIAFBCGopAwA3AwAgASkDACEFIANBADYCACACIAU3AwgCQCADQX9GDQAgAUEEayIBIAEoAgBBAWsiATYCACABDQAgA0EgQQgQnyALIAAgAikDEDcDACAAQQhqIAQpAwA3AwAgAkEgaiQADwsQ2SMAC0GdmcQAQT8Q2CMAC7QBAQF/IwBBMGsiAiQAIAIgATYCBCACIAA2AgAgAkEANgIcIAJCgICAgBA3AhQgAkGcucQANgIkIAJCoICAgA43AiggAiACQRRqNgIgIAIgAkEgahCtDUUEQCACQRBqIAJBHGooAgAiATYCACACIAIpAhQ3AwggAigCDCABEI0eIAJBCGoQ8yEgAARAIAIQ/hULIAJBMGokAA8LQcS5xABBNyACQQhqQbS5xABB/LnEABCpDgALzAICBn8DfiMAQTBrIgMkACADELgeIwBBQGoiAiQAIAIQxBkgAiADIANBEGoiBRCYCyACQSBqIAEgAhD5AiADQQhqIgYgAkEoaikAADcAACADIAIpACA3AAAgAkFAayQAIANBGGogBikAADcDACADIAMpAAA3AxBBDyEEIAUhAgNAIAItAAAhBiACIANBEGoiByAEaiIFLQAAOgAAIAUgBjoAACACQQFqIQIgBEEBayIEQQdHDQALIANBIGoiBCICIAcpAAgiCEI/iCIJIAcpAAAiCkIBhoQ3AAAgAiAIQoCAgICAgICAgH+DIAlCPoaEIAlCOYaEIAhCAYYgCkI/iISFNwAIIABB4ANqIgJCAD4CGCACQgA+AhAgAkIAPgIcIAJCAD4CFCACIAQpAAg3AgggAiAEKQAANwIAIAAgAUHgA/wKAAAgA0EwaiQAC6gBAQJ/IwBBQGoiAiQAIAJBKGoiAyABEKwZIAJBGGogAxD5CyACQRBqIgEgAkEkaigCADYCACACIAIpAhw3AwgCQCACKAIYQQFGBEAgACACKQMINwIIIABBAjYCBCAAQQE6AAAgAEEQaiABKAIANgIADAELIAJBMGogASgCACIBNgIAIAIgAikDCDcDKCAAIAIoAiwgARDUDyACQShqEPMhCyACQUBrJAALQAAgACABQdSXyABBk4zIAEHInMgAQaicyABBoJzIAEG4nMgAQcSXyABBgJzIAEGQnMgAQbKayABB7pvIABCMJgvOEQMHfAp/An4jAEHQAGsiCiQAIApBgoCAgHg2AjgjAEEQayIRJAAgEUEBOgAPAn8gEUEPaiEJAkACQCABRAAAAAAAAAAAYQ0AIAGZIQIgCS0AAEEBRgRAAnwCQAJAAn8gAr0iE0KAgICAgICACFkEQCATQv/////////3/wBWDQNBgXghCyATQiCIIhRCgIDA/wNSBEAgFKcMAgtBgIDA/wMgE6cNARpEAAAAAAAAAAAMBAtEAAAAAAAA8L8gAiACoqMgAkQAAAAAAAAAAGENAxogE0IAUw0BQct3IQsgAkQAAAAAAABQQ6K9IhNCIIinCyEJIBNC/////w+DIAlB4r4laiIJQf//P3FBnsGa/wNqrUIghoS/RAAAAAAAAPC/oCIFIAUgBUQAAAAAAADgP6KiIgahvUKAgICAcIO/IghEAAAgZUcV9z+iIgQgCUEUdiALarciA6AiAiAEIAMgAqGgIAUgCKEgBqEgBSAFRAAAAAAAAABAoKMiAiAGIAIgAqIiAiACoiIDIAMgA0SfxnjQCZrDP6JEr3iOHcVxzD+gokQE+peZmZnZP6CiIAIgAyADIANERFI+3xLxwj+iRN4Dy5ZkRsc/oKJEWZMilCRJ0j+gokSTVVVVVVXlP6CioKCioCICRAAAIGVHFfc/oiACIAigRACi7y78Bec9oqCgoAwCCyACIAKhRAAAAAAAAAAAoyECCyACC0QAAAAAAAAkQKOc/AKsQgN+IhRCIIinIBSnIgtBH3VGDQFB2LDIABCwFwALAnwCQAJAAn8gAr0iE0KAgICAgICACFkEQCATQv/////////3/wBWDQNBgXghCyATQiCIIhRCgIDA/wNSBEAgFKcMAgtBgIDA/wMgE6cNARpEAAAAAAAAAAAMBAtEAAAAAAAA8L8gAiACoqMgAkQAAAAAAAAAAGENAxogE0IAUw0BQct3IQsgAkQAAAAAAABQQ6K9IhNCIIinC0HiviVqIglBFHYgC2q3IghEAGCfUBNE0z+iIgQgE0L/////D4MgCUH//z9xQZ7Bmv8Daq1CIIaEv0QAAAAAAADwv6AiByAHIAdEAAAAAAAA4D+ioiIFob1CgICAgHCDvyIGRAAAIBV7y9s/oiIDoCICIAMgBCACoaAgByAGoSAFoSAHIAdEAAAAAAAAAECgoyICIAUgAiACoiICIAKiIgMgAyADRJ/GeNAJmsM/okSveI4dxXHMP6CiRAT6l5mZmdk/oKIgAiADIAMgA0REUj7fEvHCP6JE3gPLlmRGxz+gokRZkyKUJEnSP6CiRJNVVVVVVeU/oKKgoKKgIgJEAAAgFXvL2z+iIAhENivxEfP+WT2iIAIgBqBE1a2ayjiUuz2ioKCgoAwCCyACIAKhRAAAAAAAAAAAoyECCyACC0QAAAAAAAAIQKOc/AKsQgN+IhRCIIinIBSnIgtBH3VHDQELIAsMAQtByLDIABCwFwALIQ1BACEJIwBBEGsiDiQAAkACQAJAAkACQAJAAkBBBCAKQThqIhAoAgAiEkGAgICAeHMgEkEAThtBAWsOBAYBAgQACyAOQQRqIglBGEFoIA0gDUFoTBsiCyALQRhOGxD4BgwCCyAOQQRqIgxBGCANQQAgDUEAShsiCyALQRhOGxD4BiAOKAIEQYCAgIB4Rg0DIAxBAUEBEK4ODAQLIA5BBGoiCUFoIA0gDUFoTBsiC0EfdSALcRD4BgsgDigCBEGAgICAeEYNASAJQQFBARCuDkEAIQkMAgsgECgCCCIMBEAgECgCBCIPKAIAIgkgDUwEQCAMQQFGDQMgDygCBCILIA1KDQMgDEECRgRAIAshCQwECyAMQQJ0QQhrIQwgD0EIaiEPIAshCQNAIA8oAgAiCyANSg0EIA9BBGohDyALIQkgDEEEayIMDQALDAMLDAILQeiwyABBJUGQscgAEPYYAAsgDigCCCEJCyASQYSAgIB4TgRAIBBBBEEEEK4OCyAOQRBqJAACfCMAQRBrIQwCQCAJIgu3RAAAAAAAAAhAo0QAAAAAAAAkQKIiBL0iFEIgiEL/////B4MiE0L/37+EBFgEQCATQoCAwOQDWg0BIAREAAAAAAAA8D+gDAILIBNC//+/hARWIBRCAFlxRQRAAkAgE0L//7//B1gEQCAUQgBTDQEMAwtEAAAAAAAA8L8gBKMMAwsgBEQAAAAAAMyQwGUEQCAMRAAAAAAAAKC2IASjtjgCDCAMKgIMGkQAAAAAAAAAAAwDCyAERAAAAAAAADDDoEQAAAAAAAAwQ6AgBGENASAMRAAAAAAAAKC2IASjtjgCDCAMKgIMGgwBCyAERAAAAAAAAOB/ogwBCyAERAAAAAAAALhCoCIDvadBgAFqIgxBBHRB8B9xIgkrA+idZiICIAIgBCADRAAAAAAAALjCoKEgCSsD8J1moSICoiACIAIgAiACRHRchwOA2FU/okQABPeIq7KDP6CiRKagBNcIa6w/oKJEdcWC/72/zj+gokTvOfr+Qi7mP6CioCECAkACQAJAIAxBCHUiCUH/B0wEQCAJQYJ4Tg0DIAJEAAAAAAAAYAOiIQIgCUG4cE0NASAJQckHaiEJDAMLIAJEAAAAAAAA4H+iIQIgCUH+D0sNASAJQf8HayEJDAILIAJEAAAAAAAAYAOiIQJB8GggCSAJQfBoTRtBkg9qIQkMAQsgAkQAAAAAAADgf6IhAkH9FyAJIAlB/RdPG0H+D2shCQsgAiAJQf8Haq1CNIa/ogshAiAKQQhqIgxBAToADCAMIAs2AgggDCABIAKjOQMAIBFBEGokACAKIAotABQgCigCEEEAR3EiCTYCHCAKQYCqyABBASAJGzYCGCAKQfAHNgI0IApB8Qc2AiwgCiAKQRBqNgIoIApB8gc2AiQgCiAKQRhqNgIwIAogDDYCICAKQQM2AkwgCkGkqsgANgJIIApBAzYCRCAKQQQ2AjwgCkGEqsgANgI4IAogCkEgajYCQCAAIBAQ7gQgCkHQAGokAAvOAQEBfyMAQRBrIgIkAAJ/AkACQAJAAkACQCAAKAIAIgAtAABBAWsOBAECAwQACyACIABBBGo2AgwgAUGU4MkAQQwgAkEMakGE4MkAEKUIDAQLIAIgAEEEajYCDCABQaDgyQBBCyACQQxqQYTgyQAQpQgMAwsgAiAAQQRqNgIMIAFBq+DJAEESIAJBDGpBhODJABClCAwCCyABQb3gyQBBDxDoHgwBCyACIABBAWo2AgwgAUHc4MkAQRIgAkEMakHM4MkAEKUICyACQRBqJAALQAAgACABQdCJ1ABBs43UAEHLjdQAQcCJ1ABBq43UAEG7jdQAQYiK1ABB+IzUAEGbjdQAQYiN1ABB6IzUABCMJgvCAQEDfyMAQRBrIgQkAAJAAkAgASgCACIBKAIQQQFHBEAgBEEEaiADQQBBAUEBEKILIAQoAgghBiAEKAIEQQFGDQIgBCgCDCEFIAMEQCAFIAIgA/wKAAALIAEQyBgMAQsgAUEANgIIIAEoAgAhBiABKAIEIQUgAUKAgICAEDcCACABEMgYIANFDQAgBSACIAP8CgAACyAAIAM2AgggACAFNgIEIAAgBjYCACAEQRBqJAAPCyAGIAQoAgxByI7fABD2GwALowEBA38jAEEgayIDJAACQCABIAJGBEAMAQsgAyABLQAAOgAMQRAgAiABayICIAJBEE8bIgVBfyAFGyEEQQEhAgJAA0AgAiAFRg0BIANBDGogAmogASACai0AADoAACACQQFqIgINAAtBgIXFABCuFwALIARBEEkNACAAIAMpAgw3AAAgAEEIaiADQRRqKQIANwAAIANBIGokAA8LIARBEBDpEAALrgECBX8CfiMAQUBqIgMkAAJAAkAgAiAAKAJIRyACQcAAS3IiBg0AIANBAEHAAPwLACAAKQNAIgggAC0AzAEiBK18IgkgCFQNASAAQcwAaiEFIAAgCTcDQAJAIARBgAFGDQBBgAEgBGsiB0UNACAEIAVqQQAgB/wLAAsgAEEAOgDMASAAIAUgAxDfCyACRQ0AIAEgAyAC/AoAAAsgA0FAayQAIAYPC0HkmMUAEK4XAAv1AQEDfyMAQfAAayIEJAAgAQJ/AkACQAJ/AkACQAJAIAEtAAxBAWsOAwQBAAILIAEoAgQhAyABKAIIDAILAAsgASgCACEFQdgAQQgQhCEiA0UEQEEIQdgAEOEjAAsgA0EAOgAlIAMgBTYCICAEQQhqIgVBlKvFADYCBCAFIAM2AgAgBCgCCCEDIAFBlKvFADYCCCABIAM2AgRBlKvFAAshBSAEQRRqIAMgAiAFKAIMEQMAIAQoAhRBGEcNASAAQRg2AgBBAwwCC0HQrMUAELUXAAsgACAEQRRqQdwA/AoAACABQQRqEP4VQQELOgAMIARB8ABqJAALpAEBAX8jAEEwayIDJAACQCAAAn8gAkEgRgRAIANBD2ogASABQSBqEOgIIAMtAA9FDQIgACADKQAQNwABIABBGWogA0EoaikAADcAACAAQRFqIANBIGopAAA3AAAgAEEJaiADQRhqKQAANwAAQQAMAQsgAEEgNgIMIAAgAjYCCCAAQQY6AARBAQs6AAAgA0EwaiQADwtBwILIAEEqQeyCyAAQuREAC7gBAQJ/IwBBIGsiBSQAIAACfwJAIANBASAEGwRAIAEoAhQiAyABKAIQIgRPDQEgASgCDCEGA0AgAyAGai0AAEEwa0H/AXFBCk8NAiABIANBAWoiAzYCFCADIARHDQALDAELIAVBDjYCFCAFQQhqIAFBDGoQ+xUgACAFQRRqIAUoAgggBSgCDBDyFDYCBEEBDAELIABEAAAAAAAAAABEAAAAAAAAAIAgAhs5AwhBAAs2AgAgBUEgaiQAC6cEAQl/IwBB0ABrIgQkACABKAIEIQIgBCABKAIIIgMEfyACKAIMIQYgAi0AZAVBAAs6AE0gBEEBOgBMIAQgBjoASSAEQQE6AEggBEECNgJAIARCATcCOCAEQQA2AiAgBEIBNwIMIAQgAjYCMCAEIAIgA0HoAGxqNgI0IAQgA0EIdCADQYD+A3FBCHZyOwFEIwBB4ABrIgIkACACQQhqIARBDGoiAxC4BAJAAkACQCACLQAIBEAgAi0ACSEHIAJBHGoiBiADEPUCIAZBCCACKAIcQQFqIgVBfyAFGyIFIAVBCE0bQQBBAUEBEKILIAIoAiAhBSACKAIcQQFGDQIgAigCJCIIIAc6AAAgAkEYaiIJQQE2AgAgAiAINgIUIAIgBTYCECAGIANBxAD8CgAAIwBBIGsiAyQAIANBEGogBhC4BCADLQAQBEAgAkEQaiEFIAMtABEhBwNAIAUoAggiCCAFKAIARgRAIANBFGogBhD1AiAFIAMoAhRBAWoiCkF/IAobEKoaCyAFKAIEIAhqIAc6AAAgBSAIQQFqNgIIIANBCGogBhC4BCADLQAJIQcgAy0ACA0ACwsgBhCTFCADQSBqJAAgAEEIaiAJKAIANgIAIAAgAikCEDcCAAwBCyAAQQA2AgggAEKAgICAEDcCACADEJMUCyACQeAAaiQADAELIAUgAigCJEHE9NMAEPYbAAsgARD7ECABQQRB6AAQrg4gBEHQAGokAAu8AQEEfyMAQRBrIgMkACABKAIAIgEoAghFBEAgASgCDCEEIAFC/////y83AgggAQJ/IARBAkcEQCABKAIQIQJBAAwBCyADQQhqIAIoAgAiAigCBCACKAIAKAIAEQEAIAMoAgwhAiADKAIIIQUgASgCFCIGBEAgASgCGCAGKAIMEQIACyABIAI2AhggASAFNgIUIAEoAghBAWoLNgIIIAAgAjYCBCAAIAQ2AgAgA0EQaiQADwtB6M7UABCxJQALygEBAn8jAEFAaiIDJAACQCABKAIABEAgACABQSj8CgAADAELIANBCGoiBCACKAIALQAAIAIoAgQtAAAgAigCCC0AABCkCSADKAIIBEAgACAEQSj8CgAADAELIAMvAQwhAiADLQAOIQQgA0E4aiABQQxqKAIANgIAIAMgASkCBDcDMCAAQQRqIgEgAiAEQRB0ciICOwEMIAFBDmogAkEQdjoAACABIANBMGoiAikCBDcCBCABIAIoAgA2AgAgAEEANgIACyADQUBrJAALsQYBB38jAEEgayIEJAAgBEEMaiABEIIFAkAgBC0ADEEBRgRAIAAgBCgCEDYCBCAAQQE6AAAMAQsgBC0ADUUEQCAAQYAEOwEADAELIARBDGohAyABKAIAIQUjAEEwayIBJAAgAUEKNgIMIAFB9N3FADYCCCABQSRqIAUQsQ4CQAJAAkACQAJAAn8gAS0AJEEBRgRAIAEoAigMAQsgAS0AJUEBRgRAIAEtACZBIkcNAiAFELcaIAVBADYCCCABQSRqIAVBDGogBRCSBSABKAIoIQIgASgCJCIIQQJHDQMgA0EBOgAAIAMgAjYCBAwGCyABQQU2AhAgBSABQRBqEMgWCyECIANBAToAACADIAI2AgQMBAsgASAFIAFBCGpB9L7FABD4AzYCFAwBCyABKAIsIQcjAEEgayIGJAAgBkEPaiACIAcQ8wggAUEQaiICAn8gBi0AD0ECRgRAIAIgBi0AECEHIwBBMGsiAiQAIAIgBzoAByACQQA2AhwgAkKAgICAEDcCFCACQfzbxQA2AiQgAkKggICADjcCKCACIAJBFGo2AiAgAkEHaiACQSBqEOkdBEBBpNzFAEE3IAJBCGpBlNzFAEHc3MUAEKkOAAsgAkEQaiACQRxqKAIANgIAIAIgAikCFDcDCCACQQhqEPkBIAJBMGokADYCBEEBDAELIAIgBikADzcAASACQRFqIAZBH2otAAA6AAAgAkEJaiAGQRdqKQAANwAAQQALOgAAIAZBIGokACABLQAQIQIgCEEBcQRAIAJBAXENASADIAEpABE3AAEgA0EAOgAAIANBEWogAUEhai0AADoAACADQQlqIAFBGWopAAA3AAAMAwsgAkEBcUUNAQsgBSABKAIUEMMkIQIgA0EBOgAAIAMgAjYCBAwBCyADIAEpABE3AAEgA0EAOgAAIANBEWogAUEhai0AADoAACADQQlqIAFBGWopAAA3AAALIAFBMGokACAELQAMRQRAIAAgBCkADTcAASAAQQA6AAAgAEERaiAEQR1qLQAAOgAAIABBCWogBEEVaikAADcAAAwBCyAAIAQoAhA2AgQgAEEBOgAACyAEQSBqJAALuAEBAn8jAEEwayIBJAAgACgCCEECRwRAIABBCGogABDuEwsCQEHg0OYALQAADQAgACgCGCICRQ0AIAFBAjYCDCABQfzHxQA2AgggAUIBNwIUIAFBBTYCJCABIAIpAgw3AiggASABQSBqNgIQIAEgAUEoajYCICAAIAFBCGoQiQULIAEgADYCCCAALQBKQQNGBEAgAEFAaxD+FSAAQTRqIgAQkBYgABD7IQsgAUEIahDlDSABQTBqJAAL1wEBAX4gAAJ/AkAgAyAEakEBa0EAIANrca0gAa1+IgVCIIhQBEAgBaciBEGAgICAeCADa00NAQsgAEEANgIEQQEMAQsgBEUEQCAAIAM2AgggAEEANgIEQQAMAQsCfyACRQRAIAQgAxCEIQwBCwJAAn8gA0EJTwRAIAMgBBDzBQwBCyAEEM0BCyICRQ0AIAJBBGstAABBA3FFIARFcg0AIAJBACAE/AsACyACCyICRQRAIAAgBDYCCCAAIAM2AgRBAQwBCyAAIAI2AgggACABNgIEQQALNgIAC8QBAwF/AX4BfCMAQSBrIgIkAAJAAkACQAJAIAEoAgBBAWsOAgECAAsgASsDCCEEIAJBAzoACCACIAQ5AxAgAkEIaiACQR9qQYCXyQAQ2g0hASAAQQE2AgAgACABNgIEDAILIABBADYCACAAIAEpAwg3AwgMAQsgAAJ/IAEpAwgiA0IAUwRAIAJBAjoACCACIAM3AxAgACACQQhqIAJBH2pB/O/IABDbDTYCBEEBDAELIAAgAzcDCEEACzYCAAsgAkEgaiQAC8kBAQF/IwBBEGsiAiQAAn8CQAJAAkACQAJAIAAtAABBAWsOBAECAwQACyACIABBBGo2AgwgAUHUsckAQQwgAkEMakGoo8kAEKUIDAQLIAIgAEEEajYCDCABQeCxyQBBCyACQQxqQaijyQAQpQgMAwsgAiAAQQRqNgIMIAFB67HJAEESIAJBDGpBqKPJABClCAwCCyABQf2xyQBBDxDoHgwBCyACIABBAWo2AgwgAUGcsskAQRIgAkEMakGMsskAEKUICyACQRBqJAALpgEBA38CQCAALQAIRQRAIAAoAgQgAkcNASAAKAIAIAEgAhCaE0UPCyAAKAIEIAJHDQAgACgCACEAA0ACQCACRSEFIAJFDQAgAS0AACEDIAAtAAAhBCABQQFqIQEgAkEBayECIABBAWohACAEQSBBACAEQcEAa0H/AXFBGkkbckH/AXEgA0EgQQAgA0HBAGtB/wFxQRpJG3JB/wFxRg0BCwsgBQ8LQQAL9wEBBH8jAEFAaiIDJAAgAyABNgIEIANBBGoiBCgCACUBEFghBSMAQSBrIgIkACACQRhqIAQoAgAlARBZIAJBEGogAigCGCACKAIcELIfIAJBCGogAigCECACKAIUEPYUIANBCGogAigCCCACKAIMEIseIAJBIGokACAEKAIAJQEQWkEARyECIANBOGogA0EQaigCADYCACADIAMpAgg3AjAgAyACOgA+IAMgBTsBPCADQQE2AiwgA0EUaiICIAAgA0EsaiIEEIENIAIQ6xggA0EDNgIsIAIgACAEEIENIAIQ6xggAUGEAU8EQCABEKEWCyADQUBrJAALjQICB38BbyMAQSBrIgIkACACQRxqQQA6AAAgAkIANwIUIAJBBDYCECACQgA3AgggAkEIahCiEyEEEM4gIgMlARAnIQgQjQsiASAIJgEgARC4JSEFIAFBhAFPBEAgARChFgsgA0GEAU8EQCADEKEWCyACQYABNgIIIAJBCGooAgAlARCgASEIEI0LIgEgCCYBIAEhBiAEIAQoAgBBAWoiATYCACABRQRAAAtBBEEEEIQhIgFFBEBBBEEEEOEjAAsgASAENgIAIAFBoM3UABDYIiEHIABBBGoiA0GgzdQANgIEIAMgATYCACADIAc2AgggACAFQQFGOgAUIAAgBjYCECAAIAQ2AgAgAkEgaiQAC2IBAn8jAEEQayIDJAAgA0EEaiABQQFBAUEBEKILIAMoAgghBAJAIAMoAgQEQAwBCyADKAIMIQIgACABNgIIIAAgAjYCBCAAIAQ2AgAgA0EQaiQADwsgBCADKAIMIAIQ9hsAC4MCAQd/IwBBIGsiAiQAIAAoAgQhAyAAKAIIIgEEQCABQQV0IQQgAyEBA0AgAkEYaiIFQgA3AwAgAkEQaiIGQgA3AwAgAkEIaiIHQgA3AwAgAkIANwMAIAEgAikDADcDACABQRhqIAUpAwA3AwAgAUEQaiAGKQMANwMAIAFBCGogBykDADcDACABQSBqIQEgBEEgayIEDQALCyAAQQA2AggCQAJAIAAoAgAiAEGAgIDAAEkEQCAAQQV0IgBBAEgNASAABEADQCADQQA6AAAgA0EBaiEDIABBAWsiAA0ACwsMAgtB7LvVABDSIAALQfy71QBBLUGsvNUAEJwVAAsgAkEgaiQAC7YBAQV/IAAoAgQhAyAAKAIAIQIgACgCFCEBAkACQAJAIAAoAhAiBCAAKAIMSQRAIAAoAgggBEEDdGoiBSgCACABRg0BIAIgA0cNAgNADAALAAsgAiADRw0BQYCAxAAPCyAAIARBAWo2AhAgAUF/Rg0BIAAgAUEBajYCFCAFKAIEDwsgACACQQRqNgIAIAFBf0cEQCAAIAFBAWo2AhQgAigCAA8LQZDs1QAQrhcAC0GA7NUAEK4XAAvYAQIBfwF+IwBBwAJrIgMkACADQeAAaiABQeAAakHgAPwKAAAgAyABMQDAAUIBfSIEQpPJg9S/2Jf7FYM3A+gBIAMgBELt2NuS+tLGg9wAgzcD4AEgAyAEQsWuyYK3ipbn9wCDNwPYASADIARCurGdnvWKpqTfAIM3A9ABIAMgBEKCgLCgvIGA+muDNwPIASADIARC/f+LgICAwIT2AIM3A8ABIANB8AFqQQBBMPwLACADIAFB4AD8CgAAIANBoAJqIgEgAhDLAiAAIAMgARDwAyADQcACaiQAC7ABAQZ/IAAoAgQiAwRAIAAoAgAhBANAAkACQAJAAkAgBCACQRxsaiIAKAIADgQDAwECAAsgACgCECIBRQ0CIAAoAgwiBiEAIAEhBQNAIAAQrAsgAEEIaiEAIAVBAWsiBQ0ACyAGIAFBA3RBBBCfIAwCCyAAKAIYIgFFDQEgACgCFCABQQV0QQQQnyAMAQsgAEEMahCsCwsgAkEBaiICIANHDQALIAQgA0EcbEEEEJ8gCwuwAQEGfyAAKAIEIgMEQCAAKAIAIQQDQAJAAkACQAJAIAQgAkEcbGoiACgCAA4EAwMBAgALIAAoAhAiAUUNAiAAKAIMIgYhACABIQUDQCAAEK0LIABBCGohACAFQQFrIgUNAAsgBiABQQN0QQQQnyAMAgsgACgCGCIBRQ0BIAAoAhQgAUEFdEEEEJ8gDAELIABBDGoQrQsLIAJBAWoiAiADRw0ACyAEIANBHGxBBBCfIAsLvAEBAn8jAEEQayICJAACQAJ/AkACQAJAIAAoAgBBAWsOAgECAAsgAUGox+QAQQ0Q6B4MAgsgAUG1x+QAQQoQ6B4MAQsgAC0AFEEDRwRAIAIgAEEEajYCDCAAQRRqIAJBDGoQyAkLIAAoAhAiAyAAKAIMIgBLDQFBASABKAIAQdDH5ABBCiABKAIEKAIMEQUADQAaIAJBBGoiACABEMkZIAAQpxgLIAJBEGokAA8LIAMgACAAQcDH5AAQmxUAC7YBAQJ/AkACQAJAQQEgACgCACIBQQJrIAFBAU0bDgIAAQILIAAoAgQiABCEBiAAQTRqEO0dIAAoAgAiASABKAIAQQFrIgE2AgAgAUUEQCAAEL4UCyAAQThqIgIQgg0CQCAAKAI4IgFFDQAgASABKAIAIgFBAWs2AgAgAUEBRw0AIAIQ7BILIABBBGoQuh4gAEEQahC6HiAAQRxqELoeIABBKGoQuh4gAEE8QQQQnyAPCyAAEKUbCwtMAAJAAkACQAJAAkAgAC8BAEEGaw4NAgIDAwMDBAIEBAQCAAELIABBBGoQlRwLDwsgAEEEahDzIQ8LIABBBGoQlRwPCyAAQQhqEPMhC6QBAgF/CH4jAEEgayIDJAAgASkDCCEEIAIpAwghBSACKQMYIQkgASkDGCEKIAIpAxAhCCABKQMQIQYgAyACKQMAIgcgASkDAHwiCzcDACADIAQgBXwiBCAHIAtWrXwiBzcDCCADIAYgCHwiBiAEIAVUrSAEIAdWrXx8IgU3AxAgAyAJIAp8IAYgCFStIAUgBlStfHw3AxggACADEMcHIANBIGokAAulAQECfyMAQUBqIgIkACACQShqIgMgARCsGSACQRhqIAMQ+QsgAkEQaiIBIAJBJGooAgA2AgAgAiACKQIcNwMIAkAgAigCGEEBRgRAIAAgAikDCDcCCCAAQoGAgIAgNwIAIABBEGogASgCADYCAAwBCyACQTBqIAEoAgAiATYCACACIAIpAwg3AyggACACKAIsIAEQpAcgAkEoahDzIQsgAkFAayQAC7oBAgF/An4jAEEQayICJAAgAiABQezkygBBBBDKGQJAIAApAwgiAyAAKQMQIgSEUARAIAJBgOXKAEEFIABB8OTKABC3BxoMAQsgA0J/UgRAIAIgA0IBfDcDCCACQZjlygBBBCACQQhqIgBB8OTKABC3BxogBEJ/UgRAIAIgBEIBfDcDCCACQazlygBBBiAAQfDkygAQtwcaDAILQZzlygAQrhcAC0GI5coAEK4XAAsgAhCNECACQRBqJAAL4QMBCH8jAEEQayIGJAACQAJAAkACQCABKAIIQXBxIgUgASgCACIDKAKAAUcEQANAIAMoAoQBIgNFDQIgASADNgIAIAMoAoABIAVHDQALCwJAIAEoAgQiAyABKAIAIghGDQAgASgCCCEJAkADQCADQYgBai0AAkEBcUUNAiADKAKMASAJSw0CIAMoAoQBIgVFDQEgASAFNgIEIANCADcCgAEgA0EANgKIASACKAIAIQRBBCEHAkADQCAHQQFrIgcEQCADIAQoAoABQRBqNgKAASMAQSBrIgokACAEQYQBaiIEIAQoAgAiBCADIAQbNgIAIApBIGokACAEDQEMAgsLIANBkAFBBBCfIAsgBSIDIAhHDQALDAELQeSQ0wAQ0iAACyAGQQRqIQUCQAJ/IAEoAgAiAkGIAWooAgAiBCABKAIIIgdBD3EiAxDbGkUEQEEEIQNBACICIARBgIAIcQ0BGgwCCyAFIAIgA0EDdGoiAigCADYCBEEIIQMgAigCBAshAiADIAVqIAI2AgBBASECCyAFIAI2AgAgBigCBEEBRw0CIAYoAggNAQwCCyAAQQA2AgAMAgsgASAHQQFqNgIICyAAIAYpAgQ3AgAgAEEIaiAGQQxqKAIANgIACyAGQRBqJAALvQEBAX8jAEEQayIHJAAgACgCACABIAIgACgCBCgCDBEFACEBIAdBADoADSAHIAE6AAwgByAANgIIIAdBCGogAyAEIAUgBhC3ByEBIActAA0iAiAHLQAMIgNyIQACQCADQQFxIAJBAUdyDQAgASgCACIALQAKQYABcUUEQCAAKAIAQbX85ABBAiAAKAIEKAIMEQUAIQAMAQsgACgCAEG0/OQAQQEgACgCBCgCDBEFACEACyAHQRBqJAAgAEEBcQujAQEDfyAAKAIEQewCaiEBIAAoAgghAANAIAAEQCABQdwCayIDEJ8OIAMQoyIgAUHQAmsiAygCACICIAIoAgAiAkEBazYCACACQQFGBEAgAxDHFwsgAUHMAmsiAygCACICIAIoAgAiAkEBazYCACACQQFGBEAgAxCzDgsgAUEMaxCGIyABEIUjIAFBvAJrEPMhIABBAWshACABQYADaiEBDAELCwuHBAEHfyMAQSBrIgIkAAJAAkAgASgCACIFBEAgBUEIaiEGIwBBIGsiAyQAAkACQANAAkACQAJAAkAgBigCBCIHKAIgIgQEQCAGIAQ2AgQgBygCAEGBgICAeEcNASAEKAIAIghBgYCAgHhGDQIgBEGBgICAeDYCACADIAQpAgQ3AgQgA0EcaiAEQRxqKAIANgIAIANBFGogBEEUaikCADcCACADQQxqIARBDGopAgA3AgAgBxCqHwwDC0GBgICAeEGCgICAeCAGKAIAIAdGGyEIDAILQfC6wwBBKUGcu8MAEJwVAAtBrLvDAEEpQdi7wwAQnBUACyADIAg2AgBBgICAgHggAygCACIEIARBgICAgHhNG0H/////B3FBAWsOAgABAgsLIAJBgYCAgHg2AgAMAQsgAiADKQIANwIAIAJBGGogA0EYaikCADcCACACQRBqIANBEGopAgA3AgAgAkEIaiADQQhqKQIANwIACyADQSBqJAAgAigCAEGBgICAeEYNASAAIAIpAgA3AgAgBSAFKAIQQQFrNgIQIABBCGogAkEIaikCADcCACAAQRBqIAJBEGopAgA3AgAgAEEYaiACQRhqKQIANwIADAILIABBgYCAgHg2AgAMAQsgACAFKAIQBH9BgoCAgHgFIAEQ4BggAUEANgIAQYGAgIB4CzYCAAsgAkEgaiQAC64BAQN/IwBBEGsiAyQAIANBCGogACgCACIEQfjMwwBBjM3DACAALQAEQQFGIgUbQQFBAiAFGxD2HQJAIAMtAAhBBEcEQCADIAMpAwg3AwAMAQsgAyAEIAQoAgwgBCgCBCAEKAIIEKAYCwJAIAMQvBUiBQ0AIABBAjoABCADQQhqIgAgBCABIAIQgREgABC8FSIFDQAgA0EEOgAIIANBCGoQvBUhBQsgA0EQaiQAIAULpwECAX8BfiMAQTBrIgMkAAJAAkAgASgCAEEBRgRAIAIgASkDCCIEUw0BCyAAQTA6AAAMAQsgA0EIaiACuRCUCyADQRRqIAS5EJQLIANBLGogA0EQaigCADYAACAAIAMpAhQ3AhAgAEEYaiADQRxqKAIANgIAIABBJToAACADIAMpAgg3ACQgACADKQAhNwABIABBCGogA0EoaikAADcAAAsgA0EwaiQAC70BAgJ+An8CQAJAAkACQAJ/AkACQAJAAkAgACgCeCgCAEEFaw4FBgMACAEICyAAEIASDQEMBwsgABCBEkUNBgsgACkDwAEhAUHoASEEQdgBDAELIAAtAIACDQQgACkD2AEiAiAAKQPAAXwiASACVA0BQfgBIQRB6AELIQMgASAAIANqKQMAIgF8IgIgAVQNACACIAAgBGopAwAiAnwiASACWg0CCxDBJQALIAApA8ABIQELIAFCgQFUIQMLIAMLtAEBA38jAEEgayICJAACQCAAKAIQIgQEQAJAIAQtACxBAXENACAAKAIQIgBBIGogASgCABDACCAAKAIsIgBBAXENAEEBIQMgAEECcQ0CCyACQSBqJAAgAw8LIAJBADYCGCACQQE2AgwgAkGcz9MANgIIIAJCBDcCECACQQhqQaTP0wAQ9xgACyACQQA2AhggAkEBNgIMIAJByM/TADYCCCACQgQ3AhAgAkEIakHQz9MAEPcYAAupAQEDfyMAQUBqIgIkACAAKAIAIQMgAiAAKAIENgIQIAIgAzYCDCADKAIIRQRAIAMoAgwhACADQv////8PNwIIIAMgAAR/IAMoAhAgACgCBBECACADKAIIQQFqBUEACzYCCCACQQA2AiwgAkEUaiIAIAJBEGogAkEsahCBDSAAEOsYIAFBhAFPBEAgARChFgsgAkEMahC8GSACQUBrJAAPC0GwzNQAELElAAueAQID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AiAAIAI7AQALvgEBAn8jAEEQayICJAAgACgCACIDQQRqIQACfwJAAkACQAJAIAMoAgBBAWsOAwECAwALIAIgADYCDCABQcij0wBBF0Hfo9MAQQYgAkEMakG4o9MAELULDAMLIAIgADYCDCABQfij0wBBFiACQQxqQeij0wAQpQgMAgsgAiAANgIMIAFBoKTTAEEbIAJBDGpBkKTTABClCAwBCyACIAA2AgwgAUG7pNMAQRUgAkEMakHoo9MAEKUICyACQRBqJAALkQEBAn8jAEGgA2siAiQAIAJB+ABqIgNBAUEAIAFBIBCiFCACIAJBmAFqQfgA/AoAACADQQBBoAL8CwAgAkHhADYCnAMgAkHogOEANgKYAyACIAJBmANqIANBoAIQqgJFBEAgACADQaAC/AoAACACQaADaiQADwtBpIPhAEErIAJBmANqQZSD4QBBzIHhABCpDgALnAIBAX8jAEFAaiIDJAAgA0EYaiACQRhqKQAANwMAIANBEGogAkEQaikAADcDACADQQhqIAJBCGopAAA3AwAgAyACKQAANwMAIANBOGogAUEYaikAADcDACADQTBqIAFBEGopAAA3AwAgA0EoaiABQQhqKQAANwMAIAMgASkAADcDICMAQTBrIgEkACADQSBqIgIgAi0AH0E/cUHAAHI6AB8gAiACLQAAQfgBcToAACABQQhqIAJBCGopAAA3AwAgAUEQaiACQRBqKQAANwMAIAFBGGogAkEYaikAADcDACABIAIpAAA3AwAgAUEBNgIsIAFCgICAgIAgNwIkIAEgATYCICAAIAMgAUEgahC2AyABQTBqJAAgA0FAayQAC6MBAgJ/AX4jAEEQayIDJAACQAJAAkAgASgCCCIEIAEoAgRJBEAgASgCACAEai0AACACQf8BcUYNAQsgAEIANwMIDAELQQEhAiABIARBAWo2AgggAyABEKQGIAMtAABFBEAgAykDCCIFQn9SBEAgACAFQgF8NwMIDAILIABBADoAAQwCCyAAIAMtAAE6AAEMAQtBACECCyAAIAI6AAAgA0EQaiQAC4gBAQN/IAAoAggiAQRAIAEgAUEBcmdBH3NBCWxByQBqQQZ2akEBaiECCwJAAkAgACgCFARAIABBDGoiACgCCCEBIAAoAgggAUEBcmdBH3NBCWxByQBqQQZ2IgBqQQFqIgMgAE0NAQsgAiADaiIAIANPDQFBqO3CABCuFwALQajywgAQrhcACyAAC6kBAQR/IAEoAhQiBCgCpAQhAgJAAkAgASgCAEEIaiAERwRAIAIhAyAEIQIMAQsgAkUEQEEBIQQMAgsgASACNgIUIAIoAqQEIQMLAkAgAw0AQQIhBCACIAEoAhBGBEAgASgCACIDQQA2AqwEIAEoAhAgASADQQhqIgM2AhAgAzYCpAQgAigCpAQiAw0BCwwBCyABIAM2AhRBACEECyAAIAI2AgQgACAENgIAC5kBAQJ/IwBBIGsiAiQAIAACfyABKAIEIgNFBEAgAEEAOwECQQAMAQsgASADQQFrNgIEIAJBEGogASgCABC0BAJAIAACfyACKAIQQQFGBEAgAigCFAwBCyACQQhqIAIpAxgQ+wogAi8BCEEBRw0BIAIoAgwLNgIEQQEMAQsgACACLwEKOwEEIABBATsBAkEACzsBACACQSBqJAALrAECAn8BfiMAQSBrIgIkAAJAIAEoAgQiA0UEQCAAQQA2AgAMAQsgASADQQFrNgIEIAJBCGogASgCABC0BAJAAn8gAigCCEEBRgRAIAIoAgwMAQsgAikDECIEQoCAgIAQVA0BIAJBAToACCACIAQ3AxAgAkEIaiACQR9qQazIxQAQvBALIQEgAEECNgIAIAAgATYCBAwBCyAAIAQ+AgQgAEEBNgIACyACQSBqJAALqgEBA38jAEEQayICJAAgAkGAgICAeDYCBCACQQRqIgEQxhUhAyABENEfAkBBJEEEEIQhIgEEQCABQoCAgIAYNwIQIAEgAzYCDCABIAM2AgggAUKBgICAEDcCACABIAIpAgQ3AhggAUEgaiACQQxqKAIANgIAIAEgASgCACIDQQFqNgIAIANBAEgNASAAIAE2AgQgACABNgIAIAJBEGokAA8LQQRBJBDhIwsAC9cFAQp/IwBBIGsiBiQAIAZBADYCECAGQoCAgIAQNwIIIAZBFGohBSAGQQhqIQcjAEEQayIIJAAgASgCCCEJAkAgAS0AECIDQQJHBEAgCCADOgACIAggAS0AEToAAyAIIAE2AgQgCCABKAIMNgIIIAggCEECajYCDCAIQQRqIQIjAEEQayIDJAACQAJAIAkgBygCCCIEaiIJIARPBEAgByAJEMIZIAQgBygCCCIJTQRAIANBBGogAigCACIKKAIEIAooAgggBygCBCAEaiAJIARrIAIoAgQgAigCCCICLQAAIAItAAEQygMCQCADLQAEIgJBBkcEQCAFIAMvAAU7AAEgBUEDaiADLQAHOgAAIAUgAykCCDcCBCAFIAI6AAAMAQsgBCADKAIIIgJqIgQgAkkNAyAHIAQQgB4gBUEGOgAAIAUgAjYCBAsgA0EQaiQADAMLIAQgCSAJQZzWxwAQmxUAC0H81ccAEK4XAAtBrNbHABCuFwALDAELIAEoAgwhCiMAQRBrIgMkAAJAAkAgCSAHKAIIIgRqIgIgBE8EQCAHIAIQwhkgBCAHKAIIIgJNBEAgA0EEaiABKAIEIAEoAgggBygCBCAEaiACIARrIAoQ9wQCQCADLQAEIgJBBkcEQCAFIAMvAAU7AAEgBUEDaiADLQAHOgAAIAUgAykCCDcCBCAFIAI6AAAMAQsgBCADKAIIIgJqIgQgAkkNAyAHIAQQgB4gBUEGOgAAIAUgAjYCBAsgA0EQaiQADAMLIAQgAiACQZzWxwAQmxUAC0H81ccAEK4XAAtBrNbHABCuFwALCyABEPMhIAhBEGokAAJAIAYtABQiAUEGRwRAIAAgBi8AFTsABSAAQQdqIAYtABc6AAAgACAGKQIYNwIIIAAgAToABCAHEPMhQQEhCwwBCyAAIAYpAgg3AgQgAEEMaiAGQRBqKAIANgIACyAAIAs2AgAgBkEgaiQAC5QBAQF/IwBBsAJrIgIkACACQQhqIAEQggUCQCACLQAIQQFGBEAgACACKAIMNgIIIABCAjcDAAwBCyACLQAJRQRAIABCADcDAAwBCyACQQhqIAEoAgAQsQIgAigCCEUEQCAAQQhqIAJBEGpBoAL8CgAAIABCATcDAAwBCyAAIAIoAgw2AgggAEICNwMACyACQbACaiQAC5oBAQN/IwBBkAFrIgEkAAJAAn8gACgCECICRQRAIAFBg4CAgHg2AkggASAAQQxqIAFByABqIgMQtAMgASgCQCICQQlHBEAgAyABQcAA/AoAACABIAI2AogBIAEgASgCRDYCjAEgAxCsEwwCCyAAKAIQIQILIAJBf0YNASAAIAJBAWo2AhBBAAsgAUGQAWokAA8LQdj1yAAQrhcAC5MBAQR/IAEoAgAhBAJAAkAgAwRAIAIgA0EDdGohBiACQQRqIQEDQCABKAIAIgcgBWoiBSAHSQ0CIAFBCGohASADQQFrIgMNAAsgBCAFEKoaA0AgBCACKAIAIgEgASACQQRqKAIAahCyEiACQQhqIgIgBkcNAAsMAgsgBEEAEKoaDAELQbz3yAAQrhcACyAAQQQ6AAALrgEDAn8BfAF+IwBBIGsiAiQAAn8CfwJAIAEoAgAiA0EBRwRAAkACQCADQQFrDgIAAwELAAsgASsDCCEEIAJBAzoACCACIAQ5AxAgAkEIaiACQR9qQcjfyQAQ2g0MAgsgASgCCCEBQQAMAgsgASkDCCEFIAJBAjoACCACIAU3AxAgAkEIaiACQR9qQcjfyQAQ2g0LIQFBAQshAyAAIAE2AgQgACADNgIAIAJBIGokAAuJAwAgAEEAELkeOgDAASAAQvK3+J6W1PCVCzcDuAEgAELtlfOhiorWi2c3A7ABIABCusb2yeyJ16T5ADcDqAEgAEKg15Pfo43r1oZ/NwOgASAAQtzD0dii4YnVGDcDmAEgAELd4JL7rZK/4K1/NwOQASAAQuW1g/Tnsf/BADcDiAEgAEKiy7yH367q6Qc3A4ABIABC35K18Ja97fe7fzcDeCAAQtrGqdDKraHzZzcDcCAAQtq42vH1w76+2QA3A2ggAELKmKWCht/CucwANwNgIABC89uDm5fBiskRNwNYIABCx4rWkO+hu9tCNwNQIABC5+aGqsjZrY0bNwNIIABChvCZlI7D39g7NwNAIABCw8G15tuzsdCqfzcDOCAAQobsj/HZjvDUpX83AzAgAELX+cKapLLkwAU3AyggAELr7IzDsezts+8ANwMgIABC6d3y0dGzpsqYfzcDGCAAQoDLq/HT9qTUoX83AxAgAEKarNK96OT++rN/NwMIIABCkJTQlKD0o/l1NwMAC6sBAQF/IwBBMGsiAiQAAn8CQAJAAkACQCAAKAIAQQFrDgMBAgMACyABQbS43gBBExDoHgwDCyABQce43gBBGBDoHgwCCyABQd+43gBBNhDoHgwBCyACQdcONgIQIAIgAEEEajYCFCACIAJBFGo2AgwgASgCACABKAIEIAJCATcCJCACQQE2AhwgAkGkud4ANgIYIAIgAkEMajYCICACQRhqEKkECyACQTBqJAAL0gUBCX8jAEEgayIGJAAgBkEANgIQIAZCgICAgBA3AgggBkEUaiEFIAZBCGohByMAQRBrIggkACABKAIEIQQCQCABLQAMIgNBAkcEQCAIIAM6AAIgCCABLQANOgADIAggATYCBCAIIAEoAgg2AgggCCAIQQJqNgIMIAhBBGohAiMAQRBrIgEkAAJAAkAgBCAHKAIIIgNqIgQgA08EQCAHIAQQxxkgAyAHKAIIIgRNBEAgAUEEaiACKAIAIgkoAgAgCSgCBCAHKAIEIANqIAQgA2sgAigCBCACKAIIIgItAAAgAi0AARDKAwJAIAEtAAQiAkEGRwRAIAUgAS8ABTsAASAFQQNqIAEtAAc6AAAgBSABKQIINwIEIAUgAjoAAAwBCyADIAEoAggiAmoiAyACSQ0DIAcgAxCAHiAFQQY6AAAgBSACNgIECyABQRBqJAAMAwsgAyAEIARBmM3gABCbFQALQfjM4AAQrhcAC0GozeAAEK4XAAsMAQsgASgCCCEJIwBBEGsiAyQAAkACQCAEIAcoAggiAmoiBCACTwRAIAcgBBDHGSACIAcoAggiBE0EQCADQQRqIAEoAgAgASgCBCAHKAIEIAJqIAQgAmsgCRD3BAJAIAMtAAQiAUEGRwRAIAUgAy8ABTsAASAFQQNqIAMtAAc6AAAgBSADKQIINwIEIAUgAToAAAwBCyACIAMoAggiAWoiAiABSQ0DIAcgAhCAHiAFQQY6AAAgBSABNgIECyADQRBqJAAMAwsgAiAEIARBmM3gABCbFQALQfjM4AAQrhcAC0GozeAAEK4XAAsLIAhBEGokAAJAIAYtABQiAUEGRwRAIAAgBi8AFTsABSAAQQdqIAYtABc6AAAgACAGKQIYNwIIIAAgAToABCAHEPMhQQEhCgwBCyAAIAYpAgg3AgQgAEEMaiAGQRBqKAIANgIACyAAIAo2AgAgBkEgaiQAC4EBAQN/IwBB0ABrIgIkACABQShqIQMgAiADQSj8CgAAIAIgARDwEyAAIAJBKPwKAAAgAkEoaiIEIANBKPwKAAAgBCABEPEDIABB0ABqIAFB0ABqQSj8CgAAIABB+ABqIAFB+ABqQbjx4QAQ5gEgAEEoaiAEQSj8CgAAIAJB0ABqJAALhwECAn4EfyMAQSBrIgQkACAAKQMIIQIgACkDACEDQQAhAANAIAAgBGpBH2ogA6dBD3EtAKb7ZDoAACADQg9WIAJCAFIgAlAgAkI8hiADQgSIhCEDIABBAWshACACQgSIIQIbDQALIAFBAUG2++QAQQIgACAEakEgakEAIABrEMMDIARBIGokAAuHAQICfgR/IwBBIGsiBCQAIAApAwghAiAAKQMAIQNBACEAA0AgACAEakEfaiADp0EPcS0AuPtkOgAAIANCD1YgAkIAUiACUCACQjyGIANCBIiEIQMgAEEBayEAIAJCBIghAhsNAAsgAUEBQbb75ABBAiAAIARqQSBqQQAgAGsQwwMgBEEgaiQAC6QBAQF/IwBBMGsiASQAIAEgADoAByABQQA2AhwgAUKAgICAEDcCFCABQfi+wwA2AiQgAUKggICADjcCKCABIAFBFGo2AiAgAUEHaiABQSBqEOkdBEBBoL/DAEE3IAFBCGpBkL/DAEHYv8MAEKkOAAsgAUEQaiABQRxqKAIAIgA2AgAgASABKQIUNwMIIAEoAgwgABCNHiABQQhqEPMhIAFBMGokAAu5AQECfyMAQRBrIgIkACAAQQRqIQMCfwJAAkACQAJAIAAoAgBBAWsOAwECAwALIAIgAzYCDCABQf3qxABBF0GU68QAQQYgAkEMakGsscQAELULDAMLIAIgAzYCDCABQZrrxABBFiACQQxqQdjPxAAQpQgMAgsgAiADNgIMIAFBwOvEAEEbIAJBDGpBsOvEABClCAwBCyACIAM2AgwgAUHb68QAQRUgAkEMakHYz8QAEKUICyACQRBqJAALsAEBAX8jAEFAaiICJAAgACgCACEAIAJB0OjFADYCOCACQcDoxQA2AjAgAiAANgIsIAJBoOjFADYCKCACIABBKGo2AiQgAkGw6MUANgIgIAIgAEEQajYCHCACQaDoxQA2AhggAiAAQSRqNgIUIAJBoOjFADYCECACIABBIGo2AgwgAiAAQSxqNgI8IAIgAkE8ajYCNCABQZznxQBBCEGk58UAIAJBDGoQhQggAkFAayQAC7kBAQJ/IwBBEGsiAiQAAn8CQAJAAkBBASAAKAIAIgAoAgAiA0GAgICAeHMgA0EAThtBAWsOAgECAAsgAiAAQQRqNgIEIAFByP3HAEEQQbj8xwBBCCACQQRqQbj9xwAQtQsMAgsgAiAANgIIIAFB6P3HAEEcQbj8xwBBCCACQQhqQdj9xwAQtQsMAQsgAiAAQQRqNgIMIAFBhP7HAEERQbj8xwBBCCACQQxqQZT8xwAQtQsLIAJBEGokAAuWAQEHfyMAQSBrIgEkAAJAIAAoAhQiAiAAKAIQIgRPDQAgAEEMaiEFIAAoAgwhBgNAIAIgBmotAABBCWsiB0EXS0EBIAd0QZOAgARxRXJFBEAgACACQQFqIgI2AhQgAiAERw0BDAILCyABQRY2AhQgAUEIaiAFENQQIAFBFGogASgCCCABKAIMEPIUIQMLIAFBIGokACADC64BAQR/IwBBEGsiBCQAAkACQAJAAkACQAJAQQYgAS0AACIFQQZrIAVBBkkbQf8BcUEBaw4GAAECBQMEBQsgAUEIaiECQYi4yQAhAwwECyABQQFqIQJB1LbJACEDDAMLIAFBCGohAkGQt8kAIQMMAgsgBEEIaiABQQRqEJMVIAQoAgwhAyAEKAIIIQIMAQtBmLbJACEDIAEhAgsgACADNgIEIAAgAjYCACAEQRBqJAALoAoBA38jAEFAaiIDJAAgAyAALwEAOwEOAkACfwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIAAvAQAiBEGPA00EQCAEQeEBTQRAAkAgBEHIAWsOCQYHCAkKCwwNDgALIARB5ABrDgMCAwRACyAEQawCaw4JDg8QERITPxQVDQsCQCAEQZADaw40FhcYGRobHB0eHyAhIiMkJSYnKD8/KSorLC0uPy8wPzE/Pz8/Pz8/Pz8/Pz8/Pz8/Pz8/MgALIARB9ANrDgwyMzQ1Njc4OTo+Ozw+C0Hk5dQAIQJBCCEADD0LQezl1AAhAkETIQAMPAtB/+XUACECQQohAAw7C0GJ5tQAIQJBAiEADDoLQYvm1AAhAkEHIQAMOQtBkubUACECQQghAAw4C0Ga5tQAIQJBHSEADDcLQbfm1AAhAkEKIQAMNgtBwebUACECQQ0hAAw1C0HO5tQAIQJBDyEADDQLQd3m1AAhAkEMIQAMMwtB6ebUACECQRAhAAwyCyAEQeIBRw0xQfnm1AAhAkEHIQAMMQtBgOfUACECQRAhAAwwC0GQ59QAIQJBESEADC8LQaHn1AAhAkEFIQAMLgtBpufUACECQQkhAAwtC0Gv59QAIQJBDCEADCwLQbvn1AAhAkEJIQAMKwtBxOfUACECQRIhAAwqC0HW59QAIQJBEiEADCkLQejn1AAhAkELIQAMKAtB8+fUACECQQwhAAwnC0H/59QAIQJBECEADCYLQY/o1AAhAkEJIQAMJQtBmOjUACECQQkhAAwkC0Gh6NQAIQJBEiEADCMLQbPo1AAhAkEOIQAMIgtBwejUACECQR0hAAwhC0He6NQAIQJBDyEADCALQe3o1AAhAkEIIQAMHwtB9ejUACECQQQhAAweC0H56NQAIQJBDyEADB0LQYjp1AAhAkETIQAMHAtBm+nUACECQREhAAwbC0Gs6dQAIQJBDCEADBoLQbjp1AAhAkEWIQAMGQtBzunUACECQRUhAAwYC0Hj6dQAIQJBEiEADBcLQfXp1AAhAkEMIQAMFgtBgerUACECQRMhAAwVC0GU6tQAIQJBFCEADBQLQajq1AAhAkEGIQAMEwtBrurUACECQREhAAwSC0G/6tQAIQJBCSEADBELQcjq1AAhAkEQIQAMEAtB2OrUACECQRUhAAwPC0Ht6tQAIQJBESEADA4LQf7q1AAMDAtBnevUACECQR0hAAwMC0G669QAIQJBFSEADAsLQc/r1AAhAkEPIQAMCgtB3uvUACECQQshAAwJC0Hp69QAIQJBEyEADAgLQfzr1AAhAkEPIQAMBwtBi+zUACECQRohAAwGC0Gl7NQAIQJBFyEADAULQbzs1AAhAkEUIQAMBAtB0OzUACECQQ0hAAwDC0Hd7NQAIQJBDCEADAILQens1AALIQJBHyEACyADIAA2AgQgAyACNgIAIAMgAygCBEEVIAMoAgAiABs2AhQgAyAAQb7t1AAgABs2AhAgA0H0BzYCJCADQYkMNgIcIAMgA0EQajYCICADIANBDmo2AhggASgCBCEAIAEoAgAgA0ICNwI0IANBAjYCLCADQdTt1AA2AiggAyADQRhqNgIwIAAgA0EoahCpBCADQUBrJAALjAEBAn8Cf0H/H0H//wMgAC0AKBsgAU8EQCABQQZ2IgIgACgCBEkEQCAAKAIAIAJBAXRqLwAAIAFBP3FqDAILIAAoAhBBAWsMAQsgACgCGCABSwRAIAAgARCsBgwBCyAAKAIQQQJrCyIBIAAoAhAiA0kEfyAAKAIMIAFqLQAABSACCyAALQAsIAEgA0kbC6YBAQV/IwBBMGsiAiQAIAIgASgCACIDQbwCajYCJCACIANBEGoiBDYCICACIAQ2AhwgAiADNgIYIAJBDGogAkEYaiIFQaCU4QAQuQggAigCDCEEIAIoAhAhAyACKAIUIQYgAiABQSRqNgIsIAIgAUEEajYCKCACIAMgBmo2AiQgAiAENgIgIAIgAzYCHCACIAM2AhggACAFQcSP4QAQvwggAkEwaiQAC3sBBH8jAEGgAWsiAiQAIAFB0ABqIQQgAkHQAGogBEEo/AoAACACQdAAaiIDIAFBKGoiARDwEyACIANBKPwKAAAgAkH4AGoiBSAEQSj8CgAAIAUgARDxAyADIAUQxg8gAkEoaiIBIAIgAxDmASAAIAEQxAIgAkGgAWokAAuHAQEFfyMAQYABayICJAAgACABIAFB+ABqIgMQ5gEgAkEIaiIEIAFBKGoiBSABQdAAaiIGEOYBIAJBMGogBiADEOYBIAJB2ABqIAEgBRDmASAAQShqIARBKPwKAAAgAEHQAGogAkEwakEo/AoAACAAQfgAaiACQdgAakEo/AoAACACQYABaiQAC6MBAgJ/AX4jAEEQayICJAAgASgCCCEDIAIgARCkBgJAIAItAABBAUYEQCACLQABIQEgAEEANgIAIAAgAToABAwBCyACKQMIIgQgA0EBa61UBEAgASgCDEEBaiIDQfQDTQRAIAAgAzYCDCAAIAQ+AgggACABKQIANwIADAILIABBADYCACAAQQE6AAQMAQsgAEEANgIAIABBADoABAsgAkEQaiQAC5QBAQN/IAEoAgAhBAJAAn8CQCABKAIsBEAgBEUNAUF/IAEoAjggASgCMGsiAiABKAIIIAEoAgRraiIBIAEgAkkbIQMgASACTyECDAMLQQEhAiAERQRAQQAhAQwDCyABKAIIIAEoAgRrDAELQQEhAiABKAI4IAEoAjBrCyIDIQELIAAgATYCCCAAIAI2AgQgACADNgIAC5cBAQN/IwBBQGoiAiQAAkAgAEHqycMAQQUQ4w4iAw0AIAJBGGoiBCAAKAIAIgAQnSAgBBC8FSIDDQACfyABKAIAQQFGBEAgAkEIaiAEIAEoAgQQngYgAkEQaiIBIAAgAigCCCACKAIMEPYdIAEQvBUMAQsgABDIFwsiAw0AIAJBBDoAGCACQRhqELwVIQMLIAJBQGskACADC5YBAQJ/IwBB4AdrIgQkACAAKAIAIgAoAgAhAyAAQgA3AwACQCADQQFxBEAgBEEIaiIDIABBCGpB2Af8CgAAQcAPQQgQhCEiAEUNASAAIANB2Af8CgAAIABBADoAuA8gACACNgK0DyAAIAE2ArAPIABB9I7EABDyDCAEQeAHaiQADwtBiOjEAEExENgjAAtBCEHADxDhIwALEAAgACABIAJBhI/EABDmJgsQACAAIAEgAkGUj8QAEOYmC5wBAQF/IwBBEGsiAiQAAkAgASgCACUBEIYBBEAgAkEEaiABEO0PIABBCGogAkEMaigCADYCACAAIAIpAgQ3AgAMAQsgARDKIARAIAIgARCnJSIBNgIAIAJBBGogAhDtDyAAQQhqIAJBDGooAgA2AgAgACACKQIENwIAIAFBhAFJDQEgARChFgwBCyAAQYCAgIB4NgIACyACQRBqJAAL3wEBBH8jAEEQayIDJAACQCAAKAIkIgFBAk0EQCABRQ0BIABBBGohAANAIAAoAgAiAiACKAIAIgJBAWs2AgAgAkEBRgRAIAAQkw0LIABBBGoQ3hQgAEEQaiEAIAFBAWsiAQ0ACwwBCyADIAApAgRCIIk3AgggAyABNgIEIANBBGoiAiIAKAIIIgEEQCAAKAIEIQADQCAAKAIAIgQgBCgCACIEQQFrNgIAIARBAUYEQCAAEJMNCyAAQQRqEN4UIABBEGohACABQQFrIgENAAsLIAJBBEEQEK4OCyADQRBqJAALmgEBAX8jAEEwayICJAACfyAAKAIAQQFGBEAgAUGoi8gAQcEAEOgeDAELIAIgAEEIajYCACACIABBEGo2AgQgAkG7BjYCFCACQbsGNgIMIAIgAkEEajYCECACIAI2AgggASgCACABKAIEIAJCAjcCJCACQQM2AhwgAkGQi8gANgIYIAIgAkEIajYCICACQRhqEKkECyACQTBqJAALnAEBAn8jAEEgayICJAACQCABKAIEIgNFBEAgAEEANgIADAELIAEgA0EBazYCBCACQRBqIAEoAgAQtARBASEBAn8gAigCEEEBRgRAIAIoAhQMAQsgAkEIaiACKQMYEPwKIAIoAgghASACKAIMCyEDIAFBAXEEQCAAQQI2AgAgACADNgIEDAELIAAgAzYCBCAAQQE2AgALIAJBIGokAAuZAQEBfyMAQTBrIgIkAAJ/IAAoAgBBAUYEQCACIABBBGo2AgAgAiAAQQhqNgIEIAJB6ww2AhQgAkHrDDYCDCACIAJBBGo2AhAgAiACNgIIIAEoAgAgASgCBCACQgI3AiQgAkECNgIcIAJBnLzUADYCGCACIAJBCGo2AiAgAkEYahCpBAwBCyABQfW71ABBEBDoHgsgAkEwaiQAC6oDAQl/IwBBIGsiAyQAIANBFGogASgCCCICIAEoAgRrIgVBACACIAVPG0EAQQhBIBCiCyADKAIYIQIgAygCFEEBRgRAIAIgAygCHEGYmdUAEPYbAAsgA0EQaiIKQQA2AgAgAyADKAIcNgIMIAMgAjYCCCMAQRBrIgUkACABKAIIIgIgASgCBGsiBEEAIAIgBE8bIgYgA0EIaiICKAIAIAIoAggiBGtLBEAgAiAEIAZBCEEgEMAUIAIoAgghBAsgBSACKAIENgIMIAUgBDYCCCAFIAJBCGo2AgQjAEEgayICJAAgBUEEaiIGKAIEIQQgBigCACABKAIIIgcgASgCBCIISwR/IAEoAgAaIAcgCGshCSAEIAdqIAhrIAYoAgggBEEFdGohAQNAIAIQzQ8gAUEYaiACQRhqKQMANwMAIAFBEGogAkEQaikDADcDACABQQhqIAJBCGopAwA3AwAgASACKQMANwMAIAFBIGohASAJQQFrIgkNAAsFIAQLNgIAIAJBIGokACAFQRBqJAAgAEEIaiAKKAIANgIAIAAgAykCCDcCACADQSBqJAALngECAn8BfiMAQRBrIgIkACABKQIAIQQgAS0ACCEDIAJBC2ogAUELai0AADoAACACIAEvAAk7AAkgAEEAEKUaIAIgAzoACCACIAQ3AwACQCADQQFxDQADQCACEPYHIgFB3ABHIAFBL0dxDQEgACgCCCEDIABBARClGiAAKAIEIAAoAghqIAE6AAAgACADQQFqNgIIDAALAAsgAkEQaiQAC5UBAQF/IwBBQGoiAiQAIAIgACgCACIAKQIANwIIIAIgAEEMaq1CgICAgKABhDcDICACIABBCGqtQoCAgICgAYQ3AxggAiACQQhqrUKAgICA0PEBhDcDECABKAIEIQAgASgCACACQgM3AjQgAkEDNgIsIAJBvJHfADYCKCACIAJBEGo2AjAgACACQShqEKkEIAJBQGskAAuMAQIBfwF+IAApAgQiAkIgiEI/g0KA3O+67nmEIABBDmowAAB9IAAoAgAiAUH/A3EgAUEKdUG/hD1qIgFBnH9taiABQZADbWogAaxCtQt+QgR/p2pBs8irrQFrrEKAowV+fCACQjCIQh+DIAAvAQwiAK3CfUKQHH58IAJCKIhCP4MgAEEIdq3CfUI8fnwLpAEBA38jAEEwayICJABBASEDAkAgAUH4n+QAQRsQ6B4NAAJAIAAoAgAEQCACIAA2AgwgAkGxBTYCFCACIAJBDGo2AhAgASgCACABKAIEIAJCATcCJCACQQI2AhwgAkGcoOQANgIYIAIgAkEQajYCICACQRhqEKkERQ0BDAILIAFBrKDkAEEEEOgeDQELIAFBsKDkAEECEOgeIQMLIAJBMGokACADCywAIAAgAUGkqcMAQfCowwBBtKnDAEH4qMMAQYipwwBB0KjDAEHgqMMAEI4mC4cBAQJ/IwBBQGoiAiQAAkAgAQRAIAFBCGsiAygCAEEBRw0BIAJBEGogAUEw/AoAACADQQA2AgACQCADQX9GDQAgAUEEayIBIAEoAgBBAWsiATYCACABDQAgA0E4QQQQnyALIAAgAkEUakEs/AoAACACQUBrJAAPCxDZIwALQZ2ZxABBPxDYIwALmAEBAX8gAEEEahD1DyAAQQhqEPUPIAAQ+hggACgCDCIBIAEoAgAiAUEBazYCACABQQFGBEAgAEEMahD+EQsgACgCECIBIAEoAgAiAUEBazYCACABQQFGBEAgAEEQahDaFwsgACgCFEEIahDWDiAAKAIUIgEgASgCACIBQQFrNgIAIAFBAUYEQCAAQRRqEOQCCyAAQRhqELUYC6ABAQF/IwBBEGsiAiQAIAJBBGogARCjBAJAIAItAARBAUYEQCAAIAIoAgg2AgQgAEEBOgAADAELIAItAAVFBEAgAEEAOwEADAELIAEoAgAiARC3GiABQQA2AgggAkEEaiABQQxqIAEQkgUCQCACKAIEQQJHDQAgAigCCCIBRQ0AIABBAToAACAAIAE2AgQMAQsgAEGAAjsBAAsgAkEQaiQAC6EBAQF/IwBBMGsiAiQAIAIgATYCBCACIAA2AgAgAkEANgIcIAJCgICAgBA3AhQgAkGg+scANgIkIAJCoICAgA43AiggAiACQRRqNgIgIAIgAkEgahCtDQRAQcj6xwBBNyACQQhqQbj6xwBBgPvHABCpDgALIAJBEGogAkEcaigCADYCACACIAIpAhQ3AwggAkEIahD5ASACEMUVIAJBMGokAAueAQEDfyMAQRBrIgEkAAJ/QQEgACgCuAFFDQAaQQAgAEHRgsIAQY+DwgAgAC0AyAEbQQFBAEEAEKUNRQ0AGiAAKALAASEDIAEgACgCuAEiAjYCDCABIAIgA2o2AgggASACNgIEA0ACQCABKAIMIgIgASgCCCIDRgRAIABBADsBrAEMAQsgACABQQRqEKEHDQELCyACIANGCyABQRBqJAALLAAgACABQbCy0wBB/LHTAEHAstMAQYSy0wBBlLLTAEHcsdMAQeyx0wAQjiYLkQEBBX8jAEEgayICJAADQCAAKAIAIQECQANAIAFBAXENASAAIAFBAXIgACgCACIEIAEgBEYiBRs2AgAgBCEBIAVFDQALIAJBIGokAA8LIAFBA00EQCADQQpJIANBAWohAw0BCwsgAkEANgIYIAJBATYCDCACQbTZ0wA2AgggAkIENwIQIAJBCGpB3NnTABD3GAALnwEBBX8jAEEgayICJAAgASgCACEFIAJBFGogASgCBCIBQQBBAkEEEKILIAIoAhghAyACKAIUQQFHBEAgAigCHCEEIAFBAnQiBgRAIAQgBSAG/AoAAAsgAiABNgIcIAIgBDYCGCACIAM2AhQgAkEIaiACQRRqQYSl1AAQgxAgACACKQMINwMAIAJBIGokAA8LIAMgAigCHEGUpdQAEPYbAAsPACAAIAEgAkEDQQQQ3iYLlAEBA38jAEEwayIDJABBAiACEPAYQf8BcSIEayIFQQAgBUECTRshBSAEQQFNBEAgBSEEA0AgAUGA+dQAQQEQjx8gBEEBayIEDQALCyADIANBCGogAhC5DSABIAMoAgAgAygCBCIBEI8fIAEgASAFaiICTQRAIABBBDoAACAAIAI2AgQgA0EwaiQADwtB8PjUABCuFwALDwAgACABIAJBAUECEN4mCw8AIAAgASACQQhBCRDeJgsPACAAIAEgAkEHQQgQ3iYLDwAgACABIAJBBkEHEN4mCw8AIAAgASACQQVBBhDeJgsPACAAIAEgAkEEQQUQ3iYLDwAgACABIAJBAkEDEN4mC5sBAQJ/IwBBEGsiBCQAIAAoAgAhBSAALQAEQQFHBEAgBSgCAEG+w9UAQQEQjR8LIABBAjoABCAEIAUgASACEP0QAn8gBC0AAEEERwRAIAQgBCkDADcDCCAEQQhqEOkWDAELIAUoAgBBv8PVAEEBEI0fIAUoAgBBtsPVAEGxw9UAIAMtAAAiABtBBEEFIAAbEI0fQQALIARBEGokAAuHAQEBfyMAQeAAayIEJAAgBCABIAIgAxDlCyAEQTBqIAFBMGogAkEwaiADEOULIANB/wFxQYABRwRAIAItAGAhAiABLQBgIQEgACAEQTD8CgAAIABBMGogBEEwakEw/AoAACAAQQAgA2sgASACc3EgAXM6AGAgBEHgAGokAA8LQcyM3gAQsRcAC50BAQR/IwBBIGsiAyQAIANBFGogAkEAQQFBARCiCyADKAIYIQQgAygCFEEBRwRAIAMoAhwhBSACBEAgBSABIAL8CgAACyADQQhqEMcYIAMoAgghASADKAIMIQYgACACNgIUIAAgBTYCECAAIAQ2AgwgACAGNgIIIAAgATYCBCAAQQI6AAAgA0EgaiQADwsgBCADKAIcQcDE3gAQ9hsAC4oBAQN/IwBBEGsiAyQAQQMhAiAALQAAIgAhBCAAQQpPBEAgAyAAIABB5ABuIgRB5ABsa0H/AXFBAXQvAMn5ZDsADkEBIQILQQAgACAEG0UEQCACQQFrIgIgA0ENamogBEEBdC0AyvlkOgAACyABQQFBAUEAIANBDWogAmpBAyACaxDDAyADQRBqJAALmgEBAn8jAEEgayICJAAgASgCDCEDAkACQAJAAkACQCABKAIEDgIAAQILIAMNAUEBIQFBACEDDAILIAMNACABKAIAIgEoAgQhAyABKAIAIQEMAQsgAkEYaiABQRBqKQIANwMAIAJBEGogAUEIaikCADcDACACIAEpAgA3AwggACACQQhqEO4EDAELIAAgASADEJAPCyACQSBqJAALlAEBAX8jAEGwAmsiAiQAIAJBCGogARCCBQJAIAItAAhBAUYEQCAAIAIoAgw2AgggAEICNwMADAELIAItAAlFBEAgAEIANwMADAELIAJBCGogASgCABD3DiACKAIIRQRAIABBCGogAkEQakGgAvwKAAAgAEIBNwMADAELIAAgAigCDDYCCCAAQgI3AwALIAJBsAJqJAAL4gEBBX8jAEEgayIDJAAgASgCDCECAkACQAJAAkACQCABKAIEDgIAAQILIAINAUEBIQFBACECDAILIAINACABKAIAIgEoAgQhAiABKAIAIQEMAQsgA0EYaiABQRBqKQIANwMAIANBEGogAUEIaikCADcDACADIAEpAgA3AwggACADQQhqEO4EDAELIwBBEGsiBCQAIARBCGogAkHI88IAEJASIAQoAgghBiAEKAIMIQUgAgRAIAUgASAC/AoAAAsgACACNgIIIAAgBTYCBCAAIAY2AgAgBEEQaiQACyADQSBqJAALkQEBBX8jAEEgayICJAAgAkEANgIUIAIgACgCBCIFIAGncSIENgIQIAAoAgAhBkEIIQMDQCACIAQgBmopAAA3AxggAkEIaiAAIAJBGGogAkEQahDEFyACKAIIQQFGRQRAIAIgAzYCFCACIAMgBGogBXEiBDYCECADQQhqIQMMAQsLIAAgAigCDBCpGCACQSBqJAALoAEBAn8jAEEQayIBJAAgAC0AtAQhAiAAQQE6ALQEIAEgADYCDAJAIAApAwhQDQACQAJAIAAtALgCQQNrDgIAAQILIABBwAJqEOATDAELIAAtAPgCQQNHDQAgAC0A9AJBA0cNACAAQcgCahCwGAsgAEIANwMIAkAgAg0AIAAgACgCACIAQQFrNgIAIABBAUcNACABQQxqEOUOCyABQRBqJAALswEAAn8CQAJAAkACQAJAAkACQCACQQ9rDgwABAYGBgYDAQYGBgIFCyABQci1xABBDxCaEw0FQQAMBgsgAUHXtcQAQRYQmhMNBEEBDAULIAFBlbbEAEEaEJoTDQNBAwwECyABQa+2xABBFRCaEw0CQQQMAwsgAUHEtsQAQRAQmhMNAUEFDAILIAJBKEcNACABQe21xABBKBCaEw0AQQIMAQtBBgshAiAAQQA6AAAgACACOgABC7ABAQJ/IwBBEGsiAiQAAn8CQAJAAkAgACgCACIAKAIAIgNBH3UgA0H/////B2txQQFrDgIBAgALIAIgADYCBCABQcTqxABBDiACQQRqQbTqxAAQpQgMAgsgAiAAQQRqNgIIIAFB0urEAEERQePqxABBCCACQQhqQayxxAAQtQsMAQsgAiAAQQRqNgIMIAFB6+rEAEESQePqxABBCCACQQxqQayxxAAQtQsLIAJBEGokAAupAQEBfyMAQUBqIgIkACACQfzgxgA2AjggAkHs4MYANgIwIAJB3ODGADYCKCACQdzgxgA2AiAgAkHc4MYANgIYIAJB3ODGADYCECACIAA2AgwgAiAAQQRqNgIsIAIgAEEDajYCJCAC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AQAPC0GItd8AELQXAAsQACAAIAEgAkG8ud8AEJwmCxAAIAAgASACQdy53wAQnCYLhwEBBH8CQCAALQBoIgNBwABNBEAgASgCACEEIAEoAgQiBUHAACADa0H/AXEiAiACIAVLGyICBEAgACADaiAEIAL8CgAACyAALQBoIAJqIgNB/wFxIANGDQFBzPPgABCuFwALQbzz4AAQtBcACyAAIAM6AGggASAFIAJrNgIEIAEgAiAEajYCAAuJAQEFfyMAQRBrIgMkAAJAIAAoAgQiBCAAKAIMIgVGBEAgASgCBCECDAELIAEoAgQhAiABKAIIIQYDQCACIAZqIAQtAAA6AAAgAkEBaiECIARBAWoiBCAFRw0ACwsgASgCACACNgIAIAMgACgCADYCDCADIAAoAgg2AgggA0EIahDzISADQRBqJAALjAEBAn8jAEEwayIBJAAgACgCACIAKAIIQQJHBEAgAEEIaiAAEO0TCwJAQeDQ5gAtAAANACAAKAIYIgJFDQAgAUECNgIMIAFBiNHCADYCCCABQgE3AhQgAUEFNgIkIAEgAikCDDcCKCABIAFBIGo2AhAgASABQShqNgIgIAAgAUEIahCFBQsgAUEwaiQAC38BA38CQAJAIAEoAgBBAUYEQCABKAIUIgQgASgCGEkNASABQQA2AgALIAEoAhxFDQEgASgCICICIAEoAihGDQFBASEDIAEgAkEBajYCICACLQAAIQIMAQsgASAEai0ABCECQQEhAyABIARBAWo2AhQLIAAgAjoAASAAIAM6AAALswIBB38jAEEQayIFJAACQAJAIAEoAgAEQCAFQQhqIQYgASgCACIHKAIQIQMCQAJAA0AgA0EATgRAQQAhAwwDCyADQf////8HcSIIQf////8HRg0BIAcgCEH/////B2sgBygCECIEIAMgBEYiCRs2AhAgBCEDIAlFDQALQQEhAyAIQQFqIQQMAQtBmLrDAEHGAEHgusMAEJwVAAsgBiAENgIEIAYgAzYCACAFKAIIDQELIABBAToAICAAIAIpAgA3AgAgAEEYaiACQRhqKQIANwIAIABBEGogAkEQaikCADcCACAAQQhqIAJBCGopAgA3AgAMAQsgASgCACIEQQhqIQMgAhCfEyECIAMoAgAgAyACNgIAIAI2AiAgBEEYahD3FCAAQYGAgIB4NgIACyAFQRBq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AghBAXEEf0EBBSAIIAE2AhwgCEEGNgIYIAhB9vLEADYCFCMAQRBrIgEkACAIQRRqIgIoAgghAyABEJYfIgc2AgwgAUEMaiACKAIAIAIoAgQQ1BcgAxCjICAIIAc2AgQgCEEANgIAIAFBEGokACAIKAIEIQEgCCgCAAs2AgAgBCABNgIEIAhBIGokACAMKAIIIQIgDCgCDAwBCyAMQenyxABBDRCJFiAMKAIAIQIgDCgCBAshASAAIAI2AgAgACABNgIEIAxBEGokAAswACAAIAFB6NPHAEELQdjUxwBB9NTHAEGh1ccAQeTUxwBBmdXHAEEVQYTVxwAQ1yULcQEBfyMAQSBrIgIkACAAAn8gASgCAEGAgICAeEYEQCAAIAEtAAQ6AAEgARDBDUEADAELIAJBEGogAUEIaikDADcDACACIAEpAwA3AwggACACQQhqIAJBH2pBvNbHABC8GDYCBEEBCzoAACACQSBqJAALiQIBA38jAEHgAWsiAyQAIANBCGohBCMAQZACayICJAAgAkEAQTD8CwAgAkGgAWogASACQTAQnAcCQCACKAKgAUUEQCACKAKkASEBIARBATYCACAEIAE2AgQMAQsgAkGgAWoiASACEMMMIAJBMGogARCaF0EBIQECQCACKAIwQQFGBEAgBEEIaiACQThqQegA/AoAAEEAIQEMAQsgBEHIkskAQSkQnQ42AgQLIAQgATYCAAsgAkGQAmokAEEBIQECQCADKAIIQQFGBEAgACADKAIMNgIEDAELIANB+ABqIgEgA0EQakHoAPwKAAAgAEEIaiABEIARQQAhAQsgACABNgIAIANB4AFqJAALiQIBA38jAEHgAWsiAyQAIANBCGohBCMAQZACayICJAAgAkEAQTD8CwAgAkGgAWogASACQTAQ9w8CQCACKAKgAUUEQCACKAKkASEBIARBATYCACAEIAE2AgQMAQsgAkGgAWoiASACEMMMIAJBMGogARCaF0EBIQECQCACKAIwQQFGBEAgBEEIaiACQThqQegA/AoAAEEAIQEMAQsgBEHIkskAQSkQow42AgQLIAQgATYCAAsgAkGQAmokAEEBIQECQCADKAIIQQFGBEAgACADKAIMNgIEDAELIANB+ABqIgEgA0EQakHoAPwKAAAgAEEIaiABEIARQQAhAQsgACABNgIAIANB4AFqJAALcAEDfyMAQRBrIgIkACAAKAIMIgMgACgCBCIBRwRAIAMgAWtBBXYhAwNAIAEQ9wogAUEQahD3CiABQSBqIQEgA0EBayIDDQALCyACIAAoAgA2AgwgAiAAKAIINgIIIAJBCGpBCEEgEK4OIAJBEGokAAt2AQF/IwBBQGoiAyQAIAMgAjYCFCADIAE2AhAgAyAANgIMIANBAjYCHCADQdTSygA2AhggA0ICNwIkIANB+Ao2AjwgA0EKNgI0IAMgA0EwajYCICADIANBEGo2AjggAyADQQxqNgIwIANBGGoQywggA0FAayQACzMBAX8jAEEgayIBJAAgAEIANwIEIABBADoAACAAQQxqQQA6AAAgAEECNgIQIAFBIGokAAt2AQF/IwBBQGoiAyQAIAMgAjYCFCADIAE2AhAgAyAANgIMIANBAjYCHCADQcSd1QA2AhggA0ICNwIkIANBkQ42AjwgA0EKNgI0IAMgA0EwajYCICADIANBEGo2AjggAyADQQxqNgIwIANBGGoQ5AcgA0FAayQAC4UCAQZ/IwBBEGsiCCQAIAggAjYCDCAIIAE2AggCQCADKAIIIgQgAkcEQCAEIAhBCGpBnLTVABCDDyECIAMQ8yFBACEBDAELIAMoAgQhBSMAQSBrIgQkAAJAAkAgAkUNACACQQRPBEAgASAFIAJBAnYQ3RYLIAJBA3EiB0UNACAFIAJBfHEiBmohBSABIAZqIQYgBiAHQQFGBH9BAAUgBi8AACEHIAYgBS8AADsAACAFIAc7AAAgAkEBcUUNAUECCyIHaiIGLQAAIQkgBiAFIAdqIgUtAAA6AAAgBSAJOgAACyAEQSBqJAAMAAsgAxDzIQsgACACNgIEIAAgATYCACAIQRBqJAAL7wEBBH8jAEHgAWsiAyQAIANBCGohBCMAQaABayICJAAgAkEAQTD8CwAgAkEwaiABIAJBMBCEEAJAIAIoAjBFBEAgBCACKAI0NgIEQQEhAQwBCyACQTBqIgUgAhDDDEEBIQEgAi0AmAFBAUYEQCAEQQhqIAVB6AD8CgAAQQAhAQwBCyAEQZS61QBBKRCjDjYCBAsgBCABNgIAIAJBoAFqJABBASEBAkAgAygCCEEBRgRAIAAgAygCDDYCBAwBCyADQfgAaiIBIANBEGpB6AD8CgAAIABBCGogARCAEUEAIQELIAAgATYCACADQeABaiQACxEAIAAgAUH8CkHA3t4AEIEmCxEAIAAgAUGBDkHQhN8AEIEmC3gBAn8jAEEQayICJAACfyABKQIAQvXXvMnIzNazOoUgASkCCEL+28ub8+W5xvUAhYRQRQRAIABBGGoQliUoAhAhAyAAKAIYIAJBCGogAUEIaikCADcDACACIAEpAgA3AwAgAiADEQAADAELIABBDGoLIAJBEGokAAt4AQJ/IwBBEGsiAiQAAn8gASkCAEL117zJyMzWszqFIAEpAghC/tvLm/Plucb1AIWEUEUEQCAAQRhqEJYlKAIUIQMgACgCGCACQQhqIAFBCGopAgA3AwAgAiABKQIANwMAIAIgAxEAAAwBCyAAQQxqCyACQRBqJAALcAECfwJAIAEoAgAiAUEBcQRAIAEgAksNASACIAFrIgQgA2oiBSAETwRAIAMEQCABIAIgA/wKAAALIAAgAzYCCCAAIAE2AgQgACAFNgIADwtB2IrfABCuFwALIAAgASACIAMQ/goPC0GEit8AELQXAAt2AQF/IAEoAhAiBEUEQEHIl+EAEKwXAAsgAEEANgIcIAAgAzYCGCAAIAI2AhQgACABKQIANwIAIABBCGogAUEIaikCADcCACAAQRBqIAFBEGooAgA2AgAgACADIAJrQQJ2IgAgASgCDCAEbiIBIAAgAUkbNgIgC3gAIwBBMGsiACQAIAAgASACENMTIAAoAgAiAQRAIABBzKPkADYCDCAAIAE2AgggAEEBNgIUIABB+KLkADYCECAAQgE3AhwgAEGqBDYCLCAAIABBKGo2AhggACAAQQhqNgIoIABBEGpBgKPkABD3GAALIABBMGokAAsVACAAIAFBjLTkAEEQQeuz5AAQliYLFQAgACABQci05ABBFUGctOQAEJYmC2oBAn8jAEEQayICJAAgACgCACIAKAIIIQMgACgCBCEAIAJBBGogARDJGSADBEADQCACIAA2AgwgAkEEaiACQQxqQbjF5AAQ4gggAEEBaiEAIANBAWsiAw0ACwsgAkEEahCnGCACQRBqJAALEAAgACABIAJBuLzCABDmJQvcCgIQfwF+IwBBIGsiDSQAIA1BADYCCCANQoCAgIAQNwIAIA1B/LPCADYCECANQqCAgIAONwIUIA0gDTYCDCANQQxqIREjAEHQAGsiBCQAIAQgASkCFDcDACAEKAIA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ACAAKAIAQQFrIgA2AgAgAEUEQCADEM0YCyABQdAAaiQAC3IBAn8jAEEQayICJAACQCABKAIEIgNFBEAgAEIANwMADAELIAEgA0EBazYCBCACIAEoAgAQzgMgAigCAEEBRgRAIAIoAgQhASAAQgI3AwAgACABNgIIDAELIAAgAikDCDcDCCAAQgE3AwALIAJBEGokAAtsAQF/IwBBMGsiAiQAIAAoAgAhACACQdoONgIQIAIgADYCFCACIAJBFGo2AgwgASgCBCEAIAEoAgAgAkIBNwIkIAJBAjYCHCACQbDE3gA2AhggAiACQQxqNgIgIAAgAkEYahCpBCACQTBqJAALiQEBAn8CQAJAAkACQAJAAkAgAS0AAEEBaw4MAQUFBQUFBQUFAgMEAAsgAUEMaiECQay+3gAhAwwECyABQQxqIQJBpL/eACEDDAMLIAFBAWohAkGcwN4AIQMMAgsgAUEBaiECQei+3gAhAwwBCyABQQRqIQJB4L/eACEDCyAAIAM2AgQgACACNgIACxYAIAAgAUGgid8AQQNBBEEKQQoQjSYLcQEBfyMAQRBrIgMkAAJAIAAgAU0EQCACIAEgAGsiAmoiASACTwRAIAFBARDnHUUNAiAAIAFBARCfICADQRBqJAAPC0Goit8AEK4XAAtBhIrfABC0FwALQdiJ3wBBKyADQQ9qQciJ3wBBuIrfABCpDgALfQMBfwF+AXwjAEEQayIDJAACQAJAAkACQCAAKAIAQQFrDgIBAgALIAArAwghBSADQQM6AAAgAyAFOQMIDAILIAApAwghBCADQQE6AAAgAyAENwMIDAELIAApAwghBCADQQI6AAAgAyAENwMICyADIAEgAhDaDSADQRBqJAALZwAgAAJ/IAJBIEYEQCAAIAEpAAA3AAEgAEEZaiABQRhqKQAANwAAIABBEWogAUEQaikAADcAACAAQQlqIAFBCGopAAA3AABBAAwBCyAAQSA2AgwgACACNgIIIABBADYCBEEBCzoAAAvRAQECfyMAQcABayICJAAgAkG4AWogAUEYaikAADcDACACQbABaiABQRBqKQAANwMAIAJBqAFqIAFBCGopAAA3AwAgAiABKQAANwOgASMAQSBrIgMkACACQaABaiIBIAEtAB9BP3FBwAByOgAfIAEgAS0AAEH4AXE6AAAgA0EIaiABQQhqKQAA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AgghAyABKAIEIQRBACEBA0ACQCABIANGBEAgBCECDAELIAEgBGogAUEBaiEBLQAAIgVBIGshBkEAIQIgBUEJRiAGQf8BcUHfAElyDQELCyAAIAM2AgQgACACNgIAC+QBAQd/IwBBEGsiAyQAAn8gASgCCEUEQCABKAIEIQIgASgCAAwBCyADQQRqIQIgASgCACEHIAEoAgQhBCMAQRBrIgEkACABQQRqIARBAEEBQQIQogsgASgCCCEFAkAgASgCBEEBRwRAIAEoAgwhBiAEQQF0IggEQCAGIAcgCPwKAAALIAIgBDYCCCACIAY2AgQgAiAFNgIAIAFBEGokAAwBCyAFIAEoAgxB3IHeABD2GwALIAMoAgwhAiADKAIEIQQgAygCCAshASAAIAQ2AgggACACNgIEIAAgATYCACADQRBqJAALUwEBfyAAQSprIgFB/wFxQTZJQpmAgICAgIAQIAGtiKdBAXFxIABBMGtB/wFxQQpJIABBwQBrQf8BcUEaSXJyRQRAIABB4QBrQf8BcUEaSQ8LQQELZAEEfyMAQRBrIgEkACAAKAIMIgQgACgCBCICa0EMbiEDIAIgBEcEQANAIAIQ8yEgAkEMaiECIANBAWsiAw0ACwsgASAAKAIANgIMIAEgACgCCDYCCCABQQhqEPYgIAFBEGokAAtyAQN/IwBBEGsiAiQAIAJBBGogASgCACIEELklQQBBAUEBEKILIAIoAgghAyACKAIEQQFGBEAgAyACKAIMQbyr5AAQ9hsACyABIAIoAgwiARCnFCAAIAQQuSU2AgggACABNgIEIAAgAzYCACACQRBqJAALoAIBA38jAEGgAWsiAiQAAkACQCABRQRAIAJBCGohBCMAQbABayIBJAACQAJAIAAEQCAAQQhrIgMoAgBBAUcNASABQRBqIABBoAH8CgAAIANBADYCAAJAIANBf0YNACAAQQRrIgAgACgCAEEBayIANgIAIAANACADQagBQQgQnyALIAQgAUEYakGYAfwKAAAgAUGwAWokAAwCCxDZIwALQZ2ZxABBPxDYIwALIAJBQGsQlRwMAQsgAEUNASACIABBCGsiADYCCCAAIAAoAgBBAWsiADYCACAADQAgAkEIaigCACIAQcgAahCVHAJAIABBf0YNACAAIAAoAgRBAWsiATYCBCABDQAgAEGoAUEIEJ8gCwsg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7AIgASASNgLoAiABIBM2AuQCIAEgFDYC4AIgAUGgAmoiAiABQeACaiIDIAFBwAFqIgQQrRUgASgCqAIhESABKAKsAiESIAEoAqACIRMgASgCpAIhFCABIB03A8ABIAEgIjcDyAEgASAONgLsAiABIA82AugCIAEgCTYC5AIgASAQNgLgAiACIAMgBBCtFSABKAKoAiEOIAEoAqwCIQ8gASgCoAIhCSABKAKkAiEQIAEgJzcDwAEgASAvNwPIASABIAo2AuwCIAEgCzYC6AIgASAMNgLkAiABIA02AuACIAIgAyAEEK0VIAEoAqgCIQogASgCrAIhCyABKAKgAiEMIAEoAqQCIQ0gASAaNwPAASABIB43A8gBIAEgCDYC7AIgASAHNgLoAiABIAU2AuQCIAEgBjYC4AIgAiADIAQQrRUgASgCqAIhBSABKAKsAiEHIAEoAqACIQYgASgCpAIhCCABIBOtIBStQiCGhCAghSIgQiCIp0EQd61CIIYgIKdBEHethCIjNwPAASABIBGtIBKtQiCGhCArhSIgQiCIp0EQd61CIIYgIKdBEHethCIrNwPIASABICw3A+gCIAEgMjcD4AIgAiADIAQQrRUgASkDoAIhICABKQOoAiEyIAEgCa0gEK1CIIaEICqFIixCIIinQRB3rUIghiAsp0EQd62EIio3A8ABIAEgDq0gD61CIIaEIBuFIhtCIIinQRB3rUIghiAbp0EQd62EIi03A8gBIAEgJTcD6AIgASAcNwPgAiACIAMgBBCtFSABKQOgAiEcIAEpA6gCISUgASAMrSANrUIghoQgKYUiG0IgiKdBEHetQiCGIBunQRB3rYQiKTcDwAEgASAKrSALrUIghoQgMYUiG0IgiKdBEHetQiCGIBunQRB3rYQiMTcDyAEgASAzNwPoAiABIDA3A+ACIAIgAyAEEK0VIAEpA6ACIRsgASkDqAIhLCABIAatIAitQiCGhCAohSIwQiCIp0EQd61CIIYgMKdBEHethCIwNwPAASABIAWtIAetQiCGhCAhhSIhQiCIp0EQd61CIIYgIadBEHethCIzNwPIASABIB83A+gCIAEgJDcD4AIgAiADIAQQrRUgASkDoAIhISABKQOoAiEkIAEgLiAyhSIfQiCIp0EMd61CIIYgH6dBDHethCIuNwPIASABICAgJoUiH0IgiKdB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hIUiG0IgiKdBEHetQiCGIBunQRB3rYQiKjcDyAEgASAiNwPoAiABIB03A+ACIAIgAyAEEK0VIAEpA6gCIR0gASkDoAIhIiABIAytIA2tQiCGhCA5QiCGICWEhSIlQiCIp0EQd61CIIYgJadBEHethCItNwPAASABIAqtIAutQiCGhCAxQiCGICmEhSIlQiCIp0EQd61CIIYgJadBEHethCIpNwPIASABIBw3A+gCIAEgHzcD4AIgAiADIAQQrRUgASkDqAIhHyABKQOgAiEbIAEgBq0gCK1CIIaEIDpCIIYgLISFIhxCIIinQRB3rUIghiAcp0EQd62EIjE3A8ABIAEgBa0gB61CIIaEIDNCIIYgMISFIhxCIIinQRB3rUIghiAcp0EQd62EIjc3A8gBIAEgJDcD6AIgASAhNwPgAiACIAMgBBCtFSABKQOoAiEhIAEpA6ACISQgASAeICaFIhxCIIinQQx3rUIghiAcp0EMd62EIiY3A8ABIAEgGiAuhSIcQiCIp0EMd61CIIYgHKdBDHethCIuNwPIASABIBI2AuwCIAEgETYC6AIgASAUNgLkAiABIBM2AuACIAIgAyAEEK0VIAEoAqACIRQgASgCpAIhEyABKAKoAiESIAEoAqwCIREgASAiICiFIhxCIIinQQx3rUIghiAcp0EMd62EIjg3A8ABIAEgHSA1hSIcQiCIp0EMd61CIIYgHKdBDHethCI1NwPIASABIA82AuwCIAEgDjYC6AIgASAQNgLkAiABIAk2AuACIAIgAyAEEK0VIAEoAqACIRAgASgCpAIhCSABKAKoAiEPIAEoAqwCIQ4gASAbICeFIhxCIIinQQx3rUIghiAcp0EMd62EIic3A8ABIAEgHyAvhSIcQiCIp0EMd61CIIYgHKdBDHethCIvNwPIASABIAs2AuwCIAEgCjYC6AIgASANNgLkAiABIAw2AuACIAIgAyAEEK0VIAEoAqACIQ0gASgCpAIhDCABKAKoAiELIAEoAqwCIQogASAkIDSFIhxCIIinQQx3rUIghiAcp0EMd62EIjQ3A8ABIAEgISA2hSIcQiCIp0EMd61CIIYgHKdBDHethCI2NwPIASABIAc2AuwCIAEgBTYC6AIgASAINgLkAiABIAY2AuACIAIgAyAEEK0VIAEoAqACIQYgASgCpAIhBSABKAKoAiEHIAEoAqwCIQggASASrSARrUIghoQgI4UiHEIgiKdBCHetIiNCIIYgHKdBCHetIiiENwPIASABIBStIBOtQiCGhCArhSIcQiCIp0EId60iOUIghiAcp0EId60iK4Q3A8ABIAEgGjcD6AIgASAeNwPgAiACIAMgBBCtFSABKQOgAiEsIAEpA6gCITIgASAPrSAOrUIghoQgKoUiGkIgiKdBCHetIh5CIIYgGqdBCHetIhqENwPIASABIBCtIAmtQiCGhCAghSIcQiCIp0EId60iKkIghiAcp0EId60iOoQ3A8ABIAEgHTcD6AIgASAiNwPgAiACIAMgBBCtFSABKQOgAiElIAEpA6gCIRwgASALrSAKrUIghoQgKYUiHUIgiKdBCHetIiJCIIYgHadBCHetIh2ENwPIASABIA2tIAytQiCGhCAthSIgQiCIp0EId60iKUIghiAgp0EId60iLYQ3A8ABIAEgHzcD6AIgASAbNwPgAiACIAMgBBCtFSABKQOgAiEzIAEpA6gCITAgASAHrSAIrUIghoQgN4UiH0IgiKdBCHetIjdCIIYgH6dBCHetIh+ENwPIASABIAatIAWtQiCGhCAxhSIbQiCIp0EId60iPEIghiAbp0EId60iPYQ3A8ABIAEgITcD6AIgASAkNwPgAiArQiCGICOEISsgKEIghiA5hCEgIDpCIIYgHoQhGyAaQiCGICqEISogLUIghiAihCExIB1CIIYgKYQhKSA9QiCGIDeEISEgH0IghiA8hCEoICYgLIUiGkIgiKdBB3etIC4gMoUiHqdBB3etQiCGhCEuIB5CIIinQQd3rSAap0EHd61CIIaEISYgJSA4hSIaQiCIp0EHd60gHCA1hSIep0EHd61CIIaEISIgHkIgiKdBB3etIBqnQQd3rUIghoQhHSAnIDOFIhpCIIinQQd3rSAvIDCFIh6nQQd3rUIghoQhLyAeQiCIp0EHd60gGqdBB3etQiCGhCEnIAIgAyAEEK0VIAEpA6ACIh8gNIUiGkIgiKdBB3etIAEpA6gCIiQgNoUiI6dBB3etQiCGhCEeICNCIIinQQd3rSAap0EHd61CIIaEIRogFUEBayEVDAELCyAAKQOwAiEtIAApA6gCISMgASAINgI8IAEgBzYCOCABIAU2AjQgASAGNgIwIAEgCjYCLCABIAs2AiggASAMNgIkIAEgDTYCICABIA42AhwgASAPNgIYIAEgCTYCFCABIBA2AhAgASARNgIMIAEgEjYCCCABIBM2AgQgASAUNgIAIAEgHjcDeCABIBo3A3AgASAvNwNoIAEgJzcDYCABICI3A1ggASAdNwNQIAEgLjcDSCABICY3A0AgASAfNwO4ASABICQ3A7ABIAEgMzcDqAEgASAwNwOgASABICU3A5gBIAEgHDcDkAEgASAsNwOIASABIDI3A4ABIAEgITcD+AEgASAoNwPwASABIDE3A+gBIAEgKTcD4AEgASAbNwPYASABICo3A9ABIAEgKzcDyAEgASAgNwPAASABQYgCaiIGIBhBCGopAwA3AwAgASAYKQMANwOAAiABQZgCaiIKIBZBCGopAwA3AwAgASAWKQMANwOQAiABQagCaiAXQQhqKQMANwMAIBcpAwAhGiAAICNCBHwiHkIgiD4CrAIgACAePgKoAiABIC03A9gCIAEgLTcDyAIgASAtNwO4AiABIBo3A6ACIAEgI0IDfCIaPgLQAiABIBpCIIg+AtQCIAEgI0ICfCIaPgLAAiABIBpCIIg+AsQCIAEgI0IBfCIaPgKwAiABIBpCIIg+ArQCIAFBqANqIgIgASABQUBrIgMgAyABQYABaiIEEOwTIAFB4AJqIgMgAiAEIAFBwAFqIgQQoBAgAiADIAQgAUGAAmoQsRIgAyACIAFBoAJqIAMQsBJBACEFIAEoAqQDIgMgASgCoAMiAmsiBEEAIAMgBE8bIQggASgCiAMgAkEEdCIDIAEoApADIgRBBHRqaiELIAEoAvgCIAMgBCABKAKAA2oiBEEEdGpqIQwgASgCmAMgA2ohDSABKALwAiACIARqakEEdCICIAEoAuACaiEOIAEoAugCIAJqIQ9BACEHA0AgCARAIAFB6ANqIAUgDmoiAkEIaikCADcDACABQfgDaiAFIA9qIgNBCGopAgA3AwAgAUGIBGogBSAMaiIEQQhqKQIANwMAIAFBmARqIAUgC2oiCUEIaikCADcDACABQagEaiAFIA1qIhBBCGopAgA3AwAgASACKQIANwPgAyABIAMpAgA3A/ADIAEgBCkCADcDgAQgASAJKQIANwOQBCABIBApAgA3A6AEIAFCstqIy8eumZDrADcC6AIgAULl8MGL5o2ZkDM3AuACIAFBqANqIgQgAUHgA2og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GyICIAJBCE0bIgGtIglCIIinDQAgCaciCEH/////B0sNACADIAcEfyADIAc2AhwgAyAAKAIENgIUQQEFQQALNgIYIANBCGpBASAIIANBFGoQnA8gAygCCEEBRgRAIAMoAhAhAiADKAIMIQQMAQsgAygCDCEEIAAgATYCACAAIAQ2AgRBgYCAgHghBAsgBiACNgIEIAYgBDYCACADQSBqJAAgBSgCCCIAQYGAgIB4RwRAIAAgBSgCDEG8hN4AEPYbAAsgBUEQaiQACxQAIAAgASACIAMgBEHIi94AEKgmC0gBAX8jAEEQayICJAAgAkEIaiABENMVIAIgAigCCCACKAIMKAIYEQEAIAIoAgQhASAAIAIoAgA2AgAgACABNgIEIAJBEGokAAsUACAAIAEgAiADIARBuInfABCoJgtBAQF/IABBCnVBv4Q9aiIBQZx/bSAAQf8DcWogAUGQA21qIAGsQrULfkIEf6dqQbPIq60Ba0EHb0Hom98Aai0AAAtHAQF/IwBBEGsiAyQAIANBCGogACABQQFBBCACEKAHIAMoAggiAEGBgICAeEcEQCAAIAMoAgxBrKTfABD2GwALIANBEGokAAsQACAAIAEgAkH43t8AEKkmC1MBAn9BtOPgACECAkACQAJAQQEgASgCACIDQQhrIANBB00bQQFrDgICAQALIAFBBGohAUHw4+AAIQIMAQtB+OLgACECCyAAIAI2AgQgACABNgIAC0QBAn8jAEEQayIBJAACQCAAKAIAQQJGDQAgACgCLCICRQ0AIAEgAjYCDCABIAAoAjQ2AgggAUEIahDzIQsgAUEQaiQACxQAIAAgASACIAMgBEHwv+EAEKgmCxQAIAAgASACIAMgBEHMx+EAEKgmCxAAIAAgASACQcjR4QAQqSYLQgEBfyABKAIEIgIgASgCCE8Ef0EABSABIAJBAWo2AgQgASgCACgCACACEOodIQFBAQshAiAAIAE2AgQgACACNgIAC0gBAX8CQCABQeEAayIBQf8BcUEZSwRAQQAhAQwBCyABQQJ0QfwHcSICKAKA4WQhASACKAKY4GQhAgsgACACNgIEIAAgATYCAAsNACAAIAEgAkEnEPIlCw0AIAAgASACQToQ8iULDQAgACABIAJBFRDyJQsNACAAIAEgAkEPEPIlC1UBAn8gACgCEARAIABBEGoQghcL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ACAAIAE2AgQgAkEQaiQACzYBAX8jAEEQayICJAAgAkEIaiABEMgPIAIoAgwhASAAIAIoAgg2AgAgACABNgIEIAJBEGokAAs2AQF/IwBBEGsiAiQAIAJBCGogARCVDSACKAIMIQEgACACKAIINgIAIAAgATYCBCACQRBqJAALNgEBfyMAQRBrIgIkACACQQhqIAEQxAsgAigCDCEBIAAgAigCCDYCACAAIAE2AgQgAkEQaiQACzYBAX8jAEEQayICJAAgAkEIaiABELobIAIoAgwhASAAIAIoAgg2AgAgACABNgIEIAJBEGokAAs2AQF/IwBBEGsiAiQAIAJBCGogARD8DyACKAIMIQEgACACKAIINgIAIAAgATYCBCACQRBqJAALDgAgACABQbiyyAAQ3CYLNgEBfyMAQRBrIgIkACACQQhqIAEQiQwgAigCDCEBIAAgAigCCDYCACAAIAE2AgQgAkEQaiQACzYBAX8jAEEQayICJAAgAkEIaiABEJYNIAIoAgwhASAAIAIoAgg2AgAgACABNgIEIAJBEGokAAs2AAJAAkACQCAALQBUDgQBAgIAAgsgAC0AUEEDRgRAIABBKGoQthgLIABBFGohAAsgABDzIQsLNgEBfyMAQRBrIgIkACACQQhqIAEQohcgAigCDCEBIAAgAigCCDYCACAAIAE2AgQgAkEQaiQACzABAX8jAEEQayICJAAgAkEIaiAAQQxqENQQIAEgAigCCCACKAIMEPIUIAJBEGokAAswAQF/IwBBEGsiAiQAIAJBCGogAEEMahD7FSABIAIoAgggAigCDBDyFCACQRBqJAALLQEBfyAALQAAIgFBB0ZBzQAgAXZBAXFFckUEQCAAIAFBAnQoAoiQSmoQ8yELCzYBAX8jAEEQayICJAAgAkEIaiABEIsJIAIoAgwhASAAIAIoAgg2AgAgACABNgIEIAJBEGokAAscACAAIAFB9PvJAEEJQZH8yQBBDUGE/MkAEP0lCzYBAX8jAEEQayICJAAgAkEIaiABEPQVIAIoAgwhASAAIAIoAgg2AgAgACABNgIEIAJBEGokAAs2AQF/IwBBEGsiAiQAIAJBCGogARChCSACKAIMIQEgACACKAIINgIAIAAgATYCBCACQRBqJAALNgEBfyMAQRBrIgIkACACQQhqIAEQzBUgAigCDCEBIAAgAigCCDYCACAAIAE2AgQgAkEQaiQACxwAIAAgAUHI0coAQQVB4tHKAEEKQdjRygAQ/SULNgEBfyMAQRBrIgIkACACQQhqIAEQlhYgAigCDCEBIAAgAigCCDYCACAAIAE2AgQgAkEQaiQACzYBAX8jAEEQayICJAAgAkEIaiABEM4NIAIoAgwhASAAIAIoAgg2AgAgACABNgIEIAJBEGokAAscACAAIAFB3LHTAEEIQfyx0wBBEUHRstMAEP0lCxwAIAAgAUHcsdMAQQhB/LHTAEEYQfi00wAQ/SULNgEBfyMAQRBrIgIkACACQQhqIAEQ4xogAigCDCEBIAAgAigCCDYCACAAIAE2AgQgAkEQaiQACzYBAX8jAEEQayICJAAgAkEIaiABEMkUIAIoAgwhASAAIAIoAgg2AgAgACABNgIEIAJBEGokAAs2AQF/IwBBEGsiAiQAIAJBCGogARCXFCACKAIMIQEgACACKAIINgIAIAAgATYCBCACQRBqJAALNwEBfyAAKAIAIgBBDGoQzBMCQCAAQX9GDQAgACAAKAIEQQFrIgE2AgQgAQ0AIABBIEEEEJ8gCwsOACAAIAFB4P7UABDcJgs2AQF/IwBBEGsiAiQAIAJBCGogARDfDiACKAIMIQEgACACKAIINgIAIAAgATYCBCACQRBqJAALMQECfyMAQSBrIgEkACABQQhqIgIQnSUgAUIANwMYIAAgAiABQRhqEMwYIAFBIGokAAs1AQF/QQxBBBCEISIBRQRAQQRBDBDhIwALIAEgACkCADcCACABQQhqIABBCGooAgA2AgAgAQs2AQF/A0AgACgAACEDIAAgASgAADYAACABIAM2AAAgAEEEaiEAIAFBBGohASACQQFrIgINAAsLHAAgACABQaCw3gBBCUG9sN4AQQ1BsLDeABD9JQs2AQF/IwBBEGsiAiQAIAJBCGogARDQDyACKAIMIQEgACACKAIINgIAIAAgATYCBCACQRBqJAALHAAgACABQaS63gBBCUHBut4AQQ1BtLreABD9JQscACAAIAFB7MPeAEEJQYnE3gBBDUH8w94AEP0lCy0BAX8gAC0AACIBQQdGQc0AIAF2QQFxRXJFBEAgACABQQJ0KAL83l5qEPMhCwtFAQF/QRhBBBCEISICRQRAQQRBGBDhIwALIAIgATYCFCACIAA2AhAgAkKAgICAgICAgIB/NwIIIAJCgICAgMAANwIAIAILNgEBfyMAQRBrIgIkACACQQhqIAEQ+RUgAigCDCEBIAAgAigCCDYCACAAIAE2AgQgAkEQaiQACy0BAX8gAC0AACIBQQdGQc0AIAF2QQFxRXJFBEAgACABQQJ0KALc6V5qEPMhCws2AQF/IwBBEGsiAiQAIAJBCGogARDaIiACKAIMIQEgACACKAIINgIAIAAgATYCBCACQRBqJAALNgEBfyMAQRBrIgIkACACQQhqIAEQqSEgAigCDCEBIAAgAigCCDYCACAAIAE2AgQgAkEQaiQACzYBAX8jAEEQayICJAAgAkEIaiABEJMVIAIoAgwhASAAIAIoAgg2AgAgACABNgIEIAJBEGokAAs3AQF+IAApAgAhAUEUQQQQhCEiAEUEQEEEQRQQ4SMACyAAQgA3AgwgACABNwIEIABBATYCACAACzIBAX8jAEEQayICJAAgAkEIaiAAIAAoAggQvwQgASACKAIIIAIoAgwQ8hQgAkEQaiQACzYBAX8jAEEQayICJAAgAkEIaiABELQTIAIoAgwhASAAIAIoAgg2AgAgACABNgIEIAJBEGokAAs3AQJ/IAEoAhAiAiABKAIEIgNJBEAgACABKAIAIAJBA3RqKQIANwMADwsgAiADQaTQ4QAQjBAACzYBAX8jAEEQayICJAAgAkEIaiABEJkVIAIoAgwhASAAIAIoAgg2AgAgACABNgIEIAJBEGokAAszAQF/IwBBEGsiAiQAIAIgATYCDCAAIAJBDGoQlQ4gAUGEAU8EQCABEKEWCyACQRBqJAALEgAgACABIAIgA0H0xeQAELUmCxwAIAAgAUGU3eQAQQRBsd3kAEENQaTd5AAQ/SULOQEBfyMAQRBrIgUkACAFIAI2AgwgBSABNgIIIAAgBUEIakGokeYAIAVBDGpBqJHmACADIAQQuAYACxIAIAAgASACIANBuJHmABC1JgswACAAKAIAQQJHBEAgAEHYAGoQ7RkgAEHIAGoQlRwgAEEQahDzIQ8LIABBBGoQlRwLNAEBfyAAEKgNAkAgACgCECIBRQ0AIAEgASgCACIBQQFrNgIAIAFBAUcNACAAQRBqEOwOCwswAQJ/IAEoAgAiAyABKAIESQRAIAEgA0EBajYCAEEBIQILIAAgAzYCBCAAIAI2AgALNgACQAJAAkACQCAALQAUQQNrDgMAAQMCCyAAQRhqEIkcDwsgAEEYahD0FgsPCyAAQRhqEIkcCzoAAkACQAJAAkAgAC0AgAJBA2sOAwABAwILIABBiAJqEJweDwsgAEGEAmoQnB8LDwsgAEGIAmoQ/hcLOAEBfyABKAIIIgJBgICAEHFFBEAgAkGAgIAgcUUEQCAAIAEQtAcPCyAAIAEQuw4PCyAAIAEQug4LNAEBfyMAQSBrIgIkACACIAEpAwAgAkEMakEUEI8IIAAgAigCACACKAIEEJIPIAJBIGokAAs0AQF/IwBBIGsiAiQAIAIgASkDACACQQxqQRQQjwggACACKAIAIAIoAgQQlQ8gAkEgaiQAC9sHAg9/An4jAEEQayIPJAAgACgCCCABSQRAIA9BCGohECMAQUBqIgMkACADIAI2AgwgACgCDCEJIAMgA0EMajYCEAJ/AkAgCSABIAlqIgFNBEAgACgCBCIGIAZBAWoiB0EDdiICQQdsIAZBCEkbIgxBAXYgAUkEQCADQTBqIABBEGoiAkEIIAxBAWoiBSABIAEgBUkbEKcIIAMoAjghBSADKAI0IgYgAygCMCIERQ0DGiADIAMoAjw2AiwgAyAFNgIoIAMgBjYCJCADQoiAgICAATcCGCADIAI2AhQgAyAENgIgIARBCGohDCAAKAIAIgEpAwBCf4VCgIGChIiQoMCAf4MhEiADQSBqIQdBACECA0AgCQRAA0AgElAEQCACQQhqIQIgAUEIaiIBKQMAQn+FQoCBgoSIkKDAgH+DIRIMAQsLIAQgByADQRBqIAAgEnqnQQN2IAJqIgoQrBsiExC4DCILaiATp0EZdiINOgAAIAwgC0EIayAGcWogDToAACAEIAtBA3RrQQhrIAAoAgAgCkEDdGtBCGspAAA3AAAgCUEBayEJIBJCAX0gEoMhEgwBCwsgAyAAKAIMIgE2AiwgAyAFIAFrNgIoIAAgB0EEEN0WIAMoAiQiAEUNAiADQTBqIAMoAhggAygCHCAAQQFqEJ0NIAMoAiAgAygCOGsgAygCMCADKAI0EKweDAILIAIgB0EHcUEAR2ohASAAKAIAIgQhAgNAIAEEQCACIAIpAwAiEkJ/hUIHiEKBgoSIkKDAgAGDIBJC//79+/fv37//AIR8NwMAIAJBCGohAiABQQFrIQEMAQUCQCAHQQhPBEAgBCAHaiAEKQAANwAADAELIAdFDQAgBEEIaiAEIAf8CgAACyAEQQhqIQtBACEBA0ACQCAHIAEiAksEQCACIAIgB0lqIQEgAiAEaiIKLQAAQYABRw0CIAQgAkEDdGtBCGshDQNAIAIgBiADQRBqIAAgAhCsGyISpyIIcSIOayAAIBIQuAwiBSAOa3MgBnFBCEkNAiAEIAVqIg4tAAAgDiAIQRl2Igg6AAAgCyAFQQhrIAZxaiAIOgAAIAQgBUEDdGtBCGshCEH/AUYEQCAKQf8BOgAAIAsgAkEIayAGcWpB/wE6AAAgCCANKQAANwAADAQFIA0gCEECEN0WDAELAAsACyAAIAwgCWs2AggMBQsgCiAIQRl2Igo6AAAgCyACQQhrIAZxaiAKOgAADAALAAsACwALENQTIAMoAgQhBSADKAIADAELQYGAgIB4CyEAIBAgBTYCBCAQIAA2AgAgA0FAayQACyAPQRBqJAALLwICfwF9IwBBEGsiASQAIAFBBGoiAiAAEN4YIAEoAgQQ4Q4gAhCnHyABQRBqJAALOAEBfyABKAIIIgJBgICAEHFFBEAgAkGAgIAgcUUEQCAAIAEQtAwPCyAAIAEQig4PCyAAIAEQiQ4LDgAgACABQZjVwwAQ6CYLJwAgABDzISAAQRhqEJUcIABBJGoQlRwgAEEwahCVHCAAQQxqEPMhCzMBAX8gAC0AXUEDRgRAIABBMGoQ5hQgACgCQCIBBEAgACgCRCABKAIMEQIACyAAEPQWCwszAQF/AkAgAEUNACABKAIAIgIEQCAAIAIRAgALIAEoAgQiAkUNACAAIAIgASgCCBCfIAsLCQAgAEEEEPAlCz4AAkACQAJAAkAgAC0AWA4EAAMDAQMLIAAoAgBBjICAgHhGDQIMAQsgAEEoahCxGCAAQRxqIQALIAAQlhwLC0AAAkACQAJAAkACQCAALQDoBA4FAwQEAAEECyAAQfAEahDRDgwBCyAAQewEahCDFwsgAEG0AmohAAsgABD9EwsLOAEBfyABKAIIIgJBgICAEHFFBEAgAkGAgIAgcUUEQCAAIAEQ4wYPCyAAIAEQ8w4PCyAAIAEQ8g4LFQAgACABQezsxABBEkH87MQAENQlCzMAIAAgATYCGCAAIAIpAgA3AgAgAEEQaiACQRBqKQIANwIAIABBCGogAkEIaikCADcCAAtEAgF/AW9BASECAkAgASgCABC0JUEBRwRAQQAhAgwBCyABKAIAJQEQlAEhAxCNCyIBIAMmAQsgACABNgIEIAAgAjYCAAsvAQF/IwBBEGsiAiQAIAAEQCACIAE2AgwgAiAANgIIIAJBCGoQ/hULIAJBEGokAAsOACAAIAFBwKzFABDoJgsOACAAIAFB1K/FABDJJgsOACAAIAFBpLDFABDJJgsVACAAIAFBwOTFAEEfQdDkxQAQ1CULOAEBfyABKAIIIgJBgICAEHFFBEAgAkGAgIAgcUUEQCAAIAEQnwcPCyAAIAEQ8w4PCyAAIAEQ8g4LLQEBfyAAKAIIIgEEQCAAKAIEIQADQCAAEPMhIABBDGohACABQQFrIgENAAsLCxUAIAAgAUGomcoAQRJBxJbKABDUJQsVACAAIAFBhLHKAEETQY26ygAQ1CULDwBByOzKAEHA7MoAEL8mCy8BAX8jAEEQayICJAAgAQRAIAJBCGogABD7DyAAIAEgAigCDBD8AwsgAkEQaiQACw8AQczZ0wBBtNnTABC/JgsRACAAQdzZ0wBBtNnTABCVJgsPAEHs2dMAQbTZ0wAQvyYLNgEBfwJAIAAoAgwNACAAKAIsDQAgACgCTA0AIAAoAmwNACAAKAKMAQ0AIAAoAqwBRSEBCyABC6gLAQR/IwBBEGsiAyQAIANBCGohBQJAIAAoAgAiBCgCAARAIAQoAgghAiAEKAIEIQAMAQtBBiECQYTS1AAhAAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgBC0ABEEBaw5QAAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QC0EOIQJBitLUACEADE8LQQ8hAkGY0tQAIQAMTgtBDyECQafS1AAhAAxNC0ENIQJBttLUACEADEwLQSAhAkHD0tQAIQAMSwtBHCECQePS1AAhAAxKC0EcIQJB/9LUACEADEkLQRshAkGb09QAIQAMSAtBHSECQbbT1AAhAAxHC0EWIQJB09PUACEADEYLQR4hAkHp09QAIQAMRQtBHSECQYfU1AAhAAxEC0EDIQJBpNTUACEADEMLQQUhAkGn1NQAIQAMQgtBByECQazU1AAhAAxBC0ENIQJBs9TUACEADEALQQ0hAkHA1NQAIQAMPwtBDCECQc3U1AAhAAw+C0ERIQJB2dTUACEADD0LQQohAkHq1NQAIQAMPAtBEyECQfTU1AAhAAw7C0EQIQJBh9XUACEADDoLQRAhAkGX1dQAIQAMOQtBDiECQafV1AAhAAw4C0EQIQJBtdXUACEADDcLQQ0hAkHF1dQAIQAMNgtBFyECQdLV1AAhAAw1C0EjIQJB6dXUACEADDQLQQwhAkGM1tQAIQAMMwtBmNbUACEADDILQQMhAkGe1tQAIQAMMQtBBCECQaHW1AAhAAwwC0EEIQJBpdbUACEADC8LQanW1AAhAAwuC0EHIQJBr9bUACEADC0LQQkhAkG21tQAIQAMLAtBBCECQb/W1AAhAAwrC0EEIQJBw9bUACEADCoLQQghAkHH1tQAIQAMKQtBESECQc/W1AAhAAwoC0ENIQJB4NbUACEADCcLQQghAkHt1tQAIQAMJgtBEyECQfXW1AAhAAwlC0ENIQJBiNfUACEADCQLQQQhAkGV19QAIQAMIwtBCCECQZnX1AAhAAwiC0EMIQJBodfUACEADCELQa3X1AAhAAwgC0Gz19QAIQAMHwtBEiECQbnX1AAhAAweC0ETIQJBy9fUACEADB0LQQ8hAkHe19QAIQAMHAtBGyECQe3X1AAhAAwbC0EFIQJBiNjUACEADBoLQQchAkGN2NQAIQAMGQtBDyECQZTY1AAhAAwYC0EHIQJBo9jUACEADBcLQQshAkGq2NQAIQAMFgtBFCECQbXY1AAhAAwVC0EYIQJBydjUACEADBQLQREhAkHh2NQAIQAMEwtBFiECQfLY1AAhAAwSC0EVIQJBiNnUACEADBELQZ3Z1AAhAAwQC0EKIQJBo9nUACEADA8LQRkhAkGt2dQAIQAMDgtBAiECQcbZ1AAhAAwNC0EHIQJByNnUACEADAwLQREhAkHP2dQAIQAMCwtBCiECQeDZ1AAhAAwKC0EHIQJB6tnUACEADAkLQRkhAkHx2dQAIQAMCAtBBCECQYra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BSADQRBqJAALLAEBfyMAQRBrIgMkACADIAI3AwggACABIANBCGpB0MnhABDrBSADQRBqJAALLAEBfyMAQRBrIgMkACADIAI3AwggACABIANBCGpB4MnhABDrBSADQRBqJAALLAEBfyMAQRBrIgMkACADIAI6AA8gACABIANBD2pB8MnhABDrBSADQRBqJAALUQEBfyMAQRBrIgMkACADIAI2AgwgAyABNgIIIAMgADYCBCMAQRBrIgAkACAAIANBBGoiASkCADcCCCAAQQhqQczE5AAgASgCCEEBQQAQugoAC/wBAgJ/AX4jAEEQayICJAAgAkEBOwEMIAIgATYCCCACIAA2AgQjAEEQayIBJAAgAkEEaiIAKQIAIQQgASAANgIMIAEgBDcCBCMAQRBrIgAkACABQQRqIgEoAgAiAigCDCEDAkACQAJAAkAgAigCBA4CAAECCyADDQFBASECQQAhAwwCCyADDQAgAigCACICKAIEIQMgAigCACECDAELIABBgICAgHg2AgAgACABNgIMIABBnMXkACABKAIEIAEoAggiAC0ACCAALQAJELoKAAsgACADNgIEIAAgAjYCACAAQYDF5AAgASgCBCABKAIIIgAtAAggAC0ACRC6CgALKgEBfyAAEKAgIAAoAgAiASABKAIAIgFBAWs2AgAgAUEBRgRAIAAQ5AILCyoBAX8gABCnICAAKAIAIgEgASgCACIBQQFrNgIAIAFBAUYEQCAAEPcQCwsqAQF/IAAQsAIgACgCACIBIAEoAgAiAUEBazYCACABQQFGBEAgABCeDwsLKwAgAEHwBGoQlRwgAEH8BGoQlRwgAEGQA2oQwRcgAEHwAmoQjBMgABCcDQssACAAQYACahCVHCAAQYwCahCVHCAALQD7AUUEQCAAEJ4fCyAAQZgCahCVHAstAQF/IAEoAgAiARDtCCICBEAgAEGAgICAeDYCACAAIAI2AgQPCyAAIAEQuRMLKAAgASgCAEUEQCABQX82AgAgACABNgIEIAAgAUEEajYCAA8LENojAAslACAALQA4QQNGBEAgAEEQahD+FSAAQSxqEJUcIABBIGoQ7iALCyYBAX8gACgCCCIDIAFNBEAgASADIAIQjBAACyAAKAIEIAFBAnRqCyoAAkAgACgCAEGAgICAeEcEQCAAQQxqEJcgDAELIABBBGohAAsg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AEHoAGohAAsgABCOEAsLJgAgACgCAEGAgICAeEcEQCAAQRhqENUaIAAQ8yEgAEEMahDzIQsLKwACQAJAAkAgAC0AVA4EAQICAAILIABBQGsQ/hUgAEEgaiEACyAAELALCwsuAAJAAkACQCAALQDcAQ4EAQICAAILIABB0AFqEPkaIABB6ABqIQALIAAQ9xMLCyUBAX8gACgCACIBIAEoAgAiAUEBazYCACABQQFGBEAgABDvFQsLJQEBfyAAKAIAIgEgASgCACIBQQFrNgIAIAFBAUYEQCAAELoSCwsnAAJAAkACQCAALQDMAg4EAAICAQILIABBwAJqEPMhDwsgABDjDQsLIQACQCAABEAgACgCAA0BIAAgATYCFA8LENkjAAsQ2iMACyEAAkAgAARAIAAoAgANASAAIAE5AwgPCxDZIwALENojAAshAAJAIAAEQCAAKAIADQEgACABNgIQDwsQ2SMACxDaIwALIQACQCAABEAgACgCAA0BIAAgATYCBA8LENkjAAsQ2iMACyEAAkAgAARAIAAoAgANASAAIAE2AhgPCxDZIwALENojAAshAAJAIAAEQCAAKAIADQEgACABNgIoDwsQ2SMACxDaIwALIQACQCAABEAgACgCAA0BIAAgATYCIA8LENkjAAsQ2iMACyEAAkAgAARAIAAoAgANASAAIAE2AhwPCxDZIwALENojAAshAAJAIAAEQCAAKAIADQEgACABNgIIDwsQ2SMACxDaIwALIQACQCAABEAgACgCAA0BIAAgATYCJA8LENkjAAsQ2iMACyEAAkAgAARAIAAoAgANASAAIAE2AgwPCxDZIwALENojAAshAAJAIAAEQCAAKAIADQEgACABOgARDwsQ2SMACxDaIwALIQACQCAABEAgACgCAA0BIAAgAToAEA8LENkjAAsQ2iMACyQAIAAgAjYCCCAAIAE2AhAgAEEANgIAIAAgAiADQQN0ajYCDAskAQF/IAAoAgAgACgCCCICayABSQRAIAAgAiABQQFBARC0FAsLKgEBf0EBIQICQCABQeAAEIsfDQAgACABEKcFDQAgAUHgABCLHyECCyACCy4AAkACQAJAIAAtANwBDgQBAgIAAgsgAEHQAWoQ3xQgAEHoAGohAAsgABDeDAsLIwEBfyAAKAIAIgAgACgCACIBQQFqNgIAIAFBAEgEQAAL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BCAEQdAHajYChAUgBCAEQbAHajYC0AcgBEH0B2oiByABQRxqIARBlAhqEP0dIARBqAhqIARB8AdqKAIANgIAIAQgBCkC6Ac3A6AIIAMgBSAGIARBoAhqIAcQ9wkMBAtBrILUAEEiQdCC1AAQuREAC0GsgtQAQSJB0ILUABC5EQALQayC1ABBIkGcg9QAELkRAAtBrILUAEEiQZyD1AAQuREACyAEQbAHahDzIQsgAkGgAmoiAiAORw0ACwsgBEGwCGokACAAIAtBgAL8CgAACxoAIAAoAgAlASABBH8gASgCAAVBAAslARA/CxoAIAAoAgAlASABBH8gASgCAAVBAAslARBACxoAIAAoAgAlASABBH8gASgCAAVBAAslARBICxoAIAAoAgAlASABBH8gASgCAAVBAAslARBJCxoAIAAoAgAlASABBH8gASgCAAVBAAslARBLCxoAIAAoAgAlASABBH8gASgCAAVBAAslARBNCyoAIABBpJ/VADYCBCAAIAEoAgAiAEEEakEAIAAoAgBBgICAgHhGGzYCAAsgAQF/IAAoAgAgACgCCCICayABSQRAIAAgAiABEMIUCwskAQF/IAAoAgAgACgCCCICayABSQRAIAAgAiABQQFBARDDFAsLJAEBfyMAQSBrIgMkACADIAIQywIgACABIAMQjgQgA0EgaiQACyQBAX8jAEEgayIDJAAgAyACEMsCIAAgASADEPADIANBIGokAAsnACAAQQE2AgQgACABKAIAIgEoAgQgASgCAGsiATYCCCAAIAE2AgALJAEBfyAAKAIAIAAoAggiAmsgAUkEQCAAIAIgAUEBQQEQxRQLCyQBAX8gACgCACAAKAIIIgJrIAFJBEAgACACIAFBAUEBEMwUCwtlAQF/IwBBEGsiAiQAIAIgATYCDCACIAA2AggjAEEgayIAJAAgAEEBNgIEIABBoLXkADYCACAAQgE3AgwgACACQQhqrUKAgICAwP4AhDcDGCAAIABBGGo2AgggAEGQteQAEPcYAAuJAgEDfyMAQRBrIgMkACMAQTBrIgEkAAJAAkACQCAABEAgACgCACICQX9GDQEgACACQQFqNgIAAn8gACgCBEGAgICAeEYEQCAAIAI2AgBBACEAQQAMAQsgAUEUaiAAQQRqENYPIAAoAgAiAkUNAyAAIAJBAWs2AgBBACEAQQAgASgCFEGAgICAeEYNABogAUEoaiABQRxqKAIANgIAIAEgASkCFDcDICABQQhqIAFBIGpB3JnEABCIECABKAIIIQAgASgCDAshAiABIAAgAhCyHyADIAEpAwA3AgAgAUEwaiQADAMLENkjAAsQ2iMAC0HU58MAELQXAAsgAygCACADKAIEIANBEGokAAvwAQEGfyMAQRBrIgMkACMAQRBrIgEkACABEM4gIgU2AgggACgCACIEIAAoAgQiAigCDBECACACKAIEIgYEQCAEIAYgAigCCBCfIAsgAUGAATYCDCMAQRBrIgIkACABQQhqKAIAJQEgAUEMaigCACUBEDggAkEIahDsGSACKAIMIQQgASACKAIIQQFxNgIAIAEgBDYCBCACQRBqJAAgASgCBCECIAEoAgAhBCAFQYQBTwRAIAUQoRYLIABBCEEEEJ8gIAMgBEEBcSIANgIEIAMgAkEAIAAbNgIAIAFBEGokACADKAIAIAMoAgQgA0EQaiQACyQBAX8gABDnGCAAQQFqIQEgAC0AAEUEQCABEKMYDwsgARDBHwsjAQF/IABBBGoQ5hQgACgCFCIBBEAgACgCGCABKAIMEQIACwsoAAJAAkACQCAALQAoDgQAAgIBAgsgAEEYahCVHA8LIABBEGoQ/hULC5sBAQN/IAAoAgAEQCMAQRBrIgMkACADIAA2AgwgACgCDCAAKAIEIgFrQQxuIQIDQCACBEAgARCwFiABEPUgIAJBAWshAiABQQxqIQEMAQsLIwBBEGsiASQAIAEgA0EMaigCACICKAIANgIMIAEgAigCCDYCCCABQQhqEPYgIAFBEGokACADQRBqJAALIABBEGoQ9x4gAEEgahD3HgsmAAJAAkACQCAALQDUBw4EAQICAAILIAAQwBULIABByAdqEPMhCwskAQF/IwBB4ANrIgIkACACIAEQkgMgACACEJELIAJB4ANqJAALHwAgACgCAEGAgICAeEcEQCAAEPMhDwsgAEEEahChFQsZACAAKAIAIAEoAgBGIAAtAAQgAS0ABEZxCyUAAkACQAJAIAAtAGwOBAACAgECCyAAEPMhDwsgAEEUahDGFgsLJAEBfyAAKAIUIgFBf0YEQEHUnckAEK4XAAsgACABQQFqNgIUCxgAIAAoAgBBAWtBAU0EQCAAQQhqEPMhCwsjACAAQQA2AhAgACAB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IwBBEGsiAyQAIANBCGogAkEIaiIEEPYSAkACQCACQThqIgUgAygCCEEBcQR/IAQoAgwiBkF/Rg0BIAMoAgwhByAEIAZBAWo2AgwgAyAHELoVIAMoAgAgBSADKAIENgIEQQFqBUEACzYCACADQRBqJAAMAQtBoMLDABCuFwALIAIoAjgiA0ECRgRAIAAgAigCPDYCBCAAQQA2AgAgAkEYahDLEwwCCyADQQFxBEAgAkEYaiACKAI8EKEFGgwBCwsgACACKQMYNwMAIABBGGogAkEwaikDADcDACAAQRBqIAJBKGopAwA3AwAgAEEIaiACQSBqKQMANwMACyACQUBrJAAMAQsgAUEYaiABQQxqEP8HIAEoAhghAgJAAkACQCABLQAcIgNBAmsOAgIAAQsgAEEANgIAIAAgAjYCBAwCCyABIAM6ABQgASACNgIQQQAgARDbGyECIAFBGGoiAxDwIyADIAIgASkDGCABKQMgEJISAkADQCABQThqIQIjAEEQayIDJAAgA0EIaiABQRBqENcVAkACQCADKAIIIgVBAkcEQCADKAIMIQQgBUEBcUUNASACQQI2AgAgAiAENgIEDAILIAJBADYCAAwBCyADIAQQuhUgAygCBCEEIAMoAgBBAXFFBEAgAiAENgIEIAJBATYCAAwBCyACQQI2AgAgAiAENgIECyADQRBqJAAgASgCOCICQQJGBEAgACABKAI8NgIEIABBADYCACABQRhqEMsTDAILIAJBAXEEQCABQRhqIAEoAjwQoQUaDAELCyAAIAEpAxg3AwAgAEEYaiABQTBqKQMANwMAIABBEGogAUEoaikDADcDACAAQQhqIAFBIGopAwA3AwALIAFBEGoQ7R0MAQsjAEEQayICJAAgAUEMaiACQQ9qQZTrwgAQrAQhAyAAQQA2AgAgACADNgIEIAJBEGokAAsgAUEMahDtHSABQUBrJAALmgEBAn8gASgCACABQQA2AgAgASgCBBCuGyECIwBBEGsiASQAIAEgAjYCDAJAQQFBAiACELYlIgJBAUYbQQAgAhsiAkECRwRAIABBADoAACAAIAI6AAEMAQsjAEEQayICJAAgAUEMaiACQQ9qQYTqwgAQrAQhAyAAQQE6AAAgACADNgIEIAJBEGokAAsgAUEMahDtHSABQRBqJAALGwAgACgCACgCACABKAIAIAJB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QQNGBEAgAEEQahD+FQsLFQAgAC0ASEEDRgRAIABBDGoQgRwLCxUAIAAtAAhBBEYEQCAAQRBqEM0ZCwsVACAALQBAQQNGBEAgAEEEahCBHAsLFgAgAC0AgANBA0YEQCAAQQhqENYTCwsXACAAQQRqEPAdIABBCGoQ8B0gABD6GAsfACAAQQhqQay1wgApAgA3AgAgAEGktcIAKQIANwIACx8AIABBCGpB2M3CACkCADcCACAAQdDNwgApAgA3AgALFQAgAC0AGEEDRgRAIABBEGoQ/hULCx8AIABBCGpB9NrCACkCADcCACAAQezawgApAgA3AgALFQAgACgCAEEBRgRAIABBBGoQ8yELCx8AIABBCGpBgPnCACkCADcCACAAQfj4wgApAgA3AgALFQAgAC0APUEDRgRAIABBDGoQrxoLCx8AIABBCGpBrLfDACkCADcCACAAQaS3wwApAgA3AgALFgAgACgCAEGAgICAeEcEQCAAEPMhCwsSACAAKAIAQQBOBEAgABDzIQsLHwAgAEEIakG8usQAKQIANwIAIABBtLrEACkCADcCAAsfACAAQQhqQcy6xAApAgA3AgAgAEHEusQAKQIANwIACx8AIABBCGpB3LrEACkCADcCACAAQdS6xAApAgA3AgALHwAgAEEIakHsusQAKQIANwIAIABB5LrEACkCADcCAAsfACAAQQhqQfy6xAApAgA3AgAgAEH0usQAKQIANwIACx8AIABBCGpBjLvEACkCADcCACAAQYS7xAApAgA3AgALHwAgAEEIakGcu8QAKQIANwIAIABBlLvEACkCADcCAAsfACAAQQhqQay7xAApAgA3AgAgAEGku8QAKQIANwIACx8AIABBCGpBvLvEACkCADcCACAAQbS7xAApAgA3AgALHwAgAEEIakHMu8QAKQIANwIAIABBxLvEACkCADcCAAsdACABIAAtAABBAnQiACgCtOxEIAAoAozsRBDoHgsfACAAQQhqQcj7xAApAgA3AgAgAEHA+8QAKQIANwIACxgAIAAgAkH/AXG4EOweNgIEIABBADYCAAsZACAAIAJB//8DcbgQ7B42AgQgAEEANgIACxoAIABBADYCACAAQYEBQYABIAEtAAAbNgIECx8AIABBCGpBhIjFACkCADcCACAAQfyHxQApAgA3AgALHwAgAEEIakGUiMUAKQIANwIAIABBjIjFACkCADcCAAsaACABKAIAEIwgIQEgAEEONgIAIAAgATYCBAsfACAAQQhqQaiyxQApAgA3AgAgAEGgssUAKQIANwIACxYAIAAoAgBBgICAgHhHBEAgABD3IAsLHwAgAEEIakHkxcUAKQIANwIAIABB3MXFACkCADcCAAsfACAAQQhqQfTcxQApAgA3AgAgAEHs3MUAKQIANwIACxUAIAAoAgAiABDzISAAQRBBBBCfIAsfACAAQQhqQfDtxQApAgA3AgAgAEHo7cUAKQIANwIACx8AIABBCGpBgO7FACkCADcCACAAQfjtxQApAgA3AgALHwAgAEEIakGQ7sUAKQIANwIAIABBiO7FACkCADcCAAsfACAAQQhqQaDuxQApAgA3AgAgAEGY7sUAKQIANwIACx8AIABBCGpBsO7FACkCADcCACAAQajuxQApAgA3AgALHwAgAEEIakHA7sUAKQIANwIAIABBuO7FACkCADcCAAsfACAAQQhqQdDuxQApAgA3AgAgAEHI7sUAKQIANwIACx8AIABBCGpB4O7FACkCADcCACAAQdjuxQApAgA3AgALHwAgAEEIakHw7sUAKQIANwIAIABB6O7FACkCADcCAAsfACAAQQhqQYDvxQApAgA3AgAgAEH47sUAKQIANwIACx8AIABBCGpBkO/FACkCADcCACAAQYjvxQApAgA3AgALHwAgAEEIakGg78UAKQIANwIAIABBmO/FACkCADcCAAsfACAAQQhqQbDvxQApAgA3AgAgAEGo78UAKQIANwIACx0AIAEgAC0AAEECdCIAKAKcokYgACgC9KFGEOgeCx0AIAEgAC0AAEECdCIAKALUokYgACgCxKJGEOgeCx8AIABBCGpBkLnGACkCADcCACAAQYi5xgApAgA3AgALGQEBfyAALQAIIQEgAEEBOgAIQQAgACABGwsfACAAQQhqQajSxgApAgA3AgAgAEGg0sYAKQIANwIACx8AIABBCGpB/N7GACkCADcCACAAQfTexgApAgA3AgALGQEBfyAALQBoIQEgAEEBOgBoQQAgACABGwsfACAAQQhqQdzkxgApAgA3AgAgAEHU5MYAKQIANwIACx8AIABBCGpB7OTGACkCADcCACAAQeTkxgApAgA3AgALHwAgAEEIakH85MYAKQIANwIAIABB9OTGACkCADcCAAsfACAAQQhqQYzlxgApAgA3AgAgAEGE5cYAKQIANwIACx8AIABBCGpBjIDHACkCADcCACAAQYSAxwApAgA3AgALGwAgACgCAEGCgICAeE4EQCAAEI8XIAAQ9iALCx8AIABBCGpB6IbHACkCADcCACAAQeCGxwApAgA3AgALHwAgAEEIakHcuMcAKQIANwIAIABB1LjHACkCADcCAAsfACAAQQhqQajNxwApAgA3AgAgAEGgzccAKQIANwIACx8AIABBCGpBuM3HACkCADcCACAAQbDNxwApAgA3AgALHwAgAEEIakHIzccAKQIANwIAIABBwM3HACkCADcCAAsdACABIAAtAABBAnQiACgC1NVHIAAoAqzVRxDoHgsZACABIAIQnhEhASAAQQE2AgAgACABNgIECxkAIAEgAhCeESEBIABBAToAACAAIAE2AgQLHwAgAEEIakHwg8gAKQIANwIAIABB6IPIACkCADcCAAsfACAAQQhqQYCEyAApAgA3AgAgAEH4g8gAKQIANwIACx8AIABBCGpB2I3IACkCADcCACAAQdCNyAApAgA3AgALHwAgAEEIakHojcgAKQIANwIAIABB4I3IACkCADcCAAsfACAAQQhqQfiNyAApAgA3AgAgAEHwjcgAKQIANwIACx8AIABBCGpBiI7IACkCADcCACAAQYCOyAApAgA3AgALHwAgAEEIakGYjsgAKQIANwIAIABBkI7IACkCADcCAAsfACAAQQhqQaiOyAApAgA3AgAgAEGgjsgAKQIANwIACx8AIABBCGpBuI7IACkCADcCACAAQbCOyAApAgA3AgALHwAgAEEIakGYtMgAKQIANwIAIABBkLTIACkCADcCAAsfACAAQQhqQai0yAApAgA3AgAgAEGgtMgAKQIANwIACx8AIABBCGpBuLTIACkCADcCACAAQbC0yAApAgA3AgALHwAgAEEIakHItMgAKQIANwIAIABBwLTIACkCADcCAAsfACAAQQhqQdi0yAApAgA3AgAgAEHQtMgAKQIANwIACx8AIABBCGpB6LTIACkCADcCACAAQeC0yAApAgA3AgALHwAgAEEIakH4tMgAKQIANwIAIABB8LTIACkCADcCAAsfACAAQQhqQaD7yAApAgA3AgAgAEGY+8gAKQIANwIACx8AIABBCGpBsPvIACkCADcCACAAQaj7yAApAgA3AgALHwAgAEEIakHA+8gAKQIANwIAIABBuPvIACkCADcCAAsfACAAQQhqQdD7yAApAgA3AgAgAEHI+8gAKQIANwIACx8AIABBCGpB4PvIACkCADcCACAAQdj7yAApAgA3AgALHwAgAEEIakGElskAKQIANwIAIABB/JXJACkCADcCAAsdACABIAIQnhEhASAAQYCAgIB4NgIAIAAgATYCBAsfACAAQQhqQbiyyQApAgA3AgAgAEGwsskAKQIANwIACx8AIABBCGpBgLPJACkCADcCACAAQfiyyQApAgA3AgALHwAgAEEIakGQs8kAKQIANwIAIABBiLPJACkCADcCAAsfACAAQQhqQaCzyQApAgA3AgAgAEGYs8kAKQIANwIACx8AIABBCGpBsLPJACkCADcCACAAQaizyQApAgA3AgALHwAgAEEIakHAs8kAKQIANwIAIABBuLPJACkCADcCAAsfACAAQQhqQdCzyQApAgA3AgAgAEHIs8kAKQIANwIACx8AIABBCGpB4LPJACkCADcCACAAQdizyQApAgA3AgALHwAgAEEIakHws8kAKQIANwIAIABB6LPJACkCADcCAAsdACABIAAtAABBAnQiACgCsNhJIAAoApTYSRDoHgsdACABIAAtAABBAnQiACgC9NhJIAAoAszYSRDoHgsfACAAQQhqQYzlyQApAgA3AgAgAEGE5ckAKQIANwIACxUAIAAtAABBCk8EQCAAQQhqEP4VCwsVACAAKAIAQQNGBEAgAEEIahD+FQsLHwAgAEEIakG06skAKQIANwIAIABBrOrJACkCADcCAAsfACAAQQhqQcTqyQApAgA3AgAgAEG86skAKQIANwIACx8AIABBCGpB1OrJACkCADcCACAAQczqyQApAgA3AgALHwAgAEEIakHk6skAKQIANwIAIABB3OrJACkCADcCAAsfACAAQQhqQfTqyQApAgA3AgAgAEHs6skAKQIANwIACx8AIABBCGpBhOvJACkCADcCACAAQfzqyQApAgA3AgALHwAgAEEIakGU68kAKQIANwIAIABBjOvJACkCADcCAAsdACABIAAtAABBAnQiACgCnJZKIAAoAoSWShDoHgsfACAAQQhqQaSpygApAgA3AgAgAEGcqcoAKQIANwIACx8AIABBCGpBnKrKACkCADcCACAAQZSqygApAgA3AgALHwAgAEEIakGsqsoAKQIANwIAIABBpKrKACkCADcCAAsfACAAQQhqQbyqygApAgA3AgAgAEG0qsoAKQIANwIACx8AIABBCGpBzKrKACkCADcCACAAQcSqygApAgA3AgALHwAgAEEIakHcqsoAKQIANwIAIABB1KrKACkCADcCAAsfACAAQQhqQeyqygApAgA3AgAgAEHkqsoAKQIANwIACx8AIABBCGpB/KrKACkCADcCACAAQfSqygApAgA3AgALHQAgASAALQAAQQJ0IgAoAuS8SiAAKAK8vEoQ6B4LHwAgAEEIakGsvsoAKQIANwIAIABBpL7KACkCADcCAAsfACAAQQhqQYDOygApAgA3AgAgAEH4zcoAKQIANwIACx8AIABBCGpBkM7KACkCADcCACAAQYjOygApAgA3AgALHwAgAEEIakGgzsoAKQIANwIAIABBmM7KACkCADcCAAsfACAAQQhqQZih0wApAgA3AgAgAEGQodMAKQIANwIACx8AIABBCGpBhKvTACkCADcCACAAQfyq0wApAgA3AgALHwAgAEEIakHortMAKQIANwIAIABB4K7TACkCADcCAAsfACAAQQhqQfiu0wApAgA3AgAgAEHwrtMAKQIANwIACx8AIABBCGpBiK/TACkCADcCACAAQYCv0wApAgA3AgALHwAgAEEIakGYr9MAKQIANwIAIABBkK/TACkCADcCAAsgACAAKAIAQQA6AAAgACgCBCgCAEKBgICAwAA3AgBBAQsfACAAQQhqQcTq0wApAgA3AgAgAEG86tMAKQIANwIACx8AIABBCGpBvPTTACkCADcCACAAQbT00wApAgA3AgALHwAgAEEIakHA/NMAKQIANwIAIABBuPzTACkCADcCAAsfACAAQQhqQfCD1AApAgA3AgAgAEHog9QAKQIANwIACx8AIABBCGpBmI7UACkCADcCACAAQZCO1AApAgA3AgALHwAgAEEIakGojtQAKQIANwIAIABBoI7UACkCADcCAAsfACAAQQhqQbiO1AApAgA3AgAgAEGwjtQAKQIANwIACx8AIABBCGpByI7UACkCADcCACAAQcCO1AApAgA3AgALHwAgAEEIakHYjtQAKQIANwIAIABB0I7UACkCADcCAAsfACAAQQhqQfCh1AApAgA3AgAgAEHoodQAKQIANwIACx8AIABBCGpBgKLUACkCADcCACAAQfih1AApAgA3AgALHwAgAEEIakGQotQAKQIANwIAIABBiKLUACkCADcCAAsdACABIAAtAABBAnQiACgC3KVUIAAoArSlVBDoHgsfACAAQQhqQbSm1AApAgA3AgAgAEGsptQAKQIANwIACx8AIABBCGpB0K/UACkCADcCACAAQciv1AApAgA3AgALHwAgAEEIakHssNQAKQIANwIAIABB5LDUACkCADcCAAsfACAAQQhqQfyw1AApAgA3AgAgAEH0sNQAKQIANwIACx8AIABBCGpBjLHUACkCADcCACAAQYSx1AApAgA3AgALHwAgAEEIakGcsdQAKQIANwIAIABBlLHUACkCADcCAAsdACAALQAAQQJ0IgAoAvTfVCAAKALI31QgARDjIwsfACAAQQhqQdjh1AApAgA3AgAgAEHQ4dQAKQIANwIACx8AIABBCGpB6OHUACkCADcCACAAQeDh1AApAgA3AgALHwAgAEEIakH44dQAKQIANwIAIABB8OHUACkCADcCAAsfACAAQQhqQYji1AApAgA3AgAgAEGA4tQAKQIANwIACx8AIABBCGpBmOLUACkCADcCACAAQZDi1AApAgA3AgALHwAgAEEIakGo4tQAKQIANwIAIABBoOLUACkCADcCAAsfACAAQQhqQbji1AApAgA3AgAgAEGw4tQAKQIANwIACxkAIABBATYCACAAIAEoAgQgASgCAGs2AgQLHwAgAEEIakH4mdUAKQIANwIAIABB8JnVACkCADcCAAsfACAAQQhqQYia1QApAgA3AgAgAEGAmtUAKQIANwIACx8AIABBCGpBmJrVACkCADcCACAAQZCa1QApAgA3AgALHwAgAEEIakHMwtUAKQIANwIAIABBxMLVACkCADcCAAsaACAAQQA2AgggAEIBNwIAIAAgASkCADcCEAsfACAAQQhqQdS93gApAgA3AgAgAEHMvd4AKQIANwIACx8AIABBCGpB5L3eACkCADcCACAAQdy93gApAgA3AgALHwAgAEEIakH0vd4AKQIANwIAIABB7L3eACkCADcCAAsfACAAQQhqQYS+3gApAgA3AgAgAEH8vd4AKQIANwIACx8AIABBCGpBlL7eACkCADcCACAAQYy+3gApAgA3AgALhwIBB38gACgCAEECTwRAIwBBIGsiASQAAkACQAJAIABBBGoiAy0AEEEBaw4CAgABCyABQQA2AhggAUEBNgIMIAFB9LzeADYCCCABQgQ3AhAgAUEIakH8vN4AEPcYAAsgAygCCCIEBEAgAygCBCECA0AgAigCCCIFBEAgAigCBEEgaiEAA0AgACgCAEGAgICAeEcEQCAAEPMhCwJAIABBEGsoAgAiB0ECRg0AIABBDGshBiAHRQRAIAYQ8yEMAQsgBkECQQIQrg4LIABBLGohACAFQQFrIgUNAAsLIAJBBEEsEK4OIAJBDGohAiAEQQFrIgQNAAsLIANBBEEMEK4OCyABQSBqJAALCx8AIABBCGpByMneACkCADcCACAAQcDJ3gApAgA3AgALHwAgAEEIakHYyd4AKQIANwIAIABB0MneACkCADcCAAsdACABIAAtAABBAnQiACgC7M1eIAAoAuDNXhDoHgsdACABIAAtAABBAnQiACgC8NJeIAAoAtjSXhDoHgsfACAAQQhqQezV3gApAgA3AgAgAEHk1d4AKQIANwIACx8AIABBCGpB/NXeACkCADcCACAAQfTV3gApAgA3AgALHwAgAEEIakGM1t4AKQIANwIAIABBhNbeACkCADcCAAsfACAAQQhqQZzW3gApAgA3AgAgAEGU1t4AKQIANwIACx8AIABBCGpBrNbeACkCADcCACAAQaTW3gApAgA3AgALHQAgASAALQAAQQJ0IgAoArDfXiAAKAKY314Q6B4LHwAgAEEIakGE4t4AKQIANwIAIABB/OHeACkCADcCAAsfACAAQQhqQbzi3gApAgA3AgAgAEG04t4AKQIANwIACx8AIABBCGpBzOLeACkCADcCACAAQcTi3gApAgA3AgALHwAgAEEIakHc4t4AKQIANwIAIABB1OLeACkCADcCAAsfACAAQQhqQfTh3gApAgA3AgAgAEHs4d4AKQIANwIACx8AIABBCGpB7OLeACkCADcCACAAQeTi3gApAgA3AgALHwAgAEEIakH84t4AKQIANwIAIABB9OLeACkCADcCAAsfACAAQQhqQYzj3gApAgA3AgAgAEGE494AKQIANwIACxgAIAAQ0BUgAEEUahDlFiAAQThBBBCfIAsdACABIAAtAABBAnQiACgCkOpeIAAoAvjpXhDoHgsdACABIAAtAABBAnQiACgCoIJfIAAoAoiCXxDoHgsdACABIAAtAABBAnQiACgCmIRfIAAoAoCEXxDoHgsfACAAQQhqQdiF3wApAgA3AgAgAEHQhd8AKQIANwIACx8AIABBCGpB6IXfACkCADcCACAAQeCF3wApAgA3AgALHwAgAEEIakHYj98AKQIANwIAIABB0I/fACkCADcCAAsfACAAQQhqQZCQ3wApAgA3AgAgAEGIkN8AKQIANwIACx8AIABBCGpBiJLfACkCADcCACAAQYCS3wApAgA3AgALHwAgAEEIakGYkt8AKQIANwIAIABBkJLfACkCADcCAAsfACAAQQhqQdDf3wApAgA3AgAgAEHI398AKQIANwIACx8AIABBCGpBqMDgACkCADcCACAAQaDA4AApAgA3AgALHwAgAEEIakHkzuAAKQIANwIAIABB3M7gACkCADcCAAsfACAAQQhqQfjT4AApAgA3AgAgAEHw0+AAKQIANwIACx0AIAEgAC0AAEECdCIAKALA32AgACgCqN9gEOgeCx8AIABBCGpBwOLgACkCADcCACAAQbji4AApAgA3AgALHwAgAEEIakHQ4uAAKQIANwIAIABByOLgACkCADcCAAsfACAAQQhqQeDi4AApAgA3AgAgAEHY4uAAKQIANwIACx8AIABBCGpB+OfgACkCADcCACAAQfDn4AApAgA3AgALHwAgAEEIakGI6OAAKQIANwIAIABBgOjgACkCADcCAAsfACAAQQhqQdD54AApAgA3AgAgAEHI+eAAKQIANwIACx0AIAEgAC0AAEECdCIAKAKEiWEgACgC8IhhEOgeCx8AIABBCGpBhJDhACkCADcCACAAQfyP4QApAgA3AgALHQAgASAALQAAQQJ0IgAoApzDYSAAKAKMw2EQ6B4LHwAgAEEIakGI0uEAKQIANwIAIABBgNLhACkCADcCAAsfACAAQQhqQeii5AApAgA3AgAgAEHgouQAKQIANwIACx8AIABBCGpBkLbkACkCADcCACAAQYi25AApAgA3AgALHwAgAEEIakGgtuQAKQIANwIAIABBmLbkACkCADcCAAsdACABIAAtAABBAnQiACgCyM9kIAAoAqDOZBDoHgsVACABaUEBRiAAQYCAgIB4IAFrTXELHQAgASAALQAAQQJ0IgAoAqCdZiAAKAKMnWYQ8gMLHQAgASAALQAAQQJ0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QoCAgICAgICAgH83A8gBIAJBADYC7AEgAkKAgICAEDcC5AEgAkIBNwOAAiACQgA3A/gBIAJCgICAgBA3A/ABIAJCADcDuAEgAkEANgKQAiACQoCAgIAQNwOIAiACQgE3A8ABIAIgACkCADcDgAMgAigCyAIhCSACKALMAiEKIAIoAsQCIQAgAigC1AIhDCACKALYAiESIAIoAtACIQQgAigC5AIhECACKALoAiERIAIoAuACIQcgAkGYA2ogAkHMAWoiEyACQfACaiACKALwAkGBgICAeEYiFBsiBUEIaigCADYCACACIAUpAgA3A5ADIAIoAqACIQUgAigCqAIhFSACKAKkAiEWIAtFBEAgCBDzIQsgAkHkAWoQ8yEgAkHwAWoQ8yEgAkH8AWoQ8yEgFEUEQCATEKceCyAZQgAgDkEBcRshGCAaQgEgD0EBcRshFyADQQAgBkEBcRshE0EAIBEgB0GAgICAeEYiAxshD0EBIBAgAxshDkEAIAcgAxshB0EAIBIgBEGAgICAeEYiAxshC0EBIAwgAxshDEEAIAQgAxshEkEAIAogAEGAgICAeEYiAxshEEEBIAkgAxshEUEAIAAgAxshFEEAIBUgBUGAgICAeEYiABshCEEBIBYgABshA0EAIAUgABshBiAYpyEAIBhCIIinIRUgAkGIAmoQ8yEMBwsjAEEQayIAJAAgAkEIaiIEIAJBsAJqKAIAIgYQ7QgiAwR/QQEFIABBCGogBhC4AiAAKAIMIQMgACgCCAs2AgAgBCADNgIEIABBEGokACACKAIMIQMgAigCCEEBcQRAIAMhAAwGBUEBIQYMAQsACwALQYTnwgAQtBcACyAEEPMhDAQLQfTmwgAQtBcACyACKAK8ASEACyACQaACahCVHCACQfACahCmHiACQeACahCVHCACQdACahCVHCACQcQCahCVHCACQbgCahCVHEGAgICAeCEGCwJAIAEtABgiBEH/AUcEQCABIARBAWo6ABggARCRByEEIAJB1AFqIAJBmANqKAIANgIAIAJB4AFqIAJBiANqKAIANgIAIAIgEzYCyAEgAiAXNwPAASACIBU2ArwBIAIgADYCuAEgAiAENgKYAiACIAg2ApACIAIgAzYCjAIgAiAPNgKEAiACIA42AoACIAIgBzYC/AEgAiALNgL4ASACIAw2AvQBIAIgEjYC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EIYjDAILIAIoAtwEIQMLQQEhBQtBgICAgHghBCACKALMCUGAgICAeEcEQCACQcwJahCFIwsgAigCwAlBgICAgHhHIAVxBEAgAkHACWoQhiMLIAMhAAsCQCABLQAYIgNB/wFHBEAgASADQQFqOgAYIAEQkQchAyACIAA2AtgEIAJB2ARqQQRyIAJB9AtqIgZBqAL8CgAAIAIgAzYCkAcgAiAFNgKMByACIAk2AogHIAIgBDYChAcgBEGAgICAeEcEQCADDQIMBAsgA0UNAiACQZAHahCXDgwCC0GE58IAEK4XAAsgAkHYBGoQmx5BgICAgHghBCADIQAMAgtBgICAgHghBAwBCyACQQhqIAZBqAL8CgAAIAIpA4gHIQwLIARBgICAgHhGDQAgB0EEaiACQQhqQagC/AoAACAHIAw3A7ACIAcgBDYCrAIMAQsgASAAEMMkIQAgB0GAgICAeDYCrAILIAcgADYCACACQaAOaiQACxUAIAIgASAAQbyCxAAgAygCMBEGAAsVACACIAEgAEHMgsQAIAMoAjARBgALEQAgACABKAIAQQhqIAIQ+AcLCgAgAEEQahDzIQsTACAAIAEoAgQ2AgQgAEEANgIACw8AIAAoAgAEQCAAEKkZCwsVACACIAEgAEHg6MUAIAMoAjARBgALFQAgAiABIABB8OjFACADKAIwEQYACxUAIAIgASAAQYDpxQAgAygCMBEGAAsVACACIAEgAEGYkskAIAMoAjARBgALFQAgAiABIABBqJLJACADKAIwEQYACxUAIAIgASAAQbiSyQAgAygCMBEGAAsQACAAKAIIIAEgAhCPH0EACxAAIAAgATYCBCAAQQA2AgALEAAgACgCFCAAKAIQQQF2RgsUACAAKAIAIAEgACgCBCgCDBEAAAsRACAAKAIEIAAoAgBrQaACbgsOACAAIAEgASACahDIEgsUACAAKAIAIAEgACgCBCgCEBEAAAsUACAAKAIAIgAgACgCACgCABECAAsOACAAIAEgASACahDMEgu/AQEFfwJAIAAoAgBBCGohACMAQRBrIgUkACAAQYgCaiEGAkACQANAIAIgBE0NASAAKAKAAiIDQcAATwRAIAYgABCeFiAAQQA2AoACQQAhAwsgBUEIaiAAIANBAnRqQcAAIANrIAEgBGogAiAEaxDTDCAAKAKAAiIDIAUoAghq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cWoiAiACIANLGyICBEAgASAAIAL8CgAACyABIQILIAAQyQMLIAILCw8AIAAgASgCAEEIahDsDAsTACAAQSg2AgQgAEGMusQANgIACxAAIABBDjYCACAAIAE2AgQLEwAgAEEoNgIEIABBmPvEADYCAAsNACAAKAIAENUgQQBHCxAAIAAgAjYCBCAAIAE2AgALIQEBbyAAKAIAJQEgASgCACUBEBMhAhCNCyIAIAImASAACxEAIAAQlh82AgQgACABNgIACxAAIAAgAjYCBCAAQQA2AgALEQAgACgCBCAAKAIIIAEQ1xALEwAgAEEoNgIEIABB1IfFADYCAAsQACAAQQM6AAQgAEEMNgIACxMAIABBKDYCBCAAQfixxQA2AgALEwAgAEEoNgIEIABBtMXFADYCAAsRACAAKAIAKAIAQQUgARDkDwsRACAAKAIAKAIAQQYgARDkDwsTACAAQSg2AgQgAEG97cUANgIACxMAIABBKDYCBCAAQazkxgA2AgALEwAgAEEoNgIEIABB9czHADYCAAsRACABIAAoAgggACgCDBDoHgsPACAAEKQYIABBEGoQpBgLEwAgAEEoNgIEIABBwIPIADYCAAsTACAAQSg2AgQgAEGojcgANgIACxMAIABBKDYCBCAAQeizyAA2AgALEwAgAEEoNgIEIABB8PrIADYCAAtfAQJ/IAAoAgAoAgAhAiMAQRBrIgAkACAAQQRqIAEQyRlBGCEBA0AgACACNgIMIABBBGoiAyAAQQxqQcCE3wAQ4gggAkEIaiECIAFBCGsiAQ0ACyADEKcYIABBEGokAAsTACAAQSg2AgQgAEHUlckANgIACxMAIABBKDYCBCAAQdCyyQA2AgALDwAgABDfEyAAQRhqEIwfCxMAIABBKDYCBCAAQYTqyQA2AgALEwAgAEEoNgIEIABB7KnKADYCAAsTACAAQSg2AgQgAEH8vcoANgIACxEAIAAoAhQgACgCGCABEOMjCxMAIABBKDYCBCAAQc7NygA2AgALFAAgAEIBNwIIIABChICAgAg3AgALEQAgACgCACAAKAIEIAEQ4yMLEAAgAEEANgIAIABBADYCCAsPACAAIAAoAgBBAXI2AgALEAAgACABOgABIABBADoAAAsTACAAQSg2AgQgAEG4rtMANgIACxUAQYzM5gBBjMzmACgCAEEBazYCAAsTACAAQSg2AgQgAEGU6tMANgIACxMAIABBKDYCBCAAQeaN1AA2AgALEwAgAEEoNgIEIABBwKHUADYCAAsTACAAQSg2AgQgAEGEptQANgIACxMAIABBKDYCBCAAQaCv1AA2AgALEwAgAEEoNgIEIABBvLDUADYCAAsTACAAQSg2AgQgAEGo4dQANgIAC5oCAQV/IwBBIGsiAyQAIANBFGogAUEAQQJBBBCiCyADKAIYIQQgAygCFEEBRgRAIAQgAygCHCACEPYbAAsgA0EQaiIHQQA2AgAgAyADKAIcNgIMIAMgBDYCCCADQQhqIgUoAgAgBSgCCCICayABSQRAIAUgAiABQQJBBBDFFCAFKAIIIQILIAUoAgQgAkECdGohBAJAAkAgAUECTwRAIAFBAWshBgNAIARB//8DOwEAIARBAmpBADsBACAEQQRqIQQgBkEBayIGDQALIAEgAmpBAWshAgwBCyABRQ0BCyAEQQA7AQIgBEH//wM7AQAgAkEBaiECCyAFIAI2AgggAEEIaiAHKAIANgIAIAAgAykCCDcCACADQSBqJAALDwAgACgCACUBIAEgAhBlCxIAIAAoAgAlASABKAIAJQEQaAshAQFvIAAoAgAlASABKAIAJQEQbiECEI0LIgAgAiYBIAALEwAgAEEoNgIEIABByJnVADYCAAsRACABQby01QAgACgCBBDyDQsTACAAQSg2AgQgAEGawtUANgIACxMAIABBKDYCBCAAQaS93gA2AgALEwAgAEEoNgIEIABBmMneADYCAAsRACABIAAoAgQgACgCCBDoHgv7AQEFfwJAIwBB0ABrIgIkACACQQA2AkQgAiACQcQAajYCTCACIAJBBGoiBTYCSCACQcgAahCkICEDIAIoAkQhBAJAIAMgAUFAayABayIGIAMgBkkbIgMEQCACIAEtAAA6AAQgBEF/Rg0BIARBAWohBCADQQFrIQMgAUEBaiEBIAVBAXIhBQNAIAMEQCAFIAEtAAA6AAAgA0EBayEDIAFBAWohASAFQQFqIQUgBEEBaiIEDQEMAwsLIAIgBDYCRAsgBEHAAE8EQCAAIAJBBGpBwAD8CgAAIAJB0ABqJAAMAgsgBEHAABDpEAALIAJBfzYCREGI094AEK4XAAsLEwAgAEEoNgIEIABBvNXeADYCAAsPACAAENAVIABBFGoQ5RYLEwAgAEEoNgIEIABBjOLeADYCAAsQACAAEJMbIABBPEEEEJ8gCxMAIABB0OXeADYCBCAAIAE2AgALEwAgAEGM5t4ANgIEIAAgATYCAAsTACAAQcjm3gA2AgQgACABNgIACxMAIABBKDYCBCAAQaeF3wA2AgALEAAgABCVGyAAQRxBBBCfIAsTACAAQbyG3wA2AgQgACABNgIAC2wBAn8gACgCBCECIAAoAgghAyMAQRBrIgAkACAAQQRqIAEQyRkgAwRAIANBBHQhAQNAIAAgAjYCDCAAQQRqIABBDGpBmIffABDiCCACQRBqIQIgAUEQayIBDQALCyAAQQRqEKcYIABBEGokAAsQACAAIAEoAgAgAiADEPwGCxAAIAAgASgCACACIAMQ/goLEQAgACgCACAAKAIEIAEQ8gILEwAgAEEoNgIEIABB4I/fADYCAAsTACAAQSg2AgQgAEHYkd8ANgIACxMAIABB7JLfADYCBCAAIAE2AgALEAAgABDQFSAAQRhBBBCfIAsTACAAQSg2AgQgAEGg398ANgIACxMAIABBKDYCBCAAQfi/4AA2AgALEwAgAEEoNgIEIABBss7gADYCAAsTACAAQSg2AgQgAEHG0+AANgIACxMAIABBKDYCBCAAQZDi4AA2AgALEQAgACgCACAAKAIEIAEQ1xALEwAgAEEoNgIEIABByOfgADYCAAsTACAAQSg2AgQgAEGg+eAANgIACxMAIABBKDYCBCAAQdSP4QA2AgALDgAgACABIAFBEGoQ9wcLEgAgAEGDAjsBCCAAQoAINwIACxAAIABCBDcCCCAAQgA3AgALEwAgAEEoNgIEIABB2NHhADYCAAsPACAAEKMYIABBIGoQoxgLEwAgAEEoNgIEIABBuKLkADYCAAsTACAAQfDM5AA2AgQgACABNgIACxEAIAEgACgCACAAKAIEEPIDCxEAIAEoAgAgASgCBCAAEKkECxEBAX8QjQsiASAAJQEmASABC8oBAgV/AW8jAEEQayIDJAAgA0EEaiIEIAAQ3xggAygCBEHwAGojAEGwAmsiASQAKAIAIgAgACgCACICQQFqNgIAIAJBAEgEQAALIAFBADoAECABIAA2AggjAEHAAmsiACQAIABBEGoiBSABQQhqQagC/AoAACAAQgE3AwggACAAQQhqNgK8AiAAQbwCakGcrcIAEKwlIQIg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yJPKAEETQdyTygAQnBUAC1wBAn8gACgCACECQQohAyMAQRBrIgAkACAAQQRqIAEQyRkDQCAAIAI2AgwgAEEEaiIBIABBDGpBwJnKABDiCCACQQFqIQIgA0EBayIDDQALIAEQpxggAEEQaiQACw8AIAAoAgAoAgAgARDtEgsPACAAKAIAKAIAIAEQqAMLDwAgACgCACgCACABENkKC4wBAQF/IAAoAgAoAgAhAiMAQUBqIgAkACAAQTRqIAJBGGopAgA3AgAgAEEsaiACQRBqKQIANwIAIABBJGogAkEIaikCADcCACAAQQI6ADwgAEH4yeAANgIYIAAgAikCADcCHCAAQQxqIgIgAEEYahCrDyAAKAIQIAAoAhQgARDyAiACEPMhIABBQGskAAsPACAAKAIAKAIAIAEQ8AYLDwAgACgCACgCACABEKoNCw0AQQAgASAAIAEQyhULDgAgACgCACUBECxBAEcLDgAgACgCACUBEENBAEcLEgAgACgCACUBIAEoAgAlARBhCw0AIAAoAgAlASABEGcLDQAgACgCACUBQQEQagsPACAAKAIAJQFBARBtIAALDQAgACkDACABKQMAUQsNACAAQdAAaiABELEjCw0AIAAgASACIAMQ7RoLCgAgAUEYdCAAcgsQACAAQYD8//8DcUGAsANGCwwAIABBGGogARCxIwv2FQIRfwF+IwBBkAFrIgMkACADQeAAaiABIAIQoQoCQCADKAJgIg1FBEAgAEEENgIMIABB5a7fADYCCCAAQoGAgIAQNwMADAELAkAgAygCZCIBBEAgDS0AAEEtRg0BCyAAQgA3AwggAEIBNwMADAELIAMoAmghDiADQRBqIgIgDUEBaiABQQFrEKIKIAMoAhAhByADQQU2AmggA0EOaiIBIAIgA0HgAGogBxsiAkELai0AADoAACADIAIvAAk7AQwgB0UEQCAAIAMvAQw7AA0gAEEPaiABLQAAOgAAIABBBToADCAAQeCu3wA2AgggAEKBgICAEDcDAAwBCwJAIAMoAhQiAQRAIActAABBLUYNAQsgAEIANwMIIABCATcDAAwBCyADLQAYIQ8gA0EQaiICIAdBAWogAUEBaxDiCiADKAIQIQwgA0EDNgJoIANBDmoiASACIANB4ABqIAwbIgJBC2otAAA6AAAgAyACLwAJOwEMIAxFBEAgACAD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h9EANwPoAiACQvHt9Pilp/2npX83A+ACIAJCq/DT9K/uvLc8NwPYAiACQrvOqqbY0Ouzu383A9ACIAJBIDYCmAMgAkKokvaV/8z5hOoANwOIAiACQqiS9pX/zPmE6gA3A8gCIAMgAUHAAPwKAAAgAkKAATcDiAMgAkKAATcDkAMgAkGIAWogAyIBQYAB/AoAACAAIAFBmAP8CgAAIAJBoANqJAALDAAgACABQSAQmhNFCw8AIAAoAgAlARCFAUEARwsPACAAKAIAJQEQhwFBAEcLGQEBbyAAKAIAJQEgASACJQEgAhChFhCMAQsPACAAKAIAJQEQjgFBAEcLDwAgACgCACUBEJMBQQBHC+MBAQJ/An8jAEEgayIAJAACQAJAQbjL5gAoAgBFBEBBwMvmACgCACEBQcDL5gBBADYCACABRQ0BIAERDQAhAUG4y+YAKAIADQJBvMvmACABNgIAQbjL5gBBATYCAAsgAEEgaiQAQbzL5gAMAgsgAEEANgIYIABBATYCDCAAQbSs5AA2AgggAEIENwIQIABBCGpBvKzkABD3GAALIAAgATYCDCAAQQE2AgggAEEIaiIBEIsbIABBADYCGCAAQQE2AgwgAEHcrOQANgIIIABCBDcCECABQeSs5AAQ9xgACygCABCMIAsNACAAKAIAELUlQQFGCw4AIAAoAgAgASACEOgeCwwAIABBDGogARCECgsPAEHkoeUAQSsgABCcFQALawEBfyMAQTBrIgMkACADIAA2AgQgAyABNgIAIANBAzYCDCADQbCf5QA2AgggA0ICNwIUIAMgA0EEaq1CgICAgKABhDcDKCADIAOtQoCAgICgAYQ3AyAgAyADQSBqNgIQIANBCGogAhD3GAALDAAgACUBIAElARADCw0AIAAlAUGBASUBEBELDwEBbyAAJQEgABChFhAXC4MBAgN/AW8jAEHwBmsiACQAIABBoAFqIgIQiAggAEEIaiIBIAIQiAQgAEEANgKgASAAIAEgAhC6BCAAKAIEIQEgACgCAEEBcQRAIAAgATYCoAFB7JnEAEHPACACQfilxABBvJrEABCpDgALIABBQGsQlRwgAEHwBmokACABJQEgARChFguTAQIDfwFvIwBB8AZrIgAkACAAQaABaiICEIgIIABBAToAoAUgAEEBOgDIASAAQQhqIgEgAhCIBCAAQQA2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ABCpBCAAQTBqJAALDgAgAUHGsN4AQREQ6B4LDgAgAUGQtN4AQQ4Q6B4LDAAgACgCACABEMYCCwwAIAAoAgAgARD/CwsOACABQfPE3gBBFRDoHgsOACABQdDE3gBBERDoHgsMACAAKAIAIAEQ9wULDAAgACgCACABEMAaCwwAIAAoAgAgARDGGAsOACABQfjN3gBBAhDyAwsKACAAQQhqEOIWCwwAIAAoAgAgARC4DQsKACAAQQhqEOUWC94pAQF/IAAoAgAhAiMAQTBrIgAkAAJ/AkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCACLQAAQQFrDkMBAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZGhscHR4fICEiIyQlJicoKSorLC0uLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDAAsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB4w82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMQwsgACACQQRqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB5A82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMQgsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB5Q82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMQQsgACACQQRqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB5g82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMQAsgACACQQRqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB5w82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMPwsgACACQQRqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB6A82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMPgsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB6Q82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMPQsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB6g82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMPAsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB6w82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMOwsgACACQQRqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB7A82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMOgsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB7Q82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMOQsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB7g82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMOAsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB7w82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMNwsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB8A82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMNgsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB8Q82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMNQsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB8g82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMNAsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB8w82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMMwsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB9A82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMMgsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB9Q82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMMQsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB9g82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMMAsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB9w82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMLwsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB+A82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMLgsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB+Q82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMLQsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB+g82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMLAsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB+w82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMKwsgACACQQRqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB/A82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMKgsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB/Q82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMKQsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB/g82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMKAsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABB/w82AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMJwsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBgBA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMJgsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBgRA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMJQsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBghA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMJAsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBgxA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMIwsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBhBA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMIgsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBhRA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMIQsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBhhA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMIAsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBhxA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMHwsgACACQQRqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBiBA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMHgsgACACQQRqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBiRA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMHQsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBihA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMHAsgACACQQRqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBixA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMGwsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBjBA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMGgsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBjRA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMGQsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBjhA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMGAsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBjxA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMFwsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBkBA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMFgsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBkRA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMFQsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBkhA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMFAsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBkxA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMEwsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBlBA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMEgsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBlRA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMEQsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBlhA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMEAsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBlxA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMDwsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBmBA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMDgsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBmRA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMDQsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBmhA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMDAsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBmxA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMCwsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBnBA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMCgsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBnRA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMCQsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBnhA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMCAsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBnxA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMBwsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBoBA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMBgsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBoRA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMBQsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBohA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMBAsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBoxA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMAwsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2AhAgAEIBNwIcIABBpBA2AiwgACAAQShqNgIYIAAgAEEMajYCKCABIABBEGoQohAMAgsgACACQQFqNgIMIABBATYCFCAAQYjt3gA2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0ABrIgIkACADLQAEIQUgAiADKAIANgIMIAMoAgghAyACQQQ2AiQgAkHwnt8ANgIgIAJBBDYCFCACQdCe3wA2AhAgAiAFOwFMIAJBADYCSCACQQo2AkQgAkGRETYCPCACIABBBGo2AjggAkGRETYCNCACQZIRNgIsIAIgAEEGajYCKCACQQU2AhwgAiAAQQVqNgIwIAIgAkEoajYCGCACIAJBDGo2AkAgASADIAJBEGoQuAUgAkHQAGokACAEQSBqJAALhQYECX8EfgF8AW8CQBCJASEPEI0LIgEgDyYBIAEhBSMAQYABayIBJAAgASAFNgIsIAFBLGooAgAlARCKASEOIwBBEGsiAiQAAkAgDr0iDUL///////////8AgyILQoCAgICAgID4P1QNACALQoCAgICAgIDwxwBaBEAgC0KBgICAgICA+P8AWg0BIA1CP4ciDEL///////////8AhSEKIAxCf4UhDAwBCyACQgAgC0ILhkKAgICAgICAgIB/hEH+ACALQjSIp2tB/wBxENkQQgAgAikDACIKfSAKIA1CAFMiBBshDEIAIAIpAwgiCyAKQgBSrXx9IAsgBBshCgsgASAMNwMAIAEgCjcDCCACQRBqJAAgASkDCCELIAEpAwAhCiABQQA2AiggAUEQaiEEQgBCfyAKQgAgDkQAAAAAAADgx2YiAxsgDkT////////fR2QiBxsgDiAOYiIIGyEKIAFBKGpCACENQgAhDCMAQeAAayICJAACQCAKQgBC////////////ACALQoCAgICAgICAgH8gAxsgBxsgCBsiC4RQDQBCACAKfSAKIAtCAFMiAxshDEIAAn5CACALIApCAFKtfH0gCyADGyIKUEUEQCACQUBrQsCEPUIAIAxCABCWDiACQTBqQsCEPUIAIApCABCWDiACKQM4QgBSIAIpAzAiDCACKQNIfCIKIAxUciEGIAIpA0AMAQsgAkLAhD1CACAMIAoQlg4gAikDCCEKIAIpAwALIg19IA0gC0IAUyIDGyEMQgAgCiANQgBSrXx9IAogAxsiDSALhUIAWQ0AQQEhBgsgBCAMNwMAIAY2AgAgBCANNwMIIAJB4ABqJAAgASgCKEUEQCABQTBqIgIgASkDECABKQMYEOAJIAEoAjAEQCABQdgAaiIAIAJBKPwKAABBwKPfAEEwIABB1KLfAEHwo98AEKkOAAsgACABKQI0NwIAIABBCGogAUE8aikCADcCACAFQYQBTwRAIAUQoRYLIAFBgAFqJAAMAQtBsKPfABCwFwALC+kCAQV/IwBBEGsiBSQAIAUgARCEEQJ/IwBBIGsiAiQAIAIgACgCADYCBCACQRRqIgQgAkEEahDSBQJAAkAgAigCFCIGQX9HBEAgAiAAKQIENwMIIAQgAkEIahCzBCAGIAYgAigCHGpBAWoiA08gA0F/RnINAiACIAAvAQw7ARQgAiAAQQ5qLQAAOgAWIAMgBBDWBSADakEBaiIESQ0BDAILDAELIAJBIGokACAEDAELQbyl3wAQrhcACyEDIwBB0ABrIgIkACACIAAoAgA2AiQgAiAAKQIENwMoIAIgAEEOai0AADoANiACIAAvAQw7ATQgAkEANgIcIAJBAzYCECACQaSl3wA2AgwgAkGTETYCTCACQZQRNgJEIAJBDjYCPCACIAJBNGo2AkggAiACQShqNgJAIAIgAkEkajYCOCACQQM2AhggAiACQThqNgIUIAEgAyACQQxqELgFIAJB0ABqJAAgBUEQaiQAC5EBAgF/An4jAEEgayICJAAgAiAAEL4DIAJBEGogARC+AwJ/IAIoAgAiACACKAIQIgFHBEAgACABSiAAIAFIawwBCyACLwEEIgAgAi8BFCIBRwRAIAAgAUsgACABSWsMAQsgAikCCEL/////8+fPD4MiAyACKQIYQv/////z588PgyIEViADIARUawsgAkEgaiQACwgAIABB/wFxC30BAn8jAEEQayICJAACQCABKAIMBEAgASEADAELIAJBCGogAUEIaigCADYCACACIAEpAgA3AwAjAEEQayIDJAAgA0EIaiAAQQxqIAAoAhQQvwQgAiADKAIIIAMoAgwQ8hQhACADQRBqJAAgAUEUQQQQnyALIAJBEGokACAACwkAIAAgARCbDQsJACAAIAEQ3wILCQAgAEECNgIACwkAIAAgARDlAQsJACAAIAEQjB4LCgAgACgCABCOHgsKACAAKAIAELklCwoAIAAoAgAQuiULGAEBbyAAIAEQjwEhAhCNCyIAIAImASAACxsBAW8gACgCACUBEJEBIQEQjQsiACABJgEgAAsYAQFvIAAgARCcASECEI0LIgAgAiYBIAALGwEBbyAAKAIAJQEQnwEhARCNCyIAIAEm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IAM2AhwgByACNgIYIAcgB0EIajYCICAAIAdBGGoQqQQgB0EwaiQAC5kBAQJ/IwBBEGsiCSQAAn8CQAJAAkBBASAAKAIAIgpBgICAgHhzIApBAE4bQQFrDgIBAgALIAkgAEEEajYCBCABIAhBECADQQggCUEEaiAHELULDAILIAkgADYCCCABIAZBHCADQQggCUEIaiAFELULDAELIAkgAEEEajYCDCABIARBESADQQggCUEMaiACELULCyAJQRBqJAALYgEBfyMAQTBrIgMkACADIAA2AgwgA0GlETYCFCADIANBDGo2AhAgASgCBCEAIAEoAgAgA0IBNwIkIANBAjYCHCADIAI2AhggAyADQRBqNgIgIAAgA0EYahCpBCADQTBqJAALhgEBAn8jAEEQayIIJAACfwJAAkACQEEBIAAoAgAiCUEIayAJQQdNG0EBaw4CAQIACyAIIABBBGo2AgQgASAHQQYgCEEEaiAGEKUIDAILIAggADYCCCABIAVBBiAIQQhqIAQQpQgMAQsgCCAANgIMIAEgA0EJIAhBDGogAhClCAsgCEEQaiQAC/4EAQJ/IwBBQGoiJSQAAn8CQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAQQogACgCACImQYCAgIB4cyAmQQBOG0EBaw4QAQIDBAUGBwgJCgsMDQ4PEAALIAEgJEEUEOgeDBALICUgAEEEajYCECABICNBDyAhQQ0gJUEQaiAgELULDA8LICUgAEEEajYCECABICJBESAhQQ0gJUEQaiAgELULDA4LIAEgH0EXEOgeDA0LIAEgHkETEOgeDAwLIAEgHUETEOgeDAsLICUgAEEEajYCECABIBxBFyAaQQwgJUEQaiAZELULDAoLICUgAEEEajYCECABIBtBGSAaQQwgJUEQaiAZELULDAkLICUgAEEIajYCECABIBhBGCAXQQkgAEEEaiAQIBZBCSAlQRBqIBUQggsMCAsgJSAAQQRqNgIQIAEgFEENIBNBBSAlQRBqIBIQtQsMBwsgJSAANgIMICUgETYCPCAlIBA2AjQgJSAAQRhqNgIwICUgEDYCLCAlIABBFGo2AiggJSAQNgIkICUgAEEQajYCICAlIBA2AhwgJSAAQQxqNgIYICUgDzYCFCAlIABBHGo2AhAgJSAlQQxqNgI4IAEgDkEXIA0g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//8AABAAQZiAwAAL+bMCfQB8AHsAdGFnIHByZWZpeCBtdXN0IG5vdCBiZSBlbXB0eQBhbGlhcyB2YWx1ZSBtdXN0IG5vdCBiZSBlbXB0eQBhbmNob3IgdmFsdWUgbXVzdCBub3QgYmUgZW1wdHkAdGFnIHZhbHVlIG11c3Qgbm90IGJlIGVtcHR5AHRhZyBoYW5kbGUgbXVzdCBub3QgYmUgZW1wdHkAYWxpYXMgdmFsdWUgbXVzdCBjb250YWluIGFscGhhbnVtZXJpY2FsIGNoYXJhY3RlcnMgb25seQBhbmNob3IgdmFsdWUgbXVzdCBjb250YWluIGFscGhhbnVtZXJpY2FsIGNoYXJhY3RlcnMgb25seQB0YWcgaGFuZGxlIG11c3QgY29udGFpbiBhbHBoYW51bWVyaWNhbCBjaGFyYWN0ZXJzIG9ubHkAbGlicmFyeS9jb3JlL3NyYy9zdHIvbG9zc3kucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvZGFzaG1hcC01LjUuMy9zcmMvbWFwcmVmL2VudHJ5LnJzAGNvbW1vbi9jcmVkZW50aWFsLXN0b3JhZ2Uvc3JjL2JhY2tlbmRzL21lbW9yeS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9jb3Ntd2FzbS1zdGQtMi4yLjIvc3JjL21lbW9yeS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi90b2tpby0xLjQ3LjEvc3JjL3N5bmMvbm90aWZ5LnJzAC9ob21lL3J1bm5lci93b3JrL255bS9ueW0vY29tbW9uL2NyeXB0by9zcmMvc2hhcmVkX2tleS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zcGhpbngtcGFja2V0LTAuNi4wL3NyYy9wYXlsb2FkL2tleS5ycwBjb21tb24vZ2F0ZXdheS1yZXF1ZXN0cy9zcmMvc2hhcmVkX2tleS9sZWdhY3kucnMAL3J1c3QvZGVwcy9ydXN0Yy1kZW1hbmdsZS0wLjEuMjYvc3JjL2xlZ2FjeS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi90b2tpby0xLjQ3LjEvc3JjL3N5bmMvbXV0ZXgucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2Yvc3VidGxlLWVuY29kaW5nLTAuNS4xL3NyYy9oZXgucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvcmFuZC0wLjguNS9zcmMvZGlzdHJpYnV0aW9ucy93ZWlnaHRlZF9pbmRleC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9jdXJ2ZTI1NTE5LWRhbGVrLTQuMS4zL3NyYy93aW5kb3cucnMAbGlicmFyeS9jb3JlL3NyYy9udW0vZmx0MmRlYy9zdHJhdGVneS9ncmlzdS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9ieXRlcy0xLjEwLjEvc3JjL2J5dGVzX211dC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9ieXRlcy0xLjEwLjEvc3JjL2J1Zi9idWZfbXV0LnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3VybC0yLjUuNC9zcmMvaG9zdC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi90b2tpby0xLjQ3LjEvc3JjL3V0aWwvd2FrZV9saXN0LnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3Rva2lvLTEuNDcuMS9zcmMvdXRpbC9saW5rZWRfbGlzdC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi93YXNtdGltZXItMC40LjIvc3JjL3RpbWVyL2FyY19saXN0LnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3Rva2lvLTEuNDcuMS9zcmMvc3luYy9tcHNjL2xpc3QucnMAL2hvbWUvcnVubmVyL3dvcmsvbnltL255bS9jb21tb24vY2xpZW50LWxpYnMvdmFsaWRhdG9yLWNsaWVudC9zcmMvcnBjL3JlcXdlc3QucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvcmVxd2VzdC0wLjEyLjIyL3NyYy93YXNtL3JlcXVlc3QucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvdGVuZGVybWludC1ycGMtMC40MC40L3NyYy9yZXF1ZXN0LnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3RpbWUtMC4zLjQxL3NyYy9mb3JtYXRfZGVzY3JpcHRpb24vcGFyc2UvYXN0LnJzAGxpYnJhcnkvY29yZS9zcmMvc2xpY2Uvc29ydC9zaGFyZWQvc21hbGxzb3J0LnJzAC9ydXN0Yy9mODI5N2UzNTFhNDBjMTQzOWE0NjdiYmJiNjg3OTA4ODA0N2Y1MGIzL2xpYnJhcnkvY29yZS9zcmMvc2xpY2Uvc29ydC9zdGFibGUvcXVpY2tzb3J0LnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2Z1dHVyZXMtdXRpbC0wLjMuMzEvc3JjL3N0cmVhbS9mdXR1cmVzX3Vub3JkZXJlZC9hYm9ydC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9wYXJraW5nX2xvdF9jb3JlLTAuOS4xMS9zcmMvcGFya2luZ19sb3QucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvZnV0dXJlcy1jaGFubmVsLTAuMy4zMS9zcmMvb25lc2hvdC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9wcm9zdC0wLjEzLjUvc3JjL2VuY29kaW5nL3ZhcmludC5ycwBsaWJyYXJ5L3N0ZC9zcmMvdGhyZWFkL2N1cnJlbnQucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2Yvcnl1LTEuMC4yMC9zcmMvcHJldHR5L2V4cG9uZW50LnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3RpbWUtMC4zLjQxL3NyYy9wYXJzaW5nL2NvbXBvbmVudC5ycwBjb21tb24vbnltc3BoaW54L2NodW5raW5nL3NyYy9mcmFnbWVudC5ycwAvaG9tZS9ydW5uZXIvd29yay9ueW0vbnltL2NvbW1vbi9jbGllbnQtbGlicy92YWxpZGF0b3ItY2xpZW50L3NyYy9ueXhkL2NvbnRyYWN0X3RyYWl0cy9ka2dfcXVlcnlfY2xpZW50LnJzAC9ob21lL3J1bm5lci93b3JrL255bS9ueW0vY29tbW9uL2NsaWVudC1saWJzL3ZhbGlkYXRvci1jbGllbnQvc3JjL255eGQvY29zbXdhc21fY2xpZW50L2NsaWVudF90cmFpdHMvcXVlcnlfY2xpZW50LnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3JlcXdlc3QtMC4xMi4yMi9zcmMvd2FzbS9jbGllbnQucnMAL2hvbWUvcnVubmVyL3dvcmsvbnltL255bS9jb21tb24vZ2F0ZXdheS1yZXF1ZXN0cy9zcmMvcmVnaXN0cmF0aW9uL2hhbmRzaGFrZS9jbGllbnQucnMAbGlicmFyeS9hbGxvYy9zcmMvZm10LnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3V1aWQtMS4xNy4wL3NyYy9mbXQucnMAL3J1c3RjL2Y4Mjk3ZTM1MWE0MGMxNDM5YTQ2N2JiYmI2ODc5MDg4MDQ3ZjUwYjMvbGlicmFyeS9jb3JlL3NyYy9vcHMvYml0LnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2NoYWNoYTIwLTAuOS4xL3NyYy9iYWNrZW5kcy9zb2Z0LnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3BvbHkxMzA1LTAuOC4wL3NyYy9iYWNrZW5kL3NvZnQucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2Yvc2hhMi0wLjEwLjkvc3JjL3NoYTI1Ni9zb2Z0LnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3RpbWUtMC4zLjQxL3NyYy91dGNfb2Zmc2V0LnJzAC9ob21lL3J1bm5lci93b3JrL255bS9ueW0vY29tbW9uL255bXNwaGlueC9jaHVua2luZy9zcmMvc2V0LnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3NwaGlueC1wYWNrZXQtMC42LjAvc3JjL2hlYWRlci9zaGFyZWRfc2VjcmV0LnJzAC9ob21lL3J1bm5lci93b3JrL255bS9ueW0vbnltLW91dGZveC9zcmMvcGFja2V0LnJzAC9ydXN0Yy9mODI5N2UzNTFhNDBjMTQzOWE0NjdiYmJiNjg3OTA4ODA0N2Y1MGIzL2xpYnJhcnkvYWxsb2Mvc3JjL3ZlYy9pbl9wbGFjZV9jb2xsZWN0LnJzAGxpYnJhcnkvY29yZS9zcmMvbnVtL2RpeV9mbG9hdC5ycwBueW0tb3V0Zm94L3NyYy9mb3JtYXQucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2Yvc2VyZGUtMS4wLjIxOS9zcmMvZm9ybWF0LnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3NwaGlueC1wYWNrZXQtMC42LjAvc3JjL2hlYWRlci9rZXlzLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3NwaGlueC1wYWNrZXQtMC42LjAvc3JjL2hlYWRlci9kZWxheXMucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvcmFuZF9jaGFjaGEtMC4zLjEvc3JjL2d1dHMucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvdXJsLTIuNS40L3NyYy9wYXRoX3NlZ21lbnRzLnJzAGNvbW1vbi93YXNtL2NsaWVudC1jb3JlL3NyYy9zdG9yYWdlL3dhc21fY2xpZW50X3RyYWl0cy5ycwBjb21tb24vd2FzbS9jbGllbnQtY29yZS9zcmMvc3RvcmFnZS9jb3JlX2NsaWVudF90cmFpdHMucnMAY29tbW9uL2NsaWVudC1saWJzL2dhdGV3YXktY2xpZW50L3NyYy90cmFpdHMucnMAY29tbW9uL255bV9vZmZsaW5lX2NvbXBhY3RfZWNhc2gvc3JjL3RyYWl0cy5ycwAvaG9tZS9ydW5uZXIvd29yay9ueW0vbnltL2NvbW1vbi9jbGllbnQtY29yZS9zcmMvaW5pdC9oZWxwZXJzLnJzAGNvbW1vbi9nYXRld2F5LXJlcXVlc3RzL3NyYy90eXBlcy9oZWxwZXJzLnJzAC9ob21lL3J1bm5lci93b3JrL255bS9ueW0vY29tbW9uL2NsaWVudC1jb3JlL3NyYy9jbGllbnQvYmFzZV9jbGllbnQvc3RvcmFnZS9oZWxwZXJzLnJzAHdhc20vbm9kZS10ZXN0ZXIvc3JjL2hlbHBlcnMucnMAL2hvbWUvcnVubmVyL3dvcmsvbnltL255bS9jb21tb24vd2FzbS9jbGllbnQtY29yZS9zcmMvaGVscGVycy5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9pbmRleGVkX2RiX2Z1dHVyZXMtMC42LjQvc3JjL3RyYW5zYWN0aW9uL2xpc3RlbmVycy5ycwBsaWJyYXJ5L2NvcmUvc3JjL2ZtdC9idWlsZGVycy5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi91bnNhZmUtbGlieWFtbC0wLjIuMTEvc3JjL29wcy5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9yYW5kX2NvcmUtMC42LjQvc3JjL29zLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2FyZ29uMi0wLjUuMy9zcmMvcGFyYW1zLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3NlcmRlLTEuMC4yMTkvc3JjL3Nlci9pbXBscy5ycwAvcnVzdGMvZjgyOTdlMzUxYTQwYzE0MzlhNDY3YmJiYjY4NzkwODgwNDdmNTBiMy9saWJyYXJ5L3N0ZC9zcmMvaW8vaW1wbHMucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2Yvc2VyZGUtMS4wLjIxOS9zcmMvZGUvaW1wbHMucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvcmFuZF9jb3JlLTAuNi40L3NyYy9pbXBscy5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9yYW5kLTAuOC41L3NyYy9kaXN0cmlidXRpb25zL3V0aWxzLnJzAC9ob21lL3J1bm5lci93b3JrL255bS9ueW0vY29tbW9uL2JhbmR3aWR0aC1jb250cm9sbGVyL3NyYy91dGlscy5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9mdXR1cmVzLXV0aWwtMC4zLjMxL3NyYy9zdHJlYW0vc3RyZWFtL3JlYWR5X2NodW5rcy5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL2dpdC9jaGVja291dHMvYmxzMTJfMzgxLTUyZTA4MTc0NzIyYTczNDAvOWJmNTIwMC9zcmMvcGFpcmluZ3MucnMAY29tbW9uL255bXNwaGlueC9wYXJhbXMvc3JjL3BhY2tldF9zaXplcy5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zcGhpbngtcGFja2V0LTAuNi4wL3NyYy91dGlscy9ieXRlcy5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9ieXRlcy0xLjEwLjEvc3JjL2J5dGVzLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2dsb28tbmV0LTAuNi4wL3NyYy93ZWJzb2NrZXQvZnV0dXJlcy5ycwBjb21tb24vbnltX29mZmxpbmVfY29tcGFjdF9lY2FzaC9zcmMvc2NoZW1lL2V4cGlyYXRpb25fZGF0ZV9zaWduYXR1cmVzLnJzAC9ob21lL3J1bm5lci93b3JrL255bS9ueW0vY29tbW9uL2NsaWVudC1jb3JlL3NyYy9pbml0L3R5cGVzLnJzAGNvbW1vbi93YXNtL2NsaWVudC1jb3JlL3NyYy9zdG9yYWdlL3R5cGVzLnJzAHdhc20vbm9kZS10ZXN0ZXIvc3JjL3R5cGVzLnJzAGNvbW1vbi9jbGllbnQtY29yZS9nYXRld2F5cy1zdG9yYWdlL3NyYy90eXBlcy5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9lbmNvZGluZ19ycy0wLjguMzUvc3JjL2hhbmRsZXMucnMAY29tbW9uL2dhdGV3YXktcmVxdWVzdHMvc3JjL3JlZ2lzdHJhdGlvbi9oYW5kc2hha2UvbWVzc2FnZXMucnMAL2hvbWUvcnVubmVyL3dvcmsvbnltL255bS9ueW0tYXBpL255bS1hcGktcmVxdWVzdHMvc3JjL255bV9ub2Rlcy5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zcGhpbngtcGFja2V0LTAuNi4wL3NyYy9oZWFkZXIvcm91dGluZy9ub2Rlcy5ycwBjb21tb24vbnltc3BoaW54L2FkZHJlc3Npbmcvc3JjL25vZGVzLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3dhc20tYmluZGdlbi0wLjIuMTAwL3NyYy9jb252ZXJ0L3NsaWNlcy5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9jdXJ2ZTI1NTE5LWRhbGVrLTQuMS4zL3NyYy9lZHdhcmRzLnJzAC9ydXN0Yy9mODI5N2UzNTFhNDBjMTQzOWE0NjdiYmJiNjg3OTA4ODA0N2Y1MGIzL2xpYnJhcnkvY29yZS9zcmMvY2hhci9tZXRob2RzLnJzAC9ydXN0Yy9mODI5N2UzNTFhNDBjMTQzOWE0NjdiYmJiNjg3OTA4ODA0N2Y1MGIzL2xpYnJhcnkvc3RkL3NyYy9zeXMvc3luYy9tdXRleC9ub190aHJlYWRzLnJzAC9ydXN0Yy9mODI5N2UzNTFhNDBjMTQzOWE0NjdiYmJiNjg3OTA4ODA0N2Y1MGIzL2xpYnJhcnkvc3RkL3NyYy9zeXMvc3luYy9yd2xvY2svbm9fdGhyZWFkcy5ycwAvcnVzdGMvZjgyOTdlMzUxYTQwYzE0MzlhNDY3YmJiYjY4NzkwODgwNDdmNTBiMy9saWJyYXJ5L3N0ZC9zcmMvc3lzL3N5bmMvb25jZS9ub190aHJlYWRzLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3J5dS0xLjAuMjAvc3JjL2Qyc19pbnRyaW5zaWNzLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3J5dS0xLjAuMjAvc3JjL2Qycy5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zZXJkZV95YW1sLTAuOS4zNCtkZXByZWNhdGVkL3NyYy9saWJ5YW1sL2NzdHIucnMAbGlicmFyeS9hbGxvYy9zcmMvZmZpL2Nfc3RyLnJzAC9ydXN0Yy9mODI5N2UzNTFhNDBjMTQzOWE0NjdiYmJiNjg3OTA4ODA0N2Y1MGIzL2xpYnJhcnkvYWxsb2Mvc3JjL3N0ci5ycwAvcnVzdGMvZjgyOTdlMzUxYTQwYzE0MzlhNDY3YmJiYjY4NzkwODgwNDdmNTBiMy9saWJyYXJ5L2NvcmUvc3JjL2l0ZXIvdHJhaXRzL2l0ZXJhdG9yLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2Nvc213YXNtLXN0ZC0yLjIuMi9zcmMvZXJyb3JzL3N0ZF9lcnJvci5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zZXJkZV95YW1sLTAuOS4zNCtkZXByZWNhdGVkL3NyYy9saWJ5YW1sL2Vycm9yLnJzAGNvbW1vbi9jbGllbnQtbGlicy92YWxpZGF0b3ItY2xpZW50L3NyYy9ueXhkL2Vycm9yLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3NlcmRlX3lhbWwtMC45LjM0K2RlcHJlY2F0ZWQvc3JjL2Vycm9yLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3Byb3N0LTAuMTMuNS9zcmMvZXJyb3IucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2Yvc2VyZGVfanNvbi0xLjAuMTQxL3NyYy9lcnJvci5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9nbG9vLW5ldC0wLjYuMC9zcmMvZXJyb3IucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvbWVtY2hyLTIuNy41L3NyYy9hcmNoL2FsbC9tZW1jaHIucnMAbGlicmFyeS9jb3JlL3NyYy9zbGljZS9tZW1jaHIucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvdGltZS0wLjMuNDEvc3JjL2Zvcm1hdF9kZXNjcmlwdGlvbi9wYXJzZS9sZXhlci5ycwB3YXNtL25vZGUtdGVzdGVyL3NyYy9lcGhlbWVyYWxfcmVjZWl2ZXIucnMAL2hvbWUvcnVubmVyL3dvcmsvbnltL255bS9jb21tb24vbm9kZS10ZXN0ZXItdXRpbHMvc3JjL3JlY2VpdmVyLnJzAGNvbW1vbi9jbGllbnQtbGlicy9nYXRld2F5LWNsaWVudC9zcmMvcGFja2V0X3JvdXRlci5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zZXJkZV95YW1sLTAuOS4zNCtkZXByZWNhdGVkL3NyYy9saWJ5YW1sL2VtaXR0ZXIucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvdW5zYWZlLWxpYnlhbWwtMC4yLjExL3NyYy9lbWl0dGVyLnJzAC9ob21lL3J1bm5lci93b3JrL255bS9ueW0vY29tbW9uL25vZGUtdGVzdGVyLXV0aWxzL3NyYy90ZXN0ZXIucnMAd2FzbS9ub2RlLXRlc3Rlci9zcmMvdGVzdGVyLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3Vuc2FmZS1saWJ5YW1sLTAuMi4xMS9zcmMvd3JpdGVyLnJzAC9ydXN0Yy9mODI5N2UzNTFhNDBjMTQzOWE0NjdiYmJiNjg3OTA4ODA0N2Y1MGIzL2xpYnJhcnkvY29yZS9zcmMvc2xpY2UvaXRlci5ycwAvcnVzdGMvZjgyOTdlMzUxYTQwYzE0MzlhNDY3YmJiYjY4NzkwODgwNDdmNTBiMy9saWJyYXJ5L2FsbG9jL3NyYy9ib3hlZC9pdGVyLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2dlbmVyaWMtYXJyYXktMC4xNC43L3NyYy9pdGVyLnJzAGxpYnJhcnkvY29yZS9zcmMvbmV0L3BhcnNlci5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi91cmwtMi41LjQvc3JjL3BhcnNlci5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zZXJkZS0xLjAuMjE5L3NyYy9wcml2YXRlL3Nlci5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zZXJkZV95YW1sLTAuOS4zNCtkZXByZWNhdGVkL3NyYy9zZXIucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2Yvc2VyZGUtd2FzbS1iaW5kZ2VuLTAuNi41L3NyYy9zZXIucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2Yvc2VyZGVfanNvbi0xLjAuMTQxL3NyYy9zZXIucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvY2lwaGVyLTAuNC40L3NyYy9zdHJlYW1fd3JhcHBlci5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zaWduYXR1cmUtMi4yLjAvc3JjL3NpZ25lci5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zcGhpbngtcGFja2V0LTAuNi4wL3NyYy9oZWFkZXIvZmlsbGVyLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2Z1dHVyZXMtY29yZS0wLjMuMzEvc3JjL3Rhc2svX19pbnRlcm5hbC9hdG9taWNfd2FrZXIucnMAY29tbW9uL255bXNwaGlueC9hY2tub3dsZWRnZW1lbnRzL3NyYy9pZGVudGlmaWVyLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3RyYWNpbmctY29yZS0wLjEuMzQvc3JjL2Rpc3BhdGNoZXIucnMAbGlicmFyeS9jb3JlL3NyYy9uZXQvZGlzcGxheV9idWZmZXIucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvdG9raW8tMS40Ny4xL3NyYy9ydW50aW1lL3NjaGVkdWxlci9kZWZlci5ycwBsaWJyYXJ5L2NvcmUvc3JjL25ldC9zb2NrZXRfYWRkci5ycwBsaWJyYXJ5L2NvcmUvc3JjL25ldC9pcF9hZGRyLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2N1cnZlMjU1MTktZGFsZWstNC4xLjMvc3JjL3NjYWxhci5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9jdXJ2ZTI1NTE5LWRhbGVrLTQuMS4zL3NyYy9iYWNrZW5kL3NlcmlhbC91MzIvc2NhbGFyLnJzAGNvbW1vbi9ueW1fb2ZmbGluZV9jb21wYWN0X2VjYXNoL3NyYy9zY2hlbWUvc2V0dXAucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvZW5jb2RpbmdfcnMtMC44LjM1L3NyYy9pc29fMjAyMl9qcC5ycwAvcnVzdGMvZjgyOTdlMzUxYTQwYzE0MzlhNDY3YmJiYjY4NzkwODgwNDdmNTBiMy9saWJyYXJ5L2NvcmUvc3JjL2l0ZXIvYWRhcHRlcnMvemlwLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3dhc210aW1lci0wLjQuMi9zcmMvdG9raW8vc2xlZXAucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvaHR0cC0xLjMuMS9zcmMvaGVhZGVyL21hcC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi93YXNtdGltZXItMC40LjIvc3JjL3RpbWVyL2hlYXAucnMAL2hvbWUvcnVubmVyL3dvcmsvbnltL255bS9jb21tb24vdGFzay9zcmMvc3Bhd24ucnMAL3J1c3RjL2Y4Mjk3ZTM1MWE0MGMxNDM5YTQ2N2JiYmI2ODc5MDg4MDQ3ZjUwYjMvbGlicmFyeS9jb3JlL3NyYy9zdHIvcGF0dGVybi5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9yeXUtMS4wLjIwL3NyYy9jb21tb24ucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2Yvc2VyZGVjdC0wLjMuMC9zcmMvY29tbW9uLnJzAC9ydXN0Yy9mODI5N2UzNTFhNDBjMTQzOWE0NjdiYmJiNjg3OTA4ODA0N2Y1MGIzL2xpYnJhcnkvY29yZS9zcmMvb3B0aW9uLnJzAGNvbW1vbi9ueW1zcGhpbngvY2h1bmtpbmcvc3JjL3JlY29uc3RydWN0aW9uLnJzAC9ydXN0Yy9mODI5N2UzNTFhNDBjMTQzOWE0NjdiYmJiNjg3OTA4ODA0N2Y1MGIzL2xpYnJhcnkvY29yZS9zcmMvb3BzL2Z1bmN0aW9uLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2luZGV4ZWRfZGJfZnV0dXJlcy0wLjYuNC9zcmMvdHJhbnNhY3Rpb24ucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2Yvc3BoaW54LXBhY2tldC0wLjYuMC9zcmMvaGVhZGVyL3JvdXRpbmcvZGVzdGluYXRpb24ucnMAbGlicmFyeS9jb3JlL3NyYy9udW0vZmx0MmRlYy9zdHJhdGVneS9kcmFnb24ucnMAL2hvbWUvcnVubmVyL3dvcmsvbnltL255bS9jb21tb24vbnltX29mZmxpbmVfY29tcGFjdF9lY2FzaC9zcmMvc2NoZW1lL2tleWdlbi5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi90b2tpby0xLjQ3LjEvc3JjL3N5bmMvbXBzYy9jaGFuLnJzAGxpYnJhcnkvY29yZS9zcmMvbnVtL2JpZ251bS5ycwBsaWJyYXJ5L2NvcmUvc3JjL2ZtdC9udW0ucnMAL3J1c3RjL2Y4Mjk3ZTM1MWE0MGMxNDM5YTQ2N2JiYmI2ODc5MDg4MDQ3ZjUwYjMvbGlicmFyeS9jb3JlL3NyYy9pdGVyL3RyYWl0cy9hY2N1bS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9wYXJraW5nX2xvdF9jb3JlLTAuOS4xMS9zcmMvdGhyZWFkX3Bhcmtlci93YXNtLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3JhbmQtMC44LjUvc3JjL2Rpc3RyaWJ1dGlvbnMvdW5pZm9ybS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi90aW1lLTAuMy40MS9zcmMvcGFyc2luZy9zaGltLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3RpbWUtMC4zLjQxL3NyYy9mb3JtYXRfZGVzY3JpcHRpb24vcGFyc2UvZm9ybWF0X2l0ZW0ucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvY2lwaGVyLTAuNC40L3NyYy9zdHJlYW0ucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvcmVxd2VzdC0wLjEyLjIyL3NyYy9pbnRvX3VybC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9yZXF3ZXN0LTAuMTIuMjIvc3JjL3V0aWwucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvbGlvbmVzcy0wLjEuMi9zcmMvdXRpbC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9iaW5jb2RlLTEuMy4zL3NyYy9pbnRlcm5hbC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9jb3Ntd2FzbS1zdGQtMi4yLjIvc3JjL21hdGgvZGVjaW1hbC5ycwAvcnVzdGMvZjgyOTdlMzUxYTQwYzE0MzlhNDY3YmJiYjY4NzkwODgwNDdmNTBiMy9saWJyYXJ5L3N0ZC9zcmMvdGhyZWFkL2xvY2FsLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3dhc210aW1lci0wLjQuMi9zcmMvdGltZXIvZ2xvYmFsLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3Rva2lvLTEuNDcuMS9zcmMvc3luYy9yd2xvY2sucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvZnV0dXJlcy11dGlsLTAuMy4zMS9zcmMvbG9jay9iaWxvY2sucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvdG9raW8tMS40Ny4xL3NyYy9zeW5jL21wc2MvYmxvY2sucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvcmFuZF9jb3JlLTAuNi40L3NyYy9ibG9jay5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9hcmdvbjItMC41LjMvc3JjL2Jsb2NrLnJzAGxpYnJhcnkvc3RkL3NyYy9zeW5jL2xhenlfbG9jay5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9kYXNobWFwLTUuNS4zL3NyYy9sb2NrLnJzAC9ob21lL3J1bm5lci93b3JrL255bS9ueW0vY29tbW9uL255bXNwaGlueC9hY2tub3dsZWRnZW1lbnRzL3NyYy9zdXJiX2Fjay5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9sb2ctMC40LjI3L3NyYy9fX3ByaXZhdGVfYXBpLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3NoYTItMC4xMC45L3NyYy9jb3JlX2FwaS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9lbmNvZGluZ19ycy0wLjguMzUvc3JjL2FzY2lpLnJzAGNvbW1vbi9jbGllbnQtbGlicy9nYXRld2F5LWNsaWVudC9zcmMvYmFuZHdpZHRoLnJzAC9ob21lL3J1bm5lci93b3JrL255bS9ueW0vY29tbW9uL2h0dHAtYXBpLWNsaWVudC9zcmMvcGF0aC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi90ZW5kZXJtaW50LTAuNDAuNC9zcmMvaGFzaC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL2dpdC9jaGVja291dHMvYmxzMTJfMzgxLTUyZTA4MTc0NzIyYTczNDAvOWJmNTIwMC9zcmMvaGFzaF90b19jdXJ2ZS9leHBhbmRfbXNnLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3JhbmQtMC44LjUvc3JjL3JuZy5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9hcmdvbjItMC41LjMvc3JjL2JsYWtlMmJfbG9uZy5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9lZDI1NTE5LWRhbGVrLTIuMi4wL3NyYy92ZXJpZnlpbmcucnMAL3J1c3RjL2Y4Mjk3ZTM1MWE0MGMxNDM5YTQ2N2JiYmI2ODc5MDg4MDQ3ZjUwYjMvbGlicmFyeS9hbGxvYy9zcmMvc3RyaW5nLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3Byb3N0LTAuMTMuNS9zcmMvZW5jb2RpbmcucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2Yvc3VidGxlLWVuY29kaW5nLTAuNS4xL3NyYy9lbmNvZGluZy5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9yYW5kLTAuOC41L3NyYy9ybmdzL2FkYXB0ZXIvcmVzZWVkaW5nLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3dhc20tYmluZGdlbi0wLjIuMTAwL3NyYy9leHRlcm5yZWYucnMAL2hvbWUvcnVubmVyL3dvcmsvbnltL255bS9jb21tb24vY3J5cHRvL3NyYy9oa2RmLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2h0dHAtMS4zLjEvc3JjL2hlYWRlci92YWx1ZS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zZXJkZS0xLjAuMjE5L3NyYy9kZS92YWx1ZS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zaS1zY2FsZS0wLjIuMy9zcmMvdmFsdWUucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvZnV0dXJlcy1jaGFubmVsLTAuMy4zMS9zcmMvbXBzYy9xdWV1ZS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi93YXNtLWJpbmRnZW4tZnV0dXJlcy0wLjQuNTAvc3JjL3F1ZXVlLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2VuY29kaW5nX3JzLTAuOC4zNS9zcmMvc2luZ2xlX2J5dGUucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvdHJhY2luZy1jb3JlLTAuMS4zNC9zcmMvY2FsbHNpdGUucnMAL2hvbWUvcnVubmVyL3dvcmsvbnltL255bS9jb21tb24vY2xpZW50LWxpYnMvZ2F0ZXdheS1jbGllbnQvc3JjL3NvY2tldF9zdGF0ZS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi90b2tpby0xLjQ3LjEvc3JjL3J1bnRpbWUvdGFzay9zdGF0ZS5ycwAvaG9tZS9ydW5uZXIvd29yay9ueW0vbnltL2NvbW1vbi9nYXRld2F5LXJlcXVlc3RzL3NyYy9yZWdpc3RyYXRpb24vaGFuZHNoYWtlL3N0YXRlLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3dlYi1zeXMtMC4zLjc3L3NyYy9mZWF0dXJlcy9nZW5fSWRiUmVxdWVzdFJlYWR5U3RhdGUucnMAL3J1c3RjL2Y4Mjk3ZTM1MWE0MGMxNDM5YTQ2N2JiYmI2ODc5MDg4MDQ3ZjUwYjMvbGlicmFyeS9jb3JlL3NyYy9pdGVyL2FkYXB0ZXJzL2VudW1lcmF0ZS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi90aW1lLTAuMy40MS9zcmMvZGF0ZS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9taW1lLTAuMy4xNy9zcmMvcGFyc2UucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvcmVxd2VzdC0wLjEyLjIyL3NyYy93YXNtL3Jlc3BvbnNlLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2N1cnZlMjU1MTktZGFsZWstNC4xLjMvc3JjL2JhY2tlbmQvc2VyaWFsL3NjYWxhcl9tdWwvdmFydGltZV9kb3VibGVfYmFzZS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zaS1zY2FsZS0wLjIuMy9zcmMvYmFzZS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9mbGV4LWVycm9yLTAuNC40L3NyYy90cmFjZXJfaW1wbC9leXJlLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3Rva2lvLTEuNDcuMS9zcmMvc3luYy9iYXRjaF9zZW1hcGhvcmUucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvY2lwaGVyLTAuNC40L3NyYy9zdHJlYW1fY29yZS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi90aW1lLTAuMy40MS9zcmMvaW50ZXJvcC9qc19zeXNfZGF0ZV9vZmZzZXRkYXRldGltZS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi90aW1lLTAuMy40MS9zcmMvb2Zmc2V0X2RhdGVfdGltZS5ycwBsaWJyYXJ5L3N0ZC9zcmMvc3lzL3BhbC93YXNtLy4uL3Vuc3VwcG9ydGVkL3RpbWUucnMAL3J1c3RjL2Y4Mjk3ZTM1MWE0MGMxNDM5YTQ2N2JiYmI2ODc5MDg4MDQ3ZjUwYjMvbGlicmFyeS9jb3JlL3NyYy90aW1lLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3RpbWUtMC4zLjQxL3NyYy90aW1lLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3RpbWUtMC4zLjQxL3NyYy9mb3JtYXR0aW5nL2Zvcm1hdHRhYmxlLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2JsYWtlMy0xLjguMi9zcmMvcG9ydGFibGUucnMAbGlicmFyeS9jb3JlL3NyYy91bmljb2RlL3ByaW50YWJsZS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi90aW1lLTAuMy40MS9zcmMvcGFyc2luZy9wYXJzYWJsZS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9ieXRlcy0xLjEwLjEvc3JjL2J1Zi90YWtlLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2ljdV9jb2xsZWN0aW9ucy0yLjAuMC9zcmMvY29kZXBvaW50dHJpZS9jcHRyaWUucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvaWN1X2NvbGxlY3Rpb25zLTIuMC4wL3NyYy9jaGFyMTZ0cmllL3RyaWUucnMAL3J1c3RjL2Y4Mjk3ZTM1MWE0MGMxNDM5YTQ2N2JiYmI2ODc5MDg4MDQ3ZjUwYjMvbGlicmFyeS9jb3JlL3NyYy9pdGVyL3JhbmdlLnJzAGNvbW1vbi9ueW1zcGhpbngvc3JjL21lc3NhZ2UucnMAL2hvbWUvcnVubmVyL3dvcmsvbnltL255bS9jb21tb24vbm9kZS10ZXN0ZXItdXRpbHMvc3JjL21lc3NhZ2UucnMAY29tbW9uL2NyZWRlbnRpYWwtc3RvcmFnZS9zcmMvZXBoZW1lcmFsX3N0b3JhZ2UucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvdG9raW8tdXRpbC0wLjcuMTUvc3JjL3N5bmMvY2FuY2VsbGF0aW9uX3Rva2VuL3RyZWVfbm9kZS5ycwAvaG9tZS9ydW5uZXIvd29yay9ueW0vbnltL2NvbW1vbi90b3BvbG9neS9zcmMvbm9kZS5ycwAvaG9tZS9ydW5uZXIvd29yay9ueW0vbnltL2NvbW1vbi9ub2RlLXRlc3Rlci11dGlscy9zcmMvbm9kZS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9pZG5hLTEuMC4zL3NyYy9wdW55Y29kZS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9iczU4LTAuNS4xL3NyYy9lbmNvZGUucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvYmFzZTY0LTAuMjIuMS9zcmMvZW5jb2RlLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2JzNTgtMC41LjEvc3JjL2RlY29kZS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zZXJkZS0xLjAuMjE5L3NyYy9wcml2YXRlL2RlLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3NlcmRlX2pzb24tMS4wLjE0MS9zcmMvZGUucnMAL3J1c3RjL2Y4Mjk3ZTM1MWE0MGMxNDM5YTQ2N2JiYmI2ODc5MDg4MDQ3ZjUwYjMvbGlicmFyeS9zdGQvc3JjL3N5bmMvcG9pc29uL29uY2UucnMAL3J1c3RjL2Y4Mjk3ZTM1MWE0MGMxNDM5YTQ2N2JiYmI2ODc5MDg4MDQ3ZjUwYjMvbGlicmFyeS9hbGxvYy9zcmMvc2xpY2UucnMAbGlicmFyeS9zdGQvc3JjL2JhY2t0cmFjZS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9vbmNlX2NlbGwtMS4yMS4zL3NyYy9pbXBfc3RkLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3dhc210aW1lci0wLjQuMi9zcmMvc3RkLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3J5dS0xLjAuMjAvc3JjL3ByZXR0eS9tb2QucnMAY29tbW9uL2dhdGV3YXktcmVxdWVzdHMvc3JjL3NoYXJlZF9rZXkvbW9kLnJzAC9ydXN0L2RlcHMvaGFzaGJyb3duLTAuMTUuNS9zcmMvcmF3L21vZC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9oYXNoYnJvd24tMC4xNC41L3NyYy9yYXcvbW9kLnJzAC9ob21lL3J1bm5lci93b3JrL255bS9ueW0vY29tbW9uL2NsaWVudC1saWJzL3ZhbGlkYXRvci1jbGllbnQvc3JjL2NvY29udXQvbW9kLnJzAC9ob21lL3J1bm5lci93b3JrL255bS9ueW0vY29tbW9uL2dhdGV3YXktcmVxdWVzdHMvc3JjL3R5cGVzL3RleHRfcmVxdWVzdC9tb2QucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2Yvd2FzbS1iaW5kZ2VuLTAuMi4xMDAvc3JjL3J0L21vZC5ycwAvaG9tZS9ydW5uZXIvd29yay9ueW0vbnltL2NvbW1vbi9jbGllbnQtbGlicy92YWxpZGF0b3ItY2xpZW50L3NyYy9ueXhkL2Nvc213YXNtX2NsaWVudC9tb2QucnMAL2hvbWUvcnVubmVyL3dvcmsvbnltL255bS9jb21tb24vY2xpZW50LWxpYnMvZ2F0ZXdheS1jbGllbnQvc3JjL2NsaWVudC9tb2QucnMAbGlicmFyeS9jb3JlL3NyYy9mbXQvbW9kLnJzAC9ob21lL3J1bm5lci93b3JrL255bS9ueW0vY29tbW9uL2NsaWVudC1jb3JlL3NyYy9pbml0L21vZC5ycwBjb21tb24vc3RhdGlzdGljcy9zcmMvY2xpZW50cy9tb2QucnMAL3J1c3RjL2Y4Mjk3ZTM1MWE0MGMxNDM5YTQ2N2JiYmI2ODc5MDg4MDQ3ZjUwYjMvbGlicmFyeS9jb3JlL3NyYy9wdHIvbW9kLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3RpbWUtMC4zLjQxL3NyYy9wYXJzaW5nL2NvbWJpbmF0b3IvbW9kLnJzAGNvbW1vbi9jcmVkZW50aWFscy9zcmMvZWNhc2gvYmFuZHdpZHRoL3NlcmlhbGlzZXIvbW9kLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2JpbmNvZGUtMS4zLjMvc3JjL3Nlci9tb2QucnMAL2hvbWUvcnVubmVyL3dvcmsvbnltL255bS9jb21tb24vbnltc3BoaW54L3NyYy9wcmVwYXJlci9tb2QucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2Yvd2FzbXRpbWVyLTAuNC4yL3NyYy90aW1lci9tb2QucnMAL2hvbWUvcnVubmVyL3dvcmsvbnltL255bS9jb21tb24vY2xpZW50LWNvcmUvc3JjL2NsaWVudC9rZXlfbWFuYWdlci9tb2QucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2Yvc3BoaW54LXBhY2tldC0wLjYuMC9zcmMvaGVhZGVyL21vZC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9yYW5kLTAuOC41L3NyYy9zZXEvbW9kLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3NwaGlueC1wYWNrZXQtMC42LjAvc3JjL2NyeXB0by9tb2QucnMAL3J1c3RjL2Y4Mjk3ZTM1MWE0MGMxNDM5YTQ2N2JiYmI2ODc5MDg4MDQ3ZjUwYjMvbGlicmFyeS9zdGQvc3JjL2lvL21vZC5ycwAvcnVzdGMvZjgyOTdlMzUxYTQwYzE0MzlhNDY3YmJiYjY4NzkwODgwNDdmNTBiMy9saWJyYXJ5L2NvcmUvc3JjL251bS9tb2QucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvcmVxd2VzdC0wLjEyLjIyL3NyYy93YXNtL21vZC5ycwAvaG9tZS9ydW5uZXIvd29yay9ueW0vbnltL2NvbW1vbi9jbGllbnQtbGlicy92YWxpZGF0b3ItY2xpZW50L3NyYy9ueW1fYXBpL21vZC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zcGhpbngtcGFja2V0LTAuNi4wL3NyYy9oZWFkZXIvcm91dGluZy9tb2QucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvdGltZS0wLjMuNDEvc3JjL2Zvcm1hdHRpbmcvbW9kLnJzAGNvbW1vbi93YXNtL2NsaWVudC1jb3JlL3NyYy9jb25maWcvbW9kLnJzAGxpYnJhcnkvc3RkL3NyYy8uLi8uLi9iYWNrdHJhY2Uvc3JjL3N5bWJvbGl6ZS9tb2QucnMAL2hvbWUvcnVubmVyLy5jYXJnby9naXQvY2hlY2tvdXRzL2JsczEyXzM4MS01MmUwODE3NDcyMmE3MzQwLzliZjUyMDAvc3JjL2hhc2hfdG9fY3VydmUvbW9kLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3RpbWUtMC4zLjQxL3NyYy9mb3JtYXRfZGVzY3JpcHRpb24vcGFyc2UvbW9kLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2Jhc2U2NC0wLjIyLjEvc3JjL2VuZ2luZS9nZW5lcmFsX3B1cnBvc2UvbW9kLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2Jhc2U2NC0wLjIyLjEvc3JjL2VuZ2luZS9tb2QucnMAL2hvbWUvcnVubmVyL3dvcmsvbnltL255bS9jb21tb24vbnltX29mZmxpbmVfY29tcGFjdF9lY2FzaC9zcmMvc2NoZW1lL21vZC5ycwAvaG9tZS9ydW5uZXIvd29yay9ueW0vbnltL2NvbW1vbi93YXNtL2NsaWVudC1jb3JlL3NyYy9zdG9yYWdlL21vZC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zZXJkZS0xLjAuMjE5L3NyYy9kZS9tb2QucnMAL2hvbWUvcnVubmVyL3dvcmsvbnltL255bS9jb21tb24vY2xpZW50LWxpYnMvdmFsaWRhdG9yLWNsaWVudC9zcmMvbnl4ZC9tb2QucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvZnV0dXJlcy11dGlsLTAuMy4zMS9zcmMvc3RyZWFtL2Z1dHVyZXNfdW5vcmRlcmVkL21vZC5ycwBsaWJyYXJ5L3N0ZC9zcmMvdGhyZWFkL21vZC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9mdXR1cmVzLWNoYW5uZWwtMC4zLjMxL3NyYy9tcHNjL21vZC5ycwAvaG9tZS9ydW5uZXIvd29yay9ueW0vbnltL2NvbW1vbi9jbGllbnQtbGlicy92YWxpZGF0b3ItY2xpZW50L3NyYy9ycGMvbW9kLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3plcm92ZWMtMC4xMS4yL3NyYy96ZXJvdmVjL21vZC5ycwAvcnVzdGMvZjgyOTdlMzUxYTQwYzE0MzlhNDY3YmJiYjY4NzkwODgwNDdmNTBiMy9saWJyYXJ5L2FsbG9jL3NyYy9yYXdfdmVjL21vZC5ycwAvcnVzdGMvZjgyOTdlMzUxYTQwYzE0MzlhNDY3YmJiYjY4NzkwODgwNDdmNTBiMy9saWJyYXJ5L2FsbG9jL3NyYy92ZWMvbW9kLnJzAGxpYnJhcnkvY29yZS9zcmMvbnVtL2ZsdDJkZWMvbW9kLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3NwaGlueC1wYWNrZXQtMC42LjAvc3JjL3N1cmIvbW9kLnJzAGNvbW1vbi9jcnlwdG8vc3JjL2FzeW1tZXRyaWMvZWQyNTUxOS9tb2QucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvaHR0cC0xLjMuMS9zcmMvbWV0aG9kLnJzAGNvbW1vbi9ueW1fb2ZmbGluZV9jb21wYWN0X2VjYXNoL3NyYy9wcm9vZnMvcHJvb2Zfc3BlbmQucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvdHJhY2luZy1jb3JlLTAuMS4zNC9zcmMvZmllbGQucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvY3VydmUyNTUxOS1kYWxlay00LjEuMy9zcmMvYmFja2VuZC9zZXJpYWwvdTMyL2ZpZWxkLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2Nvc21ycy0wLjIxLjEvc3JjL2Jhc2UvYWNjb3VudF9pZC5ycwAvcnVzdGMvZjgyOTdlMzUxYTQwYzE0MzlhNDY3YmJiYjY4NzkwODgwNDdmNTBiMy9saWJyYXJ5L2FsbG9jL3NyYy9ib3hlZC5ycwAvaG9tZS9ydW5uZXIvd29yay9ueW0vbnltL2NvbW1vbi9jcmVkZW50aWFscy9zcmMvZWNhc2gvYmFuZHdpZHRoL2lzc3VlZC5ycwAvcnVzdGMvZjgyOTdlMzUxYTQwYzE0MzlhNDY3YmJiYjY4NzkwODgwNDdmNTBiMy9saWJyYXJ5L2FsbG9jL3NyYy92ZWMvc3BlY19mcm9tX2l0ZXJfbmVzdGVkLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2luZGV4ZWRfZGJfZnV0dXJlcy0wLjYuNC9zcmMvZnV0dXJlL21heWJlX2Vycm9yZWQucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvYmxvY2stYnVmZmVyLTAuMTAuNC9zcmMvc2VhbGVkLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2Z1dHVyZXMtdXRpbC0wLjMuMzEvc3JjL3NpbmsvZmVlZC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi90b2tpby0xLjQ3LjEvc3JjL3N5bmMvbXBzYy91bmJvdW5kZWQucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2Yvd2FzbS1iaW5kZ2VuLWZ1dHVyZXMtMC40LjUwL3NyYy90YXNrL3NpbmdsZXRocmVhZC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9yYW5kLTAuOC41L3NyYy9ybmdzL3RocmVhZC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zZXJkZV9qc29uLTEuMC4xNDEvc3JjL3JlYWQucnMAL3J1c3QvZGVwcy9kbG1hbGxvYy0wLjIuMTAvc3JjL2RsbWFsbG9jLnJzAGxpYnJhcnkvc3RkL3NyYy9hbGxvYy5ycwAvcnVzdGMvZjgyOTdlMzUxYTQwYzE0MzlhNDY3YmJiYjY4NzkwODgwNDdmNTBiMy9saWJyYXJ5L2FsbG9jL3NyYy9zeW5jLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2hhc2hicm93bi0wLjE0LjUvc3JjL3Jhdy9nZW5lcmljLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3Bwdi1saXRlODYtMC4yLjIxL3NyYy9nZW5lcmljLnJzAC9ydXN0Yy9mODI5N2UzNTFhNDBjMTQzOWE0NjdiYmJiNjg3OTA4ODA0N2Y1MGIzL2xpYnJhcnkvY29yZS9zcmMvc3luYy9hdG9taWMucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvYXJyYXl2ZWMtMC43LjYvc3JjL2FycmF5dmVjLnJzAC9ob21lL3J1bm5lci93b3JrL255bS9ueW0vY29tbW9uL3RvcG9sb2d5L3NyYy9saWIucnMAY29tbW9uL2NsaWVudC1saWJzL2dhdGV3YXktY2xpZW50L3NyYy9saWIucnMAL2hvbWUvcnVubmVyL3dvcmsvbnltL255bS9jb21tb24vaHR0cC1hcGktY2xpZW50L3NyYy9saWIucnMAL2hvbWUvcnVubmVyL3dvcmsvbnltL255bS9jb21tb24vYmFuZHdpZHRoLWNvbnRyb2xsZXIvc3JjL2xpYi5ycwBjb21tb24vc3RvcmUtY2lwaGVyL3NyYy9saWIucnMAY29tbW9uL255bXNwaGlueC9yb3V0aW5nL3NyYy9saWIucnMAY29tbW9uL255bXNwaGlueC9jaHVua2luZy9zcmMvbGliLnJzAC9ob21lL3J1bm5lci93b3JrL255bS9ueW0vY29tbW9uL2VjYXNoLXRpbWUvc3JjL2xpYi5ycwAvaG9tZS9ydW5uZXIvd29yay9ueW0vbnltL2NvbW1vbi93YXNtL3N0b3JhZ2Uvc3JjL2xpYi5ycwBjb21tb24vY3JlZGVudGlhbHMtaW50ZXJmYWNlL3NyYy9saWIucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvanMtc3lzLTAuMy43Ny9zcmMvbGliLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL21pbWUtMC4zLjE3L3NyYy9saWIucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvZ2VuZXJpYy1hcnJheS0wLjE0Ljcvc3JjL2xpYi5ycwAvcnVzdC9kZXBzL3J1c3RjLWRlbWFuZ2xlLTAuMS4yNi9zcmMvbGliLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2JsYWtlMi0wLjEwLjYvc3JjL2xpYi5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9lbmNvZGluZ19ycy0wLjguMzUvc3JjL2xpYi5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9pdG9hLTEuMC4xNS9zcmMvbGliLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3NlcmRlLXdhc20tYmluZGdlbi0wLjYuNS9zcmMvbGliLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3VybC0yLjUuNC9zcmMvbGliLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2dlbmVyaWMtYXJyYXktMC4xMi40L3NyYy9saWIucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvaGtkZi0wLjEyLjQvc3JjL2xpYi5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9kYXNobWFwLTUuNS4zL3NyYy9saWIucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvYXJnb24yLTAuNS4zL3NyYy9saWIucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2Yvb25jZV9jZWxsLTEuMjEuMy9zcmMvbGliLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2JsYWtlMy0xLjguMi9zcmMvbGliLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2FlYWQtMC41LjIvc3JjL2xpYi5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi91bnNhZmUtbGlieWFtbC0wLjIuMTEvc3JjL2xpYi5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9jaGFjaGEyMC0wLjkuMS9zcmMvbGliLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3plcm9pemUtMS44LjEvc3JjL2xpYi5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zdWJ0bGUtMi42LjEvc3JjL2xpYi5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zbWFsbHZlYy0xLjE1LjEvc3JjL2xpYi5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9wZXJjZW50LWVuY29kaW5nLTIuMy4xL3NyYy9saWIucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvaWRuYV9hZGFwdGVyLTEuMi4xL3NyYy9saWIucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvZm9ybV91cmxlbmNvZGVkLTEuMi4xL3NyYy9saWIucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvYWVzLWdjbS1zaXYtMC4xMS4xL3NyYy9saWIucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvYnl0ZXMtMS4xMC4xL3NyYy9saWIucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2Yvd2FzbS1iaW5kZ2VuLWZ1dHVyZXMtMC40LjUwL3NyYy9saWIucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2Yvc2VyZGUtd2FzbS1iaW5kZ2VuLTAuNS4wL3NyYy9saWIucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvYmlwMzktMi4yLjAvc3JjL2xpYi5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9iYXNlMTZjdC0wLjIuMC9zcmMvbGliLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2ljdV9ub3JtYWxpemVyLTIuMC4wL3NyYy9saWIucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvYmxha2UyLTAuOC4xL3NyYy9ibGFrZTJiLnJzAGxpYnJhcnkvY29yZS9zcmMvdW5pY29kZS91bmljb2RlX2RhdGEucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvZW5jb2RpbmdfcnMtMC44LjM1L3NyYy9kYXRhLnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3J5dS0xLjAuMjAvc3JjL3ByZXR0eS9tYW50aXNzYS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9jaGFjaGEyMC0wLjkuMS9zcmMveGNoYWNoYS5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9lbmNvZGluZ19ycy0wLjguMzUvc3JjL3V0Zl84LnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2l0b2EtMS4wLjE1L3NyYy91ZGl2MTI4LnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2lkbmEtMS4wLjMvc3JjL3V0czQ2LnJzAC9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL2N0ci0wLjkuMi9zcmMvZmxhdm9ycy9jdHI2NC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zdWJ0bGUtZW5jb2RpbmctMC41LjEvc3JjL2Jhc2U2NC5ycwBjb21tb24vbnltc3BoaW54L2Fub255bW91cy1yZXBsaWVzL3NyYy9yZXF1ZXN0cy92Mi5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zdWJ0bGUtZW5jb2RpbmctMC41LjEvc3JjL2JlY2gzMi5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9zdWJ0bGUtZW5jb2RpbmctMC41LjEvc3JjL2JlY2gzMi9iYXNlMzIucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvYWVzLTAuOC40L3NyYy9zb2Z0L2ZpeHNsaWNlMzIucnMAY29tbW9uL255bXNwaGlueC9hbm9ueW1vdXMtcmVwbGllcy9zcmMvcmVxdWVzdHMvdjEucnMAL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvY29zbW9zLXNkay1wcm90by0wLjI2LjEvc3JjL3Byb3N0L3dhc21kL2Nvc213YXNtLndhc20udjEucnMAL2hvbWUvcnVubmVyLy5jYXJnby9naXQvY2hlY2tvdXRzL2JsczEyXzM4MS01MmUwODE3NDcyMmE3MzQwLzliZjUyMDAvc3JjL2hhc2hfdG9fY3VydmUvbWFwX2cxLnJzAC9ydXN0L2RlcHMvcnVzdGMtZGVtYW5nbGUtMC4xLjI2L3NyYy92MC5ycwAvaG9tZS9ydW5uZXIvLmNhcmdvL3JlZ2lzdHJ5L3NyYy9pbmRleC5jcmF0ZXMuaW8tMTk0OWNmOGM2YjViNTU3Zi9lbmNvZGluZ19ycy0wLjguMzUvc3JjL2diMTgwMzAucnMAbGlieWFtbCBlbWl0dGVyIGZhaWxlZCBidXQgdGhlcmUgaXMgbm8gZXJyb3IAd3JpdGUgZXJyb3IAaW5jb21wYXRpYmxlICVZQU1MIGRpcmVjdGl2ZQBkdXBsaWNhdGUgJVRBRyBkaXJlY3RpdmUAbmVpdGhlciB0YWcgbm9yIGltcGxpY2l0IGZsYWdzIGFyZSBzcGVjaWZpZWQAXQBbAGV4cGVjdGVkIFNUUkVBTS1TVEFSVABleHBlY3RlZCBTQ0FMQVIsIFNFUVVFTkNFLVNUQVJULCBNQVBQSU5HLVNUQVJULCBvciBBTElBUwAlWUFNTAAlVEFHAGV4cGVjdGVkIERPQ1VNRU5ULUVORABleHBlY3RlZCBET0NVTUVOVC1TVEFSVCBvciBTVFJFQU0tRU5EAGV4cGVjdGVkIG5vdGhpbmcgYWZ0ZXIgU1RSRUFNLUVORAA/AD4AITwAdGFnOnlhbWwub3JnLDIwMDI6ADEuMgAxLjEALi4uAC0tLQAsACsAKgB0YWcgaGFuZGxlIG11c3Qgc3RhcnQgd2l0aCAnIScAdGFnIGhhbmRsZSBtdXN0IGVuZCB3aXRoICchJwAmACIAISEAAACjbRAAOAAAAMsAAAAFAAAAo20QADgAAADgAAAABQAAAKNtEAA4AAAAYQEAADQAAABhdHRlbXB0aW5nIHRvIGRlcml2ZSBuZXcgZW5jcnlwdGlvbiBrZXkAyIEQACcAAAB0aGlzIG5ldyBzdG9yYWdlIHdpbGwgbm90IHVzZSBhbnkgZW5jcnlwdGlvbviBEAAsAAAAo20QADgAAAAzAQAANAAAAGF0dGVtcHRpbmcgdG8gdXNlIHByZXZpb3VzbHkgZGVyaXZlZCBlbmNyeXB0aW9uIGtleQA8ghAAMwAAAGF0dGVtcHRpbmcgdG8gcmVzdG9yZSBvbGQgdW5lbmNyeXB0ZWQgZGF0YQAAeIIQACoAAACjbRAAOAAAAEkBAAA0AAAAY2lwaGVyX3N0b3JlX2V4cG9ydF9pbmZvX2NpcGhlcl9zdG9yZQAAAKNtEAA4AAAAHAEAAEIAAACjbRAAOAAAACcBAAAjAAAAo20QADgAAAA+AAAABQAAABQaEABCAAAALAAAAEAAAABGaWVsZFNldCBjb3JydXB0ZWQgKHRoaXMgaXMgYSBidWcpAAA8WBAAPAAAAM0AAAAFAAAAU2V0dGluZyB1cCBnYXRld2F5AABYgxAAEgAAAAAAAAAYAAAABAAAABIAAAA8WBAAPAAAANAAAAANAAAAR2F0ZXdheVNldHVwOjpNdXN0TG9hZCB3aXRoIGlkOiCUgxAAIAAAADxYEAA8AAAA2QAAAA0AAABHYXRld2F5U2V0dXA6Ok5ldyB3aXRoIHNwZWM6IAAAAMyDEAAdAAAAPFgQADwAAADpAAAADQAAAEdhdGV3YXlTZXR1cDo6UmV1c2VDb25uZWN0aW9uAAAABIQQAB0AAAA8WBAAPAAAAMwAAAABAAAAPFgQADwAAABCAAAABQAAAFNldHRpbmcgdXAgbmV3IGdhdGV3YXkAAEyEEAAWAAAAPFgQADwAAABBAAAAAQAAADxYEAA8AAAAowAAAAEAAADJHBAAPgAAAIMAAAAFAAAAZRUQAEAAAACBAQAAMgAAAGUVEABAAAAAlQEAAA0AAABGYWlsZWQgdG8gcmVnaXN0ZXIgd2l0aCB0aGUgZ2F0ZXdheSA6IAAAvIQQACQAAADghBAAAgAAAGUVEABAAAAAiwEAAAkAAABGYWlsZWQgdG8gZXN0YWJsaXNoIGNvbm5lY3Rpb24gd2l0aCBnYXRld2F5IQSFEAAsAAAAZRUQAEAAAAAXAQAABQAAAGNob29zaW5nIGdhdGV3YXkgYnkgbGF0ZW5jeSwgcGluZ2luZyAgZ2F0ZXdheXMgLi4uAABIhRAAJQAAAG2FEAANAAAAZRUQAEAAAAAcAQAAKgAAAGUVEABAAAAAFAEAACEAAABlFRAAQAAAADIBAAAFAAAAY2hvc2UgZ2F0ZXdheSAgd2l0aCBhdmVyYWdlIGxhdGVuY3kgb2YgALyFEAAOAAAAyoUQABkAAADTFRAAVgAAAIsAAAABAAAAEwAAAGgAAAAIAAAAFAAAABMAAABoAAAACAAAABUAAAAUAAAABIYQABYAAAAXAAAAGAAAABkAAAAaAAAA0xUQAFYAAAB+AAAAAQAAANMVEABWAAAAbQAAAAEAAADTFRAAVgAAAE8AAAABAAAA0xUQAFYAAABeAAAAAQAAAJBaEABKAAAAUAAAAFUAAABKFhAAQAAAAIIAAAAyAAAAShYQAEAAAADDAAAAMgAAAEoWEABAAAAAQAAAADUAAABpbmNvbnNpc3RlbnQgbm9kZXMgbWV0YWRhdGEgYmV0d2VlbiBtaXhub2RlcyBhbmQgZ2F0ZXdheXMgY2FsbHMhICBhbmQgAADAhhAAQQAAAAGHEAAFAAAAdGAQAEQAAAAqAAAALwAAAEU0EABtAAAAWQAAADgAAACLFhAAdwAAACQAAAA+AAAAaW50ZXJuYWwgZXJyb3I6IGVudGVyZWQgdW5yZWFjaGFibGUgY29kZTogVHJhbnNhY3Rpb24gbGlzdGVuZXIgY2hhbm5lbCBjbG9zZWQAAABIhxAATQAAAIsWEAB3AAAAKAAAAA0AAABfRhAATwAAAEQBAAApAAAAVGhpcyBzaG91bGQgaGF2ZSBORVZFUiBoYXBwZW5lZCAtIHJldHVybmVkIGEgc3RyZWFtIGJlZm9yZSByZWNlaXZpbmcgbm90aWZpY2F0aW9uAAAAwIcQAFEAAABfRhAATwAAAFQBAAANAAAAX0YQAE8AAABKAQAASwAAAF9GEABPAAAAaAEAACsAAADSVxAATQAAAEYEAABKAAAA0lcQAE0AAAClAgAACQAAAGF1dGhlbnRpY2F0aW5nIHdpdGggZ2F0ZXdheQBsiBAAGwAAANJXEABNAAAAoQIAAFYAAADSVxAATQAAADcEAABNAAAA0lcQAE0AAACCAgAACQAAAHVzaW5nIHYxIGF1dGhlbnRpY2F0aW9uAMCIEAAXAAAA0lcQAE0AAACBAgAASwAAANJXEABNAAAAlwIAAAkAAAB1c2luZyB2MiBhdXRoZW50aWNhdGlvbgAAiRAAFwAAANJXEABNAAAAlgIAAEsAAADSVxAATQAAAFsDAAAJAAAATm90IGVub3VnaCBiYW5kd2lkdGguIFRyeWluZyB0byBnZXQgbW9yZSBiYW5kd2lkdGgsIHRoaXMgbWlnaHQgdGFrZSBhIHdoaWxlAECJEABLAAAA0lcQAE0AAABdAwAADQAAAFRoZSBjbGllbnQgaXMgcnVubmluZyBpbiBkaXNhYmxlZCBjcmVkZW50aWFscyBtb2RlIC0gYXR0ZW1wdGluZyB0byBjbGFpbSBiYW5kd2lkdGggd2l0aG91dCBhIGNyZWRlbnRpYWwApIkQAGcAAADSVxAATQAAAFcDAAANAAAAdGhlcmUncyBhbHJlYWR5IGFuIGV4aXN0aW5nIGJhbmR3aWR0aCBjbGFpbSBvbmdvaW5nACSKEAAzAAAA0lcQAE0AAABHAwAABQAAANJXEABNAAAAgQMAABEAAABmYWlsZWQgdG8gY2xhaW0gZWNhc2ggYmFuZHdpZHRoIHdpdGggdGhlIGdhdGV3YXkuLi46IAAAAICKEAA1AAAA0lcQAE0AAACGAwAAFQAAAGF0dGVtcHRpbmcgdG8gcmV2ZXJ0IHRpY2tldCB3aXRoZHJhd2FsLi4uAAAA0IoQACkAAADSVxAATQAAAIMDAAAVAAAAdGhpcyB3YXMgZHVlIHRvIG91ciB0aWNrZXQgYmVpbmcgcmVwbGF5ZWQhIGhhdmUgeW91IG1lc3NlZCB3aXRoIHRoZSBkYXRhYmFzZSBmaWxlPwAAFIsQAFIAAADSVxAATQAAAOwAAAAJAAAAQXR0ZW1wdGluZyBnYXRld2F5IHJlY29ubmVjdGlvbi4uLgAAgIsQACIAAADSVxAATQAAAOsAAABQAAAA0lcQAE0AAAD6AAAACQAAAHJlY29ubmVjdGlvbiBhdHRlbXB0IAAAAMyLEAAVAAAA0lcQAE0AAADwAAAADQAAAC4uLgDMixAAFQAAAPyLEAADAAAA0lcQAE0AAADyAAAAEQAAAG1hbmFnZWQgdG8gcmVjb25uZWN0IQAAACCMEAAVAAAA0lcQAE0AAAAAAQAAEQAAANJXEABNAAAABAEAABEAAABmYWlsZWQgdG8gcmVjb25uZWN0IGFmdGVyICBhdHRlbXB0cwBgjBAAGgAAAHqMEAAJAAAA0lcQAE0AAADcAAAAVAAAANJXEABNAAAAAQMAAFQAAADSVxAATQAAABgDAAAmAAAA0lcQAE0AAAAVAwAAKQAAANJXEABNAAAAJwMAAAkAAABtYW5hZ2VkIHRvIGNsYWltIGVjYXNoIGJhbmR3aWR0aOSMEAAgAAAA0lcQAE0AAAAaAQAAXQAAAEdhdGV3YXlDbGllbnQgY29udHJvbCByZXNwb25zZTogUmVjZWl2ZWQgc2h1dGRvd24AAAAcjRAAMQAAANJXEABNAAAAKQEAABUAAABueW1fZ2F0ZXdheV9jbGllbnQ6OmNsaWVudEdhdGV3YXlDbGllbnQgY29udHJvbCByZXNwb25zZTogRXhpdGluZwAAAIKNEAAnAAAA0lcQAE0AAAAqAQAAFQAAAFJvdXRlIHJlY2VpdmVkIGZhaWxlZDogAMSNEAAXAAAA0lcQAE0AAAA8AQAAKQAAANJXEABNAAAAQAEAACEAAABhbGwgYnJhbmNoZXMgYXJlIGRpc2FibGVkIGFuZCB0aGVyZSBpcyBubyBlbHNlIGJyYW5jaAAAAASOEAA1AAAA0lcQAE0AAAAnAQAADQAAANJXEABNAAAAqgMAAAkAAABTZW5kaW5nICBtaXggcGFja2V0c2SOEAAIAAAAbI4QAAwAAADSVxAATQAAAKkDAAAFAAAA0lcQAE0AAABbBAAADQAAAENsYWltaW5nIG1vcmUgYmFuZHdpZHRoIHdpdGggZXhpc3RpbmcgY3JlZGVudGlhbHMuIFN0b3AgdGhlIHByb2Nlc3Mgbm93IGlmIHlvdSBkb24ndCB3YW50IHRoYXQgdG8gaGFwcGVuLgAAAKiOEABpAAAA0lcQAE0AAABRBAAABQAAAGludGVybmFsIGVycm9yOiBlbnRlcmVkIHVucmVhY2hhYmxlIGNvZGXSVxAATQAAAA4EAAASAAAA0lcQAE0AAAAEBAAAVQAAANJXEABNAAAAJwIAAAkAAAAqKiogU1RBUlRJTkcgQUVTMTI4Q1RSLUhNQUMgS0VZIFVQR1JBREUgSU5UTyBBRVMyNTZHQ00tU0lWKioqAAAAhI8QAD0AAADSVxAATQAAAEkCAAAJAAAAc2VuZGluZyB1cGdyYWRlIHJlcXVlc3QgYW5kIGF3YWl0aW5nIHRoZSBhY2tub3dsZWRnZW1lbnQgYmFjawAAANyPEAA9AAAA0lcQAE0AAAAmAgAARAAAANJXEABNAAAAXQIAABEAAAByZWNlaXZlZCBrZXkgdXBncmFkZSBhY2tub3dsZWRnZW1lbnREkBAAJAAAANJXEABNAAAALQMAAFcAAADSVxAATQAAADgDAAAJAAAAbWFuYWdlZCB0byBjbGFpbSB0ZXN0bmV0IGJhbmR3aWR0aAAAkJAQACIAAADSVxAATQAAAK8CAAAFAAAAAAAAAAQAAAAEAAAAGwAAAAAAAAAEAAAABAAAABwAAADSVxAATQAAALcCAAA9AAAA0lcQAE0AAADMAgAADQAAAHRoaXMgZ2F0ZXdheSBpcyBvbiBhbiBvbGQgdmVyc2lvbiB0aGF0IGRvZXNuJ3Qgc3VwcG9ydCBBRVMyNTYtR0NNLVNJVgAAAAyREABFAAAA0lcQAE0AAADPAgAADQAAAHRoaXMgZ2F0ZXdheSBpcyBvbiBhbiBvbGQgdmVyc2lvbiB0aGF0IGRvZXNuJ3Qgc3VwcG9ydCBhdXRoZW50aWNhdGlvbiB2MmyREABIAAAA0lcQAE0AAADSAgAADQAAAHRoaXMgZ2F0ZXdheSBpcyBvbiBhbiBvbGQgdmVyc2lvbiB0aGF0IGRvZXNuJ3Qgc3VwcG9ydCBrZXkgcm90YXRpb24gcGFja2V0cwDMkRAASwAAANJXEABNAAAA1gIAAA0AAABBbHJlYWR5IGF1dGhlbnRpY2F0ZWQAAAAwkhAAFQAAANJXEABNAAAA5gIAADsAAADSVxAATQAAAPUCAAA3AAAA0lcQAE0AAACZAQAANQAAANJXEABNAAAAbAIAACkAAABhdXRoZW50aWNhdGVkOiAsIGJhbmR3aWR0aCByZW1haW5pbmc6IAAAkJIQAA8AAACfkhAAFwAAANJXEABNAAAAeAIAABEAAADSVxAATQAAAGoBAAA1AAAA0lcQAE0AAAB9AQAADQAAANJXEABNAAAAsgEAACkAAADSVxAATQAAAL4BAAAVAAAAZmFpbGVkIHRvIGJhdGNoIHNlbmQgbWVzc2FnZXMgLSAYkxAAIAAAAPyLEAADAAAA0lcQAE0AAADBAQAAGQAAAC4uLiBhbmQgdGhlIGRlbGVnYXRlZCBzdHJlYW0gaGFzIGFsc28gZXJyb3JlZCBvdXQgLSBYkxAANAAAAHJlZ2lzdGVyaW5nIHdpdGggZ2F0ZXdheS4gdXNpbmcgbGVnYWN5IGtleSBkZXJpdmF0aW9uOiAAlJMQADcAAADSVxAATQAAAPMBAAAJAAAA0lcQAE0AAADtAQAAKQAAAMwmEAAqAAAAXQAAAEIAAAByZWFjaGVkIHRlc3QgdGltZW91dCBiZWZvcmUgcmVjZWl2aW5nIGFsbCBwYWNrZXRzLgAABJQQADIAAADMJhAAKgAAAGEAAAANAAAAjygQAB4AAAATAQAALgAAAI8oEAAeAAAAMwEAABsAAACPKBAAHgAAADYBAABSAAAAjygQAB4AAAB3AQAAGwAAAI8oEAAeAAAAkwAAADgAAACPKBAAHgAAAAkBAAAbAAAAX255bS1ub2RlLXRlc3RlcrCUEAAQAAAALQAAAAEAAAAAAAAAyJQQAAEAAACPKBAAHgAAAKEAAABQAAAAdW5zdXBwb3J0ZWQgY3VzdG9tIGdhdGV3YXkgY29uZmlndXJhdGlvbiBpbiB3YXNtIG5vZGUgdGVzdGVy7JQQADwAAACPKBAAHgAAALAAAAANAAAAjygQAB4AAAD8AAAACQAAAI8oEAAeAAAAdgAAABsAAACPKBAAHgAAAHkAAABiAAAAKhYQAB8AAAAcAAAANwAAACoWEAAfAAAAIgAAACkAAAAqFhAAHwAAACMAAAAlAAAAd2hpbGUgcHJlcGFyaW5nIGZvciB0aGUgdGVzdCBydW4sIHdlIGNsZWFyZWQgIG1lc3NhZ2VzIGFuZCAgYWNrcyB0aGF0IHdlcmUgcmVjZWl2ZWQgaW4gdGhlIG1lYW50aW1lLqCVEAAtAAAAzZUQAA4AAADblRAAKQAAACoWEAAfAAAAKwAAAGIAAABuVhAAUAAAAHcAAAABAAAAHQAAADBRAAAQAAAAHgAAAB8AAABgAgAACAAAACAAAAAhAAAAoAkAAAgAAAAiAAAAIwAAALADAAAIAAAAJAAAACUAAABgMwAACAAAACYAAAAnAAAA0FUAABAAAAAoAAAAAAAAAAQAAAAEAAAAKQAAACoAAAAAAAAABAAAAAQAAAArAAAALAAAAAAAAAAEAAAABAAAAC0AAAAuAAAAAAAAAAQAAAAEAAAALwAAADAAAAAAAAAABAAAAAQAAAAxAAAAMgAAAAAAAAAEAAAABAAAADMAAAA0AAAASXcQAGgAAADmAAAAFQAAAMNsEABAAAAAvwAAAAUAAADDbBAAQAAAAMgAAAANAAAAZmFpbGVkIHRvIHByZXBhcmUgY3JlZGVudGlhbCBzcGVuZGluZyByZXF1ZXN0LiBhdHRlbXB0aW5nIHRvIHJldmVydCB3aXRoZHJhd2FsLi4uAAAARJcQAFEAAADDbBAAQAAAANkAAAARAAAAbnltX2JhbmR3aWR0aF9jb250cm9sbGVyw2wQAEAAAAB/AAAABQAAAMNsEABAAAAATQAAAAUAAADDbBAAQAAAAJkAAAAFAAAAw2wQAEAAAABgAAAABQAAAMNsEABAAAAAcwAAAAUAAADDbBAAQAAAAIwAAAAFAAAAFBoQAEIAAACiAAAAAQAAAGFnZ3JlZ2F0ZWQgY29pbiBpbmRleCBzaWduYXR1cmVzIGZvciBlcG9jaCAAOJgQACsAAAAUGhAAQgAAAK8AAAAPAAAAFBoQAEIAAABTAAAAQQAAABQaEABCAAAARgAAAAUAAAAUGhAAQgAAAE4AAAAmAAAAFBoQAEIAAAB5AAAAAQAAAGFnZ3JlZ2F0ZWQgdmVyaWZpY2F0aW9uIGtleSBmb3IgZXBvY2ggAAC8mBAAJgAAABQaEABCAAAAhgAAAA8AAAAUGhAAQgAAANAAAAABAAAAYWdncmVnYXRlZCBjb2luIGluZGV4IHNpZ25hdHVyZXMgZm9yIGRhdGUgAAAMmRAAKgAAABQaEABCAAAA3QAAAA8AAAAUGhAAQgAAAGEAAAABAAAAZmFpbGVkIHRvIG9idGFpbiB2YWxpZCByZXNwb25zZSBmcm9tIEFQSSAAAABgmRAAKQAAAOCEEAACAAAAFBoQAEIAAABqAAAAEQAAAG55bV9iYW5kd2lkdGhfY29udHJvbGxlcjo6dXRpbHMAKhYQAB8AAABYAAAAGwAAACoWEAAfAAAASwAAABsAAADAcBAAVgAAAOIAAAAKAAAANQAAAAwAAAAEAAAANgAAADcAAAA4AEGctMIAC7EKAQAAADkAAABhIERpc3BsYXkgaW1wbGVtZW50YXRpb24gcmV0dXJuZWQgYW4gZXJyb3IgdW5leHBlY3RlZGx5AIJBEABLAAAABQsAAA4AAADZIhAAWAAAAOsHAAAJAAAAZGVzY3JpcHRpb24oKSBpcyBkZXByZWNhdGVkOyB1c2UgRGlzcGxheer0PFohRAVZZs/DHsRlVSY6AAAAIAAAAAQAAAA7AAAAY2FsbGVkIGBSZXN1bHQ6OnVud3JhcCgpYCBvbiBhbiBgRXJyYCB2YWx1ZUVycm9ygkEQAEsAAACwDAAADgAAAIJBEABLAAAAqgwAAA4AAAB7aBAAaQAAAKcAAAAvAAAA1AMQAGAAAACyAQAAMwAAANQDEABgAAAAswEAABsAAADUAxAAYAAAAIsCAAAdAAAA1AMQAGAAAACRAgAADQAAAC0tIDtkmxAAAwAAAGebEAABAAAAdHJhY2luZzo6c3Bhbk5vbmUAAAAAAAAABAAAAAQAAAA8AAAAU29tZQAAAAAEAAAABAAAAD0AAAB5MxAASgAAAJQIAAAfAAAAMlEQADUAAAAWAAAACgAAAD4AAAAAAAAABAAAAAQAAAA/AAAAQmFzZUNsaWVudEVycm9yc291cmNlAAAAAAAAAAQAAAAEAAAAQAAAAEludmFsaWRHYXRld2F5SWRlbnRpdHkAAAAAAAAEAAAABAAAAEEAAABHYXRld2F5Q2xpZW50RXJyb3IAAAAAAAAEAAAABAAAAEIAAABOeW1BcGlFcnJvcgAAAAAABAAAAAQAAABDAAAATnltQXBpUXVlcnlFcnJvcgAAAAAEAAAABAAAAEQAAABXYXNtVG9wb2xvZ3lFcnJvcgAAAAAAAAAEAAAABAAAAEUAAABUb3BvbG9neUVycm9yAAAANQAAAAwAAAAEAAAARgAAAAAAAAAEAAAABAAAAEcAAABNYWxmb3JtZWRVcmxyYXdVbmF2YWlsYWJsZU5ldHdvcmtUb3BvbG9neU5vbkV4aXN0ZW50TWl4bm9kZW1peG5vZGVfaWRlbnRpdHlOb25FeGlzdGVudEdhdGV3YXlnYXRld2F5X2lkZW50aXR5AAAAAAAAAAQAAAAEAAAASAAAAE1hbGZvcm1lZFJlY2lwaWVudAAAAAAAAAQAAAAEAAAASQAAAE1hbGZvcm1lZFNlbmRlclRhZwAAAAAAAAQAAAAEAAAASgAAAEJhc2VTdG9yYWdlRXJyb3IAAAAABAAAAAQAAABLAAAAQ2xpZW50U3RvcmFnZUVycm9yAAAAAAAABAAAAAQAAABMAAAATWFsZm9ybWVkR2F0ZXdheUFscmVhZHlSZWdpc3RlcmVkZ2F0ZXdheV9pZCBzcGFuPQAAAAEAAAAAAAAAH54QAAYAAAAtVBAASgAAAL0BAAAdAAAAAAAAADAAAAAIAAAATQAAAAAAAAAEAAAABAAAAE4AAAAAAAAABAAAAAQAAABPAAAATm9kZXNSZXNwb25zZU1ldGFkYXRhc3RhdHVzYWJzb2x1dGVfZXBvY2hfaWRyb3RhdGlvbl9pZHJlZnJlc2hlZF9hdAAAAAAABAAAAAQAAABQAAAAVW5pZm9ybVJlbW90ZW11c3RfdXNlX3Rsc1JlbW90ZUJ5TGF0ZW5jeQAAAAABAAAAAQAAAFEAAABTcGVjaWZpZWRpZGVudGl0eQAAAAAAAAAEAAAABAAAAFIAAABDdXN0b21hZGRpdGlvbmFsX2RhdGEAAAAEAAAAAAAAAAQAAAAEAEHYvsIAC4UTDAAAAFRoaXMgc2hvdWxkIGhhdmUgTkVWRVIgaGFwcGVuZWQgLSByZXR1cm5lZCBhIHN0cmVhbSBiZWZvcmUgcmVjZWl2aW5nIG5vdGlmaWNhdGlvbgAAAFyfEABRAAAAX0YQAE8AAABUAQAADQAAAF9GEABPAAAASgEAAEsAAABfRhAATwAAAGgBAAArAAAARmllbGRTZXQgY29ycnVwdGVkICh0aGlzIGlzIGEgYnVnKQAA0lcQAE0AAAClAgAACQAAAGF1dGhlbnRpY2F0aW5nIHdpdGggZ2F0ZXdheQAcoBAAGwAAAAAAAAAYAAAABAAAABIAAADSVxAATQAAAKECAABWAAAA0lcQAE0AAACCAgAACQAAAHVzaW5nIHYxIGF1dGhlbnRpY2F0aW9uAHCgEAAXAAAA0lcQAE0AAACBAgAASwAAANJXEABNAAAAlwIAAAkAAAB1c2luZyB2MiBhdXRoZW50aWNhdGlvbgCwoBAAFwAAANJXEABNAAAAlgIAAEsAAADSVxAATQAAANwAAABUAAAA0lcQAE0AAAABAwAAVAAAANJXEABNAAAAGgEAAF0AAABHYXRld2F5Q2xpZW50IGNvbnRyb2wgcmVzcG9uc2U6IFJlY2VpdmVkIHNodXRkb3duAAAAEKEQADEAAADSVxAATQAAACkBAAAVAAAAbnltX2dhdGV3YXlfY2xpZW50OjpjbGllbnRHYXRld2F5Q2xpZW50IGNvbnRyb2wgcmVzcG9uc2U6IEV4aXRpbmcAAAB2oRAAJwAAANJXEABNAAAAKgEAABUAAABSb3V0ZSByZWNlaXZlZCBmYWlsZWQ6IAC4oRAAFwAAANJXEABNAAAAPAEAACkAAADSVxAATQAAAEABAAAhAAAAYWxsIGJyYW5jaGVzIGFyZSBkaXNhYmxlZCBhbmQgdGhlcmUgaXMgbm8gZWxzZSBicmFuY2gAAAD4oRAANQAAANJXEABNAAAAJwEAAA0AAABpbnRlcm5hbCBlcnJvcjogZW50ZXJlZCB1bnJlYWNoYWJsZSBjb2Rl0lcQAE0AAAAOBAAAEgAAANJXEABNAAAABAQAAFUAAADSVxAATQAAAK8CAAAFAAAA0lcQAE0AAADMAgAADQAAAHRoaXMgZ2F0ZXdheSBpcyBvbiBhbiBvbGQgdmVyc2lvbiB0aGF0IGRvZXNuJ3Qgc3VwcG9ydCBBRVMyNTYtR0NNLVNJVgAAALCiEABFAAAA0lcQAE0AAADPAgAADQAAAHRoaXMgZ2F0ZXdheSBpcyBvbiBhbiBvbGQgdmVyc2lvbiB0aGF0IGRvZXNuJ3Qgc3VwcG9ydCBhdXRoZW50aWNhdGlvbiB2MhCjEABIAAAA0lcQAE0AAADSAgAADQAAAHRoaXMgZ2F0ZXdheSBpcyBvbiBhbiBvbGQgdmVyc2lvbiB0aGF0IGRvZXNuJ3Qgc3VwcG9ydCBrZXkgcm90YXRpb24gcGFja2V0cwBwoxAASwAAANJXEABNAAAA1gIAAA0AAABBbHJlYWR5IGF1dGhlbnRpY2F0ZWQAAADUoxAAFQAAANJXEABNAAAA5gIAADsAAADSVxAATQAAAPUCAAA3AAAA0lcQAE0AAACZAQAANQAAANJXEABNAAAAbAIAACkAAABhdXRoZW50aWNhdGVkOiAsIGJhbmR3aWR0aCByZW1haW5pbmc6IAAANKQQAA8AAABDpBAAFwAAANJXEABNAAAAeAIAABEAAADSVxAATQAAAGoBAAA1AAAA0lcQAE0AAAB9AQAADQAAAHJlZ2lzdGVyaW5nIHdpdGggZ2F0ZXdheS4gdXNpbmcgbGVnYWN5IGtleSBkZXJpdmF0aW9uOiAAnKQQADcAAADSVxAATQAAAPMBAAAJAAAA0lcQAE0AAADtAQAAKQAAAIdsEAA7AAAAsAUAAAUAAABzdGF0dXM6ICAoc3VjY2VzczogKQylEAAIAAAAFKUQAAsAAAAfpRAAAQAAAIdsEAA7AAAAsQUAAAUAAABoZWFkZXJzOiAAAABIpRAACQAAAIdsEAA7AAAApwUAAAEAAACHbBAAOwAAAOIEAAAFAAAAZXBvY2hfaWR2MWVjYXNobWFzdGVyLXZlcmlmaWNhdGlvbi1rZXkAAISlEAACAAAAhqUQAAUAAACLpRAAFwAAAP9cEABQAAAASAQAADcAAABhZ2dyZWdhdGVkLWNvaW4taW5kaWNlcy1zaWduYXR1cmVzAACEpRAAAgAAAIalEAAFAAAAzKUQACIAAAD/XBAAUAAAADMEAABGAAAA/1wQAFAAAAAcBAAALgAAAGV4cGlyYXRpb25fZGF0ZQD/XBAAUAAAACEEAAAUAAAAYWdncmVnYXRlZC1leHBpcmF0aW9uLWRhdGUtc2lnbmF0dXJlcwAAAISlEAACAAAAhqUQAAUAAABIphAAJQAAAP9cEABQAAAAFwQAAEkAAADAcBAAVgAAAOIAAAAKAAAAZGVzY3JpcHRpb24oKSBpcyBkZXByZWNhdGVkOyB1c2UgRGlzcGxheQ/yOxS3FZuVnAAp2smtCRtVAAAADAAAAAQAAABWAAAAY2FsbGVkIGBSZXN1bHQ6OnVud3JhcCgpYCBvbiBhbiBgRXJyYCB2YWx1ZQBXAAAAIAAAAAQAAAA7AAAAWAAAAAwAAAAEAAAAWQAAAFgAAAAMAAAABAAAAFoAAABZAAAALKcQAFsAAABcAAAAXQAAAF4AAABfAAAASW5zdWZmaWNpZW50VHlwZUluZm9ybWF0aW9uAAAAAAAEAAAABAAAAGAAAABJbnZhbGlkQ29tcG9uZW50AAAAAAQAAAAEAAAAYQAAAENvbXBvbmVudFJhbmdlAAAAAAAABAAAAAQAAABiAAAAU3RkSW8AAAB6MRAAXgAAACwAAAAKAAAAnVwQAGEAAAAiAAAAAQAAAHByb21pc2UgcmVzb2x2ZWQgdG8gdW5leHBlY3RlZCB0eXBlAPlIEABmAAAAYwAAADYAAAByZXNwb25zZS50ZXh0IGlzbid0IHN0cmluZwAA+UgQAGYAAAB1AAAANgAAAPlIEABmAAAAggAAABkAAAAgc3Bhbj0AAAEAAAAAAAAAbKgQAAYAAAA8LSA7hKgQAAMAAACHqBAAAQAAAHRyYWNpbmc6OnNwYW46OmFjdGl2ZS0+IK2oEAADAAAAh6gQAAEAAAAtVBAASgAAAL0BAAAdAAAABAAAAAAAAAAEAAAABABB6NHCAAvUAQwAAACHbBAAOwAAAKsFAAABAAAARmllbGRTZXQgY29ycnVwdGVkICh0aGlzIGlzIGEgYnVnKQAAh2wQADsAAACwBQAABQAAAHN0YXR1czogIChzdWNjZXNzOiApMKkQAAgAAAA4qRAACwAAAEOpEAABAAAAAAAAABgAAAAEAAAAEgAAAIdsEAA7AAAAsQUAAAUAAABoZWFkZXJzOiAAAAB8qRAACQAAAIdsEAA7AAAApwUAAAEAAABhcHBsaWNhdGlvbi9qc29uAAAAAAAAAAACAACAAEHJ08IAC6AGGQAAoKkQABAAAAAAAAAACwAAAIdsEAA7AAAABgYAAAUAAABhdHRlbXB0aW5nIHRvIHBhcnNlIHJlc3BvbnNlIGFzIOypEAAgAAAAYXBwbGljYXRpb25qc29uYmluY29kZQAAh2wQADsAAAANBgAADQAAAHVucmVjb2duaXNlZCBtaW1lIHR5cGUgLiBmYWxsaW5nIGJhY2sgdG8ganNvbiBkZWNvZGluZy4uLgAAADyqEAAXAAAAU6oQACIAAABkAAAAoAIAAAgAAABlAAAAZgAAAKACAAAIAAAAZwAAAGgAAACgAgAACAAAAGkAAACHbBAAOwAAAPMEAAAFAAAAagAAAHgAAAAIAAAAawAAAGwAAAB4AAAACAAAAG0AAABuAAAAeAAAAAgAAABvAAAAh2wQADsAAADWBAAABQAAAAAAAAAEAAAABAAAAHAAAACHbBAAOwAAAOIEAAAFAAAAcQAAAIgAAAAIAAAAcgAAAP9cEABQAAAARAQAAAUAAAAAAAAABAAAAAQAAABzAAAAZXBvY2hfaWR2MWVjYXNobWFzdGVyLXZlcmlmaWNhdGlvbi1rZXkAAGCrEAACAAAAYqsQAAUAAABnqxAAFwAAAP9cEABQAAAASAQAADcAAAB0AAAAiAAAAAgAAAB1AAAA/1wQAFAAAAAvBAAABQAAAGFnZ3JlZ2F0ZWQtY29pbi1pbmRpY2VzLXNpZ25hdHVyZXMAAGCrEAACAAAAYqsQAAUAAADIqxAAIgAAAP9cEABQAAAAMwQAAEYAAAB2AAAAkAAAAAgAAAB3AAAA/1wQAFAAAAASBAAABQAAAAAAAAAEAAAABAAAAHgAAAD/XBAAUAAAABwEAAAuAAAAZXhwaXJhdGlvbl9kYXRlAP9cEABQAAAAIQQAABQAAABhZ2dyZWdhdGVkLWV4cGlyYXRpb24tZGF0ZS1zaWduYXR1cmVzAAAAYKsQAAIAAABiqxAABQAAAHSsEAAlAAAA/1wQAFAAAAAXBAAASQAAAMBwEABWAAAA4gAAAAoAAAB5AAAADAAAAAQAAAB6AAAAewAAADgAQfTZwgALjQwBAAAAfAAAAGEgRGlzcGxheSBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB1bmV4cGVjdGVkbHkAgkEQAEsAAAAFCwAADgAAAGRlc2NyaXB0aW9uKCkgaXMgZGVwcmVjYXRlZDsgdXNlIERpc3BsYXkP8jsUtxWblZwAKdrJrQkbfQAAAAwAAAAEAAAAfgAAAGNhbGxlZCBgUmVzdWx0Ojp1bndyYXAoKWAgb24gYW4gYEVycmAgdmFsdWUAX24QAFgAAACNAAAAKgAAAF9uEABYAAAAoQAAACsAAABfbhAAWAAAAKEAAAAqAAAARXJyb3IAAACCQRAASwAAALAMAAAOAAAAgkEQAEsAAACqDAAADgAAAH8AAAAMAAAABAAAAFkAAAB/AAAADAAAAAQAAABaAAAAWQAAABCuEACAAAAAgQAAAIIAAABeAAAAgwAAAC0tIDtMrhAAAwAAAE+uEAABAAAAdHJhY2luZzo6c3Bhbkluc3VmZmljaWVudFR5cGVJbmZvcm1hdGlvbgAAAAAEAAAABAAAAGAAAABJbnZhbGlkQ29tcG9uZW50AAAAAAQAAAAEAAAAYQAAAENvbXBvbmVudFJhbmdlAAAAAAAABAAAAAQAAABiAAAAU3RkSW8AAAB6MRAAXgAAACwAAAAKAAAAnVwQAGEAAAAiAAAAAQAAAHByb21pc2UgcmVzb2x2ZWQgdG8gdW5leHBlY3RlZCB0eXBlAPlIEABmAAAAYwAAADYAAAByZXNwb25zZS50ZXh0IGlzbid0IHN0cmluZwAA+UgQAGYAAAB1AAAANgAAAPlIEABmAAAAggAAABkAAAAgc3Bhbj0AAAEAAAAAAAAAcK8QAAYAAAAtVBAASgAAAL0BAAAdAAAAZmllbGRfdHlwZWtleWRhdGFzdHJ1Y3QgUHJvb2ZPcCB3aXRoIDMgZWxlbWVudHMAqa8QAB4AAAAAAAAACAAAAAQAAACEAAAAb3Bzc3RydWN0IFByb29mT3BzIHdpdGggMSBlbGVtZW50AAAA468QAB4AAABlbmNvZGVkX2lkZW50aXR5bm9kZV9pZHR5cGVzdHJ1Y3QgVGVzdGFibGVOb2RlIHdpdGggMyBlbGVtZW50cwAAJ7AQACMAAABqc29ucnBjaWRyZXN1bHRlcnJvcnN0cnVjdCBXcmFwcGVyIHdpdGggNCBlbGVtZW50cwAAaLAQAB4AAAByZXNwb25zZXN0cnVjdCBSZXNwb25zZSB3aXRoIDEgZWxlbWVudAAAmLAQAB4AAABjb2RlbG9naW5mb2luZGV4dmFsdWVwcm9vZmhlaWdodGNvZGVzcGFjZXN0cnVjdCBWZXJpZmljYXRpb25LZXlSZXNwb25zZSB3aXRoIDEgZWxlbWVudAAA6bAQAC0AAABhbHBoYWJldGFfZzFiZXRhX2cyc3RydWN0IFZlcmlmaWNhdGlvbktleUF1dGggd2l0aCAzIGVsZW1lbnRzAAAAM7EQACoAAABAUBAAQQAAAA4AAAAVAAAAdGVzdGVkX25vZGVtc2dfaWR0b3RhbF9tc2dzc2hhcmVhbm5vdW5jZV9hZGRyZXNzbm9kZV9pbmRleG93bmVyZXBvY2hfaWR2ZXJpZmllZHN0cnVjdCBDb250cmFjdFZLU2hhcmUgd2l0aCA2IGVsZW1lbnRzAAAAx7EQACYAAABzaWduYXR1cmVzc3RydWN0IEFnZ3JlZ2F0ZWRDb2luSW5kaWNlc1NpZ25hdHVyZVJlc3BvbnNlIHdpdGggMiBlbGVtZW50cwACshAAPQAAAHNoYXJlc3Blcl9wYWdlc3RhcnRfbmV4dF9hZnRlcnN0cnVjdCBQYWdlZFZLU2hhcmVzUmVzcG9uc2Ugd2l0aCAzIGVsZW1lbnRzAABmshAALAAAAGV4cGlyYXRpb25fZGF0ZXN0cnVjdCBBZ2dyZWdhdGVkRXhwaXJhdGlvbkRhdGVTaWduYXR1cmVSZXNwb25zZSB3aXRoIDMgZWxlbWVudHMAq7IQAEAAAAB6UxAAXgAAAAcHAAARAEGM5sIACxUBAAAAhQAAAHpTEABeAAAA1AYAABEAQazmwgALBQEAAACGAEG85sIACwUBAAAAhgBBzObCAAsFAQAAAIYAQdzmwgALBQEAAACGAEHs5sIACyUBAAAAhwAA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FAEAACEAAAAmERAAPgAAABkBAAASAAAAJhEQAD4AAAAlAQAAFQAAACYREAA+AAAAIAEAABUAAAC5AAAAOAAAAAgAAAC6AAAAZmIQAEwAAAA8AAAABQAAAGFwcGxpY2F0aW9uL2pzb25SCBAAUAAAAEcAAABJAAAAAAAAAB0AQdT2wgALMW55bS1yZXF3ZXN0LXJwYy1jbGllbnQvMC4xLjBSCBAAUAAAAEwAAAASAAAAAAAAAEYAQZD3wgALFVIIEABQAAAATwAAAEAAAAAAAAAAEABBsPfCAAs1UggQAFAAAABgAAAABQAAAMBwEABWAAAA4gAAAAoAAAC7AAAADAAAAAQAAAC8AAAAvQAAADgAQfD3wgALwwEBAAAAvgAAAGEgRGlzcGxheSBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB1bmV4cGVjdGVkbHkAgkEQAEsAAAAFCwAADgAAANkiEABYAAAA6wcAAAkAAABkZXNjcmlwdGlvbigpIGlzIGRlcHJlY2F0ZWQ7IHVzZSBEaXNwbGF5D/I7FLcVm5WcACnaya0JG2NhbGxlZCBgUmVzdWx0Ojp1bndyYXAoKWAgb24gYW4gYEVycmAgdmFsdWUAQbz5wgAL2Q4BAAAAvwAAAGFjY2VwdGFjY2VwdC1jaGFyc2V0YWNjZXB0LWVuY29kaW5nYWNjZXB0LWxhbmd1YWdlYWNjZXB0LXJhbmdlc2FjY2Vzcy1jb250cm9sLWFsbG93LWNyZWRlbnRpYWxzYWNjZXNzLWNvbnRyb2wtYWxsb3ctaGVhZGVyc2FjY2Vzcy1jb250cm9sLWFsbG93LW1ldGhvZHNhY2Nlc3MtY29udHJvbC1hbGxvdy1vcmlnaW5hY2Nlc3MtY29udHJvbC1leHBvc2UtaGVhZGVyc2FjY2Vzcy1jb250cm9sLW1heC1hZ2VhY2Nlc3MtY29udHJvbC1yZXF1ZXN0LWhlYWRlcnNhY2Nlc3MtY29udHJvbC1yZXF1ZXN0LW1ldGhvZGFnZWFsbG93YWx0LXN2Y2F1dGhvcml6YXRpb25jYWNoZS1jb250cm9sY2FjaGUtc3RhdHVzY2RuLWNhY2hlLWNvbnRyb2xjb25uZWN0aW9uY29udGVudC1kaXNwb3NpdGlvbmNvbnRlbnQtZW5jb2Rpbmdjb250ZW50LWxhbmd1YWdlY29udGVudC1sZW5ndGhjb250ZW50LWxvY2F0aW9uY29udGVudC1yYW5nZWNvbnRlbnQtc2VjdXJpdHktcG9saWN5Y29udGVudC1zZWN1cml0eS1wb2xpY3ktcmVwb3J0LW9ubHljb250ZW50LXR5cGVjb29raWVkbnRkYXRlZXRhZ2V4cGVjdGV4cGlyZXNmb3J3YXJkZWRmcm9taG9zdGlmLW1hdGNoaWYtbW9kaWZpZWQtc2luY2VpZi1ub25lLW1hdGNoaWYtcmFuZ2VpZi11bm1vZGlmaWVkLXNpbmNlbGFzdC1tb2RpZmllZGxpbmtsb2NhdGlvbm1heC1mb3J3YXJkc29yaWdpbnByYWdtYXByb3h5LWF1dGhlbnRpY2F0ZXByb3h5LWF1dGhvcml6YXRpb25wdWJsaWMta2V5LXBpbnNwdWJsaWMta2V5LXBpbnMtcmVwb3J0LW9ubHlyYW5nZXJlZmVyZXJyZWZlcnJlci1wb2xpY3lyZWZyZXNocmV0cnktYWZ0ZXJzZWMtd2Vic29ja2V0LWFjY2VwdHNlYy13ZWJzb2NrZXQtZXh0ZW5zaW9uc3NlYy13ZWJzb2NrZXQta2V5c2VjLXdlYnNvY2tldC1wcm90b2NvbHNlYy13ZWJzb2NrZXQtdmVyc2lvbnNlcnZlcnNldC1jb29raWVzdHJpY3QtdHJhbnNwb3J0LXNlY3VyaXR5dGV0cmFpbGVydHJhbnNmZXItZW5jb2Rpbmd1c2VyLWFnZW50dXBncmFkZXVwZ3JhZGUtaW5zZWN1cmUtcmVxdWVzdHN2YXJ5dmlhd2FybmluZ3d3dy1hdXRoZW50aWNhdGV4LWNvbnRlbnQtdHlwZS1vcHRpb25zeC1kbnMtcHJlZmV0Y2gtY29udHJvbHgtZnJhbWUtb3B0aW9uc3gteHNzLXByb3RlY3Rpb25PUFRJT05TR0VUUE9TVFBVVERFTEVURUhFQURUUkFDRUNPTk5FQ1RQQVRDSGNhbm5vdCBzYW1wbGUgZW1wdHkgcmFuZ2VgQBAAVwAAAIYAAAAJAAAARXJyb3IAAACCQRAASwAAALAMAAAOAAAAgkEQAEsAAACqDAAADgAAALsAAAAMAAAABAAAAFkAAAC7AAAADAAAAAQAAABaAAAAWQAAALDBEADAAAAAwQAAAMIAAABeAAAAwwAAACAOEABkAAAAvQAAADkAAAB1cmwgcGFyc2VoZWFkZXJzIHRyeV9pdGVyaGVhZGVycyBoYXZlIGFuIGl0ZXJhdG9yaGVhZGVycyBpdGVyYXRvciBkb2Vzbid0IHRocm93c2VyaWFsaXplZCBoZWFkZXJzZGVzZXJpYWxpemFibGUgc2VyaWFsaXplZCBoZWFkZXJzSnNWYWx1ZSgicmVxd2VzdDo6ZXJyb3JzOjpUaW1lZE91dCIpAACdXBAAYQAAACIAAAABAAAAcHJvbWlzZSByZXNvbHZlZCB0byB1bmV4cGVjdGVkIHR5cGUAowgQAGUAAACdAQAAOAAAAPlIEABmAAAAdQAAADYAAAD5SBAAZgAAAIIAAAAZAAAALVQQAEoAAAC9AQAAHQAAACIsEABkAAAAewAAACMAAADCKxAAXwAAAKkIAAAWAAAAfXsAANETEABfAAAApAAAACcAAABtaXhub2RlZ2F0ZXdheQAATMMQAAcAAABTwxAABwAAAGVuY29kZWRfaWRlbnRpdHlub2RlX2lkdHlwZXRlc3RlZF9ub2RlbXNnX2lkdG90YWxfbXNnc3N0cnVjdCBUZXN0TWVzc2FnZVRlc3RhYmxlTm9kZWzDEAAQAAAAfMMQAAcAAACDwxAABAAAAEBQEABBAAAAPwAAABgAAABAUBAAQQAAAEEAAAASAAAAoRgQAEsAAAD4AQAADgAAANkiEABYAAAA6wcAAAkAQaCIwwALkQEBAAAAxAAAAGNhbGxlZCBgUmVzdWx0Ojp1bndyYXAoKWAgb24gYW4gYEVycmAgdmFsdWUAAAAAAAgAAAAEAAAAxQAAAGNhbm5vdCBzYW1wbGUgZW1wdHkgcmFuZ2UAAABgQBAAVwAAAIYAAAAJAAAAWzgQAFwAAAB4AAAAJwAAAFN0cmVhbUNpcGhlckVycm9yAEG8icMAC/8DaFEQAD4AAAAJAAAAKQAAAFNpemVFcnJvcgAAAPR7EABgAAAASgAAAB4AAAD0exAAYAAAAEoAAAAoAAAAEWsQAGIAAABDAgAANwAAAC1UEABKAAAAvQEAAB0AAAB6UxAAXgAAAFgHAAARAAAAj2YQAEoAAACcAAAACQAAACdgEABMAAAAwAEAAA4AAAAnYBAATAAAAM8BAABEAAAAJ2AQAEwAAAASAgAAFAAAACdgEABMAAAAEwIAABQAAAAnYBAATAAAABQCAAAUAAAAJ2AQAEwAAAAVAgAAIgAAACdgEABMAAAAMwIAACIAAAAnYBAATAAAADUCAAAUAAAAJ2AQAEwAAAA2AgAAFAAAACdgEABMAAAANwIAABQAAAAnYBAATAAAAN4BAAAWAAAAJ2AQAEwAAADfAQAAFAAAACdgEABMAAAA4wEAABAAAAAnYBAATAAAAOYBAAARAAAAJ2AQAEwAAADqAQAARQAAACdgEABMAAAA6wEAABAAAAAnYBAATAAAAO8BAAAQAAAAJ2AQAEwAAADzAQAAEAAAACdgEABMAAAA+gEAABAAAAAnYBAATAAAAP0BAAASAAAAJ2AQAEwAAAADAgAARgAAACdgEABMAAAABQIAACsAAAAnYBAATAAAAAsCAAAZAAAAxgAAAAAAAAD//////////7DGEABByI3DAAtpV3JhcHBlcmpzb25ycGNpZHJlc3VsdGVycm9yAM/GEAAHAAAA1sYQAAIAAADYxhAABgAAAN7GEAAFAAAAc3RydWN0IFdyYXBwZXIAAGYTEABqAAAAVQAAAA8AAAAEAAAAAAAAAAQAAAAEAEG8jsMAC50ODAAAAFNsaWNlIGhhZCBieXRlcyByZW1haW5pbmcgYWZ0ZXIgZGVzZXJpYWxpemF0aW9uYXR0ZW1wdGVkIHRvIHRha2Ugb3duZXJzaGlwIG9mIFJ1c3QgdmFsdWUgd2hpbGUgaXQgd2FzIGJvcnJvd2VkRmllbGRTZXQgY29ycnVwdGVkICh0aGlzIGlzIGEgYnVnKSVsEAA0AAAAXQIAABEAAABhdHRlbXB0aW5nIHRvIHRlc3Qgbm9kZSBpbiAnc3RhbmRieScgbW9kZSAtIGFyZSB5b3Ugc3VyZSB0aGF0J3Mgd2hhdCB5b3UgbWVhbnQgdG8gZG8/AAAA4McQAFUAAAAAAAAAGAAAAAQAAAASAAAAJWwQADQAAACtAQAAKgAAACVsEAA0AAAAtAEAACAAAAAlbBAANAAAAA0CAAAdAAAAJWwQADQAAAAPAgAAEwAAACVsEAA0AAAAEAIAABMAAAAlbBAANAAAABECAAATAAAAJWwQADQAAAAuAgAAEwAAAENhY2hlZEVwb2NoUmV3YXJkZWRTZXRlcG9jaF9pZGVudHJ5X2dhdGV3YXlzZXhpdF9nYXRld2F5c2xheWVyMWxheWVyMmxheWVyM3N0YW5kYnkAANbIEAAIAAAA3sgQAA4AAADsyBAADQAAAPnIEAAGAAAA/8gQAAYAAAAFyRAABgAAAAvJEAAHAAAAV2FzbUZyaWVuZGx5TnltVG9wb2xvZ3ltZXRhZGF0YXJld2FyZGVkU2V0bm9kZURldGFpbHMAAABjyRAACAAAAGvJEAALAAAAdskQAAsAAABXYXNtRnJpZW5kbHlSb3V0aW5nTm9kZW5vZGVJZG1peEhvc3RlbnRyeWlkZW50aXR5S2V5c3BoaW54S2V5c3VwcG9ydGVkUm9sZXMAs8kQAAYAAAC5yRAABwAAAMDJEAAFAAAAxckQAAsAAADQyRAACQAAANnJEAAOAAAATnltVG9wb2xvZ3lNZXRhZGF0YWtleV9yb3RhdGlvbl9pZGFic29sdXRlX2Vwb2NoX2lkcmVmcmVzaGVkX2F0ACvKEAAPAAAAOsoQABEAAABLyhAADAAAAEVudHJ5RGV0YWlsc2lwX2FkZHJlc3Nlc2NsaWVudHNfd3NfcG9ydGhvc3RuYW1lY2xpZW50c193c3NfcG9ydAB8yhAADAAAAIjKEAAPAAAAl8oQAAgAAACfyhAAEAAAAFN1cHBvcnRlZFJvbGVzbWl4bm9kZW1peG5ldF9lbnRyeW1peG5ldF9leGl03soQAAcAAADlyhAADAAAAPHKEAALAAAAQWJjaVF1ZXJ5Y29kZWxvZ2luZm9pbmRleGtleXZhbHVlcHJvb2Zwcm9vZk9wc2hlaWdodGNvZGVzcGFjZQAAAB3LEAAEAAAAIcsQAAMAAAAkyxAABAAAACjLEAAFAAAALcsQAAMAAAAwyxAABQAAADXLEAAFAAAAOssQAAgAAABCyxAABgAAAEjLEAAJAAAAcGF0aGRhdGFwcm92ZVJlc3BvbnNlcmVzcG9uc2UAAAC5yxAACAAAAGZpZWxkIGlkZW50aWZpZXJ0ZXN0X2lkAMwmEAAqAAAAQgAAABUAAAByZWNlaXZlZCBhbiBhY2sgdGhhdCB3YXMgbm90IHBhcnQgb2YgdGhlIHRlc3QhIChpZDogKQAAAPTLEAA0AAAAKMwQAAEAAADMJhAAKgAAAEgAAAAZAAAAYWxyZWFkeSByZWNlaXZlZCBhbGwgdGhlIHBhY2tldHMhIGZpbmlzaGlu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Y3RseSB0aGUgc2FtZSAob3Igb2xkZXIpIHByb3RvY29sIHZlcnNpb24gYXMgd2UgYXJlLiBXZSdyZSBnb29kIHRvIGNvbnRpbnVlIfTWEABkAAAA0lcQAE0AAADfAQAAEQAAAAEAAAAAAAAAbm8gc2hhcmVkIGtleSBwcmVzZW50IGV2ZW4gdGhvdWdoIHdlJ3JlIGF1dGhlbnRpY2F0ZWQhAADSVxAATQAAAJ0DAAASAAAA0lcQAE0AAAA/AwAALAAAANJXEABNAAAAKgQAACIAAABhc3NlcnRpb24gZmFpbGVkOiBzZWxmLmF1dGhlbnRpY2F0ZWTSVxAATQAAAJYEAAAJAAAAYXNzZXJ0aW9uIGZhaWxlZDogc2VsZi5jb25uZWN0aW9uLmlzX2F2YWlsYWJsZSgp0lcQAE0AAACXBAAACQAAAGFzc2VydGlvbiBmYWlsZWQ6IHNlbGYuc2hhcmVkX2tleS5pc19zb21lKCkA0lcQAE0AAACYBAAACQAAAGEgbWFwc3RydWN0IFZlcmlmaWNhdGlvbktleVJlc3BvbnNlIHdpdGggMSBlbGVtZW50AACV2BAALQAAAAAAAAAIAAAABAAAAIQAAABzdHJ1Y3QgVmVyaWZpY2F0aW9uS2V5QXV0aCB3aXRoIDMgZWxlbWVudHMAANzYEAAqAAAAjygQAB4AAAD8AAAAIAAAANsAAAAIAQAACAAAANwAAAD3JhAAQgAAAF0AAAAFAAAAU2ltcGxlTWVzc2FnZVJlY2VpdmVyOiByZWNlaXZlZCBzaHV0ZG93bkDZEAAoAAAAZmFpbGVkIHRvIHByb2Nlc3MgcmVjZWl2ZWQgbWl4bmV0IG1lc3NhZ2U6IABw2RAAKwAAAHRoZSBtaXhuZXQgbWVzc2FnZXMgc3RyZWFtIGhhcyB0ZXJtaW5hdGVkIQAApNkQACoAAABmYWlsZWQgdG8gcHJvY2VzcyByZWNlaXZlZCBhY2sgbWVzc2FnZTog2NkQACgAAAB0aGUgYWNrIG1lc3NhZ2VzIHN0cmVhbSBoYXMgdGVybWluYXRlZCEACNoQACcAAABTaW1wbGVNZXNzYWdlUmVjZWl2ZXI6IEV4aXRpbmcAADjaEAAeAAAAYWxsIGJyYW5jaGVzIGFyZSBkaXNhYmxlZCBhbmQgdGhlcmUgaXMgbm8gZWxzZSBicmFuY2gAAABg2hAANQAAAPcmEABCAAAAXwAAAA0AAABzdHJ1Y3QgQWdncmVnYXRlZENvaW5JbmRpY2VzU2lnbmF0dXJlUmVzcG9uc2Ugd2l0aCAyIGVsZW1lbnRzAAAAsNoQAD0AAABzdHJ1Y3QgQWdncmVnYXRlZEV4cGlyYXRpb25EYXRlU2lnbmF0dXJlUmVzcG9uc2Ugd2l0aCAzIGVsZW1lbnRz+NoQAEAAAADdAAAAEAAAAAgAAADeAAAA3QAAABAAAAAIAAAA3wAAAN4AAABA2xAA4AAAAOEAAADiAAAA4wAAAOQAAABkZXNjcmlwdGlvbigpIGlzIGRlcHJlY2F0ZWQ7IHVzZSBEaXNwbGF51C7DOIkdlv4JoVxRxKOLX05vbmUAAAAABAAAAAQAAADUAAAAU29tZQAAAAAEAAAABAAAADwAAABEYXRhYmFzZUluY29uc2lzdGVuY3lyZWFzb25JbmNvbnNpc3RlbnREYXRhTm9DcmVkZW50aWFsAAAAAAAEAAAABAAAAOUAAABOb1NpZ25hdHVyZXNlcG9jaF9pZENvbnN0cmFpbnRVbmlxdWUtVBAASgAAAL0BAAAdAAAAPTIQADIAAAAWAAAAJwAAAGF0dGVtcHRlZCB0byB0YWtlIG93bmVyc2hpcCBvZiBSdXN0IHZhbHVlIHdoaWxlIGl0IHdhcyBib3Jyb3dlZFByb29mT3BmaWVsZF90eXBldHlwZWtleWRhdGEArtwQAAoAAAC43BAABAAAALzcEAADAAAAv9wQAAQAAABQcm9vZk9wc29wcwDs3BAAAwAAAOkAAAA4AAAACAAAAOoAAAB0VxAAXQAAAHQAAAAFAAAAYnVmZmVyIHNwYWNlIGV4aGF1c3RlZDsgc2VuZGluZyB0aGlzIG1lc3NhZ2VzIHdvdWxkIG92ZXJmbG93IHRoZSBzdGF0ZQAA/WEQAGgAAAC4AQAADQAAAGFzc2VydGlvbiBmYWlsZWQ6ICgqdGFpbCkudmFsdWUuaXNfbm9uZSgpAAAAu0QQAGoAAAB7AAAAEQAAAGFzc2VydGlvbiBmYWlsZWQ6ICgqbmV4dCkudmFsdWUuaXNfc29tZSgpAAAAu0QQAGoAAAB8AAAAEQAAAFZlcmlmaWNhdGlvbktleVJlc3BvbnNlALzcEAADAAAAQWdncmVnYXRlZENvaW5JbmRpY2VzU2lnbmF0dXJlUmVzcG9uc2VlcG9jaF9pZHNpZ25hdHVyZXMu3hAACAAAADbeEAAKAAAAQWdncmVnYXRlZEV4cGlyYXRpb25EYXRlU2lnbmF0dXJlUmVzcG9uc2VleHBpcmF0aW9uX2RhdGUu3hAACAAAAHneEAAPAAAANt4QAAoAAABWZXJpZmljYXRpb25LZXlBdXRoYWxwaGFiZXRhX2cxYmV0YV9nMgAAs94QAAUAAAC43hAABwAAAL/eEAAHAAAAc3RydWN0IE55bU5vZGVUZXN0ZXJPcHRzaWRueW1BcGl0b3BvbG9neWdhdGV3YXlOeW1Ob2RlVGVzdGVyT3B0c/jeEAACAAAA+t4QAAYAAAAA3xAACAAAAAjfEAAHAAAAY2Fubm90IHJlY3Vyc2l2ZWx5IGFjcXVpcmUgbXV0ZXhA3xAAIAAAACwgEABcAAAAEwAAAAkAAADrAAAADAAAAAQAAADsAAAA7QAAADgAQZi/wwAL9QwBAAAA7gAAAGEgRGlzcGxheSBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB1bmV4cGVjdGVkbHkAgkEQAEsAAAAFCwAADgAAAEVycm9yAAAAgkEQAEsAAACwDAAADgAAAIJBEABLAAAAqgwAAA4AAABpbnZhbGlkIHZhbHVlOiAsIGV4cGVjdGVkIAAAEOAQAA8AAAAf4BAACwAAAG1pc3NpbmcgZmllbGQgYGA84BAADwAAAEvgEAABAAAAdW5rbm93biBmaWVsZCBgYCwgZXhwZWN0ZWQgAFzgEAAPAAAAa+AQAAwAAABgLCB0aGVyZSBhcmUgbm8gZmllbGRzAABc4BAADwAAAIjgEAAWAAAAZHVwbGljYXRlIGZpZWxkIGAAAACw4BAAEQAAAEvgEAABAAAASVAgYWRkcmVzcwAA/UMQAF8AAAAGBQAAEQAAAEZ1bGxEaXNjb25uZWN0ZWRUcnlTZW5kRXJyb3IAAAAAAQAAAAEAAADvAAAAa2luZP1DEABfAAAARwQAABEAAAD9YRAAaAAAAPMEAABGAAAA/WEQAGgAAADXBAAAJQAAAENvdWxkIG5vdCBkZWNvZGUgY29tcHJlc3NlZCBncm91cCBlbGVtZW50c29tZWhvdyB0b28gbG9uZyBva20gd2FzIHByb3ZpZGVkAADRAhAAOQAAADsAAAAKAAAA0QIQADkAAABAAAAAJAAAANECEAA5AAAAIgAAAAoAAADRAhAAOQAAACcAAAA9AAAAwisQAF8AAAC5CAAAFgAAAMIrEABfAAAAqQgAABYAAAB9bnVsbHssOgkJEABmAAAAXgAAAC0AAABqc29ucnBjaWRtZXRob2RwYXJhbXMAAADSVxAATQAAABoBAABdAAAAR2F0ZXdheUNsaWVudCBjb250cm9sIHJlc3BvbnNlOiBSZWNlaXZlZCBzaHV0ZG93bgAAADziEAAxAAAA0lcQAE0AAAApAQAAFQAAAG55bV9nYXRld2F5X2NsaWVudDo6Y2xpZW50R2F0ZXdheUNsaWVudCBjb250cm9sIHJlc3BvbnNlOiBFeGl0aW5nAAAAouIQACcAAADSVxAATQAAACoBAAAVAAAAUm91dGUgcmVjZWl2ZWQgZmFpbGVkOiAA5OIQABcAAADSVxAATQAAADwBAAApAAAA0lcQAE0AAABAAQAAIQAAAGFsbCBicmFuY2hlcyBhcmUgZGlzYWJsZWQgYW5kIHRoZXJlIGlzIG5vIGVsc2UgYnJhbmNoAAAAJOMQADUAAADSVxAATQAAACcBAAANAAAA0lcQAE0AAAB9AQAADQAAAL9WEABPAAAAMQAAADIAAABVcGdyYWRlS2V5aGtkZl9zYWx0ZGVyaXZlZF9rZXlfZGlnZXN0Rm9yZ2V0TWVjbGllbnRzdGF0c1JlbWVtYmVyTWVzZXNzaW9uX3R5cGUAAMwmEAAqAAAAYQAAAA0AAABWcG5NaXhuZXRXYXNtTmF0aXZlU29ja3M1VW5rbm93bmdldF9zdGF0ZWdldF9jdXJyZW50X2Vwb2NoX3N0YXRlZ2V0X2Vwb2NoX3N0YXRlX2F0X2hlaWdodGhlaWdodGdldF9jdXJyZW50X2Vwb2NoX3RocmVzaG9sZGdldF9lcG9jaF90aHJlc2hvbGRlcG9jaF9pZGNhbl9hZHZhbmNlX3N0YXRlZ2V0X3JlZ2lzdGVyZWRfZGVhbGVyZGVhbGVyX2FkZHJlc3NnZXRfZGVhbGVyX2RldGFpbHNnZXRfZXBvY2hfZGVhbGVyc19hZGRyZXNzZXNsaW1pdHN0YXJ0X2FmdGVyZ2V0X2Vwb2NoX2RlYWxlcnNnZXRfY3VycmVudF9kZWFsZXJzZ2V0X2RlYWxlcl9pbmRpY2VzZ2V0X2RlYWxpbmdzX21ldGFkYXRhZGVhbGVyZGVhbGluZ19pbmRleGdldF9kZWFsZXJfZGVhbGluZ3Nfc3RhdHVzZ2V0X2RlYWxpbmdfc3RhdHVzZ2V0X2RlYWxpbmdfY2h1bmtfc3RhdHVzY2h1bmtfaW5kZXhnZXRfZGVhbGluZ19jaHVua2dldF92ZXJpZmljYXRpb25fa2V5b3duZXJnZXRfdmVyaWZpY2F0aW9uX2tleXNnZXRfY3cyX2NvbnRyYWN0X3ZlcnNpb24AAKEYEABLAAAA+AEAAA4AQZjMwwALrQQBAAAA8wAAAPQAAAAEAAAABAAAAPUAAABjYWxsZWQgYFJlc3VsdDo6dW53cmFwKClgIG9uIGFuIGBFcnJgIHZhbHVlSW52YWxpZExlbmd0aMIrEABfAAAA8AcAAAkAAAAKAAAAwisQAF8AAADmBwAACQAAACwKOiBBIG5vZGUgdGVzdCBpcyBhbHJlYWR5IGluIHByb2dyZXNzLiBXYWl0IGZvciBpdCB0byBmaW5pc2ggYmVmb3JlIHN0YXJ0aW5nIGFub3RoZXIgb25lLmJvdGggbnltQXBpIGFkZHJlc3MgYW5kIGV4cGxpY2l0IHRvcG9sb2d5IHdlcmUgc3BlY2lmaWVkIC0gcGxlYXNlIHVzZSBvbmx5IG9uZSBvZiB0aGVtbmVpdGhlciBueW1BcGkgYWRkcmVzcyBvciBleHBsaWNpdCB0b3BvbG9neSB3ZXJlIHNwZWNpZmllZGNvdWxkIG5vdCBwYXJzZSBwcm92aWRlZCB0ZXN0ZXIgYXJndW1lbnRzOiAAAAB25xAAKwAAAHByb3ZpZGVkIHRvcG9sb2d5IHdhcyBtYWxmb3JtZWQ6IAAAAKznEAAhAAAAZmFpbGVkIHRvIHRlc3QgdGhlIG5vZGU6IAAAANjnEAAZAAAAZXhwZXJpZW5jZWQgYW4gZXJyb3Igd2l0aCB0aGUgZ2F0ZXdheSBjb25uZWN0aW9uOiAAAPznEAAyAAAABAAAAAAAAAAEAAAABABB0NDDAAvBFgwAAABhdHRlbXB0ZWQgdG8gdGFrZSBvd25lcnNoaXAgb2YgUnVzdCB2YWx1ZSB3aGlsZSBpdCB3YXMgYm9ycm93ZWQAo20QADgAAAAAAQAABQAAAKNt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AEoAAAC9AQAAHQAAAP1DEABfAAAARwQAABEAAAAAAAAABAAAAAQAAABoAQAARGVjb2RlRXJyb3IAAAAAAAQAAAAEAAAAaQEAAAAAAAAEAAAABAAAANUAAABJbnZhbGlkU2hhcmVkS2V5c1NpemVyZWNlaXZlZGV4cGVjdGVkYXR0ZW1wdGVkIHRvIHRha2Ugb3duZXJzaGlwIG9mIFJ1c3QgdmFsdWUgd2hpbGUgaXQgd2FzIGJvcnJvd2VkBh8QAGwAAAAkAQAADgAAAG91ciAnRGVidWdXYXNtJyBzdHJ1Y3Qgc2hvdWxkIGhhdmUgaGFkIGEgY29ycmVjdGx5IGRlZmluZWQgc2VyZGUgaW1wbGVtZW50YXRpb24AJF4QACkAAABFAAAACgAAACReEAApAAAAVgAAAAoAAABEZWJ1Z1dhc210cmFmZmljY292ZXJfdHJhZmZpY2dhdGV3YXlfY29ubmVjdGlvbmFja25vd2xlZGdlbWVudHN0b3BvbG9neXJlcGx5X3N1cmJzc3RhdHNfcmVwb3J0aW5nZm9yZ2V0X21lcmVtZW1iZXJfbWVUcmFmZmljV2FzbWF2ZXJhZ2VfcGFja2V0X2RlbGF5X21zbWVzc2FnZV9zZW5kaW5nX2F2ZXJhZ2VfZGVsYXlfbXNtYXhpbXVtX251bWJlcl9vZl9yZXRyYW5zbWlzc2lvbnNkZXRlcm1pbmlzdGljX3JvdXRlX3NlbGVjdGlvbmRpc2FibGVfbWFpbl9wb2lzc29uX3BhY2tldF9kaXN0cmlidXRpb251c2VfZXh0ZW5kZWRfcGFja2V0X3NpemV1c2VfbGVnYWN5X3NwaGlueF9mb3JtYXR1c2Vfb3V0Zm94ZGlzYWJsZV9taXhfaG9wc0ZvcmdldE1lV2FzbWNsaWVudHN0YXRzVG9wb2xvZ3lXYXNtdG9wb2xvZ3lfcmVmcmVzaF9yYXRlX21zdG9wb2xvZ3lfcmVzb2x1dGlvbl90aW1lb3V0X21zbWF4X3N0YXJ0dXBfZ2F0ZXdheV93YWl0aW5nX3BlcmlvZF9tc2Rpc2FibGVfcmVmcmVzaGluZ21pbmltdW1fbWl4bm9kZV9wZXJmb3JtYW5jZW1pbmltdW1fZ2F0ZXdheV9wZXJmb3JtYW5jZXVzZV9leHRlbmRlZF90b3BvbG9neWlnbm9yZV9lZ3Jlc3NfZXBvY2hfcm9sZWlnbm9yZV9pbmdyZXNzX2Vwb2NoX3JvbGVSZW1lbWJlck1lV2FzbVJlcGx5U3VyYnNXYXNtbWluaW11bV9yZXBseV9zdXJiX3N0b3JhZ2VfdGhyZXNob2xkbWF4aW11bV9yZXBseV9zdXJiX3N0b3JhZ2VfdGhyZXNob2xkbWluaW11bV9yZXBseV9zdXJiX3RocmVzaG9sZF9idWZmZXJtaW5pbXVtX3JlcGx5X3N1cmJfcmVxdWVzdF9zaXplbWF4aW11bV9yZXBseV9zdXJiX3JlcXVlc3Rfc2l6ZW1heGltdW1fYWxsb3dlZF9yZXBseV9zdXJiX3JlcXVlc3Rfc2l6ZW1heGltdW1fcmVwbHlfc3VyYl9yZXJlcXVlc3Rfd2FpdGluZ19wZXJpb2RfbXNtYXhpbXVtX3JlcGx5X3N1cmJfZHJvcF93YWl0aW5nX3BlcmlvZF9tc21heGltdW1fcmVwbHlfc3VyYnNfcmVyZXF1ZXN0c21heGltdW1fcmVwbHlfa2V5X2FnZV9tc3N1cmJfbWl4X2hvcHNDb3ZlclRyYWZmaWNXYXNtbG9vcF9jb3Zlcl90cmFmZmljX2F2ZXJhZ2VfZGVsYXlfbXNjb3Zlcl90cmFmZmljX3ByaW1hcnlfc2l6ZV9yYXRpb2Rpc2FibGVfbG9vcF9jb3Zlcl90cmFmZmljX3N0cmVhbVN0YXRzUmVwb3J0aW5nV2FzbWVuYWJsZWRwcm92aWRlcl9hZGRyZXNzcmVwb3J0aW5nX2ludGVydmFsX21zQWNrbm93bGVkZ2VtZW50c1dhc21hdmVyYWdlX2Fja19kZWxheV9tc2Fja193YWl0X211bHRpcGxpZXJhY2tfd2FpdF9hZGRpdGlvbl9tc0dhdGV3YXlDb25uZWN0aW9uV2FzbWdhdGV3YXlfcmVzcG9uc2VfdGltZW91dF9tcwAAagEAAAwAAAAEAAAAawEAAGwBAAA4AEGopcQAC98GAQAAAG0BAABhIERpc3BsYXkgaW1wbGVtZW50YXRpb24gcmV0dXJuZWQgYW4gZXJyb3IgdW5leHBlY3RlZGx5AIJBEABLAAAABQsAAA4AAABuAQAABAAAAAQAAABvAQAARXJyb3IAAACCQRAASwAAALAMAAAOAAAAgkEQAEsAAACqDAAADgAAAHkzEABKAAAAlAgAAB8AAAAAAAAABAAAAAQAAABiAQAAYW4gYXJyYXkgb2YgbGVuZ3RoIDEyZXhwZWN0ZWQgbmFub3NlY29uZGV4cGVjdGVkIG9mZnNldCBzZWNvbmRzZXhwZWN0ZWQgb2Zmc2V0IG1pbnV0ZXNleHBlY3RlZCBzZWNvbmRleHBlY3RlZCB5ZWFyZXhwZWN0ZWQgZGF5IG9mIHllYXJleHBlY3RlZCBvZmZzZXQgaG91cnNleHBlY3RlZCBob3VyZXhwZWN0ZWQgbWludXRlX2NpcGhlcl9zdG9yZe0YEABfAAAAlQQAACIAAADtGBAAXwAAAJgEAAAcAAAAdGhpcyBjbGllbnQgaXMgaW5jb21wYXRpYmxlIHdpdGggZXhpc3Rpbmcgc3RvcmFnZS4gcGxlYXNlIGluaXRpYWxpc2UgaXQgYWdhaW4ua2V5c2NvcmVhY3RpdmVfZ2F0ZXdheWdhdGV3YXlfcmVnaXN0cmF0aW9uc29udXBncmFkZW5lZWRlZEFuIGVycm9yIG9jY3VycmVkIGR1cmluZyBhbiBgaW5kZXhlZF9kYl9mdXR1cmVzYCBgIGV2ZW50IGhhbmRsZXI6IAAAvBQRADIAAADuFBEAEAAAAAAAAAAoAAAACAAAAHIBAABzAQAACAAAAAQAAAB0AQAAdQEAAEZuT25jZSBjYWxsZWQgbW9yZSB0aGFuIG9uY2VLZXlQYWlycHJpdmF0ZV9rZXlwdWJsaWNfa2V5VxURAAsAAABiFREACgAAAGluZGV4AAAAVxURAAsAAABiFREACgAAAHwVEQAFAAAARW50cnlEZXRhaWxzaXBfYWRkcmVzc2VzY2xpZW50c193c19wb3J0aG9zdG5hbWVjbGllbnRzX3dzc19wb3J0U3VwcG9ydGVkUm9sZXNtaXhub2RlbWl4bmV0X2VudHJ5bWl4bmV0X2V4aXQAQZCsxAALoQ0BAAAAfQEAAGNhbGxlZCBgUmVzdWx0Ojp1bndyYXAoKWAgb24gYW4gYEVycmAgdmFsdWVFcnJvckNbEABbAAAA9AEAABMAAABAGBAAYAAAAGgDAAA9AAAAQBgQAGAAAABlAwAANAAAAAEAAAAAAAAAQBgQAGAAAAB5AwAADQAAAEAYEABgAAAAoQMAAA0AAABAGBAAYAAAALQDAAANAAAAQBgQAGAAAABCAwAACQAAADAwMDEwMjAzMDQwNTA2MDcwODA5MTAxMTEyMTMxNDE1MTYxNzE4MTkyMDIxMjIyMzI0MjUyNjI3MjgyOTMwMzEzMjMzMzQzNTM2MzczODM5NDA0MTQyNDM0NDQ1NDY0NzQ4NDk1MDUxNTI1MzU0NTU1NjU3NTg1OTYwNjE2MjYzNjQ2NTY2Njc2ODY5NzA3MTcyNzM3NDc1NzY3Nzc4Nzk4MDgxODI4Mzg0ODU4Njg3ODg4OTkwOTE5MjkzOTQ5NTk2OTc5ODk5QBgQAGAAAAA+AwAACQAAAEAYEABgAAAAPwMAAAkAAABAGBAAYAAAADgDAAAJAAAAQBgQAGAAAAA5AwAACQAAAEAYEABgAAAAOgMAAAkAAAAAAAAABAAAAAQAAAB+AQAAAAAAAAQAAAAEAAAAPAAAAE5vSXBBZGRyZXNzZXNQcm92aWRlZG5vZGVfaWRpZGVudGl0eTFmYzQzMGNhLTViN2YtNDI5NS05MmRlLTMzY2YyYjE0NWQzOE1hcCBrZXkgaXMgbm90IGEgc3RyaW5nIGFuZCBjYW5ub3QgYmUgYW4gb2JqZWN0IGtleQBcKxAAZQAAAFsAAAAJAAAAUmV1bml0ZUVycm9yLi4uAJAYEQADAAAAAAAAAAgAAAAEAAAAiAEAAAAAAAAEAAAABAAAADwAAABDcnlwdG9LZXlOb3RJblN0b3JhZ2V0eXBHYXRld2F5RGV0YWlsc05vdEluU3RvcmFnZWdhdGV3YXlfaWQgY3J5cHRvZ3JhcGhpYyBrZXkgaXMgbm90IGF2YWlsYWJsZSBpbiBzdG9yYWdlAAABAAAAAAAAAPgYEQAuAAAAdGhlIHByaW9yIGdhdGV3YXkgZGV0YWlscyBmb3IgZ2F0ZXdheSAgYXJlIG5vdCBhdmFpbGFibGUgaW4gdGhlIHN0b3JhZ2UAOBkRACYAAABeGREAIQAAAH17AAAAAAAABAAAAAQAAABoAQAATWFsZm9ybWVkU3RyaW5nAAAAAAAEAAAABAAAAIkBAAAAAAAABAAAAAQAAADVAAAASW52YWxpZExlbmd0aHJlY2VpdmVkZXhwZWN0ZWRXYXNtRnJpZW5kbHlOeW1Ub3BvbG9neW1ldGFkYXRhcmV3YXJkZWRTZXRub2RlRGV0YWlsc1dhc21GcmllbmRseVJvdXRpbmdOb2Rlbm9kZUlkbWl4SG9zdGVudHJ5aWRlbnRpdHlLZXlzcGhpbnhLZXlzdXBwb3J0ZWRSb2xlc055bVRvcG9sb2d5TWV0YWRhdGFrZXlfcm90YXRpb25faWRhYnNvbHV0ZV9lcG9jaF9pZHJlZnJlc2hlZF9hdFdhc21SYXdSZWdpc3RlcmVkR2F0ZXdheWdhdGV3YXlfaWRfYnM1OHJlZ2lzdHJhdGlvbl90aW1lc3RhbXBkZXJpdmVkX2FlczEyOF9jdHJfYmxha2UzX2htYWNfa2V5c19iczU4ZGVyaXZlZF9hZXMyNTZfZ2NtX3Npdl9rZXlnYXRld2F5X293bmVyX2FkZHJlc3NnYXRld2F5X2xpc3RlbmVyyBoRAA8AAADXGhEAFgAAAO0aEQAoAAAAFRsRABoAAAAvGxEAFQAAAEQbEQAQAAAAc29tZWhvdyBvYnRhaW5lZCBjdXN0b20gZ2F0ZXdheSByZWdpc3RyYXRpb24gaW4gd2FzbSEAAACEGxEANQAAAAgdEAAsAAAAOAAAAA0AAABzdHJ1Y3QgV2FzbVJhd1JlZ2lzdGVyZWRHYXRld2F5AKEYEABLAAAA+AEAAA4AAADAcBAAVgAAAP8DAAAVAAAAVXJsc2NoZW1lAAAAAAAAAAEAAAABAAAAigEAAGNhbm5vdF9iZV9hX2Jhc2V1c2VybmFtZQAAAAAIAAAABAAAAIsBAABwYXNzd29yZAAAAAAUAAAABAAAAIwBAABob3N0AAAAAAQAAAACAAAAjQEAAHBvcnRwYXRocXVlcnlmcmFnbWVudAAAAI4BAAAMAAAABAAAAI8BAACQAQAAOABBvLnEAAvBMgEAAACRAQAAYSBEaXNwbGF5IGltcGxlbWVudGF0aW9uIHJldHVybmVkIGFuIGVycm9yIHVuZXhwZWN0ZWRseQCCQRAASwAAAAULAAAOAAAAZGVzY3JpcHRpb24oKSBpcyBkZXByZWNhdGVkOyB1c2UgRGlzcGxheb0KWJUSzgYarzL96xoGc8feO/a7R9eQBm+0RT0Y8nze8TYJG1wzexYjBjncoUpn8Z7cZCrOv9eFcn+HZdwusz7vM4WKADPjVd8bXV9KgkTsa+lgjalH2B3XTv8ulqrQpkzJkZ+0uk1kYsXJBOaO1DzOglewO8KK274fqWmZp+AjGW2NVzaBPguZ2XRsaCqATkeQcUo69riXG4A6I8K1JbGSAQAAEAAAAAQAAACTAQAAkgEAABAAAAAEAAAAlAEAAJMBAADUHREAlQEAAJYBAACXAQAAmAEAAJkBAACaAQAAYAAAAAgAAACbAQAAmgEAAGAAAAAIAAAAnAEAAJsBAAAQHhEAnQEAAJ4BAACfAQAAoAEAAKEBAACiAQAAXAAAAAQAAAAMAAAAogEAAFwAAAAEAAAAowEAAAwAAABMHhEApAEAAKUBAACXAQAApgEAAJkBAACnAQAAIAAAAAQAAACoAQAApwEAACAAAAAEAAAAqQEAAKgBAACIHhEAqgEAAKsBAACXAQAArAEAAJkBAACtAQAAFAAAAAQAAACuAQAArQEAABQAAAAEAAAArwEAAK4BAADEHhEAsAEAALEBAACXAQAAsgEAAJkBAAAAAAAAAQAAAAEAAACzAQAAAAAAAAEAAAABAAAAtAEAALMBAAAAHxEAtQEAALYBAAC3AQAAuAEAALkBAAC6AQAAYAAAAAgAAAA9AQAAugEAAGAAAAAIAAAAuwEAAD0BAAA8HxEAvAEAAL0BAACfAQAAvgEAAKEBAAC/AQAAEAAAAAQAAADAAQAAvwEAABAAAAAEAAAAwQEAAMABAAB4HxEAwgEAAMMBAACXAQAAxAEAAJkBAAAAAAAADAAAAAQAAADFAQAAAAAAAAwAAAAEAAAAxgEAAMUBAAC0HxEAxwEAAMgBAACXAQAAyQEAAJkBAADKAQAAaAAAAAgAAAACAAAAygEAAGgAAAAIAAAAywEAAAIAAADwHxEAzAEAAM0BAACfAQAAzgEAAKEBAABFcnJvcgAAAIJBEABLAAAAsAwAAA4AAACCQRAASwAAAKoMAAAOAAAAaW52YWxpZCB2YWx1ZTogLCBleHBlY3RlZCAAAFQgEQAPAAAAYyARAAsAAABtaXNzaW5nIGZpZWxkIGBggCARAA8AAACPIBEAAQAAAGludmFsaWQgbGVuZ3RoIACgIBEADwAAAGMgEQALAAAAZHVwbGljYXRlIGZpZWxkIGAAAADAIBEAEQAAAI8gEQABAAAAdW5rbm93biB2YXJpYW50IGBgLCBleHBlY3RlZCAAAADkIBEAEQAAAPUgEQAMAAAAYCwgdGhlcmUgYXJlIG5vIHZhcmlhbnRz5CARABEAAAAUIREAGAAAAEVtcHR5SG9zdElkbmFFcnJvckludmFsaWRQb3J0SW52YWxpZElwdjRBZGRyZXNzSW52YWxpZElwdjZBZGRyZXNzSW52YWxpZERvbWFpbkNoYXJhY3RlclJlbGF0aXZlVXJsV2l0aG91dEJhc2VSZWxhdGl2ZVVybFdpdGhDYW5ub3RCZUFCYXNlQmFzZVNldEhvc3RPbkNhbm5vdEJlQUJhc2VVcmxPdmVyZmxvd05vbmUAAAAAAAAEAAAABAAAAM8BAABTb21lAAAAAAQAAAAEAAAA1AAAAAAAAAAEAAAABAAAANABAAAAAAAABAAAAAQAAABgAAAAwHAQAFYAAAAxCwAACwAAAEpzb25JbnRlcm5hbFN0b3JhZ2VGYWlsdXJlbWVzc2FnZURiT3BlbkZhaWx1cmUAAAAAAAAEAAAABAAAANEBAABEdXBsaWNhdGVLZXljb3VudAAAAAAAAAAEAAAABAAAANIBAABDcnlwdG9TdG9yYWdlRXJyb3Jzb3VyY2VOb1Bhc3NwaHJhc2VQcm92aWRlZFVuZXhwZWN0ZWRQYXNzcGhyYXNlUHJvdmlkZWTAcBAAVgAAACoLAAALAAAATm9VcmxzUHJvdmlkZWQAAAAAAAAEAAAABAAAANMBAABSZXF3ZXN0QnVpbGRFcnJvckdlbmVyaWNSZXF1ZXN0RmFpbHVyZVJlcXdlc3RDbGllbnRFcnJvco4BAAAMAAAABAAAANQBAABNYWxmb3JtZWRVcmxyYXcA1QEAAEgAAAAEAAAA1gEAAAAAAAAEAAAABAAAANcBAABSZXF1ZXN0U2VuZEZhaWx1cmV1cmwAAADYAQAABAAAAAQAAADZAQAAAAAAAAIAAAACAAAA2gEAAFJlc3BvbnNlUmVhZEZhaWx1cmVoZWFkZXJzc3RhdHVzAAAAAAQAAAAEAAAA2wEAAFJlc3BvbnNlRGVzZXJpYWxpc2F0aW9uRmFpbHVyZQAAAAAAAAQAAAAEAAAARwAAAFVybFBhcnNlRmFpbHVyZQAAAAAABAAAAAQAAADcAQAATm90Rm91bmRBdHRlbXB0ZWRUb0Nsb25lU3RyZWFtUmVxdWVzdAAAAAAAAAAEAAAABAAAAN0BAABSZXF1ZXN0RmFpbHVyZUVtcHR5UmVzcG9uc2VFbmRwb2ludEZhaWx1cmVlcnJvclJlc3BvbnNlRGVjb2RlRmFpbHVyZWNvbnRlbnRJbnRlcm5hbFJlc3BvbnNlSW5jb25zaXN0ZW5jeWRldGFpbHMAAAAAAAQAAAAEAAAA3gEAAEJpbmNvZGUAAAAAAAQAAAAEAAAA3wEAAFlhbWwAAAAABAAAAAQAAADgAQAAUGxhaW5SZXF1ZXN0VGltZW91dEVtcHR5TmV0d29ya1RvcG9sb2d5AAAAAAAEAAAABAAAAOEBAABOb25FeGlzdGVudE5vZGVub2RlX2lkZW50aXR5SW52YWxpZEVncmVzc1JvbGVJbnN1ZmZpY2llbnRNaXhpbmdOb2Rlc05vR2F0ZXdheXNBdmFpbGFibGVOb01peG5vZGVzQXZhaWxhYmxlTm9uRXhpc3RlbnRHYXRld2F5RXJyb3JpZGVudGl0eV9rZXlUaW1lZE91dFdhaXRpbmdGb3JHYXRld2F5SW52YWxpZE51bWJlck9mSG9wc0Vycm9yYXZhaWxhYmxlcmVxdWVzdGVkRW1wdHlNaXhMYXllcmxheWVyAAAAAAAAAQAAAAEAAADiAQAAAAAAAAQAAAAEAAAA4wEAAG5vZGVzbG93ZXJfYm91bmR1cHBlcl9ib3VuZHRvdGFsX25vZGVzbGF5ZXJfZGlzdHJpYnV0aW9uSSYRAAUAAABwJhEABQAAAHUmEQALAAAAgCYRAAsAAACLJhEACwAAAJYmEQASAAAAVW5ldmVuTGF5ZXJEaXN0cmlidXRpb25QYXlsb2FkQnVpbGRlcgAAAAAAAAAEAAAABAAAAOQBAABPdXRmb3gAAAAAAAAEAAAABAAAAOUBAABGcm9tU2xpY2UAAAAAAAAABAAAAAQAAADmAQAAUGFja2V0RXJyb3JSZXF3ZXN0RXJyb3IAAAAAAAQAAAAEAAAA5wEAAFZhckVycm9yAAAAAAQAAAAEAAAAYgAAAElvRXJyb3IAAAAAAAQAAAAEAAAA6AEAAEdhdGV3YXlDbGllbnRFcnJvcgAAAAAAAAQAAAAEAAAA6QEAAEVyYXNlZEdhdGV3YXlDbGllbnRFcnJvcgAAAAAEAAAABAAAAEAAAABFZDI1NTE5UmVjb3ZlcnlFcnJvcgAAAAAEAAAABAAAAEIAAABWYWxpZGF0b3JDbGllbnRFcnJvck5vR2F0ZXdheVdpdGhJZEludmFsaWRVcmxOb0dhdGV3YXlzT25OZXR3b3JrTm9OZXdHYXRld2F5c0F2YWlsYWJsZUxpc3RPZk55bUFwaXNJc0VtcHR5AAAAAAAABAAAAAQAAADqAQAATnltQXBpUXVlcnlGYWlsdXJlAAAAAAAABAAAAAQAAABFAAAASW5zdWZmaWNpZW50TmV0d29ya1RvcG9sb2d5AAAAAAAEAAAABAAAAOsBAABTdXJiU3RvcmFnZUVycm9yS2V5U3RvcmVFcnJvckdhdGV3YXlzRGV0YWlsc1N0b3JlRXJyb3JDcmVkZW50aWFsU3RvcmVFcnJvclVua25vd25UaWNrZXRUeXBlVW5hYmxlVG9DcmVhdGVQdWJsaWNLZXlGcm9tR2F0ZXdheUlkAAAAAAAEAAAABAAAAOwBAABNYWxmb3JtZWRHYXRld2F5AAAAAAQAAAAEAAAA7QEAAEdhdGV3YXlDb25uZWN0aW9uRmFpbHVyZUdhdGV3YXlKc0Nvbm5lY3Rpb25GYWlsdXJlR2F0ZXdheUNvbm5lY3Rpb25BYnJ1cHRseUNsb3NlZEdhdGV3YXlDb25uZWN0aW9uVGltZW91dEdhdGV3YXlGYWlsZWRUb0ZvcndhcmRNZXNzYWdlc05vR2F0ZXdheU1lYXN1cmVtZW50c2lkZW50aXR5RmFpbGVkVG9SZWdpc3RlclJlY2VpdmVyVW5leHBlY3RlZEV4aXRGb3JiaWRkZW5HYXRld2F5S2V5T3ZlcndyaXRlRm9yYmlkZGVuS2V5T3ZlcndyaXRlTm9BY3RpdmVHYXRld2F5U2V0VW5hdmFpbGFibGVHYXRld2F5RGV0YWlsc1VuYXZhaWxhYmxlU2hhcmVkS2V5VW5leHBlY3RlZEdhdGV3YXlEZXRhaWxzTWlzbWF0Y2hlZEdhdGV3YXlEZXRhaWxzQ29uZmlnRmlsZVVwZ3JhZGVGYWlsdXJlY3VycmVudF92ZXJzaW9uVW5hYmxlVG9VcGdyYWRlQ29uZmlnRmlsZW5ld192ZXJzaW9uVXBncmFkZUZhaWx1cmVNaXNtYXRjaGVkU3RvcmVkR2F0ZXdheURldGFpbHNDdXN0b21HYXRld2F5U2VsZWN0aW9uRXhwZWN0ZWRVbmV4cGVjdGVkUGVyc2lzdGVkQ3VzdG9tR2F0ZXdheURldGFpbHNOb0luaXRDbGllbnRQcmVzZW50Tm9Xc3NHYXRld2F5c1Vuc3VwcG9ydGVkV3NzUHJvdG9jb2xnYXRld2F5AAAAAAAEAAAABAAAAO4BAABVbnN1cHBvcnRlZEVudHJ5aWQAAI4BAAAMAAAABAAAAO8BAABDdXN0b21Ub3BvbG9neUxvYWRGYWlsdXJlZmlsZV9wYXRoQ29uZmlnU2F2ZUZhaWx1cmVNYWxmb3JtZWRHYXRld2F5SWRlbnRpdHlNYWxmb3JtZWRMaXN0ZW5lcnJhd19saXN0ZW5lckFscmVhZHlJbml0aWFsaXNlZGNsaWVudF9pZEFscmVhZHlSZWdpc3RlcmVkVW5leHBlY3RlZEtleVVwZ3JhZGVIa2RmRGVyaXZhdGlvbkVycm9yUnBjQ2xpZW50TWlzc2luZ1VybAAAAAAAAAQAAAAEAAAA8AEAAEludmFsaWROZXR3b3JrRGV0YWlsc1JwY0NsaWVudENyZWF0aW9uRmFpbHVyZQAAAAAAAAAEAAAABAAAAPEBAABHYXRld2F5U2VsZWN0aW9uRmFpbHVyZQAAAAAABAAAAAQAAADyAQAAUmVnaXN0cnlBY2Nlc3NleHBlcmllbmNlZCBhbiBpc3N1ZSB3aXRoIGludGVybmFsIGNsaWVudCBjb21wb25lbnRzOiB2LREANgAAAFRoZSBwcm92aWRlZCBnYXRld2F5IGlkZW50aXR5IGlzIGludmFsaWQ6IAAAtC0RACoAAABHYXRld2F5IGNvbW11bmljYXRpb24gZmFpbHVyZTogAOgtEQAfAAAAZmFpbGVkIHRvIHF1ZXJ5IG55bSBhcGk6IAAAABAuEQAZAAAAVGhlIHByb3ZpZGVkIHdhc20gdG9wb2xvZ3kgd2FzIGludmFsaWQ6IDQuEQAoAAAAVGhlIHByb3ZpZGVkIG55bSB0b3BvbG9neSB3YXMgaW52YWxpZDogAGQuEQAnAAAAIGlzIG5vdCBhIHZhbGlkIHVybDogAAAAAQAAAAAAAACULhEAFQAAAE5ldHdvcmsgdG9wb2xvZ3kgaXMgY3VycmVudGx5IHVuYXZhaWxhYmxlTWl4bm9kZSAgaXMgbm90IHByZXNlbnQgaW4gdGhlIGN1cnJlbnQgbmV0d29yayB0b3BvbG9neeUuEQAIAAAA7S4RAC8AAABHYXRld2F5ICwvEQAIAAAA7S4RAC8AAAAgaXMgbm90IGEgdmFsaWQgTnltIG5ldHdvcmsgcmVjaXBpZW50OiAAAQAAAAAAAABELxEAJwAAACBpcyBub3QgYSB2YWxpZCBOeW0gQW5vbnltb3VzU2VuZGVyVGFnOiABAAAAAAAAAHwvEQAoAAAAdGhpcyBjbGllbnQgaGFzIGFscmVhZHkgcmVnaXN0ZXJlZCB3aXRoIGEgZ2F0ZXdheTogALQvEQAzAAAAQ29ubmVjdGlvbk5vdEVzdGFibGlzaGVkR2F0ZXdheUVycm9yAAAAAAQAAAAEAAAA8wEAAFR5cGVkR2F0ZXdheUVycm9yAAAAAAAAAAQAAAAEAAAA9AEAAFJlcXVlc3RFcnJvck5ldHdvcmtFcnJvckZhdGFsS2V5VXBncmFkZUZhaWx1cmVLZXlBbHJlYWR5VXBncmFkZWRLZXlBbHJlYWR5SW5Vc2UAAAAAAAQAAAAEAAAA9QEAAE5ldHdvcmtFcnJvcldhc21OZXR3b3JrQ29ubmVjdGlvbkZhaWxlZGFkZHJlc3NOb0VuZHBvaW50Rm9yQ29ubmVjdGlvbk5vU2hhcmVkS2V5QXZhaWxhYmxlTm9CYW5kd2lkdGhDb250cm9sbGVyQXZhaWxhYmxlAAAAAAAEAAAABAAAAPYBAABCYW5kd2lkdGhDb250cm9sbGVyRXJyb3JDb25uZWN0aW9uQWJydXB0bHlDbG9zZWRDb25uZWN0aW9uQ2xvc2VkR2F0ZXdheVNodXRkb3duTWFsZm9ybWVkUmVzcG9uc2VTZXJpYWxpemVDcmVkZW50aWFsAAAAAAAEAAAABAAAAPcBAABPdXRkYXRlZEdhdGV3YXlDcmVkZW50aWFsVmVyc2lvbm5lZ290aWF0ZWRfcHJvdG9jb2xOb3RBdXRoZW50aWNhdGVkAAAAAAAIAAAACAAAAPgBAAAAAAAABAAAAAQAAADlAAAATm90RW5vdWdoQmFuZHdpZHRoTm9Nb3JlQmFuZHdpZHRoQ3JlZGVudGlhbHNCYW5kd2lkdGhCZWxvd0N1dG9mZlZhbHVlYXZhaWxhYmxlX2JpMmN1dG9mZl9iaTJVbmV4cGVjdGVkUmVzcG9uc2VuYW1lQ29ubmVjdGlvbkluSW52YWxpZFN0YXRlAAAAAAAABAAAAAQAAAD5AQAAUmVnaXN0cmF0aW9uRmFpbHVyZUF1dGhlbnRpY2F0aW9uRmFpbHVyZUF1dGhlbnRpY2F0aW9uRmFpbHVyZVdpdGhQcmVleGlzdGluZ1NoYXJlZEtleVRpbWVvdXRNaXhuZXRNc2dTZW5kZXJGYWlsZWRUb1NlbmQAAAAAAAIAAAABAAAA+gEAAEluY29tcGF0aWJsZVByb3RvY29sY3VycmVudFBhY2tldFJvdXRlclVuYXZhaWxhYmxlU2h1dGRvd25JblByb2dyZXNzTnltQVBJRXJyb3IAAAAAAAQAAAAEAAAA+wEAAFRlbmRlcm1pbnRFcnJvclJwY01hbGZvcm1lZFVybFByb3ZpZGVkTnl4ZEVycm9ySW5jb25zaXN0ZW50UGFnZWRNZXRhZGF0YU5vQVBJVXJsQXZhaWxhYmxlAAAALVQQAEoAAAC9AQAAHQAAAGNhbGxlZCBgT3B0aW9uOjp1bndyYXBfdGhyb3coKWAgb24gYSBgTm9uZWAgdmFsdWVJbnZhbGlkR2F0ZXdheVR5cGUAAAAAAAQAAAAEAAAA/AEAAE1hbGZvcm1lZEdhdGV3YXlPd25lckFjY291bnRBZGRyZXNzcmF3X293bmVyAAAAAAQAAAAEAAAA/QEAAE1hbGZvcm1lZFNoYXJlZEtleXNNaXNzaW5nU2hhcmVkS2V5AAAAAAAEAAAABAAAAP4BAABNYWxmb3JtZWRCeXRlc0J5dGVzTGVuZ3RoRXJyb3JNYWxmb3JtZWRQdWJsaWNLZXlTdHJpbmdNYWxmb3JtZWRQcml2YXRlS2V5U3RyaW5nTWFsZm9ybWVkU2lnbmF0dXJlU3RyaW5nAAAAAAAEAAAABAAAAP8BAABOb2RlQ29udmVyc2lvbk1hbGZvcm1lZElkZW50aXR5cHJvdmlkZWRNYWxmb3JtZWRTcGhpbnhLZXlNYWxmb3JtZWRSZWNpcGllbnRFcnJvcnJlYXNvbk1hbGZvcm1lZElkZW50aXR5RXJyb3IAAAAABAAAAAQAAAAAAgAATWFsZm9ybWVkRW5jcnlwdGlvbktleUVycm9yTWFsZm9ybWVkR2F0ZXdheUVycm9yBAAAAAAAAAAEAAAABABBiOzEAAtTDAAAAAkAAAAJAAAACwAAABIAAAASAAAAFgAAABYAAAAgAAAAGQAAAAgAAAA8IREARSERAE4hEQBZIREAayERAH0hEQCTIREAqSERAMkhEQDiIREAQeTsxAAL7QMBAAAAHgEAAAAAAAAEAAAABAAAAOsBAABFcmFzZWRHYXRld2F5RXJyb3Jwcml2YXRlX2tleXB1YmxpY19rZXlzdHJ1Y3QgS2V5UGFpciB3aXRoIDIgZWxlbWVudHMAAACjNhEAHgAAAAAAAAAIAAAABAAAAIQAAABpbmRleHN0cnVjdCBLZXlQYWlyIHdpdGggMyBlbGVtZW50cwDhNhEAHgAAAGdhdGV3YXlfaWRfYnM1OHJlZ2lzdHJhdGlvbl90aW1lc3RhbXBkZXJpdmVkX2FlczEyOF9jdHJfYmxha2UzX2htYWNfa2V5c19iczU4ZGVyaXZlZF9hZXMyNTZfZ2NtX3Npdl9rZXlnYXRld2F5X293bmVyX2FkZHJlc3NnYXRld2F5X2xpc3RlbmVyc3RydWN0IFdhc21SYXdSZWdpc3RlcmVkR2F0ZXdheSB3aXRoIDYgZWxlbWVudHMAlDcRAC8AAABhY3RpdmVfZ2F0ZXdheV9pZF9iczU4c3RydWN0IFJhd0FjdGl2ZUdhdGV3YXkgd2l0aCAxIGVsZW1lbnTiNxEAJgAAAG92ZXJmbG93IGluIGl0ZXI6OnN1bSBvdmVyIGR1cmF0aW9uc5VMEABIAAAA7AQAAAkAAAB6UxAAXgAAANQGAAARAEHc8MQACwYBAAAALwEAQezwxAALJQEAAAAzAQAAelMQAF4AAAAsBwAAEQAAAHpTEABeAAAANwcAABEAQZzxxAALBgEAAAAtAQBBrPHEAAsGAQAAADkBAEG88cQACwYBAAAAIwEAQczxxAAL8QgBAAAANwEAAAwAAAC4bhAAYQAAADwCAAAJAAAAwisQAF8AAACpCAAAFgAAAG51bGwsOkNhY2hlZEVwb2NoUmV3YXJkZWRTZXRlcG9jaF9pZGVudHJ5X2dhdGV3YXlzZXhpdF9nYXRld2F5c2xheWVyMWxheWVyMmxheWVyM3N0YW5kYnlTdG9yZWRFeHBvcnRlZFN0b3JlQ2lwaGVybm9fZW5jcnlwdGlvbmNpcGhlcmk5EQANAAAAdjkRAAYAAABwYXJhbXNhbGdvcml0aG12ZXJzaW9ua2RmX3NhbHQAAIw5EQAGAAAAkjkRAAkAAACbOREABwAAAKI5EQAIAAAAQXJnb24yAADMOREABgAAAG5vbmNlY2lwaGVydGV4dADcOREABQAAAOE5EQAKAAAAQXJnb24yUGFyYW1zbV9jb3N0dF9jb3N0cF9jb3N0b3V0cHV0X2xlbgg6EQAGAAAADjoRAAYAAAAUOhEABgAAABo6EQAKAAAAQXJnb24yVmVyc2lvblYweDEwVjB4MTMAUToRAAUAAABWOhEABQAAAEFyZ29uMkFsZ29yaXRobUFyZ29uMmRBcmdvbjJpQXJnb24yaWQAAAB7OhEABwAAAII6EQAHAAAAiToRAAgAAABLZGZJbmZvRW5jcnlwdGVkRGF0YZs5EQAHAAAA4TkRAAoAAADcOREABQAAAENpcGhlcnRleHRJbmZvQWVzMjU2R2NtAOY6EQAJAAAARXhwb3J0ZWRTdG9yZUNpcGhlcmtkZl9pbmZvY2lwaGVydGV4dF9pbmZvAAALOxEACAAAABM7EQAPAAAAAQIAAAwAAAAEAAAAAgIAAAECAAAMAAAABAAAAAMCAAACAgAANDsRAAQCAAAFAgAABgIAAAcCAABhY3RpdmVfZ2F0ZXdheV9pZF9iczU4UmF3QWN0aXZlR2F0ZXdheQAAbDsRABYAAAChGBAASwAAAPgBAAAOAAAAVW5zdXBwb3J0ZWRDaXBoZXIAAAAAAAAABAAAAAQAAAAIAgAAQWVzRmFpbHVyZWNhdXNlAAAAAAAEAAAABAAAAAkCAABBcmdvbjJGYWlsdXJlAAAAAAAAAAQAAAAEAAAA2wEAAFNlcmRlSnNvbkZhaWx1cmVzb3VyY2UAAAAAAAAEAAAABAAAAAoCAABSYW5kb21FcnJvcgAAAAAABAAAAAQAAADUAAAAVmVyc2lvbk1pc21hdGNocmVjZWl2ZWRWZXJpZmljYXRpb25QaHJhc2VNaXNtYXRjaEludmFsaWRJbXBvcnRQYXNzcGhyYXNlLVQQAEoAAAC9AQAAHQAAAL1tEAAeAAAAJgAAAFgAAABNYXliZUVycm9yZWQgcG9sbGVkIGFmdGVyIGNvbXBsZXRpb245ZxAAdgAAACkAAAA7AAAAZW51bSBTdG9yZWRFeHBvcnRlZFN0b3JlQ2lwaGVydmFyaWFudCBpZGVudGlmaWVyRXJyb3IAAAAOAgAADAAAAAQAAAAPAgAAEAIAADgAQcj6xAAL+QgBAAAAEQIAAGEgRGlzcGxheSBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB1bmV4cGVjdGVkbHkAgkEQAEsAAAAFCwAADgAAAGRlc2NyaXB0aW9uKCkgaXMgZGVwcmVjYXRlZDsgdXNlIERpc3BsYXlZmCx9OlJvBI/QMJE3JHbfAAAAAAEAAAABAAAAEgIAAGNhbGxlZCBgUmVzdWx0Ojp1bndyYXAoKWAgb24gYW4gYEVycmAgdmFsdWUAEwIAAAwAAAAEAAAAFAIAABMCAAAMAAAABAAAABUCAAAUAgAADD4RABYCAAAXAgAAGAIAABkCAAAaAgAAQWRUb29Mb25nQWxnb3JpdGhtSW52YWxpZAAAAAAAAAAEAAAABAAAABsCAABCNjRFbmNvZGluZ0tleUlkVG9vTG9uZ01lbW9yeVRvb0xpdHRsZU1lbW9yeVRvb011Y2hPdXRwdXRUb29TaG9ydE91dHB1dFRvb0xvbmdQd2RUb29Mb25nU2FsdFRvb1Nob3J0U2FsdFRvb0xvbmdTZWNyZXRUb29Mb25nVGhyZWFkc1Rvb0Zld1RocmVhZHNUb29NYW55VGltZVRvb1NtYWxsVmVyc2lvbkludmFsaWQAAACCQRAASwAAALAMAAAOAAAAgkEQAEsAAACqDAAADgAAAFVuc3VwcG9ydGVkQ2lwaGVyAAAAAAAAAAQAAAAEAAAAHAIAAEFlc0ZhaWx1cmVjYXVzZQAAAAAABAAAAAQAAAAJAgAAQXJnb24yRmFpbHVyZQAAAAAAAAAEAAAABAAAAB0CAABTZXJkZUpzb25GYWlsdXJlc291cmNlAAAAAAAABAAAAAQAAAAKAgAAUmFuZG9tRXJyb3IAAAAAAAQAAAAEAAAA1AAAAFZlcnNpb25NaXNtYXRjaHJlY2VpdmVkVmVyaWZpY2F0aW9uUGhyYXNlTWlzbWF0Y2hJbnZhbGlkSW1wb3J0UGFzc3BocmFzZQEAAAAAAAAAc3RvcmFnZSBmYWlsdXJlOiAAAABAQBEAEQAAAGZhaWxlZCB0byBvcGVuIHRoZSBkYiBmaWxlOiBcQBEAHAAAAEZBVEFMIEVSUk9SOiBzdG9yYWdlIGtleSBpcyBzb21laG93IHByZXNlbnQgIHRpbWVzIGluIHRoZSB0YWJsZSGAQBEALAAAAKxAEQAUAAAAZW5jb3VudGVyZWQgaXNzdWUgd2l0aCBvdXIgc3RvcmFnZSBlbmNyeXB0aW9uIGxheWVyOiAAAADQQBEANQAAAGF0dGVtcHRlZCB0byB1bmxvY2sgYW4gZXhpc3RpbmcgZW5jcnlwdGVkIGNsaWVudCBzdG9yZSB3aXRob3V0IHByb3ZpZGluZyBhIHBhc3NwaHJhc2VhdHRlbXB0ZWQgdG8gYWNjZXNzIGFuIGV4aXN0aW5nIHVuZW5jcnlwdGVkIGNsaWVudCBzdG9yZSB3aXRoIGEgcGFzc3BocmFzZQAgAgAAWnAQAGUAAAA1AAAADgBBzIPFAAunAQEAAAAhAgAAAQAAAAAAAACdOhAATwAAABkBAAAZAAAAaW52YWxpZCB0eXBlOiAsIGV4cGVjdGVkIAAAAOxBEQAOAAAA+kERAAsAAAAgY2FuJ3QgYmUgcmVwcmVzZW50ZWQgYXMgYSBKYXZhU2NyaXB0IG51bWJlcgEAAAAAAAAAGEIRACwAAAAtVBAASgAAAL0BAAAdAAAAAAAAAP//////////aEIRAEGAhcUAC8EBuG4QAGEAAABeAQAAGQAAALhuEABhAAAAdgIAABUAAABzdHJ1Y3QgQXJnb24yUGFyYW1zZW51bSBBcmdvbjJWZXJzaW9udmFyaWFudCBpZGVudGlmaWVyZW51bSBBcmdvbjJBbGdvcml0aG0ALVQQAEoAAAC9AQAAHQAAAGVudW0gS2RmSW5mb3ZhcmlhbnQgaWRlbnRpZmllcnN0cnVjdCBFbmNyeXB0ZWREYXRhZW51bSBDaXBoZXJ0ZXh0SW5mbwBB5IbFAAvPCARtEAAeAAAA2AAAAEEAAABzdHJ1Y3QgRXhwb3J0ZWRTdG9yZUNpcGhlcnN0cnVjdCB2YXJpYW50IEtkZkluZm86OkFyZ29uMnN0cnVjdCB2YXJpYW50IENpcGhlcnRleHRJbmZvOjpBZXMyNTZHY21kZXNjcmlwdGlvbigpIGlzIGRlcHJlY2F0ZWQ7IHVzZSBEaXNwbGF5b6FsFEpeC2cdp+uPM4yaYujbK9QmdUIhPH3gRJozVYMnAgAADAAAAAQAAAAoAgAAY2FsbGVkIGBSZXN1bHQ6OnVud3JhcCgpYCBvbiBhbiBgRXJyYCB2YWx1ZQApAgAACAAAAAQAAAAqAgAAKQIAAAgAAAAEAAAAKwIAACoCAABYRBEALAIAAC0CAAAuAgAALwIAADACAAAx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IHNob3J0c2FsdCBpcyB0b28gbG9uZ3NlY3JldCBpcyB0b28gbG9uZ25vdCBlbm91Z2ggdGhyZWFkc3RvbyBtYW55IHRocmVhZHN0aW1lIGNvc3QgaXMgdG9vIHNtYWxsaW52YWxpZCB2ZXJzaW9uAAAA4xcQAFwAAABUAQAAAQAAAOMXEABcAAAA7QAAAAkAAADjFxAAXAAAAOIAAAApAAAA4xcQAFwAAADoAAAACQAAAOMXEABcAAAAdwAAABUAAABGbxAAWgAAAHIAAAABAAAAYXNzZXJ0aW9uIGZhaWxlZDoga2V5X3NpemUgPD0gVTY0Ojp0b191c2l6ZSgpAAAARm8QAFoAAAByAAAAAQAAAGFzc2VydGlvbiBmYWlsZWQ6IG91dHB1dF9zaXplIDw9IFU2NDo6dG9fdXNpemUoKWFzc2VydGlvbiBmYWlsZWQ6IHNhbHQubGVuKCkgPD0gbGVuZ3RoYXNzZXJ0aW9uIGZhaWxlZDogcGVyc29uYS5sZW4oKSA8PSBsZW5ndGgAF2MQAFAAAAAqAgAAEQAAAE5vbmUAAAAABAAAAAQAAAA8AgAAU29tZUludmFsaWRFbmNvZGluZ0ludmFsaWRMZW5ndGg9AgAADAAAAAQAAAA+AgAAPwIAADgAAABpbnZhbGlkIEJhc2U2NCBlbmNvZGluZ2ludmFsaWQgQmFzZTY0IGxlbmd0aGBtcHNjYCBjaGFubmVsIGRyb3BwZWQuRXhwZWN0ZWQgZXJyb3Igbm90IGZvdW5kLk5vIGV2ZW50IHRhcmdldC5gRnV0dXJlYCBwb2xsZWQgdW5leHBlY3RlZGx5LkV4cGVjdGVkIHRoZSBUcmFuc2FjdGlvbiB0byBiZSBhYm9ydGVkLCBidXQgaXQgd2FzIGNvbW1pdHRlZC5FeHBlY3RlZCB0aGUgVHJhbnNhY3Rpb24gdG8gYmUgY29tbWl0dGVkLCBidXQgaXQgd2FzIGFib3J0ZWQuTXV0ZXggcG9pc29uZWQuY2xvc3VyZSBpbnZva2VkIHJlY3Vyc2l2ZWx5IG9yIGFmdGVyIGJlaW5nIGRyb3BwZWRLAgAABAAAAAQAAABMAgAATQIAAHJlc3VsdGNhbm5vdCByZWN1cnNpdmVseSBhY3F1aXJlIG11dGV4AADuThEAIAAAACwgEABcAAAAEwAAAAkAAABNaXNzaW5nIGRhdGE6IAAAKE8RAA4AAABHZW5lcmljIEpTIGVycm9yOiAAAEBPEQASAAAAU2VyZGVFcnJvclNpbXBsZSB2YWx1ZSBwYXJzZSBlcnJvcjogZk8RABoAAAB0aGVyZSBpcyBubyBzdWNoIHRoaW5nIGFzIGEgcmVsZWFzZSBmYWlsdXJlIG9yZGVyaW5niE8RADQAAAB0axAATwAAAOcPAAAdAAAAdGhlcmUgaXMgbm8gc3VjaCB0aGluZyBhcyBhbiBhY3F1aXJlLXJlbGVhc2UgZmFpbHVyZSBvcmRlcmluZwAAANRPEQA9AAAAdGsQAE8AAADmDwAAHAAAAB48EABlAAAAXwEAACQAAAAePBAAZQAAAAMBAAAUAAAALCBbZW1wdHldAAAA7QcQAGQAAABlAQAALQAAAE5vdCBhIHN0cmluZ05vdCBhIG51bWJlck5vdCBhIGJvb2xlYW5EeW5hbWljIGNhc3QgZmFpbGVkVGhlIHZhbHVlIGlzIHRvbyBsYXJnZTogoFARABgAAABUaGUgdmFsdWUgaXMgdG9vIHNtYWxsOiDAUBEAGAAAAFRoZSB2YWx1ZSBpcyBzaWduZWQ6IAAAAOBQEQAVAAAARXJyb3JzIHBlcmZvcm1pbmcgYFRyeUZyb21Kc2Agb24gYFN3aXRjaGA6IAAAUREAKwAAAEludmFsaWRTdGF0ZUVycm9yVHJhbnNhY3Rpb25JbmFjdGl2ZUVycm9yTm90Rm91bmRFcnJvckNvbnN0cmFpbnRFcnJvckludmFsaWRBY2Nlc3NFcnJvckRhdGFFcnJvckFib3J0RXJyb3JSZWFkT25seUVycm9yRGF0YUNsb25lRXJyb3JTeW50YXhFcnJvcmFzc2VydGlvbiBmYWlsZWQ6IHNlbGYuaW5uZXIuc2VtYXBob3JlLmlzX2lkbGUoKas1EABkAAAASwEAAA0AAACrNRAAZAAAAEQBAAANAAAAOiAAAFACAAAEAAAABAAAAFECAABSAgAARm5PbmNlIGNhbGxlZCBtb3JlIHRoYW4gb25jZVACAAAEAAAABAAAAFMCAABUAgAAUAIAAAQAAAAEAAAAVQIAAFYCAABOb24tRXJyb3IgSlNWYWx1ZSBlcnJvclZlcnNpb24gY2Fubm90IGJlIHplcm9VbnN1cHBvcnRlZCBl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AgAAegIAAHsCAABeAAAAfAIAAC0tIDvUWREAAwAAANdZEQABAAAAdHJhY2luZzo6c3BhbgAAAHkzEABKAAAAlAgAAB8AAAB6MRAAXgAAACwAAAAKAAAAnVwQAGEAAAAiAAAAAQAAAHByb21pc2UgcmVzb2x2ZWQgdG8gdW5leHBlY3RlZCB0eXBlAPlIEABmAAAAYwAAADYAAAByZXNwb25zZS50ZXh0IGlzbid0IHN0cmluZwAA+UgQAGYAAAB1AAAANgAAAPlIEABmAAAAggAAABkAAAAgc3Bhbj0AAAEAAAAAAAAAmFoRAAYAAAA8LSAAsFoRAAMAAADXWREAAQAAAHRyYWNpbmc6OnNwYW46OmFjdGl2ZS0+INlaEQADAAAA11kRAAEAAACHbBAAOwAAANgDAAAFAAAAAAAAAAQAAAAEAAAAfQIAAAAAAAAdAEGgtsUAC+EHBAAAAAQAAAB+AgAALVQQAEoAAAC9AQAAHQAAAG5vZGVfaWRlZDI1NTE5X2lkZW50aXR5X3B1YmtleWlwX2FkZHJlc3Nlc21peF9wb3J0eDI1NTE5X3NwaGlueF9wdWJrZXlyb2xlc3VwcG9ydGVkX3JvbGVzZW50cnlwZXJmb3JtYW5jZXN0cnVjdCBTa2ltbWVkTm9kZSB3aXRoIDkgZWxlbWVudHMApVsRACIAAAAAAAAACAAAAAQAAACEAAAAdG90YWxwYWdlc2l6ZXN0cnVjdCBQYWdpbmF0aW9uIHdpdGggMyBlbGVtZW50cwAA7VsRACEAAABob3N0bmFtZXdzX3BvcnR3c3NfcG9ydHN0cnVjdCBCYXNpY0VudHJ5SW5mb3JtYXRpb24gd2l0aCAzIGVsZW1lbnRzAC9cEQAsAAAAc3RhdHVzYWJzb2x1dGVfZXBvY2hfaWRyb3RhdGlvbl9pZHJlZnJlc2hlZF9hdHN0cnVjdCBOb2Rlc1Jlc3BvbnNlTWV0YWRhdGEgd2l0aCA0IGVsZW1lbnRzAACSXBEALAAAAGlkZXBvY2hzX2luX2ludGVydmFsY3VycmVudF9lcG9jaF9zdGFydGN1cnJlbnRfZXBvY2hfaWRlcG9jaF9sZW5ndGh0b3RhbF9lbGFwc2VkX2Vwb2Noc3N0cnVjdCBJbnRlcnZhbCB3aXRoIDYgZWxlbWVudHMAAB9dEQAfAAAAbWl4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aW5hdGlvbiB3aXRoIDMgZWxlbWVudHMAAAB4ZBEAIQAAAHN0cnVjdCBCYXNpY0VudHJ5SW5mb3JtYXRpb24gd2l0aCAzIGVsZW1lbnRzpGQRACwAAABzdHJ1Y3QgTm9kZXNSZXNwb25zZU1ldGFkYXRhIHdpdGggNCBlbGVtZW50c9hkEQAsAAAAc3RydWN0IEludGVydmFsIHdpdGggNiBlbGVtZW50cwAMZREAHwAAAHN0cnVjdCBEZWNsYXJlZFJvbGVzIHdpdGggNCBlbGVtZW50czRlEQAkAAAAc3RydWN0IFJld2FyZGVkU2V0UmVzcG9uc2Ugd2l0aCA3IGVsZW1lbnRzAABgZREAKgAAAHN0cnVjdCBQYWdpbmF0ZWRSZXNwb25zZSB3aXRoIDIgZWxlbWVudHOUZREAKAAAAHN0cnVjdCBQYWdpbmF0ZWRDYWNoZWROb2Rlc1Jlc3BvbnNlVjIgd2l0aCAyIGVsZW1lbnRzAAAAxGURADUAQYzMxQALhhABAAAAlAIAAMBwEABWAAAA4gAAAAoAAAB5MxAASgAAAJQIAAAfAAAAJx4QAEMAAADmAAAACgAAAC1UEABKAAAApwEAAB8AAABTbGljZSBoYWQgYnl0ZXMgcmVtYWluaW5nIGFmdGVyIGRlc2VyaWFsaXphdGlvbmV2ZW50IGNvbW1vbi9jbGllbnQtY29yZS9zcmMvaW5pdC9oZWxwZXJzLnJzOjIxN255bV9jbGllbnRfY29yZTo6aW5pdDo6aGVscGVyc21lc3NhZ2XRZhEABwAAAAAAAAAMAAAABAAAAJUCAACWAgAAlwIAAGNvbW1vbi9jbGllbnQtY29yZS9zcmMvaW5pdC9oZWxwZXJzLnJzAAABAAAA2QAAAAAAAACDZhEAMAAAALNmEQAeAAAA2GYRAAEAAAA0nxkA4GYRALNmEQAeAAAA+GYRACYAAAABAAAAZXZlbnQgY29tbW9uL2NsaWVudC1jb3JlL3NyYy9pbml0L2hlbHBlcnMucnM6MjUzAQAAAP0AAAADAAAAYGcRADAAAACzZhEAHgAAANhmEQABAAAAKJ8ZAOBmEQCzZhEAHgAAAPhmEQAmAAAAAQAAAGV2ZW50IGNvbW1vbi9jbGllbnQtY29yZS9zcmMvaW5pdC9oZWxwZXJzLnJzOjIzNwEAAADtAAAA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AAAAnQIAAAAAAAAEAAAABAAAANEBAABFcnJvciBwYXJzaW5nIGRlY2ltYWwgJyc6IAAAKG8RABcAAAA/bxEAAwAAAHVsbAAEAAAAAAAAAAQAAAAEAEHw3sUAC5kIDAAAAAAAAAAEAAAABAAAAJ4CAAAAAAAABAAAAAQAAACfAgAAS2V5TWF0ZXJpYWxPZkludmFsaWRTaXplcmVjZWl2ZWRleHBlY3RlZE1pc3NpbmdOb25jZUZvckN1cnJlbnRLZXkAAAAAAAAABAAAAAQAAACgAgAAS2V5VXNhZ2VGYWlsdXJlSW52YWxpZFNpZ25hdHVyZU5ldHdvcmtFcnJvckNsb3NlZFN0cmVhbQAAAAAABAAAAAQAAAA8AAAAUmVtb3RlRXJyb3JNYWxmb3JtZWRSZXNwb25zZU1hbGZvcm1lZFJlcXVlc3RIYW5kc2hha2VGYWlsdXJlUmVjZWl2ZWRTaHV0ZG93blRpbWVvdXQAAAAAAAQAAAAEAAAA1AAAAAAAAAABAAAAAQAAAKECAAAAAAAABAAAAAQAAADwAQAATnl4ZAAAAAAEAAAABAAAAKICAABDb2NvbnV0QXBpRXJyb3IAAAAAAAQAAAAEAAAA6wEAAENyZWRlbnRpYWxTdG9yYWdlRXJyb3JOb0NyZWRlbnRpYWxzQXZhaWxhYmxlAAAAAAQAAAAEAAAAowIAAFN0b3JhZ2VFcnJvcgAAAAAEAAAABAAAAKQCAABFY2FzaEVycm9yAAAAAAAABAAAAAQAAABCAAAAVmFsaWRhdG9yRXJyb3IAAAAAAAAEAAAABAAAAKUCAABDcmVkZW50aWFsRXJyb3IAAAAAAAQAAAAEAAAAQAAAAEVkMjU1MTlQYXJzZUVycm9yAAAAAAAAAAQAAAAEAAAAAAIAAFgyNTUxOVBhcnNlRXJyb3JJbnZhbGlkVHhIYXNoTm9UaHJlc2hvbGRVbnN1cHBvcnRlZENyZWRlbnRpYWxTdG9yYWdlUmV2aXNpb25zdG9yZWRFeGhhdXN0ZWRBcGlRdWVyaWVzdHlwYW4gYXJyYXkgb2YgbGVuZ3RoIDE2AAAAAAAAAAQAAAAEAAAApgIAAE9mZnNldERhdGVUaW1lSnNvblNjaGVtYVdyYXBwZXJzZWNzbmFub3MAAAAAAAAAAAEAAACJAgAAYSBzZXF1ZW5jZQAA7RgQAF8AAACVBAAAIgAAAO0YEABfAAAAmAQAABwAAABwYWdpbmF0aW9udG90YWxlbnRyeV9nYXRld2F5c2V4aXRfZ2F0ZXdheXNsYXllcjFsYXllcjJsYXllcjNzdGFuZGJ5bWl4bm9kZWVudHJ5ZXhpdF9ucmlkZXBvY2hzX2luX2ludGVydmFsY3VycmVudF9lcG9jaF9zdGFydGN1cnJlbnRfZXBvY2hfaWRlcG9jaF9sZW5ndGh0b3RhbF9lbGFwc2VkX2Vwb2Noc3N0cnVjdCBQYWdpbmF0ZWRSZXNwb25zZQAAAG9yEQAEAAAAc3IRAAUAQZTnxQALvgwBAAAApwIAAEludGVydmFsCnMRAAIAAAAMcxEAEgAAAB5zEQATAAAAMXMRABAAAABBcxEADAAAAE1zEQAUAAAAb3ZlcmZsb3cgaW4gRHVyYXRpb246Om5ldwAAAJVMEABIAAAAyQAAABIAAABvdmVyZmxvdyBkZXNlcmlhbGl6aW5nIER1cmF0aW9uAAAAAAAEAAAABAAAAKgCAAAAAAAAEAAAAAQAAACpAgAAAAAAABAAAAAIAAAACwAAAAAAAAAEAAAABAAAANEBAAAAAAAABAAAAAQAAACqAgAAAAAAAAQAAAAEAAAAqwIAAAAAAAAEAAAABAAAAKwCAABhbiBhcnJheSBvZiBsZW5ndGggNAAAAAAEAAAABAAAAOsBAABFcmFzZWRHYXRld2F5RXJyb3JCYXNpY0VudHJ5SW5mb3JtYXRpb25ob3N0bmFtZXdzX3BvcnR3c3NfcG9ydAAA23QRAAgAAADjdBEABwAAAOp0EQAIAAAAc3RhdHVzYWJzb2x1dGVfZXBvY2hfaWRyb3RhdGlvbl9pZHJlZnJlc2hlZF9hdG5vLXVwZGF0ZXNmcmVzaAAAADp1EQAKAAAARHURAAUAAABub2Rlc01peG5vZGVFbnRyeUdhdGV3YXllbnRyeWdhdGV3YXlFeGl0R2F0ZXdheWV4aXRTdGFuZGJ5SW5hY3RpdmUAAGF1EQAHAAAAaHURAAwAAAB0dREABQAAAHl1EQAHAAAAgHURAAsAAACLdREABAAAAI91EQAHAAAAlnURAAgAAABub2RlX2lkZWQyNTUxOV9pZGVudGl0eV9wdWJrZXlpcF9hZGRyZXNzZXN4MjU1MTlfc3BoaW54X3B1YmtleWVwb2NoX3JvbGVzdXBwb3J0ZWRfcm9sZXNwZXJmb3JtYW5jZWxheWVydmFyaWFudCBpbmRleCAwIDw9IGkgPCA1AEd2EQAYAAAAAAAAAAgAAAAEAAAAhAAAAHZhcmlhbnQgaW5kZXggMCA8PSBpIDwgMnh2EQAYAAAAc3RydWN0IFBhZ2luYXRlZENhY2hlZE5vZGVzUmVzcG9uc2VWMmRlc2NyaXB0aW9uKCkgaXMgZGVwcmVjYXRlZDsgdXNlIERpc3BsYXkAAACzjK3JPW9GC7ZQssPhmTnQBfBl/v31V7Qrnu7zaKWwdsRZJhFJR777Sj+4dMmpHj1r6WCNqUfYHddO/y6WqtCmg3VgI6Ph732wFPLL2BUUQYXohr6lN2citiAGcuM3Kv38KutnuZ9FfAtEQu8PTaRtzoJXsDvCitu+H6lpmafgIxltjVc2gT4Lmdl0bGgqgE6SqwgQlrDEdZQOAKyhwWAL+or6CW3w5Bp+1T9T8rXU2IWolUVF7p2ck/vanD003kKe3GQqzr/XhXJ/h2XcLrM+uAIAACAAAAAEAAAAqAEAALgCAAAgAAAABAAAALkCAACoAQAAuHcRAKoBAAC6AgAAuwIAAKwBAAC8AgAAvQIAAFgAAAAIAAAAvgIAAL0CAABYAAAACAAAAL8CAAC+AgAA9HcRAMACAADBAgAAwgIAAMMCAADEAgAAxQIAAAQAAAAEAAAAxgIAAMUCAAAEAAAABAAAAMcCAADGAgAAMHgRAMgCAADJAgAAuwIAAMgCAADKAgAAAAAAAAEAAAABAAAAswEAAAAAAAABAAAAAQAAAMsCAACzAQAAbHgRAMwCAADNAgAAzgIAALgBAADPAgAA0AIAAAQAAAAEAAAA0QIAANACAAAEAAAABAAAANICAADRAgAAqHgRANMCAADUAgAAuwIAANMCAADVAgAAAAAAAAEAAAABAAAA1gIAAAAAAAABAAAAAQAAANcCAADWAgAA5HgRAMwCAADYAgAAzgIAAMwCAADPAgAA2QIAAAgAAAAEAAAA2gIAANkCAAAIAAAABAAAANsCAADaAgAAIHkRANwCAADdAgAAuwIAAN4CAAC8AgAA3wIAAAgAAAAEAAAA4AIAAN8CAAAIAAAABAAAAOECAADgAgAAXHkRAOICAADjAgAAuwIAAOQCAAC8AgAA5QIAABAAAAAEAAAAkwEAAOUCAAAQAAAABAAAAOYCAACTAQAAmHkRAJUBAADnAgAAuwIAAJgBAAC8AgBB3PPFAAsGAQAAAOgCAEHs88UAC/ktAQAAAOkCAADoAgAA1HkRAOoCAADrAgAA7AIAAOoCAADtAgAA7gIAAAQAAAAEAAAA7wIAAO4CAAAEAAAABAAAAPACAADvAgAAEHoRAPECAADyAgAAuwIAAPMCAADVAgAA9AIAAAQAAAAEAAAA9QIAAPQCAAAEAAAABAAAAPYCAAD1AgAATHoRAPcCAAD4AgAAuwIAAPcCAAD5AgAA+gIAAGAAAAAIAAAAmwEAAPoCAABgAAAACAAAAPsCAACbAQAAiHoRAJ0BAAD8AgAAwgIAAKABAADEAgAARW1wdHlIb3N0SWRuYUVycm9ySW52YWxpZFBvcnRJbnZhbGlkSXB2NEFkZHJlc3NJbnZhbGlkSXB2NkFkZHJlc3NJbnZhbGlkRG9tYWluQ2hhcmFjdGVyUmVsYXRpdmVVcmxXaXRob3V0QmFzZVJlbGF0aXZlVXJsV2l0aENhbm5vdEJlQUJhc2VCYXNlU2V0SG9zdE9uQ2Fubm90QmVBQmFzZVVybE92ZXJmbG93Tm9uZQAAAAAAAAQAAAAEAAAAPAAAAFNvbWUAAAAABAAAAAQAAAD9AgAAAAAAAAQAAAAEAAAA1AAAAEVtcHR5TmV0d29ya1RvcG9sb2d5AAAAAAQAAAAEAAAA4QEAAE5vbkV4aXN0ZW50Tm9kZW5vZGVfaWRlbnRpdHlJbnZhbGlkRWdyZXNzUm9sZUluc3VmZmljaWVudE1peGluZ05vZGVzTm9HYXRld2F5c0F2YWlsYWJsZU5vTWl4bm9kZXNBdmFpbGFibGVOb25FeGlzdGVudEdhdGV3YXlFcnJvcmlkZW50aXR5X2tleVRpbWVkT3V0V2FpdGluZ0ZvckdhdGV3YXkAAAAAAAAEAAAABAAAAP4CAAAAAAAABAAAAAQAAACfAgAASW52YWxpZE51bWJlck9mSG9wc0Vycm9yYXZhaWxhYmxlcmVxdWVzdGVkRW1wdHlNaXhMYXllcgAAAAAAAQAAAAEAAAD/AgAAAAAAAAQAAAAEAAAA4wEAAGxvd2VyX2JvdW5kdXBwZXJfYm91bmR0b3RhbF9ub2Rlc2xheWVyX2Rpc3RyaWJ1dGlvbgBCdhEABQAAAFx1EQAFAAAA8HwRAAsAAAD7fBEACwAAAAZ9EQALAAAAEX0RABIAAABVbmV2ZW5MYXllckRpc3RyaWJ1dGlvblBheWxvYWRCdWlsZGVyAAAAAAAAAAQAAAAEAAAA5AEAAE91dGZveAAAAAAAAAQAAAAEAAAA5QEAAEZyb21TbGljZQAAAAAAAAAEAAAABAAAAOYBAABQYWNrZXRFcnJvcgAAAAAABAAAAAQAAADTAQAAUmVxd2VzdEVycm9yAAAAAAQAAAAEAAAA5wEAAFZhckVycm9yAAAAAAQAAAAEAAAAAAMAAEkvTyBlcnJvcjogABB+EQALAAAAZ2F0ZXdheSBjbGllbnQgZXJyb3IgKCk6IAAAACR+EQAWAAAAOn4RAAMAAABjdXN0b20gZ2F0ZXdheSBjbGllbnQgZXJyb3I6IAAAAFB+EQAdAAAAZWQyNTUxOSBlcnJvcjogAHh+EQAPAAAAdmFsaWRhdG9yIGNsaWVudCBlcnJvcjogkH4RABgAAABubyBnYXRld2F5IHdpdGggaWQ6ILB+EQAUAAAASW52YWxpZCBVUkw6IAAAAMx+EQANAAAAbm8gZ2F0ZXdheXMgb24gbmV0d29ya3RoZXJlIGFyZSBubyBtb3JlIG5ldyBnYXRld2F5cyBvbiB0aGUgbmV0d29yayAtIGl0IHNlZW1zIHRoaXMgY2xpZW50IGhhcyBhbHJlYWR5IHJlZ2lzdGVyZWQgd2l0aCBhbGwgbm9kZXMgaXQgY291bGQgaGF2ZWxpc3Qgb2YgbnltIGFwaXMgaXMgZW1wdHlmYWlsZWQgdG8gcmVzb2x2ZSBhIHF1ZXJ5IHRvIG55bSBBUEk6IAAAAIt/EQAmAAAAdGhlIGN1cnJlbnQgbmV0d29yayB0b3BvbG9neSBzZWVtIHRvIGJlIGluc3VmZmljaWVudCB0byByb3V0ZSBhbnkgcGFja2V0cyB0aHJvdWdoOgoJvH8RAFQAAABleHBlcmllbmNlZCBhIGZhaWx1cmUgd2l0aCBvdXIgcmVwbHkgc3VyYiBwZXJzaXN0ZW50IHN0b3JhZ2U6IAAAGIARAD4AAABleHBlcmllbmNlZCBhIGZhaWx1cmUgd2l0aCBvdXIgY3J5cHRvZ3JhcGhpYyBrZXlzIHBlcnNpc3RlbnQgc3RvcmFnZTogAABggBEARgAAAGV4cGVyaWVuY2VkIGEgZmFpbHVyZSB3aXRoIG91ciBnYXRld2F5cyBkZXRhaWxzIHN0b3JhZ2U6IAAAALCAEQA5AAAAZXhwZXJpZW5jZWQgYSBmYWlsdXJlIHdpdGggb3VyIGNyZWRlbnRpYWxzIHN0b3JhZ2U6IPSAEQA0AAAAdGhlIHByb3ZpZGVkIHRpY2tldCB0eXBlIGlzIGludmFsaWR0aGUgZ2F0ZXdheSBpZCBpcyBpbnZhbGlkIC0gAFOBEQAcAAAAdGhlIG5vZGUgaXMgbWFsZm9ybWVkOiAAeIERABcAAABmYWlsZWQgdG8gZXN0YWJsaXNoIGNvbm5lY3Rpb24gdG8gZ2F0ZXdheTogAJiBEQArAAAAZmFpbGVkIHRvIGVzdGFibGlzaCBnYXRld2F5IGNvbm5lY3Rpb24gKHdhc20pZ2F0ZXdheSBjb25uZWN0aW9uIHdhcyBhYnJ1cHRseSBjbG9zZWR0aW1lZCBvdXQgd2hpbGUgdHJ5aW5nIHRvIGVzdGFibGlzaCBnYXRld2F5IGNvbm5lY3Rpb25mYWlsZWQgdG8gZm9yd2FyZCBtaXggbWVzc2FnZXMgdG8gZ2F0ZXdheW5vIHBpbmcgbWVhc3VyZW1lbnRzIGZvciB0aGUgZ2F0ZXdheSAoKSBwZXJmb3JtZWQAfoIRACYAAACkghEACwAAAGZhaWxlZCB0byByZWdpc3RlciByZWNlaXZlciBmb3IgcmVjb25zdHJ1Y3RlZCBtaXhuZXQgbWVzc2FnZXN1bmV4cGVjdGVkIGV4aXR0aGlzIG9wZXJhdGlvbiB3b3VsZCBoYXZlIHJlc3VsdGVkIGluIHRoZSBnYXRld2F5ICBrZXkgYmVpbmcgb3ZlcndyaXR0ZW4gd2l0aG91dCBwZXJtaXNzaW9uAAyDEQAyAAAAPoMRACkAAAB0aGlzIG9wZXJhdGlvbiB3b3VsZCBoYXZlIHJlc3VsdGVkIGluIGNsaWVudHMga2V5cyBiZWluZyBvdmVyd3JpdHRlbiB3aXRob3V0IHBlcm1pc3Npb250aGUgY2xpZW50IGRvZXNuJ3QgaGF2ZSBhbnkgZ2F0ZXdheSBzZXQgYXMgYWN0aXZlZ2F0ZXdheSBkZXRhaWxzIGZvciBnYXRld2F5ICBhcmUgdW5hdmFpbGFibGUAhBEAHAAAAByEEQAQAAAAZ2F0ZXdheSBzaGFyZWQga2V5IGlzIHVuYXZhaWxhYmxlIHdoaWxzdCB3ZSBoYXZlIGZ1bGwgbm9kZSBpbmZvcm1hdGlvbmF0dGVtcHRlZCB0byBvYnRhaW4gZnJlc2ggZ2F0ZXdheSBkZXRhaWxzIHdoaWxzdCBhbHJlYWR5IGtub3dpbmcgYWJvdXQgb25ldGhlIHByb3ZpZGVkIGdhdGV3YXkgZGV0YWlscyAoZm9yIGdhdGV3YXkgKSBkbyBub3QgY29ycmVzcG9uZCB0byB0aGUgc2hhcmVkIGtleXPMhBEAKgAAAPaEEQAmAAAAdW5hYmxlIHRvIHVwZ3JhZGUgY29uZmlnIGZpbGUgZnJvbSBgYAAAACyFEQAkAAAAUIURAAEAAAB1bmFibGUgdG8gdXBncmFkZSBjb25maWcgZmlsZSB0byBgAABkhREAIgAAAFCFEQABAAAAZmFpbGVkIHRvIHVwZ3JhZGUgY29uZmlnIGZpbGU6IACYhREAHwAAAHRoZSBwcm92aWRlZCBnYXRld2F5IGRldGFpbHMgZG9uJ3QgbXVjaCB0aGUgc3RvcmVkIGRhdGFjdXN0b20gc2VsZWN0aW9uIG9mIGdhdGV3YXkgd2FzIGV4cGVjdGVkdGhlIHBlcnNpc3RlZCBnYXRld2F5IGRldGFpbHMgd2VyZSBzZXQgZm9yIGEgY3VzdG9tIHNldHVwdGhpcyBjbGllbnQgaGFzIHBlcmZvcm1lZCBnYXRld2F5IGluaXRpYWxpc2F0aW9uIGluIGFub3RoZXIgc2Vzc2lvbnRoZXJlIGFyZSBubyBnYXRld2F5cyBzdXBwb3J0aW5nIHRoZSB3c3MgcHJvdG9jb2wgYXZhaWxhYmxldGhlIHNwZWNpZmllZCBnYXRld2F5ICcnIGRvZXMgbm90IHN1cHBvcnQgdGhlIHdzcyBwcm90b2NvbNaGEQAXAAAA7YYRACMAAABub2RlICAoKSBkb2VzIG5vdCBzdXBwb3J0IG1peG5ldCBlbnRyeSBtb2RlACCHEQAFAAAAJYcRAAIAAAAnhxEAJAAAAGZhaWxlZCB0byBsb2FkIGN1c3RvbSB0b3BvbG9neSB1c2luZyBwYXRoICcnLiBkZXRhaWxlZCBtZXNzYWdlOiBkhxEAKwAAAI+HEQAVAAAAZmFpbGVkIHRvIHNhdmUgY29uZmlnIGZpbGUgZm9yIGNsaWVudC0gaWQgIHVzaW5nIHBhdGggJwC0hxEAJgAAANqHEQAEAAAA3ocRAA0AAACPhxEAFQAAAHRoZSBwcm92aWRlZCBnYXRld2F5IGlkZW50aXR5ICBpcyBtYWxmb3JtZWQ6IAAAAAyIEQAeAAAAKogRAA8AAAB0aGUgbGlzdGVuaW5nIGFkZHJlc3Mgb2YgZ2F0ZXdheSApIGlzIG1hbGZvcm1lZDogAAAATIgRACEAAAAlhxEAAgAAAG2IEQAQAAAAdGhpcyBjbGllbnQgKGlkOiAnJykgaGFzIGFscmVhZHkgYmVlbiBpbml0aWFsaXNlZCBiZWZvcmUuIElmIHlvdSB3YW50IHRvIGFkZCBhZGRpdGlvbmFsIGdhdGV3YXksIHVzZSBgYWRkLWdhdGV3YXlgIGNvbW1hbmQAAJiIEQASAAAAqogRAGgAAAB0aGlzIGNsaWVudCBoYXMgYWxyZWFkeSByZWdpc3RlcmVkIHdpdGggZ2F0ZXdheSAkiREAMAAAAGZyZXNoIHJlZ2lzdHJhdGlvbiB3aXRoIGdhdGV3YXkgIHNvbWVob3cgcmVxdWlyZXMgYW4gYWRkaXRpb25hbCBrZXkgdXBncmFkZSFciREAIAAAAHyJEQAsAAAAZmFpbGVkIHRvIGRlcml2ZSBrZXlzIGZyb20gbWFzdGVyIGtleW1pc3NpbmcgdXJsIGZvciBjb25zdHJ1Y3RpbmcgUlBDIGNsaWVudHByb3ZpZGVkIG55bSBuZXR3b3JrIGRldGFpbHMgd2VyZSBtYWxmb3JtZWQ6IAAAAASKEQAtAAAAZmFpbGVkIHRvIGNvbnN0cnVjdCBSUEMgY2xpZW50OiA8ihEAIAAAAGZhaWxlZCB0byBzZWxlY3QgdmFsaWQgZ2F0ZXdheSBkdWUgdG8gaW5jb21wdXRhYmxlIGxhdGVuY3lDb3VsZCBub3QgYWNjZXNzIHRhc2sgcmVnaXN0cnksIAAAnooRACAAAABOb0NvbnRyYWN0QWRkcmVzc0F2YWlsYWJsZQAAAAAAAAQAAAAEAAAAAQMAAFdhbGxldEVycm9yAAAAAAAEAAAABAAAAAIDAABDb3NtcnNFcnJvcgAAAAAABAAAAAQAAAD8AQAAQ29zbXJzRXJyb3JSZXBvcnRDb21zd2FzbUV2ZW50Tm90Rm91bmRDb21zd2FzbUF0dHJpYnV0ZU5vdEZvdW5kQWNjb3VudERlcml2YXRpb25FcnJvcgAAAAAAAAAEAAAABAAAAAMDAABTaWduaW5nQWNjb3VudE5vdEZvdW5kU2lnbmluZ0ZhaWx1cmVJbnZhbGlkVHhIYXNoAAAAAAAAAAQAAAAEAAAA+wEAAFRlbmRlcm1pbnRFcnJvclJwYwAAAAAAAAQAAAAEAAAABAMAAFRlbmRlcm1pbnRFcnJvclNlcmlhbGl6YXRpb25FcnJvckRlc2VyaWFsaXphdGlvbkVycm9yAAAAAAAAAAQAAAAEAAAABQMAAFByb3RvYnVmRW5jb2RpbmdFcnJvcgAAAAAAAAAEAAAABAAAAAYDAABQcm90b2J1ZkRlY29kaW5nRXJyb3JOb25FeGlzdGVudEFjY291bnRFcnJvcgAAAAAEAAAABAAAANsBAABTZXJkZUpzb25FcnJvck1hbGZvcm1lZEFjY291bnRBZGRyZXNzSW52YWxpZFB1YmxpY0tleQAAAAAAAAAEAAAABAAAAAcDAABOb0NvZGVJbmZvcm1hdGlvbk5vQ29udHJhY3RJbmZvcm1hdGlvbkludmFsaWRDb250cmFjdEhpc3RvcnlPcGVyYXRpb25JbnZhbGlkSGVpZ2h0AAAAAAAABAAAAAQAAABiAAAAV2FzbUNvbXByZXNzaW9uRXJyb3JNYWxmb3JtZWRMb2dTdHJpbmcAAAAAAAAhAAAAAQAAAAgDAAAAAAAAEAAAAAgAAAAJAwAAQnJvYWRjYXN0VHhFcnJvckNoZWNrVHhoYXNoaGVpZ2h0Y29kZXJhd19sb2dCcm9hZGNhc3RUeEVycm9yRGVsaXZlclR4TWFsZm9ybWVkR2FzUHJpY2VHYXNFc3RpbWF0aW9uRmFpbHVyZQAACgMAAAwAAAAEAAAACwMAAAAAAAAEAAAABAAAAAwDAABBYmNpRXJyb3Jsb2dwcmV0dHlfbG9nVW5zdXBwb3J0ZWRBY2NvdW50VHlwZXR5cGVfdXJsTWFsZm9ybWVkQ29pbmNvaW5fcmVwcmVzZW50YXRpb25Ob0Jhc2VBY2NvdW50SW5mb3JtYXRpb25BdmFpbGFibGUAAAAAAAAABAAAAAQAAAANAwAAQnJvYWRjYXN0VGltZW91dHRpbWVvdXQAAAAAAAQAAAAEAAAADgMAAENvc213YXNtU3RkRXJyb3JVbmV4cGVjdGVkQmVjaDMyUHJlZml4Z290ZXhwZWN0ZWRVbmV4cGVjdGVkTnVtYmVyT2ZNc2dSZXNwb25zZXNNYWxmb3JtZWRSZXNwb25zZURhdGFFeHRlbnNpb25RdWVyeUZhaWx1cmVjb250cmFjdG1lc3NhZ2VQb2lzb25lZAAAAAAEAAAABAAAAOoBAABOeW1BUElFcnJvcnNvdXJjZQAAAAAAAAAEAAAABAAAAEcAAABNYWxmb3JtZWRVcmxQcm92aWRlZAAAAAAEAAAABAAAAPABAABOeXhkRXJyb3JJbmNvbnNpc3RlbnRQYWdlZE1ldGFkYXRhTm9BUElVcmxBdmFpbGFibGVOb1VwZGF0ZXMAAAAABAAAAAQAAAAPAwAARnJlc2hOb0l0ZW1JbnZhbGlkV2VpZ2h0QWxsV2VpZ2h0c1plcm9Ub29NYW55AAAAAAAAAAQAAAAEAAAA/gEAAE1hbGZvcm1lZEJ5dGVzQnl0ZXNMZW5ndGhFcnJvcgAAAAAAAAQAAAAEAAAAaAEAAE1hbGZvcm1lZFB1YmxpY0tleVN0cmluZ01hbGZvcm1lZFByaXZhdGVLZXlTdHJpbmdNYWxmb3JtZWRTaWduYXR1cmVTdHJpbmcAAAB6UxAAXgAAAFgHAAARAAAABAAAAAAAAAAEAAAABABB8KHGAAt/DAAAAAkAAAAJAAAACwAAABIAAAASAAAAFgAAABYAAAAgAAAAGQAAAAgAAADEehEAzXoRANZ6EQDhehEA83oRAAV7EQAbexEAMXsRAFF7EQBqexEABgAAAA0AAAAOAAAABwAAABGQEQAXkBEAJJARADKQEQAtAAAAAQAFAQAAAQBB+KLGAAsNZJERAAEAAAABAAEBAQBBkKPGAAsdZJERAAEAAAABAAABAAAAAAAAAAAgOi4AAQAGAAEAQbijxgALDKWREQABAAAAAQAHAQBB0KPGAAsMpZERAAEAAAABAAkBAEHoo8YACwymkREAAQAAAAEACgkAQYCkxgALrwGlkREAAQAAAAEADQEAAAAAAAAAAAIAAAD8kREAAgAAAAAAAAClkREAAQAAAAEADAEAAAAAAAAAAAMAAAAUkhEAAAAAAAIAAAAgkhEAAwAAAAEACwEBAAAAAAAAAAMAAABEkhEAAAAAAAIAAABokREABQAAAAAAAACkkREAAQAAAAIAAACokREABwAAAAAAAACkkREAAQAAAAIAAABQkhEAAgAAAGiSEQAFAAAAAcgeAEG8pcYACxYQAwAADAAAAAQAAAARAwAAEgMAAHYCAEHcpcYAC58OAQAAABMDAABhIERpc3BsYXkgaW1wbGVtZW50YXRpb24gcmV0dXJuZWQgYW4gZXJyb3IgdW5leHBlY3RlZGx5AIJBEABLAAAABQsAAA4AAABFcnJvcgAAAIJBEABLAAAAsAwAAA4AAACCQRAASwAAAKoMAAAOAAAA7QcQAGQAAABlAQAALQAAAE5vbmUAAAAABAAAAAQAAADUAAAAU29tZQAAAAAEAAAABAAAABQDAAAAAAAABAAAAAQAAAA8AAAATm9JcEFkZHJlc3Nlc1Byb3ZpZGVkbm9kZV9pZGlkZW50aXR5Q29ubmVjdGlvbk5vdEVzdGFibGlzaGVkR2F0ZXdheUVycm9yAAAAAAQAAAAEAAAA8wEAAFR5cGVkR2F0ZXdheUVycm9yAAAAAAAAAAQAAAAEAAAA9AEAAFJlcXVlc3RFcnJvcgAAAAAEAAAABAAAAO0BAABOZXR3b3JrRXJyb3JGYXRhbEtleVVwZ3JhZGVGYWlsdXJlS2V5QWxyZWFkeVVwZ3JhZGVkS2V5QWxyZWFkeUluVXNlAAAAAAAEAAAABAAAAPUBAABOZXR3b3JrRXJyb3JXYXNtEAMAAAwAAAAEAAAAFQMAAE5ldHdvcmtDb25uZWN0aW9uRmFpbGVkYWRkcmVzc3NvdXJjZU5vRW5kcG9pbnRGb3JDb25uZWN0aW9uSW52YWxpZFVybE5vU2hhcmVkS2V5QXZhaWxhYmxlTm9CYW5kd2lkdGhDb250cm9sbGVyQXZhaWxhYmxlAAAAAAAEAAAABAAAAPYBAABCYW5kd2lkdGhDb250cm9sbGVyRXJyb3JDb25uZWN0aW9uQWJydXB0bHlDbG9zZWRDb25uZWN0aW9uQ2xvc2VkR2F0ZXdheVNodXRkb3duTWFsZm9ybWVkUmVzcG9uc2VTZXJpYWxpemVDcmVkZW50aWFsAAAAAAAEAAAABAAAABYDAABPdXRkYXRlZEdhdGV3YXlDcmVkZW50aWFsVmVyc2lvbm5lZ290aWF0ZWRfcHJvdG9jb2xOb3RBdXRoZW50aWNhdGVkAAAAAAAIAAAACAAAABcDAAAAAAAABAAAAAQAAADlAAAATm90RW5vdWdoQmFuZHdpZHRoTm9Nb3JlQmFuZHdpZHRoQ3JlZGVudGlhbHNCYW5kd2lkdGhCZWxvd0N1dG9mZlZhbHVlYXZhaWxhYmxlX2JpMmN1dG9mZl9iaTJVbmV4cGVjdGVkUmVzcG9uc2VuYW1lQ29ubmVjdGlvbkluSW52YWxpZFN0YXRlAAAAAAAABAAAAAQAAAD5AQAAUmVnaXN0cmF0aW9uRmFpbHVyZUF1dGhlbnRpY2F0aW9uRmFpbHVyZUF1dGhlbnRpY2F0aW9uRmFpbHVyZVdpdGhQcmVleGlzdGluZ1NoYXJlZEtleVRpbWVvdXRNaXhuZXRNc2dTZW5kZXJGYWlsZWRUb1NlbmQAAAAAAAIAAAABAAAAGAMAAEluY29tcGF0aWJsZVByb3RvY29sZ2F0ZXdheWN1cnJlbnRQYWNrZXRSb3V0ZXJVbmF2YWlsYWJsZVNodXRkb3duSW5Qcm9ncmVzcwAAAAAABAAAAAQAAACgAgAAS2V5VXNhZ2VGYWlsdXJlAAAAAAAEAAAABAAAANsBAABNYWxmb3JtZWRSZXF1ZXN0VW5rbm93blJlcXVlc3RLaW5ka2luZFVua25vd25SZXNwb25zZUtpbmRJbnZhbGlkRW5jcnlwdGlvbkZsYWdUb29TaG9ydFJlcXVlc3RJbnZhbGlkTWFjAAAAAAAEAAAABAAAABkDAABJbmNvcnJlY3RseUVuY29kZWRBZGRyZXNzAAAAAAAAAAQAAAAEAAAAnwIAAFJlcXVlc3RPZkludmFsaWRTaXplTWFsZm9ybWVkU3BoaW54UGFja2V0AAAAAAAAAAQAAAAEAAAAGgMAAFNwaGlueFNlcmlhbGlzYXRpb25GYWlsdXJlTWFsZm9ybWVkRW5jcnlwdGlvbkludmFsaWRQYWNrZXRNb2RlAAAAAAAABAAAAAQAAACkAgAARWNhc2hDcmVkZW50aWFsRGVzZXJpYWxpemF0aW9uRmFpbHVyZUNyZWRlbnRpYWxEZXNlcmlhbGl6YXRpb25GYWlsdXJlRU9GAAAAAAQAAAAEAAAAGwMAAENyZWRlbnRpYWxEZXNlcmlhbGl6YXRpb25GYWlsdXJlTWFsZm9ybWVkU3RyaW5nAAAAAAAEAAAABAAAANEBAABJbnZhbGlkTnVtYmVyT2ZFbWJlZGVkUGFyYW1ldGVycwAAAAAEAAAABAAAABwDAABBdXRoZW50aWNhdGlvbk90aGVyT3V0T2ZCYW5kd2lkdGhyZXF1aXJlZGF2YWlsYWJsZVRpY2tldFJlcGxheQAA///////////wmREAQYi0xgALtR5ldmVudCBjb21tb24vY2xpZW50LWNvcmUvc3JjL2luaXQvbW9kLnJzOjIwOG55bV9jbGllbnRfY29yZTo6aW5pdG1lc3NhZ2VJmhEABwAAAAAAAAAMAAAABAAAAJUCAAAdAwAAHgMAAGNvbW1vbi9jbGllbnQtY29yZS9zcmMvaW5pdC9tb2QucnMAAAEAAADQAAAAAQAAAAiaEQAsAAAANJoRABUAAABQmhEAAQAAAOifGQBYmhEANJoRABUAAABwmhEAIgAAAAEAAABldmVudCBjb21tb24vY2xpZW50LWNvcmUvc3JjL2luaXQvbW9kLnJzOjIxNwEAAADZAAAAAQAAANSaEQAsAAAANJoRABUAAABQmhEAAQAAANCfGQBYmhEANJoRABUAAABwmhEAIgAAAAEAAABldmVudCBjb21tb24vY2xpZW50LWNvcmUvc3JjL2luaXQvbW9kLnJzOjIzMwEAAADpAAAAAQAAAECbEQAsAAAANJoRABUAAABQmhEAAQAAAPSfGQBYmhEANJoRABUAAABwmhEAIgAAAAEAAABldmVudCBjb21tb24vY2xpZW50LWNvcmUvc3JjL2luaXQvbW9kLnJzOjIwNQEAAADNAAAAAQAAAKybEQAsAAAANJoRABUAAABQmhEAAQAAANyfGQBYmhEANJoRABUAAABwmhEAIgAAAAEAAABldmVudCBjb21tb24vY2xpZW50LWNvcmUvc3JjL2luaXQvbW9kLnJzOjY2AAEAAABCAAAAAAAAABicEQArAAAANJoRABUAAABQmhEAAQAAAACgGQBYmhEANJoRABUAAABwmhEAIgAAAAEAAAAfAwAAVwCPvCIs99wbgSsAqDxQ5mFzc2VydGlvbiBmYWlsZWQ6IHNsb3QuaXNfbm9uZSgpWwsQAGcAAACCAAAADQAAAGNhbGxlZCBgT3B0aW9uOjp1bndyYXBfdGhyb3coKWAgb24gYSBgTm9uZWAgdmFsdWVjYWxsZWQgYFJlc3VsdDo6dW53cmFwX3Rocm93KClgIG9uIGFuIGBFcnJgIHZhbHVlZXZlbnQgY29tbW9uL2NsaWVudC1saWJzL2dhdGV3YXktY2xpZW50L3NyYy9zb2NrZXRfc3RhdGUucnM6MjEwbnltX2dhdGV3YXlfY2xpZW50Ojpzb2NrZXRfc3RhdGVtZXNzYWdliZ0RAAcAAAAAAAAADAAAAAQAAACVAgAAIwMAACQDAABjb21tb24vY2xpZW50LWxpYnMvZ2F0ZXdheS1jbGllbnQvc3JjL3NvY2tldF9zdGF0ZS5ycwAAAAEAAADSAAAABAAAACqdEQA/AAAAaZ0RACAAAACQnREAAQAAADCgGQCYnREAaZ0RACAAAACwnREANQAAAAEAAABldmVudCBjb21tb24vY2xpZW50LWxpYnMvZ2F0ZXdheS1jbGllbnQvc3JjL3NvY2tldF9zdGF0ZS5yczoyMDEAAQAAAMkAAAADAAAAKJ4RAD8AAABpnREAIAAAAJCdEQABAAAAJKAZAJidEQBpnREAIAAAALCdEQA1AAAAAQAAAGV2ZW50IGNvbW1vbi9jbGllbnQtbGlicy9nYXRld2F5LWNsaWVudC9zcmMvc29ja2V0X3N0YXRlLnJzOjE2NQABAAAApQAAAAQAAAConhEAPwAAAGmdEQAgAAAAkJ0RAAEAAABgoBkAmJ0RAGmdEQAgAAAAsJ0RADUAAAABAAAAZXZlbnQgY29tbW9uL2NsaWVudC1saWJzL2dhdGV3YXktY2xpZW50L3NyYy9zb2NrZXRfc3RhdGUucnM6MTk1AAEAAADDAAAAAgAAACifEQA/AAAAaZ0RACAAAACQnREAAQAAADygGQCYnREAaZ0RACAAAACwnREANQAAAAEAAABldmVudCBjb21tb24vY2xpZW50LWxpYnMvZ2F0ZXdheS1jbGllbnQvc3JjL3NvY2tldF9zdGF0ZS5yczoxOTgAAQAAAMYAAAACAAAAqJ8RAD8AAABpnREAIAAAAJCdEQABAAAADKAZAJidEQBpnREAIAAAALCdEQA1AAAAAQAAAGV2ZW50IGNvbW1vbi9jbGllbnQtbGlicy9nYXRld2F5LWNsaWVudC9zcmMvc29ja2V0X3N0YXRlLnJzOjE3NgABAAAAsAAA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ZEJhbmR3aWR0aCBjb250cm9sbGVyIGVycm9yOiAAAJK1EQAcAAAAQ29ubmVjdGlvbiB3YXMgYWJydXB0bHkgY2xvc2VkQ29ubmVjdGlvbiB3YXMgYWJydXB0bHkgY2xvc2VkIGFzIGdhdGV3YXkgd2FzIHN0b3BwZWRSZWNlaXZlZCByZXNwb25zZSB3YXMgbWFsZm9ybWVkQ3JlZGVudGlhbCBjb3VsZCBub3QgYmUgc2VyaWFsaXplZGNhbiBub3Qgc3BlbmQgYmFuZHdpZHRoIGNyZWRlbnRpYWwgd2l0aCB0aGUgZ2F0ZXdheSBhcyBpdCdzIHVzaW5nIG91dGRhdGVkIHByb3RvY29sICh2ZXJzaW9uOiApAEy2EQBeAAAAqrYRAAEAAABDbGllbnQgaXMgbm90IGF1dGhlbnRpY2F0ZWRDbGllbnQgZG9lcyBub3QgaGF2ZSBlbm91Z2ggYmFuZHdpZHRoOiBlc3RpbWF0ZWQgLCByZW1haW5pbmc6IAAAANe2EQAxAAAACLcRAA0AAABUaGVyZSBhcmUgbm8gbW9yZSBiYW5kd2lkdGggY3JlZGVudGlhbHMgYWNxdWlyZWQuIFBsZWFzZSBidXkgc29tZSBtb3JlIGlmIHlvdSB3YW50IHRvIHVzZSB0aGUgbWl4bmV0dGhlIGN1cnJlbnQgYXZhaWxhYmxlIGJhbmR3aWR0aCAoKSBpcyBiZWxvdyB0aGUgbWluaW11bSBjdXRvZmYgdGhyZXNob2xkIG9mZiAAAACMtxEAIQAAAK23EQAsAAAAcmVjZWl2ZWQgYW4gdW5leHBlY3RlZCByZXNwb25zZSBvZiB0eXBlIOy3EQAoAAAAQ29ubmVjdGlvbiBpcyBpbiBhbiBpbnZhbGlkIHN0YXRlIC0gcGxlYXNlIHNlbmQgYSBidWcgcmVwb3J0RmFpbGVkIHRvIGZpbmlzaCByZWdpc3RyYXRpb24gaGFuZHNoYWtlOiAAAABYuBEAKQAAAEF1dGhlbnRpY2F0aW9uIGZhaWx1cmVBdXRoZW50aWNhdGlvbiBmYWlsdXJlIHdpdGggcHJlZXhpc3Rpbmcgc2hhcmVkIGtleVRpbWVkIG91dEZhaWxlZCB0byBzZW5kIG1peG5ldCBtZXNzYWdlQXR0ZW1wdGVkIHRvIG5lZ290aWF0ZSBjb25uZWN0aW9uIHdpdGggZ2F0ZXdheSB1c2luZyBpbmNvbXBhdGlibGUgcHJvdG9jb2wgdmVyc2lvbi4gT3VycyBpcyAgYW5kIHRoZSBnYXRld2F5IHJlcG9ydHMgAPq4EQBcAAAAVrkRABkAAABUaGUgcGFja2V0IHJvdXRlciBoYXNuJ3QgYmVlbiBzZXQgLSBhcmUgeW91IHN1cmUgeW91IHN0YXJ0ZWQgdXAgdGhlIGNsaWVudCBjb3JyZWN0bHk/dGhpcyBvcGVyYXRpb24gY291bGRuJ3QgYmUgY29tcGxldGVkIGFzIHRoZSBwcm9ncmFtIGlzIGluIHRoZSBwcm9jZXNzIG9mIHNodXR0aW5nIGRvd24AAAAAAAQAAAAEAAAAoAIAAEtleVVzYWdlRmFpbHVyZQAAAAAABAAAAAQAAADbAQAATWFsZm9ybWVkUmVxdWVzdHNvdXJjZU1hbGZvcm1lZFJlc3BvbnNlAAAAAAAEAAAABAAAANQAAABVbmtub3duUmVxdWVzdEtpbmRraW5kVW5rbm93blJlc3BvbnNlS2luZEludmFsaWRFbmNyeXB0aW9uRmxhZ1Rvb1Nob3J0UmVxdWVzdEludmFsaWRNYWMAAAAAAAQAAAAEAAAAGQMAAEluY29ycmVjdGx5RW5jb2RlZEFkZHJlc3MAAAAAAAAABAAAAAQAAACfAgAAUmVxdWVzdE9mSW52YWxpZFNpemVNYWxmb3JtZWRTcGhpbnhQYWNrZXQAAAAAAAAABAAAAAQAAAAaAwAAU3BoaW54U2VyaWFsaXNhdGlvbkZhaWx1cmVNYWxmb3JtZWRFbmNyeXB0aW9uSW52YWxpZFBhY2tldE1vZGUAAAAAAAAEAAAABAAAAKQCAABFY2FzaENyZWRlbnRpYWxEZXNlcmlhbGl6YXRpb25GYWlsdXJlQ3JlZGVudGlhbERlc2VyaWFsaXphdGlvbkZhaWx1cmVFT0YAAAAABAAAAAQAAAAbAwAAQ3JlZGVudGlhbERlc2VyaWFsaXphdGlvbkZhaWx1cmVNYWxmb3JtZWRTdHJpbmcAAAAAAAQAAAAEAAAA0QEAAEludmFsaWROdW1iZXJPZkVtYmVkZWRQYXJhbWV0ZXJzAAAAAAQAAAAEAAAAHAMAAEF1dGhlbnRpY2F0aW9uAAAAAAAABAAAAAQAAAA8AAAAT3RoZXIAAAAAAAAABAAAAAQAAADwAQAATnl4ZAAAAAAEAAAABAAAAKICAABDb2NvbnV0QXBpRXJyb3IAAAAAAAQAAAAEAAAA6wEAAENyZWRlbnRpYWxTdG9yYWdlRXJyb3JOb0NyZWRlbnRpYWxzQXZhaWxhYmxlAAAAAAQAAAAEAAAAowIAAFN0b3JhZ2VFcnJvckVjYXNoRXJyb3IAAAAAAAAEAAAABAAAAEIAAABWYWxpZGF0b3JFcnJvcgAAAAAAAAQAAAAEAAAApQIAAENyZWRlbnRpYWxFcnJvcgAAAAAABAAAAAQAAABAAAAARWQyNTUxOVBhcnNlRXJyb3IAAAAAAAAABAAAAAQAAAAAAgAAWDI1NTE5UGFyc2VFcnJvckludmFsaWRUeEhhc2hOb1RocmVzaG9sZAAAAAABAAAAAQAAAFUDAABVbnN1cHBvcnRlZENyZWRlbnRpYWxTdG9yYWdlUmV2aXNpb25zdG9yZWRleHBlY3RlZEV4aGF1c3RlZEFwaVF1ZXJpZXN0eXAEAAAAAAAAAAQAAAAEAEHI/MYAC+EEDAAAAGJ1ZmZlciBzcGFjZSBleGhhdXN0ZWQ7IHNlbmRpbmcgdGhpcyBtZXNzYWdlcyB3b3VsZCBvdmVyZmxvdyB0aGUgc3RhdGUAAP1hEABoAAAAuAEAAA0AAABueW1fZ2F0ZXdheV9jbGllbnRtZXNzYWdlAAAAtr4RAAcAAAAAAAAADAAAAAQAAACVAgAAVgMAAFcDAABjb21tb24vY2xpZW50LWxpYnMvZ2F0ZXdheS1jbGllbnQvc3JjL2xpYi5yc2V2ZW50IGNvbW1vbi9jbGllbnQtbGlicy9nYXRld2F5LWNsaWVudC9zcmMvbGliLnJzOjYxAAAAAQAAAD0AAAADAAAADL8RADUAAACkvhEAEgAAAMC+EQABAAAAtKAZAMi+EQCkvhEAEgAAAOC+EQAsAAAAAQAAAEZpZWxkU2V0IGNvcnJ1cHRlZCAodGhpcyBpcyBhIGJ1ZykAAFpsEAAsAAAAPQAAAA0AAABtZXNzYWdlIHJlY2VpdmVkIGZyb20gdGhlIGdhdGV3YXkgd2FzIG1hbGZvcm1lZCEgLSAAuL8RADMAAAAAAAAAGAAAAAQAAAASAAAAVwCPvCIs99wbgSsAqDxQ5nNlbmQgZmFpbGVkIGJlY2F1c2UgcmVjZWl2ZXIgaXMgZ29uZXNlbmQgZmFpbGVkIGJlY2F1c2UgY2hhbm5lbCBpcyBmdWxsAP1hEABoAAAA8wQAAEYAAABhc3NlcnRpb24gZmFpbGVkOiBzbG90LmlzX25vbmUoKVsLEABnAAAAggAAAA0AAAAEAAAAAAAAAAQAAAAEAEG0gccAC8kHDAAAACs/EAAyAAAAegAAAA4AAABldmVudCBjb21tb24vY2xpZW50LWxpYnMvZ2F0ZXdheS1jbGllbnQvc3JjL2JhbmR3aWR0aC5yczo4OW55bV9nYXRld2F5X2NsaWVudDo6YmFuZHdpZHRobWVzc2FnZQAgwREABwAAAAAAAAAMAAAABAAAAJUCAABZAwAAWgMAAGNvbW1vbi9jbGllbnQtbGlicy9nYXRld2F5LWNsaWVudC9zcmMvYmFuZHdpZHRoLnJzAAABAAAAWQAAAAMAAADIwBEAOwAAAAPBEQAdAAAAKMERAAEAAADMoBkAMMERAAPBEQAdAAAASMERADIAAAABAAAAZXZlbnQgY29tbW9uL2NsaWVudC1saWJzL2dhdGV3YXktY2xpZW50L3NyYy9iYW5kd2lkdGgucnM6OTMAAQAAAF0AAAABAAAAvMERADsAAAADwREAHQAAACjBEQABAAAAwKAZADDBEQADwREAHQAAAEjBEQAyAAAAAQAAAGV2ZW50IGNvbW1vbi9jbGllbnQtbGlicy9nYXRld2F5LWNsaWVudC9zcmMvYmFuZHdpZHRoLnJzOjkxAAEAAABbAAAAAgAAADjCEQA7AAAAA8ERAB0AAAAowREAAQAAANigGQAwwREAA8ERAB0AAABIwREAMgAAAAEAAABGaWVsZFNldCBjb3JydXB0ZWQgKHRoaXMgaXMgYSBidWcpAAArPxAAMgAAAF0AAAANAAAAcmVtYWluaW5nIGJhbmR3aWR0aDogAAAA6MIRABUAAAAAAAAAGAAAAAQAAAASAAAAKz8QADIAAABbAAAADQAAACs/EAAyAAAAWQAAAA0AAABPVVQgT0YgQkFORFdJRFRILiByZW1haW5pbmc6IAAAADjDEQAdAAAAVwCPvCIs99wbgSsAqDxQ5gAAAAAoAAAACAAAAFsDAABjYWxsZWQgYFJlc3VsdDo6dW53cmFwKClgIG9uIGFuIGBFcnJgIHZhbHVlAAAAAAAIAAAABAAAAIgBAAAAAAAACAAAAAgAAABcAwAAAAAAAAQAAAAEAAAAXQMAAENvbXBvbmVudFJhbmdlbmFtZW1pbmltdW1tYXhpbXVtdmFsdWVjb25kaXRpb25hbF9tZXNzYWdlY3JpdGljYWwgZmFpbHVyZTogdGhlcmUgd2VyZSBtdWx0aXBsZSBCYW5kd2lkdGhDbGFpbUd1YXJkIGV4aXN0aW5nAAAUxBEAQgAAACs/EAAyAAAAEQAAAAkAAAAEAAAAAAAAAAQAAAAEAEGIiccAC/IuDAAAAGV2ZW50IGNvbW1vbi9jbGllbnQtbGlicy9nYXRld2F5LWNsaWVudC9zcmMvY2xpZW50L21vZC5yczo2NzdueW1fZ2F0ZXdheV9jbGllbnQ6OmNsaWVudG1lc3NhZ2UAAOPEEQAHAAAAAAAAAAwAAAAEAAAAlQIAAF4DAABfAwAAY29tbW9uL2NsaWVudC1saWJzL2dhdGV3YXktY2xpZW50L3NyYy9jbGllbnQvbW9kLnJzAAEAAAClAgAAAQAAAIzEEQA9AAAAycQRABoAAADsxBEAAQAAAOSgGQD0xBEAycQRABoAAAAMxREAMwAAAAEAAABldmVudCBjb21tb24vY2xpZW50LWxpYnMvZ2F0ZXdheS1jbGllbnQvc3JjL2NsaWVudC9tb2QucnM6NjQyAAAAAQAAAIICAAABAAAAgMURAD0AAADJxBEAGgAAAOzEEQABAAAA8KAZAPTEEQDJxBEAGgAAAAzFEQAzAAAAAQAAAGV2ZW50IGNvbW1vbi9jbGllbnQtbGlicy9nYXRld2F5LWNsaWVudC9zcmMvY2xpZW50L21vZC5yczo2NjMAAAABAAAAlwIAAAEAAAAAxhEAPQAAAMnEEQAaAAAA7MQRAAEAAAD8oBkA9MQRAMnEEQAaAAAADMURADMAAAABAAAAZXZlbnQgY29tbW9uL2NsaWVudC1saWJzL2dhdGV3YXktY2xpZW50L3NyYy9jbGllbnQvbW9kLnJzOjg5NwAAAAEAAACBAwAABAAAAIDGEQA9AAAAycQRABoAAADsxBEAAQAAACChGQD0xBEAycQRABoAAAAMxREAMwAAAAEAAABldmVudCBjb21tb24vY2xpZW50LWxpYnMvZ2F0ZXdheS1jbGllbnQvc3Jj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gkEQAEsAAAAFCwAADgAAAFcAj7wiLPfcG4ErAKg8UOZFcnJvcgAAAIJBEABLAAAAsAwAAA4AAACCQRAASwAAAKoMAAAOAAAAVGxzRmVhdHVyZU5vdEVuYWJsZWROb0hvc3ROYW1lAAAAAAAABAAAAAQAAAA8AAAAVW5hYmxlVG9Db25uZWN0VW5zdXBwb3J0ZWRVcmxTY2hlbWVFbXB0eUhvc3ROYW1lTm9QYXRoT3JRdWVyeVRvb01hbnlIZWFkZXJzAAAAAAAEAAAABAAAAGQDAAAAAAAABAAAAAQAAACfAgAATWVzc2FnZVRvb0xvbmdzaXplbWF4X3NpemVXcm9uZ0h0dHBNZXRob2RXcm9uZ0h0dHBWZXJzaW9uTWlzc2luZ0Nvbm5lY3Rpb25VcGdyYWRlSGVhZGVyTWlzc2luZ1VwZ3JhZGVXZWJTb2NrZXRIZWFkZXJNaXNzaW5nU2VjV2ViU29ja2V0VmVyc2lvbkhlYWRlck1pc3NpbmdTZWNXZWJTb2NrZXRLZXlTZWNXZWJTb2NrZXRBY2NlcHRLZXlNaXNtYXRjaEp1bmtBZnRlclJlcXVlc3RDdXN0b21SZXNwb25zZVN1Y2Nlc3NmdWxIYW5kc2hha2VJbmNvbXBsZXRlU2VuZEFmdGVyQ2xvc2luZ1JlY2VpdmVkQWZ0ZXJDbG9zaW5nTm9uWmVyb1Jlc2VydmVkQml0c1VubWFza2VkRnJhbWVGcm9tQ2xpZW50TWFza2VkRnJhbWVGcm9tU2VydmVyRnJhZ21lbnRlZENvbnRyb2xGcmFtZUNvbnRyb2xGcmFtZVRvb0JpZwAAAAAAAAAEAAAABAAAANQAAABVbmtub3duQ29udHJvbEZyYW1lVHlwZVVua25vd25EYXRhRnJhbWVUeXBlVW5leHBlY3RlZENvbnRpbnVlRnJhbWUAAAAAAAAEAAAABAAAACsDAABFeHBlY3RlZEZyYWdtZW50UmVzZXRXaXRob3V0Q2xvc2luZ0hhbmRzaGFrZUludmFsaWRPcGNvZGVJbnZhbGlkQ2xvc2VTZXF1ZW5jZVRleHQAAAAAAAAABAAAAAQAAACdAgAAQmluYXJ5UGluZ1BvbmcAAAAAAAAEAAAABAAAAGUDAABDbG9zZQAAAAAAAAAEAAAABAAAAGYDAABGcmFtZQAAAHpTEABeAAAAWAcAABEAAABXGhAAdwAAADYAAAAbAAAAaW52YWxpZCB1bmxvY2tlZCBzdGF0ZQAAtTsQAGgAAAC0AAAAEgAAAGludmFsaWQgc3RhdGU6IAAI4BEADwAAALU7EABoAAAAhAAAABsAAAC1OxAAaAAAAAIBAABKAAAAChIQAFkAAAD7AAAAAQAAAENvbm5lY3Rpb25DbG9zZWRBbHJlYWR5Q2xvc2VkAAAAAAAAAAQAAAAEAAAAYgAAAElvAAAAAAAABAAAAAQAAABnAwAAQ2FwYWNpdHkAAAAABAAAAAQAAABoAwAAUHJvdG9jb2wAAAAABAAAAAQAAABpAwAAV3JpdGVCdWZmZXJGdWxsVXRmOEF0dGFja0F0dGVtcHQAAAAABAAAAAQAAABqAwAAVXJsTm9uZQAAAAAABAAAAAQAAABrAwAAU29tZUlPRXJyb3IAAAAAAAQAAAAEAAAA3gEAAFJlY292ZXJ5Q3JlZGVudGlhbERlc2VyaWFsaXphdGlvbkZhaWx1cmVzb3VyY2UAAGwDAAAEAAAABAAAAG0DAAAAAAAABAAAAAQAAADUAAAAU2VyaWFsaXphdGlvbkZhaWx1cmVyZXZpc2lvblVuc3VwcG9ydGVkU2VyaWFsaXphdGlvblJldmlzaW9uVW5rbm93blNlcmlhbGl6YXRpb25SZXZpc2lvbk5vVmFsaWRhdG9yc0F2YWlsYWJsZQAAAAAAAAAEAAAABAAAAKQCAABDb21wYWN0RWNhc2hFcnJvcgAAAAAAAAAEAAAABAAAAEIAAABWYWxpZGF0b3JDbGllbnRFcnJvcgAAAAAEAAAABAAAAOoBAABOeW1BUElFcnJvcgAAAAAABAAAAAQAAAA8AAAAQmFuZHdpZHRoT3ZlcmZsb3dNaXNzaW5nQmFuZHdpZHRoAAAAAAAAAAQAAAAEAAAAAAIAAFBhcnNlUHVibGljS2V5Tm90RW5vdWdoU2hhcmVzU2lnbmF0dXJlQWdncmVnYXRpb25FcnJvckJhbmR3aWR0aFZvdWNoZXJEZXNlcmlhbGl6YXRpb25FcnJvck5vdEFCYW5kd2RpdGhWb3VjaGVyU2VjcDI1NmsxU2lnbkZhaWx1cmVEYXRhYmFzZUluY29uc2lzdGVuY3lyZWFzb25JbmNvbnNpc3RlbnREYXRhTm9DcmVkZW50aWFsAAAA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cnVjdCB2YXJpYW50IFNlcnZlclJlc3BvbnNlOjpFbmNyeXB0ZWRSZXNwb25zZSB3aXRoIDIgZWxlbWVudHP07REAQAAAAHN0cnVjdCB2YXJpYW50IFNlcnZlclJlc3BvbnNlOjpFcnJvciB3aXRoIDEgZWxlbWVudAA87hEAMwAAAHN0cnVjdCB2YXJpYW50IFNlcnZlclJlc3BvbnNlOjpSZWdpc3RlciB3aXRoIDIgZWxlbWVudHMAeO4RADcAAABzdHJ1Y3QgdmFyaWFudCBTZXJ2ZXJSZXNwb25zZTo6QmFuZHdpZHRoIHdpdGggMSBlbGVtZW50ALjuEQA3AAAAZGF0YXN0cnVjdCB2YXJpYW50IFJlZ2lzdHJhdGlvbkhhbmRzaGFrZTo6SGFuZHNoYWtlUGF5bG9hZCB3aXRoIDIgZWxlbWVudHMAAPzuEQBGAAAAc3RydWN0IHZhcmlhbnQgUmVnaXN0cmF0aW9uSGFuZHNoYWtlOjpIYW5kc2hha2VFcnJvciB3aXRoIDEgZWxlbWVudABM7xEAQwAAAAAAAAAQAAAABAAAAIUDAAAAAAAAEAAAAAQAAACFAwAAGFMQAGEAAAAHAgAAEQAAABhTEABhAAAACwIAABUAAAAYUxAAYQAAAPsBAAARAAAAGFMQAGEAAAD9AQAAFQAAABhTEABhAAAAdQMAABsAAAAYUxAAYQAAAIMDAAAdAAAAfXtDbGllbnRDb250cm9sUmVxdWVzdHR5cGVhdXRoZW50aWNhdGVwcm90b2NvbF92ZXJzaW9uYWRkcmVzc2VuY19hZGRyZXNzaXZBdXRoZW50aWNhdGVWMmF1dGhlbnRpY2F0ZVYycmVnaXN0ZXJIYW5kc2hha2VJbml0UmVxdWVzdGRhdGFiYW5kd2lkdGhDcmVkZW50aWFsZW5jX2NyZWRlbnRpYWxiYW5kd2lkdGhDcmVkZW50aWFsVjJlY2FzaENyZWRlbnRpYWxjbGFpbUZyZWVUZXN0bmV0QmFuZHdpZHRoZW5jcnlwdGVkUmVxdWVzdGNpcGhlcnRleHRub25jZXN1cHBvcnRlZFByb3RvY29soRgQAEsAAAD4AQAADgAAAEF1dGhlbnRpY2F0ZUVuY3J5cHRlZFJlc3BvbnNlQmFuZHdpZHRoU3VwcG9ydGVkUHJvdG9jb2xFcnJvclR5cGVkRXJyb3J0eXBlYXV0aGVudGljYXRlcHJvdG9jb2xfdmVyc2lvbnN0YXR1c2JhbmR3aWR0aF9yZW1haW5pbmdyZWdpc3RlcmVuY3J5cHRlZFJlc3BvbnNlY2lwaGVydGV4dG5vbmNlYmFuZHdpZHRoYXZhaWxhYmxlX3RvdGFsc2VuZHJlbWFpbmluZ19iYW5kd2lkdGhzdXBwb3J0ZWRQcm90b2NvbHZlcnNpb25lcnJvcm1lc3NhZ2V0eXBlZEVycm9yaW50ZXJuYWxseSB0YWdnZWQgZW51bSBTZXJ2ZXJSZXNwb25zZXN0cnVjdCB2YXJpYW50IFNlcnZlclJlc3BvbnNlOjpTdXBwb3J0ZWRQcm90b2NvbHN0cnVjdCB2YXJpYW50IFNlcnZlclJlc3BvbnNlOjpFbmNyeXB0ZWRSZXNwb25zZXN0cnVjdCB2YXJpYW50IFNlcnZlclJlc3BvbnNlOjpBdXRoZW50aWNhdGVzdHJ1Y3QgdmFyaWFudCBTZXJ2ZXJSZXNwb25zZTo6U2VuZHN0cnVjdCB2YXJpYW50IFNlcnZlclJlc3BvbnNlOjpUeXBlZEVycm9yc3RydWN0IHZhcmlhbnQgU2VydmVyUmVzcG9uc2U6OkJhbmR3aWR0aHN0cnVjdCB2YXJpYW50IFNlcnZlclJlc3BvbnNlOjpSZWdpc3RlcnN0cnVjdCB2YXJpYW50IFNlcnZlclJlc3BvbnNlOjpFcnJvcmZpZWxkIGlkZW50aWZpZXJ2YXJpYW50IGlkZW50aWZpZXIAAACG8READAAAALvxEQAIAAAAw/ERABEAAADj8REACQAAAPvxEQAEAAAAEvIRABEAAAAq8hEABQAAADbyEQAKAAAAc3RydWN0IHZhcmlhbnQgU2Vuc2l0aXZlU2VydmVyUmVzcG9uc2U6OkZvcmdldE1lQWNrc3RydWN0IHZhcmlhbnQgU2Vuc2l0aXZlU2VydmVyUmVzcG9uc2U6OlJlbWVtYmVyTWVBY2tzdHJ1Y3QgdmFyaWFudCBTZW5zaXRpdmVTZXJ2ZXJSZXNwb25zZTo6S2V5VXBncmFkZUFjawBBvOnHAAsGAQAAAIYDAEHM6ccACwYBAAAAhwMAQdzpxwALBgEAAACIAwBB7OnHAAsGAQAAAIkDAEH86ccACwYBAAAAigMAQYzqxwALBgEAAACLAwBBnOrHAAsGAQAAAIwDAEGs6scAC9UGAQAAAI0DAAAtVBAASgAAAL0BAAAdAAAAdWxscnVlYWxzZQAAelMQAF4AAACYBQAAEQAAAHpTEABeAAAAowUAABEAAAAgAAAAuG4QAGEAAAA8AgAACQAAAH0AAAC4bhAAYQAAAHYCAAAVAAAAcmVxdWVzdFNpZ25hdHVyZXByb3RvY29sVmVyc2lvbmNsaWVudElkZW50aXR5YWRkcmVzc0NpcGhlcnRleHRub25jZXJlcXVlc3RVbml4VGltZXN0YW1wAKEYEABLAAAA+AEAAA4AAADZIhAAWAAAAOsHAAAJAAAAwisQAF8AAACpCAAAFgAAAH1udWxsW3ssOl0BAAFBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6MDEyMzQ1Njc4OSsv/////////////////////////////////////////////////////////z7///8/NDU2Nzg5Ojs8Pf////////8AAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGf///////xobHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIz/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////3R5cGVoYW5kc2hha2VQYXlsb2FkcHJvdG9jb2xfdmVyc2lvbmRhdGFoYW5kc2hha2VFcnJvcm1lc3NhZ2VpbnRlcm5hbGx5IHRhZ2dlZCBlbnVtIFJlZ2lzdHJhdGlvbkhhbmRzaGFrZXN0cnVjdCB2YXJpYW50IFJlZ2lzdHJhdGlvbkhhbmRzaGFrZTo6SGFuZHNoYWtlUGF5bG9hZHN0cnVjdCB2YXJpYW50IFJlZ2lzdHJhdGlvbkhhbmRzaGFrZTo6SGFuZHNoYWtlRXJyb3J2YXJpYW50IGlkZW50aWZpZXJmaWVsZCBpZGVudGlmaWVyAABx9xEAEAAAAJX3EQAOAAAAoRgQAEsAAAD4AQAADgBBjPHHAAsGAQAAAI4DAEGc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AQAAALQDAAAAAAAABAAAAAQAAADUAAAASW52YWxpZFZlcnNpb252ZXJleHBlY3RlZF92ZXJOb0NoZWNrc3VtAC1UEABKAAAAvQEAAB0AAABUb29TaG9ydFJlcXVlc3RJbnZhbGlkTWFjTWFsZm9ybWVkTm9uY2VNaXNzaW5nQWVhZE5vbmNlAAAAAAAEAAAABAAAAAgCAABBZWFkRmFpbHVyZXRoZSByZXF1ZXN0IGlzIHRvbyBzaG9ydHByb3ZpZGVkIE1BQyBpcyBpbnZhbGlkdGhlIHByb3ZpZGVkIG5vbmNlIChvciBsZWdhY3kgSVYpIGRpZCBub3QgaGF2ZSB0aGUgZXhwZWN0ZWQgbGVuZ3RoZGlkIG5vdCBwcm92aWRlIGEgdmFsaWQgbm9uY2UgZm9yIGFlYWQgZW5jcnlwdGlvbmZhaWxlZCB0byBlaXRoZXIgZW5jcnlwdCBvciBkZWNyeXB0IHByb3ZpZGVkIG1lc3NhZ2V0aGUgc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBzaGFyZWQga2V5IHdhcyBtYWxmb3JtZWQ6IKkEEgA7AAAAdGhlIHJlY2VpdmVkIHNoYXJlZCBrZXlzIGhhZCBpbnZhbGlkIHNpemUuIEdvdDogLCBidXQgZXhwZWN0ZWQ6IOwEEgAwAAAAHAUSABAAAABpbnN1ZmZpY2llbnQgYmFuZHdpZHRoIGF2YWlsYWJsZSB0byBwcm9jZXNzIHRoZSByZXF1ZXN0LiByZXF1aXJlZDogQiwgYXZhaWxhYmxlOiBCAAA8BRIAQwAAAH8FEgAOAAAAjQUSAAEAAAB0aGUgcHJvdmlkZWQgdGlja2V0IGhhcyBhbHJlYWR5IGJlZW4gc3BlbnQgYmVmb3JlIGF0IHRoaXMgZ2F0ZXdheVNpbXBsZUdhdGV3YXlSZXF1ZXN0c0Vycm9yb3V0X29mX2JhbmR3aWR0aHJlcXVpcmVkYXZhaWxhYmxldGlja2V0X3JlcGxheQAAAAMGEgAQAAAAJAYSAA0AAAATBhIACAAAABsGEgAJAAAAdmFyaWFudCBpZGVudGlmaWVydmFyaWFudCBpbmRleCAwIDw9IGkgPCAyAABmBhIAGAAAAAAAAAAIAAAABAAAAIQAAABmaWVsZCBpZGVudGlmaWVyZGVzY3JpcHRpb24oKSBpcyBkZXByZWNhdGVkOyB1c2UgRGlzcGxheW+hbBRKXgtnHafrjzOMmmIW7+pmrbK1vrsGVbqnXSz3fnblPZv6wR/oFfQlY8SPxj8N0LjbNPJk8s+cL3EEguR/tjKu73JwIs/gjPRLb8unhCTtfHkKB1PrCOvxbz+Sm33BtQm4l+4FpISdaAjZOzC8AwAAIAAAAAQAAAC9AwAAvAMAACAAAAAEAAAAvgMAAL0DAABABxIAvwMAAMADAADBAwAAwgMAAMMDAADEAwAAEAAAAAQAAADFAwAAxAMAABAAAAAEAAAAxgMAAMUDAAB8BxIAxwMAAMgDAADBAwAAyQMAAMMDAADKAwAAIAAAAAgAAADLAwAAygMAACAAAAAIAAAAzAMAAMsDAAC4BxIAzQMAAM4DAADPAwAA0AMAANEDAADSAwAABAAAAAQAAAAyAgAA0gMAAAQAAAAEAAAA9QAAADICAAD0BxIAMwIAANMDAADBAwAANQIAAMMDAAAAAAAADAAAAAQAAADUAwAAAAAAAAwAAAAEAAAA1QMAANQDAAAwCBIA1gMAANcDAADBAwAA2AMAAMMDAADZAwAAFAAAAAQAAADaAwAA2QMAABQAAAAEAAAA2wMAANoDAABsCBIA1gMAANwDAADBAwAA3QMAAMMDAADeAwAACAAAAAQAAADfAwAA3gMAAAgAAAAEAAAA4AMAAN8DAACoCBIA4QMAAOIDAADBAwAA4wMAAMMDAADkAwAADAAAAAQAAADlAwAAAAAAAAQAAAAEAAAA5gMAAEZyb21VdGY4RXJyb3JieXRlc2Vycm9yRXhwaXJhdGlvbkRhdGVTaWduYXR1cmVWZXJpZmljYXRpb25FeHBpcmF0aW9uRGF0ZVNpZ25hdHVyZVZhbGlkaXR5QWdncmVnYXRpb25FbXB0eVNldEFnZ3JlZ2F0aW9uRHVwbGljYXRlSW5kaWNlc0FnZ3JlZ2F0aW9uVmVyaWZpY2F0aW9uSWRlbnRpdHlTaWduYXR1cmVBZ2dyZWdhdGlvblNpemVNaXNtYXRjaElkZW50aXR5Q29tbWl0bWVudEhhc2hXaXRoZHJhd2FsUmVxdWVzdFZlcmlmaWNhdGlvbktleWdlblBhcmFtZXRlcnNLZXlUb29TaG9ydEludGVycG9sYXRpb25TZXRTaXplSXNzdWFuY2VWZXJpZmljYXRpb24AAAAACAAAAAgAAADnAwAAAAAAAAQAAAAEAAAABwMAAFNwZW5kRXhjZWVkc0FsbG93YW5jZXNwZW5kaW5ncmVtYWluaW5nU3BlbmRTaWduYXR1cmVzVmFsaWRpdHlTcGVuZFNpZ25hdHVyZXNWZXJpZmljYXRpb25TcGVuZER1cGxpY2F0ZVNlcmlhbE51bWJlclNwZW5kRGF0ZVRvb0xhdGVTcGVuZERhdGVUb29FYXJseVNwZW5kWktQcm9vZlZlcmlmaWNhdGlvbgAAAAAABAAAAAQAAABoAQAATWFsZm9ybWVkU3RyaW5nQ29pbkluZGljZXNTaWduYXR1cmVWZXJpZmljYXRpb24AAAAAAAQAAAAEAAAAPAAAAERlc2VyaWFsaXphdGlvbkZhaWx1cmVvYmplY3ToAwAADAAAAAQAAADpAwAAAAAAAAQAAAAEAAAA3gEAAEJpbmFyeURlc2VyaWFsaXNhdGlvbkZhaWx1cmV0eXBlX25hbWVzb3VyY2UAAAAAAAQAAAAEAAAA6gMAAAAAAAAEAAAABAAAAJ8CAABEZXNlcmlhbGl6YXRpb25NaW5MZW5ndGhtaW5hY3R1YWxEZXNlcmlhbGl6YXRpb25MZW5ndGhNaXNtYXRjaGV4cGVjdGVkRGVzZXJpYWxpemF0aW9uSW52YWxpZExlbmd0aHRhcmdldG1vZHVsdXNfdGFyZ2V0bW9kdWx1c1NjYWxhckRlc2VyaWFsaXphdGlvbkZhaWx1cmVHMVByb2plY3RpdmVEZXNlcmlhbGl6YXRpb25GYWlsdXJlRzJQcm9qZWN0aXZlRGVzZXJpYWxpemF0aW9uRmFpbHVyZVZlcmlmaWNhdGlvbktleVRvb1Nob3J0SW5zdWZmaWNpZW50TnVtYmVyT2ZJbmRleFNpZ25hdHVyZXNJbnN1ZmZpY2llbnROdW1iZXJPZkV4cGlyYXRpb25TaWduYXR1cmVzVW5sdWNraWVzdEVycm9yVG9vRmV3Qnl0ZXNQcm92aWRlZAAAAAAAAAAEAAAABAAAADADAABJbnZhbGlkUGFja2V0VHlwZQAAAAAAAAAEAAAABAAAADEDAABJbnZhbGlkUGFja2V0U2l6ZQAAAAAAAAAEAAAABAAAADIDAABJbnZhbGlkS2V5Um90YXRpb25JbnZhbGlkQWRkcmVzc01hbGZvcm1lZFNwaGlueFBhY2tldAAAAAAAAAAEAAAABAAAAOYBAABQYWNrZXROb0J5dGVzUHJvdmlkZWQAAAAAAAAAAQAAAAEAAADrAwAAcHJvdG9jb2xfdmVyc2lvbnJlY2VpdmVkAAAAAAQAAAAEAAAA1AAAAEludmFsaWRJcFZlcnNpb25Ub29TbWFsbEJ5dGVzUmVwcmVzZW50YXRpb24AAAAAAAQAAAAEAAAAoAIAAEtleVVzYWdlRmFpbHVyZU1hbGZvcm1lZENpcGhlcnRleHQAAAAAAAAEAAAABAAAAP4BAABJbnZhbGlkU2lnbmF0dXJlTm90UmVnaXN0ZXJlZAAAAAAAAAAQAAAABAAAAKkCAAAAAAAABAAAAAQAAACmAgAARXhjZXNzaXZlVGltZXN0YW1wU2tld3NlcnZlclJlcXVlc3RSZXVzZXRoZSByZWNlaXZlZCByZXF1ZXN0IGlzIG1hbGZvcm1lZDogABAPEgAjAAAAdGhlIHJlY2VpdmVkIHJlc3BvbnNlIGlzIG1hbGZvcm1lZDogPA8SACQAAAByZWNlaXZlZCByZXF1ZXN0IHdpdGggYW4gdW5rbm93biBraW5kOiAAaA8SACcAAAByZWNlaXZlZCByZXNwb25zZSB3aXRoIGFuIHVua25vd24ga2luZDogmA8SACgAAAB0aGUgZW5jcnlwdGlvbiBmbGFnIGhhZCBhbiB1bmV4cGVjdGVkIHZhbHVldGhlIHJlcXVlc3QgaXMgdG9vIHNob3J0cHJvdmlkZWQgTUFDIGlzIGludmFsaWRhZGRyZXNzIGZpZWxkIHdhcyBpbmNvcnJlY3RseSBlbmNvZGVkOiAAAAAiEBIAJwAAAHJlY2VpdmVkIHJlcXVlc3QgaGFkIGludmFsaWQgc2l6ZS4gKGFjdHVhbDogLCBidXQgZXhwZWN0ZWQgb25lIG9mOiAgKEFDSyksICAoUkVHVUxBUiksICwgIChFWFRFTkRFRCkpAAAAVBASACwAAACAEBIAFwAAAJcQEgAIAAAAnxASAAwAAACrEBIAAgAAAKsQEgACAAAArRASAAwAAAByZWNlaXZlZCBzcGhpbnggcGFja2V0IHdhcyBtYWxmb3JtZWRmYWlsZWQgdG8gc2VyaWFsaXNlIGNyZWF0ZWQgc3BoaW54IHBhY2tl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YAAAAAgAAACbAQAAGwQAAGAAAAAIAAAAHAQAAJsBAADoGxIAnQEAAB0EAAACBAAAoAEAAAQEAABOb25lAAAAAAQAAAAEAAAA/QIAAFNvbWUAAAAABAAAAAQAAAAeBAAASU9FcnJvcgAAAAAABAAAAAQAAADeAQAAUmVjb3ZlcnlDcmVkZW50aWFsRGVzZXJpYWxpemF0aW9uRmFpbHVyZXNvdXJjZQAAHwQAAAQAAAAEAAAAbQMAAAAAAAAEAAAABAAAANQAAABTZXJpYWxpemF0aW9uRmFpbHVyZXJldmlzaW9uVW5zdXBwb3J0ZWRTZXJpYWxpemF0aW9uUmV2aXNpb25Vbmtub3duU2VyaWFsaXphdGlvblJldmlzaW9uTm9WYWxpZGF0b3JzQXZhaWxhYmxlAAAAAAAAAAQAAAAEAAAApAIAAENvbXBhY3RFY2FzaEVycm9yAAAAAAAAAAQAAAAEAAAAQgAAAFZhbGlkYXRvckNsaWVudEVycm9yAAAAAAQAAAAEAAAA6gEAAE55bUFQSUVycm9yAAAAAAAEAAAABAAAADwAAABCYW5kd2lkdGhPdmVyZmxvd01pc3NpbmdCYW5kd2lkdGgAAAAAAAAABAAAAAQAAAAAAgAAUGFyc2VQdWJsaWNLZXlOb3RFbm91Z2hTaGFyZXNTaWduYXR1cmVBZ2dyZWdhdGlvbkVycm9yQmFuZHdpZHRoVm91Y2hlckRlc2VyaWFsaXphdGlvbkVycm9yTm90QUJhbmR3ZGl0aFZvdWNoZXJTZWNwMjU2azFTaWduRmFpbHVyZUV4cGlyYXRpb25EYXRlU2lnbmF0dXJlVmVyaWZpY2F0aW9uRXhwaXJhdGlvbkRhdGVTaWduYXR1cmVWYWxpZGl0eUFnZ3JlZ2F0aW9uRW1wdHlTZXRBZ2dyZWdhdGlvbkR1cGxpY2F0ZUluZGljZXNBZ2dyZWdhdGlvblZlcmlmaWNhdGlvbklkZW50aXR5U2lnbmF0dXJlQWdncmVnYXRpb25TaXplTWlzbWF0Y2hJZGVudGl0eUNvbW1pdG1lbnRIYXNoV2l0aGRyYXdhbFJlcXVlc3RWZXJpZmljYXRpb25LZXlnZW5QYXJhbWV0ZXJzS2V5VG9vU2hvcnRJbnRlcnBvbGF0aW9uU2V0U2l6ZUlzc3VhbmNlVmVyaWZpY2F0aW9uAAAAAAAIAAAACAAAACAEAAAAAAAABAAAAAQAAAAHAwAAU3BlbmRFeGNlZWRzQWxsb3dhbmNlc3BlbmRpbmdyZW1haW5pbmdTcGVuZFNpZ25hdHVyZXNWYWxpZGl0eVNwZW5kU2lnbmF0dXJlc1ZlcmlmaWNhdGlvblNwZW5kRHVwbGljYXRlU2VyaWFsTnVtYmVyU3BlbmREYXRlVG9vTGF0ZVNwZW5kRGF0ZVRvb0Vhcmx5U3BlbmRaS1Byb29mVmVyaWZpY2F0aW9uAAAAAAAEAAAABAAAAGgBAABNYWxmb3JtZWRTdHJpbmdDb2luSW5kaWNlc1NpZ25hdHVyZVZlcmlmaWNhdGlvbkRlc2VyaWFsaXphdGlvbkZhaWx1cmVvYmplY3QAIQQAAAwAAAAEAAAAIgQAAEJpbmFyeURlc2VyaWFsaXNhdGlvbkZhaWx1cmV0eXBlX25hbWUAAAAAAAAABAAAAAQAAAAjBAAAAAAAAAQAAAAEAAAAnwIAAERlc2VyaWFsaXphdGlvbk1pbkxlbmd0aG1pbmFjdHVhbERlc2VyaWFsaXphdGlvbkxlbmd0aE1pc21hdGNoZXhwZWN0ZWREZXNlcmlhbGl6YXRpb25JbnZhbGlkTGVuZ3RodGFyZ2V0bW9kdWx1c190YXJnZXRtb2R1bHVzU2NhbGFyRGVzZXJpYWxpemF0aW9uRmFpbHVyZUcxUHJvamVjdGl2ZURlc2VyaWFsaXphdGlvbkZhaWx1cmVHMlByb2plY3RpdmVEZXNlcmlhbGl6YXRpb25GYWlsdXJlVmVyaWZpY2F0aW9uS2V5VG9vU2hvcnRJbnN1ZmZpY2llbnROdW1iZXJPZkluZGV4U2lnbmF0dXJlc0luc3VmZmljaWVudE51bWJlck9mRXhwaXJhdGlvblNpZ25hdHVyZXNVbmx1Y2tpZXN0RXJyb3JVbnZlcmlmaWVkU2hhcmUAAAAAAAAABAAAAAQAAADwAQAAQ29udHJhY3RRdWVyeUZhaWx1cmUAAAAABAAAAAQAAABHAAAATWFsZm9ybWVkQW5ub3VuY2VBZGRyZXNzTWFsZm9ybWVkVmVyaWZpY2F0aW9uS2V5Q2xpZW50RXJyb3IAAAAAAAQAAAAEAAAA/AEAAE1hbGZvcm1lZEFjY291bnRBZGRyZXNzTnltQXBpTm9Db250cmFjdEFkZHJlc3NBdmFpbGFibGUAAAAAAAQAAAAEAAAAAQMAAFdhbGxldEVycm9yAAAAAAAEAAAABAAAAAIDAABDb3NtcnNFcnJvckNvc21yc0Vycm9yUmVwb3J0Q29tc3dhc21FdmVudE5vdEZvdW5kQ29tc3dhc21BdHRyaWJ1dGVOb3RGb3VuZEFjY291bnREZXJpdmF0aW9uRXJyb3IAAAAABAAAAAQAAAADAwAAU2lnbmluZ0FjY291bnROb3RGb3VuZFNpZ25pbmdGYWlsdXJlSW52YWxpZFR4SGFzaAAAAAAAAAAEAAAABAAAAPsBAABUZW5kZXJtaW50RXJyb3JScGMAAAAAAAAEAAAABAAAAAQDAABUZW5kZXJtaW50RXJyb3JTZXJpYWxpemF0aW9uRXJyb3JEZXNlcmlhbGl6YXRpb25FcnJvcgAAAAAAAAAEAAAABAAAAAUDAABQcm90b2J1ZkVuY29kaW5nRXJyb3IAAAAAAAAABAAAAAQAAAAGAwAAUHJvdG9idWZEZWNvZGluZ0Vycm9yTm9uRXhpc3RlbnRBY2NvdW50RXJyb3IAAAAABAAAAAQAAADbAQAAU2VyZGVKc29uRXJyb3JJbnZhbGlkUHVibGljS2V5Tm9Db2RlSW5mb3JtYXRpb25Ob0NvbnRyYWN0SW5mb3JtYXRpb25JbnZhbGlkQ29udHJhY3RIaXN0b3J5T3BlcmF0aW9uSW52YWxpZEhlaWdodFdhc21Db21wcmVzc2lvbkVycm9yTWFsZm9ybWVkTG9nU3RyaW5nAAAAAAAAIQAAAAEAAAAIAwAAAAAAABAAAAAIAAAAJAQAAAAAAAAEAAAABAAAACUEAABCcm9hZGNhc3RUeEVycm9yQ2hlY2tUeGhhc2hoZWlnaHRjb2RlcmF3X2xvZ0Jyb2FkY2FzdFR4RXJyb3JEZWxpdmVyVHhNYWxmb3JtZWRHYXNQcmljZUdhc0VzdGltYXRpb25GYWlsdXJlAAAAAAAABAAAAAQAAAAMAwAAQWJjaUVycm9ybG9ncHJldHR5X2xvZ1Vuc3VwcG9ydGVkQWNjb3VudFR5cGV0eXBlX3VybE1hbGZvcm1lZENvaW5jb2luX3JlcHJlc2VudGF0aW9uTm9CYXNlQWNjb3VudEluZm9ybWF0aW9uQXZhaWxhYmxlAAAAAAAAAAQAAAAEAAAADQMAAEJyb2FkY2FzdFRpbWVvdXR0aW1lb3V0AAAAAAAEAAAABAAAAA4DAABDb3Ntd2FzbVN0ZEVycm9yVW5leHBlY3RlZEJlY2gzMlByZWZpeGdvdFVuZXhwZWN0ZWROdW1iZXJPZk1zZ1Jlc3BvbnNlc01hbGZvcm1lZFJlc3BvbnNlRGF0YUV4dGVuc2lvblF1ZXJ5RmFpbHVyZWNvbnRyYWN0bWVzc2FnZUludmFsaWRTaXplUHVibGljS2V5cmVjZWl2ZWRJbnZhbGlkU2l6ZVByaXZhdGVLZXlNYWxmb3JtZWRQdWJsaWNLZXlTdHJpbmdNYWxmb3JtZWRQcml2YXRlS2V5U3RyaW5nTWFsZm9ybWVkVXJsUHJvdmlkZWROeXhkRXJyb3JJbmNvbnNpc3RlbnRQYWdlZE1ldGFkYXRhTm9BUElVcmxBdmFpbGFibGUAAAAAAAAABAAAAAQAAAD+AQAATWFsZm9ybWVkQnl0ZXMAAAAAAAAEAAAABAAAAOUBAABCeXRlc0xlbmd0aEVycm9yTWFsZm9ybWVkU2lnbmF0dXJlU3RyaW5nTnl4ZCBlcnJvcjogNCgSAAwAAABjb2NvbnV0IGFwaSBxdWVyeSBmYWlsdXJlOiAASCgSABsAAABUaGVyZSB3YXMgYSBjcmVkZW50aWFsIHN0b3JhZ2UgZXJyb3IgLSAAbCgSACcAAAB0aGUgY3JlZGVudGlhbCBzdG9yYWdlIGRvZXMgbm90IGNvbnRhaW4gYW55IHVzYWJsZSBjcmVkZW50aWFsc0VjYXNoIGVycm9yIC0g2igSAA4AAABWYWxpZGF0b3IgY2xpZW50IGVycm9yIC0gAAAA8CgSABkAAABDcmVkZW50aWFsIGVycm9yIC0gABQpEgATAAAAQ291bGQgbm90IHBhcnNlIEVkMjU1MTkgZGF0YUNvdWxkIG5vdCBwYXJzZSBYMjU1MTkgZGF0YVRoZSB0eCBoYXNoIHByb3ZpZGVkIGlzIG5vdCB2YWxpZFRocmVzaG9sZCBub3Qgc2V0IHlldGNhbid0IGhhbmRsZSByZWNvdmVyaW5nIHN0b3JhZ2Ugd2l0aCByZXZpc2lvbiAuICB3YXMgZXhwZWN0ZWQAAJ0pEgAuAAAAyykSAAIAAADNKRIADQAAAGRpZCBub3QgcmVjZWl2ZSBhIHZhbGlkIHJlc3BvbnNlIGZvciBhZ2dyZWdhdGVkIGRhdGEgKCkgZnJvbSBBTlkgbnltLWFwafQpEgA2AAAAKioSABIAAAAEAAAAAAAAAAQAAAAEAEHk1MgAC+oDDAAAACYEAABYAAAACAAAACcEAACCUBAAMgAAALgAAABPAAAAJgQAAFgAAAAIAAAAKAQAAIJQEAAyAAAApAAAAEIAAAApBAAATAAAAAQAAAAqBAAAglAQADIAAADCAAAAKQAAACsEAABoAAAACAAAACwEAACCUBAAMgAAAM0AAABUAAAAKQQAAEwAAAAEAAAALQQAAIJQEAAyAAAArgAAACkAAAApBAAATAAAAAQAAAAuBAAAglAQADIAAADXAAAAKQAAAC8EAABwAAAABAAAADAEAACCUBAAMgAAAI4AAABCAAAAMQQAAHAAAAAIAAAAMgQAAIJQEAAyAAAAmgAAACsAAADbARAAMAAAAO8AAAAzAAAA2wEQADAAAADgAAAAJgAAANsBEAAwAAAA+AAAAAcAAADbARAAMAAAAP0AAAA0AAAA2wEQADAAAABvAAAADwAAANsBEAAwAAAAeAAAACcAAADbARAAMAAAAAQBAAA4AAAA2wEQADAAAADmAAAAWwAAANsBEAAwAAAAEAEAAAcAAADbARAAMAAAABUBAAAdAAAA2wEQADAAAABPAAAAJgAAANsBEAAwAAAAVgAAABAAAADbARAAMAAAAF8AAAAnAAAAMwQAAAwAAAAEAAAANAQAADUEAAB2AgBB2NjIAAupCAEAAAA2BAAAYSBEaXNwbGF5IGltcGxlbWVudGF0aW9uIHJldHVybmVkIGFuIGVycm9yIHVuZXhwZWN0ZWRseQCCQRAASwAAAAULAAAOAAAARXJyb3IAAACCQRAASwAAALAMAAAOAAAAgkEQAEsAAACqDAAADgAAAFM7EABhAAAArwEAADgAAABTOxAAYQAAALABAAAbAAAAaW50ZXJuYWwgZXJyb3I6IGVudGVyZWQgdW5yZWFjaGFibGUgY29kZVM7EABhAAAAtAEAABEAAABTOxAAYQAAAAQDAAA6AAAAUzsQAGEAAAAFAwAAGwAAAFM7EABhAAAACQMAABEAAABbNRAATwAAAH8AAAAcAAAA2wEQADAAAAAwAAAALwAAAHkzEABKAAAAHQgAAB8AAAA3BAAABAAAAAQAAABtAwAAOAQAAGAAAAAIAAAAOQQAAGNhbGxlZCBgUmVzdWx0Ojp1bndyYXAoKWAgb24gYW4gYEVycmAgdmFsdWUAAAAAAAQAAAAEAAAAHgQAAElPRXJyb3IAAAAAAAQAAAAEAAAA3gEAAFJlY292ZXJ5Q3JlZGVudGlhbERlc2VyaWFsaXphdGlvbkZhaWx1cmVzb3VyY2UAAAAAAAAEAAAABAAAANQAAABTZXJpYWxpemF0aW9uRmFpbHVyZXJldmlzaW9uVW5zdXBwb3J0ZWRTZXJpYWxpemF0aW9uUmV2aXNpb25Vbmtub3duU2VyaWFsaXphdGlvblJldmlzaW9uTm9WYWxpZGF0b3JzQXZhaWxhYmxlAAAAAAAAAAQAAAAEAAAApAIAAENvbXBhY3RFY2FzaEVycm9yAAAAAAAAAAQAAAAEAAAAQgAAAFZhbGlkYXRvckNsaWVudEVycm9yAAAAAAQAAAAEAAAA6gEAAE55bUFQSUVycm9yAAAAAAAEAAAABAAAADwAAABCYW5kd2lkdGhPdmVyZmxvd01pc3NpbmdCYW5kd2lkdGgAAAAAAAAABAAAAAQAAAAAAgAAUGFyc2VQdWJsaWNLZXlOb3RFbm91Z2hTaGFyZXNTaWduYXR1cmVBZ2dyZWdhdGlvbkVycm9yQmFuZHdpZHRoVm91Y2hlckRlc2VyaWFsaXphdGlvbkVycm9yTm90QUJhbmR3ZGl0aFZvdWNoZXJTZWNwMjU2azFTaWduRmFpbHVyZQAAAAAAAAQAAAAEAAAA+wEAAFRlbmRlcm1pbnRFcnJvclJwYwAAAAAAAAQAAAAEAAAARwAAAE1hbGZvcm1lZFVybFByb3ZpZGVkAAAAAAQAAAAEAAAA8AEAAE55eGRFcnJvckluY29uc2lzdGVudFBhZ2VkTWV0YWRhdGFOb0FQSVVybEF2YWlsYWJsZQBbNRAATwAAAH8AAAAcAAAABAAAAAAAAAAEAAAABABBjOHIAAulDQwAAAAAAAAABAAAAAQAAAA6BAAAOwQAADsEAAAAAAAABAAAAAQAAAA8BAAAPQQAAD0EAAAAAAAABAAAAAQAAAA+BAAAPwQAAD8EAABhbiBhcnJheSBvZiBsZW5ndGggMzJFeHBpcmF0aW9uRGF0ZVNpZ25hdHVyZVZlcmlmaWNhdGlvbkV4cGlyYXRpb25EYXRlU2lnbmF0dXJlVmFsaWRpdHlBZ2dyZWdhdGlvbkVtcHR5U2V0QWdncmVnYXRpb25EdXBsaWNhdGVJbmRpY2VzQWdncmVnYXRpb25WZXJpZmljYXRpb25JZGVudGl0eVNpZ25hdHVyZUFnZ3JlZ2F0aW9uU2l6ZU1pc21hdGNoSWRlbnRpdHlDb21taXRtZW50SGFzaFdpdGhkcmF3YWxSZXF1ZXN0VmVyaWZpY2F0aW9uS2V5Z2VuUGFyYW1ldGVyc0tleVRvb1Nob3J0SW50ZXJwb2xhdGlvblNldFNpemVJc3N1YW5jZVZlcmlmaWNhdGlvbgAAAAAAAAgAAAAIAAAAQQQAAAAAAAAEAAAABAAAAAcDAABTcGVuZEV4Y2VlZHNBbGxvd2FuY2VzcGVuZGluZ3JlbWFpbmluZ1NwZW5kU2lnbmF0dXJlc1ZhbGlkaXR5U3BlbmRTaWduYXR1cmVzVmVyaWZpY2F0aW9uU3BlbmREdXBsaWNhdGVTZXJpYWxOdW1iZXJTcGVuZERhdGVUb29MYXRlU3BlbmREYXRlVG9vRWFybHlTcGVuZFpLUHJvb2ZWZXJpZmljYXRpb24AAAAAAAQAAAAEAAAAaAEAAE1hbGZvcm1lZFN0cmluZ0NvaW5JbmRpY2VzU2lnbmF0dXJlVmVyaWZpY2F0aW9uAAAAAAAEAAAABAAAADwAAABEZXNlcmlhbGl6YXRpb25GYWlsdXJlb2JqZWN0QgQAAAwAAAAEAAAAQwQAAAAAAAAEAAAABAAAAN4BAABCaW5hcnlEZXNlcmlhbGlzYXRpb25GYWlsdXJldHlwZV9uYW1lc291cmNlAAAAAAAEAAAABAAAAEQEAAAAAAAABAAAAAQAAACfAgAARGVzZXJpYWxpemF0aW9uTWluTGVuZ3RobWluYWN0dWFsRGVzZXJpYWxpemF0aW9uTGVuZ3RoTWlzbWF0Y2hleHBlY3RlZERlc2VyaWFsaXphdGlvbkludmFsaWRMZW5ndGh0YXJnZXRtb2R1bHVzX3RhcmdldG1vZHVsdXNTY2FsYXJEZXNlcmlhbGl6YXRpb25GYWlsdXJlRzFQcm9qZWN0aXZlRGVzZXJpYWxpemF0aW9uRmFpbHVyZUcyUHJvamVjdGl2ZURlc2VyaWFsaXphdGlvbkZhaWx1cmVWZXJpZmljYXRpb25LZXlUb29TaG9ydEluc3VmZmljaWVudE51bWJlck9mSW5kZXhTaWduYXR1cmVzSW5zdWZmaWNpZW50TnVtYmVyT2ZFeHBpcmF0aW9uU2lnbmF0dXJlc1VubHVja2llc3RFcnJvcmV4cGVyaWVuY2VkIGludGVybmFsIHN0b3JhZ2UgZXJyb3IgZHVlIHRvIGRhdGFiYXNlIGluY29uc2lzdGVuY3k6IAY1EgBCAAAASW5jb25zaXN0ZW50IGRhdGEgaW4gZGF0YWJhc2VObyB1bnVzZWQgY3JlZGVudGlhbCBpbiBkYXRhYmFzZS4gWW91IG5lZWQgdG8gYnV5IGF0IGxlYXN0IG9uZU5vIHNpZ25hdHVyZXMgZm9yIGVwb2NoICBpbiB0aGUgZGF0YWJhc2UAqzUSABgAAADDNRIAEAAAAERhdGFiYXNlIHVuaXF1ZSBjb25zdHJhaW50IHZpb2xhdGlvbi4gSXMgdGhlIGNyZWRlbnRpYWwgYWxyZWFkeSBpbXBvcnRlZD9JbnZhbGlkU2l6ZVB1YmxpY0tleXJlY2VpdmVkSW52YWxpZFNpemVQcml2YXRlS2V5TWFsZm9ybWVkUHVibGljS2V5U3RyaW5nTWFsZm9ybWVkUHJpdmF0ZUtleVN0cmluZ3Byb3ZpZGVkIHZhbGlkYXRvciB1cmwgZG9lcyBub3QgaGF2ZSBhIGJhc2UhAIdsEAA7AAAAgwUAAAoAAABFBAAANAAAAAQAAABGBAAAh2wQADsAAAAgAgAABQAAAEZpZWxkU2V0IGNvcnJ1cHRlZCAodGhpcyBpcyBhIGJ1ZykAAAAAAAAEAAAABAAAAHAAAAAoKQAAwHAQAFYAAADiAAAACgBBvO7IAAulAQEAAABHBAAALS0gO0Q3EgADAAAARzcSAAEAAAB0cmFjaW5nOjpzcGFuAAAAeTMQAEoAAACUCAAAHwAAACBzcGFuPQAAAQAAAAAAAAB4NxIABgAAADwtIACQNxIAAwAAAEc3EgABAAAAdHJhY2luZzo6c3Bhbjo6YWN0aXZlLT4guTcSAAMAAABHNxIAAQAAAIdsEAA7AAAA2AMAAAUAAAAAAAAAHQBB7O/IAAsNLVQQAEoAAAC9AQAAHQBBhPDIAAuBAgEAAABIBAAAaHNzdHJ1Y3QgU2ln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bGl6ZSBhIHJlY292ZXJ5IGNyZWRlbnRpYWw6IAAAABw/EgAtAAAAZmFpbGVkIHRvIChkZSlzZXJpYWxpemUgcHJvdmlkZWQgY3JlZGVudGlhbCB1c2luZyByZXZpc2lvbiA6IAAAAFQ/EgA7AAAAjz8SAAIAAAABdW5zdXBwb3J0ZWQgZGF0YSBzZXJpYWxpemF0aW9uIHJldmlzaW9uIC4gdGhlIGN1cnJlbnQgKGFuZCBtYXggc3VwcG9ydGVkKSB2ZXJzaW9uIGlzIAAApT8SACgAAADNPxIALQAAAHVua25vd24gZGF0YSBzZXJpYWxpemF0aW9uIHJldmlzaW9uIAxAEgAkAAAAzT8SAC0AAABDb3VsZCBub3QgY29udGFjdCBhbnkgdmFsaWRhdG9yUmFuIGludG8gYSBDb21wYWN0IGVjYXNoIGVycm9yIC0gX0ASACEAAABSYW4gaW50byBhIHZhbGlkYXRvciBjbGllbnQgZXJyb3IgLSCIQBIAJAAAAE55bSBBUEkgcmVxdWVzdCBmYWlsZWQgLSAAAAC0QBIAGQAAAEJhbmR3aWR0aCBvcGVyYXRpb24gb3ZlcmZsb3dlZC4g2EASACAAAABUaGVyZSBpcyBub3QgYXNzb2NpYXRlZCBiYW5kd2lkdGggZm9yIHRoZSBnaXZlbiBjbGllbnRDb3VsZCBub3QgcGFyc2UgdGhlIGtleSAtIDZBEgAaAAAAQ291bGQgbm90IGdhdGhlciBlbm91Z2ggc2lnbmF0dXJlIHNoYXJlcy4gVHJ5IGFnYWluIHVzaW5nIHRoZSByZWNvdmVyeSBjb21tYW5kQ291bGQgbm90IGFnZ3JlZ2F0ZSBzaWduYXR1cmUgc2hhcmVzIC0gLiBUcnkgYWdhaW4gdXNpbmcgdGhlIHJlY292ZXJ5IGNvbW1hbmQApkESACcAAADNQRIAJgAAAENvdWxkIG5vdCBkZXNlcmlhbGl6ZSBiYW5kd2lkdGggdm91Y2hlciAtIAAABEISACoAAAB0aGUgcHJvdmlkZWQgaXNzdWFuY2UgZGF0YSB3YXNuJ3QgcHJlcGFyZWQgZm9yIGEgYmFuZHdpZHRoIHZvdWNoZXJmYWlsZWQgdG8gY3JlYXRlIGEgc2VjcDI1NmsxIHNpZ25hdHVyZUV4cGlyYXRpb25EYXRlU2lnbmF0dXJlVmVyaWZpY2F0aW9uRXhwaXJhdGlvbkRhdGVTaWduYXR1cmVWYWxpZGl0eUFnZ3JlZ2F0aW9uRW1wdHlTZXRBZ2dyZWdhdGlvbkR1cGxpY2F0ZUluZGljZXNBZ2dyZWdhdGlvblZlcmlmaWNhdGlvbklkZW50aXR5U2lnbmF0dXJlQWdncmVnYXRpb25TaXplTWlzbWF0Y2hJZGVudGl0eUNvbW1pdG1lbnRIYXNoV2l0aGRyYXdhbFJlcXVlc3RWZXJpZmljYXRpb25LZXlnZW5QYXJhbWV0ZXJzS2V5VG9vU2hvcnRJbnRlcnBvbGF0aW9uU2V0U2l6ZUlzc3VhbmNlVmVyaWZpY2F0aW9uAAAAAAAAAAgAAAAIAAAAcwQAAAAAAAAEAAAABAAAAAcDAABTcGVuZEV4Y2VlZHNBbGxvd2FuY2VzcGVuZGluZ3JlbWFpbmluZ1NwZW5kU2lnbmF0dXJlc1ZhbGlkaXR5U3BlbmRTaWduYXR1cmVzVmVyaWZpY2F0aW9uU3BlbmREdXBsaWNhdGVTZXJpYWxOdW1iZXJTcGVuZERhdGVUb29MYXRlU3BlbmREYXRlVG9vRWFybHlTcGVuZFpLUHJvb2ZWZXJpZmljYXRpb24AAAAAAAQAAAAEAAAAaAEAAE1hbGZvcm1lZFN0cmluZ0NvaW5JbmRpY2VzU2lnbmF0dXJlVmVyaWZpY2F0aW9uAAAAAAAEAAAABAAAADwAAABEZXNlcmlhbGl6YXRpb25GYWlsdXJlb2JqZWN0dAQAAAwAAAAEAAAAdQQAAAAAAAAEAAAABAAAAN4BAABCaW5hcnlEZXNlcmlhbGlzYXRpb25GYWlsdXJldHlwZV9uYW1lc291cmNlAAAAAAAEAAAABAAAAHYEAAAAAAAABAAAAAQAAACfAgAARGVzZXJpYWxpemF0aW9uTWluTGVuZ3RobWluYWN0dWFsRGVzZXJpYWxpemF0aW9uTGVuZ3RoTWlzbWF0Y2hleHBlY3RlZERlc2VyaWFsaXphdGlvbkludmFsaWRMZW5ndGh0YXJnZXRtb2R1bHVzX3RhcmdldG1vZHVsdXNTY2FsYXJEZXNlcmlhbGl6YXRpb25GYWlsdXJlRzFQcm9qZWN0aXZlRGVzZXJpYWxpemF0aW9uRmFpbHVyZUcyUHJvamVjdGl2ZURlc2VyaWFsaXphdGlvbkZhaWx1cmVWZXJpZmljYXRpb25LZXlUb29TaG9ydEluc3VmZmljaWVudE51bWJlck9mSW5kZXhTaWduYXR1cmVzSW5zdWZmaWNpZW50TnVtYmVyT2ZFeHBpcmF0aW9uU2lnbmF0dXJlc1VubHVja2llc3RFcnJvckludmFsaWRTaXplUHVibGljS2V5cmVjZWl2ZWRJbnZhbGlkU2l6ZVByaXZhdGVLZXlNYWxmb3JtZWRQdWJsaWNLZXlTdHJpbmdNYWxmb3JtZWRQcml2YXRlS2V5U3RyaW5nAAAAAAQAAAAEAAAA6gEAAE55bUFQSUVycm9yAAAAAAAEAAAABAAAAPsBAABUZW5kZXJtaW50RXJyb3JScGMAAAAAAAAEAAAABAAAAEcAAABNYWxmb3JtZWRVcmxQcm92aWRlZAAAAAAEAAAABAAAAPABAABOeXhkRXJyb3JJbmNvbnNpc3RlbnRQYWdlZE1ldGFkYXRhTm9BUElVcmxBdmFpbGFibGUABAAAAAAAAAAEAAAABABB3I/JAAtCDAAAAHNlcmlhbGlzYXRpb24gZmFpbHVyZQAAAFZZEAA4AAAAMAAAAA4AAAB3BAAADAAAAAQAAAB4BAAAeQQAAHYCAEGokMkAC5MDAQAAAHoEAABhIERpc3BsYXkgaW1wbGVtZW50YXRpb24gcmV0dXJuZWQgYW4gZXJyb3IgdW5leHBlY3RlZGx5AIJBEABLAAAABQsAAA4AAAB7BAAABAAAAAQAAABtAwAARXJyb3IAAACCQRAASwAAALAMAAAOAAAAgkEQAEsAAACqDAAADgAAAAAAAAAIAAAABAAAAIgBAAAAAAAACAAAAAgAAAB8BAAAAAAAAAQAAAAEAAAAXQMAAENvbXBvbmVudFJhbmdlbmFtZW1pbmltdW1tYXhpbXVtdmFsdWVjb25kaXRpb25hbF9tZXNzYWdlAAAAAAQAAAAEAAAAfQQAAAAAAAAEAAAABAAAAH4EAAAAAAAABAAAAAQAAAB/BAAAQ291bGQgbm90IGRlY29kZSBjb21wcmVzc2VkIGdyb3VwIGVsZW1lbnRbLDpddXJsOjpmb3JtX3VybGVuY29kZWQ6OlNlcmlhbGl6ZXIgZmluaXNoZWQAACx2EABiAAAAaQEAAAoAAAAtAAAAAQAFAQAAAQBBxJPJAAsNsEkSAAEAAAABAAEBAQBB3JPJAAuiA7BJEgABAAAAAQAAAQAAAAAAAAAAoRgQAEsAAAD4AQAADgAAAAAAAAAoAAAACAAAAHIBAABhIHNlcXVlbmNlAADtGBAAXwAAAJUEAAAiAAAA7RgQAF8AAACYBAAAHAAAAIAEAAAMAAAABAAAAIEEAACCBAAAgwQAAGEgZm9ybWF0dGluZyB0cmFpdCBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB3aGVuIHRoZSB1bmRlcmx5aW5nIHN0cmVhbSBkaWQgbm90AABUShIAVgAAAAdcEABJAAAAiAIAABEAAAChGBAASwAAAPgBAAAOAAAAZGVzY3JpcHRpb24oKSBpcyBkZXByZWNhdGVkOyB1c2UgRGlzcGxheQ/yOxS3FZuVnAAp2smtCRsAAAAAAAAAAAEAAACEBAAAc2l6ZSBvdmVyZmxvd3MgTUFYX1NJWkUAejEQAF4AAABgBQAADgAAAIUEAAAMAAAABAAAAFkAAACFBAAADAAAAAQAAABaAAAAWQAAAERLEgCGBAAAhwQAAIgEAABeAAAAiQQAQYiXyQALvQUBAAAASAQAAEludmFsaWQgdmFsdWUgKHUxMjggcmFuZ2UpOiB5b3UgbWF5IGhhdmUgYSB2ZXJzaW9uIG9yIGNvbmZpZ3VyYXRpb24gZGlzYWdyZWVtZW50PwpCeXRlIDI1NSBpcyB0cmVhdGVkIGFzIGFuIGV4dGVuc2lvbiBwb2ludDsgaXQgc2hvdWxkIG5vdCBiZSBlbmNvZGluZyBhbnl0aGluZy4KRG8geW91IGhhdmUgYSBtaXNtYXRjaGVkIGJpbmNvZGUgdmVyc2lvbiBvciBjb25maWd1cmF0aW9uPwotVBAASgAAAL0BAAAdAAAAc2lnbmF0dXJlZXhwaXJhdGlvbl90aW1lc3RhbXBzcGVuZGluZ190aW1lc3RhbXBTbGljZSBoYWQgYnl0ZXMgcmVtYWluaW5nIGFmdGVyIGRlc2VyaWFsaXphdGlvbgAA1DkQAF8AAAAgAAAACQAAAC1UEABKAAAAvQEAAB0AAABzaWduYXR1cmVpbmRleHZhcmlhbnQgaW5kZXggMCA8PSBpIDwgNAAACk0SABgAAAAAAAAACAAAAAQAAACEAAAATm9uZQAAAAAEAAAABAAAAIoEAABTb21lAAAAAAQAAAAEAAAABwMAAGV4cGVjdGVkIGRheSBvZiB5ZWFyZXhwZWN0ZWQgeWVhcnVsbHJ1ZWFsc2UAelMQAF4AAAB3BAAAIgAAAGludGVybmFsIGVycm9yOiBlbnRlcmVkIHVucmVhY2hhYmxlIGNvZGV6UxAAXgAAAKAEAAAiAAAAelMQAF4AAACWBAAAJgAAAHpTEABeAAAAMAIAABgAAAB6UxAAXgAAACQCAAAbAAAAelMQAF4AAAAlAgAADQAAAHpTEABeAAAAHwIAACAAAAB6UxAAXgAAAPEBAAArAAAAelMQAF4AAABjAgAAEwBB0JzJAAsGAQAAACEBAEHgnMkACwUBAAAAlQBB8JzJAAuhAQEAAAAgAQAAelMQAF4AAADVAgAAFQAAAAAAAAAIAAAABAAAAIQAAABjb2RlZGF0YW1lc3NhZ2VzdHJ1Y3QgUmVzcG9uc2VFcnJvciB3aXRoIDMgZWxlbWVudHMAp04SACQAAAC8aRAAYAAAADoCAAAJAAAAelMQAF4AAACYBQAAEQAAAHpTEABeAAAAowUAABEAAAB6UxAAXgAAANQGAAARAEGcnskACwYBAAAANQEAQayeyQALBgEAAACLBABBvJ7JAAsFAQAAAJ4AQcyeyQALBQEAAACXAEHcnskACyUBAAAAjAQAAHpTEABeAAAALAcAABEAAAB6UxAAXgAAADcHAAARAEGMn8kACyIBAAAAjQQAAAoAAIAEAACACAAAgAAAAAAAAAAAAQAAADUBAEG4n8kACwYBAAAAjAQAQcifyQALBQEAAACeAEHYn8kACwYBAAAAIAEAQeifyQALkhEBAAAAhAMAAAAAAAAQAAAABAAAAI4EAAAYUxAAYQAAAAcCAAARAAAAGFMQAGEAAAALAgAAFQAAABhTEABhAAAA+wEAABEAAAAYUxAAYQAAAP0BAAAVAAAALVQQAEoAAAC9AQAAHQAAAAEAAUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky//////////////////////////////////////////////////////////Pv///z80NTY3ODk6Ozw9/////////wABAgMEBQYHCAkKCwwNDg8QERITFBUWFxgZ////////GhscHR4fICEiIyQlJicoKSorLC0uLzAxMjP/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////Oi8vAADAcBAAVgAAACoLAAALAAAAAAAAAAQAAAAEAAAAnwIAAFVuY2xvc2VkT3BlbmluZ0JyYWNrZXRpbmRleACXBAAADAAAAAQAAACYBAAASW52YWxpZENvbXBvbmVudE5hbWVuYW1lSW52YWxpZE1vZGlmaWVydmFsdWVNaXNzaW5nQ29tcG9uZW50TmFtZQAAAAAIAAAABAAAAIgBAABNaXNzaW5nUmVxdWlyZWRNb2RpZmllckV4cGVjdGVkd2hhdE5vdFN1cHBvcnRlZGNvbnRleHQAAAAAAAAEAAAABAAAAJkEAABTaWduaW5nRmFpbHVyZQAAAAAAAAQAAAAEAAAAmgQAAEJpcDMyS2V5RGVyaXZhdGlvbkZhaWx1cmVzb3VyY2UAAAAAAAQAAAAEAAAAmwQAAEJpcDM5RXJyb3IAAAAAAAAEAAAABAAAAPwBAABBY2NvdW50RGVyaXZhdGlvbkVycm9yZmFpbGVkIHRvIGRlcml2ZSBjaGlsZCBrZXk6IAAA/lISABwAAABUaGVyZSB3YXMgYW4gaXNzdWUgd2l0aCBiaXAzOTogACRTEgAfAAAAZmFpbGVkIHRvIGRlcml2ZSBhY2NvdW50czogAExTEgAbAAAAYWJjaV9pbmZvYWJjaV9xdWVyeWJsb2NrYmxvY2tfYnlfaGFzaGJsb2NrX3Jlc3VsdHNibG9ja19zZWFyY2hibG9ja2NoYWluYnJvYWRjYXN0X3R4X2FzeW5jYnJvYWRjYXN0X3R4X3N5bmNicm9hZGNhc3RfdHhfY29tbWl0Y29tbWl0Y29uc2Vuc3VzX3BhcmFtc2NvbnNlbnN1c19zdGF0ZWdlbmVzaXNnZW5lc2lzX2NodW5rZWRoZWFkZXJoZWFkZXJfYnlfaGFzaGhlYWx0aG5ldF9pbmZvc3RhdHVzdHh0eF9zZWFyY2h2YWxpZGF0b3Jzc3Vic2Ny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AAAABAAAANwBAABOb3RGb3VuZEF0dGVtcHRlZFRvQ2xvbmVTdHJlYW1SZXF1ZXN0AAAAAAAAAAQAAAAEAAAA3QEAAFJlcXVlc3RGYWlsdXJlRW1wdHlSZXNwb25zZUVuZHBvaW50RmFpbHVyZWVycm9yUmVzcG9uc2VEZWNvZGVGYWlsdXJlbWVzc2FnZWNvbnRlbnRJbnRlcm5hbFJlc3BvbnNlSW5jb25zaXN0ZW5jeWRldGFpbHMAAAAAAAAEAAAABAAAAN4BAABCaW5jb2RlSnNvbgAAAAAABAAAAAQAAADfAQAAWWFtbAAAAAAEAAAABAAAAOABAABQbGFpblJlcXVlc3RUaW1lb3V0AAEAAAAAAAAARXhwaXJhdGlvbkRhdGVTaWduYXR1cmVWZXJpZmljYXRpb25FeHBpcmF0aW9uRGF0ZVNpZ25hdHVyZVZhbGlkaXR5QWdncmVnYXRpb25FbXB0eVNldEFnZ3JlZ2F0aW9uRHVwbGljYXRlSW5kaWNlc0FnZ3JlZ2F0aW9uVmVyaWZpY2F0aW9uSWRlbnRpdHlTaWduYXR1cmVBZ2dyZWdhdGlvblNpemVNaXNtYXRjaElkZW50aXR5Q29tbWl0bWVudEhhc2hXaXRoZHJhd2FsUmVxdWVzdFZlcmlmaWNhdGlvbktleWdlblBhcmFtZXRlcnNLZXlUb29TaG9ydEludGVycG9sYXRpb25TZXRTaXplSXNzdWFuY2VWZXJpZmljYXRpb24AAAAAAAAACAAAAAgAAADNBAAAAAAAAAQAAAAEAAAABwMAAFNwZW5kRXhjZWVkc0FsbG93YW5jZXNwZW5kaW5ncmVtYWluaW5nU3BlbmRTaWduYXR1cmVzVmFsaWRpdHlTcGVuZFNpZ25hdHVyZXNWZXJpZmljYXRpb25TcGVuZER1cGxpY2F0ZVNlcmlhbE51bWJlclNwZW5kRGF0ZVRvb0xhdGVTcGVuZERhdGVUb29FYXJseVNwZW5kWktQcm9vZlZlcmlmaWNhdGlvbgAAAAAABAAAAAQAAABoAQAATWFsZm9ybWVkU3RyaW5nQ29pbkluZGljZXNTaWduYXR1cmVWZXJpZmljYXRpb25EZXNlcmlhbGl6YXRpb25GYWlsdXJlb2JqZWN0QmluYXJ5RGVzZXJpYWxpc2F0aW9uRmFpbHVyZXR5cGVfbmFtZQAAAAAEAAAABAAAAM4EAABEZXNlcmlhbGl6YXRpb25NaW5MZW5ndGhtaW5hY3R1YWxEZXNlcmlhbGl6YXRpb25MZW5ndGhNaXNtYXRjaGV4cGVjdGVkRGVzZXJpYWxpemF0aW9uSW52YWxpZExlbmd0aHRhcmdldG1vZHVsdXNfdGFyZ2V0bW9kdWx1c1NjYWxhckRlc2VyaWFsaXphdGlvbkZhaWx1cmVHMVByb2plY3RpdmVEZXNlcmlhbGl6YXRpb25GYWlsdXJlRzJQcm9qZWN0aXZlRGVzZXJpYWxpemF0aW9uRmFpbHVyZVZlcmlmaWNhdGlvbktleVRvb1Nob3J0SW5zdWZmaWNpZW50TnVtYmVyT2ZJbmRleFNpZ25hdHVyZXNJbnN1ZmZpY2llbnROdW1iZXJPZkV4cGlyYXRpb25TaWduYXR1cmVzVW5sdWNraWVzdEVycm9yTm9Db250cmFjdEFkZHJlc3NBdmFpbGFibGUAAAAABAAAAAQAAAABAwAAV2FsbGV0RXJyb3IAAAAAAAQAAAAEAAAAAgMAAENvc21yc0Vycm9yQ29zbXJzRXJyb3JSZXBvcnRDb21zd2FzbUV2ZW50Tm90Rm91bmRDb21zd2FzbUF0dHJpYnV0ZU5vdEZvdW5kU2lnbmluZ0FjY291bnROb3RGb3VuZEludmFsaWRUeEhhc2gAAAAAAAAABAAAAAQAAAD7AQAAVGVuZGVybWludEVycm9yUnBjAAAAAAAABAAAAAQAAAAEAwAAVGVuZGVybWludEVycm9yU2VyaWFsaXphdGlvbkVycm9yRGVzZXJpYWxpemF0aW9uRXJyb3IAAAAAAAAABAAAAAQAAAAFAwAAUHJvdG9idWZFbmNvZGluZ0Vycm9yAAAAAAAAAAQAAAAEAAAABgMAAFByb3RvYnVmRGVjb2RpbmdFcnJvck5vbkV4aXN0ZW50QWNjb3VudEVycm9yU2VyZGVKc29uRXJyb3JNYWxmb3JtZWRBY2NvdW50QWRkcmVzc0ludmFsaWRQdWJsaWNLZXlOb0NvZGVJbmZvcm1hdGlvbk5vQ29udHJhY3RJbmZvcm1hdGlvbkludmFsaWRDb250cmFjdEhpc3RvcnlPcGVyYXRpb25JbnZhbGlkSGVpZ2h0AAAAAAAEAAAABAAAAB4EAABXYXNtQ29tcHJlc3Npb25FcnJvck1hbGZvcm1lZExvZ1N0cmluZwAAAAAAACEAAAABAAAACAMAAAAAAAAQAAAACAAAAM8EAAAAAAAABAAAAAQAAADQBAAAQnJvYWRjYXN0VHhFcnJvckNoZWNrVHhoYXNoaGVpZ2h0Y29kZXJhd19sb2dCcm9hZGNhc3RUeEVycm9yRGVsaXZlclR4TWFsZm9ybWVkR2FzUHJpY2VHYXNFc3RpbWF0aW9uRmFpbHVyZQAAAAAAAAQAAAAEAAAA0QQAAEFiY2lFcnJvcmxvZ3ByZXR0eV9sb2dVbnN1cHBvcnRlZEFjY291bnRUeXBldHlwZV91cmxNYWxmb3JtZWRDb2luY29pbl9yZXByZXNlbnRhdGlvbk5vQmFzZUFjY291bnRJbmZvcm1hdGlvbkF2YWlsYWJsZQAAAAAAAAAEAAAABAAAAA0DAABCcm9hZGNhc3RUaW1lb3V0dGltZW91dAAAAAAABAAAAAQAAAAOAwAAQ29zbXdhc21TdGRFcnJvclVuZXhwZWN0ZWRCZWNoMzJQcmVmaXhnb3RVbmV4cGVjdGVkTnVtYmVyT2ZNc2dSZXNwb25zZXNNYWxmb3JtZWRSZXNwb25zZURhdGFFeHRlbnNpb25RdWVyeUZhaWx1cmVjb250cmFjdHRoZSBwcm92aWRlZCBrZXkgc2hhcmUgaGFzbid0IGJlZW4gdmVyaWZpZWRmYWlsZWQgdG8gcXVlcnkgdGhlIGNvbnRyYWN0OiAAAChoEgAeAAAAdGhlIHByb3ZpZGVkIGFubm91bmNlIGFkZHJlc3MgaXMgbWFsZm9ybWVkOiBQaBIALAAAAHRoZSBwcm92aWRlZCB2ZXJpZmljYXRpb24ga2V5IGlzIG1hbGZvcm1lZDoghGgSACwAAABmYWlsZWQgdG8gY3JlYXRlIEFQSSBjbGllbnQ6IAAAALhoEgAdAAAAdGhlIHByb3ZpZGVkIGFjY291bnQgYWRkcmVzcyBpcyBtYWxmb3JtZWQ6IADgaBIAKwAAAG55bSBhcGkgZXJyb3IsIFtpZDogXSAgQCAoKQAjaRIABQAAAChpEgACAAAAKmkSAAQAAAAuaRIAAQAAAAAAAAAEAAAABAAAAOoBAABOeW1BUElFcnJvck1hbGZvcm1lZFVybFByb3ZpZGVkAAAAAAAE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czo6cXVlcnlfY2xpZW50bWVzc2FnZQAAALZwEgAHAAAAAAAAAAwAAAAEAAAAlQIAANkEAADaBAAAY29tbW9uL2NsaWVudC1saWJzL3ZhbGlkYXRvci1jbGllbnQvc3JjL255eGQvY29zbXdhc21fY2xpZW50L2NsaWVudF90cmFpdHMvcXVlcnlfY2xpZW50LnJzZXZlbnQgY29tbW9uL2NsaWVudC1saWJzL3ZhbGlkYXRvci1jbGllbnQvc3JjL255eGQvY29zbXdhc21fY2xpZW50L2NsaWVudF90cmFpdHMvcXVlcnlfY2xpZW50LnJzOjcwAAAAAQAAAEYAAAAAAAAAOnESAGMAAABucBIASAAAAMBwEgABAAAASKMZAMhwEgBucBIASAAAAOBwEgBaAAAAAQAAAGV2ZW50IGNvbW1vbi9jbGllbnQtbGlicy92YWxpZGF0b3ItY2xpZW50L3NyYy9ueXhkL2Nvc213YXNtX2NsaWVudC9jbGllbnRfdHJhaXRzL3F1ZXJ5X2NsaWVudC5yczo1NTUBAAAAKwIAAAAAAADgcRIAZAAAAG5wEgBIAAAAwHASAAEAAABUoxkAyHASAG5wEgBIAAAA4HASAFoAAAABAAAAVwCPvCIs99wbgSsAqDxQ5mV2ZW50IGNvbW1vbi9jbGllbnQtbGlicy92YWxpZGF0b3ItY2xpZW50L3NyYy9ueXhkL2NvbnRyYWN0X3RyYWl0cy9ka2dfcXVlcnlfY2xpZW50LnJzOjI4OG55bV92YWxpZGF0b3JfY2xpZW50OjpueXhkOjpjb250cmFjdF90cmFpdHM6OmRrZ19xdWVyeV9jbGllbnRjb21tb24vY2xpZW50LWxpYnMvdmFsaWRhdG9yLWNsaWVudC9zcmMvbnl4ZC9jb250cmFjdF90cmFpdHMvZGtnX3F1ZXJ5X2NsaWVudC5ycwABAAAAIAEAAAAAAACUchIAWgAAAO5yEgA9AAAAwHASAAEAAABgoxkAyHASAO5yEgA9AAAAK3MSAFAAAAABAAAAU2lnbmluZ0ZhaWx1cmVzb3VyY2UAAAAABAAAAAQAAAD8AQAAQWNjb3VudERlcml2YXRpb25FcnJvcmlkaGFzaHZhbHVlTWF4aW11bSBhbW91bnQgb2YgbG9ja2VkIGNvaW5zIGhhcyBhbHJlYWR5IGJlZW4gcGxlZGdlZE1heGltdW0gYW1vdW50IG9mIGxvY2tlZCB0b2tlbnMgaGFzIGFscmVhZHkgYmVlbiB1c2VkLiBZb3UgY2FuIG9ubHkgdXNlIHVwIHRvIDEwJSBvZiB5b3VyIGxvY2tlZCB0b2tlbnMgZm9yIGJvbmRpbmcgYW5kIGRlbGVnYXRpbmcuABMkEAA1AAAAtwAAACMAAAB0aW1lb3V0AHAyEABPAAAA5QUAABQAAABwMhAATwAAAOUFAAAhAAAAcDIQAE8AAADZBQAAIQAAAGRlc2NyaXB0aW9uKCkgaXMgZGVwcmVjYXRlZDsgdXNlIERpc3BsYXmw/3s3P/NtX0Qi2Xwg/bmHqIDRJbyLADsrW7icE7rhjW+hbBRKXgtnHafrjzOMmmLOFVVC6oAF8s8gLU1v2VAXvwtRujGZ+XK+GnT9obUJPFC2H+fTmnVBctnYaIQOInyLIwqh9DJUOhWJU/X8G5Hq5gQAACQAAAAEAAAA5wQAAOYEAAAkAAAABAAAAOgEAADnBAAAnHUSAOkEAADqBAAA6wQAAOwEAADtBAAA7gQAAAQAAAAEAAAA7wQAAO4EAAAEAAAABAAAAPAEAADvBAAA2HUSAOkEAADxBAAA6wQAAPIEAADtBAAAAAAAAAgAAAAEAAAA8wQAAAAAAAAIAAAABAAAAPQEAADzBAAAFHYSAOkEAAD1BAAA6wQAAPIEAADtBAAA9gQAABwAAAAEAAAAkwQAAPYEAAAcAAAABAAAAJMEAACTBAAAUHYSAPcEAAD4BAAA6wQAAPkEAADtBAAA+gQAAAQAAAAEAAAAMgIAAPoEAAAEAAAABAAAAPUAAAAyAgAAjHYSADMCAAD7BAAA6wQAADUCAADtBAAA/AQAACgAAAAIAAAAnAIAAPwEAAAoAAAACAAAAP0EAACcAgAAyHYSAP4EAAD/BAAAAAUAAAEFAAACBQAAAwUAAFgAAAAIAAAAwgQAAAMFAABYAAAACAAAAMIEAADCBAAABHcSAMMEAAAEBQAAAAUAAMUEAAACBQAAAAAAAAQAAAAEAAAAPAAAAEFjY291bnRJZENyeXB0b0RlY2ltYWxEZW5vbW5hbWUAAAAAAAgAAAAEAAAAiAEAAAAAAAAEAAAABAAAAAUFAABJbnZhbGlkRW51bVZhbHVlZm91bmRfdmFsdWUAAAAAAAQAAAAEAAAAyQQAAE1pc3NpbmdGaWVsZE1zZ1R5cGVleHBlY3RlZGZvdW5kAAAAAAQAAAAEAAAABgUAAFR4Tm90Rm91bmQAAAAAAAAEAAAABAAAAAcFAAAAAAAABAAAAAQAAACfAgAARW5jb2RlRXJyb3JyZXF1aXJlZHJlbWFpbmluZ05vbmUAAAAABAAAAAQAAAD9AgAAU29tZQgFAAAQAAAABAAAAAkFAAAAAAAABAAAAAQAAAAKBQAAVmVyaWZpY2F0aW9uRXJyYmFja3RyYWNlCwUAABAAAAAEAAAADAUAAFJlY292ZXJQdWJrZXlFcnINBQAADAAAAAQAAAAOBQAAR2VuZXJpY0Vycm1zZ0ludmFsaWRCYXNlNjQAAAAAAAAIAAAACAAAAA8FAABJbnZhbGlkRGF0YVNpemVhY3R1YWxJbnZhbGlkSGV4SW52YWxpZFV0ZjhOb3RGb3VuZGtpbmRQYXJzZUVycnRhcmdldF90eXBlU2VyaWFsaXplRXJyc291cmNlX3R5cGUAAAAAAQAAAAEAAAAQBQAAT3ZlcmZsb3cAAAAAAAAAAAEAAAARBQAARGl2aWRlQnlaZXJvAAAAABAAAAAEAAAAEgUAAENvbnZlcnNpb25PdmVyZmxvdwAAcDIQAE8AAABpBAAAJAAAAE5vQ29udHJhY3RBZGRyZXNzQXZhaWxhYmxlAAAAAAAABAAAAAQAAAABAwAAV2FsbGV0RXJyb3IAAAAAAAQAAAAEAAAAAgMAAENvc21yc0Vycm9yQ29zbXJzRXJyb3JSZXBvcnRDb21zd2FzbUV2ZW50Tm90Rm91bmRDb21zd2FzbUF0dHJpYnV0ZU5vdEZvdW5kAAAAAAAABAAAAAQAAAADAwAAU2lnbmluZ0FjY291bnROb3RGb3VuZEludmFsaWRUeEhhc2gAAAAAAAQAAAAEAAAA+wEAAFRlbmRlcm1pbnRFcnJvclJwYwAAAAAAAAQAAAAEAAAABAMAAFRlbmRlcm1pbnRFcnJvclNlcmlhbGl6YXRpb25FcnJvckRlc2VyaWFsaXphdGlvbkVycm9yAAAAAAAAAAQAAAAEAAAABQMAAFByb3RvYnVmRW5jb2RpbmdFcnJvcgAAAAAAAAAEAAAABAAAAAYDAABQcm90b2J1ZkRlY29kaW5nRXJyb3JOb25FeGlzdGVudEFjY291bnRFcnJvcgAAAAAEAAAABAAAANsBAABTZXJkZUpzb25FcnJvck1hbGZvcm1lZEFjY291bnRBZGRyZXNzSW52YWxpZFB1YmxpY0tleQAAAAAAAAAEAAAABAAAAAcDAABOb0NvZGVJbmZvcm1hdGlvbk5vQ29udHJhY3RJbmZvcm1hdGlvbkludmFsaWRDb250cmFjdEhpc3RvcnlPcGVyYXRpb25JbnZhbGlkSGVpZ2h0AAAAAAAABAAAAAQAAAAeBAAAV2FzbUNvbXByZXNzaW9uRXJyb3JNYWxmb3JtZWRMb2dTdHJpbmcAAAAAAAAhAAAAAQAAAAgDAAAAAAAAEAAAAAgAAAATBQAAAAAAAAQAAAAEAAAAFAUAAEJyb2FkY2FzdFR4RXJyb3JDaGVja1R4aGVpZ2h0Y29kZXJhd19sb2dCcm9hZGNhc3RUeEVycm9yRGVsaXZlclR4TWFsZm9ybWVkR2FzUHJpY2VHYXNFc3RpbWF0aW9uRmFpbHVyZQAAAAAAAAQAAAAEAAAA0QQAAEFiY2lFcnJvcmxvZ3ByZXR0eV9sb2dVbnN1cHBvcnRlZEFjY291bnRUeXBldHlwZV91cmxNYWxmb3JtZWRDb2luY29pbl9yZXByZXNlbnRhdGlvbk5vQmFzZUFjY291bnRJbmZvcm1hdGlvbkF2YWlsYWJsZQAAAAAAAAAEAAAABAAAAA0DAABCcm9hZGNhc3RUaW1lb3V0AAAAAAQAAAAEAAAADgMAAENvc213YXNtU3RkRXJyb3JVbmV4cGVjdGVkQmVjaDMyUHJlZml4Z290VW5leHBlY3RlZE51bWJlck9mTXNnUmVzcG9uc2VzTWFsZm9ybWVkUmVzcG9uc2VEYXRhRXh0ZW5zaW9uUXVlcnlGYWlsdXJlY29udHJhY3RtZXNzYWdlAAAAAAQAAAAEAAAAFQUAAE92ZXJmbG93RXJyb3JvcGVyYXRpb25ObyBjb250cmFjdCBhZGRyZXNzIGlzIGF2YWlsYWJsZSB0byBwZXJmb3JtIHRoZSBjYWxsOiAafhIANgAAAFRoZXJlIHdhcyBhbiBpc3N1ZSBvbiB0aGUgY29zbXJzIHNpZGU6IABYfhIAJwAAAGNvc213YXNtIGV2ZW50IG5vdCBmb3VuZGNvc213YXNtIGF0dHJpYnV0ZSBub3QgZm91bmRGYWlsZWQgdG8gZGVyaXZlIGFjY291bnQgYWRkcmVzc0FkZHJlc3MgIHdhcyBub3QgZm91bmQgaW4gdGhlIHdhbGxldNx+EgAIAAAA5H4SABwAAABGYWlsZWQgdG8gc2lnbiByYXcgdHJhbnNhY3Rpb24gaXMgbm90IGEgdmFsaWQgdHggaGFzaAAAAAEAAAAAAAAALn8SABcAAABUZW5kZXJtaW50IFJQQyByZXF1ZXN0IGZhaWxlZCAtIFh/EgAgAAAAdGVuZGVybWludCBsaWJyYXJ5IGZhaWx1cmU6IIB/EgAcAAAARmFpbGVkIHdoZW4gYXR0ZW1wdGluZyB0byBzZXJpYWxpemUgZGF0YSAoKQCkfxIAKgAAAM5/EgABAAAARmFpbGVkIHdoZW4gYXR0ZW1wdGluZyB0byBkZXNlcmlhbGl6ZSBkYXRhICjgfxIALAAAAM5/EgABAAAARmFpbGVkIHdoZW4gYXR0ZW1wdGluZyB0byBlbmNvZGUgb3VyIHByb3RvYnVmIGRhdGEgLSAAAAAcgBIANQAAAEZhaWxlZCB0byBkZWNvZGUgb3VyIHByb3RvYnVmIGRhdGEgLSAAAABcgBIAJQAAAEFjY291bnQgIGRvZXMgbm90IGV4aXN0IG9uIHRoZSBjaGFpboyAEgAIAAAAlIASABwAAABGYWlsZWQgb24ganNvbiBzZXJpYWxpemF0aW9uL2Rlc2VyaWFsaXphdGlvbiAtIADAgBIALwAAACBpcyBub3QgYSB2YWxpZCBhY2NvdW50IGFkZHJlc3MAjIASAAgAAAD4gBIAHwAAACBoYXMgYW4gaW52YWxpZCBhc3NvY2lhdGVkIHB1YmxpYyBrZXkAAACMgBIACAAAACiBEgAlAAAAUXVlcmllZCBjb250cmFjdCAoY29kZV9pZDogKSBkaWQgbm90IGhhdmUgYW55IGNvZGUgaW5mb3JtYXRpb24gYXR0YWNoZWQAYIESABsAAAB7gRIALAAAAFF1ZXJpZWQgY29udHJhY3QgKGFkZHJlc3M6ICkgZGlkIG5vdCBoYXZlIGFueSBjb250cmFjdCBpbmZvcm1hdGlvbiBhdHRhY2hlZAC4gRIAGwAAANOBEgAwAAAAQ29udHJhY3QgY29udGFpbnMgaW52YWxpZCBvcGVyYXRpb25zIGluIGl0cyBoaXN0b3J5QmxvY2sgaGFzIGFuIGludmFsaWQgaGVpZ2h0IChlaXRoZXIgbmVnYXRpdmUgb3IgbGFyZ2VyIHRoYW4gaTY0OjpNQVhGYWlsZWQgdG8gY29tcHJlc3MgcHJvdmlkZWQgd2FzbSBjb2RlIC0gAIuCEgAoAAAATG9ncyByZXR1cm5lZCBmcm9tIHRoZSB2YWxpZGF0b3Igd2VyZSBtYWxmb3JtZWRFcnJvciB3aGVuIGJyb2FkY2FzdGluZyB0eCAgYXQgaGVpZ2h0IC4gRXJyb3Igb2NjdXJyZWQgZHVyaW5nIENoZWNrVHggcGhhc2UuIENvZGU6IDsgUmF3IGxvZzogAAAA64ISABsAAAAGgxIACwAAABGDEgAtAAAAPoMSAAsAAAAuIEVycm9yIG9jY3VycmVkIGR1cmluZyBEZWxpdmVyVHggcGhhc2UuIENvZGU6IADrghIAGwAAAAaDEgALAAAAbIMSAC8AAAA+gxIACwAAAFRoZSBwcm92aWRlZCBnYXMgcHJpY2UgaXMgbWFsZm9ybWVkRmFpbGVkIHRvIGVzdGltYXRlIGdhcyBwcmljZSBmb3IgdGhlIHRyYW5zYWN0aW9uQWJjaSBxdWVyeSBmYWlsZWQgd2l0aCBjb2RlICAtIAAAD4QSABwAAAArhBIAAwAAAFVuc3VwcG9ydGVkIGFjY291bnQgdHlwZTogAABAhBIAGgAAACBpcyBub3QgYSB2YWxpZCBDb3Ntb3MgQ29pbgABAAAAAAAAAGSEEgAbAAAAVGhpcyBhY2NvdW50IGRvZXMgbm90IGhhdmUgQmFzZUFjY291bnQgaW5mb3JtYXRpb24gYXZhaWxhYmxlIHRvIGl0VHJhbnNhY3Rpb24gd2l0aCBJRCAgaGFzIGJlZW4gc3VibWl0dGVkIGJ1dCBub3QgeWV0IGZvdW5kIG9uIHRoZSBjaGFpbi4gWW91IG1pZ2h0IHdhbnQgdG8gY2hlY2sgZm9yIGl0IGxhdGVyLiBUaGVyZSB3YXMgYSB0b3RhbCB3YWl0IG9mICBzZWNvbmRzAADShBIAFAAAAOaEEgB0AAAAWoUSAAgAAABDb3Ntd2FzbSBzdGQgZXJyb3I6IHyFEgAUAAAAQWNjb3VudCBoYWQgYW4gdW5leHBlY3RlZCBiZWNoMzIgcHJlZml4LiBFeHBlY3RlZDogLCBnb3Q6IAAAmIUSADMAAADLhRIABwAAAHRoZSB0cmFuc2FjdGlvbiByZXR1cm5lZCB1bmV4cGVjdGVkLCAsIG51bWJlciBvZiBNc2dSZXNwb25zZS4gRXhwZWN0ZWQgdG8gcmVjZWl2ZSBhIHNpbmdsZSBvbmUAAOSFEgAlAAAACYYSADkAAAB0aGUgcmVzcG9uc2UgZGF0YSBoYXMgaW52YWxpZCBzaXplLiBnb3QgIGJ5dGVzLCBidXQgZXhwZWN0ZWQgIGJ5dGVzIGluc3RlYWQAVIYSACgAAAB8hhIAFQAAAJGGEgAOAAAAb25lIG9mIHRoZSBleHRlbnNpb24gcXVlcnkgZm9yICBmYWlsZWQgd2l0aCB0aGUgZm9sbG93aW5nIG1lc3NhZ2U6IAC4hhIAHwAAANeGEgAkAAAALVQQAEoAAAC9AQAAHQAAAERpdmlkZUJ5WmVyb0Vycm9yQ29udmVyc2lvbk92ZXJmbG93RXJyb3IAAAAABAAAAAQAAAAWBQAAQWdncmVnYXRpb25CYXRjaEVyckludmFsaWRIYXNoRm9ybWF0SW52YWxpZFNpZ25hdHVyZUZvcm1hdEludmFsaWRQdWJrZXlGb3JtYXRJbnZhbGlkUmVjb3ZlcnlQYXJhbUludmFsaWRQb2ludFVua25vd25IYXNoRnVuY3Rpb24AAAAABAAAAAQAAAAXBQAAUGFpcmluZ0VxdWFsaXR5VW5rbm93bkVycmVycm9yX2NvZGUABAAAAAAAAAAEAAAABABBoJDKAAt2DAAAAG51bGxJZE5vbmVkYXRhIGRpZCBub3QgbWF0Y2ggYW55IHZhcmlhbnQgb2YgdW50YWdnZWQgZW51bSBJZC1CEABnAAAAdQAAABsAAAChGBAASwAAAPgBAAAOAAAAGAUAAAwAAAAEAAAAGQUAABoFAAB2AgBBoJHKAAvRDwEAAAAbBQAAYSBEaXNwbGF5IGltcGxlbWVudGF0aW9uIHJldHVybmVkIGFuIGVycm9yIHVuZXhwZWN0ZWRseQCCQRAASwAAAAULAAAOAAAARXJyb3IAAACCQRAASwAAALAMAAAOAAAAgkEQAEsAAACqDAAADgAAAHVua25vd24gZmllbGQgYGAsIGV4cGVjdGVkIAAYiRIADwAAACeJEgAMAAAAYCwg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AE4FAABPBQAAWAQAAFkEAABaBAAAUAUAAFEFAABFbXB0eUhvc3RJZG5hRXJyb3JJbnZhbGlkUG9ydEludmFsaWRJcHY0QWRkcmVzc0ludmFsaWRJcHY2QWRkcmVzc0ludmFsaWREb21haW5DaGFyYWN0ZXJSZWxhdGl2ZVVybFdpdGhvdXRCYXNlUmVsYXRpdmVVcmxXaXRoQ2Fubm90QmVBQmFzZUJhc2VTZXRIb3N0T25DYW5ub3RCZUFCYXNlVXJsT3ZlcmZsb3cAAAAAAAAEAAAABAAAAFIFAABJbXBvc3NpYmxlU2VyaWFsaXphdGlvbkltcG9zc2libGVEZXNlcmlhbGl6YXRpb24AAAAABAAAAAQAAABTBQAAUGFyc2VNZXNzYWdlAAAAAAQAAAAEAAAA0wEAAGRpZCBub3QgcHJvdmlkZSBhbnkgdmFsaWQgY2xpZW50IFVSTHNmYWlsZWQgdG8gY29uc3RydWN0IGlubmVyIHJlcXdlc3QgY2xpZW50OiAAuZgSACoAAAByZXF1ZXN0IGZhaWxlZCB3aXRoIGVycm9yIG1lc3NhZ2U6IADsmBIAIwAAAHRoZXJlIHdhcyBhbiBpc3N1ZSB3aXRoIHRoZSBSRVNUIHJlcXVlc3Q6IAAAGJkSACoAAABmYWlsZWQgdG8gcGFyc2UgIGFzIGEgdmFsaWQgVVJMOiAAAABMmRIAEAAAAFyZEgARAAAAZmFpbGVkIHRvIHNlbmQgcmVxdWVzdCBmb3IgOiAAAACAmRIAGwAAAJuZEgACAAAAZmFpbGVkIHRvIHJlYWQgcmVzcG9uc2UgYm9keSBmcm9tIAAAsJkSACIAAACbmRIAAgAAAGZhaWxlZCB0byBkZXNlcmlhbGl6ZSByZWNlaXZlZCByZXNwb25zZTogAAAA5JkSACkAAABwcm92aWRlZCB1cmwgaXMgbWFsZm9ybWVkOiAAGJoSABsAAAB0aGUgcmVxdWVzdGVkIHJlc291cmNlIGNvdWxkIG5vdCBiZSBmb3VuZCBhdCAAAAA8mhIALQAAAGF0dGVtcHRlZCB0byB1c2UgZG9tYWluIGZyb250aW5nIGFuZCBjbG9uZSBhIHJlcXVlc3QgY29udGFpbmluZyBzdHJlYW0gZGF0YXRoZSByZXF1ZXN0IGZvciAgZmFpbGVkIHdpdGggc3RhdHVzICcnLiBubyBhZGRpdGlvbmFsIGVycm9yIG1lc3NhZ2UgcHJvdmlkZWQuIHJlc3BvbnNlIGhlYWRlcnM6IAC/mhIAEAAAAM+aEgAVAAAA5JoSADsAAAB0aGUgcmV0dXJuZWQgcmVzcG9uc2UgZnJvbSAgd2FzIGVtcHR5LiBzdGF0dXM6ICcnLiByZXNwb25zZSBoZWFkZXJzOiAAAAA4mxIAGwAAAFObEgAVAAAAaJsSABUAAABmYWlsZWQgdG8gcmVzb2x2ZSByZXF1ZXN0IGZvciAuIHN0YXR1czogJy4gYWRkaXRpb25hbCBlcnJvciBtZXNzYWdlOiAAAACYmxIAHgAAALabEgALAAAAaJsSABUAAADBmxIAHAAAAGZhaWxlZCB0byBkZWNvZGUgcmVzcG9uc2UgYm9keTogIGZyb20gAAAAnBIAIAAAACCcEgAGAAAAZmFpbGVkIHRvIHJlc29sdmUgcmVxdWVzdCB0byAgZHVlIHRvIGRhdGEgaW5jb25zaXN0ZW5jeTogAAAAOJwSAB0AAABVnBIAHAAAAEZhaWxlZCB0byBlbmNvZGUgYmluY29kZTogAACEnBIAGgAAAEZhaWxlZCB0byBqc29uOiConBIAEAAAAEZhaWxlZCB0byB5YW1sOiDAnBIAEAAAAEZhaWxlZCB0byBwbGFpbjogAAAA2JwSABEAAAB0aGUgcmVxdWVzdCBoYXMgdGltZWQgb3V0UmVxd2VzdEVycm9yV3JhcHBlcnRpbWVkIG91dDogcmVkaXJlY3QgbG9vcCBhdCArnRIAEQAAAJuZEgACAAAAIHN0YXR1czogAAAATJ0SAAkAAAAgdW5rbm93biBzdGF0dXMgY29kZSBzb3VyY2U6IAAAAHSdEgAJAAAAIHVua25vd24gbG93ZXItbGV2ZWwgZXJyb3Igc291cmNlAAAAcDIQAE8AAABpBAAAJAAAAGNyZWF0ZV9yZXF1ZXN0AAABAAAA2AMAAAEAAAC8nRIADgAAACKNEgATAAAAPJQSAAEAAADwoxkARI0SACKNEgATAAAAXI0SACEAAAACAAAAVAUAAFAEAAAIAAAAVQUAAKFsEAAhAAAACwQAAFgAAAAtVBAASgAAAL0BAAAdAAAACQAAAAkAAAALAAAAEgAAABIAAAAWAAAAFgAAACAAAAAZAAAACAAAAHiXEgCBlxIAipcSAJWXEgCnlxIAuZcSAM+XEgDllxIABZgSAB6YEgBWBQAADAAAAAQAAABXBQAAWAUAAFkFAEGsvcoAC4oRAQAAAFoFAABhIERpc3BsYXkgaW1wbGVtZW50YXRpb24gcmV0dXJuZWQgYW4gZXJyb3IgdW5leHBlY3RlZGx5AIJBEABLAAAABQsAAA4AAABkZXNjcmlwdGlvbigpIGlzIGRlcHJlY2F0ZWQ7IHVzZSBEaXNwbGF5D/I7FLcVm5WcACnaya0JG2FjY2VwdGFjY2VwdC1jaGFyc2V0YWNjZXB0LWVuY29kaW5nYWNjZXB0LWxhbmd1YWdlYWNjZXB0LXJhbmdlc2FjY2Vzcy1jb250cm9sLWFsbG93LWNyZWRlbnRpYWxzYWNjZXNzLWNvbnRyb2wtYWxsb3ctaGVhZGVyc2FjY2Vzcy1jb250cm9sLWFsbG93LW1ldGhvZHNhY2Nlc3MtY29udHJvbC1hbGxvdy1vcmlnaW5hY2Nlc3MtY29udHJvbC1leHBvc2UtaGVhZGVyc2FjY2Vzcy1jb250cm9sLW1heC1hZ2VhY2Nlc3MtY29udHJvbC1yZXF1ZXN0LWhlYWRlcnNhY2Nlc3MtY29udHJvbC1yZXF1ZXN0LW1ldGhvZGFnZWFsbG93YWx0LXN2Y2F1dGhvcml6YXRpb25jYWNoZS1jb250cm9sY2FjaGUtc3RhdHVzY2RuLWNhY2hlLWNvbnRyb2xjb25uZWN0aW9uY29udGVudC1kaXNwb3NpdGlvbmNvbnRlbnQtZW5jb2Rpbmdjb250ZW50LWxhbmd1YWdlY29udGVudC1sZW5ndGhjb250ZW50LWxvY2F0aW9uY29udGVudC1yYW5nZWNvbnRlbnQtc2VjdXJpdHktcG9saWN5Y29udGVudC1zZWN1cml0eS1wb2xpY3ktcmVwb3J0LW9ubHljb250ZW50LXR5cGVjb29raWVkbnRkYXRlZXRhZ2V4cGVjdGV4cGlyZXNmb3J3YXJkZWRmcm9taG9zdGlmLW1hdGNoaWYtbW9kaWZpZWQtc2luY2VpZi1ub25lLW1hdGNoaWYtcmFuZ2VpZi11bm1vZGlmaWVkLXNpbmNlbGFzdC1tb2RpZmllZGxpbmtsb2NhdGlvbm1heC1mb3J3YXJkc29yaWdpbnByYWdtYXByb3h5LWF1dGhlbnRpY2F0ZXByb3h5LWF1dGhvcml6YXRpb25wdWJsaWMta2V5LXBpbnNwdWJsaWMta2V5LXBpbnMtcmVwb3J0LW9ubHlyYW5nZXJlZmVyZXJyZWZlcnJlci1wb2xpY3lyZWZyZXNocmV0cnktYWZ0ZXJzZWMtd2Vic29ja2V0LWFjY2VwdHNlYy13ZWJzb2NrZXQtZXh0ZW5zaW9uc3NlYy13ZWJzb2NrZXQta2V5c2VjLXdlYnNvY2tldC1wcm90b2NvbHNlYy13ZWJzb2NrZXQtdmVyc2lvbnNlcnZlcnNldC1jb29raWVzdHJpY3QtdHJhbnNwb3J0LXNlY3VyaXR5dGV0cmFpbGVydHJhbnNmZXItZW5jb2Rpbmd1c2VyLWFnZW50dXBncmFkZXVwZ3JhZGUtaW5zZWN1cmUtcmVxdWVzdHN2YXJ5dmlhd2FybmluZ3d3dy1hdXRoZW50aWNhdGV4LWNvbnRlbnQtdHlwZS1vcHRpb25zeC1kbnMtcHJlZmV0Y2gtY29udHJvbHgtZnJhbWUtb3B0aW9uc3gteHNzLXByb3RlY3Rpb25PUFRJT05TR0VUUE9TVFBVVERFTEVURUhFQURUUkFDRUNPTk5FQ1RQQVRDSEVycm9ygkEQAEsAAACwDAAADgAAAIJBEABLAAAAqgwAAA4AAABWBQAADAAAAAQAAABZAAAAVgUAAAwAAAAEAAAAWgAAAFkAAAD0oxIAWwUAAFwFAABdBQAAXgUAAF8FAAAgDhAAZAAAAL0AAAA5AAAAdXJsIHBhcnNlaGVhZGVycyB0cnlfaXRlcmhlYWRlcnMgaGF2ZSBhbiBpdGVyYXRvcmhlYWRlcnMgaXRlcmF0b3IgZG9lc24ndCB0aHJvd3NlcmlhbGl6ZWQgaGVhZGVyc2Rlc2VyaWFsaXphYmxlIHNlcmlhbGl6ZWQgaGVhZGVyc0pzVmFsdWUoInJlcXdlc3Q6OmVycm9yczo6VGltZWRPdXQiKQAAnVwQAGEAAAAiAAAAAQAAAHByb21pc2UgcmVzb2x2ZWQgdG8gdW5leHBlY3RlZCB0eXBlAC1UEABKAAAAvQEAAB0AAADAcBAAVgAAAOIAAAAKAAAALVQQAEoAAACnAQAAHwAAAMBwEABWAAAA4gAAAAoAAAB5MxAASgAAAJQIAAAfAAAA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OiAAeKwSAA0AAACFrBIAAgAAAAEAAAAAAAAAbWFsbG9jIGVycm9yOiAAAKCsEgAOAAAAcScQAHUAAABGAAAAEQAAABdjEABQAAAAKgIAABEAAAAAAAAAAQAAAAIAAAAEAAAAOiAAAAEAAAAAAAAA6KwSAAIAAABpbnRlcm5hbCBlcnJvcjogZW50ZXJlZCB1bnJlYWNoYWJsZSBjb2RlSSQQAGsAAADYAAAAJgAAAEVPRiB3aGlsZSBwYXJzaW5nIGEgdmFsdWVkZXNlcmlhbGl6aW5nIGZyb20gWUFNTCBjb250YWluaW5nIG1vcmUgdGhhbiBvbmUgZG9jdW1lbnQgaXMgbm90IHN1cHBvcnRlZHJlY3Vyc2lvbiBsaW1pdCBleGNlZWRlZHJlcGV0aXRpb24gbGltaXQgZXhjZWVkZWRzZXJpYWxpemF0aW9uIGFuZCBkZXNlcmlhbGl6YXRpb24gb2YgYnl0ZXMgaW4gWUFNTCBpcyBub3QgaW1wbGVtZW50ZWR1bmtub3duIGFuY2hvcnNlcmlhbGl6aW5nIG5lc3RlZCBlbnVtcyBpbiBZQU1MIGlzIG5vdCBzdXBwb3J0ZWQgeWV0ZXhwZWN0ZWQgYSBtYXBwaW5nIG9yIGxpc3Qgb2YgbWFwcGluZ3MgZm9yIG1lcmdpbmcsIGJ1dCBmb3VuZCBzY2FsYXJ1bmV4cGVjdGVkIHRhZ2dlZCB2YWx1ZSBpbiBtZXJnZWV4cGVjdGVkIGEgbWFwcGluZyBmb3IgbWVyZ2luZywgYnV0IGZvdW5kIHNjYWxhcmV4cGVjdGVkIGEgbWFwcGluZyBmb3IgbWVyZ2luZywgYnV0IGZvdW5kIHNlcXVlbmNlZW1wdHkgWUFNTCB0YWcgaXMgbm90IGFsbG93ZWRmYWlsZWQgdG8gcGFyc2UgWUFNTCBudW1iZXIAAEkkEABrAAAA9AAAACUAAABFcnJvcigAAEkkEABrAAAAGgEAABkAAABJJBAAawAAABsBAAAZAAAALCBsaW5lOiAsIGNvbHVtbjogAACIrxIACAAAAJCvEgAKAAAAKSBhdCAAAACtrxIABAAAAIEFAAAMAAAABAAAAIIFAACDBQAAWQUAQdzfygALrQIBAAAAhAUAAGEgRGlzcGxheSBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB1bmV4cGVjdGVkbHkAgkEQAEsAAAAFCwAADgAAAEVycm9yAAAAgkEQAEsAAACqDAAADgAAAIJBEABLAAAAqgwAAA4AAACFBQAADAAAAAQAAACGBQAAhwUAAFkFAAAAAAAADAAAAAQAAACIBQAAiQUAAIoFAACdOhAATwAAABkBAAAZAAAATm9uZVNvbWUAAAAABAAAAAQAAACLBQAAAAAAAAQAAAAEAAAAjAUAAP4hEAByAAAAXQAAADkAAAD+IRAAcgAAAGwAAAAjAAAA/iEQAHIAAAByAAAAFQAAAP4hEAByAAAAdgAAACAAAABceAAA/LASAAIAAAACAEGS4soACwECAEGc4soAC80DIAAA6f4hEAByAAAAZQAAACsAAAD+IRAAcgAAAGkAAAAbAAAA/iEQAHIAAABHAAAARQAAAP4hEAByAAAASwAAACQAAAD+IRAAcgAAAEsAAAAjAAAAlYEQAP4hEAByAAAAEgAAAAkAAAAwMDAxMDIwMzA0MDUwNjA3MDgwOTEwMTExMjEzMTQxNTE2MTcxODE5MjAyMTIyMjMyNDI1MjYyNzI4MjkzMDMxMzIzMzM0MzUzNjM3MzgzOTQwNDE0MjQzNDQ0NTQ2NDc0ODQ5NTA1MTUyNTM1NDU1NTY1NzU4NTk2MDYxNjI2MzY0NjU2NjY3Njg2OTcwNzE3MjczNzQ3NTc2Nzc3ODc5ODA4MTgyODM4NDg1ODY4Nzg4ODk5MDkxOTI5Mzk0OTU5Njk3OTg5OQFwEABYAAAA3AAAAAEAAAABcBAAWAAAAN0AAAABAAAATWFyawAAAAAIAAAACAAAAJAFAABpbmRleAAAAJ8jEABzAAAAmwAAACYAAABsaW5lnyMQAHMAAACcAAAAKAAAAGNvbHVtbkVycm9yTUVNT1JZUkVBREVSU0NBTk5FUlBBUlNFUkNPTVBPU0VSV1JJVEVSRU1JVFRFUgAAAAEAQfTlygAL0QkYAAAABAAAAJEFAABraW5kAAAAAAQAAAAEAAAAkgUAAHByb2JsZW1wcm9ibGVtX29mZnNldAAAAAAAAAAYAAAACAAAAJMFAABwcm9ibGVtX21hcmtjb250ZXh0Y29udGV4dF9tYXJrcG9zaXRpb24gW7MSAAkAAACfIxAAcwAAAI4AAAARAAAAnyMQAHMAAACPAAAAEQAAAGxpbmUgIGNvbHVtbiAAAACMsxIABQAAAJGzEgAIAAAAIGF0IHBvc2l0aW9uIAAAAKyzEgANAAAAIGF0IMSzEgAEAAAALCAAANCzEgACAAAA5ycQAGYAAABjAAAACQAAAOcnEABmAAAA4gAAAAkAAADnJxAAZgAAAKoAAAARAAAA5ycQAGYAAACwAAAAEQAAAOcnEABmAAAAIgkAABcAAADnJxAAZgAAACMJAAAVAAAA5ycQAGYAAAC0AgAACQAAAOcnEABmAAAAuwIAAAkAAADnJxAAZgAAAGcCAAAJAAAA5ycQAGYAAABrAgAACQAAAOcnEABmAAAApggAABoAAADnJxAAZgAAACwAAAAFAAAA5ycQAGYAAABUAAAABQAAAOcnEABmAAAASgAAAAUAAAABIWV2ZW50LmlzX251bGwoKS9ob21lL3J1bm5lci8uY2FyZ28vcmVnaXN0cnkvc3JjL2luZGV4LmNyYXRlcy5pby0xOTQ5Y2Y4YzZiNWI1NTdmL3Vuc2FmZS1saWJ5YW1sLTAuMi4xMS9zcmMvYXBpLnJzIWVtaXR0ZXIuaXNfbnVsbCgpKCgqZW1pdHRlcikud3JpdGVfaGFuZGxlcikuaXNfbm9uZSgpIXZhbHVlLmlzX251bGwoKSF0YWdfZGlyZWN0aXZlc19zdGFydC5pc19udWxsKCkgJiYgIXRhZ19kaXJlY3RpdmVzX2VuZC5pc19udWxsKCkgfHwKdGFnX2RpcmVjdGl2ZXNfc3RhcnQgPT0gdGFnX2RpcmVjdGl2ZXNfZW5kISgoKnRhZ19kaXJlY3RpdmUpLnByZWZpeCkuaXNfbnVsbCgpISgoKnRhZ19kaXJlY3RpdmUpLmhhbmRsZSkuaXNfbnVsbCgpYXJpdGhtZXRpYyBvdmVyZmxvdwAAK7YSABMAAAAkFxAAYgAAAGsAAAAJAAAAKCgqZW1pdHRlcikud3JpdGVfaGFuZGxlcikuaXNfc29tZSgpL2hvbWUvcnVubmVyLy5jYXJnby9yZWdpc3RyeS9zcmMvaW5kZXguY3JhdGVzLmlvLTE5NDljZjhjNmI1YjU1N2YvdW5zYWZlLWxpYnlhbWwtMC4yLjExL3NyYy93cml0ZXIucnMoKmVtaXR0ZXIpLmVuY29kaW5nICE9IFlBTUxfQU5ZX0VOQ09ESU5Hbm9uLW51bGwgZnVuY3Rpb24gcG9pbnRlcgAArigQAGUAAAB9AAAAIQAAACFlbWl0dGVyLmlzX251bGwoKTo6IEFzc2VydGlvbiBgYCBmYWlsZWQuAAAAAQAAAAAAAABGtxIAAQAAAEe3EgANAAAAVLcSAAkAAACXcxAAYgAAAOEAAAAJAAAAl3MQAGIAAACqAAAAGwAAAJdzEABiAAAADwEAAAkAAADEtxIAzMcSAOjHEgBVVEYtOAAAAAEAQdDvygALEby3EgAFAAAARVVDLUpQAAAFAEHs78oACxHYtxIABgAAAEVVQy1LUgAACABBiPDKAAtl9LcSAAYAAABJQk04NjYAAABgEABABAAAAHAUABC4EgAGAAAAS09JOC1SAAAAQAEATgQAAAB9FAAsuBIABgAAAEtPSTgtVQAAAEABAE4EAAAAfhQASLgSAAYAAABnYjE4MDMwAAMAQfjwygAL1R5kuBIABwAAAGwxbDJsM2w0bDVsNmw5ODY2bWFja29pZ2JrYmlnNXV0Zjhrb2k4c2ppc3Vjcy0ybXM5MzJjcDg2NnV0Zi04Y3A4MTlhc2NpaXgtZ2JrZ3JlZWtjcDEyNTBjcDEyNTFsYXRpbjFnYjIzMTJjcDEyNTJsYXRpbjJjcDEyNTNsYXRpbjNjcDEyNTRsYXRpbjRjcDEyNTVjc2JpZzVsYXRpbjV1dGYtMTZjcDEyNTZpYm04NjZsYXRpbjZjcDEyNTdjcDEyNThncmVlazhpYm04MTlhcmFiaWN2aXN1YWxrb3JlYW5ldWMtanBrb2k4LXJrb2k4X3JldWMta3J4LXNqaXNrb2k4LXVoZWJyZXd0aXMtNjIwa3NjNTYwMWdiXzIzMTJkb3MtODc0Y24tYmlnNXVuaWNvZGVjaGluZXNlbG9naWNhbGNza29pOHJjc2V1Y2tya29pOC1ydXgtY3AxMjUwa3NjXzU2MDF4LWNwMTI1MWlzbzg4NTkxY3NnYjIzMTJ4LWNwMTI1Mmlzbzg4NTkyeC1jcDEyNTNpc284ODU5M2VjbWEtMTE0eC1jcDEyNTRpc284ODU5NHgtY3AxMjU1aXNvODg1OTV4LXgtYmlnNXgtY3AxMjU2Y3NpYm04NjZpc284ODU5NngtY3AxMjU3aXNvODg1OTdhc21vLTcwOGVjbWEtMTE4ZWxvdF85Mjh4LWNwMTI1OGlzbzg4NTk4aXNvODg1OTljeXJpbGxpY3V0Zi0xNmJldXRmLTE2bGV1cy1hc2NpaW1zX2thbmppeC1ldWMtanBpc284ODU5MTBpc284ODU5LTFpc284ODU5MTFpc284ODU5LTJpc284ODU5LTNpc284ODU5MTNpc284ODU5LTRpc284ODU5MTRpc284ODU5LTVpc284ODU5MTVpc284ODU5LTZpc284ODU5LTdpc284ODU5LThpc28taXItNThpc284ODU5LTljc3VuaWNvZGVtYWNpbnRvc2hzaGlmdC1qaXNzaGlmdF9qaXNpc28taXItMTAwaXNvODg1OS0xMGlzby1pci0xMTBnYl8yMzEyLTgwaXNvLTg4NTktMWlzb184ODU5LTFpc28taXItMTAxaXNvODg1OS0xMWlzby04ODU5LTJpc29fODg1OS0yaHotZ2ItMjMxMmlzby04ODU5LTNpc29fODg1OS0zaXNvODg1OS0xM2lzby04ODU5LTRpc29fODg1OS00aXNvODg1OS0xNGlzby1pci0xNDRpc28tODg1OS01aXNvXzg4NTktNWlzbzg4NTktMTVpc28tODg1OS02aXNvXzg4NTktNmlzby1pci0xMjZpc28tODg1OS03aXNvXzg4NTktN2lzby1pci0xMjdpc28taXItMTU3aXNvLTg4NTktOGlzb184ODU5LThpc28taXItMTM4aXNvLWlyLTE0OGlzby04ODU5LTlpc29fODg1OS05aXNvLWlyLTEwOWlzby1pci0xNDliaWc1LWhrc2NzY3NzaGlmdGppc2lzby04ODU5LTEwaXNvLTg4NTktMTFjc2lzb2xhdGluMWNzaXNvbGF0aW4yaXNvLTg4NTktMTNjc2lzb2xhdGluM2lzby04ODU5LTE0d2luZG93cy04NzRjc2lzb2xhdGluNGlzby04ODU5LTE1aXNvXzg4NTktMTVjc2lzb2xhdGluNWlzby04ODU5LTE2Y3Npc29sYXRpbjZ3aW5kb3dzLTk0OWNzaXNvbGF0aW45Y3Npc284ODU5NmVjc2lzbzg4NTk4ZXVuaWNvZGVmZmZldW5pY29kZWZlZmZjc21hY2ludG9zaGNzaXNvODg1OTZpY3Npc284ODU5OGl3aW5kb3dzLTMxangtbWFjLXJvbWFuaXNvLTIwMjItY25pc28tMjAyMi1qcGNzaXNvMjAyMmpwaXNvLTIwMjIta3Jjc2lzbzIwMjJrcnJlcGxhY2VtZW50d2luZG93cy0xMjUwd2luZG93cy0xMjUxd2luZG93cy0xMjUyd2luZG93cy0xMjUzd2luZG93cy0xMjU0d2luZG93cy0xMjU1d2luZG93cy0xMjU2d2luZG93cy0xMjU3d2luZG93cy0xMjU4aXNvLTg4NTktNi1laXNvLTg4NTktOC1laXNvLTg4NTktNi1paXNvLTg4NTktOC1pc3VuX2V1X2dyZWVrY3Nrc2M1NjAxMTk4N3VuaWNvZGUyMHV0Zjh1bmljb2RlMTF1dGY4a3NfY181NjAxLTE5ODdhbnNpX3gzLjQtMTk2OGtzX2NfNTYwMS0xOTg5eC1tYWMtY3lyaWxsaWN4LXVzZXItZGVmaW5lZGNzaXNvNThnYjIzMTI4MGlzby0xMDY0Ni11Y3MtMmlzb184ODU5LTE6MTk4N2lzb184ODU5LTI6MTk4N2lzb184ODU5LTY6MTk4N2lzb184ODU5LTc6MTk4N2lzb184ODU5LTM6MTk4OGlzb184ODU5LTQ6MTk4OGlzb184ODU5LTU6MTk4OGlzb184ODU5LTg6MTk4OHgtdW5pY29kZTIwdXRmOGlzb184ODU5LTk6MTk4OWNzaXNvbGF0aW5ncmVla3gtbWFjLXVrcmFpbmlhbmlzby0yMDIyLWNuLWV4dGNzaXNvbGF0aW5hcmFiaWNjc2lzb2xhdGluaGVicmV3dW5pY29kZS0xLTEtdXRmLThjc2lzb2xhdGluY3lyaWxsaWNjc2V1Y3BrZGZtdGphcGFuZXNlAAAAgLgSAAIAAACCuBIAAgAAAIS4EgACAAAAhrgSAAIAAACIuBIAAgAAAIq4EgACAAAAjLgSAAIAAACOuBIAAwAAAJG4EgADAAAAlLgSAAMAAACXuBIAAwAAAJq4EgAEAAAAnrgSAAQAAACiuBIABAAAAKa4EgAEAAAAqrgSAAUAAACvuBIABQAAALS4EgAFAAAAubgSAAUAAAC+uBIABQAAAMO4EgAFAAAAyLgSAAUAAADNuBIABQAAANK4EgAGAAAA2LgSAAYAAADeuBIABgAAAOS4EgAGAAAA6rgSAAYAAADwuBIABgAAAPa4EgAGAAAA/LgSAAYAAAACuRIABgAAAAi5EgAGAAAA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lQKWApsCogKkAqsCrAKwArMCvQLAAsMCxALFAskCygLNAs4C1ALYAuMC6wLuAvIC8wL3AvgC/AL9Av8CAQMCAwQDBwMKAxQDFgMXAxgDGQMaAx0DHgMfAyEDIgMjAyQDJQMmAygDKQMqAysDLwMxAzIDNAM1AzwDPgM/A0EDQgNEA0UDRgNKA1EDVQNYA1kDXgNhA2MDZANlA2gDagNrA2wDbQNwA3EDcgNzA3QDdQN4A3kDegN8A30DfgN/A4EDggODA4QDhgOIA4kDigOOA48DkAOVA5YDlwOYA6ADoQOjA6UDpgOnA6gDrAOtA64DrwOxA7IDtwO4A7kDugO7A74DwAPBA8IDwwPEA8YDxwPIA8kDzgPQA9MD2QPaA9sD3APgA+ED5gPoA+4D8gPzA/UD9wP4A/kD+gP9AwEEAgQDBAQEBQQHBAwEEAQVBBkEGwQdBB4EJAQmBCcEKAQqBC0ELgQwBDMENQQ2BD0ERgRHBEgESQRKBEsETARRBFQEVgRZBFoEXwRgBGEEYgRjBGQEZgRoBGkEagRvBHAEdgR4BHkEgQSDBIUEiASKBI4EkQSSBJMElQSWBJkEpQSqBKwErgSzBLQEtwS7BL8EwwTLBNIE1QTkBO8E9gT6BAcFEAUSBRQFFQUWBRwFHQUfBSEFJAUmBSkFKgUrBTwFPgVBBUUFRgVIBU0FTwVQBVEFVQVXBVgFXQVfBWEFYgVjBWQFZQVoBWoFbQVyBXYFewWCBYYFhwWIBYkFigWNBY4FkQWaBaEFowWlBaYFqAWqBasFrgW2BbcFuwW+BcAFwgXDBcYFyQXKBc0F0AXTBdcF2AXaBd8F5AXoBfYF/QUABgIGBQYKBhAGFQYmBicGKAYpBiwGNAY5BjwGRAZWBloGXQZoBmsGeQZ/BoAGgQaDBoUGhwaPBpAGkgaXBpgGnAaeBp8GoQalBqYGpwaoBqkGqwatBq4GsgazBrUGtga4BrkGuwa8BsEGwgbEBtEG0gbTBtYG2QbaBtsG3QbhBuMG5AboBuwG7gbwBvIG+Ab5BvsGAgcFBwkHCwcMBw0HEgcTBxUHGAckByUHKAcpByoHLAcwBzEHNQc4BzoHPAc9B0AHRwdIB0kHTgdRB1YHWAdiB2YHbQdxB3MHfAd+B4IHlAebB6kHsAexB7MHuAe6B8AHwgfHB8gHyQfKB80H0AfRB9MH1QfWB9sH8gf+BxgIGQgbCCMIMggzCDQINQg3CDkIOgg9CD4IPwhDCEUIRwhICEkISghMCE8IUAhRCFIIVQhZCFsIXAhfCGEIYghmCGkIaghzCHQIdgh4CH0IfgiFCIcIiAiKCIsIjQiRCJIIlAiVCJYIlwibCJwInQihCKUIpwiqCKwIrgiwCLMItgi6CLsIvAi9CMQIxQjMCNAI0QjWCNkI2wjdCN4I4wjoCOkI7AjtCO4I7wjzCPQI9Qj3CP0IAwkJCRAJEgkTCRQJFgkYCSIJKAkqCTAJNQk2CToJPAlBCUIJQwlGCUsJUwlbCV0JaAlqCWsJdgl3CXkJfQmKCaAJowm8CckJ0AndCd4J4AniCeMJ5QnmCegJ7QnvCfAJ8Qn0CfYJ+An5CQEKBgoICg0KDwoTChQKGgohCiYKKAoqCjkKOgo7CjwKPQpACkEKQwpGCkcKSApJCkoKTgpTClgKWQpdCmcKbQpvCnMKfwqACokKigqMCo8KkgqTCpYKlwqYCpkKmgqcCp8KowqkCqYKpwqoCq8KsAqzCsIKwwrECsgKywrMCs0KzwrQCtIK0wrWCtcK2ArbCtwK3QrgCuEK4wrkCuYK6grwCvEK8wr5CvoK/goDCwULBwsICwsLDgsQCxILFAsWCxcLGQscCx4LIAshCyQLJgsoCykLKwssCy4LMQs0CzkLPgtAC0ELSAtJC0sLTAtOC1ELUwtXC1kLWgtcC14LXwtgC2MLZwtpC20LbgtvC3ILcwt0C3YLeAt5C3sLfAt9C34LgQuDC4sLjguTC5YLmAuZC5oLmwugC6ELowukC6YLqwuvC7ALswu4C7wLwAvCC8MLxgvZC+EL4gvjC+QL5gvpC/AL9Av4C/8LAwwEDBcMGQweDCYMLwwxDDsMQQxEDEkMSgxPDFAMYQxvDHgMfgx/DIAMggyDDIYMhwyIDIwMjQyODJIMlAyZDJoMnQyeDKAMowylDKwMrgyvDLEMswy1DLcMuAy7DL8MxQzGDMcMygzLDM0MzwzTDNYM2QzaDNsM3QzeDN8M4AzhDOIM5AzmDOcM6QzqDOsM7AzwDPEM9Qz5DPsM/wwCDQMNBQ0GDQkNCw0RDRMNFw0YDRoNGw0fDScNKA0rDSwNLw0xDTUNNw07DTwNQA1BDUINQw1GDUcNTg1PDVANUQ1SDVMNVQ1XDVgNWQ1aDV8N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L1A7UD1QP1BEUElQTVBQUFZQW1BdUGZQbVB4UHxQgVCGUIlQjlCkUKZQqlCtULNQvFDQUNdQ21DoUO9Q9FD2UPxQCFEMURNRIlFCUUdRSlFMUU5RUlFXUVtRXVFjUWZRaVFvUXJRelF+UYNRhlGKUY5Rk1GYUZpRnVGhUaNRplGtUbRRuFG+UcFRxVHIUcpRzVHQUdJR3FHeUeJR5VHsUe5R8VH0UfdR/lEEUglSC1IPUhNSHFIeUiFSJVIqUixSL1IxUjRSPFI+UkRSS1JOUlJSVVJXUl1SX1JiUmZSaFJrUnBSc1J+UoBSg1KJUpFSlFKcUqRSrlK0UsBSxFLIUspSzFLRUtNS11LZUuBS5VLxUvtSAVMHUwlTDlMRUxhTG1MeUyJTJFMnUytTL1M8U0BTQlNEU0ZTS1NQU1RTWFNbU11TZVNoU2pTbFNyU3ZTeVN7U4BTg1OHU4pTjlOWU5lTm1OeU6BTpFOnU6pTr1O3U7xTwFPDU85T0lPVU9pT3FPhU+dT9FP6U/5TAlQFVAdUC1QUVBhUHFQiVCRUKlQwVDNUNlQ6VD1UP1RBVERUR1RJVExUUVRaVF1UY1RlVGdUaVR0VHlUflSBVINUhVSHVI1UkVSTVJdUnFSeVKVUrlSwVLJUtVS5VLxUvlTDVMVUylTWVNhU21TgVOtU71T0VPtU/lQAVQJVCFUKVRJVFVUcVSFVJVUoVStVLVUyVTRVOFU9VUBVQlVFVUdVS1VRVVdVXVViVWhVa1VvVXlVfVV/VYVVjFWQVZJVlVWaVZ5VoFWoVbJVtFW2VbhVulW8Vb9VxlXKVc5V1VXXVd5V4FXiVedV6VXtVfBV9FX2VfhV/1UCVgpWDVYQVhlWHFYgViVWKFYuVjNWNVY3VjpWPFZAVk9WVVZaVl1WY1ZlVm1WclZ3Vn1Wh1aQVpRWpFawVrhWvVbLVtVW2FbcVuNW5VbsVu5W8lb2VvtWAFcFVwdXC1cdVyBXJFcrVzFXNFc8Vz9XQVdDV0hXS1dSV1hXYldlV2dXbFduV3BXdFd4V31Xh1eNV5RXnFelV6hXqlesV69Xs1e1V7lXxFfMV9BX01fWV9tX3lfhV+VX7lfwV/VX+1f+VwFYA1gIWAxYDlgSWBZYGlgfWCJYJVgrWDFYNlhFWE5YUlhVWFlYX1hmWG1Yf1iCWIRYhliKWJRYm1igWKpYvVjCWMZY0ljWWOVY7VjvWPFY9Fj3WPpYA1kFWQhZDlkQWRdZG1kdWSBZJlkoWSxZMFkyWTVZO1k9WUNZRVlKWUxZUFlSWVlZW1lhWWNZZll1WXdZell+WYVZiVmLWY5ZlFmYWZpZn1mmWaxZsFmzWbpZvFm/WcdZzFnVWdlZ21neWeRZ5lnpWe1Z+ln8WQBaAloKWg1aEloUWhlaHVohWiRaJloqWjNaNVo3Wj1aQVpHWktaVlpbWmNaaFprWnhae1qAWpNanFqrWrRatlq5Wr9aw1rKWs1a01rVWtda2VrdWuJa5FrnWupa7FryWgpbGFszWzVbOFtBW1JbVlteW2BbZ1trW21bclt0W3Zbe1t+W4JbhluKW41bkFuUW5Zbn1unW6xbsVu3W7pbwFvDW8hbzVvRW9Rb4FviW+Zb6VvvW/Fb/VsAXAJcBVwHXAtcEFwSXBdcGVwbXB5cI1wmXChcLVwyXDVcQ1xGXExcUlxWXFpcX1xiXGRcZ1xwXHJce1yAXINciVyOXJJclVydXKRcqlyuXLJctFy2XLlcvlzAXMJcxVzMXNNc2lziXOdc6VzrXO5c8Vz8XARdCF0PXRVdF10cXR9dJV0oXSpdL101XT9dSF1NXVldXF1eXWpdbV1wXXVdg12aXZ5duF3GXc5d3F3fXeNd6l3sXfBd9V34Xf9dBF4HXgleDV4SXhdeHl4oXi9eMl45Xj5eQ15GXk1eVl5cXl9eY151XndeeV5+XoFehV6IXoxekl6YXptenV6hXqherl60Xrpev17LXtRe117cXule6171Xvhe+14FXwlfDF8QXxJfFF8WXxlfHF8hXyhfK18uXzBfMl87Xz1fQV9RX1RfWV9eX2NfZV9nX2tfbl9yX3RfeF96X31fg1+GX41fkV+TX5Zfml+dX6JfqV+rX69ftl+4X75fx1/KX85f01/aX95f4l/lX+hf7F/vX/Jf9l/5X/xfB2ALYBBgE2AXYBpgHmAiYCxgMGA2YD1gQGBEYExgTmBRYFNgVmBbYF5gZWBuYHFgdGB3YH5ggGCFYIpgjmCTYJVgl2CcYJ5goWCkYKdgqWCuYLBgs2C1YLlgvWDHYMxg0mDWYNlg22DeYOFg6mDxYPVg92D7YAJhB2EKYRBhFmEbYSFhJWEoYSxhQGFJYUthTWFPYVJhVmFeYWNhaWFxYXZheGGMYY9hlWGeYaphrWG4Yb9hw2HJYcxh02HVYedh9mEAYgdiCWITYhliHGIgYiNiJmIrYi1iL2I1YjhiQmJEYkpiT2JVYlliXGJkYmhicWJ0YndiemJ9YoFihWKLYpRimWKcYqNipmKpYq1ismK2YrpivmLAYsNiy2LPYtFi1WLdYuBi5GLqYvBi8mL1YvhiAGMDYwpjD2MSYxdjHGMmYyljLGMwYzNjO2M+Y0RjR2NKY1FjVmNgY2RjaGNqY29jcmN4Y3xjgWODY4tjjWORY5Njl2OZY6FjpGOmY6tjr2OxY7VjuWO7Y71jv2PFY8djymPRY9Nj12PfY+Jj5GPrY+5j82P1Y/dj+WP+YwNkBmQNZBFkFWQdZB9kImQnZCtkLmQ1ZDtkPmRAZEJkSWRLZFNkVWRZZF9kaGRqZG5ke2SDZIZkiGSTZJdkmmSfZKVkqmSvZLFktmS5ZLtkvWTBZMNkxmTPZNFk02TZZN9k42TlZOdkAWUKZRNlGWUmZSxlMGU3ZTplPGVAZUZlSmVNZVBlUmVXZVplXGVfZWRlZ2VtZXFlc2V1ZXhliGWNZZJllGWYZZplnWWgZaJlpmWoZaplrGWuZbFlumW+ZcJlx2XNZdBl02XYZeFl42XqZfJl+GX7ZQFmBGYHZgtmDWYQZhZmGmYeZiFmJmYpZi5mMGYyZjdmPWY/ZkJmRGZNZlBmWGZbZmBmYmZlZmdmaWZxZnVmeGZ7Zn9mg2aFZohmjWaSZphmnmapZq9mtWa6Zr9m2mbeZudm6mbxZvVm+Gb6Zv1mAWcMZw5nEWcWZxhnHGceZyBnJ2cpZy5nMGcyZzZnO2c+Z0FnRGdHZ0pnTWdSZ1RnV2ddZ2JnZmdrZ25ncWd0Z3ZneGd9Z4BngmeFZ4hnimeMZ5FnlmeZZ5tnn2ekZ6ZnqWesZ65nsWe0Z7lnwmfFZ9Vn22ffZ+Fn42fmZ+pn7WfyZ/Vn/mcBaAZoDWgQaBJoFGgYaB5oImgraDRoOmg/aEdoS2hNaE9oUmhWaGpobGh1aHhogmiEaIdokGiUaJhoo2ipaK5osWi0aLZowWjDaMpozGjOaNNo1mjZaNto4WjkaO9o8mj2aPto/WgCaQZpDGkPaRFpE2khaSVpLmkxaTVpOmk+aUBpQ2lVaVhpW2lfaWFpZGlnaWxpb2lyaXppfWmBaYNphWmKaY5plmmZaZ1pqWmsaa5psmm1abhpvGnCactpzWnPadFp1WncaeFp7mnzaf5pAGoLahlqIGoiailqK2owajJqNmo/akVqSGpRalpqXGpiamZqcmp6an1qgWqFao9qkmqYaqFqqmqtaiVrKGszazhrO2s/a0RrSGtKa01rWmtoa2tremt9a4VriGuMa45rlGuXa5xromura7ZruGvAa8NrxmvMa85r0GvYa9pr3Gvia+xr8Gv0a/Zr+mv+awhsDmwSbBdsHGwgbCNsJWwrbDFsM2w2bDlsPmxDbEhsS2xRbFZsWGxibGVsa2xxbHNsdWx3bHpsf2yEbIdsimyNbJFslWyabJxsoGyibKhsrGyvbLRsumzAbMZsy2zNbNFs2GzcbN9s5GzmbOls7GzybPRs+Wz/bAJtBW0IbQ1tD20TbRhtHG0fbSZtKG0sbS9tNG02bTptP21CbURtSW1MbVBtVW1bbV1tX21hbWRtZ21rbXBtdW15bX1tg22GbYptjW2PbZJtlm2cbaJtpW2sbbBts222bbltwW3Ibc1t0m3Xbdpt323ibeVt523tbe9t8m30bfht+m39bQZuC24PbhJuFW4YbhtuHm4ibiZuKm4sbi5uMG4zbjVuOW47bkVuT25VblduWW5cbmBubG5vboBuhG6HbopukW6Zbp1uoG6jbqZuqG6rbrBus261brhuvG6+bsNuyG7MbtBu0m7Wbthu227jbudu6m71bvpuA28HbwpvEG8WbyFvJW8sby5vMG8ybzRvN28/b0hvTG9Ob1lvXW9fb2NvZ29vb3NvdW95b3tvfW+Fb4pvj2+db6JvqG+0b7dvum/Bb8Nvym/Tb99v4m/wbxJwHHAkcDZwOnBNcFBwX3BucHFwd3B5cH1wgXCGcItwj3CTcJdwmnCecLBwsnC0cLpwvnDEcMlwy3DacNxw4HDlcOpw7nDwcPhw+nD+cAtxEXEUcRdxG3EncTJxN3FGcUtxTXFPcV1xX3FlcWlxb3F0cXlxe3F+cYVxi3GQcZVxmnGhcalxrXG0cbZxunHEcc9x1nHhceZx6HHvcfpxB3IecilyK3ItcjJyOnI8cj5yQHJJck5yU3JXclpyXHJecmByY3JocmpycHJzcnZye3KCcoVyjHKOcpByk3Kgcq5ysXK1crpyxXLJcs9y0XLTcthy2nIAAAIAAwAJAAsADQAOABIAEwAZABwAIAAhACQAJgAoACsALAAuADAAMgA2AEMARQBGAEoAUgBdAF4AbABxAHMAdAB1AHcAeQB9AIEAhACGAIwAjQCPAJAAkwCVAJkAmgCfAKEAogCpAK0ArgCyALMAtAC3ALsAywDMAM4A0gDbAOEA4wDkAOUA5gDnAOgA6gDvAPMABgEHAQgBCQEWARgBHQEjASQBJQEoASsBLQEuATkBOgFCAVIBaQFyAXMBdAF1AXYBfQGBAYIBiQGNAZUBlgGXAZgBnAGdAZ8BpAGmAacBqAGpAaoBqwGtAa4BsgG0AbYBtwG7Ab8BxwHKAdEB0gHVAdoB3QHfAeMB5gHnAegB6QHqAewB7QHuAfMB9AH2AfgB+wH8Af4BAgIDAgQCBgIIAgsCDAINAhECEwIXAhkCGwIcAh0CIQIiAiUCKQIqAisCLgIvAjACMgIzAjUCNwI5AjwCPQI/AkcCTQJOAlMCVAJYAl8CYgJqAmwCbQJwAnECcgJ0AnYCeAJ5AnsCfQKHApACkgKTAp0CnwKhAqICowKlAqYCpwKpAqwCsQK5AroCuwK+AsACwQLDAsUCxwLIAskC1ALYAtkC3ALdAuAC4QLmAucC6ALrAuwC7wL3Av8CBAMFAwYDCAMUAxcDGgMgAyIDLgMvAzEDMgMzAzQDNwM5AzoDPwNAA0EDTgNXA1oDXwNgA2EDYgNjA2cDaQNqA24DdAN2A3kDegN7A3wDfQN+A4EDggODA4UDhwOKA4wDjQOOA5IDkwOXA5gDmQOaA5wDoQOtA7UDuQPDA8QDxgPIA8kDzAPNA88D0APRA9ID0wPbA98D4wPlA+gD6wPvA/ID9QMDBAYECwQMBA4EEAQWBBkEJgQwBDUERARJBEoESwRPBFAEWQRbBF0EXgRgBGEEZQRmBG0EbgRzBHUEeQR9BIcEkwSeBKMEpASlBKYEqASqBKsErASvBLEEswS5BLwEvQS+BL8EwATBBMgEygTLBM0EzgTQBNQE1QTaBNwE3gThBOIE5ATzBPYE9wT4BPkE/wQJBQ4FJgUpBSoFLgUvBTAFMQU1BTgFOgU9BT4FQgVDBUYFSwVWBWEFawVtBXEFcwV0BXoFewWEBYYFhwWKBYsFjAWNBZAFkQWTBZYFlwWZBZoFnQWeBZ8FoAWiBaMFpwWoBakFqgWwBbEFsgWzBbUFtgW3BbgFuQW6BbwFvQXIBcoFzAXNBc4FzwXRBdIF1gXdBd8F4gXjBecF6gXtBfAF8gX1Bf0FAQYFBgkGCgYPBhEGFAYXBhoGHQYfBiQGKAYpBjEGNAY2BjwGRAZKBkwGWQZfBmoGjwaVBqAGpwapBqoGrQavBrAGtAa3BrkGvgbABsIGxQbGBscGyAbPBtAG0gbUBtsG4QbpBusG+QYOBw8HEwcWBxkHVwdfB40HlAcgCCUIKghkCHwIfwiACIEIgwiECIUIhgiHCIgIiQiKCIsIjAiTCJQIngigCKEIogimCKcIrAivCLEIsgi2CLoIvAjECMUIxgjLCNAI0gjTCNUI1wjeCN8I5AjmCOcI6AjrCO8I8AjxCPYI+Aj+CAEJAwkHCQgJCQkQCRMJFAkYCRoJGwkcCR4JIQkiCSQJKgkrCSwJLgkvCTAJMgk0CTcJOwk8CT8JQAlOCVQJYQljCWQJZQlmCWwJbglvCXAJcQlyCXUJdgl3CXgJegl8CX0JfgmDCYoJiwmNCY8JkAmRCZIJkwmUCZUJmQmcCZ4JoAmhCaIJowmmCbMJtQm2CbkJugm/CcYJxwnICcsJzAnPCdQJ2AnZCdoJ3QneCeAJ5AnlCeoJ6wnvCfAJ9gn4Cf0J/wkACgEKCQoPChMKFQoYChkKLwoyCjQKNQo6CkAKQQpCCkMKSApKCksKTApSClMKVApYClkKWgpbClwKXgpjCmUKZgpnCmoKcgpzCncKfwqECoUKiQqLCo0KjgqRCpIKkwqUCpgKmgqbCpwKngqfCqAKogqlCqcKqQqrCqwKrQquCrAKsQqyCrYKuQq6CrwKvgq/CsAKxQrHCsgKyQrLCswKzgrYCtoK2wrcCt0K3grfCuIK5ArmCucK7ArtCvIK8wr0CvsK/QoECwYLCgsNCxELEwsUCxULHAsgCyELIgskCycLKAsqCysLLQsxCzILMws2CzcLOgs9C0ILRwtKC00LTgtPC1MLVAtaC10LYwtrC3ELdAt8C4YLiwuMC5ALkQuWC5cLmgubC5wLnQueC6ULqQuqC6sLswu0C7YLugvHC8kLygvNC88L0AvRC9ML1wvZC9sL3AveC+QL5QvnC+gL7QvwC/sL/QsJDA0MDgwRDBMMFwwYDCEMKwwwDDQMPwxBDEUMSgxNDFYMVwxbDF0MYgxjDGoMdQx8DH8MgAyDDIkMigyRDJgMnQyfDKAMpgytDLEMwgzFDMoM1QzZDOkM6gz4DPsMCw0NDRINFQ0YDSANIQ0jDSoNMQ02DTcNPQ1CDUQNRQ1HDUkNTA1RDVQNVQ1WDVgNWg1dDV4NYA1kDWgNaw1sDW8Ncw10DXUNeA16DX4Nfw2ADYENgg2DDYUNhg2JDY0Njw2RDZMNlg2YDZ8NoQ2iDaYNqQ2qDbANsg26DbsNvg2/DcMNxg3HDckNyw3MDdEN1A3bDeMN5Q3mDekN6g3uDfAN8g33DfoN/w0GDgoODg4SDhUOHw4jDicOLQ41DjYOOg4/Dk4OVA5WDlkOXA5iDmgOag5rDnIOdA51DnYOdw54DnwOgQ6CDoMOhQ6HDogOjA6PDpQOmQ6aDqAOoQ6kDqkOrQ6xDrMOtQ65DrwOvQ6/DsQOxg7IDs8O0A7TDtUO1g7ZDuAO5Q7mDusO8A7zDvcO+w7+Dv8OCQ8LDyQPKg8+D0EPQg9DD0UPfw+AD4EPhA+HD4gPiQ+ND44Pkg+VD5gPpA+qD+AP6Q8ZECgQMBCjEMEQABEFETgRORE6ETsRPBE9ET4RPxFAEUkRTRFOEVARWBFcEWIRaRFwEXQRexF9EYARgRGIEYsRDxIQEhISExIUEhUSGBIZEhsSHRImEigSLBIxEjMSPRJAEk0SThJQElESUhJTElYSVxJbElwSXRJhEmMSZBJnEmoSaxJtEnAScRJyEnMSehJ9En4SgBKEEowSjhKTEpQSlRKWEpkSnBKeEqASoRKjEqgSrhK6ErwSvhK/EsASwRLCEscSyRLKEs0SzhLVEtgS3xLgEuwS7hLwEvcSChOhE6IToxOkE6UTphOpE60TrhOyE7YTuBO7E70TvhO/E8QTxRPGE8gTyRPLE8wTzRPOE88T0RPUE9cT2RPbE9wT3RPeE98T4RPiE+UT6xPwE/ET8xP0E/YT9xP5E/4T/xMCFAQUChQLFA0UERQWFB0UHhQfFCMUJRQqFCsULBQtFC4ULxQwFDMUNRQ4FDkUOhQ7FDwUPhRAFEIUQxRFFEgUSRRMFE8UUhRVFFcUWBRZFF0UYBRkFGcUaBR8FIAUgxSOFI8UlhSfFKEUoxSkFKgUqhSsFK4UsRSyFLMUtBS3FLwUvRS+FL8UwRTIFM4U1BTWFNoU3hTqFOsU7BTtFPcUjhWnFcYV3xVUFn8WoxbdFugWTxd7F5QXlReWF5cXmBeZF5sXnBedF54XnxegF6EXohejF6QXpRemF6cXqBepF6oXrBe0FxwYHRgeGB8YIBghGCIYIxgkGCsYLhgwGDQYNRg2GDcYOBg6GD0YQhhFGEYYRxhJGEoYTxhQGF0YXhhgGGEYYhhlGGcYaRhzGHsYfRh/GIEYgxiEGIYYhxiJGIsYjRiXGJ4YohilGKcYqBisGK0YrxiwGLMYthi4GL0YvhjJGMsYzRjOGNMY1xjqGOwY7hjvGPEY8hj0GPcYABkBGQYZDhkTGRQZFxkYGRsZIhkkGSsZLBktGS8ZMBlhGWIZZxloGeYZ5xnoGekZ6hnrGewZEhoUGhUaFxoaGiEaRRpHGmQaiRqWGpcamBqZGpsanBqdGp8aoBqhGqIarRqvGnIbcxt0G3Ubdxt5G3obexuCG4YbhxuIG4sbjRuSG5YblxubG6EbohumG6obqxusG7Ubthu9G8EbxxvKG9Ub2BvjG+Ub7RvxG/Ib9Rv2G/cb+RsgHSIdIx0lHScdKB0pHSodLh0vHTAdMR0yHTMdOB06HTwdPh1AHXwefR5+Hn8egB6BHoMehB6FHoYeiR6KHosejB6QHpEekx6UHp4eoB6kHqYerB61HrYevB7JHswezh7PHtQe2B7bHtwe3h7hHuMe5B7lHuce6B7pHu0e9h73HvgeBB8FHwYfCB8LHwwfEh8THxwfHh8lHyYfJx8oHy0fOB9lH2cfcx92H9xy33Licupy9XL5cv1yAnMEcwtzD3MUcxhzH3MjcyZzLXMvczJzNXM6c0BzTnNRc1NzWHNhc25zcHN/c4VziHOKc4xzj3OSc5dznHOgc6NzqnOsc7FztHO4c7xzwXPDc8tzznPSc9pz33Phc+Zz6HPqc+5z83MEdAd0C3QRdBx0I3QndCl0K3QtdC90MXQ3dD10QnRWdFh0XXRgdG50cXR4dH90gnSEdIh0jHSPdJF0nXSfdKp0u3TTdN1033ThdOV053TwdPV0+HQAdQV1DnUQdRJ1FHUbdR11IHUmdSp1LnU0dTZ1OXU8dT91QXVGdUl1TXVQdVV1XXVndWt1c3V1dXp1gHWEdYd1jHWQdZN1lXWYdZt1nnWidaZ1rXW2dbp1v3XGdct1znXTddd12XXcdd915XXpdex18nX1dfp1/XUCdgR2BnYLdg12EXYWdhp2HHYhdiN2J3Ysdi52MXY2djl2PXZBdkR2TnZVdld2XXZfdmR2bHZwdnl2fHZ/doN2hXaJdox2j3aSdpR2l3aadqV2r3azdrV2wHbDdsd2yXbLdtN21XbZdtx24HbmdvB283b1dvp2/Xb/dgJ3BXcKdwx3DncbdyF3I3cndyp3Lncwdzl3O3c9d0J3RHdId1J3XHdkd2d3aXdtd3p3gXeGd493k3ehd6N3pneod6t3rXexd7R3tne8d753wHfOd9h33Xfkd+Z36Hfqd+939Hf3d/l3A3gKeA54E3gVeBl4G3geeCB4JHgoeCp4LngxeDV4PXg/eEF4RnhIeE14T3hReFN4WHheeG94eHh9eIh4iniPeJJ4lHiZeJ14oHiieKR4pnioeLV4uni/eMJ4xnjMeNF41njaeOl47XjzePV4+Hj7eAJ5BnkUeR95JXk1eT15P3lCeUd5SnlUeVh5YXljeWZ5aXlueXB5eXl7eYJ5hnmLeZB5m3moebR5vHm/ecJ5xHnHecp5zHnOedN51nnZeeB55Xnoeep57HnuefF5+Xn8ef55AXoEegd6DHoPehV6GHobeh96IXokejR6OHo6ej56QHpHelJ6WHpxenV6e3qCeoV6h3qJeo56k3qZep56oXqneql6rnq0esB6zHrXetp64Xrkeud67nrwevt6/noAewV7B3sJewx7EHsSexZ7Gnscex97IXsneyl7LXsvezJ7NHs5ezt7PXs/e0Z7SHtKe017U3tVe1d7WXtce157YXtje297c3t2e3h7ent8e397gXuGe457kXuWe5h7nnuje657snu1e7l7wnvIe8170nvUe9t73nvie+d763vve/J7+Hv9e/97CHwNfBB8F3wgfCh8K3w5fEJ8Tnx1fH58inyTfJZ8mXygfKN8pnyrfK98tHy6fL98wnzGfMl8y3zOfNh82nzdfOF86XzwfPl8/HwLfSF9I30ofSx9MH1vfXh9p32vfTx+Qn5IfoN+nH6ufrR+u37WfuR+7H75fgp/EH8efzd/OX87f0N/Rn9Sf1Z/WX9bf2B/Y39rf29/c391f3p/f3+Cf4t/jX+Pf5V/m3+gf6J/pX+of7F/s3+6f75/wH/Cf8Z/y3/Nf89/1n/Zf+J/53/qf+9/8n/0f/1/AoAHgA6AEYATgBqAHYAhgCOAK4AygDSAOYA8gD6AQIBEgEeAToBTgFWAWYBbgGuAcoCBgIWAiICKgI2AlICXgJmAnoCjgKaArICwgLOAtYC4gLuAxYDHgM+A2IDfgOKA5oDugPWA94D5gPuA/oADgQeBC4EVgReBGYEbgR+BLYEwgTOBN4E5gT+BR4FJgU2BUoFWgVuBYYFmgWiBaoFvgXKBdYGBgYOBiYGLgZCBkoGZgZ6BpIGngamBq4G0gbyBxIHHgcuBzYHkgeiB64HugfWB/YH/gQOCB4IOghGCE4IVgh2CIIIkgimCLoIygjqCPII/gkWCSIJKgkyCUIJZgluCYIJpgnGCdYJ7goCCg4KFgomCjIKQgpOCmoKegqCCooKngrKCtYK6gr+CwoLFgsmC0ILWgtmC3YLigueC7ILwgvKC9YL4gvqC/IIKgw2DEIMSgxaDGIMdgymDLoMwgzKDN4M7gz2DQYNEg0iDSoNTg1WDXYNig3CDeYN+g4eDioOPg5SDmYOdg5+DoYOsg7WDu4O+g8KDxoPIg8uDzYPQg9WD14PZg96D4oPmg+uD84P6g/6DAoQFhAeEEIQShBmEHoQphDKEOYQ+hEeEUoRYhF2EYoRkhGqEboRyhHSEd4R5hHuEg4SKhI2Ej4SYhJqEnYSihLCEs4S1hLuEvoTAhMKExYTLhM6E0oTUhNeE3oThhOSE54TthPGE/YQAhQ2FEoUUhRiFG4UghSKFLYU+hUSFS4VXhVqFX4VlhWmFc4V1hXyFf4WGhYiFkIWdhaWFqYWrhbGFuIW6hcKFyoXRhdSF1oXdheWF6oX8hQCGBoYShheGKIYqhjmGPYZShlWGW4ZfhmOGbYZvhnKGg4aOhpSGloaehqWGq4athrKGt4a7hsGGxYbIhsyG0obVhtqG3IbghuWG6obvhvWG+ob/hgGHBIcLhw6HFIcWhxmHG4cdhx+HJIcmhyqHL4cyhzWHOIc8h0CHSodNh0+HVIdYh1qHYYdmh2+HcYd1h3eHf4eEh4aHiYeMh46HlIeYh6CHqYeuh7CHtIe2h7uHvofBh8eHzIfUh9yH4Yfmh+uH74f6h/+HBIgLiBSIF4gciCOIM4g6iD2IQYhGiE6IVYhYiFqIZohqiG2Ib4hxiHOIeIiAiIOIhoiJiIyIjoiTiJeInYijiKWIrIiuiLKIuIi9iMOIx4jKiM+I04jWiNqI4IjmiOmI8oj1iPqI/Yj/iAOJC4kRiRSJHIkiiSaJLIkxiTWJN4lCiUWJYIlniXyJgImCiYSJh4nDic2J04nXiduJ3YnfieSJ54nsifCJ9IkBigiKP4pJinqKi4qUigiLJ4tni22LrIuxi7uLx4vQi+qLCYwejDiMQoxIjEqMTYxWjFuMY4xsjHSMe4yDjIaMi4yNjJWMmYwgjVGNV41fjWWNaI1sjW6NcY14jYKNho2MjZKNlY2gjaSNso22jbmNu429jcCNxY3Hjc2N0I3SjdiN3I3gjeWN6Y3tjfCN9I32jfyN/o0GjguODY4QjhWOII4kjiuOLY4wjjKONo47jj6OQ45FjkyOU45ajmeOao5ujnGOc451jneOfY6AjoKOho6IjpGOlY6djp+OrY6wjrOOu47PjmqPgI+Mj5KPnY+gj6SPqo+sj7KPt4+6j7+Pw4/Gj8mPz4/Sj9aP2o/gj+OP54/sj++P8Y/0j/qP/o8HkAyQDpATkBWQGJAckCOQJ5AwkDeQOZA9kD+QQ5BFkEiQTpBUkFmQXJBkkGaQaZBvkHaQfpCBkISQiZCMkJKQlJCWkJiQmpCckJ6QpJCnkKuQrZCykLeQvJC/kMKQxpDIkMuQ0pDUkNiQ3pDjkOmQ7JDukPCQ9ZD5kP+QA5EFkRqRH5EkkTCRMpE6kUSRR5FRkVORWJFbkV+RZpFrkW2Rc5F6kYCRhpGIkYqRjpGTkZyRpJGrkbCRtpG7kciRy5HQkdKR3ZF1ko+Sr5LJkj+Ta5OQk8uT15M/lGyUkZSWlJiUx5TPlNOU2pTmlPuUHJUglSeVM5U9lUOVSJVLlVWVWpVglW6VdJV3lYCV7JX/lQeWE5YYlhuWHpYgliOWK5YvljeWPpZBlkOWSpZOllGWVpZclmCWY5ZllmuWbZZzlniWh5aJloyWjpaRlpWWmpadlqiWsZa0lreWupa/lsKWyJbKltCW05bWluGW65bwlvSW+Jb6lv+WApcFlwqXEJcUlxeXHZcflyuXLpcxlzOXOpc/l1SXV5dal1yXX5djl2aXapd1l3eXfZeGl4yXjpeTl5WXmZehl6SXrJeul7CXs5e1l+iX7pf0l/eXi5iOmJKYlZiZmKOYqJjPmNSY1pjbmOCY6ZgOmRGZL5lWmWSZZplzmXiZe5l+mYKZiZmMmY6ZmpmmmamZcpqDmomajZqUmpmappqpmrKauZq7mr2aw5rGms2a0prUmtma4Jrimuea7JrumvCa+pr8mgSbCZsQmxSbIJskmzCbM5s9m0abSptOm1CbUptVm32cgJyDnImcjJyPnJOclpydnKqcrJyvnLmcvpzInNGc2pzgnOOcJJ4nni6eMJ40njueQJ5NnlCeUp5WnlmeXZ5fnmWebp5ynnSegJ6DnomejJ6Unp6eoJ6nnrWeuZ68nr+exZ7KntCe0p7Vntme3p7hnuOe5p7onuue8J76nv2e/54Mnw+fEZ8UnxifGp8hnyOfLZ8wnzifOp88nz+fRZ9Sn4GfjZ+cn6GfSlU/lsNXKGPOVAlVwFSRdkx2PIXud36CjXgxcpiWjZcobIlb+k8JY5dmuFz6gEhoroACZs52+VFWZaxx8X+EiLJQZVnKYbNvrYJMY1Ji7VMnVAZ7a1GkdfRd1GLLjXaXimIZgF1XOJdifzhyfXbPZ352RmRwTyWN3GIXepFl7XMsZHNiLIKBmH9nSHJuYsxiNE/jdEpTnlLKfqaQLl6GaJxpgIHRftJoxXiMhlGVjVAkjN6C3oAFUxKJZVKEhfmW3U8hWHGZnVuxYqVitGZ5jI2cBnJvZ5F4smBRUxdTiI/MgB2NoZQNUMhyB1nrYBlxq4hUWe+CLGcoeyld934tdfVsZo74jzyQO5/UaxmRFHt8X6d41oQ9hdVr2WvWawFeh175de2VXWUKX8Vfn4/BWMKBf5Bblq2XuY8WfyyNQWK/T9hTXlOoj6mPq49NkAdoal+YgWiI1pyLYStSKnZsX4xl0m/obr5bSGR1UbBRxGcZTsl5fJmzcMV1dl67c+CDrWToYrWU4mxaU8NSD2TClJR7L08bXjaCFoGKgSRuymxzmlVjXFP6VGWI4FcNTgNeZWs/fOiQFmDmZBxzwYhQZ01iIo1sdymOx5FpX9yDIYUQmcJTlYaLa+1g6GB/cM2CMYLTTqdsz4XNZNl8/Wn5ZkmDlVNWe6dPjFFLbUJcbY7SY8lTLIM2g+VntHg9ZN9blFzuXeeLxmL0Z3qMAGS6Y0mHi5kXjCB/8pSnThCWpJgMZhZzOlcdXDhef5V/UKCAglNeZUV1MVUhUIWNhGKelB1nMlZub+JdNVSScGaPb2KkZKNje1+Ib/SQ44GwjxhcaGbxX4lsSJaBjWyIkWTwec5XWWoQYkhUWE4LeulghG/ai39iHpCLmuR5A1T0dQFjGVNgbN+PG19wmjuAf5+ITzpcZI3Ff6VlvXBFUbJRa4YHXaBbvWJskXR1DI4gegFheXvHTvh+hXcRTu2BHVL6UXFqqFOHjgSVz5bBbmSWWmlAeKhQ13cQZOaJBFnjY91df3o9aSBPOYKYVTJOrnWXemJeil7vlRtSOVSKcHZjJJWCVyVmP2mHkQdV822vfiKIM2LwfrV1KIPBeMyWno9IYfd0zYtkazpSUI0ha2qAcYTxVgZTzk4bTtFRl3yLkQd8w09/juF7nHpnZBRdrFAGgQF2uXzsbeB/UWdYW/hby3iuZBNkqmMrYxmVLWS+j1R7KXZTYidZRlR5a6NQNGImXoZr4043jYuIhV8ukCBgPYDFYjlOVVP4kLhjxoDmZS5sRk/uYOFt3os5X8uGU18hY1pRYYNjaABSY2NIjhJQm1x3efxbMFI7erxgU5DXdrdfl1+EdmyOb3B7dkl7qnfzUZOQJFhOT/Ru6o9MZRt7xHKkbd9/4Vq1YpVeMFeChCx7HV4fXxKQFH+gmIJjx26YeLlweFFbl6tXNXVDTzh1l17mYGBZwG2/a4l4/FPVlstRAVKJYwpUk5QDjMyNOXKfeHaH7Y8NjOBTAU7vdu5TiZR2mA6fLZWaW6KLIk4cTqxRY4TCYahSC2iXT2tgu1EebVxRlmKXZWGWRowXkNh1/ZBjd9JrinLscvuLNVh5d0yNXGdAlZqApl4hbpJZ73rtdzuVtWutZQ5/BlhRUR+W+VupWChUco5mZX+Y5FadlP52QZCHY8ZUGlk6WZtXso41Z/qNNYJBUvBgFVj+huhcRZ7ET52YuYslWnZghFN8Yk+QApF/mWlgDIA/UTOAFFx1mTFtjE4wjdFTWn9PexBPT04AltVs0HPphQZeanX7fwpq/neSlEF+4VHmcM1T1I8DgymNr3JtmdtsSlezgrllqoA/YjKWqFn/Tr+Lun4+ZfKDXpdhVd6YpYAqU/2LIFS6gJ9euGw5jayCWpEpVBtsBlK3fl9XGnF+bIl8S1n9Tv9fJGGqfDBOAVyrZwKH8FwLlc6Yr3X9cCKQr1Edf72LSVnkUVtPJlQrWXdlpIB1W3ZiwmKQj0VeH2wmew9P2E8NZ25tqm2PebGIF18rdZpihY/vT9yRp2UvgVGBnF5QgXSNb1KGiUuNDVmFUNhOHJY2cnmBH43MW6OLRJaHWRp/kFR2Vg5W5Ys5ZYJpmZTWdolucl4YdUZn0Wf/ep2Ado0fYcZ5YmVjjYhRGlKilDh/m4CyfpdcL25gZ9l7i3bYmo+BlH/VfB5kUJU/ekpU5VRMawFkCGI9nvOAmXVyUmmXW4Q8aOSGAZaUluyUKk4EVNl+OWjfjRWA9GaaXrl/wlc/gJdo5V07ZZ9SbWCan5tPrI5sUatbE1/pXV5s8WIhjXFRqZT+Up9s34LXcqJXhGctjR9ZnI/Hg5VUjXswT71sZFvRWROf5FPKhqiaN4yhgEVlfpj6VseWLlLcdFBS4VsCYwKJVk7QYipg+mhzUZhboFHCiaF7hplQf+9gTHAvjUlRf14bkHB0xIktV0V4Ul+fn/qVaI88m+GLeHZCaNxn6o01jT1Sio/abs1oBZXtkP1WnGf5iMePyFS4mmlbd20mbKVOs1uHmmORqGGvkOmXK1S1bdJb/VGKVVV/8H+8ZE1j8WW+YY1gCnFXbElsL1ltZyqC1ViOVmqM62vdkH1ZF4D3U2ltdVSdVXeDz4M4aL55jFRVTwhU0naJjAKWs2y4bWuNEIlknjqNP1bRntV1iF/gcmhg/FSoTipqYYhSYHCPxFTYcHmGP54qbY9bGF+ifolVr080czxUmlMZUA5UfFROTv1fWnT2WGuE4YB0h9ByynxWbidfToYsVaRikk6qbDdisYLXVE5TPnPRbjt1ElIWU92L0GmKXwBg7m1PVyJrr3NTaNiPE39iY6NgJFXqdWKMFXGjbaZbe15Sg0xhxJ76eFeHJ3yHdvBR9mBMcUNmTF5NYA6McHAlY4mPvV9iYNSG3lbBa5RgZ2FJU+BgZmY/jf15Gk/pcEdss4vyi9h+ZIMPZlpaQptRbfdtQYw7bRlPa3C3gxZi0WANlyeNeHn7UT5X+lc6Z3h1PXrveZV7jIBlmfmPwG+liyGe7Fnpfgl/CVSBZ9hokY9NfMaWylMlYL51cmxzU8lap34kY+BRCoHxXd+EgGKAUWNbDk9teUJSuGBObcRbwluhi7CL4mXMX0WWk1nnfqp+CVa3ZzlZc0+2W6BSWoOKmD6NMnW+lEdQPHr3TrZnfprBWnxr0XZaVxZcOnv0lU5xfFGpgHCCeFkEfyeDwGjsZ7F4d3jjYmFjgHvtT2pSz1FQg9tpdJL1jTGNwYkula179k5lUDCCUVJvmRBuhW6nbfpe9VDcWQZcRm1fbIZ1i4RoaFZZsosgU3GRTZZJhRJpAXkmcfaApE7KkEdthJoHWrxWBWTwlOt3pU8ageFy0ol6mTR/3n5/UllldZF/j4OP61OWeu1jpWOGdvh5V4g2lipiq1KCglRocGd3Y2t37XoBbdN+44nQWRJiyYWlgkx1H1DLTqV164tKXP5dS3ukZdGRyk4lbV+JJ30mlcVOKIzbj3OXS2aBedGP7HB4bT1cslJGg2JRDoNbd3ZmuJysTspgvnyzfM9+lU5mi29miJhZl4NYbGVclYRfyXVWl9963nrAUa9wmHrqY3Z6oH6Wc+2XRU54cF1OUpGpU1Fl52X8gQWCjlQxXJp1oJfYYtlyvXVFXHmayoNAXIBU6Xc+Tq5sWoDSYm5j6F13Ud2NHo4vlfFP5VPnYKxwZ1JQY0OeH1omUDd3d1PifoVkK2WJYphjFFA1csmJs1HAi91+R1fMg6eUm1EbVPtcyk/jelpt4ZCPmoBVllRhU69UAF/pY3dp71FoYQpSKljYUk5XDXgLd7ded2HgfFtil2KiTpVwA4D3YuRwYJd3V9uC72f1aNV4l5jRefNYs1TvUzRuS1E7UqJb/ouvgENVpldzYFFXLVR6elBgVFunY6Bi41NjYsdbr2ftVJ965oJ3kZNe5Ig4Wa5XDmPoje+AV1d3e6lP61+9Wz5rIVNQe8JyRmj/dzZ392W1UY9O1Ha/XKV6dYROWUGbgFCImSdhg25kVwZmRmPwVuxiaWLTXhSWg1fJYodVIYdKgaOPZlWxg2VnVo3dhGpaD2jmYu57EZZwUZxvMIz9Y8iJ0mEGf8Jw5W4FdJRp/HLKXs6QF2dqbV5js1JicgGAbE/lWWqR2XCdbdJSUE73lm2VfoXKeC99IVGSV8Jki4B7fOps8WheabdRmFOoaIFyzp7xe/hyu3kTbwZ0TmfMkaScPHmJg1SDD1QXaD1OiVOxUj54hlMpUohQi0/QT+J1y3qSfKVstpabUoN06VTpT1SAsoPej3CVyV4cYJ9tGF5bZTiB/pRLYLxww36ufMlRgWixfG+CJE6Gj8+RfmauTgWMqWRKgNpQl3XOceVbvY9mb4ZOgmRjldZemWUXUsKIyHCjUg5zM3SXZ/d4Fpc0TruQ3pzLbdtRQY0dVM5isnPxg/aWhJ/DlDZPmn/MUXVwdZatXIaY5lPkTpxuCXS0aWt4j5lZdRhSJHZBbfNnbVGZn0uAmVQ8e796hpaEV+JiR5Z8aQRaAmTTew9vS5amgmJThZiQXolws2NkU0+GgZyTnox4MpfvjUKNf55eb4R5VV9Gli5idJoVVN2Uo0/FZWVcYVwVf1GGL2yLX4dz5G7/fuZcG2NqW+ZudVNxTqBjZXWhYm6PJk/RTqZstn66ix2EuodXfzuQI5Wpe6Ga+Ig9hBtthprcfohZu56bcwF4goZsmoKaG1YXVMtXcE6mnlZTyI8JgZJ3kpnuhuFuE4X8ZmJhK28pjJKCK4PydhNs2V+9gytzBYMaldtr23fGlG9TAoOSUT1ejIw4jUhOq3OaZ4VodpEJl2RxoWwJd5JaQZXPa45/J2bQW7lZmlrolfeV7E4MhJmErGrfdjCVG3OmaF9bL3eakWGX3Hz3jxyMJV9zfNh5xYnMbByHxltCXsloIHf1fpVRTVHJUilaBX9il9eCz2OEd9CF0nk6bplemVkRhW1wEWy/Yr92T2WvYP2VDmafhyOe7ZQNVH1ULIx4ZHlkEYYhapyB6HhpZFSbuWIrZ6uDqFjYnqtsIG/eW0yWC4xfctBnx2JhcqlOxlnNa5NYrmZVXt9SVWEoZ+52ZndnckZ6/2LqVFBUoJSjkBxas34WbENOdlkQgEhZV1M3db6WylYgYxGBfGD5ldZtYlSBmYVR6Vr9gK5ZE5cqUOVsPFzfYmBPP1N7gQaQum4rhchidF6+eLVke2P1Xxhaf5Efnj9cT2NCgH1bblVKlU2VhW2oYOBn3nLdUYFb52LebFtybWKulL1+E4FTbZxRBF90WapSEmBzWZZmUIafdSpj5mHvfPqL5lQnayWetGvVhVVUdlCkbGpVtI0schVeFWA2dM1ikmNMcphfQ24+bQBlWG/YdtB4/HZUdSRS21NTTp5ewWUqgNaAm2KGVChSrnCNiNGN4Wx4VNqA+Vf0iFSNapZNkWlPm2y3VcZ2MHioYvlwjm9tX+yE2mh8ePd7qIELZ0+eZ2OweG9XEng5l3liq2KIUjV012tkVT6BsnWudjlT3nX7UEFcbIvHe09QR3KXmtiYAm/idGh5h2Sld/xikZgrjcFUWIBSTmpX+YINhHNe7VH2dMSLT1xhV/xsh5hGWjR4RJvrj5V8VlJRYvqUxk6Gg2GE6YOyhNRXNGcDV25mZm0xjN1mEXAfZzprFmgaYrtZA07EUQZv0mePbHZRy2hHWWdrZnUOXRCBUJ/XZUh5QXmRmneNglxeTgFPL1RRWQx4aFYUbMSPA199bONsq4uQY3BgPW11cmZijpTFlENTwY9+e99OJox+TtSesZSzlE1SXG9jkEVtNIwRWExdIGtJa6pnW1RUgYx/mVg3hTpfomJHajmVcmWEYGVop3dUTqhP512Yl6xk2H/tXM9PjXoHUgSDFE4vYIN6ppS1T7JO5nk0dORSuYLSZL153VuBbFKXe48ibD5Qf1MFbs5kdGYwbMVgd5j3i4ZePHR3est5GE6xkAN0QmzaVkuRxWyLjTpTxobyZq+OSFxxmiBu1lM2Woufo427UwhXp5hDZ5uRyWxoUcp182KscjhSnVI6f5RwOHZ0U0qet2lueMCW2YikfzZxw3GJUdNn5HTkWBhlt1api3aZcGLVfvlg7XDsWMFOuk7NX+eX+06kiwNSilmrflRizU7lZQ5iOIPJhGODjYeUcbZuuVvSfpdRyWPUZ4mAOYMViBJReluCWbGPc05dbGVRJYlvjy6WSoVedBCV8JWmbeWCMV+SZBJtKIRugcOcXlhbjQlOwVMeT2NlUWjTVSdOFGSammtiwlpfdHKCqW3uaOdQjoMCeEBnOVKZbLF+u1BlVV5xW3tSZspz64JJZ3FcIFJ9cWuI6pVVlsVkYY2zgYRVVWxHYi5/klgkT0ZVT41MZgpOGlzziKJoTmMNeudwjYL6UvaXEVzoVLWQzX5iWUqNx4YMgg2CZo1EZARcUWGJbT55vos3eDN1e1Q4T6uO8W0gWsV+XnmIbKFbdloadb6ATmEXbvBYH3UldXJyR1PzfgF323ZpUtyAI1cIXjFZ7nK9ZX9u14s4XHGGQVPzd/5i9mXATt+YgIaeW8aL8lPid39PTlx2mstZD186eetYFk7/Z4tO7WKTih2Qv1IvZtxVbFYCkNVOjU/KkXCZD2wCXkNgpFvGidWLNmVLYpaZiFv/W4hjLlXXUyZ2fVEshaJns2iKa5Jik4/UUxKC0W2PdWZOTo1wW59xr4WRZtlmcn8Ah82eIJ9eXC9n8I8RaF9nDWLWeoVYtl5wZTFvVWA3Ug2AVGRwiCl1BV4TaPRiHJfMUz1yAYw0bGF3DnouVKx3epgcgvSLVXgUZ8Fwr2WVZDZWHWDBefhTHU57a4aA+lvjVdtWOk88T3KZ811+ZziAAmCCmAGQi1u8i/WLHGRYgt5k/VXPgmWR108gfR+Qn3zzUFFYr26/W8mLg4B4kZyEl3t9houWj5blftOajniBXFd6QpCnll95WVtfYwt70YStaAZVKX8QdCJ9AZVAYkxY1k6DW3lZVFhtcx5jS44Pjs6A1IKsYvBT8GxekSpZAWBwbE1XSmQqjSt26W5bV4Bq8HVtby2MCIxmV+9rkoizeKJj+VOtcGRsWFgqZAJY4GibgRBV1nwYULqOzG2fjetwj2ObbdRu5n4EhENoA5DYbXaWqItXWXly5IV+gbx1ioqvaFRSIo4RldBjmJhEjnxVU0//Zo9W1WCVbUNSSVwpWftta1gwdRx1bGAUgkaBEWNhZ+KPOnfzjTSNwZQWXoVTLFTDcEBs915cUK1OrV46Y0eCGpBQaG6Rs3cMVNyUZF/lenZoRWNSe99+23V3UJViNFkPkPhRw3mBev5Wkl8UkIJtYFwfVxBUVFFNbuJWqGOTmH+BFYcqiQCQHlRvXMCB1mJYYjGBNZ5Alm6afJotaaVZ02I+VRZjx1TZhjxtA1rmdJyIamsWWUyML19+bqlzfZg4TvdwjFuXeD1jWmaWdstgm1tJWgdOVYFqbItzoU6JZ1F/gF/6ZRtn2F+EWQFazV2uX3FT5pfdj0Vo9FYvVd9gOk5Nb/R+x4IOhNRZH08qTz5crH4qZxqFc1RPdcOAglVPm01PLW4TjAlccGFrUx92KW6Khodl+5W5fjtUM3oKfe6V4VXBf+50HWMXh6FtnXoRYqFlZ1PhY4Ns611cVKiUTE5hbOyLS1zgZZyCp2g+VDRUy2tma5ROQmNIUx6CDU+uT15XCmL+lmRmaXL/UqFSn2DvixRmmXGQZ3+JUnj9d3BmO1Y4VCGVenIAem9gDF6JYJ2BFVncYIRx73CqblBsgHKEaq2ILV5gTrNanFXjlBdt+3yZlg9ixn6Od36GI1Mel5aPh2bhXKBP7XILTqZTD1kTVIBjKJVIUdlOnJykfrhUJI1UiDeC8pWObSZfzFo+ZmmWsHMuc79TeoGFmaF/qlt3llCWv374dqJTdpWZmbF7RIlYbmFO1H9leeaL82DNVKtOeZj3XWFqz1ARVGGMJ4RdeASXSlLuVKNWAJWIbbVbxm1TZg9cXVshaJaAeFURe0hlVGmbTkdrToeLl09TH2M6ZKqQnGXBgBCMmVGwaHhT+YfIYcRs+2wijFFcqoWvggyVI2ubj7Bl+1/DX+FPRYgfZmWBKXP6YHRREVKLV2JfopBMiJKReF5PZydg01lEUfZR+IAIU3lsxJaKcRFP7k+efz1nxVUIlcB5lojjfp9YDGIAl1qGGFZ7mJBfuIvEhFeR2VPtZY9eXHVkYG59f1rqfu1+aY+nVaNbrGDLZYRzCZBjdil32n50l5uFZlt0euqWQIjLUo9xql/sZeKL+1tvmuFdiWtbbK2Lr4sKkMWPi1O8YiaeLZ5AVCtOvYJZcpyGFl1ZiK9txZbRVJpOtosJcb1UCZbfcPlt0HYlThR4EoepXPZeAIqcmA6WjnC/bERZqWM8d02IFG9zgjBY1XGMUxp4wZYBVWZfMHG0WxqMjJqDay5ZL57neWhnbGJvT6F1in8LbTOWJ2zwTtJ1e1E3aD5vgJBwgZZZdnRHZCdcZZCReiOM2lmsVACCb4OBiQCAMGlOVjaAN3LOkbZRX051mJZjGk72U/NmS4EcWbJtAE75WDtT1mPxlJ1PCk9jiJCYN1lXkPt56k7wgJF1gmycW+hZXV8FaYGGGlDyXVlO43flTnqCkWITZpGQeVy/TnlfxoE4kISAq3WmTtSID2HFa8ZfSU7KdqJu44uuiwqM0YsCX/x/zH/OfjWDa4PgVrdr85c0lvtZH1T2lOttxVtumTlcFV+QlnBT8YIxanRacJ6UXih/uYMkhCWEZ4NHh86PYo3IdnFflphseCBm31TlYmNPw4HIdbhezZYKjvmGj1TzbIxtOGx/YMdSKHV9XhhPoGDnXyRcMXWukMCUuXK5bDhuSZEJZ8tT81NRT8mR8YvIU3xewo/kbY5OwnaGaV6GGmEGgllP3k8+kHycCWEdbhRuhZaITjFa6JYOTn9cuXmHW+2LvX+Jc99Xi4LBkAFUR5C7VepcoV8IYTJr8XKygImKdG3TW9WIhJhrjG2aM54KbqRRQ1GjV4GIn1P0Y5WP7VZYVAZXP3OQbhh/3I/Rgj9hKGBilvBmpn6KjcONpZSzXKR8CGemYAWWGICRTueQAFNolkFR0I90hV2RVWb1l1VbHVM4eEJnPWjJVH5wsFt9j41RKFexVBJlgmZejUOND4FshG2Q33z/UfuFo2fpZaFvpIaBjmpWIJCCdnZw5XEjjeliGVL9bDyNDmCeWI5h/mZgjU5is1Ujbi1nZ4/hlPiVKHcFaKhpi1RNTrhwyItYZItlhVuEejpQ6Fu7d+FreYqYfL5sz3apZZePLV1VXDiGCGhgUxhi2Xpbbv1+H2rgenBfM28gX4xjqG1WZwhOEF4mjddOwIA0dpyW22ItZn5ivGx1jWdxaX9GUYeA7FNukJhi8lTwhpmPBYAXlReF2Y9Zbc1zn2UfdwR1J3j7gR6NiJSmT5VnuXXKiweXL2NHlTWWuIQjY0F3gV/wcolOFGB0Ze9iY2s/ZSdex3XRkMGLnYKdZy9lMVQYh+V3ooACgUFsS07HfkyA9HYNaZZrZ2I8UIRPQFcHY2Jrvo3qU+hluH7XXxpjt2PzgfSBbn8cXtlcNlJ6Zul5GnoojZlw1HXebrtsknotTsV24F+flHeIyH7Neb+AzZHyThdPH4JoVN5dMm3Mi6V8dI+YgBpeklSxdplbPGakmuBzKmjbhjFnKnP4i9uLEJD5ettwbnHEYql3MVY7TleE8WepUsCGLo34lFF7T0/obF15e5qTYipy/WITThZ4bI+wZFqNxntpaIRexYiGWZ5k7li2cg5pJZX9j1iNYFcAfwaMxlFJY9liU1NMaCJ0AYNMkURVQHd8cEpteVGoVESN/1nLbsRtXFsrfdROfXzTblBb6oENbldbA5vVaCqOl1v8fjtgtX65kHCNT1nNY995s41SU89lVnnFizuWxH67lIJ+NFaJkQBnan8KXHWQKGbmXVBP3mdaUFxPUFenXhDoEegS6BPoFOiNTgxOQFEQTv9eRVMVTphOHk4ym2xbaVYoTrp5P04VU0dOLVk7cm5TEGzfVuSAl5nTa353F582Tp9OEJ9cTmlOk06IgltbbFUPVsROjVOdU6NTpVOuU2WXXY0aU/VTJlMuUz5TXI1mU2NTAlIIUg5SLVIzUj9SQFJMUl5SYVJcUq+EfVKCUoFSkFKTUoJRVH+7TsNOyU7CTuhO4U7rTt5OG0/zTiJPZE/1TiVPJ08JTytPXk9nTzhlWk9dT19PV08yTz1Pdk90T5FPiU+DT49Pfk97T6pPfE+sT5RP5k/oT+pPxU/aT+NP3E/RT99P+E8pUExQ808sUA9QLlAtUP5PHFAMUCVQKFB+UENQVVBIUE5QbFB7UKVQp1CpULpQ1lAGUe1Q7FDmUO5QB1ELUd1OPWxYT2VPzk+gn0ZsdHxuUf1dyZ6YmYFRFFn5Ug1TB4oQU+tRGVlVUaBOVlGzTm6IpIi1ThSB0oiAeTRbA4i4f6tRsVG9UbxRx1GWUaJRpVGgi6aLp4uqi7SLtYu3i8KLw4vLi8+LzovSi9OL1IvWi9iL2Yvci9+L4Ivki+iL6Yvui/CL84v2i/mL/Iv/iwCMAowEjAeMDIwPjBGMEowUjBWMFowZjBuMGIwdjB+MIIwhjCWMJ4wqjCuMLowvjDKMM4w1jDaMaVN6Ux2WIpYhljGWKpY9ljyWQpZJllSWX5ZnlmyWcpZ0loiWjZaXlrCWl5CbkJ2QmZCskKGQtJCzkLaQupC4kLCQz5DFkL6Q0JDEkMeQ05DmkOKQ3JDXkNuQ65DvkP6QBJEikR6RI5ExkS+ROZFDkUaRDVJCWaJSrFKtUr5S/1TQUtZS8FLfU+5xzXf0XvVR/FEvm7ZTAV9ade9dTFepV6FXfli8WMVY0VgpVyxXKlczVzlXLlcvV1xXO1dCV2lXhVdrV4ZXfFd7V2hXbVd2V3NXrVekV4xXslfPV6dXtFeTV6BX1VfYV9pX2VfSV7hX9FfvV/hX5FfdVwtYDVj9V+1XAFgeWBlYRFggWGVYbFiBWIlYmliAWKiZGZ//YXmCfYJ/go+CioKogoSCjoKRgpeCmYKrgriCvoKwgsiCyoLjgpiCt4KugsuCzILBgqmCtIKhgqqCn4LEgs6CpILhggmD94Lkgg+DB4PcgvSC0oLYggyD+4LTghGDGoMGgxSDFYPggtWCHINRg1uDXIMIg5KDPIM0gzGDm4Negy+DT4NHg0ODX4NAgxeDYIMtgzqDM4Nmg2WDaIMbg2mDbINqg22DboOwg3iDs4O0g6CDqoOTg5yDhYN8g7aDqYN9g7iDe4OYg56DqIO6g7yDwYMBhOWD2IMHWBiEC4Tdg/2D1oMchDiEEYQGhNSD34MPhAOE+IP5g+qDxYPAgyaE8IPhg1yEUYRahFmEc4SHhIiEeoSJhHiEPIRGhGmEdoSMhI6EMYRthMGEzYTQhOaEvYTThMqEv4S6hOCEoYS5hLSEl4TlhOOEDIUNdTiF8IQ5hR+FOoVWhTuF/4T8hFmFSIVohWSFXoV6haJ3Q4VyhXuFpIWohYeFj4V5ha6FnIWFhbmFt4WwhdOFwYXchf+FJ4YFhimGFoY8hv5eCF88WUFZN4BVWVpZWFkPUyJcJVwsXDRcTGJqYp9iu2LKYtpi12LuYiJj9mI5Y0tjQ2OtY/ZjcWN6Y45jtGNtY6xjimNpY65jvGPyY/hj4GP/Y8Rj3mPOY1JkxmO+Y0VkQWQLZBtkIGQMZCZkIWReZIRkbWSWZHpkt2S4ZJlkumTAZNBk12TkZOJkCWUlZS5lC1/SXxl1EV9fU/FT/VPpU+hT+1MSVBZUBlRLVFJUU1RUVFZUQ1QhVFdUWVQjVDJUglSUVHdUcVRkVJpUm1SEVHZUZlSdVNBUrVTCVLRU0lSnVKZU01TUVHJUo1TVVLtUv1TMVNlU2lTcVKlUqlSkVN1Uz1TeVBtV51QgVf1UFFXzVCJVI1UPVRFVJ1UqVWdVj1W1VUlVbVVBVVVVP1VQVTxVN1VWVXVVdlV3VTNVMFVcVYtV0lWDVbFVuVWIVYFVn1V+VdZVkVV7Vd9VvVW+VZRVmVXqVfdVyVUfVtFV61XsVdRV5lXdVcRV71XlVfJV81XMVc1V6FX1VeRVlI8eVghWDFYBViRWI1b+VQBWJ1YtVlhWOVZXVixWTVZiVllWXFZMVlRWhlZkVnFWa1Z7VnxWhVaTVq9W1FbXVt1W4Vb1VutW+Vb/VgRXClcJVxxXD14ZXhReEV4xXjtePF43XkReVF5bXl5eYV6MXHpcjVyQXJZciFyYXJlckVyaXJxctVyiXL1crFyrXLFco1zBXLdcxFzSXORcy1zlXAJdA10nXSZdLl0kXR5dBl0bXVhdPl00XT1dbF1bXW9dXV1rXUtdSl1pXXRdgl2ZXZ1dc4y3XcVdc193X4Jfh1+JX4xflV+ZX5xfqF+tX7VfvF9iiGFfrXKwcrRyt3K4csNywXLOcs1y0nLocu9y6XLycvRy93IBc/NyA3P6cvtyF3MTcyFzCnMecx1zFXMiczlzJXMsczhzMXNQc01zV3Ngc2xzb3N+cxuCJVnnmCRZAlljmWeZaJlpmWqZa5lsmXSZd5l9mYCZhJmHmYqZjZmQmZGZk5mUmZWZgF6RXotell6lXqBeuV61Xr5es15TjdJe0V7bXuhe6l66gcRfyV/WX89fA2DuXwRg4V/kX/5fBWAGYOpf7V/4XxlgNWAmYBtgD2ANYClgK2AKYD9gIWB4YHlge2B6YEJgamB9YJZgmmCtYJ1gg2CSYIxgm2DsYLtgsWDdYNhgxmDaYLRgIGEmYRVhI2H0YABhDmErYUphdWGsYZRhp2G3YdRh9WHdX7OW6ZXrlfGV85X1lfaV/JX+lQOWBJYGlgiWCpYLlgyWDZYPlhKWFZYWlheWGZYalixOP3IVYjVsVGxcbEpso2yFbJBslGyMbGhsaWx0bHZshmypbNBs1GytbPds+GzxbNdssmzgbNZs+mzrbO5ssWzTbO9s/mw5bSdtDG1DbUhtB20EbRltDm0rbU1tLm01bRptT21SbVRtM22RbW9tnm2gbV5tk22UbVxtYG18bWNtGm7HbcVt3m0Obr9t4G0RbuZt3W3ZbRZuq20Mbq5tK25ubk5ua26ybl9uhm5TblRuMm4lbkRu326xbphu4G4tb+JupW6nbr1uu263btdutG7Pbo9uwm6fbmJvRm9HbyRvFW/5bi9vNm9Lb3RvKm8JbylviW+Nb4xveG9yb3xvem/Rb8lvp2+5b7Zvwm/hb+5v3m/gb+9vGnAjcBtwOXA1cE9wXnCAW4RblVuTW6VbuFsvdZ6aNGTkW+5bMInwW0eOB4u2j9OP1Y/lj+6P5I/pj+aP84/ojwWQBJALkCaQEZANkBaQIZA1kDaQLZAvkESQUZBSkFCQaJBYkGKQW5C5ZnSQfZCCkIiQg5CLkFBfV19WX1hfO1yrVFBcWVxxW2NcZly8fypfKV8tX3SCPF87m25cgVmDWY1ZqVmqWaNZl1nKWatZnlmkWdJZslmvWddZvlkFWgZa3VkIWuNZ2Fn5WQxaCVoyWjRaEVojWhNaQFpnWkpaVVo8WmJadVrsgKpam1p3WnpavlrrWrJa0lrUWrha4FrjWvFa1lrmWtha3FoJWxdbFlsyWzdbQFsVXBxcWltlW3NbUVtTW2JbdZp3mniaepp/mn2agJqBmoWaiJqKmpCakpqTmpaamJqbmpyanZqfmqCaopqjmqWap5qffqF+o36lfqh+qX6tfrB+vn7AfsF+wn7Jfst+zH7QftR+137bfuB+4X7ofut+7n7vfvF+8n4Nf/Z++n77fv5+AX8CfwN/B38Ifwt/DH8PfxF/En8Xfxl/HH8bfx9/IX8ifyN/JH8lfyZ/J38qfyt/LH8tfy9/MH8xfzJ/M381f3pef3XbXT51lZCOc5FzrnOic59zz3PCc9Fzt3Ozc8BzyXPIc+Vz2XN8mAp06XPnc95zunPycw90KnRbdCZ0JXQodDB0LnQsdBt0GnRBdFx0V3RVdFl0d3RtdH50nHSOdIB0gXSHdIt0nnSodKl0kHSndNJ0unTql+uX7JdMZ1NnXmdIZ2lnpWeHZ2pnc2eYZ6dndWeoZ55nrWeLZ3dnfGfwZwlo2GcKaOlnsGcMaNlntWfaZ7Nn3WcAaMNnuGfiZw5owWf9ZzJoM2hgaGFoTmhiaERoZGiDaB1oVWhmaEFoZ2hAaD5oSmhJaClotWiPaHRod2iTaGtowmhuafxoH2kgafloJGnwaAtpAWlXaeNoEGlxaTlpYGlCaV1phGlraYBpmGl4aTRpzGmHaYhpzmmJaWZpY2l5aZtpp2m7aatprWnUabFpwWnKad9plWngaY1p/2kvau1pF2oYamVq8mlEaj5qoGpQaltqNWqOanlqPWooalhqfGqRapBqqWqXaqtqN3NSc4FrgmuHa4RrkmuTa41rmmuba6Frqmtrj22PcY9yj3OPdY92j3iPd495j3qPfI9+j4GPgo+Ej4ePi4+Nj46Pj4+Yj5qPzo4LYhdiG2IfYiJiIWIlYiRiLGLnge909HT/dA91EXUTdTRl7mXvZfBlCmYZZnJnA2YVZgBmhXD3Zh1mNGYxZjZmNWYGgF9mVGZBZk9mVmZhZldmd2aEZoxmp2adZr5m22bcZuZm6WYyjTONNo07jT2NQI1FjUaNSI1JjUeNTY1VjVmNx4nKicuJzInOic+J0InRiW5yn3JdcmZyb3J+cn9yhHKLco1yj3KScghjMmOwYz9k2GQEgOpr82v9a/Vr+WsFbAdsBmwNbBVsGGwZbBpsIWwpbCRsKmwybDVlVWVrZU1yUnJWcjByYoYWUp+AnICTgLyACme9gLGAq4CtgLSAt4DngOiA6YDqgNuAwoDEgNmAzYDXgBBn3YDrgPGA9IDtgA2BDoHygPyAFWcSgVqMNoEegSyBGIEygUiBTIFTgXSBWYFagXGBYIFpgXyBfYFtgWeBTVi1WoiBgoGRgdVuo4GqgcyBJmfKgbuBwYGmgSRrN2s5a0NrRmtZa9GY0pjTmNWY2ZjamLNrQF/Ca/OJkGVRn5NlvGXGZcRlw2XMZc5l0mXWZYBwnHCWcJ1wu3DAcLdwq3CxcOhwynAQcRNxFnEvcTFxc3FccWhxRXFycUpxeHF6cZhxs3G1cahxoHHgcdRx53H5cR1yKHJscBhxZnG5cT5iPWJDYkhiSWI7eUB5RnlJeVt5XHlTeVp5YnlXeWB5b3lneXp5hXmKeZp5p3mzedFf0F88YF1gWmBnYEFgWWBjYKtgBmENYV1hqWGdYcth0WEGYoCAf4CTbPZs/G32d/h3AHgJeBd4GHgReKtlLXgceB14OXg6eDt4H3g8eCV4LHgjeCl4TnhteFZ4V3gmeFB4R3hMeGp4m3iTeJp4h3iceKF4o3iyeLl4pXjUeNl4yXjsePJ4BXn0eBN5JHkeeTR5m5/5nvue/J7xdgR3DXf5dgd3CHcadyJ3GXctdyZ3NXc4d1B3UXdHd0N3Wndod2J3ZXd/d413fXeAd4x3kXefd6B3sHe1d713OnVAdU51S3VIdVt1cnV5dYN1WH9hf19/SIpof3R/cX95f4F/fn/NduV2MoiFlIaUh5SLlIqUjJSNlI+UkJSUlJeUlZSalJuUnJSjlKSUq5SqlK2UrJSvlLCUspS0lLaUt5S4lLmUupS8lL2Uv5TElMiUyZTKlMuUzJTNlM6U0JTRlNKU1ZTWlNeU2ZTYlNuU3pTflOCU4pTklOWU55TolOqU6ZTrlO6U75TzlPSU9ZT3lPmU/JT9lP+UA5UClQaVB5UJlQqVDZUOlQ+VEpUTlRSVFZUWlRiVG5UdlR6VH5UilSqVK5UplSyVMZUylTSVNpU3lTiVPJU+lT+VQpU1lUSVRZVGlUmVTJVOlU+VUpVTlVSVVpVXlViVWZVblV6VX5VdlWGVYpVklWWVZpVnlWiVaZVqlWuVbJVvlXGVcpVzlTqV53fsd8mW1XnteeN563kGekddA3oCeh56FHo5ejd6UXrPnqWZcHqIdo52k3aZdqR23nTgdCx1IJ4iniieKZ4qniueLJ4ynjGeNp44njeeOZ46nj6eQZ5CnkSeRp5HnkieSZ5LnkyeTp5RnlWeV55anlueXJ5enmOeZp5nnmieaZ5qnmuebJ5xnm2ec56SdZR1lnWgdZ11rHWjdbN1tHW4dcR1sXWwdcN1wnXWdc1143XodeZ15HXrded1A3bxdfx1/3UQdgB2BXYMdhd2CnYldhh2FXYZdht2PHYidiB2QHYtdjB2P3Y1dkN2PnYzdk12XnZUdlx2VnZrdm92yn/menh6eXqAeoZ6iHqVeqZ6oHqseqh6rXqzemSIaYhyiH2If4iCiKKIxoi3iLyIyYjiiM6I44jliPGIGon8iOiI/ojwiCGJGYkTiRuJCok0iSuJNolBiWaJe4mLdeWAsna0dtx3EoAUgBaAHIAggCKAJYAmgCeAKYAogDGAC4A1gEOARoBNgFKAaYBxgIOJeJiAmIOYiZiMmI2Yj5iUmJqYm5iemJ+YoZiimKWYpphNhlSGbIZuhn+GeoZ8hnuGqIaNhouGrIadhqeGo4aqhpOGqYa2hsSGtYbOhrCGuoaxhq+GyYbPhrSG6YbxhvKG7YbzhtCGE4fehvSG34bYhtGGA4cHh/iGCIcKhw2HCYcjhzuHHoclhy6HGoc+h0iHNIcxhymHN4c/h4KHIod9h36He4dgh3CHTIduh4uHU4djh3yHZIdZh2WHk4evh6iH0ofGh4iHhYeth5eHg4erh+WHrIe1h7OHy4fTh72H0YfAh8qH24fqh+CH7ocWiBOI/ocKiBuIIYg5iDyINn9Cf0R/RX8Qgvp6/XoIewN7BHsVewp7K3sPe0d7OHsqexl7LnsxeyB7JXskezN7Pnsee1h7WntFe3V7THtde2B7bnt7e2J7cntxe5B7pnune7h7rHude6h7hXuqe5x7onure7R70XvBe8x73Xvae+V75nvqewx8/nv8ew98FnwLfB98KnwmfDh8QXxAfP6BAYICggSC7IFEiCGCIoIjgi2CL4IogiuCOII7gjOCNII+gkSCSYJLgk+CWoJfgmiCfoiFiIiI2IjfiF6JnX+ff6d/r3+wf7J/fHxJZZF8nXycfJ58onyyfLx8vXzBfMd8zHzNfMh8xXzXfOh8boKoZr9/zn/Vf+V/4X/mf+l/7n/zf/h8d32mfa59R36bfrietJ5zjYSNlI2RjbGNZ41tjUeMSYxKkVCRTpFPkWSRYpFhkXCRaZFvkX2RfpFykXSReZGMkYWRkJGNkZGRopGjkaqRrZGuka+RtZG0kbqRVYx+nriN640FjlmOaY61jb+NvI26jcSN1o3XjdqN3o3Ojc+N243GjeyN9434jeON+Y37jeSNCY79jRSOHY4fjiyOLo4jji+OOo5AjjmONY49jjGOSY5BjkKOUY5SjkqOcI52jnyOb450joWOj46UjpCOnI6ejniMgoyKjIWMmIyUjJtl1oneidqJ3InlieuJ74k+iiaLU5fplvOW75YGlwGXCJcPlw6XKpctlzCXPpeAn4OfhZ+Gn4efiJ+Jn4qfjJ/+ngufDZ+5lryWvZbOltKWv3fglo6SrpLIkj6TapPKk4+TPpRrlH+cgpyFnIach5yInCN6i5yOnJCckZySnJSclZyanJucnpyfnKCcoZyinKOcpZymnKecqJypnKucrZyunLCcsZyynLOctJy1nLact5y6nLucvJy9nMScxZzGnMecypzLnMyczZzOnM+c0JzTnNSc1ZzXnNic2ZzcnN2c35zinHyXhZeRl5KXlJevl6uXo5eyl7SXsZqwmreaWJ62mrqavJrBmsCaxZrCmsuazJrRmkWbQ5tHm0mbSJtNm1Gb6JgNmS6ZVZlUmd+a4Zrmmu+a65r7mu2a+ZoImw+bE5sfmyObvZ6+njt+gp6Hnoiei56SntaTnZ6fntue3J7dnuCe357inume557lnuqe754inyyfL585nzefPZ8+n0SfLPl5+ZX55/nx+Qz6DfoO+g/6EfoT+hT6GPof+iD6Ifoj+iT6J/oo+in6gS4W6BfoGOiELnM0RzSILosutJ+eNRo2DjaMLpcubjkYObWfzznfOXM60Dm2n7efTjtuPOA8py4x6Lifqi5WQF9Bri43Q7Muti63LjvosUOsQ7su3UPWRGFGTEa5nyNHKUd8R41Hyi5HSXpJfUmCSYNJhUmGSZ9Jm0m3SbZJup9V6KNMn0ygTKFMd0yiTBNNFE0VTRZNF00YTRlNrk27nwAwATACMLcAyQLHAqgAAzAFMBQgXv8WICYgGCAZIBwgHSAUMBUwCDAJMAowCzAMMA0wDjAPMBYwFzAQMBEwsQDXAPcANiInIigiESIPIioiKSIIIjciGiKlIiUiICISI5kiKyIuImEiTCJIIj0iHSJgIm4ibyJkImUiHiI1IjQiQiZAJrAAMiAzIAMhBP+kAOD/4f8wIKcAFiEGJgUmyyXPJc4lxyXGJaEloCWzJbIlOyCSIZAhkSGTIRMwNf42/jn+Ov4//kD+Pf4+/kH+Qv5D/kT+F/4Y/jv+PP43/jj+Mf4Z/jP+NP4BAeEAzgHgABMB6QAbAegAKwHtANAB7ABNAfMA0gHyAGsB+gDUAfkA1gHYAdoB3AH8AOoAUQI/HkQBSAH5AWECAk4ETgVODE4STh9OI04kTihOK04uTi9OME41TkBOQU5ETkdOUU5aTlxOY05oTmlOdE51TnlOf06NTpZOl06dTq9OuU7DTtBO2k7bTuBO4U7iTuhO707xTvNO9U79Tv5O/04ATwJPA08ITwtPDE8STxVPFk8XTxlPLk8xT2BPM081TzdPOU87Tz5PQE9CT0hPSU9LT0xPUk9UT1ZPWE9fT2NPak9sT25PcU93T3hPeU96T31Pfk+BT4JPhE+FT4lPik+MT45PkE+ST5NPlE+XT5lPmk+eT59Psk+3T7lPu0+8T71Pvk/AT8FPxU/GT8hPyU/LT8xPzU/PT9JP3E/gT+JP8E/yT/xP/U//TwBQAVAEUAdQClAMUA5QEFATUBdQGFAbUBxQHVAeUCJQJ1AuUDBQMlAzUDVQQFBBUEJQRVBGUEpQTFBOUFFQUlBTUFdQWVBfUGBQYlBjUGZQZ1BqUG1QcFBxUDtQgVCDUIRQhlCKUI5Qj1CQUJJQk1CUUJZQm1CcUJ5Qn1CgUKFQolCqUK9QsFC5ULpQvVDAUMNQxFDHUMxQzlDQUNNQ1FDYUNxQ3VDfUOJQ5FDmUOhQ6VDvUPFQ9lD6UP5QA1EGUQdRCFELUQxRDVEOUfJQEFEXURlRG1EcUR1RHlEjUSdRKFEsUS1RL1ExUTNRNFE1UThROVFCUUpRT1FTUVVRV1FYUV9RZFFmUX5Rg1GEUYtRjlGYUZ1RoVGjUa1RuFG6UbxRvlG/UcJRyFHPUdFR0lHTUdVR2FHeUeJR5VHuUfJR81H0UfdRAVICUgVSElITUhVSFlIYUiJSKFIxUjJSNVI8UkVSSVJVUldSWFJaUlxSX1JgUmFSZlJuUndSeFJ5UoBSglKFUopSjFKTUpVSllKXUphSmlKcUqRSpVKmUqdSr1KwUrZSt1K4UrpSu1K9UsBSxFLGUshSzFLPUtFS1FLWUttS3FLhUuVS6FLpUupS7FLwUvFS9FL2UvdSAFMDUwpTC1MMUxFTE1MYUxtTHFMeUx9TJVMnUyhTKVMrUyxTLVMwUzJTNVM8Uz1TPlNCU0xTS1NZU1tTYVNjU2VTbFNtU3JTeVN+U4NTh1OIU45Tk1OUU5lTnVOhU6RTqlOrU69TslO0U7VTt1O4U7pTvVPAU8VTz1PSU9NT1VPaU91T3lPgU+ZT51P1UwJUE1QaVCFUJ1QoVCpUL1QxVDRUNVRDVERUR1RNVE9UXlRiVGRUZlRnVGlUa1RtVG5UdFR/VIFUg1SFVIhUiVSNVJFUlVSWVJxUn1ShVKZUp1SpVKpUrVSuVLFUt1S5VLpUu1S/VMZUylTNVM5U4FTqVOxU71T2VPxU/lT/VABVAVUFVQhVCVUMVQ1VDlUVVSpVK1UyVTVVNlU7VTxVPVVBVUdVSVVKVU1VUFVRVVhVWlVbVV5VYFVhVWRVZlV/VYFVglWGVYhVjlWPVZFVklWTVZRVl1WjVaRVrVWyVb9VwVXDVcZVyVXLVcxVzlXRVdJV01XXVdhV21XeVeJV6VX2Vf9VBVYIVgpWDVYOVg9WEFYRVhJWGVYsVjBWM1Y1VjdWOVY7VjxWPVY/VkBWQVZDVkRWRlZJVktWTVZPVlRWXlZgVmFWYlZjVmZWaVZtVm9WcVZyVnVWhFaFVohWi1aMVpVWmVaaVp1WnlafVqZWp1aoVqlWq1asVq1WsVazVrdWvlbFVslWylbLVs9W0FbMVs1W2VbcVt1W31bhVuRW5VbmVudW6FbxVutW7Vb2VvdWAVcCVwdXClcMVxFXFVcaVxtXHVcgVyJXI1ckVyVXKVcqVyxXLlcvVzNXNFc9Vz5XP1dFV0ZXTFdNV1JXYldlV2dXaFdrV21XbldvV3BXcVdzV3RXdVd3V3lXeld7V3xXfleBV4NXjFeUV5dXmVeaV5xXnVeeV59XoVeVV6dXqFepV6xXuFe9V8dXyFfMV89X1VfdV95X5FfmV+dX6VftV/BX9Vf2V/hX/Vf+V/9XA1gEWAhYCVjhVwxYDVgbWB5YH1ggWCZYJ1gtWDJYOVg/WElYTFhNWE9YUFhVWF9YYVhkWGdYaFh4WHxYf1iAWIFYh1iIWIlYiliMWI1Yj1iQWJRYllidWKBYoViiWKZYqVixWLJYxFi8WMJYyFjNWM5Y0FjSWNRY1ljaWN1Y4VjiWOlY81gFWQZZC1kMWRJZE1kUWUGGHVkhWSNZJFkoWS9ZMFkzWTVZNlk/WUNZRllSWVNZWVlbWV1ZXllfWWFZY1lrWW1Zb1lyWXVZdll5WXtZfFmLWYxZjlmSWZVZl1mfWaRZp1mtWa5Zr1mwWbNZt1m6WbxZwVnDWcRZyFnKWc1Z0lndWd5Z31njWeRZ51nuWe9Z8VnyWfRZ91kAWgRaDFoNWg5aEloTWh5aI1okWidaKFoqWi1aMFpEWkVaR1pIWkxaUFpVWl5aY1plWmdabVp3Wnpae1p+WotakFqTWpZamVqcWp5an1qgWqJap1qsWrFaslqzWrVauFq6Wrtav1rEWsZayFrPWtpa3FrgWuVa6lruWvVa9lr9WgBbAVsIWxdbNFsZWxtbHVshWyVbLVs4W0FbS1tMW1JbVlteW2hbbltvW3xbfVt+W39bgVuEW4ZbiluOW5BbkVuTW5RblluoW6lbrFutW69bsVuyW7dbulu8W8BbwVvNW89b1lvXW9hb2VvaW+Bb71vxW/Rb/VsMXBdcHlwfXCNcJlwpXCtcLFwuXDBcMlw1XDZcWVxaXFxcYlxjXGdcaFxpXG1ccFx0XHVcelx7XHxcfVyHXIhcilyPXJJcnVyfXKBcolyjXKZcqlyyXLRctVy6XMlcy1zSXN1c11zuXPFc8lz0XAFdBl0NXRJdK10jXSRdJl0nXTFdNF05XT1dP11CXUNdRl1IXVVdUV1ZXUpdX11gXWFdYl1kXWpdbV1wXXldel1+XX9dgV2DXYhdil2SXZNdlF2VXZldm12fXaBdp12rXbBdtF24Xbldw13HXctd0F3OXdhd2V3gXeRd6V34XfldAF4HXg1eEl4UXhVeGF4fXiBeLl4oXjJeNV4+XkteUF5JXlFeVl5YXlteXF5eXmheal5rXmxebV5uXnBegF6LXo5eol6kXqVeqF6qXqxesV6zXr1evl6/XsZezF7LXs5e0V7SXtRe1V7cXt5e5V7rXgJfBl8HXwhfDl8ZXxxfHV8hXyJfI18kXyhfK18sXy5fMF80XzZfO189Xz9fQF9EX0VfR19NX1BfVF9YX1tfYF9jX2RfZ19vX3JfdF91X3hfel99X35fiV+NX49fll+cX51fol+nX6tfpF+sX69fsF+xX7hfxF/HX8hfyV/LX9Bf0V/SX9Nf1F/eX+Ff4l/oX+lf6l/sX+1f7l/vX/Jf81/2X/pf/F8HYApgDWATYBRgF2AYYBpgH2AkYC1gM2A1YEBgR2BIYElgTGBRYFRgVmBXYF1gYWBnYHFgfmB/YIJghmCIYIpgjmCRYJNglWCYYJ1gnmCiYKRgpWCoYLBgsWC3YLtgvmDCYMRgyGDJYMpgy2DOYM9g1GDVYNlg22DdYN5g4mDlYPJg9WD4YPxg/WACYQdhCmEMYRBhEWESYRNhFGEWYRdhGWEcYR5hImEqYSthMGExYTVhNmE3YTlhQWFFYUZhSWFeYWBhbGFyYXhhe2F8YX9hgGGBYYNhhGGLYY1hkmGTYZdhmGGcYZ1hn2GgYaVhqGGqYa1huGG5YbxhwGHBYcJhzmHPYdVh3GHdYd5h32HhYeJh52HpYeVh7GHtYe9hAWIDYgRiB2ITYhViHGIgYiJiI2InYiliK2I5Yj1iQmJDYkRiRmJMYlBiUWJSYlRiVmJaYlxiZGJtYm9ic2J6Yn1ijWKOYo9ikGKmYqhis2K2YrdiumK+Yr9ixGLOYtVi1mLaYupi8mL0Yvxi/WIDYwRjCmMLYw1jEGMTYxZjGGMpYypjLWM1YzZjOWM8Y0FjQmNDY0RjRmNKY0tjTmNSY1NjVGNYY1tjZWNmY2xjbWNxY3RjdWN4Y3xjfWN/Y4JjhGOHY4pjkGOUY5VjmWOaY55jpGOmY61jrmOvY71jwWPFY8hjzmPRY9Nj1GPVY9xj4GPlY+pj7GPyY/Nj9WP4Y/ljCWQKZBBkEmQUZBhkHmQgZCJkJGQlZClkKmQvZDBkNWQ9ZD9kS2RPZFFkUmRTZFRkWmRbZFxkXWRfZGBkYWRjZG1kc2R0ZHtkfWSFZIdkj2SQZJFkmGSZZJtknWSfZKFko2SmZKhkrGSzZL1kvmS/ZMRkyWTKZMtkzGTOZNBk0WTVZNdk5GTlZOlk6mTtZPBk9WT3ZPtk/2QBZQRlCGUJZQplD2UTZRRlFmUZZRtlHmUfZSJlJmUpZS5lMWU6ZTxlPWVDZUdlSWVQZVJlVGVfZWBlZ2VrZXplfWWBZYVlimWSZZVlmGWdZaBlo2WmZa5lsmWzZbRlv2XCZchlyWXOZdBl1GXWZdhl32XwZfJl9GX1Zfll/mX/ZQBmBGYIZglmDWYRZhJmFWYWZh1mHmYhZiJmI2YkZiZmKWYqZitmLGYuZjBmMWYzZjlmN2ZAZkVmRmZKZkxmUWZOZldmWGZZZltmXGZgZmFm+2ZqZmtmbGZ+ZnNmdWZ/ZndmeGZ5ZntmgGZ8ZotmjGaNZpBmkmaZZppmm2acZp9moGakZq1msWayZrVmu2a/ZsBmwmbDZshmzGbOZs9m1GbbZt9m6GbrZuxm7mb6ZgVnB2cOZxNnGWccZyBnImczZz5nRWdHZ0hnTGdUZ1VnXWdmZ2xnbmd0Z3Zne2eBZ4RnjmePZ5Fnk2eWZ5hnmWebZ7BnsWeyZ7Vnu2e8Z71n+WfAZ8Jnw2fFZ8hnyWfSZ9dn2WfcZ+Fn5mfwZ/Jn9mf3Z1JoFGgZaB1oH2goaCdoLGgtaC9oMGgxaDNoO2g/aERoRWhKaExoVWhXaFhoW2hraG5ob2hwaHFocmh1aHloemh7aHxogmiEaIZoiGiWaJhommicaKFoo2ilaKloqmiuaLJou2jFaMhozGjPaNBo0WjTaNZo2WjcaN1o5WjoaOpo62jsaO1o8GjxaPVo9mj7aPxo/WgGaQlpCmkQaRFpE2kWaRdpMWkzaTVpOGk7aUJpRWlJaU5pV2lbaWNpZGllaWZpaGlpaWxpcGlxaXJpeml7aX9pgGmNaZJplmmYaaFppWmmaahpq2mtaa9pt2m4abppvGnFachp0WnWaddp4mnlae5p72nxafNp9Wn+aQBqAWoDag9qEWoVahpqHWogaiRqKGowajJqNGo3ajtqPmo/akVqRmpJakpqTmpQalFqUmpValZqW2pkamdqampxanNqfmqBaoNqhmqHaolqi2qRaptqnWqeap9qpWqraq9qsGqxarRqvWq+ar9qxmrJashqzGrQatRq1WrWatxq3Wrkaudq7GrwavFq8mr8av1qAmsDawZrB2sJaw9rEGsRaxdrG2seayRrKGsrayxrL2s1azZrO2s/a0ZrSmtNa1JrVmtYa11rYGtna2trbmtwa3VrfWt+a4JrhWuXa5trn2uga6Jro2uoa6lrrGuta65rsGu4a7lrvWu+a8NrxGvJa8xr1mvaa+Fr42vma+dr7mvxa/dr+Wv/awJsBGwFbAlsDWwObBBsEmwZbB9sJmwnbChsLGwubDNsNWw2bDpsO2w/bEpsS2xNbE9sUmxUbFlsW2xcbGtsbWxvbHRsdmx4bHlse2yFbIZsh2yJbJRslWyXbJhsnGyfbLBssmy0bMJsxmzNbM9s0GzRbNJs1GzWbNps3GzgbOds6WzrbOxs7mzybPRsBG0HbQptDm0PbRFtE20abSZtJ20obWdsLm0vbTFtOW08bT9tV21ebV9tYW1lbWdtb21wbXxtgm2HbZFtkm2UbZZtl22YbaptrG20bbdtuW29bb9txG3Ibcptzm3PbdZt223dbd9t4G3ibeVt6W3vbfBt9G32bfxtAG4Ebh5uIm4nbjJuNm45bjtuPG5EbkVuSG5JbktuT25RblJuU25UblduXG5dbl5uYm5jbmhuc257bn1ujW6TbpluoG6nbq1urm6xbrNuu26/bsBuwW7DbsduyG7Kbs1uzm7Pbutu7W7ubvlu+279bgRvCG8KbwxvDW8WbxhvGm8bbyZvKW8qby9vMG8zbzZvO288by1vT29Rb1JvU29Xb1lvWm9db15vYW9ib2hvbG99b35vg2+Hb4hvi2+Mb41vkG+Sb5NvlG+Wb5pvn2+gb6Vvpm+nb6hvrm+vb7BvtW+2b7xvxW/Hb8hvym/ab95v6G/pb/Bv9W/5b/xv/W8AcAVwBnAHcA1wF3AgcCNwL3A0cDdwOXA8cENwRHBIcElwSnBLcFRwVXBdcF5wTnBkcGVwbHBucHVwdnB+cIFwhXCGcJRwlXCWcJdwmHCbcKRwq3CwcLFwtHC3cMpw0XDTcNRw1XDWcNhw3HDkcPpwA3EEcQVxBnEHcQtxDHEPcR5xIHErcS1xL3EwcTFxOHFBcUVxRnFHcUpxS3FQcVJxV3FacVxxXnFgcWhxeXGAcYVxh3GMcZJxmnGbcaBxonGvcbBxsnGzcbpxv3HAccFxxHHLccxx03HWcdlx2nHccfhx/nEAcgdyCHIJchNyF3Iach1yH3IkcityL3I0cjhyOXJBckJyQ3JFck5yT3JQclNyVXJWclpyXHJecmByY3JocmtybnJvcnFyd3J4cntyfHJ/coRyiXKNco5yk3KbcqhyrXKucrFytHK+csFyx3LJcsxy1XLWcthy33LlcvNy9HL6cvty/nICcwRzBXMHcwtzDXMScxNzGHMZcx5zInMkcydzKHMsczFzMnM1czpzO3M9c0NzTXNQc1JzVnNYc11zXnNfc2BzZnNnc2lza3Nsc25zb3Nxc3dzeXN8c4BzgXODc4VzhnOOc5Bzk3OVc5dzmHOcc55zn3Ogc6JzpXOmc6pzq3Otc7Vzt3O5c7xzvXO/c8VzxnPJc8tzzHPPc9Jz03PWc9lz3XPhc+Nz5nPnc+lz9HP1c/dz+XP6c/tz/XP/cwB0AXQEdAd0CnQRdBp0G3QkdCZ0KHQpdCp0K3QsdC10LnQvdDB0MXQ5dEB0Q3REdEZ0R3RLdE10UXRSdFd0XXRidGZ0Z3RodGt0bXRudHF0cnSAdIF0hXSGdId0iXSPdJB0kXSSdJh0mXSadJx0n3SgdKF0o3SmdKh0qXSqdKt0rnSvdLF0snS1dLl0u3S/dMh0yXTMdNB003TYdNp023TedN905HTodOp063TvdPR0+nT7dPx0/3QGdRJ1FnUXdSB1IXUkdSd1KXUqdS91NnU5dT11PnU/dUB1Q3VHdUh1TnVQdVJ1V3VedV91YXVvdXF1eXV6dXt1fHV9dX51gXWFdZB1knWTdZV1mXWcdaJ1pHW0dbp1v3XAdcF1xHXGdcx1znXPddd13HXfdeB14XXkded17HXude918XX5dQB2AnYDdgR2B3YIdgp2DHYPdhJ2E3YVdhZ2GXYbdhx2HXYediN2JXYmdil2LXYydjN2NXY4djl2OnY8dkp2QHZBdkN2RHZFdkl2S3ZVdll2X3ZkdmV2bXZudm92cXZ0doF2hXaMdo12lXabdpx2nXafdqB2onajdqR2pXamdqd2qHaqdq12vXbBdsV2yXbLdsx2znbUdtl24Hbmduh27HbwdvF29nb5dvx2AHcGdwp3DncSdxR3FXcXdxl3GnccdyJ3KHctdy53L3c0dzV3Nnc5dz13PndCd0V3RndKd013TndPd1J3VndXd1x3Xndfd2B3Yndkd2d3andsd3B3cndzd3R3end9d4B3hHeMd413lHeVd5Z3mnefd6J3p3eqd653r3exd7V3vnfDd8l30XfSd9V32Xfed9934Hfkd+Z36nfsd/B38Xf0d/h3+3cFeAZ4CXgNeA54EXgdeCF4IngjeC14LngweDV4N3hDeER4R3hIeEx4TnhSeFx4XnhgeGF4Y3hkeGh4anhueHp4fniKeI94lHiYeKF4nXieeJ94pHioeKx4rXiweLF4snizeLt4vXi/eMd4yHjJeMx4znjSeNN41XjWeOR423jfeOB44XjmeOp48njzeAB59nj3ePp4+3j/eAZ5DHkQeRp5HHkeeR95IHkleSd5KXkteTF5NHk1eTt5PXk/eUR5RXlGeUp5S3lPeVF5VHlYeVt5XHlneWl5a3lyeXl5e3l8eX55i3mMeZF5k3mUeZV5lnmYeZt5nHmheah5qXmrea95sXm0ebh5u3nCecR5x3nIecp5z3nUedZ52nnded554HnieeV56nnree158Xn4efx5AnoDegd6CXoKegx6EXoVeht6Hnoheid6K3otei96MHo0ejV6OHo5ejp6RHpFekd6SHpMelV6VnpZelx6XXpfemB6ZXpnemp6bXp1enh6fnqAeoJ6hXqGeop6i3qQepF6lHqeeqB6o3qserN6tXq5ert6vHrGesl6zHrOetF623roeul663rsevF69Hr7ev16/noHexR7H3sjeyd7KXsqeyt7LXsuey97MHsxezR7PXs/e0B7QXtHe057VXtge2R7Zntpe2p7bXtve3J7c3t3e4R7iXuOe5B7kXuWe5t7nnuge6V7rHuve7B7snu1e7Z7unu7e7x7vXvCe8V7yHvKe9R71nvXe9l72nvbe+h76nvye/R79Xv4e/l7+nv8e/57AXwCfAN8BHwGfAl8C3wMfA58D3wZfBt8IHwlfCZ8KHwsfDF8M3w0fDZ8OXw6fEZ8SnxVfFF8UnxTfFl8WnxbfFx8XXxefGF8Y3xnfGl8bXxufHB8cnx5fHx8fXyGfId8j3yUfJ58oHymfLB8tny3fLp8u3y8fL98xHzHfMh8yXzNfM9803zUfNV813zZfNp83XzmfOl863z1fAN9B30IfQl9D30RfRJ9E30WfR19Hn0jfSZ9Kn0tfTF9PH09fT59QH1BfUd9SH1NfVF9U31XfVl9Wn1cfV19ZX1nfWp9cH14fXp9e31/fYF9gn2DfYV9hn2IfYt9jH2NfZF9ln2XfZ19nn2mfad9qn2zfbZ9t325fcJ9w33EfcV9xn3Mfc19zn3Xfdl9AH7ifeV95n3qfet97X3xffV99n35ffp9CH4QfhF+FX4Xfhx+HX4gfid+KH4sfi1+L34zfjZ+P35EfkV+R35OflB+Un5Yfl9+YX5ifmV+a35ufm9+c354fn5+gX6Gfod+in6NfpF+lX6Yfpp+nX6efjx/O389fz5/P39Df0R/R39Pf1J/U39bf1x/XX9hf2N/ZH9lf2Z/bX9xf31/fn9/f4B/i3+Nf49/kH+Rf5Z/l3+cf6F/on+mf6p/rX+0f7x/v3/Af8N/yH/Of89/23/ff+N/5X/of+x/7n/vf/J/+n/9f/5//38HgAiACoANgA6AD4ARgBOAFIAWgB2AHoAfgCCAJIAmgCyALoAwgDSANYA3gDmAOoA8gD6AQIBEgGCAZIBmgG2AcYB1gIGAiICOgJyAnoCmgKeAq4C4gLmAyIDNgM+A0oDUgNWA14DYgOCA7YDugPCA8oDzgPaA+YD6gP6AA4ELgRaBF4EYgRyBHoEggSSBJ4EsgTCBNYE6gTyBRYFHgUqBTIFSgVeBYIFhgWeBaIFpgW2Bb4F3gYGBkIGEgYWBhoGLgY6BloGYgZuBnoGiga6BsoG0gbuBy4HDgcWByoHOgc+B1YHXgduB3YHegeGB5IHrgeyB8IHxgfKB9YH2gfiB+YH9gf+BAIIDgg+CE4IUghmCGoIdgiGCIoIogjKCNII6gkOCRIJFgkaCS4JOgk+CUYJWglyCYIJjgmeCbYJ0gnuCfYJ/goCCgYKDgoSCh4KJgoqCjoKRgpSCloKYgpqCm4KggqGCo4KkgqeCqIKpgqqCroKwgrKCtIK3grqCvIK+gr+CxoLQgtWC2oLgguKC5ILoguqC7YLvgvaC94L9gv6CAIMBgweDCIMKgwuDVIMbgx2DHoMfgyGDIoMsgy2DLoMwgzODN4M6gzyDPYNCg0ODRINHg02DToNRg1WDVoNXg3CDeIN9g3+DgIOCg4SDhoONg5KDlIOVg5iDmYObg5yDnYOmg6eDqYOsg76Dv4PAg8eDyYPPg9CD0YPUg92DU4Pog+qD9oP4g/mD/IMBhAaECoQPhBGEFYQZhK2DL4Q5hEWER4RIhEqETYRPhFGEUoRWhFiEWYRahFyEYIRkhGWEZ4RqhHCEc4R0hHaEeIR8hH2EgYSFhJKEk4SVhJ6EpoSohKmEqoSvhLGEtIS6hL2EvoTAhMKEx4TIhMyEz4TThNyE54TqhO+E8ITxhPKE94QyhfqE+4T9hAKFA4UHhQyFDoUQhRyFHoUihSOFJIUlhSeFKoUrhS+FM4U0hTaFP4VGhU+FUIVRhVKFU4VWhVmFXIVdhV6FX4VghWGFYoVkhWuFb4V5hXqFe4V9hX+FgYWFhYaFiYWLhYyFj4WThZiFnYWfhaCFooWlhaeFtIW2hbeFuIW8hb2FvoW/hcKFx4XKhcuFzoWthdiF2oXfheCF5oXohe2F84X2hfyF/4UAhgSGBYYNhg6GEIYRhhKGGIYZhhuGHoYhhieGKYY2hjiGOoY8hj2GQIZChkaGUoZThlaGV4ZYhlmGXYZghmGGYoZjhmSGaYZshm+GdYZ2hneGeoaNhpGGloaYhpqGnIahhqaGp4aohq2GsYazhrSGtYa3hriGuYa/hsCGwYbDhsWG0YbShtWG14bahtyG4IbjhuWG54aIhvqG/Ib9hgSHBYcHhwuHDocPhxCHE4cUhxmHHocfhyGHI4cohy6HL4cxhzKHOYc6hzyHPYc+h0CHQ4dFh02HWIddh2GHZIdlh2+HcYdyh3uHg4eEh4WHhoeHh4iHiYeLh4yHkIeTh5WHl4eYh5mHnoegh6OHp4esh62Hroexh7WHvoe/h8GHyIfJh8qHzofVh9aH2Yfah9yH34fih+OH5Ifqh+uH7Yfxh/OH+If6h/+HAYgDiAaICYgKiAuIEIgZiBKIE4gUiBiIGogbiByIHogfiCiILYguiDCIMog1iDqIPIhBiEOIRYhIiEmISohLiE6IUYhViFaIWIhaiFyIX4hgiGSIaYhxiHmIe4iAiJiImoibiJyIn4igiKiIqoi6iL2IvojAiMqIy4jMiM2IzojRiNKI04jbiN6I54jviPCI8Yj1iPeIAYkGiQ2JDokPiRWJFokYiRmJGokciSCJJokniSiJMIkxiTKJNYk5iTqJPolAiUKJRYlGiUmJT4lSiVeJWolbiVyJYYliiWOJa4luiXCJc4l1iXqJe4l8iX2JiYmNiZCJlImViZuJnImfiaCJpYmwibSJtYm2ibeJvInUidWJ1onXidiJ5YnpieuJ7YnxifOJ9on5if2J/4kEigWKB4oPihGKEooUihWKHoogiiKKJIomiiuKLIovijWKN4o9ij6KQIpDikWKR4pJik2KTopTilaKV4pYilyKXYphimWKZ4p1inaKd4p5inqKe4p+in+KgIqDioaKi4qPipCKkoqWipeKmYqfiqeKqYquiq+Ks4q2ireKu4q+isOKxorIismKyorRitOK1IrViteK3YrfiuyK8Ir0ivWK9or8iv+KBYsGiwuLEYscix6LH4sKiy2LMIs3izyLQotDi0SLRYtGi0iLUotTi1SLWYtNi16LY4tti3aLeIt5i3yLfouBi4SLhYuLi42Lj4uUi5WLnIuei5+LOIw5jD2MPoxFjEeMSYxLjE+MUYxTjFSMV4xYjFuMXYxZjGOMZIxmjGiMaYxtjHOMdYx2jHuMfoyGjIeMi4yQjJKMk4yZjJuMnIykjLmMuozFjMaMyYzLjM+M1ozVjNmM3YzhjOiM7IzvjPCM8oz1jPeM+Iz+jP+MAY0DjQmNEo0XjRuNZY1pjWyNbo1/jYKNhI2IjY2NkI2RjZWNno2fjaCNpo2rjayNr42yjbWNt425jbuNwI3FjcaNx43IjcqNzo3RjdSN1Y3XjdmN5I3ljeeN7I3wjbyN8Y3yjfSN/Y0BjgSOBY4GjguOEY4UjhaOII4hjiKOI44mjieOMY4zjjaON444jjmOPY5AjkGOS45Njk6OT45UjluOXI5djl6OYY5ijmmObI5tjm+OcI5xjnmOeo57joKOg46JjpCOko6VjpqOm46djp6Ooo6njqmOrY6ujrOOtY66jruOwI7BjsOOxI7Hjs+O0Y7UjtyO6I7ujvCO8Y73jvmO+o7tjgCPAo8HjwiPD48QjxaPF48Yjx6PII8hjyOPJY8njyiPLI8tjy6PNI81jzaPN486j0CPQY9Dj0ePT49Rj1KPU49Uj1WPWI9dj16PZY+dj6CPoY+kj6WPpo+1j7aPuI++j8CPwY/Gj8qPy4/Nj9CP0o/Tj9WP4I/jj+SP6I/uj/GP9Y/2j/uP/o8CkASQCJAMkBiQG5AokCmQL5AqkCyQLZAzkDSQN5A/kEOQRJBMkFuQXZBikGaQZ5BskHCQdJB5kIWQiJCLkIyQjpCQkJWQl5CYkJmQm5CgkKGQopClkLCQspCzkLSQtpC9kMyQvpDDkMSQxZDHkMiQ1ZDXkNiQ2ZDckN2Q35DlkNKQ9pDrkO+Q8JD0kP6Q/5AAkQSRBZEGkQiRDZEQkRSRFpEXkRiRGpEckR6RIJElkSKRI5EnkSmRLpEvkTGRNJE2kTeROZE6kTyRPZFDkUeRSJFPkVORV5FZkVqRW5FhkWSRZ5FtkXSReZF6kXuRgZGDkYWRhpGKkY6RkZGTkZSRlZGYkZ6RoZGmkaiRrJGtka6RsJGxkbKRs5G2kbuRvJG9kb+RwpHDkcWR05HUkdeR2ZHakd6R5JHlkemR6pHske2R7pHvkfCR8ZH3kfmR+5H9kQCSAZIEkgWSBpIHkgmSCpIMkhCSEpITkhaSGJIckh2SI5IkkiWSJpIoki6SL5IwkjOSNZI2kjiSOZI6kjySPpJAkkKSQ5JGkkeSSpJNkk6ST5JRkliSWZJckl2SYJJhkmWSZ5JokmmSbpJvknCSdZJ2kneSeJJ5knuSfJJ9kn+SiJKJkoqSjZKOkpKSl5KZkp+SoJKkkqWSp5KokquSr5KykraSuJK6kruSvJK9kr+SwJLBksKSw5LFksaSx5LIksuSzJLNks6S0JLTktWS15LYktmS3JLdkt+S4JLhkuOS5ZLnkuiS7JLukvCS+ZL7kv+SAJMCkwiTDZMRkxSTFZMckx2THpMfkyGTJJMlkyeTKZMqkzOTNJM2kzeTR5NIk0mTUJNRk1KTVZNXk1iTWpNek2STZZNnk2mTapNtk2+TcJNxk3OTdJN2k3qTfZN/k4CTgZOCk4iTipOLk42Tj5OSk5WTmJObk56ToZOjk6STppOok6uTtJO1k7aTupOpk8GTxJPFk8aTx5PJk8qTy5PMk82T05PZk9yT3pPfk+KT5pPnk/mT95P4k/qT+5P9kwGUApQElAiUCZQNlA6UD5QVlBaUF5QflC6UL5QxlDKUM5Q0lDuUP5Q9lEOURZRIlEqUTJRVlFmUXJRflGGUY5RolGuUbZRulG+UcZRylISUg5R4lXmVfpWElYiVjJWNlY6VnZWelZ+VoZWmlamVq5WslbSVtpW6lb2Vv5XGlciVyZXLldCV0ZXSldOV2ZXald2V3pXfleCV5JXmlR2WHpYiliSWJZYmliyWMZYzljeWOJY5ljqWPJY9lkGWUpZUllaWV5ZYlmGWbpZ0lnuWfJZ+ln+WgZaCloOWhJaJlpGWlpaalp2Wn5aklqWWppaplq6Wr5azlrqWypbSlrJd2Jbalt2W3pbflumW75bxlvqWApcDlwWXCZcalxuXHZchlyKXI5colzGXM5dBl0OXSpdOl0+XVZdXl1iXWpdbl2OXZ5dql26Xc5d2l3eXeJd7l32Xf5eAl4mXlZeWl5eXmZeal56Xn5eil6yXrpexl7KXtZe2l7iXuZe6l7yXvpe/l8GXxJfFl8eXyZfKl8yXzZfOl9CX0ZfUl9eX2JfZl92X3pfgl9uX4Zfkl++X8Zf0l/eX+Jf6lweYCpgZmA2YDpgUmBaYHJgemCCYI5gmmCuYLpgvmDCYMpgzmDWYJZg+mESYR5hKmFGYUphTmFaYV5hZmFqYYphjmGWYZphqmGyYq5itmK6YsJi0mLeYuJi6mLuYv5jCmMWYyJjMmOGY45jlmOaY55jqmPOY9pgCmQeZCJkRmRWZFpkXmRqZG5kcmR+ZIpkmmSeZK5kxmTKZM5k0mTWZOZk6mTuZPJlAmUGZRplHmUiZTZlOmVSZWJlZmVuZXJlemV+ZYJmbmZ2Zn5mmmbCZsZmymbWZuZm6mb2Zv5nDmcmZ05nUmdmZ2pncmd6Z55nqmeuZ7JnwmfSZ9Zn5mf2Z/pkCmgOaBJoLmgyaEJoRmhaaHpogmiKaI5okmieaLZoumjOaNZo2mjiaR5pBmkSaSppLmkyaTppRmlSaVppdmqqarJqumq+aspq0mrWatpq5mruavpq/msGaw5rGmsiazprQmtKa1ZrWmtea25rcmuCa5Jrlmuea6ZrsmvKa85r1mvma+pr9mv+aAJsBmwKbA5sEmwWbCJsJmwubDJsNmw6bEJsSmxabGZsbmxybIJsmmyubLZszmzSbNZs3mzmbOps9m0ibS5tMm1WbVptXm1ubXpthm2ObZZtmm2ibaptrm2ybbZtum3ObdZt3m3ibeZt/m4CbhJuFm4abh5uJm4qbi5uNm4+bkJuUm5qbnZuem6abp5upm6ybsJuxm7Kbt5u4m7ubvJu+m7+bwZvHm8ibzpvQm9eb2Jvdm9+b5Zvnm+qb65vvm/Ob95v4m/mb+pv9m/+bAJwCnAucD5wRnBacGJwZnBqcHJwenCKcI5wmnCecKJwpnCqcMZw1nDacN5w9nEGcQ5xEnEWcSZxKnE6cT5xQnFOcVJxWnFicW5xdnF6cX5xjnGmcapxcnGucaJxunHCccpx1nHece5zmnPKc95z5nAudAp0RnRedGJ0cnR2dHp0vnTCdMp0znTSdOp08nUWdPZ1CnUOdR51KnVOdVJ1fnWOdYp1lnWmdap1rnXCddp13nXudfJ1+nYOdhJ2GnYqdjZ2OnZKdk52VnZadl52YnaGdqp2sna6dsZ21nbmdvJ2/ncOdx53Jncqd1J3Vndad153and6d353gneWd553pneud7p3wnfOd9J3+nQqeAp4Hng6eEJ4RnhKeFZ4WnhmeHJ4dnnqee558noCegp6DnoSehZ6Hno6ej56Wnpiem56enqSeqJ6snq6er56wnrOetJ61nsaeyJ7LntWe357knuee7J7tnu6e8J7xnvKe9Z74nv+eAp8DnwmfD58QnxGfEp8UnxafF58ZnxqfG58fnyKfJp8qnyufL58xnzKfNJ83nzmfOp88nz2fP59Bn0OfRJ9Fn0afR59Tn1WfVp9Xn1ifWp9dn16faJ9pn22fbp9vn3CfcZ9zn3Wfep99n4+fkJ+Rn5KflJ+Wn5efnp+hn6Kfo5+lnwAAOwA8AF0AXgC8AMYAywDVANwA7QD0APwADQEUARoBeAF7AXwBfQF+AYIBjAGNAZABkQGTAZQBlgGgAaUBqwGwAbEBswG2AbcBuAG7AbwBwAHBAcIBwwHEAcUBxgHHAdYB5gECAhwCKwIsAi4CLwIwAjQCRAJgAnoCiQKKAowCjQKOApIC5QLwAkYDTgNUA1UDbwN+A4QDhQOfAwH/5v89/+P/MTFwIQAAYCEAAJEDowMAALEDwwMAAAAAlTMTIZgzxDOjM5kzyjONM88ziDPIM6czsDOAM7ozkDMmIcAzijPWM8UzrTPbM6kz3TPQM9MzwzPJM9wzxjMAAAAAYDLQJGAkvQBTIbwAvgBbIQAAADKcJHQkuQCyAHQgfyCBIEEwAAChMAAAEAQBBBYEAAAwBFEENgQAAAIABAAJAAoADAAPABYAFwAdAB8AIgAsAC0AMwA2ADkATABOAFAAUQBWAFcAWQBcAF8AZgBnAG0AbgBwAHcAeAB7AH0AgACDAIsAjACUAJYAmACZAJoAnACdAJ4AowClAKgAqQCuAK8AsAC2ALkAvADEAMYAzADOANEA2ADZANoA4ADjAOYA7gDvAPcA+QD7AP8AAAEBAQYBCAELARYBHAEuATYBOAE7AUIBQwFLAU4BUQFkAWYBaAFuAW8BcAF2AZEBkwGVAZYBmwGcAZ0BoAGhAaIBpQGmAasBrAGvAbEBswG2Ab0BvgHEAcoB+QH6Af0BBAIFAgsCDQIYAhoCGwIhAiQCJwIxAjUCNwJSAlQCVQJWAl0CXgJfAmMCaQJ0AnoCjQKTApYCmQKgAqMCqQLEAsYCyQLPAtAC0QLWAt0C6ALuAvAC8wL6AvwCAwMGAwkDEAMaAzUDNwM4AzkDOgM+Az8DQANDA2EDYwNmA20DbgNvA3UDdgN4A30DfgN/A4ADggOFA4wDjQOTA5UDmAOfA6MDxQPGA8kDygPOA88D1APWA9kD4APhA+cD6QPsA/MD9QP3A/oD/QMUBBYEGQQaBB8EIAQhBCUEKAQrBDYEWQRcBF8EZgRnBG8EcQR0BHwEfQR+BIQEhgSIBI8EkASRBJcEqgSxBMwEzwTSBNkE4wTpBPAE8wT5BPsE/gQDBQQFBQUIBQkFDAUPBSIFJAUnBSgFLQUuBS8FMwU0BTUFNwU6BTsFPgVABUMFSgVLBVEFiAWJBYsFjAWQBZEFkgWTBZUFlgWYBZsFogWjBakFrAWvBboFwAXDBdoF3AXeBd8F4AXjBeQF5QXmBecF6QXsBe8FAgYVBhwGHwYiBikGKgYyBk0GTwZSBlkGWgZbBmEGdAZ7Bo8GlQaYBpsGowakBqUGqwauBrEGuAa8BsIGxAbGBscGzAbNBs4G1AbvBvEG8wb6BvsGAAcCBwUHDAcNBxIHFAcXBx4HHwddB18HYgdjB2cHaAdtB28Hcgd5B3oHgAeTB7YHuAe7B8cHzQfUB+cHAggFCDgIOgg9CEMIRwhpCIQIhwiKCJEIlAi2CLgIugjBCMIIygjNCNAI1wjhCOQI5wjuCO8I8Aj2CPgI+wgCCQMJBgkICQsJEgkTCRkJGwkpCSoJTAlOCVEJWAlZCV4JYAljCWoJawlsCXIJdAl3CX4JfwmFCYgJlAmVCZ0JnwmiCakJqgmrCbEJtAnECd4J5QnoCesJ8gnzCfQJ+gn9CQAKCAoJCgoKEAoSChUKHAodCh4KJAo3Cj4KWQpbCl4KZQpnCmgKbgpwCnMKegp7CnwKggqECocKjgqPCpAKkgqvCrEKtAq7CrwKvQrDCsUKxgrLCswKzQrPCtAK0grVCtwK3QriCugK9AoWCxgLGwscCyELIgsjCycLKQssCzMLNAs6CzwLPwtJC0oLTgtpC2oLbQtuC3MLdAt1C3sLfguNC68Lsgu1C70Lvgu/C8ULyAvLC9ML1AvcC90L3wvkC+UL5gvpC+oL7QvwC/gL+QsBDBwMHwwiDDUMOAw7DEIMRAxMDE8MUgxZDFsMfwyBDIMMhAyJDIoMiwyMDI4MkAyUDJUMlgyZDJsMnQygDKcMqAyrDK0Mrwy7DOEM4wzlDOYM6wzsDO0M8gz0DPYM/Qz+DAQNBg0JDRENEg0VDRcNGg0xDTINNQ08DT0NPg1EDUcNVg1dDXANdw15DXwNgw2NDZANpw2pDasNsA2xDbINtQ22Db0NyA3PDeoN7A3vDfsNAQ4EDgcODg4QDhEOFw4ZDhwOIw4kDkgOSg5NDk4OUw5UDlUOWQ5bDl4OXw5kDmUOag5sDm8Odg53Dn0Oiw6yDrQOtg69Dr8OxQ7ZDt8O7Q7uDhAPEg8VDxwPHw9dD3gPjA+SD5QPlw+eD6APoQ/7Dw8QFRAYEBsQIhBIEEoQTRBUEFUQVhBcEF0QXxBkEGUQaBBqEGwQbxB2EHcQfRB/EIIQiRCKEIsQkRCUEJcQnhCiEKgQqhCrEK8QsBC0ELUQtxC6EMEQwhDIEMoQzRDUENUQ2xDeEOEQ7RDzEPQQ9xD4EP0Q/hD/EAIRBBEGEQkRFREbER4RIREoESoRMRE0ETcRPhE/EUcRSRFMEVMRVBFVEVsRXRFfEWYRZxFoEWkRahFrEX4RhRGHEYoRkRGVEZsRnRGgEacRqBGpEa8RtRG8Eb4RvxHFEccRyhHQEdER0hH0EfYR+BH+Ef8RABIEEgUSBhIJEhASEhIXEhkSHBIjEiUSQBJiEmQSZxJoEm0SbxJ1EngSexKuEsUSxxLJEsoSzxLSEtgS2hLpEvASAxMKEw0TEBMXEyETPBM+E0ETSBNLE1ETZBNrE4YTiRO1E7sTvRPAE8ETxRPPE9IT1RPcE+cT6RPsE/MT9BP1E/sT/RP+EwIUAxQGFAcUCRQMFBMUFBQaFBwUHxQhFCUUJhQnFCoUKxQuFDEUORRDFEUURhRLFEwUTRROFFAUUxRaFFsUXBRiFGMUZhRnFGsUbhRxFHQUexR8FIMUhRSIFIkUixSMFI0UjhSSFJQUlxSeFJ8UpRSnFLIUtBS1FLsUvRTAFMcUyBTJFM8U0RTUFNsU3BTdFOMU5RToFO0U7hTvFPUU9xT6FAEVAxUJFQsVDhUVFRgVHhUgFSMVKhUrFSwVMhU0FTcVPhU/FUAVQRVFFUcVShVPFVAVURVSFVUVWBVfFWEVaRVrFW4VchVzFXYVdxV5FXoVexWAFYEVhhWIFYsVkhWTFZkVmxWcFZ0VpBWoFa4VsRW0FccVyRXMFc0V0hXTFdQV2RXbFd4V5RXmFecV7RXwFfMV+hX8FQIWHRYfFiIWIxYoFikWKhYtFjMWOxY8Fj0WAqwFrAusGKwerCGsJawurDKsOqw9rEGsTKxOrFWsWaxdrHKsdax5rHusgqyHrI2skayVrJ6soqyrrK2ssay6rL6swqzFrMmszazWrNis4qzlrOms66ztrPKs9Kz3rP6sAa0FrQetDq0QrRKtGa0drSGtKq0urTatOa09rUatSK1KrVGtVa1ZrWKtZK1urXGtd61+rYCtg62KrY2tka2eraWtuK3CrcWtya3SrdSt3a3hreWt+q39rQKuCq4Mrg6uFa4yrjWuOa47rkKuRK5HrkuuT65RrlWuV65ermKuZq5qrm2uca56rn6uhq6Nrr+uwa7Frs6u0q7art2u6a7sru6u9a75rv2uCa8OrxGvLq8xrzOvNa8+r0CvRK9Kr1GvXq9mr3qvga+Fr4mvkq+Wr52vuq+9r8Gvyq/Mr8+v1a/dr+qv8q/1r/mvArAFsA2wEbAVsB6wKbBGsEmwS7BNsE+wVrBYsFqwXrB+sIGwhbCOsJCwkrCbsJ2wo7CqsLCwsrC2sLmwvbDGsMqw0rDVsNmw4bDmsAqxDbERsRSxGrEesSaxKbEtsTaxOrFCsUWxSbFSsVaxWbFdsWGxerF9sYGxg7GKsYyxjrGVsZmxnbGpsc2x0bHVsd6x4LHqse2x8bH6sfyx/rEGsgmyDbIWshiyGrIhsjWyPbJZsl2yYbJqsnayfbKGsoqykrKVspuyorKksqeyq7KtsrGytbLKss2y0bLTstqy3LLesuOy57LpsvCy9rL8sgKzBbMJsxKzFrMds1ezWbNds2CzZrNos2qzbLNvs3KzdbN5s4KzhrONs5GzlbOis6mzrbPGs8mzzbPPs9Gz1rPYs9qz3LPes+Gz5bPps/2zEbQZtB20IbQqtCy0NbRStFW0WbRitGS0ZrRttIG0ibSetKW0qbSttLa0uLS6tMG0xbTJtNG01rTetOG05bTntO608LTytPm0FrUZtR21JrUrtTK1NbU5tUK1RrVOtVG1VbVetWK1orWltam1rLWytba1vrXBtcW1zrXStdm17bUSthW2GbYmti22NbZJtmW2abaetqG2pbattrK21bbxtvW2+bYCtwa3KrcttzG3Orc8t0W3SbdNt1a3Ybdlt2m3crd0t3a3freBt4W3jreTt5q3nbeht6q3rre2t7m3yLfKt+638bf1t/63ArgKuA24EbgauBy4HrgmuCm4Lbg2uDq4QbhFuFK4VLheuGG4ZbhuuHC4crh5uH24jripuLG4tbi5uMK4xLjGuM240bjVuN644LjiuOq47bjxuPq4/Lj+uAW5GbkhuT65QblFuU25ULlSuVq5XblhuWq5bLluuXa5ebl9uYa5iLmLuY+5rrmxubW5vrnAucK5yrnNudO52rncud+54rnmuem57bn2ufu5AroJuha6Oro9ukG6Q7pKuky6T7pWulm6Xbpmumq6crp1unm6hrqIuo26qrqturG6s7q6ury6vrrFusm62rr9ugG7BbsOuxC7ErsZux27Ibsquyy7N7s5uz+7RrtIu0q7TrtRu1W7Wbtiu2S7bbuJu427kbulu6m7rbu1u7i7wbvFu8m70bvUu/q7/bsBvAO8CrwOvBC8ErwZvCC8JrwovCq8LrwyvDW8ObxCvEa8SrxOvFG8XryGvIm8jbyPvJa8mLybvKK8pbypvLK8try+vMG8xbzOvNK81rzZvN2897z5vP28Br0IvQq9Eb0VvSW9Lb1BvUq9Tb1RvVq9Zb1pvYK9hb2LvZK9lL2WvZu9nb2lvbG9ub3Wvdm93b3qvfG99b35vQG+BL4Gvg6+Eb4Vvh6+IL5Gvkm+Tb5Pvla+WL5cvmK+Zb5pvmu+cr52vn6+gb6Fvo6+kr6avqm+0r7Vvtm+4b7mvu2+Ar8Kvxq/Hr9Cv0W/Sb9Sv1a/lb+xv8a/zr/Rv9W/3b/gv+K/PcBSwFnAXcBhwGrAksCVwJnAosCkwKbArsCxwLfAvsDCwMbAysDNwNHA2sDewObA6cDtwPbA+MD6wAHBBcEJwRHBFsEhwSXBKMEuwTLBN8E6wT3BQcFKwU7BVsFZwV3BZsFqwXHBdcF5wYbBj8GRwZXBl8GewaDBosGmwarBrcGxwb7BxcHJwc3B1cHZweHB5cHpwfLB9MH+wQHCBcIOwhDCEsIawh3CIcIqwizCLsIwwjPCNcJJwlLCVcJZwmHCZsJuwnHCdcJ+woDCgsKKwpHCmcKcwp7CpsKpwq7CtsK4wrrC3sLhwuXC7sLwwvLC98L6wv3CAcMKww7DFsMZwx3DJsMqw0bDasNtw3HDc8N6w37DhcOJw43DwcPaw93D4cPjw+rD7sP2w/nDCcQRxCXELcQxxDXEPsRJxGbEacRtxHbEesSBxJXEncS5xL3E6sTyxPXE+cT7xALFDcURxRXFHcUqxS3FMcU6xTzFPsVGxUvFT8VWxVrFX8VixWXFacVyxXbFfsWBxYXFiMWOxZDFksWWxZnFncWhxarFtsW6xb/Fy8XNxc/F0sXVxdnF4sXkxebF78XxxfXF+MUCxgnGDcYRxhrGHcYmxinGL8YxxjbGOMY6xjzGQsZFxknGUsZWxl7GYcZtxnDGcsZ6xn3GgcaKxozGjsaWxpnGncamxqjGqsayxrXGu8bCxsTGxsbOxtHG1cbexuLG6sbtxvHG+sb+xgbHCccNxxbHGMcaxyLHJccpxzLHNMc2xzjHPsdBx0XHS8dOx1DHWcddx2HHacdsx3bHecd/x4bHi8ePx5LHlceZx5vHosenx67Hsce1x77HwsfKx83Hz8fRx9nH3sflx+nH7ccCyAXICcgLyBLIFMgXyB7IIcglyC7IMMgyyDnIPchByErITshVyHLIdch5yHvIgsiEyIjIjsiVyJ7IoMiiyAAAAwAWABwAHwAiACkAKgArADEAMwBDAEkASwBOAFMAVABVAFsAbgB1AJAAkgCVAJwAnQClAKgAqwCyAL0AvwDCAMkAygDLAO0A7wDxAPIA9wD4APkA+wD8AP4A/wAAAQIBBgEHAQ0BDwESARkBGgEgASMBMwFVAVcBWgFhAWIBaAF8AYIBlQG4AboBvQHEAcUBxgHHAcsB0QHcAeMB9gH9AQACAwIKAikCLwIxAjQCOwI+AkQCVwJ5ApQCrwK+AsACwQLjAuUC6ALvAvIC9gL4AvkC+gIBAwIDBwMJAwwDEwMUAxoDHQMeAx8DJgMqA0wDTgNRA1gDWQNfA2EDZANrA2wDbQNzA3YDhQOMA48DnwOlA6cDqgOxA7IDswO5A7wDvwPLA+0D8APzA/oD+wP8AwIEEQQcBB4EIQQoBCkEKgQwBEMESgRNBGQEZwRqBHEEcgRzBHkEfAR/BIYEigSQBJIElQScBJ0EngTABMIExATKBMsEzATSBNQE1wTeBN8E4ATmBOgE6wTyBPME+QQMBS4FMAUyBTkFOgVABUIFRQVMBU0FTgVUBVcFWgVhBWIFaAWDBYUFiAWPBZAFkQWXBZkFnAWjBacFrQXBBccFzgXhBfwF/gUBBggGCQYKBhAGEwYWBiIGKAY8BkIGRAZHBk4GTwZQBlYGWQZcBmMGbgZwBnMGegZ9Bp8GoQakBqsGrAatBrMGtQa4Br4GvwbFBscGygbRBtIG2AbsBg4HEAcTBxQHGQcaByAHIgclBywHLQcuBzQHNwdGB00HUAdnB2kHbAdzB3QHdQd5B3oHfQeUB68HsgfAB8EHxwfiB+QH5wfuB+8H8Af2BwkIEAgrCC0IMAg3CDoIQAhDCEYITQhRCFcIWQhbCFwIYQhiCGoIbQhwCHcIgQiDCIYIjQiOCI8IlQiWCJkImgifCKAIowilCKcIqgixCLIIuAjuCPAI8wj6CPsIAQkDCQYJDQkOCQ8JFQkYCRsJIgkkCSoJMQk5CToJQglECUcJTglPCVAJVglqCYwJjwmmCakJrAm0CbUJvQm/CcEJwgnHCcgJyQnPCeMJBQoICgsKEgoUChwKHwoiCikKKwosCjIKNQo4Cj8KQApkCmYKaQpwCnEKcgp4CnoKfQqBCoMKhAqFCosKjQqQCpcKmAqeCrIK1ArWCtkK2grfCuAK4QrnCukK7ArzCvQK9Qr7Cv0KAAsHCwgLDgsRCxQLHAsmCygLKwsvCzELMgszCzYLOAs6Cz0LRwtIC04LUAteC18LZQtnC2oLcgtzC3QLegt9C4ALiAuJC5ELkwuWC5oLnAueC58LpQuoC6sLsgu2C7wLvgvBC80L0wvVC9gL3wvgC+EL5wvpC+wL8wv1C/YL/Av+C/8LBQwGDAcMCgwMDA8MEgwZDBwMIgwkDCcMLgwvDDAMpcipyL7IxcjJyM3I1sjYyNrI4sjlyPbI/sgByQfJDskQyRLJGcktyTXJUslVyVnJYslkyW3Jccl1yX3JismNyZHJmsmcyZ7JwsnFycnJy8nSydTJ18nbyd7J4cnjyeXJ6MnuyfLJ+sn9yQHKCsoOyhXKGcoqyk7KUcpVyl7KYsppyn7KhcqZyr7KwcrFys7K0MrSytTK2srhyu3K9coJyxHLFcsZyyLLQstKy03LUctay17LZct6y53LucvVy+XL6Mvqyw7MEcwVzB7MI8wqzC3ML8wxzDrMP8xGzEnMTcxWzFrMYcxlzGfMacxxzHbMmsydzKHMqsyuzLbMucy9zMbMyMzKzNHM1czlzO3M8cwCzQrNDc0RzRrNHM0ezSXNKc0tzTrNXc1hzWXNbs1wzXLNec2JzZbNmc2dzabNqM2qzbHNxc3NzdHN6c3tzfHN+s38zf7NBc4Jzg3OFc4aziLOJc4pzjLONM42zlrOXc5izmrObM5uznbOec59zobOiM6KzpLOlc6ZzqLOps6uzsLO5s7pzu3O9s76zgLPBc8JzxLPFM8Wzx3PIc8lzy7PMs85z1bPWc9dz2bPaM9qz3LPdc95z4HPhs+Nz6LPqc+xz8XP4s/lz+nP8s/0z/bP/c8B0AXQEtAZ0C7QNtA50D3QRtBI0ErQUdBV0FnQYdBu0HHQddB+0ILQptCp0K3QttC40LrQwtDF0MrQ0tDW0N7Q4dDl0O7Q8tD50A7RMtE10TnRO9FC0UbRTtFR0VXRXtFg0WLRadFt0X3RhdGJ0aLRpdGp0bLRtNG20bvRvdHB0dnR9dH50QjSCtIR0i7SMdI10j7SQNJC0knSXdJl0oLShdKJ0pLSltKd0qHSpdKt0rLSutK90sHSw9LK0szS1dLZ0t3S5tLy0vXS+dIC0wTTBtMP0xHTFdMX0x7TItMm0yrTLdMx0zrTPtNG037TgdOF047TktOa053TodOq06zTrtO107nTvdPG08rT0dPZ0+LT5NPu0/HT9dP+0wDUAtQJ1B7UQdRF1F3UYdRl1G7UcNR61H3UgdSD1IrUjNSO1JXUqtTN1NHU1dTd1ODU6dTt1PHU+dT81P7UBdUJ1Q3VFtUY1T7VQdVF1U7VUNVS1VrVXdVh1WbVatVs1W7VdtV51X3VhtWK1ZHVptXK1c3V0dXT1drV3NXe1ebV6dXt1fbV+NX61QLWBdYJ1hLWFtYd1iHWJdYu1jrWPdZB1kbWStZM1k7WUtZW1lnWXdZo1mrWctZ11oTWhtaO1pHWldae1qDWotap1q3Wsda61rzWxtbJ1s3W0tbV1tjW2tbh1uXW6dbx1vbW/tYB1wXXEtca1x3XIdcq1yzXLtc21znXPddF10jXStdS11XXWtdi12TXZtdq123Xcdd1137XgteK143Xkdea15zXntcArAGsBKwHrAisCawKrBCsEawSrBOsFKwVrBasF6wZrBqsG6wcrB2sIKwkrCysLawvrDCsMaw4rDmsPKxArEusTaxUrFisXKxwrHGsdKx3rHiseqyArIGsg6yErIWshqyJrIqsi6yMrJCslKycrJ2sn6ygrKGsqKyprKqsrKyvrLCsuKy5rLusvKy9rMGsxKzIrMys1azXrOCs4azkrOes6KzqrOys76zwrPGs86z1rPas/Kz9rACtBK0GrQytDa0PrRGtGK0crSCtKa0srS2tNK01rTitPK1ErUWtR61JrVCtVK1YrWGtY61srW2tcK1zrXStda12rXutfK19rX+tga2CrYitia2MrZCtnK2draStt63ArcGtxK3IrdCt0a3Trdyt4K3krfit+a38rf+tAK4BrgiuCa4Lrg2uFK4wrjGuNK43rjiuOq5ArkGuQ65FrkauSq5Mrk2uTq5QrlSuVq5crl2uX65grmGuZa5ormmubK5wrniuea57rnyufa6EroWujK68rr2uvq7ArsSuzK7Nrs+u0K7Rrtiu2a7cruiu667trvSu+K78rgevCK8NrxCvLK8trzCvMq80rzyvPa8/r0GvQq9Dr0ivSa9Qr1yvXa9kr2Wvea+Ar4SviK+Qr5Gvla+cr7ivua+8r8Cvx6/Ir8mvy6/Nr86v1K/cr+iv6a/wr/Gv9K/4rwCwAbAEsAywELAUsBywHbAosESwRbBIsEqwTLBOsFOwVLBVsFewWbBdsHywfbCAsISwjLCNsI+wkbCYsJmwmrCcsJ+woLChsKKwqLCpsKuwrLCtsK6wr7CxsLOwtLC1sLiwvLDEsMWwx7DIsMmw0LDRsNSw2LDgsOWwCLEJsQuxDLEQsRKxE7EYsRmxG7EcsR2xI7EksSWxKLEssTSxNbE3sTixObFAsUGxRLFIsVCxUbFUsVWxWLFcsWCxeLF5sXyxgLGCsYixibGLsY2xkrGTsZSxmLGcsaixzLHQsdSx3LHdsd+x6LHpseyx8LH5sfux/bEEsgWyCLILsgyyFLIVsheyGbIgsjSyPLJYslyyYLJosmmydLJ1snyyhLKFsomykLKRspSymLKZspqyoLKhsqOypbKmsqqyrLKwsrSyyLLJssyy0LLSstiy2bLbst2y4rLksuWy5rLosuuy7LLtsu6y77LzsvSy9bL3sviy+bL6svuy/7IAswGzBLMIsxCzEbMTsxSzFbMcs1SzVbNWs1izW7Ncs16zX7Nks2WzZ7Nps2uzbrNws3GzdLN4s4CzgbODs4SzhbOMs5CzlLOgs6GzqLOss8SzxbPIs8uzzLPOs9Cz1LPVs9ez2bPbs92z4LPks+iz/LMQtBi0HLQgtCi0KbQrtDS0ULRRtFS0WLRgtGG0Y7RltGy0gLSItJ20pLSotKy0tbS3tLm0wLTEtMi00LTVtNy03bTgtOO05LTmtOy07bTvtPG0+LQUtRW1GLUbtRy1JLUltSe1KLUptSq1MLUxtTS1OLVAtUG1Q7VEtUW1S7VMtU21ULVUtVy1XbVftWC1YbWgtaG1pLWotaq1q7WwtbG1s7W0tbW1u7W8tb21wLXEtcy1zbXPtdC10bXYtey1ELYRthS2GLYltiy2NLZItmS2aLactp22oLaktqu2rLaxttS28Lb0tvi2ALcBtwW3KLcptyy3L7cwtzi3Obc7t0S3SLdMt1S3Vbdgt2S3aLdwt3G3c7d1t3y3fbeAt4S3jLeNt4+3kLeRt5K3lreXt5i3mbect6C3qLept6u3rLett7S3tbe4t8e3ybfst+238Lf0t/y3/bf/twC4AbgHuAi4CbgMuBC4GLgZuBu4HbgkuCW4KLgsuDS4Nbg3uDi4ObhAuES4UbhTuFy4XbhguGS4bLhtuG+4cbh4uHy4jbiouLC4tLi4uMC4wbjDuMW4zLjQuNS43bjfuOG46LjpuOy48Lj4uPm4+7j9uAS5GLkguTy5PblAuUS5TLlPuVG5WLlZuVy5YLlouWm5a7ltuXS5dbl4uXy5hLmFuYe5ibmKuY25jrmsua25sLm0uby5vbm/ucG5yLnJucy5zrnPudC50bnSudi52bnbud253rnhueO55Lnluei57Ln0ufW597n4ufm5+rkAugG6CLoVuji6Obo8ukC6QrpIukm6S7pNuk66U7pUulW6WLpcumS6Zbpnumi6abpwunG6dLp4uoO6hLqFuoe6jLqouqm6q7qsurC6srq4urm6u7q9usS6yLrYutm6/LoAuwS7DbsPuxG7GLscuyC7KbsruzS7Nbs2uzi7O7s8uz27PrtEu0W7R7tJu027T7tQu1S7WLthu2O7bLuIu4y7kLuku6i7rLu0u7e7wLvEu8i70LvTu/i7+bv8u/+7ALwCvAi8CbwLvAy8DbwPvBG8FLwVvBa8F7wYvBu8HLwdvB68H7wkvCW8J7wpvC28MLwxvDS8OLxAvEG8Q7xEvEW8SbxMvE28ULxdvIS8hbyIvIu8jLyOvJS8lbyXvJm8mrygvKG8pLynvKi8sLyxvLO8tLy1vLy8vbzAvMS8zbzPvNC80bzVvNi83Lz0vPW89rz4vPy8BL0FvQe9Cb0QvRS9JL0svUC9SL1JvUy9UL1YvVm9ZL1ovYC9gb2EvYe9iL2JvYq9kL2RvZO9lb2ZvZq9nL2kvbC9uL3UvdW92L3cvem98L30vfi9AL4DvgW+DL4NvhC+FL4cvh2+H75EvkW+SL5Mvk6+VL5Vvle+Wb5avlu+YL5hvmS+aL5qvnC+cb5zvnS+db57vny+fb6AvoS+jL6Nvo++kL6Rvpi+mb6ovtC+0b7Uvte+2L7gvuO+5L7lvuy+Ab8Ivwm/GL8Zvxu/HL8dv0C/Qb9Ev0i/UL9Rv1W/lL+wv8W/zL/Nv9C/1L/cv9+/4b88wFHAWMBcwGDAaMBpwJDAkcCUwJjAoMChwKPApcCswK3Ar8CwwLPAtMC1wLbAvMC9wL/AwMDBwMXAyMDJwMzA0MDYwNnA28DcwN3A5MDlwOjA7MD0wPXA98D5wADBBMEIwRDBFcEcwR3BHsEfwSDBI8EkwSbBJ8EswS3BL8EwwTHBNsE4wTnBPMFAwUjBScFLwUzBTcFUwVXBWMFcwWTBZcFnwWjBacFwwXTBeMGFwYzBjcGOwZDBlMGWwZzBncGfwaHBpcGowanBrMGwwb3BxMHIwczB1MHXwdjB4MHkwejB8MHxwfPB/MH9wQDCBMIMwg3CD8IRwhjCGcIcwh/CIMIowinCK8Itwi/CMcIywjTCSMJQwlHCVMJYwmDCZcJswm3CcMJ0wnzCfcJ/woHCiMKJwpDCmMKbwp3CpMKlwqjCrMKtwrTCtcK3wrnC3MLdwuDC48LkwuvC7MLtwu/C8cL2wvjC+cL7wvzCAMMIwwnDDMMNwxPDFMMVwxjDHMMkwyXDKMMpw0XDaMNpw2zDcMNyw3jDecN8w33DhMOIw4zDwMPYw9nD3MPfw+DD4sPow+nD7cP0w/XD+MMIxBDEJMQsxDDENMQ8xD3ESMRkxGXEaMRsxHTEdcR5xIDElMScxLjEvMTpxPDE8cT0xPjE+sT/xADFAcUMxRDFFMUcxSjFKcUsxTDFOMU5xTvFPcVExUXFSMVJxUrFTMVNxU7FU8VUxVXFV8VYxVnFXcVexWDFYcVkxWjFcMVxxXPFdMV1xXzFfcWAxYTFh8WMxY3Fj8WRxZXFl8WYxZzFoMWpxbTFtcW4xbnFu8W8xb3FvsXExcXFxsXHxcjFycXKxczFzsXQxdHF1MXYxeDF4cXjxeXF7MXtxe7F8MX0xfbF98X8xf3F/sX/xQDGAcYFxgbGB8YIxgzGEMYYxhnGG8YcxiTGJcYoxizGLcYuxjDGM8Y0xjXGN8Y5xjvGQMZBxkTGSMZQxlHGU8ZUxlXGXMZdxmDGbMZvxnHGeMZ5xnzGgMaIxonGi8aNxpTGlcaYxpzGpMalxqfGqcawxrHGtMa4xrnGusbAxsHGw8bFxszGzcbQxtTG3MbdxuDG4cboxunG7MbwxvjG+cb9xgTHBccIxwzHFMcVxxfHGccgxyHHJMcoxzDHMcczxzXHN8c8xz3HQMdEx0rHTMdNx0/HUcdSx1PHVMdVx1bHV8dYx1zHYMdox2vHdMd1x3jHfMd9x37Hg8eEx4XHh8eIx4nHiseOx5DHkceUx5bHl8eYx5rHoMehx6PHpMelx6bHrMetx7DHtMe8x73Hv8fAx8HHyMfJx8zHzsfQx9jH3cfkx+jH7McAyAHIBMgIyArIEMgRyBPIFcgWyBzIHcggyCTILMgtyC/IMcg4yDzIQMhIyEnITMhNyFTIcMhxyHTIeMh6yIDIgciDyIXIhsiHyIvIjMiNyJTIncifyKHIqMi8yL3IxMjIyMzI1MjVyNfI2cjgyOHI5Mj1yPzI/cgAyQTJBckGyQzJDckPyRHJGMksyTTJUMlRyVTJWMlgyWHJY8lsyXDJdMl8yYjJicmMyZDJmMmZyZvJncnAycHJxMnHycjJysnQydHJ08nVydbJ2cnaydzJ3cngyeLJ5MnnyezJ7cnvyfDJ8cn4yfnJ/MkAygjKCcoLygzKDcoUyhjKKcpMyk3KUMpUylzKXcpfymDKYcpoyn3KhMqYyrzKvcrAysTKzMrNys/K0crTytjK2crgyuzK9MoIyxDLFMsYyyDLIctBy0jLSctMy1DLWMtZy13LZMt4y3nLnMu4y9TL5Mvny+nLDMwNzBDMFMwczB3MIcwizCfMKMwpzCzMLswwzDjMOcw7zDzMPcw+zETMRcxIzEzMVMxVzFfMWMxZzGDMZMxmzGjMcMx1zJjMmcyczKDMqMypzKvMrMytzLTMtcy4zLzMxMzFzMfMyczQzNTM5MzszPDMAc0IzQnNDM0QzRjNGc0bzR3NJM0ozSzNOc1czWDNZM1szW3Nb81xzXjNiM2UzZXNmM2czaTNpc2nzanNsM3EzczN0M3ozezN8M34zfnN+839zQTOCM4MzhTOGc4gziHOJM4ozjDOMc4zzjXOWM5ZzlzOX85gzmHOaM5pzmvObc50znXOeM58zoTOhc6HzonOkM6RzpTOmM6gzqHOo86kzqXOrM6tzsHO5M7lzujO687szvTO9c73zvjO+c4AzwHPBM8IzxDPEc8TzxXPHM8gzyTPLM8tzy/PMM8xzzjPVM9Vz1jPXM9kz2XPZ89pz3DPcc90z3jPgM+Fz4zPoc+oz7DPxM/gz+HP5M/oz/DP8c/zz/XP/M8A0ATQEdAY0C3QNNA10DjQPNBE0EXQR9BJ0FDQVNBY0GDQbNBt0HDQdNB80H3QgdCk0KXQqNCs0LTQtdC30LnQwNDB0MTQyNDJ0NDQ0dDT0NTQ1dDc0N3Q4NDk0OzQ7dDv0PDQ8dD40A3RMNEx0TTRONE60UDRQdFD0UTRRdFM0U3RUNFU0VzRXdFf0WHRaNFs0XzRhNGI0aDRodGk0ajRsNGx0bPRtdG60bzRwNHY0fTR+NEH0gnSENIs0i3SMNI00jzSPdI/0kHSSNJc0mTSgNKB0oTSiNKQ0pHSldKc0qDSpNKs0rHSuNK50rzSv9LA0sLSyNLJ0svS1NLY0tzS5NLl0vDS8dL00vjSANMB0wPTBdMM0w3TDtMQ0xTTFtMc0x3TH9Mg0yHTJdMo0ynTLNMw0zjTOdM70zzTPdNE00XTfNN904DThNOM043Tj9OQ05HTmNOZ05zToNOo06nTq9Ot07TTuNO808TTxdPI08nT0NPY0+HT49Ps0+3T8NP00/zT/dP/0wHUCNQd1EDURNRc1GDUZNRt1G/UeNR51HzUf9SA1ILUiNSJ1IvUjdSU1KnUzNTQ1NTU3NTf1OjU7NTw1PjU+9T91ATVCNUM1RTVFdUX1TzVPdVA1UTVTNVN1U/VUdVY1VnVXNVg1WXVaNVp1WvVbdV01XXVeNV81YTVhdWH1YjVidWQ1aXVyNXJ1czV0NXS1djV2dXb1d3V5NXl1ejV7NX01fXV99X51QDWAdYE1gjWENYR1hPWFNYV1hzWINYk1i3WONY51jzWQNZF1kjWSdZL1k3WUdZU1lXWWNZc1mfWadZw1nHWdNaD1oXWjNaN1pDWlNad1p/Wodao1qzWsNa51rvWxNbF1sjWzNbR1tTW19bZ1uDW5Nbo1vDW9db81v3WANcE1xHXGNcZ1xzXINco1ynXK9ct1zTXNdc41zzXRNdH10nXUNdR11TXVtdX11jXWddg12HXY9dl12nXbNdw13TXfNd914HXiNeJ14zXkNeY15nXm9ed1wAwATACMLcAJSAmIKgAAzCtABUgJSI8/zwiGCAZIBwgHSAUMBUwCDAJMAowCzAMMA0wDjAPMBAwETCxANcA9wBgImQiZSIeIjQisAAyIDMgAyErIeD/4f/l/0ImQCYgIqUiEiMCIgciYSJSIqcAOyAGJgUmyyXPJc4lxyXGJaEloCWzJbIlvSW8JZIhkCGRIZMhlCETMGoiayIaIj0iHSI1IisiLCIIIgsihiKHIoIigyIqIikiJyIoIuL/0iHUIQAiAyK0AF7/xwLYAt0C2gLZArgA2wKhAL8A0AIuIhEiDyKkAAkhMCDBJcAltyW2JWQmYCZhJmUmZyZjJpkiyCWjJdAl0SWSJaQlpSWoJaclpiWpJWgmDyYOJhwmHia2ACAgISCVIZchmSGWIZghbSZpJmombCZ/MhwyFiHHMyIhwjPYMyEhrCCuAD1Pc09HUPlQoFLvU3VU5VQJVsFatluHZrZnt2fvZ0xrwnPCdTx624IEg1eIiIg2isiMz437juaP1Zk7UnRTBFRqYGRhvGvPcxqBuonSiaOVg08KUr5YeFnmWXJeeV7HYcBjRmfsZ39ol29Odgt39XgIev96IXydgG6CcYLripOVa06dVfdmNG6jeO16W4QQiU6HqJfYUk5XKlhMXR9hvmEhYmJl0WdEahtuGHWzdeN2sHc6fa+QUZRSlJWfI1OsXDJ124BAkpiVW1IIWNxZoVwXXbdeOl9KX3dhX2x6dYZ14HxzfbF9jH9UgSGCkYVBiRuL/JJNlkecy073TgtQ8VFPWDdhPmFoYTll6mkRb6V1hnbWdod7pYLLhAD5p5OLlYBVoltRVwH5s3y5f7WRKFC7U0Vc6F3SYm5j2mTnZCBurHBbed2NHo4C+X2QRZL4kn5O9k5lUP5d+l4GYVdpcYFUhkeOdZMrml5OkVBwZ0BoCVGNUpJSomq8dxCS1J6rUi9g8o9IUKlh7WPKZDxohGrAb4iBoYmUlgVYfXKscgR1eX1tfqmAi4l0i2OQUZ2JYnpsVG9QfTp/I4p8UUphnXsZi1eSjJOsTtNPHlC+UAZRwVLNUn9TcFeDWJpekV92YaxhzmRsZW9mu2b0Zpdoh22FcPFwn3SldMp02XVseOx433r2ekV9k30VgD+AG4GWg2aLFY8VkOGTA5g4mFqa6JvCT1NVOlhRWWNbRly4YBJiQmiwaOhoqm5MdXh2zng9evt8a358fgiKoYo/jI6WxJ3kU+lTSlRxVPpW0VlkWztcq173YjdlRWVyZaBmr2fBab1s/HWQdn53P3qUfwOAoYCPgeaC/YLwg8GFMYi0iKWKA/mcjy6Tx5ZnmNiaE5/tVJtl8maPaEB6N4xgnfBWZFcRXQZmsWjNaP5uKHSeiOSbaGwE+aiam09sUXFRn1JUW+VdUGBtYPFip2M7ZdlzenqjhqKMj5cyTuFbCGKcZ9x00XnTg4eKsorojU6QS5NGmNNe6Gn/he2QBfmgUZhb7FtjYfpoPmtMcC902HShe1B/xYPAiauM3JUomS5SXWDsYgKQik9JUSFT2VjjXuBmOG2acMJy1nNQe/GAW5RmU5tja39WToBQSljeWCpgJ2HQYtBpQZuPWxh9sYBfj6RO0VCsVKxVDFugXeddKmVOZSFoS2rhco5273deffl/oIFOhd+GA49Oj8qQA5lVmqubGE5FTl1Ox07xT3dR/lJAU+NT5VOOVBRWdVeiV8dbh13QXvxh2GJRZbhn6WfLaVBrxmvsa0JsnW54cNdylnMDdL936Xd2en99CYD8gQWCCoLfgmKIM4v8jMCOEZCxkGSStpLSmUWa6ZzXnZyfC1dAXMqDoJerl7SeG1SYeqR/2YjNjuGQAFhIXJhjn3quWxNfeXqueo6CrI4mUDhS+FJ3UwhX82JyYwprw203d6VTV3NohXaO1ZU6Z8NqcG9tisyOS5kG+XdmeGu0jDybB/nrUy1XTlnGY/tp6nNFeLp6xXr+fHWEj4lzjTWQqJX7UkdXR3Vge8yDHpII+VhqS1FLUodSH2LYaHVpmZbFUKRS5FLDYaRlOWj/aX50S3u5guuDsok5i9GPSZkJ+cpOl1nSZBFmjmo0dIF5vXmpgn6If4hfiQr5JpMLT8pTJWBxYnJsGn1mfZhOYlHcd6+AAU8OT3ZRgFHcVWhWO1f6V/xXFFlHWZNZxFuQXA5d8V1+XsxfgGLXZeNlHmcfZ15ny2jEaF9qOmsjbH1sgmzHbZhzJnQqdIJ0o3R4dX91gXjveEF5R3lIeXp5lXsAfbp9iH8GgC2AjIAYik+LSIx3jSGTJJPimFGZDpoPmmWakp7KfXZPCVTuYlRo0ZGrVTpRC/kM+Rxa5mEN+c9i/2IO+Q/5EPkR+RL5E/mjkBT5FfkW+Rf5GPn+ihn5Gvkb+Rz5lmYd+VZxHvkf+eOWIPlPY3pjV1Mh+Y9nYGlzbiL5N3Uj+ST5JfkNfSb5J/lyiMpWGFoo+Sn5Kvkr+Sz5Q04t+WdRSFnwZxCALvlzWXRemmTKefVfbGDIYntj51vXW6pSL/l0WSlfEmAw+TH5MvlZdDP5NPk1+Tb5N/k4+dGZOfk6+Tv5PPk9+T75P/lA+UH5QvlD+cNvRPlF+b+Bso/xYEb5R/lmgUj5Sfk/XEr5S/lM+U35TvlP+VD5UfnpWiWKe2cQfVL5U/lU+VX5VvlX+f2AWPlZ+Txc5Ww/U7puGlk2gzlOtk5GT65VGFfHWFZft2XmZYBqtWtNbu1373oefN59y4aSiDKRW5O7ZL5venO4dVSQVlVNV7ph1GTHZuFtW25tb7lv8HVDgL2BQYWDiceKWosfk5NsU3VUew+OXZAQVQJYWFhiXgdinmTgaHZ11nyzh+ie406IV25XJ1kNXLFcNl6FXzRi4WSzc/qBi4i4jIqW256FW7dfs2ASUABSMFIWVzVYV1gOXGBc9lyLXaZekl+8YBFjiWMXZENo+WjCathtIW7UbuRv/nHcdnl3sXk7egSEqYntjPONSI4DkBSQU5D9kE2Tdpbcl9JrBnBYcqJyaHNjd7955HubfoCLqVjHYGZl/WW+ZoxsHnHJcVqME5htToF63U6sUc1R1VIMVKdhcWdQaN9oHm18b7x1s3flevSAY4SFklxRl2VcZ5Nn2HXHenODWvlGjBeQLZhvXMCBmoJBkG+QDZKXX51dWWrIcXt2SXvkhQSLJ5EwmodV9mFb+Wl2hX8/hrqH+IiPkFz5G23ZcN5zYX09hF35apHxmV75gk51UwRrEms+cBtyLYYenkxSo49QXeVkLGUWa+tvQ3ycfs2FZIm9icli2IEfiMpeF2dqbfxyBXRvdIKH3pCGTw1doF8KhLdRoGNlda5OBlBpUclRgWgRaq58sXznfG+C0oobj8+Rtk83UfVSQlTsXm5hPmLFZdpq/m8qedyFI4itlWKaapqXns6em1LGZndrHXAreWKPQpeQYQBiI2Ujb0lxiXT0fW+A7oQmjyOQSpO9URdSo1IMbchwwojJXoJlrmvCbz58dXPkTjZP+VZf+bpcul0cYLJzLXuaf85/RoAekDSS9pZIlxiYYZ+LT6dvrnm0kbeW3lJg+YhkxGTTal5vGHAQcud2AYAGhlyG740FjzKXb5v6nXWejHh/eaB9yYMEk3+ek57Wit9YBF8nZydwz3RgfH6AIVEocGJyynjCjNqM9Iz3loZO2lDuW9ZemWXOcUJ2rXdKgPyEfJAnm42f2FhBWmJcE2rabQ9vO3YvfTd+HoU4ieSTS5aJUtJl82e0aUFtnG4PcAl0YHRZdSR2a3gsi16YbVEuYniWlk8rUBld6m24fSqPi19EYRdoYfmGltJSi4DcUcxRXmkcer598YN1ltpPKVKYUw9UDlVlXKdgTmeoaGxtgXL4cgZ0g3Ri+eJ1bHx5f7h/iYPPiOGIzJHQkeKWyZsdVH5v0HGYdPqFqo6jllecn56XZ8ttM3TogRaXLHjLeiB7knxpZGp08nW8eOh4rJlUm7ue3ltVXiBvnIGrg4iQB05NUyla0l1OX2JhPWNpZvxm/24rb2NwnncshBOFO4gTj0WZO5wcVbliK2erbAmDaol6l6FOhFnYX9lfG2eyfVR/koIrg72DHo+ZkMtXuVmSWtBbJ2aaZ4Voz2tkcXV/t4zjjIGQRZsIgYqMTJZAmqWeX1sTbBtz8nbfdgyEqlGTiU1RlVHJUslolGwEdyB3v33sfWKXtZ7FbhGFpVENVH1UDmadZidpn26/dpF3F4PChJ+HaZGYkvScgoiuT5JR31LGWT1eVWF4ZHlkrmbQZyFqzWvba19yYXJBdDh323cXgLyCBYMAiyiLjIwoZ5BsZ3LudmZ3RnqpnX9rkmwiWSZnmYRvU5NYmVnfXs9jNGZzZzpuK3PXeteCKJPZUutdrmHLYQpix2KrZOBlWWlma8trIXH3c111Rn4eggKDaoWjir+MJ5dhnahY2J4RUA5SO1RPVYdldmwKfQt9XoCKhoCV75b/UpVsaXJzVJpaPlxLXUxfrl8qZ7ZoY2k8bkRuCXdzfI5/h4UOi/ePYZf0nrdctmANYathT2X7ZfxlEWzvbJ9zyXPhfZSVxlschxCLXVJaU81iD2SyZDRnOGrKbMBznnSUe5V8G36KgTaChIXrj/mWwZk0T0pTzVPbU8xiLGQAZZFlw2nubFhv7XNUdSJ25Hb8dtB4+3gseUZ9LILgh9SPEpjvmMNS1GKlZCRuUW98dsuNsZFiku6aQ5sjUI1QSleoWShcR153Xz9iPmW5ZcFlCWaLZ5xpwm7FeCF9qoCAgSuCs4KhhIyGKooXi6aQMpaQnw1Q809j+flXmF/cYpJjb2dDbhlxw3bMgNqA9Ij1iBmJ4Iwpj02RapYvT3BPG17PZyJofXZ+dkSbYV4Kamlx1HFqdWT5QX5DhemF3JgQT097cH+lleFRBl61aD5sTmzbbK9yxHsDg9VsOnT7UIhSwVjYZJdqp3RWdqd4F4bilTmXZfleUwFfiouoj6+PipAlUqV3SZwInxlOAlB1UVtcd14eZjpmxGfFaLNwAXXFdcl53XonjyCZCJrdTyFYMVj2W25mZWsRbXpufW/kcyt16YPciBOJXIsUjw9P1VAQU1xTk1upXw1nj3l5gS+DFIUHiYaJOY87j6WZEpwsZ3ZO+E9JWQFc71zwXGdj0mj9cKJxK3QrfuyEAocikNKS85wNTthO70+FUFZSb1ImVJBU4FcrWWZaWlt1W8xbnF5m+XZid2WnZW5tpW42ciZ7P3w2f1CBUYGagUCCmYKpgwOKoIzmjPuMdI26jeiQ3JEclkSW2ZnnnBdTBlIpVHRWs1hUWW5Z/1+kYW5iEGZ+bBpxxnaJfN58G32sgsGM8JZn+VtPF19/X8JiKV0LZ9pofHhDfmydFU6ZUBVTKlNRU4NZYlqHXrJgimFJYnlikGWHZ6dp1GvWa9dr2Gu4bGj5NXT6dRJ4kXjVedh5g3zLfeF/pYA+gcKB8oMah+iIuYpsi7uMGZFel9uYO5+sVipbbF+MZbNqr2tcbfFvFXBdcq1zp4zTjDuYkWE3bFiAAZpNTotOm07VTjpPPE9/T99P/1DyU/hTBlXjVdtW61hiWRFa61v6WwRc810rXplfHWBoY5xlr2X2Z/tnrWh7a5ls12wjbglwRXMCeD55QHlgecF56XsXfXJ9hoANgo6D0YTHht+IUIpeih2L3Ixmja2PqpD8mN+ZnZ5KUmn5FGdq+ZhQKlJxXGNlVWzKcyN1nXWXe5yEeJEwl3dOkmS6a15xqYUJTmv5SWfuaBdun4IYhWuI92OBbxKSr5gKTrdQz1AfUUZVqlUXVkBbGVzgXDheil6gXsJe82BRaGFqWG49ckBywHL4dmV5sXvUf/OI9IlzimGM3owcl15YvXT9jMdVbPlheiJ9coJych91JXVt+Rl7hVj7WLxdj162XpBfVWCSYn9jTWWRZtlm+GYWaPJogHJedG57bn3WfXJ/5YASgq+Ff4mTih2Q5JLNniCfFVltWS1e3GAUZnNmkGdQbMVtX2/zd6l4xoTLkSuT2U7KUEhRhFULW6NbR2J+ZctlMm59cQF0RHSHdL90bHaqedp9VX6of3qBs4E5ghqG7Id1iuONeJCRkiWUTZmum2hTUVxUacRsKW0rbgyCm4U7iS2KqorqlmefYVK5ZrJrln7+hw2Ng5Vdlh1liW3ucW75zlfTWaxbJ2D6YBBiH2ZfZilz+XPbdgF3bHtWgHKAZYGgipKRFk7iUnJrF20Fejl7MH1v+bCM7FMvVlFYtVsPXBFc4l1AYoNjFGQtZrNovGyIba9uH3CkcNJxJnWPdY51GXYRe+B7K3wgfTl9LIVthQeGNIoNkGGQtZC3kvaXN5rXT2xcX2eRbZ98jH4WixaNH5BrW/1dDWTAhFyQ4ZiHc4tbmmB+Z95tH4qmigGQDJg3UnD5UXCOeJaTcIjXke5P11P9VdpWglf9WMJaiFurXMBcJV4BYQ1iS2KIYxxkNmV4ZTlqims0bBltMW/ncelyeHMHdLJ0JnZhd8B5V3rqerl8j32sfWF+nn8pgTGDkITahOqFloiwipCLOI9CkIOQbJGWkrmSi5anlqiW1pYAlwiYlpnTmhqb1FN+WBlZcFu/W9FtWm+fcSF0uXSFgP2D4V2HX6pfQmDsZRJob2lTaolrNW3zbeNz/nasd017FH0jgRyCQIP0hGOFYorEioeRHpMGmLSZ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uk7BTgNScFPt+b1U4Fb7WcVbFV/NX25u7vnv+Wp9NYPw+ZOGjYrx+W2Xd5fy+fP5AE5aT35P+VjlZaJuOJCwk7mZ+07sWIpZ2VlBYPT59fkUevb5T4PDjGVRRFP3+fj5+fnNTmlSVVu/gtROOlKoVMlZ/1lQW1dbXFtjYEhhy26ZcG5xhnP3dLV1wXgrfQWA6oEogxeFyYXuiseMzJZcT/pSvFarZShmfHC4cDVyvX2NgkyRwJZynXFb52iYa3pv3naRXKtmW2+0eyp8NojclghO104gUzRYu1jvWGxZB1wzXoReNV+MY7JmVmcfaqNqDGs/b0Zy+vlQc4t04HqnfHiB34HngYqDbIQjhZSFz4XdiBONrJF3lZyWjVHJVChXsFtNYlBnPWiTaD1u0259cCF+wYihjAmPS59Ony1yj3vNihqTR09OTzJRgFTQWZVetWJ1Z25pF2qubBpu2XIqc711uHs1feeC+YNXhPeFW4qvjIeOGZC4kM6WX5/jUgpU4VrCW1hkdWX0bsRy+/mEdk16G3tNfD5+3397gyuLyoxkjeGNX47qj/mPaZDRk0NPek+zUGhReFFNUmpSYVh8WGBZCFxVXNtem2AwYhNov2sIbLFvTnEgdDB1OHVRdXJ2THuLe617xnuPfm6KPo9Jjz+Sk5IikyuU+5ZamGuYHpkHUipimGJZbWR2ynrAe3Z9YFO+XJdeOG+5cJh8EZeOm96epWN6ZHaHAU6VTq1OXFB1UEhUw1maW0BerV73XoFfxWA6Yz9ldGXMZXZmeGb+Z2hpiWpja0BswG3obR9uXm4ecKFwjnP9czp1W3eHeI55C3p9er58jn1HggKK6oqejC2RSpHYkWaSzJIgkwaXVpdclwKYDp82UpFSfFUkWB1eH1+MYNBjr2jfb215LHvNgbqF/Yj4ikSOjZFklpuWPZdMmEqfzk9GUctRqVIyVhRfa1+qY81k6WVBZvpm+WYdZ51o12j9aRVvbm9nceVxKnKqdDp3Vnlaed95IHqVepd833xEfXB+h4D7haSGVIq/ipmNgY4gkG2Q45E7ltWW5ZzPZQd8s43Dk1hbClxSU9liHXMnUJdbnl+wYGth1WjZbS50LnpCfZx9MX5rgSqONY5+kxiUUE9QV+Zdp14rY2p/O05PT49PWlDdWcSAalRoVP5VT1mZW95d2l5dZjFn8WcqaOhsMm1Kbo1vt3Dgc4d1THwCfSx9on0fgtuGO4qFinCNio4zjzGQTpFSkUSU0Jn5eqV8yk8BUcZRyFfvW/tcWWY9alptlm7sbwxxb3XjeiKIIZB1kMuW/5kBgy1O8k5GiM2RfVPbamtpQWx6hJ5YjmH+Zu9i3XARdcd1Un64hEmLCI1LTupTq1QwV0BX118BYwdjb2QvZehlemadZ7NnYmtgbJpsLG/ldyV4SXlXeRl9ooACgfOBnYK3ghiHjIr8+QSNvo1ykPR2GXo3elR+d4AHVdRVdVgvYyJkSWZLZm1om2mEayVtsW7Nc2h0oXRbdbl14XYed4t35nkJfh1++4EvhZeIOorRjOuOsI8ykK2TY5ZzlgeXhE/xU+pZyVoZXk5oxnS+del5knqjge2G6ozMje2Pn2UVZ/3591dXb919L4/2k8aWtV/yYYRvFE6YTx9QyVPfVW9d7l0ha2Rry3iae/75SY7Kjm6QSWM+ZEB3hHovk3+Uap+wZK9v5nGodNp0xHoSfIJ+snyYfpqLCo19lBCZTJk5Ut9b5mQtZy597VDDU3lYWGFZYfphrGXZepKLlosJUCFQdVIxVTxa4F5wXzRhXmUMZjZmombNacRuMm8WcyF2k3o5gVmC1oO8hLVQ8FfAW+hbaV+hYyZ4tX3cgyGFx5H1kYpR9WdWe6yMxFG7Wb1gVYYcUP/5VFI6XH1hGmLTYvJkpWXMbiB2CoFgjl+Wu5bfTkNTmFUpWd1dxWTJbPptlHN/ehuCpoXkjBCOd5DnkeGVIZbGl/hR8lSGVblfpGSIb7R9H49NjzWUyVAWXL5s+20bdbt3PXxkfHmKwooeWL5ZFl53Y1JyinVrd9yKvIwSj/NedGb4bX2AwYPLilGX1psA+kNS/2aVbe9u4H3mii6QXpDUmh1Sf1LoVJRhhGLbYqJoEmlaaTVqknAmcV14AXkOedJ5DXqWgHiC1YJJg0mFgoyFjWKRi5GukcNP0Vbtcdd3AIf4ifhb1l9RZ6iQ4lNaWPVbpGCBYWBkPX5wgCWFg5KuZKxQFF0AZ5xYvWKoYw5peGkeamtuunbLebuCKYTPiqiN/Y8SkUuRnJEQkxiTmpPbljaaDZwRTlx1XXn6elF7yXsufsSEWY50jviOEJAlZj9pQ3T6US5n3J5FUeBflmzyh12Id4i0YLWBA4QFjdZTOVQ0VjZaMVyKcOB/WoAGge2Bo42JkV+a8p10UMROoFP7YCxuZFyITyRQ5FXZXF9eZWCUaLtsxG2+cdR19HVhdhp6SXrHfft9bn/0gamGHI/JlrOZUp9HUsVS7ZiqiQNO0mcGb7VP4luVZ4hseG0bdCd43ZF8k8SH5Hkxeutf1k6kVD5VrlilWfBgU2LWYjZnVWk1gkCWsZndmSxQU1NEVXxXAfpYYgL64mRrZt1nwW/vbyJ0OHQXijiUUVQGVmZXSF+aYU5rWHCtcLt9lYpqWSuBomMIdz2AqoxUWC1ku2mVWxFeb24D+mmFTFHwUypZIGBLYYZrcGzwbB57zoDUgsaNsJCxmAT6x2Skb5FkBGVOURBUH1cOil9hdmgF+tt1UntxfRqQBljMaX+BKokAkDmYeFBXWaxZlWIPkCqbXWF5ctaVYVdGWvRdimKtZPpkd2fibD5tLHI2dDR4d3+tgtuNF5gkUkJXf2dIcuN0qYymjxGSKpZrUe1TTGNpTwRVlmBXZZtsf21Mcv1yF3qHiZ2MbV+Ob/lwqIEOYb9PT1BBYkdyx3vofel/TZCtlxmatoxqV3NesGcNhFWKIFQWW2Ne4l4KX4NluoA9hYmVW5ZITwVTDVMPU4ZU+lQDVwNeFmCbYrFiVWMG+uFsZm2xdTJ43oAvgd6CYYSyhI2IEokLkOqS/ZiRm0VetGbdZhFwBnIH+vVPfVJqX1NhU2cZagJv4nRoeWiIeYzHmMSYQ5rBVB96U2n3ikqMqJiumXxfq2Kyda52q4h/kEKWOVM8X8VfzGzMc2J1i3VGe/6CnZlPTjyQC05VT6ZTD1nIXjBms2xVdHeDZofAjFCQHpcVnNFYeFtQhhSLtJ3SW2hgjWDxZVdsIm+jbxpwVX/wf5GVkpVQltOXclJEj/1RK1S4VGNVilW7arVt2H1mgpySd5Z5nghUyFTSduSGpJXUlVyWok4JT+5Z5lr3XVJgl2JtZ0Fohmwvbjh/m4Aqggj6CfoFmKVOVVCzVJNXWllpW7NbyGF3aXdtI3D5h+OJcornioKQ7Zm4mr5SOGgWUHheT2dHg0yIq04RVK5W5nMVkf+XCZlXmZmZU1afWFuGMYqyYfZqe3PSjkdrqpZXmlVZAHJrjWmX1E/0XCZf+GFbZutsq3CEc7lz/nMpd013Q31ifSN+N4JSiAr64oxJkm+YUVt0ekCIAZjMWuBPVFM+Wf1c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5WXwZghnKGcga2JreWvLa9Rr22sPbDRsa3AqcjZyO3JHcllyW3KscotzGU4WThVOFE4YTjtOTU5PTk5O5U7YTtRO1U7WTtdO407kTtlO3k5FUURRiVGKUaxR+VH6UfhRClKgUp9SBVMGUxdTHVPfTkpTSVNhU2BTb1NuU7tT71PkU/NT7FPuU+lT6FP8U/hT9VPrU+ZT6lPyU/FT8FPlU+1T+1PbVtpWFlkuWTFZdFl2WVVbg1s8XOhd513mXQJeA15zXnxeAV8YXxdfxV8KYlNiVGJSYlFipWXmZS5nLGcqZytnLWdja81rEWwQbDhsQWxAbD5sr3KEc4lz3HTmdBh1H3UodSl1MHUxdTJ1M3WLdX12rna/du5223fid/N3Onm+eXR6y3oeTh9OUk5TTmlOmU6kTqZOpU7/TglPGU8KTxVPDU8QTxFPD0/yTvZO+07wTvNO/U4BTwtPSVFHUUZRSFFoUXFRjVGwURdSEVISUg5SFlKjUghTIVMgU3BTcVMJVA9UDFQKVBBUAVQLVARUEVQNVAhUA1QOVAZUElTgVt5W3VYzVzBXKFctVyxXL1cpVxlZGlk3WThZhFl4WYNZfVl5WYJZgVlXW1hbh1uIW4VbiVv6WxZceVzeXQZedl50Xg9fG1/ZX9ZfDmIMYg1iEGJjYltiWGI2Zell6GXsZe1l8mbzZglnPWc0ZzFnNWcha2Rre2sWbF1sV2xZbF9sYGxQbFVsYWxbbE1sTmxwcF9yXXJ+dvl6c3z4fDZ/in+9fwGAA4AMgBKAM4B/gImAi4CMgOOB6oHzgfyBDIIbgh+CboJygn6Ca4ZAiEyIY4h/iSGWMk6oTk1PT09HT1dPXk80T1tPVU8wT1BPUU89TzpPOE9DT1RPPE9GT2NPXE9gTy9PTk82T1lPXU9IT1pPTFFLUU1RdVG2UbdRJVIkUilSKlIoUqtSqVKqUqxSI1NzU3VTHVQtVB5UPlQmVE5UJ1RGVENUM1RIVEJUG1QpVEpUOVQ7VDhULlQ1VDZUIFQ8VEBUMVQrVB9ULFTqVvBW5FbrVkpXUVdAV01XR1dOVz5XUFdPVztX71g+WZ1ZklmoWZ5Zo1mZWZZZjVmkWZNZilmlWV1bXFtaW1tbjFuLW49bLFxAXEFcP1w+XJBckVyUXIxc610MXo9eh16KXvdeBF8fX2RfYl93X3lf2F/MX9dfzV/xX+tf+F/qXxJiEWKEYpdilmKAYnZiiWJtYopifGJ+Ynlic2KSYm9imGJuYpVik2KRYoZiOWU7ZThl8WX0Zl9nTmdPZ1BnUWdcZ1ZnXmdJZ0ZnYGdTZ1dnZWvPa0JsXmyZbIFsiGyJbIVsm2xqbHpskGxwbIxsaGyWbJJsfWyDbHJsfmx0bIZsdmyNbJRsmGyCbHZwfHB9cHhwYnJhcmByxHLCcpZzLHUrdTd1OHWCdu9243fBecB5v3l2evt8VX+WgJOAnYCYgJuAmoCygG+CkoKLgo2Ci4nSiQCKN4xGjFWMnYxkjXCNs42rjsqOm4+wj8KPxo/Fj8SP4V2RkKKQqpCmkKOQSZHGkcyRMpYuljGWKpYsliZOVk5zTotOm06eTqtOrE5vT51PjU9zT39PbE+bT4tPhk+DT3BPdU+IT2lPe0+WT35Pj0+RT3pPVFFSUVVRaVF3UXZReFG9Uf1RO1I4UjdSOlIwUi5SNlJBUr5Su1JSU1RTU1NRU2ZTd1N4U3lT1lPUU9dTc1R1VJZUeFSVVIBUe1R3VIRUklSGVHxUkFRxVHZUjFSaVGJUaFSLVH1UjlT6VoNXd1dqV2lXYVdmV2RXfFccWUlZR1lIWURZVFm+WbtZ1Fm5Wa5Z0VnGWdBZzVnLWdNZylmvWbNZ0lnFWV9bZFtjW5dbmluYW5xbmVubWxpcSFxFXEZct1yhXLhcqVyrXLFcs1wYXhpeFl4VXhteEV54Xppel16cXpVell72XiZfJ18pX4BfgV9/X3xf3V/gX/1f9V//Xw9gFGAvYDVgFmAqYBVgIWAnYClgK2AbYBZiFWI/Yj5iQGJ/YslizGLEYr9iwmK5YtJi22KrYtNi1GLLYshiqGK9Yrxi0GLZYsdizWK1YtpisWLYYtZi12LGYqxizmI+ZadlvGX6ZRRmE2YMZgZmAmYOZgBmD2YVZgpmB2YNZwtnbWeLZ5VncWecZ3Nnd2eHZ51nl2dvZ3Bnf2eJZ35nkGd1Z5pnk2d8Z2pncmcja2ZrZ2t/axNsG2zjbOhs82yxbMxs5WyzbL1svmy8bOJsq2zVbNNsuGzEbLlswWyubNdsxWzxbL9su2zhbNtsymysbO9s3GzWbOBslXCOcJJwinCZcCxyLXI4ckhyZ3JpcsByznLZctdy0HKpc6hzn3Orc6VzPXWddZl1mnWEdsJ28nb0duV3/Xc+eUB5QXnJech5enp5evp6/nxUf4x/i38FgLqApYCigLGAoYCrgKmAtICqgK+A5YH+gQ2Cs4KdgpmCrYK9gp+CuYKxgqyCpYKvgriCo4Kwgr6Ct4JOhnGGHVJoiMuOzo/Uj9GPtZC4kLGQtpDHkdGRd5WAlRyWQJY/ljuWRJZClrmW6JZSl16Xn06tTq5O4U+1T69Pv0/gT9FPz0/dT8NPtk/YT99Pyk/XT65P0E/ET8JP2k/OT95Pt09XUZJRkVGgUU5SQ1JKUk1STFJLUkdSx1LJUsNSwVINU1dTe1OaU9tTrFTAVKhUzlTJVLhUplSzVMdUwlS9VKpUwVTEVMhUr1SrVLFUu1SpVKdUv1T/VoJXi1egV6NXolfOV65Xk1dVWVFZT1lOWVBZ3FnYWf9Z41noWQNa5VnqWdpZ5lkBWvtZaVujW6ZbpFuiW6VbAVxOXE9cTVxLXNlc0lz3XR1eJV4fXn1eoF6mXvpeCF8tX2VfiF+FX4pfi1+HX4xfiV8SYB1gIGAlYA5gKGBNYHBgaGBiYEZgQ2BsYGtgamBkYEFi3GIWYwlj/GLtYgFj7mL9Ygdj8WL3Yu9i7GL+YvRiEWMCYz9lRWWrZb1l4mUlZi1mIGYnZi9mH2YoZjFmJGb3Zv9n02fxZ9Rn0GfsZ7Znr2f1Z+ln72fEZ9FntGfaZ+VnuGfPZ95n82ewZ9ln4mfdZ9JnamuDa4ZrtWvSa9drH2zJbAttMm0qbUFtJW0MbTFtHm0XbTttPW0+bTZtG231bDltJ204bSltLm01bQ5tK22rcLpws3CscK9wrXC4cK5wpHAwcnJyb3J0culy4HLhcrdzynO7c7JzzXPAc7NzGnUtdU91THVOdUt1q3WkdaV1onWjdXh2hnaHdoh2yHbGdsN2xXYBd/l2+HYJdwt3/nb8dgd33HcCeBR4DHgNeEZ5SXlIeUd5uXm6edF50nnLeX96gXr/ev16fXwCfQV9AH0JfQd9BH0GfTh/jn+/fwSAEIANgBGANoDWgOWA2oDDgMSAzIDhgNuAzoDegOSA3YD0gSKC54IDgwWD44LbguaCBIPlggKDCYPSgteC8YIBg9yC1ILRgt6C04Lfgu+CBoNQhnmGe4Z6hk2Ia4iBidSJCIoCigOKnoygjHSNc420jc2OzI7wj+aP4o/qj+WP7Y/rj+SP6I/KkM6QwZDDkEuRSpHNkYKVUJZLlkyWTZZil2mXy5ftl/OXAZiomNuY35iWmZmZWE6zTgxQDVAjUO9PJlAlUPhPKVAWUAZQPFAfUBpQElARUPpPAFAUUChQ8U8hUAtQGVAYUPNP7k8tUCpQ/k8rUAlQfFGkUaVRolHNUcxRxlHLUVZSXFJUUltSXVIqU39Tn1OdU99T6FQQVQFVN1X8VOVU8lQGVfpUFFXpVO1U4VQJVe5U6lTmVCdVB1X9VA9VA1cEV8JX1FfLV8NXCVgPWVdZWFlaWRFaGFocWh9aG1oTWuxZIFojWilaJVoMWglaa1tYXLBbs1u2W7Rbrlu1W7lbuFsEXFFcVVxQXO1c/Vz7XOpc6FzwXPZcAV30XO5dLV4rXqterV6nXjFfkl+RX5BfWWBjYGVgUGBVYG1gaWBvYIRgn2CaYI1glGCMYIVglmBHYvNiCGP/Yk5jPmMvY1VjQmNGY09jSWM6Y1BjPWMqYytjKGNNY0xjSGVJZZllwWXFZUJmSWZPZkNmUmZMZkVmQWb4ZhRnFWcXZyFoOGhIaEZoU2g5aEJoVGgpaLNoF2hMaFFoPWj0Z1BoQGg8aENoKmhFaBNoGGhBaIpriWu3ayNsJ2wobCZsJGzwbGptlW2IbYdtZm14bXdtWW2TbWxtiW1ubVptdG1pbYxtim15bYVtZW2Ubcpw2HDkcNlwyHDPcDlyeXL8cvly/XL4cvdyhnPtcwl07nPgc+pz3nNUdV11XHVadVl1vnXFdcd1snWzdb11vHW5dcJ1uHWLdrB2ynbNds52KXcfdyB3KHfpdzB4J3g4eB14NHg3eCV4LXggeB94MnhVeVB5YHlfeVZ5XnldeVd5WnnkeeN553nfeeZ56XnYeYR6iHrZegZ7EXuJfCF9F30LfQp9IH0ifRR9EH0VfRp9HH0NfRl9G306f19/lH/Ff8F/BoAYgBWAGYAXgD2AP4DxgAKB8IAFge2A9IAGgfiA84AIgf2ACoH8gO+A7YHsgQCCEIIqgiuCKIIsgruCK4NSg1SDSoM4g1CDSYM1gzSDT4MygzmDNoMXg0CDMYMog0ODVIaKhqqGk4akhqmGjIajhpyGcIh3iIGIgoh9iHmIGIoQig6KDIoVigqKF4oTihaKD4oRikiMeox5jKGMoox3jayO0o7Ujs+OsY8BkAaQ948AkPqP9I8DkP2PBZD4j5WQ4ZDdkOKQUpFNkUyR2JHdkdeR3JHZkYOVYpZjlmGWW5ZdlmSWWJZelruW4pismaia2JolmzKbPJt+TnpQfVBcUEdQQ1BMUFpQSVBlUHZQTlBVUHVQdFB3UE9QD1BvUG1QXFGVUfBRalJvUtJS2VLYUtVSEFMPUxlTP1NAUz5Tw1P8ZkZValVmVURVXlVhVUNVSlUxVVZVT1VVVS9VZFU4VS5VXFUsVWNVM1VBVVdVCFcLVwlX31cFWApYBljgV+RX+lcCWDVY91f5VyBZYlk2WkFaSVpmWmpaQFo8WmJaWlpGWkpacFvHW8VbxFvCW79bxlsJXAhcB1xgXFxcXVwHXQZdDl0bXRZdIl0RXSldFF0ZXSRdJ10XXeJdOF42XjNeN163Xrhetl61Xr5eNV83X1dfbF9pX2tfl1+ZX55fmF+hX6BfnF9/YKNgiWCgYKhgy2C0YOZgvWDFYLtgtWDcYLxg2GDVYMZg32C4YNpgx2AaYhtiSGKgY6djcmOWY6JjpWN3Y2djmGOqY3FjqWOJY4Njm2NrY6hjhGOIY5ljoWOsY5Jjj2OAY3tjaWNoY3pjXWVWZVFlWWVXZV9VT2VYZVVlVGWcZZtlrGXPZctlzGXOZV1mWmZkZmhmZmZeZvlm11IbZ4For2iiaJNotWh/aHZosWinaJdosGiDaMRorWiGaIVolGidaKhon2ihaIJoMmu6a+tr7GsrbI5tvG3zbdltsm3hbcxt5G37bfptBW7Hbcttr23Rba5t3m35bbht9231bcVt0m0abrVt2m3rbdht6m3xbe5t6G3GbcRtqm3sbb9t5m35cAlxCnH9cO9wPXJ9coFyHHMbcxZzE3MZc4dzBXQKdAN0BnT+cw104HT2dPd0HHUidWV1ZnVidXB1j3XUddV1tXXKdc11jnbUdtJ223Y3dz53PHc2dzh3OndreEN4TnhleWh5bXn7eZJ6lXogeyh7G3sseyZ7GXseey57knyXfJV8Rn1DfXF9Ln05fTx9QH0wfTN9RH0vfUJ9Mn0xfT1/nn+af8x/zn/SfxyASoBGgC+BFoEjgSuBKYEwgSSBAoI1gjeCNoI5go6DnoOYg3iDooOWg72Dq4OSg4qDk4OJg6CDd4N7g3yDhoOng1WGal/HhsCGtobEhrWGxobLhrGGr4bJhlOInoiIiKuIkoiWiI2Ii4iTiY+JKoodiiOKJYoxii2KH4obiiKKSYxajKmMrIyrjKiMqoynjGeNZo2+jbqN247fjhmQDZAakBeQI5AfkB2QEJAVkB6QIJAPkCKQFpAbkBSQ6JDtkP2QV5HOkfWR5pHjkeeR7ZHpkYmVapZ1lnOWeJZwlnSWdpZ3lmyWwJbqlumW4HrfegKYA5ham+WcdZ5/nqWeu56iUI1QhVCZUJFQgFCWUJhQmlAAZ/FRclJ0UnVSaVLeUt1S21JaU6VTe1WAVadVfFWKVZ1VmFWCVZxVqlWUVYdVi1WDVbNVrlWfVT5VslWaVbtVrFWxVX5ViVWrVZlVDVcvWCpYNFgkWDBYMVghWB1YIFj5WPpYYFl3Wppaf1qSWptap1pzW3Fb0lvMW9Nb0FsKXAtcMVxMXVBdNF1HXf1dRV49XkBeQ15+XspewV7CXsRePF9tX6lfql+oX9Fg4WCyYLZg4GAcYSNh+mAVYfBg+2D0YGhh8WAOYfZgCWEAYRJhH2JJYqNjjGPPY8Bj6WPJY8ZjzWPSY+Nj0GPhY9Zj7WPuY3Zj9GPqY9tjUmTaY/ljXmVmZWJlY2WRZZBlr2VuZnBmdGZ2Zm9mkWZ6Zn5md2b+Zv9mH2cdZ/po1WjgaNho12gFad9o9WjuaOdo+WjSaPJo42jLaM1oDWkSaQ5pyWjaaG5p+2g+azprPWuYa5ZrvGvvay5sL2wsbC9uOG5UbiFuMm5nbkpuIG4lbiNuG25bblhuJG5Wbm5uLW4mbm9uNG5NbjpuLG5Dbh1uPm7LboluGW5ObmNuRG5ybmluX24ZcRpxJnEwcSFxNnFucRxxTHKEcoByNnMlczRzKXM6dCp0M3QidCV0NXQ2dDR0L3QbdCZ0KHQldSZ1a3VqdeJ123Xjddl12HXedeB1e3Z8dpZ2k3a0dtx2T3ftd114bHhveA16CHoLegV6AHqYepd6lnrleuN6SXtWe0Z7UHtSe1R7TXtLe097UXuffKV8Xn1QfWh9VX0rfW59cn1hfWZ9Yn1wfXN9hFXUf9V/C4BSgIWAVYFUgUuBUYFOgTmBRoE+gUyBU4F0gRKCHILpgwOE+IMNhOCDxYMLhMGD74Pxg/SDV4QKhPCDDITMg/2D8oPKgziEDoQEhNyDB4TUg9+DW4bfhtmG7YbUhtuG5IbQht6GV4jBiMKIsYiDiZaJO4pgilWKXoo8ikGKVIpbilCKRoo0ijqKNopWimGMgoyvjLyMs4y9jMGMu4zAjLSMt4y2jL+MuIyKjYWNgY3Ojd2Ny43ajdGNzI3bjcaN+474jvyOnI8ukDWQMZA4kDKQNpACkfWQCZH+kGORZZHPkRSSFZIjkgmSHpINkhCSB5IRkpSVj5WLlZGVk5WSlY6VipaOlouWfZaFloaWjZZyloSWwZbFlsSWxpbHlu+W8pbMlwWYBpgImOeY6pjvmOmY8pjtmK6ZrZnDns2e0Z6CTq1QtVCyULNQxVC+UKxQt1C7UK9Qx1B/UndSfVLfUuZS5FLiUuNSL1PfVehV01XmVc5V3FXHVdFV41XkVe9V2lXhVcVVxlXlVclVElcTV15YUVhYWFdYWlhUWGtYTFhtWEpYYlhSWEtYZ1nBWslazFq+Wr1avFqzWsJaslppXW9dTF55XsleyF4SX1lfrF+uXxphD2FIYR9h82AbYflgAWEIYU5hTGFEYU1hPmE0YSdhDWEGYTdhIWIiYhNkPmQeZCpkLWQ9ZCxkD2QcZBRkDWQ2ZBZkF2QGZGxln2WwZZdmiWaHZohmlmaEZphmjWYDZ5RpbWlaaXdpYGlUaXVpMGmCaUppaGlraV5pU2l5aYZpXWljaVtpR2tya8Brv2vTa/1rom6vbtNutm7CbpBunW7HbsVupW6Ybrxuum6rbtFulm6cbsRu1G6qbqdutG5OcVlxaXFkcUlxZ3FccWxxZnFMcWVxXnFGcWhxVnE6clJyN3NFcz9zPnNvdFp0VXRfdF50QXQ/dFl0W3RcdHZ1eHUAdvB1AXbydfF1+nX/dfR183Xedt92W3drd2Z3Xndjd3l3andsd1x3ZXdod2J37neOeLB4l3iYeIx4iXh8eJF4k3h/eHp5f3mBeSyEvXkcehp6IHoUeh96HnqfeqB6d3vAe2B7bntne7F8s3y1fJN9eX2RfYF9j31bfW5/aX9qf3J/qX+of6R/VoBYgIaAhIBxgXCBeIFlgW6Bc4FrgXmBeoFmgQWCR4KChHeEPYQxhHWEZoRrhEmEbIRbhDyENYRhhGOEaYRthEaEXoZchl+G+YYThwiHB4cAh/6G+4YChwOHBocKh1mI34jUiNmI3IjYiN2I4YjKiNWI0oicieOJa4pyinOKZoppinCKh4p8imOKoIpxioWKbYpiim6KbIp5inuKPopoimKMioyJjMqMx4zIjMSMsozDjMKMxYzhjd+N6I3vjfON+o3qjeSN5o2yjgOPCY/+jgqPn4+yj0uQSpBTkEKQVJA8kFWQUJBHkE+QTpBNkFGQPpBBkBKRF5FskWqRaZHJkTeSV5I4kj2SQJI+kluSS5JkklGSNJJJkk2SRZI5kj+SWpKYlZiWlJaVls2Wy5bJlsqW95b7lvmW9pZWl3SXdpcQmBGYE5gKmBKYDJj8mPSY/Zj+mLOZsZm0meGa6ZyCng6fE58gn+dQ7lDlUNZQ7VDaUNVQz1DRUPFQzlDpUGJR81GDUoJSMVOtU/5VAFYbVhdW/VUUVgZWCVYNVg5W91UWVh9WCFYQVvZVGFcWV3VYfliDWJNYilh5WIVYfVj9WCVZIlkkWWpZaVnhWuZa6VrXWtZa2FrjWnVb3lvnW+Fb5VvmW+hb4lvkW99bDVxiXIRdh11bXmNeVV5XXlRe017WXgpfRl9wX7lfR2E/YUthd2FiYWNhX2FaYVhhdWEqYodkWGRUZKRkeGRfZHpkUWRnZDRkbWR7ZHJloWXXZdZlomaoZp1mnGmoaZVpwWmuadNpy2mbabdpu2mrabRp0GnNaa1pzGmmacNpo2lJa0xrM2wzbxRv/m4Tb/RuKW8+byBvLG8PbwJvIm//bu9uBm8xbzhvMm8jbxVvK28vb4hvKm/sbgFv8m7MbvdulHGZcX1xinGEcZJxPnKScpZyRHNQc2R0Y3RqdHB0bXQEdZF1J3YNdgt2CXYTduF243aEd313f3dhd8F4n3ineLN4qXijeI55j3mNeS56MXqqeql67XrveqF7lXuLe3V7l3ude5R7j3u4e4d7hHu5fL18vny7fbB9nH29fb59oH3KfbR9sn2xfbp9on2/fbV9uH2tfdJ9x32sfXB/4H/hf99/XoBagIeAUIGAgY+BiIGKgX+BgoHngfqBB4IUgh6CS4LJhL+ExoTEhJmEnoSyhJyEy4S4hMCE04SQhLyE0YTKhD+HHIc7hyKHJYc0hxiHVYc3hymH84gCifSI+Yj4iP2I6Igaie+IpoqMip6Ko4qNiqGKk4qkiqqKpYqoipiKkYqaiqeKaoyNjIyM04zRjNKMa42ZjZWN/I0UjxKPFY8Tj6OPYJBYkFyQY5BZkF6QYpBdkFuQGZEYkR6RdZF4kXeRdJF4koCShZKYkpaSe5KTkpySqJJ8kpGSoZWolamVo5WllaSVmZaclpuWzJbSlgCXfJeFl/aXF5gYmK+YsZgDmQWZDJkJmcGZr5qwmuaaQZtCm/Sc9pzznLyeO59KnwRRAFH7UPVQ+VACUQhRCVEFUdxRh1KIUolSjVKKUvBSslMuVjtWOVYyVj9WNFYpVlNWTlZXVnRWNlYvVjBWgFifWJ5Ys1icWK5YqVimWG1ZCVv7Wgtb9VoMWwhb7lvsW+lb61tkXGVcnV2UXWJeX15hXuJe2l7fXt1e417gXkhfcV+3X7VfdmFnYW5hXWFVYYJhfGFwYWthfmGnYZBhq2GOYaxhmmGkYZRhrmEuYmlkb2R5ZJ5ksmSIZJBksGSlZJNklWSpZJJkrmStZKtkmmSsZJlkomSzZHVld2V4Za5mq2a0ZrFmI2ofauhpAWoeahlq/WkhahNqCmrzaQJqBWrtaRFqUGtOa6RrxWvGaz9vfG+Eb1FvZm9Ub4ZvbW9bb3hvbm+Ob3pvcG9kb5dvWG/Vbm9vYG9fb59xrHGxcahxVnKbck5zV3NpdIt0g3R+dIB0f3Ugdil2H3YkdiZ2IXYidpp2unbkdo53h3eMd5F3i3fLeMV4unjKeL541Xi8eNB4P3o8ekB6PXo3ejt6r3queq17sXvEe7R7xnvHe8F7oHvMe8p84H30fe99+33Yfex93X3ofeN92n3efel9nn3ZffJ9+X11f3d/r3/pfyaAm4GcgZ2BoIGagZiBF4U9hRqF7oQshS2FE4URhSOFIYUUheyEJYX/hAaFgod0h3aHYIdmh3iHaIdZh1eHTIdTh1uIXYgQiQeJEokTiRWJCom8itKKx4rEipWKy4r4irKKyYrCir+KsIrWis2Ktoq5ituKTIxOjGyM4IzejOaM5IzsjO2M4ozjjNyM6ozhjG2Nn42jjSuOEI4djiKOD44pjh+OIY4ejrqOHY8bjx+PKY8mjyqPHI8ejyWPaZBukGiQbZB3kDCRLZEnkTGRh5GJkYuRg5HFkruSt5LqkqyS5JLBkrOSvJLSkseS8JKykq2VsZUElwaXB5cJl2CXjZeLl4+XIZgrmByYs5gKmROZEpkYmd2Z0JnfmduZ0ZnVmdKZ2Zm3mu6a75onm0WbRJt3m2+bBp0JnQOdqZ6+ns6eqFhSnxJRGFEUURBRFVGAUapR3VGRUpNS81JZVmtWeVZpVmRWeFZqVmhWZVZxVm9WbFZiVnZWwVi+WMdYxVhuWR1bNFt4W/BbDlxKX7JhkWGpYYphzWG2Yb5hymHIYTBixWTBZMtku2S8ZNpkxGTHZMJkzWS/ZNJk1GS+ZHRlxmbJZrlmxGbHZrhmPWo4ajpqWWpralhqOWpEamJqYWpLakdqNWpfakhqWWt3awVswm+xb6Fvw2+kb8Fvp2+zb8BvuW+2b6ZvoG+0b75xyXHQcdJxyHHVcblxznHZcdxxw3HEcWhznHSjdJh0n3SedOJ0DHUNdTR2OHY6dud25Xagd553n3eld+h42njseOd4pnlNek56RnpMekt6unrZexF8yXvke9t74Xvpe+Z71XzWfAp+EX4Ifht+I34efh1+CX4Qfnl/sn/wf/F/7n8ogLOBqYGogfuBCIJYglmCSoVZhUiFaIVphUOFSYVthWqFXoWDh5+Hnoeih42HYYgqiTKJJYkriSGJqommieaK+orrivGKAIvciueK7or+igGLAov3iu2K84r2ivyKa4xtjJOM9IxEjjGONI5CjjmONY47jy+POI8zj6iPpo91kHSQeJBykHyQepA0kZKRIJM2k/iSM5MvkyKT/JIrkwSTGpMQkyaTIZMVky6TGZO7laeWqJaqltWWDpcRlxaXDZcTlw+XW5dcl2aXmJcwmDiYO5g3mC2YOZgkmBCZKJkemRuZIZkame2Z4pnxmbiavJr7mu2aKJuRmxWdI50mnSidEp0bndie1J6Nn5yfKlEfUSFRMlH1Uo5WgFaQVoVWh1aPVtVY01jRWM5YMFsqWyRbels3XGhcvF26Xb1duF1rXkxfvV/JYcJhx2HmYcthMmI0Ys5kymTYZOBk8GTmZOxk8WTiZO1kgmWDZdlm1maAapRqhGqiapxq22qjan5ql2qQaqBqXGuua9prCGzYb/Fv32/gb9tv5G/rb+9vgG/sb+Fv6W/Vb+5v8G/ncd9x7nHmceVx7XHscfRx4HE1ckZycHNyc6l0sHSmdKh0RnZCdkx26nazd6p3sHesd6d3rXfvd/d4+nj0eO94AXmneap5V3q/egd8DXz+e/d7DHzge+B83HzefOJ833zZfN18Ln4+fkZ+N34yfkN+K349fjF+RX5BfjR+OX5IfjV+P34vfkR/83/8f3GAcoBwgG+Ac4DGgcOBuoHCgcCBv4G9gcmBvoHogQmCcYKqhYSFfoWchZGFlIWvhZuFh4WohYqFZ4bAh9GHs4fSh8aHq4e7h7qHyIfLhzuJNolEiTiJPYmsiQ6LF4sZixuLCosgix2LBIsQi0GMP4xzjPqM/Yz8jPiM+4yojUmOS45IjkqORI8+j0KPRY8/j3+QfZCEkIGQgpCAkDmRo5GekZyRTZOCkyiTdZNKk2WTS5MYk36TbJNbk3CTWpNUk8qVy5XMlciVxpWxlriW1pYclx6XoJfTl0aYtpg1mQGa/5mum6ubqputmzudP52Lns+e3p7cnt2e254+n0uf4lOVVq5W2VjYWDhbXV/jYTNi9GTyZP5kBmX6ZPtk92S3ZdxmJmezaqxqw2q7arhqwmquaq9qX2t4a69rCXALcP5vBnD6bxFwD3D7cfxx/nH4cXdzdXOndL90FXVWdlh2Una9d793u3e8dw55rnlhemJ6YHrEesV6K3wnfCp8HnwjfCF853xUflV+Xn5afmF+Un5Zfkh/+X/7f3eAdoDNgc+BCoLPhamFzYXQhcmFsIW6hbmFpoXvh+yH8ofgh4aJson0iSiLOYssiyuLUIwFjVmOY45mjmSOX45VjsCOSY9Nj4eQg5CIkKuRrJHQkZSTipOWk6KTs5Ouk6yTsJOYk5qTl5PUldaV0JXVleKW3JbZltuW3pYkl6OXppetl/mXTZhPmEyYTphTmLqYPpk/mT2ZLpmlmQ6awZoDmwabT5tOm02bypvJm/2byJvAm1GdXZ1gneCeFZ8snzNRpVbeWN9Y4lj1W5Cf7F7yYfdh9mH1YQBlD2XgZt1m5Wrdatpq02obcB9wKHAacB1wFXAYcAZyDXJYcqJyeHN6c710ynTjdId1hnVfdmF2x3cZebF5a3ppej58P3w4fD18N3xAfGt+bX55fml+an6Ff3N+tn+5f7h/2IHphd2F6oXVheSF5YX3hfuHBYgNiPmH/odgiV+JVoleiUGLXItYi0mLWotOi0+LRotZiwiNCo18jnKOh452jmyOeo50jlSPTo+tj4qQi5Cxka6R4ZPRk9+Tw5PIk9yT3ZPWk+KTzZPYk+ST15Pok9yVtJbjliqXJ5dhl9yX+5demFiYW5i8mEWZSZkWmhmaDZvom+eb1pvbm4mdYZ1ynWqdbJ2Snpeek560nvhSqFa3VrZWtFa8VuRYQFtDW31b9lvJXfhh+mEYZRRlGWXmZidn7Go+cDBwMnAQcntzz3RidmV2JnkqeSx5K3nHevZ6THxDfE1873zwfK6PfX58foJ+TH8AgNqBZoL7hfmFEYb6hQaGC4YHhgqGFIgViGSJuon4iXCLbItmi2+LX4triw+NDY2JjoGOhY6CjrSRy5EYlAOU/ZPhlTCXxJhSmVGZqJkrmjCaN5o1mhOcDZx5nrWe6J4vn1+fY59hnzdROFHBVsBWwlYUWWxczV38Yf5hHWUcZZVl6Wb7agRr+mqya0xwG3KnctZ01HRpdtN3UHyPfox+vH8Xhi2GGoYjiCKIIYgfiGqJbIm9iXSLd4t9ixONio6NjouOX4+vj7qRLpQzlDWUOpQ4lDKUK5TilTiXOZcyl/+XZ5hlmFeZRZpDmkCaPprPmlSbUZstnCWcr520ncKduJ2dnu+eGZ9cn2afZ588UTtRyFbKVslWf1vUXdJdTl//YSRlCmtha1FwWHCAc+R0inVudmx2s3lgfF98foB9gN+BcolvifyJgIsWjReNkY6TjmGPSJFElFGUUpQ9lz6Xw5fBl2uYVZlVmk2a0poam0mcMZw+nDuc053XnTSfbJ9qn5SfzFbWXQBiI2UrZSpl7GYQa9p0ynpkfGN8ZXyTfpZ+lH7igTiGP4YxiIqLkJCPkGOUYJRklGiXb5hcmVqaW5pXmtOa1JrRmlScV5xWnOWdn570ntFW6VgsZV5wcXZydtd3UH+IfzaIOYhiiJOLkouWi3eCG43AkWqUQpdIl0SXxpdwmF+aIptYm1+c+Z36nXyefZ4Hn3efcp/zXhZrY3BsfG58O4jAiaGOwZFylHCUcZhemdaaI5vMnmRw2neai3eUyZdimmWanH6ci6qOxZF9lH6UfJR3nHic955UjH+UGp4ocmqaMZsbnh6ecnxgJGEkYiRjJGQkZSRmJGckaCRpJHQkdSR2JHckeCR5JHokeyR8JH0kcCFxIXIhcyF0IXUhdiF3IXgheSE2Tj9OhU6gToJRllGrUflSOFNpU7ZTClmAW9tdMy9/XvReUF9hXzRl4GWSdXZ2tY+2lqgAxgL9MP4wnTCeMAMw3U4FMAYwBzD8MDv/Pf89J0EwQjBDMEQwRTBGMEcwSDBJMEowSzBMME0wTjBPMFAwUTBSMFMwVDBVMFYwVzBYMFkwWjBbMFwwXTBeMF8wYDBhMGIwYzBkMGUwZjBnMGgwaTBqMGswbDBtMG4wbzBwMHEwcjBzMHQwdTB2MHcweDB5MHowezB8MH0wfjB/MIAwgTCCMIMwhDCFMIYwhzCIMIkwijCLMIwwjTCOMI8wkDCRMJIwkzChMKIwozCkMKUwpjCnMKgwqTCqMKswrDCtMK4wrzCwMLEwsjCzMLQwtTC2MLcwuDC5MLowuzC8ML0wvjC/MMAwwTDCMMMwxDDFMMYwxzDIMMkwyjDLMMwwzTDOMM8w0DDRMNIw0zDUMNUw1jDXMNgw2TDaMNsw3DDdMN4w3zDgMOEw4jDjMOQw5TDmMOcw6DDpMOow6zDsMO0w7jDvMPAw8TDyMPMw9DD1MPYwEAQRBBIEEwQUBBUEAQQWBBcEGAQZBBoEGwQcBB0EHgQfBCAEIQQiBCMEJAQlBCYEJwQoBCkEKgQrBCwELQQuBC8EMAQxBDIEMwQ0BDUEUQQ2BDcEOAQ5BDoEOwQ8BD0EPgQ/BEAEQQRCBEMERARFBEYERwRIBEkESgRLBEwETQROBE8E5yG4IbkhzzHMAFpOigACUpFEsJ+IUbGfB3YAQZbI0AALuYUB4v/k/wf/Av8xMhYhISGbMJwwgC6ELoYuhy6ILooujC6NLpUunC6dLqUupy6qLqwuri62Lrwuvi7GLsouzC7NLs8u1i7XLt4u4y4AAAAAAACDAlACWwJUAnUCUwH4AEsBigJqAkJOXE71URpTglMHTgxOR06NTtdWDPpuXHNfD06HUQ5OLk6TTsJOyU7ITphR/FJsU7lTIFcDWSxZEFz/XeFls2vMaxRsP3IxTjxO6E7cTulO4U7dTtpODFIcU0xTIlcjVxdZL1mBW4RbElw7XHRcc1wEXoBegl7JXwliUGIVbDZsQ2w/bDtsrnKwcopzuHmKgB6WDk8YTyxP9U4UT/FOAE/3TghPHU8CTwVPIk8TTwRP9E4ST7FRE1IJUhBSplIiUx9TTVOKUwdU4VbfVi5XKlc0VzxZgFl8WYVZe1l+WXdZf1lWWxVcJVx8XHpce1x+XN9ddV6EXgJfGl90X9Vf1F/PX1xiXmJkYmFiZmJiYlliYGJaYmVi72XuZT5nOWc4ZztnOmc/ZzxnM2cYbEZsUmxcbE9sSmxUbEtsTGxxcF5ytHK1co5zKnV/dnV6UX94gnyCgIJ9gn+CTYZ+iZmQl5CYkJuQlJAiliSWIJYjllZPO09iT0lPU09kTz5PZ09ST19PQU9YTy1PM08/T2FPj1G5URxSHlIhUq1SrlIJU2NTclOOU49TMFQ3VCpUVFRFVBlUHFQlVBhUPVRPVEFUKFQkVEdU7lbnVuVWQVdFV0xXSVdLV1JXBllAWaZZmFmgWZdZjlmiWZBZj1mnWaFZjluSWyhcKlyNXI9ciFyLXIlcklyKXIZck1yVXOBdCl4OXoteiV6MXohejV4FXx1feF92X9Jf0V/QX+1f6F/uX/Nf4V/kX+Nf+l/vX/df+18AYPRfOmKDYoxijmKPYpRih2JxYntiemJwYoFiiGJ3Yn1icmJ0Yjdl8GX0ZfNl8mX1ZUVnR2dZZ1VnTGdIZ11nTWdaZ0tn0GsZbBpseGxnbGtshGyLbI9scWxvbGlsmmxtbIdslWycbGZsc2xlbHtsjmx0cHpwY3K/cr1yw3LGcsFyunLFcpVzl3OTc5RzknM6dTl1lHWVdYF2PXk0gJWAmYCQgJKAnICQgo+ChYKOgpGCk4KKgoOChIJ4jMmPv4+fkKGQpZCekKeQoJAwliiWL5YtljNOmE98T4VPfU+AT4dPdk90T4lPhE93T0xPl09qT5pPeU+BT3hPkE+cT5RPnk+ST4JPlU9rT25PnlG8Ub5RNVIyUjNSRlIxUrxSClMLUzxTklOUU4dUf1SBVJFUglSIVGtUelR+VGVUbFR0VGZUjVRvVGFUYFSYVGNUZ1RkVPdW+VZvV3JXbVdrV3FXcFd2V4BXdVd7V3NXdFdiV2hXfVcMWUVZtVm6Wc9ZzlmyWcxZwVm2WbxZw1nWWbFZvVnAWchZtFnHWWJbZVuTW5VbRFxHXK5cpFygXLVcr1yoXKxcn1yjXK1colyqXKdcnVylXLZcsFymXBdeFF4ZXihfIl8jXyRfVF+CX35ffV/eX+VfLWAmYBlgMmALYDRgCmAXYDNgGmAeYCxgImANYBBgLmATYBFgDGAJYBxgFGI9Yq1itGLRYr5iqmK2YspirmKzYq9iu2KpYrBiuGI9Zahlu2UJZvxlBGYSZghm+2UDZgtmDWYFZv1lEWYQZvZmCmeFZ2xnjmeSZ3Zne2eYZ4ZnhGd0Z41njGd6Z59nkWeZZ4NnfWeBZ3hneWeUZyVrgGt+a95rHWyTbOxs62zubNlstmzUbK1s52y3bNBswmy6bMNsxmztbPJs0mzdbLRsimydbIBs3mzAbDBtzWzHbLBs+WzPbOls0WyUcJhwhXCTcIZwhHCRcJZwgnCacINwanLWcsty2HLJctxy0nLUctpyzHLRcqRzoXOtc6ZzonOgc6xznXPddOh0P3VAdT51jHWYda9283bxdvB29Xb4d/x3+Xf7d/p393dCeT95xXl4ent6+3p1fP18NYCPgK6Ao4C4gLWArYAggqCCwIKrgpqCmIKbgrWCp4KugryCnoK6grSCqIKhgqmCwoKkgsOCtoKignCGb4Zthm6GVozSj8uP04/Nj9aP1Y/Xj7KQtJCvkLOQsJA5lj2WPJY6lkOWzU/FT9NPsk/JT8tPwU/UT9xP2U+7T7NP20/HT9ZPuk/AT7lP7E9EUklSwFLCUj1TfFOXU5ZTmVOYU7pUoVStVKVUz1TDVA2Dt1SuVNZUtlTFVMZUoFRwVLxUolS+VHJU3lSwVLVXnlefV6RXjFeXV51Xm1eUV5hXj1eZV6VXmleVV/RYDVlTWeFZ3lnuWQBa8VndWfpZ/Vn8WfZZ5FnyWfdZ21npWfNZ9VngWf5Z9FntWahbTFzQXNhczFzXXMtc21zeXNpcyVzHXMpc1lzTXNRcz1zIXMZczlzfXPhc+V0hXiJeI14gXiResF6kXqJem16jXqVeB18uX1Zfhl83YDlgVGByYF5gRWBTYEdgSWBbYExgQGBCYF9gJGBEYFhgZmBuYEJiQ2LPYg1jC2P1Yg5jA2PrYvliD2MMY/hi9mIAYxNjFGP6YhVj+2LwYkFlQ2WqZb9lNmYhZjJmNWYcZiZmImYzZitmOmYdZjRmOWYuZg9nEGfBZ/JnyGe6Z9xnu2f4Z9hnwGe3Z8Vn62fkZ99ntWfNZ7Nn92f2Z+5n42fCZ7lnzmfnZ/Bnsmf8Z8Zn7WfMZ65n5mfbZ/pnyWfKZ8Nn6mfLZyhrgmuEa7Zr1mvYa+BrIGwhbChtNG0tbR9tPG0/bRJtCm3abDNtBG0ZbTptGm0RbQBtHW1CbQFtGG03bQNtD21AbQdtIG0sbQhtIm0JbRBtt3CfcL5wsXCwcKFwtHC1cKlwQXJJckpybHJwcnNybnLKcuRy6HLrct9y6nLmcuNyhXPMc8JzyHPFc7lztnO1c7Rz63O/c8dzvnPDc8ZzuHPLc+x07nQudUd1SHWndap1eXbEdgh3A3cEdwV3Cnf3dvt2+nbnd+h3BngReBJ4BXgQeA94DngJeAN4E3hKeUx5S3lFeUR51XnNec951nnOeYB6fnrRegB7AXt6fHh8eXx/fIB8gXwDfQh9AX1Yf5F/jX++fweADoAPgBSAN4DYgMeA4IDRgMiAwoDQgMWA44DZgNyAyoDVgMmAz4DXgOaAzYD/gSGClILZgv6C+YIHg+iCAIPVgjqD64LWgvSC7ILhgvKC9YIMg/uC9oLwguqC5ILggvqC84LtgneGdIZ8hnOGQYhOiGeIaohpiNOJBIoHinKN44/hj+6P4I/xkL2Qv5DVkMWQvpDHkMuQyJDUkdORVJZPllGWU5ZKlk6WHlAFUAdQE1AiUDBQG1D1T/RPM1A3UCxQ9k/3TxdQHFAgUCdQNVAvUDFQDlBaUZRRk1HKUcRRxVHIUc5RYVJaUlJSXlJfUlVSYlLNUg5TnlMmVeJUF1USVedU81TkVBpV/1QEVQhV61QRVQVV8VQKVftU91T4VOBUDlUDVQtVAVcCV8xXMljVV9JXulfGV71XvFe4V7ZXv1fHV9BXuVfBVw5ZSlkZWhZaLVouWhVaD1oXWgpaHlozWmxbp1utW6xbA1xWXFRc7Fz/XO5c8Vz3XABd+VwpXiheqF6uXqperF4zXzBfZ19dYFpgZ2BBYKJgiGCAYJJggWCdYINglWCbYJdgh2CcYI5gGWJGYvJiEGNWYyxjRGNFYzZjQ2PkYzljS2NKYzxjKWNBYzRjWGNUY1ljLWNHYzNjWmNRYzhjV2NAY0hjSmVGZcZlw2XEZcJlSmZfZkdmUWYSZxNnH2gaaEloMmgzaDtoS2hPaBZoMWgcaDVoK2gtaC9oTmhEaDRoHWgSaBRoJmgoaC5oTWg6aCVoIGgsay9rLWsxazRrbWuCgIhr5mvka+hr42via+drJWx6bWNtZG12bQ1tYW2SbVhtYm1tbW9tkW2Nbe9tf22GbV5tZ21gbZdtcG18bV9tgm2YbS9taG2LbX5tgG2EbRZtg217bX1tdW2Qbdxw03DRcN1wy3A5f+Jw13DScN5w4HDUcM1wxXDGcMdw2nDOcOFwQnJ4cndydnIAc/py9HL+cvZy83L7cgFz03PZc+Vz1nO8c+dz43Ppc9xz0nPbc9Rz3XPac9dz2HPoc95033T0dPV0IXVbdV91sHXBdbt1xHXAdb91tnW6dYp2yXYddxt3EHcTdxJ3I3cRdxV3GXcadyJ3J3cjeCx4Ing1eC94KHgueCt4IXgpeDN4KngxeFR5W3lPeVx5U3lSeVF563nseeB57nnteep53Hneed15hnqJeoV6i3qMeop6h3rYehB7BHsTewV7D3sIewp7DnsJexJ7hHyRfIp8jHyIfI18hXwefR19EX0OfRh9Fn0TfR99En0PfQx9XH9hf15/YH9df1t/ln+Sf8N/wn/AfxaAPoA5gPqA8oD5gPWAAYH7gACBAYIvgiWCM4Mtg0SDGYNRgyWDVoM/g0GDJoMcgyKDQoNOgxuDKoMIgzyDTYMWgySDIIM3gy+DKYNHg0WDTINTgx6DLINLgyeDSINThlKGooaohpaGjYaRhp6Gh4aXhoaGi4aahoWGpYaZhqGGp4aVhpiGjoadhpCGlIZDiESIbYh1iHaIcoiAiHGIf4hviIOIfoh0iHyIEopHjFeMe4ykjKOMdo14jbWNt422jdGO047+j/WPApD/j/uPBJD8j/aP1pDgkNmQ2pDjkN+Q5ZDYkNuQ15DckOSQUJFOkU+R1ZHikdqRXJZflryW45jfmi+bf05wUGpQYVBeUGBQU1BLUF1QclBIUE1QQVBbUEpQYlAVUEVQX1BpUGtQY1BkUEZQQFBuUHNQV1BRUNBRa1JtUmxSblLWUtNSLVOcU3VVdlU8VU1VUFU0VSpVUVViVTZVNVUwVVJVRVUMVTJVZVVOVTlVSFUtVTtVQFVLVQpXB1f7VxRY4lf2V9xX9FcAWO1X/VcIWPhXC1jzV89XB1juV+NX8lflV+xX4VcOWPxXEFjnVwFYDFjxV+lX8FcNWARYXFlgWlhaVVpnWl5aOFo1Wm1aUFpfWmVabFpTWmRaV1pDWl1aUlpEWltaSFqOWj5aTVo5WkxacFppWkdaUVpWWkJaXFpyW25bwVvAW1lcHl0LXR1dGl0gXQxdKF0NXSZdJV0PXTBdEl0jXR9dLl0+XjResV60Xrlesl6zXjZfOF+bX5Zfn1+KYJBghmC+YLBgumDTYNRgz2DkYNlg3WDIYLFg22C3YMpgv2DDYM1gwGAyY2VjimOCY31jvWOeY61jnWOXY6tjjmNvY4djkGNuY69jdWOcY21jrmN8Y6RjO2OfY3hjhWOBY5FjjWNwY1NlzWVlZmFmW2ZZZlxmYmYYZ3loh2iQaJxobWhuaK5oq2hWaW9oo2isaKlodWh0aLJoj2h3aJJofGhraHJoqmiAaHFofmibaJZoi2igaIlopGh4aHtokWiMaIpofWg2azNrN2s4a5Frj2uNa45rjGsqbMBtq220bbNtdG6sbelt4m23bfZt1G0Absht4G3fbdZtvm3lbdxt3W3bbfRtym29be1t8G26bdVtwm3Pbclt0G3ybdNt/W3Xbc1t4227bfpwDXH3cBdx9HAMcfBwBHHzcBBx/HD/cAZxE3EAcfhw9nALcQJxDnF+cntyfHJ/ch1zF3MHcxFzGHMKcwhz/3IPcx5ziHP2c/hz9XMEdAF0/XMHdAB0+nP8c/9zDHQLdPRzCHRkdWN1znXSdc91y3XMddF10HWPdol203Y5dy93LXcxdzJ3NHczdz13JXc7dzV3SHhSeEl4TXhKeEx4JnhFeFB4ZHlneWl5anljeWt5YXm7efp5+Hn2efd5j3qUepB6NXtHezR7JXsweyJ7JHszexh7KnsdezF7K3stey97Mns4exp7I3uUfJh8lnyjfDV9PX04fTZ9On1FfSx9KX1BfUd9Pn0/fUp9O30ofWN/lX+cf51/m3/Kf8t/zX/Qf9F/x3/Pf8l/H4AegBuAR4BDgEiAGIElgRmBG4EtgR+BLIEegSGBFYEngR2BIoERgjiCM4I6gjSCMoJ0gpCDo4Oog42DeoNzg6SDdIOPg4GDlYOZg3WDlIOpg32Dg4OMg52Dm4Oqg4uDfoOlg6+DiIOXg7CDf4Omg4eDroN2g5qDWYZWhr+Gt4bChsGGxYa6hrCGyIa5hrOGuIbMhrSGu4a8hsOGvYa+hlKIiYiViKiIooiqiJqIkYihiJ+ImIiniJmIm4iXiKSIrIiMiJOIjoiCidaJ2YnViTCKJ4osih6KOYw7jFyMXYx9jKWMfY17jXmNvI3CjbmNv43BjdiO3o7djtyO147gjuGOJJALkBGQHJAMkCGQ75DqkPCQ9JDykPOQ1JDrkOyQ6ZBWkViRWpFTkVWR7JH0kfGR85H4keSR+ZHqkeuR95Hoke6RepWGlYiVfJZtlmuWcZZvlr+WapcEmOWYl5mbUJVQlFCeUItQo1CDUIxQjlCdUGhQnFCSUIJQh1BfUdRRElMRU6RTp1ORVahVpVWtVXdVRVaiVZNViFWPVbVVgVWjVZJVpFV9VYxVplV/VZVVoVWOVQxXKVg3WBlYHlgnWCNYKFj1V0hYJVgcWBtYM1g/WDZYLlg5WDhYLVgsWDtYYVmvWpRan1p6WqJanlp4WqZafFqlWqxalVquWjdahFqKWpdag1qLWqlae1p9WoxanFqPWpNanVrqW81by1vUW9FbylvOWwxcMFw3XUNda11BXUtdP101XVFdTl1VXTNdOl1SXT1dMV1ZXUJdOV1JXThdPF0yXTZdQF1FXUReQV5YX6ZfpV+rX8lguWDMYOJgzmDEYBRh8mAKYRZhBWH1YBNh+GD8YP5gwWADYRhhHWEQYf9gBGELYUpilGOxY7BjzmPlY+hj72PDY51k82PKY+Bj9mPVY/Jj9WNhZN9jvmPdY9xjxGPYY9NjwmPHY8xjy2PIY/Bj12PZYzJlZ2VqZWRlXGVoZWVljGWdZZ5lrmXQZdJlfGZsZntmgGZxZnlmamZyZgFnDGnTaARp3Ggqaexo6mjxaA9p1mj3aOto5Gj2aBNpEGnzaOFoB2nMaAhpcGm0aBFp72jGaBRp+GjQaP1o/GjoaAtpCmkXac5oyGjdaN5o5mj0aNFoBmnUaOloFWklacdoOWs7az9rPGuUa5drmWuVa71r8Gvya/NrMGz8bUZuR24fbkluiG48bj1uRW5ibituP25Bbl1uc24cbjNuS25AblFuO24Dbi5uXm5oblxuYW4xbihuYG5xbmtuOW4ibjBuU25lbidueG5kbnduVW55blJuZm41bjZuWm4gcR5xL3H7cC5xMXEjcSVxInEycR9xKHE6cRtxS3JacohyiXKGcoVyi3IScwtzMHMiczFzM3MnczJzLXMmcyNzNXMMcy50LHQwdCt0FnQadCF0LXQxdCR0I3QddCl0IHQydPt0L3VvdWx153XadeF15nXddd915HXXdZV2knbadkZ3R3dEd013RXdKd053S3dMd9537HdgeGR4ZXhceG14cXhqeG54cHhpeGh4XnhieHR5c3lyeXB5AnoKegN6DHoEepl65nrkekp7O3tEe0h7THtOe0B7WHtFe6J8nnyofKF8WH1vfWN9U31WfWd9an1PfW19XH1rfVJ9VH1pfVF9X31OfT5/P39lf2Z/on+gf6F/139RgE+AUID+gNSAQ4FKgVKBT4FHgT2BTYE6geaB7oH3gfiB+YEEgjyCPYI/gnWCO4PPg/mDI4TAg+iDEoTng+SD/IP2gxCExoPIg+uD44O/gwGE3YPlg9iD/4Phg8uDzoPWg/WDyYMJhA+E3oMRhAaEwoPzg9WD+oPHg9GD6oMThMOD7IPug8SD+4PXg+KDG4Tbg/6D2IbihuaG04bjhtqG6obdhuuG3IbshumG14bohtGGSIhWiFWIuojXiLmIuIjAiL6Itoi8iLeIvYiyiAGJyYiViZiJl4ndidqJ24lOik2KOYpZikCKV4pYikSKRYpSikiKUYpKikyKT4pfjIGMgIy6jL6MsIy5jLWMhI2AjYmN2I3Tjc2Nx43WjdyNz43VjdmNyI3XjcWN7473jvqO+Y7mju6O5Y71jueO6I72juuO8Y7sjvSO6Y4tkDSQL5AGkSyRBJH/kPyQCJH5kPuQAZEAkQeRBZEDkWGRZJFfkWKRYJEBkgqSJZIDkhqSJpIPkgySAJISkv+R/ZEGkgSSJ5ICkhySJJIZkheSBZIWknuVjZWMlZCVh5Z+loiWiZaDloCWwpbIlsOW8ZbwlmyXcJdulweYqZjrmOac+Z6DToROtk69UL9QxlCuUMRQylC0UMhQwlCwUMFQulCxUMtQyVC2ULhQ11F6UnhSe1J8UsNV21XMVdBVy1XKVd1VwFXUVcRV6VW/VdJVjVXPVdVV4lXWVchV8lXNVdlVwlUUV1NYaFhkWE9YTVhJWG9YVVhOWF1YWVhlWFtYPVhjWHFY/FjHWsRay1q6WrhasVq1WrBav1rIWrtaxlq3WsBaylq0WrZazVq5WpBa1lvYW9lbH1wzXHFdY11KXWVdcl1sXV5daF1nXWJd8F1PXk5eSl5NXktexV7MXsZey17HXkBfr1+tX/dgSWFKYSthRWE2YTJhLmFGYS9hT2EpYUBhIGJokSNiJWIkYsVj8WPrYxBkEmQJZCBkJGQzZENkH2QVZBhkOWQ3ZCJkI2QMZCZkMGQoZEFkNWQvZApkGmRAZCVkJ2QLZOdjG2QuZCFkDmRvZZJl02WGZoxmlWaQZotmimaZZpRmeGYgZ2ZpX2k4aU5pYmlxaT9pRWlqaTlpQmlXaVlpemlIaUlpNWlsaTNpPWllafBoeGk0aWlpQGlvaURpdmlYaUFpdGlMaTtpS2k3aVxpT2lRaTJpUmkvaXtpPGlGa0VrQ2tCa0hrQWubaw36+2v8a/lr92v4a5tu1m7Ibo9uwG6fbpNulG6gbrFuuW7GbtJuvW7Bbp5uyW63brBuzW6mbs9usm6+bsNu3G7Ybplukm6Obo1upG6hbr9us27Qbspul26ubqNuR3FUcVJxY3FgcUFxXXFicXJxeHFqcWFxQnFYcUNxS3FwcV9xUHFTcURxTXFacU9yjXKMcpFykHKOcjxzQnM7czpzQHNKc0lzRHRKdEt0UnRRdFd0QHRPdFB0TnRCdEZ0TXRUdOF0/3T+dP10HXV5dXd1g2nvdQ92A3b3df51/HX5dfh1EHb7dfZ17XX1df11mXa1dt12VXdfd2B3UndWd1p3aXdnd1R3WXdtd+B3h3iaeJR4j3iEeJV4hXiGeKF4g3h5eJl4gHiWeHt4fHmCeX15eXkRehh6GXoSehd6FXoiehN6G3oQeqN6onqeeut6Zntke217dHtpe3J7ZXtze3F7cHthe3h7dntje7J8tHyvfIh9hn2AfY19f32FfXp9jn17fYN9fH2MfZR9hH19fZJ9bX9rf2d/aH9sf6Z/pX+nf9t/3H8hgGSBYIF3gVyBaYFbgWKBcoEhZ16BdoFngW+BRIFhgR2CSYJEgkCCQoJFgvGEP4RWhHaEeYSPhI2EZYRRhECEhoRnhDCETYR9hFqEWYR0hHOEXYQHhV6EN4Q6hDSEeoRDhHiEMoRFhCmE2YNLhC+EQoQthF+EcIQ5hE6ETIRShG+ExYSOhDuER4Q2hDOEaIR+hESEK4RghFSEboRQhAuHBIf3hgyH+obWhvWGTYf4hg6HCYcBh/aGDYcFh9aIy4jNiM6I3ojbiNqIzIjQiIWJm4nfieWJ5InhieCJ4oncieaJdoqGin+KYYo/ineKgoqEinWKg4qBinSKeoo8jEuMSoxljGSMZoyGjISMhYzMjGiNaY2RjYyNjo2PjY2Nk42UjZCNko3wjeCN7I3xje6N0I3pjeON4o3njfKN6430jQaP/44BjwCPBY8HjwiPAo8Lj1KQP5BEkEmQPZAQkQ2RD5ERkRaRFJELkQ6RbpFvkUiSUpIwkjqSZpIzkmWSXpKDki6SSpJGkm2SbJJPkmCSZ5JvkjaSYZJwkjGSVJJjklCScpJOklOSTJJWkjKSn5WclZ6Vm5WSlpOWkZaXls6W+pb9lviW9ZZzl3eXeJdylw+YDZgOmKyY9pj5mK+ZspmwmbWZrZqrmlub6pztnOecgJ79nuZQ1FDXUOhQ81DbUOpQ3VDkUNNQ7FDwUO9Q41DgUNhRgFKBUulS61IwU6xTJ1YVVgxWElb8VQ9WHFYBVhNWAlb6VR1WBFb/VflViVh8WJBYmFiGWIFYf1h0WItYeliHWJFYjlh2WIJYiFh7WJRYj1j+WGtZ3FruWuVa1VrqWtpa7VrrWvNa4lrgWtta7FreWt1a2VroWt9ad1vgW+NbY1yCXYBdfV2GXXpdgV13XYpdiV2IXX5dfF2NXXldf11YXlleU17YXtFe117OXtxe1V7ZXtJe1F5EX0Nfb1+2XyxhKGFBYV5hcWFzYVJhU2FyYWxhgGF0YVRhemFbYWVhO2FqYWFhVmEpYidiK2IrZE1kW2RdZHRkdmRyZHNkfWR1ZGZkpmROZIJkXmRcZEtkU2RgZFBkf2Q/ZGxka2RZZGVkd2RzZaBloWagZp9mBWcEZyJnsWm2aclpoGnOaZZpsGmsabxpkWmZaY5pp2mNaalpvmmvab9pxGm9aaRp1Gm5acppmmnPabNpk2mqaaFpnmnZaZdpkGnCabVppWnGaUprTWtLa55rn2uga8NrxGv+a85u9W7xbgNvJW/4bjdv+24ubwlvTm8ZbxpvJ28YbztvEm/tbgpvNm9zb/lu7m4tb0BvMG88bzVv624Hbw5vQ28Fb/1u9m45bxxv/G46bx9vDW8ebwhvIW+HcZBxiXGAcYVxgnGPcXtxhnGBcZdxRHJTcpdylXKTckNzTXNRc0xzYnRzdHF0dXRydGd0bnQAdQJ1A3V9dZB1FnYIdgx2FXYRdgp2FHa4doF3fHeFd4J3bneAd293fneDd7J4qni0eK14qHh+eKt4nnileKB4rHiieKR4mHmKeYt5lnmVeZR5k3mXeYh5knmQeSt6Snowei96KHomeqh6q3qseu56iHuce4p7kXuQe5Z7jXuMe5t7jnuFe5h7hFKZe6R7gnu7fL98vHy6fKd9t33CfaN9qn3BfcB9xX2dfc59xH3Gfct9zH2vfbl9ln28fZ99pn2ufal9oX3JfXN/4n/jf+V/3n8kgF2AXICJgYaBg4GHgY2BjIGLgRWCl4SkhKGEn4S6hM6EwoSshK6Eq4S5hLSEwYTNhKqEmoSxhNCEnYSnhLuEooSUhMeEzISbhKmEr4SohNaEmIS2hM+EoITXhNSE0oTbhLCEkYRhhjOHI4coh2uHQIcuhx6HIYcZhxuHQ4csh0GHPodGhyCHMocqhy2HPIcShzqHMYc1h0KHJocnhziHJIcahzCHEYf3iOeI8YjyiPqI/ojuiPyI9oj7iPCI7IjriJ2JoYmfiZ6J6YnrieiJq4qZiouKkoqPipaKPYxojGmM1YzPjNeMlo0JjgKO/40Njv2NCo4DjgeOBo4Fjv6NAI4EjhCPEY8Ojw2PI5EckSCRIpEfkR2RGpEkkSGRG5F6kXKReZFzkaWSpJJ2kpuSepKgkpSSqpKNkqaSmpKrknmSl5J/kqOS7pKOkoKSlZKikn2SiJKhkoqShpKMkpmSp5J+koeSqZKdkouSLZKelqGW/5ZYl32Xepd+l4OXgJeCl3uXhJeBl3+XzpfNlxaYrZiumAKZAJkHmZ2ZnJnDmbmZu5m6mcKZvZnHmbGa45rnmj6bP5tgm2GbX5vxnPKc9Zynnv9QA1EwUfhQBlEHUfZQ/lALUQxR/VAKUYtSjFLxUu9SSFZCVkxWNVZBVkpWSVZGVlhWWlZAVjNWPVYsVj5WOFYqVjpWGlerWJ1YsVigWKNYr1isWKVYoVj/WP9a9Fr9Wvda9loDW/haAlv5WgFbB1sFWw9bZ1yZXZddn12SXaJdk12VXaBdnF2hXZpdnl1pXl1eYF5cXvN9217eXuFeSV+yX4thg2F5YbFhsGGiYYlhm2GTYa9hrWGfYZJhqmGhYY1hZmGzYS1ibmRwZJZkoGSFZJdknGSPZItkimSMZKNkn2RoZLFkmGR2ZXpleWV7ZbJls2W1ZrBmqWayZrdmqmavZgBqBmoXauVp+GkVavFp5Gkgav9p7GniaRtqHWr+aSdq8mnuaRRq92nnaUBqCGrmaftpDWr8aetpCWoEahhqJWoPavZpJmoHavRpFmpRa6Vro2uia6ZrAWwAbP9rAmxBbyZvfm+Hb8Zvkm+Nb4lvjG9ib09vhW9ab5Zvdm9sb4JvVW9yb1JvUG9Xb5Rvk29dbwBvYW9rb31vZ2+Qb1Nvi29pb39vlW9jb3dvam97b7Jxr3GbcbBxoHGacalxtXGdcaVxnnGkcaFxqnGccadxs3GYcppyWHNSc15zX3Ngc11zW3Nhc1pzWXNic4d0iXSKdIZ0gXR9dIV0iHR8dHl0CHUHdX51JXYedhl2HXYcdiN2GnYodht2nHaddp52m3aNd493iXeId814u3jPeMx40XjOeNR4yHjDeMR4yXiaeaF5oHmceaJ5m3l2azl6snq0erN6t3vLe757rHvOe697uXvKe7V7xXzIfMx8y3z3fdt96n3nfdd94X0Dfvp95n32ffF98H3ufd99dn+sf7B/rX/tf+t/6n/sf+Z/6H9kgGeAo4GfgZ6BlYGigZmBl4EWgk+CU4JSglCCToJRgiSFO4UPhQCFKYUOhQmFDYUfhQqFJ4UchfuEK4X6hAiFDIX0hCqF8oQVhfeE64TzhPyEEoXqhOmEFoX+hCiFHYUuhQKF/YQehfaEMYUmheeE6ITwhO+E+YQYhSCFMIULhRmFL4VihlaHY4dkh3eH4Ydzh1iHVIdbh1KHYYdah1GHXodth2qHUIdOh1+HXYdvh2yHeoduh1yHZYdPh3uHdYdih2eHaYdaiAWJDIkUiQuJF4kYiRmJBokWiRGJDokJiaKJpImjie2J8Insic+Kxoq4itOK0YrUitWKu4rXir6KwIrFitiKw4q6ir2K2Yo+jE2Mj4zljN+M2YzojNqM3YznjKCNnI2hjZuNII4jjiWOJI4ujhWOG44WjhGOGY4mjieOFI4SjhiOE44cjheOGo4sjySPGI8ajyCPI48WjxePc5BwkG+QZ5BrkC+RK5EpkSqRMpEmkS6RhZGGkYqRgZGCkYSRgJHQksOSxJLAktmStpLPkvGS35LYkumS15LdksyS75LCkuiSypLIks6S5pLNktWSyZLgkt6S55LRktOStZLhksaStJJ8layVq5WulbCVpJailtOWBZcIlwKXWpeKl46XiJfQl8+XHpgdmCaYKZgomCCYG5gnmLKYCJn6mBGZFJkWmReZFZncmc2Zz5nTmdSZzpnJmdaZ2JnLmdeZzJmzmuya65rzmvKa8ZpGm0ObZ5t0m3GbZpt2m3WbcJtom2SbbJv8nPqc/Zz/nPecB50Anfmc+5wInQWdBJ2DntOeD58QnxxRE1EXURpREVHeUTRT4VNwVmBWblZzVmZWY1ZtVnJWXlZ3VhxXG1fIWL1YyVi/WLpYwli8WMZYF1sZWxtbIVsUWxNbEFsWWyhbGlsgWx5b71usXbFdqV2nXbVdsF2uXapdqF2yXa1dr120XWdeaF5mXm9e6V7nXuZe6F7lXktfvF+dYahhlmHFYbRhxmHBYcxhumG/YbhhjGHXZNZk0GTPZMlkvWSJZMNk22TzZNlkM2V/ZXxlomXIZr5mwGbKZstmz2a9ZrtmumbMZiNnNGpmaklqZ2oyamhqPmpdam1qdmpbalFqKGpaajtqP2pBampqZGpQak9qVGpvamlqYGo8al5qVmpVak1qTmpGalVrVGtWa6drqmura8hrx2sEbANsBmytb8tvo2/Hb7xvzm/Ib15vxG+9b55vym+obwRwpW+ub7pvrG+qb89vv2+4b6JvyW+rb81vr2+yb7BvxXHCcb9xuHHWccBxwXHLcdRxynHHcc9xvXHYcbxxxnHacdtxnXKecmlzZnNnc2xzZXNrc2pzf3SadKB0lHSSdJV0oXQLdYB1L3YtdjF2PXYzdjx2NXYydjB2u3bmdpp3nXehd5x3m3eid6N3lXeZd5d33XjpeOV46njeeON423jheOJ47XjfeOB4pHlEekh6R3q2erh6tXqxerd63nvje+d73XvVe+V72nvoe/l71Hvqe+J73Hvre9h733vSfNR813zQfNF8En4hfhd+DH4ffiB+E34Ofhx+FX4afiJ+C34PfhZ+DX4UfiV+JH5Df3t/fH96f7F/738qgCmAbICxgaaBroG5gbWBq4GwgayBtIGygbeBp4HygVWCVoJXglaFRYVrhU2FU4VhhViFQIVGhWSFQYVihUSFUYVHhWOFPoVbhXGFToVuhXWFVYVnhWCFjIVmhV2FVIVlhWyFY4ZlhmSGm4ePh5eHk4eSh4iHgYeWh5iHeYeHh6OHhYeQh5GHnYeEh5SHnIeah4mHHokmiTCJLYkuiSeJMYkiiSmJI4kviSyJH4nxieCK4oryivSK9YrdihSL5IrfivCKyIreiuGK6Ir/iu+K+4qRjJKMkIz1jO6M8YzwjPOMbI1ujaWNp40zjj6OOI5AjkWONo48jj2OQY4wjj+OvY42jy6PNY8yjzmPN480j3aQeZB7kIaQ+pAzkTWRNpGTkZCRkZGNkY+RJ5MekwiTH5MGkw+TepM4kzyTG5MjkxKTAZNGky2TDpMNk8uSHZP6kiWTE5P5kveSNJMCkyST/5IpkzmTNZMqkxSTDJMLk/6SCZMAk/uSFpO8lc2VvpW5lbqVtpW/lbWVvZWpltSWC5cSlxCXmZeXl5SX8Jf4lzWYL5gymCSZH5knmSmZnpnumeyZ5ZnkmfCZ45nqmemZ55m5mr+atJq7mvaa+pr5mveaM5uAm4Wbh5t8m36be5uCm5ObkpuQm3qblZt9m4ibJZ0XnSCdHp0UnSmdHZ0YnSKdEJ0ZnR+diJ6Gnoeerp6tntWe1p76nhKfPZ8mUSVRIlEkUSBRKVH0UpNWjFaNVoZWhFaDVn5WglZ/VoFW1ljUWM9Y0lgtWyVbMlsjWyxbJ1smWy9bLlt7W/Fb8lu3XWxeal6+X7tfw2G1Ybxh52HgYeVh5GHoYd5h72TpZONk62TkZOhkgWWAZbZl2mXSZo1qlmqBaqVqiWqfaptqoWqeaodqk2qOapVqg2qoaqRqkWp/aqZqmmqFaoxqkmpba61rCWzMb6lv9G/Ub+Nv3G/tb+dv5m/eb/Jv3W/ib+hv4XHxcehx8nHkcfBx4nFzc25zb3OXdLJ0q3SQdKp0rXSxdKV0r3QQdRF1EnUPdYR1Q3ZIdkl2R3akdul2tXerd7J3t3e2d7R3sXeod/B383j9eAJ5+3j8ePJ4BXn5eP54BHmreah5XHpbelZ6WHpUelp6vnrAesF6BXwPfPJ7AHz/e/t7Dnz0ewt883sCfAl8A3wBfPh7/XsGfPB78XsQfAp86Hwtfjx+Qn4zfkiYOH4qfkl+QH5Hfil+TH4wfjt+Nn5Efjp+RX9/f35/fX/0f/J/LIC7gcSBzIHKgcWBx4G8gemBW4JaglyCg4WAhY+Fp4WVhaCFi4WjhXuFpIWahZ6Fd4V8hYmFoYV6hXiFV4WOhZaFhoWNhZmFnYWBhaKFgoWIhYWFeYV2hZiFkIWfhWiGvoeqh62HxYewh6yHuYe1h7yHrofJh8OHwofMh7eHr4fEh8qHtIe2h7+HuIe9h96Hsoc1iTOJPIk+iUGJUok3iUKJrYmvia6J8onziR6LGIsWixGLBYsLiyKLD4sSixWLB4sNiwiLBoscixOLGotPjHCMcoxxjG+MlYyUjPmMb41Ojk2OU45QjkyOR45Dj0CPhZB+kDiRmpGikZuRmZGfkaGRnZGgkaGTg5Ovk2STVpNHk3yTWJNck3aTSZNQk1GTYJNtk4+TTJNqk3mTV5NVk1KTT5Nxk3eTe5Nhk16TY5Nnk4CTTpNZk8eVwJXJlcOVxZW3la6WsJasliCXH5cYlx2XGZeal6GXnJeel52X1ZfUl/GXQZhEmEqYSZhFmEOYJZkrmSyZKpkzmTKZL5ktmTGZMJmYmaOZoZkCmvqZ9Jn3mfmZ+Jn2mfuZ/Zn+mfyZA5q+mv6a/ZoBm/yaSJuam6ibnpubm6aboZulm6Sbhpuim6Cbr5sznUGdZ502nS6dL50xnTidMJ1FnUKdQ50+nTedQJ09nfV/LZ2KnomejZ6wnsie2p77nv+eJJ8jnyKfVJ+gnzFRLVEuUZhWnFaXVppWnVaZVnBZPFtpXGpcwF1tXm5e2GHfYe1h7mHxYeph8GHrYdZh6WH/ZARl/WT4ZAFlA2X8ZJRl22XaZttm2GbFarlqvWrhasZqumq2ardqx2q0aq1qXmvJawtsB3AMcA1wAXAFcBRwDnD/bwBw+28mcPxv928KcAFy/3H5cQNy/XF2c7h0wHS1dMF0vnS2dLt0wnQUdRN1XHZkdll2UHZTdld2Wnamdr127HbCd7p3/3gMeRN5FHkJeRB5EnkRea15rHlfehx8KXwZfCB8H3wtfB18JnwofCJ8JXwwfFx+UH5WfmN+WH5ifl9+UX5gfld+U361f7N/93/4f3WA0YHSgdCBX4JegrSFxoXAhcOFwoWzhbWFvYXHhcSFv4XLhc6FyIXFhbGFtoXShSSGuIW3hb6FaYbnh+aH4ofbh+uH6oflh9+H84fkh9SH3IfTh+2H2Ifjh6SH14fZhwGI9Ifoh92HU4lLiU+JTIlGiVCJUYlJiSqLJ4sjizOLMIs1i0eLL4s8iz6LMYslizeLJos2iy6LJIs7iz2LOotCjHWMmYyYjJeM/owEjQKNAI1cjmKOYI5XjlaOXo5ljmeOW45ajmGOXY5pjlSORo9Hj0iPS48okTqRO5E+kaiRpZGnka+RqpG1k4yTkpO3k5uTnZOJk6eTjpOqk56TppOVk4iTmZOfk42TsZORk7KTpJOok7STo5Olk9KV05XRlbOW15balsJd35bYlt2WI5cilyWXrJeul6iXq5ekl6qXopell9eX2ZfWl9iX+pdQmFGYUpi4mEGZPJk6mQ+aC5oJmg2aBJoRmgqaBZoHmgaawJrcmgibBJsFmymbNZtKm0ybS5vHm8abw5u/m8GbtZu4m9ObtpvEm7mbvZtcnVOdT51KnVudS51ZnVadTJ1XnVKdVJ1fnVidWp2Onoye354BnwCfFp8lnyufKp8pnyifTJ9VnzRRNVGWUvdStFOrVq1WplanVqpWrFbaWN1Y21gSWT1bPls/W8NdcF6/X/thB2UQZQ1lCWUMZQ5lhGXeZd1l3mbnauBqzGrRatlqy2rfatxq0Grras9qzWreamBrsGsMbBlwJ3AgcBZwK3AhcCJwI3ApcBdwJHAccCpwDHIKcgdyAnIFcqVypnKkcqNyoXLLdMV0t3TDdBZ1YHbJd8p3xHfxdx15G3kheRx5F3keebB5Z3poejN8PHw5fCx8O3zsfOp8dn51fnh+cH53fm9+en5yfnR+aH5Lf0p/g3+Gf7d//X/+f3iA14HVgWSCYYJjguuF8YXthdmF4YXohdqF14XshfKF+IXYhd+F44XchdGF8IXmhe+F3oXihQCI+ocDiPaH94cJiAyIC4gGiPyHCIj/hwqIAohiiVqJW4lXiWGJXIlYiV2JWYmIibeJton2iVCLSItKi0CLU4tWi1SLS4tVi1GLQotSi1eLQ4x3jHaMmowGjQeNCY2sjaqNrY2rjW2OeI5zjmqOb457jsKOUo9Rj0+PUI9Tj7SPQJE/kbCRrZHek8eTz5PCk9qT0JP5k+yTzJPZk6mT5pPKk9ST7pPjk9WTxJPOk8CT0pPnk32V2pXbleGWKZcrlyyXKJcml7OXt5e2l92X3pffl1yYWZhdmFeYv5i9mLuYvphImUeZQ5mmmaeZGpoVmiWaHZokmhuaIpogmieaI5oemhyaFJrCmgubCpsOmwybN5vqm+ub4Jvem+Sb5pvim/Cb1JvXm+yb3JvZm+Wb1Zvhm9qbd52BnYqdhJ2InXGdgJ14nYadi52MnX2da510nXWdcJ1pnYWdc517nYKdb515nX+dh51onZSekZ7AnvyeLZ9An0GfTZ9Wn1efWJ83U7JWtVazVuNYRVvGXcdd7l7vXsBfwV/5YRdlFmUVZRNl32XoZuNm5GbzavBq6mroavlq8Wruau9qPHA1cC9wN3A0cDFwQnA4cD9wOnA5cEBwO3AzcEFwE3IUcqhyfXN8c7p0q3aqdr527XbMd853z3fNd/J3JXkjeSd5KHkkeSl5snluemx6bXr3ekl8SHxKfEd8RXzufHt+fn6BfoB+un//f3mA24HZgQuCaIJpgiKG/4UBhv6FG4YAhvaFBIYJhgWGDIb9hRmIEIgRiBeIE4gWiGOJZom5ifeJYItqi12LaItji2WLZ4tti66Nho6IjoSOWY9Wj1ePVY9Yj1qPjZBDkUGRt5G1kbKRs5ELlBOU+5MglA+UFJT+kxWUEJQolBmUDZT1kwCU95MHlA6UFpQSlPqTCZT4kwqU/5P8kwyU9pMRlAaU3pXgld+VLpcvl7mXu5f9l/6XYJhimGOYX5jBmMKYUJlOmVmZTJlLmVOZMpo0mjGaLJoqmjaaKZoumjiaLZrHmsqaxpoQmxKbEZsLnAic95sFnBKc+JtAnAecDpwGnBecFJwJnJ+dmZ2knZ2dkp2YnZCdm52gnZSdnJ2qnZedoZ2anaKdqJ2enaOdv52pnZadpp2nnZmem56anuWe5J7nnuaeMJ8un1ufYJ9en12fWZ+RnzpROVGYUpdSw1a9Vr5WSFtHW8tdz13xXv1hG2UCa/xqA2v4agBrQ3BEcEpwSHBJcEVwRnAdchpyGXJ+cxd1anbQdy15MXkveVR8U3zyfIp+h36Ifot+hn6Nfk1/u38wgN2BGIYqhiaGH4YjhhyGGYYnhi6GIYYghimGHoYlhimIHYgbiCCIJIgciCuISohtiWmJbolrifqJeYt4i0WLeot7ixCNFI2vjY6OjI5ej1uPXY9GkUSRRZG5kT+UO5Q2lCmUPZQ8lDCUOZQqlDeULJRAlDGU5ZXkleOVNZc6l7+X4ZdkmMmYxpjAmFiZVpk5mj2aRppEmkKaQZo6mj+azZoVmxebGJsWmzqbUpsrnB2cHJwsnCOcKJwpnCScIZy3nbadvJ3Bncedyp3Pnb6dxZ3DnbudtZ3Onbmdup2sncidsZ2tncyds53NnbKdep6cnuue7p7tnhufGJ8anzGfTp9ln2Sfkp+5TsZWxVbLVnFZS1tMW9Vd0V3yXiFlIGUmZSJlC2sIawlrDWxVcFZwV3BScB5yH3Kpcn9z2HTVdNl013Rtdq12NXm0eXB6cXpXfFx8WXxbfFp89HzxfJF+T3+Hf96Ba4I0hjWGM4YshjKGNoYsiCiIJogqiCWIcYm/ib6J+4l+i4SLgouGi4WLf4sVjZWOlI6ajpKOkI6WjpeOYI9ij0eRTJRQlEqUS5RPlEeURZRIlEmURpQ/l+OXaphpmMuYVJlbmU6aU5pUmkyaT5pImkqaSZpSmlCa0JoZmyubO5tWm1WbRpxInD+cRJw5nDOcQZw8nDecNJwynD2cNpzbndKd3p3ancud0J3cndGd353pndmd2J3WnfWd1Z3dnbae8J41nzOfMp9Cn2uflZ+inz1RmVLoWOdYcllNW9hdL4hPXwFiA2IEYillJWWWZetmEWsSaw9rymtbcFpwInKCc4Fzg3NwdtR3Z3xmfJV+bII6hkCGOYY8hjGGO4Y+hjCIMoguiDOIdol0iXOJ/omMi46Li4uIi0WMGY2YjmSPY4+8kWKUVZRdlFeUXpTEl8WXAJhWmlmaHpsfmyCbUpxYnFCcSpxNnEucVZxZnEyc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zQPOAwAAgACBAIIAgwCEAIUAhgCHAIgAiQCKAIsAjACNAI4AjwCQAJEAkgCTAJQAlQCWAJcAmACZAJoAmwCcAJ0AngCfAKAAAACiAKMApAClAKYApwCoAKkA1wCrAKwArQCuAK8AsACxALIAswC0ALUAtgC3ALgAuQD3ALsAvAC9AL4AQb7v0QAL9B0XINAF0QXSBdMF1AXVBdYF1wXYBdkF2gXbBdwF3QXeBd8F4AXhBeIF4wXkBeUF5gXnBegF6QXqBQAAAAAOIA8gAACAAIEAggCDAIQAhQCGAIcAiACJAIoAiwCMAI0AjgCPAJAAkQCSAJMAlACVAJYAlwCYAJkAmgCbAJwAnQCeAJ8AoAAEARIBIgEqASgBNgGnADsBEAFgAWYBfQGtAGoBSgGwAAUBEwEjASsBKQE3AbcAPAERAWEBZwF+ARUgawFLAQABwQDCAMMAxADFAMYALgEMAckAGAHLABYBzQDOAM8A0ABFAUwB0wDUANUA1gBoAdgAcgHaANsA3ADdAN4A3wABAeEA4gDjAOQA5QDmAC8BDQHpABkB6wAXAe0A7gDvAPAARgFNAfMA9AD1APYAaQH4AHMB+gD7APwA/QD+ADgBgACBAIIAgwCEAIUAhgCHAIgAiQCKAIsAjACNAI4AjwCQAJEAkgCTAJQAlQCWAJcAmACZAJoAmwCcAJ0AngCfAKAAHSCiAKMApAAeIKYApwDYAKkAVgGrAKwArQCuAMYAsACxALIAswAcILUAtgC3APgAuQBXAbsAvAC9AL4A5gAEAS4BAAEGAcQAxQAYARIBDAHJAHkBFgEiATYBKgE7AWABQwFFAdMATAHVANYA1wByAUEBWgFqAdwAewF9Ad8ABQEvAQEBBwHkAOUAGQETAQ0B6QB6ARcBIwE3ASsBPAFhAUQBRgHzAE0B9QD2APcAcwFCAVsBawH8AHwBfgEZIIAAgQCCAIMAhACFAIYAhwCIAIkAigCLAIwAjQCOAI8AkACRAJIAkwCUAJUAlgCXAJgAmQCaAJsAnACdAJ4AnwCgAAIeAx6jAAoBCwEKHqcAgB6pAIIeCx7yHq0ArgB4AR4eHx4gASEBQB5BHrYAVh6BHlcegx5gHvMehB6FHmEewADBAMIAwwDEAMUAxgDHAMgAyQDKAMsAzADNAM4AzwB0AdEA0gDTANQA1QDWAGoe2ADZANoA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3wBVAeEA4gADAeQAOgEHAecADQHpABkB6wAbAe0A7gAPAREBRAFIAfMA9ABRAfYA9wBZAW8B+gBxAfwA/QBjAdkCAgQDBBogUwQeICYgICAhIKwgMCAJBDkgCgQMBAsEDwRSBBggGSAcIB0gIiATIBQgmAAiIVkEOiBaBFwEWwRfBKAADgReBAgEpACQBKYApwABBKkABASrAKwArQCuAAcEsACxAAYEVgSRBLUAtgC3AFEEFiFUBLsAWAQFBFUEVwQQBBEEEgQTBBQEFQQWBBcEGAQZBBoEGwQcBB0EHgQfBCAEIQQiBCMEJAQlBCYEJwQoBCkEKgQrBCwELQQuBC8EMAQxBDIEMwQ0BDUENgQ3BDgEOQQ6BDsEPAQ9BD4EPwRABEEEQgRDBEQERQRGBEcESARJBEoESwRMBE0ETgRPBKwggQAaIJIBHiAmICAgISDGAjAgYAE5IFIBjQB9AY8AkAAYIBkgHCAdICIgEyAUINwCIiFhATogUwGdAH4BeAGgAKEAogCjAKQApQCmAKcAqACpAKoAqwCsAK0ArgCvALAAsQCyALMAtAC1ALYAtwC4ALkAugC7ALwAvQC+AL8AwADBAMIAwwDEAMUAxgDHAMgAyQDKAMsAzADNAM4AzwDQANEA0gDTANQA1QDWANcA2ADZANoA2wDcAN0A3gDfAOAA4QDiAOMA5ADlAOYA5wDoAOkA6gDrAOwA7QDuAO8A8ADxAPIA8wD0APUA9gD3APgA+QD6APsA/AD9AP4A/wCsIIEAGiCSAR4gJiAgICEgiAAwIIoAOSCMAI0AjgCPAJAAGCAZIBwgHSAiIBMgFCCYACIhmgA6IJwAnQCeAJ8AoACFA4YDowCkAKUApgCnAKgAqQAAAKsArACtAK4AFSCwALEAsgCzAIQDtQC2ALcAiAOJA4oDuwCMA70AjgOPA5ADkQOSA5MDlAOVA5YDlwOYA5kDmgObA5wDnQOeA58DoAOhAwAAowOkA6UDpgOnA6gDqQOqA6sDrAOtA64DrwOwA7EDsgOzA7QDtQO2A7cDuAO5A7oDuwO8A70DvgO/A8ADwQPCA8MDxAPFA8YDxwPIA8kDygPLA8wDzQPOAwAArCCBABogkgEeICYgICAhIMYCMCBgATkgUgGNAI4AjwCQABggGSAcIB0gIiATIBQg3AIiIWEBOiBTAZ0AngB4AaAAoQCiAKMApAClAKYApwCoAKkAqgCrAKwArQCuAK8AsACxALIAswC0ALUAtgC3ALgAuQC6ALsAvAC9AL4AvwDAAMEAwgDDAMQAxQDGAMcAyADJAMoAywDMAM0AzgDPAB4B0QDSANMA1ADVANYA1wDYANkA2gDbANwAMAFeAd8A4ADhAOIA4wDkAOUA5gDnAOgA6QDqAOsA7ADtAO4A7wAfAfEA8gDzAPQA9QD2APcA+AD5APoA+wD8ADEBXwH/AKwggQAaIJIBHiAmICAgISDGAjAgigA5IIwAjQCOAI8AkAAYIBkgHCAdICIgEyAUINwCIiGaADognACdAJ4AnwCgAKEAogCjAKogpQCmAKcAqACpANcAqwCsAK0ArgCvALAAsQCyALMAtAC1ALYAtwC4ALkA9wC7ALwAvQC+AL8AsAWxBbIFswW0BbUFtgW3BbgFuQW6BbsFvAW9Bb4FvwXABcEFwgXDBfAF8QXyBfMF9AUAQcCN0gALw3bQBdEF0gXTBdQF1QXWBdcF2AXZBdoF2wXcBd0F3gXfBeAF4QXiBeMF5AXlBeYF5wXoBekF6gUAAAAADiAPIAAArCB+BhogkgEeICYgICAhIMYCMCB5BjkgUgGGBpgGiAavBhggGSAcIB0gIiATIBQgqQYiIZEGOiBTAQwgDSC6BqAADAaiAKMApAClAKYApwCoAKkAvgarAKwArQCuAK8AsACxALIAswC0ALUAtgC3ALgAuQAbBrsAvAC9AL4AHwbBBiEGIgYjBiQGJQYmBicGKAYpBioGKwYsBi0GLgYvBjAGMQYyBjMGNAY1BjYG1wA3BjgGOQY6BkAGQQZCBkMG4ABEBuIARQZGBkcGSAbnAOgA6QDqAOsASQZKBu4A7wBLBkwGTQZOBvQATwZQBvcAUQb5AFIG+wD8AA4gDyDSBqwggQAaIIMAHiAmICAgISCIADAgigA5IIwAqADHArgAkAAYIBkgHCAdICIgEyAUIJgAIiGaADognACvANsCnwCgAAAAogCjAKQAAACmAKcA2ACpAFYBqwCsAK0ArgDGALAAsQCyALMAtAC1ALYAtwD4ALkAVwG7ALwAvQC+AOYABAEuAQABBgHEAMUAGAESAQwByQB5ARYBIgE2ASoBOwFgAUMBRQHTAEwB1QDWANcAcgFBAVoBagHcAHsBfQHfAAUBLwEBAQcB5ADlABkBEwENAekAegEXASMBNwErATwBYQFEAUYB8wBNAfUA9gD3AHMBQgFbAWsB/AB8AX4B2QKsIIEAGiCSAR4gJiAgICEgxgIwIIoAOSBSAY0AjgCPAJAAGCAZIBwgHSAiIBMgFCDcAiIhmgA6IFMBnQCeAHgBoAChAKIAowCkAKUApgCnAKgAqQCqAKsArACtAK4ArwCwALEAsgCzALQAtQC2ALcAuAC5ALoAuwC8AL0AvgC/AMAAwQDCAAIBxADFAMYAxwDIAMkAygDLAAADzQDOAM8AEAHRAAkD0wDUAKAB1gDXANgA2QDaANsA3ACvAQMD3wDgAOEA4gADAeQA5QDmAOcA6ADpAOoA6wABA+0A7gDvABEB8QAjA/MA9AChAfYA9wD4APkA+gD7APwAsAGrIP8AEAQRBBIEEwQUBBUEFgQXBBgEGQQaBBsEHAQdBB4EHwQgBCEEIgQjBCQEJQQmBCcEKAQpBCoEKwQsBC0ELgQvBCAgsACQBKMApwAiILYABgSuAKkAIiECBFIEYCIDBFMEHiKxAGQiZSJWBLUAkQQIBAQEVAQHBFcECQRZBAoEWgRYBAUErAAaIpIBSCIGIqsAuwAmIKAACwRbBAwEXARVBBMgFCAcIB0gGCAZIPcAHiAOBF4EDwRfBBYhAQRRBE8EMAQxBDIEMwQ0BDUENgQ3BDgEOQQ6BDsEPAQ9BD4EPwRABEEEQgRDBEQERQRGBEcESARJBEoESwRMBE0ETgSsIIp+HIlIk4iS3ITJT7twMWbIaPmS+2ZFXyhO4U78TgBPA085T1ZPkk+KT5pPlE/NT0BQIlD/Tx5QRlBwUEJQlFD0UNhQSlFkUZ1RvlHsURVSnFKmUsBS21IAUwdTJFNyU5NTslPdUw76nFSKVKlU/1SGVVlXZVesV8hXx1cP+hD6nliyWAtZU1lbWV1ZY1mkWbpZVlvAWy912FvsWx5cply6XPVcJ11TXRH6Ql1tXbhduV3QXSFfNF9nX7df3l9dYIVgimDeYNVgIGHyYBFhN2EwYZhhE2KmYvVjYGSdZM5kTmUAZhVmO2YJZi5mHmYkZmVmV2ZZZhL6c2aZZqBmsma/ZvpmDmcp+WZnu2dSaMBnAWhEaM9oE/poaRT6mGniaTBqa2pGanNqfmriauRq1ms/bFxshmxvbNpsBG2HbW9tlm2sbc9t+G3ybfxtOW5cbiduPG6/bohvtW/1bwVwB3AocIVwq3APcQRxXHFGcUdxFfrBcf5xsXK+ciRzFvp3c71zyXPWc+Nz0nMHdPVzJnQqdCl0LnRidIl0n3QBdW91gnacdp52m3amdhf6RnevUiF4TnhkeHp4MHkY+hn6GvqUeRv6m3nReud6HPrrep57HfpIfVx9t32gfdZ9Un5Hf6F/HvoBg2KDf4PHg/aDSIS0hFOFWYVrhR/6sIUg+iH6B4j1iBKKN4p5iqeKvorfiiL69opTi3+L8Iz0jBKNdo0j+s+OJPol+meQ3pAm+hWRJ5HakdeR3pHtke6R5JHlkQaSEJIKkjqSQJI8kk6SWZJRkjmSZ5KnkneSeJLnkteS2ZLQkif61ZLgktOSJZMhk/uSKPoek/+SHZMCk3CTV5Okk8aT3pP4kzGURZRIlJKV3Pkp+p2Wr5YzlzuXQ5dNl0+XUZdVl1eYZZgq+iv6J5ks+p6ZTprZmtyadZtym4+bsZu7mwCccJ1rnS36GZ7RnpxOFlUDWj+WwFQbYShj9lkikHWEHINQeqpg4WMlbu1lZoSmgvWbk2gnV6FlcWKbW9BZe4b0mGJ9vn2OmxZin3y3iIlbtV4JY5dmSGjHlY2XT2flTgpPTU+dT0lQ8lY3WdRZAVoJXN9gD2FwYRNmBWm6cE91cHX7ea19733DgA6EY4gCi1WQepA7U5VOpU7fV7KAwZDveABO8ViibjiQMnoog4uCL5xBUXBTvVThVOBW+1kVX/KY623kgC2FYpZwlqCW+5cLVPNTh1vPcL1/wo/olm9TXJ26ehFOk3j8gSZuGFYEVR1rGoU7nOVZqVNmbdx0j5VCVpFOS5Dylk+DDJnhU7ZVMFtxXyBm82YEaDhs82wpbVt0yHZOejSY8YJbiGCK7ZKybat1ynbFmaZgAYuKjbKVjmmtU4ZRElcwWERZtFv2XihgqWP0Y79sFG+OcBRxWXHVcT9zAX52gtGCl4VgkFuSG51pWLxlWmwldflRLlllWYBf3F+8YvplKmona7Rri3PBf1aJLJ0OncSeoVyWbHuDBFFLXLZhxoF2aGFyWU76T3hTaWApbk9685cLThZT7k5VTz1PoU9zT6BS71MJVg9ZwVq2W+Fb0XmHZpxntmdMa7Nsa3DCc415vnk8eod7sYLbggSDd4Pvg9ODZoeyiilWqIzmj06QHpeKhsRP6FwRYllyO3Xlgb2C/obAjMWWE5nVmctOGk/jid5WSljKWPte618qYJRgYmDQYRJi0GI5ZUGbZmawaHdtcHBMdYZ2dX2lgvmHi5WOlp2M8VG+UhZZs1SzWxZdaGGCaa9tjXjLhFeIcoqnk7iabG2omdmGo1f/Z86GDpKDUodWBFTTXuFiuWQ8aDhou2tyc7p4a3qaidKJa40Dj+2Qo5WUlmmXZluzXH1pTZhOmJtjIHsran9qtmgNnF9vclKdVXBg7GI7bQdu0W5bhBCJRI8UTjmc9lMbaTpqhJcqaFxRw3qyhNyRjJNbViidImgFgzGEpXwIUsWC5nR+ToNPoFHSWwpS2FLnUvtdmlUqWOZZjFuYW9tbcl55XqNgH2FjYb5h22NiZdFnU2j6aD5rU2tXbCJvl29Fb7B0GHXjdgt3/3qheyF86X02f/B/nYBmgp6Ds4nMiquMhJBRlJOVkZWilWWW05comRiCOE4rVLhczF2pc0x2PHepXOt/C43BlhGYVJhYmAFPDk9xU5xVaFb6V0dZCVvEW5BcDF5+Xsxf7mM6Z9dl4mUfZ8toxGhfajBexWsXbH1sf3VIeWNbAHoAfb1fj4kYirSMd43Mjh2P4pgOmjybgE59UABRk1mcWy9igGLsZDproHKRdUd5qX/7h7yKcIusY8qDoJcJVANUq1VUaFhqcIoneHVnzZ50U6JbGoFQhgaQGE5FTsdOEU/KUzhUrlsTXyVgUWU9Z0JscmzjbHhwA3R2eq56CHsaff58Zn3nZVtyu1NFXOhd0mLgYhljIG5ahjGK3Y34kgFvpnlam6hOq06sTptPoE/RUEdR9npxUfZRVFMhU39T61OsVYNY4Vw3X0pfL2BQYG1gH2NZZUtqwWzCcu1y73f4gAWBCIJOhfeQ4ZP/l1eZWprwTt1RLVyBZm1pQFzyZnVpiXNQaIF8xVDkUkdX/l0mk6RlI2s9azR0gXm9eUt7yn25gsyDf4hfiTmL0Y/RkR9UgJJdTjZQ5VM6U9dylnPpd+aCr47GmciZ0pl3URphXoawVXp6dlDTW0eQhZYyTttq55FRXEhcmGOfepNsdJdhj6p6inGIloJ8F2hwflFobJPyUhtUq4UTiqR/zY7hkGZTiIhBecJPvlARUkRRU1UtV+pzi1dRWWJfhF91YHZhZ2GpYbJjOmRsZW9mQmgTbmZ1PXr7fEx9mX1Lfmt/DoNKg82GCIpjimaL/Y4amI+duILOj+ibh1IfYoNkwG+ZlkFokVAga3psVG90elB9QIgjighn9k45UCZQZVB8UThSY1KnVQ9XBVjMWvpesmH4YfNicmMcaSlqfXKsci5zFHhveHl9DHepgIuJGYvijNKOY5B1k3qWVZgTmnieQ1GfU7NTe14mXxtukG6Ec/5zQ303ggCK+opQlk5OC1DkU3xU+lbRWWRb8V2rXidfOGJFZa9nVm7Qcsp8tIihgOGA8INOhoeK6I03kseWZ5gTn5ROkk4NT0hTSVQ+VC9ajF+hX59gp2iOalp0gXieiqSKd4uQkV5OyZukTnxPr08ZUBZQSVFsUZ9SuVL+UppT41MRVA5UiVVRV6JXfVlUW11bj1vlXedd9114XoNeml63XhhfUmBMYZdi2GKnYztlAmZDZvRmbWchaJdoy2lfbCptaW0vbp1uMnWHdmx4P3rgfAV9GH1efbF9FYADgK+AsYBUgY+BKoJSg0yIYYgbi6KM/IzKkHWRcZI/ePySpJVNlgWYmZnYmjudW1KrUvdTCFTVWPdi4G9qjF+PuZ5LUTtSSlT9VkB6d5FgndKeRHMJb3CBEXX9X9pgqJrbcryPZGsDmMpO8FZkV75YWlpoYMdhD2YGZjlosWj3bdV1On1ugkKbm05QT8lTBlVvXeZd7l37Z5lsc3QCeFCKlpPfiFBXp14rY7VQrFCNUQBnyVReWLtZsFtpX01ioWM9aHNrCG59cMeRgHIVeCZ4bXmOZTB93IPBiAmPm5ZkUihXUGdqf6GMtFFCVyqWOliKabSAslQOXfxXlXj6nVxPSlKLVD5kKGYUZ/VnhHpWeyJ9L5NcaK2bOXsZU4pRN1LfW/ZirmTmZC1numuphdGWkHbWm0xjBpOrm792UmYJTphQwlNxXOhgkmRjZV9o5nHKcyN1l3uCfpWGg4vbjHiREJmsZatmi2vVTtROOk9/TzpS+FPyU+NV21brWMtZyVn/WVBbTVwCXite118dYAdjL2VcW69lvWXoZZ1nYmt7aw9sRXNJecF5+HwZfSt9ooACgfOBloleimmKZoqMiu6Kx4zcjMyW/Jhva4tOPE+NT1BRV1v6W0hhAWNCZiFry267bD5yvXTUdcF4OnkMgDOA6oGUhJ6PUGx/ng9fWIsrnfp6+I6NW+uWA07xU/dXMVnJWqRbiWB/bgZvvnXqjJ9bAIXge3JQ9GedgmFcSoUefg6CmVEEXGhjZo2cZW5xPnkXfQWAHYvKjm6Qx4aqkB9Q+lI6XFNnfHA1ckyRyJErk+WCwlsxX/lgO07WU4hbS2IxZ4pr6XLgcy56a4GjjVKRlpkSUddTalT/W4hjOWqsfQCX2lbOU2hUl1sxXN5d7k8BYf5iMm3Aect5Qn1NftJ/7YEfgpCERohyiZCLdI4vjzGQS5FskcaWnJHATk9PRVFBU5NfDmLUZ0FsC25jcyZ+zZGDktRTGVm/W9FtXXkufpt8flifcfpRU4jwj8pP+1wlZqx343ocgv+ZxlGqX+xlb2mJa/Ntlm5kb/52FH3hXXWQh5EGmOZRHVJAYpFm2WYabrZe0n1yf/hmr4X3hfiKqVLZU3NZj16QX1Vg5JJklrdQH1HdUiBTR1PsU+hURlUxVRdWaFm+WTxatVsGXA9cEVwaXIReil7gXnBff2KEYttijGN3YwdmDGYtZnZmfmeiaB9qNWq8bIhtCW5YbjxxJnFnccd1AXddeAF5ZXnweeB6EXunfDl9loDWg4uESYVdiPOIH4o8ilSKc4phjN6MpJFmkn6TGJSclpiXCk4ITh5OV06XUXBSzlc0WMxYIls4XsVg/mRhZ1ZnRG22cnN1Y3q4hHKLuJEgkzFW9Ff+mO1iDWmWa+1xVH53gHKC5onfmFWHsY87XDhP4U+1TwdVIFrdW+lbw19OYS9jsGVLZu5om2l4bfFtM3W5dR93XnnmeTN944GvgqqFqok6iquOm48ykN2RB5e6TsFOA1J1WOxYC1wadT1cToEKisWPY5ZtlyV7z4oImGKR81aoUxeQOVSCVyVeqGM0bIpwYXeLfOB/cIhCkFSREJMYk4+WXnTEmgddaV1wZaJnqI3blm5jSWcZacWDF5jAlv6IhG96ZPhbFk4scF11L2bEUTZS4lLTWYFfJ2AQYj9ldGUfZnRm8mgWaGNrBW5ych9123a+fFaA8Fj9iH+JoIqTisuKHZCSkVKXWZeJZQ56BoG7li1e3GAaYqVlFGaQZ/N3TXpNfD5+CoGsjGSN4Y1fjql4B1LZYqVjQmSYYi2Kg3rAe6yK6pZ2fQyCSYfZTkhRQ1NgU6NbAlwWXN1dJmJHYrBkE2g0aMlsRW0XbdNnXG9OcX1xy2V/eq172n1Kfqh/eoEbgjmCpoVuis6M9Y14kHeQrZKRkoOVrptNUoRVOG82cWhRhXlVfrOBznxMVlFYqFyqY/5m/WZaadlyj3WOdQ55VnnfeZd8IH1EfQeGNIo7lmGQIJ/nUHVSzFPiUwlQqlXuWE9ZPXKLW2RcHVPjYPNgXGODYz9ju2PNZOll+WbjXc1p/WkVb+VxiU7pdfh2k3rffM99nH1hgEmDWINshLyE+4XFiHCNAZBtkJeTHJcSms9Ql1iOYdOBNYUIjSCQw090UEdSc1NvYEljX2csbrONH5DXT15cyozPZZp9UlOWiHZRw2NYW2tbClwNZFFnXJDWThpZKllwbFGKPlUVWKVZ8GBTYsFnNYJVaUCWxJkomlNPBlj+WxCAsVwvXoVfIGBLYTRi/2bwbN5uzoB/gdSCi4i4jACQLpCKltue25vjTvBTJ1kse42RTJj5nd1uJ3BTU0RVhVtYYp5i02KibO9vInQXijiUwW/+ijiD51H4hupT6VNGT1SQsI9qWTGB/V3qer+P2mg3jPhySJw9arCKOU5YUwZWZlfFYqJj5mVOa+FtW26tcO1373qqe7t9PYDGgMuGlYpbk+NWx1g+X61llmaAarVrN3XHiiRQ5XcwVxtfZWB6ZmBs9HUaem5/9IEYh0WQs5nJe1x1+XpRe8SEEJDpeZJ6NoPhWkB3LU7yTplb4F+9Yjxm8WfobGuGd4g7ik6R85LQmRdqJnAqc+eCV4SvjAFORlHLUYtV9VsWXjNegV4UXzVfa1+0X/JhEWOiZh1nbm9Scjp1Ond0gDmBeIF2h7+K3IqFjfONmpJ3lQKY5ZzFUldj9HYVZ4hszXPDjK6Tc5YlbZxYDmnMaf2PmpPbdRqQWlgCaLRj+2lDTyxv2Ge7jyaFtH1Ukz9pcG9qV/dYLFssfSpyClTjkbSdrU5OT1xQdVBDUp6MSFQkWJpbHV6VXq1e914fX4xgtWI6Y9Bjr2hAbId4jnkLeuB9R4ICiuaKRI4TkLiQLZHYkQ6f5WxYZOJkdWX0boR2G3tpkNGTum7yVLlfpGRNj+2PRJJ4UWtYKVlVXJde+22Pfhx1vIzijluYuXAdT79rsW8wdfuWTlEQVDVYV1isWWBckl+XZVxnIW57dt+D7YwUkP2QTZMleDp4qlKmXh9XdFkSYBJQWlGsUc1RAFIQVVRYWFhXWZVb9lyLXbxglWItZHFnQ2i8aN9o13bYbW9um21vcMhxU1/YdXd5SXtUe1J71nxxfTBSY4RpheSFDooEi0aMD44DkA+QGZR2li2YMJrYlc1Q1VIMVAJYDlynYZ5kHm2zd+V69IAEhFOQhZLgXAedP1OXX7NfnG15cmN3v3nke9Jr7HKtigNoYWr4UYF6NGlKXPac64LFW0mRHnB4Vm9cx2BmZYxsWoxBkBOYUVTHZg2SSFmjkIVRTU7qUZmFDotYcHpjS5NiabSZBH53dVdTYGnfjuOWXWyMTjxcEF/pjwJT0YyJgHmG/17lZXNOZVGCWT9c7pf7TopZzV+NiuFvsHlieedbcYQrc7FxdF71X3tjmmTDcZh8Q078XktO3FeiVqlgw28Nff2AM4G/gbKPl4mkhvRdimKtZIeJd2fibD5tNnQ0eEZadX+tgqyZ80/DXt1ikmNXZW9nw3ZMcsyAuoApj02RDVD5V5JahWhzaWRx/XK3jPJY4IxqlhmQf4fkeed3KYQvT2VSWlPNYs9nymx9dpR7lXw2goSF64/dZiBvBnIbfquDwZmmnv1RsXtyeLh7h4BIe+hqYV6MgFF1YHVrUWKSjG56dpeR6poQT3B/nGJPe6WV6Zx6VllY5Ia8ljRPJFJKU81T21MGXixkkWV/Zz5sTmxIcq9y7XNUdUF+LILphamMxHvGkWlxEpjvmD1jaWZqdeR20HhDhe6GKlNRUyZUg1mHXnxfsmBJYnliq2KQZdRrzGyyda52kXjYect9d3+lgKuIuYq7jH+QXpfbmAtqOHyZUD5crl+HZ9hrNXQJd45/O5/KZxd6OVOLde2aZl+dgfGDmIA8X8VfYnVGezyQZ2jrWZtaEH1+diyL9U9qXxlqN2wCb+J0aHloiFWKeYzfXs9jxXXSedeCKJPykpyE7YYtnMFUbF+MZVxtFXCnjNOMO5hPZfZ0DU7YTuBXK1lmWsxbqFEDXpxeFmB2Yndlp2VuZm5tNnIme1CBmoGZglyLoIzmjHSNHJZElq5Pq2Rmax6CYYRqheiQAVxTaaiYeoRXhQ9Pb1KpX0VeDWePeXmBB4mGifVtF19VYrhsz05pcpKbBlI7VHRWs1ikYW5iGnFuWYl83nwbffCWh2VegBlOdU91UUBYY15zXgpfxGcmTj2FiZVblnN8AZj7UMFYVnaneCVSpXcRhYZ7T1AJWUdyx3vofbqP1I9NkL9PyVIpWgFfrZfdTxeC6pIDV1VjaWsrddyIFI9Cet9Sk1hVYQpirmbNaz986YMjUPhPBVNGVDFYSVmdW/Bc71wpXZZesWJnYz5luWULZ9Vs4Wz5cDJ4K37egLOCDITshAKHEokqikqMppDSkv2Y85xsnU9OoU6NUFZSSleoWT1e2F/ZXz9itGYbZ9Bn0miSUSF9qoCogQCLjIy/jH6SMpYgVCyYF1PVUFxTqFiyZDRnZ3Jmd0Z65pHDUqFshmsAWExeVFksZ/t/4VHGdmlk6HhUm7uey1e5WSdmmmfOa+lU2WlVXpyBlWeqm/5nUpxdaKZO40/IU7liK2erbMSPrU9tfr+eB05iYYBuK28ThXNUKmdFm/NdlXusXMZbHIdKbtGEFHoIgZlZjXwRbCB32VIiWSFxX3LbdyeXYZ0LaX9aGFqlUQ1UfVQOZt9294+YkvSc6lldcsVuTVHJaL997H1il7qeeGQhagKDhFlfW9trG3PydrJ9F4CZhDJRKGfZnu52Ymf/UgWZJFw7Yn58sIxPVbZgC32AlQFTX062URxZOnI2gM6RJV/id4RTeV8EfayFM4qNjlaX82euhVOUCWEIYblsUnbtijiPL1VRTypRx1LLU6VbfV6gYIJh1mMJZ9pnZ26MbTZzN3MxdVB51YiYikqQkZD1kMSWjYcVWYhOWU8OTomKP48QmK1QfF6WWblbuF7aY/pjwWTcZkpp2GkLbbZulHEoda96in8AgEmEyYSBiSGLCo5lkH2WCpl+YZFiMmuDbHRtzH/8f8BthX+6h/iIZWexgzyY95YbbWF9PYRqkXFOdVNQXQRr62/NhS2Gp4kpUg9UZVxOZ6hoBnSDdOJ1z4jhiMyR4pZ4lotfh3PLek6EoGNldYlSQW2cbgl0WXVreJJ8hpbceo2ftk9uYcVlXIaGTq5O2lAhTsxR7luZZYFovG0fc0J2rXcceud8b4LSinyQz5F1lhiYm1LRfStQmFOXZ8tt0HEzdOiBKo+jllecn55gdEFYmW0vfV6Y5E42T4tPt1GxUrpdHGCyczx504I0kreW9pYKl5eeYp+mZnRrF1KjUshwwojJXktgkGEjb0lxPnz0fW+A7oQjkCyTQlRvm9NqiXDCjO+NMpe0UkFayl4EXxdnfGmUaWptD29icvxy7XsBgH6AS4fOkG1Rk56EeYuAMpPWii1QjFRximprxIwHgdFgoGfynZlOmE4QnGuKwYVohQBpfm6XeFWBDF8QThVOKk4xTjZOPE4/TkJOVk5YToJOhU5rjIpOEoINX45Onk6fTqBOok6wTrNOtk7OTs1OxE7GTsJO107eTu1O3073TglPWk8wT1tPXU9XT0dPdk+IT49PmE97T2lPcE+RT29Phk+WTxhR1E/fT85P2E/bT9FP2k/QT+RP5U8aUChQFFAqUCVQBVAcT/ZPIVApUCxQ/k/vTxFQBlBDUEdQA2dVUFBQSFBaUFZQbFB4UIBQmlCFULRQslDJUMpQs1DCUNZQ3lDlUO1Q41DuUPlQ9VAJUQFRAlEWURVRFFEaUSFROlE3UTxRO1E/UUBRUlFMUVRRYlH4emlRalFuUYBRglHYVoxRiVGPUZFRk1GVUZZRpFGmUaJRqVGqUatRs1GxUbJRsFG1Ub1RxVHJUdtR4FFVhulR7VHwUfVR/lEEUgtSFFIOUidSKlIuUjNSOVJPUkRSS1JMUl5SVFJqUnRSaVJzUn9SfVKNUpRSklJxUohSkVKoj6ePrFKtUrxStVLBUs1S11LeUuNS5lLtmOBS81L1UvhS+VIGUwhTOHUNUxBTD1MVUxpTI1MvUzFTM1M4U0BTRlNFUxdOSVNNU9ZRXlNpU25TGFl7U3dTglOWU6BTplOlU65TsFO2U8NTEnzZlt9T/Gbuce5T6FPtU/pTAVQ9VEBULFQtVDxULlQ2VClUHVROVI9UdVSOVF9UcVR3VHBUklR7VIBUdlSEVJBUhlTHVKJUuFSlVKxUxFTIVKhUq1TCVKRUvlS8VNhU5VTmVA9VFFX9VO5U7VT6VOJUOVVAVWNVTFUuVVxVRVVWVVdVOFUzVV1VmVWAVa9UilWfVXtVflWYVZ5VrlV8VYNVqVWHVahV2lXFVd9VxFXcVeRV1FUUVvdVFlb+Vf1VG1b5VU5WUFbfcTRWNlYyVjhWa1ZkVi9WbFZqVoZWgFaKVqBWlFaPVqVWrla2VrRWwla8VsFWw1bAVshWzlbRVtNW11buVvlWAFf/VgRXCVcIVwtXDVcTVxhXFlfHVRxXJlc3VzhXTlc7V0BXT1dpV8BXiFdhV39XiVeTV6BXs1ekV6pXsFfDV8ZX1FfSV9NXCljWV+NXC1gZWB1YclghWGJYS1hwWMBrUlg9WHlYhVi5WJ9Yq1i6WN5Yu1i4WK5YxVjTWNFY11jZWNhY5VjcWORY31jvWPpY+Vj7WPxY/VgCWQpZEFkbWaZoJVksWS1ZMlk4WT5Z0npVWVBZTllaWVhZYllgWWdZbFlpWXhZgVmdWV5Pq0+jWbJZxlnoWdxZjVnZWdpZJVofWhFaHFoJWhpaQFpsWklaNVo2WmJaalqaWrxavlrLWsJavVrjWtda5lrpWtZa+lr7WgxbC1sWWzJb0FoqWzZbPltDW0VbQFtRW1VbWltbW2VbaVtwW3NbdVt4W4hleluAW4Nbplu4W8Nbx1vJW9Rb0FvkW+Zb4lveW+Vb61vwW/Zb81sFXAdcCFwNXBNcIFwiXChcOFw5XEFcRlxOXFNcUFxPXHFbbFxuXGJOdlx5XIxckVyUXJtZq1y7XLZcvFy3XMVcvlzHXNlc6Vz9XPpc7VyMXepcC10VXRddXF0fXRtdEV0UXSJdGl0ZXRhdTF1SXU5dS11sXXNddl2HXYRdgl2iXZ1drF2uXb1dkF23XbxdyV3NXdNd0l3WXdtd613yXfVdC14aXhleEV4bXjZeN15EXkNeQF5OXldeVF5fXmJeZF5HXnVedl56Xryef16gXsFewl7IXtBez17WXuNe3V7aXtte4l7hXuhe6V7sXvFe817wXvRe+F7+XgNfCV9dX1xfC18RXxZfKV8tXzhfQV9IX0xfTl8vX1FfVl9XX1lfYV9tX3Nfd1+DX4Jff1+KX4hfkV+HX55fmV+YX6BfqF+tX7xf1l/7X+Rf+F/xX91fs2D/XyFgYGAZYBBgKWAOYDFgG2AVYCtgJmAPYDpgWmBBYGpgd2BfYEpgRmBNYGNgQ2BkYEJgbGBrYFlggWCNYOdgg2CaYIRgm2CWYJdgkmCnYItg4WC4YOBg02C0YPBfvWDGYLVg2GBNYRVhBmH2YPdgAGH0YPpgA2EhYftg8WANYQ5hR2E+YShhJ2FKYT9hPGEsYTRhPWFCYURhc2F3YVhhWWFaYWthdGFvYWVhcWFfYV1hU2F1YZlhlmGHYaxhlGGaYYphkWGrYa5hzGHKYclh92HIYcNhxmG6YctheX/NYeZh42H2Yfph9GH/Yf1h/GH+YQBiCGIJYg1iDGIUYhtiHmIhYipiLmIwYjJiM2JBYk5iXmJjYltiYGJoYnxigmKJYn5ikmKTYpZi1GKDYpRi12LRYrtiz2L/YsZi1GTIYtxizGLKYsJix2KbYsliDGPuYvFiJ2MCYwhj72L1YlBjPmNNYxxkT2OWY45jgGOrY3Zjo2OPY4ljn2O1Y2tjaWO+Y+ljwGPGY+NjyWPSY/ZjxGMWZDRkBmQTZCZkNmQdZRdkKGQPZGdkb2R2ZE5kKmWVZJNkpWSpZIhkvGTaZNJkxWTHZLtk2GTCZPFk52QJguBk4WSsYuNk72QsZfZk9GTyZPpkAGX9ZBhlHGUFZSRlI2UrZTRlNWU3ZTZlOGVLdUhlVmVVZU1lWGVeZV1lcmV4ZYJlg2WKi5tln2WrZbdlw2XGZcFlxGXMZdJl22XZZeBl4WXxZXJnCmYDZvtlc2c1ZjZmNGYcZk9mRGZJZkFmXmZdZmRmZ2ZoZl9mYmZwZoNmiGaOZolmhGaYZp1mwWa5Zslmvma8ZsRmuGbWZtpm4GY/ZuZm6WbwZvVm92YPZxZnHmcmZydnOJcuZz9nNmdBZzhnN2dGZ15nYGdZZ2NnZGeJZ3BnqWd8Z2pnjGeLZ6ZnoWeFZ7dn72e0Z+xns2fpZ7hn5GfeZ91n4mfuZ7lnzmfGZ+dnnGoeaEZoKWhAaE1oMmhOaLNoK2hZaGNod2h/aJ9oj2itaJRonWibaINormq5aHRotWigaLpoD2mNaH5oAWnKaAhp2GgiaSZp4WgMac1o1GjnaNVoNmkSaQRp12jjaCVp+WjgaO9oKGkqaRppI2khacZoeWl3aVxpeGlraVRpfmluaTlpdGk9aVlpMGlhaV5pXWmBaWppsmmuadBpv2nBadNpvmnOaehbymndabtpw2mnaS5qkWmgaZxplWm0ad5p6GkCahtq/2kKa/lp8mnnaQVqsWkeau1pFGrraQpqEmrBaiNqE2pEagxqcmo2anhqR2piallqZmpIajhqImqQao1qoGqEaqJqo2qXaheGu2rDasJquGqzaqxq3mrRat9qqmraaupq+2oFaxaG+moSaxZrMZsfazhrN2vcdjlr7phHa0NrSWtQa1lrVGtba19rYWt4a3lrf2uAa4Rrg2uNa5hrlWuea6Rrqmura69rsmuxa7Nrt2u8a8Zry2vTa99r7Gvra/Nr72u+nghsE2wUbBtsJGwjbF5sVWxibGpsgmyNbJpsgWybbH5saGxzbJJskGzEbPFs02y9bNdsxWzdbK5ssWy+bLps22zvbNls6mwfbU2INm0rbT1tOG0ZbTVtM20SbQxtY22TbWRtWm15bVltjm2VbeRvhW35bRVuCm61bcdt5m24bcZt7G3ebcxt6G3SbcVt+m3ZbeRt1W3qbe5tLW5ubi5uGW5ybl9uPm4jbmtuK252bk1uH25DbjpuTm4kbv9uHW44boJuqm6Ybslut27Tbr1ur27EbrJu1G7Vbo9upW7Cbp9uQW8Rb0xw7G74bv5uP2/ybjFv724yb8xuPm8Tb/duhm96b3hvgW+Ab29vW2/zb21vgm98b1hvjm+Rb8JvZm+zb6NvoW+kb7lvxm+qb99v1W/sb9Rv2G/xb+5v228JcAtw+m8RcAFwD3D+bxtwGnB0bx1wGHAfcDBwPnAycFFwY3CZcJJwr3DxcKxwuHCzcK5w33DLcN1w2XAJcf1wHHEZcWVxVXGIcWZxYnFMcVZxbHGPcftxhHGVcahxrHHXcblxvnHScclx1HHOceBx7HHncfVx/HH5cf9xDXIQchtyKHItcixyMHIycjtyPHI/ckByRnJLclhydHJ+coJygXKHcpJylnKicqdyuXKycsNyxnLEcs5y0nLicuBy4XL5cvdyD1AXcwpzHHMWcx1zNHMvcylzJXM+c05zT3PYnldzanNoc3BzeHN1c3tzenPIc7NzznO7c8Bz5XPuc95zonQFdG90JXT4czJ0OnRVdD90X3RZdEF0XHRpdHB0Y3RqdHZ0fnSLdJ50p3TKdM901HTxc+B043TndOl07nTydPB08XT4dPd0BHUDdQV1DHUOdQ11FXUTdR51JnUsdTx1RHVNdUp1SXVbdUZ1WnVpdWR1Z3VrdW11eHV2dYZ1h3V0dYp1iXWCdZR1mnWddaV1o3XCdbN1w3W1db11uHW8dbF1zXXKddJ12XXjdd51/nX/dfx1AXbwdfp18nXzdQt2DXYJdh92J3YgdiF2InYkdjR2MHY7dkd2SHZGdlx2WHZhdmJ2aHZpdmp2Z3ZsdnB2cnZ2dnh2fHaAdoN2iHaLdo52lnaTdpl2mnawdrR2uHa5drp2wnbNdtZ20nbeduF25Xbndup2L4b7dgh3B3cEdyl3JHcedyV3Jncbdzd3OHdHd1p3aHdrd1t3ZXd/d353eXeOd4t3kXegd553sHe2d7l3v3e8d713u3fHd81313fad9x343fud/x3DHgSeCZ5IHgqeUV4jnh0eIZ4fHiaeIx4o3i1eKp4r3jReMZ4y3jUeL54vHjFeMp47HjneNp4/Xj0eAd5EnkReRl5LHkreUB5YHlXeV95WnlVeVN5enl/eYp5nXmneUufqnmuebN5uXm6ecl51Xnneex54XnjeQh6DXoYehl6IHofeoB5MXo7ej56N3pDeld6SXphemJ6aXqdn3B6eXp9eoh6l3qVeph6lnqpesh6sHq2esV6xHq/eoOQx3rKes16z3rVetN62Xraet164XrieuZ67XrwegJ7D3sKewZ7M3sYexl7Hns1eyh7NntQe3p7BHtNewt7THtFe3V7ZXt0e2d7cHtxe2x7bnude5h7n3uNe5x7mnuLe5J7j3tde5l7y3vBe8x7z3u0e8Z73XvpexF8FHzme+V7YHwAfAd8E3zze/d7F3wNfPZ7I3wnfCp8H3w3fCt8PXxMfEN8VHxPfEB8UHxYfF98ZHxWfGV8bHx1fIN8kHykfK18onyrfKF8qHyzfLJ8sXyufLl8vXzAfMV8wnzYfNJ83HzifDub73zyfPR89nz6fAZ9An0cfRV9Cn1FfUt9Ln0yfT99NX1GfXN9Vn1OfXJ9aH1ufU99Y32TfYl9W32PfX19m326fa59o321fcd9vX2rfT1+on2vfdx9uH2ffbB92H3dfeR93n37ffJ94X0Ffgp+I34hfhJ+MX4ffgl+C34ifkZ+Zn47fjV+OX5Dfjd+Mn46fmd+XX5Wfl5+WX5afnl+an5pfnx+e36DftV9fX6uj39+iH6Jfox+kn6QfpN+lH6Wfo5+m36cfjh/On9Ff0x/TX9Of1B/UX9Vf1R/WH9ff2B/aH9pf2d/eH+Cf4Z/g3+If4d/jH+Uf55/nX+af6N/r3+yf7l/rn+2f7h/cYvFf8Z/yn/Vf9R/4X/mf+l/83/5f9yYBoAEgAuAEoAYgBmAHIAhgCiAP4A7gEqARoBSgFiAWoBfgGKAaIBzgHKAcIB2gHmAfYB/gISAhoCFgJuAk4CagK2AkFGsgNuA5YDZgN2AxIDagNaACYHvgPGAG4EpgSOBL4FLgYuWRoE+gVOBUYH8gHGBboFlgWaBdIGDgYiBioGAgYKBoIGVgaSBo4FfgZOBqYGwgbWBvoG4gb2BwIHCgbqByYHNgdGB2YHYgciB2oHfgeCB54H6gfuB/oEBggKCBYIHggqCDYIQghaCKYIrgjiCM4JAglmCWIJdglqCX4JkgmKCaIJqgmuCLoJxgneCeIJ+go2CkoKrgp+Cu4KsguGC44LfgtKC9ILzgvqCk4MDg/uC+YLeggaD3IIJg9mCNYM0gxaDMoMxg0CDOYNQg0WDL4MrgxeDGIOFg5qDqoOfg6KDloMjg46Dh4OKg3yDtYNzg3WDoIOJg6iD9IMThOuDzoP9gwOE2IMLhMGD94MHhOCD8oMNhCKEIIS9gziEBoX7g22EKoQ8hFqFhIR3hGuErYRuhIKEaYRGhCyEb4R5hDWEyoRihLmEv4SfhNmEzYS7hNqE0ITBhMaE1oShhCGF/4T0hBeFGIUshR+FFYUUhfyEQIVjhViFSIVBhQKGS4VVhYCFpIWIhZGFioWohW2FlIWbheqFh4WchXeFfoWQhcmFuoXPhbmF0IXVhd2F5YXchfmFCoYThguG/oX6hQaGIoYahjCGP4ZNhlVOVIZfhmeGcYaThqOGqYaqhouGjIa2hq+GxIbGhrCGyYYjiKuG1IbehumG7IbfhtuG74YShwaHCIcAhwOH+4YRhwmHDYf5hgqHNIc/hzeHO4clhymHGodgh1+HeIdMh06HdIdXh2iHbodZh1OHY4dqhwWIooefh4KHr4fLh72HwIfQh9aWq4fEh7OHx4fGh7uH74fyh+CHD4gNiP6H9of3hw6I0ocRiBaIFYgiiCGIMYg2iDmIJ4g7iESIQohSiFmIXohiiGuIgYh+iJ6IdYh9iLWIcoiCiJeIkoiuiJmIooiNiKSIsIi/iLGIw4jEiNSI2IjZiN2I+YgCifyI9IjoiPKIBIkMiQqJE4lDiR6JJYkqiSuJQYlEiTuJNok4iUyJHYlgiV6JZolkiW2JaolviXSJd4l+iYOJiImKiZOJmImhiamJpomsia+Jsom6ib2Jv4nAidqJ3IndieeJ9In4iQOKFooQigyKG4odiiWKNopBiluKUopGikiKfIptimyKYoqFioKKhIqoiqGKkYqliqaKmoqjisSKzYrCitqK64rziueK5IrxihSL4IriiveK3orbigyLB4sai+GKFosQixeLIIszi6uXJosriz6LKItBi0yLT4tOi0mLVotbi1qLa4tfi2yLb4t0i32LgIuMi46LkouTi5aLmYuaizqMQYw/jEiMTIxOjFCMVYxijGyMeIx6jIKMiYyFjIqMjYyOjJSMfIyYjB1irYyqjL2MsoyzjK6MtozIjMGM5IzjjNqM/Yz6jPuMBI0FjQqNB40PjQ2NEI1OnxONzYwUjRaNZ41tjXGNc42BjZmNwo2+jbqNz43ajdaNzI3bjcuN6o3rjd+N4438jQiOCY7/jR2OHo4Qjh+OQo41jjCONI5KjkeOSY5MjlCOSI5ZjmSOYI4qjmOOVY52jnKOfI6BjoeOhY6EjouOio6TjpGOlI6ZjqqOoY6sjrCOxo6xjr6OxY7IjsuO247jjvyO+47rjv6OCo8FjxWPEo8ZjxOPHI8fjxuPDI8mjzOPO485j0WPQo8+j0yPSY9Gj06PV49cj2KPY49kj5yPn4+jj62Pr4+3j9qP5Y/ij+qP74+HkPSPBZD5j/qPEZAVkCGQDZAekBaQC5AnkDaQNZA5kPiPT5BQkFGQUpAOkEmQPpBWkFiQXpBokG+QdpColnKQgpB9kIGQgJCKkImQj5CokK+QsZC1kOKQ5JBIYtuQApESkRmRMpEwkUqRVpFYkWORZZFpkXORcpGLkYmRgpGikauRr5GqkbWRtJG6kcCRwZHJkcuR0JHWkd+R4ZHbkfyR9ZH2kR6S/5EUkiySFZIRkl6SV5JFkkmSZJJIkpWSP5JLklCSnJKWkpOSm5Jaks+SuZK3kumSD5P6kkSTLpMZkyKTGpMjkzqTNZM7k1yTYJN8k26TVpOwk6yTrZOUk7mT1pPXk+iT5ZPYk8OT3ZPQk8iT5JMalBSUE5QDlAeUEJQ2lCuUNZQhlDqUQZRSlESUW5RglGKUXpRqlCmScJR1lHeUfZRalHyUfpSBlH+UgpWHlYqVlJWWlZiVmZWglaiVp5WtlbyVu5W5lb6VypX2b8OVzZXMldWV1JXWldyV4ZXlleKVIZYoli6WL5ZClkyWT5ZLlneWXJZell2WX5ZmlnKWbJaNlpiWlZaXlqqWp5axlrKWsJa0lraWuJa5ls6Wy5bJls2WTYnclg2X1Zb5lgSXBpcIlxOXDpcRlw+XFpcZlySXKpcwlzmXPZc+l0SXRpdIl0KXSZdcl2CXZJdml2iX0lJrl3GXeZeFl3yXgZd6l4aXi5ePl5CXnJeol6aXo5ezl7SXw5fGl8iXy5fcl+2XT5/yl9969pf1lw+YDJg4mCSYIZg3mD2YRphPmEuYa5hvmHCYcZh0mHOYqpivmLGYtpjEmMOYxpjpmOuYA5kJmRKZFJkYmSGZHZkemSSZIJksmS6ZPZk+mUKZSZlFmVCZS5lRmVKZTJlVmZeZmJmlma2Zrpm8md+Z25ndmdiZ0Zntme6Z8ZnymfuZ+JkBmg+aBZrimRmaK5o3mkWaQppAmkOaPppVmk2aW5pXml+aYpplmmSaaZprmmqarZqwmryawJrPmtGa05rUmt6a35rimuOa5prvmuua7pr0mvGa95r7mgabGJsamx+bIpsjmyWbJ5somymbKpsumy+bMptEm0ObT5tNm06bUZtYm3Sbk5uDm5GblpuXm5+boJuom7SbwJvKm7mbxpvPm9Gb0pvjm+Kb5JvUm+GbOpzym/Gb8JsVnBScCZwTnAycBpwInBKcCpwEnC6cG5wlnCScIZwwnEecMpxGnD6cWpxgnGecdpx4nOec7JzwnAmdCJ3rnAOdBp0qnSadr50jnR+dRJ0VnRKdQZ0/nT6dRp1InV2dXp1knVGdUJ1ZnXKdiZ2Hnaudb516nZqdpJ2pnbKdxJ3BnbuduJ26ncadz53Cndmd0534nead7Z3vnf2dGp4bnh6edZ55nn2egZ6InouejJ6SnpWekZ6dnqWeqZ64nqqerZ5hl8yezp7PntCe1J7cnt6e3Z7gnuWe6J7vnvSe9p73nvme+578nv2eB58In7d2FZ8hnyyfPp9Kn1KfVJ9jn1+fYJ9hn2afZ59sn2qfd59yn3aflZ+cn6CfL1jHaVmQZHTcUZlxADABMAIwDP8O//swGv8b/x//Af+bMJwwtABA/6gAPv/j/z///TD+MJ0wnjADMN1OBTAGMAcw/DAVIBAgD/88/17/JSJc/yYgJSAYIBkgHCAdIAj/Cf8UMBUwO/89/1v/Xf8IMAkwCjALMAwwDTAOMA8wEDARMAv/Df+xANcA9wAd/2AiHP8e/2YiZyIeIjQiQiZAJrAAMiAzIAMh5f8E/+D/4f8F/wP/Bv8K/yD/pwAGJgUmyyXPJc4lxyXGJaEloCWzJbIlvSW8JTsgEjCSIZAhkSGTIRMwCCILIoYihyKCIoMiKiIpIiciKCLi/9Ih1CEAIgMiICKlIhIjAiIHImEiUiJqImsiGiI9Ih0iNSIrIiwiKyEwIG8mbSZqJiAgISC2AO8lACUCJQwlECUYJRQlHCUsJSQlNCU8JQElAyUPJRMlGyUXJSMlMyUrJTslSyUgJS8lKCU3JT8lHSUwJSUlOCVCJUkzFDMiM00zGDMnMwMzNjNRM1czDTMmMyMzKzNKMzsznDOdM54zjjOPM8QzoTN7Mx0wHzAWIc0zISGkMqUypjKnMqgyMTIyMjkyfjN9M3wzUiJhIisiLiIRIhoipSIgIh8ivyI1IikiKiLi/+T/B/8C/zEyFiEhITUiywAKABD/3AAaACH//AAaAEH/1gERAJED5wEHAKMD9gERALEDBwIHAMMDNAIGABAEOgIBAAEEOwIaABYEZAIGADAEagIBAFEEawIaADYEaAQUAGAkfAQKAGAhuiEKAHAh3CkKAHAh5ikKAGAhAABsAAAAdwAIAGwAhwAHAHQAmQAPAHsArwAIAIoAuwABAJIAkgIgAJMAhwQXALMApgQeAMoA8CkIAOgAxCEEAOgAQaWE0wALXgEAAQEBAQEAAAEBAAEBAAEBAQEBAQEBAQEAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAEAQYSG0wAL+QHoRxAAWwAAAFIAAAAJAAAAnkgQAFoAAAAaAQAAGQAAAGNoYXJzZXQAnkgQAFoAAAAbAQAAKgAAAJ5IEABaAAAAHAEAACQAAAB1dGYtOAAAAJ5IEABaAAAAHAEAADMAAACeSBAAWgAAACMBAAAVAAAAnkgQAFoAAAAmAQAAPAAAACTDFAAHAAAAAQAAAJ5IEABaAAAAJwEAACMAAABMwxQABQAAAAEAAACeSBAAWgAAADUBAAAKAAAAnkgQAFoAAAA4AQAADgAAAJ5IEABaAAAAPAEAABIAAACeSBAAWgAAAD0BAAASAAAAKi8qAJ5IEABaAAAArAAAAA4AQYiI0wALBAIAAIAAQZmI0wAL+Q4BAADswxQAAwAAAAAAAAABAAAALVQQAEoAAAC9AQAAHQAAAHN0cnVjdCBUZXN0YWJsZU5vZGV2YXJpYW50IGlkZW50aWZpZXJjb3VsZCBub3QgcmVjb3ZlciByZWNlaXZlZCB0ZXN0IG1lc3NhZ2U6IAAAYcQUACkAAABUaGUgc3BlY2lmaWVkIG1peG5vZGUgKGlkOiApIGRvZXNuJ3QgZXhpc3QAAJTEFAAbAAAAr8QUAA8AAABUaGUgc3BlY2lmaWVkIG1peG5vZGUgKGlkZW50aXR5OiAAAADQxBQAIQAAAK/EFAAPAAAAVGhlIHNwZWNpZmllZCBnYXRld2F5IChpZDogAATFFAAbAAAAr8QUAA8AAABUaGUgcHJvdmlkZWQgdGVzdCBtZXNzYWdlIGlzIHRvbyBsb25nIHRvIGZpdCBpbiBhIHNpbmdsZSBzcGhpbnggcGFja2V0Y291bGQgbm90IHJlY292ZXIgdW5kZXJseWluZyBkYXRhIGZyb20gdGhlIHJlY2VpdmVkIHBhY2tldCBzaW5jZSBpdCB3YXMgbWFsZm9ybWVkOiAAAAB2xRQAUwAAAFJlY2VpdmVkIGFjayBwYWNrZXQgY291bGQgbm90IGJlIHJlY292ZXJlZGNvdWxkIG5vdCByZWNvdmVyIGFjayBGcmFnbWVudElkZW50aWZpZXI6IP7FFAAqAAAAcmVjZWl2ZWQgYSBwYWNrZXQgdGhhdCBjb3VsZCBub3QgYmUgcmVjb25zdHJ1Y3RlZCBpbnRvIGEgZnVsbCBtZXNzYWdlIHdpdGggYSBzaW5nbGUgZnJhZ21lbnR0aGUgcmVjaXBpZW50IG9mIHRoZSB0ZXN0IHBhY2tldCB3YXMgbmV2ZXIgc3BlY2lmaWVkYXNzZXJ0aW9uIGZhaWxlZDogKCp0YWlsKS52YWx1ZS5pc19ub25lKCkAAAC7RBAAagAAAHsAAAARAAAAYXNzZXJ0aW9uIGZhaWxlZDogKCpuZXh0KS52YWx1ZS5pc19zb21lKCkAAAC7RBAAagAAAHwAAAARAAAAAAAAAAQAAAAEAAAAlwUAAP1hEABoAAAAWwQAAEYAAAB0aGUgcnVudGltZSByZWdpc3RyeSBpcyBwb2lzb25lZHRoZXJlIGlzIG5vIHN1Y2ggdGhpbmcgYXMgYSByZWxlYXNlIGZhaWx1cmUgb3JkZXJpbmd4xxQANAAAAHRrEABPAAAA5w8AAB0AAAB0aGVyZSBpcyBubyBzdWNoIHRoaW5nIGFzIGFuIGFjcXVpcmUtcmVsZWFzZSBmYWlsdXJlIG9yZGVyaW5nAAAAxMcUAD0AAAB0axAATwAAAOYPAAAcAAAAHjwQAGUAAABfAQAAJAAAAGNhbm5vdCByZWN1cnNpdmVseSBhY3F1aXJlIG11dGV4LMgUACAAAAAsIBAAXAAAABMAAAAJAAAA7QcQAGQAAABlAQAALQAAAE5vbmUAAAAABAAAAAQAAACYBQAAU29tZQAAAAAEAAAABAAAAJkFAAAeBxAAZgAAAHsAAAAJAAAA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ANkxEABjAAAAWAAAADUAAADZMRAAYwAAAFoAAAAnAAAA2TEQAGMAAADKAAAACwAAANkxEABjAAAAzAAAACMAAADuChAAbAAAAGsBAAAXAAAA7goQAGwAAACGAQAAFwAAAO4KEABsAAAAWwEAACUAAADuChAAbAAAAFsBAAAFAAAAUGFya2luZyBub3Qgc3VwcG9ydGVkIG9uIHRoaXMgcGxhdGZvcm0AAIzsFAAmAAAAoTYQAHMAAAAmAAAACQAAAKE2EABzAAAAKgAAAAkAAAChNhAAcwAAABoAAAAJAAAAoTYQAHMAAAAiAAAACQAAAKE2EABzAAAAHgAAAAkAAADuChAAbAAAALMAAAAbAAAA7goQAGwAAAAOAQAAIwAAAO4KEABsAAAASgEAAAwAAADuChAAbAAAAFsBAAAlAAAA7goQAGwAAABbAQAABQAAAO4KEABsAAAARwAAABgAAADuChAAbAAAAEsAAAAbAAAA7goQAGwAAABSAAAAHgAAAO4KEABsAAAATgAAABUAAABRXBAASwAAANoEAAAFAAAAY2FwYWNpdHkgb3ZlcmZsb3cAAACs7RQAEQAAAARSEABaAAAAQAAAABUAAAAEUhAAWgAAAEAAAAAOAAAABFIQAFoAAABBAAAAHgAAAARSEABaAAAAQgAAABcAAABwcm92aWRlZCBieXRlcyBoYXZlIGludmFsaWQgbGVuZ3RoU2xpY2UgbXVzdCBiZSB0aGUgc2FtZSBsZW5ndGggYXMgdGhlIGFycmF5uG4QAGEAAABcAgAADgAAAP////////////////////////////////////////////////////////////////8AAQIDBAUGBwj/////////CQoLDA0ODxD/ERITFBX/FhcYGRobHB0eHyD///////8hIiMkJSYnKCkqK/8sLS4vMDEyMzQ1Njc4Of//////MTIzNDU2Nzg5QUJDREVGR0hKS0xNTlBRUlNUVVZXWFlaYWJjZGVmZ2hpamttbm9wcXJzdHV2d3h5egAABFIQAFoAAAA9AQAAIAAAANkiEABYAAAA6wcAAAkAAADmBQAAFAAAAAQAAADnBQAAY2FsbGVkIGBSZXN1bHQ6OnVud3JhcCgpYCBvbiBhbiBgRXJyYCB2YWx1ZQBBhN/TAAu1DgEAAADoBQAAQnVmZmVyVG9vU21hbGwAAAAAAAAEAAAABAAAAJ8CAAAAAAAAAQAAAAEAAADpBQAAAAAAAAQAAAAEAAAA1AAAAOoFAAAMAAAABAAAAOUDAAAAAAAABAAAAAQAAADmAwAARnJvbVV0ZjhFcnJvcmJ5dGVzZXJyb3IABFIQAFoAAACTAAAAKwAAAAAAAAAEAAAABAAAAOsFAABJbnZhbGlkU2l6ZVB1YmxpY0tleXJlY2VpdmVkZXhwZWN0ZWRJbnZhbGlkU2l6ZVByaXZhdGVLZXkAAAAAAAAABAAAAAQAAABoAQAATWFsZm9ybWVkUHVibGljS2V5U3RyaW5nc291cmNlTWFsZm9ybWVkUHJpdmF0ZUtleVN0cmluZwAtVBAASgAAAL0BAAAdAAAAAAAAAAQAAAAEAAAA/gEAAE1hbGZvcm1lZEJ5dGVzAAAAAAAABAAAAAQAAADlAQAAQnl0ZXNMZW5ndGhFcnJvck1hbGZvcm1lZFNpZ25hdHVyZVN0cmluZ05vQnl0ZXNQcm92aWRlZFRvb0Zld0J5dGVzUHJvdmlkZWRwcm90b2NvbF92ZXJzaW9ucmVxdWlyZWRJbnZhbGlkSXBWZXJzaW9uVG9vU21hbGxCeXRlc1JlcHJlc2VudGF0aW9uZGlkIG5vdCByZWNlaXZlIGVub3VnaCBkYXRhIHRvIHJlY292ZXIgYSByZXBseSBTVVJCdHJpZWQgdG8gdXNlIHJlcGx5IFNVUkIgd2l0aCBhbiB1bnBhZGRlZCBtZXNzYWdlcmVwbHkgU1VSQiBpcyBpbmNvcnJlY3RseSBmb3JtYXR0ZWQ6IAAAANjxFAAlAAAAZmFpbGVkIHRvIHJlY292ZXIgcmVwbHkgU1VSQiBmcm9tIGJ5dGVzOiAAAAAI8hQAKQAAAGZhaWxlZCB0byB2YWxpZGF0ZSB0aGUgZmlyc3QgaG9wIGFkZHJlc3Mgb2YgdGhlIHJlY292ZXJlZCByZXBseSBTVVJCOiAAADzyFABGAAAAZmFpbGVkIHRvIHJlY292ZXIgcmVwbHkgU1VSQiBlbmNyeXB0aW9uIGtleSBmcm9tIGJ5dGVzOiCM8hQAOAAAAERpZCBub3QgcHJvdmlkZSBzdWZmaWNpZW50IG51bWJlciBvZiBieXRlcyB0byBkZXNlcmlhbGlzZSBhIHZhbGlkIHJlcXVlc3QgaXMgbm90IGEgdmFsaWQgY29udGVudCB0YWcgZm9yIGEgcmVwbGlhYmxlIG1lc3NhZ2UBAAAAAAAAABXzFAAzAAAAIGlzIG5vdCBhIHZhbGlkIGNvbnRlbnQgdGFnIGZvciBhIHJlcGx5IG1lc3NhZ2UAAQAAAAAAAABY8xQALwAAAGZhaWxlZCB0byBkZXNlcmlhbGlzZSBzcGhpbngga2V5IHJvdGF0aW9uIGRldGFpbHM6IACY8xQAMwAAAGZhaWxlZCB0byBkZXNlcmlhbGlzZSByZWNpcGllbnQgaW5mb3JtYXRpb246IAAAANTzFAAtAAAAZmFpbGVkIHRvIGRlc2VyaWFsaXNlIHJlcGx5U1VSQjogAAAADPQUACEAAABGYWlsZWQgdG8gZGVjb2RlIHRoZSBiYXNlNTgtZW5jb2RlZCBzdHJpbmcgLSAAAAA49BQALQAAAERlY29kZWQgQW5vbnltb3VzU2VuZGVyVGFnIGhhcyBpbnZhbGlkIGxlbmd0aC4gRXhwZWN0ZWQgLCBidXQgZ290IAAAcPQUADgAAACo9BQACgAAAGF0dGVtcHRlZCB0byB0YWtlIG93bmVyc2hpcCBvZiBSdXN0IHZhbHVlIHdoaWxlIGl0IHdhcyBib3Jyb3dlZADZIhAAWAAAAOsHAAAJAAAAZGVzY3JpcHRpb24oKSBpcyBkZXByZWNhdGVkOyB1c2UgRGlzcGxheTLElDM6ftc0P1gEOgF7NvEAAAAADAAAAAQAAACkAwAAAAAAAAwAAAAEAAAA9gUAAKQDAABM9RQA9wUAAPgFAAD5BQAAqQMAAPoFAABCdWZmZXJUb29TbWFsbAAAAAAAAAQAAAAEAAAAsQMAAAAAAAAEAAAABAAAAJ8CAABJbnZhbGlkQ2hhcmFjdGVyY2hhcmFjdGVyaW5kZXhOb25Bc2NpaUNoYXJhY3RlcgAAAAAABAAAAAEAAACyAwAAAAAAAAQAAAAEAAAAswMAAEludmFsaWRDaGVja3N1bWNoZWNrc3VtZXhwZWN0ZWRfY2hlY2tzdW0AAAAAAQAAAAEAAAD7BQAAAAAAAAQAAAAEAAAA1AAAAEludmFsaWRWZXJzaW9udmVyZXhwZWN0ZWRfdmVyTm9DaGVja3N1bQAtVBAASgAAAL0BAAAdAAAAIGtpQiByZXBseSBkYXRhIG1lc3NhZ2UAAQAAAAAAAACI9hQAFwAAAAAAAgAAAAAAAgBBxO3TAAv9ByAAAPByZXF1ZXN0IGZvciAgYWRkaXRpb25hbCByZXBseSBTVVJCcyBmcm9tIAAAAMj2FAAMAAAA1PYUAB0AAAAgZnJvbSAAAAEAAAAAAAAABPcUAAYAAAABAAAAAAAAALhuEABhAAAAdgIAABUAAABWMiByZXBsaWFibGUgYWRkaXRpb25hbCBzdXJicyBtZXNzYWdlICggcmVwbHkgc3VyYnMgYXR0YWNoZWQpAAAANPcUACcAAABb9xQAFgAAAGV2ZW50IGNvbW1vbi9ueW1zcGhpbngvYW5vbnltb3VzLXJlcGxpZXMvc3JjL3JlcXVlc3RzL3YyLnJzOjE5M255bV9zcGhpbnhfYW5vbnltb3VzX3JlcGxpZXM6OnJlcXVlc3RzOjp2Mm1lc3NhZ2Xt9xQABwAAAAAAAAAMAAAABAAAAJUCAAD8BQAA/QUAAGNvbW1vbi9ueW1zcGhpbngvYW5vbnltb3VzLXJlcGxpZXMvc3JjL3JlcXVlc3RzL3YyLnJzAAAAAQAAAMEAAAADAAAAhPcUAD8AAADD9xQAKgAAAPT3FAABAAAAwKQZAPz3FADD9xQAKgAAABT4FAA1AAAAAQAAALt8EAA1AAAAwAAAABwAAABGaWVsZFNldCBjb3JydXB0ZWQgKHRoaXMgaXMgYSBidWcpAAC7fBAANQAAAMEAAAANAAAAdHJhaWxpbmcgIGJ5dGVzIGFmdGVyIHYyIGhlYXJ0YmVhdCBtZXNzYWdlAADQ+BQACQAAANn4FAAhAAAAAAAAABgAAAAEAAAAEgAAAGV2ZW50IGNvbW1vbi9ueW1zcGhpbngvYW5vbnltb3VzLXJlcGxpZXMvc3JjL3JlcXVlc3RzL3YyLnJzOjE3MwABAAAArQAAAAMAAAAc+RQAPwAAAMP3FAAqAAAA9PcUAAEAAADMpBkA/PcUAMP3FAAqAAAAFPgUADUAAAABAAAAu3wQADUAAACsAAAAHAAAALt8EAA1AAAArQAAAA0AAAAgYnl0ZXMgYWZ0ZXIgdjIgYWRkaXRpb25hbCBzdXJicyBtZXNzYWdl0PgUAAkAAAC8+RQAKAAAALt8EAA1AAAARgAAABsAAAC7fBAANQAAAEgAAAAgAAAAu3wQADUAAABKAAAAFQAAALt8EAA1AAAAmgAAABsAAABXAI+8Iiz33BuBKwCoPFDm2SIQAFgAAADrBwAACQAAAC1UEABKAAAAvQEAAB0AAABWMiByZXBsaWFibGUgIGtpQiBkYXRhIG1lc3NhZ2Ugd2l0aCAgcmVwbHkgc3VyYnMgYXR0YWNoZWQAAABk+hQADQAAAHH6FAAXAAAAiPoUABUAAAAAAAIAAAAAAAIAQcz10wAL+QcgAADwAgAAAAAAAAACAAAAAAAAAAEAAAAgAADgVjIgcmVwbGlhYmxlIGhlYXJ0YmVhdCBtZXNzYWdlICjo+hQAIAAAAFv3FAAWAAAAVjEgcmVwbGlhYmxlIGFkZGl0aW9uYWwgc3VyYnMgbWVzc2FnZSAoIHJlcGx5IHN1cmJzIGF0dGFjaGVkKQAAABj7FAAnAAAAP/sUABYAAABldmVudCBjb21tb24vbnltc3BoaW54L2Fub255bW91cy1yZXBsaWVzL3NyYy9yZXF1ZXN0cy92MS5yczoxNjdueW1fc3BoaW54X2Fub255bW91c19yZXBsaWVzOjpyZXF1ZXN0czo6djFtZXNzYWdl0fsUAAcAAAAAAAAADAAAAAQAAACVAgAA/gUAAP8FAABjb21tb24vbnltc3BoaW54L2Fub255bW91cy1yZXBsaWVzL3NyYy9yZXF1ZXN0cy92MS5ycwAAAAEAAACnAAAAAwAAAGj7FAA/AAAAp/sUACoAAADY+xQAAQAAANikGQDg+xQAp/sUACoAAAD4+xQANQAAAAEAAAAnfhAANQAAAKUAAAAcAAAARmllbGRTZXQgY29ycnVwdGVkICh0aGlzIGlzIGEgYnVnKQAAJ34QADUAAACnAAAADQAAAHRyYWlsaW5nICBieXRlcyBhZnRlciB2MSBoZWFydGJlYXQgbWVzc2FnZQAAtPwUAAkAAAC9/BQAIQAAAAAAAAAYAAAABAAAABIAAABldmVudCBjb21tb24vbnltc3BoaW54L2Fub255bW91cy1yZXBsaWVzL3NyYy9yZXF1ZXN0cy92MS5yczoxNDYAAQAAAJIAAAADAAAAAP0UAD8AAACn+xQAKgAAANj7FAABAAAA5KQZAOD7FACn+xQAKgAAAPj7FAA1AAAAAQAAACd+EAA1AAAAkAAAABwAAAAnfhAANQAAAJIAAAANAAAAIGJ5dGVzIGFmdGVyIHYxIGFkZGl0aW9uYWwgc3VyYnMgbWVzc2FnZbT8FAAJAAAAoP0UACgAAAAnfhAANQAAACkAAAAiAAAAJ34QADUAAAAtAAAAGwAAACd+EAA1AAAALwAAACsAAAAnfhAANQAAAC8AAAAgAAAAJ34QADUAAAAxAAAAFQAAACd+EAA1AAAAfgAAABsAAABXAI+8Iiz33BuBKwCoPFDm2SIQAFgAAADrBwAACQAAAC1UEABKAAAAvQEAAB0AAABWMSByZXBsaWFibGUgIGtpQiBkYXRhIG1lc3NhZ2Ugd2l0aCAgcmVwbHkgc3VyYnMgYXR0YWNoZWQAAABo/hQADQAAAHX+FAAXAAAAjP4UABUAAAAAAAIAAAAAAAIAQdD90wALiwEgAADwAgAAAAAAAAACAAAAAAAAAAEAAAAgAADgVjEgcmVwbGlhYmxlIGhlYXJ0YmVhdCBtZXNzYWdlICjs/hQAIAAAAD/7FAAWAAAAI20QACMAAAARAAAACQAAAHkzEABKAAAAlAgAAB8AAABMURAAGwAAABYAAAAKAAAAAAAAAP//////////UP8UAEHs/tMAC5cFBAAAAAQAAAAABgAAAQYAAAEGAAAAAAAABAAAAAQAAAACBgAAAwYAAAMGAAAAAAAABAAAAAQAAAAEBgAABQYAAAUGAABueW1fdG9wb2xvZ3ltZXNzYWdlALz/FAAHAAAAAAAAAAwAAAAEAAAAlQIAAAcGAAAIBgAAY29tbW9uL3RvcG9sb2d5L3NyYy9saWIucnNldmVudCBjb21tb24vdG9wb2xvZ3kvc3JjL2xpYi5yczo2MDUAAAEAAABdAgAAAwAAAP7/FAAkAAAAsP8UAAwAAADE/xQAAQAAAPCkGQDM/xQAsP8UAAwAAADk/xQAGgAAAAEAAABldmVudCBjb21tb24vdG9wb2xvZ3kvc3JjL2xpYi5yczozMjYBAAAARgEAAAEAAABkABUAJAAAALD/FAAMAAAAxP8UAAEAAAD8pBkAzP8UALD/FAAMAAAA5P8UABoAAAABAAAAZXZlbnQgY29tbW9uL3RvcG9sb2d5L3NyYy9saWIucnM6MzIyAQAAAEIBAAABAAAAyAAVACQAAACw/xQADAAAAMT/FAABAAAACKUZAMz/FACw/xQADAAAAOT/FAAaAAAAAQAAAEZpZWxkU2V0IGNvcnJ1cHRlZCAodGhpcyBpcyBhIGJ1ZykAAD9sEAAaAAAAQgEAABkAAABvdmVyd3JpdGluZyBub2RlIGRldGFpbHMgZm9yIG5vZGUgAABgARUAIgAAAAAAAAAYAAAABAAAABIAAAA/bBAAGgAAAEYBAAAVAAAAbWFsZm9ybWVkIG5vZGUgZGV0YWlsczogrAEVABgAAABzdHJ1Y3QgTnltVG9wb2xvZ3lNZXRhZGF0YQAAVwCPvCIs99wbgSsAqDxQ5v//////////+AEVAEGQhNQAC6IBTFEQABsAAAB+AAAALgAAAHdzczovLzoAIAIVAAYAAAAmAhUAAQAAAHdzOi8vAAAAOAIVAAUAAAAmAhUAAQAAAHN0cnVjdCBFbnRyeURldGFpbHNzdHJ1Y3QgU3VwcG9ydGVkUm9sZXNzdHJ1Y3QgQ2FjaGVkRXBvY2hSZXdhcmRlZFNldAAAAAsGAAAMBgAADAAAAAQAAAANBgAADgYAAHYCAEG8hdQAC/8BAQAAAA8GAABhIERpc3BsYXkgaW1wbGVtZW50YXRpb24gcmV0dXJuZWQgYW4gZXJyb3IgdW5leHBlY3RlZGx5AIJBEABLAAAABQsAAA4AAABFcnJvcgAAAIJBEABLAAAAsAwAAA4AAACCQRAASwAAAKoMAAAOAAAAeTMQAEoAAACUCAAAHwAAAG5vZGUgICgnJykgaGFzIG5vdCBwcm92aWRlZCBhbnkgdmFsaWQgaXAgYWRkcmVzc2VzAABEAxUABQAAAEkDFQADAAAATAMVACoAAABMURAAGwAAAGgAAAAOAAAA2SIQAFgAAADrBwAACQAAAP//////////sAMVAEHIh9QAC1JzdHJ1Y3QgV2FzbUZyaWVuZGx5TnltVG9wb2xvZ3lzdHJ1Y3QgV2FzbUZyaWVuZGx5Um91dGluZ05vZGUQBgAADAAAAAQAAAARBgAAEgYAAHYCAEGkiNQAC/YGAQAAABMGAABhIERpc3BsYXkgaW1wbGVtZW50YXRpb24gcmV0dXJuZWQgYW4gZXJyb3IgdW5leHBlY3RlZGx5AIJBEABLAAAABQsAAA4AAAAAAAAABAAAAAQAAAAUBgAAAAAAAAwAAAAEAAAAFQYAAGNhbGxlZCBgUmVzdWx0Ojp1bndyYXAoKWAgb24gYW4gYEVycmAgdmFsdWUAAAAAAAQAAAAEAAAA1AAAAAAAAAAEAAAABAAAAJ8CAABFcnJvcgAAAIJBEABLAAAAsAwAAA4AAACCQRAASwAAAKoMAAAOAAAAAAAAAAQAAAAEAAAAFgYAAExlbk1pc21hdGNoZXhwZWN0ZWRnb3QAAAAAAAAEAAAABAAAABcGAABDaGFDaGEyMEludmFsaWRMZW5ndGhzb3VyY2UAAAAAAAQAAAAEAAAAPAAAAENoYUNoYTIwUG9seTEzMDVFcnJvckludmFsaWRLZXlMZW5ndGhJbnZhbGlkTWVzc2FnZUxlbmd0aAAAAAAAAAAEAAAABAAAAOUBAABUcnlGcm9tU2xpY2VJbnZhbGlkSGVhZGVyTGVuZ3RoAAAAAAAEAAAABAAAABgGAABJbnZhbGlkTWFnaWNCeXRlcwAAABkGAAAgaXMgbm90IGEgdmFsaWQgZWQyNTUxOSBwdWJsaWMga2V5AAABAAAAAAAAAAAGFQAiAAAAIGlzIG5vdCBhIHZhbGlkIHgyNTUxOSBwdWJsaWMga2V5AAAAAQAAAAAAAAA0BhUAIQAAAE5vQnl0ZXNQcm92aWRlZAAAAAAAAQAAAAEAAAAaBgAAVG9vRmV3Qnl0ZXNQcm92aWRlZHByb3RvY29sX3ZlcnNpb25yZWNlaXZlZHJlcXVpcmVkSW52YWxpZElwVmVyc2lvblRvb1NtYWxsQnl0ZXNSZXByZXNlbnRhdGlvbmRlc2NyaXB0aW9uKCkgaXMgZGVwcmVjYXRlZDsgdXNlIERpc3BsYXkAANmluziTO/T2H5hMbQK0pLGwXiabXa08KtQQPRqpiLMrnJ1SxjWopbKdHungfNkNxdX3kss8f5D9Cr+HGUmsHBaryng+iB7p4GavNuTHRWubIAYAABAAAAAEAAAAIQYAACAGAAAQAAAABAAAACIGAAAhBgAAYAcVACMGAAAkBgAAJQYAACYGAAAnBgBBpI/UAAsGAQAAACgGAEG0j9QAC70MAQAAACkGAAAoBgAAnAcVACoGAAArBgAALAYAAC0GAAAuBgAALwYAABAAAAAEAAAAvgUAAC8GAAAQAAAABAAAADAGAAC+BQAA2AcVAMAFAAAxBgAAJQYAAMIFAAAnBgAAMgYAAAQAAAAEAAAAQQUAADIGAAAEAAAABAAAAEIFAABBBQAAFAgVAEMFAAAzBgAAJQYAAEUFAAAnBgAANAYAAAwAAAAEAAAANQYAADQGAAAMAAAABAAAADYGAAA1BgAAUAgVADcGAAA4BgAAJQYAADkGAAAnBgAATm90UHJlc2VudAAAAAAAAAQAAAAEAAAAOgYAAE5vdFVuaWNvZGUAAAAAAAAEAAAABAAAADsGAABUcnlGcm9tU2xpY2VFcnJvcgAAAAAAAAAEAAAABAAAADwGAAAAAAAABAAAAAQAAACfAgAATGVuTWlzbWF0Y2hleHBlY3RlZGdvdAAAAAAAAAQAAAAEAAAAFwYAAENoYUNoYTIwSW52YWxpZExlbmd0aHNvdXJjZQAAAAAABAAAAAQAAAA8AAAAQ2hhQ2hhMjBQb2x5MTMwNUVycm9ySW52YWxpZEtleUxlbmd0aEludmFsaWRNZXNzYWdlTGVuZ3RoAAAAAAAAAAQAAAAEAAAA5QEAAFRyeUZyb21TbGljZUludmFsaWRIZWFkZXJMZW5ndGgAAAAAAAQAAAAEAAAAGAYAAEludmFsaWRNYWdpY0J5dGVzY291bGQgbm90IGNvbnZlcnQgc2xpY2UgdG8gYXJyYXkAAAAAAAAABAAAAAQAAACrBQAAU3BoaW54AAAAAAAABAAAAAQAAADkAQAAT3V0Zm94RnJvbVNsaWNldGhlIHByb3ZpZGVkIG5ldHdvcmsgdG9wb2xvZ3kgaXMgZW1wdHkgLSB0aGVyZSBhcmUgbm8gdmFsaWQgbm9kZXMgb24gaXQgLSB0aGUgbmV0d29yayByZXF1ZXN0KHMpIHByb2JhYmx5IGZhaWxlZG5vIG5vZGUgd2l0aCBpZGVudGl0eSAgaXMga25vd24AAKMKFQAWAAAAuQoVAAkAAABjb3VsZCBub3QgdXNlIG5vZGUgd2l0aCBpZGVudGl0eSAgYXMgZWdyZXNzIHNpbmNlIGl0IGRpZG4ndCBnZXQgYXNzaWduZWQgdmFsaWQgcm9sZSBpbiB0aGUgY3VycmVudCBlcG9jaNQKFQAhAAAA9QoVAEcAAABvbmUgKG9yIG1vcmUpIG9mIG1peGluZyBsYXllcnMgZG9lcyBub3QgaGF2ZSBhbnkgdmFsaWQgbm9kZXMgYXZhaWxhYmxlVGhlIHByb3ZpZGVkIG5ldHdvcmsgdG9wb2xvZ3kgaGFzIG5vIGdhdGV3YXlzIGF2YWlsYWJsZVRo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aW1pdCBleGNlZWRlZDogAADoGRUAFgAAAFdlYlNvY2tldCBwcm90b2NvbCBlcnJvcjogAAAIGhUAGgAAAFdyaXRlIGJ1ZmZlciBpcyBmdWxsVVRGLTggZW5jb2RpbmcgZXJyb3JBdHRhY2sgYXR0ZW1wdCBkZXRlY3RlZFVSTCBlcnJvcjogAABrGhUACwAAAFRsc0ZlYXR1cmVOb3RFbmFibGVkTm9Ib3N0TmFtZQAAAAAAAAQAAAAEAAAAhAYAAFVuYWJsZVRvQ29ubmVjdFVuc3VwcG9ydGVkVXJsU2NoZW1lRW1wdHlIb3N0TmFtZU5vUGF0aE9yUXVlcnlUTFMgc3VwcG9ydCBub3QgY29tcGlsZWQgaW5ObyBob3N0IG5hbWUgaW4gdGhlIFVSTFVuYWJsZSB0byBjb25uZWN0IHRvIB8bFQAVAAAAVVJMIHNjaGVtZSBub3Qgc3VwcG9ydGVkVVJMIGNvbnRhaW5zIGVtcHR5IGhvc3QgbmFtZU5vIHBhdGgvcXVlcnkgaW4gVVJMVG9vTWFueUhlYWRlcnMAAAAAAAAEAAAABAAAAIUGAAAAAAAABAAAAAQAAACfAgAATWVzc2FnZVRvb0xvbmdzaXplbWF4X3NpemVXcm9uZ0h0dHBNZXRob2RXcm9uZ0h0dHBWZXJzaW9uTWlzc2luZ0Nvbm5lY3Rpb25VcGdyYWRlSGVhZGVyTWlzc2luZ1VwZ3JhZGVXZWJTb2NrZXRIZWFkZXJNaXNzaW5nU2VjV2ViU29ja2V0VmVyc2lvbkhlYWRlck1pc3NpbmdTZWNXZWJTb2NrZXRLZXlTZWNXZWJTb2NrZXRBY2NlcHRLZXlNaXNtYXRjaEp1bmtBZnRlclJlcXVlc3RDdXN0b21SZXNwb25zZVN1Y2Nlc3NmdWxIYW5kc2hha2VJbmNvbXBsZXRlU2VuZEFmdGVyQ2xvc2luZ1JlY2VpdmVkQWZ0ZXJDbG9zaW5nTm9uWmVyb1Jlc2VydmVkQml0c1VubWFza2VkRnJhbWVGcm9tQ2xpZW50TWFza2VkRnJhbWVGcm9tU2VydmVyRnJhZ21lbnRlZENvbnRyb2xGcmFtZUNvbnRyb2xGcmFtZVRvb0JpZwAAAAAAAAAEAAAABAAAADwCAABVbmtub3duQ29udHJvbEZyYW1lVHlwZVVua25vd25EYXRhRnJhbWVUeXBlVW5leHBlY3RlZENvbnRpbnVlRnJhbWUAAAAAAAAEAAAABAAAACsDAABFeHBlY3RlZEZyYWdtZW50UmVzZXRXaXRob3V0Q2xvc2luZ0hhbmRzaGFrZUludmFsaWRPcGNvZGVJbnZhbGlkQ2xvc2VTZXF1ZW5jZVRvbyBtYW55IGhlYWRlcnNNZXNzYWdlIHRvbyBsb25nOiAgPiAAAAUeFQASAAAAFx4VAAMAAABVbnN1cHBvcnRlZCBIVFRQIG1ldGhvZCB1c2VkIC0gb25seSBHRVQgaXMgYWxsb3dlZEhUVFAgdmVyc2lvbiBtdXN0IGJlIDEuMSBvciBoaWdoZXJObyAiQ29ubmVjdGlvbjogdXBncmFkZSIgaGVhZGVyTm8gIlVwZ3JhZGU6IHdlYnNvY2tldCIgaGVhZGVyTm8gIlNlYy1XZWJTb2NrZXQtVmVyc2lvbjogMTMiIGhlYWRlck5vICJTZWMtV2ViU29ja2V0LUtleSIgaGVhZGVyS2V5IG1pc21hdGNoIGluICJTZWMtV2ViU29ja2V0LUFjY2VwdCIgaGVhZGVySnVuayBhZnRlciBjbGllbnQgcmVxdWVzdEN1c3RvbSByZXNwb25zZSBtdXN0IG5vdCBiZSBzdWNjZXNzZnVsSGFuZHNoYWtlIG5vdCBmaW5pc2hlZFNlbmRpbmcgYWZ0ZXIgY2xvc2luZyBpcyBub3QgYWxsb3dlZFJlbW90ZSBzZW50IGFmdGVyIGhhdmluZyBjbG9zZWRSZXNlcnZlZCBiaXRzIGFyZSBub24temVyb1JlY2VpdmVkIGFuIHVubWFza2VkIGZyYW1lIGZyb20gY2xpZW50UmVjZWl2ZWQgYSBtYXNrZWQgZnJhbWUgZnJvbSBzZXJ2ZXJGcmFnbWVudGVkIGNvbnRyb2wgZnJhbWVDb250cm9sIGZyYW1lIHRvbyBiaWcgKHBheWxvYWQgbXVzdCBiZSAxMjUgYnl0ZXMgb3IgbGVzcylVbmtub3duIGNvbnRyb2wgZnJhbWUgdHlwZTogeCAVABwAAABVbmtub3duIGRhdGEgZnJhbWUgdHlwZTogAAAAnCAVABkAAABDb250aW51ZSBmcmFtZSBidXQgbm90aGluZyB0byBjb250aW51ZVdoaWxlIHdhaXRpbmcgZm9yIG1vcmUgZnJhZ21lbnRzIHJlY2VpdmVkOiAAAADmIBUAKwAAAENvbm5lY3Rpb24gcmVzZXQgd2l0aG91dCBjbG9zaW5nIGhhbmRzaGFrZUVuY291bnRlcmVkIGludmFsaWQgb3Bjb2RlOiAAAEYhFQAcAAAASW52YWxpZCBjbG9zZSBzZXF1ZW5jZQAAAQAAAAAAAABCaW5hcnkgRGF0YTxsZW5ndGg9PowhFQATAAAAnyEVAAEAAAACAAAABAAAAAoAAABOb25lU29tZQAAAAAEAAAABAAAALMDAABDb250aW51ZVRleHRCaW5hcnkAAAAAAAAEAAAABAAAADwCAABSZXNlcnZlZENPTlRJTlVFVEVYVEJJTkFSWVJFU0VSVkVEX0RBVEFfEiIVAA4AAABDbG9zZVBpbmdQb25nTm9ybWFsQXdheVByb3RvY29sVW5zdXBwb3J0ZWRTdGF0dXNBYm5vcm1hbEludmFsaWRQb2xpY3lTaXplRXh0ZW5zaW9uRXJyb3JSZXN0YXJ0QWdhaW5UbHMAAAAAAAAEAAAABAAAAIYGAABJYW5hTGlicmFyeUJhZAAAAAAAAAQAAAACAAAAhwYAAAAAAAAEAAAABAAAAIQGAABDbG9zZUZyYW1lY29kZXJlYXNvbi1UEABKAAAAvQEAAB0AAABjbG9zdXJlIGludm9rZWQgcmVjdXJzaXZlbHkgb3IgYWZ0ZXIgYmVpbmcgZHJvcHBlZGFzc2VydGlvbiBmYWlsZWQ6ICgqdGFpbCkudmFsdWUuaXNfbm9uZSgpALtEEABqAAAAewAAABEAAABhc3NlcnRpb24gZmFpbGVkOiAoKm5leHQpLnZhbHVlLmlzX3NvbWUoKQAAALtEEABqAAAAfAAAABEAAABidWZmZXIgc3BhY2UgZXhoYXVzdGVkOyBzZW5kaW5nIHRoaXMgbWVzc2FnZXMgd291bGQgb3ZlcmZsb3cgdGhlIHN0YXRlAAD9YRAAaAAAALgBAAANAAAA/WEQAGgAAADzBAAARgAAAP1hEABoAAAAeAMAABgAAABjYW5ub3QgY2xvbmUgYFNlbmRlcmAgLS0gdG9vIG1hbnkgb3V0c3RhbmRpbmcgc2VuZGVycwAAAP1hEABoAAAAcwMAABEAAAD9YRAAaAAAANcEAAAlAAAAY2xvc3VyZSBpbnZva2VkIHJlY3Vyc2l2ZWx5IG9yIGFmdGVyIGJlaW5nIGRyb3BwZWRpbnRlcm5hbCBlcnJvcjogZW50ZXJlZCB1bnJlYWNoYWJsZSBjb2RlOiBKc1ZhbHVlIHBhc3NlZCBpcyBub3QgYW4gRXJyb3IgdHlwZSAtLSB0aGlzIGlzIGEgYnVnniQVAF4AAABzJRAAXQAAACgAAAAXAAAAFRwQAGkAAAAZAQAAHgAAAJEGAAAEAAAABAAAAB4CAABjYWxsZWQgYFJlc3VsdDo6dW53cmFwKClgIG9uIGFuIGBFcnJgIHZhbHVlaW50ZXJuYWwgZXJyb3I6IGVudGVyZWQgdW5yZWFjaGFibGUgY29kZTogbWVzc2FnZSBldmVudCwgcmVjZWl2ZWQgVW5rbm93bjogAABfJRUASwAAABUcEABpAAAADwEAAAkAAACSBgAABAAAAAQAAACTBgAAlAYAAG9wZW6VBgAABAAAAAQAAACWBgAAlwYAAG1lc3NhZ2UAmAYAAAgAAAAEAAAAmQYAAJoGAABlcnJvcgAAAJUGAAAEAAAABAAAAJsGAACcBgAAY2xvc2UAAAAVHBAAaQAAAKUAAAAsAAAAFRwQAGkAAACJAAAALAAAABUcEABpAAAASgEAABkAAABjbGllbnQgZHJvcHBlZGNsb3N1cmUgaW52b2tlZCByZWN1cnNpdmVseSBvciBhZnRlciBiZWluZyBkcm9wcGVkoQYAAAQAAAAEAAAAogYAAKMGAACkBgAApQYAAKYGAACnBgAA5WgQAHYAAABnAAAAJQAAAOVoEAB2AAAAIgAAABUAAAAmRRAAagAAACUAAAAuAAAAJkUQAGoAAAAoAAAAKQAAACZFEABqAAAAPgAAABoAAAAmRRAAagAAAD4AAAAnAAAAqQYAAAQAAAAEAAAAqgYAAKsGAACpBgAABAAAAAQAAACsBgAArQYAAEZuT25jZSBjYWxsZWQgbW9yZSB0aGFuIG9uY2VJdxAAaAAAALsAAAAkAAAASXcQAGgAAACxAAAADwAAAEl3EABoAAAAkQAAACcAAABMYXp5IGluc3RhbmNlIGhhcyBwcmV2aW91c2x5IGJlZW4gcG9pc29uZWQAAJgnFQAqAAAAh3IQAF0AAAAIAwAAGQAAAHJlZW50cmFudCBpbml0AADcJxUADgAAAIdyEABdAAAAegIAAA0AQaXQ1AALXiEAIyQlJicAACorAC0uADAxMjM0NTY3ODkAAAAAAAAAYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoAAABeX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5egB8AH4AQYTS1AALyhBhY2NlcHRhY2NlcHQtY2hhcnNldGFjY2VwdC1lbmNvZGluZ2FjY2VwdC1sYW5ndWFnZWFjY2VwdC1yYW5nZXNhY2Nlc3MtY29udHJvbC1hbGxvdy1jcmVkZW50aWFsc2FjY2Vzcy1jb250cm9sLWFsbG93LWhlYWRlcnNhY2Nlc3MtY29udHJvbC1hbGxvdy1tZXRob2RzYWNjZXNzLWNvbnRyb2wtYWxsb3ctb3JpZ2luYWNjZXNzLWNvbnRyb2wtZXhwb3NlLWhlYWRlcnNhY2Nlc3MtY29udHJvbC1tYXgtYWdlYWNjZXNzLWNvbnRyb2wtcmVxdWVzdC1oZWFkZXJzYWNjZXNzLWNvbnRyb2wtcmVxdWVzdC1tZXRob2RhZ2VhbGxvd2FsdC1zdmNhdXRob3JpemF0aW9uY2FjaGUtY29udHJvbGNhY2hlLXN0YXR1c2Nkbi1jYWNoZS1jb250cm9sY29ubmVjdGlvbmNvbnRlbnQtZGlzcG9zaXRpb25jb250ZW50LWVuY29kaW5nY29udGVudC1sYW5ndWFnZWNvbnRlbnQtbGVuZ3RoY29udGVudC1sb2NhdGlvbmNvbnRlbnQtcmFuZ2Vjb250ZW50LXNlY3VyaXR5LXBvbGljeWNvbnRlbnQtc2VjdXJpdHktcG9saWN5LXJlcG9ydC1vbmx5Y29udGVudC10eXBlY29va2llZG50ZGF0ZWV0YWdleHBlY3RleHBpcmVzZm9yd2FyZGVkZnJvbWhvc3RpZi1tYXRjaGlmLW1vZGlmaWVkLXNpbmNlaWYtbm9uZS1tYXRjaGlmLXJhbmdlaWYtdW5tb2RpZmllZC1zaW5jZWxhc3QtbW9kaWZpZWRsaW5rbG9jYXRpb25tYXgtZm9yd2FyZHNvcmlnaW5wcmFnbWFwcm94eS1hdXRoZW50aWNhdGVwcm94eS1hdXRob3JpemF0aW9ucHVibGljLWtleS1waW5zcHVibGljLWtleS1waW5zLXJlcG9ydC1vbmx5cmFuZ2VyZWZlcmVycmVmZXJyZXItcG9saWN5cmVmcmVzaHJldHJ5LWFmdGVyc2VjLXdlYnNvY2tldC1hY2NlcHRzZWMtd2Vic29ja2V0LWV4dGVuc2lvbnNzZWMtd2Vic29ja2V0LWtleXNlYy13ZWJzb2NrZXQtcHJvdG9jb2xzZWMtd2Vic29ja2V0LXZlcnNpb25zZXJ2ZXJzZXQtY29va2llc3RyaWN0LXRyYW5zcG9ydC1zZWN1cml0eXRldHJhaWxlcnRyYW5zZmVyLWVuY29kaW5ndXNlci1hZ2VudHVwZ3JhZGV1cGdyYWRlLWluc2VjdXJlLXJlcXVlc3RzdmFyeXZpYXdhcm5pbmd3d3ctYXV0aGVudGljYXRleC1jb250ZW50LXR5cGUtb3B0aW9uc3gtZG5zLXByZWZldGNoLWNvbnRyb2x4LWZyYW1lLW9wdGlvbnN4LXhzcy1wcm90ZWN0aW9uAJ8FEABfAAAAlQAAABwAAABjYW5ub3QgYWR2YW5jZSBwYXN0IGByZW1haW5pbmdgOiAgPD0gAAAAhC0VACEAAAClLRUABAAAALkbEABbAAAAxwIAAAkAAABJbnZhbGlkSGVhZGVyTmFtZWludmFsaWQgSFRUUCBoZWFkZXIgbmFtZQAAAAAAAAAEAAAABAAAAK8GAAAAAAAABAAAAAQAAACwBgAAa2QQAFoAAABRAQAANAAAAGludmFsaWQgdXJpIGNoYXJhY3RlcmludmFsaWQgc2NoZW1laW52YWxpZCBhdXRob3JpdHlpbnZhbGlkIHBvcnRpbnZhbGlkIGZvcm1hdHNjaGVtZSBtaXNzaW5nYXV0aG9yaXR5IG1pc3NpbmdwYXRoIG1pc3Npbmd1cmkgdG9vIGxvbmdlbXB0eSBzdHJpbmdzY2hlbWUgdG9vIGxvbmdJbnZhbGlkVXJpQ2hhckludmFsaWRTY2hlbWVJbnZhbGlkQXV0aG9yaXR5SW52YWxpZFBvcnRJbnZhbGlkRm9ybWF0U2NoZW1lTWlzc2luZ0F1dGhvcml0eU1pc3NpbmdQYXRoQW5kUXVlcnlNaXNzaW5nVG9vTG9uZ0VtcHR5U2NoZW1lVG9vTG9uZwAAAAAEAAAABAAAALEGAABJbnZhbGlkVXJpAAAOAAAADQAAABAAAAALAAAADQAAAA0AAAAQAAAAEwAAAAcAAAAFAAAADQAAAMguFQDWLhUA4y4VAPMuFQD+LhUACy8VABgvFQAoLxUAOy8VAEIvFQBHLxUAFQAAAA4AAAARAAAADAAAAA4AAAAOAAAAEQAAAAwAAAAMAAAADAAAAA8AAAAoLhUAPS4VAEsuFQBcLhUAaC4VAHYuFQCELhUAlS4VAKEuFQCtLhUAuS4VACIAAACcQxAAYAAAAJcBAABBAAAAnEMQAGAAAACMAQAATQAAAFwiXHhGMBUAAgAAAFNlbnNpdGl2ZWZhaWxlZCB0byBjb252ZXJ0IGhlYWRlciB0byBhIHN0ckludmFsaWRIZWFkZXJWYWx1ZWZhaWxlZCB0byBwYXJzZSBoZWFkZXIgdmFsdWVkZXNjcmlwdGlvbigpIGlzIGRlcHJlY2F0ZWQ7IHVzZSBEaXNwbGF5Mc3ivoC1xzwMT02JVBBc6y3OxExFtwF9z2XN1PBzJo9iWyUZoJivgbbcvI79ypZf9OUXnLBZ/yXOAosLiXfIZykVOnxik92rWdRUxK8ctvKvGho8ZuHfT8Z9Cbvk2PREHSzbUBmh9AkulJr6VU8MwwAAAAAAAAAAAQAAALMGAEHY4tQACyIBAAAAtAYAALMGAABAMRUAtQYAALYGAAC3BgAAtQYAALgGAEGE49QACwYBAAAAuQYAQZTj1AALmgEBAAAAugYAALkGAAB8MRUAtQYAALsGAAC3BgAAtQYAALgGAAAAAAAAAQAAAAEAAAC8BgAAAAAAAAEAAAABAAAAvQYAALwGAAC4MRUAvgYAAL8GAADABgAAwQYAAMIGAAAAAAAAAQAAAAEAAADDBgAAAAAAAAEAAAABAAAAxAYAAMMGAAD0MRUAvgYAAMUGAADABgAAwQYAAMIGAEG45NQACwYBAAAAxgYAQcjk1AALIgEAAADHBgAAxgYAADAyFQC1BgAAyAYAALcGAADJBgAAuAYAQfTk1AALBgEAAADKBgBBhOXUAAsiAQAAAL8AAADKBgAAbDIVALUGAADLBgAAtwYAAMwGAAC4BgBBsOXUAAsGAQAAAM0GAEHA5dQAC6sMAQAAAIQEAADNBgAAqDIVALUGAADOBgAAtwYAALUGAAC4BgAAQ29udGludWVTd2l0Y2hpbmcgUHJvdG9jb2xzUHJvY2Vzc2luZ09LQ3JlYXRlZEFjY2VwdGVkTm9uIEF1dGhvcml0YXRpdmUgSW5mb3JtYXRpb25ObyBDb250ZW50UmVzZXQgQ29udGVudFBhcnRpYWwgQ29udGVudE11bHRpLVN0YXR1c0FscmVhZHkgUmVwb3J0ZWRJTSBVc2VkTXVsdGlwbGUgQ2hvaWNlc01vdmVkIFBlcm1hbmVudGx5Rm91bmRTZWUgT3RoZXJOb3QgTW9kaWZpZWRVc2UgUHJveHlUZW1wb3JhcnkgUmVkaXJlY3RQZXJtYW5lbnQgUmVkaXJlY3RCYWQgUmVxdWVzdFVuYXV0aG9yaXplZFBheW1lbnQgUmVxdWlyZWRGb3JiaWRkZW5Ob3QgRm91bmRNZXRob2QgTm90IEFsbG93ZWROb3QgQWNjZXB0YWJsZVByb3h5IEF1dGhlbnRpY2F0aW9uIFJlcXVpcmVkUmVxdWVzdCBUaW1lb3V0Q29uZmxpY3RHb25lTGVuZ3RoIFJlcXVpcmVkUHJlY29uZGl0aW9uIEZhaWxlZFBheWxvYWQgVG9vIExhcmdlVVJJIFRvbyBMb25nVW5zdXBwb3J0ZWQgTWVkaWEgVHlwZVJhbmdlIE5vdCBTYXRpc2ZpYWJsZUV4cGVjdGF0aW9uIEZhaWxlZEknbSBhIHRlYXBvdE1pc2RpcmVjdGVkIFJlcXVlc3RVbnByb2Nlc3NhYmxlIEVudGl0eUxvY2tlZEZhaWxlZCBEZXBlbmRlbmN5VG9vIEVhcmx5VXBncmFkZSBSZXF1aXJlZFByZWNvbmRpdGlvbiBSZXF1aXJlZFRvbyBNYW55IFJlcXVlc3RzUmVxdWVzdCBIZWFkZXIgRmllbGRzIFRvbyBMYXJnZVVuYXZhaWxhYmxlIEZvciBMZWdhbCBSZWFzb25zSW50ZXJuYWwgU2VydmVyIEVycm9yTm90IEltcGxlbWVudGVkQmFkIEdhdGV3YXlTZXJ2aWNlIFVuYXZhaWxhYmxlR2F0ZXdheSBUaW1lb3V0SFRUUCBWZXJzaW9uIE5vdCBTdXBwb3J0ZWRWYXJpYW50IEFsc28gTmVnb3RpYXRlc0luc3VmZmljaWVudCBTdG9yYWdlTG9vcCBEZXRlY3RlZE5vdCBFeHRlbmRlZE5ldHdvcmsgQXV0aGVudGljYXRpb24gUmVxdWlyZWRodHRwOjpFcnJvcgAAAAAACAAAAAQAAADPBgAAAAAAAAQAAAAEAAAAsQYAAEludmFsaWRVcmk8dW5rbm93biBzdGF0dXMgY29kZT4gAQAAAAAAAADTNhUAAQAAAAAAAAAEAAAABAAAANAGAABJbnZhbGlkVXJpUGFydHNJbnZhbGlkTWV0aG9kaW52YWxpZCBIVFRQIG1ldGhvZEludmFsaWRTdGF0dXNDb2RlTWF4U2l6ZVJlYWNoZWRpbnZhbGlkIHN0YXR1cyBjb2RlbWF4IHNpemUgcmVhY2hlZAAAAHoxEABeAAAA0QgAABAAAAB6MRAAXgAAANkIAAAmAAAAejEQAF4AAADhCAAAMwAAAFAxFQCMMRUAyDEVAAQyFQBAMhUAfDIVALgyFQBKc0Vycm9yANIGAAAMAAAABAAAANMGAABuYW1lbWVzc2FnZQABAAAAAAAAAGludGVybmFsIGVycm9yOiBlbnRlcmVkIHVucmVhY2hhYmxlIGNvZGU6IFRoZSBKUyBiaW5kaW5nIHNob3VsZCBvbmx5IGV2ZXIgcHJvZHVjZSBhIHZhbGlkIHZhbHVlIG9yIHRoZSBzcGVjaWZpYyAnaW52YWxpZCcgdmFsdWUA4DcVAH8AAABuRxAAeQAAAAQAAAABAAAA1AYAALJ3EABlAAAANQAAAA4AAAABAAAAAAAAAJ06EABPAAAAGQEAABkAAABpbnZhbGlkIHR5cGU6ICwgZXhwZWN0ZWQgAAAApDgVAA4AAACyOBUACwAAAC1UEABKAAAAvQEAAB0AAAD//////////+A4FQBB+PHUAAvLBnN0cnVjdCBWZXJpZmljYXRpb25LZXlSZXNwb25zZXN0cnVjdCBBZ2dyZWdhdGVkQ29pbkluZGljZXNTaWduYXR1cmVSZXNwb25zZXN0cnVjdCBBZ2dyZWdhdGVkRXhwaXJhdGlvbkRhdGVTaWduYXR1cmVSZXNwb25zZXN0cnVjdCBTa2ltbWVkTm9kZXZhcmlhbnQgaWRlbnRpZmllcnN0cnVjdCBCYXNpY0VudHJ5SW5mb3JtYXRpb25zdHJ1Y3QgTm9kZXNSZXNwb25zZU1ldGFkYXRhc3RydWN0IHZhcmlhbnQgTm9kZVJvbGU6Ok1peG5vZGUsOgAAAKEYEABLAAAA+AEAAA4AAABzdHJ1Y3QgRGVjbGFyZWRSb2xlc6EYEABLAAAA+AEAAA4AAABRXBAASwAAACcBAAAFAAAAYW1B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bmVsAAAgQRUAKgAAAHR1bmdzdGVuaXRlIGVycm9yAAAAVEEVABEAAABJbnZhbGlkIHByb3h5IGNvbmZpZ3VyYXRpb24AcEEVABsAAABpbnZhbGlkIHBhcmFtcyBlcnJvcjogAACUQRUAFgAAAHNlcnZlciByZXR1cm5lZCBtYWxmb3JtYXR0ZWQgSlNPTiAobm8gJ3Jlc3VsdCcgb3IgJ2Vycm9yJykAALRBFQA6AAAAY2xpZW50IGludGVybmFsIGVycm9yOiAA+EEVABcAAABtZXRob2Qgbm90IGZvdW5kOiAAABhCFQASAAAAbm8gbWF0Y2hpbmcgcmVzcG9uc2UgZm9yIGluY29taW5nIHJlcXVlc3QAAAA0QhUAKQAAAHJlYWRpbmcgZnJvbSBXZWJTb2NrZXQgY29ubmVjdGlvbiB0aW1lZCBvdXQgYWZ0ZXIgIHNlY29uZHMAAGhCFQAyAAAAmkIVAAgAAABIVFRQIHJlcXVlc3QgZmFpbGVkIHdpdGggbm9uLTIwMCBzdGF0dXMgY29kZTogAAC0QhUALgAAAGludmFsaWQgY29tcGF0aWJpbGl0eSBtb2RlOiAnJyAoc3VwcG9ydGVkOiAp7EIVAB0AAAAJQxUADgAAABdDFQABAAAAdW5zdXBwb3J0ZWQgc2NoZW1lOiAwQxUAFAAAAG9ubHkgVENQLWJhc2VkIG5vZGUgYWRkcmVzc2VzIGFyZSBzdXBwb3J0ZWQATEMVACsAAAB1bnJlY29nbml6ZWQgZXZlbnQgdHlwZTogAAAAgEMVABkAAABzZXJ2ZXIgUlBDIHZlcnNpb24gdW5zdXBwb3J0ZWQ6ICcnIChvbmx5ICcnIHN1cHBvcnRlZCkAAKRDFQAhAAAAxUMVAAkAAADOQxUADAAAAGludmFsaWQgVGVuZGVybWludCB2ZXJzaW9uIHJlcG9ydGVkIGJ5IHRoZSBub2RlOiAAAAD0QxUAMQAAAHVuc3VwcG9ydGVkIFRlbmRlcm1pbnQgdmVyc2lvbiByZXBvcnRlZCBieSB0aGUgbm9kZTogAAAAMEQVADUAAABzdHJ1Y3QgUmVzcG9uc2VzdHJ1Y3QgQWJjaVF1ZXJ5APwGAAAMAAAABAAAAP0GAAD+BgAA/wYAQbCJ1QAL4SQBAAAAAAcAAGEgRGlzcGxheSBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB1bmV4cGVjdGVkbHkAgkEQAEsAAAAFCwAADgAAAEVycm9yAAAAgkEQAEsAAACwDAAADgAAAIJBEABLAAAAqgwAAA4AAAABAAAAAAAAAHN0cnVjdCBSZXNwb25zZUVycm9yIChjb2RlOiApAAAAAQAAAAAAAABERRUACAAAAExFFQABAAAAOiAAAAEAAAAAAAAAaEUVAAIAAABERRUACAAAAExFFQABAAAAAQAAAAAAAABLShAAagAAAAoAAAAJAAAAMi4wAC1UEABKAAAAvQEAAB0AAAAwMTIzNDU2Nzg5YWJjZGVmMDEyMzQ1Njc4OUFCQ0RFRvUOEABYAAAAuwAAAA0AAAD1DhAAWAAAALMAAAAVAAAA9Q4QAFgAAAC2AAAADQAAAPUOEABYAAAAtwAAAA0AAABCdWZmZXJUb29TbWFsbAAAAAAAAAQAAAAEAAAAsQMAAAAAAAAEAAAABAAAANQFAABJbnZhbGlkQ2hhcmFjdGVyY2hhcmFjdGVyaW5kZXhOb25Bc2NpaUNoYXJhY3RlcgAAAAAABAAAAAEAAACyAwAAAAAAAAQAAAAEAAAABgcAAEludmFsaWRDaGVja3N1bWNoZWNrc3VtZXhwZWN0ZWRfY2hlY2tzdW0AAAAAAQAAAAEAAAAHBwAAAAAAAAQAAAAEAAAA1AAAAEludmFsaWRWZXJzaW9udmVyZXhwZWN0ZWRfdmVyTm9DaGVja3N1bSw6AAAAoRgQAEsAAAD4AQAADgAAAC1UEABKAAAAvQEAAB0AAAAIBwAAFAAAAAQAAAAJBwAAAAAAAAQAAAAEAAAACgcAAAAAAAAEAAAABAAAAHoFAABVdGY4RXJyb3J2YWxpZF91cF90b2Vycm9yX2xlbgAAAAsHAAAMAAAABAAAAAwHAAAAAAAABAAAAAQAAAANBwAARnJvbVV0ZjhFcnJvcmJ5dGVzZXJyb3IAX1IQAF0AAABQAAAAMwAAAHVzaXplIG92ZXJmbG93IHdoZW4gY2FsY3VsYXRpbmcgYjY0IGxlbmd0aAAAX1IQAF0AAABXAAAACgAAAGludGVnZXIgb3ZlcmZsb3cgd2hlbiBjYWxjdWxhdGluZyBidWZmZXIgc2l6ZQAAAMVfEABhAAAAeQAAABIAAADFXxAAYQAAAHsAAAAbAAAASW52YWxpZCBVVEY4xV8QAGEAAAB/AAAAJAAAAE5vbmUAAAAABAAAAAQAAAAOBwAAU29tZXN0cnVjdCBJbnRlcnZhbGFuIHJmYzMzMzkgYE9mZnNldERhdGVUaW1lYAAA3G0QACcAAABTAAAADwAAANxtEAAnAAAAVAAAAA8AAADcbRAAJwAAAFUAAAAPAAAA3G0QACcAAABWAAAADwAAANxtEAAnAAAAVwAAAA8AAABSbmc6OmZpbGwgZmFpbGVkYEAQAFcAAADbAAAAMAAAAHYxLW1peG5ldC1lbnRyeXYxLW1peG5ldC1leGl0djEtd2lyZWd1YXJkLWVudHJ5djEtd2lyZWd1YXJkLWV4aXTGZBAAOgAAAI8AAAA+AAAAxmQQADoAAACcAAAARAAAAGdhbW1hAAAAgEkVAAUAAABjYXBhY2l0eSBvdmVyZmxvdwAAAJBJFQARAAAABFIQAFoAAABAAAAAFQAAAARSEABaAAAAQAAAAA4AAAAEUhAAWgAAAEEAAAAeAAAABFIQAFoAAABCAAAAFwAAAGs+EABdAAAAJAAAAAkAAAAtVBAASgAAAL0BAAAdAAAA2SIQAFgAAADrBwAACQAAAGs+EABdAAAAJAAAAAkAAABrPhAAXQAAAD4AAAA2AAAAaz4QAF0AAAA+AAAAFwAAAGs+EABdAAAAQgAAABMAAAAAAAAAZ+YJaoWuZ7ty8248OvVPpX9SDlGMaAWbq9mDHxnN4FtBYBAAMgAAADgBAAALAAAAQWAQADIAAAA5AQAACwAAAEFgEAAyAAAA0AAAAAwAAABBYBAAMgAAANMAAAAcAAAANhUQAC4AAACKAAAAAQAAAA8HAAAEAAAABAAAABAHAABjYWxsZWQgYFJlc3VsdDo6dW53cmFwKClgIG9uIGFuIGBFcnJgIHZhbHVlAHU1EAA1AAAAtwAAABsAAAB1NRAANQAAAMUAAAAbAAAAdTUQADUAAADIAAAAFwAAAHU1EAA1AAAAywAAACUAAAB1NRAANQAAAM4AAAAVAAAAdTUQADUAAAC6AAAAGQAAAHU1EAA1AAAAuwAAABcAAAB1NRAANQAAAL4AAAAlAAAAdTUQADUAAADCAAAAFQAAAFZlcmlmaWNhdGlvbl9rZXkgYmV0YXMAAHU1EAA1AAAAngAAACEAAAB2ZXJpZmljYXRpb24ga2V5IjAQADQAAAA4AAAAGQAAACIwEAA0AAAAOgAAABMAAABhc3NlcnRpb24gZmFpbGVkOiBhdHRyaWJ1dGVzID4gMCIwEAA0AAAAGwAAAAkAAABkZWx0YQAAAHU1EAA1AAAAUAEAABkAAAB1NRAANQAAAFIBAAAPAAAAdTUQADUAAABUAQAADwAAAHU1EAA1AAAAWwEAABMAAAB1NRAANQAAAFcBAAATAAAAc3RydWN0IFZlcmlmaWNhdGlvbktleUF1dGgAANkiEABYAAAA6wcAAAkAAAAtVBAASgAAAL0BAAAdAAAAc3RydWN0IFNpZ25hdHVyZWRlc2NyaXB0aW9uKCkgaXMgZGVwcmVjYXRlZDsgdXNlIERpc3BsYXmSqwgQlrDEdZQOAKyhwWALMsSUMzp+1zQ/WAQ6AXs28fDm7PrhUYj5PV+JLS7cn/IAAAAADAAAAAQAAACkAwAAAAAAAAwAAAAEAAAAFgcAAKQDAAAgTRUAFwcAABgHAAAZBwAAFwcAABoHAAAbBwAABAAAAAQAAAAcBwAAGwcAAAQAAAAEAAAAEAcAABwHAABcTRUAFwcAAB0HAAAZBwAAHgcAABoHAABCdWZmZXJUb29TbWFsbAAAAAAAAAQAAAAEAAAAsQMAAAAAAAAEAAAABAAAAB8HAABJbnZhbGlkQ2hhcmFjdGVyY2hhcmFjdGVyaW5kZXhOb25Bc2NpaUNoYXJhY3RlcgAAAAAABAAAAAEAAACyAwAAAAAAAAQAAAAEAAAAIAcAAEludmFsaWRDaGVja3N1bWNoZWNrc3VtZXhwZWN0ZWRfY2hlY2tzdW0AAAAAAQAAAAEAAAAhBwAAAAAAAAQAAAAEAAAA1AAAAEludmFsaWRWZXJzaW9udmVyZXhwZWN0ZWRfdmVyTm9DaGVja3N1bWludmFsaWQgdmFsdWU6ICwgZXhwZWN0ZWQgAAAAh04VAA8AAACWThUACwAAAGludmFsaWQgbGVuZ3RoIAC0ThUADwAAAJZOFQALAAAAAAAAAAQAAAAEAAAAIgcAAElvAAAAAAAABAAAAAQAAAAjBwAASW52YWxpZFV0ZjhFbmNvZGluZ0ludmFsaWRCb29sRW5jb2RpbmdJbnZhbGlkQ2hhckVuY29kaW5nSW52YWxpZFRhZ0VuY29kaW5nRGVzZXJpYWxpemVBbnlOb3RTdXBwb3J0ZWRTaXplTGltaXRTZXF1ZW5jZU11c3RIYXZlTGVuZ3RoAAAAAAQAAAAEAAAAJAcAAEN1c3RvbQAAJQcAAAgAAAAEAAAA2gIAACUHAAAIAAAABAAAANsCAADaAgAAlE8VANwCAAAmBwAAGQcAAN4CAAAaBwAAZmFpbGVkIHRvIHZlcmlmeSBleHBpcmF0aW9uIGRhdGUgc2lnbmF0dXJlc2ZhaWxlZCB0byB2YWxpZGF0ZSBleHBpcmF0aW9uIGRhdGUgc2lnbmF0dXJlc2VtcHR5IHNldCBmb3IgYWdncmVnYXRpb25kdXBsaWNhdGUgaW5kaWNlcyBmb3IgYWdncmVnYXRpb25hZ2dyZWdhdGlvbiB2ZXJpZmljYXRpb24gZXJyb3J0aGUgcHJvdmlkZWQgc2lnbmF0dXJlIGlzIGF0IGluZmluaXR5ZGlmZmVyZW50IGVsZW1lbnQgc2l6ZSBmb3IgYWdncmVnYXRpb250aGUgcHJvdmlkZWQgY29tbWl0bWVudCBoYXNoIGlzIGF0IGluZmluaXR5d2l0aGRyYXdhbCByZXF1ZXN0IGZhaWxlZCB0byB2ZXJpZnlpbnZhbGlkIGtleSBnZW5lcmF0aW9uIHBhcmFtZXRlcnNzaWduaW5nIGF1dGhvcml0eSdzIGtleSBpcyB0b28gc2hvcnRlbXB0eS9pbmNvbXBsZXRlIHNldCBvZiBjb29yZGluYXRlcyBmb3IgaW50ZXJwb2xhdGlvbmlzc3VhbmNlIHZlcmlmaWNhdGlvbiBmYWlsZWR0cnlpbmcgdG8gc3BlbmQgbW9yZSB0aGFuIHdoYXQncyBhdmFpbGFibGUuIFNwZW5kaW5nIDogLCBhdmFpbGFibGUgOiCvURUANwAAAOZRFQAOAAAAc2lnbmF0dXJlIGZhaWxlZCB2YWxpZGl0eSBjaGVja3NpZ25hdHVyZSBmYWlsZWQgdmVyaWZpY2F0aW9uIGNoZWNrZHVwbGljYXRlIHNlcmlhbCBudW1iZXIgaW4gdGhlIHBheW1lbnRnaXZlbiBzcGVuZCBkYXRlIGlzIHRvbyBsYXRlZ2l2ZW4gc3BlbmQgZGF0ZSBpcyB0b28gZWFybHlaSyBwcm9vZiBmYWlsZWQgdG8gdmVyaWZ5Y291bGQgbm90IGRlY29kZSBiYXNlIDU4IHN0cmluZyAtIL5SFQAiAAAAZmFpbGVkIHRvIHZlcmlmeSBjb2luIGluZGljZXMgc2lnbmF0dXJlc2ZhaWxlZCB0byBkZXNlcmlhbGl6ZSBhIBBTFQAYAAAAZmFpbGVkIHRvIGRlc2VyaWFsaXNlIDogMFMVABYAAABGUxUAAgAAAGRlc2VyaWFsaXphdGlvbiBlcnJvciwgZXhwZWN0ZWQgYXQgbGVhc3QgIGJ5dGVzLCBnb3QgAAAAWFMVACkAAACBUxUADAAAACBkZXNlcmlhbGl6YXRpb24gZXJyb3IsIGV4cGVjdGVkIAAAAAEAAAAAAAAAoFMVACEAAACBUxUADAAAAHRyaWVkIHRvIGRlc2VyaWFsaXplICB3aXRoIGJ5dGVzIG9mIGludmFsaWQgbGVuZ3RoLiBFeHBlY3RlZCAgPCAgb3IgICUgID09IDDcUxUAFQAAAPFTFQAoAAAAGVQVAAMAAAAcVBUABAAAACBUFQADAAAAI1QVAAUAAABmYWlsZWQgdG8gZGVzZXJpYWxpemUgc2NhbGFyIGZyb20gdGhlIHJlY2VpdmVkIGJ5dGVzIC0gaXQgbWlnaHQgbm90IGhhdmUgYmVlbiBjYW5vbmljYWxseSBlbmNvZGVkZmFpbGVkIHRvIGRlc2VyaWFsaXplIEcxUHJvamVjdGl2ZSBwb2ludCBmcm9tIHRoZSByZWNlaXZlZCBieXRlcyAtIGl0IG1pZ2h0IG5vdCBoYXZlIGJlZW4gY2Fub25pY2FsbHkgZW5jb2RlZGZhaWxlZCB0byBkZXNlcmlhbGl6ZSBHMlByb2plY3RpdmUgcG9pbnQgZnJvbSB0aGUgcmVjZWl2ZWQgYnl0ZXMgLSBpdCBtaWdodCBub3QgaGF2ZSBiZWVuIGNhbm9uaWNhbGx5IGVuY29kZWR2ZXJpZmljYXRpb24ga2V5IGlzIGludmFsaWQgZm9yIHRoaXMgb3BlcmF0aW9uZGlkIG5vdCBwcm92aWRlIHRoZSBzdWZmaWNpZW50IG51bWJlciBvZiBjb2luIGluZGV4IHNpZ25hdHVyZXNkaWQgbm90IHByb3ZpZGUgdGhlIHN1ZmZpY2llbnQgbnVtYmVyIG9mIGV4cGlyYXRpb24gZGF0ZSBzaWduYXR1cmVzeW91J3JlIG9uZSBvZiB0aGUgbW9zdCB1bmx1Y2sgcGVyc29uIG9uIHlvdXIgcGxhbmV0IGFuZCB5b3VyIHdhbGxldCBjYW5ub3QgY29tcGxldGUgdGhpcyBwYXltZW50AAAtVBAASgAAAL0BAAAdAAAABFIQAFoAAADQAQAAGwAAAARSEABaAAAA0QEAABAAAAAEUhAAWgAAAMwBAAAJAAAABFIQAFoAAAC5AQAAIAAAAARSEABaAAAAPQEAACAAAAAEUhAAWgAAAJkBAAAhAEGcrtUAC6AkAQAAACcHAABjYWxsZWQgYFJlc3VsdDo6dW53cmFwKClgIG9uIGFuIGBFcnJgIHZhbHVlACgHAAAUAAAABAAAACkHAABCdWZmZXJUb29TbWFsbAAAKgcAAAwAAAAEAAAAKwcAAAAAAAAEAAAABAAAACMHAABGcm9tVXRmOEVycm9yYnl0ZXNlcnJvcgAEUhAAWgAAAJMAAAArAAAAaz4QAF0AAAAkAAAACQAAAEludmFsaWQgdmFsdWUgKHUxMjggcmFuZ2UpOiB5b3UgbWF5IGhhdmUgYSB2ZXJzaW9uIG9yIGNvbmZpZ3VyYXRpb24gZGlzYWdyZWVtZW50PwpCeXRlIDI1NSBpcyB0cmVhdGVkIGFzIGFuIGV4dGVuc2lvbiBwb2ludDsgaXQgc2hvdWxkIG5vdCBiZSBlbmNvZGluZyBhbnl0aGluZy4KRG8geW91IGhhdmUgYSBtaXNtYXRjaGVkIGJpbmNvZGUgdmVyc2lvbiBvciBjb25maWd1cmF0aW9uPwrUORAAXwAAACAAAAAJAAAALVQQAEoAAAC9AQAAHQAAAKEYEABLAAAA+AEAAA4AAACPWRAAXgAAAPIAAAAJAAAAuG4QAGEAAABeAQAAGQAAAE5ZTUVDQVNILVYwMS1DUzAyLXdpdGgtZXhwYW5kZXItU0hBMjU2TllNRUNBU0gtVjAxLUNTMDItd2l0aC1CTFMxMjM4MUcxX1hNRDpTSEEtMjU2X1NTV1VfUk9fg14QAF0AAAA5AAAAHAAAAENvdWxkIG5vdCBkZWNvZGUgc2NhbGFyc3RydWN0IEFubm90YXRlZENvaW5JbmRleFNpZ25hdHVyZU9uY2UgaW5zdGFuY2UgaGFzIHByZXZpb3VzbHkgYmVlbiBwb2lzb25lZACZWRUAKgAAAG9uZS10aW1lIGluaXRpYWxpemF0aW9uIG1heSBub3QgYmUgcGVyZm9ybWVkIHJlY3Vyc2l2ZWx5zFkVADgAAADZUxAAUwAAANcAAAAxAAAAAAAAAAgAAAAEAAAALAcAABszEABdAAAAlwAAABQAAABhbiBhcnJheWRlc3RpbmF0aW9uIGFuZCBzb3VyY2Ugc2xpY2VzIGhhdmUgZGlmZmVyZW50IGxlbmd0aHNEWhUANAAAAAAAAAAIAAAABAAAAIQAAABzdHJ1Y3QgU2lnbmF0dXJlIHdpdGggMiBlbGVtZW50c5BaFQAgAAAALVQQAEoAAAC9AQAAHQAAAHF4EABbAAAAcwAAACMAAABxeBAAWwAAAHMAAABBAAAAfxwQAEkAAACFAQAACQAAAHN0cnVjdCBBbm5vdGF0ZWRFeHBpcmF0aW9uRGF0ZVNpZ25hdHVyZf////////////////////////////////////////////////////////////////8AAQIDBAUGBwj/////////CQoLDA0ODxD/ERITFBX/FhcYGRobHB0eHyD///////8hIiMkJSYnKCkqK/8sLS4vMDEyMzQ1Njc4Of//////MTIzNDU2Nzg5QUJDREVGR0hKS0xNTlBRUlNUVVZXWFlaYWJjZGVmZ2hpamttbm9wcXJzdHV2d3h5egAAAPs/EABkAAAAAgEAABQAAABJbnZhbGlkIEV4cGFuZE1zZ1htZCB1c2FnZTogZWxsID4gMjU1AAAA7FsVACUAAAD7PxAAZAAAAAQBAAANAAAA+z8QAGQAAAArAQAAIAAAAPs/EABkAAAAPgEAABEAAAD7PxAAZAAAAC4BAAAeAAAA+z8QAGQAAAAuAQAAFwAAAPs/EABkAAAALwEAADgAAAD7PxAAZAAAAC8BAAAvAAAAaz4QAF0AAAAkAAAACQAAAGs+EABdAAAAPgAAADYAAABrPhAAXQAAAD4AAAAXAAAAaz4QAF0AAABCAAAAEwAAAAAAAABn5glqha5nu3Lzbjw69U+lf1IOUYxoBZur2YMfGc3gW0gyQy1PVkVSU0laRS1EU1QtAAAAg14QAF0AAAA5AAAAHAAAAENvdWxkIG5vdCBkZWNvZGUgY29tcHJlc3NlZCBncm91cCBlbGVtZW50AAAAxmQQADoAAAByAAAAKgAAAMZkEAA6AAAAfQAAAFsAAADGZBAAOgAAAIEA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ZXJ0aW9uIGZhaWxlZDogIXNlbGYuc2VyaWFsaXphdGlvbltzY2hlbWVfZW5kX2FzX3VzaXplLi5dLnN0YXJ0c193aXRoKCI6Ly8iKQAANSoQAFkAAACPBQAADQAAADUqEABZAAAAgQUAAA0AAAA1KhAAWQAAAHUFAAAiAAAANSoQAFkAAAB4BQAAJAAAADUqEABZAAAAeQUAABEAAAA1KhAAWQAAAHsFAAAoAAAANSoQAFkAAAB7BQAADQAAADUqEABZAAAArgUAACQAAAA1KhAAWQAAALsFAAAcAAAAUHJvZ3JhbW1pbmcgZXJyb3IuIHBhcnNlX3F1ZXJ5X2FuZF9mcmFnbWVudCgpIGNhbGxlZCB3aXRob3V0ID8gb3IgIwA1KhAAWQAAALcFAAASAAAANSoQAFkAAAAhBQAAMAAAAP////8AQcfS1QALboA1KhAAWQAAAD8FAAA0AAAANSoQAFkAAAA/BQAATgAAADUqEABZAAAARAUAAEoAAAA1KhAAWQAAAEYFAAAkAAAANSoQAFkAAABHBAAAJgAAADUqEABZAAAAOQQAABYAAAA1KhAAWQAAADsEAAANAEHA09UAC+EJAQAAADUHAABjYWxsZWQgYFJlc3VsdDo6dW53cmFwKClgIG9uIGFuIGBFcnJgIHZhbHVlRXJyb3Jhc3NlcnRpb24gZmFpbGVkOiBzZWxmLmlzX2NoYXJfYm91bmRhcnkoaWR4KYJBEABLAAAA6AEAABcAAABhc3NlcnRpb24gZmFpbGVkOiBzZWxmLmlzX2NoYXJfYm91bmRhcnkobmV3X2xlbilhc3NlcnRpb24gZmFpbGVkOiBzZWxmLmlzX2NoYXJfYm91bmRhcnkoYXQpZW1wdHkgaG9zdGludmFsaWQgaW50ZXJuYXRpb25hbCBkb21haW4gbmFtZWludmFsaWQgcG9ydCBudW1iZXJpbnZhbGlkIElQdjQgYWRkcmVzc2ludmFsaWQgSVB2NiBhZGRyZXNzaW52YWxpZCBkb21haW4gY2hhcmFjdGVycmVsYXRpdmUgVVJMIHdpdGhvdXQgYSBiYXNlcmVsYXRpdmUgVVJMIHdpdGggYSBjYW5ub3QtYmUtYS1iYXNlIGJhc2VhIGNhbm5vdC1iZS1hLWJhc2UgVVJMIGRvZXNu4oCZdCBoYXZlIGEgaG9zdCB0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VYCRAXWAkQFVgIQBdYCEAREAdAERAHEBEQBuAREAawERAGgBEQBlAREAYgERAF8BEQBcAREAWQFZAIABeQCAAVmAkQF5gJEBWYCEAXmAhAFZgIEBeYCBAQBBtPjWAAuECLGDiQGxA4oBEQDgABEA3AARANgAEQDUABEA0AARAMwAkYOJAZEDigERAMIAEQC+ABEAugARALYAEQCyABEArgC1g4kBtQOKAREAVgERAFMBEQBQAREATQEAAAAAAAAAAJWDiQGVA4oBEQBKAREARwERAEQBEQBBAQAAAAAAAAAAt4OJAbcDigERAKQAEQCgABEAnAARAJgAEQCUABEAkACXg4kBlwOKAREAhgARAIIAEQB+ABEAegARAHYAEQByALmDiQG5A4oBEQA+AREAOwERADgBEQA1AREAMgERAC8BmYOJAZkDigERACwBEQApAREAJgERACMBEQAgAREAHQG/g4kBvwOKAREAGgERABcBEQAUAREAEQEAAAAAAAAAAJ+DiQGfA4oBEQAOAREACwERAAgBEQAFAQAAAAAAAAAAxYOJAcUDigERAAIBEQD/ABEA/AARAPkAEQD2ABEA8wAAAAAApQOKAQAAAAARAPAAAAAAABEA7QAAAAAAEQDqAMmDiQHJA4oBEQBoABEAZAARAGAAEQBcABEAWAARAFQAqYOJAakDigERAEoAEQBGABEAQgARAD4AEQA6ABEANgCxA4ABsYOAQbUDgAG1g4BBtwOAAbeDgEG5A4ABuYOAQb8DgAG/g4BBxQOAAcWDgEHJA4AByYOAQQAAAAAAAAAAEQDnABEA5AASAOAAEgDcABIA2AASANQAEgDQABIAzAARAMkAEQDGABIAwgASAL4AEgC6ABIAtgASALIAEgCuABEAqwARAKgAEgCkABIAoAASAJwAEgCYABIAlAASAJAAEQCNABEAigASAIYAEgCCABIAfgASAHoAEgB2ABIAcgARAG8AEQBsABIAaAASAGQAEgBgABIAXAASAFgAEgBUABEAUQARAE4AEgBKABIARgASAEIAEgA+ABIAOgASADYAsQODAbEDggERADMAsYOiAREAMAAAAAAAsQOhAREALQCRA4MBkQOCAZEDgAGRg4BBkYOiAQAAAAC5AwBAAAAAAKgAoQERACoAt4OiAREAJwAAAAAAtwOhAREAJACVA4ABlYOA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BdwF6wX7BQsGGwYqBjoGSgZaBmkGeQaJBpkGKgY6BkoGWgaoBrgGyAbYBugG+AYIBxgHJgc2B0YHVgdkB3QHhAeUB6QHtAfEB9QH5Af0BwQIFAgjCDMIQwhTCKwFvAXMBdwFYghyCIIIkgiECJQIpAi0CMMI0wjjCPMIAgkSCSIJMgk4CUgJWAloCU8JXwlvCX8JjwmfCa8JvwmeCa4JvgnOCQ0CHQItAj0C2wnrCfsJCwoZCikKOQpJClMKYwpzCoMKpwW3BccF1wX3APcAPQqTCvcAogobAq8KvQqgBfcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcAPQr3APcA9wDNCvcA9wD3APcA9wD3AEAA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wDdCiwB9wD3APcA9wD3APcA9wDrCvcAjQX3AI0F9wCNBfcA9wD3APcKegkBC/cAzQoRC/cA9wD3APcA9wD3APcAigX3AKQF9wD3APcA9wD3APcA9wAgCy4LPgv3APcA9wD3APcA9wD3APcATQBrAWsB9wBHC/cA9wD3AFMLYQtuC/cA9wD3AHwBrQH3APcA9wAYAvcA9wB+C6sF9wA/ChgCGgL3AIwL9wD3APcAmgsaAvcA9wA+CqkL9wD3APcA9wD3APcA9wD3APcAaAq5C8IL9wD3APcA9wD3APcA9wD3APcA9wD3APcAfAF8AXwBfAH3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wDMC9sLTgBOACoB6wtrAfsLCwwXDBwMLAw8DEwM9wBcDFwMXAx8AXwBGwJsDHgMhgwtAZYMawH3APcApAxrAWsBawFrAWsBawFrAbQMawFrAWsBawFrAWsBawFrAWsBawFrAWsBawFrAWsBawFrATsA9wD3APcAUABrAWUBawFrAWsBawFrAWsBzQr3AFEB9wBrAWsBvAzEDPcA9wD3APcAUQBrAWsBawFrAWsBawFrAWsBawFrAWsBawFrAWsBawFrAWsB1AxrAWsBawFrAWsBawFrAWsBawFrAWsBawFrAWsBawFrAWsBawFrAWsBawH3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3AGsBawFrAWsBawFrAWsBawFrAWsBawFrAWsBawFrAWsBawFrAWsBawFrAWsBawFIAWsBZAFrAWsBawFrAWsBawH3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA5AzzDPcA9wD3APcA9wD3APcAWQX3APcA9wD3APcA9wB8AXwBawFrAWsBawFrAT4B9wD3AGsB/AxrAWsBawFrAWsBPQBrAWsBawFrAWsBawFrAWsBawFrAWsBawFrATsA9wBrAQwNawEbDSsN9wD3APcA9wD3ADsNQAD3APcA9wD3AMsA9wD3APcA9wD3APcA9wD3APcA9wD3APcAawFrAUsN9wAqAfcA9wD3AGsB9wBbDfcA9wD3AGoBTwD3APcA9wD3APcA9wD3APcA9wD3AGoN9wD3APcA9wD3AE0A9wBMAPcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wBrAWsBawFrAfcA9wD3APcA9wD3APcA9wD3AGsBawFrAVsI9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wBOAPcA9wD3APcA9wBZBXoN9wD/BfcA9wD3APcA9wAaAmsBawE/APcA9wD3APcA9wDOAPcA9wD3APcA9wD3APcAig33AJYNFQb3APcA9wCcDPcA9wD3APcAiwX3AHwBpg33APcAkAn3AEMKGgL3APcAGQL3APcAsg33APcAqAX3APcAwA3PDdwN9wD3AKEF9wD3APcA7A2sBfcAAQanBfcA9wD3APcA9wD3AC0B9wD3APcA9wD3APcA9wD8DfcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wAKDhkOjgKOAiwDLAMsAywDLAMsAywDLAMsAywDLAMsAywDLAMsAywDLAMsAywDKQ5rASwDLAMsAywDLAMsAywDOQ6FAIUAOw58Ac0KfAFrAWsBSw5bDiwDLAMsAywDLAMsAywDLANrDnsOMABAAFAAQABQADsA9wD3APcA9wD3APcA9wCLDpsO9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wDVAPcA9wD3AGsBawFrAWsBTwFPAUAA9wD3APcA9wCgBfcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wCrDsQM9wD3APcA9wD3APcA9wC7DvcA9wD3APcA9wD3APcA9wCOAo4CjgKOAo4CjgKOAo4CjgKOAo4CjgKOAo4CjgKOAo4Cyw6OAo4CjgKOAo4CjgKOAo4CjgKOAo4CjgKOAo4C2w6OAo4C6w6OAo4CjgKOAo4CjgKOAo4CjgKOAvsOjgKOAo4CjgICD44CjgKOAo4CjgKOAo4CjgKOAo4CjgKOAo4CjgKOAo4CLAMsAxIPIg8yD44CPA+OAo4CjgKOAo4CjgKOAo4CjgJMD00PjgKOAlwPjgIsAywDLAP6Ao4CjgKOAiwDAAPgAiwDjgJqD44CjgKOAo4CjgKOAo4CrAX3APcAQgoVAjwBOwB6DxoC9wD3AIYPqwX3APcA9wAZAvcAkQ8XAvcA9wD3AKoFGgL3APcAoQ+AD/cA9wD3AFkFrg+sBfcA9wD3APcA9wD3APcA9wBZBZMJ9wAaAvcA9wACBhsC9wAPAhcC9wD3APcAPwqnDecGjgX3APcA9wBCCkgJWgX3APcA9wD3APcAvQ8pBvcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wDKDxsCAQb3APcA9wDaDxsC9wBPAfcA9wD3AF0F4gb3APcA9wD3APcAWwXqD/cA9wD3APcA9wD3APcA9wD3APcA9wD3APcAWQVQCvcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APYPqgX3APcA9wD3APcA9wD3APcAhQ8bAvcABRD3APcAEhCmBSEQ9wD3AEAKMRD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3AEEQ9wD3APcA9wD3AEgKURBgEPcA9wD3APcA9wD3APcAbxDiBvcA9wD3APcAfhD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wCMBRoC9wD3ALsO5wajBfcA9wD3APcA9wD3APcAiRCYED8A9wD3APcA9wCgDxYC9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3AP8FqBD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wAXAvcA9wD3ABUC9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3AFkF9wD3APcAWQUZAvcA9wD3APcAuBD3APcA9wD3APcA9wD3APcA9wAABsgQ9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcAawFrAWsBawFrAWsBawFrAWsBawFrAWsBawE7APcAsQ5rAWsBawFrAWsBawFrAWsBawFrAWsBawFrAWsBawFrAT0A9wD3APcA9wB8AXwBrgF8ARUC9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wDmCtUQ4hD3AH8P9wD3APcALgH3AGsBawFrAWsB8hD3APcA9wD3APcA9wD3APcA9wD3APcAawFrAWsBawFrAVsI9wD3APcA9wD3APcA9wD3APcA9wD3APcA1QDLAPcAywD3ANEA9wDRAEwA9wBMAPcAzQD3AM0A9wD/EA0RDRENEXwBfAF8AR0RfAF8Aa8BqAWpBT8Kawr3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wBkCigRNhH3APcA9wD3APcAWQX3APcA9wD3APcA9wD3APcA9wD3ABUC9wD3APcA9wD3APcA9wD3APcA9wD3APcAWgX3APcA9wA+CkER9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wA+CvcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3AP8F9wCOAo4CjgKOAo4CjgKOAo4CjgKOAo4CjgKOAlERjgKOAo4CjgKOAo4CXRGOAo4CjgKOAo4CjgKOAo4CjgKOAo4CjgKOAo4CjgKOAo4CjgKOAo4CjgKOAo4CjgKOAo4CjgKOAo4CjgKOAo4CLAMsAywDLAMsA44CjgKOAo4CLAMsAywDLAMsA44CjgKOAo4CjgKOAo4CjgKOAo4CjgIsAywDLAMsAywDLAMsAywDLAMsAywDLAMsAywDLAM3Do4CjgKOAo4CjgKOAo4CjgKOAo4CjgKOAo4CjgKOAo4CawFrAVABawFrAWsBawFrAWsBPQBtEWoBagFqAWsBOwB9EfcATAD3APcA9wBRAPcA9wD3AMkA9wD3APcA9wD3APcAOwD3APcA9wD3APcA9wD3APcA9wBrAWsBawFrAWsBawFrAWsBawFrAWsBawFrAWsBawFrAWsBawFrAWsBawFrAWsBawFrAWsBawFrAWsBawFrAWsBiBFPAU8BawFrAWsBawFrAWsBawGJEWsBawFrAWsBawHNClABQABQAWsBawFrARQNzQprAWsBFA1rAT4BUAE/APcA9wD3AGsBawFrAWsBawFrAWsBawFrAWsBawFrAWsBawFrAWsBPQA+AU8BUgFrAWsBawGUET8BzQqiEWsBawFrAWsBawFrAWsBawFrAWcBawFrAWsBawFrAbEO9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wD3APcA9wCrEYUAhQCFAIUAhQCFAIUAhQCFAIUAhQCFAIUAhQCFAIUAfAF8AXwBfAF8AXwBfAF8AXwBfAF8AXwBfAF8AXwBhQCFAIUAhQCFAIUAhQCFAIUAhQCFAIUAhQCFAIUAhQCFAIUAhQCFAIUAhQCFAIUAhQCFAIUAhQCFAIUAhQCFAIQAnAC8ANwA/AAcATwBXAF8AYcBpwG/Ad8B/wEfAj8CXwJ+ApwCsgLSAuICAgMiA0IDYQOBA4EDgQOBA4EDgQOFA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDpQPFA+UDBASBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDIwQ4BFgEeASYBIEDgQO4BNgE7AQGBSYFRAVjBYEFnwW/BdwF9gWBA4EDgQOBA4EDgQOBA4EDgQOBAxYGgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQMlBoEDgQOBA4EDOAaBA0wGgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDawaBA4EDgQOBA4EDgQOLBqAGtQbVBoED6waBAwsHgQOBAysHQQdTB4EDcweIB6EHwQfhB/wHDAgfCD8IWgiBA3oIgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA3oImgi5CLkIuQi5CLkIuQi5CIEDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBA4EDgQOBAxISEhISEhISEggHCAkHEhISEhISEhISEhISEhIHBwcICQoKBAQECgoKCgoDBgMGBgICAgICAgICAgIGCgoKCgoKAEGP+9cACwYKCgoKCgoAQa/71wALRAoKCgoSEhISEgcSEhISEhISEhISEhISEhISEhISEhISEhISEgYKBAQEBAoKCgoACgoSCgoEBAICCgAKCgoCAAoKCgoKAEGK/NcACwEKAEGq/NcACwEKAEHr/NcAC5wBCgoAAAAAAAoKCgoKCgoKCgoKCgoKAAAKCgoKCgoKCgoKCgoKCgAAAAAACgoKCgoKCgoKAAoKCgoKCgoKCgoKCgoKCgoKEREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREQAAAAAKCgAAAAAAAAAACgAAAAAKCgAKAEG//tcACwEKAEHJ/tcACwcRERERERERAEGG/9cAC98FCgAACgoEAREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREQEREQEREQERAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEFBQUFBQUKCg0EBA0GDQoKERERERERERERERENDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NERERERERERERERERERERERERERERBQUFBQUFBQUFBQQFBQ0NDRENDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NEREREREREQUKERERERERDQ0REQoRERERDQ0CAgICAgICAgICDQ0NDQ0NDQ0NDQ0NDQ0NDQ0RDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NEREREREREREREREREREREQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NERERERERERERERENDQ0NDQ0NDQ0NDQ0NDQ0BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBERERERERERERAQEKCgoKAQEBEQEBAQEBAQEBAQEBAQEBAQEBAQEBAQERERERAREREREREREREQEREREBEREREREBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBERERAQEBAQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NBQUNDQ0NDREREREREREREQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NDQ0NERERERERERERERERERERERERERERERERBRERERERERERERERERERERERERERERERERERERERAEGchdgACx0RABEAAAAREREREREREQAAAAARAAAAEREREREREQBBw4XYAAsCEREAQeGF2AALAREAQZyG2AALEREAAAARERERAAAAAAAAAAARAEHBhtgACwIREQBB0YbYAAsQBAQAAAAAAAAABAAAEQAREQBBmofYAAsVEQAAABERAAAAABERAAAREREAAAARAEHNh9gACwYREQAAABEAQd2H2AALDRERERERABERAAAAABEAQf6H2AALAhERAEGNiNgACxEEAAAAAAAAAAAREREREREAEQBB2IjYAAsZEQAAEREREQAAAAAAAAAAEQAAAAAAAAAREQBB/IjYAAsCEREAQZqJ2AALAREAQdiJ2AALAREAQeWJ2AALAREAQYuK2AALEgoKCgoKCgQKAAAAAAARAAAAEQBB1IrYAAsaEQAREQAAAAAAERERABEREREAAAAAAAAAEREAQfmK2AALAhERAEGPi9gACwcKCgoKCgoKAEGii9gACwIREQBBuIvYAAsCEREAQfOL2AALEhERAAAAEREREQAAAAAAAAAAEQBBmYzYAAsCEREAQbeM2AALAREAQfaM2AALDREAAAAAAAAAERERABEAQbSN2AALHhEAABEREREREREAAAAABAAAAAAAAAAREREREREREQBBg47YAAsMEQAAERERERERERERAEGnjtgACwIREQBBxI7YAAsJEQARABEKCgoKAEH+jtgAC2oREREREREREREREREREQAREQAAAAAAEREREREREREREREAERERERERERERERERERERERERERERERERERERERERERERERERAAAAEQAREREREREAEREAABERAAAAAAAAAAAREQAAAAARERERAEHzj9gACx8RAAAREQAAAAAAABEAAAoKCgoKCgoKCgoAAAAAAAAJAEGhkNgACwMREREAQa+Q2AALSRERABEREREREREAAAAAAAAABAARAAAKCgoKCgoKCgoKChERERIREREAAAAAEREAAAAAAAAAEQAAAAAAABEREQAAAAAKAAAACgoAQYKR2AALfhERAAARAAAAAAAAEQARERERERERABEAABERERERERERAAAAEREREREREREREQAAEQAAAAARABERERERABEAAAARERERAAAREQAREREAAAAAAAARABERAAAAEQARERERAAAREQAAAAAAAAAAEQARERERERERAAAAABEAAAAREQBBjZLYAAsECgAKCgBBnJLYAAu8AQoKCgkJCQkJCQkJCQkJEhISAAEKCgoKCgoKCgkHCw4QDA8GBAQEBAQKCgoKCgoKCgoKCgYKCgoKCgoKCgoKCgoKCgoJEhISEhISFBUTFhISEhISEgIAAAACAgICAgIDAwoKCgACAgICAgICAgICAwMKCgoABAQEBAQEBAQEBAQEBAQEBAoKAAoKCgoACgoAAAAAAAAKAAoKCgAAAAAACgoKCgAKAAoACgAAAAAEAAoKCgoKAAAAAAAKCgoKAEHhk9gAC28KCgoAAAAACgoDBAoKCgoKCgoKCgoKCgICAgICAgICAgICAgAAAAAKCgoKCgoKCgoKCgoACgoKAAAAAAAKCgoKCgoAAAAAEREAAAAAAAAACgoKCgoKCgoKCgAKCgoKCgkKCgoKAAAACgoKCgoKCgoAQdmU2AALFhEREREAAAoAAAAAAAoKAAAAAAAKCgoAQfiU2AALDRERCgoAAAAKCgoKCgoAQY6V2AALAQoAQZuV2AALQQoKCgAAAAAAAAAKCgoKAAAAAAAREREKEREREREREREREQoKAAARAAAAEQAAAAARAAAAAAAREQAKCgoKEQAAABERAEHpldgACwsRAAARERERAAAREQBB/ZXYAAsNERERERERABERAAAREQBBk5bYAAsrEQAAAAAAAAAAEQAAABEAERERAAAREQAAAAAAEREAAAAAABEAABEAAAAAEQBBy5bYAAvoAgERAQEBAQEBAQEBAwEBAQEBAQ0NDQ0NDQ0NDQ0NDQ0NCgoNDQ0NDQ0NDQ0NDQ0NDQ0KCgoGCgYACgYKCgoKCgoKCgoECgoDAwoKCgAKBAQKAAAAAA0NDQ0NDQ0NDQ0NDQ0NDRIACgoEBAQKCgoKCgMGAwYGBAQKCgoEBAAKCgoKCgoKABISEhISEhISEgoKCgoKEhIRAgICAgICAgICAgICAgICAAAAAAAAEREREREAAAAAAAEBAQEBAQEBAQEBAQEBAQoBERERARERAQEBAQERERERAQEBAQEBAQEREREBAQEBEQEBAQEBEREBAQEBAQEBAQEKCgoKCgoKDQ0NDRERERENDQ0NDQ0NDQUFBQUFBQUFBQUNDQ0NDQ0FBQUFBQUFBQUFAQEBAQEBAQEBEREREREKAQUFBQUFBQUFBQUFBQUFBQUBAQEBAQEBAQEBARERAQEBEREREQEBAQEBAQEBAQERAAAREQBBvZnYAAttEREREQAAEREAAAAAAAAAEREREREAERERAAAAAAAAERERERERERERAAARABERAAAAAAAAEQAAABEREREREQARAAAAABEREREAAAAAAAAREQARAAAAEREREREREREAABEAEQAAEREREQAREREREQBBtZrYAAtmEREAEQAREREREREAABERAAAAAAAREREREREAABEREREAERERERERAAAREREAAAAAEREREREREQAREQAAAAAAABEREREREREAERERERERAAAREREREREREQAAERERERERABERABERAEGkm9gAC00REREREREAAAARABERABERAAAAEQARAAAAAAAAAAAKCgoKCgoKCgQEBAoKCgoKCgoKCgoKCgoKChEREREREREREREAAAAREREAAAoAEQBB/JvYAAsEEhISEgBBjJzYAAsgEhISEhISEhIREREREQAAEREREREREQAAAAAKChEREQoAQbac2AALAQoAQcGc2AALNAICAgICAgICAgICAgICAgIRERERERERAAAAABEREREREREREQAAEREREREAEREAEREREREAQYSd2AALWwQRERERERERAQEBAQEBAQEBEREREREREQEBAQEBCgoKCgoKCgoKCgoKCgoKAAICAgICAgICAgICCgoKCgoKCgoAAAAACgoKCgoKCgAAAAAAAAAKCgoKCgoKCgoAQe2d2AALLBISAGDpFQDqCQAAAAAAADT9FQC8EQAAAAAAAAAAEQD3AAAAAAAAABABgQMBAEGintgACwNAAFMAQbie2AALA5MAowBBxJ7YAAuvBeAAAAAAAAAADwFNAX0BvQH1ATUC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DwIPAv0NAEGKtdgACw9/AAAAkwCTAJMAkwCTAJMAQaq12AALvgOTAJMAkwCTAJMAkwCTAJMAkwCTAJMAkwCTAJMAkwAAAHkAiQChAMAA4AAAASABQAFgAWsBgQGQAbABzwHvAYEBDwKBAYEBgQGBAYEBIQKBAUECgQGBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQGBAVsCewKaAoEBgQGBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQG5AoEB2QL5AhkDgQGBAYEBOQNUA2sDiwOpA8gD5gMEBCQEQQRbBIEBgQGBAYEBgQGBAYEBgQGBAYEBeASBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQGBAYcEgQGBAYEBgQGaBIEBrgSBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQGBAYEBgQHNBIEBgQGBAYEBgQGBAYEB3QTyBA4FgQGBAYEBLgWBAYEBTgVkBXYFgQGVBYEBgQGBAYEBgQGBAYEBgQGBAYEBgQG1BQBB6LnYAAsBBQBB+7nYAAtABQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQBBy7rYAAsHBQUFBQUFBQBBiLvYAAs1BQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFAAUFAAUFAAUAQfW72AALUAUFBQUFBQUFBQUFAAUAAAACAAQEBAQCBAIEAgICAgIEBAQEAgICAgICAgICAgICAgECAgICAgICBAICBQUFBQUFBQUFBQUFBQUFBQUFBQUFAEHTvNgAC3oCAgUEBAQABAQEAgICAgICAgIEBAQEBAQEBAQEBAQEBAQEBAQCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQCAgQEBAQEBAQEBAIEAgQCAgQEAAQFBQUFBQUFAAAFBQUFBQUAAAUFAAUFBQUEBABB173YAAsGAgICAAACAEHsvdgAC2YFBAUCAgIEBAQEBAICAgIEAgIC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khXqFJwV6hQZERkRGREZERkRGREZERkRGREZERkRGREZERkRGREZEeoU6hTqFOoU6hTqFOoU6hSfFacV6hTqFOoUsBXqFLwV6hTqFOoU6hTqFOoU6hTqFOoU6hTqFOoU6hTqFOoU6hQZERkRGRHqFMoVGREZEdcVGRHhFRkRGREZERkRGREZEUEAQQBBAGEAYQBhAPEVABb/AP8A/wD/AP8A/wAPFh4WYQBhAC4WowWjBaMFPhZOFqMFXhZqCGoIaghqCM4CzgJuFnwWjBacFqwWvBYYDRgNGRHdFRkRGREZERkRGRHMFhkRGREZERkRGREZERkRGREZERkRGREZERkR3BYYDRkR7Bb6FgoXGhcBBaMFowWjBaMFKhe9D6MFowWjBaMFORf9BKMFowUBBaMFowWjBaMFDgVJF6MFowUZERkRUxejBRkRYhdOFRkRchd9FBkRGRFOFRkRGRF9FBkRGREZERkRGREZERkRGREZERkRGREZERkRGREZERkRGREZERkRGRGjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFGREZERkRGRGjBW0FowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFEAUZERkRGRFSF6MFowUVEqMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFghejBZIXGA3/AP8AoheyF/8AwhejBaMFowWjBdIX4he9AvIXAhj9AP8A/wD/ABIYIBgwGDYYQBhMGFwYGA1qGHgYowWFGJUYowWjBaMFpRi1GKMFowXBGM0YJAvOAt0YngajBe0YowV2Bf0YowUQBcoHowWjBQ0ZHBksGTwZ8RCjBaMFQxlSGWIZchmjBYIZowWjBaMFkhmiGacZtxnHGdYZuhBqCGEAYQDmGfYZYQBhAGEAYQBhAKMFowUGGiQLowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBZcNowUWGqMFowURBSYaJhomGiYaJhomGiYaJhomGiYaJhomGiYaJhomGiYaJhomGiYaJhomGiYaJhomGiYaJhomGiYaJhomGiYaJho2GjYa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owWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBX0cowWjBaMFowWjBaMFowWjBaMFowWjBaMFowW7EBgNlAmUEBgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgN4ySjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWYDZEJGA3zJP8kowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFEQUYDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDaMFowWjBaMFowWjBT4HEAWUEA8lHyUYDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0ZERkRGREZERkRGREZERkRGREZERkRGREZERkRGREkCxkRGREZERkRGREZERkRGREZERkRGREZERkRGREZERkRzBYYDRgNGA0YDc4CzgJBBs4CGhQZERkRGREZERkRGREZEcwWGA0YDRgNGREZERkRGREZERkRGREZERkRGREZERkRGREZERkR3BYZERkRLyUZERkRGRE6JUclVCUZEWAlGREZERkRPBUYDRkRGREZERkRbiUYDRgNGA0YDRgNGA0YDX4UfiV+FH4lGREZERkRGREZEVIXfhQBHBgNGA0YDRgNGA0YDRgNGA1BALIDYQCOJa4DnBynEkEA3ACeJa4lvCWdHEEAsgNhAMkl1iVhAOQl9CUDJgcmQQDYAGEAQQCyA2EAjiWuA2EApxJBANwAByZBANgAYQBBALIDYQAXJkEAJibrAIoDNiZhAEImQQAiJucAMCbHAGEA7QBBAE4mYQBbJpUhlSGVIRkRGREZERkRGREZERkRGREZERkRGREZERkRGREZERkRGREZERkRGREZERkRGREZERkRGREZERkRGREZERkRGRHOAs4CzgJrJs4CzgJ2JoMmjyb3E8IEGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNWgKfJq4mGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA1MDr4mzCaAAoACgALcJhgN8xMYDRgNGA0YDRgNGA0YDaMFowUQBewm/CYYDRgNGA0YDRgNGA0YDRgNGA0YDRgNowUMJxgNowWjBTMGHCcYDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDaMFiwckCxgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNowUxBiwnGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNPCcOBaMFowWjBaMFowWjBaMFowWjBaMFowWjBUwnGhQYDRgNQQBBANwAYQBcJywZGA0YDRgNGA0YDRgNGA0YDRgNGA2uH34UfhRsJ3wnGA0YDRgNGA2uH34UjCf8GxgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDeQKowWcJ6kntyfHJ9Un3SdnCBEF7CcRBRgNGA0YDfwnGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0ZERkROxUZERkRGREZERkRGRHMFmIXGBEYERgRGRHcFgwoGREZERkRGREZERkRGREZERkRORUYDRgNGA1cFxkR2BsZERkROxVQF9kb3BYYDRgNGA0YDRgNGA0YDRgNGA0ZERkRGREZERkRGREZERkRGREZERkRGREZERkRGREZKBkRGREZERkRGREZERkRGREZERkRGREZERkRKSg6FToVGREZERkRGREZERkRGREqKBkRGREZERkRGRGdDzsV2hs7FRkRGREZEVEXnQ8ZERkRURcZETkVOxXZGxgNGA0YDRkRGREZERkRGREZERkRGREZERkRGREZERkRGREZERkRzBY5FToVNSgZERkRGRFEKFIonQ9QFxkRGREZERkRGREZERkRGREZEWEoGREZERkRGREZESQLowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBRgNGA2jBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBZMQowWjBaMFowWjBaMFowWjBaMFowWjBaMFDwWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWZDaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBZMJowWjBaMFowWjBQ8FGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNGA0YDRgNowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBT4HowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFowWjBaMFGA0YDRgNGA0YDXEoGA0GJAYkBiQGJAYkBiQYDRgNGA0YDRgNGA0YDRgNzgLOAs4CzgLOAs4CzgLOAs4CzgLOAs4CzgLOAs4CGA02GjYaNho2GjYaNho2GjYaNho2GjYaNho2GjYaNho2GjYaNho2GjYaNho2GjYaNho2GjYaNho2GjYaNho2GoEohACkAMQA5AAEASQBRAFkAYQBoAHAAdoB+gEaAjoCWgJ6ApoCuQLZAvkCGQM5A1kDeQOZA7kDuQO5A7kDuQO5A70DuQO5A7kDuQO5A7kDuQO5A7kDuQO5A7kDuQO5A7kDuQO5A7kDuQO5A7kDuQO5A7kDuQPdA7kD9QMVBDUEVQS5A7kDuQO5A7kDuQO5A7kDuQO5A7kDdQSVBJUElQSVBLUEtQS1BLUEtQS1BLUEtQS1BLUEtQS1BMUE3wT9BB0FPQVdBX0FnQW9Bd0F/QUXBjcGVwZ3BpcGtwbXBvcGEge5AzIHUgdnB2cHZwdnB24HuQO5A44HuQO5A7kDuQO5A5QHuQO0B2cHZwdnB2cHZwdnB2cHZwdnB2cHZwdnB8QHZwdnB2cHuQPkB/0HGQi5A7kDuQO5A7kDuQO5A7kDOQi5A7kDWQhnB2cHZwdnB2cHZwdnB2cHZwdnB2cHZwdnB2cHZwdnB2oIigihCGcHZwdnB2cHwQhnB2cHZwdnB2cHZwfhCPYIFgk2CVYJdgmWCbYJZwfGCeYJ/QkQCjAKUApnB2kKiQqpCskKlgnpCgkLJAtnB2cHuQO5A7kDuQO5A7kDuQO5A7kDuQO5A7kDuQO5A7kDuQO5A7kDuQO5A7kDuQO5A7kDuQO5A7kDuQO5A7kDuQO5A0QLuQO5A7kDuQO5A7kDuQNUC3MLuQO5A7kDuQO5A7kDuQOJC7kDuQO5A7kDuQO5A7kDuQO5A7kDuQO5A7kDlAu5A7MLZwdnB2cHZwe5A7cLZwdnB7kDuQO5A7kDuQO5A7kDuQO5A9cLuQO5A7kDuQO5A7kDuQPsC2cHZwdnB2cHZwdnB2cHZwdnB2cHZwdnB2cHZwdnB2cHZwdnB2cHZwdnB2cHZwdnB2cHZwdnB2cHZwdnB2cHZwcMDGcHZwdnB2cHZwdnB2cHZwdnB2cHZwdnB2cHZwdnB2cHZwdnB2cHZwdnB2cHZwdnB2cHZwdnB2cHZwdnB2cHtQS1BLUEtQS1BLUEtQS1BLUEtQS1BLUEtQS1BLUEtQS1BLUEtQS1BLUEtQS1BLUEtQS1BLUEtQS1BLUEtQS1BCwMDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8MFxcXGRcXFxQVFxgXExcXCQkJCQkJCQkJCRcXGBgYFxcBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBARQXFRoWGgICAgICAgICAgICAgICAgICAgICAgICAgICFBgVGA8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDw8PDBcZGRkZGxcaGwUcGBAbGhsYCwsaAhcXGgsFHQsLCxcBAQEBAQEBAQEBAQEBAQEBAQEBAQEBARgBAQEBAQEBAgICAgICAgICAgICAgICAgICAgICAgICGAICAgICAgICAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQICAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgEBAgECAQICAQECAQIBAQIBAQECAgEBAQECAQECAQEBAgICAQECAQECAQIBAgEBAgECAgECAQECAQEBAgECAQECAgUBAgICBQUFBQEDAgEDAgEDAgECAQIBAgECAQIBAgECAQICAQIBAgECAQIBAgECAQIBAgECAgEDAgECAQEBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAgICAgICAQECAQECAQIBAQEBAgECAQIBAgECAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQICAgICAgICAgICAgICAgICAgICAgICAgICAgQEBAQEBAQEBAQEBAQEBAQaGhoaBAQEBAQEBAQEBAQEGhoaGhoaGhoaGhoaGhoEBAQEBBoaGhoaGhoEGgQaGhoaGhoaGhoaGhoaGhoaGgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYBAgECBBoBAgAABAICAhcBAAAAABoaARcBAQEAAQABAQIBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQECAgICAgICAgICAgICAgICAgICAgECAgEBAQICAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgICAgIBAhgBAgEBAgIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQECAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECGwYGBgYGBwcBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAQIBAgECAQIBAgECAQICAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAQIBAgECAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAEFxcXFxcXAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIXEwAAGxsZAAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBhMGFwYGFwYGFwYAAAAAAAAAAAUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQAAAAAFBQUFFxcAQaKX2QAL3gIQEBAQEBAYGBgXFxkXFxsbBgYGBgYGBgYGBgYXEBcXFwUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBAUFBQUFBQUFBQUGBgYGBgYGBgYGBgYGBgYGBgYGBgYJCQkJCQkJCQkJFxcXFwUFBgUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUXBQYGBgYGBgYQGwYGBgYGBgQEBgYbBgYGBgUFCQkJCQkJCQkJCQUFBRsbBRcXFxcXFxcXFxcXFxcXABAFBgUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQYGBgYGBgYGBgYGBgYGBgYAAAUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQYGBgYGBgYGBgYGBQBBjprZAAueBQkJCQkJCQkJCQkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUGBgYGBgYGBgYEBBsXFxcEAAAGGRkFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBgYGBgQGBgYGBgYGBgYEBgYGBAYGBgYGAAAXFxcXFxcXFxcXFxcXFxcABQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQYGBgAAFwAFBQUFBQUFBQUFBQAAAAAABQUFBQUFBQUFBQUFBQUFBRoFBQUFBQUAEBAAAAAAAAYGBgYGBgYGBgUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBhAGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBggFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUGCAYFCAgGBgYGBgYGBggICAgGCAgFBgYGBgYGBgUFBQUFBQUFBQUGBhcXCQkJCQkJCQkJCRcEBQUFBQUFBQUFBQUFBQUGCAgABQUFBQUFBQUAAAUFAAAFBQUFBQUFBQUFBQUFBQUFBQUFBQUFAAUFBQUFBQUABQAAAAUFBQUAAAYFCAgGBgYGAAAICAAACAgGBQAAAAAAAAAACAAAAAAFBQAFBQUGBgAACQkJCQkJCQkJCQUFGRkLCwsLCwsbGQUXBgAGBggABQUFBQUFAAAAAAUFAAAFBQUFBQUFBQUFBQUFBQUFBQUFBQUFAAUFBQUFBQUABQUABQUABQUAAAYACAgGBgAAAAAGBgAABgYGAAAABgAAAAAAAAAFBQUFAAUAAAAAAAAACQkJCQkJCQkJCQYGBQUFBhcAQbWf2QALTwYGCAAFBQUFBQUFBQUABQUFAAUFBQUFBQUFBQUFBQUFBQUFBQUFBQUABQUFBQUFBQAFBQAFBQUFBQAABgUICAYGBgYGAAYGCAAICAYAAAUAQZOg2QAL9AEFBQYGAAAJCQkJCQkJCQkJFxkAAAAAAAAABQYGBgYGBgAGCAgABQUFBQUFBQUAAAUFAAAFBQUFBQUFBQUFBQUFBQUFBQUFBQUFAAUFBQUFBQUABQUABQUFBQUAAAYFCAYGBgYAAAgIAAAICAYAAAAAAAAABgYIAAAAAAUFAAUFBQYGAAAJCQkJCQkJCQkJGwULCwsLCwsAAAAAAAAAAAYFAAUFBQUFBQAAAAUFBQAFBQUFAAAABQUABQAFBQAAAAUFAAAABQUFAAAABQUFBQUFBQUFBQUFAAAAAAgIBggIAAAACAgIAAgICAYAAAUAAAAAAAAIAEGVotkAC40CCQkJCQkJCQkJCQsLCxsbGxsbGxkbAAAAAAAGCAgIBgUFBQUFBQUFAAUFBQAFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQAFBQUFBQUFBQUFBQUFBQUFAAAGBQYGCAgICAAGBgYABgYGBgAAAAAAAAAGBgAFBQUAAAUAAAUFBgYAAAkJCQkJCQkJCQkAAAAAAAAAFwsLCwsLCwsbBQYICBcFBQUFBQUFBQAFBQUABQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUABQUFBQUFBQUFBQAFBQUFBQAABgUIBggICAgIAAYICAAICAYGAAAAAAAAAAgIAAAAAAAABQUABQUGBgAACQkJCQkJCQkJCQAFBQgAQa6k2QAL9AEGBggIBQUFBQUFBQUFAAUFBQAFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQYGBQgIBgYGBgAICAgACAgIBgUbAAAAAAUFBQgLCwsLCwsLBQUFBgYAAAkJCQkJCQkJCQkLCwsLCwsLCwsbBQUFBQUFAAYICAAFBQUFBQUFBQUFBQUFBQUFBQUAAAAFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUABQUFBQUFBQUFAAUAAAUFBQUFBQUAAAAGAAAAAAgICAYGBgAGAAgICAgICAgIAAAAAAAACQkJCQkJCQkJCQAACAgXAEGtptkAC1sFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUGBQUGBgYGBgYGAAAAABkFBQUFBQUEBgYGBgYGBgYXCQkJCQkJCQkJCRcXAEGsp9kAC18FBQAFAAUFBQUFAAUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQAFAAUFBQUFBQUFBQUGBQUGBgYGBgYGBgYFAAAFBQUFBQAEAAYGBgYGBgYACQkJCQkJCQkJCQAABQUFBQBBq6jZAAvZAQUbGxsXFxcXFxcXFxcXFxcXFxcbFxsbGwYGGxsbGxsbCQkJCQkJCQkJCQsLCwsLCwsLCwsbBhsGGwYUFRQVCAgFBQUFBQUFBQAFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUFBQUAAAAABgYGBgYGBgYGBgYGBgYIBgYGBgYXBgYFBQUFBQYGBgYGBgYGBgYGAAYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgYGBgAbGxsbGxsGGxsbGxsbABsbFxcXFxcbGxsbFxcAQamq2QAL0QIFBQUFBQUFBQUFBQgIBgYGCAYGBgYGBggGBggIBgYFCQkJCQkJCQkJCRcXFxcXFwUFBQUFBQgIBgYFBQUFBgYFCAgIBQUICAgICAgIBQUGBgYGBQUFBQUFBQUFBQUGCAgGBggICAgICAYFCAkJCQkJCQkJCQkICAgGGxsBAQEBAQEAAQAAAAAAAQAAAgICAgICAgICAgIXBAICAgUFBQUFBQUFBQAFBQUFAAAFBQUFBQUFAAUABQUFBQAABQUFBQUFBQUFBQUAAAYGBhcXFxcXFxcXFwsLCwsLCwsLCwsLCwsAAAAbGxsbGxsbGxsbAAAAAAAAAQEBAQEBAAACAgICAgIAABMFBQUFBQUFBQUFBQUFBQUbFwUMBQUFBQUFBQUFBQUFBQUFFBUAAAAFBQUFBQUFBQUFBRcXFwoKBQUFBQUFBQUAAAAAAAAABQUGBgYIAEGDrdkACwcFBQYGCBcXAEGTrdkACwQFBQYGAEGjrdkACwQFAAYGAEGzrdkAC34FBQUFBgYIBgYGBgYGBggICAgICAYICAYGBgYGBgYXFxcEFxcXGQUGAAALCwsLCwsLCwsLAAAAAAAAFxcXFxcXExcXFxcGBgYQBgUFBQQFBQUFBQUFBQUFBQUAAAAAAAAABQUFBQUGBgUFBQUFBQUFBQYFAAAAAAAFBQUFBQUAQbuu2QALNQYGBggICAgGBggICAAAAAAICAYICAgICAgGBgYAAAAAGwAAABcXCQkJCQkJCQkJCQUFBQUFAEH7rtkAC+gFCQkJCQkJCQkJCQsAAAAbGxsbGxsbGxsbGxsbGxsbBQUFBQUFBQYGCAgGAAAXFwUFBQUFCAYIBgYGBgYGBgAGCAYICAYGBgYGBgYGCAgIBgYGBgYGBgYGBgAABhcXFxcXFxcEFxcXFxcXAAAGBgYGBgYGBgYGBgYGBgcGBQUFBQYIBgYGBgYIBggICAYICAUFBQUFBQUFABcXGxsbGxsbGxsbGwYGBgYGGxsbGxsbGxsbFxcXBQgGBgYGCAgGBggGBgYFBQUFBQUGCAYGCAgIBggGBggIAAAAAAAAAAAXFxcXBQUFBQgICAgICAgIBgYGBggIBgYAAAAXFxcXFwkJCQkJCQkJCQkAAAAFBQUFBQUFBQQEBAQEBBcXAgICAgICAgICAQIAAAAAAAEBAQEBAQEBAQEBAAABAQEXFxcXFxcXFwAAAAAAAAAABgYGFwYGBgYGBgYGBgYGBggGBgYGBgYGBQUFBQYFBQgGBgUAAAAAAAQEBAQEBAQEBAQEAgICAgICAgIEAgICAgICAgECAQIBAgICAgICAgICAQICAgICAgICAQEBAQEBAQECAgICAgIAAAEBAQEBAQAAAgICAgICAgIAAQABAAEAAQICAgICAgICAgICAgICAAACAgICAgICAgMDAwMDAwMDAgICAgIAAgIBAQEBAxoCGhoCAgIAAgIBAQEBAxoaGgICAgIAAAICAQEBAQAaGhoCAgICAgICAgEBAQEBGhoaAAACAgIAAgIBAQEBAxoaAAwMDAwMDAwMDAwMEBAQEBATExMTExMXFxwdFBwcHRQcFxcXFxcXFxcNDhAQEBAQDBcXFxcXFxcXFxwdFxcXFxYXFxcYFBUXFxcXFxcXFxcYFxYXFxcXFxcXFxcXDBAQEBAQABAQEBAQEBAQEBALBAAACwsLCwsLGBgYFBUECwsLCwsLCwsLCxgYGBQVAAQEBAQEBAQEBAQEBAQAAAAZGRkZGRkZGRkZGRkZGRkZAEHytNkACx8GBgYGBgYGBgYGBgYGBwcHBgcHBwYGBgYGBgYGBgYGAEGgtdkAC58EGxsBGxsbGwEbGwIBAQECAgEBAQIbARsbGAEBAQEBGxsbGwEbARsBGwEBAQEbAgEBAQECBQUFBQIbGwICAQEYGBgYGAECAgICGxgbGwIbCwsLCwsLCwsLCwsLCwsLCwoKCgoKCgoKCgoKCgoKCgoBAgoKCgoLGxsAAAAAGBgYGBgbGxsbGxgYGxsbGxgbGxgbGxgbGxsbGxsbGBsbGxsbGxsbGxsb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MAP3ADADTgAxA1sAOAOCAEIDHAAoHyQAUR8SAGgfCABoH26faR9vn78fz5/+H9+fUR9Xn1kfX59gH2afYR9nnzEfCAAxHzefOB8+nzkfP59QH1afKB8unykfL58wHzafywMQAAgfCAAIHw6fCR8PnyAfJp8hHyefywPnnwAfBp8BHwefuQMIALkD1p/FA+afyQP2n8oD15+oAMGfsQO2n7cDxp8FAGUABgBlABueaQAtnnUAdZ5FABqeSQAsnlUAdJ4QAGIAFABsAAoAbAA7nm4ASZ5yAF+edABvnnoAlZ5iAAeeZAAPnmgAlp5rADWeTgAIAE4ASJ5SAF6eVABunloAlJ5CAAaeRAAOnksANJ5MADqeKwByIjYAhyIaAKkiDgCzIgYAsyLrorQi7KK1Iu2iqSKuoqsir6KyIuqihyKJopEi4qKSIuOioiKsoqgiraJ7Ig4AgiIGAIIihKKDIoWihiKIonsigaJ8IuCifSLhonIidKJzInWidiJ4oncieaJ6IoCiCyIaAEUiDgBhIgYAYSJiomQicKJlInGiRSJHokgiSaJNIm2iCyIMoiMiJKIlIiaiPCJBokMiRKKUIQ4A1CEGANQhzqEDIgSiCCIJopQhrqHQIc2h0iHPoTwAbqI9AGCiPgBvopAhmqGSIZuhJwMKACgDPwAtA1QALgMBAEgAKp5oACueFQBjABoAawAOAHIABgByAFeBcwBfgXQAY4FrADeBbAA8gW4ARoFjAOeAZAARnmUAKYJnACOBaAApnksADgBSAAYAUgBWgVMAXoFUAGKBSwA2gUwAO4FOAEWBQwDHgEQAEJ5FACiCRwAigUgAKJ4JAGEACgBhAAWBZQAZgWkAL4FvAOuBdQBzgUEABIFFABiBSQAugU8A6oFVAHKBCwBkAA4AbgAGAG4AS550AHGedQB3nmQAE55lABmebAA9nk4ABgBOAEqeVABwnlUAdp5EABKeRQAYnkwAPJ4jA4EAIwMOACQDcwAlA3YAJgMDAFMAGIJUABqCcwAZgnQAG4IpAGQAMgBzABoAeQAOAKEBBgChAeOerwHwnrAB8Z55APWeegCTnqAB4p5zAGOedABtnnUA5Z52AH+edwCJnmwACgBsADeebQBDnm4AR55vAM2ecgBbnmQADZ5lALmeaAAlnmkAy55rADOeTwAaAFYADgBaAAYAWgCSnmEAoZ5iAAWeVgB+nlcAiJ5ZAPSeTwDMnlIAWp5TAGKeVABsnlUA5J5JAAoASQDKnksAMp5MADaeTQBCnk4ARp5BAKCeQgAEnkQADJ5FALieSAAkngEAVQBynnUAc54BAEEAAJ5hAAGeEwMMABQDLQAbAwMATwCggVUAr4FvAKGBdQCwgQ0AtQMQAL8DCAC/A0CfwQPkn8UDUJ/JA2CftQMQn7cDIJ+5AzCfmQMIAJkDOJ+fA0ifqQNon7EDAJ+RAwiflQMYn5cDKJ8PALEDEgC/AwgAvwNBn8ED5Z/FA1GfyQNhn7EDAZ+1AxGftwMhn7kDMZ+fAwgAnwNJn6ED7J+lA1mfqQNpn5EDCZ+VAxmflwMpn5kDOZ8IA5IBCwOxAAsDJAAMAzEADwOIABEDCwBhAA4AbwAGAG8AD4JyABOCdQAXgmEAA4JlAAeCaQALgk8ABgBPAA6CUgASglUAFoJBAAKCRQAGgkkACoIFAHUABgB1AHGBIwTyhEME84RPAFCBVQBwgW8AUYEkAGQALABvABYAegAKAHoAfoHcANmB/ADagbcB7oGSAu+BbwDSgXIAWYFzAGGBdABlgXUA1IFpAAoAaQDQgWoA8IFrAOmBbAA+gW4ASIFkAA+BZQAbgWcA54FoAB+CTgAUAFQACgBUAGSBVQDTgVoAfYFhAM6BYwANgU4AR4FPANGBUgBYgVMAYIFHAAoARwDmgUgAHoJJAM+BSwDogUwAPYFBAM2BQwAMgUQADoFFABqBDQBlABAAcgAIAHIAEYJ1ABWCdAR2hHUEd4RlAAWCaQAJgm8ADYJPAAgATwAMglIAEIJVABSCYQABgkEAAIJFAASCSQAIgggDEgAJA5wACgMFAHUABgB1AG+BdwCYnnkAmZ5BAMWAVQBugWEA5YAAADUA0gNEADUEIgBLBBAA2AQIANgE2oTZBNuE6ATqhOkE64RLBPmETQTthFYEV4Q4BAgAOATlhD4E54RDBPGERwT1hDUEUYQ2BN2ENwTfhBgEEAAnBAgAJwT0hCsE+IQtBOyEMATThBgE5IQeBOaEIwTwhBUEBgAVBAGEFgTchBcE3oTSA9SDBgQHhBAE0oRvACIA9QAQAJkDCACZA6qDpQOrg7kDyoPFA8uD9QBPnmoBep5rAXuedwAIAHcAhZ54AI2eeQD/gNUATp5vAPaAdACXnnUA/IBXABAAYQAIAGEA5IBlAOuAaAAnnmkA74BXAISeWACMnlkAeIFJAAYASQDPgE8A1oBVANyAQQDEgEUAy4BIACaeFwDCAB4AAgEOAKEBBgChAd+erwHsnrAB7Z4CAbKeAwGznqAB3p7iAAYA4gCpnuoAw570ANWewgConsoAwp7UANSeYQAOAG8ABgBvAM+edQDnnnkA955hAKOeZQC7nmkAyZ5PAAYATwDOnlUA5p5ZAPaeQQCinkUAup5JAMieAwONAQMDhgAEA8sABgM4AQcDLgBkAEQAdwAkAGABFABiHgwAYh5onmMeaZ4B2AEA0t0BwMkF2t0BwOQFYAFmnmEBZ55/AZueegAGAHoAfIFaAWSeWwFlnncAh554AIueeQCPnm4ADgByAAYAcgBZnnMAYZ50AGuebgBFnm8AL4JwAFeeZwAGAGcAIYFoACOebQBBnmQAC55lABeBZgAfnk8AHgBYAA4AYQAGAGEAJ4JiAAOeYwALgVgAip5ZAI6eWgB7gVMABgBTAGCeVABqnlcAhp5PAC6CUABWnlIAWJ5GAA4ASQAGAEkAMIFNAECeTgBEnkYAHp5HACCBSAAinkEAJoJCAAKeQwAKgUQACp5FABaBGwB2ACIA9AAQAKABCACgAeCeoQHhnq8B7p6wAe+e9ADXngIBtJ4DAbWeygAIAMoAxJ7UANae4gCrnuoAxZ52AH2eeQD5nsIAqp5ZABAAaQAIAGkAKYFuAPGAbwD1gHUAaYFZAPieYQDjgGUAvZ5OAAgATgDRgE8A1YBVAGiBVgB8nkEAw4BFALyeSQAogSsA9gA2ALEDGgA4BA4ANx4GADceOZ5aHlyeWx5dnjgE44RDBO+ENh44nrEDsZ+5A9GfxQPhnxgE4oQjBO6EJwIOAJEDBgCRA7mfmQPZn6UD6Z8nAuGBLgIwgi8CMYL2ACuC/ADWgeoB7IHrAe2BJgLggW8AGgDVAA4A5AAGAOQA34HmAOOB9QAtgtUALILWACqC3ADVgW8ATYF1AGuBeQAzgsQA3oHGAOKBVQAOAGUABgBlABOBZwAhnmkAK4FVAGqBWQAygmEAAYFBAACBRQASgUcAIJ5JACqBTwBMgR8ApQMmACMEEgA4BAgAOAQ5hEMEXoSgHraeoR63niMEDoQwBNGENQTXhDYEwoQQBAgAEATQhBUE1oQWBMGEGAQZhKUD6J+xA7CfuQPQn8UD4J9nABIAKAIIACgCHJ4pAh2ekQO4n5kD2J9nAB+BaQAtgW8AT4F1AG2BTwAIAE8AToFVAGyBYQADgWUAFYFBAAKBRQAUgUcAHoFJACyBAANSAAEDIAECAx8AZwAmAHkAEgC4HggAuB7Gnrkex57MHtiezR7ZnnkAd4F6AJGeoB6snqEerZ5vAAgAbwD0gHMAXYF1APuAdwB1gWcAHYFoACWBaQDugGoANYFTABIAWgAIAFoAkJ5hAOKAYwAJgWUA6oBTAFyBVQDbgFcAdIFZAHaBSAAIAEgAJIFJAM6ASgA0gU8A1IBBAMKAQwAIgUUAyoBHAByBAABTALEDZgAgHzIASB8aAGAfDgBpHwYAaR9rn78fzZ/+H92fYB9in2EfY59oH2qfSB9Kn0kfS59QH1KfUR9Tn1kfW58xHwoAMR8znzgfOp85HzufQB9Cn0EfQ58gHyKfIR8jnygfKp8pHyufMB8ynxgEGgAIHw4AER8GABEfE58YHxqfGR8bnwgfCp8JHwufEB8SnxgEDYQ1BFCEOARdhAAfAp8BHwOfxQMKAMUDep/JA3yfygPSn8sD4p8VBACEsQNwn7UDcp+3A3SfuQN2n78DeJ/iADIAoAEaAJUDDgCfAwYAnwP4n6UD6p+pA/qflQPIn5cDyp+ZA9qfoAHcnqEB3Z6vAeqesAHrnpEDup8DAQoAAwGxnhIBFJ4TARWeTAFQnk0BUZ7iAKee6gDBnvQA0578ANyBAgGwnmkAGgB5AA4AygAGAMoAwJ7UANKe3ADbgXkA856oAO2fwgCmnmkA7IBuAPmBbwDygHUA+YB3AIGeVQAKAFUA2YBXAICeWQDynmEA4IBlAOiAQQDAgEUAyIBJAMyATgD4gU8A0oAAAHQAEwGUADoESgA4HyQAUR8SAGgfCABoH2yfaR9tn78fzp/+H96fUR9Vn1kfXZ9gH2SfYR9ln0EfCABBH0WfSB9Mn0kfTZ9QH1SfOB88nzkfPZ9AH0SfGB8SACgfCAAoHyyfKR8tnzAfNJ8xHzWfGB8cnxkfHZ8gHySfIR8lnwgfCAAIHwyfCR8NnxAfFJ8RHxWfOgRchAAfBJ8BHwWfpQMkAMUDEgDSAwgA0gPTgxMEA4QaBAyEMwRThMUDzYPJA86DygOQg8sDsIO1AwgAtQOtg7cDroO5A6+DvwPMg6UDjoOpA4+DsQOsg68BEACVAwgAlQOIg5cDiYOZA4qDnwOMg68B6J6wAemekQOGg2gBCABoAXieaQF5nqAB2p6hAdueEwEXnkwBUp5NAVOecwBIANgAJADvABIA/AAIAPwA2IECAa6eAwGvnhIBFp7vAC+e9ADRnvUATZ74AP+B5QAIAOUA+4HmAP2B5wAJnuoAv57YAP6B3ADXgeIApZ7FABAAygAIAMoAvp7PAC6e1ADQntUATJ7FAPqBxgD8gccACJ55AAgAeQD9gHoAeoGoAIWDwgCknnMAW4F1APqAdwCDnlcAJABpABIAbgAIAG4ARIFvAPOAcABVnnIAVYFpAO2AawAxnmwAOoFtAD+eYQAIAGEA4YBjAAeBZQDpgGcA9YFXAIKeWQDdgFoAeYFNABAAUAAIAFAAVJ5SAFSBUwBagVUA2oBNAD6eTgBDgU8A04BHAAgARwD0gUkAzYBLADCeTAA5gUEAwYBDAAaBRQDJgDRvFgBeCgAAAAAAABQwV2UVMBQw3VIVMBQw13YVMBQwU2IVMBQwuXAVMBQwiVsVMBQwjE4VMBQwCU4VMBQwLGcVMLMwszB7MEswRABKAE0AUgBNAEQATQBDAFcAQwBQAFAAVgBTAFMAUwBEAE0AVgBIAFYAVwBaAEMARAAUMFMAFTAoAFoAKQAoAFkAKQAoAFgAKQAoAFcAKQAoAFYAKQAoAFUAKQAoAFQAKQAoAFMAKQAoAFIAKQAoAFEAKQAoAFAAKQAoAE8AKQAoAE4AKQAoAE0AKQAoAEwAKQAoAEsAKQAoAEoAKQAoAEkAKQAoAEgAKQAoAEcAKQAoAEYAKQAoAEUAKQAoAEQAKQAoAEMAKQAoAEIAKQAoAEEAKQA5ACwAOAAsADcALAA2ACwANQAsADQALAAzACwAMgAsADEALAAwACwAMAAuAEQGJwZEBicGVQZEBicGVAZEBicGUwYuAC4ALgAuAC4AMQbMBicGRAYsBkQGIAAsBkQGJwZEBkcGNQZEBkkGSAYzBkQGRQY5BkQGSgZHBjEGMwZIBkQGNQZEBjkGRQZFBi0GRQYvBicGQwYoBjEGJwZEBkQGRwZCBkQG0gY1BkQG0gZGBiwGSgYzBi4GSgY1BkUGRQY5BiwGRQZDBkUGRQYoBi0GSgZBBkUGSgZFBiwGSgYtBiwGSgYsBi0GSgZGBiwGLQZEBiwGRQZFBi4GSgZDBkUGSgY5BkUGSgZEBi0GRQZCBkUGLQZGBi0GSgZCBkUGSgZFBkUGSgZKBkUGSgZKBiwGSgZKBi0GSgZEBkUGSgZEBiwGSgY2Bi0GSgY0Bi0GSgY1Bi0GSgYzBi4GSQYsBkUGSQYsBi0GSQYsBkUGSgYqBkUGSQYqBkUGSgYqBi4GSQYqBi4GSgYqBiwGSQYqBiwGSgYoBi4GSgZGBkUGSQZGBkUGSgZGBiwGSQZGBiwGRQZGBi0GSQZGBi0GRQZHBkUGRQZHBkUGLAZFBiwGLgZFBi4GRQZFBi4GLAZFBiwGLQZFBi0GSgZFBi0GLAZEBkUGLQZEBi4GRQZEBiwGLAZEBi0GSQZEBi0GSgZCBkUGRQZBBi4GRQY6BkUGSQY6BkUGSgY6BkUGRQY5BkUGSQY3BkUGSgY3BkUGRQY3BkUGLQY2Bi4GRQY2Bi0GSQY0BkUGRQY0BkUGLgY0BiwGSgY0Bi0GRQY1Bi0GLQYzBkUGRQYzBkUGLAYzBkUGLQYzBiwGSQYzBiwGLQYzBi0GLAYtBkUGSQYtBkUGSgYsBkUGLQYqBkUGLgYqBkUGLQYqBkUGLAYqBi4GRQYqBi0GRQYqBi0GLAYqBiwGRQY4BkUGNAYuBjQGRwYzBkcGNgYxBjUGMQYzBjEGNAYxBjYGSgY2BkkGNQZKBjUGSQY0BkoGNAZJBjMGSgYzBkkGOgZKBjoGSQY5BkoGOQZJBjcGSgY3BkkGQAZQBlEGQAZPBlEGQAZOBlEGRgZHBkMGRAYrBkcGKwZFBioGRwYoBkcGKAZFBkoGVAZHBkoGVAZFBkoGLgZHBiwGRgYuBkMGLgZDBi0GQwYsBkIGLQZBBi0GQQYsBjoGLAY3Bi0GNgZFBjYGLAY1Bi4GKAYsBkoGVAYuBkoGVAYtBkoGVAYsBkoGSQZKBjIGSgYxBkYGSgZGBkkGRgZGBkYGMgZGBjEGRQYnBkMGSgZDBkkGQwYnBkIGSgZCBkkGQQZKBkEGSQYrBkoGKwZJBisGRgYrBjIGKwYxBioGSgYqBkkGKgZGBioGMgYqBjEGKAZKBigGSQYoBkYGKAYyBkoGVAZKBkoGVAZJBkoGVAZGBkoGVAYyBkoGVAYxBiAAUQZwBiAAUAZRBiAATwZRBiAATgZRBiAATQZRBiAATAZRBkcGSQYuBi0GKwYsBkoGVAbQBkoGVAbIBkoGVAbGBkoGVAbHBkoGVAZIBkoGVAbVBkoGVAYnBscGdAbQBdwFdAVtBX4FdgV0BWsFdAVlBXQFdgVzAHQAZgBmAGwAZgBmAGkAZwBhAGwAMwAxAOVlMwAwAOVlMgA5AOVlMgA4AOVlMgA3AOVlMgA2AOVlMgA1AOVlMgA0AOVlMgAzAOVlMgAyAOVlMgAxAOVlMgAwAOVlMQA5AOVlMQA4AOVlMQA3AOVlMQA2AOVlMQA1AOVlMQA0AOVlMQAzAOVlMQAyAOVlMQAxAOVlMQAwAOVlQQAVIm0AVgAVIm0AVwBiAFMAdgBzAHIAUABSAFAAUABNAHAALgBtAC4AUABIAG0AbwBsAG0AaQBsAG0AYgBsAHgAbABvAGcAbABuAGsAdABLAE0ASwBLAGkAbgBIAFAAaABhAEcAeQBkAEIAQwBvAC4AQwAVImsAZwBjAGQAYwBjAEIAcQBhAC4AbQAuAE0AqQNrAKkDTQBXAGsAVwC8A1cAbgBXAHAAVwBrAFYAvANWAG4AVgBwAFYAbQBzALwDcwBuAHMAcABzAHIAYQBkABUicwAyAEcAUABhAE0AUABhAGsAUABhAG0AFSJzADIAawBtADMAYwBtADMAbQBtADMAawBtADIAYwBtADIAbQBtADIAvANtAG4AbQBmAG0AawBsAGQAbABtAGwAvANsAFQASAB6AEcASAB6AE0ASAB6AGsASAB6AG0AZwC8A2cAvANGAG4ARgBwAEYAawBjAGEAbABHAEIATQBCAEsAQgBrAEEAbQBBALwDQQBuAEEAcABBACpoD18aTz55Dma7bCdZY2stZoxUc14QYkkAVQBkAG0AMwBkAG0AMgBwAGMAbwBWAGIAYQByAEEAVQBkAGEAaABQAGEAMgA0ALlwMgAzALlwMgAyALlwMgAxALlwMgAwALlwMQA5ALlwMQA4ALlwMQA3ALlwMQA2ALlwMQA1ALlwMQA0ALlwMQAzALlwMQAyALlwMQAxALlwMQAwALlw7zDDMMgw7DDzMMgwsTCZMPMw7DDgMOsw/DDVMJkw6zDrMNIwmjD8MOow6TDqMMMwyDDrMOYwojDzMOQw/DDrMOQw/DDIMJkw4TD8MMgw6zDhMKswmTDIMPMw3zDqMM8wmTD8MOsw3zCvMO0w8zDeMPMwtzDnMPMw3jDrMK8w3jDDMM8w3jCkMOsw3jCkMK8w7TDbMPww8zDbMPww6zDbMJow8zDIMJkw2zDzMNswmTDrMMgw2zCaMKQw8zDIMNgwmTD8ML8w2DCaMPwwtzCZMNgwmjDzMLkw2DDrMMQw2DCaMMsw0jDYMJowvTDYMK8wvzD8MOsw1TDpMPMw1TCZMMMwtzCnMOsw1TCjMPwwyDDVMKEw6TDDMMgwmTDSMJkw6zDSMJowszDSMJowrzDrMNIwmjCiMLkwyDDrMM8wmTD8MOww6zDPMJow/DDEMM8wmjD8MLsw8zDIMM8wpDDEMM4wwzDIMMowzjDIMJkw6zDGMJkwtzC/MJkw/DC5MLsw8zDBMLcw6jDzMK8wmTC1MPMwwTD8MOAwtTCkMK8w6zCzMPww2zCaMLMw6zDKMLEw/DC5MK8w7TD8MM0wrzDrMLswmTCkMO0wrzCZMOkw4DDIMPMwrTDtMO8wwzDIMK0w7TDhMPwwyDDrMK0w7TCvMJkw6TDgMK0wmTDrML8wmTD8MK0w5TDqMPwwrTCZMMsw/DCtMJkwqzCZMKswmTDzMN4wqzCZMO0w8zCrMO0w6jD8MKsw6TDDMMgwqzCkMOowqjD8MOAwqjDzMLkwqDD8MKsw/DCoMLkwrzD8MMgwmTCmMKkw8zCkMPMwwTCkMMsw8zCvMJkwojD8MOswojDzMNgwmjCiMKIw6zDVMKEwojDPMJow/DDIMOROjFRMAFQARABlAFYAZQByAGcASABnADEAMgAIZzEAMQAIZzEAMAAIZzkACGc4AAhnNwAIZzYACGc1AAhnNAAIZzMACGc1ADAANAA5ADQAOAA0ADcANAA2ADQANQA0ADQANAAzADQAMgA0ADEANAAwADMAOQAzADgAMwA3ADMANgALEW4RDBFuEQsRdBEOEWERtxEAEWkREhFhERERYREQEWERDxFhEQwRYRELEWERCRFhEQcRYREGEWERBRFhEQMRYRECEWERABFhETMANQAzADMAMwAyAFAAVABFACgA84EpACgA6oEpACgAEU8pACgAbXkpACgAVFMpACgAx4wpACgAAU8pACgA43YpACgAZlspACgAfFQpACgA404pACgAtFIpACgAXXkpACgAoYwpACgAeXIpACgADVQpACgAPnkpACgACWcpACgAKmgpACgA5WUpACgAH1cpACgA0ZEpACgAKGcpACgANGwpACgAa3ApACgACGcpACgAQVMpACgAXU4pACgAa1EpACgAA04pACgAbVEpACgAlE4pACgA21YpACgACU4pACgAjE4pACgAAE4pACgACxFpERIRbhEpACgACxFpEQwRZRGrESkAKAAMEW4RKQAoABIRYREpACgAERFhESkAKAAQEWERKQAoAA8RYREpACgADhFhESkAKAAMEWERKQAoAAsRYREpACgACRFhESkAKAAHEWERKQAoAAYRYREpACgABRFhESkAKAADEWERKQAoAAIRYREpACgAABFhESkAKAASESkAKAARESkAKAAQESkAKAAPESkAKAAOESkAKAAMESkAKAALESkAKAAJESkAKAAHESkAKAAGESkAKAAFESkAKAADESkAKAACESkAKAAAESkAszDIMIgwijA9AD0APQA6ADoAPQArIisiKyIrIigAegApACgAeQApACgAeAApACgAdwApACgAdgApACgAdQApACgAdAApACgAcwApACgAcgApACgAcQApACgAcAApACgAbwApACgAbgApACgAbQApACgAbAApACgAawApACgAagApACgAaQApACgAaAApACgAZwApACgAZgApACgAZQApACgAZAApACgAYwApACgAYgApACgAYQApADIAMAAuADEAOQAuADEAOAAuADEANwAuADEANgAuADEANQAuADEANAAuADEAMwAuADEAMgAuADEAMQAuADEAMAAuACgAMgAwACkAKAAxADkAKQAoADEAOAApACgAMQA3ACkAKAAxADYAKQAoADEANQApACgAMQA0ACkAKAAxADMAKQAoADEAMgApACgAMQAxACkAKAAxADAAKQAoADkAKQAoADgAKQAoADcAKQAoADYAKQAoADUAKQAoADQAKQAoADMAKQAoADIAKQAoADEAKQAuIi4iLiIwAEQgMwB4AGkAaQBpAHgAdgBpAGkAaQBpAHYAWABJAEkASQBYAFYASQBJAEkASQBWADEARCA3AEQgOAA1AEQgOAAzAEQgOAAxAEQgOAA1AEQgNgAxAEQgNgA0AEQgNQAzAEQgNQAyAEQgNQAxAEQgNQAyAEQgMwAxAEQgMwAxAEQgMQAwADEARCA5AEYAQQBYAFQATQBUAEUATABTAE0ATgBvALAARgBjAC8AdQBjAC8AbwCwAEMAYQAvAHMAYQAvAGMAUgBzADIgMiAyIDIgIQA/AD8AIQAhACEANSA1IDUgIAAIAwEDIAAIAwADIAAUA0IDIAAUAwEDIAAUAwADIAATA0IDIAATAwEDIAATAwADIAAIA0IDYQC+ArMPcQ+AD7IPcQ+AD6sOoQ6rDpkOzQ6yDk0OMg5KBnQGSAZ0BicGdAZlBYIFZAB6AEQAegBEAFoAbgBqAE4AagBOAEoAbABqAEwAagBMAEoAZAB6AAwDRAB6AAwDRABaAAwDvAJuAGwAtwBMALcAaQBqAEkASgAzAEQgNAAxAEQgMgAxAEQgNABkAGoAbQByAG0AZABtAGMAdwBjAHAAcAB2AHMAcwBzAGQAbQB2AGgAdgB3AHoAFDBzABUwYQAVIm0AdgAVIm0AdwBiAHMAdgBwAHIAcABwAG0AcABoAGsAawBoAHAAZwB5AGQAYgBjABUiawBnAGIAcQBtAMkDawDJA2sAdwC8A3cAbgB3AHAAdwBrAHYAvAN2AG4AdgBnAHAAYQBtAHAAYQBrAHAAYQB0AGgAegBnAGgAegBtAGgAegBrAGgAegC8A2YAbgBmAHAAZgBrAGIAawBhAG0AYQC8A2EAbgBhAGkAdQBvAHYAYQB1AGgAcABhAGwAdABkAGUAdgBoAGcAcAB0AGUAZgBhAHgAdABtAHQAZQBsAHMAbQBuAG8AsABmALAAYwByAHMAyQO5A8kDQgO5A8kDAQO5A8kDAAO5A7cDuQO3A0IDuQO3AwEDuQO3AwADuQOxA7kDsQNCA7kDsQMBA7kDsQMAA7kDyQMUA0IDuQPJAxMDQgO5A8kDFAMBA7kDyQMTAwEDuQPJAxQDAAO5A8kDEwMAA7kDyQMUA7kDyQMTA7kDtwMUA0IDuQO3AxMDQgO5A7cDFAMBA7kDtwMTAwEDuQO3AxQDAAO5A7cDEwMAA7kDtwMUA7kDtwMTA7kDsQMUA0IDuQOxAxMDQgO5A7EDFAMBA7kDsQMTAwEDuQOxAxQDAAO5A7EDEwMAA7kDsQMUA7kDsQMTA7kDIAC5Ax7fAQrfAQjfAQbfAQXfAQTfAUPpAULpAUHpAUDpAT/pAT7pAT3pATzpATvpATrpATnpATjpATfpATbpATXpATTpATPpATLpATHpATDpAS/pAS7pAS3pASzpASvpASrpASnpASjpASfpASbpASXpASTpASPpASLpAX9uAX5uAX1uAXxuAXtuAXpuAXluAXhuAXdu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YYCSAWKAg0FigIMBYoCRQWKAkQFigJhBYoCYAREAZ0IRAGcCZICDQWSAgwFkgJFBZICRAWSAmEFkgJgBZICTQWSAkwFkgJZBZICWAREAYUIRAGECEQBbQhEAWwJlgJZBZYCWAWUAmEFlAJgBEQBVQhEAVQJmgINBZoCDAWcAgkFnAIIBaICDQWiAgwFogJFBaICRAWgAhEFoAIQBaICTQWiAkwFoAJdBaACXAWkAmEFpAJgBEQBPQhEATwJrgIBBa4CAAWuAkUFrgJEBa4CYQWuAmAFsgJFBbICRAREASUIRAEkCbICYQWyAmAFsgJZBbICWAW2AgEFtgIABbYCDQW2AgwFtgJFBbYCRAW6Ag0FugIMBboCRQW6AkQFugJhBboCYAW6AlkFugJYBEQBDQhEAQwIRAD1CEQA9AhEAN0IRADcCEQAxQhEAMQJwgIBBcICAAXCAg0FwgIMBcoCDQXKAgwFygJFBcoCRAREAK0IRACsCcoCYQXKAmAFzgINBc4CDAXOAkUFzgJEBEQAlQhEAJQIRAB9CEQAfAhEAGUIRABkCdICDQXSAgwF0gJFBdICRAXSAmEF0gJgBdICWQXSAlgF1AJJBdQCSAXUAmEF1AJgBdYCWQXWAlgERABNCEQATAhEADUIRAA0CdoCBQXaAgQF2gJFBdoCRAXcAgEF3AIABd4CAQXeAgAF3AIRBdwCEAXeAg0F3gIMBd4CRQXeAkQF4gINBeICDAXgAhEF4AIQBeYCDQXmAgwF6AIFBegCBAXqAkUF6gJEBeoCYQXqAmAFogJgBdACEAXcAhQF5AIUBAAD3S3OAg0EAAAAAAAAAAN8AAEAAAAAAYYCRQWGAkQFhgIRBYYCEAREAB0IRAAcCEQABQhEAAQIRAPtBEQD7AREA9UERAPUBEQDvQREA7wERAOlBEQDpAREA40ERAOMBEQDdQREA3QERANdBEQDXAREA0UERANEBZYCRQWWAkQFlgIRBZYCEAWWAgUFlgIEBEQDLQREAywERAMVBEQDFAREAv0ERAL8BEQC5QREAuQERALNBEQCzAWmAhEFpgIQBaYCRQWmAkQFvgJFBb4CRAW+AhEFvgIQBEQCtQREArQERAKdBEQCnAREAoUERAKEBEQCbQREAmwERAJVBEQCVAREAj0ERAI8BEQCJQREAiQERAINBEQCDAREAfUERAH0BEQB3QREAdwF1gJFBdYCRAXWAhEF1gIQBEQBxQREAcQERAGtBEQBrAREAZUERAGUBEQBfQREAXwERAFlBEQBZAXkAgEF5AIABeYCRQXmAkQF5gIRBeYCEAXmAgUF5gIEB+x4AQAAAAAD9HgBAAAAAAP8eAEAAAAAAsYOJAbEDigERAOAAEQDcABEA2AARANQAEQDQABEAzACxg4lBsQOKQREA4EARANxAEQDYQBEA1EARANBAEQDMQLWDiQG1A4oBEQBWAREAUwERAFABEQBNAf3/AED9/wBAtYOJQbUDikERAFZBEQBTQREAUEERAE1B/f8AQP3/AEC3g4kBtwOKAREApAARAKAAEQCcABEAmAARAJQAEQCQALeDiUG3A4pBEQCkQBEAoEARAJxAEQCYQBEAlEARAJBAuYOJAbkDigERAD4BEQA7AREAOAERADUBEQAyAREALwG5g4lBuQOKQREAPkERADtBEQA4QREANUERADJBEQAvQb+DiQG/A4oBEQAaAREAFwERABQBEQARAf3/AED9/wBAv4OJQb8DikERABpBEQAXQREAFEERABFB/f8AQP3/AEDFg4kBxQOKAREAAgERAP8AEQD8ABEA+QARAPYAEQDzAP3/AEDFA4pB/f8AQBEA/0D9/wBAEQD5QP3/AEARAPNAyYOJAckDigERAGgAEQBkABEAYAARAFwAEQBYABEAVADJg4lByQOKQREAaEARAGRAEQBgQBEAXEARAFhAEQBUQLEDgAGxg4BBtQOAAbWDgEG3A4ABt4OAQbkDgAG5g4BBvwOAAb+DgEHFA4ABxYOAQckDgAHJg4BB/f8AQP3/AEABAEpNAQBHTQIAQ00CAD9NAgA7TQIAN00CADNNAgAvTQEASk0BAEdNAgBDTQIAP00CADtNAgA3TQIAM00CAC9NAQAsTQEAKU0CACVNAgAhTQIAHU0CABlNAgAVTQIAEU0BACxNAQApTQIAJU0CACFNAgAdTQIAGU0CABVNAgARTQEADk0BAAtNAgAHTQIAA00CAP9MAgD7TAIA90wCAPNMAQAOTQEAC00CAAdNAgADTQIA/0wCAPtMAgD3TAIA80yxA4MBsQOCAQEA8EwAAOhMAQDtTP3/AECxA6EBAQDqTLEDg0GxA4JBsQOAQbGDgEEAAOhMIICJQbkDAEAggIlBIAChQREA9EsBAOVMAADdTAEA4kz9/wBAtwOhAQEA30y1A4BBtYOAQbcDgEG3g4BBAADdTBEA8UsRAO5LEQDrS7kDgwG5A4IBEQAhABEAHkD9/wBA/f8AQLkDoQERABsAuQODQbkDgkG5A4BBuYOAQf3/AEARAOhLEQDlSxEA4kvFA4MBxQOCAREAGAARABVAwYOJAcEDigHFA6EBEQASAMUDg0HFA4JBxQOAQcWDgEHBA4pBEQDfSxEA3EtgAABA/f8AQP3/AEABANpMAADSTAEA10z9/wBAyQOhAQEA1Ey/A4BBv4OAQckDgEHJg4BBAADSTCCAgEEgAIpB/f8AQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABAIAAAQCAAAEAgAABA/////wAAAAAAAAAA/f8AQP3/AEAAAAAAECAAQABB3IncAAsEIICZQQBBgIrcAAsw/f8AQP3/AED9/wBAAAAAAP3/AED9/wBA/f8AQP3/AED9/wBA/f8AQP3/AEAgAABAAEG+itwACxLPSwEAz0sAAAAAAADZSwEA2UsAQeKK3AALCtZLAAAAACCAgkEAQYqL3AALCtRLAADVSwAA00sAQbCL3AALBAIAz0sAQdCL3AALhAIgAABA///////////////////////////9/wBA/f8AQP3/AED9/wBA/f8AQP///////////////////////////////zAAAEBpAABA/f8AQP3/AEA0AABANQAAQDYAAEA3AABAOAAAQDkAAEArAABAEiIAQD0AAEAoAABAKQAAQG4AAEAwAABAMQAAQDIAAEAzAABANAAAQDUAAEA2AABANwAAQDgAAEA5AABAKwAAQBIiAEA9AABAKAAAQCkAAED9/wBAYQAAQGUAAEBvAABAeAAAQFkCAEBoAABAawAAQGwAAEBtAABAbgAAQHAAAEBzAABAdAAAQP3/AED9/wBA/f8AQABB9o3cAAsC0EwAQZSO3AALNObYAIDm2ACAAdgAgAHYAIDm2ACA5tgAgObYAIDm2ACAAdgAgAHYAIAB2ACA5tgAgObYAIAAQdSO3AALBObYAIAAQeSO3AAL5AEB2ACAAdgAgObYAIDc2ACA5tgAgAHYAIAB2ACA3NgAgNzYAIDc2ACA3NgAgObYAID9/wBA/f8AQP3/AED9/wBA/f8AQP3/AED9/wBA/f8AQP3/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SAEAwkgBAL9IAAA1SAAAvUgBALpIAQC3SAQAsUgCAK1IAwCoSAQAokgCAJ5IAQCbSAEAmEgEAJJIAgCOSAQAiEgBAIVIAwCASAEAfUgCAHlIAQB2SAIAckgDAG1IAgBpSAMAZEgCAGBIAABeSAMAWUgBAFZIAQBTSAIAT0gBAExIAQBJSAEARkgDAEFIAgA9SAAAN0gEADdIAQAySAMAMkgCAC5IAgAqSAEAJ0gBACRIAgAgSAAAHkgCABpIAwAVSAAAE0gEAA1IAQAKSAAA6kcAAOdHAADkRwAA4UcAAN5HAAD5RwAA9kcAAPNHAADwRwAA7UcBAAdIAQAESAEAAUgBAP5HAQD7RwEA+EcBAPVHAQDyRwEA70cBAOxHAQDpRwEA5kcBAONHAQDgRwEA3UcBALNMAADYRwAAsUwBANNHAACvTAAAz0cAAMlHAQDMRwEAyUcAAK1MAADFRwAAw0cAAMFHAAC/RwIAu0cAAIlMAACrTAAAqUwAAKdMAAClTAAAo0wAABZHAABzTAEAqEcCAKdHAAChTAAAn0wAAJ1MAACfRwAAnUcAADRHAACSTAEAmkwBAJdMAQCUTAEAkUwAAI9HAACNRwAAi0cAAIlHAACHRwAAhUcAAINHAAB3RwAAdEcAAHFHAQCARwEAfUcAAHtHAQB6RwEAd0cBAHRHAAByRwEAcUcBAG1HAgBtRwAAiUwBAI5MAQCLTAEAiEwBAF5HAwBeRwQAXkcAAFxHAABaRwAAWEcAAFZHAABITAAAhkwAAIRMAABOTAAAgkwAAE5MAACATAAAfkwAAHxMAABcTAAAekwAAFxMAAB4TAAAdkz9/wBAAAB0TAAAOEcAADZHAgBwTP3/AEAAAG5MAABsTAAAKUcAAGpMAAAlRwAAaEwAAHFHAAAfRwAAEkcAAB1HAQAaRwAAGEcAABZHAQATRwEAEEcAAGZM/f8AQAEAY0wAAGFMAAADRwAAX0wAAF1MAQBaTAEAV0wAALhGAADTRgAA0EYAAM1GAADKRgAAx0YAAMRGAADBRgAAvkYBAPZGAQDzRgEA8EYBAO1GAQDqRgEA50YBAORGAQDhRgEA3kYBANtGAQDYRgEA1UYBANJGAQDPRgEAzEYBAMlGAQDGRgEAw0YBAMBGAQC9RgEAukYBALdGAQC0RkGmAEAAAAAAQ6YAQAAAAABFpgBAAAAA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AQBKRQEAR0UBAEdFAQBERQEAlkQBAEFFAQA+RQEAM0UBADtFAQA4Rf3/AED9/wBAAQA1RQEAMkUBAC9FAQAsRQEAKUUBACZFAQAmRQEAI0UBACBFAQAdRQEA4EQBAOBEAQAaRQEAF0UBABRFAQARRQEADkUBAAtFAQAIRQEABUUBAAJFAQD/RAEA/EQBAPlEAQD2RAEA80QBAPBEAQDtRAEA6kQBAOdEAQDkRAEA4UQBAN5EAQDbRAEA2EQBANVEAQDSRAEAz0QBAMZEAQDMRAEAyUQBALREAQDJRAEAxkQBAMNEAQDARAEAvUQBALpEAQC3RAEAtEQBALFEAQCuRAEAq0QBAKhE/f8AQP3/AED9/wBA/f8AQP3/AED9/wBA/f8AQAAAAAABAKVEAQCiRAIAnkQCAJpEAgCWRAIAkkQCAI5EAgCKRAIAhkQBAINEAQAAQAYAe0QCAHdEAEHE/twAC5wP/////////////////////////////////////////////////////////////////////////////////////ywAAEABMABA/f8AQDoAAEA7AABAIQAAQD8AAEAWMABAFzAAQP3/AED9/wBA/f8AQP3/AED9/wBA/f8AQP3/AEDm2ACA5tgAgObYAIDm2ACA5tgAgObYAIDm2ACA3NgAgNzYAIDc2ACA3NgAgNzYAIDc2ACA3NgAgObYAIDm2ACA/f8AQBQgAEATIABAXwAAQF8AAEAoAABAKQAAQHsAAEB9AABAFDAAQBUwAEAQMABAETAAQAowAEALMABACDAAQAkwAEAMMABADTAAQA4wAEAPMABAAAAAAAAAAABbAABAXQAAQCCAgkEggIJBIICCQSCAgkFfAABAXwAAQF8AAEAsAABAATAAQP3/AED9/wBAOwAAQDoAAEA/AABAIQAAQBQgAEAoAABAKQAAQHsAAEB9AABAFDAAQBUwAEAjAABAJgAAQCoAAEArAABALQAAQDwAAEA+AABAPQAAQP3/AEBcAABAJAAAQCUAAEBAAABA/f8AQP3/AED9/wBA/f8AQCCAJUNAhiVDIAAmQwAAAAAggCZD/f8AQCAAJ0NABidDIIAnQ0CGJ0MgAChDQAYoQyCAKENAhihDIAApQ0AGKUMhBgBAJ4YpQyeGKUMnBipDJwYqQ0gGKkNIBipDJ4YqQyeGKkNKBipDSgYqQ0oGKkNKBipDJwYAQCcGAEAoBgBAKAYAQCgGAEApBgBAKQYAQCoGAEAqBgBAKgYAQCoGAEArBgBAKwYAQCsGAEArBgBALAYAQCwGAEAsBgBALQYAQC0GAEAtBgBALQYAQC4GAEAuBgBALgYAQC4GAEAvBgBALwYAQDAGAEAwBgBAMQYAQDEGAEAyBgBAMwYAQDMGAEAzBgBAMwYAQDQGAEA0BgBANAYAQDQGAEA1BgBANQYAQDUGAEA1BgBANgYAQDYGAEA2BgBANwYAQDcGAEA3BgBANwYAQDgGAEA4BgBAOAYAQDgGAEA5BgBAOQYAQDkGAEA5BgBAOgYAQDoGAEA6BgBAQQYAQEEGAEBBBgBAQQYAQEIGAEBCBgBAQgYAQEIGAEBDBgBAQwYAQEMGAEBDBgBARAYAQEQGAEBEBgBARQYAQEUGAEBFBgBARQYAQEYGAEBGBgBARgYAQEYGAEBHBgBARwYAQEcGAEBHBgBASAYAQEgGAEBJBgBASgYAQEoGAEBKBgBASgYAQAEAb0QBAG9EAQBsRAEAbEQBAGlEAQBpRAAAZ0QAAGdE/f8AQP3/AED//////f8AQCEAAEAiAABAIwAAQCQAAEAlAABAJgAAQCcAAEAoAABAKQAAQCoAAEArAABALAAAQC0AAEAuAABALwAAQDAAAEAxAABAMgAAQDMAAEA0AABANQAAQDYAAEA3AABAOAAAQDkAAEA6AABAOwAAQDwAAEA9AABAPgAAQD8AAEBAAABAYQAAQGIAAEBjAABAZAAAQGUAAEBmAABAZwAAQGgAAEBpAABAagAAQGsAAEBsAABAbQAAQG4AAEBvAABAcAAAQHEAAEByAABAcwAAQHQAAEB1AABAdgAAQHcAAEB4AABAeQAAQHoAAEBbAABAXAAAQF0AAEBeAABAXwAAQGAAAEBhAABAYgAAQGMAAEBkAABAZQAAQGYAAEBnAABAaAAAQGkAAEBqAABAawAAQGwAAEBtAABAbgAAQG8AAEBwAABAcQAAQHIAAEBzAABAdAAAQHUAAEB2AABAdwAAQHgAAEB5AABAegAAQHsAAEB8AABAfQAAQH4AAECFKQBAhikAQC4AAEAMMABADTAAQAEwAED7MABA8jAAQKEwAECjMABApTAAQKcwAECpMABA4zAAQOUwAEDnMABAwzAAQPwwAECiMABApDAAQKYwAECoMABAqjAAQKswAECtMABArzAAQLEwAECzMABAtTAAQLcwAEC5MABAuzAAQL0wAEDfMABA4DAAQOEwAEDiMABA5DAAQOYwAEDoMABA6TAAQOowAEDrMABA7DAAQO0wAEDvMABA8zAAQADZAMAA2QDA/////wARAEABEQBAqhEAwAIRAECsEQDArREAwAMRAEAEEQBABREAQLARAMCxEQDAshEAwLMRAMC0EQDAtREAwBoRAEAGEQBABxEAQAgRAEAhEQBACREAQAoRAEALEQBADBEAQA0RAEAOEQBADxEAQBARAEAREQBAEhEAQP3/AED9/wBAYREAwGIRAMBjEQDAZBEAwGURAMBmEQDA/f8AQP3/AEBnEQDAaBEAwGkRAMBqEQDAaxEAwGwRAMD9/wBA/f8AQG0RAMBuEQDAbxEAwHARAMBxEQDAchEAwP3/AED9/wBAcxEAwHQRAMB1EQDA/f8AQP3/AED9/wBAogAAQKMAAECsAABAIACCQaYAAEClAABAqSAAQP3/AEACJQBAkCEAQJEhAECSIQBAkyEAQKAlAEDLJQBA/f8AQP3/AED9/wBA/f8AQP3/AED9/wBA/f8AQP3/AED9/wBA/f8AQP3/AED9/wBA/f8AQAAAAMD9/wBA/f8AQABBjI7dAAsQ/f8AQAAAAAAAAAAA/f8AQABBqI7dAAsQ/f8AQP3/AED9/wBA/f8AQABB7I7dAAsM3NgAgP3/AED9/wBAAEGQj90ACyjm2ACA5tgAgObYAIDm2ACA5tgAgP3/AED9/wBA/f8AQP3/AED9/wBAAEHIj90ACxD9/wBA/f8AQP3/AED9/wBAAEH4j90AC6ABEABuThAAbU4QAGxOEABrThAAak4QAGlOEABoThAAZ04QAGZOEABlThAAZE4QAGNOEABiThAAYU4QAGBOEABfThAAXk4QAF1OEABcThAAW04QAFpOEABZThAAWE4QAFdOEABWThAAVU4QAFROEABTThAAUk4QAFFOEABQThAAT04QAE5OEABNThAATE4QAEtOEABKThAASU4QAEhOEABHTgBBuJHdAAugARAARk4QAEVOEABEThAAQ04QAEJOEABBThAAQE4QAD9OEAA+ThAAPU4QADxOEAA7ThAAOk4QADlOEAA4ThAAN04QADZOEAA1ThAANE4Q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QP3/AED9/wBA/f8AQABBjLndAAsg/f8AQP3/AED9/wBA/f8AQP3/AED9/wBA/f8AQP3/AEAAQdS53QALmAH9/wBA/f8AQAAAAAAAAAAAAdgAgAAAAAD//////////////////////f8AQP3/AED9/wBA/f8AQP3/AED9/wBA/f8AQP3/AED9/wBA/f8AQP3/AED9/wBAMAAAQDEAAEAyAABAMwAAQDQAAEA1AABANgAAQDcAAEA4AABAOQAAQP3/AED9/wBA/f8AQP3/AED9/wBA/f8AQABBpLvdAAswEQCHQxEAeEMSAIRDEgCBQxIAfkMSAHtDEgB4Q9jYAIDY2ACAAdgAgAHYAIAB2ACAAEHgu90AC2ji2ACA2NgAgNjYAIDY2ACA///////////////////////////////////////////c2ACA3NgAgNzYAIDc2ACA3NgAgAAAAAAAAAAA5tgAgObYAIDm2ACA5tgAgObYAIDc2ACA3NgAgABB8LzdAAsQ5tgAgObYAIDm2ACA5tgAgABBrL3dAAsYEQBvQxEAbEMSAHVDEgByQxIAb0MSAGxDAEGAvt0AC9wJ5tgAgObYAIDm2ACAAAAAAP3/AED9/wBA/f8AQP3/AED9/wBA/f8AQP3/AED9/wBA/f8AQP3/AEBxAABAcgAAQHMAAEB0AABAdQAAQHYAAEB3AABAeAAAQHkAAEB6AABAYQAAQGIAAEBjAABAZAAAQGUAAEBmAABAZwAAQGgAAEBpAABAagAAQGsAAEBsAABAbQAAQG4AAEBvAABAcAAAQHEAAEByAABAcwAAQHQAAEB1AABAdgAAQHcAAEB4AABAeQAAQHoAAEBhAABAYgAAQGMAAEBkAABAZQAAQGYAAEBnAABA/f8AQGkAAEBqAABAawAAQGwAAEBtAABAbgAAQG8AAEBwAABAcQAAQHIAAEBzAABAdAAAQHUAAEB2AABAdwAAQHgAAEB5AABAegAAQGEAAED9/wBAYwAAQGQAAED9/wBA/f8AQGcAAED9/wBA/f8AQGoAAEBrAABA/f8AQP3/AEBuAABAbwAAQHAAAEBxAABA/f8AQHMAAEB0AABAdQAAQHYAAEB3AABAeAAAQHkAAEB6AABAYQAAQGIAAEBjAABAZAAAQP3/AEBmAABA/f8AQGgAAEBpAABAagAAQGsAAEBs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lwMTA0IDRQOXAxQDAQNFA5cDEwMBA0UDlwMUAwADRQOXAxMDAANFA5cDFANFA5cDEwNFA7cDFANCA0UDtwMTA0IDRQO3AxQDAQNFA7cDEwMBA0UDtwMUAwADRQO3AxMDAANFA7cDFANFA7cDEwNFA5EDFANCA0UDkQMTA0IDRQORAxQDAQNFA5EDEwMBA0UDkQMUAwADRQORAxMDAANFA5EDFANFA5EDEwNFA7EDFANCA0UDsQMTA0IDRQOxAxQDAQNFA7EDEwMBA0UDsQMUAwADRQOxAxMDAANFA7EDFANFA7EDEwNFA6UDFANCA6UDFAMBA6UDFAMAA8UDFANCA8UDEwNCA8UDFAMBA8UDEwMBA8UDFAMAA8UDEwMAA58DFAMBA58DEwMBA58DFAMAA58DEwMAA78DFAMBA78DEwMBA78DFAMAA78DEwMAA5kDFANCA5kDEwNCA5kDFAMBA5kDEwMBA5kDFAMAA5kDEwMAA7kDFANCA7kDEwNCA7kDFAMBA7kDEwMBA7kDFAMAA7kDEwMAA5UDFAMBA5UDEwMBA5UDFAMAA5UDEwMAA7UDFAMBA7UDEwMBA7UDFAMAA7UDEwMAA3UAGwMjA1UAGwMjA3UAGwMDA1UAGwMDA3UAGwMJA1UAGwMJA3UAGwMAA1UAGwMAA3UAGwMBA1UAGwMBA28AGwMjA08AGwMjA28AGwMDA08AGwMDA28AGwMJA08AGwMJA28AGwMAA08AGwMAA28AGwMBA08AGwMBA28AIwMCA08AIwMCA28AAgMDA08AAgMDA28AAgMJA08AAgMJA28AAgMAA08AAgMAA28AAgMBA08AAgMBA2UAIwMCA0UAIwMCA2UAAgMDA0UAAgMDA2UAAgMJA0UAAgMJA2UAAgMAA0UAAgMAA2UAAgMBA0UAAgMBA2EAIwMGA0EAIwMGA2EABgMDA0EABgMDA2EABgMJA0EABgMJA2EABgMAA0EABgMAA2EABgMBA0EABgMBA2EAIwMCA0EAIwMCA2EAAgMDA0EAAgMDA2EAAgMJA0EAAgMJA2EAAgMAA0EAAgMAA2EAAgMBA0EAAgMBA3UABAMIA1UABAMIA3UAAwMBA1UAAwMBA3MAIwMHA1MAIwMHA3MADAMHA1MADAMHA3MAAQMHA1MAAQMHA3IAIwMEA1IAIwMEA28ABAMBA08ABAMBA28A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Ekmn72oRCsFEJ78QHBBUMWo6BY3xuwL2JvCe8+ygU1HclkmdAPzTCL3VCQIAuTzXDEfkX54Y0l5XoWxUvX5VGwgdmFp95CHK1LYltrJXzCCFIgS6obDzfxDCg4lzmNaBnXnE290TNUmDOS6fMQkhXLC9LJWeA5Nk96Kpd7pVZ2QIxt/jBP0udHh9LoOV+w5er8xOwvkO/f8CAAAACXYCAAzECwD067pYx1NXmEhfRVdScFNYzndt7FailxoHXJPkgPrDXvYVcIkXAAwAAACwixcACwAAAMCNFwAQAAAAwJAXABAAAADbfhAAYAAAAGMCAAAVAAAA234QAGAAAABmAgAALwAAAP3/AgAAAAl2AgAMxAsA9Ou6WMdTV5hIX0VXUnBTWM53bexWopcaB1yT5ID6w172Famq//////65//9Tsf7/qx4k9rD2oNIwZ78ShfOES3dk16xLQ7anG0ua5n856hEBGqrq////v3/u//9UrP//qgeJPaw9qDTM2a9E4Tzh0h3ZNevSkO3pxpKm+V+OekSABlXV////f//c//+pWP//VQ8Se1h7UGmYs1+JwnnCpTuya9alIdvTjSVN878c9YgADQEAAACxdBAAWQAAAL0CAAAJAAAAAAAAAA+CzsXXPFsHC9s+HGK6xj7Oa/8r2BOKFtJJxPhLPGaHMNjI3YNM8xWFLqqctCiWD0YXNBw0H9/08QTRCabmdgrVtpVMbEfljcCDnZOpiOtnLZUZtYU+eZqq48qS5Y+YEf3/AgAAAAl2AgAMxAsA9Ou6WMdTV5hIX0VXUnBTWM53bexWopcaB1yT5ID6w172FU4PEABLAAAAfwIAAAEAAAAgb2YgbGVuZ3RoIAABAAAAAAAAAHiVFwALAAAAc3RydWN0IENvbnRyYWN0VktTaGFyZXN0cnVjdCBQYWdlZFZLU2hhcmVzUmVzcG9uc2UAAL1SEABaAAAAagAAABUAAAC9UhAAWgAAAGoAAAAOAAAAvVIQAFoAAABrAAAAHgAAAL1SEABaAAAAbAAAABcAAAD/////////////////////////////////////////////////////////////////AAECAwQFBgcI/////////wkKCwwNDg8Q/xESExQV/xYXGBkaGxwdHh8g////////ISIjJCUmJygpKiv/LC0uLzAxMjM0NTY3ODn//////zEyMzQ1Njc4OUFCQ0RFRkdISktMTU5QUVJTVFVWV1hZWmFiY2RlZmdoaWprbW5vcHFyc3R1dnd4eXoAAEQHAAAQAAAABAAAAEUHAAAAAAAABAAAAAQAAAAKBQAAVmVyaWZpY2F0aW9uRXJyc291cmNlYmFja3RyYWNlAABGBwAAEAAAAAQAAABHBwAAUmVjb3ZlclB1YmtleUVyckgHAAAMAAAABAAAAEkHAABHZW5lcmljRXJybXNnSW52YWxpZEJhc2U2NAAAAAAAAAgAAAAIAAAASgcAAEludmFsaWREYXRhU2l6ZWV4cGVjdGVkYWN0dWFsSW52YWxpZEhleEludmFsaWRVdGY4Tm90Rm91bmRraW5kUGFyc2VFcnJ0YXJnZXRfdHlwZVNlcmlhbGl6ZUVycnNvdXJjZV90eXBlAAAAAAEAAAABAAAASwcAAE92ZXJmbG93AAAAAAAAAAABAAAATAcAAERpdmlkZUJ5WmVybwAAAAAQAAAABAAAAE0HAABDb252ZXJzaW9uT3ZlcmZsb3cAAAAAAAAEAAAABAAAABUFAABPdmVyZmxvd0Vycm9yb3BlcmF0aW9uRGl2aWRlQnlaZXJvRXJyb3IAAAAAAAgAAAAEAAAALQUAAAAAAAAEAAAABAAAAE4HAABDb252ZXJzaW9uT3ZlcmZsb3dFcnJvcgAAAAAABAAAAAQAAAAWBQAAQWdncmVnYXRpb25CYXRjaEVyckludmFsaWRIYXNoRm9ybWF0SW52YWxpZFNpZ25hdHVyZUZvcm1hdEludmFsaWRQdWJrZXlGb3JtYXRJbnZhbGlkUmVjb3ZlcnlQYXJhbUludmFsaWRQb2ludFVua25vd25IYXNoRnVuY3Rpb24AAAAABAAAAAQAAAAXBQAAUGFpcmluZ0VxdWFsaXR5AAAAAAAEAAAABAAAAE8HAABVbmtub3duRXJyZXJyb3JfY29kZQRSEABaAAAA0AEAABsAAAAEUhAAWgAAANEBAAAQAAAABFIQAFoAAADMAQAACQAAAARSEABaAAAAuQEAACAAAAAEUhAAWgAAAD0BAAAgAAAABFIQAFoAAACZAQAAIQBBzLPeAAuKCwEAAABQBwAAY2FsbGVkIGBSZXN1bHQ6OnVud3JhcCgpYCBvbiBhbiBgRXJyYCB2YWx1ZQBRBwAAFAAAAAQAAABSBwAAQnVmZmVyVG9vU21hbGwAAFMHAAAMAAAABAAAAFQHAAAAAAAABAAAAAQAAABVBwAARnJvbVV0ZjhFcnJvcmJ5dGVzZXJyb3IABFIQAFoAAACTAAAAKwAAAP////////////////////////////////////////////////////////////////8AAQIDBAUGBwj/////////CQoLDA0ODxD/ERITFBX/FhcYGRobHB0eHyD///////8hIiMkJSYnKCkqK/8sLS4vMDEyMzQ1Njc4Of//////MTIzNDU2Nzg5QUJDREVGR0hKS0xNTlBRUlNUVVZXWFlaYWJjZGVmZ2hpamttbm9wcXJzdHV2d3h5egAAvVIQAFoAAABqAAAAFQAAAL1SEABaAAAAagAAAA4AAAC9UhAAWgAAAGsAAAAeAAAAvVIQAFoAAABsAAAAFwAAAARSEABaAAAAQAAAABUAAAAEUhAAWgAAAEAAAAAOAAAABFIQAFoAAABBAAAAHgAAAARSEABaAAAAQgAAABcAAABQYXJzaW5nIHUxMjg6IAAApJsXAA4AAABSZWdpb24gcG9pbnRlciBpcyBudWxsAAC8mxcAFgAAAAwCEABiAAAAPgAAAAkAAAAMAhAAYgAAAEQAAAAUAAAAUmVnaW9uIHN0YXJ0cyBhdCBudWxsIHBvaW50ZXIAAAD8mxcAHQAAAAwCEABiAAAAkwAAAA0AAABJbnZhbGlkIGhhc2ggZm9ybWF0SW52YWxpZCBzaWduYXR1cmUgZm9ybWF0SW52YWxpZCByZWNvdmVyeSBwYXJhbWV0ZXIuIFN1cHBvcnRlZCB2YWx1ZXM6IDAgYW5kIDEuVW5rbm93biBlcnJvcjoglZwXAA8AAABRXBAASwAAAKIEAAAFAAAAAAAAAAEAAAABAAAAWAcAAGNhbGxlZCBgUmVzdWx0Ojp1bndyYXAoKWAgb24gYW4gYEVycmAgdmFsdWUAEgAAAHAyEABPAAAAzgEAADcAAABzdHJpbmctZW5jb2RlZCBkZWNpbWFsAAAAAAAABAAAAAQAAAAVBQAAT3ZlcmZsb3dFcnJvcm9wZXJhdGlvbgAANDoQAGgAAAAlAgAALAAAADQ6EABoAAAAPwIAAD8AAABVbmV4cGVjdGVkIG51bWJlciBvZiBkb3RzRXJyb3IgcGFyc2luZyB3aG9sZVZhbHVlIHRvbyBiaWdDYW5ub3QgcGFyc2UgbW9yZSB0aGFuICBmcmFjdGlvbmFsIGRpZ2l0cwAApZ0XABcAAAC8nRcAEgAAAEVycm9yIHBhcnNpbmcgZnJhY3Rpb25hbAAAAAAEAAAABAAAAFkHAAAAAAAABAAAAAQAAAB6BQAAVXRmOEVycm9ydmFsaWRfdXBfdG9lcnJvcl9sZW5pbnRlcm5hbCBlcnJvcjogZW50ZXJlZCB1bnJlYWNoYWJsZSBjb2RlOiBpbnZhbGlkIE9uY2Ugc3RhdGUAAAA1nhcAPAAAAOcgEABbAAAANQAAABIAAAABAAAAAAAAADIjEABsAAAAbAAAABgAAABkZXNjcmlwdGlvbigpIGlzIGRlcHJlY2F0ZWQ7IHVzZSBEaXNwbGF5+ZFqc9lA46hY4yYqy0jvuRgEU/+5OdjfbgeoxUDECmcCumge+tDJxqIfNkj+2yT1LncEaDZZILxlbtnzRanFYQoZdXgwQQikedeTTa1LgCthBwAAEAAAAAQAAABiBwAAYQcAABAAAAAEAAAAYwcAAGIHAAAcnxcAZAcAAGUHAABmBwAAZwcAAGgHAEHgvt4ACwYBAAAAaQcAQfC+3gALmSABAAAAagcAAGkHAABYnxcAawcAAGwHAABtBwAAawcAAG4HAABvBwAAEAAAAAQAAABwBwAAbwcAABAAAAAEAAAAcQcAAHAHAACUnxcAcgcAAHMHAABmBwAAdAcAAGgHAAAAAAAAEAAAAAQAAAB1BwAAAAAAABAAAAAEAAAAdgcAAHUHAADQnxcAcgcAAHcHAABmBwAAcgcAAGgHAAAAAAAAAQAAAAEAAAB4BwAAAAAAAAEAAAABAAAAeQcAAHgHAAAMoBcAegcAAHsHAAB8BwAAegcAAH0HAABWZXJpZmljYXRpb24gZXJyb3I6IEigFwAUAAAAUmVjb3ZlciBwdWJrZXkgZXJyb3I6IAAAZKAXABYAAABHZW5lcmljIGVycm9yOiAAhKAXAA8AAABJbnZhbGlkIEJhc2U2NCBzdHJpbmc6IACcoBcAFwAAAEludmFsaWQgZGF0YSBzaXplOiBleHBlY3RlZD0gYWN0dWFsPbygFwAcAAAA2KAXAAgAAABJbnZhbGlkIGhleCBzdHJpbmc6IPCgFwAUAAAAQ2Fubm90IGRlY29kZSBVVEY4IGJ5dGVzIGludG8gc3RyaW5nOiAAAAyhFwAmAAAAIG5vdCBmb3VuZAAAAQAAAAAAAAA8oRcACgAAAEVycm9yIHBhcnNpbmcgaW50byB0eXBlIDogAABYoRcAGAAAAHChFwACAAAARXJyb3Igc2VyaWFsaXppbmcgdHlwZSAAhKEXABcAAABwoRcAAgAAAE92ZXJmbG93OiAAAKyhFwAKAAAARGl2aWRlIGJ5IHplcm86IMChFwAQAAAAQ29udmVyc2lvbiBlcnJvcjogAAAAAAAABAAAAAQAAAAVBQAAT3ZlcmZsb3dFcnJvcm9wZXJhdGlvbkNhbm5vdCAgd2l0aCBnaXZlbiBvcGVyYW5kcwAAABKiFwAHAAAAGaIXABQAAAAtVBAASgAAAL0BAAAdAAAARGl2aWRlQnlaZXJvRXJyb3JBZGRTdWJNdWxQb3dTaHJTaGxDYW5ub3QgZGl2aWRlIGJ5IHplcm8AAAAACAAAAAQAAAAtBQAAAAAAAAQAAAAEAAAATgcAAENvbnZlcnNpb25PdmVyZmxvd0Vycm9yc291cmNlX3R5cGV0YXJnZXRfdHlwZUVycm9yIGNvbnZlcnRpbmcgIHRvIAAA1aIXABEAAADmohcABAAAAAAAAAAEAAAABAAAABYFAABBZ2dyZWdhdGlvbnNvdXJjZUJhdGNoRXJyR2VuZXJpY0VyckludmFsaWRIYXNoRm9ybWF0SW52YWxpZFNpZ25hdHVyZUZvcm1hdEludmFsaWRQdWJrZXlGb3JtYXRJbnZhbGlkUmVjb3ZlcnlQYXJhbUludmFsaWRQb2ludFVua25vd25IYXNoRnVuY3Rpb24AAAAABAAAAAQAAAAXBQAAUGFpcmluZ0VxdWFsaXR5AAAAAAAEAAAABAAAAH4HAAAAAAAABAAAAAQAAAAKBQAAVW5rbm93bkVycmVycm9yX2NvZGViYWNrdHJhY2UAAABhohcAZKIXAGeiFwBqohcAbaIXAHCiFwBMaXN0IGlzIG5vdCBhIG11bHRpcGxlIG9mIDQ4TGlzdCBpcyBub3QgYSBtdWx0aXBsZSBvZiA5Nk5vdCB0aGUgc2FtZSBhbW91bnQgb2YgcG9pbnRzIHBhc3NlZIEHAAAYAAAABAAAAIIHAACBBwAAGAAAAAQAAACDBwAAggcA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AHYCAAAVAAAAAQAAAAAAAAACAEHG7N4ACwECAEHQ7N4AC/UcIAAA6XVuc3VwcG9ydGVkIEFwcGx5U25hcHNob3RDaHVua1Jlc3VsdCB0eXBlAAAAVLYXACkAAAABAAAAAAAAAHVuc3VwcG9ydGVkIE9mZmVyU25hcHNob3RDaHVua1Jlc3VsdCB0eXBlAAAAkLYXACkAAAB1bnN1cHBvcnRlZCBWZXJpZnlWb3RlRXh0ZW5zaW9uIHN0YXR1cyB2YWx1ZcS2FwAsAAAAc3RydWN0IFByb29mT3BzdHJ1Y3QgUHJvb2ZPcHNlcnJvciBwYXJzaW5nIGRhdGE6IAAAABW3FwAUAAAAY3J5cHRvZ3JhcGhpYyBlcnJvcgA0txcAEwAAAGxlbmd0aCBlcnJvclC3FwAMAAAAZXJyb3IgcGFyc2luZyBpbnQgZGF0YTogZLcXABgAAABwcm90b2NvbCBlcnJvcjoghLcXABAAAABzaWduYXR1cmUgZXJyb3IAnLcXAA8AAAB0aW1lIHBhcnNpbmcgZXJyb3IAALS3FwASAAAAaW52YWxpZCBrZXk6IAAAANC3FwANAAAAaW52YWxpZCBibG9jayBpZCBmbGFnAAAA6LcXABUAAABtaXNzaW5nIGRhdGEgZmllbGQAAAi4FwASAAAAbm8gdm90ZSBmb3VuZAAAACS4FwANAAAAaW52YWxpZCBibG9jazogADy4FwAPAAAAbWlzc2luZyBoZWFkZXIgZmllbGRUuBcAFAAAAG5lZ2F0aXZlIHBvd2VyAABwuBcADgAAAG5lZ2F0aXZlIHJvdW5kAACIuBcADgAAAGRhdGUgb3V0IG9mIHJhbmdlAAAAoLgXABEAAABlbXB0eSBzaWduYXR1cmUAvLgXAA8AAABtaXNzaW5nIHZlcnNpb24A1LgXAA8AAABuZWdhdGl2ZSBoZWlnaHQA7LgXAA8AAABzdWJ0bGUgZW5jb2RpbmcgZXJyb3IAAAAEuRcAFQAAAGludGVnZXIgb3ZlcmZsb3ckuRcAEAAAAGludmFsaWQgZXZpZGVuY2U8uRcAEAAAAGludmFsaWQgaGFzaDogZXhwZWN0ZWQgaGFzaCBzaXplIHRvIGJlIDMyIGJ5dGVzAFS5FwAvAAAAbWlzc2luZyBldmlkZW5jZSBmaWVsZAAAjLkXABYAAABubyBwcm9wb3NhbCBmb3VuZAAAAKy5FwARAAAAaW52YWxpZCBzaWduYXR1cmU6IADIuRcAEwAAAGludmFsaWQgdGltZXN0YW1wOiAA5LkXABMAAABtaXNzaW5nIHB1YmxpYyBrZXkAAAC6FwASAAAAbWlzc2luZyB0aW1lc3RhbXAgZmllbGQAHLoXABcAAABtaXNzaW5nIHZhbGlkYXRvcgAAADy6FwARAAAAbmVnYXRpdmUgUE9MIHJvdW5kAABYuhcAEgAAAGFic2VudCBjb21taXRzaWcgaGFzIG5vbi16ZXJvIHRpbWVzdGFtcAB0uhcAJwAAAHByb3Bvc2VyIHdpdGggYWRkcmVzcyAnJyBubyBmb3VuZCBpbiB2YWxpZGF0b3Igc2V0AACkuhcAFwAAALu6FwAbAAAAYmFkIHNpZ25hdHVyZTogAOi6FwAPAAAAbmVnYXRpdmUgbWF4X2FnZV9udW1fYmxvY2tzAAC7FwAbAAAAZHVyYXRpb24gdmFsdWUgb3V0IG9mIHJhbmdlACS7FwAbAAAAbGFzdF9ibG9ja19pZCBpcyBub3QgbnVsbCBvbiBmaXJzdCBoZWlnaHQAAABIuxcAKQAAAGludmFsaWQgbWVzc2FnZSB0eXBlfLsXABQAAABtaXNzaW5nIGdlbmVzaXMgdGltZZi7FwAUAAAAbmVnYXRpdmUgaXRlbSBpbmRleCBpbiBwcm9vZrS7FwAcAAAAbmVnYXRpdmUgbnVtYmVyIG9mIGl0ZW1zIGluIHByb29mAAAA2LsXACEAAAB1bnN1cHBvcnRlZCBrZXkgdHlwZQS8FwAUAAAAaW52YWxpZCBzaWduZWQgaGVhZGVyAAAAILwXABUAAAB0aW1lc3RhbXAgY29udmVyc2lvbiBlcnJvcgAAQLwXABoAAABpbnZhbGlkIGFwcCBoYXNoIGxlbmd0aABkvBcAFwAAAGludmFsaWQgcGFydCBzZXQgaGVhZGVyOiAAAACEvBcAGQAAAGludmFsaWQgdmVyc2lvbiBwYXJhbWV0ZXJzAACovBcAGgAAAG1pc3NpbmcgbGFzdCBjb21taXQgaW5mb8y8FwAYAAAAbWlzc2luZyBtYXhfYWdlX2R1cmF0aW9u7LwXABgAAABpbnZhbGlkIEFCQ0kgcmVxdWVzdCB0eXBlAAAADL0XABkAAABpbnZhbGlkIGFjY291bnQgSUQgbGVuZ3RoAAAAML0XABkAAABpbnZhbGlkIHZhbGlkYXRvciBwYXJhbWV0ZXJzVL0XABwAAABtaXNzaW5nIGNvbnNlbnN1cyBwYXJhbXN4vRcAGAAAAG5lZ2F0aXZlIHZhbGlkYXRvciBpbmRleJi9FwAYAAAAdHJ1c3QgdGhyZXNob2xkIGlzIHRvbyBsYXJnZSAobXVzdCBiZSA8PSAxKQC4vRcAKwAAAHRydXN0IHRocmVzaG9sZCB0b28gc21hbGwgKG11c3QgYmUgPj0gMS8zKQAA7L0XACoAAAB1bnN1cHBvcnRlZCBDaGVja1R4IHR5cGUgvhcAGAAAAGludmFsaWQgQUJDSSByZXNwb25zZSB0eXBlAABAvhcAGgAAAGludmFsaWQgdmFsaWRhdG9yIGFkZHJlc3MAAABkvhcAGQAAAHVuZGVmaW5lZCB0cnVzdCB0aHJlc2hvbGQgKGRlbm9taW5hdG9yIGNhbm5vdCBiZSAwKQCIvhcAMwAAAGludmFsaWQgc2lnbmF0dXJlIElEIGxlbmd0aADEvhcAGwAAAHRpbWVzdGFtcCBuYW5vc2Vjb25kIGNvbXBvbmVudCBpcyBvdXQgb2YgcmFuZ2UAAOi+FwAuAAAAdG90YWwgdm90aW5nIHBvd2VyIGluIHZhbGlkYXRvciBzZXQgZG9lcyBub3QgbWF0Y2ggdGhlIHN1bSBvZiBwYXJ0aWNpcGFudHMnIHBvd2VycwAAIL8XAFIAAAB0b3RhbCB2b3RpbmcgcG93ZXIgaW4gdmFsaWRhdG9yIHNldCBleGNlZWRzIHRoZSBhbGxvd2VkIG1heGltdW0AfL8XAD8AAAB1bnN1cHBvcnRlZCBQcm9jZXNzUHJvcG9zYWwgc3RhdHVzIHZhbHVlxL8XACgAAABpbnRlZ2VyIG9yIHN0cmluZwAAAAAAAAABAAAAAQAAACoIAABjYWxsZWQgYFJlc3VsdDo6dW53cmFwKClgIG9uIGFuIGBFcnJgIHZhbHVlSGFzaDo6U2hhMjU2KCkAAABDwBcADQAAAFDAFwABAAAASGFzaDo6Tm9uZQAAmz8QAF8AAACXAAAASgAAAAEAAAAAAAAAQ2hlY2tzdW1JbnZhbGlkRW5jb2RpbmdJbnZhbGlkSW9FcnJvckxlbmd0aEludmFs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AAAEAAAAXQMAAENvbXBvbmVudFJhbmdlbmFtZW1pbmltdW1tYXhpbXVtdmFsdWVjb25kaXRpb25hbF9tZXNzYWdlAQAAAAAAAAAk0RcAAQAAACTRFwABAAAA+0sQAGUAAABUBQAADQAAAHNpZ25wYWRkaW5nbG93ZXJ1cHBlcnJlcHJzaG9ydGxvbmdzdW5kYXltb25kYXlhdXRvbWF0aWNtYW5kYXRvcnlwcmVjaXNpb25pc28xMjM0NTY3ODkxK2ZhbHNldHJ1ZWRheWVuZGhvdXJpZ25vcmVtaW51dGVtb250aG9mZnNldF9ob3Vyb2Zmc2V0X21pbnV0ZW9mZnNldF9zZWNvbmRvcmRpbmFscGVyaW9kc2Vjb25kc3Vic2Vjb25kdW5peF90aW1lc3RhbXB3ZWVrZGF5d2Vla19udW1iZXJ5ZWFybWlsbGlzZWNvbmRtaWNyb3NlY29uZG5hbm9zZWNvbmRbcmFuZ2ViYXNlY2FzZV9zZW5zaXRpdmVjb3VudGNhc2VzcGFjZXplcm9ub25lb25lX2luZGV4ZWQxMjI0Y2FsZW5kYXJpc29fd2Vla2Z1bGxjZW50dXJ5bGFzdF90d29udW1lcmljYWxkaWdpdHNzdGFuZGFyZGV4dGVuZGVkANkiEABYAAAA6wcAAAkAAABpbnRlcm5hbCBlcnJvcjogY2xvc2luZyBicmFja2V0IHNob3VsZCBoYXZlIGJlZW4gY29uc3VtZWQgYnkgYHBhcnNlX2NvbXBvbmVudGAAAFzUFwBOAAAAcAkQAHEAAACjAAAAEQAAAGludGVybmFsIGVycm9yOiBjb21wb25lbnQgcGFydCBzaG91bGQgaGF2ZSBiZWVuIGNvbnN1bWVkIGJ5IGBwYXJzZV9jb21wb25lbnRgAAAAxNQXAE0AAABwCRAAcQAAAKoAAAARAAAAaW50ZXJuYWwgZXJyb3I6IGxpdGVyYWwgc2hvdWxkIG5vdCBiZSBwcmVzZW50IGluIG5lc3RlZCBkZXNjcmlwdGlvbgAs1RcAQwAAAHAJEABxAAAAhQAAABEAAABpbnRlcm5hbCBlcnJvcjogY2xvc2luZyBicmFja2V0IHNob3VsZCBiZSBjYXVnaHQgYnkgdGhlIGBpZmAgc3RhdGVtZW50AACI1RcARgAAAHAJEABxAAAAnQAAABEAAABvcGVuaW5nIGJyYWNrZXQAcAkQAHEAAABFAQAAEwAAAHAJEABxAAAAWgEAAB4AAABwCRAAcQAAAPYAAAAoAAAAcAkQAHEAAAAHAQAARAAAAHdoaXRlc3BhY2UgYWZ0ZXIgYGZpcnN0YHdoaXRlc3BhY2UgYWZ0ZXIgYG9wdGlvbmFsYAAtVBAASgAAAL0BAAAdAAAA4TcQAHkAAAAUAQAAAQAAAGludGVybmFsIGVycm9yOiByZXF1aXJlZCBtb2RpZmllciB3YXMgbm90IHNldAAAAIzWFwAtAAAA4V4QAHEAAAC6AAAAFwAAAOFeEABxAAAAsAAAABcAAADhXhAAcQAAAIAAAAATAAAAChIQAFkAAAD7AAAAAQAAAHRoZSBgUGFyc2VkYCBzdHJ1Y3QgZGlkIG5vdCBpbmNsdWRlIGVub3VnaCBpbmZvcm1hdGlvbiB0byBjb25zdHJ1Y3QgdGhlIHR5cGUtVBAASgAAAL0BAAAdAAAAbW9udGh5ZWFyZGF5c2VwYXJhdG9yaG91cm1pbnV0ZXNlY29uZHN1YnNlY29uZG9mZnNldCBob3Vyb2Zmc2V0IG1pbnV0ZQAAKU4QAGUAAACOAgAAFQAAAClOEABlAAAAqgIAABkAAABiZWNhdXNlIGxlYXAgc2Vjb25kcyBhcmUgbm90IHN1cHBvcnRlZGhvdXJzbWludXRlc05vbmUAAAAAAAAEAAAABAAAAMkEAABTb21lIG11c3QgYmUgaW4gdGhlIHJhbmdlIC4uPQAAAAEAAAAAAAAAFNgXABYAAAAq2BcAAwAAACAAAABI2BcAAQAAAGEgdmFsdWUgaW4gdGhlIHJhbmdlIAAAAFTYFwAVAAAAKtgXAAMAAAABAAAAAAAAAG9wdGlvbmFsIGl0ZW1ydW50aW1lLXBhcnNlZCBmb3JtYXQgZGVzY3JpcHRpb25zJ2ZpcnN0JyBpdGVtAOFeEABxAAAAYAAAAAkAAABYJhAAcwAAAMsAAAAjAAAAWCYQAHMAAADOAAAAFQAAAFgmEABzAAAAzwAAACMAAABYJhAAcwAAAOQAAAAfAAAAWCYQAHMAAAD0AAAAFQAAAFgmEABzAAAA9wAAACMAAABYJhAAcwAAAAcBAAAVAAAAWCYQAHMAAAAKAQAAIwAAAOpYEABrAAAAYgAAABsAAABhbiBgT2Zmc2V0RGF0ZVRpbWVgYW4gUkZDMzMzOS1mb3JtYXR0ZWQgYE9mZnNldERhdGVUaW1lYNkiEABYAAAA6wcAAAkAAADhXhAAcQAAAGAAAAAJAAAAKU4QAGUAAACKAgAAHgAAAK8MEABmAAAAEwEAAD0AAACvDBAAZgAAABwBAAArAAAArwwQAGYAAAASAQAAOwAAAK8MEABmAAAAEQEAADsAAACvDBAAZgAAABUBAAA8AAAArwwQAGYAAAAUAQAAPAAAAK8MEABmAAAAGAEAAD0AAACvDBAAZgAAABcBAAA9AAAArwwQAGYAAAAWAQAAOwAAAK8MEABmAAAAZAEAABgAAACvDBAAZgAAAGIBAAAYAAAArwwQAGYAAABmAQAAGAAAAH83EABhAAAAIgAAAAEAAABjKRAATwAAAJAAAAAuAAAAESUQAGEAAADnAQAAKgAAACBhdCBsaW5lIAAAABElEABhAAAA9QEAABkAAAARJRAAYQAAAPcBAAAhAAAAESUQAGEAAAD7AQAADAAAACBjb2x1bW4gESUQAGEAAAAAAgAAGwAAABElEABhAAAAAgIAACEAAAARJRAAYQAAAAsCAAAqAAAAESUQAGEAAAAPAgAALAAAABElEABhAAAAFAIAAAkAAAARJRAAYQAAAAMCAAAJAAAAESUQAGEAAAD4AQAACQAAAJoIAAAMAAAABAAAAJsIAACcCAAAZQYAQYy33wALoRQBAAAAnQgAAGEgRGlzcGxheSBpbXBsZW1lbnRhdGlvbiByZXR1cm5lZCBhbiBlcnJvciB1bmV4cGVjdGVkbHkAgkEQAEsAAAAFCwAADgAAAHAyEABPAAAAPAYAABQAAABwMhAATwAAADwGAAAhAAAAcDIQAE8AAAAwBgAAFAAAAHAyEABPAAAAMAYAACEAAABFcnJvcgAAAIJBEABLAAAAqgwAAA4AAABhc3NlcnRpb24gZmFpbGVkOiBzZWxmLmlzX2NoYXJfYm91bmRhcnkobmV3X2xlbilFcnJvcigsIGxpbmU6ICwgY29sdW1uOiApAAAAZNwXAAYAAABq3BcACAAAAHLcFwAKAAAAfNwXAAEAAABpbnZhbGlkIHR5cGU6ICwgZXhwZWN0ZWQgAAAAoNwXAA4AAACu3BcACwAAAGludmFsaWQgdmFsdWU6IADM3BcADwAAAK7cFwALAAAARU9GIHdoaWxlIHBhcnNpbmcgYSBsaXN0RU9GIHdoaWxlIHBhcnNpbmcgYW4gb2JqZWN0RU9GIHdoaWxlIHBhcnNpbmcgYSBzdHJpbmdFT0Ygd2hpbGUgcGFyc2luZyBhIHZhbHVlZXhwZWN0ZWQgYDpgZXhwZWN0ZWQgYCxgIG9yIGBdYGV4cGVjdGVkIGAsYCBvciBgfWBleHBlY3RlZCBpZGVudGV4cGVjdGVkIHZhbHVlZXhwZWN0ZWQgYCJgaW52YWxpZCBlc2NhcGVpbnZhbGlkIG51bWJlcm51bWJlciBvdXQgb2YgcmFuZ2VpbnZhbGlkIHVuaWNvZGUgY29kZSBwb2ludGNvbnRyb2wgY2hhcmFjdGVyIChcdTAwMDAtXHUwMDFGKSBmb3VuZCB3aGlsZSBwYXJzaW5nIGEgc3RyaW5na2V5IG11c3QgYmUgYSBzdHJpbmdpbnZhbGlkIHZhbHVlOiBleHBlY3RlZCBrZXkgdG8gYmUgYSBudW1iZXIgaW4gcXVvdGVzZmxvYXQga2V5IG11c3QgYmUgZmluaXRlIChnb3QgTmFOIG9yICsvLWluZilsb25lIGxlYWRpbmcgc3Vycm9nYXRlIGluIGhleCBlc2NhcGV0cmFpbGluZyBjb21tYXRyYWlsaW5nIGNoYXJhY3RlcnN1bmV4cGVjdGVkIGVuZCBvZiBoZXggZXNjYXBlcmVjdXJzaW9uIGxpbWl0IGV4Y2VlZGVkAQAAAAAAAAC42hcACQAAAPTaFwAIAAAAZmxvYXRpbmcgcG9pbnQgYGAAAAA43xcAEAAAAEjfFwABAAAAbnVsbC1UEABKAAAAvQEAAB0AAABwMhAATwAAAL0EAAAkAAAAvGkQAGAAAAByAwAAGQAAALxpEABgAAAAcwMAABoAAAC8aRAAYAAAAHQDAAAZAAAAvGkQAGAAAAB1AwAAGQAAALxpEABgAAAAdgMAABkAAAC8aRAAYAAAAHcDAAAZAAAAvGkQAGAAAAB4AwAAGQAAALxpEABgAAAAeQMAABkAAAC8aRAAYAAAANQDAAARAAAA////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////AAABAAIAAwAEAAUABgAHAAgACQD//////////////////woACwAMAA0ADgAPAP////////////////////////////////////////////////////////////////////8KAAsADAANAA4ADwD///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////8AABAAIAAwAEAAUABgAHAAgACQAP//////////////////oACwAMAA0ADgAPAA/////////////////////////////////////////////////////////////////////6AAsADAANAA4ADwAP//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////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AAAABAAAAAQAAACvCAAATWFsZm9ybWVkUHVibGljS2V5U3RyaW5nc291cmNlTWFsZm9ybWVkUHJpdmF0ZUtleVN0cmluZ3JlY2lwaWVudCBpcyBtYWxmb3JtZWQgLSAgAAAAKyEYABkAAABEIRgAAQAAAHJlY2lwaWVudCdzIGlkZW50aXR5IGtleSBpcyBtYWxmb3JtZWQ6IABYIRgAJwAAAHJlY2lwaWVudCdzIGVuY3J5cHRpb24ga2V5IGlzIG1hbGZvcm1lZDogAAAAiCEYACkAAAByZWNpcGllbnQgZ2F0ZXdheSdzIGlkZW50aXR5IGtleSBpcyBtYWxmb3JtZWQ6IAC8IRgALwAAAN0eEAAoAAAAxgAAABwAAADZIhAAWAAAAOsHAAAJAAAAQnVmZmVyVG9vU21hbGwAAAAAAAAEAAAABAAAALEDAAAAAAAABAAAAAQAAADUBQAASW52YWxpZENoYXJhY3RlcmNoYXJhY3RlcmluZGV4Tm9uQXNjaWlDaGFyYWN0ZXIAAAAAAAQAAAABAAAAsgMAAAAAAAAEAAAABAAAAAYHAABJbnZhbGlkQ2hlY2tzdW1jaGVja3N1bWV4cGVjdGVkX2NoZWNrc3VtAAAAAAEAAAABAAAAsQgAAAAAAAAEAAAABAAAANQAAABJbnZhbGlkVmVyc2lvbnZlcmV4cGVjdGVkX3Zlck5vQ2hlY2tzdW0ALVQQAEoAAAC9AQAAHQAAAEF0dGVtcHRlZCB0byBkZXNlcmlhbGl6ZSBOeW1Ob2RlUm91dGluZ0FkZHJlc3Mgd2l0aG91dCBwcm92aWRpbmcgYW55IGJ5dGVzUHJvdmlkZWQgaW5zdWZmaWNpZW50IGFtb3VudCBvZiBmZXcgYnl0ZXMgdG8gZGVzZXJpYWxpemUgYSB2YWxpZCBOeW1Ob2RlUm91dGluZ0FkZHJlc3MgZm9yIElQdiB2YXJpYW50LiBSZWNlaXZlZCAgYW5kIHJlcXVpcmVkIAAAAF4jGABeAAAAvCMYABMAAADPIxgADgAAACBpcyBub3QgYSB2YWxpZCB2ZXJzaW9uIG9mIHRoZSBJbnRlcm5ldCBQcm90b2NvbCAoSVApLiBFeHBlY3RlZCBlaXRoZXIgJzQnIG9yICc2JwAAAAEAAAAAAAAA+CMYAFEAAAAgAAAAQ291bGQgbm90IHNlcmlhbGl6ZSBOeW1Ob2RlUm91dGluZ0FkZHJlc3MgaW50byBOb2RlQWRkcmVzc0J5dGVzIGFzIHRoYXQgcmVxdWlyZXMgdXNpbmcgYXQgbGVhc3QgIGJ5dGVzIGFuZCBvbmx5ICBhcmUgYXZhaWxhYmxlAABgJBgAYAAAAMAkGAAQAAAA0CQYAA4AAAD/////////////////////////////////////////////////////////////////AAECAwQFBgcI/////////wkKCwwNDg8Q/xESExQV/xYXGBkaGxwdHh8g////////ISIjJCUmJygpKiv/LC0uLzAxMjM0NTY3ODn//////zEyMzQ1Njc4OUFCQ0RFRkdISktMTU5QUVJTVFVWV1hZWmFiY2RlZmdoaWprbW5vcHFyc3R1dnd4eXoAAARSEABaAAAAPQEAACAAAACyCAAAFAAAAAQAAACzCAAAtAgAAAgAAAAEAAAA4AMAAGNhbGxlZCBgUmVzdWx0Ojp1bndyYXAoKWAgb24gYW4gYEVycmAgdmFsdWUAQZjM4AAL3hYBAAAAtQgAAEJ1ZmZlclRvb1NtYWxsAAC2CAAADAAAAAQAAAC3CAAAAAAAAAQAAAAEAAAAuAgAAEZyb21VdGY4RXJyb3JieXRlc2Vycm9yAARSEABaAAAAkwAAACsAAAC9UhAAWgAAAGoAAAAVAAAAvVIQAFoAAABqAAAADgAAAL1SEABaAAAAawAAAB4AAAC9UhAAWgAAAGwAAAAXAAAABFIQAFoAAABAAAAAFQAAAARSEABaAAAAQAAAAA4AAAAEUhAAWgAAAEEAAAAeAAAABFIQAFoAAABCAAAAFwAAAHNpZ25hdHVyZSBvcGVyYXRpb24gZmFpbGVkAACHLBAAXwAAABAAAAAcAAAAc3RydWN0IEtleVBhaXJkZXNjcmlwdGlvbigpIGlzIGRlcHJlY2F0ZWQ7IHVzZSBEaXNwbGF5AAAyxJQzOn7XND9YBDoBezbxAAAAAAwAAAAEAAAApAMAAAAAAAAMAAAABAAAALkIAACkAwAAbCcYALoIAAC7CAAAvAgAAKkDAAC9CAAAQnVmZmVyVG9vU21hbGwAAAAAAAAEAAAABAAAALEDAAAAAAAABAAAAAQAAADUBQAASW52YWxpZENoYXJhY3RlcmNoYXJhY3RlcmluZGV4Tm9uQXNjaWlDaGFyYWN0ZXIAAAAAAAQAAAABAAAAsgMAAAAAAAAEAAAABAAAAAYHAABJbnZhbGlkQ2hlY2tzdW1jaGVja3N1bWV4cGVjdGVkX2NoZWNrc3VtAAAAAAEAAAABAAAAvggAAAAAAAAEAAAABAAAANQAAABJbnZhbGlkVmVyc2lvbnZlcmV4cGVjdGVkX3Zlck5vQ2hlY2tzdW1yZWNlaXZlZCBwdWJsaWMga2V5IG9mIGludmFsaWQgc2l6ZS4gR290OiAsIGV4cGVjdGVkOiAAAACXKBgAKgAAAMEoGAAMAAAAcmVjZWl2ZWQgcHJpdmF0ZSBrZXkgb2YgaW52YWxpZCBzaXplLiBHb3Q6IADgKBgAKwAAAMEoGAAMAAAAdGhlIGJhc2U1OCByZXByZXNlbnRhdGlvbiBvZiB0aGUgcHVibGljIGtleSB3YXMgbWFsZm9ybWVkIC0gHCkYADwAAAB0aGUgYmFzZTU4IHJlcHJlc2VudGF0aW9uIG9mIHRoZSBwcml2YXRlIGtleSB3YXMgbWFsZm9ybWVkIC0gAAAAYCkYAD0AAAA/ZBAAKwAAALcAAAAbAAAAc3RydWN0IEtleVBhaXJkZXNjcmlwdGlvbigpIGlzIGRlcHJlY2F0ZWQ7IHVzZSBEaXNwbGF5AAAyxJQzOn7XND9YBDoBezbxAAAAAAwAAAAEAAAApAMAAAAAAAAMAAAABAAAAL8IAACkAwAAACoYAMAIAADBCAAAwggAAKkDAADDCAAAQnVmZmVyVG9vU21hbGwAAAAAAAAEAAAABAAAALEDAAAAAAAABAAAAAQAAADUBQAASW52YWxpZENoYXJhY3RlcmNoYXJhY3RlcmluZGV4Tm9uQXNjaWlDaGFyYWN0ZXIAAAAAAAQAAAABAAAAsgMAAAAAAAAEAAAABAAAAAYHAABJbnZhbGlkQ2hlY2tzdW1jaGVja3N1bWV4cGVjdGVkX2NoZWNrc3VtAAAAAAEAAAABAAAAxAgAAAAAAAAEAAAABAAAANQAAABJbnZhbGlkVmVyc2lvbnZlcmV4cGVjdGVkX3Zlck5vQ2hlY2tzdW1jb3VsZCBub3QgY29udmVydCBzbGljZSB0byBhcnJheQAtVBAASgAAAL0BAAAdAAAAdGhlIGJhc2U1OCByZXByZXNlbnRh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NgAAAGs+EABdAAAAPgAAABcAAABrPhAAXQAAAEIAAAATAAAAZ+YJaoWuZ7ty8248OvVPpX9SDlGMaAWbq9mDHxnN4FsNAAAADQAAAA4AAAALAAAADgAAAM9DGADcQxgA6UMYAPdDGAACRBgA5ywQAGoAAAAnAAAALQBBuInhAAumCv////////////////////////////////////////////////////////////////8AAQIDBAUGBwj/////////CQoLDA0ODxD/ERITFBX/FhcYGRobHB0eHyD///////8hIiMkJSYnKCkqK/8sLS4vMDEyMzQ1Njc4Of//////MTIzNDU2Nzg5QUJDREVGR0hKS0xNTlBRUlNUVVZXWFlaYWJjZGVmZ2hpamttbm9wcXJzdHV2d3h5ek5vbmUAAAAAAAAEAAAABAAAANQAAABTb21lL3kQAF0AAAAEAAAAAQAAAGludGVybmFsIGVycm9yOiBlbnRlcmVkIHVucmVhY2hhYmxlIGNvZGW/MBAAVQAAANkAAAAFAAAA/RIQAGgAAABEAAAAKwAAAP0SEABoAAAAWAAAACUAAAD9EhAAaAAAADIAAAAiAAAA/RIQAGgAAAA0AAAAJQAAAHBhY2tldCBwcm9jZXNzaW5nIGZhaWx1cmVoZWFkZXIgcHJvY2Vzc2luZyBmYWlsdXJlcGF5bG9hZCBwcm9jZXNzaW5nIGZhaWx1cmVTVVJCIHByb2Nlc3NpbmcgZmFpbHVyZXJvdXRpbmcgaW5mb3JtYXRpb24gcHJvY2Vzc2luZyBmYWlsdXJlAAAAXAEAAHRyaWVkIHRvIHJlY292ZXIgdXNpbmcgIGJ5dGVzLCBleHBlY3RlZCCkRhgAFwAAALtGGAARAAAA21oQAGcAAACiAAAAUQAAANtaEABnAAAAogAAAE4AAABoAQAA5ywQAGoAAAA8AAAAKQAAAOcsEABqAAAAPAAAAA0AAADnLBAAagAAADoAAAAJAAAA5ywQAGoAAAA+AAAAGgAAAOcsEABqAAAARQAAADwAAADnLBAAagAAAEUAAAAhAAAA5ywQAGoAAAA2AAAACQAAAGFzc2VydGlvbiBmYWlsZWQ6IGV4cGFuZGVkX3NoYXJlZF9zZWNyZXRzLmxlbigpIDw9IE1BWF9QQVRIX0xFTkdUSAAA5ywQAGoA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ICAgICAgICAgYXQgOgAAAFgbGQABAAAACjogAAEAAAAAAAAAZRsZAAIAAAACAEGCt+QACwEEAEGMt+QACzEgAADoIC0gAAEAAAAAAAAAkBsZAAMAAAAgICAgICA8dW5rbm93bj4AAgAAAAAAAAACAEHIt+QAC7UgIACA4O+/vQBOXhAANAAAAGcBAAAwAAAAb3BlcmF0aW9uIG5vdCBzdXBwb3J0ZWQgb24gdGhpcyBwbGF0Zm9ybeAbGQAoAAAAJAAAAAAAAAACAAAACBwZAE9zAAAAAAAABAAAAAQAAABrCQAAY29kZQAAAAABAAAAAQAAAGwJAABraW5kbQkAAAwAAAAEAAAAbgkAAG1lc3NhZ2VLaW5kRXJyb3IAAAAACAAAAAQAAABvCQAAAAAAAAQAAAAEAAAAcAkAAEN1c3RvbWVycm9yZW50aXR5IG5vdCBmb3VuZHBlcm1pc3Npb24gZGVuaWVkY29ubmVjdGlvbiByZWZ1c2VkY29ubmVjdGlvbiByZXNldGhvc3QgdW5yZWFjaGFibGVuZXR3b3JrIHVucmVhY2hhYmxlY29ubmVjdGlvbiBhYm9ydGVkbm90IGNvbm5lY3RlZGFkZHJlc3MgaW4gdXNlYWRkcmVzcyBub3QgYXZhaWxhYmxlbmV0d29yayBkb3duYnJva2VuIHBpcGVlbnRpdHkgYWxyZWFkeSBleGlzdHNvcGVyYXRpb24gd291bGQgYmxvY2tub3QgYSBkaXJlY3RvcnlpcyBhIGRpcmVjdG9yeWRpcmVjdG9yeSBub3QgZW1wdHlyZWFkLW9ubHkgZmlsZXN5c3RlbSBvciBzdG9yYWdlIG1lZGl1bWZpbGVzeXN0ZW0gbG9vcCBvciBpbmRpcmVjdGlvbiBsaW1pdCAoZS5nLiBzeW1saW5rIGxvb3Apc3RhbGUgbmV0d29yayBmaWxlIGhhbmRsZWludmFsaWQgaW5wdXQgcGFyYW1ldGVyaW52YWxpZCBkYXRhdGltZWQgb3V0d3JpdGUgemVyb25vIHN0b3JhZ2Ugc3BhY2VzZWVrIG9uIHVuc2Vla2FibGUgZmlsZXF1b3RhIGV4Y2VlZGVkZmlsZSB0b28gbGFyZ2VyZXNvdXJjZSBidXN5ZXhlY3V0YWJsZSBmaWxlIGJ1c3lkZWFkbG9ja2Nyb3NzLWRldmljZSBsaW5rIG9yIHJlbmFtZXRvbyBtYW55IGxpbmtzaW52YWxpZCBmaWxlbmFtZWFyZ3VtZW50IGxpc3QgdG9vIGxvbmdvcGVyYXRpb24gaW50ZXJydXB0ZWR1bnN1cHBvcnRlZHVuZXhwZWN0ZWQgZW5kIG9mIGZpbGVvdXQgb2YgbWVtb3J5aW4gcHJvZ3Jlc3NvdGhlciBlcnJvcnVuY2F0ZWdvcml6ZWQgZXJyb3JvcGVyYXRpb24gc3VjY2Vzc2Z1bHRpbWUgbm90IGltcGxlbWVudGVkIG9uIHRoaXMgcGxhdGZvcm0AAACYHxkAJQAAAGFMEAAzAAAAHwAAAAkAAABvdmVyZmxvdyB3aGVuIHN1YnRyYWN0aW5nIGR1cmF0aW9ucwCVTBAASAAAAI0EAAAfAAAAb25lLXRpbWUgaW5pdGlhbGl6YXRpb24gbWF5IG5vdCBiZSBwZXJmb3JtZWQgcmVjdXJzaXZlbHkMIBkAOAAAAGNhbm5vdCByZWN1cnNpdmVseSBhY3F1aXJlIG11dGV4TCAZACAAAABcIBAALAAAABMAAAAJAAAAAAAAAAlUEAAjAAAA1wAAABQAAAAJVBAAIwAAANcAAAAxAAAATGF6eUxvY2sgaW5zdGFuY2UgaGFzIHByZXZpb3VzbHkgYmVlbiBwb2lzb25lZAAAqCAZAC4AAAA/PRAAIQAAAJcBAAAFAAAAbWVtb3J5IGFsbG9jYXRpb24gb2YgIGJ5dGVzIGZhaWxlZAAA8CAZABUAAAAFIRkADQAAAEhqEAAYAAAAZAEAAAkAAABjYW5ub3QgYWNjZXNzIGEgVGhyZWFkIExvY2FsIFN0b3JhZ2UgdmFsdWUgZHVyaW5nIG9yIGFmdGVyIGRlc3RydWN0aW9uOiA0IRkASAAAAHVzZSBvZiBzdGQ6OnRocmVhZDo6Y3VycmVudCgpIGlzIG5vdCBwb3NzaWJsZSBhZnRlciB0aGUgdGhyZWFkJ3MgbG9jYWwgZGF0YSBoYXMgYmVlbiBkZXN0cm95ZWQAAIQhGQBeAAAAKQwQACEAAAAPAQAACQAAAGZhaWxlZCB0byBnZW5lcmF0ZSB1bmlxdWUgdGhyZWFkIElEOiBiaXRzcGFjZSBleGhhdXN0ZWQA/CEZADcAAADfYRAAHQAAANQEAAANAAAAAAAAAAgAAAAEAAAAcQkAAHIJAABzCQAAdAkAAG0JAAAMAAAABAAAAHUJAAB2CQAAdwkAAAAAAAAIAAAABAAAAHgJAAB5CQAAegkAAHsJAAB8CQAAEAAAAAQAAAB9CQAAfgkAAH8JAAB0CQAAAAAAAAQAAAAEAAAAgAkAAG92ZXJmbG93IGluIER1cmF0aW9uOjpuZXcAAACVTBAASAAAAMkAAAASAAAAAAAAAAQAAAAEAAAAgQkAAAAAAAAEAAAABAAAAIIJAABlbnZpcm9ubWVudCB2YXJpYWJsZSBub3QgZm91bmRlbnZpcm9ubWVudCB2YXJpYWJsZSB3YXMgbm90IHZhbGlkIHVuaWNvZGU6IAAAMiMZACwAAABXb3VsZEJsb2NrAAAXYxAAUAAAACoCAAARAAAAIChvcyBlcnJvciApAQAAAAAAAACEIxkACwAAAI8jGQABAAAAPHVuc3VwcG9ydGVkPjxkaXNhYmxlZD4AeFQQABwAAAC3AAAAJQAAAEJhY2t0cmFjZSBOb3RGb3VuZFBlcm1pc3Npb25EZW5pZWRDb25uZWN0aW9uUmVmdXNlZENvbm5lY3Rpb25SZXNldEhvc3RVbnJlYWNoYWJsZU5ldHdvcmtVbnJlYWNoYWJsZUNvbm5lY3Rpb25BYm9ydGVkTm90Q29ubmVjdGVkQWRkckluVXNlQWRkck5vdEF2YWlsYWJsZU5ldHdvcmtEb3duQnJva2VuUGlwZUFscmVhZHlFeGlzdHNOb3RBRGlyZWN0b3J5SXNBRGlyZWN0b3J5RGlyZWN0b3J5Tm90RW1wdHlSZWFkT25seUZpbGVzeXN0ZW1GaWxlc3lzdGVtTG9vcFN0YWxlTmV0d29ya0ZpbGVIYW5kbGVJbnZhbGlkSW5wdXRJbnZhbGlkRGF0YVRpbWVkT3V0V3JpdGVaZXJvU3RvcmFnZUZ1bGxOb3RTZWVrYWJsZVF1b3RhRXhjZWVkZWRGaWxlVG9vTGFyZ2VSZXNvdXJjZUJ1c3lFeGVjdXRhYmxlRmlsZUJ1c3lEZWFkbG9ja0Nyb3NzZXNEZXZpY2VzVG9vTWFueUxpbmtzSW52YWxpZEZpbGVuYW1lQXJndW1lbnRMaXN0VG9vTG9uZ0ludGVycnVwdGVkVW5zdXBwb3J0ZWRVbmV4cGVjdGVkRW9mT3V0T2ZNZW1vcnlJblByb2dyZXNz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CwQBAgEYGCsDLAEHAgUJKTo3AQEBBAgEAQMHCgINAQ8BOgEEBAgBFAIaAQICOQEEAgQCAgMDAR4CAwELAjkBBAUBAgQBFAIWBgEBOgECAQEECAEHAgsCHgE9AQwBMgEDATcBAQMFAwEEBwILAh0BOgECAQYBBQIUAhwCOQIEBAgBFAIdAUgBBwMBAVoBAgcLCWIBAgkJAQEHSQIbAQEBAQE3DgEFAQIFCwEkCQFmBAEGAQICAhkCBAMQBA0BAgIGAQ8BXgEAAwADHQIeAh4CQAIBBwgBAgsDAQUBLQUzAUECIgF2AwQCCQEGA9sCAgE6AQEHAQEBAQIIBgoCAScBCB8xBDABAQUBAQUBKAkMAiAEAgIBAzgBAQIDAQEDOggCAkAGUgMBDQEHBAEGAQMCMj8NASJlAAEBAwsDDQMNAw0CDAUIAgoBAgECBTEFAQoBAQ0BEA0zIQACcQN9AQ8BYCAvAQABJAQDBQUBXQZdAwABAAYAAWIEAQoBARwEUAIOIk4BFwNnAwMCCAEDAQQBGQIFAZcCGhINASYIGQsuAzABAgQCAhEBFQJCBgICAgIMAQgBIwELATMBAQMCAgUCAQEbAQ4CBQIBAWQFCQN5AQIBBAEAAZMRABADAQwQIgECAakBBwEGAQsBIwEBAS8BLQJDARUDAAHiAZUFAAYBKgEJAAMBAgUEKAMEAaUCAAQmARoFAQEAAk8ERgsxBHsBNg8pAQICCgMxBAICAgEEAQoBMgMkBQEIPgEMAjQJCgQCAV8DAgEBAgYBAgGdAQMIFQI5AgMBJQcDBUYGDQEBAQEBDgJVCAIDAQEXAVQGAQEEAgEC7gQGAgECGwJVCAIBAQJqAQEBAgYBAWUBAQECBAEFAAkBAgACAQEEAZAEAgIEASAKKAYCBAgBCQYCAy4NAQIABwEGAQFSFgIHAQIBAnoGAwEBAgEHAQFIAgMBAQEAAgsCNAUFAQEBFwEAEQYPAAwDAwAFOwcJBAADKAIAAT8RQAIBAgAEAQcBAgACAQQALgIXAAMJEAIHHgSUAwA3BDIIAQ4BFgUBDwAHARECBwECAQUFPiEBoA4AAT0EAAX+AgAHbQgABQABHmCA8AAAcAAHAC0BAQECAQIBAUgLMBUQAWUHAgYCAgEEIwEeG1sLOgkJARgEAQkBAwEFKwM7CSoYASA3AQEBBAgEAQMHCgIdAToBAQECBAgBCQEKAhoBAgI5AQQCBAICAwMBHgIDAQsCOQEEBQECBAEUAhYGAQE6AQECAQQIAQcDCgIeATsBAQEMAQkBKAEDATcBAQMFAwEEBwILAh0BOgECAgEBAwMBBAcCCwIcAjkCAQECBAgBCQEKAh0BSAEEAQIDAQEIAVEBAgcMCGIBAgkLB0kCGwEBAQEBNw4BBQECBQsBJAkBZgQBBgECAgIZAgQDEAQNAQICBgEPAQADAAQcAx0CHgJAAgEHCAECCwkBLQMBAXUCIgF2AwQCCQEGA9sCAgE6AQEHAQEBAQIIBgoCATAfMQQwCgQDJgkMAiAEAgY4AQECAwEBBTgIAgKYAwENAQcEAQYBAwLGQAABwyEAA40BYCAABmkCAAQBCiACUAIAAQMBBAEZAgUBlwIaEg0BJggZCwEBLAMwAQIEAgICASQBQwYCAgICDAEIAS8BMwEBAwICBQIBASoCCAHuAQIBBAEAAQAQEBAAAgAB4gGVBQADAQIFBCgDBAGlAgAEQQUAAk8ERgsxBHsBNg8pAQICCgMxBAICBwE9AyQFAQg+AQwCNAkBAQgEAgFfAwIEBgECAZ0BAwgVAjkCAQEBAQwBCQEOBwMFQwECBgEBAgEBAwQDAQEOAlUIAgMBARcBUQECBgEBAgEBAgEC6wECBAYCAQIbAlUIAgEBAmoBAQECCGUBAQECBAEFAAkBAvUBCgQEAZAEAgIEASAKKAYCBAgBCQYCAy4NAQIABwEGAQFSFgIHAQIBAnoGAwEBAgEHAQFIAgMBAQEAAgsCNAUFAxcBAAEGDwAMAwMABTsHAAE/BFEBCwIAAgAuAhcABQMGCAgCBx4ElAMANwQyCAEOARYFAQ8ABwERAgcBAgEFZAGgBwABPQQABP4CAAdtBwBggPAAqgEKAQQBBRcBHwHDAQQE0AEkBwIeBWABKgQCAgIEAQEGAQEDAQEBFAFTAYsIpgEmCSkAJgEBBQECKwEEAFYCBgALBSsCA0DAQAACBgImAgYCCAEBAQEBAQEfAjUBBwEBAwMBBwMEAgYEDQUDAQd0AQ0BEA1lAQQBAgoBAQMFBgEBAQEBAQQBBgQBAgQFBQQBESADAgA0AOUGBAMCDCYBAQUBAC4SHoRmAwQBPgICAQEBCBUFAQMAKwEOBlAABwwFABoGGgBQYCQEJHQLAQ8BBwECAQsBDwEHAQIA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AAAGLQAApxAAAActAACoEAAACC0AAKkQAAAJLQAAqhAAAAotAACrEAAACy0AAKwQAAAMLQAArRAAAA0tAACuEAAADi0AAK8QAAAPLQAAsBAAABAtAACxEAAAES0AALIQAAASLQAAsxAAABMtAAC0EAAAFC0AALUQAAAVLQAAthAAABYtAAC3EAAAFy0AALgQAAAYLQAAuRAAABktAAC6EAAAGi0AALsQAAAbLQAAvBAAABwtAAC9EAAAHS0AAL4QAAAeLQAAvxAAAB8tAADAEAAAIC0AAMEQAAAhLQAAwhAAACItAADDEAAAIy0AAMQQAAAkLQAAxRAAACUtAADHEAAAJy0AAM0QAAAtLQAAoBMAAHCrAAChEwAAcasAAKITAAByqwAAoxMAAHOrAACkEwAAdKsAAKUTAAB1qwAAphMAAHarAACnEwAAd6sAAKgTAAB4qwAAqRMAAHmrAACqEwAAeqsAAKsTAAB7qwAArBMAAHyrAACtEwAAfasAAK4TAAB+qwAArxMAAH+rAACwEwAAgKsAALETAACBqwAAshMAAIKrAACzEwAAg6sAALQTAACEqwAAtRMAAIWrAAC2EwAAhqsAALcTAACHqwAAuBMAAIirAAC5EwAAiasAALoTAACKqwAAuxMAAIurAAC8EwAAjKsAAL0TAACNqwAAvhMAAI6rAAC/EwAAj6sAAMATAACQqwAAwRMAAJGrAADCEwAAkqsAAMMTAACTqwAAxBMAAJSrAADFEwAAlasAAMYTAACWqwAAxxMAAJerAADIEwAAmKsAAMkTAACZqwAAyhMAAJqrAADLEwAAm6sAAMwTAACcqwAAzRMAAJ2rAADOEwAAnqsAAM8TAACfqwAA0BMAAKCrAADREwAAoasAANITAACiqwAA0xMAAKOrAADUEwAApKsAANUTAAClqwAA1hMAAKarAADXEwAAp6sAANgTAACoqwAA2RMAAKmrAADaEwAAqqsAANsTAACrqwAA3BMAAKyrAADdEwAArasAAN4TAACuqwAA3xMAAK+rAADgEwAAsKsAAOETAACxqwAA4hMAALKrAADjEwAAs6sAAOQTAAC0qwAA5RMAALWrAADmEwAAtqsAAOcTAAC3qwAA6BMAALirAADpEwAAuasAAOoTAAC6qwAA6xMAALurAADsEwAAvKsAAO0TAAC9qwAA7hMAAL6rAADvEwAAv6sAAPATAAD4EwAA8RMAAPkTAADyEwAA+hMAAPMTAAD7EwAA9BMAAPwTAAD1EwAA/RMAAIkcAACKHAAAkBwAANAQAACRHAAA0RAAAJIcAADSEAAAkxwAANMQAACUHAAA1BAAAJUcAADVEAAAlhwAANYQAACXHAAA1xAAAJgcAADYEAAAmRwAANkQAACaHAAA2hAAAJscAADbEAAAnBwAANwQAACdHAAA3RAAAJ4cAADeEAAAnxwAAN8QAACgHAAA4BAAAKEcAADhEAAAohwAAOIQAACjHAAA4xAAAKQcAADkEAAApRwAAOUQAACmHAAA5hAAAKccAADnEAAAqBwAAOgQAACpHAAA6RAAAKocAADqEAAAqxwAAOsQAACsHAAA7BAAAK0cAADtEAAArhwAAO4QAACvHAAA7xAAALAcAADwEAAAsRwAAPEQAACyHAAA8hAAALMcAADzEAAAtBwAAPQQAAC1HAAA9RAAALYcAAD2EAAAtxwAAPcQAAC4HAAA+BAAALkcAAD5EAAAuhwAAPoQAAC9HAAA/RAAAL4cAAD+EAAAvxwAAP8QAAAAHgAAAR4AAAIeAAADHgAABB4AAAUeAAAGHgAABx4AAAgeAAAJHgAACh4AAAseAAAMHgAADR4AAA4eAAAPHgAAEB4AABEeAAASHgAAEx4AABQeAAAVHgAAFh4AABceAAAYHgAAGR4AABoeAAAbHgAAHB4AAB0eAAAeHgAAHx4AACAeAAAhHgAAIh4AACMeAAAkHgAAJR4AACYeAAAnHgAAKB4AACkeAAAqHgAAKx4AACweAAAtHgAALh4AAC8eAAAwHgAAMR4AADIeAAAzHgAANB4AADUeAAA2HgAANx4AADgeAAA5HgAAOh4AADseAAA8HgAAPR4AAD4eAAA/HgAAQB4AAEEeAABCHgAAQx4AAEQeAABFHgAARh4AAEceAABIHgAASR4AAEoeAABLHgAATB4AAE0eAABOHgAATx4AAFAeAABRHgAAUh4AAFMeAABUHgAAVR4AAFYeAABXHgAAWB4AAFkeAABaHgAAWx4AAFweAABdHgAAXh4AAF8eAABgHgAAYR4AAGIeAABjHgAAZB4AAGUeAABmHgAAZx4AAGgeAABpHgAAah4AAGseAABsHgAAbR4AAG4eAABvHgAAcB4AAHEeAAByHgAAcx4AAHQeAAB1HgAAdh4AAHceAAB4HgAAeR4AAHoeAAB7HgAAfB4AAH0eAAB+HgAAfx4AAIAeAACBHgAAgh4AAIMeAACEHgAAhR4AAIYeAACHHgAAiB4AAIkeAACKHgAAix4AAIweAACNHgAAjh4AAI8eAACQHgAAkR4AAJIeAACTHgAAlB4AAJUeAACeHgAA3wAAAKAeAAChHgAAoh4AAKMeAACkHgAApR4AAKYeAACnHgAAqB4AAKkeAACqHgAAqx4AAKweAACtHgAArh4AAK8eAACwHgAAsR4AALIeAACzHgAAtB4AALUeAAC2HgAAtx4AALgeAAC5HgAAuh4AALseAAC8HgAAvR4AAL4eAAC/HgAAwB4AAMEeAADCHgAAwx4AAMQeAADFHgAAxh4AAMceAADIHgAAyR4AAMoeAADLHgAAzB4AAM0eAADOHgAAzx4AANAeAADRHgAA0h4AANMeAADUHgAA1R4AANYeAADXHgAA2B4AANkeAADaHgAA2x4AANweAADdHgAA3h4AAN8eAADgHgAA4R4AAOIeAADjHgAA5B4AAOUeAADmHgAA5x4AAOgeAADpHgAA6h4AAOseAADsHgAA7R4AAO4eAADvHgAA8B4AAPEeAADyHgAA8x4AAPQeAAD1HgAA9h4AAPceAAD4HgAA+R4AAPoeAAD7HgAA/B4AAP0eAAD+HgAA/x4AAAgfAAAAHwAACR8AAAEfAAAKHwAAAh8AAAsfAAADHwAADB8AAAQfAAANHwAABR8AAA4fAAAGHwAADx8AAAcfAAAYHwAAEB8AABkfAAARHwAAGh8AABIfAAAbHwAAEx8AABwfAAAUHwAAHR8AABUfAAAoHwAAIB8AACkfAAAhHwAAKh8AACIfAAArHwAAIx8AACwfAAAkHwAALR8AACUfAAAuHwAAJh8AAC8fAAAnHwAAOB8AADAfAAA5HwAAMR8AADofAAAyHwAAOx8AADMfAAA8HwAANB8AAD0fAAA1HwAAPh8AADYfAAA/HwAANx8AAEgfAABAHwAASR8AAEEfAABKHwAAQh8AAEsfAABDHwAATB8AAEQfAABNHwAARR8AAFkfAABRHwAAWx8AAFMfAABdHwAAVR8AAF8fAABXHwAAaB8AAGAfAABpHwAAYR8AAGofAABiHwAAax8AAGMfAABsHwAAZB8AAG0fAABlHwAAbh8AAGYfAABvHwAAZx8AAIgfAACAHwAAiR8AAIEfAACKHwAAgh8AAIsfAACDHwAAjB8AAIQfAACNHwAAhR8AAI4fAACGHwAAjx8AAIcfAACYHwAAkB8AAJkfAACRHwAAmh8AAJIfAACbHwAAkx8AAJwfAACUHwAAnR8AAJUfAACeHwAAlh8AAJ8fAACXHwAAqB8AAKAfAACpHwAAoR8AAKofAACiHwAAqx8AAKMfAACsHwAApB8AAK0fAAClHwAArh8AAKYfAACvHwAApx8AALgfAACwHwAAuR8AALEfAAC6HwAAcB8AALsfAABxHwAAvB8AALMfAADIHwAAch8AAMkfAABzHwAAyh8AAHQfAADLHwAAdR8AAMwfAADDHwAA2B8AANAfAADZHwAA0R8AANofAAB2HwAA2x8AAHcfAADoHwAA4B8AAOkfAADhHwAA6h8AAHofAADrHwAAex8AAOwfAADlHwAA+B8AAHgfAAD5HwAAeR8AAPofAAB8HwAA+x8AAH0fAAD8HwAA8x8AACYhAADJAwAAKiEAAGsAAAArIQAA5QAAADIhAABOIQAAYCEAAHAhAABhIQAAcSEAAGIhAAByIQAAYyEAAHMhAABkIQAAdCEAAGUhAAB1IQAAZiEAAHYhAABnIQAAdyEAAGghAAB4IQAAaSEAAHkhAABqIQAAeiEAAGshAAB7IQAAbCEAAHwhAABtIQAAfSEAAG4hAAB+IQAAbyEAAH8hAACDIQAAhCEAALYkAADQJAAAtyQAANEkAAC4JAAA0iQAALkkAADTJAAAuiQAANQkAAC7JAAA1SQAALwkAADWJAAAvSQAANckAAC+JAAA2CQAAL8kAADZJAAAwCQAANokAADBJAAA2yQAAMIkAADcJAAAwyQAAN0kAADEJAAA3iQAAMUkAADfJAAAxiQAAOAkAADHJAAA4SQAAMgkAADiJAAAySQAAOMkAADKJAAA5CQAAMskAADlJAAAzCQAAOYkAADNJAAA5yQAAM4kAADoJAAAzyQAAOkkAAAALAAAMCwAAAEsAAAxLAAAAiwAADIsAAADLAAAMywAAAQsAAA0LAAABSwAADUsAAAGLAAANiwAAAcsAAA3LAAACCwAADgsAAAJLAAAOSwAAAosAAA6LAAACywAADssAAAMLAAAPCwAAA0sAAA9LAAADiwAAD4sAAAPLAAAPywAABAsAABALAAAESwAAEEsAAASLAAAQiwAABMsAABDLAAAFCwAAEQsAAAVLAAARSwAABYsAABGLAAAFywAAEcsAAAYLAAASCwAABksAABJLAAAGiwAAEosAAAbLAAASywAABwsAABMLAAAHSwAAE0sAAAeLAAATiwAAB8sAABPLAAAICwAAFAsAAAhLAAAUSwAACIsAABSLAAAIywAAFMsAAAkLAAAVCwAACUsAABVLAAAJiwAAFYsAAAnLAAAVywAACgsAABYLAAAKSwAAFksAAAqLAAAWiwAACssAABbLAAALCwAAFwsAAAtLAAAXSwAAC4sAABeLAAALywAAF8sAABgLAAAYSwAAGIsAABrAgAAYywAAH0dAABkLAAAfQIAAGcsAABoLAAAaSwAAGosAABrLAAAbCwAAG0sAABRAgAAbiwAAHECAABvLAAAUAIAAHAsAABSAgAAciwAAHMsAAB1LAAAdiwAAH4sAAA/AgAAfywAAEACAACALAAAgSwAAIIsAACDLAAAhCwAAIUsAACGLAAAhywAAIgsAACJLAAAiiwAAIssAACMLAAAjSwAAI4sAACPLAAAkCwAAJEsAACSLAAAkywAAJQsAACVLAAAliwAAJcsAACYLAAAmSwAAJosAACbLAAAnCwAAJ0sAACeLAAAnywAAKAsAAChLAAAoiwAAKMsAACkLAAApSwAAKYsAACnLAAAqCwAAKksAACqLAAAqywAAKwsAACtLAAAriwAAK8sAACwLAAAsSwAALIsAACzLAAAtCwAALUsAAC2LAAAtywAALgsAAC5LAAAuiwAALssAAC8LAAAvSwAAL4sAAC/LAAAwCwAAMEsAADCLAAAwywAAMQsAADFLAAAxiwAAMcsAADILAAAySwAAMosAADLLAAAzCwAAM0sAADOLAAAzywAANAsAADRLAAA0iwAANMsAADULAAA1SwAANYsAADXLAAA2CwAANksAADaLAAA2ywAANwsAADdLAAA3iwAAN8sAADgLAAA4SwAAOIsAADjLAAA6ywAAOwsAADtLAAA7iwAAPIsAADzLAAAQKYAAEGmAABCpgAAQ6YAAESmAABFpgAARqYAAEemAABIpgAASaYAAEqmAABLpgAATKYAAE2mAABOpgAAT6YAAFCmAABRpgAAUqYAAFOmAABUpgAAVaYAAFamAABXpgAAWKYAAFmmAABapgAAW6YAAFymAABdpgAAXqYAAF+mAABgpgAAYaYAAGKmAABjpgAAZKYAAGWmAABmpgAAZ6YAAGimAABppgAAaqYAAGumAABspgAAbaYAAICmAACBpgAAgqYAAIOmAACEpgAAhaYAAIamAACHpgAAiKYAAImmAACKpgAAi6YAAIymAACNpgAAjqYAAI+mAACQpgAAkaYAAJKmAACTpgAAlKYAAJWmAACWpgAAl6YAAJimAACZpgAAmqYAAJumAAAipwAAI6cAACSnAAAlpwAAJqcAACenAAAopwAAKacAACqnAAArpwAALKcAAC2nAAAupwAAL6cAADKnAAAzpwAANKcAADWnAAA2pwAAN6cAADinAAA5pwAAOqcAADunAAA8pwAAPacAAD6nAAA/pwAAQKcAAEGnAABCpwAAQ6cAAESnAABFpwAARqcAAEenAABIpwAASacAAEqnAABLpwAATKcAAE2nAABOpwAAT6cAAFCnAABRpwAAUqcAAFOnAABUpwAAVacAAFanAABXpwAAWKcAAFmnAABapwAAW6cAAFynAABdpwAAXqcAAF+nAABgpwAAYacAAGKnAABjpwAAZKcAAGWnAABmpwAAZ6cAAGinAABppwAAaqcAAGunAABspwAAbacAAG6nAABvpwAAeacAAHqnAAB7pwAAfKcAAH2nAAB5HQAAfqcAAH+nAACApwAAgacAAIKnAACDpwAAhKcAAIWnAACGpwAAh6cAAIunAACMpwAAjacAAGUCAACQpwAAkacAAJKnAACTpwAAlqcAAJenAACYpwAAmacAAJqnAACbpwAAnKcAAJ2nAACepwAAn6cAAKCnAAChpwAAoqcAAKOnAACkpwAApacAAKanAACnpwAAqKcAAKmnAACqpwAAZgIAAKunAABcAgAArKcAAGECAACtpwAAbAIAAK6nAABqAgAAsKcAAJ4CAACxpwAAhwIAALKnAACdAgAAs6cAAFOrAAC0pwAAtacAALanAAC3pwAAuKcAALmnAAC6pwAAu6cAALynAAC9pwAAvqcAAL+nAADApwAAwacAAMKnAADDpwAAxKcAAJSnAADFpwAAggIAAManAACOHQAAx6cAAMinAADJpwAAyqcAAMunAABkAgAAzKcAAM2nAADQpwAA0acAANanAADXpwAA2KcAANmnAADapwAA26cAANynAACbAQAA9acAAPanAAAh/wAAQf8AACL/AABC/wAAI/8AAEP/AAAk/wAARP8AACX/AABF/wAAJv8AAEb/AAAn/wAAR/8AACj/AABI/wAAKf8AAEn/AAAq/wAASv8AACv/AABL/wAALP8AAEz/AAAt/wAATf8AAC7/AABO/wAAL/8AAE//AAAw/wAAUP8AADH/AABR/wAAMv8AAFL/AAAz/wAAU/8AADT/AABU/wAANf8AAFX/AAA2/wAAVv8AADf/AABX/wAAOP8AAFj/AAA5/wAAWf8AADr/AABa/wAAAAQBACgEAQABBAEAKQQBAAIEAQAqBAEAAwQBACsEAQAEBAEALAQBAAUEAQAtBAEABgQBAC4EAQAHBAEALwQBAAgEAQAwBAEACQQBADEEAQAKBAEAMgQBAAsEAQAzBAEADAQBADQEAQANBAEANQQBAA4EAQA2BAEADwQBADcEAQAQBAEAOAQBABEEAQA5BAEAEgQBADoEAQATBAEAOwQBABQEAQA8BAEAFQQBAD0EAQAWBAEAPgQBABcEAQA/BAEAGAQBAEAEAQAZBAEAQQQBABoEAQBCBAEAGwQBAEMEAQAcBAEARAQBAB0EAQBFBAEAHgQBAEYEAQAfBAEARwQBACAEAQBIBAEAIQQBAEkEAQAiBAEASgQBACMEAQBLBAEAJAQBAEwEAQAlBAEATQQBACYEAQBOBAEAJwQBAE8EAQCwBAEA2AQBALEEAQDZBAEAsgQBANoEAQCzBAEA2wQBALQEAQDcBAEAtQQBAN0EAQC2BAEA3gQBALcEAQDfBAEAuAQBAOAEAQC5BAEA4QQBALoEAQDiBAEAuwQBAOMEAQC8BAEA5AQBAL0EAQDlBAEAvgQBAOYEAQC/BAEA5wQBAMAEAQDoBAEAwQQBAOkEAQDCBAEA6gQBAMMEAQDrBAEAxAQBAOwEAQDFBAEA7QQBAMYEAQDuBAEAxwQBAO8EAQDIBAEA8AQBAMkEAQDxBAEAygQBAPIEAQDLBAEA8wQBAMwEAQD0BAEAzQQBAPUEAQDOBAEA9gQBAM8EAQD3BAEA0AQBAPgEAQDRBAEA+QQBANIEAQD6BAEA0wQBAPsEAQBwBQEAlwUBAHEFAQCYBQEAcgUBAJkFAQBzBQEAmgUBAHQFAQCbBQEAdQUBAJwFAQB2BQEAnQUBAHcFAQCeBQEAeAUBAJ8FAQB5BQEAoAUBAHoFAQChBQEAfAUBAKMFAQB9BQEApAUBAH4FAQClBQEAfwUBAKYFAQCABQEApwUBAIEFAQCoBQEAggUBAKkFAQCDBQEAqgUBAIQFAQCrBQEAhQUBAKwFAQCGBQEArQUBAIcFAQCuBQEAiAUBAK8FAQCJBQEAsAUBAIoFAQCxBQEAjAUBALMFAQCNBQEAtAUBAI4FAQC1BQEAjwUBALYFAQCQBQEAtwUBAJEFAQC4BQEAkgUBALkFAQCUBQEAuwUBAJUFAQC8BQEAgAwBAMAMAQCBDAEAwQwBAIIMAQDCDAEAgwwBAMMMAQCEDAEAxAwBAIUMAQDFDAEAhgwBAMYMAQCHDAEAxwwBAIgMAQDIDAEAiQwBAMkMAQCKDAEAygwBAIsMAQDLDAEAjAwBAMwMAQCNDAEAzQwBAI4MAQDODAEAjwwBAM8MAQCQDAEA0AwBAJEMAQDRDAEAkgwBANIMAQCTDAEA0wwBAJQMAQDUDAEAlQwBANUMAQCWDAEA1gwBAJcMAQDXDAEAmAwBANgMAQCZDAEA2QwBAJoMAQDaDAEAmwwBANsMAQCcDAEA3AwBAJ0MAQDdDAEAngwBAN4MAQCfDAEA3wwBAKAMAQDgDAEAoQwBAOEMAQCiDAEA4gwBAKMMAQDjDAEApAwBAOQMAQClDAEA5QwBAKYMAQDmDAEApwwBAOcMAQCoDAEA6AwBAKkMAQDpDAEAqgwBAOoMAQCrDAEA6wwBAKwMAQDsDAEArQwBAO0MAQCuDAEA7gwBAK8MAQDvDAEAsAwBAPAMAQCxDAEA8QwBALIMAQDyDAEAUA0BAHANAQBRDQEAcQ0BAFINAQByDQEAUw0BAHMNAQBUDQEAdA0BAFUNAQB1DQEAVg0BAHYNAQBXDQEAdw0BAFgNAQB4DQEAWQ0BAHkNAQBaDQEAeg0BAFsNAQB7DQEAXA0BAHwNAQBdDQEAfQ0BAF4NAQB+DQEAXw0BAH8NAQBgDQEAgA0BAGENAQCBDQEAYg0BAIINAQBjDQEAgw0BAGQNAQCEDQEAZQ0BAIUNAQCgGAEAwBgBAKEYAQDBGAEAohgBAMIYAQCjGAEAwxgBAKQYAQDEGAEApRgBAMUYAQCmGAEAxhgBAKcYAQDHGAEAqBgBAMgYAQCpGAEAyRgBAKoYAQDKGAEAqxgBAMsYAQCsGAEAzBgBAK0Y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AP8AAADA0BEAAAAAAP8AAABA0BEAAAAAAP8AAADA0REAAAAAAP8AAABE0hEAAAAAAP8AAABE1BEAAAAAAP8AAADE0hEAAAAAAP8AAABE0xEAAAAAAP8AAADE0xEAAAAAAP8AAABE1REAAAAAAP8AAADE1BEAAAAAAP8AAACU2BEAAAAAAP8AAAD82REAAAAAAP8AAAA81hEAAAAAAP8AAAAM2REAAAAAAP8AAAAc2BEAAAAAAP8AAACk1xEAAAAAAP8AAADs2hEAAAAAAP8AAAAs1xEAAAAAAP8AAABk2xEAAAAAAP8AAACE2REAAAAAAP8AAAB02hEAAAAAAP8AAAC01hEAAAAAAP8AAABwVRIAAAAAAP8AAADoVRIAAAAAAP8AAABIVhIAAAAAAP8AAACsVhIAAAAAAP8AAAAgVxIAAAAAAP8AAACMVxIAAAAAAP8AAACgcRIAAAAAAP8AAABEchIAAAAAAP8AAAB8cxIAAAAAAP8AAACAjRIAAAAAAP8AAACAjhIAAAAAAP8AAABUjxIAAAAAAP8AAAAskBIAAAAAAP8AAADAjxIAAAAAAP8AAABUkRIAAAAAAP8AAADokBIAAAAAAP8AAADQkRIAAAAAAP8AAAA8khIAAAAAAP8AAACokhIAAAAAAP8AAABMlBIAAAAAAP8AAADMnRIAAAAAAP8AAAABAEGuyOYAC0QCAETPFAAAAAAA/wAAANTOFAAAAAAA/wAAALTPFAAAAAAA/wAAACTQFAAAAAAA/wAAADzTFAAAAAAA/wAAAAAAAADPBQBBmMnmAAsC0AUAQcDJ5gALUUz4FAAAAAAA/wAAAFz5FAAAAAAA/wAAADD8FAAAAAAA/wAAAED9FAAAAAAA/wAAACQAFQAAAAAA/wAAAIgAFQAAAAAA/wAAAOwAFQAAAAAA/wBBqMrmAAsVAgAAAKgGAAABAAAAwGUYAAAAAAACAEHIyuYACxUBAAAAAAAAANhlGADYZRgABQAAAAEAQfjK5gALBTQJAAADAEGIy+YACy4CAAAAAAAAAEsJAAACAAAAAAAAAEwJAAACAAAAAAAAAE0JAAACAAAAAAAAAE4JAEHAy+YACwJPCQBB3MvmAAsCXQkAfAlwcm9kdWNlcnMCCGxhbmd1YWdlAQRSdXN0AAxwcm9jZXNzZWQtYnkDBXJ1c3RjHTEuOTEuMCAoZjgyOTdlMzUxIDIwMjUtMTAtMjgpBndhbHJ1cwYwLjIzLjMMd2FzbS1iaW5kZ2VuEzAuMi4xMDAgKDI0MDVlYzJiNCkAaw90YXJnZXRfZmVhdHVyZXMGKw9tdXRhYmxlLWdsb2JhbHMrE25vbnRyYXBwaW5nLWZwdG9pbnQrC2J1bGstbWVtb3J5KwhzaWduLWV4dCsPcmVmZXJlbmNlLXR5cGVzKwptdWx0aXZhbHVl', imports)} + +let wasm; + +let WASM_VECTOR_LEN = 0; + +let cachedUint8ArrayMemory0 = null; + +function getUint8ArrayMemory0() { + if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) { + cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8ArrayMemory0; +} + +const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } ); + +const encodeString = (typeof cachedTextEncoder.encodeInto === 'function' + ? function (arg, view) { + return cachedTextEncoder.encodeInto(arg, view); +} + : function (arg, view) { + const buf = cachedTextEncoder.encode(arg); + view.set(buf); + return { + read: arg.length, + written: buf.length + }; +}); + +function passStringToWasm0(arg, malloc, realloc) { + + if (realloc === undefined) { + const buf = cachedTextEncoder.encode(arg); + const ptr = malloc(buf.length, 1) >>> 0; + getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf); + WASM_VECTOR_LEN = buf.length; + return ptr; + } + + let len = arg.length; + let ptr = malloc(len, 1) >>> 0; + + const mem = getUint8ArrayMemory0(); + + let offset = 0; + + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7F) break; + mem[ptr + offset] = code; + } + + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset); + } + ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0; + const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len); + const ret = encodeString(arg, view); + + offset += ret.written; + ptr = realloc(ptr, len, offset, 1) >>> 0; + } + + WASM_VECTOR_LEN = offset; + return ptr; +} + +let cachedDataViewMemory0 = null; + +function getDataViewMemory0() { + if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) { + cachedDataViewMemory0 = new DataView(wasm.memory.buffer); + } + return cachedDataViewMemory0; +} + +function addToExternrefTable0(obj) { + const idx = wasm.__externref_table_alloc(); + wasm.__wbindgen_export_4.set(idx, obj); + return idx; +} + +function handleError(f, args) { + try { + return f.apply(this, args); + } catch (e) { + const idx = addToExternrefTable0(e); + wasm.__wbindgen_exn_store(idx); + } +} + +const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } ); + +if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); } +function getStringFromWasm0(ptr, len) { + ptr = ptr >>> 0; + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + +function isLikeNone(x) { + return x === undefined || x === null; +} + +function getArrayU8FromWasm0(ptr, len) { + ptr = ptr >>> 0; + return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len); +} + +const CLOSURE_DTORS = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(state => { + wasm.__wbindgen_export_5.get(state.dtor)(state.a, state.b); +}); + +function makeMutClosure(arg0, arg1, dtor, f) { + const state = { a: arg0, b: arg1, cnt: 1, dtor }; + const real = (...args) => { + // First up with a closure we increment the internal reference + // count. This ensures that the Rust closure environment won't + // be deallocated while we're invoking it. + state.cnt++; + const a = state.a; + state.a = 0; + try { + return f(a, state.b, ...args); + } finally { + if (--state.cnt === 0) { + wasm.__wbindgen_export_5.get(state.dtor)(a, state.b); + CLOSURE_DTORS.unregister(state); + } else { + state.a = a; + } + } + }; + real.original = state; + CLOSURE_DTORS.register(real, state, state); + return real; +} + +function debugString(val) { + // primitive types + const type = typeof val; + if (type == 'number' || type == 'boolean' || val == null) { + return `${val}`; + } + if (type == 'string') { + return `"${val}"`; + } + if (type == 'symbol') { + const description = val.description; + if (description == null) { + return 'Symbol'; + } else { + return `Symbol(${description})`; + } + } + if (type == 'function') { + const name = val.name; + if (typeof name == 'string' && name.length > 0) { + return `Function(${name})`; + } else { + return 'Function'; + } + } + // objects + if (Array.isArray(val)) { + const length = val.length; + let debug = '['; + if (length > 0) { + debug += debugString(val[0]); + } + for(let i = 1; i < length; i++) { + debug += ', ' + debugString(val[i]); + } + debug += ']'; + return debug; + } + // Test for built-in + const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val)); + let className; + if (builtInMatches && builtInMatches.length > 1) { + className = builtInMatches[1]; + } else { + // Failed to match the standard '[object ClassName]' + return toString.call(val); + } + if (className == 'Object') { + // we're a user defined class or Object + // JSON.stringify avoids problems with cycles, and is generally much + // easier than looping through ownProperties of `val`. + try { + return 'Object(' + JSON.stringify(val) + ')'; + } catch (_) { + return 'Object'; + } + } + // errors + if (val instanceof Error) { + return `${val.name}: ${val.message}\n${val.stack}`; + } + // TODO we could test for more things here, like `Set`s and `Map`s. + return className; +} + +function takeFromExternrefTable0(idx) { + const value = wasm.__wbindgen_export_4.get(idx); + wasm.__externref_table_dealloc(idx); + return value; +} + +function __wbg_adapter_52(arg0, arg1, arg2) { + const ret = wasm.closure376_externref_shim_multivalue_shim(arg0, arg1, arg2); + if (ret[1]) { + throw takeFromExternrefTable0(ret[0]); + } +} + +function __wbg_adapter_55(arg0, arg1, arg2) { + wasm.closure578_externref_shim(arg0, arg1, arg2); +} + +function __wbg_adapter_58(arg0, arg1) { + wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h5f07214c5ea9e2c2(arg0, arg1); +} + +function __wbg_adapter_61(arg0, arg1) { + wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h1493ada6ea6dbab7(arg0, arg1); +} + +function __wbg_adapter_64(arg0, arg1) { + wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hfcd93e280acb29be(arg0, arg1); +} + +function __wbg_adapter_67(arg0, arg1, arg2) { + wasm.closure1680_externref_shim(arg0, arg1, arg2); +} + +function __wbg_adapter_72(arg0, arg1) { + wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h7966d21919d30dcf(arg0, arg1); +} + +function __wbg_adapter_77(arg0, arg1, arg2) { + wasm.closure1694_externref_shim(arg0, arg1, arg2); +} + +function __wbg_adapter_452(arg0, arg1, arg2, arg3) { + wasm.closure2385_externref_shim(arg0, arg1, arg2, arg3); +} + +const __wbindgen_enum_BinaryType = ["blob", "arraybuffer"]; + +const __wbindgen_enum_IdbRequestReadyState = ["pending", "done"]; + +const __wbindgen_enum_IdbTransactionMode = ["readonly", "readwrite", "versionchange", "readwriteflush", "cleanup"]; + +const __wbindgen_enum_RequestCredentials = ["omit", "same-origin", "include"]; + +const __wbindgen_enum_RequestMode = ["same-origin", "no-cors", "cors", "navigate"]; + +(typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_acknowledgementswasm_free(ptr >>> 0, 1)); + +(typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_anonymoussendertag_free(ptr >>> 0, 1)); + +const ClientStorageFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_clientstorage_free(ptr >>> 0, 1)); + +class ClientStorage { + + static __wrap(ptr) { + ptr = ptr >>> 0; + const obj = Object.create(ClientStorage.prototype); + obj.__wbg_ptr = ptr; + ClientStorageFinalization.register(obj, obj.__wbg_ptr, obj); + return obj; + } + + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + ClientStorageFinalization.unregister(this); + return ptr; + } + + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_clientstorage_free(ptr, 0); + } + /** + * @param {string} client_id + * @returns {Promise} + */ + static new_unencrypted(client_id) { + const ptr0 = passStringToWasm0(client_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.clientstorage_new_unencrypted(ptr0, len0); + return ret; + } + /** + * @param {string} client_id + * @param {string} passphrase + */ + constructor(client_id, passphrase) { + const ptr0 = passStringToWasm0(client_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(passphrase, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + const ret = wasm.clientstorage_new(ptr0, len0, ptr1, len1); + return ret; + } + /** + * @param {string} client_id + * @param {string | null} [passphrase] + * @returns {Promise} + */ + static new_async(client_id, passphrase) { + const ptr0 = passStringToWasm0(client_id, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + var ptr1 = isLikeNone(passphrase) ? 0 : passStringToWasm0(passphrase, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len1 = WASM_VECTOR_LEN; + const ret = wasm.clientstorage_new_async(ptr0, len0, ptr1, len1); + return ret; + } +} + +(typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_covertrafficwasm_free(ptr >>> 0, 1)); + +(typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_debugwasm_free(ptr >>> 0, 1)); + +(typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_forgetmewasm_free(ptr >>> 0, 1)); + +(typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_gatewayconnectionwasm_free(ptr >>> 0, 1)); + +const NodeTestResultFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_nodetestresult_free(ptr >>> 0, 1)); + +class NodeTestResult { + + static __wrap(ptr) { + ptr = ptr >>> 0; + const obj = Object.create(NodeTestResult.prototype); + obj.__wbg_ptr = ptr; + NodeTestResultFinalization.register(obj, obj.__wbg_ptr, obj); + return obj; + } + + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + NodeTestResultFinalization.unregister(this); + return ptr; + } + + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_nodetestresult_free(ptr, 0); + } + log_details() { + wasm.nodetestresult_log_details(this.__wbg_ptr); + } + /** + * @returns {number} + */ + score() { + const ret = wasm.nodetestresult_score(this.__wbg_ptr); + return ret; + } + /** + * @returns {number} + */ + get sent_packets() { + const ret = wasm.__wbg_get_nodetestresult_sent_packets(this.__wbg_ptr); + return ret >>> 0; + } + /** + * @param {number} arg0 + */ + set sent_packets(arg0) { + wasm.__wbg_set_nodetestresult_sent_packets(this.__wbg_ptr, arg0); + } + /** + * @returns {number} + */ + get received_packets() { + const ret = wasm.__wbg_get_nodetestresult_received_packets(this.__wbg_ptr); + return ret >>> 0; + } + /** + * @param {number} arg0 + */ + set received_packets(arg0) { + wasm.__wbg_set_nodetestresult_received_packets(this.__wbg_ptr, arg0); + } + /** + * @returns {number} + */ + get received_acks() { + const ret = wasm.__wbg_get_nodetestresult_received_acks(this.__wbg_ptr); + return ret >>> 0; + } + /** + * @param {number} arg0 + */ + set received_acks(arg0) { + wasm.__wbg_set_nodetestresult_received_acks(this.__wbg_ptr, arg0); + } + /** + * @returns {number} + */ + get duplicate_packets() { + const ret = wasm.__wbg_get_nodetestresult_duplicate_packets(this.__wbg_ptr); + return ret >>> 0; + } + /** + * @param {number} arg0 + */ + set duplicate_packets(arg0) { + wasm.__wbg_set_nodetestresult_duplicate_packets(this.__wbg_ptr, arg0); + } + /** + * @returns {number} + */ + get duplicate_acks() { + const ret = wasm.__wbg_get_nodetestresult_duplicate_acks(this.__wbg_ptr); + return ret >>> 0; + } + /** + * @param {number} arg0 + */ + set duplicate_acks(arg0) { + wasm.__wbg_set_nodetestresult_duplicate_acks(this.__wbg_ptr, arg0); + } +} + +const NymNodeTesterFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_nymnodetester_free(ptr >>> 0, 1)); + +class NymNodeTester { + + static __wrap(ptr) { + ptr = ptr >>> 0; + const obj = Object.create(NymNodeTester.prototype); + obj.__wbg_ptr = ptr; + NymNodeTesterFinalization.register(obj, obj.__wbg_ptr, obj); + return obj; + } + + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + NymNodeTesterFinalization.unregister(this); + return ptr; + } + + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_nymnodetester_free(ptr, 0); + } + /** + * @returns {Promise} + */ + reconnect_to_gateway() { + const ret = wasm.nymnodetester_reconnect_to_gateway(this.__wbg_ptr); + return ret; + } + /** + * @returns {Promise} + */ + disconnect_from_gateway() { + const ret = wasm.nymnodetester_disconnect_from_gateway(this.__wbg_ptr); + return ret; + } + /** + * @param {NymNodeTesterOpts} args + */ + constructor(args) { + const ret = wasm.nymnodetester_new(args); + return ret; + } + /** + * @param {string} mixnode_identity + * @param {bigint | null} [timeout_millis] + * @param {number | null} [num_test_packets] + * @returns {Promise} + */ + test_node(mixnode_identity, timeout_millis, num_test_packets) { + const ptr0 = passStringToWasm0(mixnode_identity, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.nymnodetester_test_node(this.__wbg_ptr, ptr0, len0, !isLikeNone(timeout_millis), isLikeNone(timeout_millis) ? BigInt(0) : timeout_millis, isLikeNone(num_test_packets) ? 0x100000001 : (num_test_packets) >>> 0); + return ret; + } +} + +const NymNodeTesterBuilderFinalization = (typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_nymnodetesterbuilder_free(ptr >>> 0, 1)); + +class NymNodeTesterBuilder { + + static __wrap(ptr) { + ptr = ptr >>> 0; + const obj = Object.create(NymNodeTesterBuilder.prototype); + obj.__wbg_ptr = ptr; + NymNodeTesterBuilderFinalization.register(obj, obj.__wbg_ptr, obj); + return obj; + } + + __destroy_into_raw() { + const ptr = this.__wbg_ptr; + this.__wbg_ptr = 0; + NymNodeTesterBuilderFinalization.unregister(this); + return ptr; + } + + free() { + const ptr = this.__destroy_into_raw(); + wasm.__wbg_nymnodetesterbuilder_free(ptr, 0); + } + /** + * @returns {Promise} + */ + setup_client() { + const ptr = this.__destroy_into_raw(); + const ret = wasm.nymnodetesterbuilder_setup_client(ptr); + return ret; + } + /** + * @param {NymNodeTesterOpts} args + */ + constructor(args) { + const ret = wasm.nymnodetesterbuilder_new(args); + return ret; + } +} + +(typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_remembermewasm_free(ptr >>> 0, 1)); + +(typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_replysurbswasm_free(ptr >>> 0, 1)); + +(typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_statsreportingwasm_free(ptr >>> 0, 1)); + +(typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_topologywasm_free(ptr >>> 0, 1)); + +(typeof FinalizationRegistry === 'undefined') + ? { register: () => {}, unregister: () => {} } + : new FinalizationRegistry(ptr => wasm.__wbg_trafficwasm_free(ptr >>> 0, 1)); + +async function __wbg_load(module, imports) { + if (typeof Response === 'function' && module instanceof Response) { + if (typeof WebAssembly.instantiateStreaming === 'function') { + try { + return await WebAssembly.instantiateStreaming(module, imports); + + } catch (e) { + if (module.headers.get('Content-Type') != 'application/wasm') { + console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); + + } else { + throw e; + } + } + } + + const bytes = await module.arrayBuffer(); + return await WebAssembly.instantiate(bytes, imports); + + } else { + const instance = await WebAssembly.instantiate(module, imports); + + if (instance instanceof WebAssembly.Instance) { + return { instance, module }; + + } else { + return instance; + } + } +} + +function __wbg_get_imports() { + const imports = {}; + imports.wbg = {}; + imports.wbg.__wbg_String_8f0eb39a4a4c2f66 = function(arg0, arg1) { + const ret = String(arg1); + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }; + imports.wbg.__wbg_String_eecc4a11987127d6 = function(arg0, arg1) { + const ret = String(arg1); + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }; + imports.wbg.__wbg_Window_41559019033ede94 = function(arg0) { + const ret = arg0.Window; + return ret; + }; + imports.wbg.__wbg_WorkerGlobalScope_d324bffbeaef9f3a = function(arg0) { + const ret = arg0.WorkerGlobalScope; + return ret; + }; + imports.wbg.__wbg_abort_410ec47a64ac6117 = function(arg0, arg1) { + arg0.abort(arg1); + }; + imports.wbg.__wbg_abort_775ef1d17fc65868 = function(arg0) { + arg0.abort(); + }; + imports.wbg.__wbg_abort_99fc644e2c79c9fb = function() { return handleError(function (arg0) { + arg0.abort(); + }, arguments) }; + imports.wbg.__wbg_addEventListener_84ae3eac6e15480a = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) { + arg0.addEventListener(getStringFromWasm0(arg1, arg2), arg3, arg4); + }, arguments) }; + imports.wbg.__wbg_addEventListener_90e553fdce254421 = function() { return handleError(function (arg0, arg1, arg2, arg3) { + arg0.addEventListener(getStringFromWasm0(arg1, arg2), arg3); + }, arguments) }; + imports.wbg.__wbg_append_8c7dd8d641a5f01b = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) { + arg0.append(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4)); + }, arguments) }; + imports.wbg.__wbg_arrayBuffer_d1b44c4390db422f = function() { return handleError(function (arg0) { + const ret = arg0.arrayBuffer(); + return ret; + }, arguments) }; + imports.wbg.__wbg_bound_f2afc3766d4545cf = function() { return handleError(function (arg0, arg1, arg2, arg3) { + const ret = IDBKeyRange.bound(arg0, arg1, arg2 !== 0, arg3 !== 0); + return ret; + }, arguments) }; + imports.wbg.__wbg_buffer_609cc3eee51ed158 = function(arg0) { + const ret = arg0.buffer; + return ret; + }; + imports.wbg.__wbg_call_672a4d21634d4a24 = function() { return handleError(function (arg0, arg1) { + const ret = arg0.call(arg1); + return ret; + }, arguments) }; + imports.wbg.__wbg_call_7cccdd69e0791ae2 = function() { return handleError(function (arg0, arg1, arg2) { + const ret = arg0.call(arg1, arg2); + return ret; + }, arguments) }; + imports.wbg.__wbg_clearTimeout_0b53d391c1b94dda = function(arg0) { + const ret = clearTimeout(arg0); + return ret; + }; + imports.wbg.__wbg_clientstorage_new = function(arg0) { + const ret = ClientStorage.__wrap(arg0); + return ret; + }; + imports.wbg.__wbg_close_2893b7d056a0627d = function() { return handleError(function (arg0) { + arg0.close(); + }, arguments) }; + imports.wbg.__wbg_code_f4ec1e6e2e1b0417 = function(arg0) { + const ret = arg0.code; + return ret; + }; + imports.wbg.__wbg_commit_a54edce65f3858f2 = function() { return handleError(function (arg0) { + arg0.commit(); + }, arguments) }; + imports.wbg.__wbg_count_9dbedee4d2474ff8 = function() { return handleError(function (arg0, arg1) { + const ret = arg0.count(arg1); + return ret; + }, arguments) }; + imports.wbg.__wbg_createObjectStore_e566459f7161f82f = function() { return handleError(function (arg0, arg1, arg2) { + const ret = arg0.createObjectStore(getStringFromWasm0(arg1, arg2)); + return ret; + }, arguments) }; + imports.wbg.__wbg_crypto_574e78ad8b13b65f = function(arg0) { + const ret = arg0.crypto; + return ret; + }; + imports.wbg.__wbg_data_432d9c3df2630942 = function(arg0) { + const ret = arg0.data; + return ret; + }; + imports.wbg.__wbg_dispatchEvent_9e259d7c1d603dfb = function() { return handleError(function (arg0, arg1) { + const ret = arg0.dispatchEvent(arg1); + return ret; + }, arguments) }; + imports.wbg.__wbg_done_769e5ede4b31c67b = function(arg0) { + const ret = arg0.done; + return ret; + }; + imports.wbg.__wbg_entries_3265d4158b33e5dc = function(arg0) { + const ret = Object.entries(arg0); + return ret; + }; + imports.wbg.__wbg_error_9b6c8c01427f9836 = function(arg0, arg1) { + console.error(getStringFromWasm0(arg0, arg1)); + }; + imports.wbg.__wbg_error_ff4ddaabdfc5dbb3 = function() { return handleError(function (arg0) { + const ret = arg0.error; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }, arguments) }; + imports.wbg.__wbg_fetch_11bff8299d0ecd2b = function(arg0) { + const ret = fetch(arg0); + return ret; + }; + imports.wbg.__wbg_fetch_509096533071c657 = function(arg0, arg1) { + const ret = arg0.fetch(arg1); + return ret; + }; + imports.wbg.__wbg_getRandomValues_b8f5dbd5f3995a9e = function() { return handleError(function (arg0, arg1) { + arg0.getRandomValues(arg1); + }, arguments) }; + imports.wbg.__wbg_getTime_46267b1c24877e30 = function(arg0) { + const ret = arg0.getTime(); + return ret; + }; + imports.wbg.__wbg_get_67b2ba62fc30de12 = function() { return handleError(function (arg0, arg1) { + const ret = Reflect.get(arg0, arg1); + return ret; + }, arguments) }; + imports.wbg.__wbg_get_8da03f81f6a1111e = function() { return handleError(function (arg0, arg1) { + const ret = arg0.get(arg1); + return ret; + }, arguments) }; + imports.wbg.__wbg_get_b9b93047fe3cf45b = function(arg0, arg1) { + const ret = arg0[arg1 >>> 0]; + return ret; + }; + imports.wbg.__wbg_getwithrefkey_1dc361bd10053bfe = function(arg0, arg1) { + const ret = arg0[arg1]; + return ret; + }; + imports.wbg.__wbg_getwithrefkey_6550b2c093d2eb18 = function(arg0, arg1) { + const ret = arg0[arg1]; + return ret; + }; + imports.wbg.__wbg_global_f5c2926e57ba457f = function(arg0) { + const ret = arg0.global; + return ret; + }; + imports.wbg.__wbg_has_a5ea9117f258a0ec = function() { return handleError(function (arg0, arg1) { + const ret = Reflect.has(arg0, arg1); + return ret; + }, arguments) }; + imports.wbg.__wbg_headers_9cb51cfd2ac780a4 = function(arg0) { + const ret = arg0.headers; + return ret; + }; + imports.wbg.__wbg_indexedDB_54f01430b1e194e8 = function() { return handleError(function (arg0) { + const ret = arg0.indexedDB; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }, arguments) }; + imports.wbg.__wbg_indexedDB_b1f49280282046f8 = function() { return handleError(function (arg0) { + const ret = arg0.indexedDB; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }, arguments) }; + imports.wbg.__wbg_indexedDB_f6b47b0dc333fd2f = function() { return handleError(function (arg0) { + const ret = arg0.indexedDB; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }, arguments) }; + imports.wbg.__wbg_instanceof_ArrayBuffer_e14585432e3737fc = function(arg0) { + let result; + try { + result = arg0 instanceof ArrayBuffer; + } catch (_) { + result = false; + } + const ret = result; + return ret; + }; + imports.wbg.__wbg_instanceof_DomException_ed1ccb7aaf39034c = function(arg0) { + let result; + try { + result = arg0 instanceof DOMException; + } catch (_) { + result = false; + } + const ret = result; + return ret; + }; + imports.wbg.__wbg_instanceof_Error_4d54113b22d20306 = function(arg0) { + let result; + try { + result = arg0 instanceof Error; + } catch (_) { + result = false; + } + const ret = result; + return ret; + }; + imports.wbg.__wbg_instanceof_IdbDatabase_a3ef009ca00059f9 = function(arg0) { + let result; + try { + result = arg0 instanceof IDBDatabase; + } catch (_) { + result = false; + } + const ret = result; + return ret; + }; + imports.wbg.__wbg_instanceof_IdbRequest_4813c3f207666aa4 = function(arg0) { + let result; + try { + result = arg0 instanceof IDBRequest; + } catch (_) { + result = false; + } + const ret = result; + return ret; + }; + imports.wbg.__wbg_instanceof_Response_f2cc20d9f7dfd644 = function(arg0) { + let result; + try { + result = arg0 instanceof Response; + } catch (_) { + result = false; + } + const ret = result; + return ret; + }; + imports.wbg.__wbg_instanceof_Uint8Array_17156bcf118086a9 = function(arg0) { + let result; + try { + result = arg0 instanceof Uint8Array; + } catch (_) { + result = false; + } + const ret = result; + return ret; + }; + imports.wbg.__wbg_isArray_a1eab7e0d067391b = function(arg0) { + const ret = Array.isArray(arg0); + return ret; + }; + imports.wbg.__wbg_isSafeInteger_343e2beeeece1bb0 = function(arg0) { + const ret = Number.isSafeInteger(arg0); + return ret; + }; + imports.wbg.__wbg_iterator_9a24c88df860dc65 = function() { + const ret = Symbol.iterator; + return ret; + }; + imports.wbg.__wbg_length_a446193dc22c12f8 = function(arg0) { + const ret = arg0.length; + return ret; + }; + imports.wbg.__wbg_length_e2d2a49132c1b256 = function(arg0) { + const ret = arg0.length; + return ret; + }; + imports.wbg.__wbg_log_6d91553816f3c6e3 = function(arg0, arg1) { + console.log(getStringFromWasm0(arg0, arg1)); + }; + imports.wbg.__wbg_lowerBound_1872d19f5bcf83c6 = function() { return handleError(function (arg0, arg1) { + const ret = IDBKeyRange.lowerBound(arg0, arg1 !== 0); + return ret; + }, arguments) }; + imports.wbg.__wbg_message_5c5d919204d42400 = function(arg0, arg1) { + const ret = arg1.message; + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }; + imports.wbg.__wbg_message_97a2af9b89d693a3 = function(arg0) { + const ret = arg0.message; + return ret; + }; + imports.wbg.__wbg_msCrypto_a61aeb35a24c1329 = function(arg0) { + const ret = arg0.msCrypto; + return ret; + }; + imports.wbg.__wbg_name_0b327d569f00ebee = function(arg0) { + const ret = arg0.name; + return ret; + }; + imports.wbg.__wbg_name_f2d27098bfd843e7 = function(arg0, arg1) { + const ret = arg1.name; + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }; + imports.wbg.__wbg_new0_f788a2397c7ca929 = function() { + const ret = new Date(); + return ret; + }; + imports.wbg.__wbg_new_018dcc2d6c8c2f6a = function() { return handleError(function () { + const ret = new Headers(); + return ret; + }, arguments) }; + imports.wbg.__wbg_new_23a2665fac83c611 = function(arg0, arg1) { + try { + var state0 = {a: arg0, b: arg1}; + var cb0 = (arg0, arg1) => { + const a = state0.a; + state0.a = 0; + try { + return __wbg_adapter_452(a, state0.b, arg0, arg1); + } finally { + state0.a = a; + } + }; + const ret = new Promise(cb0); + return ret; + } finally { + state0.a = state0.b = 0; + } + }; + imports.wbg.__wbg_new_405e22f390576ce2 = function() { + const ret = new Object(); + return ret; + }; + imports.wbg.__wbg_new_5e0be73521bc8c17 = function() { + const ret = new Map(); + return ret; + }; + imports.wbg.__wbg_new_78feb108b6472713 = function() { + const ret = new Array(); + return ret; + }; + imports.wbg.__wbg_new_92c54fc74574ef55 = function() { return handleError(function (arg0, arg1) { + const ret = new WebSocket(getStringFromWasm0(arg0, arg1)); + return ret; + }, arguments) }; + imports.wbg.__wbg_new_a12002a7f91c75be = function(arg0) { + const ret = new Uint8Array(arg0); + return ret; + }; + imports.wbg.__wbg_new_c68d7209be747379 = function(arg0, arg1) { + const ret = new Error(getStringFromWasm0(arg0, arg1)); + return ret; + }; + imports.wbg.__wbg_new_e25e5aab09ff45db = function() { return handleError(function () { + const ret = new AbortController(); + return ret; + }, arguments) }; + imports.wbg.__wbg_newnoargs_105ed471475aaf50 = function(arg0, arg1) { + const ret = new Function(getStringFromWasm0(arg0, arg1)); + return ret; + }; + imports.wbg.__wbg_newwithbyteoffsetandlength_d97e637ebe145a9a = function(arg0, arg1, arg2) { + const ret = new Uint8Array(arg0, arg1 >>> 0, arg2 >>> 0); + return ret; + }; + imports.wbg.__wbg_newwitheventinitdict_502dbfa1b3d2fcbc = function() { return handleError(function (arg0, arg1, arg2) { + const ret = new CloseEvent(getStringFromWasm0(arg0, arg1), arg2); + return ret; + }, arguments) }; + imports.wbg.__wbg_newwithlength_a381634e90c276d4 = function(arg0) { + const ret = new Uint8Array(arg0 >>> 0); + return ret; + }; + imports.wbg.__wbg_newwithstrandinit_06c535e0a867c635 = function() { return handleError(function (arg0, arg1, arg2) { + const ret = new Request(getStringFromWasm0(arg0, arg1), arg2); + return ret; + }, arguments) }; + imports.wbg.__wbg_next_25feadfc0913fea9 = function(arg0) { + const ret = arg0.next; + return ret; + }; + imports.wbg.__wbg_next_6574e1a8a62d1055 = function() { return handleError(function (arg0) { + const ret = arg0.next(); + return ret; + }, arguments) }; + imports.wbg.__wbg_node_905d3e251edff8a2 = function(arg0) { + const ret = arg0.node; + return ret; + }; + imports.wbg.__wbg_nodetestresult_new = function(arg0) { + const ret = NodeTestResult.__wrap(arg0); + return ret; + }; + imports.wbg.__wbg_now_e1163c67115ff874 = function(arg0) { + const ret = arg0.now(); + return ret; + }; + imports.wbg.__wbg_nymnodetester_new = function(arg0) { + const ret = NymNodeTester.__wrap(arg0); + return ret; + }; + imports.wbg.__wbg_nymnodetesterbuilder_new = function(arg0) { + const ret = NymNodeTesterBuilder.__wrap(arg0); + return ret; + }; + imports.wbg.__wbg_objectStore_21878d46d25b64b6 = function() { return handleError(function (arg0, arg1, arg2) { + const ret = arg0.objectStore(getStringFromWasm0(arg1, arg2)); + return ret; + }, arguments) }; + imports.wbg.__wbg_oldVersion_e8337811e52861c6 = function(arg0) { + const ret = arg0.oldVersion; + return ret; + }; + imports.wbg.__wbg_open_e0c0b2993eb596e1 = function() { return handleError(function (arg0, arg1, arg2, arg3) { + const ret = arg0.open(getStringFromWasm0(arg1, arg2), arg3 >>> 0); + return ret; + }, arguments) }; + imports.wbg.__wbg_performance_7fe0928f3ab059e5 = function(arg0) { + const ret = arg0.performance; + return ret; + }; + imports.wbg.__wbg_postMessage_83a8d58d3fcb6c13 = function() { return handleError(function (arg0, arg1) { + arg0.postMessage(arg1); + }, arguments) }; + imports.wbg.__wbg_process_dc0fbacc7c1c06f7 = function(arg0) { + const ret = arg0.process; + return ret; + }; + imports.wbg.__wbg_put_066faa31a6a88f5b = function() { return handleError(function (arg0, arg1, arg2) { + const ret = arg0.put(arg1, arg2); + return ret; + }, arguments) }; + imports.wbg.__wbg_queueMicrotask_97d92b4fcc8a61c5 = function(arg0) { + queueMicrotask(arg0); + }; + imports.wbg.__wbg_queueMicrotask_d3219def82552485 = function(arg0) { + const ret = arg0.queueMicrotask; + return ret; + }; + imports.wbg.__wbg_randomFillSync_ac0988aba3254290 = function() { return handleError(function (arg0, arg1) { + arg0.randomFillSync(arg1); + }, arguments) }; + imports.wbg.__wbg_readyState_4013cfdf4f22afb0 = function(arg0) { + const ret = arg0.readyState; + return (__wbindgen_enum_IdbRequestReadyState.indexOf(ret) + 1 || 3) - 1; + }; + imports.wbg.__wbg_readyState_7ef6e63c349899ed = function(arg0) { + const ret = arg0.readyState; + return ret; + }; + imports.wbg.__wbg_reason_49f1cede8bcf23dd = function(arg0, arg1) { + const ret = arg1.reason; + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }; + imports.wbg.__wbg_reject_b3fcf99063186ff7 = function(arg0) { + const ret = Promise.reject(arg0); + return ret; + }; + imports.wbg.__wbg_removeEventListener_056dfe8c3d6c58f9 = function() { return handleError(function (arg0, arg1, arg2, arg3) { + arg0.removeEventListener(getStringFromWasm0(arg1, arg2), arg3); + }, arguments) }; + imports.wbg.__wbg_require_60cc747a6bc5215a = function() { return handleError(function () { + const ret = module.require; + return ret; + }, arguments) }; + imports.wbg.__wbg_resolve_4851785c9c5f573d = function(arg0) { + const ret = Promise.resolve(arg0); + return ret; + }; + imports.wbg.__wbg_result_f29afabdf2c05826 = function() { return handleError(function (arg0) { + const ret = arg0.result; + return ret; + }, arguments) }; + imports.wbg.__wbg_send_0293179ba074ffb4 = function() { return handleError(function (arg0, arg1, arg2) { + arg0.send(getStringFromWasm0(arg1, arg2)); + }, arguments) }; + imports.wbg.__wbg_send_fc0c204e8a1757f4 = function() { return handleError(function (arg0, arg1, arg2) { + arg0.send(getArrayU8FromWasm0(arg1, arg2)); + }, arguments) }; + imports.wbg.__wbg_setTimeout_42370cb3051b8c2c = function() { return handleError(function (arg0, arg1, arg2) { + const ret = arg0.setTimeout(arg1, arg2); + return ret; + }, arguments) }; + imports.wbg.__wbg_setTimeout_73ce8df12de4f2f2 = function(arg0, arg1) { + const ret = setTimeout(arg0, arg1); + return ret; + }; + imports.wbg.__wbg_set_37837023f3d740e8 = function(arg0, arg1, arg2) { + arg0[arg1 >>> 0] = arg2; + }; + imports.wbg.__wbg_set_3f1d0b984ed272ed = function(arg0, arg1, arg2) { + arg0[arg1] = arg2; + }; + imports.wbg.__wbg_set_65595bdd868b3009 = function(arg0, arg1, arg2) { + arg0.set(arg1, arg2 >>> 0); + }; + imports.wbg.__wbg_set_8fc6bf8a5b1071d1 = function(arg0, arg1, arg2) { + const ret = arg0.set(arg1, arg2); + return ret; + }; + imports.wbg.__wbg_setbinaryType_92fa1ffd873b327c = function(arg0, arg1) { + arg0.binaryType = __wbindgen_enum_BinaryType[arg1]; + }; + imports.wbg.__wbg_setbody_5923b78a95eedf29 = function(arg0, arg1) { + arg0.body = arg1; + }; + imports.wbg.__wbg_setcode_156060465a2f8f79 = function(arg0, arg1) { + arg0.code = arg1; + }; + imports.wbg.__wbg_setcredentials_c3a22f1cd105a2c6 = function(arg0, arg1) { + arg0.credentials = __wbindgen_enum_RequestCredentials[arg1]; + }; + imports.wbg.__wbg_setheaders_834c0bdb6a8949ad = function(arg0, arg1) { + arg0.headers = arg1; + }; + imports.wbg.__wbg_setmethod_3c5280fe5d890842 = function(arg0, arg1, arg2) { + arg0.method = getStringFromWasm0(arg1, arg2); + }; + imports.wbg.__wbg_setmode_5dc300b865044b65 = function(arg0, arg1) { + arg0.mode = __wbindgen_enum_RequestMode[arg1]; + }; + imports.wbg.__wbg_setonabort_3bf4db6614fa98e9 = function(arg0, arg1) { + arg0.onabort = arg1; + }; + imports.wbg.__wbg_setonce_0cb80aea26303a35 = function(arg0, arg1) { + arg0.once = arg1 !== 0; + }; + imports.wbg.__wbg_setoncomplete_4d19df0dadb7c4d4 = function(arg0, arg1) { + arg0.oncomplete = arg1; + }; + imports.wbg.__wbg_setonerror_b0d9d723b8fddbbb = function(arg0, arg1) { + arg0.onerror = arg1; + }; + imports.wbg.__wbg_setonerror_d7e3056cc6e56085 = function(arg0, arg1) { + arg0.onerror = arg1; + }; + imports.wbg.__wbg_setonsuccess_afa464ee777a396d = function(arg0, arg1) { + arg0.onsuccess = arg1; + }; + imports.wbg.__wbg_setonupgradeneeded_fcf7ce4f2eb0cb5f = function(arg0, arg1) { + arg0.onupgradeneeded = arg1; + }; + imports.wbg.__wbg_setreason_d29ac0402eeeb81a = function(arg0, arg1, arg2) { + arg0.reason = getStringFromWasm0(arg1, arg2); + }; + imports.wbg.__wbg_setsignal_75b21ef3a81de905 = function(arg0, arg1) { + arg0.signal = arg1; + }; + imports.wbg.__wbg_signal_aaf9ad74119f20a4 = function(arg0) { + const ret = arg0.signal; + return ret; + }; + imports.wbg.__wbg_static_accessor_GLOBAL_88a902d13a557d07 = function() { + const ret = typeof global === 'undefined' ? null : global; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }; + imports.wbg.__wbg_static_accessor_GLOBAL_THIS_56578be7e9f832b0 = function() { + const ret = typeof globalThis === 'undefined' ? null : globalThis; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }; + imports.wbg.__wbg_static_accessor_SELF_37c5d418e4bf5819 = function() { + const ret = typeof self === 'undefined' ? null : self; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }; + imports.wbg.__wbg_static_accessor_WINDOW_5de37043a91a9c40 = function() { + const ret = typeof window === 'undefined' ? null : window; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }; + imports.wbg.__wbg_status_f6360336ca686bf0 = function(arg0) { + const ret = arg0.status; + return ret; + }; + imports.wbg.__wbg_stringify_f7ed6987935b4a24 = function() { return handleError(function (arg0) { + const ret = JSON.stringify(arg0); + return ret; + }, arguments) }; + imports.wbg.__wbg_subarray_aa9065fa9dc5df96 = function(arg0, arg1, arg2) { + const ret = arg0.subarray(arg1 >>> 0, arg2 >>> 0); + return ret; + }; + imports.wbg.__wbg_target_0a62d9d79a2a1ede = function(arg0) { + const ret = arg0.target; + return isLikeNone(ret) ? 0 : addToExternrefTable0(ret); + }; + imports.wbg.__wbg_text_7805bea50de2af49 = function() { return handleError(function (arg0) { + const ret = arg0.text(); + return ret; + }, arguments) }; + imports.wbg.__wbg_then_44b73946d2fb3e7d = function(arg0, arg1) { + const ret = arg0.then(arg1); + return ret; + }; + imports.wbg.__wbg_then_48b406749878a531 = function(arg0, arg1, arg2) { + const ret = arg0.then(arg1, arg2); + return ret; + }; + imports.wbg.__wbg_toString_5285597960676b7b = function(arg0) { + const ret = arg0.toString(); + return ret; + }; + imports.wbg.__wbg_toString_c813bbd34d063839 = function(arg0) { + const ret = arg0.toString(); + return ret; + }; + imports.wbg.__wbg_transaction_7d452475ef3c3c33 = function(arg0) { + const ret = arg0.transaction; + return ret; + }; + imports.wbg.__wbg_transaction_babc423936946a37 = function() { return handleError(function (arg0, arg1, arg2, arg3) { + const ret = arg0.transaction(getStringFromWasm0(arg1, arg2), __wbindgen_enum_IdbTransactionMode[arg3]); + return ret; + }, arguments) }; + imports.wbg.__wbg_upperBound_76a00814e81f6891 = function() { return handleError(function (arg0, arg1) { + const ret = IDBKeyRange.upperBound(arg0, arg1 !== 0); + return ret; + }, arguments) }; + imports.wbg.__wbg_url_ae10c34ca209681d = function(arg0, arg1) { + const ret = arg1.url; + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }; + imports.wbg.__wbg_value_cd1ffa7b1ab794f1 = function(arg0) { + const ret = arg0.value; + return ret; + }; + imports.wbg.__wbg_versions_c01dfd4722a88165 = function(arg0) { + const ret = arg0.versions; + return ret; + }; + imports.wbg.__wbg_warn_af6ab09472df19f5 = function(arg0, arg1) { + console.warn(getStringFromWasm0(arg0, arg1)); + }; + imports.wbg.__wbg_wasClean_605b4fd66d44354a = function(arg0) { + const ret = arg0.wasClean; + return ret; + }; + imports.wbg.__wbindgen_as_number = function(arg0) { + const ret = +arg0; + return ret; + }; + imports.wbg.__wbindgen_bigint_from_u64 = function(arg0) { + const ret = BigInt.asUintN(64, arg0); + return ret; + }; + imports.wbg.__wbindgen_bigint_get_as_i64 = function(arg0, arg1) { + const v = arg1; + const ret = typeof(v) === 'bigint' ? v : undefined; + getDataViewMemory0().setBigInt64(arg0 + 8 * 1, isLikeNone(ret) ? BigInt(0) : ret, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true); + }; + imports.wbg.__wbindgen_boolean_get = function(arg0) { + const v = arg0; + const ret = typeof(v) === 'boolean' ? (v ? 1 : 0) : 2; + return ret; + }; + imports.wbg.__wbindgen_cb_drop = function(arg0) { + const obj = arg0.original; + if (obj.cnt-- == 1) { + obj.a = 0; + return true; + } + const ret = false; + return ret; + }; + imports.wbg.__wbindgen_closure_wrapper1846 = function(arg0, arg1, arg2) { + const ret = makeMutClosure(arg0, arg1, 377, __wbg_adapter_52); + return ret; + }; + imports.wbg.__wbindgen_closure_wrapper2876 = function(arg0, arg1, arg2) { + const ret = makeMutClosure(arg0, arg1, 579, __wbg_adapter_55); + return ret; + }; + imports.wbg.__wbindgen_closure_wrapper2877 = function(arg0, arg1, arg2) { + const ret = makeMutClosure(arg0, arg1, 581, __wbg_adapter_58); + return ret; + }; + imports.wbg.__wbindgen_closure_wrapper5671 = function(arg0, arg1, arg2) { + const ret = makeMutClosure(arg0, arg1, 1498, __wbg_adapter_61); + return ret; + }; + imports.wbg.__wbindgen_closure_wrapper6096 = function(arg0, arg1, arg2) { + const ret = makeMutClosure(arg0, arg1, 1625, __wbg_adapter_64); + return ret; + }; + imports.wbg.__wbindgen_closure_wrapper6199 = function(arg0, arg1, arg2) { + const ret = makeMutClosure(arg0, arg1, 1679, __wbg_adapter_67); + return ret; + }; + imports.wbg.__wbindgen_closure_wrapper6201 = function(arg0, arg1, arg2) { + const ret = makeMutClosure(arg0, arg1, 1679, __wbg_adapter_67); + return ret; + }; + imports.wbg.__wbindgen_closure_wrapper6203 = function(arg0, arg1, arg2) { + const ret = makeMutClosure(arg0, arg1, 1679, __wbg_adapter_72); + return ret; + }; + imports.wbg.__wbindgen_closure_wrapper6205 = function(arg0, arg1, arg2) { + const ret = makeMutClosure(arg0, arg1, 1679, __wbg_adapter_67); + return ret; + }; + imports.wbg.__wbindgen_closure_wrapper6263 = function(arg0, arg1, arg2) { + const ret = makeMutClosure(arg0, arg1, 1695, __wbg_adapter_77); + return ret; + }; + imports.wbg.__wbindgen_debug_string = function(arg0, arg1) { + const ret = debugString(arg1); + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + const len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }; + imports.wbg.__wbindgen_error_new = function(arg0, arg1) { + const ret = new Error(getStringFromWasm0(arg0, arg1)); + return ret; + }; + imports.wbg.__wbindgen_in = function(arg0, arg1) { + const ret = arg0 in arg1; + return ret; + }; + imports.wbg.__wbindgen_init_externref_table = function() { + const table = wasm.__wbindgen_export_4; + const offset = table.grow(4); + table.set(0, undefined); + table.set(offset + 0, undefined); + table.set(offset + 1, null); + table.set(offset + 2, true); + table.set(offset + 3, false); + }; + imports.wbg.__wbindgen_is_bigint = function(arg0) { + const ret = typeof(arg0) === 'bigint'; + return ret; + }; + imports.wbg.__wbindgen_is_function = function(arg0) { + const ret = typeof(arg0) === 'function'; + return ret; + }; + imports.wbg.__wbindgen_is_null = function(arg0) { + const ret = arg0 === null; + return ret; + }; + imports.wbg.__wbindgen_is_object = function(arg0) { + const val = arg0; + const ret = typeof(val) === 'object' && val !== null; + return ret; + }; + imports.wbg.__wbindgen_is_string = function(arg0) { + const ret = typeof(arg0) === 'string'; + return ret; + }; + imports.wbg.__wbindgen_is_undefined = function(arg0) { + const ret = arg0 === undefined; + return ret; + }; + imports.wbg.__wbindgen_jsval_eq = function(arg0, arg1) { + const ret = arg0 === arg1; + return ret; + }; + imports.wbg.__wbindgen_jsval_loose_eq = function(arg0, arg1) { + const ret = arg0 == arg1; + return ret; + }; + imports.wbg.__wbindgen_memory = function() { + const ret = wasm.memory; + return ret; + }; + imports.wbg.__wbindgen_number_get = function(arg0, arg1) { + const obj = arg1; + const ret = typeof(obj) === 'number' ? obj : undefined; + getDataViewMemory0().setFloat64(arg0 + 8 * 1, isLikeNone(ret) ? 0 : ret, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true); + }; + imports.wbg.__wbindgen_number_new = function(arg0) { + const ret = arg0; + return ret; + }; + imports.wbg.__wbindgen_string_get = function(arg0, arg1) { + const obj = arg1; + const ret = typeof(obj) === 'string' ? obj : undefined; + var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc); + var len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }; + imports.wbg.__wbindgen_string_new = function(arg0, arg1) { + const ret = getStringFromWasm0(arg0, arg1); + return ret; + }; + imports.wbg.__wbindgen_throw = function(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); + }; + + return imports; +} + +function __wbg_finalize_init(instance, module) { + wasm = instance.exports; + __wbg_init.__wbindgen_wasm_module = module; + cachedDataViewMemory0 = null; + cachedUint8ArrayMemory0 = null; + + + wasm.__wbindgen_start(); + return wasm; +} + +async function __wbg_init(module_or_path) { + if (wasm !== undefined) return wasm; + + + if (typeof module_or_path !== 'undefined') { + if (Object.getPrototypeOf(module_or_path) === Object.prototype) { + ({module_or_path} = module_or_path); + } else { + console.warn('using deprecated parameters for the initialization function; pass a single object instead'); + } + } + + if (typeof module_or_path === 'undefined') { + module_or_path = new URL('nym_node_tester_wasm_bg.wasm', (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('worker.js', document.baseURI).href))); + } + const imports = __wbg_get_imports(); + + if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) { + module_or_path = fetch(module_or_path); + } + + const { instance, module } = await __wbg_load(await module_or_path, imports); + + return __wbg_finalize_init(instance, module); +} + +var NodeTesterEventKinds; +(function (NodeTesterEventKinds) { + NodeTesterEventKinds["Loaded"] = "Loaded"; + NodeTesterEventKinds["Connected"] = "Connected"; +})(NodeTesterEventKinds || (NodeTesterEventKinds = {})); + +// Copyright 2020-2023 Nym Technologies SA +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +/** + * Helper method to send typed messages. + * @param event The strongly typed message to send back to the calling thread. + */ +// eslint-disable-next-line no-restricted-globals +var postMessageWithType = function (event) { return self.postMessage(event); }; +console.log('[Nym WASM client] Starting Nym WASM web worker...'); +var buildTester = function (validatorUrl, nodeTesterId) { return __awaiter(void 0, void 0, void 0, function () { return __generator(this, function (_a) { + return [2 /*return*/, new NymNodeTester({ nymApi: validatorUrl, id: nodeTesterId })]; +}); }); }; +function main() { + return __awaiter(this, void 0, void 0, function () { + var importResult, nodeTester, webWorker; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, __wbg_init(wasmBytes())]; + case 1: + importResult = _a.sent(); + importResult.set_panic_hook(); + nodeTester = null; + webWorker = { + init: function (validatorUrl, nodeTesterId) { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, buildTester(validatorUrl, nodeTesterId)]; + case 1: + nodeTester = _a.sent(); + return [2 /*return*/]; + } + }); + }); + }, + reconnectToGateway: function () { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + if (!nodeTester) { + throw Error('Please run init first'); + } + return [4 /*yield*/, nodeTester.reconnect_to_gateway()]; + case 1: + _a.sent(); + return [2 /*return*/]; + } + }); + }); + }, + disconnectFromGateway: function () { + return __awaiter(this, void 0, void 0, function () { + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + if (!nodeTester) { + throw Error('Please run init first'); + } + return [4 /*yield*/, nodeTester.disconnect_from_gateway()]; + case 1: + _a.sent(); + return [2 /*return*/]; + } + }); + }); + }, + startTest: function (mixnodeIdentityKey) { + return __awaiter(this, void 0, void 0, function () { + var result, duplicate_acks, duplicate_packets, received_acks, received_packets, sent_packets; + return __generator(this, function (_a) { + switch (_a.label) { + case 0: + if (!nodeTester) { + throw Error('Please run init first'); + } + console.log("Testing mixnode with identity key = ".concat(mixnodeIdentityKey)); + return [4 /*yield*/, nodeTester.test_node(mixnodeIdentityKey)]; + case 1: + result = (_a.sent()); + // return early if there was an error + if (!result) { + return [2 /*return*/, result]; + } + // log the result in the worker so that the packet stats are visible somewhere and extract the score + result.log_details(); + duplicate_acks = result.duplicate_acks, duplicate_packets = result.duplicate_packets, received_acks = result.received_acks, received_packets = result.received_packets, sent_packets = result.sent_packets; + // construct the response to avoid any weird proxy effects + return [2 /*return*/, { + score: result.score(), + sentPackets: sent_packets, + receivedPackets: received_packets, + receivedAcks: received_acks, + duplicatePackets: duplicate_packets, + duplicateAcks: duplicate_acks, + }]; + } + }); + }); + }, + }; + // start comlink listening for messages and handle them above + expose(webWorker); + // notify any listeners that the web worker has loaded and is ready for testing + postMessageWithType({ kind: NodeTesterEventKinds.Loaded, args: { loaded: true } }); + return [2 /*return*/]; + } + }); + }); +} +main(); diff --git a/sdk/typescript/packages/node-tester/src/worker.ts b/sdk/typescript/packages/node-tester/src/worker.ts deleted file mode 100644 index 2251ac3909..0000000000 --- a/sdk/typescript/packages/node-tester/src/worker.ts +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2020-2023 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import * as Comlink from 'comlink'; - -// -// Rollup will replace wasmBytes with a function that loads the WASM bundle from a base64 string embedded in the output. -// -// Doing it this way, saves having to support a large variety of bundlers and their quirks. -// -// @ts-ignore -// eslint-disable-next-line import/no-extraneous-dependencies -import wasmBytes from '@nymproject/nym-node-tester-wasm/nym_node_tester_wasm_bg.wasm'; - -/* eslint-disable no-restricted-globals */ -import init, { NymNodeTester, NodeTestResult } from '@nymproject/nym-node-tester-wasm/nym_node_tester_wasm'; -import type { INodeTesterWorkerAsync, NodeTesterLoadedEvent } from './types'; -import { NodeTesterEventKinds } from './types'; - -/** - * Helper method to send typed messages. - * @param event The strongly typed message to send back to the calling thread. - */ -// eslint-disable-next-line no-restricted-globals -const postMessageWithType = (event: E) => self.postMessage(event); - -console.log('[Nym WASM client] Starting Nym WASM web worker...'); - -const buildTester = async (validatorUrl: string, nodeTesterId?: string): Promise => - new NymNodeTester({ nymApi: validatorUrl, id: nodeTesterId }); - -async function main() { - const importResult = await init(wasmBytes()); - importResult.set_panic_hook(); - - let nodeTester: NymNodeTester | null = null; - - const webWorker: INodeTesterWorkerAsync = { - async init(validatorUrl: string, nodeTesterId?: string) { - nodeTester = await buildTester(validatorUrl, nodeTesterId); - }, - async reconnectToGateway() { - if (!nodeTester) { - throw Error('Please run init first'); - } - await nodeTester.reconnect_to_gateway(); - }, - async disconnectFromGateway() { - if (!nodeTester) { - throw Error('Please run init first'); - } - await nodeTester.disconnect_from_gateway(); - }, - async startTest(mixnodeIdentityKey: string) { - if (!nodeTester) { - throw Error('Please run init first'); - } - console.log(`Testing mixnode with identity key = ${mixnodeIdentityKey}`); - // TODO: fix typing in Rust code - const result = (await nodeTester.test_node(mixnodeIdentityKey)) as NodeTestResult | undefined; - - // return early if there was an error - if (!result) { - return result; - } - - // log the result in the worker so that the packet stats are visible somewhere and extract the score - result.log_details(); - - // eslint-disable-next-line @typescript-eslint/naming-convention - const { duplicate_acks, duplicate_packets, received_acks, received_packets, sent_packets } = result; - - // construct the response to avoid any weird proxy effects - return { - score: result.score(), - sentPackets: sent_packets, - receivedPackets: received_packets, - receivedAcks: received_acks, - duplicatePackets: duplicate_packets, - duplicateAcks: duplicate_acks, - }; - }, - }; - - // start comlink listening for messages and handle them above - Comlink.expose(webWorker); - - // notify any listeners that the web worker has loaded and is ready for testing - postMessageWithType({ kind: NodeTesterEventKinds.Loaded, args: { loaded: true } }); -} - -main(); diff --git a/sdk/typescript/packages/node-tester/tsconfig.jest.json b/sdk/typescript/packages/node-tester/tsconfig.jest.json deleted file mode 100644 index 2e6284589e..0000000000 --- a/sdk/typescript/packages/node-tester/tsconfig.jest.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "compileOnSave": false, - "compilerOptions": { - "lib": [ - "es2021", - "dom", - "dom.iterable", - "esnext", - "webworker" - ], - "module": "CommonJS", - "target": "es5", - "strict": true, - "moduleResolution": "node", - "skipLibCheck": true, - "skipDefaultLibCheck": true, - "declaration": true, - "baseUrl": ".", - "esModuleInterop": true, - "allowJs": true, - "downlevelIteration": true - }, - "include": [ - "src/**/*.ts" - ], - "exclude": [ - "jest.*", - "webpack.config.js", - "webpack.prod.js", - "webpack.common.js", - "node_modules", - "**/node_modules", - "dist", - "**/dist", - "scripts", - "jest", - "__tests__", - "**/__tests__", - "__jest__", - "**/__jest__", - "config/*" - ] -} diff --git a/sdk/typescript/packages/node-tester/tsconfig.json b/sdk/typescript/packages/node-tester/tsconfig.json deleted file mode 100644 index de7de44877..0000000000 --- a/sdk/typescript/packages/node-tester/tsconfig.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "compileOnSave": false, - "compilerOptions": { - "lib": [ - "es2021", - "dom", - "dom.iterable", - "esnext", - "webworker" - ], - "outDir": "./dist/", - "module": "esnext", - "target": "esnext", - "allowJs": false, - "strict": true, - "moduleResolution": "node", - "skipLibCheck": true, - "skipDefaultLibCheck": true, - "declaration": true, - "baseUrl": ".", - "downlevelIteration": true - }, - "include": [ - "src/**/*.ts", - "src/*.ts", - "typings" - ], - "exclude": [ - "jest.config.js", - "webpack.config.js", - "webpack.prod.js", - "webpack.common.js", - "node_modules", - "**/node_modules", - "dist", - "**/dist", - "scripts", - "jest", - "__tests__", - "**/__tests__", - "__jest__", - "**/__jest__", - "config/*", - ] -} diff --git a/sdk/typescript/packages/node-tester/typings/rollup-worker.d.ts b/sdk/typescript/packages/node-tester/typings/rollup-worker.d.ts deleted file mode 100644 index ead3d9e1f4..0000000000 --- a/sdk/typescript/packages/node-tester/typings/rollup-worker.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module 'web-worker:*' { - const WorkerFactory: new () => Worker; - export default WorkerFactory; -} diff --git a/sdk/typescript/packages/nodejs-client/package.json b/sdk/typescript/packages/nodejs-client/package.json index 4b03632cd2..3346de3b84 100644 --- a/sdk/typescript/packages/nodejs-client/package.json +++ b/sdk/typescript/packages/nodejs-client/package.json @@ -17,11 +17,11 @@ "docs:generate:prod": "typedoc --basePath ./docs/tsdoc/nymproject/sdk/", "docs:prod:build": "scripts/build-prod-docs-collect.sh", "docs:serve": "reload -b -d ./docs -p 3000", - "docs:watch": "nodemon --ext ts --watch './src/**/*' --watch './typedoc.json' --exec \"yarn docs:generate\"", + "docs:watch": "nodemon --ext ts --watch './src/**/*' --watch './typedoc.json' --exec \"pnpm docs:generate\"", "lint": "eslint src", "lint:fix": "eslint src --fix", "start": "tsc -w", - "start:dev": "nodemon --watch src -e ts,json --exec 'yarn build:dev:esm'", + "start:dev": "nodemon --watch src -e ts,json --exec 'pnpm build:dev:esm'", "tsc": "tsc --noEmit true" }, "dependencies": { @@ -40,27 +40,29 @@ "@rollup/plugin-url": "^8.0.1", "@rollup/plugin-wasm": "^6.1.1", "@types/node": "^16.7.13", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", + "@types/ws": "catalog:", + "@typescript-eslint/eslint-plugin": "catalog:", + "@typescript-eslint/parser": "catalog:", "eslint": "^8.10.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^16.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-react": "^7.29.2", - "eslint-plugin-react-hooks": "^4.3.0", + "eslint-config-airbnb": "catalog:", + "eslint-config-airbnb-typescript": "catalog:", + "eslint-config-prettier": "catalog:", + "eslint-import-resolver-root-import": "catalog:", + "eslint-plugin-import": "catalog:", + "eslint-plugin-jest": "catalog:", + "eslint-plugin-jsx-a11y": "catalog:", + "eslint-plugin-prettier": "catalog:", + "eslint-plugin-react": "catalog:", + "eslint-plugin-react-hooks": "catalog:", "nodemon": "3.0.1", "reload": "^3.2.1", - "rimraf": "^3.0.2", + "rimraf": "catalog:", "rollup": "^3.9.1", "rollup-plugin-base64": "^1.0.1", "rollup-plugin-modify": "^3.0.0", "rollup-plugin-web-worker-loader": "^1.6.1", - "ts-loader": "^9.4.2", + "ts-loader": "catalog:", + "tslib": "catalog:", "typedoc": "^0.24.8", "typescript": "^4.8.4" }, diff --git a/sdk/typescript/packages/nodejs-client/scripts/build-prod-docs-collect.sh b/sdk/typescript/packages/nodejs-client/scripts/build-prod-docs-collect.sh index 9cd137bcde..361037fcd5 100755 --- a/sdk/typescript/packages/nodejs-client/scripts/build-prod-docs-collect.sh +++ b/sdk/typescript/packages/nodejs-client/scripts/build-prod-docs-collect.sh @@ -7,7 +7,7 @@ set -o pipefail rm -rf ../../../../dist/ts/docs/tsdoc/nymproject/sdk || true # run the build -yarn docs:generate:prod +pnpm docs:generate:prod # move the output outside of the yarn/npm workspaces mkdir -p ../../../../dist/ts/docs/tsdoc/nymproject diff --git a/sdk/typescript/packages/react-components/package.json b/sdk/typescript/packages/react-components/package.json index 162b41e668..739a93aa01 100644 --- a/sdk/typescript/packages/react-components/package.json +++ b/sdk/typescript/packages/react-components/package.json @@ -29,57 +29,59 @@ "@mui/material": "5", "@mui/styles": "5", "@mui/system": "5", - "@nymproject/mui-theme": "1", + "@nymproject/mui-theme": "workspace:*", "@nymproject/nym-validator-client": "^0.18.0", - "@nymproject/types": "1", - "base58": "4", + "@nymproject/types": "workspace:*", + "base58": "2", "bech32": "^1.1.4", - "react": "^18.2.0", - "react-dom": "^18.2.0", + "react": "catalog:", + "react-dom": "catalog:", "zxcvbn": "^4.4.2" }, "dependencies": { - "@mui/lab": "5.0.0-alpha.170", - "@mui/x-tree-view": "^7.11.1", - "flat": "^5.0.2", - "use-clipboard-copy": "^0.2.0" + "@mui/lab": "catalog:", + "@mui/x-tree-view": "catalog:", + "flat": "catalog:", + "use-clipboard-copy": "catalog:" }, "devDependencies": { - "@babel/core": "^7.17.5", - "@nymproject/eslint-config-react-typescript": "^1.0.0", - "@storybook/addon-actions": "^6.5.8", - "@storybook/addon-essentials": "^6.5.8", - "@storybook/addon-interactions": "^6.5.8", - "@storybook/addon-links": "^6.5.8", - "@storybook/builder-webpack5": "^6.5.8", - "@storybook/manager-webpack5": "^6.5.8", - "@storybook/react": "^6.5.15", - "@storybook/testing-library": "^0.0.9", - "@svgr/webpack": "^6.1.1", - "@types/flat": "^5.0.2", - "@types/react": "^18.0.26", - "@types/react-dom": "^18.0.10", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", - "babel-loader": "^8.2.3", + "@babel/core": "catalog:", + "@nymproject/eslint-config-react-typescript": "workspace:*", + "@storybook/addon-actions": "catalog:", + "@storybook/addon-docs": "catalog:", + "@storybook/addon-essentials": "catalog:", + "@storybook/addon-interactions": "catalog:", + "@storybook/addon-links": "catalog:", + "@storybook/builder-webpack5": "catalog:", + "@storybook/manager-webpack5": "catalog:", + "@storybook/react": "catalog:", + "@storybook/testing-library": "catalog:", + "@svgr/webpack": "catalog:", + "@types/flat": "catalog:", + "@types/zxcvbn": "catalog:", + "@types/react": "catalog:", + "@types/react-dom": "catalog:", + "@typescript-eslint/eslint-plugin": "catalog:", + "@typescript-eslint/parser": "catalog:", + "babel-loader": "catalog:", "babel-plugin-root-import": "^5.1.0", - "eslint": "^9.26.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^16.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-react": "^7.29.2", - "eslint-plugin-react-hooks": "^4.3.0", - "eslint-plugin-storybook": "^0.5.12", - "jest": "^27.1.0", - "prettier": "^2.8.7", - "rimraf": "^3.0.2", - "ts-jest": "^27.0.5", - "tsconfig-paths-webpack-plugin": "^3.5.2", + "eslint": "catalog:", + "eslint-config-airbnb": "catalog:", + "eslint-config-airbnb-typescript": "catalog:", + "eslint-config-prettier": "catalog:", + "eslint-import-resolver-root-import": "catalog:", + "eslint-plugin-import": "catalog:", + "eslint-plugin-jest": "catalog:", + "eslint-plugin-jsx-a11y": "catalog:", + "eslint-plugin-prettier": "catalog:", + "eslint-plugin-react": "catalog:", + "eslint-plugin-react-hooks": "catalog:", + "eslint-plugin-storybook": "catalog:", + "jest": "catalog:", + "prettier": "catalog:", + "rimraf": "catalog:", + "ts-jest": "catalog:", + "tsconfig-paths-webpack-plugin": "catalog:", "typescript": "^4.6.2" }, "scripts": { diff --git a/sdk/typescript/packages/sdk-react/package.json b/sdk/typescript/packages/sdk-react/package.json index 1144cf1563..bfc9d6b036 100644 --- a/sdk/typescript/packages/sdk-react/package.json +++ b/sdk/typescript/packages/sdk-react/package.json @@ -23,46 +23,46 @@ "@nymproject/sdk": ">=1.4.1-rc.3 || ^1" }, "devDependencies": { - "@babel/core": "^7.17.5", - "@nymproject/eslint-config-react-typescript": "^1.0.0", - "@storybook/addon-actions": "^6.5.8", - "@storybook/addon-essentials": "^6.5.8", - "@storybook/addon-interactions": "^6.5.8", - "@storybook/addon-links": "^6.5.8", - "@storybook/builder-webpack5": "^6.5.8", - "@storybook/manager-webpack5": "^6.5.8", - "@storybook/react": "^6.5.15", - "@storybook/testing-library": "^0.0.9", - "@svgr/webpack": "^6.1.1", - "@types/flat": "^5.0.2", - "@types/react": "^18.0.26", - "@types/react-dom": "^18.0.10", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", - "babel-loader": "^8.2.3", + "@babel/core": "catalog:", + "@nymproject/eslint-config-react-typescript": "workspace:*", + "@storybook/addon-actions": "catalog:", + "@storybook/addon-essentials": "catalog:", + "@storybook/addon-interactions": "catalog:", + "@storybook/addon-links": "catalog:", + "@storybook/builder-webpack5": "catalog:", + "@storybook/manager-webpack5": "catalog:", + "@storybook/react": "catalog:", + "@storybook/testing-library": "catalog:", + "@svgr/webpack": "catalog:", + "@types/flat": "catalog:", + "@types/react": "catalog:", + "@types/react-dom": "catalog:", + "@typescript-eslint/eslint-plugin": "catalog:", + "@typescript-eslint/parser": "catalog:", + "babel-loader": "catalog:", "babel-plugin-root-import": "^5.1.0", "eslint": "^8.10.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^16.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-react": "^7.29.2", - "eslint-plugin-react-hooks": "^4.3.0", - "eslint-plugin-storybook": "^0.5.12", - "jest": "^27.1.0", - "prettier": "^2.8.7", - "rimraf": "^3.0.2", - "ts-jest": "^27.0.5", - "tsconfig-paths-webpack-plugin": "^3.5.2", + "eslint-config-airbnb": "catalog:", + "eslint-config-airbnb-typescript": "catalog:", + "eslint-config-prettier": "catalog:", + "eslint-import-resolver-root-import": "catalog:", + "eslint-plugin-import": "catalog:", + "eslint-plugin-jest": "catalog:", + "eslint-plugin-jsx-a11y": "catalog:", + "eslint-plugin-prettier": "catalog:", + "eslint-plugin-react": "catalog:", + "eslint-plugin-react-hooks": "catalog:", + "eslint-plugin-storybook": "catalog:", + "jest": "catalog:", + "prettier": "catalog:", + "rimraf": "catalog:", + "ts-jest": "catalog:", + "tsconfig-paths-webpack-plugin": "catalog:", "typescript": "^4.6.2" }, "peerDependencies": { - "react": "^18.2.0", - "react-dom": "^18.2.0" + "react": "catalog:", + "react-dom": "catalog:" }, "private": false, "type": "module", diff --git a/sdk/typescript/packages/sdk/DEVELOPERS.md b/sdk/typescript/packages/sdk/DEVELOPERS.md index 2f12b0546f..ff1f687baa 100644 --- a/sdk/typescript/packages/sdk/DEVELOPERS.md +++ b/sdk/typescript/packages/sdk/DEVELOPERS.md @@ -14,17 +14,17 @@ The SDK depends on WASM packages that must be built from Rust first. From the **root of the monorepo**: ```bash -yarn dev:on # add dev workspaces to root package.json -yarn # install dependencies -yarn build:wasm # build Rust -> WASM packages +pnpm dev:on # add dev workspaces to root package.json +pnpm i # install dependencies +pnpm build:wasm # build Rust -> WASM packages ``` Then from `sdk/typescript/packages/sdk`: ```bash -yarn build:dev # full dev build -> dist/ -yarn build:dev:esm # ESM-only (faster iteration) -yarn start:dev # watch mode, rebuilds ESM on changes +pnpm build:dev # full dev build -> dist/ +pnpm build:dev:esm # ESM-only (faster iteration) +pnpm start:dev # watch mode, rebuilds ESM on changes ``` ## Local mixFetch development @@ -45,14 +45,14 @@ The `publish-sdk-npm` GitHub Actions workflow (`.github/workflows/publish-sdk-np 1. Bump versions, commit, and push: ```bash - yarn sdk:versions:bump + pnpm sdk:versions:bump git add -A && git commit -m "chore: bump sdk versions" git push ``` 2. Trigger the `publish-sdk-npm` workflow from GitHub Actions. 3. After the workflow succeeds, add the RC suffix, commit, and push: ```bash - yarn sdk:versions:add-rc + pnpm sdk:versions:add-rc git add -A && git commit -m "chore: add rc suffix" git push ``` @@ -65,7 +65,7 @@ The `publish-sdk-npm` GitHub Actions workflow (`.github/workflows/publish-sdk-np ``` 2. Bump version numbers: ```bash - yarn sdk:versions:bump + pnpm sdk:versions:bump ``` 3. Build and publish: ```bash @@ -73,5 +73,5 @@ The `publish-sdk-npm` GitHub Actions workflow (`.github/workflows/publish-sdk-np ``` 4. Add RC suffix and commit: ```bash - yarn sdk:versions:add-rc + pnpm sdk:versions:add-rc ``` diff --git a/sdk/typescript/packages/sdk/README-GenerateDocs.md b/sdk/typescript/packages/sdk/README-GenerateDocs.md index 7458ba1069..d2a5a6aef6 100644 --- a/sdk/typescript/packages/sdk/README-GenerateDocs.md +++ b/sdk/typescript/packages/sdk/README-GenerateDocs.md @@ -1,17 +1,17 @@ ## Install dependencies -run `yarn install` to install dependencies +run `pnpm i` to install dependencies ## Generate docs We use TypeDoc for document generation https://typedoc.org/ -To generate docs run `yarn docs:generate`. Generated docs can be found the `./docs` directory. +To generate docs run `pnpm docs:generate`. Generated docs can be found the `./docs` directory. -To view the generated docs in a webpage run `yarn docs:serve`. The docs will be available to view at `http://localhost:3000`. +To view the generated docs in a webpage run `pnpm docs:serve`. The docs will be available to view at `http://localhost:3000`. ## Local document development To support the development process we have a local server that will watch for changes to the src files and update the docs in real time. -Run `yarn docs:dev` to start a local server to view the docs. Again, The docs will be available to view at `http://localhost:3000`. +Run `pnpm docs:dev` to start a local server to view the docs. Again, The docs will be available to view at `http://localhost:3000`. diff --git a/sdk/typescript/packages/sdk/package.json b/sdk/typescript/packages/sdk/package.json index 0f2effe91d..fbec514227 100644 --- a/sdk/typescript/packages/sdk/package.json +++ b/sdk/typescript/packages/sdk/package.json @@ -21,12 +21,12 @@ "docs:generate:prod": "typedoc --basePath ./docs/tsdoc/nymproject/sdk/", "docs:prod:build": "scripts/build-prod-docs-collect.sh", "docs:serve": "reload -b -d ./docs -p 3000", - "docs:watch": "nodemon --ext ts --watch './src/**/*' --watch './typedoc.json' --exec \"yarn docs:generate\"", + "docs:watch": "nodemon --ext ts --watch './src/**/*' --watch './typedoc.json' --exec \"pnpm docs:generate\"", "lint": "eslint src", "lint:fix": "eslint src --fix", "prebuild": "node scripts/showDependencyLocation.cjs", "start": "tsc -w", - "start:dev": "nodemon --watch src -e ts,json --exec 'yarn build:dev:esm'", + "start:dev": "nodemon --watch src -e ts,json --exec 'pnpm build:dev:esm'", "test": "node --experimental-vm-modules --no-warnings node_modules/jest/bin/jest.js -c=jest.config.mjs --no-cache", "tsc": "tsc --noEmit true" }, @@ -35,12 +35,12 @@ "comlink": "^4.3.1" }, "devDependencies": { - "@babel/core": "^7.15.0", - "@babel/plugin-transform-async-to-generator": "^7.14.5", - "@babel/preset-env": "^7.15.0", - "@babel/preset-react": "^7.14.5", - "@babel/preset-typescript": "^7.15.0", - "@nymproject/eslint-config-react-typescript": "^1.0.0", + "@babel/core": "catalog:", + "@babel/plugin-transform-async-to-generator": "catalog:", + "@babel/preset-env": "catalog:", + "@babel/preset-react": "catalog:", + "@babel/preset-typescript": "catalog:", + "@nymproject/eslint-config-react-typescript": "workspace:*", "@rollup/plugin-commonjs": "^24.0.1", "@rollup/plugin-inject": "^5.0.3", "@rollup/plugin-json": "^6.0.0", @@ -53,29 +53,31 @@ "@types/jest": "^27.0.1", "@types/minimatch": "5.1.2", "@types/node": "^16.7.13", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", + "@typescript-eslint/eslint-plugin": "catalog:", + "@typescript-eslint/parser": "catalog:", "eslint": "^8.10.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^16.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-react": "^7.29.2", - "eslint-plugin-react-hooks": "^4.3.0", + "eslint-config-airbnb": "catalog:", + "eslint-config-airbnb-typescript": "catalog:", + "eslint-config-prettier": "catalog:", + "eslint-import-resolver-root-import": "catalog:", + "eslint-plugin-import": "catalog:", + "eslint-plugin-jest": "catalog:", + "eslint-plugin-jsx-a11y": "catalog:", + "eslint-plugin-prettier": "catalog:", + "eslint-plugin-react": "catalog:", + "eslint-plugin-react-hooks": "catalog:", + "glob": "catalog:", "handlebars": "^4.7.8", "jest": "^29.5.0", + "tslib": "catalog:", "nodemon": "3.0.1", "reload": "^3.2.1", - "rimraf": "^3.0.2", + "rimraf": "catalog:", "rollup": "^3.9.1", "rollup-plugin-base64": "^1.0.1", "rollup-plugin-web-worker-loader": "^1.6.1", "ts-jest": "^29.1.0", - "ts-loader": "^9.4.2", + "ts-loader": "catalog:", "typedoc": "^0.24.8", "typescript": "^4.8.4" }, diff --git a/sdk/typescript/packages/sdk/scripts/build-prod-docs-collect.sh b/sdk/typescript/packages/sdk/scripts/build-prod-docs-collect.sh index 9cd137bcde..361037fcd5 100755 --- a/sdk/typescript/packages/sdk/scripts/build-prod-docs-collect.sh +++ b/sdk/typescript/packages/sdk/scripts/build-prod-docs-collect.sh @@ -7,7 +7,7 @@ set -o pipefail rm -rf ../../../../dist/ts/docs/tsdoc/nymproject/sdk || true # run the build -yarn docs:generate:prod +pnpm docs:generate:prod # move the output outside of the yarn/npm workspaces mkdir -p ../../../../dist/ts/docs/tsdoc/nymproject diff --git a/sdk/typescript/packages/sdk/scripts/hbs.mjs b/sdk/typescript/packages/sdk/scripts/hbs.mjs index 275a79d468..460d7948d4 100644 --- a/sdk/typescript/packages/sdk/scripts/hbs.mjs +++ b/sdk/typescript/packages/sdk/scripts/hbs.mjs @@ -1,14 +1,14 @@ import Handlebars from "handlebars"; import fs from 'fs'; import path from 'path'; -import glob from 'glob'; +import { globSync } from 'glob'; const filename = process.argv[2]; const outputFilename = process.argv[3]; console.log(`Processing file ${filename} as ${outputFilename}...`); const template = Handlebars.compile(fs.readFileSync(filename).toString()); -glob.sync('./partials/*.md').forEach(g => { +globSync('./partials/*.md').forEach(g => { const key = path.parse(g).name; console.log(`Registering partial ${g} as ${key}...`); Handlebars.registerPartial(key, fs.readFileSync(g).toString()); diff --git a/sdk/typescript/packages/validator-client/package.json b/sdk/typescript/packages/validator-client/package.json index d21a994b6d..daf82f7160 100644 --- a/sdk/typescript/packages/validator-client/package.json +++ b/sdk/typescript/packages/validator-client/package.json @@ -34,29 +34,29 @@ "@cosmjs/stargate": "^0.29.5", "@cosmjs/tendermint-rpc": "^0.29.5", "@favware/rollup-type-bundler": "^2.0.0", - "@nymproject/types": "^1.0.0", + "@nymproject/types": "workspace:*", "@rollup/plugin-commonjs": "^24.0.1", "@rollup/plugin-json": "^6.0.0", "@rollup/plugin-node-resolve": "^15.0.1", "@rollup/plugin-typescript": "^11.0.0", "@types/minimatch": "5.1.2", - "@typescript-eslint/eslint-plugin": "^5.7.0", - "@typescript-eslint/parser": "^5.7.0", + "@typescript-eslint/eslint-plugin": "catalog:", + "@typescript-eslint/parser": "catalog:", "axios": "^1.3.3", "cosmjs-types": "^0.4.1", "dotenv": "^16.0.3", "eslint": "^7.18.0", - "eslint-config-airbnb": "^19.0.2", - "eslint-config-airbnb-typescript": "^16.1.0", - "eslint-config-prettier": "^8.3.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", + "eslint-config-airbnb": "catalog:", + "eslint-config-airbnb-typescript": "catalog:", + "eslint-config-prettier": "catalog:", + "eslint-import-resolver-root-import": "catalog:", + "eslint-plugin-import": "catalog:", "eslint-plugin-mocha": "^10.0.3", - "eslint-plugin-prettier": "^4.0.0", + "eslint-plugin-prettier": "catalog:", "expect": "^28.1.3", "mocha": "^10.0.0", "moq.ts": "^7.3.4", - "prettier": "^2.8.7", + "prettier": "catalog:", "rollup": "^3.17.2", "rollup-plugin-dts": "^5.2.0", "rollup-plugin-node-polyfills": "^0.2.1", diff --git a/sdk/typescript/scripts/build-prod-examples.sh b/sdk/typescript/scripts/build-prod-examples.sh index f93a4d764e..e6cc9b77a8 100755 --- a/sdk/typescript/scripts/build-prod-examples.sh +++ b/sdk/typescript/scripts/build-prod-examples.sh @@ -16,12 +16,7 @@ packages=( "chat-app/plain-html" "chat-app/react-webpack-with-theme-example" -"chrome-extension" -"firefox-extension" -"node-tester/parcel" -"node-tester/plain-html" -"node-tester/react" "react/mui-theme" "react/sdk-react" diff --git a/sdk/typescript/scripts/build-prod-sdk.sh b/sdk/typescript/scripts/build-prod-sdk.sh index 12e68c3264..e34985d8d0 100755 --- a/sdk/typescript/scripts/build-prod-sdk.sh +++ b/sdk/typescript/scripts/build-prod-sdk.sh @@ -7,21 +7,21 @@ set -o pipefail rm -rf dist || true ##--------------------------------------------------------------------------- -## ✅ Run this script from the root of the repository using `yarn sdk:build` +## ✅ Run this script from the root of the repository using `pnpm sdk:build` ##--------------------------------------------------------------------------- # use wasm-pack to build packages -yarn build:wasm +pnpm build:wasm # enable dev mode and then install dev packages -yarn dev:on -yarn +pnpm dev:on +pnpm install # build the Typescript SDK packages -yarn build:ci:sdk +pnpm build:ci:sdk # build documentation -#yarn docs:prod:build +#pnpm docs:prod:build # turn dev mode off -yarn dev:off +pnpm dev:off diff --git a/sdk/typescript/scripts/dev-mode-add.mjs b/sdk/typescript/scripts/dev-mode-add.mjs index df00f685d7..5d8bd1099c 100644 --- a/sdk/typescript/scripts/dev-mode-add.mjs +++ b/sdk/typescript/scripts/dev-mode-add.mjs @@ -1,6 +1,6 @@ import fs from 'fs'; -const packageJson = JSON.parse(fs.readFileSync('package.json').toString()); +const WORKSPACE_FILE = 'pnpm-workspace.yaml'; const devWorkspace = [ 'dist/**', @@ -8,10 +8,21 @@ const devWorkspace = [ 'sdk/typescript/examples/**', 'sdk/typescript/codegen/**', ]; -if (!packageJson.workspaces.includes(devWorkspace)) { - // add - packageJson.workspaces.push(...devWorkspace); - // write out modified file - fs.writeFileSync('package.json', JSON.stringify(packageJson, null, 2)); -} +const content = fs.readFileSync(WORKSPACE_FILE, 'utf-8'); + +// Match the packages: block — one or more indented list items +const packagesRegex = /(^packages:\n)((?: - .+\n)+)/m; +const match = content.match(packagesRegex); +if (!match) throw new Error('Could not find packages: section in pnpm-workspace.yaml'); + +const current = match[2] + .split('\n') + .filter(l => l.startsWith(' - ')) + .map(l => l.replace(/^ - ['"]?/, '').replace(/['"]?\s*$/, '')); + +const toAdd = devWorkspace.filter(e => !current.includes(e)); +if (toAdd.length === 0) process.exit(0); + +const updated = [...current, ...toAdd].map(p => ` - '${p}'`).join('\n') + '\n'; +fs.writeFileSync(WORKSPACE_FILE, content.replace(packagesRegex, `$1${updated}`)); diff --git a/sdk/typescript/scripts/dev-mode-remove.mjs b/sdk/typescript/scripts/dev-mode-remove.mjs index cf0041823e..e17c0b8d5e 100644 --- a/sdk/typescript/scripts/dev-mode-remove.mjs +++ b/sdk/typescript/scripts/dev-mode-remove.mjs @@ -1,6 +1,6 @@ import fs from 'fs'; -const packageJson = JSON.parse(fs.readFileSync('package.json').toString()); +const WORKSPACE_FILE = 'pnpm-workspace.yaml'; const devWorkspace = [ 'dist/**', @@ -9,8 +9,20 @@ const devWorkspace = [ 'sdk/typescript/codegen/**', ]; -// remove -packageJson.workspaces = packageJson.workspaces.filter((w) => !devWorkspace.includes(w)); +const content = fs.readFileSync(WORKSPACE_FILE, 'utf-8'); -// write out modified file -fs.writeFileSync('package.json', JSON.stringify(packageJson, null, 2)); +// Match the packages: block — one or more indented list items +const packagesRegex = /(^packages:\n)((?: - .+\n)+)/m; +const match = content.match(packagesRegex); +if (!match) throw new Error('Could not find packages: section in pnpm-workspace.yaml'); + +const current = match[2] + .split('\n') + .filter(l => l.startsWith(' - ')) + .map(l => l.replace(/^ - ['"]?/, '').replace(/['"]?\s*$/, '')); + +const updated = current + .filter(p => !devWorkspace.includes(p)) + .map(p => ` - '${p}'`).join('\n') + '\n'; + +fs.writeFileSync(WORKSPACE_FILE, content.replace(packagesRegex, `$1${updated}`)); diff --git a/sdk/typescript/scripts/publish.sh b/sdk/typescript/scripts/publish.sh index b46579dc86..d2d1dac7ee 100755 --- a/sdk/typescript/scripts/publish.sh +++ b/sdk/typescript/scripts/publish.sh @@ -14,19 +14,14 @@ cd dist #chat-app/parcel #chat-app/plain-html #chat-app/react-webpack-with-theme-example -#chrome-extension -#firefox-extension -#node-tester/parcel -#node-tester/plain-html -#node-tester/react + #react/mui-theme #react/sdk-react #) packages=( # "wasm/client" "wasm/mix-fetch" -# "wasm/node-tester" -# "wasm/extension-storage" + # "node/wasm/client" #"node/wasm/mix-fetch" @@ -39,11 +34,6 @@ packages=( # "ts/sdk/nodejs-client/cjs" "ts/sdk/mix-fetch-node/cjs" -# "ts/sdk/node-tester/cjs" -# "ts/sdk/node-tester/cjs-full-fat" -# "ts/sdk/node-tester/esm" -# "ts/sdk/node-tester/esm-full-fat" - # "ts/sdk/sdk/cjs" # "ts/sdk/sdk/cjs-full-fat" # "ts/sdk/sdk/esm" diff --git a/sdk/typescript/scripts/release.sh b/sdk/typescript/scripts/release.sh index 5f30eb18bc..a40a46efcb 100755 --- a/sdk/typescript/scripts/release.sh +++ b/sdk/typescript/scripts/release.sh @@ -8,8 +8,8 @@ set -o pipefail make sdk-wasm-build # Build Typescript packages -yarn -yarn build:sdk +pnpm i +pnpm build:sdk # Publish to NPM ./sdk/typescript/scripts/publish.sh diff --git a/tools/internal/sdk-version-bump/src/main.rs b/tools/internal/sdk-version-bump/src/main.rs index cf77ba6be0..9c419ad626 100644 --- a/tools/internal/sdk-version-bump/src/main.rs +++ b/tools/internal/sdk-version-bump/src/main.rs @@ -226,9 +226,6 @@ fn initialise_internal_packages>(root: P) -> InternalPackages { // cargo packages that will have their Cargo.toml modified packages.register_cargo("wasm/mix-fetch"); packages.register_cargo("wasm/client"); - packages.register_cargo("wasm/node-tester"); - // packages.register_cargo("wasm/full-nym-wasm"); - packages.register_cargo("nym-browser-extension/storage"); // js packages that will have their package.json modified packages.register_json("nym-wallet"); @@ -236,17 +233,11 @@ fn initialise_internal_packages>(root: P) -> InternalPackages { packages.register_json("sdk/typescript/examples/chat-app/parcel"); packages.register_json("sdk/typescript/examples/chat-app/plain-html"); packages.register_json("sdk/typescript/examples/chat-app/react-webpack-with-theme-example"); - packages.register_json("sdk/typescript/examples/chrome-extension"); - packages.register_json("sdk/typescript/examples/firefox-extension"); packages.register_json("sdk/typescript/examples/mix-fetch/browser"); - packages.register_json("sdk/typescript/examples/node-tester/parcel"); - packages.register_json("sdk/typescript/examples/node-tester/plain-html"); - packages.register_json("sdk/typescript/examples/node-tester/react"); packages.register_json("sdk/typescript/packages/mix-fetch"); packages.register_json("sdk/typescript/packages/mix-fetch-node"); packages.register_json("sdk/typescript/packages/mix-fetch/internal-dev"); packages.register_json("sdk/typescript/packages/mix-fetch/internal-dev/parcel"); - packages.register_json("sdk/typescript/packages/node-tester"); packages.register_json("sdk/typescript/packages/nodejs-client"); packages.register_json("sdk/typescript/packages/sdk"); packages.register_json("sdk/typescript/packages/sdk-react"); @@ -259,14 +250,12 @@ fn initialise_internal_packages>(root: P) -> InternalPackages { packages.register_known_js_dependency("@nymproject/mix-fetch-wasm-node"); // WASM - packages.register_known_js_dependency("@nymproject/nym-node-tester-wasm"); packages.register_known_js_dependency("@nymproject/nym-client-wasm"); packages.register_known_js_dependency("@nymproject/mix-fetch-wasm"); packages.register_known_js_dependency("@nymproject/mix-fetch"); packages.register_known_js_dependency("@nymproject/mix-fetch-full-fat"); packages.register_known_js_dependency("@nymproject/mui-theme"); - packages.register_known_js_dependency("@nymproject/node-tester"); packages.register_known_js_dependency("@nymproject/react-components"); packages.register_known_js_dependency("@nymproject/sdk"); packages.register_known_js_dependency("@nymproject/sdk-full-fat"); diff --git a/ts-packages/eslint-config-react-typescript/package.json b/ts-packages/eslint-config-react-typescript/package.json index 92929feebb..8e25cd615d 100644 --- a/ts-packages/eslint-config-react-typescript/package.json +++ b/ts-packages/eslint-config-react-typescript/package.json @@ -19,21 +19,21 @@ "eslint-plugin-react": ">= 7", "eslint-plugin-react-hooks": ">= 4", "eslint-plugin-storybook": "*", - "react": "^18.2.0", - "react-dom": "^18.2.0" + "react": "catalog:", + "react-dom": "catalog:" }, "devDependencies": { - "eslint": "^9.26.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-prettier": "^8.5.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-react": "^7.29.2", - "eslint-plugin-react-hooks": "^4.3.0", - "prettier": "^2.8.7" + "eslint": "catalog:", + "eslint-config-airbnb": "catalog:", + "eslint-config-prettier": "catalog:", + "eslint-import-resolver-root-import": "catalog:", + "eslint-plugin-import": "catalog:", + "eslint-plugin-jest": "catalog:", + "eslint-plugin-jsx-a11y": "catalog:", + "eslint-plugin-prettier": "catalog:", + "eslint-plugin-react": "catalog:", + "eslint-plugin-react-hooks": "catalog:", + "prettier": "catalog:" }, "eslintConfig": { "plugins": [ diff --git a/ts-packages/types/package.json b/ts-packages/types/package.json index 8a95e038d7..f1b9335e35 100644 --- a/ts-packages/types/package.json +++ b/ts-packages/types/package.json @@ -10,26 +10,27 @@ "bech32": "^1.1.4" }, "devDependencies": { - "@nymproject/eslint-config-react-typescript": "^1.0.0", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", - "eslint": "^9.26.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^16.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-react": "^7.29.2", - "eslint-plugin-react-hooks": "^4.3.0", - "prettier": "^2.8.7", - "typescript": "^4.6.2", - "ts-jest": "^27.0.5", - "jest": "^27.1.0", + "@nymproject/eslint-config-react-typescript": "workspace:*", + "@types/bs58": "catalog:", + "@typescript-eslint/eslint-plugin": "catalog:", + "@typescript-eslint/parser": "catalog:", "babel-plugin-root-import": "^5.1.0", - "rimraf": "^3.0.2" + "eslint": "catalog:", + "eslint-config-airbnb": "catalog:", + "eslint-config-airbnb-typescript": "catalog:", + "eslint-config-prettier": "catalog:", + "eslint-import-resolver-root-import": "catalog:", + "eslint-plugin-import": "catalog:", + "eslint-plugin-jest": "catalog:", + "eslint-plugin-jsx-a11y": "catalog:", + "eslint-plugin-prettier": "catalog:", + "eslint-plugin-react": "catalog:", + "eslint-plugin-react-hooks": "catalog:", + "jest": "catalog:", + "prettier": "catalog:", + "rimraf": "catalog:", + "ts-jest": "catalog:", + "typescript": "^4.6.2" }, "scripts": { "clean": "rimraf dist", diff --git a/ts-packages/webpack/package.json b/ts-packages/webpack/package.json index 7b3b6e6106..42219cbc76 100644 --- a/ts-packages/webpack/package.json +++ b/ts-packages/webpack/package.json @@ -5,37 +5,37 @@ "license": "Apache-2.0", "main": "index.js", "peerDependencies": { - "react": "^18.2.0", - "react-dom": "^18.2.0" + "react": "catalog:", + "react-dom": "catalog:" }, "devDependencies": { - "@babel/core": "^7.15.0", - "@babel/plugin-transform-async-to-generator": "^7.14.5", - "@babel/preset-env": "^7.15.0", - "@babel/preset-react": "^7.14.5", - "@babel/preset-typescript": "^7.15.0", - "@svgr/webpack": "^6.1.1", - "babel-loader": "^8.3.0", - "clean-webpack-plugin": "^4.0.0", - "css-loader": "^6.7.3", - "dotenv-webpack": "^7.0.3", - "eslint": "^9.26.0", - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-prettier": "^4.0.0", - "favicons": "^7.0.2", - "favicons-webpack-plugin": "^5.0.2", - "file-loader": "^6.2.0", - "fork-ts-checker-webpack-plugin": "^7.2.1", - "html-webpack-plugin": "^5.3.2", - "prettier": "^2.8.7", - "style-loader": "^3.3.1", - "tsconfig-paths-webpack-plugin": "^3.5.2", - "url-loader": "^4.1.1", - "webpack": "^5.75.0", - "webpack-cli": "^4.8.0", - "webpack-dev-server": "^4.5.0", - "webpack-favicons": "^1.3.8", - "webpack-merge": "^5.8.0" + "@babel/core": "catalog:", + "@babel/plugin-transform-async-to-generator": "catalog:", + "@babel/preset-env": "catalog:", + "@babel/preset-react": "catalog:", + "@babel/preset-typescript": "catalog:", + "@svgr/webpack": "catalog:", + "babel-loader": "catalog:", + "clean-webpack-plugin": "catalog:", + "css-loader": "catalog:", + "dotenv-webpack": "catalog:", + "eslint": "catalog:", + "eslint-config-prettier": "catalog:", + "eslint-plugin-prettier": "catalog:", + "favicons": "catalog:", + "favicons-webpack-plugin": "catalog:", + "file-loader": "catalog:", + "fork-ts-checker-webpack-plugin": "catalog:", + "html-webpack-plugin": "catalog:", + "prettier": "catalog:", + "style-loader": "catalog:", + "tsconfig-paths-webpack-plugin": "catalog:", + "url-loader": "catalog:", + "webpack": "catalog:", + "webpack-cli": "catalog:", + "webpack-dev-server": "catalog:", + "webpack-favicons": "catalog:", + "webpack-merge": "catalog:" }, "scripts": { "lint": "eslint *.js", diff --git a/wasm/client/Cargo.toml b/wasm/client/Cargo.toml index eed416767b..51433ca602 100644 --- a/wasm/client/Cargo.toml +++ b/wasm/client/Cargo.toml @@ -38,10 +38,6 @@ nym-wasm-client-core = { workspace = true } nym-wasm-utils = { workspace = true } nym-gateway-requests = { workspace = true } -nym-node-tester-utils = { workspace = true, optional = true } - -nym-node-tester-wasm = { path = "../node-tester", optional = true } - tokio_with_wasm = { workspace = true, features = ["full"] } @@ -49,8 +45,7 @@ tokio_with_wasm = { workspace = true, features = ["full"] } wasm-bindgen-test = { workspace = true } [features] -default = ["node-tester"] -node-tester = ["nym-node-tester-wasm", "nym-node-tester-utils"] +default = [] [package.metadata.wasm-pack.profile.release] wasm-opt = false diff --git a/wasm/client/Makefile b/wasm/client/Makefile index 049108e8d1..79ff276f55 100644 --- a/wasm/client/Makefile +++ b/wasm/client/Makefile @@ -1,18 +1,25 @@ +UNAME_S := $(shell uname -s) +ifeq ($(UNAME_S),Linux) + TASKSET := taskset -c 0-11 +else + TASKSET := +endif + all: build build-node build: test build-wasm build-wasm: - taskset -c 0-11 wasm-pack build --scope nymproject --target web --out-dir ../../dist/wasm/client - taskset -c 0-11 wasm-opt -Oz -o ../../dist/wasm/client/nym_client_wasm_bg.wasm ../../dist/wasm/client/nym_client_wasm_bg.wasm + $(TASKSET) wasm-pack build --scope nymproject --target web --out-dir ../../dist/wasm/client + $(TASKSET) wasm-opt -Oz -o ../../dist/wasm/client/nym_client_wasm_bg.wasm ../../dist/wasm/client/nym_client_wasm_bg.wasm build-debug-dev: wasm-pack build --debug --scope nymproject --target no-modules build-rust-node: - taskset -c 0-11 wasm-pack build --scope nymproject --target nodejs --out-dir ../../dist/node/wasm/client - taskset -c 0-11 wasm-opt -Oz -o ../../dist/node/wasm/client/nym_client_wasm_bg.wasm ../../dist/node/wasm/client/nym_client_wasm_bg.wasm + $(TASKSET) wasm-pack build --scope nymproject --target nodejs --out-dir ../../dist/node/wasm/client + $(TASKSET) wasm-opt -Oz -o ../../dist/node/wasm/client/nym_client_wasm_bg.wasm ../../dist/node/wasm/client/nym_client_wasm_bg.wasm build-package-json-node: node build-node.mjs diff --git a/wasm/client/src/client.rs b/wasm/client/src/client.rs index 7d6df14b35..1a5f14f431 100644 --- a/wasm/client/src/client.rs +++ b/wasm/client/src/client.rs @@ -28,8 +28,8 @@ use nym_wasm_client_core::nym_task::ShutdownTracker; use nym_wasm_client_core::storage::core_client_traits::FullWasmClientStorage; use nym_wasm_client_core::storage::wasm_client_traits::WasmClientStorage; use nym_wasm_client_core::storage::ClientStorage; -use nym_wasm_client_core::topology::{SerializableTopologyExt, WasmFriendlyNymTopology}; -use nym_wasm_client_core::{IdentityKey, NymTopology, PacketType, QueryReqwestRpcNyxdClient}; +use nym_wasm_client_core::topology::WasmFriendlyNymTopology; +use nym_wasm_client_core::{IdentityKey, PacketType, QueryReqwestRpcNyxdClient}; use nym_wasm_utils::error::PromisableResult; use nym_wasm_utils::{check_promise_result, console_error, console_log}; use serde::{Deserialize, Serialize}; @@ -39,16 +39,6 @@ use tsify::Tsify; use wasm_bindgen::prelude::*; use wasm_bindgen_futures::future_to_promise; -#[cfg(feature = "node-tester")] -use crate::helpers::{NymClientTestRequest, WasmTopologyTestExt}; - -#[cfg(feature = "node-tester")] -use rand::{rngs::OsRng, RngCore}; - -#[cfg(feature = "node-tester")] -#[allow(dead_code)] -pub(crate) const NODE_TESTER_CLIENT_ID: &str = "_nym-node-tester-client"; - pub type ClientRequestSender = mpsc::Sender; #[wasm_bindgen] @@ -57,10 +47,6 @@ pub struct NymClient { client_input: Arc, client_state: Arc, - // keep track of the "old" topology for the purposes of node tester - // so that it could be restored after the check is done - _full_topology: Option, - // even though we don't use graceful shutdowns, other components rely on existence of this struct // and if it's dropped, everything will start going offline _task_manager: ShutdownTracker, @@ -102,37 +88,6 @@ impl NymClientBuilder { } } - // no cover traffic - // no poisson delay - // hardcoded topology - // NOTE: you most likely want to use `[NymNodeTester]` instead. - #[cfg(feature = "node-tester")] - pub fn new_tester( - topology: WasmFriendlyNymTopology, - on_message: js_sys::Function, - gateway: Option, - ) -> Result { - if let Some(gateway_id) = &gateway { - if !topology.ensure_contains_gateway_id(gateway_id) { - panic!("the specified topology does not contain the gateway used by the client") - } - } - - let _ = on_message; - // let full_config = ClientConfig::new_tester_config(NODE_TESTER_CLIENT_ID); - // Ok(NymClientBuilder { - // config: full_config, - // force_tls: false, - // custom_topology: Some(topology.try_into()?), - // on_message, - // storage_passphrase: None, - // preferred_gateway: gateway, - // latency_based_selection: None, - // }) - - Err(WasmClientError::DisabledTester) - } - fn start_reconstructed_pusher(client_output: ClientOutput, on_message: js_sys::Function) { ResponsePusher::new(client_output, on_message).start() } @@ -255,7 +210,6 @@ impl NymClientBuilder { self_address, client_input: Arc::new(client_input), client_state: Arc::new(started_client.client_state), - _full_topology: None, _task_manager: started_client.shutdown_handle, packet_type, }) @@ -394,34 +348,11 @@ impl NymClient { }) } - // no cover traffic - // no poisson delay - // hardcoded topology - // NOTE: you most likely want to use `[NymNodeTester]` instead. - #[cfg(feature = "node-tester")] - #[wasm_bindgen(js_name = "newTester")] - pub fn new_tester() -> Promise { - todo!() - } - #[wasm_bindgen(js_name = "selfAddress")] pub fn self_address(&self) -> String { self.self_address.clone() } - #[cfg(feature = "node-tester")] - pub fn try_construct_test_packet_request( - &self, - mixnode_identity: String, - num_test_packets: Option, - ) -> Promise { - // TODO: improve the source of rng (i.e. don't make it ephemeral...) - let mut ephemeral_rng = OsRng; - let test_id = ephemeral_rng.next_u32(); - self.client_state - .mix_test_request(test_id, mixnode_identity, num_test_packets) - } - pub fn change_hardcoded_topology(&self, topology: WasmFriendlyNymTopology) -> Promise { self.client_state.change_hardcoded_topology(topology) } @@ -430,30 +361,6 @@ impl NymClient { self.client_state.current_topology() } - /// Sends a test packet through the current network topology. - /// It's the responsibility of the caller to ensure the correct topology has been injected and - /// correct onmessage handlers have been setup. - #[cfg(feature = "node-tester")] - pub fn try_send_test_packets(&mut self, request: NymClientTestRequest) -> Promise { - // TOOD: use the premade packets instead - console_log!( - "Attempting to send {} test packets", - request.test_msgs.len() - ); - - // our address MUST BE valid - let recipient = parse_recipient(&self.self_address()).unwrap(); - - let lane = TransmissionLane::General; - let input_msgs = request - .test_msgs - .into_iter() - .map(|p| InputMessage::new_regular(recipient, p, lane, None)) - .collect(); - - self.client_input.send_messages(input_msgs) - } - /// The simplest message variant where no additional information is attached. /// You're simply sending your `data` to specified `recipient` without any tagging. /// diff --git a/wasm/client/src/config.rs b/wasm/client/src/config.rs index 06249c6bd4..706e60c760 100644 --- a/wasm/client/src/config.rs +++ b/wasm/client/src/config.rs @@ -52,17 +52,6 @@ impl ClientConfig { base: new_base_client_config(id, version, opts.nym_api, opts.nyxd, opts.debug)?, }) } - - #[cfg(feature = "node-tester")] - #[allow(dead_code)] - pub(crate) fn new_tester_config>(id: S) -> Self { - ClientConfig { - base: BaseClientConfig::new(id.into(), env!("CARGO_PKG_VERSION").to_string()) - .with_disabled_credentials(true) - .with_disabled_cover_traffic(true) - .with_disabled_topology_refresh(true), - } - } } impl ClientConfig { diff --git a/wasm/client/src/error.rs b/wasm/client/src/error.rs index 48598833b2..77e78cc282 100644 --- a/wasm/client/src/error.rs +++ b/wasm/client/src/error.rs @@ -7,9 +7,6 @@ use nym_wasm_client_core::ClientCoreError; use nym_wasm_utils::wasm_error; use thiserror::Error; -#[cfg(feature = "node-tester")] -use nym_node_tester_utils::error::NetworkTestingError; - #[derive(Debug, Error)] pub enum WasmClientError { #[error(transparent)] @@ -29,16 +26,6 @@ pub enum WasmClientError { #[from] source: WasmTopologyError, }, - - #[cfg(feature = "node-tester")] - #[error("failed to test the node: {source}")] - NodeTestingFailure { - #[from] - source: NetworkTestingError, - }, - - #[error("the node testing features are currently disabled")] - DisabledTester, } // I dislike this so much - there must be a better way. diff --git a/wasm/client/src/helpers.rs b/wasm/client/src/helpers.rs index d568d76250..a756242148 100644 --- a/wasm/client/src/helpers.rs +++ b/wasm/client/src/helpers.rs @@ -5,7 +5,7 @@ use js_sys::Promise; use nym_wasm_client_core::client::base_client::{ClientInput, ClientState}; use nym_wasm_client_core::client::inbound_messages::InputMessage; use nym_wasm_client_core::error::WasmCoreError; -use nym_wasm_client_core::topology::{Role, WasmFriendlyNymTopology}; +use nym_wasm_client_core::topology::WasmFriendlyNymTopology; use nym_wasm_client_core::NymTopology; use nym_wasm_utils::error::simple_js_error; use nym_wasm_utils::{check_promise_result, console_log}; @@ -13,38 +13,11 @@ use std::sync::Arc; use wasm_bindgen::JsValue; use wasm_bindgen_futures::future_to_promise; -#[cfg(feature = "node-tester")] -use nym_node_tester_wasm::types::{NodeTestMessage, WasmTestMessageExt}; - -#[cfg(feature = "node-tester")] -use wasm_bindgen::prelude::wasm_bindgen; - -#[cfg(feature = "node-tester")] -pub(crate) const DEFAULT_TEST_PACKETS: u32 = 20; - -#[cfg(feature = "node-tester")] -#[wasm_bindgen] -pub struct NymClientTestRequest { - // serialized NodeTestMessage - pub(crate) test_msgs: Vec>, - - // specially constructed network topology that only contains the target - // node on the tested layer - pub(crate) testable_topology: NymTopology, -} - -#[cfg(feature = "node-tester")] -#[wasm_bindgen] -impl NymClientTestRequest { - pub fn injectable_topology(&self) -> WasmFriendlyNymTopology { - self.testable_topology.clone().into() - } -} - // defining helper trait as we could directly call the method on the wrapper pub(crate) trait InputSender { fn send_message(&self, message: InputMessage) -> Promise; + #[allow(dead_code)] fn send_messages(&self, messages: Vec) -> Promise; } @@ -84,17 +57,6 @@ pub(crate) trait WasmTopologyExt { fn current_topology(&self) -> Promise; } -#[cfg(feature = "node-tester")] -pub(crate) trait WasmTopologyTestExt { - /// Creates a `NymClientTestRequest` with a variant of `this` topology where the target node is the only one on its layer. - fn mix_test_request( - &self, - test_id: u32, - mixnode_identity: String, - num_test_packets: Option, - ) -> Promise; -} - impl WasmTopologyExt for Arc { fn change_hardcoded_topology(&self, topology: WasmFriendlyNymTopology) -> Promise { let nym_topology: NymTopology = check_promise_result!(topology.try_into()); @@ -122,43 +84,3 @@ impl WasmTopologyExt for Arc { }) } } - -#[cfg(feature = "node-tester")] -impl WasmTopologyTestExt for Arc { - fn mix_test_request( - &self, - test_id: u32, - mixnode_identity: String, - num_test_packets: Option, - ) -> Promise { - let num_test_packets = num_test_packets.unwrap_or(DEFAULT_TEST_PACKETS); - - let this = Arc::clone(self); - future_to_promise(async move { - let Some(current_topology) = this.topology_accessor.current_route_provider().await - else { - return Err(WasmCoreError::UnavailableNetworkTopology.into()); - }; - - let Ok(node_identity) = mixnode_identity.parse() else { - return Err(WasmCoreError::NonExistentMixnode { mixnode_identity }.into()); - }; - - let Some(mix) = current_topology.node_by_identity(node_identity) else { - return Err(WasmCoreError::NonExistentMixnode { mixnode_identity }.into()); - }; - - let mut updated = current_topology.topology.clone(); - updated.set_testable_node(Role::Layer2, mix.clone()); - - let ext = WasmTestMessageExt::new(test_id); - let test_msgs = NodeTestMessage::mix_plaintexts(mix, num_test_packets, ext) - .map_err(crate::error::WasmClientError::from)?; - - Ok(JsValue::from(NymClientTestRequest { - test_msgs, - testable_topology: updated, - })) - }) - } -} diff --git a/wasm/full-nym-wasm/.cargo/config.toml b/wasm/full-nym-wasm/.cargo/config.toml deleted file mode 100644 index e9c3438b6e..0000000000 --- a/wasm/full-nym-wasm/.cargo/config.toml +++ /dev/null @@ -1,4 +0,0 @@ -[build] -target = "wasm32-unknown-unknown" -target_arch = "wasm32" -rustflags = ["--cfg=getrandom_backend=\"wasm_js\""] \ No newline at end of file diff --git a/wasm/full-nym-wasm/Cargo.toml b/wasm/full-nym-wasm/Cargo.toml deleted file mode 100644 index ee6aadf5fe..0000000000 --- a/wasm/full-nym-wasm/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "nym-wasm-sdk" -version = "1.2.2" -authors = ["Jedrzej Stuczynski "] -edition = "2021" -license = "Apache-2.0" -repository = "https://github.com/nymtech/nym" -rust-version = "1.85" -publish = false -keywords = ["nym", "sphinx", "wasm", "webassembly", "privacy"] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -crate-type = ["cdylib", "rlib"] - -[dependencies] -nym-client-wasm = { workspace = true, optional = true } - -nym-node-tester-wasm = { path = "../node-tester", optional = true } -mix-fetch-wasm = { workspace = true, optional = true } - -[features] -default = ["client", "node-tester"] -client = ["nym-client-wasm"] -node-tester = ["nym-node-tester-wasm"] -mix-fetch = ["mix-fetch-wasm"] - -[package.metadata.wasm-pack.profile.release] -wasm-opt = false diff --git a/wasm/full-nym-wasm/Makefile b/wasm/full-nym-wasm/Makefile deleted file mode 100644 index fa2467d10c..0000000000 --- a/wasm/full-nym-wasm/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -all: build-full - -build-full: - taskset -c 0-11 wasm-pack build --all-features --scope nymproject --target web --out-dir ../../dist/wasm/full-nym-wasm - taskset -c 0-11 wasm-opt -Oz -o ../../dist/wasm/full-nym-wasm/nym_wasm_sdk_bg.wasm ../../dist/wasm/full-nym-wasm/nym_wasm_sdk_bg.wasm diff --git a/wasm/full-nym-wasm/src/lib.rs b/wasm/full-nym-wasm/src/lib.rs deleted file mode 100644 index 8f2009bcbf..0000000000 --- a/wasm/full-nym-wasm/src/lib.rs +++ /dev/null @@ -1,11 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -#[cfg(all(target_arch = "wasm32", feature = "client"))] -pub use nym_client_wasm as client; - -#[cfg(all(target_arch = "wasm32", feature = "node-tester"))] -pub use nym_node_tester_wasm as node_tester; - -#[cfg(all(target_arch = "wasm32", feature = "mix-fetch"))] -pub use mix_fetch_wasm as mix_fetch; diff --git a/wasm/mix-fetch/Makefile b/wasm/mix-fetch/Makefile index 66a3106377..1f55c9846f 100644 --- a/wasm/mix-fetch/Makefile +++ b/wasm/mix-fetch/Makefile @@ -1,3 +1,10 @@ +UNAME_S := $(shell uname -s) +ifeq ($(UNAME_S),Linux) + TASKSET := taskset -c 0-11 +else + TASKSET := +endif + build: build-go-opt build-rust build-package-json check-fmt: check-fmt-go check-fmt-rust @@ -9,9 +16,9 @@ build-go-opt: $(MAKE) -C go-mix-conn build-go-opt build-rust: - taskset -c 0-11 wasm-pack build --scope nymproject --target web --out-dir ../../dist/wasm/mix-fetch - # taskset -c 0-11 wasm-pack build --scope nymproject --target no-modules --out-dir ../../dist/wasm/mix-fetch - taskset -c 0-11 wasm-opt -Oz -o ../../dist/wasm/mix-fetch/mix_fetch_wasm_bg.wasm ../../dist/wasm/mix-fetch/mix_fetch_wasm_bg.wasm + $(TASKSET) wasm-pack build --scope nymproject --target web --out-dir ../../dist/wasm/mix-fetch + # $(TASKSET) wasm-pack build --scope nymproject --target no-modules --out-dir ../../dist/wasm/mix-fetch + $(TASKSET) wasm-opt -Oz -o ../../dist/wasm/mix-fetch/mix_fetch_wasm_bg.wasm ../../dist/wasm/mix-fetch/mix_fetch_wasm_bg.wasm build-rust-debug: wasm-pack build --debug --scope nymproject --target no-modules diff --git a/wasm/node-tester/.cargo/config.toml b/wasm/node-tester/.cargo/config.toml deleted file mode 100644 index e9c3438b6e..0000000000 --- a/wasm/node-tester/.cargo/config.toml +++ /dev/null @@ -1,4 +0,0 @@ -[build] -target = "wasm32-unknown-unknown" -target_arch = "wasm32" -rustflags = ["--cfg=getrandom_backend=\"wasm_js\""] \ No newline at end of file diff --git a/wasm/node-tester/Cargo.toml b/wasm/node-tester/Cargo.toml deleted file mode 100644 index 88e7e5b9a5..0000000000 --- a/wasm/node-tester/Cargo.toml +++ /dev/null @@ -1,36 +0,0 @@ -[package] -name = "nym-node-tester-wasm" -version = "1.3.1" -authors = ["Jedrzej Stuczynski "] -edition = "2021" -license = "Apache-2.0" -repository = "https://github.com/nymtech/nym" -rust-version = "1.85" -publish = false -keywords = ["nym", "sphinx", "webassembly", "privacy", "tester"] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -crate-type = ["cdylib", "rlib"] - -[dependencies] -futures = { workspace = true } -js-sys = { workspace = true } -rand = { workspace = true } -serde = { workspace = true, features = ["derive"] } -serde-wasm-bindgen = { workspace = true } -tokio = { workspace = true, features = ["sync"] } -wasm-bindgen = { workspace = true } -wasm-bindgen-futures = { workspace = true } -thiserror = { workspace = true } -tsify = { workspace = true, features = ["js"] } - -wasmtimer = { workspace = true } - -nym-node-tester-utils = { workspace = true } -nym-wasm-client-core = { workspace = true } -nym-wasm-utils = { workspace = true } - -[package.metadata.wasm-pack.profile.release] -wasm-opt = false diff --git a/wasm/node-tester/Makefile b/wasm/node-tester/Makefile deleted file mode 100644 index a3014ca0ba..0000000000 --- a/wasm/node-tester/Makefile +++ /dev/null @@ -1,5 +0,0 @@ -all: build - -build: - wasm-pack build --scope nymproject --target web --out-dir ../../dist/wasm/node-tester - wasm-opt -Oz -o ../../dist/wasm/node-tester/nym_node_tester_wasm_bg.wasm ../../dist/wasm/node-tester/nym_node_tester_wasm_bg.wasm diff --git a/wasm/node-tester/internal-dev/.gitignore b/wasm/node-tester/internal-dev/.gitignore deleted file mode 100644 index f06235c460..0000000000 --- a/wasm/node-tester/internal-dev/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -dist diff --git a/wasm/node-tester/internal-dev/bootstrap.js b/wasm/node-tester/internal-dev/bootstrap.js deleted file mode 100644 index a017926b28..0000000000 --- a/wasm/node-tester/internal-dev/bootstrap.js +++ /dev/null @@ -1,5 +0,0 @@ -// A dependency graph that contains any wasm must all be imported -// asynchronously. This `bootstrap.js` file does the single async import, so -// that no one else needs to worry about it again. -import('./index.js') - .catch(e => console.error('Error importing `index.js`:', e)); diff --git a/wasm/node-tester/internal-dev/index.html b/wasm/node-tester/internal-dev/index.html deleted file mode 100644 index 8182be7ab6..0000000000 --- a/wasm/node-tester/internal-dev/index.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - - Nym WebAssembly Demo - - - - -

- -

- -

- -

-

- -

-

- -

- -
- - - -
- - -

Send messages from your browser, through the mixnet, and to the recipient using the "send" button.

-

Sent messages show in blue, received - messages show in green.

- -
-

- -

- - - - \ No newline at end of file diff --git a/wasm/node-tester/internal-dev/index.js b/wasm/node-tester/internal-dev/index.js deleted file mode 100644 index 0ff5c3a191..0000000000 --- a/wasm/node-tester/internal-dev/index.js +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright 2020-2023 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -class WebWorkerClient { - worker = null; - - constructor() { - this.worker = new Worker('./worker.js'); - - this.worker.onmessage = (ev) => { - if (ev.data && ev.data.kind) { - switch (ev.data.kind) { - case 'Ready': - const {selfAddress} = ev.data.args; - displaySenderAddress(selfAddress); - break; - case 'ReceiveMessage': - const {message, senderTag, isTestPacket } = ev.data.args; - displayReceived(message, senderTag, isTestPacket); - break; - case 'DisplayString': - const { rawString } = ev.data.args; - displayReceivedRawString(rawString) - break; - case 'DisableMagicTestButton': - const magicButton = document.querySelector('#magic-button'); - magicButton.setAttribute('disabled', "true") - break; - case 'DisplayTesterResults': - const {score, sentPackets, receivedPackets, receivedAcks, duplicatePackets, duplicateAcks} = ev.data.args; - const resultText = `Test score: ${score}. Sent ${sentPackets} packets. Received ${receivedPackets} packets and ${receivedAcks} acks back. We also got ${duplicatePackets} duplicate packets and ${duplicateAcks} duplicate acks.` - displayReceivedRawString(resultText) - break; - } - } - }; - } - - sendMessage = (message, recipient) => { - if (!this.worker) { - console.error('Could not send message because worker does not exist'); - return; - } - - this.worker.postMessage({ - kind: 'SendMessage', - args: { - message, recipient, - }, - }); - }; - - sendMagicPayload = (mixnodeIdentity) => { - if (!this.worker) { - console.error('Could not send message because worker does not exist'); - return; - } - - this.worker.postMessage({ - kind: 'MagicPayload', - args: { - mixnodeIdentity, - }, - }); - } -} - -let client = null; - -async function main() { - client = new WebWorkerClient(); - - const sendButton = document.querySelector('#send-button'); - sendButton.onclick = function () { - sendMessageTo(); - }; - - const magicButton = document.querySelector('#magic-button'); - magicButton.onclick = function () { - sendMagicPayload(); - } -} - -/** - * Create a Sphinx packet and send it to the mixnet through the gateway node. - * - * Message and recipient are taken from the values in the user interface. - * - */ -async function sendMessageTo() { - const message = document.getElementById('message').value; - const recipient = document.getElementById('recipient').value; - - await client.sendMessage(message, recipient); - displaySend(message); -} - -async function sendMagicPayload() { - const payload = document.getElementById('magic_payload').value; - await client.sendMagicPayload(payload) - - displaySend(`clicked the button and the payload is: ${payload}...`); -} - -/** - * Display messages that have been sent up the websocket. Colours them blue. - * - * @param {string} message - */ -function displaySend(message) { - let timestamp = new Date().toISOString().substr(11, 12); - - let sendDiv = document.createElement('div'); - let paragraph = document.createElement('p'); - paragraph.setAttribute('style', 'color: blue'); - let paragraphContent = document.createTextNode(timestamp + ' sent >>> ' + message); - paragraph.appendChild(paragraphContent); - - sendDiv.appendChild(paragraph); - document.getElementById('output').appendChild(sendDiv); -} - -/** - * Display received text messages in the browser. Colour them green. - * - * @param {Uint8Array} raw - */ -function displayReceived(raw, sender_tag, isTestPacket) { - let content = new TextDecoder().decode(raw); - if (sender_tag !== undefined) { - console.log("this message also contained some surbs from", sender_tag) - } - - if (isTestPacket) { - const decoded = JSON.parse(content) - content = `Received packet ${decoded.msg_id} / ${decoded.total_msgs} for node ${decoded.encoded_node_identity} (test: ${decoded.test_id})` - } - - displayReceivedRawString(content) -} - -function displayReceivedRawString(raw) { - let timestamp = new Date().toISOString().substr(11, 12); - let receivedDiv = document.createElement('div'); - let paragraph = document.createElement('p'); - paragraph.setAttribute('style', 'color: green'); - let paragraphContent = document.createTextNode(timestamp + ' received >>> ' + raw); - paragraph.appendChild(paragraphContent); - receivedDiv.appendChild(paragraph); - document.getElementById('output').appendChild(receivedDiv); -} - -/** - * Display the nymClient's sender address in the user interface - * - * @param {String} address - */ -function displaySenderAddress(address) { - document.getElementById('sender').value = address; -} - -main(); diff --git a/wasm/node-tester/internal-dev/package.json b/wasm/node-tester/internal-dev/package.json deleted file mode 100644 index c4f96d644c..0000000000 --- a/wasm/node-tester/internal-dev/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "create-wasm-app", - "version": "0.1.0", - "description": "create an app to consume rust-generated wasm packages", - "main": "index.js", - "bin": { - "create-wasm-app": ".bin/create-wasm-app.js" - }, - "scripts": { - "build": "webpack --config webpack.config.js", - "build:wasm": "cd ../ && make wasm-build", - "start": "webpack-dev-server --port 8001" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/rustwasm/create-wasm-app.git" - }, - "keywords": [ - "webassembly", - "wasm", - "rust", - "webpack" - ], - "author": "Dave Hrycyszyn ", - "license": "Apache-2.0", - "bugs": { - "url": "https://github.com/nymtech/nym/issues" - }, - "homepage": "https://nymtech.net/docs", - "devDependencies": { - "copy-webpack-plugin": "^11.0.0", - "hello-wasm-pack": "^0.1.0", - "webpack": "^5.70.0", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.7.4" - }, - "dependencies": { - "@nymproject/nym_node_tester_wasm": "file:../../../dist/wasm/node-tester" - } -} diff --git a/wasm/node-tester/internal-dev/webpack.config.js b/wasm/node-tester/internal-dev/webpack.config.js deleted file mode 100644 index 2e7ec5ce87..0000000000 --- a/wasm/node-tester/internal-dev/webpack.config.js +++ /dev/null @@ -1,33 +0,0 @@ -const CopyWebpackPlugin = require('copy-webpack-plugin'); -const path = require('path'); - -module.exports = { - performance: { - hints: false, - maxEntrypointSize: 512000, - maxAssetSize: 512000 - }, - entry: { - bootstrap: './bootstrap.js', - worker: './worker.js', - }, - output: { - path: path.resolve(__dirname, 'dist'), - filename: '[name].js', - }, - mode: 'development', - // mode: 'production', - plugins: [ - new CopyWebpackPlugin({ - patterns: [ - 'index.html', - { - from: '../../../dist/wasm/node-tester/*.(js|wasm)', - to: '[name][ext]', - }, - ], - }), - - ], - experiments: { syncWebAssembly: true }, -}; diff --git a/wasm/node-tester/internal-dev/worker.js b/wasm/node-tester/internal-dev/worker.js deleted file mode 100644 index a06e7e8a8c..0000000000 --- a/wasm/node-tester/internal-dev/worker.js +++ /dev/null @@ -1,152 +0,0 @@ -// Copyright 2020-2023 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -const RUST_WASM_URL = "nym_node_tester_wasm_bg.wasm" - -importScripts('nym_node_tester_wasm.js'); - -console.log('Initializing worker'); - -// wasm_bindgen creates a global variable (with the exports attached) that is in scope after `importScripts` -const { - default_debug, - no_cover_debug, - NymNodeTester, - set_panic_hook, - currentNetworkTopology, -} = wasm_bindgen; - -let client = null; - -function dummyTopology() { - const l1Mixnode = { - mixId: 1, - owner: 'n1lftjhnl35cjsfd533zhgrwrspx6qmumd8vjgp9', - host: '80.85.86.75', - mixPort: 1789, - identityKey: '91mNjhJSBkJ9Lb6f1iuYMDQPLiX3kAv6paSUCWjGRwQz', - sphinxKey: 'DmfN1mL1T95nPXvLK44AQKCpW1pStHNQCi6Fgpz5dxDV', - layer: 1, - version: '1.1.20', - }; - const l2Mixnode = { - mixId: 2, - owner: 'n18ztkyh20gwzrel0e5m4sahd358fq9p4skwa7d3', - host: '139.162.199.75', - mixPort: 1789, - identityKey: 'BkLhuKQNyPS19sHZ3HHKCTKwK7hCU6XiFLndyZZHiB7s', - sphinxKey: '7KGC97tJRhJZKhDqFcsp4Vu715VVxizuD7BktnzuSmZC', - layer: 2, - version: '1.1.20', - }; - const l3Mixnode = { - mixId: 3, - owner: 'n1njq8h4nndp7ngays5el2rdp22hq67lwqcaq3ph', - host: '139.162.244.139', - identityKey: 'EPja9Kv8JtPHsFbzPdBQierMu5GmQy5roE5njyD6dmND', - sphinxKey: 'HWpsZChDrtEH8XNscW3qJMRzdCfUD8N8DmMcKqFv7tcf', - layer: 3, - }; - - const gateway = { - owner: 'n1d9lclqnfddgg57xe5p0fw4ng54m9f95hal5tlq', - host: '85.159.211.99', - mixPort: 1789, - clientsPort: 9000, - identityKey: '6pXQcG1Jt9hxBzMgTbQL5Y58z6mu4KXVRbA1idmibwsw', - sphinxKey: 'GSdqV7GFSwHWQrVV13pNLMeafTLDVFKBKVPxuhdGrpR3', - version: '1.1.19', - }; - - const mixnodes = new Map(); - mixnodes.set(1, [l1Mixnode]); - mixnodes.set(2, [l2Mixnode]); - mixnodes.set(3, [l3Mixnode]); - - const gateways = [gateway]; - - return { - mixnodes, gateways - } -} - - -function printAndDisplayTestResult(result) { - result.log_details(); - - self.postMessage({ - kind: 'DisplayTesterResults', - args: { - score: result.score(), - sentPackets: result.sent_packets, - receivedPackets: result.received_packets, - receivedAcks: result.received_acks, - duplicatePackets: result.duplicate_packets, - duplicateAcks: result.duplicate_acks, - }, - }); -} - -async function testWithTester() { - const preferredGateway = "6pXQcG1Jt9hxBzMgTbQL5Y58z6mu4KXVRbA1idmibwsw"; - const nymApi = 'https://qa-nym-api.qa.nymte.ch/api'; - - // A) construct with hardcoded topology - const topology = dummyTopology() - - // optional arguments: id, gateway - // mandatory (one of) arguments: topology, nymApi - const nodeTester = await new NymNodeTester({ id: "foomp", topology: topology }); - - // B) first get topology directly from nym-api - // const topology = await currentNetworkTopology(nymApi) - // const nodeTester = await new NymNodeTester({topology}); - - // C) use nym-api in the constructor (note: it does no filtering for 'good' nodes on other layers) - // const validator = 'https://qa-nym-api.qa.nymte.ch/api'; - // const nodeTester = await new NymNodeTester({nymApi}); - - self.onmessage = async event => { - if (event.data && event.data.kind) { - switch (event.data.kind) { - case 'MagicPayload': { - const {mixnodeIdentity} = event.data.args; - console.log("starting node test..."); - - let result = await nodeTester.test_node(mixnodeIdentity); - printAndDisplayTestResult(result) - } - } - } - }; -} - -async function main() { - console.log(">>>>>>>>>>>>>>>>>>>>> JS WORKER MAIN START"); - - // load rust WASM package - await wasm_bindgen(RUST_WASM_URL); - console.log('Loaded RUST WASM'); - - // sets up better stack traces in case of in-rust panics - set_panic_hook(); - // - // run test on simplified and dedicated tester: - await testWithTester(); - // - console.log(">>>>>>>>>>>>>>>>>>>>> JS WORKER MAIN END") -} - -// Let's get started! -main(); \ No newline at end of file diff --git a/wasm/node-tester/internal-dev/yarn-error.log b/wasm/node-tester/internal-dev/yarn-error.log deleted file mode 100644 index d3dea0efe1..0000000000 --- a/wasm/node-tester/internal-dev/yarn-error.log +++ /dev/null @@ -1,2261 +0,0 @@ -Arguments: - /Users/jedrzej/.nvm/versions/node/v16.20.0/bin/node /Users/jedrzej/.nvm/versions/node/v16.20.0/bin/yarn install - -PATH: - /Users/jedrzej/.nvm/versions/node/v16.20.0/bin:/Library/Frameworks/Python.framework/Versions/3.11/bin:/opt/homebrew/bin:/opt/homebrew/sbin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/go/bin:/Library/Apple/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/Users/jedrzej/.cargo/bin:/Users/jedrzej/Library/Application Support/JetBrains/Toolbox/scripts - -Yarn version: - 1.22.19 - -Node version: - 16.20.0 - -Platform: - darwin arm64 - -Trace: - SyntaxError: /Users/jedrzej/workspace/nym/wasm/client/internal-dev/package.json: Unexpected token } in JSON at position 1030 - at JSON.parse () - at /Users/jedrzej/.nvm/versions/node/v16.20.0/lib/node_modules/yarn/lib/cli.js:1629:59 - at Generator.next () - at step (/Users/jedrzej/.nvm/versions/node/v16.20.0/lib/node_modules/yarn/lib/cli.js:310:30) - at /Users/jedrzej/.nvm/versions/node/v16.20.0/lib/node_modules/yarn/lib/cli.js:321:13 - -npm manifest: - { - "name": "create-wasm-app", - "version": "0.1.0", - "description": "create an app to consume rust-generated wasm packages", - "main": "index.js", - "bin": { - "create-wasm-app": ".bin/create-wasm-app.js" - }, - "scripts": { - "build": "webpack --config webpack.config.js", - "build:wasm": "cd ../ && make wasm-build", - "start": "webpack-dev-server --port 8001" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/rustwasm/create-wasm-app.git" - }, - "keywords": [ - "webassembly", - "wasm", - "rust", - "webpack" - ], - "author": "Dave Hrycyszyn ", - "license": "Apache-2.0", - "bugs": { - "url": "https://github.com/nymtech/nym/issues" - }, - "homepage": "https://nymtech.net/docs", - "devDependencies": { - "copy-webpack-plugin": "^10.2.4", - "hello-wasm-pack": "^0.1.0", - "webpack": "^5.70.0", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.7.4" - }, - "dependencies": { - "@nymproject/nym-client-wasm": "file:../pkg", - } - } - -yarn manifest: - No manifest - -Lockfile: - # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. - # yarn lockfile v1 - - - "@discoveryjs/json-ext@^0.5.0": - version "0.5.7" - resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" - integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== - - "@jridgewell/gen-mapping@^0.3.0": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" - integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - - "@jridgewell/resolve-uri@3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78" - integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w== - - "@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== - - "@jridgewell/source-map@^0.3.2": - version "0.3.2" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" - integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== - dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" - - "@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10": - version "1.4.14" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" - integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== - - "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.17" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" - integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== - dependencies: - "@jridgewell/resolve-uri" "3.1.0" - "@jridgewell/sourcemap-codec" "1.4.14" - - "@leichtgewicht/ip-codec@^2.0.1": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" - integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== - - "@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - - "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - - "@nodelib/fs.walk@^1.2.3": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - - "@nymproject/nym-client-wasm@file:../pkg": - version "1.1.1" - - "@types/body-parser@*": - version "1.19.2" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" - integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== - dependencies: - "@types/connect" "*" - "@types/node" "*" - - "@types/bonjour@^3.5.9": - version "3.5.10" - resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" - integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== - dependencies: - "@types/node" "*" - - "@types/connect-history-api-fallback@^1.3.5": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" - integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== - dependencies: - "@types/express-serve-static-core" "*" - "@types/node" "*" - - "@types/connect@*": - version "3.4.35" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" - integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== - dependencies: - "@types/node" "*" - - "@types/eslint-scope@^3.7.3": - version "3.7.4" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.4.tgz#37fc1223f0786c39627068a12e94d6e6fc61de16" - integrity sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" - - "@types/eslint@*": - version "8.37.0" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.37.0.tgz#29cebc6c2a3ac7fea7113207bf5a828fdf4d7ef1" - integrity sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - - "@types/estree@*": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2" - integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ== - - "@types/estree@^0.0.51": - version "0.0.51" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" - integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== - - "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": - version "4.17.33" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz#de35d30a9d637dc1450ad18dd583d75d5733d543" - integrity sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - - "@types/express@*", "@types/express@^4.17.13": - version "4.17.17" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.17.tgz#01d5437f6ef9cfa8668e616e13c2f2ac9a491ae4" - integrity sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.33" - "@types/qs" "*" - "@types/serve-static" "*" - - "@types/http-proxy@^1.17.8": - version "1.17.10" - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.10.tgz#e576c8e4a0cc5c6a138819025a88e167ebb38d6c" - integrity sha512-Qs5aULi+zV1bwKAg5z1PWnDXWmsn+LxIvUGv6E2+OOMYhclZMO+OXd9pYVf2gLykf2I7IV2u7oTHwChPNsvJ7g== - dependencies: - "@types/node" "*" - - "@types/json-schema@*", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": - version "7.0.11" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" - integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== - - "@types/mime@*": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" - integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== - - "@types/node@*": - version "18.15.11" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.11.tgz#b3b790f09cb1696cffcec605de025b088fa4225f" - integrity sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q== - - "@types/qs@*": - version "6.9.7" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" - integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== - - "@types/range-parser@*": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" - integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== - - "@types/retry@0.12.0": - version "0.12.0" - resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" - integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== - - "@types/serve-index@^1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" - integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== - dependencies: - "@types/express" "*" - - "@types/serve-static@*", "@types/serve-static@^1.13.10": - version "1.15.1" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.1.tgz#86b1753f0be4f9a1bee68d459fcda5be4ea52b5d" - integrity sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ== - dependencies: - "@types/mime" "*" - "@types/node" "*" - - "@types/sockjs@^0.3.33": - version "0.3.33" - resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" - integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== - dependencies: - "@types/node" "*" - - "@types/ws@^8.5.1": - version "8.5.4" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.4.tgz#bb10e36116d6e570dd943735f86c933c1587b8a5" - integrity sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg== - dependencies: - "@types/node" "*" - - "@webassemblyjs/ast@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7" - integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw== - dependencies: - "@webassemblyjs/helper-numbers" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - - "@webassemblyjs/floating-point-hex-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" - integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== - - "@webassemblyjs/helper-api-error@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" - integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== - - "@webassemblyjs/helper-buffer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" - integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== - - "@webassemblyjs/helper-numbers@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" - integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ== - dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@xtuc/long" "4.2.2" - - "@webassemblyjs/helper-wasm-bytecode@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" - integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== - - "@webassemblyjs/helper-wasm-section@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" - integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - - "@webassemblyjs/ieee754@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" - integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ== - dependencies: - "@xtuc/ieee754" "^1.2.0" - - "@webassemblyjs/leb128@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" - integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw== - dependencies: - "@xtuc/long" "4.2.2" - - "@webassemblyjs/utf8@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" - integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== - - "@webassemblyjs/wasm-edit@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" - integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/helper-wasm-section" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-opt" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - "@webassemblyjs/wast-printer" "1.11.1" - - "@webassemblyjs/wasm-gen@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" - integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - - "@webassemblyjs/wasm-opt@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" - integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-buffer" "1.11.1" - "@webassemblyjs/wasm-gen" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - - "@webassemblyjs/wasm-parser@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" - integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/helper-api-error" "1.11.1" - "@webassemblyjs/helper-wasm-bytecode" "1.11.1" - "@webassemblyjs/ieee754" "1.11.1" - "@webassemblyjs/leb128" "1.11.1" - "@webassemblyjs/utf8" "1.11.1" - - "@webassemblyjs/wast-printer@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" - integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg== - dependencies: - "@webassemblyjs/ast" "1.11.1" - "@xtuc/long" "4.2.2" - - "@webpack-cli/configtest@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.2.0.tgz#7b20ce1c12533912c3b217ea68262365fa29a6f5" - integrity sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg== - - "@webpack-cli/info@^1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.5.0.tgz#6c78c13c5874852d6e2dd17f08a41f3fe4c261b1" - integrity sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ== - dependencies: - envinfo "^7.7.3" - - "@webpack-cli/serve@^1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.7.0.tgz#e1993689ac42d2b16e9194376cfb6753f6254db1" - integrity sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q== - - "@xtuc/ieee754@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" - integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== - - "@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" - integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== - - accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: - version "1.3.8" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" - integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== - dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" - - acorn-import-assertions@^1.7.6: - version "1.8.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" - integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== - - acorn@^8.5.0, acorn@^8.7.1: - version "8.8.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" - integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== - - ajv-formats@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" - integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== - dependencies: - ajv "^8.0.0" - - ajv-keywords@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" - integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== - - ajv-keywords@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" - integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== - dependencies: - fast-deep-equal "^3.1.3" - - ajv@^6.12.5: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - - ajv@^8.0.0, ajv@^8.8.0: - version "8.12.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" - integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - - ansi-html-community@^0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" - integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== - - anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - - array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== - - array-flatten@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" - integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== - - array-union@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-3.0.1.tgz#da52630d327f8b88cfbfb57728e2af5cd9b6b975" - integrity sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw== - - balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - - batch@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" - integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== - - binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - - body-parser@1.20.1: - version "1.20.1" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" - integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== - dependencies: - bytes "3.1.2" - content-type "~1.0.4" - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.11.0" - raw-body "2.5.1" - type-is "~1.6.18" - unpipe "1.0.0" - - bonjour-service@^1.0.11: - version "1.1.1" - resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.1.1.tgz#960948fa0e0153f5d26743ab15baf8e33752c135" - integrity sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg== - dependencies: - array-flatten "^2.1.2" - dns-equal "^1.0.0" - fast-deep-equal "^3.1.3" - multicast-dns "^7.2.5" - - brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - - braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - - browserslist@^4.14.5: - version "4.21.5" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" - integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== - dependencies: - caniuse-lite "^1.0.30001449" - electron-to-chromium "^1.4.284" - node-releases "^2.0.8" - update-browserslist-db "^1.0.10" - - buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - - bytes@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== - - bytes@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" - integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== - - call-bind@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - - caniuse-lite@^1.0.30001449: - version "1.0.30001474" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001474.tgz#13b6fe301a831fe666cce8ca4ef89352334133d5" - integrity sha512-iaIZ8gVrWfemh5DG3T9/YqarVZoYf0r188IjaGwx68j4Pf0SGY6CQkmJUIE+NZHkkecQGohzXmBGEwWDr9aM3Q== - - chokidar@^3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - - chrome-trace-event@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" - integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== - - clone-deep@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" - integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== - dependencies: - is-plain-object "^2.0.4" - kind-of "^6.0.2" - shallow-clone "^3.0.0" - - colorette@^2.0.10, colorette@^2.0.14: - version "2.0.19" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" - integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== - - commander@^2.20.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - - commander@^7.0.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - - compressible@~2.0.16: - version "2.0.18" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" - integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== - dependencies: - mime-db ">= 1.43.0 < 2" - - compression@^1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" - integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== - dependencies: - accepts "~1.3.5" - bytes "3.0.0" - compressible "~2.0.16" - debug "2.6.9" - on-headers "~1.0.2" - safe-buffer "5.1.2" - vary "~1.1.2" - - concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - - connect-history-api-fallback@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" - integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== - - content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - - content-type@~1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" - integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== - - cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== - - cookie@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== - - copy-webpack-plugin@^10.2.4: - version "10.2.4" - resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-10.2.4.tgz#6c854be3fdaae22025da34b9112ccf81c63308fe" - integrity sha512-xFVltahqlsRcyyJqQbDY6EYTtyQZF9rf+JPjwHObLdPFMEISqkFkr7mFoVOC6BfYS/dNThyoQKvziugm+OnwBg== - dependencies: - fast-glob "^3.2.7" - glob-parent "^6.0.1" - globby "^12.0.2" - normalize-path "^3.0.0" - schema-utils "^4.0.0" - serialize-javascript "^6.0.0" - - core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - - cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - - debug@2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - - debug@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - - default-gateway@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" - integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== - dependencies: - execa "^5.0.0" - - define-lazy-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" - integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== - - depd@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - - depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== - - destroy@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" - integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== - - detect-node@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" - integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== - - dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - - dns-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" - integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== - - dns-packet@^5.2.2: - version "5.5.0" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.5.0.tgz#f59cbf3396c130957c56a6ad5fd3959ccdc30065" - integrity sha512-USawdAUzRkV6xrqTjiAEp6M9YagZEzWcSUaZTcIFAiyQWW1SoI6KyId8y2+/71wbgHKQAKd+iupLv4YvEwYWvA== - dependencies: - "@leichtgewicht/ip-codec" "^2.0.1" - - ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== - - electron-to-chromium@^1.4.284: - version "1.4.352" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.352.tgz#be96bd7c2f4b980deebc9338a49a67430a33ed73" - integrity sha512-ikFUEyu5/q+wJpMOxWxTaEVk2M1qKqTGKKyfJmod1CPZxKfYnxVS41/GCBQg21ItBpZybyN8sNpRqCUGm+Zc4Q== - - encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== - - enhanced-resolve@^5.10.0: - version "5.12.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.12.0.tgz#300e1c90228f5b570c4d35babf263f6da7155634" - integrity sha512-QHTXI/sZQmko1cbDoNAa3mJ5qhWUUNAq3vR0/YiD379fWQrcfuoX1+HW2S0MTt7XmoPLapdaDKUtelUSPic7hQ== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - - envinfo@^7.7.3: - version "7.8.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" - integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== - - es-module-lexer@^0.9.0: - version "0.9.3" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" - integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== - - escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - - escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== - - eslint-scope@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - - esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - - estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - - estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - - etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== - - eventemitter3@^4.0.0: - version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" - integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== - - events@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - - execa@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - - express@^4.17.3: - version "4.18.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" - integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "1.20.1" - content-disposition "0.5.4" - content-type "~1.0.4" - cookie "0.5.0" - cookie-signature "1.0.6" - debug "2.6.9" - depd "2.0.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "1.2.0" - fresh "0.5.2" - http-errors "2.0.0" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "2.4.1" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.7" - qs "6.11.0" - range-parser "~1.2.1" - safe-buffer "5.2.1" - send "0.18.0" - serve-static "1.15.0" - setprototypeof "1.2.0" - statuses "2.0.1" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - - fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - - fast-glob@^3.2.7: - version "3.2.12" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - - fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - - fastest-levenshtein@^1.0.12: - version "1.0.16" - resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" - integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== - - fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== - dependencies: - reusify "^1.0.4" - - faye-websocket@^0.11.3: - version "0.11.4" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" - integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== - dependencies: - websocket-driver ">=0.5.1" - - fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - - finalhandler@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" - integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "2.4.1" - parseurl "~1.3.3" - statuses "2.0.1" - unpipe "~1.0.0" - - find-up@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - - follow-redirects@^1.0.0: - version "1.15.2" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== - - forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - - fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== - - fs-monkey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" - integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== - - fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - - fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - - function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - - get-intrinsic@^1.0.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" - integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.3" - - get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - - glob-parent@^5.1.2, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - - glob-parent@^6.0.1: - version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - - glob-to-regexp@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" - integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== - - glob@^7.1.3: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - - globby@^12.0.2: - version "12.2.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-12.2.0.tgz#2ab8046b4fba4ff6eede835b29f678f90e3d3c22" - integrity sha512-wiSuFQLZ+urS9x2gGPl1H5drc5twabmm4m2gTR27XDFyjUHJUNsS8o/2aKyIF6IoBaR630atdher0XJ5g6OMmA== - dependencies: - array-union "^3.0.1" - dir-glob "^3.0.1" - fast-glob "^3.2.7" - ignore "^5.1.9" - merge2 "^1.4.1" - slash "^4.0.0" - - "go-mix-conn@file:../go-mix-conn/build": - version "0.0.0" - - graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: - version "4.2.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" - integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== - - handle-thing@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" - integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== - - has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - - has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - - has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - - hello-wasm-pack@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/hello-wasm-pack/-/hello-wasm-pack-0.1.0.tgz#482a2e3371828056ac35f5b5fec76c0b99dcd530" - integrity sha512-3hx0GDkDLf/a9ThCMV2qG4mwza8N/MCtm8aeFFc/cdBCL2zMJ1kW1wjNl7xPqD1lz8Yl5+uhnc/cpui4dLwz/w== - - hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" - integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== - dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - - html-entities@^2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" - integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== - - http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" - integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== - - http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== - dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" - - http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - - http-parser-js@>=0.5.1: - version "0.5.8" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" - integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== - - http-proxy-middleware@^2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" - integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== - dependencies: - "@types/http-proxy" "^1.17.8" - http-proxy "^1.18.1" - is-glob "^4.0.1" - is-plain-obj "^3.0.0" - micromatch "^4.0.2" - - http-proxy@^1.18.1: - version "1.18.1" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" - integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== - dependencies: - eventemitter3 "^4.0.0" - follow-redirects "^1.0.0" - requires-port "^1.0.0" - - human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - - iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - - ignore@^5.1.9: - version "5.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== - - import-local@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" - integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - - inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - - inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - - inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== - - interpret@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" - integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== - - ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - - ipaddr.js@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" - integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== - - is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - - is-core-module@^2.9.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== - dependencies: - has "^1.0.3" - - is-docker@^2.0.0, is-docker@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - - is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - - is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - - is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - - is-plain-obj@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" - integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== - - is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - - is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - - is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - - isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - - isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - - isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== - - jest-worker@^27.4.5: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" - integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - - json-parse-even-better-errors@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - - json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - - json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - - kind-of@^6.0.2: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - - launch-editor@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.6.0.tgz#4c0c1a6ac126c572bd9ff9a30da1d2cae66defd7" - integrity sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ== - dependencies: - picocolors "^1.0.0" - shell-quote "^1.7.3" - - loader-runner@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" - integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== - - locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - - media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== - - memfs@^3.4.3: - version "3.4.13" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.13.tgz#248a8bd239b3c240175cd5ec548de5227fc4f345" - integrity sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg== - dependencies: - fs-monkey "^1.0.3" - - merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== - - merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - - merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - - methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== - - micromatch@^4.0.2, micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - - mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - - mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - - mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - - mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - - minimalistic-assert@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - - minimatch@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - - ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - - ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - - ms@2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - - multicast-dns@^7.2.5: - version "7.2.5" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" - integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== - dependencies: - dns-packet "^5.2.2" - thunky "^1.0.2" - - negotiator@0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - - neo-async@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - - node-forge@^1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" - integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== - - node-releases@^2.0.8: - version "2.0.10" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" - integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== - - normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - - npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - - object-inspect@^1.9.0: - version "1.12.3" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" - integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== - - obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" - integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== - - on-finished@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" - integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== - dependencies: - ee-first "1.1.1" - - on-headers@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" - integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== - - once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - - onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - - open@^8.0.9: - version "8.4.2" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" - integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== - dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" - - p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - - p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - - p-retry@^4.5.0: - version "4.6.2" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" - integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== - dependencies: - "@types/retry" "0.12.0" - retry "^0.13.1" - - p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - - parseurl@~1.3.2, parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - - path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - - path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - - path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - - path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - - path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== - - path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - - picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - - picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - - pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - - process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - - proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - - punycode@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== - - qs@6.11.0: - version "6.11.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" - integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== - dependencies: - side-channel "^1.0.4" - - queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - - randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - - range-parser@^1.2.1, range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - - raw-body@2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" - integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - - readable-stream@^2.0.1: - version "2.3.8" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" - integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - - readable-stream@^3.0.6: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - - readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - - rechoir@^0.7.0: - version "0.7.1" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" - integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== - dependencies: - resolve "^1.9.0" - - require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - - requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== - - resolve-cwd@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" - integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== - dependencies: - resolve-from "^5.0.0" - - resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - - resolve@^1.9.0: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== - dependencies: - is-core-module "^2.9.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - - retry@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" - integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== - - reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - - rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - - run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - - safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - - safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - - "safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - - schema-utils@^3.1.0, schema-utils@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281" - integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw== - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - - schema-utils@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" - integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== - dependencies: - "@types/json-schema" "^7.0.9" - ajv "^8.8.0" - ajv-formats "^2.1.1" - ajv-keywords "^5.0.0" - - select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" - integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== - - selfsigned@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.1.1.tgz#18a7613d714c0cd3385c48af0075abf3f266af61" - integrity sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ== - dependencies: - node-forge "^1" - - send@0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" - integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== - dependencies: - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "2.0.0" - mime "1.6.0" - ms "2.1.3" - on-finished "2.4.1" - range-parser "~1.2.1" - statuses "2.0.1" - - serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" - integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== - dependencies: - randombytes "^2.1.0" - - serve-index@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" - integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== - dependencies: - accepts "~1.3.4" - batch "0.6.1" - debug "2.6.9" - escape-html "~1.0.3" - http-errors "~1.6.2" - mime-types "~2.1.17" - parseurl "~1.3.2" - - serve-static@1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" - integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.18.0" - - setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== - - setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - - shallow-clone@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" - integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== - dependencies: - kind-of "^6.0.2" - - shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - - shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - - shell-quote@^1.7.3: - version "1.8.0" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.0.tgz#20d078d0eaf71d54f43bd2ba14a1b5b9bfa5c8ba" - integrity sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ== - - side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - - signal-exit@^3.0.3: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - - slash@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" - integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== - - sockjs@^0.3.24: - version "0.3.24" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" - integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== - dependencies: - faye-websocket "^0.11.3" - uuid "^8.3.2" - websocket-driver "^0.7.4" - - source-map-support@~0.5.20: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - - source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - - spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" - integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - - spdy@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" - integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - - statuses@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - - "statuses@>= 1.4.0 < 2": - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== - - string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - - string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - - strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - - supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - - supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - - tapable@^2.1.1, tapable@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== - - terser-webpack-plugin@^5.1.3: - version "5.3.7" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.7.tgz#ef760632d24991760f339fe9290deb936ad1ffc7" - integrity sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw== - dependencies: - "@jridgewell/trace-mapping" "^0.3.17" - jest-worker "^27.4.5" - schema-utils "^3.1.1" - serialize-javascript "^6.0.1" - terser "^5.16.5" - - terser@^5.16.5: - version "5.16.8" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.8.tgz#ccde583dabe71df3f4ed02b65eb6532e0fae15d5" - integrity sha512-QI5g1E/ef7d+PsDifb+a6nnVgC4F22Bg6T0xrBrz6iloVB4PUkkunp6V8nzoOOZJIzjWVdAGqCdlKlhLq/TbIA== - dependencies: - "@jridgewell/source-map" "^0.3.2" - acorn "^8.5.0" - commander "^2.20.0" - source-map-support "~0.5.20" - - thunky@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" - integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== - - to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - - toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - - type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - - unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== - - update-browserslist-db@^1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" - integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - - uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - - util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - - utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== - - uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - - vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== - - watchpack@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" - integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== - dependencies: - glob-to-regexp "^0.4.1" - graceful-fs "^4.1.2" - - wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" - integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== - dependencies: - minimalistic-assert "^1.0.0" - - webpack-cli@^4.9.2: - version "4.10.0" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.10.0.tgz#37c1d69c8d85214c5a65e589378f53aec64dab31" - integrity sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w== - dependencies: - "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^1.2.0" - "@webpack-cli/info" "^1.5.0" - "@webpack-cli/serve" "^1.7.0" - colorette "^2.0.14" - commander "^7.0.0" - cross-spawn "^7.0.3" - fastest-levenshtein "^1.0.12" - import-local "^3.0.2" - interpret "^2.2.0" - rechoir "^0.7.0" - webpack-merge "^5.7.3" - - webpack-dev-middleware@^5.3.1: - version "5.3.3" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" - integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== - dependencies: - colorette "^2.0.10" - memfs "^3.4.3" - mime-types "^2.1.31" - range-parser "^1.2.1" - schema-utils "^4.0.0" - - webpack-dev-server@^4.7.4: - version "4.13.2" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.13.2.tgz#d97445481d78691efe6d9a3b230833d802fc31f9" - integrity sha512-5i6TrGBRxG4vnfDpB6qSQGfnB6skGBXNL5/542w2uRGLimX6qeE5BQMLrzIC3JYV/xlGOv+s+hTleI9AZKUQNw== - dependencies: - "@types/bonjour" "^3.5.9" - "@types/connect-history-api-fallback" "^1.3.5" - "@types/express" "^4.17.13" - "@types/serve-index" "^1.9.1" - "@types/serve-static" "^1.13.10" - "@types/sockjs" "^0.3.33" - "@types/ws" "^8.5.1" - ansi-html-community "^0.0.8" - bonjour-service "^1.0.11" - chokidar "^3.5.3" - colorette "^2.0.10" - compression "^1.7.4" - connect-history-api-fallback "^2.0.0" - default-gateway "^6.0.3" - express "^4.17.3" - graceful-fs "^4.2.6" - html-entities "^2.3.2" - http-proxy-middleware "^2.0.3" - ipaddr.js "^2.0.1" - launch-editor "^2.6.0" - open "^8.0.9" - p-retry "^4.5.0" - rimraf "^3.0.2" - schema-utils "^4.0.0" - selfsigned "^2.1.1" - serve-index "^1.9.1" - sockjs "^0.3.24" - spdy "^4.0.2" - webpack-dev-middleware "^5.3.1" - ws "^8.13.0" - - webpack-merge@^5.7.3: - version "5.8.0" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" - integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== - dependencies: - clone-deep "^4.0.1" - wildcard "^2.0.0" - - webpack-sources@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" - integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== - - webpack@^5.70.0: - version "5.77.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.77.0.tgz#dea3ad16d7ea6b84aa55fa42f4eac9f30e7eb9b4" - integrity sha512-sbGNjBr5Ya5ss91yzjeJTLKyfiwo5C628AFjEa6WSXcZa4E+F57om3Cc8xLb1Jh0b243AWuSYRf3dn7HVeFQ9Q== - dependencies: - "@types/eslint-scope" "^3.7.3" - "@types/estree" "^0.0.51" - "@webassemblyjs/ast" "1.11.1" - "@webassemblyjs/wasm-edit" "1.11.1" - "@webassemblyjs/wasm-parser" "1.11.1" - acorn "^8.7.1" - acorn-import-assertions "^1.7.6" - browserslist "^4.14.5" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.10.0" - es-module-lexer "^0.9.0" - eslint-scope "5.1.1" - events "^3.2.0" - glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" - json-parse-even-better-errors "^2.3.1" - loader-runner "^4.2.0" - mime-types "^2.1.27" - neo-async "^2.6.2" - schema-utils "^3.1.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.1.3" - watchpack "^2.4.0" - webpack-sources "^3.2.3" - - websocket-driver@>=0.5.1, websocket-driver@^0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" - integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== - dependencies: - http-parser-js ">=0.5.1" - safe-buffer ">=5.1.0" - websocket-extensions ">=0.1.1" - - websocket-extensions@>=0.1.1: - version "0.1.4" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" - integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== - - which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - - wildcard@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" - integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== - - wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - - ws@^8.13.0: - version "8.13.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" - integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== diff --git a/wasm/node-tester/internal-dev/yarn.lock b/wasm/node-tester/internal-dev/yarn.lock deleted file mode 100644 index 7f8cb8f0f3..0000000000 --- a/wasm/node-tester/internal-dev/yarn.lock +++ /dev/null @@ -1,2172 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@discoveryjs/json-ext@^0.5.0": - version "0.5.7" - resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" - integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== - -"@jridgewell/gen-mapping@^0.3.5": - version "0.3.13" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f" - integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA== - dependencies: - "@jridgewell/sourcemap-codec" "^1.5.0" - "@jridgewell/trace-mapping" "^0.3.24" - -"@jridgewell/resolve-uri@^3.1.0": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" - integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== - -"@jridgewell/source-map@^0.3.3": - version "0.3.11" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.11.tgz#b21835cbd36db656b857c2ad02ebd413cc13a9ba" - integrity sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA== - dependencies: - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.25" - -"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": - version "1.5.5" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" - integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== - -"@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": - version "0.3.31" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0" - integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - -"@leichtgewicht/ip-codec@^2.0.1": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" - integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@nymproject/nym_node_tester_wasm@file:../../../dist/wasm/node-tester": - version "1.0.0" - -"@types/body-parser@*": - version "1.19.2" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" - integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== - dependencies: - "@types/connect" "*" - "@types/node" "*" - -"@types/bonjour@^3.5.9": - version "3.5.10" - resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" - integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== - dependencies: - "@types/node" "*" - -"@types/connect-history-api-fallback@^1.3.5": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" - integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== - dependencies: - "@types/express-serve-static-core" "*" - "@types/node" "*" - -"@types/connect@*": - version "3.4.35" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" - integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== - dependencies: - "@types/node" "*" - -"@types/eslint-scope@^3.7.7": - version "3.7.7" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" - integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" - -"@types/eslint@*": - version "8.37.0" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.37.0.tgz#29cebc6c2a3ac7fea7113207bf5a828fdf4d7ef1" - integrity sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - -"@types/estree@*", "@types/estree@^1.0.8": - version "1.0.8" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" - integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== - -"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": - version "4.17.33" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz#de35d30a9d637dc1450ad18dd583d75d5733d543" - integrity sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - -"@types/express@*", "@types/express@^4.17.13": - version "4.17.17" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.17.tgz#01d5437f6ef9cfa8668e616e13c2f2ac9a491ae4" - integrity sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.33" - "@types/qs" "*" - "@types/serve-static" "*" - -"@types/http-proxy@^1.17.8": - version "1.17.10" - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.10.tgz#e576c8e4a0cc5c6a138819025a88e167ebb38d6c" - integrity sha512-Qs5aULi+zV1bwKAg5z1PWnDXWmsn+LxIvUGv6E2+OOMYhclZMO+OXd9pYVf2gLykf2I7IV2u7oTHwChPNsvJ7g== - dependencies: - "@types/node" "*" - -"@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.9": - version "7.0.15" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" - integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== - -"@types/mime@*": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.1.tgz#5f8f2bca0a5863cb69bc0b0acd88c96cb1d4ae10" - integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== - -"@types/node@*": - version "18.15.11" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.11.tgz#b3b790f09cb1696cffcec605de025b088fa4225f" - integrity sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q== - -"@types/qs@*": - version "6.9.7" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" - integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== - -"@types/range-parser@*": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" - integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== - -"@types/retry@0.12.0": - version "0.12.0" - resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" - integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== - -"@types/serve-index@^1.9.1": - version "1.9.1" - resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" - integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== - dependencies: - "@types/express" "*" - -"@types/serve-static@*", "@types/serve-static@^1.13.10": - version "1.15.1" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.1.tgz#86b1753f0be4f9a1bee68d459fcda5be4ea52b5d" - integrity sha512-NUo5XNiAdULrJENtJXZZ3fHtfMolzZwczzBbnAeBbqBwG+LaG6YaJtuwzwGSQZ2wsCrxjEhNNjAkKigy3n8teQ== - dependencies: - "@types/mime" "*" - "@types/node" "*" - -"@types/sockjs@^0.3.33": - version "0.3.33" - resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" - integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== - dependencies: - "@types/node" "*" - -"@types/ws@^8.5.1": - version "8.5.4" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.4.tgz#bb10e36116d6e570dd943735f86c933c1587b8a5" - integrity sha512-zdQDHKUgcX/zBc4GrwsE/7dVdAD8JR4EuiAXiiUhhfyIJXXb2+PrGshFyeXWQPMmmZ2XxgaqclgpIC7eTXc1mg== - dependencies: - "@types/node" "*" - -"@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.14.1.tgz#a9f6a07f2b03c95c8d38c4536a1fdfb521ff55b6" - integrity sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ== - dependencies: - "@webassemblyjs/helper-numbers" "1.13.2" - "@webassemblyjs/helper-wasm-bytecode" "1.13.2" - -"@webassemblyjs/floating-point-hex-parser@1.13.2": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz#fcca1eeddb1cc4e7b6eed4fc7956d6813b21b9fb" - integrity sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA== - -"@webassemblyjs/helper-api-error@1.13.2": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz#e0a16152248bc38daee76dd7e21f15c5ef3ab1e7" - integrity sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ== - -"@webassemblyjs/helper-buffer@1.14.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz#822a9bc603166531f7d5df84e67b5bf99b72b96b" - integrity sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA== - -"@webassemblyjs/helper-numbers@1.13.2": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz#dbd932548e7119f4b8a7877fd5a8d20e63490b2d" - integrity sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA== - dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.13.2" - "@webassemblyjs/helper-api-error" "1.13.2" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/helper-wasm-bytecode@1.13.2": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz#e556108758f448aae84c850e593ce18a0eb31e0b" - integrity sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA== - -"@webassemblyjs/helper-wasm-section@1.14.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz#9629dda9c4430eab54b591053d6dc6f3ba050348" - integrity sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw== - dependencies: - "@webassemblyjs/ast" "1.14.1" - "@webassemblyjs/helper-buffer" "1.14.1" - "@webassemblyjs/helper-wasm-bytecode" "1.13.2" - "@webassemblyjs/wasm-gen" "1.14.1" - -"@webassemblyjs/ieee754@1.13.2": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz#1c5eaace1d606ada2c7fd7045ea9356c59ee0dba" - integrity sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw== - dependencies: - "@xtuc/ieee754" "^1.2.0" - -"@webassemblyjs/leb128@1.13.2": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.13.2.tgz#57c5c3deb0105d02ce25fa3fd74f4ebc9fd0bbb0" - integrity sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw== - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/utf8@1.13.2": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.13.2.tgz#917a20e93f71ad5602966c2d685ae0c6c21f60f1" - integrity sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ== - -"@webassemblyjs/wasm-edit@^1.14.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz#ac6689f502219b59198ddec42dcd496b1004d597" - integrity sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ== - dependencies: - "@webassemblyjs/ast" "1.14.1" - "@webassemblyjs/helper-buffer" "1.14.1" - "@webassemblyjs/helper-wasm-bytecode" "1.13.2" - "@webassemblyjs/helper-wasm-section" "1.14.1" - "@webassemblyjs/wasm-gen" "1.14.1" - "@webassemblyjs/wasm-opt" "1.14.1" - "@webassemblyjs/wasm-parser" "1.14.1" - "@webassemblyjs/wast-printer" "1.14.1" - -"@webassemblyjs/wasm-gen@1.14.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz#991e7f0c090cb0bb62bbac882076e3d219da9570" - integrity sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg== - dependencies: - "@webassemblyjs/ast" "1.14.1" - "@webassemblyjs/helper-wasm-bytecode" "1.13.2" - "@webassemblyjs/ieee754" "1.13.2" - "@webassemblyjs/leb128" "1.13.2" - "@webassemblyjs/utf8" "1.13.2" - -"@webassemblyjs/wasm-opt@1.14.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz#e6f71ed7ccae46781c206017d3c14c50efa8106b" - integrity sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw== - dependencies: - "@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@1.14.1", "@webassemblyjs/wasm-parser@^1.14.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz#b3e13f1893605ca78b52c68e54cf6a865f90b9fb" - integrity sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ== - dependencies: - "@webassemblyjs/ast" "1.14.1" - "@webassemblyjs/helper-api-error" "1.13.2" - "@webassemblyjs/helper-wasm-bytecode" "1.13.2" - "@webassemblyjs/ieee754" "1.13.2" - "@webassemblyjs/leb128" "1.13.2" - "@webassemblyjs/utf8" "1.13.2" - -"@webassemblyjs/wast-printer@1.14.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz#3bb3e9638a8ae5fdaf9610e7a06b4d9f9aa6fe07" - integrity sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw== - dependencies: - "@webassemblyjs/ast" "1.14.1" - "@xtuc/long" "4.2.2" - -"@webpack-cli/configtest@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.2.0.tgz#7b20ce1c12533912c3b217ea68262365fa29a6f5" - integrity sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg== - -"@webpack-cli/info@^1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.5.0.tgz#6c78c13c5874852d6e2dd17f08a41f3fe4c261b1" - integrity sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ== - dependencies: - envinfo "^7.7.3" - -"@webpack-cli/serve@^1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.7.0.tgz#e1993689ac42d2b16e9194376cfb6753f6254db1" - integrity sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q== - -"@xtuc/ieee754@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" - integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== - -"@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" - integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== - -accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: - version "1.3.8" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" - integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== - dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" - -acorn-import-phases@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz#16eb850ba99a056cb7cbfe872ffb8972e18c8bd7" - integrity sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ== - -acorn@^8.15.0: - version "8.15.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" - integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== - -ajv-formats@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" - integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== - dependencies: - ajv "^8.0.0" - -ajv-keywords@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" - integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== - dependencies: - fast-deep-equal "^3.1.3" - -ajv@^8.0.0: - version "8.12.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" - integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== - dependencies: - fast-deep-equal "^3.1.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - uri-js "^4.2.2" - -ajv@^8.9.0: - version "8.17.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" - integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== - dependencies: - fast-deep-equal "^3.1.3" - fast-uri "^3.0.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - -ansi-html-community@^0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" - integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== - -anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== - -array-flatten@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" - integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -baseline-browser-mapping@^2.9.0: - version "2.9.19" - resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz#3e508c43c46d961eb4d7d2e5b8d1dd0f9ee4f488" - integrity sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg== - -batch@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" - integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -body-parser@1.20.2: - version "1.20.2" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" - integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== - dependencies: - bytes "3.1.2" - content-type "~1.0.5" - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.11.0" - raw-body "2.5.2" - type-is "~1.6.18" - unpipe "1.0.0" - -bonjour-service@^1.0.11: - version "1.1.1" - resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.1.1.tgz#960948fa0e0153f5d26743ab15baf8e33752c135" - integrity sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg== - dependencies: - array-flatten "^2.1.2" - dns-equal "^1.0.0" - fast-deep-equal "^3.1.3" - multicast-dns "^7.2.5" - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - -browserslist@^4.28.1: - version "4.28.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.1.tgz#7f534594628c53c63101079e27e40de490456a95" - integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== - dependencies: - 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" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -bytes@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== - -bytes@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" - integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== - -call-bind@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -caniuse-lite@^1.0.30001759: - version "1.0.30001769" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz#1ad91594fad7dc233777c2781879ab5409f7d9c2" - integrity sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg== - -chokidar@^3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chrome-trace-event@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" - integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== - -clone-deep@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" - integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== - dependencies: - is-plain-object "^2.0.4" - kind-of "^6.0.2" - shallow-clone "^3.0.0" - -colorette@^2.0.10, colorette@^2.0.14: - version "2.0.19" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" - integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== - -commander@^2.20.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commander@^7.0.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - -compressible@~2.0.16: - version "2.0.18" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" - integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== - dependencies: - mime-db ">= 1.43.0 < 2" - -compression@^1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" - integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== - dependencies: - accepts "~1.3.5" - bytes "3.0.0" - compressible "~2.0.16" - debug "2.6.9" - on-headers "~1.0.2" - safe-buffer "5.1.2" - vary "~1.1.2" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -connect-history-api-fallback@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" - integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== - -content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - -content-type@~1.0.4, content-type@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" - integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== - -cookie@0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" - integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== - -copy-webpack-plugin@^11.0.0: - version "11.0.0" - resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz#96d4dbdb5f73d02dd72d0528d1958721ab72e04a" - integrity sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ== - dependencies: - fast-glob "^3.2.11" - glob-parent "^6.0.1" - globby "^13.1.1" - normalize-path "^3.0.0" - schema-utils "^4.0.0" - serialize-javascript "^6.0.0" - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - -cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -debug@2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^4.1.0: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -default-gateway@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" - integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== - dependencies: - execa "^5.0.0" - -define-lazy-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" - integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== - -depd@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== - -destroy@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" - integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== - -detect-node@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" - integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -dns-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" - integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== - -dns-packet@^5.2.2: - version "5.5.0" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.5.0.tgz#f59cbf3396c130957c56a6ad5fd3959ccdc30065" - integrity sha512-USawdAUzRkV6xrqTjiAEp6M9YagZEzWcSUaZTcIFAiyQWW1SoI6KyId8y2+/71wbgHKQAKd+iupLv4YvEwYWvA== - dependencies: - "@leichtgewicht/ip-codec" "^2.0.1" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== - -electron-to-chromium@^1.5.263: - version "1.5.286" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz#142be1ab5e1cd5044954db0e5898f60a4960384e" - integrity sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== - -enhanced-resolve@^5.17.4: - version "5.19.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz#6687446a15e969eaa63c2fa2694510e17ae6d97c" - integrity sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.3.0" - -envinfo@^7.7.3: - version "7.8.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" - integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== - -es-module-lexer@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-2.0.0.tgz#f657cd7a9448dcdda9c070a3cb75e5dc1e85f5b1" - integrity sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw== - -escalade@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" - integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== - -eslint-scope@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== - -eventemitter3@^4.0.0: - version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" - integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== - -events@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -express@^4.17.3: - version "4.19.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" - integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "1.20.2" - content-disposition "0.5.4" - content-type "~1.0.4" - cookie "0.6.0" - cookie-signature "1.0.6" - debug "2.6.9" - depd "2.0.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "1.2.0" - fresh "0.5.2" - http-errors "2.0.0" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "2.4.1" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.7" - qs "6.11.0" - range-parser "~1.2.1" - safe-buffer "5.2.1" - send "0.18.0" - serve-static "1.15.0" - setprototypeof "1.2.0" - statuses "2.0.1" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-glob@^3.2.11, fast-glob@^3.3.0: - version "3.3.2" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" - integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-uri@^3.0.1: - version "3.1.0" - resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.0.tgz#66eecff6c764c0df9b762e62ca7edcfb53b4edfa" - integrity sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA== - -fastest-levenshtein@^1.0.12: - version "1.0.16" - resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" - integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== - -fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== - dependencies: - reusify "^1.0.4" - -faye-websocket@^0.11.3: - version "0.11.4" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" - integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== - dependencies: - websocket-driver ">=0.5.1" - -fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - -finalhandler@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" - integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "2.4.1" - parseurl "~1.3.3" - statuses "2.0.1" - unpipe "~1.0.0" - -find-up@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -follow-redirects@^1.0.0: - version "1.15.6" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" - integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== - -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== - -fs-monkey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" - integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -fsevents@~2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" - integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== - -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== - -get-intrinsic@^1.0.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" - integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-symbols "^1.0.3" - -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -glob-parent@^5.1.2, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-parent@^6.0.1: - version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob-to-regexp@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" - integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== - -glob@^7.1.3: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -globby@^13.1.1: - version "13.2.2" - resolved "https://registry.yarnpkg.com/globby/-/globby-13.2.2.tgz#63b90b1bf68619c2135475cbd4e71e66aa090592" - integrity sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w== - dependencies: - dir-glob "^3.0.1" - fast-glob "^3.3.0" - ignore "^5.2.4" - merge2 "^1.4.1" - slash "^4.0.0" - -graceful-fs@^4.1.2, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6: - version "4.2.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" - integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== - -handle-thing@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" - integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" - integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== - dependencies: - function-bind "^1.1.1" - -hello-wasm-pack@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/hello-wasm-pack/-/hello-wasm-pack-0.1.0.tgz#482a2e3371828056ac35f5b5fec76c0b99dcd530" - integrity sha512-3hx0GDkDLf/a9ThCMV2qG4mwza8N/MCtm8aeFFc/cdBCL2zMJ1kW1wjNl7xPqD1lz8Yl5+uhnc/cpui4dLwz/w== - -hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" - integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== - dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - -html-entities@^2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" - integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== - -http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" - integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== - -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== - dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" - -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - -http-parser-js@>=0.5.1: - version "0.5.8" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" - integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== - -http-proxy-middleware@^2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" - integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== - dependencies: - "@types/http-proxy" "^1.17.8" - http-proxy "^1.18.1" - is-glob "^4.0.1" - is-plain-obj "^3.0.0" - micromatch "^4.0.2" - -http-proxy@^1.18.1: - version "1.18.1" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" - integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== - dependencies: - eventemitter3 "^4.0.0" - follow-redirects "^1.0.0" - requires-port "^1.0.0" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ignore@^5.2.4: - version "5.3.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" - integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== - -import-local@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" - integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== - -interpret@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" - integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== - -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -ipaddr.js@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" - integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-core-module@^2.9.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" - integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== - dependencies: - has "^1.0.3" - -is-docker@^2.0.0, is-docker@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-plain-obj@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" - integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== - -is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== - -jest-worker@^27.4.5: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" - integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -json-parse-even-better-errors@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -kind-of@^6.0.2: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -launch-editor@^2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.6.0.tgz#4c0c1a6ac126c572bd9ff9a30da1d2cae66defd7" - integrity sha512-JpDCcQnyAAzZZaZ7vEiSqL690w7dAEyLao+KC96zBplnYbJS7TYNjvM3M7y3dGz+v7aIsJk3hllWuc0kWAjyRQ== - dependencies: - picocolors "^1.0.0" - shell-quote "^1.7.3" - -loader-runner@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.1.tgz#6c76ed29b0ccce9af379208299f07f876de737e3" - integrity sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q== - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== - -memfs@^3.4.3: - version "3.4.13" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.13.tgz#248a8bd239b3c240175cd5ec548de5227fc4f345" - integrity sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg== - dependencies: - fs-monkey "^1.0.3" - -merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== - -micromatch@^4.0.2, micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -minimalistic-assert@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimatch@^3.1.1: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -multicast-dns@^7.2.5: - version "7.2.5" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" - integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== - dependencies: - dns-packet "^5.2.2" - thunky "^1.0.2" - -negotiator@0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - -neo-async@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - -node-forge@^1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" - integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== - -node-releases@^2.0.27: - version "2.0.27" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" - integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -object-inspect@^1.9.0: - version "1.12.3" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" - integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== - -obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" - integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== - -on-finished@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" - integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== - dependencies: - ee-first "1.1.1" - -on-headers@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" - integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -open@^8.0.9: - version "8.4.2" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" - integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== - dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" - -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-retry@^4.5.0: - version "4.6.2" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" - integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== - dependencies: - "@types/retry" "0.12.0" - retry "^0.13.1" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -parseurl@~1.3.2, parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picocolors@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" - integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - -punycode@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== - -qs@6.11.0: - version "6.11.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" - integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== - dependencies: - side-channel "^1.0.4" - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -range-parser@^1.2.1, range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -raw-body@2.5.2: - version "2.5.2" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" - integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - -readable-stream@^2.0.1: - version "2.3.8" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" - integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.0.6: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -rechoir@^0.7.0: - version "0.7.1" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" - integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== - dependencies: - resolve "^1.9.0" - -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== - -resolve-cwd@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" - integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== - dependencies: - resolve-from "^5.0.0" - -resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - -resolve@^1.9.0: - version "1.22.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" - integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== - dependencies: - is-core-module "^2.9.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -retry@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" - integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.1.0, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -schema-utils@^4.0.0, schema-utils@^4.3.0, schema-utils@^4.3.3: - version "4.3.3" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.3.tgz#5b1850912fa31df90716963d45d9121fdfc09f46" - integrity sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA== - dependencies: - "@types/json-schema" "^7.0.9" - ajv "^8.9.0" - ajv-formats "^2.1.1" - ajv-keywords "^5.1.0" - -select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" - integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== - -selfsigned@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.1.1.tgz#18a7613d714c0cd3385c48af0075abf3f266af61" - integrity sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ== - dependencies: - node-forge "^1" - -send@0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" - integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== - dependencies: - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "2.0.0" - mime "1.6.0" - ms "2.1.3" - on-finished "2.4.1" - range-parser "~1.2.1" - statuses "2.0.1" - -serialize-javascript@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" - integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== - dependencies: - randombytes "^2.1.0" - -serialize-javascript@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" - integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== - dependencies: - randombytes "^2.1.0" - -serve-index@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" - integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== - dependencies: - accepts "~1.3.4" - batch "0.6.1" - debug "2.6.9" - escape-html "~1.0.3" - http-errors "~1.6.2" - mime-types "~2.1.17" - parseurl "~1.3.2" - -serve-static@1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" - integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.18.0" - -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -shallow-clone@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" - integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== - dependencies: - kind-of "^6.0.2" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -shell-quote@^1.7.3: - version "1.8.0" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.0.tgz#20d078d0eaf71d54f43bd2ba14a1b5b9bfa5c8ba" - integrity sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ== - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -signal-exit@^3.0.3: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -slash@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" - integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== - -sockjs@^0.3.24: - version "0.3.24" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" - integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== - dependencies: - faye-websocket "^0.11.3" - uuid "^8.3.2" - websocket-driver "^0.7.4" - -source-map-support@~0.5.20: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" - integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - -spdy@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" - integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - -"statuses@>= 1.4.0 < 2": - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== - -string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -tapable@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6" - integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== - -terser-webpack-plugin@^5.3.16: - version "5.3.16" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz#741e448cc3f93d8026ebe4f7ef9e4afacfd56330" - integrity sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q== - dependencies: - "@jridgewell/trace-mapping" "^0.3.25" - jest-worker "^27.4.5" - schema-utils "^4.3.0" - serialize-javascript "^6.0.2" - terser "^5.31.1" - -terser@^5.31.1: - version "5.46.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.46.0.tgz#1b81e560d584bbdd74a8ede87b4d9477b0ff9695" - integrity sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg== - dependencies: - "@jridgewell/source-map" "^0.3.3" - acorn "^8.15.0" - commander "^2.20.0" - source-map-support "~0.5.20" - -thunky@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" - integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - -type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== - -update-browserslist-db@^1.2.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d" - integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w== - dependencies: - escalade "^3.2.0" - picocolors "^1.1.1" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== - -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== - -watchpack@^2.4.4: - version "2.5.1" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.5.1.tgz#dd38b601f669e0cbf567cb802e75cead82cde102" - integrity sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg== - dependencies: - glob-to-regexp "^0.4.1" - graceful-fs "^4.1.2" - -wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" - integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== - dependencies: - minimalistic-assert "^1.0.0" - -webpack-cli@^4.9.2: - version "4.10.0" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.10.0.tgz#37c1d69c8d85214c5a65e589378f53aec64dab31" - integrity sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w== - dependencies: - "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^1.2.0" - "@webpack-cli/info" "^1.5.0" - "@webpack-cli/serve" "^1.7.0" - colorette "^2.0.14" - commander "^7.0.0" - cross-spawn "^7.0.3" - fastest-levenshtein "^1.0.12" - import-local "^3.0.2" - interpret "^2.2.0" - rechoir "^0.7.0" - webpack-merge "^5.7.3" - -webpack-dev-middleware@^5.3.1: - version "5.3.4" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz#eb7b39281cbce10e104eb2b8bf2b63fce49a3517" - integrity sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q== - dependencies: - colorette "^2.0.10" - memfs "^3.4.3" - mime-types "^2.1.31" - range-parser "^1.2.1" - schema-utils "^4.0.0" - -webpack-dev-server@^4.7.4: - version "4.13.2" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.13.2.tgz#d97445481d78691efe6d9a3b230833d802fc31f9" - integrity sha512-5i6TrGBRxG4vnfDpB6qSQGfnB6skGBXNL5/542w2uRGLimX6qeE5BQMLrzIC3JYV/xlGOv+s+hTleI9AZKUQNw== - dependencies: - "@types/bonjour" "^3.5.9" - "@types/connect-history-api-fallback" "^1.3.5" - "@types/express" "^4.17.13" - "@types/serve-index" "^1.9.1" - "@types/serve-static" "^1.13.10" - "@types/sockjs" "^0.3.33" - "@types/ws" "^8.5.1" - ansi-html-community "^0.0.8" - bonjour-service "^1.0.11" - chokidar "^3.5.3" - colorette "^2.0.10" - compression "^1.7.4" - connect-history-api-fallback "^2.0.0" - default-gateway "^6.0.3" - express "^4.17.3" - graceful-fs "^4.2.6" - html-entities "^2.3.2" - http-proxy-middleware "^2.0.3" - ipaddr.js "^2.0.1" - launch-editor "^2.6.0" - open "^8.0.9" - p-retry "^4.5.0" - rimraf "^3.0.2" - schema-utils "^4.0.0" - selfsigned "^2.1.1" - serve-index "^1.9.1" - sockjs "^0.3.24" - spdy "^4.0.2" - webpack-dev-middleware "^5.3.1" - ws "^8.13.0" - -webpack-merge@^5.7.3: - version "5.8.0" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61" - integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q== - dependencies: - clone-deep "^4.0.1" - wildcard "^2.0.0" - -webpack-sources@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.3.tgz#d4bf7f9909675d7a070ff14d0ef2a4f3c982c723" - integrity sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg== - -webpack@^5.70.0: - version "5.104.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.104.1.tgz#94bd41eb5dbf06e93be165ba8be41b8260d4fb1a" - integrity sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA== - dependencies: - "@types/eslint-scope" "^3.7.7" - "@types/estree" "^1.0.8" - "@types/json-schema" "^7.0.15" - "@webassemblyjs/ast" "^1.14.1" - "@webassemblyjs/wasm-edit" "^1.14.1" - "@webassemblyjs/wasm-parser" "^1.14.1" - acorn "^8.15.0" - acorn-import-phases "^1.0.3" - browserslist "^4.28.1" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.17.4" - 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.4.4" - webpack-sources "^3.3.3" - -websocket-driver@>=0.5.1, websocket-driver@^0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" - integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== - dependencies: - http-parser-js ">=0.5.1" - safe-buffer ">=5.1.0" - websocket-extensions ">=0.1.1" - -websocket-extensions@>=0.1.1: - version "0.1.4" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" - integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -wildcard@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" - integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -ws@^8.13.0: - version "8.13.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.13.0.tgz#9a9fb92f93cf41512a0735c8f4dd09b8a1211cd0" - integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== diff --git a/wasm/node-tester/src/ephemeral_receiver.rs b/wasm/node-tester/src/ephemeral_receiver.rs deleted file mode 100644 index 4ad0f9d041..0000000000 --- a/wasm/node-tester/src/ephemeral_receiver.rs +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use crate::types::{NodeTestResult, WasmTestMessageExt}; -use futures::StreamExt; -use nym_node_tester_utils::processor::Received; -use nym_node_tester_utils::receiver::ReceivedReceiver; -use nym_node_tester_utils::FragmentIdentifier; -use nym_wasm_utils::{console_error, console_log, console_warn}; -use std::collections::HashSet; -use std::time::Duration; -use tokio::sync::MutexGuard as AsyncMutexGuard; -use wasmtimer::tokio::sleep; - -pub(crate) struct EphemeralTestReceiver<'a> { - sent_packets: u32, - expected_acks: HashSet, - - received_valid_messages: HashSet, - received_valid_acks: HashSet, - duplicate_packets: u32, - duplicate_acks: u32, - - timeout_duration: Duration, - receiver_permit: AsyncMutexGuard<'a, ReceivedReceiver>, -} - -impl<'a> EphemeralTestReceiver<'a> { - pub(crate) fn finish(self) -> NodeTestResult { - NodeTestResult { - sent_packets: self.sent_packets, - received_packets: self.received_valid_messages.len() as u32, - received_acks: self.received_valid_acks.len() as u32, - duplicate_packets: self.duplicate_packets, - duplicate_acks: self.duplicate_acks, - } - } - - pub(crate) fn new( - sent_packets: u32, - expected_acks: HashSet, - receiver_permit: AsyncMutexGuard<'a, ReceivedReceiver>, - timeout: Duration, - ) -> Self { - EphemeralTestReceiver { - sent_packets, - expected_acks, - received_valid_messages: Default::default(), - received_valid_acks: Default::default(), - duplicate_packets: 0, - duplicate_acks: 0, - timeout_duration: timeout, - receiver_permit, - } - } - - fn on_next_received_packet(&mut self, packet: Option>) -> bool { - let Some(received_packet) = packet else { - // can't do anything more... - console_error!("packet receiver has stopped processing results!"); - return true; - }; - match received_packet { - Received::Message(msg) => { - if !self.received_valid_messages.insert(msg.msg_id) { - self.duplicate_packets += 1; - } - } - Received::Ack(frag_id) => { - if self.expected_acks.contains(&frag_id) { - if !self.received_valid_acks.insert(frag_id) { - self.duplicate_acks += 1 - } - } else { - console_warn!("received an ack that was not part of the test! (id: {frag_id})") - } - } - } - - if self.received_all() { - console_log!("already received all the packets! finishing the test..."); - true - } else { - false - } - } - - fn received_all(&self) -> bool { - self.received_valid_acks.len() == self.received_valid_messages.len() - && self.received_valid_acks.len() == self.sent_packets as usize - } - - pub(crate) async fn perform_test(mut self) -> NodeTestResult { - let mut timeout_fut = sleep(self.timeout_duration); - - loop { - tokio::select! { - _ = &mut timeout_fut => { - console_warn!("reached test timeout before receiving all packets."); - break - } - received_packet = self.receiver_permit.next() => { - let is_done = self.on_next_received_packet(received_packet); - if is_done { - break - } - } - } - } - - self.finish() - } -} diff --git a/wasm/node-tester/src/error.rs b/wasm/node-tester/src/error.rs deleted file mode 100644 index 65bf60ecbb..0000000000 --- a/wasm/node-tester/src/error.rs +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use nym_node_tester_utils::error::NetworkTestingError; -use nym_wasm_client_core::error::WasmCoreError; -use nym_wasm_client_core::topology::WasmTopologyError; -use nym_wasm_client_core::{ClientCoreError, GatewayClientError}; -use nym_wasm_utils::wasm_error; -use thiserror::Error; - -#[derive(Debug, Error)] -pub enum NodeTesterError { - #[error( - "A node test is already in progress. Wait for it to finish before starting another one." - )] - TestInProgress, - - #[error( - "both nymApi address and explicit topology were specified - please use only one of them" - )] - DuplicateTopologySource, - - #[error("neither nymApi address or explicit topology were specified")] - NoTopologySource, - - #[error("could not parse provided tester arguments: {err}")] - MalformedNodeTesterArguments { err: String }, - - #[error(transparent)] - CoreError { - #[from] - source: WasmCoreError, - }, - - #[error("provided topology was malformed: {source}")] - InvalidTopology { - #[from] - source: WasmTopologyError, - }, - - #[error("failed to test the node: {source}")] - NodeTestingFailure { - #[from] - source: NetworkTestingError, - }, - - #[error("experienced an error with the gateway connection: {source}")] - GatewayConnectionError { - #[from] - source: GatewayClientError, - }, -} - -// I dislike this so much - there must be a better way. -impl From for NodeTesterError { - fn from(value: ClientCoreError) -> Self { - NodeTesterError::CoreError { - source: WasmCoreError::BaseClientError { source: value }, - } - } -} - -wasm_error!(NodeTesterError); diff --git a/wasm/node-tester/src/helpers.rs b/wasm/node-tester/src/helpers.rs deleted file mode 100644 index 6562ae65ec..0000000000 --- a/wasm/node-tester/src/helpers.rs +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -// due to expansion of #[wasm_bindgen] macro on NodeTestResult -#![allow(clippy::drop_non_drop)] - -use crate::error::NodeTesterError; -use crate::tester::LockedGatewayClient; -use crate::types::WasmTestMessageExt; -use js_sys::Promise; -use nym_node_tester_utils::processor::Received; -use nym_node_tester_utils::receiver::ReceivedReceiver; -use nym_wasm_utils::console_warn; -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::Arc; -use tokio::sync::{Mutex as AsyncMutex, MutexGuard as AsyncMutexGuard}; -use wasm_bindgen::prelude::*; -use wasm_bindgen_futures::future_to_promise; - -#[derive(Clone)] -pub(super) struct ReceivedReceiverWrapper(Arc>>); - -impl ReceivedReceiverWrapper { - pub(super) fn new(inner: ReceivedReceiver) -> Self { - ReceivedReceiverWrapper(Arc::new(AsyncMutex::new(inner))) - } - - pub(super) async fn clear_received_channel(&self) { - let mut lost_msgs = 0; - let mut lost_acks = 0; - let mut permit = self.0.lock().await; - while let Ok(Some(received)) = permit.try_next() { - match received { - Received::Message(_) => lost_msgs += 1, - Received::Ack(_) => lost_acks += 1, - } - } - if lost_msgs > 0 || lost_acks > 0 { - console_warn!("while preparing for the test run, we cleared {lost_msgs} messages and {lost_acks} acks that were received in the meantime.") - } - } - - pub(super) async fn lock(&self) -> AsyncMutexGuard<'_, ReceivedReceiver> { - self.0.lock().await - } -} - -pub(crate) struct TestMarker { - value: Arc, -} - -impl TestMarker { - pub fn new(value: Arc) -> Self { - Self { value } - } -} - -impl Drop for TestMarker { - // make sure to clear the test flag when the marker is dropped - fn drop(&mut self) { - self.value.store(false, Ordering::SeqCst) - } -} - -pub(crate) trait GatewayReconnection { - fn disconnect_from_gateway(&self) -> Promise; - - fn reconnect_to_gateway(&self) -> Promise; -} - -impl GatewayReconnection for LockedGatewayClient { - fn disconnect_from_gateway(&self) -> Promise { - let this = self.clone(); - - future_to_promise(async move { - let mut guard = this.lock().await; - guard - .disconnect() - .await - .map_err(|err| JsValue::from(NodeTesterError::from(err)))?; - Ok(JsValue::undefined()) - }) - } - - fn reconnect_to_gateway(&self) -> Promise { - let this = self.clone(); - - future_to_promise(async move { - let mut guard = this.lock().await; - guard - .try_reconnect() - .await - .map_err(|err| JsValue::from(NodeTesterError::from(err)))?; - Ok(JsValue::undefined()) - }) - } -} diff --git a/wasm/node-tester/src/lib.rs b/wasm/node-tester/src/lib.rs deleted file mode 100644 index 0828ecbc43..0000000000 --- a/wasm/node-tester/src/lib.rs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -#[cfg(target_arch = "wasm32")] -mod ephemeral_receiver; -#[cfg(target_arch = "wasm32")] -pub mod error; -#[cfg(target_arch = "wasm32")] -mod helpers; -#[cfg(target_arch = "wasm32")] -pub mod tester; -#[cfg(target_arch = "wasm32")] -pub mod types; - -#[cfg(target_arch = "wasm32")] -pub use nym_wasm_client_core::set_panic_hook; diff --git a/wasm/node-tester/src/tester.rs b/wasm/node-tester/src/tester.rs deleted file mode 100644 index f525ad1c77..0000000000 --- a/wasm/node-tester/src/tester.rs +++ /dev/null @@ -1,380 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -#![allow(unknown_lints)] -// clippy::empty_docs is not on stable as of 1.77 -// due to the code generated by Tsify -#![allow(clippy::empty_docs)] - -use crate::ephemeral_receiver::EphemeralTestReceiver; -use crate::error::NodeTesterError; -use crate::helpers::{GatewayReconnection, ReceivedReceiverWrapper, TestMarker}; -use crate::types::{NodeTestResult, WasmTestMessageExt}; -use futures::channel::mpsc; -use js_sys::Promise; -use nym_node_tester_utils::receiver::SimpleMessageReceiver; -use nym_node_tester_utils::tester::LegacyMixLayer; -use nym_node_tester_utils::{NodeTester, PacketSize, PreparedFragment}; -use nym_wasm_client_core::client::base_client::storage::gateways_storage::GatewayDetails; -use nym_wasm_client_core::client::mix_traffic::transceiver::PacketRouter; -use nym_wasm_client_core::helpers::{ - current_network_topology_async, setup_from_topology, EphemeralCredentialStorage, -}; -use nym_wasm_client_core::nym_task::ShutdownManager; -use nym_wasm_client_core::storage::ClientStorage; -use nym_wasm_client_core::topology::WasmFriendlyNymTopology; -use nym_wasm_client_core::{ - nym_task, BandwidthController, ClientKeys, ClientStatsSender, GatewayClient, - GatewayClientConfig, GatewayConfig, IdentityKey, InitialisationResult, NodeIdentity, - NymTopology, QueryReqwestRpcNyxdClient, Recipient, -}; -use nym_wasm_utils::check_promise_result; -use nym_wasm_utils::error::PromisableResult; -use rand::rngs::OsRng; -use serde::{Deserialize, Serialize}; -use std::collections::HashSet; -use std::sync::atomic::{AtomicBool, AtomicU32, Ordering}; -use std::sync::{Arc, Mutex as SyncMutex}; -use std::time::Duration; -use tokio::sync::Mutex as AsyncMutex; -use tsify::Tsify; -use wasm_bindgen::prelude::*; -use wasm_bindgen_futures::future_to_promise; - -pub const NODE_TESTER_ID: &str = "_nym-node-tester"; - -pub(crate) const DEFAULT_TEST_TIMEOUT: Duration = Duration::from_secs(10); -pub(crate) const DEFAULT_TEST_PACKETS: u32 = 20; - -pub(crate) type LockedGatewayClient = - Arc>>; - -#[wasm_bindgen] -pub struct NymNodeTester { - test_in_progress: Arc, - - // we need to increment the nonce between tests to distinguish the packets - // but we can't make the tester mutable because of wasm... - // so we're using the atomics - current_test_nonce: AtomicU32, - - // blame all those mutexes on being unable to have an async method with internal mutability... - tester: Arc>>, - gateway_client: LockedGatewayClient, - - // we have to put it behind the lock due to wasm limitations and borrowing... - // the mutex acquisition should be instant as there aren't going to be any threads attempting - // to get simultaneous access - processed_receiver: ReceivedReceiverWrapper, - - // even though we don't use graceful shutdowns, other components rely on existence of this struct - // and if it's dropped, everything will start going offline - _task_manager: ShutdownManager, -} - -#[wasm_bindgen] -pub struct NymNodeTesterBuilder { - gateway: Option, - id: Option, - - base_topology: NymTopology, - - // unimplemented - bandwidth_controller: - Option>, -} - -fn address(keys: &ClientKeys, gateway_identity: NodeIdentity) -> Recipient { - Recipient::new( - *keys.identity_keypair().public_key(), - *keys.encryption_keypair().public_key(), - gateway_identity, - ) -} - -#[derive(Tsify, Debug, Clone, Serialize, Deserialize)] -#[tsify(into_wasm_abi, from_wasm_abi)] -#[serde(rename_all = "camelCase")] -pub struct NymNodeTesterOpts { - #[tsify(optional)] - id: Option, - - #[tsify(optional)] - nym_api: Option, - - #[tsify(optional)] - topology: Option, - - #[tsify(optional)] - gateway: Option, -} - -#[wasm_bindgen] -impl NymNodeTesterBuilder { - #[wasm_bindgen(constructor)] - #[allow(clippy::new_ret_no_self)] - pub fn new(args: NymNodeTesterOpts) -> Promise { - future_to_promise(async move { Self::new_async(args).await.into_promise_result() }) - } - - async fn new_async(args: NymNodeTesterOpts) -> Result { - if args.nym_api.is_some() && args.topology.is_some() { - return Err(NodeTesterError::DuplicateTopologySource); - } - if args.nym_api.is_none() && args.topology.is_none() { - return Err(NodeTesterError::NoTopologySource); - } - - let topology = if let Some(topology) = args.topology { - topology - } else { - // the unwrap here is fine as we just ensured one of the branches would be true - current_network_topology_async(args.nym_api.unwrap()).await? - }; - - Ok(NymNodeTesterBuilder { - gateway: args.gateway, - id: args.id, - base_topology: topology.try_into()?, - bandwidth_controller: None, - }) - } - - async fn gateway_info( - &self, - client_store: &ClientStorage, - ) -> Result { - if let Ok(loaded) = InitialisationResult::try_load(client_store, client_store).await { - Ok(loaded) - } else { - Ok(setup_from_topology( - self.gateway.clone(), - false, - &self.base_topology, - client_store, - ) - .await?) - } - } - - async fn _setup_client(mut self) -> Result { - let task_manager = ShutdownManager::new_without_signals(); - - let storage_id = if let Some(client_id) = &self.id { - format!("{NODE_TESTER_ID}-{client_id}") - } else { - NODE_TESTER_ID.to_owned() - }; - - let client_store = ClientStorage::new_async(&storage_id, None).await?; - let initialisation_result = self.gateway_info(&client_store).await?; - let GatewayDetails::Remote(gateway_info) = - initialisation_result.gateway_registration.details - else { - // don't bother supporting it - panic!("unsupported custom gateway configuration in wasm node tester") - }; - - let managed_keys = initialisation_result.client_keys; - - let (mixnet_message_sender, mixnet_message_receiver) = mpsc::unbounded(); - let (ack_sender, ack_receiver) = mpsc::unbounded(); - - let gateway_task = task_manager.clone_shutdown_token(); - let packet_router = - PacketRouter::new(ack_sender, mixnet_message_sender, gateway_task.clone()); - - let gateway_identity = gateway_info.gateway_id; - - let stats_sender_task = task_manager.clone_shutdown_token(); - - let mut gateway_client = - if let Some(existing_client) = initialisation_result.authenticated_ephemeral_client { - existing_client.upgrade( - packet_router, - self.bandwidth_controller.take(), - ClientStatsSender::new(None, stats_sender_task), - gateway_task.clone(), - ) - } else { - let cfg = GatewayConfig::new( - gateway_info.gateway_id, - gateway_info.published_data.listeners, - ); - GatewayClient::new( - GatewayClientConfig::new_default().with_disabled_credentials_mode(true), - cfg, - managed_keys.identity_keypair(), - Some(gateway_info.shared_key), - packet_router, - self.bandwidth_controller.take(), - ClientStatsSender::new(None, stats_sender_task), - gateway_task, - ) - }; - - let _auth_res = gateway_client.perform_initial_authentication().await?; - - gateway_client.claim_initial_bandwidth().await?; - gateway_client.start_listening_for_mixnet_messages()?; - - // TODO: make those values configurable later - let tester = NodeTester::new( - OsRng, - self.base_topology, - Some(address(&managed_keys, gateway_identity)), - PacketSize::default(), - false, - Duration::from_millis(5), - Duration::from_millis(5), - true, - managed_keys.ack_key(), - ); - - let (processed_sender, processed_receiver) = mpsc::unbounded(); - - let mut receiver = SimpleMessageReceiver::new_sphinx_receiver( - managed_keys.encryption_keypair(), - managed_keys.ack_key(), - mixnet_message_receiver, - ack_receiver, - processed_sender, - task_manager.clone_shutdown_token(), - ); - - nym_task::spawn_future(async move { receiver.run().await }); - - Ok(NymNodeTester { - test_in_progress: Arc::new(AtomicBool::new(false)), - current_test_nonce: Default::default(), - tester: Arc::new(SyncMutex::new(tester)), - gateway_client: Arc::new(AsyncMutex::new(gateway_client)), - processed_receiver: ReceivedReceiverWrapper::new(processed_receiver), - _task_manager: task_manager, - }) - } - - pub fn setup_client(self) -> Promise { - future_to_promise(async move { self._setup_client().await.into_promise_result() }) - } -} - -async fn test_mixnode( - test_packets: Vec, - gateway_client: LockedGatewayClient, - processed_receiver: ReceivedReceiverWrapper, - _test_marker: TestMarker, - timeout: Duration, -) -> Result { - let num_test_packets = test_packets.len() as u32; - - let expected_ack_ids = test_packets - .iter() - .map(|p| p.fragment_identifier) - .collect::>(); - - let mix_packets = test_packets.into_iter().map(|p| p.mix_packet).collect(); - - // start by clearing any messages that might have been received between tests - processed_receiver.clear_received_channel().await; - - // locking the gateway client so that we could get mutable access to data without having to declare - // self mutable - let mut gateway_permit = gateway_client.lock().await; - gateway_permit.batch_send_mix_packets(mix_packets).await?; - - let receiver_permit = processed_receiver.lock().await; - let result = - EphemeralTestReceiver::new(num_test_packets, expected_ack_ids, receiver_permit, timeout) - .perform_test() - .await; - - Ok(result) -} - -#[wasm_bindgen] -impl NymNodeTester { - #[wasm_bindgen(constructor)] - #[allow(clippy::new_ret_no_self)] - pub fn new(args: NymNodeTesterOpts) -> Promise { - future_to_promise(async move { Self::new_async(args).await.into_promise_result() }) - } - - async fn new_async(args: NymNodeTesterOpts) -> Result { - NymNodeTesterBuilder::new_async(args) - .await? - ._setup_client() - .await - } - - pub fn disconnect_from_gateway(&self) -> Promise { - self.gateway_client.disconnect_from_gateway() - } - - pub fn reconnect_to_gateway(&self) -> Promise { - self.gateway_client.reconnect_to_gateway() - } - - fn prepare_test_packets( - &self, - mixnode_identity: String, - test_nonce: u32, - num_test_packets: u32, - ) -> Result, NodeTesterError> { - let test_ext = WasmTestMessageExt::new(test_nonce); - let mut tester_permit = self.tester.lock().expect("mutex got poisoned"); - tester_permit - .existing_identity_mixnode_test_packets( - mixnode_identity, - LegacyMixLayer::Two, - test_ext, - num_test_packets, - None, - ) - .map_err(Into::into) - } - - pub fn test_node( - &self, - mixnode_identity: String, - timeout_millis: Option, - num_test_packets: Option, - ) -> Promise { - // establish test parameters - let timeout = timeout_millis - .map(Duration::from_millis) - .unwrap_or(DEFAULT_TEST_TIMEOUT); - let num_test_packets = num_test_packets.unwrap_or(DEFAULT_TEST_PACKETS); - - // mark start of the test - if self.test_in_progress.swap(true, Ordering::SeqCst) { - return NodeTesterError::TestInProgress.into_rejected_promise(); - } - - // prepare test packets - // (I simultaneously feel both disgusted and amazed by this workaround) - let test_nonce = self.current_test_nonce.fetch_add(1, Ordering::Relaxed); - let test_packets = check_promise_result!(self.prepare_test_packets( - mixnode_identity, - test_nonce, - num_test_packets - )); - - let processed_receiver_clone = self.processed_receiver.clone(); - let gateway_client_clone = Arc::clone(&self.gateway_client); - let tester_marker = TestMarker::new(Arc::clone(&self.test_in_progress)); - - // start doing async things (send packets and watch for anything coming back) - future_to_promise(async move { - test_mixnode( - test_packets, - gateway_client_clone, - processed_receiver_clone, - tester_marker, - timeout, - ) - .await - .into_promise_result() - }) - } -} diff --git a/wasm/node-tester/src/types.rs b/wasm/node-tester/src/types.rs deleted file mode 100644 index 2bcbe84395..0000000000 --- a/wasm/node-tester/src/types.rs +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use nym_node_tester_utils::TestMessage; -use nym_wasm_utils::console_log; -use serde::{Deserialize, Serialize}; -use std::fmt::{Display, Formatter}; -use wasm_bindgen::prelude::wasm_bindgen; - -pub type NodeTestMessage = TestMessage; - -#[derive(Serialize, Deserialize, Copy, Clone)] -pub struct WasmTestMessageExt { - pub test_id: u32, -} - -impl WasmTestMessageExt { - pub fn new(test_id: u32) -> Self { - WasmTestMessageExt { test_id } - } -} - -// TODO: maybe put it in the tester utils -#[wasm_bindgen] -pub struct NodeTestResult { - pub sent_packets: u32, - pub received_packets: u32, - pub received_acks: u32, - - pub duplicate_packets: u32, - pub duplicate_acks: u32, -} - -impl Display for NodeTestResult { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - writeln!(f, "Test results: ")?; - writeln!(f, "Total score: {:.2}%", self.score())?; - writeln!(f, "Sent packets: {}", self.sent_packets)?; - writeln!(f, "Received (valid) packets: {}", self.received_packets)?; - writeln!(f, "Received (valid) acks: {}", self.received_acks)?; - writeln!(f, "Received duplicate packets: {}", self.duplicate_packets)?; - write!(f, "Received duplicate acks: {}", self.duplicate_acks) - } -} - -#[wasm_bindgen] -impl NodeTestResult { - pub fn log_details(&self) { - console_log!("{}", self) - } - - pub fn score(&self) -> f32 { - let expected = self.sent_packets * 2; - let actual = (self.received_packets + self.received_acks) - .saturating_sub(self.duplicate_packets + self.duplicate_acks); - - actual as f32 / expected as f32 * 100. - } -} diff --git a/yarn.lock b/yarn.lock deleted file mode 100644 index ca139999cb..0000000000 --- a/yarn.lock +++ /dev/null @@ -1,24029 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@adobe/css-tools@^4.4.0": - version "4.4.4" - resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.4.4.tgz#2856c55443d3d461693f32d2b96fb6ea92e1ffa9" - integrity sha512-Elp+iwUx5rN5+Y8xLt5/GRoG20WGoDCQ/1Fb+1LiGtvwbDavuSk0jhD/eZdckHAuzcDzccnkv+rEjyWfRx18gg== - -"@asamuzakjp/css-color@^4.0.3": - version "4.0.5" - resolved "https://registry.yarnpkg.com/@asamuzakjp/css-color/-/css-color-4.0.5.tgz#cc533095241d8a56c49614591955280ab8c4bb02" - integrity sha512-lMrXidNhPGsDjytDy11Vwlb6OIGrT3CmLg3VWNFyWkLWtijKl7xjvForlh8vuj0SHGjgl4qZEQzUmYTeQA2JFQ== - dependencies: - "@csstools/css-calc" "^2.1.4" - "@csstools/css-color-parser" "^3.1.0" - "@csstools/css-parser-algorithms" "^3.0.5" - "@csstools/css-tokenizer" "^3.0.4" - lru-cache "^11.2.1" - -"@asamuzakjp/dom-selector@^6.7.2": - version "6.7.2" - resolved "https://registry.yarnpkg.com/@asamuzakjp/dom-selector/-/dom-selector-6.7.2.tgz#bce7e730e969610ce8574b98ff3dd69db6ac9e6a" - integrity sha512-ccKogJI+0aiDhOahdjANIc9SDixSud1gbwdVrhn7kMopAtLXqsz9MKmQQtIl6Y5aC2IYq+j4dz/oedL2AVMmVQ== - dependencies: - "@asamuzakjp/nwsapi" "^2.3.9" - bidi-js "^1.0.3" - css-tree "^3.1.0" - is-potential-custom-element-name "^1.0.1" - lru-cache "^11.2.2" - -"@asamuzakjp/nwsapi@^2.3.9": - version "2.3.9" - resolved "https://registry.yarnpkg.com/@asamuzakjp/nwsapi/-/nwsapi-2.3.9.tgz#ad5549322dfe9d153d4b4dd6f7ff2ae234b06e24" - integrity sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q== - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.27.1", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.27.1.tgz#200f715e66d52a23b221a9435534a91cc13ad5be" - integrity sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg== - dependencies: - "@babel/helper-validator-identifier" "^7.27.1" - js-tokens "^4.0.0" - picocolors "^1.1.1" - -"@babel/code-frame@^7.28.6", "@babel/code-frame@^7.29.0": - version "7.29.0" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.29.0.tgz#7cd7a59f15b3cc0dcd803038f7792712a7d0b15c" - integrity sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw== - dependencies: - "@babel/helper-validator-identifier" "^7.28.5" - js-tokens "^4.0.0" - picocolors "^1.1.1" - -"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.27.2", "@babel/compat-data@^7.27.7", "@babel/compat-data@^7.28.5": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.28.5.tgz#a8a4962e1567121ac0b3b487f52107443b455c7f" - integrity sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA== - -"@babel/compat-data@^7.28.6": - version "7.29.0" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.29.0.tgz#00d03e8c0ac24dd9be942c5370990cbe1f17d88d" - integrity sha512-T1NCJqT/j9+cn8fvkt7jtwbLBfLC/1y1c7NtCeXFRgzGTsafi68MRv8yzkYSapBnFA6L3U2VSc02ciDzoAJhJg== - -"@babel/core@7.12.9": - version "7.12.9" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.9.tgz#fd450c4ec10cdbb980e2928b7aa7a28484593fc8" - integrity sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/generator" "^7.12.5" - "@babel/helper-module-transforms" "^7.12.1" - "@babel/helpers" "^7.12.5" - "@babel/parser" "^7.12.7" - "@babel/template" "^7.12.7" - "@babel/traverse" "^7.12.9" - "@babel/types" "^7.12.7" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.1" - json5 "^2.1.2" - lodash "^4.17.19" - resolve "^1.3.2" - semver "^5.4.1" - source-map "^0.5.0" - -"@babel/core@^7.1.0", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.15.0", "@babel/core@^7.17.5", "@babel/core@^7.19.6", "@babel/core@^7.22.10", "@babel/core@^7.7.2", "@babel/core@^7.7.5", "@babel/core@^7.8.0": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.28.5.tgz#4c81b35e51e1b734f510c99b07dfbc7bbbb48f7e" - integrity sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw== - 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" - "@jridgewell/remapping" "^2.3.5" - convert-source-map "^2.0.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.3" - semver "^6.3.1" - -"@babel/core@^7.23.9", "@babel/core@^7.27.4": - version "7.29.0" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.29.0.tgz#5286ad785df7f79d656e88ce86e650d16ca5f322" - integrity sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA== - dependencies: - "@babel/code-frame" "^7.29.0" - "@babel/generator" "^7.29.0" - "@babel/helper-compilation-targets" "^7.28.6" - "@babel/helper-module-transforms" "^7.28.6" - "@babel/helpers" "^7.28.6" - "@babel/parser" "^7.29.0" - "@babel/template" "^7.28.6" - "@babel/traverse" "^7.29.0" - "@babel/types" "^7.29.0" - "@jridgewell/remapping" "^2.3.5" - convert-source-map "^2.0.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.3" - semver "^6.3.1" - -"@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.28.5", "@babel/generator@^7.7.2": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.28.5.tgz#712722d5e50f44d07bc7ac9fe84438742dd61298" - integrity sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ== - dependencies: - "@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" - -"@babel/generator@^7.27.5", "@babel/generator@^7.29.0": - version "7.29.1" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.29.1.tgz#d09876290111abbb00ef962a7b83a5307fba0d50" - integrity sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw== - dependencies: - "@babel/parser" "^7.29.0" - "@babel/types" "^7.29.0" - "@jridgewell/gen-mapping" "^0.3.12" - "@jridgewell/trace-mapping" "^0.3.28" - jsesc "^3.0.2" - -"@babel/helper-annotate-as-pure@^7.18.6", "@babel/helper-annotate-as-pure@^7.27.1", "@babel/helper-annotate-as-pure@^7.27.3": - version "7.27.3" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz#f31fd86b915fc4daf1f3ac6976c59be7084ed9c5" - integrity sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg== - dependencies: - "@babel/types" "^7.27.3" - -"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.27.1", "@babel/helper-compilation-targets@^7.27.2": - version "7.27.2" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz#46a0f6efab808d51d29ce96858dd10ce8732733d" - integrity sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ== - dependencies: - "@babel/compat-data" "^7.27.2" - "@babel/helper-validator-option" "^7.27.1" - browserslist "^4.24.0" - lru-cache "^5.1.1" - semver "^6.3.1" - -"@babel/helper-compilation-targets@^7.28.6": - version "7.28.6" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz#32c4a3f41f12ed1532179b108a4d746e105c2b25" - integrity sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA== - dependencies: - "@babel/compat-data" "^7.28.6" - "@babel/helper-validator-option" "^7.27.1" - browserslist "^4.24.0" - lru-cache "^5.1.1" - semver "^6.3.1" - -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0", "@babel/helper-create-class-features-plugin@^7.27.1", "@babel/helper-create-class-features-plugin@^7.28.3", "@babel/helper-create-class-features-plugin@^7.28.5": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.28.5.tgz#472d0c28028850968979ad89f173594a6995da46" - integrity sha512-q3WC4JfdODypvxArsJQROfupPBq9+lMwjKq7C33GhbFYJsufD0yd/ziwD+hJucLeWsnFPWZjsU2DNFqBPE7jwQ== - dependencies: - "@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" - -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.27.1": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.28.5.tgz#7c1ddd64b2065c7f78034b25b43346a7e19ed997" - integrity sha512-N1EhvLtHzOvj7QQOUCCS3NrPJP8c5W6ZXCHDn7Yialuy1iu4r5EmIYkXlKNqT99Ciw+W0mDqWoR6HWMZlFP3hw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.27.3" - regexpu-core "^6.3.1" - semver "^6.3.1" - -"@babel/helper-define-polyfill-provider@^0.1.5": - version "0.1.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz#3c2f91b7971b9fc11fe779c945c014065dea340e" - integrity sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg== - dependencies: - "@babel/helper-compilation-targets" "^7.13.0" - "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/traverse" "^7.13.0" - debug "^4.1.1" - lodash.debounce "^4.0.8" - resolve "^1.14.2" - semver "^6.1.2" - -"@babel/helper-define-polyfill-provider@^0.6.5": - version "0.6.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz#742ccf1cb003c07b48859fc9fa2c1bbe40e5f753" - integrity sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg== - dependencies: - "@babel/helper-compilation-targets" "^7.27.2" - "@babel/helper-plugin-utils" "^7.27.1" - debug "^4.4.1" - lodash.debounce "^4.0.8" - resolve "^1.22.10" - -"@babel/helper-globals@^7.28.0": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/helper-globals/-/helper-globals-7.28.0.tgz#b9430df2aa4e17bc28665eadeae8aa1d985e6674" - integrity sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw== - -"@babel/helper-member-expression-to-functions@^7.27.1", "@babel/helper-member-expression-to-functions@^7.28.5": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.28.5.tgz#f3e07a10be37ed7a63461c63e6929575945a6150" - integrity sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg== - dependencies: - "@babel/traverse" "^7.28.5" - "@babel/types" "^7.28.5" - -"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz#7ef769a323e2655e126673bb6d2d6913bbead204" - integrity sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w== - dependencies: - "@babel/traverse" "^7.27.1" - "@babel/types" "^7.27.1" - -"@babel/helper-module-imports@^7.28.6": - version "7.28.6" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.28.6.tgz#60632cbd6ffb70b22823187201116762a03e2d5c" - integrity sha512-l5XkZK7r7wa9LucGw9LwZyyCUscb4x37JWTPz7swwFE/0FMQAGpiWUZn8u9DzkSBWEcK25jmvubfpw2dnAMdbw== - dependencies: - "@babel/traverse" "^7.28.6" - "@babel/types" "^7.28.6" - -"@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.27.1", "@babel/helper-module-transforms@^7.28.3": - version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz#a2b37d3da3b2344fe085dab234426f2b9a2fa5f6" - integrity sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw== - dependencies: - "@babel/helper-module-imports" "^7.27.1" - "@babel/helper-validator-identifier" "^7.27.1" - "@babel/traverse" "^7.28.3" - -"@babel/helper-module-transforms@^7.28.6": - version "7.28.6" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz#9312d9d9e56edc35aeb6e95c25d4106b50b9eb1e" - integrity sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA== - dependencies: - "@babel/helper-module-imports" "^7.28.6" - "@babel/helper-validator-identifier" "^7.28.5" - "@babel/traverse" "^7.28.6" - -"@babel/helper-optimise-call-expression@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz#c65221b61a643f3e62705e5dd2b5f115e35f9200" - integrity sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw== - dependencies: - "@babel/types" "^7.27.1" - -"@babel/helper-plugin-utils@7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" - integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.27.1", "@babel/helper-plugin-utils@^7.8.0": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz#ddb2f876534ff8013e6c2b299bf4d39b3c51d44c" - integrity sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw== - -"@babel/helper-remap-async-to-generator@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz#4601d5c7ce2eb2aea58328d43725523fcd362ce6" - integrity sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.27.1" - "@babel/helper-wrap-function" "^7.27.1" - "@babel/traverse" "^7.27.1" - -"@babel/helper-replace-supers@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz#b1ed2d634ce3bdb730e4b52de30f8cccfd692bc0" - integrity sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.27.1" - "@babel/helper-optimise-call-expression" "^7.27.1" - "@babel/traverse" "^7.27.1" - -"@babel/helper-simple-access@^7.25.9": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.27.1.tgz#7f2171e29d95d6283ede286a4994f985cbe07973" - integrity sha512-OU4zVQrJgFBNXMjrHs1yFSdlTgufO4tefcUZoqNhukVfw0p8x1Asht/gcGZ3bpHbi8gu/76m4JhrlKPqkrs/WQ== - dependencies: - "@babel/traverse" "^7.27.1" - "@babel/types" "^7.27.1" - -"@babel/helper-skip-transparent-expression-wrappers@^7.20.0", "@babel/helper-skip-transparent-expression-wrappers@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz#62bb91b3abba8c7f1fec0252d9dbea11b3ee7a56" - integrity sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg== - dependencies: - "@babel/traverse" "^7.27.1" - "@babel/types" "^7.27.1" - -"@babel/helper-string-parser@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz#54da796097ab19ce67ed9f88b47bb2ec49367687" - integrity sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA== - -"@babel/helper-validator-identifier@^7.27.1", "@babel/helper-validator-identifier@^7.28.5": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz#010b6938fab7cb7df74aa2bbc06aa503b8fe5fb4" - integrity sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q== - -"@babel/helper-validator-option@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz#fa52f5b1e7db1ab049445b421c4471303897702f" - integrity sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg== - -"@babel/helper-wrap-function@^7.27.1": - version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.28.3.tgz#fe4872092bc1438ffd0ce579e6f699609f9d0a7a" - integrity sha512-zdf983tNfLZFletc0RRXYrHrucBEg95NIFMkn6K9dbeMYnsgHaSBGcQqdsCSStG2PYwRre0Qc2NNSCXbG+xc6g== - dependencies: - "@babel/template" "^7.27.2" - "@babel/traverse" "^7.28.3" - "@babel/types" "^7.28.2" - -"@babel/helpers@^7.12.5", "@babel/helpers@^7.28.4": - version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.28.4.tgz#fe07274742e95bdf7cf1443593eeb8926ab63827" - integrity sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w== - dependencies: - "@babel/template" "^7.27.2" - "@babel/types" "^7.28.4" - -"@babel/helpers@^7.28.6": - version "7.29.2" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.29.2.tgz#9cfbccb02b8e229892c0b07038052cc1a8709c49" - integrity sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw== - dependencies: - "@babel/template" "^7.28.6" - "@babel/types" "^7.29.0" - -"@babel/parser@^7.1.0", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.27.2", "@babel/parser@^7.28.5": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.28.5.tgz#0b0225ee90362f030efd644e8034c99468893b08" - integrity sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ== - dependencies: - "@babel/types" "^7.28.5" - -"@babel/parser@^7.23.9", "@babel/parser@^7.28.6", "@babel/parser@^7.29.0": - version "7.29.2" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.29.2.tgz#58bd50b9a7951d134988a1ae177a35ef9a703ba1" - integrity sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA== - dependencies: - "@babel/types" "^7.29.0" - -"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.28.5": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.28.5.tgz#fbde57974707bbfa0376d34d425ff4fa6c732421" - integrity sha512-87GDMS3tsmMSi/3bWOte1UblL+YUTFMV8SZPZ2eSEL17s74Cw/l63rR6NmGVKMYW2GYi85nE+/d6Hw5N0bEk2Q== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/traverse" "^7.28.5" - -"@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz#43f70a6d7efd52370eefbdf55ae03d91b293856d" - integrity sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz#beb623bd573b8b6f3047bd04c32506adc3e58a72" - integrity sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz#e134a5479eb2ba9c02714e8c1ebf1ec9076124fd" - integrity sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" - "@babel/plugin-transform-optional-chaining" "^7.27.1" - -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.28.3": - version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.28.3.tgz#373f6e2de0016f73caf8f27004f61d167743742a" - integrity sha512-b6YTX108evsvE4YgWyQ921ZAFFQm3Bn+CA3+ZXlNVnPhx+UfsVURoPjfGAPCjBgrqo30yX/C2nZGX96DxvR9Iw== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/traverse" "^7.28.3" - -"@babel/plugin-proposal-class-properties@^7.12.1": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" - integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-proposal-decorators@^7.12.12": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.28.0.tgz#419c8acc31088e05a774344c021800f7ddc39bf0" - integrity sha512-zOiZqvANjWDUaUS9xMxbMcK/Zccztbe/6ikvUXaG9nsPH3w6qh5UaPGAnirI/WhIbZ8m3OHU0ReyPrknG+ZKeg== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.27.1" - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/plugin-syntax-decorators" "^7.27.1" - -"@babel/plugin-proposal-export-default-from@^7.12.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.27.1.tgz#59b050b0e5fdc366162ab01af4fcbac06ea40919" - integrity sha512-hjlsMBl1aJc5lp8MoCDEZCiYzlgdRAShOjAfRw6X+GlpLpUPU7c3XNLsKFZbQk/1cRzBlJ7CXg3xJAJMrFa1Uw== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" - integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - -"@babel/plugin-proposal-object-rest-spread@7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz#def9bd03cea0f9b72283dac0ec22d289c7691069" - integrity sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-transform-parameters" "^7.12.1" - -"@babel/plugin-proposal-object-rest-spread@^7.12.1": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz#aa662940ef425779c75534a5c41e9d936edc390a" - integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg== - dependencies: - "@babel/compat-data" "^7.20.5" - "@babel/helper-compilation-targets" "^7.20.7" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.20.7" - -"@babel/plugin-proposal-optional-chaining@^7.12.7": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz#886f5c8978deb7d30f678b2e24346b287234d3ea" - integrity sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA== - dependencies: - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - -"@babel/plugin-proposal-private-methods@^7.12.1": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea" - integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": - version "7.21.0-placeholder-for-preset-env.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" - integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== - -"@babel/plugin-proposal-private-property-in-object@^7.12.1": - version "7.21.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz#69d597086b6760c4126525cfa154f34631ff272c" - integrity sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.18.6" - "@babel/helper-create-class-features-plugin" "^7.21.0" - "@babel/helper-plugin-utils" "^7.20.2" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - -"@babel/plugin-syntax-async-generators@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" - integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-bigint@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" - integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-class-properties@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" - integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== - dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - -"@babel/plugin-syntax-class-static-block@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" - integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-decorators@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.27.1.tgz#ee7dd9590aeebc05f9d4c8c0560007b05979a63d" - integrity sha512-YMq8Z87Lhl8EGkmb0MwYkt36QnxC+fzCgrl66ereamPlYToRpIk5nUjKUY3QKLWq8mwUB1BgbeXcTJhZOCDg5A== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-syntax-dynamic-import@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" - integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-flow@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.27.1.tgz#6c83cf0d7d635b716827284b7ecd5aead9237662" - integrity sha512-p9OkPbZ5G7UT1MofwYFigGebnrzGJacoBSQM0/6bi/PUMVE+qlWDD/OalvQKbwgQzU6dl0xAv6r4X7Jme0RYxA== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-syntax-import-assertions@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz#88894aefd2b03b5ee6ad1562a7c8e1587496aecd" - integrity sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-syntax-import-attributes@^7.24.7", "@babel/plugin-syntax-import-attributes@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.27.1.tgz#34c017d54496f9b11b61474e7ea3dfd5563ffe07" - integrity sha512-oFT0FrKHgF53f4vOsZGi2Hh3I35PfSmVs4IBFLFj4dnafP+hIWDLg3VyKmUHfLoLHlyxY4C7DGtmHuJgn+IGww== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-syntax-import-meta@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" - integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-json-strings@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" - integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-jsx@7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz#9d9d357cc818aa7ae7935917c1257f67677a0926" - integrity sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-jsx@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz#2f9beb5eff30fa507c5532d107daac7b888fa34c" - integrity sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" - integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-numeric-separator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" - integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-object-rest-spread@7.8.3", "@babel/plugin-syntax-object-rest-spread@^7.8.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-private-property-in-object@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" - integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-top-level-await@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" - integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-typescript@^7.27.1", "@babel/plugin-syntax-typescript@^7.7.2": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz#5147d29066a793450f220c63fa3a9431b7e6dd18" - integrity sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-syntax-unicode-sets-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" - integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - -"@babel/plugin-transform-arrow-functions@^7.12.1", "@babel/plugin-transform-arrow-functions@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz#6e2061067ba3ab0266d834a9f94811196f2aba9a" - integrity sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-async-generator-functions@^7.28.0": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.28.0.tgz#1276e6c7285ab2cd1eccb0bc7356b7a69ff842c2" - integrity sha512-BEOdvX4+M765icNPZeidyADIvQ1m1gmunXufXxvRESy/jNNyfovIqUyE7MVgGBjWktCoJlzvFA1To2O4ymIO3Q== - dependencies: - "@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@^7.14.5", "@babel/plugin-transform-async-to-generator@^7.22.5", "@babel/plugin-transform-async-to-generator@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.27.1.tgz#9a93893b9379b39466c74474f55af03de78c66e7" - integrity sha512-NREkZsZVJS4xmTr8qzE5y8AfIPqsdQfRuUiLRTEzb7Qii8iFWCyDKaUV2c0rCuh4ljDZ98ALHP/PetiBV2nddA== - dependencies: - "@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@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz#558a9d6e24cf72802dd3b62a4b51e0d62c0f57f9" - integrity sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-block-scoping@^7.12.12", "@babel/plugin-transform-block-scoping@^7.28.5": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.5.tgz#e0d3af63bd8c80de2e567e690a54e84d85eb16f6" - integrity sha512-45DmULpySVvmq9Pj3X9B+62Xe+DJGov27QravQJU1LLcapR6/10i+gYVAucGGJpHBp5mYxIMK4nDAT/QDLr47g== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-class-properties@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz#dd40a6a370dfd49d32362ae206ddaf2bb082a925" - integrity sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.27.1" - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-class-static-block@^7.28.3": - version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.28.3.tgz#d1b8e69b54c9993bc558203e1f49bfc979bfd852" - integrity sha512-LtPXlBbRoc4Njl/oh1CeD/3jC+atytbnf/UqLoqTDcEYGUPj022+rvfkbDYieUrSj3CaV4yHDByPE+T2HwfsJg== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.28.3" - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-classes@^7.12.1", "@babel/plugin-transform-classes@^7.28.4": - version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.4.tgz#75d66175486788c56728a73424d67cbc7473495c" - integrity sha512-cFOlhIYPBv/iBoc+KS3M6et2XPtbT2HiCRfBXWtfpc9OAyostldxIf9YAYB6ypURBBbx+Qv6nyrLzASfJe+hBA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.27.3" - "@babel/helper-compilation-targets" "^7.27.2" - "@babel/helper-globals" "^7.28.0" - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/helper-replace-supers" "^7.27.1" - "@babel/traverse" "^7.28.4" - -"@babel/plugin-transform-computed-properties@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz#81662e78bf5e734a97982c2b7f0a793288ef3caa" - integrity sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/template" "^7.27.1" - -"@babel/plugin-transform-destructuring@^7.12.1", "@babel/plugin-transform-destructuring@^7.28.0", "@babel/plugin-transform-destructuring@^7.28.5": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.5.tgz#b8402764df96179a2070bb7b501a1586cf8ad7a7" - integrity sha512-Kl9Bc6D0zTUcFUvkNuQh4eGXPKKNDOJQXVyyM4ZAQPMveniJdxi8XMJwLo+xSoW3MIq81bD33lcUe9kZpl0MCw== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/traverse" "^7.28.5" - -"@babel/plugin-transform-dotall-regex@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz#aa6821de864c528b1fecf286f0a174e38e826f4d" - integrity sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.27.1" - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-duplicate-keys@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz#f1fbf628ece18e12e7b32b175940e68358f546d1" - integrity sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz#5043854ca620a94149372e69030ff8cb6a9eb0ec" - integrity sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.27.1" - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-dynamic-import@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz#4c78f35552ac0e06aa1f6e3c573d67695e8af5a4" - integrity sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-explicit-resource-management@^7.28.0": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-explicit-resource-management/-/plugin-transform-explicit-resource-management-7.28.0.tgz#45be6211b778dbf4b9d54c4e8a2b42fa72e09a1a" - integrity sha512-K8nhUcn3f6iB+P3gwCv/no7OdzOZQcKchW6N389V6PD8NUWKZHzndOd9sPDVbMoBsbmjMqlB4L9fm+fEFNVlwQ== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/plugin-transform-destructuring" "^7.28.0" - -"@babel/plugin-transform-exponentiation-operator@^7.28.5": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.28.5.tgz#7cc90a8170e83532676cfa505278e147056e94fe" - integrity sha512-D4WIMaFtwa2NizOp+dnoFjRez/ClKiC2BqqImwKd1X28nqBtZEyCYJ2ozQrrzlxAFrcrjxo39S6khe9RNDlGzw== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-export-namespace-from@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz#71ca69d3471edd6daa711cf4dfc3400415df9c23" - integrity sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-flow-strip-types@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.27.1.tgz#5def3e1e7730f008d683144fb79b724f92c5cdf9" - integrity sha512-G5eDKsu50udECw7DL2AcsysXiQyB7Nfg521t2OAJ4tbfTJ27doHLeF/vlI1NZGlLdbb/v+ibvtL1YBQqYOwJGg== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/plugin-syntax-flow" "^7.27.1" - -"@babel/plugin-transform-for-of@^7.12.1", "@babel/plugin-transform-for-of@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz#bc24f7080e9ff721b63a70ac7b2564ca15b6c40a" - integrity sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" - -"@babel/plugin-transform-function-name@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz#4d0bf307720e4dce6d7c30fcb1fd6ca77bdeb3a7" - integrity sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ== - dependencies: - "@babel/helper-compilation-targets" "^7.27.1" - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/traverse" "^7.27.1" - -"@babel/plugin-transform-json-strings@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz#a2e0ce6ef256376bd527f290da023983527a4f4c" - integrity sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-literals@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz#baaefa4d10a1d4206f9dcdda50d7d5827bb70b24" - integrity sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-logical-assignment-operators@^7.28.5": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.28.5.tgz#d028fd6db8c081dee4abebc812c2325e24a85b0e" - integrity sha512-axUuqnUTBuXyHGcJEVVh9pORaN6wC5bYfE7FGzPiaWa3syib9m7g+/IT/4VgCOe2Upef43PHzeAvcrVek6QuuA== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-member-expression-literals@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz#37b88ba594d852418e99536f5612f795f23aeaf9" - integrity sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-modules-amd@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz#a4145f9d87c2291fe2d05f994b65dba4e3e7196f" - integrity sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA== - dependencies: - "@babel/helper-module-transforms" "^7.27.1" - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-modules-commonjs@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz#8e44ed37c2787ecc23bdc367f49977476614e832" - integrity sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw== - dependencies: - "@babel/helper-module-transforms" "^7.27.1" - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-modules-systemjs@^7.28.5": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.28.5.tgz#7439e592a92d7670dfcb95d0cbc04bd3e64801d2" - integrity sha512-vn5Jma98LCOeBy/KpeQhXcV2WZgaRUtjwQmjoBuLNlOmkg0fB5pdvYVeWRYI69wWKwK2cD1QbMiUQnoujWvrew== - 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/plugin-transform-modules-umd@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz#63f2cf4f6dc15debc12f694e44714863d34cd334" - integrity sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w== - dependencies: - "@babel/helper-module-transforms" "^7.27.1" - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-named-capturing-groups-regex@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz#f32b8f7818d8fc0cc46ee20a8ef75f071af976e1" - integrity sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.27.1" - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-new-target@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz#259c43939728cad1706ac17351b7e6a7bea1abeb" - integrity sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-nullish-coalescing-operator@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz#4f9d3153bf6782d73dd42785a9d22d03197bc91d" - integrity sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-numeric-separator@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz#614e0b15cc800e5997dadd9bd6ea524ed6c819c6" - integrity sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-object-rest-spread@^7.28.4": - version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.4.tgz#9ee1ceca80b3e6c4bac9247b2149e36958f7f98d" - integrity sha512-373KA2HQzKhQCYiRVIRr+3MjpCObqzDlyrM6u4I201wL8Mp2wHf7uB8GhDwis03k2ti8Zr65Zyyqs1xOxUF/Ew== - dependencies: - "@babel/helper-compilation-targets" "^7.27.2" - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/plugin-transform-destructuring" "^7.28.0" - "@babel/plugin-transform-parameters" "^7.27.7" - "@babel/traverse" "^7.28.4" - -"@babel/plugin-transform-object-super@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz#1c932cd27bf3874c43a5cac4f43ebf970c9871b5" - integrity sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/helper-replace-supers" "^7.27.1" - -"@babel/plugin-transform-optional-catch-binding@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz#84c7341ebde35ccd36b137e9e45866825072a30c" - integrity sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-optional-chaining@^7.27.1", "@babel/plugin-transform-optional-chaining@^7.28.5": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.28.5.tgz#8238c785f9d5c1c515a90bf196efb50d075a4b26" - integrity sha512-N6fut9IZlPnjPwgiQkXNhb+cT8wQKFlJNqcZkWlcTqkcqx6/kU4ynGmLFoa4LViBSirn05YAwk+sQBbPfxtYzQ== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" - -"@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.27.7": - version "7.27.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz#1fd2febb7c74e7d21cf3b05f7aebc907940af53a" - integrity sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-private-methods@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz#fdacbab1c5ed81ec70dfdbb8b213d65da148b6af" - integrity sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.27.1" - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-private-property-in-object@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz#4dbbef283b5b2f01a21e81e299f76e35f900fb11" - integrity sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.27.1" - "@babel/helper-create-class-features-plugin" "^7.27.1" - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-property-literals@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz#07eafd618800591e88073a0af1b940d9a42c6424" - integrity sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-react-constant-elements@^7.18.12": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.27.1.tgz#6c6b50424e749a6e48afd14cf7b92f98cb9383f9" - integrity sha512-edoidOjl/ZxvYo4lSBOQGDSyToYVkTAwyVoa2tkuYTSmjrB1+uAedoL5iROVLXkxH+vRgA7uP4tMg2pUJpZ3Ug== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-react-display-name@^7.28.0": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.28.0.tgz#6f20a7295fea7df42eb42fed8f896813f5b934de" - integrity sha512-D6Eujc2zMxKjfa4Zxl4GHMsmhKKZ9VpcqIchJLvwTxad9zWIYulwYItBovpDOoNLISpcZSXoDJ5gaGbQUDqViA== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-react-jsx-development@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.27.1.tgz#47ff95940e20a3a70e68ad3d4fcb657b647f6c98" - integrity sha512-ykDdF5yI4f1WrAolLqeF3hmYU12j9ntLQl/AOG1HAS21jxyg1Q0/J/tpREuYLfatGdGmXp/3yS0ZA76kOlVq9Q== - dependencies: - "@babel/plugin-transform-react-jsx" "^7.27.1" - -"@babel/plugin-transform-react-jsx@^7.12.12", "@babel/plugin-transform-react-jsx@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.27.1.tgz#1023bc94b78b0a2d68c82b5e96aed573bcfb9db0" - integrity sha512-2KH4LWGSrJIkVf5tSiBFYuXDAoWRq2MMwgivCf+93dd0GQi8RXLjKA/0EvRnVV5G0hrHczsquXuD01L8s6dmBw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.27.1" - "@babel/helper-module-imports" "^7.27.1" - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/plugin-syntax-jsx" "^7.27.1" - "@babel/types" "^7.27.1" - -"@babel/plugin-transform-react-pure-annotations@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.27.1.tgz#339f1ce355eae242e0649f232b1c68907c02e879" - integrity sha512-JfuinvDOsD9FVMTHpzA/pBLisxpv1aSf+OIV8lgH3MuWrks19R27e6a6DipIg4aX1Zm9Wpb04p8wljfKrVSnPA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.27.1" - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-regenerator@^7.28.4": - version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.4.tgz#9d3fa3bebb48ddd0091ce5729139cd99c67cea51" - integrity sha512-+ZEdQlBoRg9m2NnzvEeLgtvBMO4tkFBw5SQIUgLICgTrumLoU7lr+Oghi6km2PFj+dbUt2u1oby2w3BDO9YQnA== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-regexp-modifiers@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz#df9ba5577c974e3f1449888b70b76169998a6d09" - integrity sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.27.1" - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-reserved-words@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz#40fba4878ccbd1c56605a4479a3a891ac0274bb4" - integrity sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-shorthand-properties@^7.12.1", "@babel/plugin-transform-shorthand-properties@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz#532abdacdec87bfee1e0ef8e2fcdee543fe32b90" - integrity sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-spread@^7.12.1", "@babel/plugin-transform-spread@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz#1a264d5fc12750918f50e3fe3e24e437178abb08" - integrity sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" - -"@babel/plugin-transform-sticky-regex@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz#18984935d9d2296843a491d78a014939f7dcd280" - integrity sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-template-literals@^7.12.1", "@babel/plugin-transform-template-literals@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz#1a0eb35d8bb3e6efc06c9fd40eb0bcef548328b8" - integrity sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-typeof-symbol@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz#70e966bb492e03509cf37eafa6dcc3051f844369" - integrity sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-typescript@^7.28.5": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.28.5.tgz#441c5f9a4a1315039516c6c612fc66d5f4594e72" - integrity sha512-x2Qa+v/CuEoX7Dr31iAfr0IhInrVOWZU/2vJMJ00FOR/2nM0BcBEclpaf9sWCDc+v5e9dMrhSH8/atq/kX7+bA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.27.3" - "@babel/helper-create-class-features-plugin" "^7.28.5" - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/helper-skip-transparent-expression-wrappers" "^7.27.1" - "@babel/plugin-syntax-typescript" "^7.27.1" - -"@babel/plugin-transform-unicode-escapes@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz#3e3143f8438aef842de28816ece58780190cf806" - integrity sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-unicode-property-regex@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz#bdfe2d3170c78c5691a3c3be934c8c0087525956" - integrity sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.27.1" - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-unicode-regex@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz#25948f5c395db15f609028e370667ed8bae9af97" - integrity sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.27.1" - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/plugin-transform-unicode-sets-regex@^7.27.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz#6ab706d10f801b5c72da8bb2548561fa04193cd1" - integrity sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.27.1" - "@babel/helper-plugin-utils" "^7.27.1" - -"@babel/preset-env@^7.12.11", "@babel/preset-env@^7.15.0", "@babel/preset-env@^7.19.4", "@babel/preset-env@^7.22.10": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.28.5.tgz#82dd159d1563f219a1ce94324b3071eb89e280b0" - integrity sha512-S36mOoi1Sb6Fz98fBfE+UZSpYw5mJm0NUHtIKrOuNcqeFauy1J6dIvXm2KRVKobOSaGq4t/hBXdN4HGU3wL9Wg== - dependencies: - "@babel/compat-data" "^7.28.5" - "@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.28.5" - "@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.5" - "@babel/plugin-transform-class-properties" "^7.27.1" - "@babel/plugin-transform-class-static-block" "^7.28.3" - "@babel/plugin-transform-classes" "^7.28.4" - "@babel/plugin-transform-computed-properties" "^7.27.1" - "@babel/plugin-transform-destructuring" "^7.28.5" - "@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.28.5" - "@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.28.5" - "@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.28.5" - "@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.4" - "@babel/plugin-transform-object-super" "^7.27.1" - "@babel/plugin-transform-optional-catch-binding" "^7.27.1" - "@babel/plugin-transform-optional-chaining" "^7.28.5" - "@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.4" - "@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" - -"@babel/preset-flow@^7.12.1": - version "7.27.1" - resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.27.1.tgz#3050ed7c619e8c4bfd0e0eeee87a2fa86a4bb1c6" - integrity sha512-ez3a2it5Fn6P54W8QkbfIyyIbxlXvcxyWHHvno1Wg0Ej5eiJY5hBb8ExttoIOJJk7V2dZE6prP7iby5q2aQ0Lg== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/helper-validator-option" "^7.27.1" - "@babel/plugin-transform-flow-strip-types" "^7.27.1" - -"@babel/preset-modules@0.1.6-no-external-plugins": - version "0.1.6-no-external-plugins" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a" - integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/types" "^7.4.4" - esutils "^2.0.2" - -"@babel/preset-react@^7.12.10", "@babel/preset-react@^7.14.5", "@babel/preset-react@^7.18.6": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.28.5.tgz#6fcc0400fa79698433d653092c3919bb4b0878d9" - integrity sha512-Z3J8vhRq7CeLjdC58jLv4lnZ5RKFUJWqH5emvxmv9Hv3BD1T9R/Im713R4MTKwvFaV74ejZ3sM01LyEKk4ugNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/helper-validator-option" "^7.27.1" - "@babel/plugin-transform-react-display-name" "^7.28.0" - "@babel/plugin-transform-react-jsx" "^7.27.1" - "@babel/plugin-transform-react-jsx-development" "^7.27.1" - "@babel/plugin-transform-react-pure-annotations" "^7.27.1" - -"@babel/preset-typescript@^7.12.7", "@babel/preset-typescript@^7.15.0", "@babel/preset-typescript@^7.18.6", "@babel/preset-typescript@^7.22.5": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.28.5.tgz#540359efa3028236958466342967522fd8f2a60c" - integrity sha512-+bQy5WOI2V6LJZpPVxY+yp66XdZ2yifu0Mc1aP5CQKgjn4QM5IN2i5fAZ4xKop47pr8rpVhiAeu+nDQa12C8+g== - dependencies: - "@babel/helper-plugin-utils" "^7.27.1" - "@babel/helper-validator-option" "^7.27.1" - "@babel/plugin-syntax-jsx" "^7.27.1" - "@babel/plugin-transform-modules-commonjs" "^7.27.1" - "@babel/plugin-transform-typescript" "^7.28.5" - -"@babel/register@^7.12.1": - version "7.28.3" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.28.3.tgz#abd8a3753480c799bdaf9c9092d6745d16e052c2" - integrity sha512-CieDOtd8u208eI49bYl4z1J22ySFw87IGwE+IswFEExH7e3rLgKb0WNQeumnacQ1+VoDJLYI5QFA3AJZuyZQfA== - dependencies: - clone-deep "^4.0.1" - find-cache-dir "^2.0.0" - make-dir "^2.1.0" - pirates "^4.0.6" - source-map-support "^0.5.16" - -"@babel/runtime@7.7.2": - version "7.7.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.2.tgz#111a78002a5c25fc8e3361bedc9529c696b85a6a" - integrity sha512-JONRbXbTXc9WQE2mAZd1p0Z3DZ/6vaQIkgYMSTP3KjRCyd7rCZCcfhCyX+YjwcKxcZ82UrxbRD358bpExNgrjw== - dependencies: - regenerator-runtime "^0.13.2" - -"@babel/runtime@^7.0.0", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.2", "@babel/runtime@^7.23.9", "@babel/runtime@^7.25.7", "@babel/runtime@^7.26.0", "@babel/runtime@^7.26.10", "@babel/runtime@^7.27.6", "@babel/runtime@^7.28.4", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.7": - version "7.28.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.28.4.tgz#a70226016fabe25c5783b2f22d3e1c9bc5ca3326" - integrity sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ== - -"@babel/runtime@^7.3.1", "@babel/runtime@^7.8.3": - version "7.29.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.29.2.tgz#9a6e2d05f4b6692e1801cd4fb176ad823930ed5e" - integrity sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g== - -"@babel/runtime@~7.5.4": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" - integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== - dependencies: - regenerator-runtime "^0.13.2" - -"@babel/template@^7.12.7", "@babel/template@^7.27.1", "@babel/template@^7.27.2", "@babel/template@^7.3.3": - version "7.27.2" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.2.tgz#fa78ceed3c4e7b63ebf6cb39e5852fca45f6809d" - integrity sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw== - dependencies: - "@babel/code-frame" "^7.27.1" - "@babel/parser" "^7.27.2" - "@babel/types" "^7.27.1" - -"@babel/template@^7.28.6": - version "7.28.6" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.28.6.tgz#0e7e56ecedb78aeef66ce7972b082fce76a23e57" - integrity sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ== - dependencies: - "@babel/code-frame" "^7.28.6" - "@babel/parser" "^7.28.6" - "@babel/types" "^7.28.6" - -"@babel/traverse@^7.1.6", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.27.1", "@babel/traverse@^7.28.0", "@babel/traverse@^7.28.3", "@babel/traverse@^7.28.4", "@babel/traverse@^7.28.5", "@babel/traverse@^7.7.2": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.28.5.tgz#450cab9135d21a7a2ca9d2d35aa05c20e68c360b" - integrity sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ== - 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" - debug "^4.3.1" - -"@babel/traverse@^7.28.6", "@babel/traverse@^7.29.0": - version "7.29.0" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.29.0.tgz#f323d05001440253eead3c9c858adbe00b90310a" - integrity sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA== - dependencies: - "@babel/code-frame" "^7.29.0" - "@babel/generator" "^7.29.0" - "@babel/helper-globals" "^7.28.0" - "@babel/parser" "^7.29.0" - "@babel/template" "^7.28.6" - "@babel/types" "^7.29.0" - debug "^4.3.1" - -"@babel/types@^7.0.0", "@babel/types@^7.12.11", "@babel/types@^7.12.7", "@babel/types@^7.2.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.27.1", "@babel/types@^7.27.3", "@babel/types@^7.28.2", "@babel/types@^7.28.4", "@babel/types@^7.28.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4": - version "7.28.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.28.5.tgz#10fc405f60897c35f07e85493c932c7b5ca0592b" - integrity sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA== - dependencies: - "@babel/helper-string-parser" "^7.27.1" - "@babel/helper-validator-identifier" "^7.28.5" - -"@babel/types@^7.28.6", "@babel/types@^7.29.0": - version "7.29.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.29.0.tgz#9f5b1e838c446e72cf3cd4b918152b8c605e37c7" - integrity sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A== - dependencies: - "@babel/helper-string-parser" "^7.27.1" - "@babel/helper-validator-identifier" "^7.28.5" - -"@base2/pretty-print-object@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz#371ba8be66d556812dc7fb169ebc3c08378f69d4" - integrity sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA== - -"@bcoe/v8-coverage@^0.2.3": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" - integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== - -"@biomejs/biome@1.9.4": - version "1.9.4" - resolved "https://registry.yarnpkg.com/@biomejs/biome/-/biome-1.9.4.tgz#89766281cbc3a0aae865a7ff13d6aaffea2842bf" - integrity sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog== - optionalDependencies: - "@biomejs/cli-darwin-arm64" "1.9.4" - "@biomejs/cli-darwin-x64" "1.9.4" - "@biomejs/cli-linux-arm64" "1.9.4" - "@biomejs/cli-linux-arm64-musl" "1.9.4" - "@biomejs/cli-linux-x64" "1.9.4" - "@biomejs/cli-linux-x64-musl" "1.9.4" - "@biomejs/cli-win32-arm64" "1.9.4" - "@biomejs/cli-win32-x64" "1.9.4" - -"@biomejs/cli-darwin-arm64@1.9.4": - version "1.9.4" - resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz#dfa376d23a54a2d8f17133c92f23c1bf2e62509f" - integrity sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw== - -"@biomejs/cli-darwin-x64@1.9.4": - version "1.9.4" - resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz#eafc2ce3849d385fc02238aad1ca4a73395a64d9" - integrity sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg== - -"@biomejs/cli-linux-arm64-musl@1.9.4": - version "1.9.4" - resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz#d780c3e01758fc90f3268357e3f19163d1f84fca" - integrity sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA== - -"@biomejs/cli-linux-arm64@1.9.4": - version "1.9.4" - resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz#8ed1dd0e89419a4b66a47f95aefb8c46ae6041c9" - integrity sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g== - -"@biomejs/cli-linux-x64-musl@1.9.4": - version "1.9.4" - resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.4.tgz#f36982b966bd671a36671e1de4417963d7db15fb" - integrity sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg== - -"@biomejs/cli-linux-x64@1.9.4": - version "1.9.4" - resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.4.tgz#a0a7f56680c76b8034ddc149dbf398bdd3a462e8" - integrity sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg== - -"@biomejs/cli-win32-arm64@1.9.4": - version "1.9.4" - resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz#e2ef4e0084e76b7e26f0fc887c5ef1265ea56200" - integrity sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg== - -"@biomejs/cli-win32-x64@1.9.4": - version "1.9.4" - resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz#4c7afa90e3970213599b4095e62f87e5972b2340" - integrity sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA== - -"@chain-registry/client@^1.49.11": - version "1.53.238" - resolved "https://registry.yarnpkg.com/@chain-registry/client/-/client-1.53.238.tgz#9083121817b3c2e1ed18866b381b932f9a4fe2cc" - integrity sha512-BN8sD4xlmkt4i6HU+/u5EFc8yhnfufX024euKhlp5prEmfL3ZtD91cJCH03tQ8q/4LPPSsdrHTJbdAfUlm94tQ== - dependencies: - "@chain-registry/types" "^0.50.238" - "@chain-registry/utils" "^1.51.238" - bfs-path "^1.0.2" - cross-fetch "^3.1.5" - -"@chain-registry/keplr@^1.69.13": - version "1.74.378" - resolved "https://registry.yarnpkg.com/@chain-registry/keplr/-/keplr-1.74.378.tgz#ad8af0d715a84831adb7a693f60e55f3ddc54662" - integrity sha512-XNSVFki72PNOCszB4VDttqVcemW//1kYrHFDJtOKWAmERwbLpig3AiwjMkC0obsZPFrZGtxo+Ff0zkBMGTJHfg== - dependencies: - "@chain-registry/types" "^0.50.238" - "@keplr-wallet/cosmos" "0.12.28" - "@keplr-wallet/crypto" "0.12.28" - semver "^7.5.0" - -"@chain-registry/types@^0.46.11": - version "0.46.15" - resolved "https://registry.yarnpkg.com/@chain-registry/types/-/types-0.46.15.tgz#f4c0219fb7060d97cb224b55f349adb1d436aac9" - integrity sha512-gzf+pkAbEZ7fKuTuwmrEAEcx1K/BNrKuCnB9s+WwSo9Ad/3s+GV5LOXcOOxjjHh9Mrs9kvnxKvzKjOwWu8gDJw== - -"@chain-registry/types@^0.50.238", "@chain-registry/types@^0.50.36": - version "0.50.238" - resolved "https://registry.yarnpkg.com/@chain-registry/types/-/types-0.50.238.tgz#0d9f5e5e65e1f8ab6ef8a6aea34b3c9a11a961f2" - integrity sha512-NJL9n5ND3SAro08jR/NjEBs8trVQ9YqBGIpeZZQJV5ACPU11PzzO1n+TWGcv2302VnI8L1BBaEaEaQq4AJKkng== - -"@chain-registry/utils@^1.51.238": - version "1.51.238" - resolved "https://registry.yarnpkg.com/@chain-registry/utils/-/utils-1.51.238.tgz#f6a808f55839f5163f035c28025e6d00771e5e0f" - integrity sha512-+80RunNYd9xnkiMEdTE2iNi0NMnDzmubyQtVXVv0z2EcK83+0CCsSaMB7/WlDrx/n1P9bvu62hKmZIV2bG6KlA== - dependencies: - "@chain-registry/types" "^0.50.238" - bignumber.js "9.1.2" - sha.js "^2.4.11" - -"@cnakazawa/watch@^1.0.3": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" - integrity sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ== - dependencies: - exec-sh "^0.3.2" - minimist "^1.2.0" - -"@colors/colors@1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" - integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== - -"@confio/ics23@^0.6.8": - version "0.6.8" - resolved "https://registry.yarnpkg.com/@confio/ics23/-/ics23-0.6.8.tgz#2a6b4f1f2b7b20a35d9a0745bb5a446e72930b3d" - integrity sha512-wB6uo+3A50m0sW/EWcU64xpV/8wShZ6bMTa7pF8eYsTrSkQA7oLUIJcs/wb8g4y2Oyq701BaGiO6n/ak5WXO1w== - dependencies: - "@noble/hashes" "^1.0.0" - protobufjs "^6.8.8" - -"@cosmjs/amino@^0.32.3", "@cosmjs/amino@^0.32.4": - version "0.32.4" - resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.32.4.tgz#3908946c0394e6d431694c8992c5147079a1c860" - integrity sha512-zKYOt6hPy8obIFtLie/xtygCkH9ZROiQ12UHfKsOkWaZfPQUvVbtgmu6R4Kn1tFLI/SRkw7eqhaogmW/3NYu/Q== - dependencies: - "@cosmjs/crypto" "^0.32.4" - "@cosmjs/encoding" "^0.32.4" - "@cosmjs/math" "^0.32.4" - "@cosmjs/utils" "^0.32.4" - -"@cosmjs/cosmwasm-stargate@^0.32.3": - version "0.32.4" - resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.32.4.tgz#2ee93f2cc0b1c146ac369b2bf8ef9ee2e159fd50" - integrity sha512-Fuo9BGEiB+POJ5WeRyBGuhyKR1ordvxZGLPuPosFJOH9U0gKMgcjwKMCgAlWFkMlHaTB+tNdA8AifWiHrI7VgA== - dependencies: - "@cosmjs/amino" "^0.32.4" - "@cosmjs/crypto" "^0.32.4" - "@cosmjs/encoding" "^0.32.4" - "@cosmjs/math" "^0.32.4" - "@cosmjs/proto-signing" "^0.32.4" - "@cosmjs/stargate" "^0.32.4" - "@cosmjs/tendermint-rpc" "^0.32.4" - "@cosmjs/utils" "^0.32.4" - cosmjs-types "^0.9.0" - pako "^2.0.2" - -"@cosmjs/crypto@^0.32.4": - version "0.32.4" - resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.32.4.tgz#5d29633b661eaf092ddb3e7ea6299cfd6f4507a2" - integrity sha512-zicjGU051LF1V9v7bp8p7ovq+VyC91xlaHdsFOTo2oVry3KQikp8L/81RkXmUIT8FxMwdx1T7DmFwVQikcSDIw== - dependencies: - "@cosmjs/encoding" "^0.32.4" - "@cosmjs/math" "^0.32.4" - "@cosmjs/utils" "^0.32.4" - "@noble/hashes" "^1" - bn.js "^5.2.0" - elliptic "^6.5.4" - libsodium-wrappers-sumo "^0.7.11" - -"@cosmjs/encoding@^0.32.4": - version "0.32.4" - resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.32.4.tgz#646e0e809f7f4f1414d8fa991fb0ffe6c633aede" - integrity sha512-tjvaEy6ZGxJchiizzTn7HVRiyTg1i4CObRRaTRPknm5EalE13SV+TCHq38gIDfyUeden4fCuaBVEdBR5+ti7Hw== - dependencies: - base64-js "^1.3.0" - bech32 "^1.1.4" - readonly-date "^1.0.0" - -"@cosmjs/json-rpc@^0.32.4": - version "0.32.4" - resolved "https://registry.yarnpkg.com/@cosmjs/json-rpc/-/json-rpc-0.32.4.tgz#be91eb89ea78bd5dc02d0a9fa184dd6790790f0b" - integrity sha512-/jt4mBl7nYzfJ2J/VJ+r19c92mUKF0Lt0JxM3MXEJl7wlwW5haHAWtzRujHkyYMXOwIR+gBqT2S0vntXVBRyhQ== - dependencies: - "@cosmjs/stream" "^0.32.4" - xstream "^11.14.0" - -"@cosmjs/math@^0.32.4": - version "0.32.4" - resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.32.4.tgz#87ac9eadc06696e30a30bdb562a495974bfd0a1a" - integrity sha512-++dqq2TJkoB8zsPVYCvrt88oJWsy1vMOuSOKcdlnXuOA/ASheTJuYy4+oZlTQ3Fr8eALDLGGPhJI02W2HyAQaw== - dependencies: - bn.js "^5.2.0" - -"@cosmjs/proto-signing@^0.32.3", "@cosmjs/proto-signing@^0.32.4": - version "0.32.4" - resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.32.4.tgz#5a06e087c6d677439c8c9b25b5223d5e72c4cd93" - integrity sha512-QdyQDbezvdRI4xxSlyM1rSVBO2st5sqtbEIl3IX03uJ7YiZIQHyv6vaHVf1V4mapusCqguiHJzm4N4gsFdLBbQ== - dependencies: - "@cosmjs/amino" "^0.32.4" - "@cosmjs/crypto" "^0.32.4" - "@cosmjs/encoding" "^0.32.4" - "@cosmjs/math" "^0.32.4" - "@cosmjs/utils" "^0.32.4" - cosmjs-types "^0.9.0" - -"@cosmjs/socket@^0.32.4": - version "0.32.4" - resolved "https://registry.yarnpkg.com/@cosmjs/socket/-/socket-0.32.4.tgz#86ab6adf3a442314774c0810b7a7cfcddf4f2082" - integrity sha512-davcyYziBhkzfXQTu1l5NrpDYv0K9GekZCC9apBRvL1dvMc9F/ygM7iemHjUA+z8tJkxKxrt/YPjJ6XNHzLrkw== - dependencies: - "@cosmjs/stream" "^0.32.4" - isomorphic-ws "^4.0.1" - ws "^7" - xstream "^11.14.0" - -"@cosmjs/stargate@^0.32.3", "@cosmjs/stargate@^0.32.4": - version "0.32.4" - resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.32.4.tgz#bd0e4d3bf613b629addbf5f875d3d3b50f640af1" - integrity sha512-usj08LxBSsPRq9sbpCeVdyLx2guEcOHfJS9mHGCLCXpdAPEIEQEtWLDpEUc0LEhWOx6+k/ChXTc5NpFkdrtGUQ== - dependencies: - "@confio/ics23" "^0.6.8" - "@cosmjs/amino" "^0.32.4" - "@cosmjs/encoding" "^0.32.4" - "@cosmjs/math" "^0.32.4" - "@cosmjs/proto-signing" "^0.32.4" - "@cosmjs/stream" "^0.32.4" - "@cosmjs/tendermint-rpc" "^0.32.4" - "@cosmjs/utils" "^0.32.4" - cosmjs-types "^0.9.0" - xstream "^11.14.0" - -"@cosmjs/stream@^0.32.4": - version "0.32.4" - resolved "https://registry.yarnpkg.com/@cosmjs/stream/-/stream-0.32.4.tgz#83e1f2285807467c56d9ea0e1113f79d9fa63802" - integrity sha512-Gih++NYHEiP+oyD4jNEUxU9antoC0pFSg+33Hpp0JlHwH0wXhtD3OOKnzSfDB7OIoEbrzLJUpEjOgpCp5Z+W3A== - dependencies: - xstream "^11.14.0" - -"@cosmjs/tendermint-rpc@^0.32.4": - version "0.32.4" - resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.32.4.tgz#b36f9ec657498e42c97e21bb7368798ef6279752" - integrity sha512-MWvUUno+4bCb/LmlMIErLypXxy7ckUuzEmpufYYYd9wgbdCXaTaO08SZzyFM5PI8UJ/0S2AmUrgWhldlbxO8mw== - dependencies: - "@cosmjs/crypto" "^0.32.4" - "@cosmjs/encoding" "^0.32.4" - "@cosmjs/json-rpc" "^0.32.4" - "@cosmjs/math" "^0.32.4" - "@cosmjs/socket" "^0.32.4" - "@cosmjs/stream" "^0.32.4" - "@cosmjs/utils" "^0.32.4" - axios "^1.6.0" - readonly-date "^1.0.0" - xstream "^11.14.0" - -"@cosmjs/utils@^0.32.4": - version "0.32.4" - resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.32.4.tgz#a9a717c9fd7b1984d9cefdd0ef6c6f254060c671" - integrity sha512-D1Yc+Zy8oL/hkUkFUL/bwxvuDBzRGpc4cF7/SkdhxX4iHpSLgdOuTt1mhCh9+kl6NQREy9t7SYZ6xeW5gFe60w== - -"@cosmos-kit/core@^2.16.6": - version "2.16.6" - resolved "https://registry.yarnpkg.com/@cosmos-kit/core/-/core-2.16.6.tgz#329b502a37005eaee141bce5941b894e6a1f2d55" - integrity sha512-/mqCxzGE10/tJlDKzTVrpVIhM64llGDvifh6dHDneZFYdi8FKxhvzCIPXN7Blci4UfOtk0SVZvAQxN/ei+fqXg== - dependencies: - "@chain-registry/client" "^1.49.11" - "@chain-registry/keplr" "^1.69.13" - "@chain-registry/types" "^0.46.11" - "@cosmjs/amino" "^0.32.3" - "@cosmjs/cosmwasm-stargate" "^0.32.3" - "@cosmjs/proto-signing" "^0.32.3" - "@cosmjs/stargate" "^0.32.3" - "@dao-dao/cosmiframe" "^1.0.0" - "@walletconnect/types" "2.11.0" - bowser "2.11.0" - cosmjs-types "^0.9.0" - events "3.3.0" - nock "13.5.4" - uuid "^9.0.1" - -"@cosmos-kit/keplr-extension@^2.14.0": - version "2.15.7" - resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-extension/-/keplr-extension-2.15.7.tgz#3d8058d29615492be687567999a0a7f9bbd0f55e" - integrity sha512-0PvrXelwWG4GTEuVTcRX/RT2TaQRGlY3H4LNpQrjIg4UgDuKA6zphw5bDq6/OsdsAbbdWSq1/MUYoc7TQjcf+A== - dependencies: - "@chain-registry/keplr" "^1.69.13" - "@cosmos-kit/core" "^2.16.6" - "@keplr-wallet/provider-extension" "^0.12.95" - "@keplr-wallet/types" "^0.12.95" - -"@cosmos-kit/react-lite@^2.16.6": - version "2.16.6" - resolved "https://registry.yarnpkg.com/@cosmos-kit/react-lite/-/react-lite-2.16.6.tgz#ec89b00aa69e672a5592fc38b6b0a609fa368cbf" - integrity sha512-2B8fsYGmO1ZM1mBC2pQtSe/7gTxnoG55VePZ7ZeK0vAc19gjk0RQyMW5FhvLiMhikwUdTZzXopNHAx/XuQo5Vw== - dependencies: - "@chain-registry/types" "^0.46.11" - "@cosmos-kit/core" "^2.16.6" - "@dao-dao/cosmiframe" "^1.0.0" - -"@cosmos-kit/react@^2.20.1": - version "2.22.6" - resolved "https://registry.yarnpkg.com/@cosmos-kit/react/-/react-2.22.6.tgz#23afc83cd1a46afcb4635d1b2d920abea03b06b9" - integrity sha512-FdhGRempqw+/VKi7vxZAqwRsHlCWzBkSksgjNnay3swmHB6t6PY7b+pLlvIDmb9Br5A7JxthE4wthTRr87zEFw== - dependencies: - "@chain-registry/types" "^0.46.11" - "@cosmos-kit/core" "^2.16.6" - "@cosmos-kit/react-lite" "^2.16.6" - "@react-icons/all-files" "^4.1.0" - -"@csstools/color-helpers@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@csstools/color-helpers/-/color-helpers-5.1.0.tgz#106c54c808cabfd1ab4c602d8505ee584c2996ef" - integrity sha512-S11EXWJyy0Mz5SYvRmY8nJYTFFd1LCNV+7cXyAgQtOOuzb4EsgfqDufL+9esx72/eLhsRdGZwaldu/h+E4t4BA== - -"@csstools/css-calc@^2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@csstools/css-calc/-/css-calc-2.1.4.tgz#8473f63e2fcd6e459838dd412401d5948f224c65" - integrity sha512-3N8oaj+0juUw/1H3YwmDDJXCgTB1gKU6Hc/bB502u9zR0q2vd786XJH9QfrKIEgFlZmhZiq6epXl4rHqhzsIgQ== - -"@csstools/css-color-parser@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@csstools/css-color-parser/-/css-color-parser-3.1.0.tgz#4e386af3a99dd36c46fef013cfe4c1c341eed6f0" - integrity sha512-nbtKwh3a6xNVIp/VRuXV64yTKnb1IjTAEEh3irzS+HkKjAOYLTGNb9pmVNntZ8iVBHcWDA2Dof0QtPgFI1BaTA== - dependencies: - "@csstools/color-helpers" "^5.1.0" - "@csstools/css-calc" "^2.1.4" - -"@csstools/css-parser-algorithms@^3.0.5": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-3.0.5.tgz#5755370a9a29abaec5515b43c8b3f2cf9c2e3076" - integrity sha512-DaDeUkXZKjdGhgYaHNJTV9pV7Y9B3b644jCLs9Upc3VeNGg6LWARAT6O+Q+/COo+2gg/bM5rhpMAtf70WqfBdQ== - -"@csstools/css-syntax-patches-for-csstree@^1.0.14": - version "1.0.14" - resolved "https://registry.yarnpkg.com/@csstools/css-syntax-patches-for-csstree/-/css-syntax-patches-for-csstree-1.0.14.tgz#96e8bd829dea29da6460ac7568ee922f48ecc382" - integrity sha512-zSlIxa20WvMojjpCSy8WrNpcZ61RqfTfX3XTaOeVlGJrt/8HF3YbzgFZa01yTbT4GWQLwfTcC3EB8i3XnB647Q== - -"@csstools/css-tokenizer@^3.0.4": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@csstools/css-tokenizer/-/css-tokenizer-3.0.4.tgz#333fedabc3fd1a8e5d0100013731cf19e6a8c5d3" - integrity sha512-Vd/9EVDiu6PPJt9yAh6roZP6El1xHrdvIVGjyBsHR0RYwNHgL7FJPyIIW4fANJNG6FtyZfvlRPpFI4ZM/lubvw== - -"@dao-dao/cosmiframe@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@dao-dao/cosmiframe/-/cosmiframe-1.0.0.tgz#c780a2c3f14560ccd0f178616567328ca0bc9fcf" - integrity sha512-xPaD9MV1tUueYl+VIJD7CEi4+MCdcgo4E1R9w8XplKlM7pvmBaSBeTz88HwITpKxWKI+DWoJngeCWu5/8oqLJQ== - dependencies: - uuid "^9.0.1" - -"@design-systems/utils@2.12.0": - version "2.12.0" - resolved "https://registry.yarnpkg.com/@design-systems/utils/-/utils-2.12.0.tgz#955c108be07cb8f01532207cbfea8f848fa760c9" - integrity sha512-Y/d2Zzr+JJfN6u1gbuBUb1ufBuLMJJRZQk+dRmw8GaTpqKx5uf7cGUYGTwN02dIb3I+Tf+cW8jcGBTRiFxdYFg== - dependencies: - "@babel/runtime" "^7.11.2" - clsx "^1.0.4" - focus-lock "^0.8.0" - react-merge-refs "^1.0.0" - -"@devtools-ds/object-inspector@^1.1.2": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@devtools-ds/object-inspector/-/object-inspector-1.2.1.tgz#2b380ed475d898d2828e7855c2dc2c82f091d326" - integrity sha512-nrAVVj4c4Iv9958oE4HA7Mk6T+4Mn/4xBRlFDeX4Ps6SMzsqO8bKhw/y6+bOfNyb/TYHmC0/pnPS68GDVZcg5Q== - dependencies: - "@babel/runtime" "7.7.2" - "@devtools-ds/object-parser" "^1.2.1" - "@devtools-ds/themes" "^1.2.1" - "@devtools-ds/tree" "^1.2.1" - clsx "1.1.0" - -"@devtools-ds/object-parser@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@devtools-ds/object-parser/-/object-parser-1.2.1.tgz#5ab709a2db807ce99cb12bf35511379d6e47a3b8" - integrity sha512-6qB+THhQfJqXyHn8wpJ1KFxXcbpLTlRyCVmkelhr0c1+MPLZcC+0XJxpVZ1AOEXPa6CWVZThBYSCvnYQEvfCqw== - dependencies: - "@babel/runtime" "~7.5.4" - -"@devtools-ds/themes@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@devtools-ds/themes/-/themes-1.2.1.tgz#060a0a1a2b38f68b01deca62240d2c94585f00dd" - integrity sha512-4/KFsHnokGxUq8CSCchINcVBb6fQ74HtEfNtMuitGtGg3VCRV0kaVSOsz6wzShzhLEaVLd5coSRQKaZj7yx72w== - dependencies: - "@babel/runtime" "~7.5.4" - "@design-systems/utils" "2.12.0" - clsx "1.1.0" - -"@devtools-ds/tree@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@devtools-ds/tree/-/tree-1.2.1.tgz#88d44dbbf96101fd8f18af92e514ed9dd00c8ceb" - integrity sha512-2ZHG28oWJno0gD+20EoSJO0yffm6JS5r7YzYhGMkrnLGvcCRZuwXSxMmIshSPLIR0cjidiAfGCqsrigHIR4ZQA== - dependencies: - "@babel/runtime" "7.7.2" - "@devtools-ds/themes" "^1.2.1" - clsx "1.1.0" - -"@discoveryjs/json-ext@^0.5.0", "@discoveryjs/json-ext@^0.5.3": - version "0.5.7" - resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" - integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== - -"@emnapi/core@^1.4.3": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@emnapi/core/-/core-1.6.0.tgz#517f65d1c8270d5d5aa1aad660d5acb897430dca" - integrity sha512-zq/ay+9fNIJJtJiZxdTnXS20PllcYMX3OE23ESc4HK/bdYu3cOWYVhsOhVnXALfU/uqJIxn5NBPd9z4v+SfoSg== - dependencies: - "@emnapi/wasi-threads" "1.1.0" - tslib "^2.4.0" - -"@emnapi/runtime@^1.2.0", "@emnapi/runtime@^1.4.3": - version "1.6.0" - resolved "https://registry.yarnpkg.com/@emnapi/runtime/-/runtime-1.6.0.tgz#8fe297e0090f6e89a57a1f31f1c440bdbc3c01d8" - integrity sha512-obtUmAHTMjll499P+D9A3axeJFlhdjOWdKUNs/U6QIGT7V5RjcUW1xToAzjvmgTSQhDbYn/NwfTRoJcQ2rNBxA== - dependencies: - tslib "^2.4.0" - -"@emnapi/wasi-threads@1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz#60b2102fddc9ccb78607e4a3cf8403ea69be41bf" - integrity sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ== - dependencies: - tslib "^2.4.0" - -"@emotion/babel-plugin@^11.13.5": - version "11.13.5" - resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz#eab8d65dbded74e0ecfd28dc218e75607c4e7bc0" - integrity sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ== - dependencies: - "@babel/helper-module-imports" "^7.16.7" - "@babel/runtime" "^7.18.3" - "@emotion/hash" "^0.9.2" - "@emotion/memoize" "^0.9.0" - "@emotion/serialize" "^1.3.3" - babel-plugin-macros "^3.1.0" - convert-source-map "^1.5.0" - escape-string-regexp "^4.0.0" - find-root "^1.1.0" - source-map "^0.5.7" - stylis "4.2.0" - -"@emotion/cache@^11.13.5", "@emotion/cache@^11.14.0": - version "11.14.0" - resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.14.0.tgz#ee44b26986eeb93c8be82bb92f1f7a9b21b2ed76" - integrity sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA== - dependencies: - "@emotion/memoize" "^0.9.0" - "@emotion/sheet" "^1.4.0" - "@emotion/utils" "^1.4.2" - "@emotion/weak-memoize" "^0.4.0" - stylis "4.2.0" - -"@emotion/hash@^0.9.0", "@emotion/hash@^0.9.1", "@emotion/hash@^0.9.2": - version "0.9.2" - resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.2.tgz#ff9221b9f58b4dfe61e619a7788734bd63f6898b" - integrity sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g== - -"@emotion/is-prop-valid@^1.3.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.4.0.tgz#e9ad47adff0b5c94c72db3669ce46de33edf28c0" - integrity sha512-QgD4fyscGcbbKwJmqNvUMSE02OsHUa+lAWKdEUIJKgqe5IwRSKd7+KhibEWdaKwgjLj0DRSHA9biAIqGBk05lw== - dependencies: - "@emotion/memoize" "^0.9.0" - -"@emotion/memoize@^0.9.0": - version "0.9.0" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.9.0.tgz#745969d649977776b43fc7648c556aaa462b4102" - integrity sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ== - -"@emotion/react@^11.13.5", "@emotion/react@^11.7.0": - version "11.14.0" - resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.14.0.tgz#cfaae35ebc67dd9ef4ea2e9acc6cd29e157dd05d" - integrity sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA== - dependencies: - "@babel/runtime" "^7.18.3" - "@emotion/babel-plugin" "^11.13.5" - "@emotion/cache" "^11.14.0" - "@emotion/serialize" "^1.3.3" - "@emotion/use-insertion-effect-with-fallbacks" "^1.2.0" - "@emotion/utils" "^1.4.2" - "@emotion/weak-memoize" "^0.4.0" - hoist-non-react-statics "^3.3.1" - -"@emotion/serialize@^1.3.3": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.3.3.tgz#d291531005f17d704d0463a032fe679f376509e8" - integrity sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA== - dependencies: - "@emotion/hash" "^0.9.2" - "@emotion/memoize" "^0.9.0" - "@emotion/unitless" "^0.10.0" - "@emotion/utils" "^1.4.2" - csstype "^3.0.2" - -"@emotion/sheet@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.4.0.tgz#c9299c34d248bc26e82563735f78953d2efca83c" - integrity sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg== - -"@emotion/styled@^11.13.5", "@emotion/styled@^11.6.0": - version "11.14.1" - resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.14.1.tgz#8c34bed2948e83e1980370305614c20955aacd1c" - integrity sha512-qEEJt42DuToa3gurlH4Qqc1kVpNq8wO8cJtDzU46TjlzWjDlsVyevtYCRijVq3SrHsROS+gVQ8Fnea108GnKzw== - dependencies: - "@babel/runtime" "^7.18.3" - "@emotion/babel-plugin" "^11.13.5" - "@emotion/is-prop-valid" "^1.3.0" - "@emotion/serialize" "^1.3.3" - "@emotion/use-insertion-effect-with-fallbacks" "^1.2.0" - "@emotion/utils" "^1.4.2" - -"@emotion/unitless@^0.10.0": - version "0.10.0" - resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.10.0.tgz#2af2f7c7e5150f497bdabd848ce7b218a27cf745" - integrity sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg== - -"@emotion/use-insertion-effect-with-fallbacks@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz#8a8cb77b590e09affb960f4ff1e9a89e532738bf" - integrity sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg== - -"@emotion/utils@^1.4.2": - version "1.4.2" - resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.4.2.tgz#6df6c45881fcb1c412d6688a311a98b7f59c1b52" - integrity sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA== - -"@emotion/weak-memoize@^0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz#5e13fac887f08c44f76b0ccaf3370eb00fec9bb6" - integrity sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg== - -"@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.8.0", "@eslint-community/eslint-utils@^4.9.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz#4e90af67bc51ddee6cdef5284edf572ec376b595" - integrity sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ== - dependencies: - eslint-visitor-keys "^3.4.3" - -"@eslint-community/regexpp@^4.12.1", "@eslint-community/regexpp@^4.12.2", "@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1": - version "4.12.2" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz#bccdf615bcf7b6e8db830ec0b8d21c9a25de597b" - integrity sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew== - -"@eslint/config-array@^0.21.2": - version "0.21.2" - resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.21.2.tgz#f29e22057ad5316cf23836cee9a34c81fffcb7e6" - integrity sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw== - dependencies: - "@eslint/object-schema" "^2.1.7" - debug "^4.3.1" - minimatch "^3.1.5" - -"@eslint/config-helpers@^0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@eslint/config-helpers/-/config-helpers-0.4.2.tgz#1bd006ceeb7e2e55b2b773ab318d300e1a66aeda" - integrity sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw== - dependencies: - "@eslint/core" "^0.17.0" - -"@eslint/core@^0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.17.0.tgz#77225820413d9617509da9342190a2019e78761c" - integrity sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ== - dependencies: - "@types/json-schema" "^7.0.15" - -"@eslint/eslintrc@^2.1.4": - version "2.1.4" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" - integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.6.0" - globals "^13.19.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - -"@eslint/eslintrc@^3.3.5": - version "3.3.5" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.3.5.tgz#c131793cfc1a7b96f24a83e0a8bbd4b881558c60" - integrity sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg== - dependencies: - 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.1" - minimatch "^3.1.5" - strip-json-comments "^3.1.1" - -"@eslint/js@8.57.1": - version "8.57.1" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.1.tgz#de633db3ec2ef6a3c89e2f19038063e8a122e2c2" - integrity sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q== - -"@eslint/js@9.39.4": - version "9.39.4" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.39.4.tgz#a3f83bfc6fd9bf33a853dfacd0b49b398eb596c1" - integrity sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw== - -"@eslint/object-schema@^2.1.7": - version "2.1.7" - resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.7.tgz#6e2126a1347e86a4dedf8706ec67ff8e107ebbad" - integrity sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA== - -"@eslint/plugin-kit@^0.4.1": - version "0.4.1" - resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz#9779e3fd9b7ee33571a57435cf4335a1794a6cb2" - integrity sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA== - dependencies: - "@eslint/core" "^0.17.0" - levn "^0.4.1" - -"@ethersproject/address@^5.6.0": - version "5.8.0" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.8.0.tgz#3007a2c352eee566ad745dca1dbbebdb50a6a983" - integrity sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA== - dependencies: - "@ethersproject/bignumber" "^5.8.0" - "@ethersproject/bytes" "^5.8.0" - "@ethersproject/keccak256" "^5.8.0" - "@ethersproject/logger" "^5.8.0" - "@ethersproject/rlp" "^5.8.0" - -"@ethersproject/bignumber@^5.8.0": - version "5.8.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.8.0.tgz#c381d178f9eeb370923d389284efa19f69efa5d7" - integrity sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA== - dependencies: - "@ethersproject/bytes" "^5.8.0" - "@ethersproject/logger" "^5.8.0" - bn.js "^5.2.1" - -"@ethersproject/bytes@^5.8.0": - version "5.8.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.8.0.tgz#9074820e1cac7507a34372cadeb035461463be34" - integrity sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A== - dependencies: - "@ethersproject/logger" "^5.8.0" - -"@ethersproject/keccak256@^5.5.0", "@ethersproject/keccak256@^5.8.0": - version "5.8.0" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.8.0.tgz#d2123a379567faf2d75d2aaea074ffd4df349e6a" - integrity sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng== - dependencies: - "@ethersproject/bytes" "^5.8.0" - js-sha3 "0.8.0" - -"@ethersproject/logger@^5.8.0": - version "5.8.0" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.8.0.tgz#f0232968a4f87d29623a0481690a2732662713d6" - integrity sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA== - -"@ethersproject/rlp@^5.8.0": - version "5.8.0" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.8.0.tgz#5a0d49f61bc53e051532a5179472779141451de5" - integrity sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q== - dependencies: - "@ethersproject/bytes" "^5.8.0" - "@ethersproject/logger" "^5.8.0" - -"@floating-ui/core@^1.6.7", "@floating-ui/core@^1.7.3": - version "1.7.3" - resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.7.3.tgz#462d722f001e23e46d86fd2bd0d21b7693ccb8b7" - integrity sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w== - dependencies: - "@floating-ui/utils" "^0.2.10" - -"@floating-ui/dom@^1.6.10", "@floating-ui/dom@^1.7.4": - version "1.7.4" - resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.7.4.tgz#ee667549998745c9c3e3e84683b909c31d6c9a77" - integrity sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA== - dependencies: - "@floating-ui/core" "^1.7.3" - "@floating-ui/utils" "^0.2.10" - -"@floating-ui/react-dom@^2.0.8", "@floating-ui/react-dom@^2.1.1", "@floating-ui/react-dom@^2.1.2": - version "2.1.6" - resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.1.6.tgz#189f681043c1400561f62972f461b93f01bf2231" - integrity sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw== - dependencies: - "@floating-ui/dom" "^1.7.4" - -"@floating-ui/react@^0.26.23": - version "0.26.28" - resolved "https://registry.yarnpkg.com/@floating-ui/react/-/react-0.26.28.tgz#93f44ebaeb02409312e9df9507e83aab4a8c0dc7" - integrity sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw== - dependencies: - "@floating-ui/react-dom" "^2.1.2" - "@floating-ui/utils" "^0.2.8" - tabbable "^6.0.0" - -"@floating-ui/utils@^0.2.10", "@floating-ui/utils@^0.2.7", "@floating-ui/utils@^0.2.8": - version "0.2.10" - resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.10.tgz#a2a1e3812d14525f725d011a73eceb41fef5bc1c" - integrity sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ== - -"@formatjs/ecma402-abstract@2.3.6": - version "2.3.6" - resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.6.tgz#d6ca9d3579054fe1e1a0a0b5e872e0d64922e4e1" - integrity sha512-HJnTFeRM2kVFVr5gr5kH1XP6K0JcJtE7Lzvtr3FS/so5f1kpsqqqxy5JF+FRaO6H2qmcMfAUIox7AJteieRtVw== - dependencies: - "@formatjs/fast-memoize" "2.2.7" - "@formatjs/intl-localematcher" "0.6.2" - decimal.js "^10.4.3" - tslib "^2.8.0" - -"@formatjs/fast-memoize@2.2.7": - version "2.2.7" - resolved "https://registry.yarnpkg.com/@formatjs/fast-memoize/-/fast-memoize-2.2.7.tgz#707f9ddaeb522a32f6715bb7950b0831f4cc7b15" - integrity sha512-Yabmi9nSvyOMrlSeGGWDiH7rf3a7sIwplbvo/dlz9WCIjzIQAfy1RMf4S0X3yG724n5Ghu2GmEl5NJIV6O9sZQ== - dependencies: - tslib "^2.8.0" - -"@formatjs/icu-messageformat-parser@2.11.4": - version "2.11.4" - resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.11.4.tgz#63bd2cd82d08ae2bef55adeeb86486df68826f32" - integrity sha512-7kR78cRrPNB4fjGFZg3Rmj5aah8rQj9KPzuLsmcSn4ipLXQvC04keycTI1F7kJYDwIXtT2+7IDEto842CfZBtw== - dependencies: - "@formatjs/ecma402-abstract" "2.3.6" - "@formatjs/icu-skeleton-parser" "1.8.16" - tslib "^2.8.0" - -"@formatjs/icu-skeleton-parser@1.8.16": - version "1.8.16" - resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.16.tgz#13f81f6845c7cf6599623006aacaf7d6b4ad2970" - integrity sha512-H13E9Xl+PxBd8D5/6TVUluSpxGNvFSlN/b3coUp0e0JpuWXXnQDiavIpY3NnvSp4xhEMoXyyBvVfdFX8jglOHQ== - dependencies: - "@formatjs/ecma402-abstract" "2.3.6" - tslib "^2.8.0" - -"@formatjs/intl-localematcher@0.6.2": - version "0.6.2" - resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.6.2.tgz#e9ebe0b4082d7d48e5b2d753579fb7ece4eaefea" - integrity sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA== - dependencies: - tslib "^2.8.0" - -"@formkit/auto-animate@^0.8.2": - version "0.8.4" - resolved "https://registry.yarnpkg.com/@formkit/auto-animate/-/auto-animate-0.8.4.tgz#2c857102bbf612c0e7bd4a0aac0e05a7f0efd8e7" - integrity sha512-DHHC01EJ1p70Q0z/ZFRBIY8NDnmfKccQoyoM84Tgb6omLMat6jivCdf272Y8k3nf4Lzdin/Y4R9q8uFtU0GbnA== - -"@gar/promisify@^1.0.1", "@gar/promisify@^1.1.3": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" - integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== - -"@hapi/hoek@^9.0.0", "@hapi/hoek@^9.3.0": - version "9.3.0" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" - integrity sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ== - -"@hapi/topo@^5.1.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012" - integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg== - dependencies: - "@hapi/hoek" "^9.0.0" - -"@hookform/resolvers@^2.8.0": - version "2.9.11" - resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-2.9.11.tgz#9ce96e7746625a89239f68ca57c4f654264c17ef" - integrity sha512-bA3aZ79UgcHj7tFV7RlgThzwSSHZgvfbt2wprldRkYBcMopdMvHyO17Wwp/twcJasNFischFfS7oz8Katz8DdQ== - -"@humanfs/core@^0.19.2": - version "0.19.2" - resolved "https://registry.yarnpkg.com/@humanfs/core/-/core-0.19.2.tgz#a8272ca03b2acf492670222b2320b6c421bfde60" - integrity sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA== - dependencies: - "@humanfs/types" "^0.15.0" - -"@humanfs/node@^0.16.6": - version "0.16.8" - resolved "https://registry.yarnpkg.com/@humanfs/node/-/node-0.16.8.tgz#8f800cccc13f4f8cd3116e2d9c0a94939da3e3ed" - integrity sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ== - dependencies: - "@humanfs/core" "^0.19.2" - "@humanfs/types" "^0.15.0" - "@humanwhocodes/retry" "^0.4.0" - -"@humanfs/types@^0.15.0": - version "0.15.0" - resolved "https://registry.yarnpkg.com/@humanfs/types/-/types-0.15.0.tgz#f2a09f62012390b2bff3fc6fb248ddec8c09a090" - integrity sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q== - -"@humanwhocodes/config-array@^0.13.0": - version "0.13.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz#fb907624df3256d04b9aa2df50d7aa97ec648748" - integrity sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw== - dependencies: - "@humanwhocodes/object-schema" "^2.0.3" - debug "^4.3.1" - minimatch "^3.0.5" - -"@humanwhocodes/module-importer@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" - integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== - -"@humanwhocodes/object-schema@^2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" - integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== - -"@humanwhocodes/retry@^0.4.0", "@humanwhocodes/retry@^0.4.2": - version "0.4.3" - resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.3.tgz#c2b9d2e374ee62c586d3adbea87199b1d7a7a6ba" - integrity sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ== - -"@hutson/parse-repository-url@^3.0.0": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340" - integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q== - -"@img/sharp-darwin-arm64@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz#ef5b5a07862805f1e8145a377c8ba6e98813ca08" - integrity sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ== - optionalDependencies: - "@img/sharp-libvips-darwin-arm64" "1.0.4" - -"@img/sharp-darwin-x64@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz#e03d3451cd9e664faa72948cc70a403ea4063d61" - integrity sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q== - optionalDependencies: - "@img/sharp-libvips-darwin-x64" "1.0.4" - -"@img/sharp-libvips-darwin-arm64@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz#447c5026700c01a993c7804eb8af5f6e9868c07f" - integrity sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg== - -"@img/sharp-libvips-darwin-x64@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz#e0456f8f7c623f9dbfbdc77383caa72281d86062" - integrity sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ== - -"@img/sharp-libvips-linux-arm64@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz#979b1c66c9a91f7ff2893556ef267f90ebe51704" - integrity sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA== - -"@img/sharp-libvips-linux-arm@1.0.5": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz#99f922d4e15216ec205dcb6891b721bfd2884197" - integrity sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g== - -"@img/sharp-libvips-linux-s390x@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz#f8a5eb1f374a082f72b3f45e2fb25b8118a8a5ce" - integrity sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA== - -"@img/sharp-libvips-linux-x64@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz#d4c4619cdd157774906e15770ee119931c7ef5e0" - integrity sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw== - -"@img/sharp-libvips-linuxmusl-arm64@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz#166778da0f48dd2bded1fa3033cee6b588f0d5d5" - integrity sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA== - -"@img/sharp-libvips-linuxmusl-x64@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz#93794e4d7720b077fcad3e02982f2f1c246751ff" - integrity sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw== - -"@img/sharp-linux-arm64@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz#edb0697e7a8279c9fc829a60fc35644c4839bb22" - integrity sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA== - optionalDependencies: - "@img/sharp-libvips-linux-arm64" "1.0.4" - -"@img/sharp-linux-arm@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz#422c1a352e7b5832842577dc51602bcd5b6f5eff" - integrity sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ== - optionalDependencies: - "@img/sharp-libvips-linux-arm" "1.0.5" - -"@img/sharp-linux-s390x@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz#f5c077926b48e97e4a04d004dfaf175972059667" - integrity sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q== - optionalDependencies: - "@img/sharp-libvips-linux-s390x" "1.0.4" - -"@img/sharp-linux-x64@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz#d806e0afd71ae6775cc87f0da8f2d03a7c2209cb" - integrity sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA== - optionalDependencies: - "@img/sharp-libvips-linux-x64" "1.0.4" - -"@img/sharp-linuxmusl-arm64@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz#252975b915894fb315af5deea174651e208d3d6b" - integrity sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g== - optionalDependencies: - "@img/sharp-libvips-linuxmusl-arm64" "1.0.4" - -"@img/sharp-linuxmusl-x64@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz#3f4609ac5d8ef8ec7dadee80b560961a60fd4f48" - integrity sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw== - optionalDependencies: - "@img/sharp-libvips-linuxmusl-x64" "1.0.4" - -"@img/sharp-wasm32@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz#6f44f3283069d935bb5ca5813153572f3e6f61a1" - integrity sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg== - dependencies: - "@emnapi/runtime" "^1.2.0" - -"@img/sharp-win32-ia32@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz#1a0c839a40c5351e9885628c85f2e5dfd02b52a9" - integrity sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ== - -"@img/sharp-win32-x64@0.33.5": - version "0.33.5" - resolved "https://registry.yarnpkg.com/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz#56f00962ff0c4e0eb93d34a047d29fa995e3e342" - integrity sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg== - -"@inquirer/external-editor@^1.0.0": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@inquirer/external-editor/-/external-editor-1.0.2.tgz#dc16e7064c46c53be09918db639ff780718c071a" - integrity sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ== - dependencies: - chardet "^2.1.0" - iconv-lite "^0.7.0" - -"@interchain-ui/react@^1.26.1": - version "1.26.3" - resolved "https://registry.yarnpkg.com/@interchain-ui/react/-/react-1.26.3.tgz#71c18d95a43eb57b2b3b2ecc256a24e4edc73cd9" - integrity sha512-kvGOZaSDJLNxtxieiyPMHOzxBGkpHR/BCpg/UEMDl2l7nLoPrygB/Oux1QEv/cwkw8GvepOBM7pzfJf8xk1IbQ== - dependencies: - "@floating-ui/core" "^1.6.7" - "@floating-ui/dom" "^1.6.10" - "@floating-ui/react" "^0.26.23" - "@floating-ui/react-dom" "^2.1.1" - "@floating-ui/utils" "^0.2.7" - "@formkit/auto-animate" "^0.8.2" - "@react-aria/listbox" "^3.13.3" - "@react-aria/overlays" "^3.23.2" - "@react-aria/utils" "^3.25.2" - "@tanstack/react-virtual" "^3.10.5" - "@vanilla-extract/css" "^1.15.5" - "@vanilla-extract/css-utils" "^0.1.4" - "@vanilla-extract/dynamic" "^2.1.2" - "@vanilla-extract/private" "^1.0.6" - "@vanilla-extract/recipes" "^0.5.5" - animejs "^3.2.2" - bignumber.js "^9.1.2" - client-only "^0.0.1" - clsx "^2.1.1" - copy-to-clipboard "^3.3.3" - immer "^10.1.1" - lodash "^4.17.21" - rainbow-sprinkles "^0.17.3" - react-aria "^3.34.3" - react-stately "^3.32.2" - zustand "^4.5.5" - -"@internationalized/date@^3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@internationalized/date/-/date-3.10.0.tgz#056db64a4facdf48c6937ad498a882a8151d640a" - integrity sha512-oxDR/NTEJ1k+UFVQElaNIk65E/Z83HK1z1WI3lQyhTtnNg4R5oVXaPzK3jcpKG8UHKDVuDQHzn+wsxSz8RP3aw== - dependencies: - "@swc/helpers" "^0.5.0" - -"@internationalized/message@^3.1.8": - version "3.1.8" - resolved "https://registry.yarnpkg.com/@internationalized/message/-/message-3.1.8.tgz#7181e8178f0868535f4507a573bf285e925832cb" - integrity sha512-Rwk3j/TlYZhn3HQ6PyXUV0XP9Uv42jqZGNegt0BXlxjE6G3+LwHjbQZAGHhCnCPdaA6Tvd3ma/7QzLlLkJxAWA== - dependencies: - "@swc/helpers" "^0.5.0" - intl-messageformat "^10.1.0" - -"@internationalized/number@^3.6.5": - version "3.6.5" - resolved "https://registry.yarnpkg.com/@internationalized/number/-/number-3.6.5.tgz#1103f2832ca8d9dd3e4eecf95733d497791dbbbe" - integrity sha512-6hY4Kl4HPBvtfS62asS/R22JzNNy8vi/Ssev7x6EobfCp+9QIB2hKvI2EtbdJ0VSQacxVNtqhE/NmF/NZ0gm6g== - dependencies: - "@swc/helpers" "^0.5.0" - -"@internationalized/string@^3.2.7": - version "3.2.7" - resolved "https://registry.yarnpkg.com/@internationalized/string/-/string-3.2.7.tgz#76ae10f1e6e1fdaec7d0028a3f807d37a71bd2dd" - integrity sha512-D4OHBjrinH+PFZPvfCXvG28n2LSykWcJ7GIioQL+ok0LON15SdfoUssoHzzOUmVZLbRoREsQXVzA6r8JKsbP6A== - dependencies: - "@swc/helpers" "^0.5.0" - -"@isaacs/balanced-match@^4.0.1": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz#3081dadbc3460661b751e7591d7faea5df39dd29" - integrity sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ== - -"@isaacs/brace-expansion@^5.0.0": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@isaacs/brace-expansion/-/brace-expansion-5.0.1.tgz#0ef5a92d91f2fff2a37646ce54da9e5f599f6eff" - integrity sha512-WMz71T1JS624nWj2n2fnYAuPovhv7EUhk69R6i9dsVyzxt5eM3bjwvgk9L+APE1TRscGysAVMANkB0jh0LQZrQ== - dependencies: - "@isaacs/balanced-match" "^4.0.1" - -"@isaacs/cliui@^8.0.2": - version "8.0.2" - resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" - integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== - dependencies: - string-width "^5.1.2" - string-width-cjs "npm:string-width@^4.2.0" - strip-ansi "^7.0.1" - strip-ansi-cjs "npm:strip-ansi@^6.0.1" - wrap-ansi "^8.1.0" - wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" - -"@istanbuljs/load-nyc-config@^1.0.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" - integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== - dependencies: - camelcase "^5.3.1" - find-up "^4.1.0" - get-package-type "^0.1.0" - js-yaml "^3.13.1" - resolve-from "^5.0.0" - -"@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" - integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== - -"@jest/console@30.3.0": - version "30.3.0" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-30.3.0.tgz#42ccc3f995d400a8fe35b8850cfe10a8d4804cdf" - integrity sha512-PAwCvFJ4696XP2qZj+LAn1BWjZaJ6RjG6c7/lkMaUJnkyMS34ucuIsfqYvfskVNvUI27R/u4P1HMYFnlVXG/Ww== - dependencies: - "@jest/types" "30.3.0" - "@types/node" "*" - chalk "^4.1.2" - jest-message-util "30.3.0" - jest-util "30.3.0" - slash "^3.0.0" - -"@jest/console@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.5.1.tgz#260fe7239602fe5130a94f1aa386eff54b014bba" - integrity sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg== - dependencies: - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - jest-message-util "^27.5.1" - jest-util "^27.5.1" - slash "^3.0.0" - -"@jest/core@30.3.0": - version "30.3.0" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-30.3.0.tgz#d06bb8456f35350f6494fd2405bcec4abb97b994" - integrity sha512-U5mVPsBxLSO6xYbf+tgkymLx+iAhvZX43/xI1+ej2ZOPnPdkdO1CzDmFKh2mZBn2s4XZixszHeQnzp1gm/DIxw== - dependencies: - "@jest/console" "30.3.0" - "@jest/pattern" "30.0.1" - "@jest/reporters" "30.3.0" - "@jest/test-result" "30.3.0" - "@jest/transform" "30.3.0" - "@jest/types" "30.3.0" - "@types/node" "*" - ansi-escapes "^4.3.2" - chalk "^4.1.2" - ci-info "^4.2.0" - exit-x "^0.2.2" - graceful-fs "^4.2.11" - jest-changed-files "30.3.0" - jest-config "30.3.0" - jest-haste-map "30.3.0" - jest-message-util "30.3.0" - jest-regex-util "30.0.1" - jest-resolve "30.3.0" - jest-resolve-dependencies "30.3.0" - jest-runner "30.3.0" - jest-runtime "30.3.0" - jest-snapshot "30.3.0" - jest-util "30.3.0" - jest-validate "30.3.0" - jest-watcher "30.3.0" - pretty-format "30.3.0" - slash "^3.0.0" - -"@jest/core@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.5.1.tgz#267ac5f704e09dc52de2922cbf3af9edcd64b626" - integrity sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ== - dependencies: - "@jest/console" "^27.5.1" - "@jest/reporters" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - emittery "^0.8.1" - exit "^0.1.2" - graceful-fs "^4.2.9" - jest-changed-files "^27.5.1" - jest-config "^27.5.1" - jest-haste-map "^27.5.1" - jest-message-util "^27.5.1" - jest-regex-util "^27.5.1" - jest-resolve "^27.5.1" - jest-resolve-dependencies "^27.5.1" - jest-runner "^27.5.1" - jest-runtime "^27.5.1" - jest-snapshot "^27.5.1" - jest-util "^27.5.1" - jest-validate "^27.5.1" - jest-watcher "^27.5.1" - micromatch "^4.0.4" - rimraf "^3.0.0" - slash "^3.0.0" - strip-ansi "^6.0.0" - -"@jest/diff-sequences@30.3.0": - version "30.3.0" - resolved "https://registry.yarnpkg.com/@jest/diff-sequences/-/diff-sequences-30.3.0.tgz#25b0818d3d83f00b9c7b04e069b8810f9014b143" - integrity sha512-cG51MVnLq1ecVUaQ3fr6YuuAOitHK1S4WUJHnsPFE/quQr33ADUx1FfrTCpMCRxvy0Yr9BThKpDjSlcTi91tMA== - -"@jest/environment@30.3.0": - version "30.3.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-30.3.0.tgz#b0657c2944b6ef3352f7b25903cc3a23e6ab70f6" - integrity sha512-SlLSF4Be735yQXyh2+mctBOzNDx5s5uLv88/j8Qn1wH679PDcwy67+YdADn8NJnGjzlXtN62asGH/T4vWOkfaw== - dependencies: - "@jest/fake-timers" "30.3.0" - "@jest/types" "30.3.0" - "@types/node" "*" - jest-mock "30.3.0" - -"@jest/environment@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.5.1.tgz#d7425820511fe7158abbecc010140c3fd3be9c74" - integrity sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA== - dependencies: - "@jest/fake-timers" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - jest-mock "^27.5.1" - -"@jest/expect-utils@30.3.0": - version "30.3.0" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-30.3.0.tgz#c45b2da9802ffed33bf43b3e019ddb95e5ad95e8" - integrity sha512-j0+W5iQQ8hBh7tHZkTQv3q2Fh/M7Je72cIsYqC4OaktgtO7v1So9UTjp6uPBHIaB6beoF/RRsCgMJKvti0wADA== - dependencies: - "@jest/get-type" "30.1.0" - -"@jest/expect-utils@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" - integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== - dependencies: - jest-get-type "^29.6.3" - -"@jest/expect@30.3.0": - version "30.3.0" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-30.3.0.tgz#08ee7f5b610167b0068743246c0b568f4c40c773" - integrity sha512-76Nlh4xJxk2D/9URCn3wFi98d2hb19uWE1idLsTt2ywhvdOldbw3S570hBgn25P4ICUZ/cBjybrBex2g17IDbg== - dependencies: - expect "30.3.0" - jest-snapshot "30.3.0" - -"@jest/fake-timers@30.3.0": - version "30.3.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-30.3.0.tgz#2b2868130c1d28233a79566874c42cae1c5a70bc" - integrity sha512-WUQDs8SOP9URStX1DzhD425CqbN/HxUYCTwVrT8sTVBfMvFqYt/s61EK5T05qnHu0po6RitXIvP9otZxYDzTGQ== - dependencies: - "@jest/types" "30.3.0" - "@sinonjs/fake-timers" "^15.0.0" - "@types/node" "*" - jest-message-util "30.3.0" - jest-mock "30.3.0" - jest-util "30.3.0" - -"@jest/fake-timers@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz#76979745ce0579c8a94a4678af7a748eda8ada74" - integrity sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ== - dependencies: - "@jest/types" "^27.5.1" - "@sinonjs/fake-timers" "^8.0.1" - "@types/node" "*" - jest-message-util "^27.5.1" - jest-mock "^27.5.1" - jest-util "^27.5.1" - -"@jest/get-type@30.1.0": - version "30.1.0" - resolved "https://registry.yarnpkg.com/@jest/get-type/-/get-type-30.1.0.tgz#4fcb4dc2ebcf0811be1c04fd1cb79c2dba431cbc" - integrity sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA== - -"@jest/globals@30.3.0": - version "30.3.0" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-30.3.0.tgz#40f4c90e5602629ecda1ca773a8fb21575bb64ea" - integrity sha512-+owLCBBdfpgL3HU+BD5etr1SvbXpSitJK0is1kiYjJxAAJggYMRQz5hSdd5pq1sSggfxPbw2ld71pt4x5wwViA== - dependencies: - "@jest/environment" "30.3.0" - "@jest/expect" "30.3.0" - "@jest/types" "30.3.0" - jest-mock "30.3.0" - -"@jest/globals@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.5.1.tgz#7ac06ce57ab966566c7963431cef458434601b2b" - integrity sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/types" "^27.5.1" - expect "^27.5.1" - -"@jest/pattern@30.0.1": - version "30.0.1" - resolved "https://registry.yarnpkg.com/@jest/pattern/-/pattern-30.0.1.tgz#d5304147f49a052900b4b853dedb111d080e199f" - integrity sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA== - dependencies: - "@types/node" "*" - jest-regex-util "30.0.1" - -"@jest/reporters@30.3.0": - version "30.3.0" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-30.3.0.tgz#0c1065f6c892665e5a051df22b19df4466ed816b" - integrity sha512-a09z89S+PkQnL055bVj8+pe2Caed2PBOaczHcXCykW5ngxX9EWx/1uAwncxc/HiU0oZqfwseMjyhxgRjS49qPw== - dependencies: - "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "30.3.0" - "@jest/test-result" "30.3.0" - "@jest/transform" "30.3.0" - "@jest/types" "30.3.0" - "@jridgewell/trace-mapping" "^0.3.25" - "@types/node" "*" - chalk "^4.1.2" - collect-v8-coverage "^1.0.2" - exit-x "^0.2.2" - glob "^10.5.0" - graceful-fs "^4.2.11" - istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^6.0.0" - istanbul-lib-report "^3.0.0" - istanbul-lib-source-maps "^5.0.0" - istanbul-reports "^3.1.3" - jest-message-util "30.3.0" - jest-util "30.3.0" - jest-worker "30.3.0" - slash "^3.0.0" - string-length "^4.0.2" - v8-to-istanbul "^9.0.1" - -"@jest/reporters@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.5.1.tgz#ceda7be96170b03c923c37987b64015812ffec04" - integrity sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw== - dependencies: - "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - collect-v8-coverage "^1.0.0" - exit "^0.1.2" - glob "^7.1.2" - graceful-fs "^4.2.9" - istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^5.1.0" - istanbul-lib-report "^3.0.0" - istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.1.3" - jest-haste-map "^27.5.1" - jest-resolve "^27.5.1" - jest-util "^27.5.1" - jest-worker "^27.5.1" - slash "^3.0.0" - source-map "^0.6.0" - string-length "^4.0.1" - terminal-link "^2.0.0" - v8-to-istanbul "^8.1.0" - -"@jest/schemas@30.0.5": - version "30.0.5" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-30.0.5.tgz#7bdf69fc5a368a5abdb49fd91036c55225846473" - integrity sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA== - dependencies: - "@sinclair/typebox" "^0.34.0" - -"@jest/schemas@^29.6.3": - version "29.6.3" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" - integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== - dependencies: - "@sinclair/typebox" "^0.27.8" - -"@jest/snapshot-utils@30.3.0": - version "30.3.0" - resolved "https://registry.yarnpkg.com/@jest/snapshot-utils/-/snapshot-utils-30.3.0.tgz#ca003c91a3e1e4e4956dee716a2aaf04b6707f31" - integrity sha512-ORbRN9sf5PP82v3FXNSwmO1OTDR2vzR2YTaR+E3VkSBZ8zadQE6IqYdYEeFH1NIkeB2HIGdF02dapb6K0Mj05g== - dependencies: - "@jest/types" "30.3.0" - chalk "^4.1.2" - graceful-fs "^4.2.11" - natural-compare "^1.4.0" - -"@jest/source-map@30.0.1": - version "30.0.1" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-30.0.1.tgz#305ebec50468f13e658b3d5c26f85107a5620aaa" - integrity sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg== - dependencies: - "@jridgewell/trace-mapping" "^0.3.25" - callsites "^3.1.0" - graceful-fs "^4.2.11" - -"@jest/source-map@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf" - integrity sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg== - dependencies: - callsites "^3.0.0" - graceful-fs "^4.2.9" - source-map "^0.6.0" - -"@jest/test-result@30.3.0": - version "30.3.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-30.3.0.tgz#cd8882d683d467fcffb98c09501a65687a76aae9" - integrity sha512-e/52nJGuD74AKTSe0P4y5wFRlaXP0qmrS17rqOMHeSwm278VyNyXE3gFO/4DTGF9w+65ra3lo3VKj0LBrzmgdQ== - dependencies: - "@jest/console" "30.3.0" - "@jest/types" "30.3.0" - "@types/istanbul-lib-coverage" "^2.0.6" - collect-v8-coverage "^1.0.2" - -"@jest/test-result@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.5.1.tgz#56a6585fa80f7cdab72b8c5fc2e871d03832f5bb" - integrity sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag== - dependencies: - "@jest/console" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/istanbul-lib-coverage" "^2.0.0" - collect-v8-coverage "^1.0.0" - -"@jest/test-sequencer@30.3.0": - version "30.3.0" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-30.3.0.tgz#27002b2093f4e0d9e0e1ebb0bc274a242fdadc14" - integrity sha512-dgbWy9b8QDlQeRZcv7LNF+/jFiiYHTKho1xirauZ7kVwY7avjFF6uTT0RqlgudB5OuIPagFdVtfFMosjVbk1eA== - dependencies: - "@jest/test-result" "30.3.0" - graceful-fs "^4.2.11" - jest-haste-map "30.3.0" - slash "^3.0.0" - -"@jest/test-sequencer@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz#4057e0e9cea4439e544c6353c6affe58d095745b" - integrity sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ== - dependencies: - "@jest/test-result" "^27.5.1" - graceful-fs "^4.2.9" - jest-haste-map "^27.5.1" - jest-runtime "^27.5.1" - -"@jest/transform@30.3.0": - version "30.3.0" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-30.3.0.tgz#9e6f78ffa205449bf956e269fd707c160f47ce2f" - integrity sha512-TLKY33fSLVd/lKB2YI1pH69ijyUblO/BQvCj566YvnwuzoTNr648iE0j22vRvVNk2HsPwByPxATg3MleS3gf5A== - dependencies: - "@babel/core" "^7.27.4" - "@jest/types" "30.3.0" - "@jridgewell/trace-mapping" "^0.3.25" - babel-plugin-istanbul "^7.0.1" - chalk "^4.1.2" - convert-source-map "^2.0.0" - fast-json-stable-stringify "^2.1.0" - graceful-fs "^4.2.11" - jest-haste-map "30.3.0" - jest-regex-util "30.0.1" - jest-util "30.3.0" - pirates "^4.0.7" - slash "^3.0.0" - write-file-atomic "^5.0.1" - -"@jest/transform@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b" - integrity sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA== - dependencies: - "@babel/core" "^7.1.0" - "@jest/types" "^26.6.2" - babel-plugin-istanbul "^6.0.0" - chalk "^4.0.0" - convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.2.4" - jest-haste-map "^26.6.2" - jest-regex-util "^26.0.0" - jest-util "^26.6.2" - micromatch "^4.0.2" - pirates "^4.0.1" - slash "^3.0.0" - source-map "^0.6.1" - write-file-atomic "^3.0.0" - -"@jest/transform@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.5.1.tgz#6c3501dcc00c4c08915f292a600ece5ecfe1f409" - integrity sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw== - dependencies: - "@babel/core" "^7.1.0" - "@jest/types" "^27.5.1" - babel-plugin-istanbul "^6.1.1" - chalk "^4.0.0" - convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.2.9" - jest-haste-map "^27.5.1" - jest-regex-util "^27.5.1" - jest-util "^27.5.1" - micromatch "^4.0.4" - pirates "^4.0.4" - slash "^3.0.0" - source-map "^0.6.1" - write-file-atomic "^3.0.0" - -"@jest/types@30.3.0": - version "30.3.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-30.3.0.tgz#cada800d323cb74945c24ac74615fdb312a6c85f" - integrity sha512-JHm87k7bA33hpBngtU8h6UBub/fqqA9uXfw+21j5Hmk7ooPHlboRNxHq0JcMtC+n8VJGP1mcfnD3Mk+XKe1oSw== - dependencies: - "@jest/pattern" "30.0.1" - "@jest/schemas" "30.0.5" - "@types/istanbul-lib-coverage" "^2.0.6" - "@types/istanbul-reports" "^3.0.4" - "@types/node" "*" - "@types/yargs" "^17.0.33" - chalk "^4.1.2" - -"@jest/types@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" - integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^15.0.0" - chalk "^4.0.0" - -"@jest/types@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" - integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^16.0.0" - chalk "^4.0.0" - -"@jest/types@^29.6.3": - version "29.6.3" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" - integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== - dependencies: - "@jest/schemas" "^29.6.3" - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^17.0.8" - chalk "^4.0.0" - -"@jridgewell/gen-mapping@^0.3.12", "@jridgewell/gen-mapping@^0.3.5": - version "0.3.13" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz#6342a19f44347518c93e43b1ac69deb3c4656a1f" - integrity sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA== - dependencies: - "@jridgewell/sourcemap-codec" "^1.5.0" - "@jridgewell/trace-mapping" "^0.3.24" - -"@jridgewell/remapping@^2.3.5": - version "2.3.5" - resolved "https://registry.yarnpkg.com/@jridgewell/remapping/-/remapping-2.3.5.tgz#375c476d1972947851ba1e15ae8f123047445aa1" - integrity sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ== - dependencies: - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.24" - -"@jridgewell/resolve-uri@^3.1.0": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz#7a0ee601f60f99a20c7c7c5ff0c80388c1189bd6" - integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== - -"@jridgewell/source-map@^0.3.3": - version "0.3.11" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.11.tgz#b21835cbd36db656b857c2ad02ebd413cc13a9ba" - integrity sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA== - dependencies: - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.25" - -"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": - version "1.5.5" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz#6912b00d2c631c0d15ce1a7ab57cd657f2a8f8ba" - integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og== - -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.23", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25", "@jridgewell/trace-mapping@^0.3.28": - version "0.3.31" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz#db15d6781c931f3a251a3dac39501c98a6082fd0" - integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - -"@keplr-wallet/common@0.12.28": - version "0.12.28" - resolved "https://registry.yarnpkg.com/@keplr-wallet/common/-/common-0.12.28.tgz#1d5d985070aced31a34a6426c9ac4b775081acca" - integrity sha512-ESQorPZw8PRiUXhsrxED+E1FEWkAdc6Kwi3Az7ce204gMBQDI2j0XJtTd4uCUp+C24Em9fk0samdHzdoB4caIg== - dependencies: - "@keplr-wallet/crypto" "0.12.28" - "@keplr-wallet/types" "0.12.28" - buffer "^6.0.3" - delay "^4.4.0" - mobx "^6.1.7" - -"@keplr-wallet/cosmos@0.12.28": - version "0.12.28" - resolved "https://registry.yarnpkg.com/@keplr-wallet/cosmos/-/cosmos-0.12.28.tgz#d56e73468256e7276a66bb41f145449dbf11efa1" - integrity sha512-IuqmSBgKgIeWBA0XGQKKs28IXFeFMCrfadCbtiZccNc7qnNr5Y/Cyyk01BPC8Dd1ZyEyAByoICgrxvtGN0GGvA== - dependencies: - "@ethersproject/address" "^5.6.0" - "@keplr-wallet/common" "0.12.28" - "@keplr-wallet/crypto" "0.12.28" - "@keplr-wallet/proto-types" "0.12.28" - "@keplr-wallet/simple-fetch" "0.12.28" - "@keplr-wallet/types" "0.12.28" - "@keplr-wallet/unit" "0.12.28" - bech32 "^1.1.4" - buffer "^6.0.3" - long "^4.0.0" - protobufjs "^6.11.2" - -"@keplr-wallet/crypto@0.12.28": - version "0.12.28" - resolved "https://registry.yarnpkg.com/@keplr-wallet/crypto/-/crypto-0.12.28.tgz#28410ba1f707fa5a1506f111f6fd8baf071c394d" - integrity sha512-le1je+78/4213qshSMgQTYqhCCvzsL9+YfhjXg1kd/ali69MLWK8L8Z09ducHPS6C+LqQXXTNJQpbH2uiFSd5w== - dependencies: - "@ethersproject/keccak256" "^5.5.0" - bip32 "^2.0.6" - bip39 "^3.0.3" - bs58check "^2.1.2" - buffer "^6.0.3" - crypto-js "^4.0.0" - elliptic "^6.5.3" - sha.js "^2.4.11" - -"@keplr-wallet/proto-types@0.12.28": - version "0.12.28" - resolved "https://registry.yarnpkg.com/@keplr-wallet/proto-types/-/proto-types-0.12.28.tgz#2fb2c37749ce7db974f01d07387e966c9b99027d" - integrity sha512-ukti/eCTltPUP64jxtk5TjtwJogyfKPqlBIT3KGUCGzBLIPeYMsffL5w5aoHsMjINzOITjYqzXyEF8LTIK/fmw== - dependencies: - long "^4.0.0" - protobufjs "^6.11.2" - -"@keplr-wallet/provider-extension@^0.12.95": - version "0.12.282" - resolved "https://registry.yarnpkg.com/@keplr-wallet/provider-extension/-/provider-extension-0.12.282.tgz#e24b3bcd929249b153fc4f5e06285c788955eed2" - integrity sha512-X93arcvqh1Ep1pOc5XgQOs9cg1fqDU7lYhtNf4lyGv5Jv80qhtuWWIoduRzqWenXaWpsNSOGXrWiTRzDl4foqg== - dependencies: - "@keplr-wallet/types" "0.12.282" - deepmerge "^4.2.2" - long "^4.0.0" - uuid "^11.1.0" - -"@keplr-wallet/simple-fetch@0.12.28": - version "0.12.28" - resolved "https://registry.yarnpkg.com/@keplr-wallet/simple-fetch/-/simple-fetch-0.12.28.tgz#44225df5b329c823076280df1ec9930a21b1373e" - integrity sha512-T2CiKS2B5n0ZA7CWw0CA6qIAH0XYI1siE50MP+i+V0ZniCGBeL+BMcDw64vFJUcEH+1L5X4sDAzV37fQxGwllA== - -"@keplr-wallet/types@0.12.28": - version "0.12.28" - resolved "https://registry.yarnpkg.com/@keplr-wallet/types/-/types-0.12.28.tgz#eac3c2c9d4560856c5c403a87e67925992a04fbf" - integrity sha512-EcM9d46hYDm3AO4lf4GUbTSLRySONtTmhKb7p88q56OQOgJN3MMjRacEo2p9jX9gpPe7gRIjMUalhAfUiFpZoQ== - dependencies: - long "^4.0.0" - -"@keplr-wallet/types@0.12.282", "@keplr-wallet/types@^0.12.211", "@keplr-wallet/types@^0.12.95": - version "0.12.282" - resolved "https://registry.yarnpkg.com/@keplr-wallet/types/-/types-0.12.282.tgz#e761a60d443acaf90ca372ac18c139b2701f3c6a" - integrity sha512-ygbzBwyLKdQNpW1UijQfpC6prwGUsS+aYoF/X5bJl4R8mmFa6/E4SH2deBWYDCK2J88iERlKDon+Mxmu1eVskw== - dependencies: - long "^4.0.0" - -"@keplr-wallet/unit@0.12.28": - version "0.12.28" - resolved "https://registry.yarnpkg.com/@keplr-wallet/unit/-/unit-0.12.28.tgz#907c7fa0b49a729cda207fca14fc0a38871cc6c4" - integrity sha512-kpXigHDBJGOmhtPkv9hqsQid9zkFo7OQPeKgO2n8GUlOINIXW6kWG5LXYTi/Yg9Uiw1CQF69gFMuZCJ8IzVHlA== - dependencies: - "@keplr-wallet/types" "0.12.28" - big-integer "^1.6.48" - utility-types "^3.10.0" - -"@leichtgewicht/ip-codec@^2.0.1": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz#4fc56c15c580b9adb7dc3c333a134e540b44bfb1" - integrity sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw== - -"@lerna/child-process@7.4.2": - version "7.4.2" - resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-7.4.2.tgz#a2fd013ac2150dc288270d3e0d0b850c06bec511" - integrity sha512-je+kkrfcvPcwL5Tg8JRENRqlbzjdlZXyaR88UcnCdNW0AJ1jX9IfHRys1X7AwSroU2ug8ESNC+suoBw1vX833Q== - dependencies: - chalk "^4.1.0" - execa "^5.0.0" - strong-log-transformer "^2.1.0" - -"@lerna/create@7.4.2": - version "7.4.2" - resolved "https://registry.yarnpkg.com/@lerna/create/-/create-7.4.2.tgz#f845fad1480e46555af98bd39af29571605dddc9" - integrity sha512-1wplFbQ52K8E/unnqB0Tq39Z4e+NEoNrpovEnl6GpsTUrC6WDp8+w0Le2uCBV0hXyemxChduCkLz4/y1H1wTeg== - dependencies: - "@lerna/child-process" "7.4.2" - "@npmcli/run-script" "6.0.2" - "@nx/devkit" ">=16.5.1 < 17" - "@octokit/plugin-enterprise-rest" "6.0.1" - "@octokit/rest" "19.0.11" - byte-size "8.1.1" - chalk "4.1.0" - clone-deep "4.0.1" - cmd-shim "6.0.1" - columnify "1.6.0" - conventional-changelog-core "5.0.1" - conventional-recommended-bump "7.0.1" - cosmiconfig "^8.2.0" - dedent "0.7.0" - execa "5.0.0" - fs-extra "^11.1.1" - get-stream "6.0.0" - git-url-parse "13.1.0" - glob-parent "5.1.2" - globby "11.1.0" - graceful-fs "4.2.11" - has-unicode "2.0.1" - ini "^1.3.8" - init-package-json "5.0.0" - inquirer "^8.2.4" - is-ci "3.0.1" - is-stream "2.0.0" - js-yaml "4.1.0" - libnpmpublish "7.3.0" - load-json-file "6.2.0" - lodash "^4.17.21" - make-dir "4.0.0" - minimatch "3.0.5" - multimatch "5.0.0" - node-fetch "2.6.7" - npm-package-arg "8.1.1" - npm-packlist "5.1.1" - npm-registry-fetch "^14.0.5" - npmlog "^6.0.2" - nx ">=16.5.1 < 17" - p-map "4.0.0" - p-map-series "2.1.0" - p-queue "6.6.2" - p-reduce "^2.1.0" - pacote "^15.2.0" - pify "5.0.0" - read-cmd-shim "4.0.0" - read-package-json "6.0.4" - resolve-from "5.0.0" - rimraf "^4.4.1" - semver "^7.3.4" - signal-exit "3.0.7" - slash "^3.0.0" - ssri "^9.0.1" - strong-log-transformer "2.1.0" - tar "6.1.11" - temp-dir "1.0.0" - upath "2.0.1" - uuid "^9.0.0" - validate-npm-package-license "^3.0.4" - validate-npm-package-name "5.0.0" - write-file-atomic "5.0.1" - write-pkg "4.0.0" - yargs "16.2.0" - yargs-parser "20.2.4" - -"@mdx-js/mdx@^1.6.22": - version "1.6.22" - resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.6.22.tgz#8a723157bf90e78f17dc0f27995398e6c731f1ba" - integrity sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA== - dependencies: - "@babel/core" "7.12.9" - "@babel/plugin-syntax-jsx" "7.12.1" - "@babel/plugin-syntax-object-rest-spread" "7.8.3" - "@mdx-js/util" "1.6.22" - babel-plugin-apply-mdx-type-prop "1.6.22" - babel-plugin-extract-import-names "1.6.22" - camelcase-css "2.0.1" - detab "2.0.4" - hast-util-raw "6.0.1" - lodash.uniq "4.5.0" - mdast-util-to-hast "10.0.1" - remark-footnotes "2.0.0" - remark-mdx "1.6.22" - remark-parse "8.0.3" - remark-squeeze-paragraphs "4.0.0" - style-to-object "0.3.0" - unified "9.2.0" - unist-builder "2.0.3" - unist-util-visit "2.0.3" - -"@mdx-js/react@^1.6.22": - version "1.6.22" - resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-1.6.22.tgz#ae09b4744fddc74714ee9f9d6f17a66e77c43573" - integrity sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg== - -"@mdx-js/util@1.6.22": - version "1.6.22" - resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.6.22.tgz#219dfd89ae5b97a8801f015323ffa4b62f45718b" - integrity sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA== - -"@mrmlnc/readdir-enhanced@^2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" - integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== - dependencies: - call-me-maybe "^1.0.1" - glob-to-regexp "^0.3.0" - -"@mui/base@5.0.0-beta.40": - version "5.0.0-beta.40" - resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.40.tgz#1f8a782f1fbf3f84a961e954c8176b187de3dae2" - integrity sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ== - dependencies: - "@babel/runtime" "^7.23.9" - "@floating-ui/react-dom" "^2.0.8" - "@mui/types" "^7.2.14" - "@mui/utils" "^5.15.14" - "@popperjs/core" "^2.11.8" - clsx "^2.1.0" - prop-types "^15.8.1" - -"@mui/core-downloads-tracker@^5.18.0": - version "5.18.0" - resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.18.0.tgz#85019a8704b0f63305fc5600635ee663810f2b66" - integrity sha512-jbhwoQ1AY200PSSOrNXmrFCaSDSJWP7qk6urkTmIirvRXDROkqe+QwcLlUiw/PrREwsIF/vm3/dAXvjlMHF0RA== - -"@mui/core-downloads-tracker@^6.5.0": - version "6.5.0" - resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-6.5.0.tgz#e9f7049d7e7bb1ee05839f7a0ce813755f137432" - integrity sha512-LGb8t8i6M2ZtS3Drn3GbTI1DVhDY6FJ9crEey2lZ0aN2EMZo8IZBZj9wRf4vqbZHaWjsYgtbOnJw5V8UWbmK2Q== - -"@mui/icons-material@^5.16.11", "@mui/icons-material@^5.2.0": - version "5.18.0" - resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.18.0.tgz#97d87f1b7bee5fa7b9ba844518631de3112c1e57" - integrity sha512-1s0vEZj5XFXDMmz3Arl/R7IncFqJ+WQ95LDp1roHWGDE2oCO3IS4/hmiOv1/8SD9r6B7tv9GLiqVZYHo+6PkTg== - dependencies: - "@babel/runtime" "^7.23.9" - -"@mui/lab@5.0.0-alpha.170": - version "5.0.0-alpha.170" - resolved "https://registry.yarnpkg.com/@mui/lab/-/lab-5.0.0-alpha.170.tgz#4519dfc8d1c51ca54fb9d8b91b95a3733d07be16" - integrity sha512-0bDVECGmrNjd3+bLdcLiwYZ0O4HP5j5WSQm5DV6iA/Z9kr8O6AnvZ1bv9ImQbbX7Gj3pX4o43EKwCutj3EQxQg== - dependencies: - "@babel/runtime" "^7.23.9" - "@mui/base" "5.0.0-beta.40" - "@mui/system" "^5.15.15" - "@mui/types" "^7.2.14" - "@mui/utils" "^5.15.14" - clsx "^2.1.0" - prop-types "^15.8.1" - -"@mui/material-nextjs@^6.1.9": - version "6.5.0" - resolved "https://registry.yarnpkg.com/@mui/material-nextjs/-/material-nextjs-6.5.0.tgz#740993e8175c27e4dd7bd8cec2c1a17e49081d5e" - integrity sha512-VV+4BhmnY32pbPuIevs+rPl0R+bkVvqGCqRqZqNhkdBdX0pn1IHQ5mG/EfYJKoKUkF7q9FKSag5wduSTUxDqnQ== - dependencies: - "@babel/runtime" "^7.26.0" - -"@mui/material@^5.2.2": - version "5.18.0" - resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.18.0.tgz#71e72d52338252edc6f8d9461e04fdf0d61905cd" - integrity sha512-bbH/HaJZpFtXGvWg3TsBWG4eyt3gah3E7nCNU8GLyRjVoWcA91Vm/T+sjHfUcwgJSw9iLtucfHBoq+qW/T30aA== - dependencies: - "@babel/runtime" "^7.23.9" - "@mui/core-downloads-tracker" "^5.18.0" - "@mui/system" "^5.18.0" - "@mui/types" "~7.2.15" - "@mui/utils" "^5.17.1" - "@popperjs/core" "^2.11.8" - "@types/react-transition-group" "^4.4.10" - clsx "^2.1.0" - csstype "^3.1.3" - prop-types "^15.8.1" - react-is "^19.0.0" - react-transition-group "^4.4.5" - -"@mui/material@^6.1.10": - version "6.5.0" - resolved "https://registry.yarnpkg.com/@mui/material/-/material-6.5.0.tgz#c7eccfe260030433c51b7aec17574bae4504cacc" - integrity sha512-yjvtXoFcrPLGtgKRxFaH6OQPtcLPhkloC0BML6rBG5UeldR0nPULR/2E2BfXdo5JNV7j7lOzrrLX2Qf/iSidow== - dependencies: - "@babel/runtime" "^7.26.0" - "@mui/core-downloads-tracker" "^6.5.0" - "@mui/system" "^6.5.0" - "@mui/types" "~7.2.24" - "@mui/utils" "^6.4.9" - "@popperjs/core" "^2.11.8" - "@types/react-transition-group" "^4.4.12" - clsx "^2.1.1" - csstype "^3.1.3" - prop-types "^15.8.1" - react-is "^19.0.0" - react-transition-group "^4.4.5" - -"@mui/private-theming@^5.17.1": - version "5.17.1" - resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.17.1.tgz#b4b6fbece27830754ef78186e3f1307dca42f295" - integrity sha512-XMxU0NTYcKqdsG8LRmSoxERPXwMbp16sIXPcLVgLGII/bVNagX0xaheWAwFv8+zDK7tI3ajllkuD3GZZE++ICQ== - dependencies: - "@babel/runtime" "^7.23.9" - "@mui/utils" "^5.17.1" - prop-types "^15.8.1" - -"@mui/private-theming@^6.4.9": - version "6.4.9" - resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-6.4.9.tgz#0c1d65a638a1740aad0eb715d79e76471abe8175" - integrity sha512-LktcVmI5X17/Q5SkwjCcdOLBzt1hXuc14jYa7NPShog0GBDCDvKtcnP0V7a2s6EiVRlv7BzbWEJzH6+l/zaCxw== - dependencies: - "@babel/runtime" "^7.26.0" - "@mui/utils" "^6.4.9" - prop-types "^15.8.1" - -"@mui/styled-engine@^5.18.0": - version "5.18.0" - resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.18.0.tgz#914cca1385bb33ce0cde31721f529c8bd7fa301c" - integrity sha512-BN/vKV/O6uaQh2z5rXV+MBlVrEkwoS/TK75rFQ2mjxA7+NBo8qtTAOA4UaM0XeJfn7kh2wZ+xQw2HAx0u+TiBg== - dependencies: - "@babel/runtime" "^7.23.9" - "@emotion/cache" "^11.13.5" - "@emotion/serialize" "^1.3.3" - csstype "^3.1.3" - prop-types "^15.8.1" - -"@mui/styled-engine@^6.5.0": - version "6.5.0" - resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-6.5.0.tgz#cf9b3e706517f5f2989df92d2aea0d2917a77c8a" - integrity sha512-8woC2zAqF4qUDSPIBZ8v3sakj+WgweolpyM/FXf8jAx6FMls+IE4Y8VDZc+zS805J7PRz31vz73n2SovKGaYgw== - dependencies: - "@babel/runtime" "^7.26.0" - "@emotion/cache" "^11.13.5" - "@emotion/serialize" "^1.3.3" - "@emotion/sheet" "^1.4.0" - csstype "^3.1.3" - prop-types "^15.8.1" - -"@mui/styles@^5.18.0": - version "5.18.0" - resolved "https://registry.yarnpkg.com/@mui/styles/-/styles-5.18.0.tgz#e70330282e2c64880cc5f36f3fd9fa94257177d5" - integrity sha512-GDgFUfl2MMN8iGrYTuhJ0hHRoja2kVOlXnHb5d3BBQCHFxOBaAPDKQxaNkoAwRf/vBhhwXWDsJA2XlkNHUPBgA== - dependencies: - "@babel/runtime" "^7.23.9" - "@emotion/hash" "^0.9.1" - "@mui/private-theming" "^5.17.1" - "@mui/types" "~7.2.15" - "@mui/utils" "^5.17.1" - clsx "^2.1.0" - csstype "^3.1.3" - hoist-non-react-statics "^3.3.2" - jss "^10.10.0" - jss-plugin-camel-case "^10.10.0" - jss-plugin-default-unit "^10.10.0" - jss-plugin-global "^10.10.0" - jss-plugin-nested "^10.10.0" - jss-plugin-props-sort "^10.10.0" - jss-plugin-rule-value-function "^10.10.0" - jss-plugin-vendor-prefixer "^10.10.0" - prop-types "^15.8.1" - -"@mui/system@^5.15.15", "@mui/system@^5.18.0": - version "5.18.0" - resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.18.0.tgz#e55331203a40584b26c5a855a07949ac8973bfb6" - integrity sha512-ojZGVcRWqWhu557cdO3pWHloIGJdzVtxs3rk0F9L+x55LsUjcMUVkEhiF7E4TMxZoF9MmIHGGs0ZX3FDLAf0Xw== - dependencies: - "@babel/runtime" "^7.23.9" - "@mui/private-theming" "^5.17.1" - "@mui/styled-engine" "^5.18.0" - "@mui/types" "~7.2.15" - "@mui/utils" "^5.17.1" - clsx "^2.1.0" - csstype "^3.1.3" - prop-types "^15.8.1" - -"@mui/system@^6.5.0": - version "6.5.0" - resolved "https://registry.yarnpkg.com/@mui/system/-/system-6.5.0.tgz#52751ac4e3a546f53bc34fd2ef2731c28a824b92" - integrity sha512-XcbBYxDS+h/lgsoGe78ExXFZXtuIlSBpn/KsZq8PtZcIkUNJInkuDqcLd2rVBQrDC1u+rvVovdaWPf2FHKJf3w== - dependencies: - "@babel/runtime" "^7.26.0" - "@mui/private-theming" "^6.4.9" - "@mui/styled-engine" "^6.5.0" - "@mui/types" "~7.2.24" - "@mui/utils" "^6.4.9" - clsx "^2.1.1" - csstype "^3.1.3" - prop-types "^15.8.1" - -"@mui/types@^7.2.14", "@mui/types@^7.4.7": - version "7.4.7" - resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.4.7.tgz#7231f6c050586b5e732c7169f4a934e1856efd51" - integrity sha512-8vVje9rdEr1rY8oIkYgP+Su5Kwl6ik7O3jQ0wl78JGSmiZhRHV+vkjooGdKD8pbtZbutXFVTWQYshu2b3sG9zw== - dependencies: - "@babel/runtime" "^7.28.4" - -"@mui/types@~7.2.15", "@mui/types@~7.2.24": - version "7.2.24" - resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.24.tgz#5eff63129d9c29d80bbf2d2e561bd0690314dec2" - integrity sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw== - -"@mui/utils@^5.15.14", "@mui/utils@^5.17.1", "@mui/utils@^5.7.0": - version "5.17.1" - resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.17.1.tgz#72ba4ffa79f7bdf69d67458139390f18484b6e6b" - integrity sha512-jEZ8FTqInt2WzxDV8bhImWBqeQRD99c/id/fq83H0ER9tFl+sfZlaAoCdznGvbSQQ9ividMxqSV2c7cC1vBcQg== - dependencies: - "@babel/runtime" "^7.23.9" - "@mui/types" "~7.2.15" - "@types/prop-types" "^15.7.12" - clsx "^2.1.1" - prop-types "^15.8.1" - react-is "^19.0.0" - -"@mui/utils@^5.16.6 || ^6.0.0 || ^7.0.0": - version "7.3.3" - resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-7.3.3.tgz#9fe030b94451466fba51428804937286c5103a95" - integrity sha512-kwNAUh7bLZ7mRz9JZ+6qfRnnxbE4Zuc+RzXnhSpRSxjTlSTj7b4JxRLXpG+MVtPVtqks5k/XC8No1Vs3x4Z2gg== - dependencies: - "@babel/runtime" "^7.28.4" - "@mui/types" "^7.4.7" - "@types/prop-types" "^15.7.15" - clsx "^2.1.1" - prop-types "^15.8.1" - react-is "^19.1.1" - -"@mui/utils@^6.4.9": - version "6.4.9" - resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-6.4.9.tgz#b0df01daa254c7c32a1a30b30a5179e19ef071a7" - integrity sha512-Y12Q9hbK9g+ZY0T3Rxrx9m2m10gaphDuUMgWxyV5kNJevVxXYCLclYUCC9vXaIk1/NdNDTcW2Yfr2OGvNFNmHg== - dependencies: - "@babel/runtime" "^7.26.0" - "@mui/types" "~7.2.24" - "@types/prop-types" "^15.7.14" - clsx "^2.1.1" - prop-types "^15.8.1" - react-is "^19.0.0" - -"@mui/x-date-pickers@^7.23.2": - version "7.29.4" - resolved "https://registry.yarnpkg.com/@mui/x-date-pickers/-/x-date-pickers-7.29.4.tgz#b8808cb8e28c1d4e528b37b336effc8074e65faf" - integrity sha512-wJ3tsqk/y6dp+mXGtT9czciAMEO5Zr3IIAHg9x6IL0Eqanqy0N3chbmQQZv3iq0m2qUpQDLvZ4utZBUTJdjNzw== - dependencies: - "@babel/runtime" "^7.25.7" - "@mui/utils" "^5.16.6 || ^6.0.0 || ^7.0.0" - "@mui/x-internals" "7.29.0" - "@types/react-transition-group" "^4.4.11" - clsx "^2.1.1" - prop-types "^15.8.1" - react-transition-group "^4.4.5" - -"@mui/x-internals@7.29.0": - version "7.29.0" - resolved "https://registry.yarnpkg.com/@mui/x-internals/-/x-internals-7.29.0.tgz#1f353b697ed1bf5594ac549556ade2e6841f4bf5" - integrity sha512-+Gk6VTZIFD70XreWvdXBwKd8GZ2FlSCuecQFzm6znwqXg1ZsndavrhG9tkxpxo2fM1Zf7Tk8+HcOO0hCbhTQFA== - dependencies: - "@babel/runtime" "^7.25.7" - "@mui/utils" "^5.16.6 || ^6.0.0 || ^7.0.0" - -"@mui/x-tree-view@^7.11.1": - version "7.29.10" - resolved "https://registry.yarnpkg.com/@mui/x-tree-view/-/x-tree-view-7.29.10.tgz#aa41547f3cf52a447195a8a2777eca158c630032" - integrity sha512-/ZcM582yIaQN2PmadIlQYRJzc3yXV7bh463J4GHtTmFw+PEjzUfzETBWe3VxmU3EPgIFzVQPjqAAJwylmQSJOg== - dependencies: - "@babel/runtime" "^7.25.7" - "@mui/utils" "^5.16.6 || ^6.0.0 || ^7.0.0" - "@mui/x-internals" "7.29.0" - "@types/react-transition-group" "^4.4.11" - clsx "^2.1.1" - prop-types "^15.8.1" - react-transition-group "^4.4.5" - -"@napi-rs/wasm-runtime@^0.2.11": - version "0.2.12" - resolved "https://registry.yarnpkg.com/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz#3e78a8b96e6c33a6c517e1894efbd5385a7cb6f2" - integrity sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ== - dependencies: - "@emnapi/core" "^1.4.3" - "@emnapi/runtime" "^1.4.3" - "@tybys/wasm-util" "^0.10.0" - -"@next/env@14.2.35": - version "14.2.35" - resolved "https://registry.yarnpkg.com/@next/env/-/env-14.2.35.tgz#e979016d0ca8500a47d41ffd02625fe29b8df35a" - integrity sha512-DuhvCtj4t9Gwrx80dmz2F4t/zKQ4ktN8WrMwOuVzkJfBilwAwGr6v16M5eI8yCuZ63H9TTuEU09Iu2HqkzFPVQ== - -"@next/eslint-plugin-next@15.0.3": - version "15.0.3" - resolved "https://registry.yarnpkg.com/@next/eslint-plugin-next/-/eslint-plugin-next-15.0.3.tgz#ce953098036d462f6901e423cc6445fc165b78c4" - integrity sha512-3Ln/nHq2V+v8uIaxCR6YfYo7ceRgZNXfTd3yW1ukTaFbO+/I8jNakrjYWODvG9BuR2v5kgVtH/C8r0i11quOgw== - dependencies: - fast-glob "3.3.1" - -"@next/swc-darwin-arm64@14.2.33": - version "14.2.33" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-14.2.33.tgz#9e74a4223f1e5e39ca4f9f85709e0d95b869b298" - integrity sha512-HqYnb6pxlsshoSTubdXKu15g3iivcbsMXg4bYpjL2iS/V6aQot+iyF4BUc2qA/J/n55YtvE4PHMKWBKGCF/+wA== - -"@next/swc-darwin-x64@14.2.33": - version "14.2.33" - resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-14.2.33.tgz#fcf0c45938da9b0cc2ec86357d6aefca90bd17f3" - integrity sha512-8HGBeAE5rX3jzKvF593XTTFg3gxeU4f+UWnswa6JPhzaR6+zblO5+fjltJWIZc4aUalqTclvN2QtTC37LxvZAA== - -"@next/swc-linux-arm64-gnu@14.2.33": - version "14.2.33" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-14.2.33.tgz#837f91a740eb4420c06f34c4677645315479d9be" - integrity sha512-JXMBka6lNNmqbkvcTtaX8Gu5by9547bukHQvPoLe9VRBx1gHwzf5tdt4AaezW85HAB3pikcvyqBToRTDA4DeLw== - -"@next/swc-linux-arm64-musl@14.2.33": - version "14.2.33" - resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-14.2.33.tgz#dc8903469e5c887b25e3c2217a048bd30c58d3d4" - integrity sha512-Bm+QulsAItD/x6Ih8wGIMfRJy4G73tu1HJsrccPW6AfqdZd0Sfm5Imhgkgq2+kly065rYMnCOxTBvmvFY1BKfg== - -"@next/swc-linux-x64-gnu@14.2.33": - version "14.2.33" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-14.2.33.tgz#344438be592b6b28cc540194274561e41f9933e5" - integrity sha512-FnFn+ZBgsVMbGDsTqo8zsnRzydvsGV8vfiWwUo1LD8FTmPTdV+otGSWKc4LJec0oSexFnCYVO4hX8P8qQKaSlg== - -"@next/swc-linux-x64-musl@14.2.33": - version "14.2.33" - resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-14.2.33.tgz#3379fad5e0181000b2a4fac0b80f7ca4ffe795c8" - integrity sha512-345tsIWMzoXaQndUTDv1qypDRiebFxGYx9pYkhwY4hBRaOLt8UGfiWKr9FSSHs25dFIf8ZqIFaPdy5MljdoawA== - -"@next/swc-win32-arm64-msvc@14.2.33": - version "14.2.33" - resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-14.2.33.tgz#bca8f4dde34656aef8e99f1e5696de255c2f00e5" - integrity sha512-nscpt0G6UCTkrT2ppnJnFsYbPDQwmum4GNXYTeoTIdsmMydSKFz9Iny2jpaRupTb+Wl298+Rh82WKzt9LCcqSQ== - -"@next/swc-win32-ia32-msvc@14.2.33": - version "14.2.33" - resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-14.2.33.tgz#a69c581483ea51dd3b8907ce33bb101fe07ec1df" - integrity sha512-pc9LpGNKhJ0dXQhZ5QMmYxtARwwmWLpeocFmVG5Z0DzWq5Uf0izcI8tLc+qOpqxO1PWqZ5A7J1blrUIKrIFc7Q== - -"@next/swc-win32-x64-msvc@14.2.33": - version "14.2.33" - resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-14.2.33.tgz#f1a40062530c17c35a86d8c430b3ae465eb7cea1" - integrity sha512-nOjfZMy8B94MdisuzZo9/57xuFVLHJaDj5e/xrduJp9CV2/HrfxTRH2fbyLe+K9QT41WBLUd4iXX3R7jBp0EUg== - -"@nivo/annotations@0.88.0": - version "0.88.0" - resolved "https://registry.yarnpkg.com/@nivo/annotations/-/annotations-0.88.0.tgz#96830d735331dea2b60e66ce3971ef43b45cca8c" - integrity sha512-NXE+1oIUn+EGWMQpnpeRMLgi2wyuzhGDoJQY4OUHissCUiNotid2oNQ/PXJwN0toiu+/j9SyhzI32xr70OPi7Q== - dependencies: - "@nivo/colors" "0.88.0" - "@nivo/core" "0.88.0" - "@react-spring/web" "9.4.5 || ^9.7.2" - lodash "^4.17.21" - -"@nivo/axes@0.88.0": - version "0.88.0" - resolved "https://registry.yarnpkg.com/@nivo/axes/-/axes-0.88.0.tgz#b773efb217fc0faedbb5f8bc458f4b78820e2761" - integrity sha512-jF7aIxzTNayV5cI1J/b9Q1FfpMBxTXGk3OwSigXMSfYWlliskDn2u0qGRLiYhuXFdQAWIp4oXsO1GcAQ0eRVdg== - dependencies: - "@nivo/core" "0.88.0" - "@nivo/scales" "0.88.0" - "@react-spring/web" "9.4.5 || ^9.7.2" - "@types/d3-format" "^1.4.1" - "@types/d3-time-format" "^2.3.1" - d3-format "^1.4.4" - d3-time-format "^3.0.0" - -"@nivo/colors@0.88.0": - version "0.88.0" - resolved "https://registry.yarnpkg.com/@nivo/colors/-/colors-0.88.0.tgz#2790ac0607381800270f2902e4d957e65e2cad70" - integrity sha512-IZ+leYIqAlo7dyLHmsQwujanfRgXyoQ5H7PU3RWLEn1PP0zxDKLgEjFEDADpDauuslh2Tx0L81GNkWR6QSP0Mw== - dependencies: - "@nivo/core" "0.88.0" - "@types/d3-color" "^3.0.0" - "@types/d3-scale" "^4.0.8" - "@types/d3-scale-chromatic" "^3.0.0" - "@types/prop-types" "^15.7.2" - d3-color "^3.1.0" - d3-scale "^4.0.2" - d3-scale-chromatic "^3.0.0" - lodash "^4.17.21" - prop-types "^15.7.2" - -"@nivo/core@0.88.0": - version "0.88.0" - resolved "https://registry.yarnpkg.com/@nivo/core/-/core-0.88.0.tgz#ec79c7d63311473f15a463fd78274d9971a52848" - integrity sha512-XjUkA5MmwjLP38bdrJwn36Gj7T5SYMKD55LYQp/1nIJPdxqJ38dUfE4XyBDfIEgfP6yrHOihw3C63cUdnUBoiw== - dependencies: - "@nivo/tooltip" "0.88.0" - "@react-spring/web" "9.4.5 || ^9.7.2" - "@types/d3-shape" "^3.1.6" - d3-color "^3.1.0" - d3-format "^1.4.4" - d3-interpolate "^3.0.1" - d3-scale "^4.0.2" - d3-scale-chromatic "^3.0.0" - d3-shape "^3.2.0" - d3-time-format "^3.0.0" - lodash "^4.17.21" - prop-types "^15.7.2" - -"@nivo/legends@0.88.0": - version "0.88.0" - resolved "https://registry.yarnpkg.com/@nivo/legends/-/legends-0.88.0.tgz#a6007492048358a14bd061472a117ed34e7b0c81" - integrity sha512-d4DF9pHbD8LmGJlp/Gp1cF4e8y2wfQTcw3jVhbZj9zkb7ZWB7JfeF60VHRfbXNux9bjQ9U78/SssQqueVDPEmg== - dependencies: - "@nivo/colors" "0.88.0" - "@nivo/core" "0.88.0" - "@types/d3-scale" "^4.0.8" - d3-scale "^4.0.2" - -"@nivo/line@^0.88.0": - version "0.88.0" - resolved "https://registry.yarnpkg.com/@nivo/line/-/line-0.88.0.tgz#145b194f2c1bff2dd6071ab46fe114f9c4237811" - integrity sha512-hFTyZ3BdAZvq2HwdwMj2SJGUeodjEW+7DLtFMIIoVIxmjZlAs3z533HcJ9cJd3it928fDm8SF/rgHs0TztYf9Q== - dependencies: - "@nivo/annotations" "0.88.0" - "@nivo/axes" "0.88.0" - "@nivo/colors" "0.88.0" - "@nivo/core" "0.88.0" - "@nivo/legends" "0.88.0" - "@nivo/scales" "0.88.0" - "@nivo/tooltip" "0.88.0" - "@nivo/voronoi" "0.88.0" - "@react-spring/web" "9.4.5 || ^9.7.2" - d3-shape "^3.2.0" - -"@nivo/scales@0.88.0": - version "0.88.0" - resolved "https://registry.yarnpkg.com/@nivo/scales/-/scales-0.88.0.tgz#c69110b5ab504debb80a5a01a7824780af241ffb" - integrity sha512-HbpxkQp6tHCltZ1yDGeqdLcaJl5ze54NPjurfGtx/Uq+H5IQoBd4Tln49bUar5CsFAMsXw8yF1HQvASr7I1SIA== - dependencies: - "@types/d3-scale" "^4.0.8" - "@types/d3-time" "^1.1.1" - "@types/d3-time-format" "^3.0.0" - d3-scale "^4.0.2" - d3-time "^1.0.11" - d3-time-format "^3.0.0" - lodash "^4.17.21" - -"@nivo/tooltip@0.88.0": - version "0.88.0" - resolved "https://registry.yarnpkg.com/@nivo/tooltip/-/tooltip-0.88.0.tgz#b98348c0d617fea09c1bbddccc443c12ca697620" - integrity sha512-iEjVfQA8gumAzg/yUinjTwswygCkE5Iwuo8opwnrbpNIqMrleBV+EAKIgB0PrzepIoW8CFG/SJhoiRfbU8jhOw== - dependencies: - "@nivo/core" "0.88.0" - "@react-spring/web" "9.4.5 || ^9.7.2" - -"@nivo/voronoi@0.88.0": - version "0.88.0" - resolved "https://registry.yarnpkg.com/@nivo/voronoi/-/voronoi-0.88.0.tgz#029f984ccb6e72b415f398e1bd74c572960197ae" - integrity sha512-MyiNLvODthFoMjQ7Wjp693nogbTmVEx8Yn/7QkJhyPQbFyyA37TF/D1a/ox4h2OslXtP6K9QFN+42gB/zu7ixw== - dependencies: - "@nivo/core" "0.88.0" - "@nivo/tooltip" "0.88.0" - "@types/d3-delaunay" "^6.0.4" - "@types/d3-scale" "^4.0.8" - d3-delaunay "^6.0.4" - d3-scale "^4.0.2" - -"@noble/hashes@^1", "@noble/hashes@^1.0.0", "@noble/hashes@^1.2.0": - version "1.8.0" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.8.0.tgz#cee43d801fcef9644b11b8194857695acd5f815a" - integrity sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.stat@^1.1.2": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" - integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== - -"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@nolyfill/is-core-module@1.0.39": - version "1.0.39" - resolved "https://registry.yarnpkg.com/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz#3dc35ba0f1e66b403c00b39344f870298ebb1c8e" - integrity sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA== - -"@npmcli/fs@^1.0.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-1.1.1.tgz#72f719fe935e687c56a4faecf3c03d06ba593257" - integrity sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ== - dependencies: - "@gar/promisify" "^1.0.1" - semver "^7.3.5" - -"@npmcli/fs@^2.1.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-2.1.2.tgz#a9e2541a4a2fec2e69c29b35e6060973da79b865" - integrity sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ== - dependencies: - "@gar/promisify" "^1.1.3" - semver "^7.3.5" - -"@npmcli/fs@^3.1.0": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.1.tgz#59cdaa5adca95d135fc00f2bb53f5771575ce726" - integrity sha512-q9CRWjpHCMIh5sVyefoD1cA7PkvILqCZsnSOEUUivORLjxCO/Irmue2DprETiNgEqktDBZaM1Bi+jrarx1XdCg== - dependencies: - semver "^7.3.5" - -"@npmcli/git@^4.0.0": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-4.1.0.tgz#ab0ad3fd82bc4d8c1351b6c62f0fa56e8fe6afa6" - integrity sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ== - dependencies: - "@npmcli/promise-spawn" "^6.0.0" - lru-cache "^7.4.4" - npm-pick-manifest "^8.0.0" - proc-log "^3.0.0" - promise-inflight "^1.0.1" - promise-retry "^2.0.1" - semver "^7.3.5" - which "^3.0.0" - -"@npmcli/installed-package-contents@^2.0.1": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-2.1.0.tgz#63048e5f6e40947a3a88dcbcb4fd9b76fdd37c17" - integrity sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w== - dependencies: - npm-bundled "^3.0.0" - npm-normalize-package-bin "^3.0.0" - -"@npmcli/move-file@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" - integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== - dependencies: - mkdirp "^1.0.4" - rimraf "^3.0.2" - -"@npmcli/move-file@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-2.0.1.tgz#26f6bdc379d87f75e55739bab89db525b06100e4" - integrity sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ== - dependencies: - mkdirp "^1.0.4" - rimraf "^3.0.2" - -"@npmcli/node-gyp@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz#101b2d0490ef1aa20ed460e4c0813f0db560545a" - integrity sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA== - -"@npmcli/promise-spawn@^6.0.0", "@npmcli/promise-spawn@^6.0.1": - version "6.0.2" - resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz#c8bc4fa2bd0f01cb979d8798ba038f314cfa70f2" - integrity sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg== - dependencies: - which "^3.0.0" - -"@npmcli/run-script@6.0.2", "@npmcli/run-script@^6.0.0": - version "6.0.2" - resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-6.0.2.tgz#a25452d45ee7f7fb8c16dfaf9624423c0c0eb885" - integrity sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA== - dependencies: - "@npmcli/node-gyp" "^3.0.0" - "@npmcli/promise-spawn" "^6.0.0" - node-gyp "^9.0.0" - read-package-json-fast "^3.0.0" - which "^3.0.0" - -"@nrwl/devkit@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-16.10.0.tgz#ac8c5b4db00f12c4b817c937be2f7c4eb8f2593c" - integrity sha512-fRloARtsDQoQgQ7HKEy0RJiusg/HSygnmg4gX/0n/Z+SUS+4KoZzvHjXc6T5ZdEiSjvLypJ+HBM8dQzIcVACPQ== - dependencies: - "@nx/devkit" "16.10.0" - -"@nrwl/tao@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-16.10.0.tgz#94642a0380709b8e387e1e33705a5a9624933375" - integrity sha512-QNAanpINbr+Pod6e1xNgFbzK1x5wmZl+jMocgiEFXZ67KHvmbD6MAQQr0MMz+GPhIu7EE4QCTLTyCEMlAG+K5Q== - dependencies: - nx "16.10.0" - tslib "^2.3.0" - -"@nx/devkit@16.10.0", "@nx/devkit@>=16.5.1 < 17": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/devkit/-/devkit-16.10.0.tgz#7e466be2dee2dcb1ccaf286786ca2a0a639aa007" - integrity sha512-IvKQqRJFDDiaj33SPfGd3ckNHhHi6ceEoqCbAP4UuMXOPPVOX6H0KVk+9tknkPb48B7jWIw6/AgOeWkBxPRO5w== - dependencies: - "@nrwl/devkit" "16.10.0" - ejs "^3.1.7" - enquirer "~2.3.6" - ignore "^5.0.4" - semver "7.5.3" - tmp "~0.2.1" - tslib "^2.3.0" - -"@nx/nx-darwin-arm64@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-darwin-arm64/-/nx-darwin-arm64-16.10.0.tgz#0c73010cac7a502549483b12bad347da9014e6f1" - integrity sha512-YF+MIpeuwFkyvM5OwgY/rTNRpgVAI/YiR0yTYCZR+X3AAvP775IVlusNgQ3oedTBRUzyRnI4Tknj1WniENFsvQ== - -"@nx/nx-darwin-x64@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-darwin-x64/-/nx-darwin-x64-16.10.0.tgz#2ccf270418d552fd0a8e0d6089aee4944315adaa" - integrity sha512-ypi6YxwXgb0kg2ixKXE3pwf5myVNUgWf1CsV5OzVccCM8NzheMO51KDXTDmEpXdzUsfT0AkO1sk5GZeCjhVONg== - -"@nx/nx-freebsd-x64@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-freebsd-x64/-/nx-freebsd-x64-16.10.0.tgz#c3ee6914256e69493fed9355b0d6661d0e86da44" - integrity sha512-UeEYFDmdbbDkTQamqvtU8ibgu5jQLgFF1ruNb/U4Ywvwutw2d4ruOMl2e0u9hiNja9NFFAnDbvzrDcMo7jYqYw== - -"@nx/nx-linux-arm-gnueabihf@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-16.10.0.tgz#a961eccbb38acb2da7fc125b29d1fead0b39152f" - integrity sha512-WV3XUC2DB6/+bz1sx+d1Ai9q2Cdr+kTZRN50SOkfmZUQyEBaF6DRYpx/a4ahhxH3ktpNfyY8Maa9OEYxGCBkQA== - -"@nx/nx-linux-arm64-gnu@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-16.10.0.tgz#795f20072549d03822b5c4639ef438e473dbb541" - integrity sha512-aWIkOUw995V3ItfpAi5FuxQ+1e9EWLS1cjWM1jmeuo+5WtaKToJn5itgQOkvSlPz+HSLgM3VfXMvOFALNk125g== - -"@nx/nx-linux-arm64-musl@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-16.10.0.tgz#f2428ee6dbe2b2c326e8973f76c97666def33607" - integrity sha512-uO6Gg+irqpVcCKMcEPIQcTFZ+tDI02AZkqkP7koQAjniLEappd8DnUBSQdcn53T086pHpdc264X/ZEpXFfrKWQ== - -"@nx/nx-linux-x64-gnu@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-16.10.0.tgz#d36c2bcf94d49eaa24e3880ddaf6f1f617de539b" - integrity sha512-134PW/u/arNFAQKpqMJniC7irbChMPz+W+qtyKPAUXE0XFKPa7c1GtlI/wK2dvP9qJDZ6bKf0KtA0U/m2HMUOA== - -"@nx/nx-linux-x64-musl@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-16.10.0.tgz#78bd2ab97a583b3d4ea3387b67fd7b136907493c" - integrity sha512-q8sINYLdIJxK/iUx9vRk5jWAWb/2O0PAbOJFwv4qkxBv4rLoN7y+otgCZ5v0xfx/zztFgk/oNY4lg5xYjIso2Q== - -"@nx/nx-win32-arm64-msvc@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-16.10.0.tgz#ef20ec8d0c83d66e73e20df12d2c788b8f866396" - integrity sha512-moJkL9kcqxUdJSRpG7dET3UeLIciwrfP08mzBQ12ewo8K8FzxU8ZUsTIVVdNrwt01CXOdXoweGfdQLjJ4qTURA== - -"@nx/nx-win32-x64-msvc@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.10.0.tgz#7410a51d0f8be631eec9552f01b2e5946285927c" - integrity sha512-5iV2NKZnzxJwZZ4DM5JVbRG/nkhAbzEskKaLBB82PmYGKzaDHuMHP1lcPoD/rtYMlowZgNA/RQndfKvPBPwmXA== - -"@nymproject/contract-clients@^1.4.1": - version "1.4.1" - resolved "https://registry.yarnpkg.com/@nymproject/contract-clients/-/contract-clients-1.4.1.tgz#ae2644387b518eb13e8825fa8021d4c81ffe7852" - integrity sha512-HuJZ4Hv+Rl6ZZEtCHKgurNLJapM+QQRJlGkevFH2a4UdqUqF9omUkUi3AVes4679dPoSFgvA7plyVSDBdbgV6w== - -"@nymproject/mix-fetch@>=1.4.2-rc.0 || ^1": - version "1.4.4" - resolved "https://registry.yarnpkg.com/@nymproject/mix-fetch/-/mix-fetch-1.4.4.tgz#f10fbde17255c16f9de8c3dd6e8c8f49c4d12c88" - integrity sha512-sdyXXJG7sYv2OFOEf6FYm7HglKfMvJmJjrQC3Rbusy5rH5C2ajg2KyuBbZReLgIIbkkx3mK8sc5WRUOKTcKt2Q== - -"@nymproject/node-tester@^1.3.1": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@nymproject/node-tester/-/node-tester-1.3.1.tgz#605a82c4a3c251a45279043f20fef5583de6c84b" - integrity sha512-JDFsNF84737cynclIYu8y6/MawrLFSiauHeh3dlyJCnY0FBTBRxq/8tN/2QtuaJQf/CvtcfKRH5QoYnCmg+wpQ== - -"@octokit/auth-token@^3.0.0": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-3.0.4.tgz#70e941ba742bdd2b49bdb7393e821dea8520a3db" - integrity sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ== - -"@octokit/core@^4.2.1": - version "4.2.4" - resolved "https://registry.yarnpkg.com/@octokit/core/-/core-4.2.4.tgz#d8769ec2b43ff37cc3ea89ec4681a20ba58ef907" - integrity sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ== - dependencies: - "@octokit/auth-token" "^3.0.0" - "@octokit/graphql" "^5.0.0" - "@octokit/request" "^6.0.0" - "@octokit/request-error" "^3.0.0" - "@octokit/types" "^9.0.0" - before-after-hook "^2.2.0" - universal-user-agent "^6.0.0" - -"@octokit/endpoint@^7.0.0": - version "7.0.6" - resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-7.0.6.tgz#791f65d3937555141fb6c08f91d618a7d645f1e2" - integrity sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg== - dependencies: - "@octokit/types" "^9.0.0" - is-plain-object "^5.0.0" - universal-user-agent "^6.0.0" - -"@octokit/graphql@^5.0.0": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-5.0.6.tgz#9eac411ac4353ccc5d3fca7d76736e6888c5d248" - integrity sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw== - dependencies: - "@octokit/request" "^6.0.0" - "@octokit/types" "^9.0.0" - universal-user-agent "^6.0.0" - -"@octokit/openapi-types@^18.0.0": - version "18.1.1" - resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-18.1.1.tgz#09bdfdabfd8e16d16324326da5148010d765f009" - integrity sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw== - -"@octokit/plugin-enterprise-rest@6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz#e07896739618dab8da7d4077c658003775f95437" - integrity sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw== - -"@octokit/plugin-paginate-rest@^6.1.2": - version "6.1.2" - resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz#f86456a7a1fe9e58fec6385a85cf1b34072341f8" - integrity sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ== - dependencies: - "@octokit/tsconfig" "^1.0.2" - "@octokit/types" "^9.2.3" - -"@octokit/plugin-request-log@^1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz#5e50ed7083a613816b1e4a28aeec5fb7f1462e85" - integrity sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA== - -"@octokit/plugin-rest-endpoint-methods@^7.1.2": - version "7.2.3" - resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.2.3.tgz#37a84b171a6cb6658816c82c4082ac3512021797" - integrity sha512-I5Gml6kTAkzVlN7KCtjOM+Ruwe/rQppp0QU372K1GP7kNOYEKe8Xn5BW4sE62JAHdwpq95OQK/qGNyKQMUzVgA== - dependencies: - "@octokit/types" "^10.0.0" - -"@octokit/request-error@^3.0.0": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-3.0.3.tgz#ef3dd08b8e964e53e55d471acfe00baa892b9c69" - integrity sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ== - dependencies: - "@octokit/types" "^9.0.0" - deprecation "^2.0.0" - once "^1.4.0" - -"@octokit/request@^6.0.0": - version "6.2.8" - resolved "https://registry.yarnpkg.com/@octokit/request/-/request-6.2.8.tgz#aaf480b32ab2b210e9dadd8271d187c93171d8eb" - integrity sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw== - dependencies: - "@octokit/endpoint" "^7.0.0" - "@octokit/request-error" "^3.0.0" - "@octokit/types" "^9.0.0" - is-plain-object "^5.0.0" - node-fetch "^2.6.7" - universal-user-agent "^6.0.0" - -"@octokit/rest@19.0.11": - version "19.0.11" - resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-19.0.11.tgz#2ae01634fed4bd1fca5b642767205ed3fd36177c" - integrity sha512-m2a9VhaP5/tUw8FwfnW2ICXlXpLPIqxtg3XcAiGMLj/Xhw3RSBfZ8le/466ktO1Gcjr8oXudGnHhxV1TXJgFxw== - dependencies: - "@octokit/core" "^4.2.1" - "@octokit/plugin-paginate-rest" "^6.1.2" - "@octokit/plugin-request-log" "^1.0.4" - "@octokit/plugin-rest-endpoint-methods" "^7.1.2" - -"@octokit/tsconfig@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@octokit/tsconfig/-/tsconfig-1.0.2.tgz#59b024d6f3c0ed82f00d08ead5b3750469125af7" - integrity sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA== - -"@octokit/types@^10.0.0": - version "10.0.0" - resolved "https://registry.yarnpkg.com/@octokit/types/-/types-10.0.0.tgz#7ee19c464ea4ada306c43f1a45d444000f419a4a" - integrity sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg== - dependencies: - "@octokit/openapi-types" "^18.0.0" - -"@octokit/types@^9.0.0", "@octokit/types@^9.2.3": - version "9.3.2" - resolved "https://registry.yarnpkg.com/@octokit/types/-/types-9.3.2.tgz#3f5f89903b69f6a2d196d78ec35f888c0013cac5" - integrity sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA== - dependencies: - "@octokit/openapi-types" "^18.0.0" - -"@parcel/watcher@2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.0.4.tgz#f300fef4cc38008ff4b8c29d92588eced3ce014b" - integrity sha512-cTDi+FUDBIUOBKEtj+nhiJ71AZVlkAsQFuGQTun5tV9mwQBQgZvhCzG+URPQc8myeN32yRVZEfVAPCs1RW+Jvg== - dependencies: - node-addon-api "^3.2.1" - node-gyp-build "^4.3.0" - -"@pkgjs/parseargs@^0.11.0": - version "0.11.0" - resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" - integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== - -"@pkgr/core@^0.2.9": - version "0.2.9" - resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.2.9.tgz#d229a7b7f9dac167a156992ef23c7f023653f53b" - integrity sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA== - -"@pmmmwh/react-refresh-webpack-plugin@^0.5.3", "@pmmmwh/react-refresh-webpack-plugin@^0.5.4": - version "0.5.17" - resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.17.tgz#8c2f34ca8651df74895422046e11ce5a120e7930" - integrity sha512-tXDyE1/jzFsHXjhRZQ3hMl0IVhYe5qula43LDWIhVfjp9G/nT5OQY5AORVOrkEGAUltBJOfOWeETbmhm6kHhuQ== - dependencies: - ansi-html "^0.0.9" - core-js-pure "^3.23.3" - error-stack-parser "^2.0.6" - html-entities "^2.1.0" - loader-utils "^2.0.4" - schema-utils "^4.2.0" - source-map "^0.7.3" - -"@popperjs/core@^2.11.8": - version "2.11.8" - resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" - integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== - -"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" - integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== - -"@protobufjs/base64@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" - integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== - -"@protobufjs/codegen@^2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" - integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== - -"@protobufjs/eventemitter@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" - integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== - -"@protobufjs/fetch@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" - integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== - dependencies: - "@protobufjs/aspromise" "^1.1.1" - "@protobufjs/inquire" "^1.1.0" - -"@protobufjs/float@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" - integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== - -"@protobufjs/inquire@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" - integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== - -"@protobufjs/path@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" - integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== - -"@protobufjs/pool@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" - integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== - -"@protobufjs/utf8@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" - integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== - -"@react-aria/breadcrumbs@^3.5.29": - version "3.5.29" - resolved "https://registry.yarnpkg.com/@react-aria/breadcrumbs/-/breadcrumbs-3.5.29.tgz#bfc1e953eccd7393bd457f1c9698a928142f0fc7" - integrity sha512-rKS0dryllaZJqrr3f/EAf2liz8CBEfmL5XACj+Z1TAig6GIYe1QuA3BtkX0cV9OkMugXdX8e3cbA7nD10ORRqg== - dependencies: - "@react-aria/i18n" "^3.12.13" - "@react-aria/link" "^3.8.6" - "@react-aria/utils" "^3.31.0" - "@react-types/breadcrumbs" "^3.7.17" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/button@^3.14.2": - version "3.14.2" - resolved "https://registry.yarnpkg.com/@react-aria/button/-/button-3.14.2.tgz#9dcd2fa53e7968a563b4898ace3360c85ccc22f5" - integrity sha512-VbLIA+Kd6f/MDjd+TJBUg2+vNDw66pnvsj2E4RLomjI9dfBuN7d+Yo2UnsqKVyhePjCUZ6xxa2yDuD63IOSIYA== - dependencies: - "@react-aria/interactions" "^3.25.6" - "@react-aria/toolbar" "3.0.0-beta.21" - "@react-aria/utils" "^3.31.0" - "@react-stately/toggle" "^3.9.2" - "@react-types/button" "^3.14.1" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/calendar@^3.9.2": - version "3.9.2" - resolved "https://registry.yarnpkg.com/@react-aria/calendar/-/calendar-3.9.2.tgz#4b6e428ee3fb81f5729cb80193b9d4ba9b26d5f1" - integrity sha512-uSLxLgOPRnEU4Jg59lAhUVA+uDx/55NBg4lpfsP2ynazyiJ5LCXmYceJi+VuOqMml7d9W0dB87OldOeLdIxYVA== - dependencies: - "@internationalized/date" "^3.10.0" - "@react-aria/i18n" "^3.12.13" - "@react-aria/interactions" "^3.25.6" - "@react-aria/live-announcer" "^3.4.4" - "@react-aria/utils" "^3.31.0" - "@react-stately/calendar" "^3.9.0" - "@react-types/button" "^3.14.1" - "@react-types/calendar" "^3.8.0" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/checkbox@^3.16.2": - version "3.16.2" - resolved "https://registry.yarnpkg.com/@react-aria/checkbox/-/checkbox-3.16.2.tgz#b1a3310d327826fe354625c332f3b80acb025a39" - integrity sha512-29Mj9ZqXioJ0bcMnNGooHztnTau5pikZqX3qCRj5bYR3by/ZFFavYoMroh9F7s/MbFm/tsKX+Sf02lYFEdXRjA== - dependencies: - "@react-aria/form" "^3.1.2" - "@react-aria/interactions" "^3.25.6" - "@react-aria/label" "^3.7.22" - "@react-aria/toggle" "^3.12.2" - "@react-aria/utils" "^3.31.0" - "@react-stately/checkbox" "^3.7.2" - "@react-stately/form" "^3.2.2" - "@react-stately/toggle" "^3.9.2" - "@react-types/checkbox" "^3.10.2" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/color@^3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@react-aria/color/-/color-3.1.2.tgz#9ee2a86e4cf4622ca8ff78bddd34a2bf1bdcdd34" - integrity sha512-jCC+Q7rAQGLQBkHjkPAeDuGYuMbc4neifjlNRiyZ9as1z4gg63H8MteoWYYk6K4vCKKxSixgt8MfI29XWMOWPQ== - dependencies: - "@react-aria/i18n" "^3.12.13" - "@react-aria/interactions" "^3.25.6" - "@react-aria/numberfield" "^3.12.2" - "@react-aria/slider" "^3.8.2" - "@react-aria/spinbutton" "^3.6.19" - "@react-aria/textfield" "^3.18.2" - "@react-aria/utils" "^3.31.0" - "@react-aria/visually-hidden" "^3.8.28" - "@react-stately/color" "^3.9.2" - "@react-stately/form" "^3.2.2" - "@react-types/color" "^3.1.2" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/combobox@^3.14.0": - version "3.14.0" - resolved "https://registry.yarnpkg.com/@react-aria/combobox/-/combobox-3.14.0.tgz#1e6c55a319d367d6a0a9e19f2bd68d3a9a0c8b9a" - integrity sha512-z4ro0Hma//p4nL2IJx5iUa7NwxeXbzSoZ0se5uTYjG1rUUMszg+wqQh/AQoL+eiULn7rs18JY9wwNbVIkRNKWA== - dependencies: - "@react-aria/focus" "^3.21.2" - "@react-aria/i18n" "^3.12.13" - "@react-aria/listbox" "^3.15.0" - "@react-aria/live-announcer" "^3.4.4" - "@react-aria/menu" "^3.19.3" - "@react-aria/overlays" "^3.30.0" - "@react-aria/selection" "^3.26.0" - "@react-aria/textfield" "^3.18.2" - "@react-aria/utils" "^3.31.0" - "@react-stately/collections" "^3.12.8" - "@react-stately/combobox" "^3.12.0" - "@react-stately/form" "^3.2.2" - "@react-types/button" "^3.14.1" - "@react-types/combobox" "^3.13.9" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/datepicker@^3.15.2": - version "3.15.2" - resolved "https://registry.yarnpkg.com/@react-aria/datepicker/-/datepicker-3.15.2.tgz#22bca8cfdd00e32a42f8e53b35e5ba7e886f047d" - integrity sha512-th078hyNqPf4P2K10su/y32zPDjs3lOYVdHvsL9/+5K1dnTvLHCK5vgUyLuyn8FchhF7cmHV49D+LZVv65PEpQ== - dependencies: - "@internationalized/date" "^3.10.0" - "@internationalized/number" "^3.6.5" - "@internationalized/string" "^3.2.7" - "@react-aria/focus" "^3.21.2" - "@react-aria/form" "^3.1.2" - "@react-aria/i18n" "^3.12.13" - "@react-aria/interactions" "^3.25.6" - "@react-aria/label" "^3.7.22" - "@react-aria/spinbutton" "^3.6.19" - "@react-aria/utils" "^3.31.0" - "@react-stately/datepicker" "^3.15.2" - "@react-stately/form" "^3.2.2" - "@react-types/button" "^3.14.1" - "@react-types/calendar" "^3.8.0" - "@react-types/datepicker" "^3.13.2" - "@react-types/dialog" "^3.5.22" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/dialog@^3.5.31": - version "3.5.31" - resolved "https://registry.yarnpkg.com/@react-aria/dialog/-/dialog-3.5.31.tgz#1c1682a89dd6a4c6bc7bb0e58ea78eb6f2750a65" - integrity sha512-inxQMyrzX0UBW9Mhraq0nZ4HjHdygQvllzloT1E/RlDd61lr3RbmJR6pLsrbKOTtSvDIBJpCso1xEdHCFNmA0Q== - dependencies: - "@react-aria/interactions" "^3.25.6" - "@react-aria/overlays" "^3.30.0" - "@react-aria/utils" "^3.31.0" - "@react-types/dialog" "^3.5.22" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/disclosure@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@react-aria/disclosure/-/disclosure-3.1.0.tgz#c08a0f9696fa80ca69de78f37c8bf0b65a7a9397" - integrity sha512-5996BeBpnj+yKXYysz+UuhFQxGFPvaZZ3zNBd052wz/i+TVFVGSqqYJ6cwZyO1AfBR8zOT0ZIiK4EC3ETwSvtQ== - dependencies: - "@react-aria/ssr" "^3.9.10" - "@react-aria/utils" "^3.31.0" - "@react-stately/disclosure" "^3.0.8" - "@react-types/button" "^3.14.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/dnd@^3.11.3": - version "3.11.3" - resolved "https://registry.yarnpkg.com/@react-aria/dnd/-/dnd-3.11.3.tgz#438b4603ef9b2560775ea02b64ea3dcdf15bf474" - integrity sha512-MyTziciik1Owz3rqDghu0K3ZtTFvmj/R2ZsLDwbU9N4hKqGX/BKnrI8SytTn8RDqVv5LmA/GhApLngiupTAsXw== - dependencies: - "@internationalized/string" "^3.2.7" - "@react-aria/i18n" "^3.12.13" - "@react-aria/interactions" "^3.25.6" - "@react-aria/live-announcer" "^3.4.4" - "@react-aria/overlays" "^3.30.0" - "@react-aria/utils" "^3.31.0" - "@react-stately/collections" "^3.12.8" - "@react-stately/dnd" "^3.7.1" - "@react-types/button" "^3.14.1" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/focus@^3.21.2": - version "3.21.2" - resolved "https://registry.yarnpkg.com/@react-aria/focus/-/focus-3.21.2.tgz#3ce90450c3ee69f11c0647b4717c26d10941231c" - integrity sha512-JWaCR7wJVggj+ldmM/cb/DXFg47CXR55lznJhZBh4XVqJjMKwaOOqpT5vNN7kpC1wUpXicGNuDnJDN1S/+6dhQ== - dependencies: - "@react-aria/interactions" "^3.25.6" - "@react-aria/utils" "^3.31.0" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - clsx "^2.0.0" - -"@react-aria/form@^3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@react-aria/form/-/form-3.1.2.tgz#e0aeb608d309594a59f12a7b05eb7374f2033a07" - integrity sha512-R3i7L7Ci61PqZQvOrnL9xJeWEbh28UkTVgkj72EvBBn39y4h7ReH++0stv7rRs8p5ozETSKezBbGfu4UsBewWw== - dependencies: - "@react-aria/interactions" "^3.25.6" - "@react-aria/utils" "^3.31.0" - "@react-stately/form" "^3.2.2" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/grid@^3.14.5": - version "3.14.5" - resolved "https://registry.yarnpkg.com/@react-aria/grid/-/grid-3.14.5.tgz#fccd1e3b64cdad7b17aff0dada6da64df0cd1d8c" - integrity sha512-XHw6rgjlTqc85e3zjsWo3U0EVwjN5MOYtrolCKc/lc2ItNdcY3OlMhpsU9+6jHwg/U3VCSWkGvwAz9hg7krd8Q== - dependencies: - "@react-aria/focus" "^3.21.2" - "@react-aria/i18n" "^3.12.13" - "@react-aria/interactions" "^3.25.6" - "@react-aria/live-announcer" "^3.4.4" - "@react-aria/selection" "^3.26.0" - "@react-aria/utils" "^3.31.0" - "@react-stately/collections" "^3.12.8" - "@react-stately/grid" "^3.11.6" - "@react-stately/selection" "^3.20.6" - "@react-types/checkbox" "^3.10.2" - "@react-types/grid" "^3.3.6" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/gridlist@^3.14.1": - version "3.14.1" - resolved "https://registry.yarnpkg.com/@react-aria/gridlist/-/gridlist-3.14.1.tgz#4aa636ad1342f859dc5ce1a350211535ae5ae424" - integrity sha512-keS03Am07aOn7RuNaRsMOyh0jscyhDn95asCVy4lxhl9A9TFk1Jw0o2L6q6cWRj1gFiKeacj/otG5H8ZKQQ2Wg== - dependencies: - "@react-aria/focus" "^3.21.2" - "@react-aria/grid" "^3.14.5" - "@react-aria/i18n" "^3.12.13" - "@react-aria/interactions" "^3.25.6" - "@react-aria/selection" "^3.26.0" - "@react-aria/utils" "^3.31.0" - "@react-stately/list" "^3.13.1" - "@react-stately/tree" "^3.9.3" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/i18n@^3.12.13": - version "3.12.13" - resolved "https://registry.yarnpkg.com/@react-aria/i18n/-/i18n-3.12.13.tgz#7c920d131cd07d4d5af21bd33ea7a5da0ce2ad11" - integrity sha512-YTM2BPg0v1RvmP8keHenJBmlx8FXUKsdYIEX7x6QWRd1hKlcDwphfjzvt0InX9wiLiPHsT5EoBTpuUk8SXc0Mg== - dependencies: - "@internationalized/date" "^3.10.0" - "@internationalized/message" "^3.1.8" - "@internationalized/number" "^3.6.5" - "@internationalized/string" "^3.2.7" - "@react-aria/ssr" "^3.9.10" - "@react-aria/utils" "^3.31.0" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/interactions@^3.25.6": - version "3.25.6" - resolved "https://registry.yarnpkg.com/@react-aria/interactions/-/interactions-3.25.6.tgz#6fdf287337c5e4285045c35cf94b2ec8ae3b3a49" - integrity sha512-5UgwZmohpixwNMVkMvn9K1ceJe6TzlRlAfuYoQDUuOkk62/JVJNDLAPKIf5YMRc7d2B0rmfgaZLMtbREb0Zvkw== - dependencies: - "@react-aria/ssr" "^3.9.10" - "@react-aria/utils" "^3.31.0" - "@react-stately/flags" "^3.1.2" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/label@^3.7.22": - version "3.7.22" - resolved "https://registry.yarnpkg.com/@react-aria/label/-/label-3.7.22.tgz#13fbf1d568c37becca4652e5c5d0b490c29e5e52" - integrity sha512-jLquJeA5ZNqDT64UpTc9XJ7kQYltUlNcgxZ37/v4mHe0UZ7QohCKdKQhXHONb0h2jjNUpp2HOZI8J9++jOpzxA== - dependencies: - "@react-aria/utils" "^3.31.0" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/landmark@^3.0.7": - version "3.0.7" - resolved "https://registry.yarnpkg.com/@react-aria/landmark/-/landmark-3.0.7.tgz#6ffc06c870018f6ead456f6f67cccebd655910f0" - integrity sha512-t8c610b8hPLS6Vwv+rbuSyljZosI1s5+Tosfa0Fk4q7d+Ex6Yj7hLfUFy59GxZAufhUYfGX396fT0gPqAbU1tg== - dependencies: - "@react-aria/utils" "^3.31.0" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - use-sync-external-store "^1.4.0" - -"@react-aria/link@^3.8.6": - version "3.8.6" - resolved "https://registry.yarnpkg.com/@react-aria/link/-/link-3.8.6.tgz#522c246b9fcf62fbe75f9c07d056d6b984523143" - integrity sha512-7F7UDJnwbU9IjfoAdl6f3Hho5/WB7rwcydUOjUux0p7YVWh/fTjIFjfAGyIir7MJhPapun1D0t97QQ3+8jXVcg== - dependencies: - "@react-aria/interactions" "^3.25.6" - "@react-aria/utils" "^3.31.0" - "@react-types/link" "^3.6.5" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/listbox@^3.13.3", "@react-aria/listbox@^3.15.0": - version "3.15.0" - resolved "https://registry.yarnpkg.com/@react-aria/listbox/-/listbox-3.15.0.tgz#4218e24c20ec68069f51175c57fa2bf55b1acc46" - integrity sha512-Ub1Wu79R9sgxM7h4HeEdjOgOKDHwduvYcnDqsSddGXgpkL8ADjsy2YUQ0hHY5VnzA4BxK36bLp4mzSna8Qvj1w== - dependencies: - "@react-aria/interactions" "^3.25.6" - "@react-aria/label" "^3.7.22" - "@react-aria/selection" "^3.26.0" - "@react-aria/utils" "^3.31.0" - "@react-stately/collections" "^3.12.8" - "@react-stately/list" "^3.13.1" - "@react-types/listbox" "^3.7.4" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/live-announcer@^3.4.4": - version "3.4.4" - resolved "https://registry.yarnpkg.com/@react-aria/live-announcer/-/live-announcer-3.4.4.tgz#0e6533940222208b323b71d56ac8e115b2121e6a" - integrity sha512-PTTBIjNRnrdJOIRTDGNifY2d//kA7GUAwRFJNOEwSNG4FW+Bq9awqLiflw0JkpyB0VNIwou6lqKPHZVLsGWOXA== - dependencies: - "@swc/helpers" "^0.5.0" - -"@react-aria/menu@^3.19.3": - version "3.19.3" - resolved "https://registry.yarnpkg.com/@react-aria/menu/-/menu-3.19.3.tgz#65a6dc14b27648be611bf28ab4bbcd2823b612a8" - integrity sha512-52fh8y8b2776R2VrfZPpUBJYC9oTP7XDy+zZuZTxPEd7Ywk0JNUl5F92y6ru22yPkS13sdhrNM/Op+V/KulmAg== - dependencies: - "@react-aria/focus" "^3.21.2" - "@react-aria/i18n" "^3.12.13" - "@react-aria/interactions" "^3.25.6" - "@react-aria/overlays" "^3.30.0" - "@react-aria/selection" "^3.26.0" - "@react-aria/utils" "^3.31.0" - "@react-stately/collections" "^3.12.8" - "@react-stately/menu" "^3.9.8" - "@react-stately/selection" "^3.20.6" - "@react-stately/tree" "^3.9.3" - "@react-types/button" "^3.14.1" - "@react-types/menu" "^3.10.5" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/meter@^3.4.27": - version "3.4.27" - resolved "https://registry.yarnpkg.com/@react-aria/meter/-/meter-3.4.27.tgz#01cf9bbd12f05bd0515e048960690b017b0b9dd2" - integrity sha512-andOOdJkgRJF9vBi5VWRmFodK+GT+5X1lLeNUmb4qOX8/MVfX/RbK72LDeIhd7xC7rSCFHj3WvZ198rK4q0k3w== - dependencies: - "@react-aria/progress" "^3.4.27" - "@react-types/meter" "^3.4.13" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/numberfield@^3.12.2": - version "3.12.2" - resolved "https://registry.yarnpkg.com/@react-aria/numberfield/-/numberfield-3.12.2.tgz#c219ecfba2076865e891cb2435c6bad558d6eabf" - integrity sha512-M2b+z0HIXiXpGAWOQkO2kpIjaLNUXJ5Q3/GMa3Fkr+B1piFX0VuOynYrtddKVrmXCe+r5t+XcGb0KS29uqv7nQ== - dependencies: - "@react-aria/i18n" "^3.12.13" - "@react-aria/interactions" "^3.25.6" - "@react-aria/spinbutton" "^3.6.19" - "@react-aria/textfield" "^3.18.2" - "@react-aria/utils" "^3.31.0" - "@react-stately/form" "^3.2.2" - "@react-stately/numberfield" "^3.10.2" - "@react-types/button" "^3.14.1" - "@react-types/numberfield" "^3.8.15" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/overlays@^3.23.2", "@react-aria/overlays@^3.30.0": - version "3.30.0" - resolved "https://registry.yarnpkg.com/@react-aria/overlays/-/overlays-3.30.0.tgz#e19f804c7fb9d99b25e33230cc3c155ed0b3cefb" - integrity sha512-UpjqSjYZx5FAhceWCRVsW6fX1sEwya1fQ/TKkL53FAlLFR8QKuoKqFlmiL43YUFTcGK3UdEOy3cWTleLQwdSmQ== - dependencies: - "@react-aria/focus" "^3.21.2" - "@react-aria/i18n" "^3.12.13" - "@react-aria/interactions" "^3.25.6" - "@react-aria/ssr" "^3.9.10" - "@react-aria/utils" "^3.31.0" - "@react-aria/visually-hidden" "^3.8.28" - "@react-stately/overlays" "^3.6.20" - "@react-types/button" "^3.14.1" - "@react-types/overlays" "^3.9.2" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/progress@^3.4.27": - version "3.4.27" - resolved "https://registry.yarnpkg.com/@react-aria/progress/-/progress-3.4.27.tgz#bdc968f133ddd33e5feaf2903d43aa34435dad51" - integrity sha512-0OA1shs1575g1zmO8+rWozdbTnxThFFhOfuoL1m7UV5Dley6FHpueoKB1ECv7B+Qm4dQt6DoEqLg7wsbbQDhmg== - dependencies: - "@react-aria/i18n" "^3.12.13" - "@react-aria/label" "^3.7.22" - "@react-aria/utils" "^3.31.0" - "@react-types/progress" "^3.5.16" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/radio@^3.12.2": - version "3.12.2" - resolved "https://registry.yarnpkg.com/@react-aria/radio/-/radio-3.12.2.tgz#48ae0e9ba93e5c29e998fa3b64155a324a87f63e" - integrity sha512-I11f6I90neCh56rT/6ieAs3XyDKvEfbj/QmbU5cX3p+SJpRRPN0vxQi5D1hkh0uxDpeClxygSr31NmZsd4sqfg== - dependencies: - "@react-aria/focus" "^3.21.2" - "@react-aria/form" "^3.1.2" - "@react-aria/i18n" "^3.12.13" - "@react-aria/interactions" "^3.25.6" - "@react-aria/label" "^3.7.22" - "@react-aria/utils" "^3.31.0" - "@react-stately/radio" "^3.11.2" - "@react-types/radio" "^3.9.2" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/searchfield@^3.8.9": - version "3.8.9" - resolved "https://registry.yarnpkg.com/@react-aria/searchfield/-/searchfield-3.8.9.tgz#faa82c976bf3ef6c678bf9a2f9ae9bea9d4d3096" - integrity sha512-Yt2pj8Wb5/XsUr2T0DQqFv+DlFpzzWIWnNr9cJATUcWV/xw6ok7YFEg9+7EHtBmsCQxFFJtock1QfZzBw6qLtQ== - dependencies: - "@react-aria/i18n" "^3.12.13" - "@react-aria/textfield" "^3.18.2" - "@react-aria/utils" "^3.31.0" - "@react-stately/searchfield" "^3.5.16" - "@react-types/button" "^3.14.1" - "@react-types/searchfield" "^3.6.6" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/select@^3.17.0": - version "3.17.0" - resolved "https://registry.yarnpkg.com/@react-aria/select/-/select-3.17.0.tgz#d96933daca43939f4d59518f843c87a4f600426f" - integrity sha512-q5ZuyAn5jSOeI0Ys99951TaGcF4O7u1SSBVxPMwVVXOU8ZhToCNx+WG3n/JDYHEjqdo7sbsVRaPA7LkBzBGf5w== - dependencies: - "@react-aria/form" "^3.1.2" - "@react-aria/i18n" "^3.12.13" - "@react-aria/interactions" "^3.25.6" - "@react-aria/label" "^3.7.22" - "@react-aria/listbox" "^3.15.0" - "@react-aria/menu" "^3.19.3" - "@react-aria/selection" "^3.26.0" - "@react-aria/utils" "^3.31.0" - "@react-aria/visually-hidden" "^3.8.28" - "@react-stately/select" "^3.8.0" - "@react-types/button" "^3.14.1" - "@react-types/select" "^3.11.0" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/selection@^3.26.0": - version "3.26.0" - resolved "https://registry.yarnpkg.com/@react-aria/selection/-/selection-3.26.0.tgz#dc5906aa732b0dbd54d26dd6a5f1dc793055e29c" - integrity sha512-ZBH3EfWZ+RfhTj01dH8L17uT7iNbXWS8u77/fUpHgtrm0pwNVhx0TYVnLU1YpazQ/3WVpvWhmBB8sWwD1FlD/g== - dependencies: - "@react-aria/focus" "^3.21.2" - "@react-aria/i18n" "^3.12.13" - "@react-aria/interactions" "^3.25.6" - "@react-aria/utils" "^3.31.0" - "@react-stately/selection" "^3.20.6" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/separator@^3.4.13": - version "3.4.13" - resolved "https://registry.yarnpkg.com/@react-aria/separator/-/separator-3.4.13.tgz#6eea332c68b67d1081f4d8c2af8198c6bc46bfb4" - integrity sha512-0NlcrdBfQbcjWEXdHl3+uSY1272n2ljT1gWL2RIf6aQsQWTZ0gz0rTgRHy0MTXN+y+tICItUERJT4vmTLtIzVg== - dependencies: - "@react-aria/utils" "^3.31.0" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/slider@^3.8.2": - version "3.8.2" - resolved "https://registry.yarnpkg.com/@react-aria/slider/-/slider-3.8.2.tgz#a075205b06fa714733e3aabfdbc63d11f5c67be7" - integrity sha512-6KyUGaVzRE4xAz1LKHbNh1q5wzxe58pdTHFSnxNe6nk1SCoHw7NfI4h2s2m6LgJ0megFxsT0Ir8aHaFyyxmbgg== - dependencies: - "@react-aria/i18n" "^3.12.13" - "@react-aria/interactions" "^3.25.6" - "@react-aria/label" "^3.7.22" - "@react-aria/utils" "^3.31.0" - "@react-stately/slider" "^3.7.2" - "@react-types/shared" "^3.32.1" - "@react-types/slider" "^3.8.2" - "@swc/helpers" "^0.5.0" - -"@react-aria/spinbutton@^3.6.19": - version "3.6.19" - resolved "https://registry.yarnpkg.com/@react-aria/spinbutton/-/spinbutton-3.6.19.tgz#fd0253b95b88e9fb12ff406b722b4fd1e1c8c836" - integrity sha512-xOIXegDpts9t3RSHdIN0iYQpdts0FZ3LbpYJIYVvdEHo9OpDS+ElnDzCGtwZLguvZlwc5s1LAKuKopDUsAEMkw== - dependencies: - "@react-aria/i18n" "^3.12.13" - "@react-aria/live-announcer" "^3.4.4" - "@react-aria/utils" "^3.31.0" - "@react-types/button" "^3.14.1" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/ssr@^3.9.10": - version "3.9.10" - resolved "https://registry.yarnpkg.com/@react-aria/ssr/-/ssr-3.9.10.tgz#7fdc09e811944ce0df1d7e713de1449abd7435e6" - integrity sha512-hvTm77Pf+pMBhuBm760Li0BVIO38jv1IBws1xFm1NoL26PU+fe+FMW5+VZWyANR6nYL65joaJKZqOdTQMkO9IQ== - dependencies: - "@swc/helpers" "^0.5.0" - -"@react-aria/switch@^3.7.8": - version "3.7.8" - resolved "https://registry.yarnpkg.com/@react-aria/switch/-/switch-3.7.8.tgz#e0a14f5eeda6017ae4d2b1cd236270d45c03e5ca" - integrity sha512-AfsUq1/YiuoprhcBUD9vDPyWaigAwctQNW1fMb8dROL+i/12B+Zekj8Ml+jbU69/kIVtfL0Jl7/0Bo9KK3X0xQ== - dependencies: - "@react-aria/toggle" "^3.12.2" - "@react-stately/toggle" "^3.9.2" - "@react-types/shared" "^3.32.1" - "@react-types/switch" "^3.5.15" - "@swc/helpers" "^0.5.0" - -"@react-aria/table@^3.17.8": - version "3.17.8" - resolved "https://registry.yarnpkg.com/@react-aria/table/-/table-3.17.8.tgz#bf9c72cfe13775d6ad6934855f21456d73844ef0" - integrity sha512-bXiZoxTMbsqUJsYDhHPzKc3jw0HFJ/xMsJ49a0f7mp5r9zACxNLeIU0wJ4Uvx37dnYOHKzGliG+rj5l4sph7MA== - dependencies: - "@react-aria/focus" "^3.21.2" - "@react-aria/grid" "^3.14.5" - "@react-aria/i18n" "^3.12.13" - "@react-aria/interactions" "^3.25.6" - "@react-aria/live-announcer" "^3.4.4" - "@react-aria/utils" "^3.31.0" - "@react-aria/visually-hidden" "^3.8.28" - "@react-stately/collections" "^3.12.8" - "@react-stately/flags" "^3.1.2" - "@react-stately/table" "^3.15.1" - "@react-types/checkbox" "^3.10.2" - "@react-types/grid" "^3.3.6" - "@react-types/shared" "^3.32.1" - "@react-types/table" "^3.13.4" - "@swc/helpers" "^0.5.0" - -"@react-aria/tabs@^3.10.8": - version "3.10.8" - resolved "https://registry.yarnpkg.com/@react-aria/tabs/-/tabs-3.10.8.tgz#95c76badd8a9c9583449d0c765ab9289627847bc" - integrity sha512-sPPJyTyoAqsBh76JinBAxStOcbjZvyWFYKpJ9Uqw+XT0ObshAPPFSGeh8DiQemPs02RwJdrfARPMhyqiX8t59A== - dependencies: - "@react-aria/focus" "^3.21.2" - "@react-aria/i18n" "^3.12.13" - "@react-aria/selection" "^3.26.0" - "@react-aria/utils" "^3.31.0" - "@react-stately/tabs" "^3.8.6" - "@react-types/shared" "^3.32.1" - "@react-types/tabs" "^3.3.19" - "@swc/helpers" "^0.5.0" - -"@react-aria/tag@^3.7.2": - version "3.7.2" - resolved "https://registry.yarnpkg.com/@react-aria/tag/-/tag-3.7.2.tgz#5a655640deaf1705b8001abd636a7b96ae2250e9" - integrity sha512-JV679P5r4DftbqyNBRt7Nw9mP7dxaKPfikjyQuvUoEOa06wBLbM/hU9RJUPRvqK+Un6lgBDAmXD9NNf4N2xpdw== - dependencies: - "@react-aria/gridlist" "^3.14.1" - "@react-aria/i18n" "^3.12.13" - "@react-aria/interactions" "^3.25.6" - "@react-aria/label" "^3.7.22" - "@react-aria/selection" "^3.26.0" - "@react-aria/utils" "^3.31.0" - "@react-stately/list" "^3.13.1" - "@react-types/button" "^3.14.1" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/textfield@^3.18.2": - version "3.18.2" - resolved "https://registry.yarnpkg.com/@react-aria/textfield/-/textfield-3.18.2.tgz#d0198ac9833396f3b831e7e3c4cbe751979a4014" - integrity sha512-G+lM8VYSor6g9Yptc6hLZ6BF+0cq0pYol1z6wdQUQgJN8tg4HPtzq75lsZtlCSIznL3amgRAxJtd0dUrsAnvaQ== - dependencies: - "@react-aria/form" "^3.1.2" - "@react-aria/interactions" "^3.25.6" - "@react-aria/label" "^3.7.22" - "@react-aria/utils" "^3.31.0" - "@react-stately/form" "^3.2.2" - "@react-stately/utils" "^3.10.8" - "@react-types/shared" "^3.32.1" - "@react-types/textfield" "^3.12.6" - "@swc/helpers" "^0.5.0" - -"@react-aria/toast@^3.0.8": - version "3.0.8" - resolved "https://registry.yarnpkg.com/@react-aria/toast/-/toast-3.0.8.tgz#50a751654a4f4917649a2a411f1e28418dc60dd1" - integrity sha512-rfJIms6AkMyQ7ZgKrMZgGfPwGcB/t1JoEwbc1PAmXcAvFI/hzF6YF7ZFDXiq38ucFsP9PnHmbXIzM9w4ccl18A== - dependencies: - "@react-aria/i18n" "^3.12.13" - "@react-aria/interactions" "^3.25.6" - "@react-aria/landmark" "^3.0.7" - "@react-aria/utils" "^3.31.0" - "@react-stately/toast" "^3.1.2" - "@react-types/button" "^3.14.1" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/toggle@^3.12.2": - version "3.12.2" - resolved "https://registry.yarnpkg.com/@react-aria/toggle/-/toggle-3.12.2.tgz#909c7c8b9bbeb2cc93a18297363eebb46354b0d4" - integrity sha512-g25XLYqJuJpt0/YoYz2Rab8ax+hBfbssllcEFh0v0jiwfk2gwTWfRU9KAZUvxIqbV8Nm8EBmrYychDpDcvW1kw== - dependencies: - "@react-aria/interactions" "^3.25.6" - "@react-aria/utils" "^3.31.0" - "@react-stately/toggle" "^3.9.2" - "@react-types/checkbox" "^3.10.2" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/toolbar@3.0.0-beta.21": - version "3.0.0-beta.21" - resolved "https://registry.yarnpkg.com/@react-aria/toolbar/-/toolbar-3.0.0-beta.21.tgz#936929637fb89b1ba562aeeeeeaae6253a952bdd" - integrity sha512-yRCk/GD8g+BhdDgxd3I0a0c8Ni4Wyo6ERzfSoBkPkwQ4X2E2nkopmraM9D0fXw4UcIr4bnmvADzkHXtBN0XrBg== - dependencies: - "@react-aria/focus" "^3.21.2" - "@react-aria/i18n" "^3.12.13" - "@react-aria/utils" "^3.31.0" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/tooltip@^3.8.8": - version "3.8.8" - resolved "https://registry.yarnpkg.com/@react-aria/tooltip/-/tooltip-3.8.8.tgz#a9320dd5edc953fbf7a24b9c30312408730e9743" - integrity sha512-CmHUqtXtFWmG4AHMEr9hIVex+oscK6xcM2V47gq9ijNInxe3M6UBu/dBdkgGP/jYv9N7tzCAjTR8nNIHQXwvWw== - dependencies: - "@react-aria/interactions" "^3.25.6" - "@react-aria/utils" "^3.31.0" - "@react-stately/tooltip" "^3.5.8" - "@react-types/shared" "^3.32.1" - "@react-types/tooltip" "^3.4.21" - "@swc/helpers" "^0.5.0" - -"@react-aria/tree@^3.1.4": - version "3.1.4" - resolved "https://registry.yarnpkg.com/@react-aria/tree/-/tree-3.1.4.tgz#d264355534c4af5203a6b6f3a659681504e31f00" - integrity sha512-6pbFeN0dAsCOrFGUKU39CNjft20zCAjLfMqfkRWisL+JkUHI2nq6odUJF5jJTsU1C+1951+3oFOmVxPX+K+akQ== - dependencies: - "@react-aria/gridlist" "^3.14.1" - "@react-aria/i18n" "^3.12.13" - "@react-aria/selection" "^3.26.0" - "@react-aria/utils" "^3.31.0" - "@react-stately/tree" "^3.9.3" - "@react-types/button" "^3.14.1" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/utils@^3.25.2", "@react-aria/utils@^3.31.0": - version "3.31.0" - resolved "https://registry.yarnpkg.com/@react-aria/utils/-/utils-3.31.0.tgz#4710e35bf658234cf4b53eec9742f25e51637b12" - integrity sha512-ABOzCsZrWzf78ysswmguJbx3McQUja7yeGj6/vZo4JVsZNlxAN+E9rs381ExBRI0KzVo6iBTeX5De8eMZPJXig== - dependencies: - "@react-aria/ssr" "^3.9.10" - "@react-stately/flags" "^3.1.2" - "@react-stately/utils" "^3.10.8" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - clsx "^2.0.0" - -"@react-aria/visually-hidden@^3.8.28": - version "3.8.28" - resolved "https://registry.yarnpkg.com/@react-aria/visually-hidden/-/visually-hidden-3.8.28.tgz#61fc99c2d2662e7347abe25a421d138a3a81db46" - integrity sha512-KRRjbVVob2CeBidF24dzufMxBveEUtUu7IM+hpdZKB+gxVROoh4XRLPv9SFmaH89Z7D9To3QoykVZoWD0lan6Q== - dependencies: - "@react-aria/interactions" "^3.25.6" - "@react-aria/utils" "^3.31.0" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-icons/all-files@^4.1.0": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@react-icons/all-files/-/all-files-4.1.0.tgz#477284873a0821928224b6fc84c62d2534d6650b" - integrity sha512-hxBI2UOuVaI3O/BhQfhtb4kcGn9ft12RWAFVMUeNjqqhLsHvFtzIkFaptBJpFDANTKoDfdVoHTKZDlwKCACbMQ== - -"@react-spring/animated@~9.7.5": - version "9.7.5" - resolved "https://registry.yarnpkg.com/@react-spring/animated/-/animated-9.7.5.tgz#eb0373aaf99b879736b380c2829312dae3b05f28" - integrity sha512-Tqrwz7pIlsSDITzxoLS3n/v/YCUHQdOIKtOJf4yL6kYVSDTSmVK1LI1Q3M/uu2Sx4X3pIWF3xLUhlsA6SPNTNg== - dependencies: - "@react-spring/shared" "~9.7.5" - "@react-spring/types" "~9.7.5" - -"@react-spring/core@~9.7.5": - version "9.7.5" - resolved "https://registry.yarnpkg.com/@react-spring/core/-/core-9.7.5.tgz#72159079f52c1c12813d78b52d4f17c0bf6411f7" - integrity sha512-rmEqcxRcu7dWh7MnCcMXLvrf6/SDlSokLaLTxiPlAYi11nN3B5oiCUAblO72o+9z/87j2uzxa2Inm8UbLjXA+w== - dependencies: - "@react-spring/animated" "~9.7.5" - "@react-spring/shared" "~9.7.5" - "@react-spring/types" "~9.7.5" - -"@react-spring/rafz@~9.7.5": - version "9.7.5" - resolved "https://registry.yarnpkg.com/@react-spring/rafz/-/rafz-9.7.5.tgz#ee7959676e7b5d6a3813e8c17d5e50df98b95df9" - integrity sha512-5ZenDQMC48wjUzPAm1EtwQ5Ot3bLIAwwqP2w2owG5KoNdNHpEJV263nGhCeKKmuA3vG2zLLOdu3or6kuDjA6Aw== - -"@react-spring/shared@~9.7.5": - version "9.7.5" - resolved "https://registry.yarnpkg.com/@react-spring/shared/-/shared-9.7.5.tgz#6d513622df6ad750bbbd4dedb4ca0a653ec92073" - integrity sha512-wdtoJrhUeeyD/PP/zo+np2s1Z820Ohr/BbuVYv+3dVLW7WctoiN7std8rISoYoHpUXtbkpesSKuPIw/6U1w1Pw== - dependencies: - "@react-spring/rafz" "~9.7.5" - "@react-spring/types" "~9.7.5" - -"@react-spring/types@~9.7.5": - version "9.7.5" - resolved "https://registry.yarnpkg.com/@react-spring/types/-/types-9.7.5.tgz#e5dd180f3ed985b44fd2cd2f32aa9203752ef3e8" - integrity sha512-HVj7LrZ4ReHWBimBvu2SKND3cDVUPWKLqRTmWe/fNY6o1owGOX0cAHbdPDTMelgBlVbrTKrre6lFkhqGZErK/g== - -"@react-spring/web@9.4.5 || ^9.7.2": - version "9.7.5" - resolved "https://registry.yarnpkg.com/@react-spring/web/-/web-9.7.5.tgz#7d7782560b3a6fb9066b52824690da738605de80" - integrity sha512-lmvqGwpe+CSttsWNZVr+Dg62adtKhauGwLyGE/RRyZ8AAMLgb9x3NDMA5RMElXo+IMyTkPp7nxTB8ZQlmhb6JQ== - dependencies: - "@react-spring/animated" "~9.7.5" - "@react-spring/core" "~9.7.5" - "@react-spring/shared" "~9.7.5" - "@react-spring/types" "~9.7.5" - -"@react-stately/calendar@^3.9.0": - version "3.9.0" - resolved "https://registry.yarnpkg.com/@react-stately/calendar/-/calendar-3.9.0.tgz#22da3b99692eabf53f94a58df7768d2135664c91" - integrity sha512-U5Nf2kx9gDhJRxdDUm5gjfyUlt/uUfOvM1vDW2UA62cA6+2k2cavMLc2wNlXOb/twFtl6p0joYKHG7T4xnEFkg== - dependencies: - "@internationalized/date" "^3.10.0" - "@react-stately/utils" "^3.10.8" - "@react-types/calendar" "^3.8.0" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-stately/checkbox@^3.7.2": - version "3.7.2" - resolved "https://registry.yarnpkg.com/@react-stately/checkbox/-/checkbox-3.7.2.tgz#0a2293e7b97a366f94b7830d3deb2c0e9876c829" - integrity sha512-j1ycUVz5JmqhaL6mDZgDNZqBilOB8PBW096sDPFaTtuYreDx2HOd1igxiIvwlvPESZwsJP7FVM3mYnaoXtpKPA== - dependencies: - "@react-stately/form" "^3.2.2" - "@react-stately/utils" "^3.10.8" - "@react-types/checkbox" "^3.10.2" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-stately/collections@^3.12.8": - version "3.12.8" - resolved "https://registry.yarnpkg.com/@react-stately/collections/-/collections-3.12.8.tgz#f38692fb9c6384fb91d1c50052a40e595d3efa2c" - integrity sha512-AceJYLLXt1Y2XIcOPi6LEJSs4G/ubeYW3LqOCQbhfIgMaNqKfQMIfagDnPeJX9FVmPFSlgoCBxb1pTJW2vjCAQ== - dependencies: - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-stately/color@^3.9.2": - version "3.9.2" - resolved "https://registry.yarnpkg.com/@react-stately/color/-/color-3.9.2.tgz#87ac8461a01478208c302efa47582e872ff78c65" - integrity sha512-F+6Do8W3yu/4n7MpzZtbXwVukcLTFYYDIUtpoR+Jl52UmAr9Hf1CQgkyTI2azv1ZMzj1mVrTBhpBL0q27kFZig== - dependencies: - "@internationalized/number" "^3.6.5" - "@internationalized/string" "^3.2.7" - "@react-stately/form" "^3.2.2" - "@react-stately/numberfield" "^3.10.2" - "@react-stately/slider" "^3.7.2" - "@react-stately/utils" "^3.10.8" - "@react-types/color" "^3.1.2" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-stately/combobox@^3.12.0": - version "3.12.0" - resolved "https://registry.yarnpkg.com/@react-stately/combobox/-/combobox-3.12.0.tgz#71e6c9a8ee2f75edc1d233df7b6d7a0b7aeb6fbe" - integrity sha512-A6q9R/7cEa/qoQsBkdslXWvD7ztNLLQ9AhBhVN9QvzrmrH5B4ymUwcTU8lWl22ykH7RRwfonLeLXJL4C+/L2oQ== - dependencies: - "@react-stately/collections" "^3.12.8" - "@react-stately/form" "^3.2.2" - "@react-stately/list" "^3.13.1" - "@react-stately/overlays" "^3.6.20" - "@react-stately/utils" "^3.10.8" - "@react-types/combobox" "^3.13.9" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-stately/data@^3.14.1": - version "3.14.1" - resolved "https://registry.yarnpkg.com/@react-stately/data/-/data-3.14.1.tgz#ba5550dee9d0d8ba10a4f6c763c3251631f73582" - integrity sha512-lDNc4gZ6kVZcrABeeQZPTTnP+1ykNylSvFzAC/Hq1fs8+s54xLRvoENWIyG+yK19N9TIGEoA0AOFG8PoAun43g== - dependencies: - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-stately/datepicker@^3.15.2": - version "3.15.2" - resolved "https://registry.yarnpkg.com/@react-stately/datepicker/-/datepicker-3.15.2.tgz#e873aecb5ec037b2da21b267c365c52443437dcb" - integrity sha512-S5GL+W37chvV8knv9v0JRv0L6hKo732qqabCCHXzOpYxkLIkV4f/y3cHdEzFWzpZ0O0Gkg7WgeYo160xOdBKYg== - dependencies: - "@internationalized/date" "^3.10.0" - "@internationalized/string" "^3.2.7" - "@react-stately/form" "^3.2.2" - "@react-stately/overlays" "^3.6.20" - "@react-stately/utils" "^3.10.8" - "@react-types/datepicker" "^3.13.2" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-stately/disclosure@^3.0.8": - version "3.0.8" - resolved "https://registry.yarnpkg.com/@react-stately/disclosure/-/disclosure-3.0.8.tgz#ff6a3cc61993d25881cb8d6a82fcf829f139e02a" - integrity sha512-/Ce/Z76y85eSBZiemfU/uEyXkBBa1RdfLRaKD13rnfUV7/nS3ae1VtNlsXgmwQjWv2pmAiSuEKYMbZfVL7q/lQ== - dependencies: - "@react-stately/utils" "^3.10.8" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-stately/dnd@^3.7.1": - version "3.7.1" - resolved "https://registry.yarnpkg.com/@react-stately/dnd/-/dnd-3.7.1.tgz#23b2425553fc1cbc76821c96b30ecca1c9d16013" - integrity sha512-O1JBJ4HI1rVNKuoa5NXiC5FCrCEkr9KVBoKNlTZU8/cnQselhbEsUfMglAakO2EuwIaM1tIXoNF5J/N5P+6lTA== - dependencies: - "@react-stately/selection" "^3.20.6" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-stately/flags@^3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@react-stately/flags/-/flags-3.1.2.tgz#5c8e5ae416d37d37e2e583d2fcb3a046293504f2" - integrity sha512-2HjFcZx1MyQXoPqcBGALwWWmgFVUk2TuKVIQxCbRq7fPyWXIl6VHcakCLurdtYC2Iks7zizvz0Idv48MQ38DWg== - dependencies: - "@swc/helpers" "^0.5.0" - -"@react-stately/form@^3.2.2": - version "3.2.2" - resolved "https://registry.yarnpkg.com/@react-stately/form/-/form-3.2.2.tgz#c1ae1264a414dd5e3e8ae0f21baf4814588d8c53" - integrity sha512-soAheOd7oaTO6eNs6LXnfn0tTqvOoe3zN9FvtIhhrErKz9XPc5sUmh3QWwR45+zKbitOi1HOjfA/gifKhZcfWw== - dependencies: - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-stately/grid@^3.11.6": - version "3.11.6" - resolved "https://registry.yarnpkg.com/@react-stately/grid/-/grid-3.11.6.tgz#2993450ec5d0602e794f731fd49b3475f57e5547" - integrity sha512-vWPAkzpeTIsrurHfMubzMuqEw7vKzFhIJeEK5sEcLunyr1rlADwTzeWrHNbPMl66NAIAi70Dr1yNq+kahQyvMA== - dependencies: - "@react-stately/collections" "^3.12.8" - "@react-stately/selection" "^3.20.6" - "@react-types/grid" "^3.3.6" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-stately/list@^3.13.1": - version "3.13.1" - resolved "https://registry.yarnpkg.com/@react-stately/list/-/list-3.13.1.tgz#4afd36a87c8fd991a4447d28cc76d51fffddb837" - integrity sha512-eHaoauh21twbcl0kkwULhVJ+CzYcy1jUjMikNVMHOQdhr4WIBdExf7PmSgKHKqsSPhpGg6IpTCY2dUX3RycjDg== - dependencies: - "@react-stately/collections" "^3.12.8" - "@react-stately/selection" "^3.20.6" - "@react-stately/utils" "^3.10.8" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-stately/menu@^3.9.8": - version "3.9.8" - resolved "https://registry.yarnpkg.com/@react-stately/menu/-/menu-3.9.8.tgz#5c2e781dadc3331bc5b3735fe30bf62616f9145f" - integrity sha512-bo0NOhofnTHLESiYfsSSw6gyXiPVJJ0UlN2igUXtJk5PmyhWjFzUzTzcnd7B028OB0si9w3LIWM3stqz5271Eg== - dependencies: - "@react-stately/overlays" "^3.6.20" - "@react-types/menu" "^3.10.5" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-stately/numberfield@^3.10.2": - version "3.10.2" - resolved "https://registry.yarnpkg.com/@react-stately/numberfield/-/numberfield-3.10.2.tgz#aa1fcaec84cd441ea5e847dd3e9eca784045be21" - integrity sha512-jlKVFYaH3RX5KvQ7a+SAMQuPccZCzxLkeYkBE64u1Zvi7YhJ8hkTMHG/fmZMbk1rHlseE2wfBdk0Rlya3MvoNQ== - dependencies: - "@internationalized/number" "^3.6.5" - "@react-stately/form" "^3.2.2" - "@react-stately/utils" "^3.10.8" - "@react-types/numberfield" "^3.8.15" - "@swc/helpers" "^0.5.0" - -"@react-stately/overlays@^3.6.20": - version "3.6.20" - resolved "https://registry.yarnpkg.com/@react-stately/overlays/-/overlays-3.6.20.tgz#e638ad0e073b6cf1d27f018aa41a4ce0fbae5f5b" - integrity sha512-YAIe+uI8GUXX8F/0Pzr53YeC5c/bjqbzDFlV8NKfdlCPa6+Jp4B/IlYVjIooBj9+94QvbQdjylegvYWK/iPwlg== - dependencies: - "@react-stately/utils" "^3.10.8" - "@react-types/overlays" "^3.9.2" - "@swc/helpers" "^0.5.0" - -"@react-stately/radio@^3.11.2": - version "3.11.2" - resolved "https://registry.yarnpkg.com/@react-stately/radio/-/radio-3.11.2.tgz#a149fb9448dc258441662893f83a70e88e4d4aea" - integrity sha512-UM7L6AW+k8edhSBUEPZAqiWNRNadfOKK7BrCXyBiG79zTz0zPcXRR+N+gzkDn7EMSawDeyK1SHYUuoSltTactg== - dependencies: - "@react-stately/form" "^3.2.2" - "@react-stately/utils" "^3.10.8" - "@react-types/radio" "^3.9.2" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-stately/searchfield@^3.5.16": - version "3.5.16" - resolved "https://registry.yarnpkg.com/@react-stately/searchfield/-/searchfield-3.5.16.tgz#3b768870d08fa2ef7747513d02d167717961d548" - integrity sha512-MRfqT1lZ24r94GuFNcGJXsfijZoWjSMySCT60T6NXtbOzVPuAF3K+pL70Rayq/EWLJjS2NPHND11VTs0VdcE0Q== - dependencies: - "@react-stately/utils" "^3.10.8" - "@react-types/searchfield" "^3.6.6" - "@swc/helpers" "^0.5.0" - -"@react-stately/select@^3.8.0": - version "3.8.0" - resolved "https://registry.yarnpkg.com/@react-stately/select/-/select-3.8.0.tgz#ccb1b7d6d0f40b166444f3df27273892854ff23e" - integrity sha512-A721nlt0DSCDit0wKvhcrXFTG5Vv1qkEVkeKvobmETZy6piKvwh0aaN8iQno5AFuZaj1iOZeNjZ/20TsDJR/4A== - dependencies: - "@react-stately/form" "^3.2.2" - "@react-stately/list" "^3.13.1" - "@react-stately/overlays" "^3.6.20" - "@react-stately/utils" "^3.10.8" - "@react-types/select" "^3.11.0" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-stately/selection@^3.20.6": - version "3.20.6" - resolved "https://registry.yarnpkg.com/@react-stately/selection/-/selection-3.20.6.tgz#17d4d4553403de6ab690172a8d36e0423a5173fb" - integrity sha512-a0bjuP2pJYPKEiedz2Us1W1aSz0iHRuyeQEdBOyL6Z6VUa6hIMq9H60kvseir2T85cOa4QggizuRV7mcO6bU5w== - dependencies: - "@react-stately/collections" "^3.12.8" - "@react-stately/utils" "^3.10.8" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-stately/slider@^3.7.2": - version "3.7.2" - resolved "https://registry.yarnpkg.com/@react-stately/slider/-/slider-3.7.2.tgz#9dfe6f7e74397f717b1623bc06ba8e375510d056" - integrity sha512-EVBHUdUYwj++XqAEiQg2fGi8Reccznba0uyQ3gPejF0pAc390Q/J5aqiTEDfiCM7uJ6WHxTM6lcCqHQBISk2dQ== - dependencies: - "@react-stately/utils" "^3.10.8" - "@react-types/shared" "^3.32.1" - "@react-types/slider" "^3.8.2" - "@swc/helpers" "^0.5.0" - -"@react-stately/table@^3.15.1": - version "3.15.1" - resolved "https://registry.yarnpkg.com/@react-stately/table/-/table-3.15.1.tgz#3a2f5ca0788cea200c4c96858604fb4c0139f8b0" - integrity sha512-MhMAgE/LgAzHcAn1P3p/nQErzJ6DiixSJ1AOt2JlnAKEb5YJg4ATKWCb2IjBLwywt9ZCzfm3KMUzkctZqAoxwA== - dependencies: - "@react-stately/collections" "^3.12.8" - "@react-stately/flags" "^3.1.2" - "@react-stately/grid" "^3.11.6" - "@react-stately/selection" "^3.20.6" - "@react-stately/utils" "^3.10.8" - "@react-types/grid" "^3.3.6" - "@react-types/shared" "^3.32.1" - "@react-types/table" "^3.13.4" - "@swc/helpers" "^0.5.0" - -"@react-stately/tabs@^3.8.6": - version "3.8.6" - resolved "https://registry.yarnpkg.com/@react-stately/tabs/-/tabs-3.8.6.tgz#c71e3ed2462d89ad9c06fb78c69b2069625c68fd" - integrity sha512-9RYxmgjVIxUpIsGKPIF7uRoHWOEz8muwaYiStCVeyiYBPmarvZoIYtTXcwSMN/vEs7heVN5uGCL6/bfdY4+WiA== - dependencies: - "@react-stately/list" "^3.13.1" - "@react-types/shared" "^3.32.1" - "@react-types/tabs" "^3.3.19" - "@swc/helpers" "^0.5.0" - -"@react-stately/toast@^3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@react-stately/toast/-/toast-3.1.2.tgz#0502040b6bd57479eaba1bca2f4c66e9e957e55a" - integrity sha512-HiInm7bck32khFBHZThTQaAF6e6/qm57F4mYRWdTq8IVeGDzpkbUYibnLxRhk0UZ5ybc6me+nqqPkG/lVmM42Q== - dependencies: - "@swc/helpers" "^0.5.0" - use-sync-external-store "^1.4.0" - -"@react-stately/toggle@^3.9.2": - version "3.9.2" - resolved "https://registry.yarnpkg.com/@react-stately/toggle/-/toggle-3.9.2.tgz#8a50def68efdcefa268a870deda8bb65e5f054a8" - integrity sha512-dOxs9wrVXHUmA7lc8l+N9NbTJMAaXcYsnNGsMwfXIXQ3rdq+IjWGNYJ52UmNQyRYFcg0jrzRrU16TyGbNjOdNQ== - dependencies: - "@react-stately/utils" "^3.10.8" - "@react-types/checkbox" "^3.10.2" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-stately/tooltip@^3.5.8": - version "3.5.8" - resolved "https://registry.yarnpkg.com/@react-stately/tooltip/-/tooltip-3.5.8.tgz#c4a329c63294e8ccae3d9ee7853d40c2fb93ce73" - integrity sha512-gkcUx2ROhCiGNAYd2BaTejakXUUNLPnnoJ5+V/mN480pN+OrO8/2V9pqb/IQmpqxLsso93zkM3A4wFHHLBBmPQ== - dependencies: - "@react-stately/overlays" "^3.6.20" - "@react-types/tooltip" "^3.4.21" - "@swc/helpers" "^0.5.0" - -"@react-stately/tree@^3.9.3": - version "3.9.3" - resolved "https://registry.yarnpkg.com/@react-stately/tree/-/tree-3.9.3.tgz#398de3406d2a06477bb0af2bdb2a0021265eeade" - integrity sha512-ZngG79nLFxE/GYmpwX6E/Rma2MMkzdoJPRI3iWk3dgqnGMMzpPnUp/cvjDsU3UHF7xDVusC5BT6pjWN0uxCIFQ== - dependencies: - "@react-stately/collections" "^3.12.8" - "@react-stately/selection" "^3.20.6" - "@react-stately/utils" "^3.10.8" - "@react-types/shared" "^3.32.1" - "@swc/helpers" "^0.5.0" - -"@react-stately/utils@^3.10.8": - version "3.10.8" - resolved "https://registry.yarnpkg.com/@react-stately/utils/-/utils-3.10.8.tgz#fdb9d172f7bbc2d083e69190f5ef0edfa4b4392f" - integrity sha512-SN3/h7SzRsusVQjQ4v10LaVsDc81jyyR0DD5HnsQitm/I5WDpaSr2nRHtyloPFU48jlql1XX/S04T2DLQM7Y3g== - dependencies: - "@swc/helpers" "^0.5.0" - -"@react-types/breadcrumbs@^3.7.17": - version "3.7.17" - resolved "https://registry.yarnpkg.com/@react-types/breadcrumbs/-/breadcrumbs-3.7.17.tgz#e584352cc4f79e638e20774af04f28064cd9b66b" - integrity sha512-IhvVTcfli5o/UDlGACXxjlor2afGlMQA8pNR3faH0bBUay1Fmm3IWktVw9Xwmk+KraV2RTAg9e+E6p8DOQZfiw== - dependencies: - "@react-types/link" "^3.6.5" - "@react-types/shared" "^3.32.1" - -"@react-types/button@^3.14.1": - version "3.14.1" - resolved "https://registry.yarnpkg.com/@react-types/button/-/button-3.14.1.tgz#41c25f7c7dd1b31a359a6af9cbec5bed5dbb5aa1" - integrity sha512-D8C4IEwKB7zEtiWYVJ3WE/5HDcWlze9mLWQ5hfsBfpePyWCgO3bT/+wjb/7pJvcAocrkXo90QrMm85LcpBtrpg== - dependencies: - "@react-types/shared" "^3.32.1" - -"@react-types/calendar@^3.8.0": - version "3.8.0" - resolved "https://registry.yarnpkg.com/@react-types/calendar/-/calendar-3.8.0.tgz#51dad3445586f1c22886c35499cfcc872462a30f" - integrity sha512-ZDZgfZgbz1ydWOFs1mH7QFfX3ioJrmb3Y/lkoubQE0HWXLZzyYNvhhKyFJRS1QJ40IofLSBHriwbQb/tsUnGlw== - dependencies: - "@internationalized/date" "^3.10.0" - "@react-types/shared" "^3.32.1" - -"@react-types/checkbox@^3.10.2": - version "3.10.2" - resolved "https://registry.yarnpkg.com/@react-types/checkbox/-/checkbox-3.10.2.tgz#0190c9690e3649348a4d7045b168cbda657ce9de" - integrity sha512-ktPkl6ZfIdGS1tIaGSU/2S5Agf2NvXI9qAgtdMDNva0oLyAZ4RLQb6WecPvofw1J7YKXu0VA5Mu7nlX+FM2weQ== - dependencies: - "@react-types/shared" "^3.32.1" - -"@react-types/color@^3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@react-types/color/-/color-3.1.2.tgz#06a0e81b463f3a8d4553e7cd535b2881d721e231" - integrity sha512-NP0TAY3j4tlMztOp/bBfMlPwC9AQKTjSiTFmc2oQNkx5M4sl3QpPqFPosdt7jZ8M4nItvfCWZrlZGjST4SB83A== - dependencies: - "@react-types/shared" "^3.32.1" - "@react-types/slider" "^3.8.2" - -"@react-types/combobox@^3.13.9": - version "3.13.9" - resolved "https://registry.yarnpkg.com/@react-types/combobox/-/combobox-3.13.9.tgz#58bc5c39ca1d7bdbb4beebf79d2ba11b337e927f" - integrity sha512-G6GmLbzVkLW6VScxPAr/RtliEyPhBClfYaIllK1IZv+Z42SVnOpKzhnoe79BpmiFqy1AaC3+LjZX783mrsHCwA== - dependencies: - "@react-types/shared" "^3.32.1" - -"@react-types/datepicker@^3.13.2": - version "3.13.2" - resolved "https://registry.yarnpkg.com/@react-types/datepicker/-/datepicker-3.13.2.tgz#775e43b6edcb8d3d5968e0a35cfacd14be3c847c" - integrity sha512-+M6UZxJnejYY8kz0spbY/hP08QJ5rsZ3aNarRQQHc48xV2oelFLX5MhAqizfLEsvyfb0JYrhWoh4z1xZtAmYCg== - dependencies: - "@internationalized/date" "^3.10.0" - "@react-types/calendar" "^3.8.0" - "@react-types/overlays" "^3.9.2" - "@react-types/shared" "^3.32.1" - -"@react-types/dialog@^3.5.22": - version "3.5.22" - resolved "https://registry.yarnpkg.com/@react-types/dialog/-/dialog-3.5.22.tgz#ed772c303042c6ee5e8a9bc9e58b5b9d08ed634b" - integrity sha512-smSvzOcqKE196rWk0oqJDnz+ox5JM5+OT0PmmJXiUD4q7P5g32O6W5Bg7hMIFUI9clBtngo8kLaX2iMg+GqAzg== - dependencies: - "@react-types/overlays" "^3.9.2" - "@react-types/shared" "^3.32.1" - -"@react-types/grid@^3.3.6": - version "3.3.6" - resolved "https://registry.yarnpkg.com/@react-types/grid/-/grid-3.3.6.tgz#9fc60f5baa8a1668bb2257a981dd514dd64706c3" - integrity sha512-vIZJlYTii2n1We9nAugXwM2wpcpsC6JigJFBd6vGhStRdRWRoU4yv1Gc98Usbx0FQ/J7GLVIgeG8+1VMTKBdxw== - dependencies: - "@react-types/shared" "^3.32.1" - -"@react-types/link@^3.6.5": - version "3.6.5" - resolved "https://registry.yarnpkg.com/@react-types/link/-/link-3.6.5.tgz#28cf2b90f69e83af7ff507021eec0449f148eb45" - integrity sha512-+I2s3XWBEvLrzts0GnNeA84mUkwo+a7kLUWoaJkW0TOBDG7my95HFYxF9WnqKye7NgpOkCqz4s3oW96xPdIniQ== - dependencies: - "@react-types/shared" "^3.32.1" - -"@react-types/listbox@^3.7.4": - version "3.7.4" - resolved "https://registry.yarnpkg.com/@react-types/listbox/-/listbox-3.7.4.tgz#712329de62c0fddf44c062bb18c51135309c9fe8" - integrity sha512-p4YEpTl/VQGrqVE8GIfqTS5LkT5jtjDTbVeZgrkPnX/fiPhsfbTPiZ6g0FNap4+aOGJFGEEZUv2q4vx+rCORww== - dependencies: - "@react-types/shared" "^3.32.1" - -"@react-types/menu@^3.10.5": - version "3.10.5" - resolved "https://registry.yarnpkg.com/@react-types/menu/-/menu-3.10.5.tgz#0e3a66aab3c636dc3ef965529640bb678b13a431" - integrity sha512-HBTrKll2hm0VKJNM4ubIv1L9MNo8JuOnm2G3M+wXvb6EYIyDNxxJkhjsqsGpUXJdAOSkacHBDcNh2HsZABNX4A== - dependencies: - "@react-types/overlays" "^3.9.2" - "@react-types/shared" "^3.32.1" - -"@react-types/meter@^3.4.13": - version "3.4.13" - resolved "https://registry.yarnpkg.com/@react-types/meter/-/meter-3.4.13.tgz#ddd54e1d56a9af79646d832a3cf4a8979e473ead" - integrity sha512-EiarfbpHcvmeyXvXcr6XLaHkNHuGc4g7fBVEiDPwssFJKKfbUzqnnknDxPjyspqUVRcXC08CokS98J1jYobqDg== - dependencies: - "@react-types/progress" "^3.5.16" - -"@react-types/numberfield@^3.8.15": - version "3.8.15" - resolved "https://registry.yarnpkg.com/@react-types/numberfield/-/numberfield-3.8.15.tgz#0fcd77217bae5d7a2bf35d41c7eb61d8ae52bc03" - integrity sha512-97r92D23GKCOjGIGMeW9nt+/KlfM3GeWH39Czcmd2/D5y3k6z4j0avbsfx2OttCtJszrnENjw3GraYGYI2KosQ== - dependencies: - "@react-types/shared" "^3.32.1" - -"@react-types/overlays@^3.9.2": - version "3.9.2" - resolved "https://registry.yarnpkg.com/@react-types/overlays/-/overlays-3.9.2.tgz#721dc248afcb42db988391037a6386bb61556cd4" - integrity sha512-Q0cRPcBGzNGmC8dBuHyoPR7N3057KTS5g+vZfQ53k8WwmilXBtemFJPLsogJbspuewQ/QJ3o2HYsp2pne7/iNw== - dependencies: - "@react-types/shared" "^3.32.1" - -"@react-types/progress@^3.5.16": - version "3.5.16" - resolved "https://registry.yarnpkg.com/@react-types/progress/-/progress-3.5.16.tgz#f40e1b674e630276d6412297a92eb0dd3761d426" - integrity sha512-I9tSdCFfvQ7gHJtm90VAKgwdTWXQgVNvLRStEc0z9h+bXBxdvZb+QuiRPERChwFQ9VkK4p4rDqaFo69nDqWkpw== - dependencies: - "@react-types/shared" "^3.32.1" - -"@react-types/radio@^3.9.2": - version "3.9.2" - resolved "https://registry.yarnpkg.com/@react-types/radio/-/radio-3.9.2.tgz#c6ac396b49cc03334e4bb63a96f366effce3a615" - integrity sha512-3UcJXu37JrTkRyP4GJPDBU7NmDTInrEdOe+bVzA1j4EegzdkJmLBkLg5cLDAbpiEHB+xIsvbJdx6dxeMuc+H3g== - dependencies: - "@react-types/shared" "^3.32.1" - -"@react-types/searchfield@^3.6.6": - version "3.6.6" - resolved "https://registry.yarnpkg.com/@react-types/searchfield/-/searchfield-3.6.6.tgz#fd41bd78246789ac4284462abe222b6f85d191b2" - integrity sha512-cl3itr/fk7wbIQc2Gz5Ie8aVeUmPjVX/mRGS5/EXlmzycAKNYTvqf2mlxwObLndtLISmt7IgNjRRhbUUDI8Ang== - dependencies: - "@react-types/shared" "^3.32.1" - "@react-types/textfield" "^3.12.6" - -"@react-types/select@^3.11.0": - version "3.11.0" - resolved "https://registry.yarnpkg.com/@react-types/select/-/select-3.11.0.tgz#808aec480f0cc20075953af9717ca38d1eb15b8d" - integrity sha512-SzIsMFVPCbXE1Z1TLfpdfiwJ1xnIkcL1/CjGilmUKkNk5uT7rYX1xCJqWCjXI0vAU1xM4Qn+T3n8de4fw6HRBg== - dependencies: - "@react-types/shared" "^3.32.1" - -"@react-types/shared@^3.32.1": - version "3.32.1" - resolved "https://registry.yarnpkg.com/@react-types/shared/-/shared-3.32.1.tgz#abfeb839d65d0abe923576f34ac08342c25dfa55" - integrity sha512-famxyD5emrGGpFuUlgOP6fVW2h/ZaF405G5KDi3zPHzyjAWys/8W6NAVJtNbkCkhedmvL0xOhvt8feGXyXaw5w== - -"@react-types/slider@^3.8.2": - version "3.8.2" - resolved "https://registry.yarnpkg.com/@react-types/slider/-/slider-3.8.2.tgz#37e02c42514aca842954c715082d1ae06a661ee4" - integrity sha512-MQYZP76OEOYe7/yA2To+Dl0LNb0cKKnvh5JtvNvDnAvEprn1RuLiay8Oi/rTtXmc2KmBa4VdTcsXsmkbbkeN2Q== - dependencies: - "@react-types/shared" "^3.32.1" - -"@react-types/switch@^3.5.15": - version "3.5.15" - resolved "https://registry.yarnpkg.com/@react-types/switch/-/switch-3.5.15.tgz#43806d6e7034d1d07e20c89ec9618e607fef9e62" - integrity sha512-r/ouGWQmIeHyYSP1e5luET+oiR7N7cLrAlWsrAfYRWHxqXOSNQloQnZJ3PLHrKFT02fsrQhx2rHaK2LfKeyN3A== - dependencies: - "@react-types/shared" "^3.32.1" - -"@react-types/table@^3.13.4": - version "3.13.4" - resolved "https://registry.yarnpkg.com/@react-types/table/-/table-3.13.4.tgz#c3d5952d4bd2a04992255850538856829b12c99a" - integrity sha512-I/DYiZQl6aNbMmjk90J9SOhkzVDZvyA3Vn3wMWCiajkMNjvubFhTfda5DDf2SgFP5l0Yh6TGGH5XumRv9LqL5Q== - dependencies: - "@react-types/grid" "^3.3.6" - "@react-types/shared" "^3.32.1" - -"@react-types/tabs@^3.3.19": - version "3.3.19" - resolved "https://registry.yarnpkg.com/@react-types/tabs/-/tabs-3.3.19.tgz#344a22bd15400b738aebc26918cf96dacde1ffef" - integrity sha512-fE+qI43yR5pAMpeqPxGqQq9jDHXEPqXskuxNHERMW0PYMdPyem2Cw6goc5F4qeZO3Hf6uPZgHkvJz2OAq7TbBw== - dependencies: - "@react-types/shared" "^3.32.1" - -"@react-types/textfield@^3.12.6": - version "3.12.6" - resolved "https://registry.yarnpkg.com/@react-types/textfield/-/textfield-3.12.6.tgz#0f90a4108c8d75e7c2c26753e760cd580339be12" - integrity sha512-hpEVKE+M3uUkTjw2WrX1NrH/B3rqDJFUa+ViNK2eVranLY4ZwFqbqaYXSzHupOF3ecSjJJv2C103JrwFvx6TPQ== - dependencies: - "@react-types/shared" "^3.32.1" - -"@react-types/tooltip@^3.4.21": - version "3.4.21" - resolved "https://registry.yarnpkg.com/@react-types/tooltip/-/tooltip-3.4.21.tgz#63596cf87d7166499656bc15f212c75c9ffa8991" - integrity sha512-ugGHOZU6WbOdeTdbjnaEc+Ms7/WhsUCg+T3PCOIeOT9FG02Ce189yJ/+hd7oqL/tVwIhEMYJIqSCgSELFox+QA== - dependencies: - "@react-types/overlays" "^3.9.2" - "@react-types/shared" "^3.32.1" - -"@remix-run/router@1.23.0": - version "1.23.0" - resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.23.0.tgz#35390d0e7779626c026b11376da6789eb8389242" - integrity sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA== - -"@rtsao/scc@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8" - integrity sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g== - -"@rushstack/eslint-patch@^1.10.3": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@rushstack/eslint-patch/-/eslint-patch-1.14.1.tgz#5f7c5c335643cff62ad8e6a9432d708a9c51e98c" - integrity sha512-jGTk8UD/RdjsNZW8qq10r0RBvxL8OWtoT+kImlzPDFilmozzM+9QmIJsmze9UiSBrFU45ZxhTYBypn9q9z/VfQ== - -"@sideway/address@^4.1.5": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.5.tgz#4bc149a0076623ced99ca8208ba780d65a99b9d5" - integrity sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q== - dependencies: - "@hapi/hoek" "^9.0.0" - -"@sideway/formula@^3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f" - integrity sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg== - -"@sideway/pinpoint@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" - integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== - -"@sigstore/bundle@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@sigstore/bundle/-/bundle-1.1.0.tgz#17f8d813b09348b16eeed66a8cf1c3d6bd3d04f1" - integrity sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog== - dependencies: - "@sigstore/protobuf-specs" "^0.2.0" - -"@sigstore/protobuf-specs@^0.2.0": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@sigstore/protobuf-specs/-/protobuf-specs-0.2.1.tgz#be9ef4f3c38052c43bd399d3f792c97ff9e2277b" - integrity sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A== - -"@sigstore/sign@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@sigstore/sign/-/sign-1.0.0.tgz#6b08ebc2f6c92aa5acb07a49784cb6738796f7b4" - integrity sha512-INxFVNQteLtcfGmcoldzV6Je0sbbfh9I16DM4yJPw3j5+TFP8X6uIiA18mvpEa9yyeycAKgPmOA3X9hVdVTPUA== - dependencies: - "@sigstore/bundle" "^1.1.0" - "@sigstore/protobuf-specs" "^0.2.0" - make-fetch-happen "^11.0.1" - -"@sigstore/tuf@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@sigstore/tuf/-/tuf-1.0.3.tgz#2a65986772ede996485728f027b0514c0b70b160" - integrity sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg== - dependencies: - "@sigstore/protobuf-specs" "^0.2.0" - tuf-js "^1.1.7" - -"@sinclair/typebox@^0.27.8": - version "0.27.8" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" - integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== - -"@sinclair/typebox@^0.34.0": - version "0.34.41" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.34.41.tgz#aa51a6c1946df2c5a11494a2cdb9318e026db16c" - integrity sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g== - -"@sinonjs/commons@^1.7.0": - version "1.8.6" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.6.tgz#80c516a4dc264c2a69115e7578d62581ff455ed9" - integrity sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ== - dependencies: - type-detect "4.0.8" - -"@sinonjs/commons@^3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.1.tgz#1029357e44ca901a615585f6d27738dbc89084cd" - integrity sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ== - dependencies: - type-detect "4.0.8" - -"@sinonjs/fake-timers@^15.0.0": - version "15.3.2" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-15.3.2.tgz#afecc36681e26aab9e0fe809fd9ad578096a3058" - integrity sha512-mrn35Jl2pCpns+mE3HaZa1yPN5EYCRgiMI+135COjr2hr8Cls9DXqIZ57vZe2cz7y2XVSq92tcs6kGQcT1J8Rw== - dependencies: - "@sinonjs/commons" "^3.0.1" - -"@sinonjs/fake-timers@^8.0.1": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" - integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== - dependencies: - "@sinonjs/commons" "^1.7.0" - -"@storybook/addon-actions@6.5.16", "@storybook/addon-actions@^6.5.8": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-6.5.16.tgz#2d7679f64899bef165a338582cb928102a09e364" - integrity sha512-aADjilFmuD6TNGz2CRPSupnyiA/IGkPJHDBTqMpsDXTUr8xnuD122xkIhg6UxmCM2y1c+ncwYXy3WPK2xXK57g== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - fast-deep-equal "^3.1.3" - global "^4.4.0" - lodash "^4.17.21" - polished "^4.2.2" - prop-types "^15.7.2" - react-inspector "^5.1.0" - regenerator-runtime "^0.13.7" - telejson "^6.0.8" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - uuid-browser "^3.1.0" - -"@storybook/addon-backgrounds@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-6.5.16.tgz#a93ea53955f714b4a4432dda1b88942cc87dd390" - integrity sha512-t7qooZ892BruhilFmzYPbysFwpULt/q4zYXNSmKVbAYta8UVvitjcU4F18p8FpWd9WvhiTr0SDlyhNZuzvDfug== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - global "^4.4.0" - memoizerific "^1.11.3" - regenerator-runtime "^0.13.7" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - -"@storybook/addon-controls@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-controls/-/addon-controls-6.5.16.tgz#5017805b8ca413edf6e9d87b90a9436e79eb5e59" - integrity sha512-kShSGjq1MjmmyL3l8i+uPz6yddtf82mzys0l82VKtcuyjrr5944wYFJ5NTXMfZxrO/U6FeFsfuFZE/k6ex3EMg== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/node-logger" "6.5.16" - "@storybook/store" "6.5.16" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - lodash "^4.17.21" - ts-dedent "^2.0.0" - -"@storybook/addon-docs@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-6.5.16.tgz#3de912f51fb8e48b9a53b11a5b1cede067acbe70" - integrity sha512-QM9WDZG9P02UvbzLu947a8ZngOrQeAKAT8jCibQFM/+RJ39xBlfm8rm+cQy3dm94wgtjmVkA3mKGOV/yrrsddg== - dependencies: - "@babel/plugin-transform-react-jsx" "^7.12.12" - "@babel/preset-env" "^7.12.11" - "@jest/transform" "^26.6.2" - "@mdx-js/react" "^1.6.22" - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/docs-tools" "6.5.16" - "@storybook/mdx1-csf" "^0.0.1" - "@storybook/node-logger" "6.5.16" - "@storybook/postinstall" "6.5.16" - "@storybook/preview-web" "6.5.16" - "@storybook/source-loader" "6.5.16" - "@storybook/store" "6.5.16" - "@storybook/theming" "6.5.16" - babel-loader "^8.0.0" - core-js "^3.8.2" - fast-deep-equal "^3.1.3" - global "^4.4.0" - lodash "^4.17.21" - regenerator-runtime "^0.13.7" - remark-external-links "^8.0.0" - remark-slug "^6.0.0" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - -"@storybook/addon-essentials@^6.5.8": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-essentials/-/addon-essentials-6.5.16.tgz#815991366a4a90b60bf0aa4022eb0bb0c2bb536d" - integrity sha512-TeoMr6tEit4Pe91GH6f8g/oar1P4M0JL9S6oMcFxxrhhtOGO7XkWD5EnfyCx272Ok2VYfE58FNBTGPNBVIqYKQ== - dependencies: - "@storybook/addon-actions" "6.5.16" - "@storybook/addon-backgrounds" "6.5.16" - "@storybook/addon-controls" "6.5.16" - "@storybook/addon-docs" "6.5.16" - "@storybook/addon-measure" "6.5.16" - "@storybook/addon-outline" "6.5.16" - "@storybook/addon-toolbars" "6.5.16" - "@storybook/addon-viewport" "6.5.16" - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/node-logger" "6.5.16" - core-js "^3.8.2" - regenerator-runtime "^0.13.7" - ts-dedent "^2.0.0" - -"@storybook/addon-interactions@^6.5.8": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-interactions/-/addon-interactions-6.5.16.tgz#2855fe946c9d8595c3486ae696f1d99e7fca582b" - integrity sha512-DdTtyp3DgB/SpbM1GQgMnuSEBCkadxmj1mUcPk+Wp2iY+fDwsuoRDkr1H9Oe7IvlBKe7ciR79LEjoaABXNdw4w== - dependencies: - "@devtools-ds/object-inspector" "^1.1.2" - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/instrumenter" "6.5.16" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - global "^4.4.0" - jest-mock "^27.0.6" - polished "^4.2.2" - ts-dedent "^2.2.0" - -"@storybook/addon-links@^6.5.8": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-links/-/addon-links-6.5.16.tgz#cacb20cd0656f0681a874709d428d3f3577828c3" - integrity sha512-P/mmqK57NGXnR0i3d/T5B0rIt0Lg8Yq+qionRr3LK3AwG/4yGnYt4GNomLEknn/eEwABYq1Q/Z1aOpgIhNdq5A== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/router" "6.5.16" - "@types/qs" "^6.9.5" - core-js "^3.8.2" - global "^4.4.0" - prop-types "^15.7.2" - qs "^6.10.0" - regenerator-runtime "^0.13.7" - ts-dedent "^2.0.0" - -"@storybook/addon-measure@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-measure/-/addon-measure-6.5.16.tgz#7f7bfdc0b624fbf18386b20a5e460027bf87115c" - integrity sha512-DMwnXkmM2L6POTh4KaOWvOAtQ2p9Tr1UUNxz6VXiN5cKFohpCs6x0txdLU5WN8eWIq0VFsO7u5ZX34CGCc6gCg== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - core-js "^3.8.2" - global "^4.4.0" - -"@storybook/addon-outline@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-outline/-/addon-outline-6.5.16.tgz#6985b6a0b0122db36561c81dde2aa851604657b7" - integrity sha512-0du96nha4qltexO0Xq1xB7LeRSbqjC9XqtZLflXG7/X3ABoPD2cXgOV97eeaXUodIyb2qYBbHUfftBeA75x0+w== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - core-js "^3.8.2" - global "^4.4.0" - regenerator-runtime "^0.13.7" - ts-dedent "^2.0.0" - -"@storybook/addon-toolbars@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-toolbars/-/addon-toolbars-6.5.16.tgz#9de04f9cc64b68d6cb680aa1c4fbf874e11afa32" - integrity sha512-y3PuUKiwOWrAvqx1YdUvArg0UaAwmboXFeR2bkrowk1xcT+xnRO3rML4npFeUl26OQ1FzwxX/cw6nknREBBLEA== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - regenerator-runtime "^0.13.7" - -"@storybook/addon-viewport@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-viewport/-/addon-viewport-6.5.16.tgz#226aa0ab93df68264269eb31adb104e7e48f6c68" - integrity sha512-1Vyqf1U6Qng6TXlf4SdqUKyizlw1Wn6+qW8YeA2q1lbkJqn3UlnHXIp8Q0t/5q1dK5BFtREox3+jkGwbJrzkmA== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - global "^4.4.0" - memoizerific "^1.11.3" - prop-types "^15.7.2" - regenerator-runtime "^0.13.7" - -"@storybook/addons@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-6.5.16.tgz#07e8f2205f86fa4c9dada719e3e096cb468e3cdd" - integrity sha512-p3DqQi+8QRL5k7jXhXmJZLsE/GqHqyY6PcoA1oNTJr0try48uhTGUOYkgzmqtDaa/qPFO5LP+xCPzZXckGtquQ== - dependencies: - "@storybook/api" "6.5.16" - "@storybook/channels" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/router" "6.5.16" - "@storybook/theming" "6.5.16" - "@types/webpack-env" "^1.16.0" - core-js "^3.8.2" - global "^4.4.0" - regenerator-runtime "^0.13.7" - -"@storybook/api@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/api/-/api-6.5.16.tgz#897915b76de05587fd702951d5d836f708043662" - integrity sha512-HOsuT8iomqeTMQJrRx5U8nsC7lJTwRr1DhdD0SzlqL4c80S/7uuCy4IZvOt4sYQjOzW5fOo/kamcoBXyLproTA== - dependencies: - "@storybook/channels" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/router" "6.5.16" - "@storybook/semver" "^7.3.2" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - fast-deep-equal "^3.1.3" - global "^4.4.0" - lodash "^4.17.21" - memoizerific "^1.11.3" - regenerator-runtime "^0.13.7" - store2 "^2.12.0" - telejson "^6.0.8" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - -"@storybook/builder-webpack4@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/builder-webpack4/-/builder-webpack4-6.5.16.tgz#ac468d244835a7f3bd01936398fee47244da35c1" - integrity sha512-YqDIrVNsUo8r9xc6AxsYDLxVYtMgl5Bxk+8/h1adsOko+jAFhdg6hOcAVxEmoSI0TMASOOVMFlT2hr23ppN2rQ== - dependencies: - "@babel/core" "^7.12.10" - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/channel-postmessage" "6.5.16" - "@storybook/channels" "6.5.16" - "@storybook/client-api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/node-logger" "6.5.16" - "@storybook/preview-web" "6.5.16" - "@storybook/router" "6.5.16" - "@storybook/semver" "^7.3.2" - "@storybook/store" "6.5.16" - "@storybook/theming" "6.5.16" - "@storybook/ui" "6.5.16" - "@types/node" "^14.0.10 || ^16.0.0" - "@types/webpack" "^4.41.26" - autoprefixer "^9.8.6" - babel-loader "^8.0.0" - case-sensitive-paths-webpack-plugin "^2.3.0" - core-js "^3.8.2" - css-loader "^3.6.0" - file-loader "^6.2.0" - find-up "^5.0.0" - fork-ts-checker-webpack-plugin "^4.1.6" - glob "^7.1.6" - glob-promise "^3.4.0" - global "^4.4.0" - html-webpack-plugin "^4.0.0" - pnp-webpack-plugin "1.6.4" - postcss "^7.0.36" - postcss-flexbugs-fixes "^4.2.1" - postcss-loader "^4.2.0" - raw-loader "^4.0.2" - stable "^0.1.8" - style-loader "^1.3.0" - terser-webpack-plugin "^4.2.3" - ts-dedent "^2.0.0" - url-loader "^4.1.1" - util-deprecate "^1.0.2" - webpack "4" - webpack-dev-middleware "^3.7.3" - webpack-filter-warnings-plugin "^1.2.1" - webpack-hot-middleware "^2.25.1" - webpack-virtual-modules "^0.2.2" - -"@storybook/builder-webpack5@^6.5.8": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/builder-webpack5/-/builder-webpack5-6.5.16.tgz#2f260e29fbc87f6f3bb3212459048ce37f3fb54e" - integrity sha512-kh8Sofm1sbijaHDWtm0sXabqACHVFjikU/fIkkW786kpjoPIPIec1a+hrLgDsZxMU3I7XapSOaCFzWt6FjVXjg== - dependencies: - "@babel/core" "^7.12.10" - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/channel-postmessage" "6.5.16" - "@storybook/channels" "6.5.16" - "@storybook/client-api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/node-logger" "6.5.16" - "@storybook/preview-web" "6.5.16" - "@storybook/router" "6.5.16" - "@storybook/semver" "^7.3.2" - "@storybook/store" "6.5.16" - "@storybook/theming" "6.5.16" - "@types/node" "^14.0.10 || ^16.0.0" - babel-loader "^8.0.0" - babel-plugin-named-exports-order "^0.0.2" - browser-assert "^1.2.1" - case-sensitive-paths-webpack-plugin "^2.3.0" - core-js "^3.8.2" - css-loader "^5.0.1" - fork-ts-checker-webpack-plugin "^6.0.4" - glob "^7.1.6" - glob-promise "^3.4.0" - html-webpack-plugin "^5.0.0" - path-browserify "^1.0.1" - process "^0.11.10" - stable "^0.1.8" - style-loader "^2.0.0" - terser-webpack-plugin "^5.0.3" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - webpack "^5.9.0" - webpack-dev-middleware "^4.1.0" - webpack-hot-middleware "^2.25.1" - webpack-virtual-modules "^0.4.1" - -"@storybook/channel-postmessage@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-6.5.16.tgz#06167c0a66c06b2b5f8ff01d1dd436fff8119a15" - integrity sha512-fZZSN29dsUArWOx7e7lTdMA9+7zijVwCwbvi2Fo4fqhRLh1DsTb/VXfz1FKMCWAjNlcX7QQvV25tnxbqsD6lyw== - dependencies: - "@storybook/channels" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - core-js "^3.8.2" - global "^4.4.0" - qs "^6.10.0" - telejson "^6.0.8" - -"@storybook/channel-websocket@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/channel-websocket/-/channel-websocket-6.5.16.tgz#41f69ca9444a4dfbf72580b4696900c5b1d2b817" - integrity sha512-wJg2lpBjmRC2GJFzmhB9kxlh109VE58r/0WhFtLbwKvPqsvGf82xkBEl6BtBCvIQ4stzYnj/XijjA8qSi2zpOg== - dependencies: - "@storybook/channels" "6.5.16" - "@storybook/client-logger" "6.5.16" - core-js "^3.8.2" - global "^4.4.0" - telejson "^6.0.8" - -"@storybook/channels@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-6.5.16.tgz#3fb9a3b5666ecb951a2d0cf8b0699b084ef2d3c6" - integrity sha512-VylzaWQZaMozEwZPJdyJoz+0jpDa8GRyaqu9TGG6QGv+KU5POoZaGLDkRE7TzWkyyP0KQLo80K99MssZCpgSeg== - dependencies: - core-js "^3.8.2" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - -"@storybook/client-api@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-6.5.16.tgz#13e5a7c3d1f0f951ec4ef51cfcf2c5aafb560e12" - integrity sha512-i3UwkzzUFw8I+E6fOcgB5sc4oU2fhvaKnqC1mpd9IYGJ9JN9MnGIaVl3Ko28DtFItu/QabC9JsLIJVripFLktQ== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/channel-postmessage" "6.5.16" - "@storybook/channels" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/store" "6.5.16" - "@types/qs" "^6.9.5" - "@types/webpack-env" "^1.16.0" - core-js "^3.8.2" - fast-deep-equal "^3.1.3" - global "^4.4.0" - lodash "^4.17.21" - memoizerific "^1.11.3" - qs "^6.10.0" - regenerator-runtime "^0.13.7" - store2 "^2.12.0" - synchronous-promise "^2.0.15" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - -"@storybook/client-logger@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-6.5.16.tgz#955cc46b389e7151c9eb1585a75e6a0605af61a1" - integrity sha512-pxcNaCj3ItDdicPTXTtmYJE3YC1SjxFrBmHcyrN+nffeNyiMuViJdOOZzzzucTUG0wcOOX8jaSyak+nnHg5H1Q== - dependencies: - core-js "^3.8.2" - global "^4.4.0" - -"@storybook/client-logger@^6.4.0 || >=6.5.0-0": - version "8.6.14" - resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-8.6.14.tgz#2b067b606c4ad5c07458c9d76b0b3a63abe94f76" - integrity sha512-DqB54TiXr58nCS2QO2YxxY14uc0yGEhgTgtw1eIGFEC1RKxgbOos+4lDtwhU7EYI6kHewVlZ4NXi85wnj/Qq+A== - -"@storybook/components@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/components/-/components-6.5.16.tgz#f8dc51213bc08fe32154be964e1e8b0e2f670ed6" - integrity sha512-LzBOFJKITLtDcbW9jXl0/PaG+4xAz25PK8JxPZpIALbmOpYWOAPcO6V9C2heX6e6NgWFMUxjplkULEk9RCQMNA== - dependencies: - "@storybook/client-logger" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - memoizerific "^1.11.3" - qs "^6.10.0" - regenerator-runtime "^0.13.7" - util-deprecate "^1.0.2" - -"@storybook/core-client@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/core-client/-/core-client-6.5.16.tgz#ed2328fd38c6111fe887f6a91b28d9dc2b17092a" - integrity sha512-14IRaDrVtKrQ+gNWC0wPwkCNfkZOKghYV/swCUnQX3rP99defsZK8Hc7xHIYoAiOP5+sc3sweRAxgmFiJeQ1Ig== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/channel-postmessage" "6.5.16" - "@storybook/channel-websocket" "6.5.16" - "@storybook/client-api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/preview-web" "6.5.16" - "@storybook/store" "6.5.16" - "@storybook/ui" "6.5.16" - airbnb-js-shims "^2.2.1" - ansi-to-html "^0.6.11" - core-js "^3.8.2" - global "^4.4.0" - lodash "^4.17.21" - qs "^6.10.0" - regenerator-runtime "^0.13.7" - ts-dedent "^2.0.0" - unfetch "^4.2.0" - util-deprecate "^1.0.2" - -"@storybook/core-common@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/core-common/-/core-common-6.5.16.tgz#db80aa6f220a576a83db821f720e103190a914ae" - integrity sha512-2qtnKP3TTOzt2cp6LXKRTh7XrI9z5VanMnMTgeoFcA5ebnndD4V6BExQUdYPClE/QooLx6blUWNgS9dFEpjSqQ== - dependencies: - "@babel/core" "^7.12.10" - "@babel/plugin-proposal-class-properties" "^7.12.1" - "@babel/plugin-proposal-decorators" "^7.12.12" - "@babel/plugin-proposal-export-default-from" "^7.12.1" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1" - "@babel/plugin-proposal-object-rest-spread" "^7.12.1" - "@babel/plugin-proposal-optional-chaining" "^7.12.7" - "@babel/plugin-proposal-private-methods" "^7.12.1" - "@babel/plugin-proposal-private-property-in-object" "^7.12.1" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-transform-arrow-functions" "^7.12.1" - "@babel/plugin-transform-block-scoping" "^7.12.12" - "@babel/plugin-transform-classes" "^7.12.1" - "@babel/plugin-transform-destructuring" "^7.12.1" - "@babel/plugin-transform-for-of" "^7.12.1" - "@babel/plugin-transform-parameters" "^7.12.1" - "@babel/plugin-transform-shorthand-properties" "^7.12.1" - "@babel/plugin-transform-spread" "^7.12.1" - "@babel/preset-env" "^7.12.11" - "@babel/preset-react" "^7.12.10" - "@babel/preset-typescript" "^7.12.7" - "@babel/register" "^7.12.1" - "@storybook/node-logger" "6.5.16" - "@storybook/semver" "^7.3.2" - "@types/node" "^14.0.10 || ^16.0.0" - "@types/pretty-hrtime" "^1.0.0" - babel-loader "^8.0.0" - babel-plugin-macros "^3.0.1" - babel-plugin-polyfill-corejs3 "^0.1.0" - chalk "^4.1.0" - core-js "^3.8.2" - express "^4.17.1" - file-system-cache "^1.0.5" - find-up "^5.0.0" - fork-ts-checker-webpack-plugin "^6.0.4" - fs-extra "^9.0.1" - glob "^7.1.6" - handlebars "^4.7.7" - interpret "^2.2.0" - json5 "^2.2.3" - lazy-universal-dotenv "^3.0.1" - picomatch "^2.3.0" - pkg-dir "^5.0.0" - pretty-hrtime "^1.0.3" - resolve-from "^5.0.0" - slash "^3.0.0" - telejson "^6.0.8" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - webpack "4" - -"@storybook/core-events@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-6.5.16.tgz#b1c265dac755007dae172d9d4b72656c9e5d7bb3" - integrity sha512-qMZQwmvzpH5F2uwNUllTPg6eZXr2OaYZQRRN8VZJiuorZzDNdAFmiVWMWdkThwmyLEJuQKXxqCL8lMj/7PPM+g== - dependencies: - core-js "^3.8.2" - -"@storybook/core-server@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/core-server/-/core-server-6.5.16.tgz#f40de3413de49388129d29c74e5e48321af03f12" - integrity sha512-/3NPfmNyply395Dm0zaVZ8P9aruwO+tPx4D6/jpw8aqrRSwvAMndPMpoMCm0NXcpSm5rdX+Je4S3JW6JcggFkA== - dependencies: - "@discoveryjs/json-ext" "^0.5.3" - "@storybook/builder-webpack4" "6.5.16" - "@storybook/core-client" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/csf-tools" "6.5.16" - "@storybook/manager-webpack4" "6.5.16" - "@storybook/node-logger" "6.5.16" - "@storybook/semver" "^7.3.2" - "@storybook/store" "6.5.16" - "@storybook/telemetry" "6.5.16" - "@types/node" "^14.0.10 || ^16.0.0" - "@types/node-fetch" "^2.5.7" - "@types/pretty-hrtime" "^1.0.0" - "@types/webpack" "^4.41.26" - better-opn "^2.1.1" - boxen "^5.1.2" - chalk "^4.1.0" - cli-table3 "^0.6.1" - commander "^6.2.1" - compression "^1.7.4" - core-js "^3.8.2" - cpy "^8.1.2" - detect-port "^1.3.0" - express "^4.17.1" - fs-extra "^9.0.1" - global "^4.4.0" - globby "^11.0.2" - ip "^2.0.0" - lodash "^4.17.21" - node-fetch "^2.6.7" - open "^8.4.0" - pretty-hrtime "^1.0.3" - prompts "^2.4.0" - regenerator-runtime "^0.13.7" - serve-favicon "^2.5.0" - slash "^3.0.0" - telejson "^6.0.8" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - watchpack "^2.2.0" - webpack "4" - ws "^8.2.3" - x-default-browser "^0.4.0" - -"@storybook/core@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/core/-/core-6.5.16.tgz#ae994f01327fe81b6e652963c35bac7a74f0da06" - integrity sha512-CEF3QFTsm/VMnMKtRNr4rRdLeIkIG0g1t26WcmxTdSThNPBd8CsWzQJ7Jqu7CKiut+MU4A1LMOwbwCE5F2gmyA== - dependencies: - "@storybook/core-client" "6.5.16" - "@storybook/core-server" "6.5.16" - -"@storybook/csf-tools@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/csf-tools/-/csf-tools-6.5.16.tgz#367889a3ddb33c93261129104ec2958215ec5459" - integrity sha512-+WD4sH/OwAfXZX3IN6/LOZ9D9iGEFcN+Vvgv9wOsLRgsAZ10DG/NK6c1unXKDM/ogJtJYccNI8Hd+qNE/GFV6A== - dependencies: - "@babel/core" "^7.12.10" - "@babel/generator" "^7.12.11" - "@babel/parser" "^7.12.11" - "@babel/plugin-transform-react-jsx" "^7.12.12" - "@babel/preset-env" "^7.12.11" - "@babel/traverse" "^7.12.11" - "@babel/types" "^7.12.11" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/mdx1-csf" "^0.0.1" - core-js "^3.8.2" - fs-extra "^9.0.1" - global "^4.4.0" - regenerator-runtime "^0.13.7" - ts-dedent "^2.0.0" - -"@storybook/csf@0.0.2--canary.4566f4d.1": - version "0.0.2--canary.4566f4d.1" - resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.0.2--canary.4566f4d.1.tgz#dac52a21c40ef198554e71fe4d20d61e17f65327" - integrity sha512-9OVvMVh3t9znYZwb0Svf/YQoxX2gVOeQTGe2bses2yj+a3+OJnCrUF3/hGv6Em7KujtOdL2LL+JnG49oMVGFgQ== - dependencies: - lodash "^4.17.15" - -"@storybook/csf@^0.0.1": - version "0.0.1" - resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.0.1.tgz#95901507dc02f0bc6f9ac8ee1983e2fc5bb98ce6" - integrity sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw== - dependencies: - lodash "^4.17.15" - -"@storybook/docs-tools@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/docs-tools/-/docs-tools-6.5.16.tgz#1ec5433eeab63a214d37ffc4660cdaec9704ac39" - integrity sha512-o+rAWPRGifjBF5xZzTKOqnHN3XQWkl0QFJYVDIiJYJrVll7ExCkpEq/PahOGzIBBV+tpMstJgmKM3lr/lu/jmg== - dependencies: - "@babel/core" "^7.12.10" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/store" "6.5.16" - core-js "^3.8.2" - doctrine "^3.0.0" - lodash "^4.17.21" - regenerator-runtime "^0.13.7" - -"@storybook/global@^5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@storybook/global/-/global-5.0.0.tgz#b793d34b94f572c1d7d9e0f44fac4e0dbc9572ed" - integrity sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ== - -"@storybook/instrumenter@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/instrumenter/-/instrumenter-6.5.16.tgz#62acd94e35f1ec403dbc0145b026dfc042ca2f65" - integrity sha512-q8/GaBk8PA/cL7m5OW+ec5t63+Zja9YvYSPGXrYtW17koSv7OnNPmk6RvI7tIHHO0mODBYnaHjF4zQfEGoyR5Q== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - core-js "^3.8.2" - global "^4.4.0" - -"@storybook/instrumenter@^6.4.0 || >=6.5.0-0": - version "8.6.14" - resolved "https://registry.yarnpkg.com/@storybook/instrumenter/-/instrumenter-8.6.14.tgz#85bf47e34348f17dfbb99080312eefb2f535bd65" - integrity sha512-iG4MlWCcz1L7Yu8AwgsnfVAmMbvyRSk700Mfy2g4c8y5O+Cv1ejshE1LBBsCwHgkuqU0H4R0qu4g23+6UnUemQ== - dependencies: - "@storybook/global" "^5.0.0" - "@vitest/utils" "^2.1.1" - -"@storybook/manager-webpack4@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/manager-webpack4/-/manager-webpack4-6.5.16.tgz#7033228d38f048ceff3d403ba918d7f206b926a5" - integrity sha512-5VJZwmQU6AgdsBPsYdu886UKBHQ9SJEnFMaeUxKEclXk+iRsmbzlL4GHKyVd6oGX/ZaecZtcHPR6xrzmA4Ziew== - dependencies: - "@babel/core" "^7.12.10" - "@babel/plugin-transform-template-literals" "^7.12.1" - "@babel/preset-react" "^7.12.10" - "@storybook/addons" "6.5.16" - "@storybook/core-client" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/node-logger" "6.5.16" - "@storybook/theming" "6.5.16" - "@storybook/ui" "6.5.16" - "@types/node" "^14.0.10 || ^16.0.0" - "@types/webpack" "^4.41.26" - babel-loader "^8.0.0" - case-sensitive-paths-webpack-plugin "^2.3.0" - chalk "^4.1.0" - core-js "^3.8.2" - css-loader "^3.6.0" - express "^4.17.1" - file-loader "^6.2.0" - find-up "^5.0.0" - fs-extra "^9.0.1" - html-webpack-plugin "^4.0.0" - node-fetch "^2.6.7" - pnp-webpack-plugin "1.6.4" - read-pkg-up "^7.0.1" - regenerator-runtime "^0.13.7" - resolve-from "^5.0.0" - style-loader "^1.3.0" - telejson "^6.0.8" - terser-webpack-plugin "^4.2.3" - ts-dedent "^2.0.0" - url-loader "^4.1.1" - util-deprecate "^1.0.2" - webpack "4" - webpack-dev-middleware "^3.7.3" - webpack-virtual-modules "^0.2.2" - -"@storybook/manager-webpack5@^6.5.8": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/manager-webpack5/-/manager-webpack5-6.5.16.tgz#48b223557d9633614ff8c6e3227c01a57ab4eb55" - integrity sha512-OtxXv8JCe0r/0rE5HxaFicsNsXA+fqZxzokxquFFgrYf/1Jg4d7QX6/pG5wINF+5qInJfVkRG6xhPzv1s5bk9Q== - dependencies: - "@babel/core" "^7.12.10" - "@babel/plugin-transform-template-literals" "^7.12.1" - "@babel/preset-react" "^7.12.10" - "@storybook/addons" "6.5.16" - "@storybook/core-client" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/node-logger" "6.5.16" - "@storybook/theming" "6.5.16" - "@storybook/ui" "6.5.16" - "@types/node" "^14.0.10 || ^16.0.0" - babel-loader "^8.0.0" - case-sensitive-paths-webpack-plugin "^2.3.0" - chalk "^4.1.0" - core-js "^3.8.2" - css-loader "^5.0.1" - express "^4.17.1" - find-up "^5.0.0" - fs-extra "^9.0.1" - html-webpack-plugin "^5.0.0" - node-fetch "^2.6.7" - process "^0.11.10" - read-pkg-up "^7.0.1" - regenerator-runtime "^0.13.7" - resolve-from "^5.0.0" - style-loader "^2.0.0" - telejson "^6.0.8" - terser-webpack-plugin "^5.0.3" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - webpack "^5.9.0" - webpack-dev-middleware "^4.1.0" - webpack-virtual-modules "^0.4.1" - -"@storybook/mdx1-csf@^0.0.1": - version "0.0.1" - resolved "https://registry.yarnpkg.com/@storybook/mdx1-csf/-/mdx1-csf-0.0.1.tgz#d4184e3f6486fade9f7a6bfaf934d9bc07718d5b" - integrity sha512-4biZIWWzoWlCarMZmTpqcJNgo/RBesYZwGFbQeXiGYsswuvfWARZnW9RE9aUEMZ4XPn7B1N3EKkWcdcWe/K2tg== - dependencies: - "@babel/generator" "^7.12.11" - "@babel/parser" "^7.12.11" - "@babel/preset-env" "^7.12.11" - "@babel/types" "^7.12.11" - "@mdx-js/mdx" "^1.6.22" - "@types/lodash" "^4.14.167" - js-string-escape "^1.0.1" - loader-utils "^2.0.0" - lodash "^4.17.21" - prettier ">=2.2.1 <=2.3.0" - ts-dedent "^2.0.0" - -"@storybook/node-logger@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-6.5.16.tgz#d57fd6204c2abfbc297551d98ad5475dd73207cc" - integrity sha512-YjhBKrclQtjhqFNSO+BZK+RXOx6EQypAELJKoLFaawg331e8VUfvUuRCNB3fcEWp8G9oH13PQQte0OTjLyyOYg== - dependencies: - "@types/npmlog" "^4.1.2" - chalk "^4.1.0" - core-js "^3.8.2" - npmlog "^5.0.1" - pretty-hrtime "^1.0.3" - -"@storybook/postinstall@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/postinstall/-/postinstall-6.5.16.tgz#20aa02fd4513fa0b60ed838b413c46f351f64f60" - integrity sha512-08K2q+qN6pqyPW7PHLCZ5G5Xa6Wosd6t0F16PQ4abX2ItlJLabVoJN5mZ0gm/aeLTjD8QYr8IDvacu4eXh0SVA== - dependencies: - core-js "^3.8.2" - -"@storybook/preview-web@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/preview-web/-/preview-web-6.5.16.tgz#1d32a72be25776f9597e33ffc1914f3430fae689" - integrity sha512-IJnvfe2sKCfk7apN9Fu9U8qibbarrPX5JB55ZzK1amSHVmSDuYk5MIMc/U3NnSQNnvd1DO5v/zMcGgj563hrtg== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/channel-postmessage" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/store" "6.5.16" - ansi-to-html "^0.6.11" - core-js "^3.8.2" - global "^4.4.0" - lodash "^4.17.21" - qs "^6.10.0" - regenerator-runtime "^0.13.7" - synchronous-promise "^2.0.15" - ts-dedent "^2.0.0" - unfetch "^4.2.0" - util-deprecate "^1.0.2" - -"@storybook/react-docgen-typescript-plugin@1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0": - version "1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0" - resolved "https://registry.yarnpkg.com/@storybook/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0.tgz#3103532ff494fb7dc3cf835f10740ecf6a26c0f9" - integrity sha512-eVg3BxlOm2P+chijHBTByr90IZVUtgRW56qEOLX7xlww2NBuKrcavBlcmn+HH7GIUktquWkMPtvy6e0W0NgA5w== - dependencies: - debug "^4.1.1" - endent "^2.0.1" - find-cache-dir "^3.3.1" - flat-cache "^3.0.4" - micromatch "^4.0.2" - react-docgen-typescript "^2.1.1" - tslib "^2.0.0" - -"@storybook/react@^6.5.15": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/react/-/react-6.5.16.tgz#f7b82ba87f5bb73b4e4e83cce298a98710a88398" - integrity sha512-cBtNlOzf/MySpNLBK22lJ8wFU22HnfTB2xJyBk7W7Zi71Lm7Uxkhv1Pz8HdiQndJ0SlsAAQOWjQYsSZsGkZIaA== - dependencies: - "@babel/preset-flow" "^7.12.1" - "@babel/preset-react" "^7.12.10" - "@pmmmwh/react-refresh-webpack-plugin" "^0.5.3" - "@storybook/addons" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/docs-tools" "6.5.16" - "@storybook/node-logger" "6.5.16" - "@storybook/react-docgen-typescript-plugin" "1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0" - "@storybook/semver" "^7.3.2" - "@storybook/store" "6.5.16" - "@types/estree" "^0.0.51" - "@types/node" "^14.14.20 || ^16.0.0" - "@types/webpack-env" "^1.16.0" - acorn "^7.4.1" - acorn-jsx "^5.3.1" - acorn-walk "^7.2.0" - babel-plugin-add-react-displayname "^0.0.5" - babel-plugin-react-docgen "^4.2.1" - core-js "^3.8.2" - escodegen "^2.0.0" - fs-extra "^9.0.1" - global "^4.4.0" - html-tags "^3.1.0" - lodash "^4.17.21" - prop-types "^15.7.2" - react-element-to-jsx-string "^14.3.4" - react-refresh "^0.11.0" - read-pkg-up "^7.0.1" - regenerator-runtime "^0.13.7" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - webpack ">=4.43.0 <6.0.0" - -"@storybook/router@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/router/-/router-6.5.16.tgz#28fb4d34e8219351a40bee1fc94dcacda6e1bd8b" - integrity sha512-ZgeP8a5YV/iuKbv31V8DjPxlV4AzorRiR8OuSt/KqaiYXNXlOoQDz/qMmiNcrshrfLpmkzoq7fSo4T8lWo2UwQ== - dependencies: - "@storybook/client-logger" "6.5.16" - core-js "^3.8.2" - memoizerific "^1.11.3" - qs "^6.10.0" - regenerator-runtime "^0.13.7" - -"@storybook/semver@^7.3.2": - version "7.3.2" - resolved "https://registry.yarnpkg.com/@storybook/semver/-/semver-7.3.2.tgz#f3b9c44a1c9a0b933c04e66d0048fcf2fa10dac0" - integrity sha512-SWeszlsiPsMI0Ps0jVNtH64cI5c0UF3f7KgjVKJoNP30crQ6wUSddY2hsdeczZXEKVJGEn50Q60flcGsQGIcrg== - dependencies: - core-js "^3.6.5" - find-up "^4.1.0" - -"@storybook/source-loader@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/source-loader/-/source-loader-6.5.16.tgz#b691a024e6ff36bbd1144ecb4a65986f0e149741" - integrity sha512-fyVl4jrM/5JLrb48aqXPu7sTsmySQaVGFp1zfeqvPPlJRFMastDrePm5XGPN7Qjv1wsKmpuBvuweFKOT1pru3g== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - core-js "^3.8.2" - estraverse "^5.2.0" - global "^4.4.0" - loader-utils "^2.0.4" - lodash "^4.17.21" - prettier ">=2.2.1 <=2.3.0" - regenerator-runtime "^0.13.7" - -"@storybook/store@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/store/-/store-6.5.16.tgz#b308701293a3a11bfcc766770584495874fd17da" - integrity sha512-g+bVL5hmMq/9cM51K04e37OviUPHT0rHHrRm5wj/hrf18Kd9120b3sxdQ5Dc+HZ292yuME0n+cyrQPTYx9Epmw== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - core-js "^3.8.2" - fast-deep-equal "^3.1.3" - global "^4.4.0" - lodash "^4.17.21" - memoizerific "^1.11.3" - regenerator-runtime "^0.13.7" - slash "^3.0.0" - stable "^0.1.8" - synchronous-promise "^2.0.15" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - -"@storybook/telemetry@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/telemetry/-/telemetry-6.5.16.tgz#b13c8133e02c28e37b7716c987e7414b1ddc5363" - integrity sha512-CWr5Uko1l9jJW88yTXsZTj/3GTabPvw0o7pDPOXPp8JRZiJTxv1JFaFCafhK9UzYbgcRuGfCC8kEWPZims7iKA== - dependencies: - "@storybook/client-logger" "6.5.16" - "@storybook/core-common" "6.5.16" - chalk "^4.1.0" - core-js "^3.8.2" - detect-package-manager "^2.0.1" - fetch-retry "^5.0.2" - fs-extra "^9.0.1" - global "^4.4.0" - isomorphic-unfetch "^3.1.0" - nanoid "^3.3.1" - read-pkg-up "^7.0.1" - regenerator-runtime "^0.13.7" - -"@storybook/testing-library@^0.0.9": - version "0.0.9" - resolved "https://registry.yarnpkg.com/@storybook/testing-library/-/testing-library-0.0.9.tgz#e3d6e8077d58305bb352903e820dcae9306e7a7f" - integrity sha512-X4/Tk7RryB0tZ/9NLUHYTBXW01zRpf6+IhdhqsVl6WOWRyUaIv3zEhr43gQyZhBe4ZZyt5d90FJC9qWmY1oFKg== - dependencies: - "@storybook/client-logger" "^6.4.0 || >=6.5.0-0" - "@storybook/instrumenter" "^6.4.0 || >=6.5.0-0" - "@testing-library/dom" "^8.3.0" - "@testing-library/user-event" "^13.2.1" - ts-dedent "^2.2.0" - -"@storybook/theming@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-6.5.16.tgz#b999bdb98945b605b93b9dfdf7408535b701e2aa" - integrity sha512-hNLctkjaYLRdk1+xYTkC1mg4dYz2wSv6SqbLpcKMbkPHTE0ElhddGPHQqB362md/w9emYXNkt1LSMD8Xk9JzVQ== - dependencies: - "@storybook/client-logger" "6.5.16" - core-js "^3.8.2" - memoizerific "^1.11.3" - regenerator-runtime "^0.13.7" - -"@storybook/ui@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-6.5.16.tgz#c73bf456e672ecf2370b4365070088487fc0ce57" - integrity sha512-rHn/n12WM8BaXtZ3IApNZCiS+C4Oc5+Lkl4MoctX8V7QSml0SxZBB5hsJ/AiWkgbRxjQpa/L/Nt7/Qw0FjTH/A== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/channels" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/router" "6.5.16" - "@storybook/semver" "^7.3.2" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - memoizerific "^1.11.3" - qs "^6.10.0" - regenerator-runtime "^0.13.7" - resolve-from "^5.0.0" - -"@svgr/babel-plugin-add-jsx-attribute@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.5.1.tgz#74a5d648bd0347bda99d82409d87b8ca80b9a1ba" - integrity sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ== - -"@svgr/babel-plugin-remove-jsx-attribute@*": - version "8.0.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz#69177f7937233caca3a1afb051906698f2f59186" - integrity sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA== - -"@svgr/babel-plugin-remove-jsx-empty-expression@*": - version "8.0.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz#c2c48104cfd7dcd557f373b70a56e9e3bdae1d44" - integrity sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA== - -"@svgr/babel-plugin-replace-jsx-attribute-value@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.5.1.tgz#fb9d22ea26d2bc5e0a44b763d4c46d5d3f596c60" - integrity sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg== - -"@svgr/babel-plugin-svg-dynamic-title@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.5.1.tgz#01b2024a2b53ffaa5efceaa0bf3e1d5a4c520ce4" - integrity sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw== - -"@svgr/babel-plugin-svg-em-dimensions@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.5.1.tgz#dd3fa9f5b24eb4f93bcf121c3d40ff5facecb217" - integrity sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA== - -"@svgr/babel-plugin-transform-react-native-svg@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.5.1.tgz#1d8e945a03df65b601551097d8f5e34351d3d305" - integrity sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg== - -"@svgr/babel-plugin-transform-svg-component@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.5.1.tgz#48620b9e590e25ff95a80f811544218d27f8a250" - integrity sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ== - -"@svgr/babel-preset@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-6.5.1.tgz#b90de7979c8843c5c580c7e2ec71f024b49eb828" - integrity sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw== - dependencies: - "@svgr/babel-plugin-add-jsx-attribute" "^6.5.1" - "@svgr/babel-plugin-remove-jsx-attribute" "*" - "@svgr/babel-plugin-remove-jsx-empty-expression" "*" - "@svgr/babel-plugin-replace-jsx-attribute-value" "^6.5.1" - "@svgr/babel-plugin-svg-dynamic-title" "^6.5.1" - "@svgr/babel-plugin-svg-em-dimensions" "^6.5.1" - "@svgr/babel-plugin-transform-react-native-svg" "^6.5.1" - "@svgr/babel-plugin-transform-svg-component" "^6.5.1" - -"@svgr/core@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/core/-/core-6.5.1.tgz#d3e8aa9dbe3fbd747f9ee4282c1c77a27410488a" - integrity sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw== - dependencies: - "@babel/core" "^7.19.6" - "@svgr/babel-preset" "^6.5.1" - "@svgr/plugin-jsx" "^6.5.1" - camelcase "^6.2.0" - cosmiconfig "^7.0.1" - -"@svgr/hast-util-to-babel-ast@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.5.1.tgz#81800bd09b5bcdb968bf6ee7c863d2288fdb80d2" - integrity sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw== - dependencies: - "@babel/types" "^7.20.0" - entities "^4.4.0" - -"@svgr/plugin-jsx@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-6.5.1.tgz#0e30d1878e771ca753c94e69581c7971542a7072" - integrity sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw== - dependencies: - "@babel/core" "^7.19.6" - "@svgr/babel-preset" "^6.5.1" - "@svgr/hast-util-to-babel-ast" "^6.5.1" - svg-parser "^2.0.4" - -"@svgr/plugin-svgo@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-6.5.1.tgz#0f91910e988fc0b842f88e0960c2862e022abe84" - integrity sha512-omvZKf8ixP9z6GWgwbtmP9qQMPX4ODXi+wzbVZgomNFsUIlHA1sf4fThdwTWSsZGgvGAG6yE+b/F5gWUkcZ/iQ== - dependencies: - cosmiconfig "^7.0.1" - deepmerge "^4.2.2" - svgo "^2.8.0" - -"@svgr/webpack@^6.1.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-6.5.1.tgz#ecf027814fc1cb2decc29dc92f39c3cf691e40e8" - integrity sha512-cQ/AsnBkXPkEK8cLbv4Dm7JGXq2XrumKnL1dRpJD9rIO2fTIlJI9a1uCciYG1F2aUsox/hJQyNGbt3soDxSRkA== - dependencies: - "@babel/core" "^7.19.6" - "@babel/plugin-transform-react-constant-elements" "^7.18.12" - "@babel/preset-env" "^7.19.4" - "@babel/preset-react" "^7.18.6" - "@babel/preset-typescript" "^7.18.6" - "@svgr/core" "^6.5.1" - "@svgr/plugin-jsx" "^6.5.1" - "@svgr/plugin-svgo" "^6.5.1" - -"@swc/counter@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@swc/counter/-/counter-0.1.3.tgz#cc7463bd02949611c6329596fccd2b0ec782b0e9" - integrity sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ== - -"@swc/helpers@0.5.5": - version "0.5.5" - resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.5.tgz#12689df71bfc9b21c4f4ca00ae55f2f16c8b77c0" - integrity sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A== - dependencies: - "@swc/counter" "^0.1.3" - tslib "^2.4.0" - -"@swc/helpers@^0.5.0": - version "0.5.17" - resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.17.tgz#5a7be95ac0f0bf186e7e6e890e7a6f6cda6ce971" - integrity sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A== - dependencies: - tslib "^2.8.0" - -"@tanstack/match-sorter-utils@8.19.4": - version "8.19.4" - resolved "https://registry.yarnpkg.com/@tanstack/match-sorter-utils/-/match-sorter-utils-8.19.4.tgz#dacf772b5d94f4684f10dbeb2518cf72dccab8a5" - integrity sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg== - dependencies: - remove-accents "0.5.0" - -"@tanstack/query-core@5.100.9": - version "5.100.9" - resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.100.9.tgz#dcf44ef25cf42a4da229bcab1d8d33e80a740a99" - integrity sha512-SJSFw1S8+kQ0+knv/XGfrbocWoAlT7vDKsSImtLx3ZPQmEcR46hkDjLSvynSy25N8Ms4tIEini1FuBd5k7IscQ== - -"@tanstack/query-core@5.90.5": - version "5.90.5" - resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.90.5.tgz#0175f9f517514906db8ab379589ed3f96694ecc4" - integrity sha512-wLamYp7FaDq6ZnNehypKI5fNvxHPfTYylE0m/ZpuuzJfJqhR5Pxg9gvGBHZx4n7J+V5Rg5mZxHHTlv25Zt5u+w== - -"@tanstack/query-devtools@5.90.1": - version "5.90.1" - resolved "https://registry.yarnpkg.com/@tanstack/query-devtools/-/query-devtools-5.90.1.tgz#c57a739a5293f4960a4a6b6fb4b7e4a56e6bd932" - integrity sha512-GtINOPjPUH0OegJExZ70UahT9ykmAhmtNVcmtdnOZbxLwT7R5OmRztR5Ahe3/Cu7LArEmR6/588tAycuaWb1xQ== - -"@tanstack/react-query-devtools@^5.64.2": - version "5.90.2" - resolved "https://registry.yarnpkg.com/@tanstack/react-query-devtools/-/react-query-devtools-5.90.2.tgz#248d6ae89ace7dc2da816fa95cdc2b4f63c9e4d2" - integrity sha512-vAXJzZuBXtCQtrY3F/yUNJCV4obT/A/n81kb3+YqLbro5Z2+phdAbceO+deU3ywPw8B42oyJlp4FhO0SoivDFQ== - dependencies: - "@tanstack/query-devtools" "5.90.1" - -"@tanstack/react-query-next-experimental@^5.66.0": - version "5.90.2" - resolved "https://registry.yarnpkg.com/@tanstack/react-query-next-experimental/-/react-query-next-experimental-5.90.2.tgz#4454119d2e5ac7aa42dfb540ba300e956f4336df" - integrity sha512-f7vJ9SHRO5GjiTBIpaSdLTczPlDybu6OzLG2thcNev55Qi69JkYsSOyUVWKpa3tGgufyJx1kDAO5lJjv4jF/bw== - -"@tanstack/react-query@^5.62.0": - version "5.100.9" - resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.100.9.tgz#0c701bf56f38b484602255a92d4c9e452a04807d" - integrity sha512-Oa44XkaI3kCNN6ME0KByU3xT3SEUNOMfZpHxL6+wFoTm+OeUFYHKdeYVe0aOXlRDm/f15sgLwEt2HDorIdW8+A== - dependencies: - "@tanstack/query-core" "5.100.9" - -"@tanstack/react-query@^5.64.2": - version "5.90.5" - resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.90.5.tgz#545e61282c787bd87ac5785da9a4943462f78ef6" - integrity sha512-pN+8UWpxZkEJ/Rnnj2v2Sxpx1WFlaa9L6a4UO89p6tTQbeo+m0MS8oYDjbggrR8QcTyjKoYWKS3xJQGr3ExT8Q== - dependencies: - "@tanstack/query-core" "5.90.5" - -"@tanstack/react-table@8.20.6": - version "8.20.6" - resolved "https://registry.yarnpkg.com/@tanstack/react-table/-/react-table-8.20.6.tgz#a1f3103327aa59aa621931f4087a7604a21054d0" - integrity sha512-w0jluT718MrOKthRcr2xsjqzx+oEM7B7s/XXyfs19ll++hlId3fjTm+B2zrR3ijpANpkzBAr15j1XGVOMxpggQ== - dependencies: - "@tanstack/table-core" "8.20.5" - -"@tanstack/react-table@^8.20.6": - version "8.21.3" - resolved "https://registry.yarnpkg.com/@tanstack/react-table/-/react-table-8.21.3.tgz#2c38c747a5731c1a07174fda764b9c2b1fb5e91b" - integrity sha512-5nNMTSETP4ykGegmVkhjcS8tTLW6Vl4axfEGQN3v0zdHYbK4UfoqfPChclTrJ4EoK9QynqAu9oUf8VEmrpZ5Ww== - dependencies: - "@tanstack/table-core" "8.21.3" - -"@tanstack/react-virtual@3.11.2": - version "3.11.2" - resolved "https://registry.yarnpkg.com/@tanstack/react-virtual/-/react-virtual-3.11.2.tgz#d6b9bd999c181f0a2edce270c87a2febead04322" - integrity sha512-OuFzMXPF4+xZgx8UzJha0AieuMihhhaWG0tCqpp6tDzlFwOmNBPYMuLOtMJ1Tr4pXLHmgjcWhG6RlknY2oNTdQ== - dependencies: - "@tanstack/virtual-core" "3.11.2" - -"@tanstack/react-virtual@^3.10.5": - version "3.13.12" - resolved "https://registry.yarnpkg.com/@tanstack/react-virtual/-/react-virtual-3.13.12.tgz#d372dc2783739cc04ec1a728ca8203937687a819" - integrity sha512-Gd13QdxPSukP8ZrkbgS2RwoZseTTbQPLnQEn7HY/rqtM+8Zt95f7xKC7N0EsKs7aoz0WzZ+fditZux+F8EzYxA== - dependencies: - "@tanstack/virtual-core" "3.13.12" - -"@tanstack/table-core@8.20.5": - version "8.20.5" - resolved "https://registry.yarnpkg.com/@tanstack/table-core/-/table-core-8.20.5.tgz#3974f0b090bed11243d4107283824167a395cf1d" - integrity sha512-P9dF7XbibHph2PFRz8gfBKEXEY/HJPOhym8CHmjF8y3q5mWpKx9xtZapXQUWCgkqvsK0R46Azuz+VaxD4Xl+Tg== - -"@tanstack/table-core@8.21.3": - version "8.21.3" - resolved "https://registry.yarnpkg.com/@tanstack/table-core/-/table-core-8.21.3.tgz#2977727d8fc8dfa079112d9f4d4c019110f1732c" - integrity sha512-ldZXEhOBb8Is7xLs01fR3YEc3DERiz5silj8tnGkFZytt1abEvl/GhUmCE0PMLaMPTa3Jk4HbKmRlHmu+gCftg== - -"@tanstack/virtual-core@3.11.2": - version "3.11.2" - resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.11.2.tgz#00409e743ac4eea9afe5b7708594d5fcebb00212" - integrity sha512-vTtpNt7mKCiZ1pwU9hfKPhpdVO2sVzFQsxoVBGtOSHxlrRRzYr8iQ2TlwbAcRYCcEiZ9ECAM8kBzH0v2+VzfKw== - -"@tanstack/virtual-core@3.13.12": - version "3.13.12" - resolved "https://registry.yarnpkg.com/@tanstack/virtual-core/-/virtual-core-3.13.12.tgz#1dff176df9cc8f93c78c5e46bcea11079b397578" - integrity sha512-1YBOJfRHV4sXUmWsFSf5rQor4Ss82G8dQWLRbnk3GA4jeP8hQt1hxXh0tmflpC0dz3VgEv/1+qwPyLeWkQuPFA== - -"@tauri-apps/api@^2.10.1", "@tauri-apps/api@^2.8.0": - version "2.10.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/api/-/api-2.10.1.tgz#57c1bae6114ec33d977eb2b50dfefc25fa84fc93" - integrity sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw== - -"@tauri-apps/cli-darwin-arm64@2.10.1": - version "2.10.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-2.10.1.tgz#7abb013926613555559cce1583ab6521e07b997c" - integrity sha512-Z2OjCXiZ+fbYZy7PmP3WRnOpM9+Fy+oonKDEmUE6MwN4IGaYqgceTjwHucc/kEEYZos5GICve35f7ZiizgqEnQ== - -"@tauri-apps/cli-darwin-x64@2.10.1": - version "2.10.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-2.10.1.tgz#cd1abd24782d488d0ee26f15015016b83a5b4bde" - integrity sha512-V/irQVvjPMGOTQqNj55PnQPVuH4VJP8vZCN7ajnj+ZS8Kom1tEM2hR3qbbIRoS3dBKs5mbG8yg1WC+97dq17Pw== - -"@tauri-apps/cli-linux-arm-gnueabihf@2.10.1": - version "2.10.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-2.10.1.tgz#9afdc71d24d44941d76fdc353f4401e82e9ccac5" - integrity sha512-Hyzwsb4VnCWKGfTw+wSt15Z2pLw2f0JdFBfq2vHBOBhvg7oi6uhKiF87hmbXOBXUZaGkyRDkCHsdzJcIfoJC2w== - -"@tauri-apps/cli-linux-arm64-gnu@2.10.1": - version "2.10.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-2.10.1.tgz#3a0a1e31eda8f01b69db09179094e0dc7ff5bb60" - integrity sha512-OyOYs2t5GkBIvyWjA1+h4CZxTcdz1OZPCWAPz5DYEfB0cnWHERTnQ/SLayQzncrT0kwRoSfSz9KxenkyJoTelA== - -"@tauri-apps/cli-linux-arm64-musl@2.10.1": - version "2.10.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.10.1.tgz#6fc7e74e4a6053dd64b81dfdaf9dbabb6df31971" - integrity sha512-MIj78PDDGjkg3NqGptDOGgfXks7SYJwhiMh8SBoZS+vfdz7yP5jN18bNaLnDhsVIPARcAhE1TlsZe/8Yxo2zqg== - -"@tauri-apps/cli-linux-riscv64-gnu@2.10.1": - version "2.10.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-riscv64-gnu/-/cli-linux-riscv64-gnu-2.10.1.tgz#9a5d3bb8efb17ef65146d0f319c6cf212e2a724a" - integrity sha512-X0lvOVUg8PCVaoEtEAnpxmnkwlE1gcMDTqfhbefICKDnOTJ5Est3qL0SrWxizDackIOKBcvtpejrSiVpuJI1kw== - -"@tauri-apps/cli-linux-x64-gnu@2.10.1": - version "2.10.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-2.10.1.tgz#cf54e3754d2a54894323840aef1f9789888e0d57" - integrity sha512-2/12bEzsJS9fAKybxgicCDFxYD1WEI9kO+tlDwX5znWG2GwMBaiWcmhGlZ8fi+DMe9CXlcVarMTYc0L3REIRxw== - -"@tauri-apps/cli-linux-x64-musl@2.10.1": - version "2.10.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-2.10.1.tgz#dc4bd17e812b448b3ccec0684f336f19fb47b069" - integrity sha512-Y8J0ZzswPz50UcGOFuXGEMrxbjwKSPgXftx5qnkuMs2rmwQB5ssvLb6tn54wDSYxe7S6vlLob9vt0VKuNOaCIQ== - -"@tauri-apps/cli-win32-arm64-msvc@2.10.1": - version "2.10.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-2.10.1.tgz#2f398fb17f4665fefe5b8cb21566cde7062236f5" - integrity sha512-iSt5B86jHYAPJa/IlYw++SXtFPGnWtFJriHn7X0NFBVunF6zu9+/zOn8OgqIWSl8RgzhLGXQEEtGBdR4wzpVgg== - -"@tauri-apps/cli-win32-ia32-msvc@2.10.1": - version "2.10.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-2.10.1.tgz#ffcbc2fa6a1d71f0b38672ea3468c07581f5cfaf" - integrity sha512-gXyxgEzsFegmnWywYU5pEBURkcFN/Oo45EAwvZrHMh+zUSEAvO5E8TXsgPADYm31d1u7OQU3O3HsYfVBf2moHw== - -"@tauri-apps/cli-win32-x64-msvc@2.10.1": - version "2.10.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-2.10.1.tgz#75a3842ecab5e13b15ad2eead4c1b9cc3916e78d" - integrity sha512-6Cn7YpPFwzChy0ERz6djKEmUehWrYlM+xTaNzGPgZocw3BD7OfwfWHKVWxXzdjEW2KfKkHddfdxK1XXTYqBRLg== - -"@tauri-apps/cli@^2.10.1": - version "2.10.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli/-/cli-2.10.1.tgz#d9b0290f03d569e10eb349a0bb72f448880bf9d7" - integrity sha512-jQNGF/5quwORdZSSLtTluyKQ+o6SMa/AUICfhf4egCGFdMHqWssApVgYSbg+jmrZoc8e1DscNvjTnXtlHLS11g== - optionalDependencies: - "@tauri-apps/cli-darwin-arm64" "2.10.1" - "@tauri-apps/cli-darwin-x64" "2.10.1" - "@tauri-apps/cli-linux-arm-gnueabihf" "2.10.1" - "@tauri-apps/cli-linux-arm64-gnu" "2.10.1" - "@tauri-apps/cli-linux-arm64-musl" "2.10.1" - "@tauri-apps/cli-linux-riscv64-gnu" "2.10.1" - "@tauri-apps/cli-linux-x64-gnu" "2.10.1" - "@tauri-apps/cli-linux-x64-musl" "2.10.1" - "@tauri-apps/cli-win32-arm64-msvc" "2.10.1" - "@tauri-apps/cli-win32-ia32-msvc" "2.10.1" - "@tauri-apps/cli-win32-x64-msvc" "2.10.1" - -"@tauri-apps/plugin-clipboard-manager@^2.3.2": - version "2.3.2" - resolved "https://registry.yarnpkg.com/@tauri-apps/plugin-clipboard-manager/-/plugin-clipboard-manager-2.3.2.tgz#41def8a008eca94fd5abe2915d26a9c4b6ce54ca" - integrity sha512-CUlb5Hqi2oZbcZf4VUyUH53XWPPdtpw43EUpCza5HWZJwxEoDowFzNUDt1tRUXA8Uq+XPn17Ysfptip33sG4eQ== - dependencies: - "@tauri-apps/api" "^2.8.0" - -"@tauri-apps/plugin-opener@^2.5.3": - version "2.5.3" - resolved "https://registry.yarnpkg.com/@tauri-apps/plugin-opener/-/plugin-opener-2.5.3.tgz#09f8fe143567839cc491f4f8fde21caa0f1a8b89" - integrity sha512-CCcUltXMOfUEArbf3db3kCE7Ggy1ExBEBl51Ko2ODJ6GDYHRp1nSNlQm5uNCFY5k7/ufaK5Ib3Du/Zir19IYQQ== - dependencies: - "@tauri-apps/api" "^2.8.0" - -"@tauri-apps/plugin-process@^2.3.1": - version "2.3.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/plugin-process/-/plugin-process-2.3.1.tgz#fff77aa7550c9c5347689c859d581f88287bf7ae" - integrity sha512-nCa4fGVaDL/B9ai03VyPOjfAHRHSBz5v6F/ObsB73r/dA3MHHhZtldaDMIc0V/pnUw9ehzr2iEG+XkSEyC0JJA== - dependencies: - "@tauri-apps/api" "^2.8.0" - -"@tauri-apps/plugin-updater@^2.10.1": - version "2.10.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/plugin-updater/-/plugin-updater-2.10.1.tgz#ea0efd766890394b6c719b9fc21de7da0029c69c" - integrity sha512-NFYMg+tWOZPJdzE/PpFj2qfqwAWwNS3kXrb1tm1gnBJ9mYzZ4WDRrwy8udzWoAnfGCHLuePNLY1WVCNHnh3eRA== - dependencies: - "@tauri-apps/api" "^2.10.1" - -"@tauri-apps/tauri-forage@^1.0.0-beta.2": - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/@tauri-apps/tauri-forage/-/tauri-forage-1.0.0-beta.2.tgz#c11b438ba32731dc7b4c8689d9fda4130baadc07" - integrity sha512-aGObWlY8sgEfImt8+Cv4D+hqWhWB4KwPLVRQTv2uPtHSrXpXrvkJ8vTjy+QsT7tGPyVhcLPBchbyGu0JReErSQ== - dependencies: - localforage "^1.7.3" - ramda "^0.26.1" - tweetnacl "^1.0.1" - tweetnacl-util "^0.15.0" - -"@testing-library/dom@^10.4.1": - version "10.4.1" - resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-10.4.1.tgz#d444f8a889e9a46e9a3b4f3b88e0fcb3efb6cf95" - integrity sha512-o4PXJQidqJl82ckFaXUeoAW+XysPLauYI43Abki5hABd853iMhitooc6znOnczgbTYmEP6U6/y1ZyKAIsvMKGg== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/runtime" "^7.12.5" - "@types/aria-query" "^5.0.1" - aria-query "5.3.0" - dom-accessibility-api "^0.5.9" - lz-string "^1.5.0" - picocolors "1.1.1" - pretty-format "^27.0.2" - -"@testing-library/dom@^8.3.0": - version "8.20.1" - resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.20.1.tgz#2e52a32e46fc88369eef7eef634ac2a192decd9f" - integrity sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/runtime" "^7.12.5" - "@types/aria-query" "^5.0.1" - aria-query "5.1.3" - chalk "^4.1.0" - dom-accessibility-api "^0.5.9" - lz-string "^1.5.0" - pretty-format "^27.0.2" - -"@testing-library/jest-dom@^6.9.1": - version "6.9.1" - resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-6.9.1.tgz#7613a04e146dd2976d24ddf019730d57a89d56c2" - integrity sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA== - dependencies: - "@adobe/css-tools" "^4.4.0" - aria-query "^5.0.0" - css.escape "^1.5.1" - dom-accessibility-api "^0.6.3" - picocolors "^1.1.1" - redent "^3.0.0" - -"@testing-library/react@^16.3.2": - version "16.3.2" - resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-16.3.2.tgz#672883b7acb8e775fc0492d9e9d25e06e89786d0" - integrity sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g== - dependencies: - "@babel/runtime" "^7.12.5" - -"@testing-library/user-event@^13.2.1": - version "13.5.0" - resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-13.5.0.tgz#69d77007f1e124d55314a2b73fd204b333b13295" - integrity sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg== - dependencies: - "@babel/runtime" "^7.12.5" - -"@tootallnate/once@1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== - -"@tootallnate/once@2": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" - integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== - -"@trysound/sax@0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" - integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== - -"@tufjs/canonical-json@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz#eade9fd1f537993bc1f0949f3aea276ecc4fab31" - integrity sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ== - -"@tufjs/models@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@tufjs/models/-/models-1.0.4.tgz#5a689630f6b9dbda338d4b208019336562f176ef" - integrity sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A== - dependencies: - "@tufjs/canonical-json" "1.0.0" - minimatch "^9.0.0" - -"@tybys/wasm-util@^0.10.0": - version "0.10.1" - resolved "https://registry.yarnpkg.com/@tybys/wasm-util/-/wasm-util-0.10.1.tgz#ecddd3205cf1e2d5274649ff0eedd2991ed7f414" - integrity sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg== - dependencies: - tslib "^2.4.0" - -"@types/aria-query@^5.0.1": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.4.tgz#1a31c3d378850d2778dabb6374d036dcba4ba708" - integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw== - -"@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14", "@types/babel__core@^7.20.5": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" - integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== - dependencies: - "@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.yarnpkg.com/@types/babel__generator/-/babel__generator-7.27.0.tgz#b5819294c51179957afaec341442f9341e4108a9" - integrity sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg== - dependencies: - "@babel/types" "^7.0.0" - -"@types/babel__template@*": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" - integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - -"@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.28.0" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.28.0.tgz#07d713d6cce0d265c9849db0cbe62d3f61f36f74" - integrity sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q== - dependencies: - "@babel/types" "^7.28.2" - -"@types/big.js@^6.1.6": - version "6.2.2" - resolved "https://registry.yarnpkg.com/@types/big.js/-/big.js-6.2.2.tgz#69422ec9ef59df1330ccfde2106d9e1159a083c3" - integrity sha512-e2cOW9YlVzFY2iScnGBBkplKsrn2CsObHQ2Hiw4V1sSyiGbgWL8IyqE3zFi1Pt5o1pdAtYkDAIsF3KKUPjdzaA== - -"@types/body-parser@*": - version "1.19.6" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.6.tgz#1859bebb8fd7dac9918a45d54c1971ab8b5af474" - integrity sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g== - dependencies: - "@types/connect" "*" - "@types/node" "*" - -"@types/bonjour@^3.5.9": - version "3.5.13" - resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.13.tgz#adf90ce1a105e81dd1f9c61fdc5afda1bfb92956" - integrity sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ== - dependencies: - "@types/node" "*" - -"@types/bs58@^4.0.1": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@types/bs58/-/bs58-4.0.4.tgz#49fbcb0c7db5f7cea26f0e0f61dc4a41a2445aab" - integrity sha512-0IEpMFXXQi2zXaXl9GJ3sRwQo0uEkD+yFOv+FnAU5lkPtcu6h61xb7jc2CFPEZ5BUOaiP13ThuGc9HD4R8lR5g== - dependencies: - "@types/node" "*" - base-x "^3.0.6" - -"@types/connect-history-api-fallback@^1.3.5": - version "1.5.4" - resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz#7de71645a103056b48ac3ce07b3520b819c1d5b3" - integrity sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw== - dependencies: - "@types/express-serve-static-core" "*" - "@types/node" "*" - -"@types/connect@*": - version "3.4.38" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" - integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== - dependencies: - "@types/node" "*" - -"@types/d3-array@^3.0.3": - version "3.2.2" - resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.2.2.tgz#e02151464d02d4a1b44646d0fcdb93faf88fde8c" - integrity sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw== - -"@types/d3-color@*", "@types/d3-color@^3.0.0": - version "3.1.3" - resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.3.tgz#368c961a18de721da8200e80bf3943fb53136af2" - integrity sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A== - -"@types/d3-delaunay@^6.0.4": - version "6.0.4" - resolved "https://registry.yarnpkg.com/@types/d3-delaunay/-/d3-delaunay-6.0.4.tgz#185c1a80cc807fdda2a3fe960f7c11c4a27952e1" - integrity sha512-ZMaSKu4THYCU6sV64Lhg6qjf1orxBthaC161plr5KuPHo3CNm8DTHiLw/5Eq2b6TsNP0W0iJrUOFscY6Q450Hw== - -"@types/d3-ease@^3.0.0": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-3.0.2.tgz#e28db1bfbfa617076f7770dd1d9a48eaa3b6c51b" - integrity sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA== - -"@types/d3-format@^1.4.1": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@types/d3-format/-/d3-format-1.4.5.tgz#6392303c2ca3c287c3a1a2046455cd0a0bd50bbe" - integrity sha512-mLxrC1MSWupOSncXN/HOlWUAAIffAEBaI4+PKy2uMPsKe4FNZlk7qrbTjmzJXITQQqBHivaks4Td18azgqnotA== - -"@types/d3-interpolate@^3.0.1": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz#412b90e84870285f2ff8a846c6eb60344f12a41c" - integrity sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA== - dependencies: - "@types/d3-color" "*" - -"@types/d3-path@*": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-3.1.1.tgz#f632b380c3aca1dba8e34aa049bcd6a4af23df8a" - integrity sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg== - -"@types/d3-scale-chromatic@^3.0.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@types/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz#dc6d4f9a98376f18ea50bad6c39537f1b5463c39" - integrity sha512-iWMJgwkK7yTRmWqRB5plb1kadXyQ5Sj8V/zYlFGMUBbIPKQScw+Dku9cAAMgJG+z5GYDoMjWGLVOvjghDEFnKQ== - -"@types/d3-scale@^4.0.2", "@types/d3-scale@^4.0.8": - version "4.0.9" - resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.9.tgz#57a2f707242e6fe1de81ad7bfcccaaf606179afb" - integrity sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw== - dependencies: - "@types/d3-time" "*" - -"@types/d3-shape@^3.1.0", "@types/d3-shape@^3.1.6": - version "3.1.7" - resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.7.tgz#2b7b423dc2dfe69c8c93596e673e37443348c555" - integrity sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg== - dependencies: - "@types/d3-path" "*" - -"@types/d3-time-format@^2.3.1": - version "2.3.4" - resolved "https://registry.yarnpkg.com/@types/d3-time-format/-/d3-time-format-2.3.4.tgz#544af5184df8b3fc4d9b42b14058789acee2905e" - integrity sha512-xdDXbpVO74EvadI3UDxjxTdR6QIxm1FKzEA/+F8tL4GWWUg/hgvBqf6chql64U5A9ZUGWo7pEu4eNlyLwbKdhg== - -"@types/d3-time-format@^3.0.0": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/d3-time-format/-/d3-time-format-3.0.4.tgz#f972bdd7be1048184577cf235a44721a78c6bb4b" - integrity sha512-or9DiDnYI1h38J9hxKEsw513+KVuFbEVhl7qdxcaudoiqWWepapUen+2vAriFGexr6W5+P4l9+HJrB39GG+oRg== - -"@types/d3-time@*", "@types/d3-time@^3.0.0": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.4.tgz#8472feecd639691450dd8000eb33edd444e1323f" - integrity sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g== - -"@types/d3-time@^1.1.1": - version "1.1.4" - resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-1.1.4.tgz#20da4b75c537a940e7319b75717c67a2e499515a" - integrity sha512-JIvy2HjRInE+TXOmIGN5LCmeO0hkFZx5f9FZ7kiN+D+YTcc8pptsiLiuHsvwxwC7VVKmJ2ExHUgNlAiV7vQM9g== - -"@types/d3-timer@^3.0.0": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-3.0.2.tgz#70bbda77dc23aa727413e22e214afa3f0e852f70" - integrity sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw== - -"@types/debug@^4.0.0": - version "4.1.12" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917" - integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ== - dependencies: - "@types/ms" "*" - -"@types/eslint-scope@^3.7.7": - version "3.7.7" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" - integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" - -"@types/eslint@*": - version "9.6.1" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-9.6.1.tgz#d5795ad732ce81715f27f75da913004a56751584" - integrity sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - -"@types/estree-jsx@^1.0.0": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-1.0.5.tgz#858a88ea20f34fe65111f005a689fa1ebf70dc18" - integrity sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg== - dependencies: - "@types/estree" "*" - -"@types/estree@*", "@types/estree@^1.0.0", "@types/estree@^1.0.6", "@types/estree@^1.0.8": - version "1.0.8" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.8.tgz#958b91c991b1867ced318bedea0e215ee050726e" - integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== - -"@types/estree@^0.0.51": - version "0.0.51" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" - integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== - -"@types/express-serve-static-core@*", "@types/express-serve-static-core@^5.0.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-5.1.0.tgz#74f47555b3d804b54cb7030e6f9aa0c7485cfc5b" - integrity sha512-jnHMsrd0Mwa9Cf4IdOzbz543y4XJepXrbia2T4b6+spXC2We3t1y6K44D3mR8XMFSXMCf3/l7rCgddfx7UNVBA== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - "@types/send" "*" - -"@types/express-serve-static-core@^4.17.33": - version "4.19.7" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.19.7.tgz#f1d306dcc03b1aafbfb6b4fe684cce8a31cffc10" - integrity sha512-FvPtiIf1LfhzsaIXhv/PHan/2FeQBbtBDtfX2QfvPxdUelMDEckK08SM6nqo1MIZY3RUlfA+HV8+hFUSio78qg== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - "@types/send" "*" - -"@types/express@*": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@types/express/-/express-5.0.4.tgz#975e7fc1097066a83b992fd2bb8a4819622e8bae" - integrity sha512-g64dbryHk7loCIrsa0R3shBnEu5p6LPJ09bu9NG58+jz+cRUjFrc3Bz0kNQ7j9bXeCsrRDvNET1G54P/GJkAyA== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "^5.0.0" - "@types/serve-static" "*" - -"@types/express@^4.17.13": - version "4.17.24" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.24.tgz#7d4be463143e9f2f146ef805a619076ce4aaec26" - integrity sha512-Mbrt4SRlXSTWryOnHAh2d4UQ/E7n9lZyGSi6KgX+4hkuL9soYbLOVXVhnk/ODp12YsGc95f4pOvqywJ6kngUwg== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.33" - "@types/qs" "*" - "@types/serve-static" "*" - -"@types/favicons@5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@types/favicons/-/favicons-5.5.0.tgz#c1cb3d2a14955eedf479f3cc51948630c56e3a64" - integrity sha512-s76OlRaBfqtGu2ZBobnZv2NETfqsQUVfKKlOkKNGo4ArBsqiblodKsnQ3j29hCCgmpQacEfLxealV96za+tzVQ== - dependencies: - "@types/node" "*" - -"@types/flat@^5.0.2": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@types/flat/-/flat-5.0.5.tgz#2304df0b2b1e6dde50d81f029593e0a1bc2474d3" - integrity sha512-nPLljZQKSnac53KDUDzuzdRfGI0TDb5qPrb+SrQyN3MtdQrOnGsKniHN1iYZsJEBIVQve94Y6gNz22sgISZq+Q== - -"@types/glob@*": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-9.0.0.tgz#7b942fafe09c55671912b34f04e8e4676faf32b1" - integrity sha512-00UxlRaIUvYm4R4W9WYkN8/J+kV8fmOQ7okeH6YFtGWFMt3odD45tpG5yA5wnL7HE6lLgjaTW5n14ju2hl2NNA== - dependencies: - glob "*" - -"@types/glob@^7.1.1": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" - integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== - dependencies: - "@types/minimatch" "*" - "@types/node" "*" - -"@types/graceful-fs@^4.1.2": - version "4.1.9" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" - integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== - dependencies: - "@types/node" "*" - -"@types/hast@^2.0.0": - version "2.3.10" - resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.10.tgz#5c9d9e0b304bbb8879b857225c5ebab2d81d7643" - integrity sha512-McWspRw8xx8J9HurkVBfYj0xKoE25tOFlHGdx4MJ5xORQrMGZNqJhVQWaIbm6Oyla5kYOXtDiopzKRJzEOkwJw== - dependencies: - "@types/unist" "^2" - -"@types/hast@^3.0.0": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/hast/-/hast-3.0.4.tgz#1d6b39993b82cea6ad783945b0508c25903e15aa" - integrity sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ== - dependencies: - "@types/unist" "*" - -"@types/html-minifier-terser@^5.0.0": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.2.tgz#693b316ad323ea97eed6b38ed1a3cc02b1672b57" - integrity sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w== - -"@types/html-minifier-terser@^6.0.0": - version "6.1.0" - resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" - integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== - -"@types/http-errors@*": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.5.tgz#5b749ab2b16ba113423feb1a64a95dcd30398472" - integrity sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg== - -"@types/http-proxy@^1.17.8": - version "1.17.17" - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.17.tgz#d9e2c4571fe3507343cb210cd41790375e59a533" - integrity sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw== - dependencies: - "@types/node" "*" - -"@types/is-function@^1.0.0": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@types/is-function/-/is-function-1.0.3.tgz#548f851db5d30a12abeea2569ba75890dbf89425" - integrity sha512-/CLhCW79JUeLKznI6mbVieGbl4QU5Hfn+6udw1YHZoofASjbQ5zaP5LzAUZYDpRYEjS4/P+DhEgyJ/PQmGGTWw== - -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1", "@types/istanbul-lib-coverage@^2.0.6": - version "2.0.6" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" - integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== - -"@types/istanbul-lib-report@*": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" - integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== - dependencies: - "@types/istanbul-lib-coverage" "*" - -"@types/istanbul-reports@^3.0.0", "@types/istanbul-reports@^3.0.4": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" - integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== - dependencies: - "@types/istanbul-lib-report" "*" - -"@types/jest@^27.0.1": - version "27.5.2" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.5.2.tgz#ec49d29d926500ffb9fd22b84262e862049c026c" - integrity sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA== - dependencies: - jest-matcher-utils "^27.0.0" - pretty-format "^27.0.0" - -"@types/jest@^29.5.14": - version "29.5.14" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.14.tgz#2b910912fa1d6856cadcd0c1f95af7df1d6049e5" - integrity sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ== - dependencies: - expect "^29.0.0" - pretty-format "^29.0.0" - -"@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": - version "7.0.15" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" - integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== - -"@types/lodash@^4.14.167", "@types/lodash@^4.14.175": - version "4.17.20" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.17.20.tgz#1ca77361d7363432d29f5e55950d9ec1e1c6ea93" - integrity sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA== - -"@types/long@^4.0.1": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" - integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== - -"@types/mdast@^3.0.0": - version "3.0.15" - resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.15.tgz#49c524a263f30ffa28b71ae282f813ed000ab9f5" - integrity sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ== - dependencies: - "@types/unist" "^2" - -"@types/mdast@^4.0.0": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-4.0.4.tgz#7ccf72edd2f1aa7dd3437e180c64373585804dd6" - integrity sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA== - dependencies: - "@types/unist" "*" - -"@types/mime@^1": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" - integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== - -"@types/minimatch@*", "@types/minimatch@5.1.2", "@types/minimatch@^3.0.3": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" - integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== - -"@types/minimist@^1.2.0": - version "1.2.5" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.5.tgz#ec10755e871497bcd83efe927e43ec46e8c0747e" - integrity sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag== - -"@types/ms@*": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@types/ms/-/ms-2.1.0.tgz#052aa67a48eccc4309d7f0191b7e41434b90bb78" - integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA== - -"@types/node-fetch@^2.5.7": - version "2.6.13" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.13.tgz#e0c9b7b5edbdb1b50ce32c127e85e880872d56ee" - integrity sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw== - dependencies: - "@types/node" "*" - form-data "^4.0.4" - -"@types/node-forge@^1.3.0": - version "1.3.14" - resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.14.tgz#006c2616ccd65550560c2757d8472eb6d3ecea0b" - integrity sha512-mhVF2BnD4BO+jtOp7z1CdzaK4mbuK0LLQYAvdOLqHTavxFNq4zA1EmYkpnFjP8HOUzedfQkRnp0E2ulSAYSzAw== - dependencies: - "@types/node" "*" - -"@types/node@*", "@types/node@>=13.7.0": - version "24.9.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-24.9.1.tgz#b7360b3c789089e57e192695a855aa4f6981a53c" - integrity sha512-QoiaXANRkSXK6p0Duvt56W208du4P9Uye9hWLWgGMDTEoKPhuenzNcC4vGUmrNkiOKTlIrBoyNQYNpSwfEZXSg== - dependencies: - undici-types "~7.16.0" - -"@types/node@10.12.18": - version "10.12.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" - integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== - -"@types/node@^14.0.10 || ^16.0.0", "@types/node@^14.14.20 || ^16.0.0", "@types/node@^16.7.13": - version "16.18.126" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.126.tgz#27875faa2926c0f475b39a8bb1e546c0176f8d4b" - integrity sha512-OTcgaiwfGFBKacvfwuHzzn1KLxH/er8mluiy8/uM3sGXHaRe73RrSIj01jow9t4kJEW633Ov+cOexXeiApTyAw== - -"@types/node@^20": - version "20.19.23" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.19.23.tgz#7de99389c814071cca78656a3243f224fed7453d" - integrity sha512-yIdlVVVHXpmqRhtyovZAcSy0MiPcYWGkoO4CGe/+jpP0hmNuihm4XhHbADpK++MsiLHP5MVlv+bcgdF99kSiFQ== - dependencies: - undici-types "~6.21.0" - -"@types/node@^22.15.29": - version "22.19.17" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.19.17.tgz#09c71fb34ba2510f8ac865361b1fcb9552b8a581" - integrity sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q== - dependencies: - undici-types "~6.21.0" - -"@types/normalize-package-data@^2.4.0": - version "2.4.4" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" - integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== - -"@types/npmlog@^4.1.2": - version "4.1.6" - resolved "https://registry.yarnpkg.com/@types/npmlog/-/npmlog-4.1.6.tgz#792341665000209ee76997df8a16300fda6d77cb" - integrity sha512-0l3z16vnlJGl2Mi/rgJFrdwfLZ4jfNYgE6ZShEpjqhHuGTqdEzNles03NpYHwUMVYZa+Tj46UxKIEpE78lQ3DQ== - dependencies: - "@types/node" "*" - -"@types/parse-json@^4.0.0": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" - integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== - -"@types/parse5@^5.0.0": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" - integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== - -"@types/prettier@^2.1.5": - version "2.7.3" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" - integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== - -"@types/pretty-hrtime@^1.0.0": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#ee1bd8c9f7a01b3445786aad0ef23aba5f511a44" - integrity sha512-nj39q0wAIdhwn7DGUyT9irmsKK1tV0bd5WFEhgpqNTMFZ8cE+jieuTphCW0tfdm47S2zVT5mr09B28b1chmQMA== - -"@types/prop-types@*", "@types/prop-types@^15.7.12", "@types/prop-types@^15.7.14", "@types/prop-types@^15.7.15", "@types/prop-types@^15.7.2": - version "15.7.15" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.15.tgz#e6e5a86d602beaca71ce5163fadf5f95d70931c7" - integrity sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw== - -"@types/qrcode.react@^1.0.2": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@types/qrcode.react/-/qrcode.react-1.0.5.tgz#d4ddcacee8f34d22a663029a230c5f0ab908cfb7" - integrity sha512-BghPtnlwvrvq8QkGa1H25YnN+5OIgCKFuQruncGWLGJYOzeSKiix/4+B9BtfKF2wf5ja8yfyWYA3OXju995G8w== - dependencies: - "@types/react" "*" - -"@types/qs@*", "@types/qs@^6.9.18", "@types/qs@^6.9.5": - version "6.14.0" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.14.0.tgz#d8b60cecf62f2db0fb68e5e006077b9178b85de5" - integrity sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ== - -"@types/range-parser@*": - version "1.2.7" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" - integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== - -"@types/react-dom@^18", "@types/react-dom@^18.0.10": - version "18.3.7" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.7.tgz#b89ddf2cd83b4feafcc4e2ea41afdfb95a0d194f" - integrity sha512-MEe3UeoENYVFXzoXEWsvcpg6ZvlrFNlOQ7EOsvhI3CfAXwzPfO8Qwuxd40nepsYKqyyVQnTdEfv68q91yLcKrQ== - -"@types/react-dom@^19.2.3": - version "19.2.3" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-19.2.3.tgz#c1e305d15a52a3e508d54dca770d202cb63abf2c" - integrity sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ== - -"@types/react-transition-group@^4.4.10", "@types/react-transition-group@^4.4.11", "@types/react-transition-group@^4.4.12": - version "4.4.12" - resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.12.tgz#b5d76568485b02a307238270bfe96cb51ee2a044" - integrity sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w== - -"@types/react@*": - version "19.2.2" - resolved "https://registry.yarnpkg.com/@types/react/-/react-19.2.2.tgz#ba123a75d4c2a51158697160a4ea2ff70aa6bf36" - integrity sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA== - dependencies: - csstype "^3.0.2" - -"@types/react@^18", "@types/react@^18.0.26": - version "18.3.26" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.26.tgz#4c5970878d30db3d2a0bca1e4eb5f258e391bbeb" - integrity sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA== - dependencies: - "@types/prop-types" "*" - csstype "^3.0.2" - -"@types/react@^19.2.14": - version "19.2.14" - resolved "https://registry.yarnpkg.com/@types/react/-/react-19.2.14.tgz#39604929b5e3957e3a6fa0001dafb17c7af70bad" - integrity sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w== - dependencies: - csstype "^3.2.2" - -"@types/retry@0.12.0": - version "0.12.0" - resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" - integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== - -"@types/semver@^7.3.12", "@types/semver@^7.3.8": - version "7.7.1" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.7.1.tgz#3ce3af1a5524ef327d2da9e4fd8b6d95c8d70528" - integrity sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA== - -"@types/send@*": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@types/send/-/send-1.2.1.tgz#6a784e45543c18c774c049bff6d3dbaf045c9c74" - integrity sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ== - dependencies: - "@types/node" "*" - -"@types/send@<1": - version "0.17.6" - resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.6.tgz#aeb5385be62ff58a52cd5459daa509ae91651d25" - integrity sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og== - dependencies: - "@types/mime" "^1" - "@types/node" "*" - -"@types/serve-index@^1.9.1": - version "1.9.4" - resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.4.tgz#e6ae13d5053cb06ed36392110b4f9a49ac4ec898" - integrity sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug== - dependencies: - "@types/express" "*" - -"@types/serve-static@*", "@types/serve-static@^1.13.10": - version "1.15.10" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.10.tgz#768169145a778f8f5dfcb6360aead414a3994fee" - integrity sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw== - dependencies: - "@types/http-errors" "*" - "@types/node" "*" - "@types/send" "<1" - -"@types/sockjs@^0.3.33": - version "0.3.36" - resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.36.tgz#ce322cf07bcc119d4cbf7f88954f3a3bd0f67535" - integrity sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q== - dependencies: - "@types/node" "*" - -"@types/source-list-map@*": - version "0.1.6" - resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.6.tgz#164e169dd061795b50b83c19e4d3be09f8d3a454" - integrity sha512-5JcVt1u5HDmlXkwOD2nslZVllBBc7HDuOICfiZah2Z0is8M8g+ddAEawbmd3VjedfDHBzxCaXLs07QEmb7y54g== - -"@types/stack-utils@^2.0.0", "@types/stack-utils@^2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" - integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== - -"@types/tapable@^1", "@types/tapable@^1.0.5": - version "1.0.12" - resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.12.tgz#bc2cab12e87978eee89fb21576b670350d6d86ab" - integrity sha512-bTHG8fcxEqv1M9+TD14P8ok8hjxoOCkfKc8XXLaaD05kI7ohpeI956jtDOD3XHKBQrlyPughUtzm1jtVhHpA5Q== - -"@types/trusted-types@^2.0.7": - version "2.0.7" - resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.7.tgz#baccb07a970b91707df3a3e8ba6896c57ead2d11" - integrity sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw== - -"@types/uglify-js@*": - version "3.17.5" - resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.17.5.tgz#905ce03a3cbbf2e31cbefcbc68d15497ee2e17df" - integrity sha512-TU+fZFBTBcXj/GpDpDaBmgWk/gn96kMZ+uocaFUlV2f8a6WdMzzI44QBCmGcCiYR0Y6ZlNRiyUyKKt5nl/lbzQ== - dependencies: - source-map "^0.6.1" - -"@types/unist@*", "@types/unist@^3.0.0": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-3.0.3.tgz#acaab0f919ce69cce629c2d4ed2eb4adc1b6c20c" - integrity sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q== - -"@types/unist@^2", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3": - version "2.0.11" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.11.tgz#11af57b127e32487774841f7a4e54eab166d03c4" - integrity sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA== - -"@types/uuid@^8.3.4": - version "8.3.4" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" - integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== - -"@types/webpack-env@^1.16.0": - version "1.18.8" - resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.18.8.tgz#71f083718c094204d7b64443701d32f1db3989e3" - integrity sha512-G9eAoJRMLjcvN4I08wB5I7YofOb/kaJNd5uoCMX+LbKXTPCF+ZIHuqTnFaK9Jz1rgs035f9JUPUhNFtqgucy/A== - -"@types/webpack-sources@*": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-3.2.3.tgz#b667bd13e9fa15a9c26603dce502c7985418c3d8" - integrity sha512-4nZOdMwSPHZ4pTEZzSp0AsTM4K7Qmu40UKW4tJDiOVs20UzYF9l+qUe4s0ftfN0pin06n+5cWWDJXH+sbhAiDw== - dependencies: - "@types/node" "*" - "@types/source-list-map" "*" - source-map "^0.7.3" - -"@types/webpack@^4.41.26", "@types/webpack@^4.41.8": - version "4.41.40" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.40.tgz#41ea11cfafe08de24c3ef410c58976350667e2d1" - integrity sha512-u6kMFSBM9HcoTpUXnL6mt2HSzftqb3JgYV6oxIgL2dl6sX6aCa5k6SOkzv5DuZjBTPUE/dJltKtwwuqrkZHpfw== - dependencies: - "@types/node" "*" - "@types/tapable" "^1" - "@types/uglify-js" "*" - "@types/webpack-sources" "*" - anymatch "^3.0.0" - source-map "^0.6.0" - -"@types/ws@^8.5.5": - version "8.18.1" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.18.1.tgz#48464e4bf2ddfd17db13d845467f6070ffea4aa9" - integrity sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg== - dependencies: - "@types/node" "*" - -"@types/yargs-parser@*": - version "21.0.3" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" - integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== - -"@types/yargs@^15.0.0": - version "15.0.19" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.19.tgz#328fb89e46109ecbdb70c295d96ff2f46dfd01b9" - integrity sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA== - dependencies: - "@types/yargs-parser" "*" - -"@types/yargs@^16.0.0": - version "16.0.10" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.10.tgz#2376eed83bc9dbda3d7253a44e18328fc0854477" - integrity sha512-0xbOE6Ht/oj0MTVVXCCdEZzUk7adwW3YB1Tg1ZBm95jrkrUMI0VA4sf3SgxC1TG8p5aKkn3jxT9A2BDw1mM/TQ== - dependencies: - "@types/yargs-parser" "*" - -"@types/yargs@^17.0.33", "@types/yargs@^17.0.8": - version "17.0.34" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.34.tgz#1c2f9635b71d5401827373a01ce2e8a7670ea839" - integrity sha512-KExbHVa92aJpw9WDQvzBaGVE2/Pz+pLZQloT2hjL8IqsZnV62rlPOYvNnLmf/L2dyllfVUOVBj64M0z/46eR2A== - dependencies: - "@types/yargs-parser" "*" - -"@types/zxcvbn@^4.4.1": - version "4.4.5" - resolved "https://registry.yarnpkg.com/@types/zxcvbn/-/zxcvbn-4.4.5.tgz#8ce8623ed7a36e3a76d1c0b539708dfb2e859bc0" - integrity sha512-FZJgC5Bxuqg7Rhsm/bx6gAruHHhDQ55r+s0JhDh8CQ16fD7NsJJ+p8YMMQDhSQoIrSmjpqqYWA96oQVMNkjRyA== - -"@typescript-eslint/eslint-plugin@^5.13.0", "@typescript-eslint/eslint-plugin@^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db" - integrity sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag== - dependencies: - "@eslint-community/regexpp" "^4.4.0" - "@typescript-eslint/scope-manager" "5.62.0" - "@typescript-eslint/type-utils" "5.62.0" - "@typescript-eslint/utils" "5.62.0" - debug "^4.3.4" - graphemer "^1.4.0" - ignore "^5.2.0" - natural-compare-lite "^1.4.0" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/eslint-plugin@^8.56.1": - version "8.59.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.2.tgz#f37b2c189a0177141fe3de3b08f2a83991bfdbfa" - integrity sha512-j/bwmkBvHUtPNxzuWe5z6BEk3q54YRyGlBXkSsmfoih7zNrBvl5A9A98anlp/7JbyZcWIJ8KXo/3Tq/DjFLtuQ== - dependencies: - "@eslint-community/regexpp" "^4.12.2" - "@typescript-eslint/scope-manager" "8.59.2" - "@typescript-eslint/type-utils" "8.59.2" - "@typescript-eslint/utils" "8.59.2" - "@typescript-eslint/visitor-keys" "8.59.2" - ignore "^7.0.5" - natural-compare "^1.4.0" - ts-api-utils "^2.5.0" - -"@typescript-eslint/experimental-utils@^5.3.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz#14559bf73383a308026b427a4a6129bae2146741" - integrity sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw== - dependencies: - "@typescript-eslint/utils" "5.62.0" - -"@typescript-eslint/parser@^5.13.0", "@typescript-eslint/parser@^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7" - integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== - dependencies: - "@typescript-eslint/scope-manager" "5.62.0" - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/typescript-estree" "5.62.0" - debug "^4.3.4" - -"@typescript-eslint/parser@^8.56.1": - version "8.59.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.59.2.tgz#e2fd0084baa5dd0c24cd789af1c72cbc3a7a1c62" - integrity sha512-plR3pp6D+SSUn1HM7xvSkx12/DhoHInI2YF35KAcVFNZvlC0gtrWqx7Qq1oH2Ssgi0vlFRCTbP+DZc7B9+TtsQ== - dependencies: - "@typescript-eslint/scope-manager" "8.59.2" - "@typescript-eslint/types" "8.59.2" - "@typescript-eslint/typescript-estree" "8.59.2" - "@typescript-eslint/visitor-keys" "8.59.2" - debug "^4.4.3" - -"@typescript-eslint/project-service@8.59.2": - version "8.59.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/project-service/-/project-service-8.59.2.tgz#f8b8cbf8692e3a51c2c394acf8cf6900f7e755af" - integrity sha512-+2hqvEkeyf/0FBor67duF0Ll7Ot8jyKzDQOSrxazF/danillRq2DwR9dLptsXpoZQqxE1UisSmoZewrlPas9Vw== - dependencies: - "@typescript-eslint/tsconfig-utils" "^8.59.2" - "@typescript-eslint/types" "^8.59.2" - debug "^4.4.3" - -"@typescript-eslint/scope-manager@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" - integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== - dependencies: - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/visitor-keys" "5.62.0" - -"@typescript-eslint/scope-manager@8.59.2": - version "8.59.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.59.2.tgz#63cbd0af2e3180949d6be81122cc555bc71e736d" - integrity sha512-JzfyEpEtOU89CcFSwyNS3mu4MLvLSXqnmX05+aKBDM+TdR5jzcGOEBwxwGNxrEQ7p/z6kK2WyioCGBf2zZBnvg== - dependencies: - "@typescript-eslint/types" "8.59.2" - "@typescript-eslint/visitor-keys" "8.59.2" - -"@typescript-eslint/tsconfig-utils@8.59.2", "@typescript-eslint/tsconfig-utils@^8.59.2": - version "8.59.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.2.tgz#6e92bc412083753185a79c9f1431e78169d9232f" - integrity sha512-BKK4alN7oi4C/zv4VqHQ+uRU+lTa6JGIZ7s1juw7b3RHo9OfKB+bKX3u0iVZetdsUCBBkSbdWbarJbmN0fTeSw== - -"@typescript-eslint/type-utils@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz#286f0389c41681376cdad96b309cedd17d70346a" - integrity sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew== - dependencies: - "@typescript-eslint/typescript-estree" "5.62.0" - "@typescript-eslint/utils" "5.62.0" - debug "^4.3.4" - tsutils "^3.21.0" - -"@typescript-eslint/type-utils@8.59.2": - version "8.59.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.59.2.tgz#a60a1192a804fa472a92c41656853ac6a9ba7176" - integrity sha512-nhqaj1nmTdVVl/BP5omXNRGO38jn5iosis2vbdmupF2txCf8ylWT8lx+JlvMYYVqzGVKtjojUFoQ3JRWK+mfzQ== - dependencies: - "@typescript-eslint/types" "8.59.2" - "@typescript-eslint/typescript-estree" "8.59.2" - "@typescript-eslint/utils" "8.59.2" - debug "^4.4.3" - ts-api-utils "^2.5.0" - -"@typescript-eslint/types@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" - integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== - -"@typescript-eslint/types@8.59.2", "@typescript-eslint/types@^8.59.2": - version "8.59.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.59.2.tgz#01caabcd7e4715c33ad5e11cab260829714d6b9c" - integrity sha512-e82GVOE8Ps3E++Egvb6Y3Dw0S10u8NkQ9KXmtRhCWJJ8kDhOJTvtMAWnFL16kB1583goCWXsr0NieKCZMs2/0Q== - -"@typescript-eslint/typescript-estree@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" - integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== - dependencies: - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/visitor-keys" "5.62.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/typescript-estree@8.59.2": - version "8.59.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.2.tgz#6a217ef65b18dbd12c718fc86a675d1d7a1414cc" - integrity sha512-o0XPGNwcWw+FIwStOWn+BwBuEmL6QXP0rsvAFg7ET1dey1Nr6Wb1ac8p5HEsK0ygO/6mUxlk+YWQD9xcb/nnXg== - dependencies: - "@typescript-eslint/project-service" "8.59.2" - "@typescript-eslint/tsconfig-utils" "8.59.2" - "@typescript-eslint/types" "8.59.2" - "@typescript-eslint/visitor-keys" "8.59.2" - debug "^4.4.3" - minimatch "^10.2.2" - semver "^7.7.3" - tinyglobby "^0.2.15" - ts-api-utils "^2.5.0" - -"@typescript-eslint/utils@5.62.0", "@typescript-eslint/utils@^5.10.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" - integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@types/json-schema" "^7.0.9" - "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.62.0" - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/typescript-estree" "5.62.0" - eslint-scope "^5.1.1" - semver "^7.3.7" - -"@typescript-eslint/utils@8.59.2": - version "8.59.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.59.2.tgz#ff619a6a3075f4017fa91b8610b752a8ca3366aa" - integrity sha512-Juw3EinkXqjaffxz6roowvV7GZT/kET5vSKKZT6upl5TXdWkLkYmNPXwDDL2Vkt2DPn0nODIS4egC/0AGxKo/Q== - dependencies: - "@eslint-community/eslint-utils" "^4.9.1" - "@typescript-eslint/scope-manager" "8.59.2" - "@typescript-eslint/types" "8.59.2" - "@typescript-eslint/typescript-estree" "8.59.2" - -"@typescript-eslint/visitor-keys@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" - integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== - dependencies: - "@typescript-eslint/types" "5.62.0" - eslint-visitor-keys "^3.3.0" - -"@typescript-eslint/visitor-keys@8.59.2": - version "8.59.2" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.2.tgz#5ccc486913cd347883d69158836b1189a660bfe6" - integrity sha512-NwjLUnGy8/Zfx23fl50tRC8rYaYnM52xNRYFAXvmiil9yh1+K6aRVQMnzW6gQB/1DLgWt977lYQn7C+wtgXZiA== - dependencies: - "@typescript-eslint/types" "8.59.2" - eslint-visitor-keys "^5.0.0" - -"@uidotdev/usehooks@^2.4.1": - version "2.4.1" - resolved "https://registry.yarnpkg.com/@uidotdev/usehooks/-/usehooks-2.4.1.tgz#4b733eaeae09a7be143c6c9ca158b56cc1ea75bf" - integrity sha512-1I+RwWyS+kdv3Mv0Vmc+p0dPYH0DTRAo04HLyXReYBL9AeseDWUJyi4THuksBJcu9F0Pih69Ak150VDnqbVnXg== - -"@ungap/structured-clone@^1.0.0", "@ungap/structured-clone@^1.2.0", "@ungap/structured-clone@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.3.0.tgz#d06bbb384ebcf6c505fde1c3d0ed4ddffe0aaff8" - integrity sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g== - -"@unrs/resolver-binding-android-arm-eabi@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.11.1.tgz#9f5b04503088e6a354295e8ea8fe3cb99e43af81" - integrity sha512-ppLRUgHVaGRWUx0R0Ut06Mjo9gBaBkg3v/8AxusGLhsIotbBLuRk51rAzqLC8gq6NyyAojEXglNjzf6R948DNw== - -"@unrs/resolver-binding-android-arm64@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.11.1.tgz#7414885431bd7178b989aedc4d25cccb3865bc9f" - integrity sha512-lCxkVtb4wp1v+EoN+HjIG9cIIzPkX5OtM03pQYkG+U5O/wL53LC4QbIeazgiKqluGeVEeBlZahHalCaBvU1a2g== - -"@unrs/resolver-binding-darwin-arm64@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.11.1.tgz#b4a8556f42171fb9c9f7bac8235045e82aa0cbdf" - integrity sha512-gPVA1UjRu1Y/IsB/dQEsp2V1pm44Of6+LWvbLc9SDk1c2KhhDRDBUkQCYVWe6f26uJb3fOK8saWMgtX8IrMk3g== - -"@unrs/resolver-binding-darwin-x64@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.11.1.tgz#fd4d81257b13f4d1a083890a6a17c00de571f0dc" - integrity sha512-cFzP7rWKd3lZaCsDze07QX1SC24lO8mPty9vdP+YVa3MGdVgPmFc59317b2ioXtgCMKGiCLxJ4HQs62oz6GfRQ== - -"@unrs/resolver-binding-freebsd-x64@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.11.1.tgz#d2513084d0f37c407757e22f32bd924a78cfd99b" - integrity sha512-fqtGgak3zX4DCB6PFpsH5+Kmt/8CIi4Bry4rb1ho6Av2QHTREM+47y282Uqiu3ZRF5IQioJQ5qWRV6jduA+iGw== - -"@unrs/resolver-binding-linux-arm-gnueabihf@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.11.1.tgz#844d2605d057488d77fab09705f2866b86164e0a" - integrity sha512-u92mvlcYtp9MRKmP+ZvMmtPN34+/3lMHlyMj7wXJDeXxuM0Vgzz0+PPJNsro1m3IZPYChIkn944wW8TYgGKFHw== - -"@unrs/resolver-binding-linux-arm-musleabihf@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.11.1.tgz#204892995cefb6bd1d017d52d097193bc61ddad3" - integrity sha512-cINaoY2z7LVCrfHkIcmvj7osTOtm6VVT16b5oQdS4beibX2SYBwgYLmqhBjA1t51CarSaBuX5YNsWLjsqfW5Cw== - -"@unrs/resolver-binding-linux-arm64-gnu@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.11.1.tgz#023eb0c3aac46066a10be7a3f362e7b34f3bdf9d" - integrity sha512-34gw7PjDGB9JgePJEmhEqBhWvCiiWCuXsL9hYphDF7crW7UgI05gyBAi6MF58uGcMOiOqSJ2ybEeCvHcq0BCmQ== - -"@unrs/resolver-binding-linux-arm64-musl@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.11.1.tgz#9e6f9abb06424e3140a60ac996139786f5d99be0" - integrity sha512-RyMIx6Uf53hhOtJDIamSbTskA99sPHS96wxVE/bJtePJJtpdKGXO1wY90oRdXuYOGOTuqjT8ACccMc4K6QmT3w== - -"@unrs/resolver-binding-linux-ppc64-gnu@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.11.1.tgz#b111417f17c9d1b02efbec8e08398f0c5527bb44" - integrity sha512-D8Vae74A4/a+mZH0FbOkFJL9DSK2R6TFPC9M+jCWYia/q2einCubX10pecpDiTmkJVUH+y8K3BZClycD8nCShA== - -"@unrs/resolver-binding-linux-riscv64-gnu@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.11.1.tgz#92ffbf02748af3e99873945c9a8a5ead01d508a9" - integrity sha512-frxL4OrzOWVVsOc96+V3aqTIQl1O2TjgExV4EKgRY09AJ9leZpEg8Ak9phadbuX0BA4k8U5qtvMSQQGGmaJqcQ== - -"@unrs/resolver-binding-linux-riscv64-musl@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.11.1.tgz#0bec6f1258fc390e6b305e9ff44256cb207de165" - integrity sha512-mJ5vuDaIZ+l/acv01sHoXfpnyrNKOk/3aDoEdLO/Xtn9HuZlDD6jKxHlkN8ZhWyLJsRBxfv9GYM2utQ1SChKew== - -"@unrs/resolver-binding-linux-s390x-gnu@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.11.1.tgz#577843a084c5952f5906770633ccfb89dac9bc94" - integrity sha512-kELo8ebBVtb9sA7rMe1Cph4QHreByhaZ2QEADd9NzIQsYNQpt9UkM9iqr2lhGr5afh885d/cB5QeTXSbZHTYPg== - -"@unrs/resolver-binding-linux-x64-gnu@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.11.1.tgz#36fb318eebdd690f6da32ac5e0499a76fa881935" - integrity sha512-C3ZAHugKgovV5YvAMsxhq0gtXuwESUKc5MhEtjBpLoHPLYM+iuwSj3lflFwK3DPm68660rZ7G8BMcwSro7hD5w== - -"@unrs/resolver-binding-linux-x64-musl@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.11.1.tgz#bfb9af75f783f98f6a22c4244214efe4df1853d6" - integrity sha512-rV0YSoyhK2nZ4vEswT/QwqzqQXw5I6CjoaYMOX0TqBlWhojUf8P94mvI7nuJTeaCkkds3QE4+zS8Ko+GdXuZtA== - -"@unrs/resolver-binding-wasm32-wasi@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.11.1.tgz#752c359dd875684b27429500d88226d7cc72f71d" - integrity sha512-5u4RkfxJm+Ng7IWgkzi3qrFOvLvQYnPBmjmZQ8+szTK/b31fQCnleNl1GgEt7nIsZRIf5PLhPwT0WM+q45x/UQ== - dependencies: - "@napi-rs/wasm-runtime" "^0.2.11" - -"@unrs/resolver-binding-win32-arm64-msvc@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.11.1.tgz#ce5735e600e4c2fbb409cd051b3b7da4a399af35" - integrity sha512-nRcz5Il4ln0kMhfL8S3hLkxI85BXs3o8EYoattsJNdsX4YUU89iOkVn7g0VHSRxFuVMdM4Q1jEpIId1Ihim/Uw== - -"@unrs/resolver-binding-win32-ia32-msvc@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.11.1.tgz#72fc57bc7c64ec5c3de0d64ee0d1810317bc60a6" - integrity sha512-DCEI6t5i1NmAZp6pFonpD5m7i6aFrpofcp4LA2i8IIq60Jyo28hamKBxNrZcyOwVOZkgsRp9O2sXWBWP8MnvIQ== - -"@unrs/resolver-binding-win32-x64-msvc@1.11.1": - version "1.11.1" - resolved "https://registry.yarnpkg.com/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.11.1.tgz#538b1e103bf8d9864e7b85cc96fa8d6fb6c40777" - integrity sha512-lrW200hZdbfRtztbygyaq/6jP6AKE8qQN2KvPcJ+x7wiD038YtnYtZ82IMNJ69GJibV7bwL3y9FgK+5w/pYt6g== - -"@vanilla-extract/css-utils@^0.1.4": - version "0.1.6" - resolved "https://registry.yarnpkg.com/@vanilla-extract/css-utils/-/css-utils-0.1.6.tgz#f83df9b8d30e65dae2c301c711546212e5246a53" - integrity sha512-iICpaHma0s2EEnQDw/JRqudQJwYw1JERyWfIllNQplps226KVphjGb3jyGMiBK5Waw69RD3q4gulgRVQAQmKmA== - -"@vanilla-extract/css@^1.15.5": - version "1.17.4" - resolved "https://registry.yarnpkg.com/@vanilla-extract/css/-/css-1.17.4.tgz#c73353992b8243e8ab140582bf6d673ebc709b0a" - integrity sha512-m3g9nQDWPtL+sTFdtCGRMI1Vrp86Ay4PBYq1Bo7Bnchj5ElNtAJpOqD+zg+apthVA4fB7oVpMWNjwpa6ElDWFQ== - dependencies: - "@emotion/hash" "^0.9.0" - "@vanilla-extract/private" "^1.0.9" - css-what "^6.1.0" - cssesc "^3.0.0" - csstype "^3.0.7" - dedent "^1.5.3" - deep-object-diff "^1.1.9" - deepmerge "^4.2.2" - lru-cache "^10.4.3" - media-query-parser "^2.0.2" - modern-ahocorasick "^1.0.0" - picocolors "^1.0.0" - -"@vanilla-extract/dynamic@^2.1.2": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@vanilla-extract/dynamic/-/dynamic-2.1.5.tgz#2e2721d5e17071c161e3fdf29b8204772e3bbabc" - integrity sha512-QGIFGb1qyXQkbzx6X6i3+3LMc/iv/ZMBttMBL+Wm/DetQd36KsKsFg5CtH3qy+1hCA/5w93mEIIAiL4fkM8ycw== - dependencies: - "@vanilla-extract/private" "^1.0.9" - -"@vanilla-extract/private@^1.0.6", "@vanilla-extract/private@^1.0.9": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@vanilla-extract/private/-/private-1.0.9.tgz#bb8aaf72d2e04439792f2e389d9b705cfe691bc0" - integrity sha512-gT2jbfZuaaCLrAxwXbRgIhGhcXbRZCG3v4TTUnjw0EJ7ArdBRxkq4msNJkbuRkCgfIK5ATmprB5t9ljvLeFDEA== - -"@vanilla-extract/recipes@^0.5.5": - version "0.5.7" - resolved "https://registry.yarnpkg.com/@vanilla-extract/recipes/-/recipes-0.5.7.tgz#6677a267ca278e2277ac8ab41b64e57e84c1150c" - integrity sha512-Fvr+htdyb6LVUu+PhH61UFPhwkjgDEk8L4Zq9oIdte42sntpKrgFy90MyTRtGwjVALmrJ0pwRUVr8UoByYeW8A== - -"@vitest/pretty-format@2.1.9": - version "2.1.9" - resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-2.1.9.tgz#434ff2f7611689f9ce70cd7d567eceb883653fdf" - integrity sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ== - dependencies: - tinyrainbow "^1.2.0" - -"@vitest/utils@^2.1.1": - version "2.1.9" - resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-2.1.9.tgz#4f2486de8a54acf7ecbf2c5c24ad7994a680a6c1" - integrity sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ== - dependencies: - "@vitest/pretty-format" "2.1.9" - loupe "^3.1.2" - tinyrainbow "^1.2.0" - -"@walletconnect/events@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@walletconnect/events/-/events-1.0.1.tgz#2b5f9c7202019e229d7ccae1369a9e86bda7816c" - integrity sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ== - dependencies: - keyvaluestorage-interface "^1.0.0" - tslib "1.14.1" - -"@walletconnect/heartbeat@1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@walletconnect/heartbeat/-/heartbeat-1.2.1.tgz#afaa3a53232ae182d7c9cff41c1084472d8f32e9" - integrity sha512-yVzws616xsDLJxuG/28FqtZ5rzrTA4gUjdEMTbWB5Y8V1XHRmqq4efAxCw5ie7WjbXFSUyBHaWlMR+2/CpQC5Q== - dependencies: - "@walletconnect/events" "^1.0.1" - "@walletconnect/time" "^1.0.2" - tslib "1.14.1" - -"@walletconnect/jsonrpc-types@1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-types/-/jsonrpc-types-1.0.3.tgz#65e3b77046f1a7fa8347ae02bc1b841abe6f290c" - integrity sha512-iIQ8hboBl3o5ufmJ8cuduGad0CQm3ZlsHtujv9Eu16xq89q+BG7Nh5VLxxUgmtpnrePgFkTwXirCTkwJH1v+Yw== - dependencies: - keyvaluestorage-interface "^1.0.0" - tslib "1.14.1" - -"@walletconnect/keyvaluestorage@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@walletconnect/keyvaluestorage/-/keyvaluestorage-1.1.1.tgz#dd2caddabfbaf80f6b8993a0704d8b83115a1842" - integrity sha512-V7ZQq2+mSxAq7MrRqDxanTzu2RcElfK1PfNYiaVnJgJ7Q7G7hTVwF8voIBx92qsRyGHZihrwNPHuZd1aKkd0rA== - dependencies: - "@walletconnect/safe-json" "^1.0.1" - idb-keyval "^6.2.1" - unstorage "^1.9.0" - -"@walletconnect/logger@^2.0.1": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@walletconnect/logger/-/logger-2.1.3.tgz#f7b2ba46652a960fb731839cad271a94a0523a08" - integrity sha512-wRsD0eDQSajj8YMM/jpxoH1yeSLyS7FPkh0VKCQ1BWrERTy1Z7/DmOE8FYm/gmd7Cg6BNXVWiymhGq6wnmlq8w== - dependencies: - "@walletconnect/safe-json" "^1.0.2" - pino "7.11.0" - -"@walletconnect/safe-json@^1.0.1", "@walletconnect/safe-json@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@walletconnect/safe-json/-/safe-json-1.0.2.tgz#7237e5ca48046e4476154e503c6d3c914126fa77" - integrity sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA== - dependencies: - tslib "1.14.1" - -"@walletconnect/time@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@walletconnect/time/-/time-1.0.2.tgz#6c5888b835750ecb4299d28eecc5e72c6d336523" - integrity sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g== - dependencies: - tslib "1.14.1" - -"@walletconnect/types@2.11.0": - version "2.11.0" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.11.0.tgz#474a009c56faa9ef4063b76ed84415c801dc9f1e" - integrity sha512-AB5b1lrEbCGHxqS2vqfCkIoODieH+ZAUp9rA1O2ftrhnqDJiJK983Df87JhYhECsQUBHHfALphA8ydER0q+9sw== - dependencies: - "@walletconnect/events" "^1.0.1" - "@walletconnect/heartbeat" "1.2.1" - "@walletconnect/jsonrpc-types" "1.0.3" - "@walletconnect/keyvaluestorage" "^1.1.1" - "@walletconnect/logger" "^2.0.1" - events "^3.3.0" - -"@webassemblyjs/ast@1.14.1", "@webassemblyjs/ast@^1.14.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.14.1.tgz#a9f6a07f2b03c95c8d38c4536a1fdfb521ff55b6" - integrity sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ== - dependencies: - "@webassemblyjs/helper-numbers" "1.13.2" - "@webassemblyjs/helper-wasm-bytecode" "1.13.2" - -"@webassemblyjs/ast@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" - integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== - dependencies: - "@webassemblyjs/helper-module-context" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/wast-parser" "1.9.0" - -"@webassemblyjs/floating-point-hex-parser@1.13.2": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz#fcca1eeddb1cc4e7b6eed4fc7956d6813b21b9fb" - integrity sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA== - -"@webassemblyjs/floating-point-hex-parser@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" - integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== - -"@webassemblyjs/helper-api-error@1.13.2": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz#e0a16152248bc38daee76dd7e21f15c5ef3ab1e7" - integrity sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ== - -"@webassemblyjs/helper-api-error@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" - integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== - -"@webassemblyjs/helper-buffer@1.14.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz#822a9bc603166531f7d5df84e67b5bf99b72b96b" - integrity sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA== - -"@webassemblyjs/helper-buffer@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" - integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== - -"@webassemblyjs/helper-code-frame@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" - integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== - dependencies: - "@webassemblyjs/wast-printer" "1.9.0" - -"@webassemblyjs/helper-fsm@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" - integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== - -"@webassemblyjs/helper-module-context@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" - integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== - dependencies: - "@webassemblyjs/ast" "1.9.0" - -"@webassemblyjs/helper-numbers@1.13.2": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz#dbd932548e7119f4b8a7877fd5a8d20e63490b2d" - integrity sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA== - dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.13.2" - "@webassemblyjs/helper-api-error" "1.13.2" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/helper-wasm-bytecode@1.13.2": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz#e556108758f448aae84c850e593ce18a0eb31e0b" - integrity sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA== - -"@webassemblyjs/helper-wasm-bytecode@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" - integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== - -"@webassemblyjs/helper-wasm-section@1.14.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz#9629dda9c4430eab54b591053d6dc6f3ba050348" - integrity sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw== - dependencies: - "@webassemblyjs/ast" "1.14.1" - "@webassemblyjs/helper-buffer" "1.14.1" - "@webassemblyjs/helper-wasm-bytecode" "1.13.2" - "@webassemblyjs/wasm-gen" "1.14.1" - -"@webassemblyjs/helper-wasm-section@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" - integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-buffer" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/wasm-gen" "1.9.0" - -"@webassemblyjs/ieee754@1.13.2": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz#1c5eaace1d606ada2c7fd7045ea9356c59ee0dba" - integrity sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw== - dependencies: - "@xtuc/ieee754" "^1.2.0" - -"@webassemblyjs/ieee754@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" - integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== - dependencies: - "@xtuc/ieee754" "^1.2.0" - -"@webassemblyjs/leb128@1.13.2": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.13.2.tgz#57c5c3deb0105d02ce25fa3fd74f4ebc9fd0bbb0" - integrity sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw== - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/leb128@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" - integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/utf8@1.13.2": - version "1.13.2" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.13.2.tgz#917a20e93f71ad5602966c2d685ae0c6c21f60f1" - integrity sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ== - -"@webassemblyjs/utf8@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" - integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== - -"@webassemblyjs/wasm-edit@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" - integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-buffer" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/helper-wasm-section" "1.9.0" - "@webassemblyjs/wasm-gen" "1.9.0" - "@webassemblyjs/wasm-opt" "1.9.0" - "@webassemblyjs/wasm-parser" "1.9.0" - "@webassemblyjs/wast-printer" "1.9.0" - -"@webassemblyjs/wasm-edit@^1.14.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz#ac6689f502219b59198ddec42dcd496b1004d597" - integrity sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ== - dependencies: - "@webassemblyjs/ast" "1.14.1" - "@webassemblyjs/helper-buffer" "1.14.1" - "@webassemblyjs/helper-wasm-bytecode" "1.13.2" - "@webassemblyjs/helper-wasm-section" "1.14.1" - "@webassemblyjs/wasm-gen" "1.14.1" - "@webassemblyjs/wasm-opt" "1.14.1" - "@webassemblyjs/wasm-parser" "1.14.1" - "@webassemblyjs/wast-printer" "1.14.1" - -"@webassemblyjs/wasm-gen@1.14.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz#991e7f0c090cb0bb62bbac882076e3d219da9570" - integrity sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg== - dependencies: - "@webassemblyjs/ast" "1.14.1" - "@webassemblyjs/helper-wasm-bytecode" "1.13.2" - "@webassemblyjs/ieee754" "1.13.2" - "@webassemblyjs/leb128" "1.13.2" - "@webassemblyjs/utf8" "1.13.2" - -"@webassemblyjs/wasm-gen@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" - integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/ieee754" "1.9.0" - "@webassemblyjs/leb128" "1.9.0" - "@webassemblyjs/utf8" "1.9.0" - -"@webassemblyjs/wasm-opt@1.14.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz#e6f71ed7ccae46781c206017d3c14c50efa8106b" - integrity sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw== - dependencies: - "@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-opt@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" - integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-buffer" "1.9.0" - "@webassemblyjs/wasm-gen" "1.9.0" - "@webassemblyjs/wasm-parser" "1.9.0" - -"@webassemblyjs/wasm-parser@1.14.1", "@webassemblyjs/wasm-parser@^1.14.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz#b3e13f1893605ca78b52c68e54cf6a865f90b9fb" - integrity sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ== - dependencies: - "@webassemblyjs/ast" "1.14.1" - "@webassemblyjs/helper-api-error" "1.13.2" - "@webassemblyjs/helper-wasm-bytecode" "1.13.2" - "@webassemblyjs/ieee754" "1.13.2" - "@webassemblyjs/leb128" "1.13.2" - "@webassemblyjs/utf8" "1.13.2" - -"@webassemblyjs/wasm-parser@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" - integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-api-error" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/ieee754" "1.9.0" - "@webassemblyjs/leb128" "1.9.0" - "@webassemblyjs/utf8" "1.9.0" - -"@webassemblyjs/wast-parser@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" - integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/floating-point-hex-parser" "1.9.0" - "@webassemblyjs/helper-api-error" "1.9.0" - "@webassemblyjs/helper-code-frame" "1.9.0" - "@webassemblyjs/helper-fsm" "1.9.0" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/wast-printer@1.14.1": - version "1.14.1" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz#3bb3e9638a8ae5fdaf9610e7a06b4d9f9aa6fe07" - integrity sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw== - dependencies: - "@webassemblyjs/ast" "1.14.1" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/wast-printer@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" - integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/wast-parser" "1.9.0" - "@xtuc/long" "4.2.2" - -"@webpack-cli/configtest@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.2.0.tgz#7b20ce1c12533912c3b217ea68262365fa29a6f5" - integrity sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg== - -"@webpack-cli/configtest@^2.1.1": - version "2.1.1" - resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-2.1.1.tgz#3b2f852e91dac6e3b85fb2a314fb8bef46d94646" - integrity sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw== - -"@webpack-cli/info@^1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.5.0.tgz#6c78c13c5874852d6e2dd17f08a41f3fe4c261b1" - integrity sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ== - dependencies: - envinfo "^7.7.3" - -"@webpack-cli/info@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-2.0.2.tgz#cc3fbf22efeb88ff62310cf885c5b09f44ae0fdd" - integrity sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A== - -"@webpack-cli/serve@^1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.7.0.tgz#e1993689ac42d2b16e9194376cfb6753f6254db1" - integrity sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q== - -"@webpack-cli/serve@^2.0.5": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-2.0.5.tgz#325db42395cd49fe6c14057f9a900e427df8810e" - integrity sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ== - -"@xtuc/ieee754@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" - integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== - -"@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" - integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== - -"@yarnpkg/lockfile@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" - integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== - -"@yarnpkg/parsers@3.0.0-rc.46": - version "3.0.0-rc.46" - resolved "https://registry.yarnpkg.com/@yarnpkg/parsers/-/parsers-3.0.0-rc.46.tgz#03f8363111efc0ea670e53b0282cd3ef62de4e01" - integrity sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q== - dependencies: - js-yaml "^3.10.0" - tslib "^2.4.0" - -"@zkochan/js-yaml@0.0.6": - version "0.0.6" - resolved "https://registry.yarnpkg.com/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz#975f0b306e705e28b8068a07737fa46d3fc04826" - integrity sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg== - dependencies: - argparse "^2.0.1" - -JSONStream@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" - integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - -abab@^2.0.3, abab@^2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" - integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== - -abbrev@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -accepts@~1.3.4, accepts@~1.3.8: - version "1.3.8" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" - integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== - dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" - -acorn-globals@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" - integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== - dependencies: - acorn "^7.1.1" - acorn-walk "^7.1.1" - -acorn-import-phases@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz#16eb850ba99a056cb7cbfe872ffb8972e18c8bd7" - integrity sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ== - -acorn-jsx@^5.3.1, acorn-jsx@^5.3.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn-walk@^7.1.1, acorn-walk@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" - integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== - -acorn@^6.4.1: - version "6.4.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" - integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== - -acorn@^7.1.1, acorn@^7.4.1: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== - -acorn@^8.15.0, acorn@^8.2.4: - version "8.15.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" - integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== - -acorn@^8.9.0: - version "8.16.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.16.0.tgz#4ce79c89be40afe7afe8f3adb902a1f1ce9ac08a" - integrity sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw== - -add-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" - integrity sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ== - -address@^1.0.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e" - integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA== - -agent-base@6, agent-base@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -agent-base@^7.1.0, agent-base@^7.1.2: - version "7.1.4" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-7.1.4.tgz#e3cd76d4c548ee895d3c3fd8dc1f6c5b9032e7a8" - integrity sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ== - -agentkeepalive@^4.2.1: - version "4.6.0" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.6.0.tgz#35f73e94b3f40bf65f105219c623ad19c136ea6a" - integrity sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ== - dependencies: - humanize-ms "^1.2.1" - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -airbnb-js-shims@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/airbnb-js-shims/-/airbnb-js-shims-2.2.1.tgz#db481102d682b98ed1daa4c5baa697a05ce5c040" - integrity sha512-wJNXPH66U2xjgo1Zwyjf9EydvJ2Si94+vSdk6EERcBfB2VZkeltpqIats0cqIZMLCXP3zcyaUKGYQeIBT6XjsQ== - dependencies: - array-includes "^3.0.3" - array.prototype.flat "^1.2.1" - array.prototype.flatmap "^1.2.1" - es5-shim "^4.5.13" - es6-shim "^0.35.5" - function.prototype.name "^1.1.0" - globalthis "^1.0.0" - object.entries "^1.1.0" - object.fromentries "^2.0.0 || ^1.0.0" - object.getownpropertydescriptors "^2.0.3" - object.values "^1.1.0" - promise.allsettled "^1.0.0" - promise.prototype.finally "^3.1.0" - string.prototype.matchall "^4.0.0 || ^3.0.1" - string.prototype.padend "^3.0.0" - string.prototype.padstart "^3.0.0" - symbol.prototype.description "^1.0.0" - -ajv-errors@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" - integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== - -ajv-formats@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" - integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== - dependencies: - ajv "^8.0.0" - -ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" - integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== - -ajv-keywords@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" - integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== - dependencies: - fast-deep-equal "^3.1.3" - -ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ajv@^6.14.0: - version "6.15.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.15.0.tgz#07e982c74626167aa7a2495c53817892d7139492" - integrity sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw== - 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" - -ajv@^8.0.0, ajv@^8.9.0: - version "8.17.1" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.17.1.tgz#37d9a5c776af6bc92d7f4f9510eba4c0a60d11a6" - integrity sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g== - dependencies: - fast-deep-equal "^3.1.3" - fast-uri "^3.0.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - -animejs@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/animejs/-/animejs-3.2.2.tgz#59be98c58834339d5847f4a70ddba74ac75b6afc" - integrity sha512-Ao95qWLpDPXXM+WrmwcKbl6uNlC5tjnowlaRYtuVDHHoygjtIPfDUoK9NthrlZsQSKjZXlmji2TrBUAVbiH0LQ== - -ansi-align@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" - integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== - dependencies: - string-width "^4.1.0" - -ansi-colors@^3.0.0: - version "3.2.4" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" - integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== - -ansi-colors@^4.1.1: - version "4.1.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" - integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== - -ansi-escapes@^4.2.1, ansi-escapes@^4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-html-community@0.0.8, ansi-html-community@^0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" - integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== - -ansi-html@^0.0.9: - version "0.0.9" - resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.9.tgz#6512d02342ae2cc68131952644a129cb734cd3f0" - integrity sha512-ozbS3LuenHVxNRh/wdnN16QapUHzauqSomAl1jwwJRRsGwFwtj644lIhxfWu0Fy0acCij2+AEgHvjscq3dlVXg== - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-regex@^6.0.1: - version "6.2.2" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.2.2.tgz#60216eea464d864597ce2832000738a0589650c1" - integrity sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^5.0.0, ansi-styles@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" - integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== - -ansi-styles@^6.1.0: - version "6.2.3" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.3.tgz#c044d5dcc521a076413472597a1acb1f103c4041" - integrity sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg== - -ansi-to-html@^0.6.11: - version "0.6.15" - resolved "https://registry.yarnpkg.com/ansi-to-html/-/ansi-to-html-0.6.15.tgz#ac6ad4798a00f6aa045535d7f6a9cb9294eebea7" - integrity sha512-28ijx2aHJGdzbs+O5SNQF65r6rrKYnkuwTYm8lZlChuoJ9P1vVzIpWO20sQTqTPDXYp6NFwk326vApTtLVFXpQ== - dependencies: - entities "^2.0.0" - -anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" - -anymatch@^3.0.0, anymatch@^3.0.3, anymatch@^3.1.3, anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -app-root-dir@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/app-root-dir/-/app-root-dir-1.0.2.tgz#38187ec2dea7577fff033ffcb12172692ff6e118" - integrity sha512-jlpIfsOoNoafl92Sz//64uQHGSyMrD2vYG5d8o2a4qGvyNCvXur7bzIsWtAC/6flI2RYAp3kv8rsfBtaLm7w0g== - -"aproba@^1.0.3 || ^2.0.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.1.0.tgz#75500a190313d95c64e871e7e4284c6ac219f0b1" - integrity sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew== - -aproba@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - -are-we-there-yet@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" - integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== - dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" - -are-we-there-yet@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz#679df222b278c64f2cdba1175cdc00b0d96164bd" - integrity sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg== - dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -aria-query@5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.1.3.tgz#19db27cd101152773631396f7a95a3b58c22c35e" - integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== - dependencies: - deep-equal "^2.0.5" - -aria-query@5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" - integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== - dependencies: - dequal "^2.0.3" - -aria-query@^5.0.0, aria-query@^5.3.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.2.tgz#93f81a43480e33a338f19163a3d10a50c01dcd59" - integrity sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw== - -arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== - -arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== - -array-buffer-byte-length@^1.0.0, array-buffer-byte-length@^1.0.1, array-buffer-byte-length@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.2.tgz#384d12a37295aec3769ab022ad323a18a51ccf8b" - integrity sha512-LHE+8BuR7RYGDKvnrmcuSq3tDcKv9OFEXQt/HpbZhY7V6h0zlUXutnAD82GiFx9rdieCMjkvtcsPqBwgUl1Iiw== - dependencies: - call-bound "^1.0.3" - is-array-buffer "^3.0.5" - -array-differ@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-3.0.0.tgz#3cbb3d0f316810eafcc47624734237d6aee4ae6b" - integrity sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg== - -array-find-index@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" - integrity sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw== - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== - -array-ify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" - integrity sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng== - -array-includes@^3.0.3, array-includes@^3.1.6, array-includes@^3.1.8, array-includes@^3.1.9: - version "3.1.9" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.9.tgz#1f0ccaa08e90cdbc3eb433210f903ad0f17c3f3a" - integrity sha512-FmeCCAenzH0KH381SPT5FZmiA/TmpndpcaShhfgEN9eCVjnFBqq3l1xrI42y8+PPLI6hypzou4GXw00WHmPBLQ== - dependencies: - call-bind "^1.0.8" - call-bound "^1.0.4" - define-properties "^1.2.1" - es-abstract "^1.24.0" - es-object-atoms "^1.1.1" - get-intrinsic "^1.3.0" - is-string "^1.1.1" - math-intrinsics "^1.1.0" - -array-union@^1.0.1, array-union@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" - integrity sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng== - dependencies: - array-uniq "^1.0.1" - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== - -array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== - -array.prototype.findlast@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz#3e4fbcb30a15a7f5bf64cf2faae22d139c2e4904" - integrity sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-abstract "^1.23.2" - es-errors "^1.3.0" - es-object-atoms "^1.0.0" - es-shim-unscopables "^1.0.2" - -array.prototype.findlastindex@^1.2.6: - version "1.2.6" - resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz#cfa1065c81dcb64e34557c9b81d012f6a421c564" - integrity sha512-F/TKATkzseUExPlfvmwQKGITM3DGTK+vkAsCZoDc5daVygbJBnjEUCbgkAvVFsgfXfX4YIqZ/27G3k3tdXrTxQ== - dependencies: - call-bind "^1.0.8" - call-bound "^1.0.4" - define-properties "^1.2.1" - es-abstract "^1.23.9" - es-errors "^1.3.0" - es-object-atoms "^1.1.1" - es-shim-unscopables "^1.1.0" - -array.prototype.flat@^1.2.1, array.prototype.flat@^1.3.1, array.prototype.flat@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.3.tgz#534aaf9e6e8dd79fb6b9a9917f839ef1ec63afe5" - integrity sha512-rwG/ja1neyLqCuGZ5YYrznA62D4mZXg0i1cIskIUKSiqF3Cje9/wXAls9B9s1Wa2fomMsIv8czB8jZcPmxCXFg== - dependencies: - call-bind "^1.0.8" - define-properties "^1.2.1" - es-abstract "^1.23.5" - es-shim-unscopables "^1.0.2" - -array.prototype.flatmap@^1.2.1, array.prototype.flatmap@^1.3.2, array.prototype.flatmap@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.3.tgz#712cc792ae70370ae40586264629e33aab5dd38b" - integrity sha512-Y7Wt51eKJSyi80hFrJCePGGNo5ktJCslFuboqJsbf57CCPcm5zztluPlc4/aD8sWsKvlwatezpV4U1efk8kpjg== - dependencies: - call-bind "^1.0.8" - define-properties "^1.2.1" - es-abstract "^1.23.5" - es-shim-unscopables "^1.0.2" - -array.prototype.map@^1.0.5: - version "1.0.8" - resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.8.tgz#22f4aae44d3081ce3cd1dd6fd37532e7a3433451" - integrity sha512-YocPM7bYYu2hXGxWpb5vwZ8cMeudNHYtYBcUDY4Z1GWa53qcnQMWSl25jeBHNzitjl9HW2AWW4ro/S/nftUaOQ== - dependencies: - call-bind "^1.0.8" - call-bound "^1.0.3" - define-properties "^1.2.1" - es-abstract "^1.23.6" - es-array-method-boxes-properly "^1.0.0" - es-object-atoms "^1.0.0" - is-string "^1.1.1" - -array.prototype.reduce@^1.0.6: - version "1.0.8" - resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.8.tgz#42f97f5078daedca687d4463fd3c05cbfd83da57" - integrity sha512-DwuEqgXFBwbmZSRqt3BpQigWNUoqw9Ml2dTWdF3B2zQlQX4OeUE0zyuzX0fX0IbTvjdkZbcBTU3idgpO78qkTw== - dependencies: - call-bind "^1.0.8" - call-bound "^1.0.4" - define-properties "^1.2.1" - es-abstract "^1.23.9" - es-array-method-boxes-properly "^1.0.0" - es-errors "^1.3.0" - es-object-atoms "^1.1.1" - is-string "^1.1.1" - -array.prototype.tosorted@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz#fe954678ff53034e717ea3352a03f0b0b86f7ffc" - integrity sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-abstract "^1.23.3" - es-errors "^1.3.0" - es-shim-unscopables "^1.0.2" - -arraybuffer.prototype.slice@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.4.tgz#9d760d84dbdd06d0cbf92c8849615a1a7ab3183c" - integrity sha512-BNoCY6SXXPQ7gF2opIP4GBE+Xw7U+pHMYKuzjgCN3GwiaIR09UUeKfheyIry77QtrCBlC0KK0q5/TER/tYh3PQ== - dependencies: - array-buffer-byte-length "^1.0.1" - call-bind "^1.0.8" - define-properties "^1.2.1" - es-abstract "^1.23.5" - es-errors "^1.3.0" - get-intrinsic "^1.2.6" - is-array-buffer "^3.0.4" - -arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== - -arrify@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" - integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== - -asn1.js@^4.10.1: - version "4.10.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" - integrity sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw== - dependencies: - bn.js "^4.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -assert@^1.1.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.1.tgz#038ab248e4ff078e7bc2485ba6e6388466c78f76" - integrity sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A== - dependencies: - object.assign "^4.1.4" - util "^0.10.4" - -assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== - -ast-types-flow@^0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.8.tgz#0a85e1c92695769ac13a428bb653e7538bea27d6" - integrity sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ== - -ast-types@^0.14.2: - version "0.14.2" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.14.2.tgz#600b882df8583e3cd4f2df5fa20fa83759d4bdfd" - integrity sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA== - dependencies: - tslib "^2.0.1" - -async-each@^1.0.1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.6.tgz#52f1d9403818c179b7561e11a5d1b77eb2160e77" - integrity sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg== - -async-function@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/async-function/-/async-function-1.0.0.tgz#509c9fca60eaf85034c6829838188e4e4c8ffb2b" - integrity sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA== - -async@^3.2.6: - version "3.2.6" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.6.tgz#1b0728e14929d51b85b449b7f06e27c1145e38ce" - integrity sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA== - -asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - -at-least-node@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" - integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== - -atob@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - -atomic-sleep@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" - integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== - -author-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/author-regex/-/author-regex-1.0.0.tgz#d08885be6b9bbf9439fe087c76287245f0a81450" - integrity sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g== - -autoprefixer@^9.8.6: - version "9.8.8" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.8.tgz#fd4bd4595385fa6f06599de749a4d5f7a474957a" - integrity sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA== - dependencies: - browserslist "^4.12.0" - caniuse-lite "^1.0.30001109" - normalize-range "^0.1.2" - num2fraction "^1.2.2" - picocolors "^0.2.1" - postcss "^7.0.32" - postcss-value-parser "^4.1.0" - -available-typed-arrays@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846" - integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ== - dependencies: - possible-typed-array-names "^1.0.0" - -axe-core@^4.10.0: - version "4.11.0" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.11.0.tgz#16f74d6482e343ff263d4f4503829e9ee91a86b6" - integrity sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ== - -axios@^1.0.0, axios@^1.6.0: - version "1.12.2" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.12.2.tgz#6c307390136cf7a2278d09cec63b136dfc6e6da7" - integrity sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw== - dependencies: - follow-redirects "^1.15.6" - form-data "^4.0.4" - proxy-from-env "^1.1.0" - -axobject-query@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-4.1.0.tgz#28768c76d0e3cff21bc62a9e2d0b6ac30042a1ee" - integrity sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ== - -babel-jest@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-30.3.0.tgz#3ff5553fa3bcbb8738d2d7335a4dbdc3bd1a0eb5" - integrity sha512-gRpauEU2KRrCox5Z296aeVHR4jQ98BCnu0IO332D/xpHNOsIH/bgSRk9k6GbKIbBw8vFeN6ctuu6tV8WOyVfYQ== - dependencies: - "@jest/transform" "30.3.0" - "@types/babel__core" "^7.20.5" - babel-plugin-istanbul "^7.0.1" - babel-preset-jest "30.3.0" - chalk "^4.1.2" - graceful-fs "^4.2.11" - slash "^3.0.0" - -babel-jest@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" - integrity sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg== - dependencies: - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/babel__core" "^7.1.14" - babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^27.5.1" - chalk "^4.0.0" - graceful-fs "^4.2.9" - slash "^3.0.0" - -babel-loader@^8.0.0, babel-loader@^8.2.3, babel-loader@^8.3.0: - version "8.4.1" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.4.1.tgz#6ccb75c66e62c3b144e1c5f2eaec5b8f6c08c675" - integrity sha512-nXzRChX+Z1GoE6yWavBQg6jDslyFF3SDjl2paADuoQtQW10JqShJt62R6eJQ5m/pjJFDT8xgKIWSP85OY8eXeA== - dependencies: - find-cache-dir "^3.3.1" - loader-utils "^2.0.4" - make-dir "^3.1.0" - schema-utils "^2.6.5" - -babel-loader@^9.1.3: - version "9.2.1" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-9.2.1.tgz#04c7835db16c246dd19ba0914418f3937797587b" - integrity sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA== - dependencies: - find-cache-dir "^4.0.0" - schema-utils "^4.0.0" - -babel-plugin-add-react-displayname@^0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/babel-plugin-add-react-displayname/-/babel-plugin-add-react-displayname-0.0.5.tgz#339d4cddb7b65fd62d1df9db9fe04de134122bd5" - integrity sha512-LY3+Y0XVDYcShHHorshrDbt4KFWL4bSeniCtl4SYZbask+Syngk1uMPCeN9+nSiZo6zX5s0RTq/J9Pnaaf/KHw== - -babel-plugin-apply-mdx-type-prop@1.6.22: - version "1.6.22" - resolved "https://registry.yarnpkg.com/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.22.tgz#d216e8fd0de91de3f1478ef3231e05446bc8705b" - integrity sha512-VefL+8o+F/DfK24lPZMtJctrCVOfgbqLAGZSkxwhazQv4VxPg3Za/i40fu22KR2m8eEda+IfSOlPLUSIiLcnCQ== - dependencies: - "@babel/helper-plugin-utils" "7.10.4" - "@mdx-js/util" "1.6.22" - -babel-plugin-extract-import-names@1.6.22: - version "1.6.22" - resolved "https://registry.yarnpkg.com/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.6.22.tgz#de5f9a28eb12f3eb2578bf74472204e66d1a13dc" - integrity sha512-yJ9BsJaISua7d8zNT7oRG1ZLBJCIdZ4PZqmH8qa9N5AK01ifk3fnkc98AXhtzE7UkfCsEumvoQWgoYLhOnJ7jQ== - dependencies: - "@babel/helper-plugin-utils" "7.10.4" - -babel-plugin-istanbul@^6.0.0, babel-plugin-istanbul@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" - integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@istanbuljs/load-nyc-config" "^1.0.0" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-instrument "^5.0.4" - test-exclude "^6.0.0" - -babel-plugin-istanbul@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-7.0.1.tgz#d8b518c8ea199364cf84ccc82de89740236daf92" - integrity sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@istanbuljs/load-nyc-config" "^1.0.0" - "@istanbuljs/schema" "^0.1.3" - istanbul-lib-instrument "^6.0.2" - test-exclude "^6.0.0" - -babel-plugin-jest-hoist@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.3.0.tgz#235ad714a45c18b12566becf439e1c604e277015" - integrity sha512-+TRkByhsws6sfPjVaitzadk1I0F5sPvOVUH5tyTSzhePpsGIVrdeunHSw/C36QeocS95OOk8lunc4rlu5Anwsg== - dependencies: - "@types/babel__core" "^7.20.5" - -babel-plugin-jest-hoist@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz#9be98ecf28c331eb9f5df9c72d6f89deb8181c2e" - integrity sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ== - dependencies: - "@babel/template" "^7.3.3" - "@babel/types" "^7.3.3" - "@types/babel__core" "^7.0.0" - "@types/babel__traverse" "^7.0.6" - -babel-plugin-macros@^3.0.1, babel-plugin-macros@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" - integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== - dependencies: - "@babel/runtime" "^7.12.5" - cosmiconfig "^7.0.0" - resolve "^1.19.0" - -babel-plugin-named-exports-order@^0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/babel-plugin-named-exports-order/-/babel-plugin-named-exports-order-0.0.2.tgz#ae14909521cf9606094a2048239d69847540cb09" - integrity sha512-OgOYHOLoRK+/mvXU9imKHlG6GkPLYrUCvFXG/CM93R/aNNO8pOOF4aS+S8CCHMDQoNSeiOYEZb/G6RwL95Jktw== - -babel-plugin-polyfill-corejs2@^0.4.14: - version "0.4.14" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz#8101b82b769c568835611542488d463395c2ef8f" - integrity sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg== - dependencies: - "@babel/compat-data" "^7.27.7" - "@babel/helper-define-polyfill-provider" "^0.6.5" - semver "^6.3.1" - -babel-plugin-polyfill-corejs3@^0.1.0: - version "0.1.7" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.7.tgz#80449d9d6f2274912e05d9e182b54816904befd0" - integrity sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.1.5" - core-js-compat "^3.8.1" - -babel-plugin-polyfill-corejs3@^0.13.0: - version "0.13.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.13.0.tgz#bb7f6aeef7addff17f7602a08a6d19a128c30164" - integrity sha512-U+GNwMdSFgzVmfhNm8GJUX88AadB3uo9KpJqS3FaqNIPKgySuvMb+bHPsOmmuWyIcuqZj/pzt1RUIUZns4y2+A== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.6.5" - core-js-compat "^3.43.0" - -babel-plugin-polyfill-regenerator@^0.6.5: - version "0.6.5" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz#32752e38ab6f6767b92650347bf26a31b16ae8c5" - integrity sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.6.5" - -babel-plugin-react-docgen@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/babel-plugin-react-docgen/-/babel-plugin-react-docgen-4.2.1.tgz#7cc8e2f94e8dc057a06e953162f0810e4e72257b" - integrity sha512-UQ0NmGHj/HAqi5Bew8WvNfCk8wSsmdgNd8ZdMjBCICtyCJCq9LiqgqvjCYe570/Wg7AQArSq1VQ60Dd/CHN7mQ== - dependencies: - ast-types "^0.14.2" - lodash "^4.17.15" - react-docgen "^5.0.0" - -babel-plugin-root-import@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/babel-plugin-root-import/-/babel-plugin-root-import-5.1.0.tgz#80ea1cd5945b463a5e3f7e204a69478c573e328c" - integrity sha512-9VYUlnHtM7zjM9vM3kFClUDH7jjhqnvQwxWYGP18EciPsPZYZD9wGqVGwry6gQv0UdZS0+WmbPSlKSjKv1wZFw== - dependencies: - slash "^1.0.0" - -babel-plugin-root-import@^6.6.0: - version "6.6.0" - resolved "https://registry.yarnpkg.com/babel-plugin-root-import/-/babel-plugin-root-import-6.6.0.tgz#85940840f308a8c292f66ca0b5bdd314046273ed" - integrity sha512-SPzVOHd7nDh5loZwZBxtX/oOu1MXeKjTkz+1VnnzLWC0dk8sJIGC2IDQ2uWIBjE5mUtXlQ35MTHSqN0Xn7qHrg== - dependencies: - slash "^3.0.0" - -babel-preset-current-node-syntax@^1.0.0, babel-preset-current-node-syntax@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.2.0.tgz#20730d6cdc7dda5d89401cab10ac6a32067acde6" - integrity sha512-E/VlAEzRrsLEb2+dv8yp3bo4scof3l9nR4lrld+Iy5NyVqgVYUJnDAmunkhPMisRI32Qc4iRiz425d8vM++2fg== - dependencies: - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-bigint" "^7.8.3" - "@babel/plugin-syntax-class-properties" "^7.12.13" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - "@babel/plugin-syntax-import-attributes" "^7.24.7" - "@babel/plugin-syntax-import-meta" "^7.10.4" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - "@babel/plugin-syntax-top-level-await" "^7.14.5" - -babel-preset-jest@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-30.3.0.tgz#21cf3d19a6f5e9924426c879ee0b7f092636d043" - integrity sha512-6ZcUbWHC+dMz2vfzdNwi87Z1gQsLNK2uLuK1Q89R11xdvejcivlYYwDlEv0FHX3VwEXpbBQ9uufB/MUNpZGfhQ== - dependencies: - babel-plugin-jest-hoist "30.3.0" - babel-preset-current-node-syntax "^1.2.0" - -babel-preset-jest@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz#91f10f58034cb7989cb4f962b69fa6eef6a6bc81" - integrity sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag== - dependencies: - babel-plugin-jest-hoist "^27.5.1" - babel-preset-current-node-syntax "^1.0.0" - -bail@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776" - integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ== - -bail@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d" - integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -balanced-match@^4.0.2: - version "4.0.4" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-4.0.4.tgz#bfb10662feed8196a2c62e7c68e17720c274179a" - integrity sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA== - -base-x@^3.0.2, base-x@^3.0.6: - version "3.0.11" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.11.tgz#40d80e2a1aeacba29792ccc6c5354806421287ff" - integrity sha512-xz7wQ8xDhdyP7tQxwdteLYeFfS68tSMNCZ/Y37WJ4bhGfKPpqEIlmIyueQHqOyoPhE6xNUqjzRr8ra0eF9VRvA== - dependencies: - safe-buffer "^5.0.1" - -base64-js@^1.0.2, base64-js@^1.3.0, base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - -base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - -baseline-browser-mapping@^2.9.0: - version "2.9.19" - resolved "https://registry.yarnpkg.com/baseline-browser-mapping/-/baseline-browser-mapping-2.9.19.tgz#3e508c43c46d961eb4d7d2e5b8d1dd0f9ee4f488" - integrity sha512-ipDqC8FrAl/76p2SSWKSI+H9tFwm7vYqXQrItCuiVPt26Km0jS+NzSsBWAaBusvSbQcfJG+JitdMm+wZAgTYqg== - -batch@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" - integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== - -bech32@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" - integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== - -before-after-hook@^2.2.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c" - integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ== - -better-opn@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/better-opn/-/better-opn-2.1.1.tgz#94a55b4695dc79288f31d7d0e5f658320759f7c6" - integrity sha512-kIPXZS5qwyKiX/HcRvDYfmBQUa8XP17I0mYZZ0y4UhpYOSvtsLHDYqmomS+Mj20aDvD3knEiQ0ecQy2nhio3yA== - dependencies: - open "^7.0.3" - -bfs-path@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/bfs-path/-/bfs-path-1.0.2.tgz#9b5fa4b8c4ad226597fc4d2ee15398bdcc644a07" - integrity sha512-KTKx2JJtAAAT7C/rJYDXXWA2VLPycAS4kwFktKsxUo0hj4UTtw/Gm5PJuY7Uf3xSlIQNo7HRCSWei2ivncVwbQ== - -bidi-js@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/bidi-js/-/bidi-js-1.0.3.tgz#6f8bcf3c877c4d9220ddf49b9bb6930c88f877d2" - integrity sha512-RKshQI1R3YQ+n9YJz2QQ147P66ELpa1FQEg20Dk8oW9t2KgLbpDLLp9aGZ7y8WHSshDknG0bknqGw5/tyCs5tw== - dependencies: - require-from-string "^2.0.2" - -big-integer@^1.6.48, big-integer@^1.6.7: - version "1.6.52" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" - integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg== - -big.js@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" - integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== - -big.js@^6.2.1: - version "6.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-6.2.2.tgz#be3bb9ac834558b53b099deef2a1d06ac6368e1a" - integrity sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ== - -bignumber.js@9.1.2: - version "9.1.2" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" - integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== - -bignumber.js@^9.1.2: - version "9.3.1" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.3.1.tgz#759c5aaddf2ffdc4f154f7b493e1c8770f88c4d7" - integrity sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ== - -binary-extensions@^1.0.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" - integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== - -binary-extensions@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.3.0.tgz#f6e14a97858d327252200242d4ccfe522c445522" - integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== - -bindings@^1.3.0, bindings@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" - -bip32@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/bip32/-/bip32-2.0.6.tgz#6a81d9f98c4cd57d05150c60d8f9e75121635134" - integrity sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA== - dependencies: - "@types/node" "10.12.18" - bs58check "^2.1.1" - create-hash "^1.2.0" - create-hmac "^1.1.7" - tiny-secp256k1 "^1.1.3" - typeforce "^1.11.5" - wif "^2.0.6" - -bip39@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.1.0.tgz#c55a418deaf48826a6ceb34ac55b3ee1577e18a3" - integrity sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A== - dependencies: - "@noble/hashes" "^1.2.0" - -bl@^4.0.3, bl@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" - integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - -bluebird@^3.5.5: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - -bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.8, bn.js@^4.11.9: - version "4.12.3" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.3.tgz#2cc2c679188eb35b006f2d0d4710bed8437a769e" - integrity sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g== - -bn.js@^5.2.0, bn.js@^5.2.1, bn.js@^5.2.2: - version "5.2.3" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.3.tgz#16a9e409616b23fef3ccbedb8d42f13bff80295e" - integrity sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w== - -body-parser@1.20.3: - version "1.20.3" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.3.tgz#1953431221c6fb5cd63c4b36d53fab0928e548c6" - integrity sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g== - dependencies: - bytes "3.1.2" - content-type "~1.0.5" - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.13.0" - raw-body "2.5.2" - type-is "~1.6.18" - unpipe "1.0.0" - -bonjour-service@^1.0.11: - version "1.3.0" - resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.3.0.tgz#80d867430b5a0da64e82a8047fc1e355bdb71722" - integrity sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA== - dependencies: - fast-deep-equal "^3.1.3" - multicast-dns "^7.2.5" - -boolbase@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== - -bowser@2.11.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" - integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA== - -boxen@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" - integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== - dependencies: - ansi-align "^3.0.0" - camelcase "^6.2.0" - chalk "^4.1.0" - cli-boxes "^2.2.1" - string-width "^4.2.2" - type-fest "^0.20.2" - widest-line "^3.1.0" - wrap-ansi "^7.0.0" - -bplist-parser@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.1.1.tgz#d60d5dcc20cba6dc7e1f299b35d3e1f95dafbae6" - integrity sha512-2AEM0FXy8ZxVLBuqX0hqt1gDwcnz2zygEkQ6zaD5Wko/sB9paUNwlpawrFtKeHUAQUOzjVy9AO4oeonqIHKA9Q== - dependencies: - big-integer "^1.6.7" - -brace-expansion@^1.1.7: - version "1.1.12" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.12.tgz#ab9b454466e5a8cc3a187beaad580412a9c5b843" - integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.2.tgz#54fc53237a613d854c7bd37463aad17df87214e7" - integrity sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ== - dependencies: - balanced-match "^1.0.0" - -brace-expansion@^5.0.5: - version "5.0.5" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-5.0.5.tgz#dcc3a37116b79f3e1b46db994ced5d570e930fdb" - integrity sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ== - dependencies: - balanced-match "^4.0.2" - -braces@^2.3.1, braces@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - -braces@^3.0.3, braces@~3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" - integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== - dependencies: - fill-range "^7.1.1" - -brorand@^1.0.1, brorand@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== - -browser-assert@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/browser-assert/-/browser-assert-1.2.1.tgz#9aaa5a2a8c74685c2ae05bfe46efd606f068c200" - integrity sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ== - -browser-process-hrtime@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" - integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== - -browserify-aes@^1.0.4, browserify-aes@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - -browserify-cipher@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" - integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== - dependencies: - browserify-aes "^1.0.4" - browserify-des "^1.0.0" - evp_bytestokey "^1.0.0" - -browserify-des@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" - integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== - dependencies: - cipher-base "^1.0.1" - des.js "^1.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -browserify-rsa@^4.0.0, browserify-rsa@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.1.tgz#06e530907fe2949dc21fc3c2e2302e10b1437238" - integrity sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ== - dependencies: - bn.js "^5.2.1" - randombytes "^2.1.0" - safe-buffer "^5.2.1" - -browserify-sign@^4.2.3: - version "4.2.5" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.5.tgz#3979269fa8af55ba18aac35deef11b45515cd27d" - integrity sha512-C2AUdAJg6rlM2W5QMp2Q4KGQMVBwR1lIimTsUnutJ8bMpW5B52pGpR2gEnNBNwijumDo5FojQ0L9JrXA8m4YEw== - dependencies: - bn.js "^5.2.2" - browserify-rsa "^4.1.1" - create-hash "^1.2.0" - create-hmac "^1.1.7" - elliptic "^6.6.1" - inherits "^2.0.4" - parse-asn1 "^5.1.9" - readable-stream "^2.3.8" - safe-buffer "^5.2.1" - -browserify-zlib@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" - integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== - dependencies: - pako "~1.0.5" - -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.21.4, browserslist@^4.23.0, browserslist@^4.24.0, browserslist@^4.26.3, browserslist@^4.28.1: - version "4.28.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.28.1.tgz#7f534594628c53c63101079e27e40de490456a95" - integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== - dependencies: - 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-logger@0.x, bs-logger@^0.2.6: - version "0.2.6" - resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" - integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== - dependencies: - fast-json-stable-stringify "2.x" - -bs58@^4.0.0, bs58@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" - integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== - dependencies: - base-x "^3.0.2" - -bs58check@<3.0.0, bs58check@^2.1.1, bs58check@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" - integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== - dependencies: - bs58 "^4.0.0" - create-hash "^1.1.0" - safe-buffer "^5.1.2" - -bser@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" - integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== - dependencies: - node-int64 "^0.4.0" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== - -buffer@^4.3.0: - version "4.9.2" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" - integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" - -buffer@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - -buffer@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - -builtin-status-codes@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" - integrity sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ== - -builtins@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" - integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ== - -builtins@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-5.1.0.tgz#6d85eeb360c4ebc166c3fdef922a15aa7316a5e8" - integrity sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg== - dependencies: - semver "^7.0.0" - -busboy@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" - integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== - dependencies: - streamsearch "^1.1.0" - -byte-size@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-8.1.1.tgz#3424608c62d59de5bfda05d31e0313c6174842ae" - integrity sha512-tUkzZWK0M/qdoLEqikxBWe4kumyuwjl3HO6zHTr4yEI23EojPtLYXdG1+AQY7MN0cGyNDvEaJ8wiYQm6P2bPxg== - -bytes@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" - integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== - -c8@^7.6.0: - version "7.14.0" - resolved "https://registry.yarnpkg.com/c8/-/c8-7.14.0.tgz#f368184c73b125a80565e9ab2396ff0be4d732f3" - integrity sha512-i04rtkkcNcCf7zsQcSv/T9EbUn4RXQ6mropeMcjFOsQXQ0iGLAr/xT6TImQg4+U9hmNpN9XdvPkjUL1IzbgxJw== - dependencies: - "@bcoe/v8-coverage" "^0.2.3" - "@istanbuljs/schema" "^0.1.3" - find-up "^5.0.0" - foreground-child "^2.0.0" - istanbul-lib-coverage "^3.2.0" - istanbul-lib-report "^3.0.0" - istanbul-reports "^3.1.4" - rimraf "^3.0.2" - test-exclude "^6.0.0" - v8-to-istanbul "^9.0.0" - yargs "^16.2.0" - yargs-parser "^20.2.9" - -cacache@^12.0.2: - version "12.0.4" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" - integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== - dependencies: - bluebird "^3.5.5" - chownr "^1.1.1" - figgy-pudding "^3.5.1" - glob "^7.1.4" - graceful-fs "^4.1.15" - infer-owner "^1.0.3" - lru-cache "^5.1.1" - mississippi "^3.0.0" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - promise-inflight "^1.0.1" - rimraf "^2.6.3" - ssri "^6.0.1" - unique-filename "^1.1.1" - y18n "^4.0.0" - -cacache@^15.0.5: - version "15.3.0" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" - integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== - dependencies: - "@npmcli/fs" "^1.0.0" - "@npmcli/move-file" "^1.0.1" - chownr "^2.0.0" - fs-minipass "^2.0.0" - glob "^7.1.4" - infer-owner "^1.0.4" - lru-cache "^6.0.0" - minipass "^3.1.1" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.2" - mkdirp "^1.0.3" - p-map "^4.0.0" - promise-inflight "^1.0.1" - rimraf "^3.0.2" - ssri "^8.0.1" - tar "^6.0.2" - unique-filename "^1.1.1" - -cacache@^16.1.0: - version "16.1.3" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-16.1.3.tgz#a02b9f34ecfaf9a78c9f4bc16fceb94d5d67a38e" - integrity sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ== - dependencies: - "@npmcli/fs" "^2.1.0" - "@npmcli/move-file" "^2.0.0" - chownr "^2.0.0" - fs-minipass "^2.1.0" - glob "^8.0.1" - infer-owner "^1.0.4" - lru-cache "^7.7.1" - minipass "^3.1.6" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - mkdirp "^1.0.4" - p-map "^4.0.0" - promise-inflight "^1.0.1" - rimraf "^3.0.2" - ssri "^9.0.0" - tar "^6.1.11" - unique-filename "^2.0.0" - -cacache@^17.0.0: - version "17.1.4" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-17.1.4.tgz#b3ff381580b47e85c6e64f801101508e26604b35" - integrity sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A== - dependencies: - "@npmcli/fs" "^3.1.0" - fs-minipass "^3.0.0" - glob "^10.2.2" - lru-cache "^7.7.1" - minipass "^7.0.3" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - p-map "^4.0.0" - ssri "^10.0.0" - tar "^6.1.11" - unique-filename "^3.0.0" - -cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - -call-bind-apply-helpers@^1.0.0, call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz#4b5428c222be985d79c3d82657479dbe0b59b2d6" - integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== - dependencies: - es-errors "^1.3.0" - function-bind "^1.1.2" - -call-bind@^1.0.2, call-bind@^1.0.5, call-bind@^1.0.7, call-bind@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.8.tgz#0736a9660f537e3388826f440d5ec45f744eaa4c" - integrity sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww== - dependencies: - call-bind-apply-helpers "^1.0.0" - es-define-property "^1.0.0" - get-intrinsic "^1.2.4" - set-function-length "^1.2.2" - -call-bound@^1.0.2, call-bound@^1.0.3, call-bound@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/call-bound/-/call-bound-1.0.4.tgz#238de935d2a2a692928c538c7ccfa91067fd062a" - integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== - dependencies: - call-bind-apply-helpers "^1.0.2" - get-intrinsic "^1.3.0" - -call-me-maybe@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.2.tgz#03f964f19522ba643b1b0693acb9152fe2074baa" - integrity sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ== - -callsites@^3.0.0, callsites@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camel-case@^4.1.1, camel-case@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" - integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== - dependencies: - pascal-case "^3.1.2" - tslib "^2.0.3" - -camelcase-css@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" - integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== - -camelcase-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" - integrity sha512-bA/Z/DERHKqoEOrp+qeGKw1QlvEQkGZSc0XaY6VnTxZr+Kv1G5zFwttpjv8qxZ/sBPT4nthwZaAcsAZTJlSKXQ== - dependencies: - camelcase "^2.0.0" - map-obj "^1.0.0" - -camelcase-keys@^6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz#5e755d6ba51aa223ec7d3d52f25778210f9dc3c0" - integrity sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg== - dependencies: - camelcase "^5.3.1" - map-obj "^4.0.0" - quick-lru "^4.0.1" - -camelcase@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" - integrity sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw== - -camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.2.0, camelcase@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -caniuse-api@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" - integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== - dependencies: - browserslist "^4.0.0" - caniuse-lite "^1.0.0" - lodash.memoize "^4.1.2" - lodash.uniq "^4.5.0" - -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001579: - version "1.0.30001751" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001751.tgz#dacd5d9f4baeea841641640139d2b2a4df4226ad" - integrity sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw== - -caniuse-lite@^1.0.30001759: - version "1.0.30001769" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001769.tgz#1ad91594fad7dc233777c2781879ab5409f7d9c2" - integrity sha512-BCfFL1sHijQlBGWBMuJyhZUhzo7wer5sVj9hqekB/7xn0Ypy+pER/edCYQm4exbXj4WiySGp40P8UuTh6w1srg== - -capture-exit@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" - integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g== - dependencies: - rsvp "^4.8.4" - -case-sensitive-paths-webpack-plugin@^2.3.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" - integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== - -ccount@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" - integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== - -ccount@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" - integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== - -chain-registry@^1.69.64: - version "1.69.378" - resolved "https://registry.yarnpkg.com/chain-registry/-/chain-registry-1.69.378.tgz#7184fe44d19d50082abb460e890abb1fbeec8390" - integrity sha512-jDSpxQsp0X+jPISKHAoY+ysxjlzh7jjkYRrvFE5bmdpRxrZyjCdgqdZM15qwvbZKoBwlVmxfZ2KnDSODX4raCQ== - dependencies: - "@chain-registry/types" "^0.50.238" - -chalk@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@^2.4.1: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -char-regex@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" - integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== - -character-entities-html4@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-2.1.0.tgz#1f1adb940c971a4b22ba39ddca6b618dc6e56b2b" - integrity sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA== - -character-entities-legacy@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" - integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== - -character-entities-legacy@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz#76bc83a90738901d7bc223a9e93759fdd560125b" - integrity sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ== - -character-entities@^1.0.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" - integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== - -character-entities@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-2.0.2.tgz#2d09c2e72cd9523076ccb21157dff66ad43fcc22" - integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ== - -character-reference-invalid@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" - integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== - -character-reference-invalid@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz#85c66b041e43b47210faf401278abf808ac45cb9" - integrity sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw== - -chardet@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-2.1.0.tgz#1007f441a1ae9f9199a4a67f6e978fb0aa9aa3fe" - integrity sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA== - -chokidar@^2.1.8: - version "2.1.8" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" - integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== - dependencies: - anymatch "^2.0.0" - async-each "^1.0.1" - braces "^2.3.2" - glob-parent "^3.1.0" - inherits "^2.0.3" - is-binary-path "^1.0.0" - is-glob "^4.0.0" - normalize-path "^3.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.2.1" - upath "^1.1.1" - optionalDependencies: - fsevents "^1.2.7" - -chokidar@^3.4.1, chokidar@^3.4.2, chokidar@^3.5.3: - version "3.6.0" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" - integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chokidar@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.3.tgz#7be37a4c03c9aee1ecfe862a4a23b2c70c205d30" - integrity sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA== - dependencies: - readdirp "^4.0.1" - -chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - -chownr@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" - integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== - -chrome-trace-event@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b" - integrity sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ== - -ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - -ci-info@^3.2.0, ci-info@^3.6.1: - version "3.9.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" - integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== - -ci-info@^4.2.0: - version "4.3.1" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-4.3.1.tgz#355ad571920810b5623e11d40232f443f16f1daa" - integrity sha512-Wdy2Igu8OcBpI2pZePZ5oWjPC38tmDVx5WKUXKwlLYkA0ozo85sLsLvkBbBn/sZaSCMFOGZJ14fvW9t5/d7kdA== - -cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.7" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.7.tgz#bd094bfef42634ccfd9e13b9fc73274997111e39" - integrity sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA== - dependencies: - inherits "^2.0.4" - safe-buffer "^5.2.1" - to-buffer "^1.2.2" - -cjs-module-lexer@^1.0.0: - version "1.4.3" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz#0f79731eb8cfe1ec72acd4066efac9d61991b00d" - integrity sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q== - -cjs-module-lexer@^2.1.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz#b3ca5101843389259ade7d88c77bd06ce55849ca" - integrity sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ== - -class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - -cldr-compact-number@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/cldr-compact-number/-/cldr-compact-number-0.4.0.tgz#d74bb8cedab92ca63032423a1bd26aaaf76b9b2c" - integrity sha512-f/Wz46qoQrfhF2Mq4TcsSbIXMaB70LhioR4fJAbYi5nTnczh1LnSsWuBOXuyKTwFsyrMCRnPFr0OHjl0XB6y9A== - -clean-css@^4.2.3: - version "4.2.4" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.4.tgz#733bf46eba4e607c6891ea57c24a989356831178" - integrity sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A== - dependencies: - source-map "~0.6.0" - -clean-css@^5.2.2: - version "5.3.3" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.3.tgz#b330653cd3bd6b75009cc25c714cae7b93351ccd" - integrity sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg== - dependencies: - source-map "~0.6.0" - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - -clean-webpack-plugin@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/clean-webpack-plugin/-/clean-webpack-plugin-4.0.0.tgz#72947d4403d452f38ed61a9ff0ada8122aacd729" - integrity sha512-WuWE1nyTNAyW5T7oNyys2EN0cfP2fdRxhxnIQWiAp0bMabPdHhoGxM8A6YL2GhqwgrPnnaemVE7nv5XJ2Fhh2w== - dependencies: - del "^4.1.1" - -cli-boxes@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" - integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== - -cli-cursor@3.1.0, cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - -cli-spinners@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" - integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== - -cli-spinners@^2.5.0: - version "2.9.2" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" - integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== - -cli-table3@^0.6.1: - version "0.6.5" - resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.5.tgz#013b91351762739c16a9567c21a04632e449bf2f" - integrity sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ== - dependencies: - string-width "^4.2.0" - optionalDependencies: - "@colors/colors" "1.5.0" - -cli-width@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" - integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== - -client-only@0.0.1, client-only@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" - integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== - -clipboard-copy@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/clipboard-copy/-/clipboard-copy-3.2.0.tgz#3c5b8651d3512dcfad295d77a9eb09e7fac8d5fb" - integrity sha512-vooFaGFL6ulEP1liiaWFBmmfuPm3cY3y7T9eB83ZTnYc/oFeAKsq3NcDrOkBC8XaauEE8zHQwI7k0+JSYiVQSQ== - -cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - -cliui@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" - integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.1" - wrap-ansi "^7.0.0" - -clone-deep@4.0.1, clone-deep@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" - integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== - dependencies: - is-plain-object "^2.0.4" - kind-of "^6.0.2" - shallow-clone "^3.0.0" - -clone@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== - -clsx@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.0.tgz#62937c6adfea771247c34b54d320fb99624f5702" - integrity sha512-3avwM37fSK5oP6M5rQ9CNe99lwxhXDOeSWVPAOYF6OazUTgZCMb0yWlJpmdD74REy1gkEaFiub2ULv4fq9GUhA== - -clsx@^1.0.4, clsx@^1.1.0, clsx@^1.1.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" - integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== - -clsx@^2.0.0, clsx@^2.1.0, clsx@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999" - integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== - -cmd-shim@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-6.0.1.tgz#a65878080548e1dca760b3aea1e21ed05194da9d" - integrity sha512-S9iI9y0nKR4hwEQsVWpyxld/6kRfGepGfzff83FcaiEBpmvlbA2nnGe7Cylgrx2f/p1P5S5wpRm9oL8z1PbS3Q== - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== - -collapse-white-space@^1.0.2: - version "1.0.6" - resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.6.tgz#e63629c0016665792060dbbeb79c42239d2c5287" - integrity sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ== - -collect-v8-coverage@^1.0.0, collect-v8-coverage@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz#cc1f01eb8d02298cbc9a437c74c70ab4e5210b80" - integrity sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw== - -collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - -color-name@^1.0.0, color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -color-string@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4" - integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - -color-support@^1.1.2, color-support@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" - integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== - -color@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a" - integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A== - dependencies: - color-convert "^2.0.1" - color-string "^1.9.0" - -colord@^2.9.1, colord@^2.9.3: - version "2.9.3" - resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43" - integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== - -colorette@^1.2.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40" - integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g== - -colorette@^2.0.10, colorette@^2.0.14: - version "2.0.20" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" - integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== - -colornames@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/colornames/-/colornames-1.1.1.tgz#f8889030685c7c4ff9e2a559f5077eb76a816f96" - integrity sha512-/pyV40IrsdulWv+wFPmERh9k/mjsPZ64yUMDmWrtj/k1nmgrzzIENWKdaVKyBbvFdQWqkcaRxr+polCo3VMe7A== - -columnify@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.6.0.tgz#6989531713c9008bb29735e61e37acf5bd553cf3" - integrity sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q== - dependencies: - strip-ansi "^6.0.1" - wcwidth "^1.0.0" - -combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - -comma-separated-tokens@^1.0.0: - version "1.0.8" - resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" - integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== - -comma-separated-tokens@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz#4e89c9458acb61bc8fef19f4529973b2392839ee" - integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== - -commander@^10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-10.0.1.tgz#881ee46b4f77d1c1dccc5823433aa39b022cbe06" - integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== - -commander@^2.19.0, commander@^2.20.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - -commander@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" - integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== - -commander@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" - integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== - -commander@^7.0.0, commander@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - -commander@^8.3.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" - integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== - -common-path-prefix@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0" - integrity sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== - -compare-func@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-2.0.0.tgz#fb65e75edbddfd2e568554e8b5b05fff7a51fcb3" - integrity sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA== - dependencies: - array-ify "^1.0.0" - dot-prop "^5.1.0" - -component-emitter@^1.2.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.1.tgz#ef1d5796f7d93f135ee6fb684340b26403c97d17" - integrity sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ== - -compressible@~2.0.18: - version "2.0.18" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" - integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== - dependencies: - mime-db ">= 1.43.0 < 2" - -compression@^1.7.4: - version "1.8.1" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.8.1.tgz#4a45d909ac16509195a9a28bd91094889c180d79" - integrity sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w== - dependencies: - 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" - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -concat-stream@^1.5.0: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - -concat-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-2.0.0.tgz#414cf5af790a48c60ab9be4527d56d5e41133cb1" - integrity sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.0.2" - typedarray "^0.0.6" - -confusing-browser-globals@^1.0.10: - version "1.0.11" - resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81" - integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA== - -connect-history-api-fallback@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" - integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== - -console-browserify@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" - integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== - -console-control-strings@^1.0.0, console-control-strings@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== - -constants-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" - integrity sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ== - -content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - -content-type@~1.0.4, content-type@~1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" - integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== - -conventional-changelog-angular@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz#5eec8edbff15aa9b1680a8dcfbd53e2d7eb2ba7a" - integrity sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ== - dependencies: - compare-func "^2.0.0" - -conventional-changelog-core@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-5.0.1.tgz#3c331b155d5b9850f47b4760aeddfc983a92ad49" - integrity sha512-Rvi5pH+LvgsqGwZPZ3Cq/tz4ty7mjijhr3qR4m9IBXNbxGGYgTVVO+duXzz9aArmHxFtwZ+LRkrNIMDQzgoY4A== - dependencies: - add-stream "^1.0.0" - conventional-changelog-writer "^6.0.0" - conventional-commits-parser "^4.0.0" - dateformat "^3.0.3" - get-pkg-repo "^4.2.1" - git-raw-commits "^3.0.0" - git-remote-origin-url "^2.0.0" - git-semver-tags "^5.0.0" - normalize-package-data "^3.0.3" - read-pkg "^3.0.0" - read-pkg-up "^3.0.0" - -conventional-changelog-preset-loader@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-3.0.0.tgz#14975ef759d22515d6eabae6396c2ae721d4c105" - integrity sha512-qy9XbdSLmVnwnvzEisjxdDiLA4OmV3o8db+Zdg4WiFw14fP3B6XNz98X0swPPpkTd/pc1K7+adKgEDM1JCUMiA== - -conventional-changelog-writer@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-6.0.1.tgz#d8d3bb5e1f6230caed969dcc762b1c368a8f7b01" - integrity sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ== - dependencies: - conventional-commits-filter "^3.0.0" - dateformat "^3.0.3" - handlebars "^4.7.7" - json-stringify-safe "^5.0.1" - meow "^8.1.2" - semver "^7.0.0" - split "^1.0.1" - -conventional-commits-filter@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz#bf1113266151dd64c49cd269e3eb7d71d7015ee2" - integrity sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q== - dependencies: - lodash.ismatch "^4.4.0" - modify-values "^1.0.1" - -conventional-commits-parser@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz#02ae1178a381304839bce7cea9da5f1b549ae505" - integrity sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg== - dependencies: - JSONStream "^1.3.5" - is-text-path "^1.0.1" - meow "^8.1.2" - split2 "^3.2.2" - -conventional-recommended-bump@7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-7.0.1.tgz#ec01f6c7f5d0e2491c2d89488b0d757393392424" - integrity sha512-Ft79FF4SlOFvX4PkwFDRnaNiIVX7YbmqGU0RwccUaiGvgp3S0a8ipR2/Qxk31vclDNM+GSdJOVs2KrsUCjblVA== - dependencies: - concat-stream "^2.0.0" - conventional-changelog-preset-loader "^3.0.0" - conventional-commits-filter "^3.0.0" - conventional-commits-parser "^4.0.0" - git-raw-commits "^3.0.0" - git-semver-tags "^5.0.0" - meow "^8.1.2" - -convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" - integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== - -convert-source-map@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" - integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== - -cookie-es@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/cookie-es/-/cookie-es-1.2.2.tgz#18ceef9eb513cac1cb6c14bcbf8bdb2679b34821" - integrity sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg== - -cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== - -cookie@0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.1.tgz#2f73c42142d5d5cf71310a74fc4ae61670e5dbc9" - integrity sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w== - -copy-concurrently@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" - integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== - dependencies: - aproba "^1.1.1" - fs-write-stream-atomic "^1.0.8" - iferr "^0.1.5" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.0" - -copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== - -copy-to-clipboard@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz#55ac43a1db8ae639a4bd99511c148cdd1b83a1b0" - integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA== - dependencies: - toggle-selection "^1.0.6" - -copy-webpack-plugin@^11.0.0: - version "11.0.0" - resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz#96d4dbdb5f73d02dd72d0528d1958721ab72e04a" - integrity sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ== - dependencies: - fast-glob "^3.2.11" - glob-parent "^6.0.1" - globby "^13.1.1" - normalize-path "^3.0.0" - schema-utils "^4.0.0" - serialize-javascript "^6.0.0" - -core-js-compat@^3.43.0, core-js-compat@^3.8.1: - version "3.46.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.46.0.tgz#0c87126a19a1af00371e12b02a2b088a40f3c6f7" - integrity sha512-p9hObIIEENxSV8xIu+V68JjSeARg6UVMG5mR+JEUguG3sI6MsiS1njz2jHmyJDvA+8jX/sytkBHup6kxhM9law== - dependencies: - browserslist "^4.26.3" - -core-js-pure@^3.23.3: - version "3.46.0" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.46.0.tgz#9bb80248584c6334bb54cd381b0f41c619ef1b43" - integrity sha512-NMCW30bHNofuhwLhYPt66OLOKTMbOhgTTatKVbaQC3KRHpTCiRIBYvtshr+NBYSnBxwAFhjW/RfJ0XbIjS16rw== - -core-js@^3.0.4, core-js@^3.6.5, core-js@^3.8.2: - version "3.46.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.46.0.tgz#323a092b96381a9184d0cd49ee9083b2f93373bb" - integrity sha512-vDMm9B0xnqqZ8uSBpZ8sNtRtOdmfShrvT6h2TuQGLs0Is+cR0DYbj/KWP6ALVNbWPpqA/qPLoOuppJN07humpA== - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - -cosmiconfig@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" - integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.1.0" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.7.2" - -cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" - integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.2.1" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.10.0" - -cosmiconfig@^8.2.0: - version "8.3.6" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" - integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== - dependencies: - import-fresh "^3.3.0" - js-yaml "^4.1.0" - parse-json "^5.2.0" - path-type "^4.0.0" - -cosmjs-types@^0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/cosmjs-types/-/cosmjs-types-0.9.0.tgz#c3bc482d28c7dfa25d1445093fdb2d9da1f6cfcc" - integrity sha512-MN/yUe6mkJwHnCFfsNPeCfXVhyxHYW6c/xDUzrSbBycYzw++XvWDMJArXp2pLdgD6FQ8DW79vkPjeNKVrXaHeQ== - -cp-file@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/cp-file/-/cp-file-7.0.0.tgz#b9454cfd07fe3b974ab9ea0e5f29655791a9b8cd" - integrity sha512-0Cbj7gyvFVApzpK/uhCtQ/9kE9UnYpxMzaq5nQQC/Dh4iaj5fxp7iEFIullrYwzj8nf0qnsI1Qsx34hAeAebvw== - dependencies: - graceful-fs "^4.1.2" - make-dir "^3.0.0" - nested-error-stacks "^2.0.0" - p-event "^4.1.0" - -cpy@^8.1.2: - version "8.1.2" - resolved "https://registry.yarnpkg.com/cpy/-/cpy-8.1.2.tgz#e339ea54797ad23f8e3919a5cffd37bfc3f25935" - integrity sha512-dmC4mUesv0OYH2kNFEidtf/skUwv4zePmGeepjyyJ0qTo5+8KhA1o99oIAwVVLzQMAeDJml74d6wPPKb6EZUTg== - dependencies: - arrify "^2.0.1" - cp-file "^7.0.0" - globby "^9.2.0" - has-glob "^1.0.0" - junk "^3.1.0" - nested-error-stacks "^2.1.0" - p-all "^2.1.0" - p-filter "^2.1.0" - p-map "^3.0.0" - -create-ecdh@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" - integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== - dependencies: - bn.js "^4.1.0" - elliptic "^6.5.3" - -create-hash@^1.1.0, create-hash@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - -create-hmac@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - -cross-fetch@^3.1.5: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.2.0.tgz#34e9192f53bc757d6614304d9e5e6fb4edb782e3" - integrity sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q== - dependencies: - node-fetch "^2.7.0" - -cross-spawn@^6.0.0, cross-spawn@^6.0.5: - version "6.0.6" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.6.tgz#30d0efa0712ddb7eb5a76e1e8721bffafa6b5d57" - integrity sha512-VqCUuhcd1iB+dsv8gxPttb5iZh/D0iubSP21g36KXdEuf6I5JiioesUVjpCdHV9MZRUfVFlvwtIUyPfxo5trtw== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3, cross-spawn@^7.0.6: - version "7.0.6" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" - integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -crossws@^0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/crossws/-/crossws-0.3.5.tgz#daad331d44148ea6500098bc858869f3a5ab81a6" - integrity sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA== - dependencies: - uncrypto "^0.1.3" - -crypto-browserify@^3.11.0: - version "3.12.1" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.1.tgz#bb8921bec9acc81633379aa8f52d69b0b69e0dac" - integrity sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ== - dependencies: - browserify-cipher "^1.0.1" - browserify-sign "^4.2.3" - create-ecdh "^4.0.4" - create-hash "^1.2.0" - create-hmac "^1.1.7" - diffie-hellman "^5.0.3" - hash-base "~3.0.4" - inherits "^2.0.4" - pbkdf2 "^3.1.2" - public-encrypt "^4.0.3" - randombytes "^2.1.0" - randomfill "^1.0.4" - -crypto-js@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631" - integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q== - -css-declaration-sorter@^6.3.1: - version "6.4.1" - resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz#28beac7c20bad7f1775be3a7129d7eae409a3a71" - integrity sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g== - -css-declaration-sorter@^7.2.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-7.3.0.tgz#edc45c36bcdfea0788b1d4452829f142ef1c4a4a" - integrity sha512-LQF6N/3vkAMYF4xoHLJfG718HRJh34Z8BnNhd6bosOMIVjMlhuZK5++oZa3uYAgrI5+7x2o27gUqTR2U/KjUOQ== - -css-loader@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645" - integrity sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ== - dependencies: - camelcase "^5.3.1" - cssesc "^3.0.0" - icss-utils "^4.1.1" - loader-utils "^1.2.3" - normalize-path "^3.0.0" - postcss "^7.0.32" - postcss-modules-extract-imports "^2.0.0" - postcss-modules-local-by-default "^3.0.2" - postcss-modules-scope "^2.2.0" - postcss-modules-values "^3.0.0" - postcss-value-parser "^4.1.0" - schema-utils "^2.7.0" - semver "^6.3.0" - -css-loader@^5.0.1: - version "5.2.7" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.7.tgz#9b9f111edf6fb2be5dc62525644cbc9c232064ae" - integrity sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg== - dependencies: - icss-utils "^5.1.0" - loader-utils "^2.0.0" - postcss "^8.2.15" - postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.0" - postcss-modules-scope "^3.0.0" - postcss-modules-values "^4.0.0" - postcss-value-parser "^4.1.0" - schema-utils "^3.0.0" - semver "^7.3.5" - -css-loader@^6.7.3, css-loader@^6.8.1: - version "6.11.0" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.11.0.tgz#33bae3bf6363d0a7c2cf9031c96c744ff54d85ba" - integrity sha512-CTJ+AEQJjq5NzLga5pE39qdiSV56F8ywCIsqNIRF0r7BDgWsN25aazToqAFg7ZrtA/U016xudB3ffgweORxX7g== - dependencies: - icss-utils "^5.1.0" - postcss "^8.4.33" - postcss-modules-extract-imports "^3.1.0" - postcss-modules-local-by-default "^4.0.5" - postcss-modules-scope "^3.2.0" - postcss-modules-values "^4.0.0" - postcss-value-parser "^4.2.0" - semver "^7.5.4" - -css-minimizer-webpack-plugin@^3.0.2: - version "3.4.1" - resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz#ab78f781ced9181992fe7b6e4f3422e76429878f" - integrity sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q== - dependencies: - cssnano "^5.0.6" - jest-worker "^27.0.2" - postcss "^8.3.5" - schema-utils "^4.0.0" - serialize-javascript "^6.0.0" - source-map "^0.6.1" - -css-minimizer-webpack-plugin@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-5.0.1.tgz#33effe662edb1a0bf08ad633c32fa75d0f7ec565" - integrity sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg== - dependencies: - "@jridgewell/trace-mapping" "^0.3.18" - cssnano "^6.0.1" - jest-worker "^29.4.3" - postcss "^8.4.24" - schema-utils "^4.0.1" - serialize-javascript "^6.0.1" - -css-select@^4.1.3: - version "4.3.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" - integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== - dependencies: - boolbase "^1.0.0" - css-what "^6.0.1" - domhandler "^4.3.1" - domutils "^2.8.0" - nth-check "^2.0.1" - -css-select@^5.1.0: - version "5.2.2" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.2.2.tgz#01b6e8d163637bb2dd6c982ca4ed65863682786e" - integrity sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw== - dependencies: - boolbase "^1.0.0" - css-what "^6.1.0" - domhandler "^5.0.2" - domutils "^3.0.1" - nth-check "^2.0.1" - -css-tree@^1.1.2, css-tree@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" - integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== - dependencies: - mdn-data "2.0.14" - source-map "^0.6.1" - -css-tree@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20" - integrity sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw== - dependencies: - mdn-data "2.0.30" - source-map-js "^1.0.1" - -css-tree@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-3.1.0.tgz#7aabc035f4e66b5c86f54570d55e05b1346eb0fd" - integrity sha512-0eW44TGN5SQXU1mWSkKwFstI/22X2bG1nYzZTYMAWjylYURhse752YgbE4Cx46AC+bAvI+/dYTPRk1LqSUnu6w== - dependencies: - mdn-data "2.12.2" - source-map-js "^1.0.1" - -css-tree@~2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.2.1.tgz#36115d382d60afd271e377f9c5f67d02bd48c032" - integrity sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA== - dependencies: - mdn-data "2.0.28" - source-map-js "^1.0.1" - -css-vendor@^2.0.8: - version "2.0.8" - resolved "https://registry.yarnpkg.com/css-vendor/-/css-vendor-2.0.8.tgz#e47f91d3bd3117d49180a3c935e62e3d9f7f449d" - integrity sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ== - dependencies: - "@babel/runtime" "^7.8.3" - is-in-browser "^1.0.2" - -css-what@^6.0.1, css-what@^6.1.0: - version "6.2.2" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.2.2.tgz#cdcc8f9b6977719fdfbd1de7aec24abf756b9dea" - integrity sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA== - -css.escape@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" - integrity sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg== - -cssesc@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" - integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== - -cssnano-preset-default@^5.2.14: - version "5.2.14" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz#309def4f7b7e16d71ab2438052093330d9ab45d8" - integrity sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A== - dependencies: - css-declaration-sorter "^6.3.1" - cssnano-utils "^3.1.0" - postcss-calc "^8.2.3" - postcss-colormin "^5.3.1" - postcss-convert-values "^5.1.3" - postcss-discard-comments "^5.1.2" - postcss-discard-duplicates "^5.1.0" - postcss-discard-empty "^5.1.1" - postcss-discard-overridden "^5.1.0" - postcss-merge-longhand "^5.1.7" - postcss-merge-rules "^5.1.4" - postcss-minify-font-values "^5.1.0" - postcss-minify-gradients "^5.1.1" - postcss-minify-params "^5.1.4" - postcss-minify-selectors "^5.2.1" - postcss-normalize-charset "^5.1.0" - postcss-normalize-display-values "^5.1.0" - postcss-normalize-positions "^5.1.1" - postcss-normalize-repeat-style "^5.1.1" - postcss-normalize-string "^5.1.0" - postcss-normalize-timing-functions "^5.1.0" - postcss-normalize-unicode "^5.1.1" - postcss-normalize-url "^5.1.0" - postcss-normalize-whitespace "^5.1.1" - postcss-ordered-values "^5.1.3" - postcss-reduce-initial "^5.1.2" - postcss-reduce-transforms "^5.1.0" - postcss-svgo "^5.1.0" - postcss-unique-selectors "^5.1.1" - -cssnano-preset-default@^6.1.2: - version "6.1.2" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-6.1.2.tgz#adf4b89b975aa775f2750c89dbaf199bbd9da35e" - integrity sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg== - dependencies: - browserslist "^4.23.0" - css-declaration-sorter "^7.2.0" - cssnano-utils "^4.0.2" - postcss-calc "^9.0.1" - postcss-colormin "^6.1.0" - postcss-convert-values "^6.1.0" - postcss-discard-comments "^6.0.2" - postcss-discard-duplicates "^6.0.3" - postcss-discard-empty "^6.0.3" - postcss-discard-overridden "^6.0.2" - postcss-merge-longhand "^6.0.5" - postcss-merge-rules "^6.1.1" - postcss-minify-font-values "^6.1.0" - postcss-minify-gradients "^6.0.3" - postcss-minify-params "^6.1.0" - postcss-minify-selectors "^6.0.4" - postcss-normalize-charset "^6.0.2" - postcss-normalize-display-values "^6.0.2" - postcss-normalize-positions "^6.0.2" - postcss-normalize-repeat-style "^6.0.2" - postcss-normalize-string "^6.0.2" - postcss-normalize-timing-functions "^6.0.2" - postcss-normalize-unicode "^6.1.0" - postcss-normalize-url "^6.0.2" - postcss-normalize-whitespace "^6.0.2" - postcss-ordered-values "^6.0.2" - postcss-reduce-initial "^6.1.0" - postcss-reduce-transforms "^6.0.2" - postcss-svgo "^6.0.3" - postcss-unique-selectors "^6.0.4" - -cssnano-utils@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-3.1.0.tgz#95684d08c91511edfc70d2636338ca37ef3a6861" - integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA== - -cssnano-utils@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-4.0.2.tgz#56f61c126cd0f11f2eef1596239d730d9fceff3c" - integrity sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ== - -cssnano@^5.0.6: - version "5.1.15" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.15.tgz#ded66b5480d5127fcb44dac12ea5a983755136bf" - integrity sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw== - dependencies: - cssnano-preset-default "^5.2.14" - lilconfig "^2.0.3" - yaml "^1.10.2" - -cssnano@^6.0.1: - version "6.1.2" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-6.1.2.tgz#4bd19e505bd37ee7cf0dc902d3d869f6d79c66b8" - integrity sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA== - dependencies: - cssnano-preset-default "^6.1.2" - lilconfig "^3.1.1" - -csso@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" - integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== - dependencies: - css-tree "^1.1.2" - -csso@^5.0.5: - version "5.0.5" - resolved "https://registry.yarnpkg.com/csso/-/csso-5.0.5.tgz#f9b7fe6cc6ac0b7d90781bb16d5e9874303e2ca6" - integrity sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ== - dependencies: - css-tree "~2.2.0" - -cssom@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" - integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== - -cssom@~0.3.6: - version "0.3.8" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" - integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== - -cssstyle@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" - integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== - dependencies: - cssom "~0.3.6" - -cssstyle@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-5.3.1.tgz#f55a9cc73d12705da8a341261d5e85003fe3a441" - integrity sha512-g5PC9Aiph9eiczFpcgUhd9S4UUO3F+LHGRIi5NUMZ+4xtoIYbHNZwZnWA2JsFGe8OU8nl4WyaEFiZuGuxlutJQ== - dependencies: - "@asamuzakjp/css-color" "^4.0.3" - "@csstools/css-syntax-patches-for-csstree" "^1.0.14" - css-tree "^3.1.0" - -csstype@^3.0.2, csstype@^3.0.7, csstype@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.3.tgz#d80ff294d114fb0e6ac500fbf85b60137d7eff81" - integrity sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw== - -csstype@^3.2.2: - version "3.2.3" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.2.3.tgz#ec48c0f3e993e50648c86da559e2610995cf989a" - integrity sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ== - -currently-unhandled@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" - integrity sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng== - dependencies: - array-find-index "^1.0.1" - -cyclist@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.2.tgz#673b5f233bf34d8e602b949429f8171d9121bea3" - integrity sha512-0sVXIohTfLqVIW3kb/0n6IiWF3Ifj5nm2XaSrLq2DI6fKIGa2fYAZdk917rUneaeLVpYfFcyXE2ft0fe3remsA== - -d3-array@2: - version "2.12.1" - resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81" - integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== - dependencies: - internmap "^1.0.0" - -"d3-array@2 - 3", "d3-array@2.10.0 - 3", d3-array@^3.1.6: - version "3.2.4" - resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.4.tgz#15fec33b237f97ac5d7c986dc77da273a8ed0bb5" - integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== - dependencies: - internmap "1 - 2" - -"d3-color@1 - 3", d3-color@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2" - integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== - -d3-delaunay@^6.0.4: - version "6.0.4" - resolved "https://registry.yarnpkg.com/d3-delaunay/-/d3-delaunay-6.0.4.tgz#98169038733a0a5babbeda55054f795bb9e4a58b" - integrity sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A== - dependencies: - delaunator "5" - -d3-ease@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-3.0.1.tgz#9658ac38a2140d59d346160f1f6c30fda0bd12f4" - integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== - -"d3-format@1 - 3": - version "3.1.0" - resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641" - integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA== - -d3-format@^1.4.4: - version "1.4.5" - resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.4.5.tgz#374f2ba1320e3717eb74a9356c67daee17a7edb4" - integrity sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ== - -"d3-interpolate@1 - 3", "d3-interpolate@1.2.0 - 3", d3-interpolate@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d" - integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== - dependencies: - d3-color "1 - 3" - -d3-path@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-3.1.0.tgz#22df939032fb5a71ae8b1800d61ddb7851c42526" - integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== - -d3-scale-chromatic@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz#34c39da298b23c20e02f1a4b239bd0f22e7f1314" - integrity sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ== - dependencies: - d3-color "1 - 3" - d3-interpolate "1 - 3" - -d3-scale@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-4.0.2.tgz#82b38e8e8ff7080764f8dcec77bd4be393689396" - integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ== - dependencies: - d3-array "2.10.0 - 3" - d3-format "1 - 3" - d3-interpolate "1.2.0 - 3" - d3-time "2.1.1 - 3" - d3-time-format "2 - 4" - -d3-shape@^3.1.0, d3-shape@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-3.2.0.tgz#a1a839cbd9ba45f28674c69d7f855bcf91dfc6a5" - integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA== - dependencies: - d3-path "^3.1.0" - -"d3-time-format@2 - 4": - version "4.1.0" - resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a" - integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg== - dependencies: - d3-time "1 - 3" - -d3-time-format@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-3.0.0.tgz#df8056c83659e01f20ac5da5fdeae7c08d5f1bb6" - integrity sha512-UXJh6EKsHBTjopVqZBhFysQcoXSv/5yLONZvkQ5Kk3qbwiUYkdX17Xa1PT6U1ZWXGGfB1ey5L8dKMlFq2DO0Ag== - dependencies: - d3-time "1 - 2" - -"d3-time@1 - 2": - version "2.1.1" - resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-2.1.1.tgz#e9d8a8a88691f4548e68ca085e5ff956724a6682" - integrity sha512-/eIQe/eR4kCQwq7yxi7z4c6qEXf2IYGcjoWB5OOQy4Tq9Uv39/947qlDcN2TLkiTzQWzvnsuYPB9TrWaNfipKQ== - dependencies: - d3-array "2" - -"d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.1.0.tgz#9310db56e992e3c0175e1ef385e545e48a9bb5c7" - integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q== - dependencies: - d3-array "2 - 3" - -d3-time@^1.0.11: - version "1.1.0" - resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-1.1.0.tgz#b1e19d307dae9c900b7e5b25ffc5dcc249a8a0f1" - integrity sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA== - -d3-timer@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0" - integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== - -damerau-levenshtein@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" - integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== - -dargs@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" - integrity sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg== - -data-urls@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" - integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== - dependencies: - abab "^2.0.3" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.0.0" - -data-urls@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-6.0.0.tgz#95a7943c8ac14c1d563b771f2621cc50e8ec7744" - integrity sha512-BnBS08aLUM+DKamupXs3w2tJJoqU+AkaE/+6vQxi/G/DPmIZFJJp9Dkb1kM03AZx8ADehDUZgsNxju3mPXZYIA== - dependencies: - whatwg-mimetype "^4.0.0" - whatwg-url "^15.0.0" - -data-view-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/data-view-buffer/-/data-view-buffer-1.0.2.tgz#211a03ba95ecaf7798a8c7198d79536211f88570" - integrity sha512-EmKO5V3OLXh1rtK2wgXRansaK1/mtVdTUEiEI0W8RkvgT05kfxaH29PliLnpLP73yYO6142Q72QNa8Wx/A5CqQ== - dependencies: - call-bound "^1.0.3" - es-errors "^1.3.0" - is-data-view "^1.0.2" - -data-view-byte-length@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/data-view-byte-length/-/data-view-byte-length-1.0.2.tgz#9e80f7ca52453ce3e93d25a35318767ea7704735" - integrity sha512-tuhGbE6CfTM9+5ANGf+oQb72Ky/0+s3xKUpHvShfiz2RxMFgFPjsXuRLBVMtvMs15awe45SRb83D6wH4ew6wlQ== - dependencies: - call-bound "^1.0.3" - es-errors "^1.3.0" - is-data-view "^1.0.2" - -data-view-byte-offset@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/data-view-byte-offset/-/data-view-byte-offset-1.0.1.tgz#068307f9b71ab76dbbe10291389e020856606191" - integrity sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ== - dependencies: - call-bound "^1.0.2" - es-errors "^1.3.0" - is-data-view "^1.0.1" - -date-fns@^2.28.0: - version "2.30.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" - integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== - dependencies: - "@babel/runtime" "^7.21.0" - -date-fns@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-4.1.0.tgz#64b3d83fff5aa80438f5b1a633c2e83b8a1c2d14" - integrity sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg== - -dateformat@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" - integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== - -debug@2.6.9, debug@^2.2.0, debug@^2.3.3: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@4, debug@^4.0.0, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@^4.4.0, debug@^4.4.1, debug@^4.4.3: - version "4.4.3" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.3.tgz#c6ae432d9bd9662582fce08709b038c58e9e3d6a" - integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== - dependencies: - ms "^2.1.3" - -debug@^3.0.0, debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -decamelize-keys@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz#04a2d523b2f18d80d0158a43b895d56dff8d19d8" - integrity sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg== - dependencies: - decamelize "^1.1.0" - map-obj "^1.0.0" - -decamelize@^1.1.0, decamelize@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== - -decimal.js-light@^2.4.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934" - integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== - -decimal.js@^10.2.1, decimal.js@^10.4.3, decimal.js@^10.6.0: - version "10.6.0" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.6.0.tgz#e649a43e3ab953a72192ff5983865e509f37ed9a" - integrity sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg== - -decode-named-character-reference@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.2.0.tgz#25c32ae6dd5e21889549d40f676030e9514cc0ed" - integrity sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q== - dependencies: - character-entities "^2.0.0" - -decode-uri-component@^0.2.0: - version "0.2.2" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" - integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== - -dedent@0.7.0, dedent@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== - -dedent@^1.5.3: - version "1.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.7.0.tgz#c1f9445335f0175a96587be245a282ff451446ca" - integrity sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ== - -dedent@^1.6.0: - version "1.7.2" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.7.2.tgz#34e2264ab538301e27cf7b07bf2369c19baa8dd9" - integrity sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA== - -deep-equal@^2.0.5: - version "2.2.3" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.3.tgz#af89dafb23a396c7da3e862abc0be27cf51d56e1" - integrity sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA== - dependencies: - array-buffer-byte-length "^1.0.0" - call-bind "^1.0.5" - es-get-iterator "^1.1.3" - get-intrinsic "^1.2.2" - is-arguments "^1.1.1" - is-array-buffer "^3.0.2" - is-date-object "^1.0.5" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - isarray "^2.0.5" - object-is "^1.1.5" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.5.1" - side-channel "^1.0.4" - which-boxed-primitive "^1.0.2" - which-collection "^1.0.1" - which-typed-array "^1.1.13" - -deep-is@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - -deep-object-diff@^1.1.9: - version "1.1.9" - resolved "https://registry.yarnpkg.com/deep-object-diff/-/deep-object-diff-1.1.9.tgz#6df7ef035ad6a0caa44479c536ed7b02570f4595" - integrity sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA== - -deepmerge@^4.2.2, deepmerge@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" - integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== - -default-browser-id@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-1.0.4.tgz#e59d09a5d157b828b876c26816e61c3d2a2c203a" - integrity sha512-qPy925qewwul9Hifs+3sx1ZYn14obHxpkX+mPD369w4Rzg+YkJBgi3SOvwUq81nWSjqGUegIgEPwD8u+HUnxlw== - dependencies: - bplist-parser "^0.1.0" - meow "^3.1.0" - untildify "^2.0.0" - -default-gateway@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" - integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== - dependencies: - execa "^5.0.0" - -defaults@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" - integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== - dependencies: - clone "^1.0.2" - -define-data-property@^1.0.1, define-data-property@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e" - integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A== - dependencies: - es-define-property "^1.0.0" - es-errors "^1.3.0" - gopd "^1.0.1" - -define-lazy-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" - integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== - -define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" - integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== - dependencies: - define-data-property "^1.0.1" - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== - dependencies: - is-descriptor "^0.1.0" - -define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== - dependencies: - is-descriptor "^1.0.0" - -define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - -defu@^6.1.4: - version "6.1.4" - resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.4.tgz#4e0c9cf9ff68fe5f3d7f2765cc1a012dfdcb0479" - integrity sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg== - -del@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" - integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ== - dependencies: - "@types/glob" "^7.1.1" - globby "^6.1.0" - is-path-cwd "^2.0.0" - is-path-in-cwd "^2.0.0" - p-map "^2.0.0" - pify "^4.0.1" - rimraf "^2.6.3" - -delaunator@5: - version "5.0.1" - resolved "https://registry.yarnpkg.com/delaunator/-/delaunator-5.0.1.tgz#39032b08053923e924d6094fe2cde1a99cc51278" - integrity sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw== - dependencies: - robust-predicates "^3.0.2" - -delay@^4.4.0: - version "4.4.1" - resolved "https://registry.yarnpkg.com/delay/-/delay-4.4.1.tgz#6e02d02946a1b6ab98b39262ced965acba2ac4d1" - integrity sha512-aL3AhqtfhOlT/3ai6sWXeqwnw63ATNpnUiN4HL7x9q+My5QtHlO3OIkasmug9LKzpheLdmUKGRKnYXYAS7FQkQ== - -delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== - -depd@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== - -deprecation@^2.0.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" - integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== - -dequal@^2.0.0, dequal@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" - integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== - -des.js@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.1.0.tgz#1d37f5766f3bbff4ee9638e871a8768c173b81da" - integrity sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg== - dependencies: - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - -destr@^2.0.3, destr@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/destr/-/destr-2.0.5.tgz#7d112ff1b925fb8d2079fac5bdb4a90973b51fdb" - integrity sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA== - -destroy@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" - integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== - -detab@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/detab/-/detab-2.0.4.tgz#b927892069aff405fbb9a186fe97a44a92a94b43" - integrity sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g== - dependencies: - repeat-string "^1.5.4" - -detect-indent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" - integrity sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g== - -detect-libc@^2.0.3: - version "2.1.2" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.1.2.tgz#689c5dcdc1900ef5583a4cb9f6d7b473742074ad" - integrity sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ== - -detect-newline@^3.0.0, detect-newline@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" - integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== - -detect-node@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" - integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== - -detect-package-manager@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/detect-package-manager/-/detect-package-manager-2.0.1.tgz#6b182e3ae5e1826752bfef1de9a7b828cffa50d8" - integrity sha512-j/lJHyoLlWi6G1LDdLgvUtz60Zo5GEj+sVYtTVXnYLDPuzgC3llMxonXym9zIwhhUII8vjdw0LXxavpLqTbl1A== - dependencies: - execa "^5.1.1" - -detect-port@^1.3.0: - version "1.6.1" - resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.6.1.tgz#45e4073997c5f292b957cb678fb0bb8ed4250a67" - integrity sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q== - dependencies: - address "^1.0.1" - debug "4" - -devlop@^1.0.0, devlop@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/devlop/-/devlop-1.1.0.tgz#4db7c2ca4dc6e0e834c30be70c94bbc976dc7018" - integrity sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA== - dependencies: - dequal "^2.0.0" - -diff-sequences@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" - integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== - -diff-sequences@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" - integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== - -diffie-hellman@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" - integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== - dependencies: - bn.js "^4.1.0" - miller-rabin "^4.0.0" - randombytes "^2.0.0" - -dir-glob@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" - integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== - dependencies: - path-type "^3.0.0" - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -dns-packet@^5.2.2: - version "5.6.1" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.6.1.tgz#ae888ad425a9d1478a0674256ab866de1012cf2f" - integrity sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw== - dependencies: - "@leichtgewicht/ip-codec" "^2.0.1" - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -dom-accessibility-api@^0.5.9: - version "0.5.16" - resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453" - integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== - -dom-accessibility-api@^0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.6.3.tgz#993e925cc1d73f2c662e7d75dd5a5445259a8fd8" - integrity sha512-7ZgogeTnjuHbo+ct10G9Ffp0mif17idi0IyWNVA/wcwcm7NPOD/WEHVP3n7n3MhXqxoIYm8d6MuZohYWIZ4T3w== - -dom-converter@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" - integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== - dependencies: - utila "~0.4" - -dom-helpers@^5.0.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902" - integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== - dependencies: - "@babel/runtime" "^7.8.7" - csstype "^3.0.2" - -dom-serializer@^1.0.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" - integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.2.0" - entities "^2.0.0" - -dom-serializer@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" - integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== - dependencies: - domelementtype "^2.3.0" - domhandler "^5.0.2" - entities "^4.2.0" - -dom-walk@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" - integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== - -domain-browser@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" - integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== - -domelementtype@^2.0.1, domelementtype@^2.2.0, domelementtype@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" - integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== - -domexception@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" - integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== - dependencies: - webidl-conversions "^5.0.0" - -domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" - integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== - dependencies: - domelementtype "^2.2.0" - -domhandler@^5.0.2, domhandler@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" - integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== - dependencies: - domelementtype "^2.3.0" - -dompurify@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.3.0.tgz#aaaadbb83d87e1c2fbb066452416359e5b62ec97" - integrity sha512-r+f6MYR1gGN1eJv0TVQbhA7if/U7P87cdPl3HN5rikqaBSBxLiCb/b9O+2eG0cxz0ghyU+mU1QkbsOwERMYlWQ== - optionalDependencies: - "@types/trusted-types" "^2.0.7" - -domutils@^2.5.2, domutils@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" - integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== - dependencies: - dom-serializer "^1.0.1" - domelementtype "^2.2.0" - domhandler "^4.2.0" - -domutils@^3.0.1: - version "3.2.2" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.2.2.tgz#edbfe2b668b0c1d97c24baf0f1062b132221bc78" - integrity sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw== - dependencies: - dom-serializer "^2.0.0" - domelementtype "^2.3.0" - domhandler "^5.0.3" - -dot-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" - integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - -dot-prop@^5.1.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" - integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== - dependencies: - is-obj "^2.0.0" - -dotenv-defaults@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/dotenv-defaults/-/dotenv-defaults-2.0.2.tgz#6b3ec2e4319aafb70940abda72d3856770ee77ac" - integrity sha512-iOIzovWfsUHU91L5i8bJce3NYK5JXeAwH50Jh6+ARUdLiiGlYWfGw6UkzsYqaXZH/hjE/eCd/PlfM/qqyK0AMg== - dependencies: - dotenv "^8.2.0" - -dotenv-expand@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" - integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== - -dotenv-expand@~10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-10.0.0.tgz#12605d00fb0af6d0a592e6558585784032e4ef37" - integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A== - -dotenv-webpack@^7.0.3: - version "7.1.1" - resolved "https://registry.yarnpkg.com/dotenv-webpack/-/dotenv-webpack-7.1.1.tgz#ee8a699e1d736fd8eb9363fbc7054cfff1bd9dbf" - integrity sha512-xw/19VqHDkXALtBOJAnnrSU/AZDIQRXczAmJyp0lZv6SH2aBLzUTl96W1MVryJZ7okZ+djZS4Gj4KlZ0xP7deA== - dependencies: - dotenv-defaults "^2.0.2" - -dotenv-webpack@^8.0.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/dotenv-webpack/-/dotenv-webpack-8.1.1.tgz#4fd82b5ddb374639baad2384f95401bf657f63d4" - integrity sha512-+TY/AJ2k9bU2EML3mxgLmaAvEcqs1Wbv6deCIUSI3eW3Xeo8LBQumYib6puyaSwbjC9JCzg/y5Pwjd/lePX04w== - dependencies: - dotenv-defaults "^2.0.2" - -dotenv@^8.0.0, dotenv@^8.2.0: - version "8.6.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b" - integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g== - -dotenv@~16.3.1: - version "16.3.2" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.2.tgz#3cb611ce5a63002dbabf7c281bc331f69d28f03f" - integrity sha512-HTlk5nmhkm8F6JcdXvHIzaorzCoziNQT9mGxLPVXW8wJF1TiGSL60ZGB4gHWabHOaMmWmhvk2/lPHfnBiT78AQ== - -dunder-proto@^1.0.0, dunder-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/dunder-proto/-/dunder-proto-1.0.1.tgz#d7ae667e1dc83482f8b70fd0f6eefc50da30f58a" - integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== - dependencies: - call-bind-apply-helpers "^1.0.1" - es-errors "^1.3.0" - gopd "^1.2.0" - -duplexer@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" - integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== - -duplexify@^3.4.2, duplexify@^3.6.0: - version "3.7.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" - integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - -duplexify@^4.1.2: - version "4.1.3" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-4.1.3.tgz#a07e1c0d0a2c001158563d32592ba58bddb0236f" - integrity sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA== - dependencies: - end-of-stream "^1.4.1" - inherits "^2.0.3" - readable-stream "^3.1.1" - stream-shift "^1.0.2" - -eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== - -ejs@^3.1.7: - version "3.1.10" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.10.tgz#69ab8358b14e896f80cc39e62087b88500c3ac3b" - integrity sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA== - dependencies: - jake "^10.8.5" - -electron-to-chromium@^1.5.263: - version "1.5.286" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.286.tgz#142be1ab5e1cd5044954db0e5898f60a4960384e" - integrity sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A== - -elliptic@^6.4.0, elliptic@^6.5.3, elliptic@^6.5.4, elliptic@^6.6.1: - version "6.6.1" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.6.1.tgz#3b8ffb02670bf69e382c7f65bf524c97c5405c06" - integrity sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g== - dependencies: - bn.js "^4.11.9" - brorand "^1.1.0" - hash.js "^1.0.0" - hmac-drbg "^1.0.1" - inherits "^2.0.4" - minimalistic-assert "^1.0.1" - minimalistic-crypto-utils "^1.0.1" - -emittery@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" - integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== - -emittery@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" - integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -emojis-list@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" - integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== - -encodeurl@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-2.0.0.tgz#7b8ea898077d7e409d3ac45474ea38eaf0857a58" - integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== - -encoding@^0.1.13: - version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - -end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: - version "1.4.5" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.5.tgz#7344d711dea40e0b74abc2ed49778743ccedb08c" - integrity sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg== - dependencies: - once "^1.4.0" - -endent@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/endent/-/endent-2.1.0.tgz#5aaba698fb569e5e18e69e1ff7a28ff35373cd88" - integrity sha512-r8VyPX7XL8U01Xgnb1CjZ3XV+z90cXIJ9JPE/R9SEC9vpw2P6CfsRPJmp20DppC5N7ZAMCmjYkJIa744Iyg96w== - dependencies: - dedent "^0.7.0" - fast-json-parse "^1.0.3" - objectorarray "^1.0.5" - -enhanced-resolve@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" - integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg== - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.5.0" - tapable "^1.0.0" - -enhanced-resolve@^5.0.0, enhanced-resolve@^5.17.4, enhanced-resolve@^5.7.0: - version "5.19.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz#6687446a15e969eaa63c2fa2694510e17ae6d97c" - integrity sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.3.0" - -enquirer@~2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - -entities@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" - integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== - -entities@^4.2.0, entities@^4.4.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" - integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== - -entities@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/entities/-/entities-6.0.1.tgz#c28c34a43379ca7f61d074130b2f5f7020a30694" - integrity sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g== - -env-paths@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" - integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== - -envinfo@7.8.1: - version "7.8.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" - integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== - -envinfo@^7.7.3: - version "7.19.0" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.19.0.tgz#b4b4507a27e9900b0175f556167fd3a95f8623f1" - integrity sha512-DoSM9VyG6O3vqBf+p3Gjgr/Q52HYBBtO3v+4koAxt1MnWr+zEnxE+nke/yXS4lt2P4SYCHQ4V3f1i88LQVOpAw== - -err-code@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" - integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== - -errno@^0.1.3, errno@~0.1.7: - version "0.1.8" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" - integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== - dependencies: - prr "~1.0.1" - -error-ex@^1.2.0, error-ex@^1.3.1: - version "1.3.4" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.4.tgz#b3a8d8bb6f92eecc1629e3e27d3c8607a8a32414" - integrity sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ== - dependencies: - is-arrayish "^0.2.1" - -error-stack-parser@^2.0.6: - version "2.1.4" - resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz#229cb01cdbfa84440bfa91876285b94680188286" - integrity sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ== - dependencies: - stackframe "^1.3.4" - -es-abstract@^1.17.5, es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.2, es-abstract@^1.23.3, es-abstract@^1.23.5, es-abstract@^1.23.6, es-abstract@^1.23.9, es-abstract@^1.24.0: - version "1.24.0" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.24.0.tgz#c44732d2beb0acc1ed60df840869e3106e7af328" - integrity sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg== - dependencies: - array-buffer-byte-length "^1.0.2" - arraybuffer.prototype.slice "^1.0.4" - available-typed-arrays "^1.0.7" - call-bind "^1.0.8" - call-bound "^1.0.4" - data-view-buffer "^1.0.2" - data-view-byte-length "^1.0.2" - data-view-byte-offset "^1.0.1" - es-define-property "^1.0.1" - es-errors "^1.3.0" - es-object-atoms "^1.1.1" - es-set-tostringtag "^2.1.0" - es-to-primitive "^1.3.0" - function.prototype.name "^1.1.8" - get-intrinsic "^1.3.0" - get-proto "^1.0.1" - get-symbol-description "^1.1.0" - globalthis "^1.0.4" - gopd "^1.2.0" - has-property-descriptors "^1.0.2" - has-proto "^1.2.0" - has-symbols "^1.1.0" - hasown "^2.0.2" - internal-slot "^1.1.0" - is-array-buffer "^3.0.5" - is-callable "^1.2.7" - is-data-view "^1.0.2" - is-negative-zero "^2.0.3" - is-regex "^1.2.1" - is-set "^2.0.3" - is-shared-array-buffer "^1.0.4" - is-string "^1.1.1" - is-typed-array "^1.1.15" - is-weakref "^1.1.1" - math-intrinsics "^1.1.0" - object-inspect "^1.13.4" - object-keys "^1.1.1" - object.assign "^4.1.7" - own-keys "^1.0.1" - regexp.prototype.flags "^1.5.4" - safe-array-concat "^1.1.3" - safe-push-apply "^1.0.0" - safe-regex-test "^1.1.0" - set-proto "^1.0.0" - stop-iteration-iterator "^1.1.0" - string.prototype.trim "^1.2.10" - string.prototype.trimend "^1.0.9" - string.prototype.trimstart "^1.0.8" - typed-array-buffer "^1.0.3" - typed-array-byte-length "^1.0.3" - typed-array-byte-offset "^1.0.4" - typed-array-length "^1.0.7" - unbox-primitive "^1.1.0" - which-typed-array "^1.1.19" - -es-array-method-boxes-properly@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" - integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== - -es-define-property@^1.0.0, es-define-property@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.1.tgz#983eb2f9a6724e9303f61addf011c72e09e0b0fa" - integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== - -es-errors@^1.0.0, es-errors@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" - integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== - -es-get-iterator@^1.0.2, es-get-iterator@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6" - integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - has-symbols "^1.0.3" - is-arguments "^1.1.1" - is-map "^2.0.2" - is-set "^2.0.2" - is-string "^1.0.7" - isarray "^2.0.5" - stop-iteration-iterator "^1.0.0" - -es-iterator-helpers@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.2.1.tgz#d1dd0f58129054c0ad922e6a9a1e65eef435fe75" - integrity sha512-uDn+FE1yrDzyC0pCo961B2IHbdM8y/ACZsKD4dG6WqrjV53BADjwa7D+1aom2rsNVfLyDgU/eigvlJGJ08OQ4w== - dependencies: - call-bind "^1.0.8" - call-bound "^1.0.3" - define-properties "^1.2.1" - es-abstract "^1.23.6" - es-errors "^1.3.0" - es-set-tostringtag "^2.0.3" - function-bind "^1.1.2" - get-intrinsic "^1.2.6" - globalthis "^1.0.4" - gopd "^1.2.0" - has-property-descriptors "^1.0.2" - has-proto "^1.2.0" - has-symbols "^1.1.0" - internal-slot "^1.1.0" - iterator.prototype "^1.1.4" - safe-array-concat "^1.1.3" - -es-module-lexer@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-2.0.0.tgz#f657cd7a9448dcdda9c070a3cb75e5dc1e85f5b1" - integrity sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw== - -es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/es-object-atoms/-/es-object-atoms-1.1.1.tgz#1c4f2c4837327597ce69d2ca190a7fdd172338c1" - integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== - dependencies: - es-errors "^1.3.0" - -es-set-tostringtag@^2.0.3, es-set-tostringtag@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz#f31dbbe0c183b00a6d26eb6325c810c0fd18bd4d" - integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA== - dependencies: - es-errors "^1.3.0" - get-intrinsic "^1.2.6" - has-tostringtag "^1.0.2" - hasown "^2.0.2" - -es-shim-unscopables@^1.0.2, es-shim-unscopables@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.1.0.tgz#438df35520dac5d105f3943d927549ea3b00f4b5" - integrity sha512-d9T8ucsEhh8Bi1woXCf+TIKDIROLG5WCkxg8geBCbvk22kzwC5G2OnXVMO6FUsvQlgUUXQ2itephWDLqDzbeCw== - dependencies: - hasown "^2.0.2" - -es-to-primitive@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.3.0.tgz#96c89c82cc49fd8794a24835ba3e1ff87f214e18" - integrity sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g== - dependencies: - is-callable "^1.2.7" - is-date-object "^1.0.5" - is-symbol "^1.0.4" - -es5-shim@^4.5.13: - version "4.6.7" - resolved "https://registry.yarnpkg.com/es5-shim/-/es5-shim-4.6.7.tgz#bc67ae0fc3dd520636e0a1601cc73b450ad3e955" - integrity sha512-jg21/dmlrNQI7JyyA2w7n+yifSxBng0ZralnSfVZjoCawgNTCnS+yBCyVM9DL5itm7SUnDGgv7hcq2XCZX4iRQ== - -es6-shim@^0.35.5: - version "0.35.8" - resolved "https://registry.yarnpkg.com/es6-shim/-/es6-shim-0.35.8.tgz#89216f6fbf8bacba3f897c8c0e814d2a41c05fb7" - integrity sha512-Twf7I2v4/1tLoIXMT8HlqaBSS5H2wQTs2wx3MNYCI8K1R1/clXyCazrcVCPm/FuO9cyV8+leEaZOWD5C253NDg== - -escalade@^3.1.1, escalade@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" - integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== - -escape-html@^1.0.3, escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -escape-string-regexp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -escodegen@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17" - integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w== - dependencies: - esprima "^4.0.1" - estraverse "^5.2.0" - esutils "^2.0.2" - optionalDependencies: - source-map "~0.6.1" - -eslint-config-airbnb-base@^15.0.0: - version "15.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz#6b09add90ac79c2f8d723a2580e07f3925afd236" - integrity sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig== - dependencies: - confusing-browser-globals "^1.0.10" - object.assign "^4.1.2" - object.entries "^1.1.5" - semver "^6.3.0" - -eslint-config-airbnb-typescript@^16.1.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-16.2.0.tgz#9193fafd62f1cbf444895f4495eae334baf3265b" - integrity sha512-OUaMPZpTOZGKd5tXOjJ9PRU4iYNW/Z5DoHIynjsVK/FpkWdiY5+nxQW6TiJAlLwVI1l53xUOrnlZWtVBVQzuWA== - dependencies: - eslint-config-airbnb-base "^15.0.0" - -eslint-config-airbnb@^19.0.4: - version "19.0.4" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz#84d4c3490ad70a0ffa571138ebcdea6ab085fdc3" - integrity sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew== - dependencies: - eslint-config-airbnb-base "^15.0.0" - object.assign "^4.1.2" - object.entries "^1.1.5" - -eslint-config-next@15.0.3: - version "15.0.3" - resolved "https://registry.yarnpkg.com/eslint-config-next/-/eslint-config-next-15.0.3.tgz#b483585260d5e55050d4ab87e053c88089ae12ee" - integrity sha512-IGP2DdQQrgjcr4mwFPve4DrCqo7CVVez1WoYY47XwKSrYO4hC0Dlb+iJA60i0YfICOzgNADIb8r28BpQ5Zs0wg== - dependencies: - "@next/eslint-plugin-next" "15.0.3" - "@rushstack/eslint-patch" "^1.10.3" - "@typescript-eslint/eslint-plugin" "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0" - "@typescript-eslint/parser" "^5.4.2 || ^6.0.0 || ^7.0.0 || ^8.0.0" - eslint-import-resolver-node "^0.3.6" - eslint-import-resolver-typescript "^3.5.2" - eslint-plugin-import "^2.31.0" - eslint-plugin-jsx-a11y "^6.10.0" - eslint-plugin-react "^7.35.0" - eslint-plugin-react-hooks "^5.0.0" - -eslint-config-prettier@^8.5.0: - version "8.10.2" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.10.2.tgz#0642e53625ebc62c31c24726b0f050df6bd97a2e" - integrity sha512-/IGJ6+Dka158JnP5n5YFMOszjDWrXggGz1LaK/guZq9vZTmniaKlHcsscvkAhn9y4U+BU3JuUdYvtAMcv30y4A== - -eslint-import-resolver-node@^0.3.2, eslint-import-resolver-node@^0.3.6, eslint-import-resolver-node@^0.3.9: - version "0.3.9" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" - integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== - dependencies: - debug "^3.2.7" - is-core-module "^2.13.0" - resolve "^1.22.4" - -eslint-import-resolver-root-import@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-root-import/-/eslint-import-resolver-root-import-1.0.4.tgz#82991138d8014b5e2283b27622ad1ba21f535609" - integrity sha512-c8cUQcELRBe0mnblBZJKEfL+jIUGR8pctK5gdru5N7bBOIve2WZ0R3KoO5GOksXJ4WzZhtcBS2xPaTJYEe4IdQ== - dependencies: - eslint-import-resolver-node "^0.3.2" - json5 "^2.1.0" - -eslint-import-resolver-typescript@^3.5.2: - version "3.10.1" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz#23dac32efa86a88e2b8232eb244ac499ad636db2" - integrity sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ== - dependencies: - "@nolyfill/is-core-module" "1.0.39" - debug "^4.4.0" - get-tsconfig "^4.10.0" - is-bun-module "^2.0.0" - stable-hash "^0.0.5" - tinyglobby "^0.2.13" - unrs-resolver "^1.6.2" - -eslint-module-utils@^2.12.1: - version "2.12.1" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz#f76d3220bfb83c057651359295ab5854eaad75ff" - integrity sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw== - dependencies: - debug "^3.2.7" - -eslint-plugin-import@^2.25.4, eslint-plugin-import@^2.31.0: - version "2.32.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz#602b55faa6e4caeaa5e970c198b5c00a37708980" - integrity sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA== - dependencies: - "@rtsao/scc" "^1.1.0" - array-includes "^3.1.9" - array.prototype.findlastindex "^1.2.6" - array.prototype.flat "^1.3.3" - array.prototype.flatmap "^1.3.3" - debug "^3.2.7" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.9" - eslint-module-utils "^2.12.1" - hasown "^2.0.2" - is-core-module "^2.16.1" - is-glob "^4.0.3" - minimatch "^3.1.2" - object.fromentries "^2.0.8" - object.groupby "^1.0.3" - object.values "^1.2.1" - semver "^6.3.1" - string.prototype.trimend "^1.0.9" - tsconfig-paths "^3.15.0" - -eslint-plugin-jest@^26.1.1: - version "26.9.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-26.9.0.tgz#7931c31000b1c19e57dbfb71bbf71b817d1bf949" - integrity sha512-TWJxWGp1J628gxh2KhaH1H1paEdgE2J61BBF1I59c6xWeL5+D1BzMxGDN/nXAfX+aSkR5u80K+XhskK6Gwq9ng== - dependencies: - "@typescript-eslint/utils" "^5.10.0" - -eslint-plugin-jsx-a11y@^6.10.0, eslint-plugin-jsx-a11y@^6.5.1: - version "6.10.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.10.2.tgz#d2812bb23bf1ab4665f1718ea442e8372e638483" - integrity sha512-scB3nz4WmG75pV8+3eRUQOHZlNSUhFNq37xnpgRkCCELU3XMvXAxLk1eqWWyE22Ki4Q01Fnsw9BA3cJHDPgn2Q== - dependencies: - aria-query "^5.3.2" - array-includes "^3.1.8" - array.prototype.flatmap "^1.3.2" - ast-types-flow "^0.0.8" - axe-core "^4.10.0" - axobject-query "^4.1.0" - damerau-levenshtein "^1.0.8" - emoji-regex "^9.2.2" - hasown "^2.0.2" - jsx-ast-utils "^3.3.5" - language-tags "^1.0.9" - minimatch "^3.1.2" - object.fromentries "^2.0.8" - safe-regex-test "^1.0.3" - string.prototype.includes "^2.0.1" - -eslint-plugin-prettier@^4.0.0: - version "4.2.5" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.5.tgz#91ca3f2f01a84f1272cce04e9717550494c0fe06" - integrity sha512-9Ni+xgemM2IWLq6aXEpP2+V/V30GeA/46Ar629vcMqVPodFFWC9skHu/D1phvuqtS8bJCFnNf01/qcmqYEwNfg== - dependencies: - prettier-linter-helpers "^1.0.0" - -eslint-plugin-react-hooks@^4.3.0: - version "4.6.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz#c829eb06c0e6f484b3fbb85a97e57784f328c596" - integrity sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ== - -eslint-plugin-react-hooks@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-5.2.0.tgz#1be0080901e6ac31ce7971beed3d3ec0a423d9e3" - integrity sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg== - -eslint-plugin-react@^7.29.2, eslint-plugin-react@^7.35.0: - version "7.37.5" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz#2975511472bdda1b272b34d779335c9b0e877065" - integrity sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA== - dependencies: - array-includes "^3.1.8" - array.prototype.findlast "^1.2.5" - array.prototype.flatmap "^1.3.3" - array.prototype.tosorted "^1.1.4" - doctrine "^2.1.0" - es-iterator-helpers "^1.2.1" - estraverse "^5.3.0" - hasown "^2.0.2" - jsx-ast-utils "^2.4.1 || ^3.0.0" - minimatch "^3.1.2" - object.entries "^1.1.9" - object.fromentries "^2.0.8" - object.values "^1.2.1" - prop-types "^15.8.1" - resolve "^2.0.0-next.5" - semver "^6.3.1" - string.prototype.matchall "^4.0.12" - string.prototype.repeat "^1.0.0" - -eslint-plugin-storybook@^0.5.12: - version "0.5.13" - resolved "https://registry.yarnpkg.com/eslint-plugin-storybook/-/eslint-plugin-storybook-0.5.13.tgz#dee4056eaa59c886a9ae78fb7b2ee0ed5fad4366" - integrity sha512-82x3FH1VAi68Awu1VEjn/hLkzFZsOP8ItcC5/uGF9WszIrj6n7Q3MZD57oE26k3aKwuPfFtAPnSjFnaBkBab+g== - dependencies: - "@storybook/csf" "^0.0.1" - "@typescript-eslint/experimental-utils" "^5.3.0" - requireindex "^1.1.0" - -eslint-scope@5.1.1, eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-scope@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" - integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - -eslint-scope@^7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" - integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-scope@^8.4.0: - version "8.4.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.4.0.tgz#88e646a207fad61436ffa39eb505147200655c82" - integrity sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: - version "3.4.3" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" - integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== - -eslint-visitor-keys@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz#4cfea60fe7dd0ad8e816e1ed026c1d5251b512c1" - integrity sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ== - -eslint-visitor-keys@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz#9e3c9489697824d2d4ce3a8ad12628f91e9f59be" - integrity sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA== - -eslint@^8.57.1: - version "8.57.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.1.tgz#7df109654aba7e3bbe5c8eae533c5e461d3c6ca9" - integrity sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.6.1" - "@eslint/eslintrc" "^2.1.4" - "@eslint/js" "8.57.1" - "@humanwhocodes/config-array" "^0.13.0" - "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" - "@ungap/structured-clone" "^1.2.0" - ajv "^6.12.4" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.2.2" - eslint-visitor-keys "^3.4.3" - espree "^9.6.1" - esquery "^1.4.2" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - glob-parent "^6.0.2" - globals "^13.19.0" - graphemer "^1.4.0" - ignore "^5.2.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - is-path-inside "^3.0.3" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.3" - strip-ansi "^6.0.1" - text-table "^0.2.0" - -eslint@^9, eslint@^9.26.0: - version "9.39.4" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.39.4.tgz#855da1b2e2ad66dc5991195f35e262bcec8117b5" - integrity sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ== - dependencies: - "@eslint-community/eslint-utils" "^4.8.0" - "@eslint-community/regexpp" "^4.12.1" - "@eslint/config-array" "^0.21.2" - "@eslint/config-helpers" "^0.4.2" - "@eslint/core" "^0.17.0" - "@eslint/eslintrc" "^3.3.5" - "@eslint/js" "9.39.4" - "@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.14.0" - 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.5" - natural-compare "^1.4.0" - optionator "^0.9.3" - -espree@^10.0.1, espree@^10.4.0: - version "10.4.0" - resolved "https://registry.yarnpkg.com/espree/-/espree-10.4.0.tgz#d54f4949d4629005a1fa168d937c3ff1f7e2a837" - integrity sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ== - dependencies: - acorn "^8.15.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^4.2.1" - -espree@^9.6.0, espree@^9.6.1: - version "9.6.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" - integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== - dependencies: - acorn "^8.9.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" - -esprima@^4.0.0, esprima@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.4.2, esquery@^1.5.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.7.0.tgz#08d048f261f0ddedb5bae95f46809463d9c9496d" - integrity sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.1.0, esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -estree-to-babel@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/estree-to-babel/-/estree-to-babel-3.2.1.tgz#82e78315275c3ca74475fdc8ac1a5103c8a75bf5" - integrity sha512-YNF+mZ/Wu2FU/gvmzuWtYc8rloubL7wfXCTgouFrnjGVXPA/EeYYA7pupXWrb3Iv1cTBeSSxxJIbK23l4MRNqg== - dependencies: - "@babel/traverse" "^7.1.6" - "@babel/types" "^7.2.0" - c8 "^7.6.0" - -estree-util-is-identifier-name@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz#0b5ef4c4ff13508b34dcd01ecfa945f61fce5dbd" - integrity sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== - -eventemitter3@^4.0.0, eventemitter3@^4.0.1, eventemitter3@^4.0.4: - version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" - integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== - -events@3.3.0, events@^3.0.0, events@^3.2.0, events@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - -evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - -exec-sh@^0.3.2: - version "0.3.6" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.6.tgz#ff264f9e325519a60cb5e273692943483cca63bc" - integrity sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w== - -execa@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376" - integrity sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - -execa@^5.0.0, execa@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -exit-x@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/exit-x/-/exit-x-0.2.2.tgz#1f9052de3b8d99a696b10dad5bced9bdd5c3aa64" - integrity sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ== - -exit@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" - integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== - -expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -expect@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-30.3.0.tgz#1b82111517d1ab030f3db0cf1b4061c8aa644f61" - integrity sha512-1zQrciTiQfRdo7qJM1uG4navm8DayFa2TgCSRlzUyNkhcJ6XUZF3hjnpkyr3VhAqPH7i/9GkG7Tv5abz6fqz0Q== - dependencies: - "@jest/expect-utils" "30.3.0" - "@jest/get-type" "30.1.0" - jest-matcher-utils "30.3.0" - jest-message-util "30.3.0" - jest-mock "30.3.0" - jest-util "30.3.0" - -expect@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74" - integrity sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw== - dependencies: - "@jest/types" "^27.5.1" - jest-get-type "^27.5.1" - jest-matcher-utils "^27.5.1" - jest-message-util "^27.5.1" - -expect@^29.0.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" - integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== - dependencies: - "@jest/expect-utils" "^29.7.0" - jest-get-type "^29.6.3" - jest-matcher-utils "^29.7.0" - jest-message-util "^29.7.0" - jest-util "^29.7.0" - -exponential-backoff@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.3.tgz#51cf92c1c0493c766053f9d3abee4434c244d2f6" - integrity sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA== - -express@^4.17.1, express@^4.17.3: - version "4.21.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.21.2.tgz#cf250e48362174ead6cea4a566abef0162c1ec32" - integrity sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA== - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "1.20.3" - content-disposition "0.5.4" - content-type "~1.0.4" - cookie "0.7.1" - cookie-signature "1.0.6" - debug "2.6.9" - depd "2.0.0" - encodeurl "~2.0.0" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "1.3.1" - fresh "0.5.2" - http-errors "2.0.0" - merge-descriptors "1.0.3" - methods "~1.1.2" - on-finished "2.4.1" - parseurl "~1.3.3" - path-to-regexp "0.1.12" - proxy-addr "~2.0.7" - qs "6.13.0" - range-parser "~1.2.1" - safe-buffer "5.2.1" - send "0.19.0" - serve-static "1.16.2" - setprototypeof "1.2.0" - statuses "2.0.1" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - -extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== - dependencies: - is-extendable "^0.1.0" - -extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - -extend@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - -extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-diff@^1.1.2: - version "1.3.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" - integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== - -fast-equals@^5.0.1: - version "5.3.2" - resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-5.3.2.tgz#75a9c7b1c2f627851349a2db94327d79b774ce83" - integrity sha512-6rxyATwPCkaFIL3JLqw8qXqMpIZ942pTX/tbQFkRsDGblS8tNGtlUauA/+mt6RUfqn/4MoEr+WDkYoIQbibWuQ== - -fast-glob@3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" - integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-glob@^2.2.6: - version "2.2.7" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" - integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== - dependencies: - "@mrmlnc/readdir-enhanced" "^2.2.1" - "@nodelib/fs.stat" "^1.1.2" - glob-parent "^3.1.0" - is-glob "^4.0.0" - merge2 "^1.2.3" - micromatch "^3.1.10" - -fast-glob@^3.2.11, fast-glob@^3.2.9, fast-glob@^3.3.0: - version "3.3.3" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.3.tgz#d06d585ce8dba90a16b0505c543c3ccfb3aeb818" - integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.8" - -fast-json-parse@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/fast-json-parse/-/fast-json-parse-1.0.3.tgz#43e5c61ee4efa9265633046b770fb682a7577c4d" - integrity sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw== - -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== - -fast-redact@^3.0.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.5.0.tgz#e9ea02f7e57d0cd8438180083e93077e496285e4" - integrity sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A== - -fast-uri@^3.0.1: - version "3.1.0" - resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.1.0.tgz#66eecff6c764c0df9b762e62ca7edcfb53b4edfa" - integrity sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA== - -fastest-levenshtein@^1.0.12: - version "1.0.16" - resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" - integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== - -fastq@^1.6.0: - version "1.19.1" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.19.1.tgz#d50eaba803c8846a883c16492821ebcd2cda55f5" - integrity sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ== - dependencies: - reusify "^1.0.4" - -favicons-webpack-plugin@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/favicons-webpack-plugin/-/favicons-webpack-plugin-5.0.2.tgz#0837a753ee4485785fa2cec1c3b83472f9ff60ce" - integrity sha512-D/A+Ze0x57+YZBU69hK/lR3NI636qQnKduWyQm0THGl1y3jt16whPHHsi8yjsuXvetv84Eh/I/yYJbAMC2iQxg== - dependencies: - "@types/favicons" "5.5.0" - find-root "^1.1.0" - parse-author "^2.0.0" - parse5 "^6.0.1" - optionalDependencies: - html-webpack-plugin ">=5.0.0" - -favicons@7.2.0, favicons@^7.0.2: - version "7.2.0" - resolved "https://registry.yarnpkg.com/favicons/-/favicons-7.2.0.tgz#1f1662f1f69e5637c19275209003b7b822c24250" - integrity sha512-k/2rVBRIRzOeom3wI9jBPaSEvoTSQEW4iM0EveBmBBKFxO8mSyyRWtDlfC3VnEfu0avmjrMzy8/ZFPSe6F71Hw== - dependencies: - escape-html "^1.0.3" - sharp "^0.33.1" - xml2js "^0.6.1" - -faye-websocket@^0.11.3: - version "0.11.4" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" - integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== - dependencies: - websocket-driver ">=0.5.1" - -fb-watchman@^2.0.0, fb-watchman@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" - integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== - dependencies: - bser "2.1.1" - -fdir@^6.5.0: - version "6.5.0" - resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.5.0.tgz#ed2ab967a331ade62f18d077dae192684d50d350" - integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg== - -fetch-retry@^5.0.2: - version "5.0.6" - resolved "https://registry.yarnpkg.com/fetch-retry/-/fetch-retry-5.0.6.tgz#17d0bc90423405b7a88b74355bf364acd2a7fa56" - integrity sha512-3yurQZ2hD9VISAhJJP9bpYFNQrHHBXE2JxxjY5aLEcDi46RmAzJE2OC9FAde0yis5ElW0jTTzs0zfg/Cca4XqQ== - -figgy-pudding@^3.5.1: - version "3.5.2" - resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" - integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== - -figures@3.2.0, figures@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" - integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== - dependencies: - escape-string-regexp "^1.0.5" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -file-entry-cache@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-8.0.0.tgz#7787bddcf1131bffb92636c69457bbc0edd6d81f" - integrity sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ== - dependencies: - flat-cache "^4.0.0" - -file-loader@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" - integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== - dependencies: - loader-utils "^2.0.0" - schema-utils "^3.0.0" - -file-system-cache@^1.0.5: - version "1.1.0" - resolved "https://registry.yarnpkg.com/file-system-cache/-/file-system-cache-1.1.0.tgz#984de17b976b75a77a27e08d6828137c1aa80fa1" - integrity sha512-IzF5MBq+5CR0jXx5RxPe4BICl/oEhBSXKaL9fLhAXrIfIUS77Hr4vzrYyqYMHN6uTt+BOqi3fDCTjjEBCjERKw== - dependencies: - fs-extra "^10.1.0" - ramda "^0.28.0" - -file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== - -filelist@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" - integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== - dependencies: - minimatch "^5.0.1" - -fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - -fill-range@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" - integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== - dependencies: - to-regex-range "^5.0.1" - -finalhandler@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.3.1.tgz#0c575f1d1d324ddd1da35ad7ece3df7d19088019" - integrity sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ== - dependencies: - debug "2.6.9" - encodeurl "~2.0.0" - escape-html "~1.0.3" - on-finished "2.4.1" - parseurl "~1.3.3" - statuses "2.0.1" - unpipe "~1.0.0" - -find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" - integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== - dependencies: - commondir "^1.0.1" - make-dir "^2.0.0" - pkg-dir "^3.0.0" - -find-cache-dir@^3.3.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" - integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== - dependencies: - commondir "^1.0.1" - make-dir "^3.0.2" - pkg-dir "^4.1.0" - -find-cache-dir@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-4.0.0.tgz#a30ee0448f81a3990708f6453633c733e2f6eec2" - integrity sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg== - dependencies: - common-path-prefix "^3.0.0" - pkg-dir "^7.0.0" - -find-root@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" - integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== - -find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA== - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - -find-up@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== - dependencies: - locate-path "^2.0.0" - -find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -find-up@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-6.3.0.tgz#2abab3d3280b2dc7ac10199ef324c4e002c8c790" - integrity sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw== - dependencies: - locate-path "^7.1.0" - path-exists "^5.0.0" - -flat-cache@^3.0.4: - version "3.2.0" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" - integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== - dependencies: - flatted "^3.2.9" - keyv "^4.5.3" - rimraf "^3.0.2" - -flat-cache@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-4.0.1.tgz#0ece39fcb14ee012f4b0410bd33dd9c1f011127c" - integrity sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw== - dependencies: - flatted "^3.2.9" - keyv "^4.5.4" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -flatted@^3.2.9: - version "3.3.3" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.3.tgz#67c8fad95454a7c7abebf74bb78ee74a44023358" - integrity sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg== - -flush-write-stream@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" - integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== - dependencies: - inherits "^2.0.3" - readable-stream "^2.3.6" - -focus-lock@^0.8.0: - version "0.8.1" - resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-0.8.1.tgz#bb36968abf77a2063fa173cb6c47b12ac8599d33" - integrity sha512-/LFZOIo82WDsyyv7h7oc0MJF9ACOvDRdx9rWPZ2pgMfNWu/z8hQDBtOchuB/0BVLmuFOZjV02YwUVzNsWx/EzA== - dependencies: - tslib "^1.9.3" - -follow-redirects@^1.0.0, follow-redirects@^1.15.6: - version "1.15.11" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.11.tgz#777d73d72a92f8ec4d2e410eb47352a56b8e8340" - integrity sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ== - -for-each@^0.3.3, for-each@^0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.5.tgz#d650688027826920feeb0af747ee7b9421a41d47" - integrity sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg== - dependencies: - is-callable "^1.2.7" - -for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== - -foreground-child@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-2.0.0.tgz#71b32800c9f15aa8f2f83f4a6bd9bff35d861a53" - integrity sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA== - dependencies: - cross-spawn "^7.0.0" - signal-exit "^3.0.2" - -foreground-child@^3.1.0, foreground-child@^3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.1.tgz#32e8e9ed1b68a3497befb9ac2b6adf92a638576f" - integrity sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw== - dependencies: - cross-spawn "^7.0.6" - signal-exit "^4.0.1" - -fork-ts-checker-webpack-plugin@^4.1.6: - version "4.1.6" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-4.1.6.tgz#5055c703febcf37fa06405d400c122b905167fc5" - integrity sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw== - dependencies: - "@babel/code-frame" "^7.5.5" - chalk "^2.4.1" - micromatch "^3.1.10" - minimatch "^3.0.4" - semver "^5.6.0" - tapable "^1.0.0" - worker-rpc "^0.1.0" - -fork-ts-checker-webpack-plugin@^6.0.4: - version "6.5.3" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz#eda2eff6e22476a2688d10661688c47f611b37f3" - integrity sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ== - dependencies: - "@babel/code-frame" "^7.8.3" - "@types/json-schema" "^7.0.5" - chalk "^4.1.0" - chokidar "^3.4.2" - cosmiconfig "^6.0.0" - deepmerge "^4.2.2" - fs-extra "^9.0.0" - glob "^7.1.6" - memfs "^3.1.2" - minimatch "^3.0.4" - schema-utils "2.7.0" - semver "^7.3.2" - tapable "^1.0.0" - -fork-ts-checker-webpack-plugin@^7.2.1: - version "7.3.0" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.3.0.tgz#a9c984a018493962360d7c7e77a67b44a2d5f3aa" - integrity sha512-IN+XTzusCjR5VgntYFgxbxVx3WraPRnKehBFrf00cMSrtUuW9MsG9dhL6MWpY6MkjC3wVwoujfCDgZZCQwbswA== - dependencies: - "@babel/code-frame" "^7.16.7" - chalk "^4.1.2" - chokidar "^3.5.3" - cosmiconfig "^7.0.1" - deepmerge "^4.2.2" - fs-extra "^10.0.0" - memfs "^3.4.1" - minimatch "^3.0.4" - node-abort-controller "^3.0.1" - schema-utils "^3.1.1" - semver "^7.3.5" - tapable "^2.2.1" - -fork-ts-checker-webpack-plugin@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-8.0.0.tgz#dae45dfe7298aa5d553e2580096ced79b6179504" - integrity sha512-mX3qW3idpueT2klaQXBzrIM/pHw+T0B/V9KHEvNrqijTq9NFnMZU6oreVxDYcf33P8a5cW+67PjodNHthGnNVg== - dependencies: - "@babel/code-frame" "^7.16.7" - chalk "^4.1.2" - chokidar "^3.5.3" - cosmiconfig "^7.0.1" - deepmerge "^4.2.2" - fs-extra "^10.0.0" - memfs "^3.4.1" - minimatch "^3.0.4" - node-abort-controller "^3.0.1" - schema-utils "^3.1.1" - semver "^7.3.5" - tapable "^2.2.1" - -form-data@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.4.tgz#938273171d3f999286a4557528ce022dc2c98df1" - integrity sha512-f0cRzm6dkyVYV3nPoooP8XlccPQukegwhAnpoLcXy+X+A8KfpGOoXwDr9FLZd3wzgLaBGQBE3lY93Zm/i1JvIQ== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - es-set-tostringtag "^2.1.0" - hasown "^2.0.2" - mime-types "^2.1.35" - -form-data@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.4.tgz#784cdcce0669a9d68e94d11ac4eea98088edd2c4" - integrity sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow== - 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" - -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - -fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== - dependencies: - map-cache "^0.2.2" - -fresh@0.5.2, fresh@~0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== - -from2@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" - integrity sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g== - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.0" - -fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - -fs-extra@^10.0.0, fs-extra@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" - integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-extra@^11.1.0, fs-extra@^11.1.1: - version "11.3.2" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.3.2.tgz#c838aeddc6f4a8c74dd15f85e11fe5511bfe02a4" - integrity sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-extra@^9.0.0, fs-extra@^9.0.1: - version "9.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - -fs-minipass@^2.0.0, fs-minipass@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" - integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== - dependencies: - minipass "^3.0.0" - -fs-minipass@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-3.0.3.tgz#79a85981c4dc120065e96f62086bf6f9dc26cc54" - integrity sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw== - dependencies: - minipass "^7.0.3" - -fs-monkey@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.1.0.tgz#632aa15a20e71828ed56b24303363fb1414e5997" - integrity sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw== - -fs-write-stream-atomic@^1.0.8: - version "1.0.10" - resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" - integrity sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA== - dependencies: - graceful-fs "^4.1.2" - iferr "^0.1.5" - imurmurhash "^0.1.4" - readable-stream "1 || 2" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -fsevents@^1.2.7: - version "1.2.13" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" - integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== - dependencies: - bindings "^1.5.0" - nan "^2.12.1" - -fsevents@^2.1.2, fsevents@^2.3.2, fsevents@^2.3.3, fsevents@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - -function-bind@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" - integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== - -function.prototype.name@^1.1.0, function.prototype.name@^1.1.6, function.prototype.name@^1.1.8: - version "1.1.8" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.8.tgz#e68e1df7b259a5c949eeef95cdbde53edffabb78" - integrity sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q== - dependencies: - call-bind "^1.0.8" - call-bound "^1.0.3" - define-properties "^1.2.1" - functions-have-names "^1.2.3" - hasown "^2.0.2" - is-callable "^1.2.7" - -functions-have-names@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== - -gauge@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395" - integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q== - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.2" - console-control-strings "^1.0.0" - has-unicode "^2.0.1" - object-assign "^4.1.1" - signal-exit "^3.0.0" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.2" - -gauge@^4.0.3: - version "4.0.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce" - integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.3" - console-control-strings "^1.1.0" - has-unicode "^2.0.1" - signal-exit "^3.0.7" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.5" - -generator-function@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/generator-function/-/generator-function-2.0.1.tgz#0e75dd410d1243687a0ba2e951b94eedb8f737a2" - integrity sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g== - -gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" - integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-intrinsic@^1.1.3, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2, get-intrinsic@^1.2.4, get-intrinsic@^1.2.5, get-intrinsic@^1.2.6, get-intrinsic@^1.2.7, get-intrinsic@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz#743f0e3b6964a93a5491ed1bffaae054d7f98d01" - integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== - dependencies: - call-bind-apply-helpers "^1.0.2" - es-define-property "^1.0.1" - es-errors "^1.3.0" - es-object-atoms "^1.1.1" - function-bind "^1.1.2" - get-proto "^1.0.1" - gopd "^1.2.0" - has-symbols "^1.1.0" - hasown "^2.0.2" - math-intrinsics "^1.1.0" - -get-package-type@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" - integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== - -get-pkg-repo@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz#75973e1c8050c73f48190c52047c4cee3acbf385" - integrity sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA== - dependencies: - "@hutson/parse-repository-url" "^3.0.0" - hosted-git-info "^4.0.0" - through2 "^2.0.0" - yargs "^16.2.0" - -get-port@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" - integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== - -get-proto@^1.0.0, get-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/get-proto/-/get-proto-1.0.1.tgz#150b3f2743869ef3e851ec0c49d15b1d14d00ee1" - integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== - dependencies: - dunder-proto "^1.0.1" - es-object-atoms "^1.0.0" - -get-stdin@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" - integrity sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw== - -get-stream@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.0.tgz#3e0012cb6827319da2706e601a1583e8629a6718" - integrity sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg== - -get-stream@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -get-symbol-description@^1.0.2, get-symbol-description@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.1.0.tgz#7bdd54e0befe8ffc9f3b4e203220d9f1e881b6ee" - integrity sha512-w9UMqWwJxHNOvoNzSJ2oPF5wvYcvP7jUvYzhp67yEhTi17ZDBBC1z9pTdGuzjD+EFIqLSYRweZjqfiPzQ06Ebg== - dependencies: - call-bound "^1.0.3" - es-errors "^1.3.0" - get-intrinsic "^1.2.6" - -get-tsconfig@^4.10.0: - version "4.13.0" - resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.13.0.tgz#fcdd991e6d22ab9a600f00e91c318707a5d9a0d7" - integrity sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ== - dependencies: - resolve-pkg-maps "^1.0.0" - -get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== - -git-raw-commits@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-3.0.0.tgz#5432f053a9744f67e8db03dbc48add81252cfdeb" - integrity sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw== - dependencies: - dargs "^7.0.0" - meow "^8.1.2" - split2 "^3.2.2" - -git-remote-origin-url@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz#5282659dae2107145a11126112ad3216ec5fa65f" - integrity sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw== - dependencies: - gitconfiglocal "^1.0.0" - pify "^2.3.0" - -git-semver-tags@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-5.0.1.tgz#db748aa0e43d313bf38dcd68624d8443234e1c15" - integrity sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA== - dependencies: - meow "^8.1.2" - semver "^7.0.0" - -git-up@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/git-up/-/git-up-7.0.0.tgz#bace30786e36f56ea341b6f69adfd83286337467" - integrity sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ== - dependencies: - is-ssh "^1.4.0" - parse-url "^8.1.0" - -git-url-parse@13.1.0: - version "13.1.0" - resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-13.1.0.tgz#07e136b5baa08d59fabdf0e33170de425adf07b4" - integrity sha512-5FvPJP/70WkIprlUZ33bm4UAaFdjcLkJLpWft1BeZKqwR0uhhNGoKwlUaPtVb4LxCSQ++erHapRak9kWGj+FCA== - dependencies: - git-up "^7.0.0" - -gitconfiglocal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b" - integrity sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ== - dependencies: - ini "^1.3.2" - -github-slugger@^1.0.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.5.0.tgz#17891bbc73232051474d68bd867a34625c955f7d" - integrity sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw== - -glob-parent@5.1.2, glob-parent@^5.1.2, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA== - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - -glob-parent@^6.0.1, glob-parent@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob-promise@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/glob-promise/-/glob-promise-3.4.0.tgz#b6b8f084504216f702dc2ce8c9bc9ac8866fdb20" - integrity sha512-q08RJ6O+eJn+dVanerAndJwIcumgbDdYiUT7zFQl3Wm1xD6fBKtah7H8ZJChj4wP+8C+QfeVy8xautR7rdmKEw== - dependencies: - "@types/glob" "*" - -glob-to-regexp@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" - integrity sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig== - -glob-to-regexp@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" - integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== - -glob@*: - version "11.0.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-11.0.3.tgz#9d8087e6d72ddb3c4707b1d2778f80ea3eaefcd6" - integrity sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA== - dependencies: - foreground-child "^3.3.1" - jackspeak "^4.1.1" - minimatch "^10.0.3" - minipass "^7.1.2" - package-json-from-dist "^1.0.0" - path-scurry "^2.0.0" - -glob@7.1.4: - version "7.1.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" - integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^10.2.2: - version "10.4.5" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956" - integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg== - dependencies: - foreground-child "^3.1.0" - jackspeak "^3.1.2" - minimatch "^9.0.4" - minipass "^7.1.2" - package-json-from-dist "^1.0.0" - path-scurry "^1.11.1" - -glob@^10.5.0: - version "10.5.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.5.0.tgz#8ec0355919cd3338c28428a23d4f24ecc5fe738c" - integrity sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg== - dependencies: - foreground-child "^3.1.0" - jackspeak "^3.1.2" - minimatch "^9.0.4" - minipass "^7.1.2" - package-json-from-dist "^1.0.0" - path-scurry "^1.11.1" - -glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^8.0.1: - version "8.1.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" - integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^5.0.1" - once "^1.3.0" - -glob@^9.2.0: - version "9.3.5" - resolved "https://registry.yarnpkg.com/glob/-/glob-9.3.5.tgz#ca2ed8ca452781a3009685607fdf025a899dfe21" - integrity sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q== - dependencies: - fs.realpath "^1.0.0" - minimatch "^8.0.2" - minipass "^4.2.4" - path-scurry "^1.6.1" - -global@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" - integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== - dependencies: - min-document "^2.19.0" - process "^0.11.10" - -globals@^13.19.0: - version "13.24.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.24.0.tgz#8432a19d78ce0c1e833949c36adb345400bb1171" - integrity sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ== - dependencies: - type-fest "^0.20.2" - -globals@^14.0.0: - version "14.0.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e" - integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== - -globalthis@^1.0.0, globalthis@^1.0.1, globalthis@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236" - integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ== - dependencies: - define-properties "^1.2.1" - gopd "^1.0.1" - -globby@11.1.0, globby@^11.0.2, globby@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - -globby@^13.1.1: - version "13.2.2" - resolved "https://registry.yarnpkg.com/globby/-/globby-13.2.2.tgz#63b90b1bf68619c2135475cbd4e71e66aa090592" - integrity sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w== - dependencies: - dir-glob "^3.0.1" - fast-glob "^3.3.0" - ignore "^5.2.4" - merge2 "^1.4.1" - slash "^4.0.0" - -globby@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" - integrity sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw== - dependencies: - array-union "^1.0.1" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -globby@^9.2.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" - integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg== - dependencies: - "@types/glob" "^7.1.1" - array-union "^1.0.2" - dir-glob "^2.2.2" - fast-glob "^2.2.6" - glob "^7.1.3" - ignore "^4.0.3" - pify "^4.0.1" - slash "^2.0.0" - -gopd@^1.0.1, gopd@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" - integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== - -graceful-fs@4.2.11, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: - version "4.2.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" - integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== - -graphemer@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" - integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== - -h3@^1.15.4: - version "1.15.5" - resolved "https://registry.yarnpkg.com/h3/-/h3-1.15.5.tgz#e2f28d4a66a249973bb050eaddb06b9ab55506f8" - integrity sha512-xEyq3rSl+dhGX2Lm0+eFQIAzlDN6Fs0EcC4f7BNUmzaRX/PTzeuM+Tr2lHB8FoXggsQIeXLj8EDVgs5ywxyxmg== - dependencies: - cookie-es "^1.2.2" - crossws "^0.3.5" - defu "^6.1.4" - destr "^2.0.5" - iron-webcrypto "^1.2.1" - node-mock-http "^1.0.4" - radix3 "^1.1.2" - ufo "^1.6.3" - uncrypto "^0.1.3" - -handle-thing@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" - integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== - -handlebars@^4.7.7: - version "4.7.8" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" - integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== - dependencies: - minimist "^1.2.5" - neo-async "^2.6.2" - source-map "^0.6.1" - wordwrap "^1.0.0" - optionalDependencies: - uglify-js "^3.1.4" - -handlebars@^4.7.9: - version "4.7.9" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.9.tgz#6f139082ab58dc4e5a0e51efe7db5ae890d56a0f" - integrity sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ== - dependencies: - minimist "^1.2.5" - neo-async "^2.6.2" - source-map "^0.6.1" - wordwrap "^1.0.0" - optionalDependencies: - uglify-js "^3.1.4" - -hard-rejection@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" - integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== - -has-bigints@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.1.0.tgz#28607e965ac967e03cd2a2c70a2636a1edad49fe" - integrity sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-glob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-glob/-/has-glob-1.0.0.tgz#9aaa9eedbffb1ba3990a7b0010fb678ee0081207" - integrity sha512-D+8A457fBShSEI3tFCj65PAbT++5sKiFtdCdOam0gnfBgw9D277OERk+HM9qYJXmdVLZ/znez10SqHN0BBQ50g== - dependencies: - is-glob "^3.0.0" - -has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854" - integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg== - dependencies: - es-define-property "^1.0.0" - -has-proto@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.2.0.tgz#5de5a6eabd95fdffd9818b43055e8065e39fe9d5" - integrity sha512-KIL7eQPfHQRC8+XluaIw7BHUwwqL19bQn4hzNgdr+1wXoU0KKj6rufu47lhY7KbJR2C6T6+PfyN0Ea7wkSS+qQ== - dependencies: - dunder-proto "^1.0.0" - -has-symbols@^1.0.3, has-symbols@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.1.0.tgz#fc9c6a783a084951d0b971fe1018de813707a338" - integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== - -has-tostringtag@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc" - integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== - dependencies: - has-symbols "^1.0.3" - -has-unicode@2.0.1, has-unicode@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== - -has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - -has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - -has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== - -has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - -hash-base@^3.0.0, hash-base@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.2.tgz#79d72def7611c3f6e3c3b5730652638001b10a74" - integrity sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg== - dependencies: - inherits "^2.0.4" - readable-stream "^2.3.8" - safe-buffer "^5.2.1" - to-buffer "^1.2.1" - -hash-base@~3.0.4: - version "3.0.5" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.5.tgz#52480e285395cf7fba17dc4c9e47acdc7f248a8a" - integrity sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg== - dependencies: - inherits "^2.0.4" - safe-buffer "^5.2.1" - -hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - -hasown@^2.0.0, hasown@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" - integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== - dependencies: - function-bind "^1.1.2" - -hast-to-hyperscript@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz#9b67fd188e4c81e8ad66f803855334173920218d" - integrity sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA== - dependencies: - "@types/unist" "^2.0.3" - comma-separated-tokens "^1.0.0" - property-information "^5.3.0" - space-separated-tokens "^1.0.0" - style-to-object "^0.3.0" - unist-util-is "^4.0.0" - web-namespaces "^1.0.0" - -hast-util-from-parse5@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz#554e34abdeea25ac76f5bd950a1f0180e0b3bc2a" - integrity sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA== - dependencies: - "@types/parse5" "^5.0.0" - hastscript "^6.0.0" - property-information "^5.0.0" - vfile "^4.0.0" - vfile-location "^3.2.0" - web-namespaces "^1.0.0" - -hast-util-parse-selector@^2.0.0: - version "2.2.5" - resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz#d57c23f4da16ae3c63b3b6ca4616683313499c3a" - integrity sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ== - -hast-util-raw@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-6.0.1.tgz#973b15930b7529a7b66984c98148b46526885977" - integrity sha512-ZMuiYA+UF7BXBtsTBNcLBF5HzXzkyE6MLzJnL605LKE8GJylNjGc4jjxazAHUtcwT5/CEt6afRKViYB4X66dig== - dependencies: - "@types/hast" "^2.0.0" - hast-util-from-parse5 "^6.0.0" - hast-util-to-parse5 "^6.0.0" - html-void-elements "^1.0.0" - parse5 "^6.0.0" - unist-util-position "^3.0.0" - vfile "^4.0.0" - web-namespaces "^1.0.0" - xtend "^4.0.0" - zwitch "^1.0.0" - -hast-util-to-jsx-runtime@^2.0.0: - version "2.3.6" - resolved "https://registry.yarnpkg.com/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz#ff31897aae59f62232e21594eac7ef6b63333e98" - integrity sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg== - dependencies: - "@types/estree" "^1.0.0" - "@types/hast" "^3.0.0" - "@types/unist" "^3.0.0" - comma-separated-tokens "^2.0.0" - devlop "^1.0.0" - estree-util-is-identifier-name "^3.0.0" - hast-util-whitespace "^3.0.0" - mdast-util-mdx-expression "^2.0.0" - mdast-util-mdx-jsx "^3.0.0" - mdast-util-mdxjs-esm "^2.0.0" - property-information "^7.0.0" - space-separated-tokens "^2.0.0" - style-to-js "^1.0.0" - unist-util-position "^5.0.0" - vfile-message "^4.0.0" - -hast-util-to-parse5@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz#1ec44650b631d72952066cea9b1445df699f8479" - integrity sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ== - dependencies: - hast-to-hyperscript "^9.0.0" - property-information "^5.0.0" - web-namespaces "^1.0.0" - xtend "^4.0.0" - zwitch "^1.0.0" - -hast-util-whitespace@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz#7778ed9d3c92dd9e8c5c8f648a49c21fc51cb621" - integrity sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw== - dependencies: - "@types/hast" "^3.0.0" - -hastscript@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640" - integrity sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w== - dependencies: - "@types/hast" "^2.0.0" - comma-separated-tokens "^1.0.0" - hast-util-parse-selector "^2.0.0" - property-information "^5.0.0" - space-separated-tokens "^1.0.0" - -he@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - -hex-rgb@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/hex-rgb/-/hex-rgb-4.3.0.tgz#af5e974e83bb2fefe44d55182b004ec818c07776" - integrity sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw== - -highlight-words@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/highlight-words/-/highlight-words-2.0.0.tgz#06853d68f1f7c8e59d6ef2dd072fe2f64fc93936" - integrity sha512-If5n+IhSBRXTScE7wl16VPmd+44Vy7kof24EdqhjsZsDuHikpv1OCagVcJFpB4fS4UPUniedlWqrjIO8vWOsIQ== - -hmac-drbg@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - -hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" - integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== - dependencies: - react-is "^16.7.0" - -hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - -hosted-git-info@^3.0.6: - version "3.0.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.8.tgz#6e35d4cc87af2c5f816e4cb9ce350ba87a3f370d" - integrity sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw== - dependencies: - lru-cache "^6.0.0" - -hosted-git-info@^4.0.0, hosted-git-info@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" - integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== - dependencies: - lru-cache "^6.0.0" - -hosted-git-info@^6.0.0: - version "6.1.3" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-6.1.3.tgz#2ee1a14a097a1236bddf8672c35b613c46c55946" - integrity sha512-HVJyzUrLIL1c0QmviVh5E8VGyUS7xCFPS6yydaVd1UegW+ibV/CohqTH9MkOLDp5o+rb82DMo77PTuc9F/8GKw== - dependencies: - lru-cache "^7.5.1" - -hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" - integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== - dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - -html-encoding-sniffer@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" - integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== - dependencies: - whatwg-encoding "^1.0.5" - -html-encoding-sniffer@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz#696df529a7cfd82446369dc5193e590a3735b448" - integrity sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ== - dependencies: - whatwg-encoding "^3.1.1" - -html-entities@^2.1.0, html-entities@^2.3.2: - version "2.6.0" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.6.0.tgz#7c64f1ea3b36818ccae3d3fb48b6974208e984f8" - integrity sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ== - -html-escaper@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" - integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== - -html-minifier-terser@^5.0.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#922e96f1f3bb60832c2634b79884096389b1f054" - integrity sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg== - dependencies: - camel-case "^4.1.1" - clean-css "^4.2.3" - commander "^4.1.1" - he "^1.2.0" - param-case "^3.0.3" - relateurl "^0.2.7" - terser "^4.6.3" - -html-minifier-terser@^6.0.2: - version "6.1.0" - resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab" - integrity sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw== - dependencies: - camel-case "^4.1.2" - clean-css "^5.2.2" - commander "^8.3.0" - he "^1.2.0" - param-case "^3.0.4" - relateurl "^0.2.7" - terser "^5.10.0" - -html-parse-stringify@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz#dfc1017347ce9f77c8141a507f233040c59c55d2" - integrity sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg== - dependencies: - void-elements "3.1.0" - -html-tags@^3.1.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce" - integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ== - -html-url-attributes@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/html-url-attributes/-/html-url-attributes-3.0.1.tgz#83b052cd5e437071b756cd74ae70f708870c2d87" - integrity sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ== - -html-void-elements@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483" - integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w== - -html-webpack-plugin@>=5.0.0, html-webpack-plugin@^5.0.0, html-webpack-plugin@^5.3.2, html-webpack-plugin@^5.5.3: - version "5.6.4" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.6.4.tgz#d8cb0f7edff7745ae7d6cccb0bff592e9f7f7959" - integrity sha512-V/PZeWsqhfpE27nKeX9EO2sbR+D17A+tLf6qU+ht66jdUsN0QLKJN27Z+1+gHrVMKgndBahes0PU6rRihDgHTw== - dependencies: - "@types/html-minifier-terser" "^6.0.0" - html-minifier-terser "^6.0.2" - lodash "^4.17.21" - pretty-error "^4.0.0" - tapable "^2.0.0" - -html-webpack-plugin@^4.0.0: - version "4.5.2" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.5.2.tgz#76fc83fa1a0f12dd5f7da0404a54e2699666bc12" - integrity sha512-q5oYdzjKUIPQVjOosjgvCHQOv9Ett9CYYHlgvJeXG0qQvdSojnBq4vAdQBwn1+yGveAwHCoe/rMR86ozX3+c2A== - dependencies: - "@types/html-minifier-terser" "^5.0.0" - "@types/tapable" "^1.0.5" - "@types/webpack" "^4.41.8" - html-minifier-terser "^5.0.1" - loader-utils "^1.2.3" - lodash "^4.17.20" - pretty-error "^2.1.1" - tapable "^1.1.3" - util.promisify "1.0.0" - -htmlparser2@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" - integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.0.0" - domutils "^2.5.2" - entities "^2.0.0" - -http-cache-semantics@^4.1.0, http-cache-semantics@^4.1.1: - version "4.2.0" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz#205f4db64f8562b76a4ff9235aa5279839a09dd5" - integrity sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ== - -http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" - integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== - -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== - dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" - -http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - -http-parser-js@>=0.5.1: - version "0.5.10" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.10.tgz#b3277bd6d7ed5588e20ea73bf724fcbe44609075" - integrity sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA== - -http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - -http-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" - integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== - dependencies: - "@tootallnate/once" "2" - agent-base "6" - debug "4" - -http-proxy-agent@^7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz#9a8b1f246866c028509486585f62b8f2c18c270e" - integrity sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig== - dependencies: - agent-base "^7.1.0" - debug "^4.3.4" - -http-proxy-middleware@^2.0.3: - version "2.0.9" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz#e9e63d68afaa4eee3d147f39149ab84c0c2815ef" - integrity sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q== - dependencies: - "@types/http-proxy" "^1.17.8" - http-proxy "^1.18.1" - is-glob "^4.0.1" - is-plain-obj "^3.0.0" - micromatch "^4.0.2" - -http-proxy@^1.18.1: - version "1.18.1" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" - integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== - dependencies: - eventemitter3 "^4.0.0" - follow-redirects "^1.0.0" - requires-port "^1.0.0" - -https-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" - integrity sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg== - -https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" - -https-proxy-agent@^7.0.6: - version "7.0.6" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz#da8dfeac7da130b05c2ba4b59c9b6cd66611a6b9" - integrity sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw== - dependencies: - agent-base "^7.1.2" - debug "4" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -humanize-ms@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" - integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== - dependencies: - ms "^2.0.0" - -hyphenate-style-name@^1.0.3: - version "1.1.0" - resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.1.0.tgz#1797bf50369588b47b72ca6d5e65374607cf4436" - integrity sha512-WDC/ui2VVRrz3jOVi+XtjqkDjiVjTtFaAGiW37k6b+ohyQ5wYDOGkvCZa8+H0nx3gyvv0+BST9xuOgIyGQ00gw== - -i18next-resources-to-backend@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/i18next-resources-to-backend/-/i18next-resources-to-backend-1.2.1.tgz#fded121e63e3139ce839c9901b9449dbbea7351d" - integrity sha512-okHbVA+HZ7n1/76MsfhPqDou0fptl2dAlhRDu2ideXloRRduzHsqDOznJBef+R3DFZnbvWoBW+KxJ7fnFjd6Yw== - dependencies: - "@babel/runtime" "^7.23.2" - -i18next@^24.2.2: - version "24.2.3" - resolved "https://registry.yarnpkg.com/i18next/-/i18next-24.2.3.tgz#3a05f72615cbd7c00d7e348667e2aabef1df753b" - integrity sha512-lfbf80OzkocvX7nmZtu7nSTNbrTYR52sLWxPtlXX1zAhVw8WEnFk4puUkCR4B1dNQwbSpEHHHemcZu//7EcB7A== - dependencies: - "@babel/runtime" "^7.26.10" - -iconv-lite@0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -iconv-lite@0.6.3, iconv-lite@^0.6.2: - version "0.6.3" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -iconv-lite@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.7.0.tgz#c50cd80e6746ca8115eb98743afa81aa0e147a3e" - integrity sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -icss-utils@^4.0.0, icss-utils@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" - integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== - dependencies: - postcss "^7.0.14" - -icss-utils@^5.0.0, icss-utils@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" - integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== - -idb-keyval@^6.2.1: - version "6.2.2" - resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-6.2.2.tgz#b0171b5f73944854a3291a5cdba8e12768c4854a" - integrity sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg== - -ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - -iferr@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" - integrity sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA== - -ignore-walk@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-5.0.1.tgz#5f199e23e1288f518d90358d461387788a154776" - integrity sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw== - dependencies: - minimatch "^5.0.1" - -ignore-walk@^6.0.0: - version "6.0.5" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-6.0.5.tgz#ef8d61eab7da169078723d1f82833b36e200b0dd" - integrity sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A== - dependencies: - minimatch "^9.0.0" - -ignore@^4.0.3: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - -ignore@^5.0.4, ignore@^5.2.0, ignore@^5.2.4: - version "5.3.2" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" - integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== - -ignore@^7.0.5: - version "7.0.5" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-7.0.5.tgz#4cb5f6cd7d4c7ab0365738c7aea888baa6d7efd9" - integrity sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg== - -immediate@~3.0.5: - version "3.0.6" - resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" - integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== - -immer@^10.1.1: - version "10.1.3" - resolved "https://registry.yarnpkg.com/immer/-/immer-10.1.3.tgz#e38a0b97db59949d31d9b381b04c2e441b1c3747" - integrity sha512-tmjF/k8QDKydUlm3mZU+tjM6zeq9/fFpPqH9SzWmBnVVKsPBg/V66qsMwb3/Bo90cgUN+ghdVBess+hPsxUyRw== - -import-fresh@^3.1.0, import-fresh@^3.2.1, import-fresh@^3.3.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.1.tgz#9cecb56503c0ada1f2741dbbd6546e4b13b57ccf" - integrity sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-local@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" - integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - -import-local@^3.0.2, import-local@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.2.0.tgz#c3d5c745798c02a6f8b897726aba5100186ee260" - integrity sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -indent-string@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" - integrity sha512-aqwDFWSgSgfRaEwao5lg5KEcVd/2a+D1rvoG7NdilmYz0NwRk6StWpWdz/Hpk34MKPpx7s8XxUqimfcQK6gGlg== - dependencies: - repeating "^2.0.0" - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - -infer-owner@^1.0.3, infer-owner@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" - integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== - -ini@^1.3.2, ini@^1.3.8: - version "1.3.8" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - -init-package-json@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-5.0.0.tgz#030cf0ea9c84cfc1b0dc2e898b45d171393e4b40" - integrity sha512-kBhlSheBfYmq3e0L1ii+VKe3zBTLL5lDCDWR+f9dLmEGSB3MqLlMlsolubSsyI88Bg6EA+BIMlomAnQ1SwgQBw== - dependencies: - npm-package-arg "^10.0.0" - promzard "^1.0.0" - read "^2.0.0" - read-package-json "^6.0.0" - semver "^7.3.5" - validate-npm-package-license "^3.0.4" - validate-npm-package-name "^5.0.0" - -inline-style-parser@0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" - integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== - -inline-style-parser@0.2.4: - version "0.2.4" - resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.2.4.tgz#f4af5fe72e612839fcd453d989a586566d695f22" - integrity sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q== - -inquirer@^8.2.4: - version "8.2.7" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.7.tgz#62f6b931a9b7f8735dc42db927316d8fb6f71de8" - integrity sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA== - dependencies: - "@inquirer/external-editor" "^1.0.0" - ansi-escapes "^4.2.1" - chalk "^4.1.1" - cli-cursor "^3.1.0" - cli-width "^3.0.0" - figures "^3.0.0" - lodash "^4.17.21" - mute-stream "0.0.8" - ora "^5.4.1" - run-async "^2.4.0" - rxjs "^7.5.5" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" - wrap-ansi "^6.0.1" - -internal-slot@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.1.0.tgz#1eac91762947d2f7056bc838d93e13b2e9604961" - integrity sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw== - dependencies: - es-errors "^1.3.0" - hasown "^2.0.2" - side-channel "^1.1.0" - -"internmap@1 - 2": - version "2.0.3" - resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009" - integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== - -internmap@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95" - integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== - -interpret@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" - integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== - -interpret@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4" - integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ== - -intl-messageformat@^10.1.0: - version "10.7.18" - resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.7.18.tgz#51a6f387afbca9b0f881b2ec081566db8c540b0d" - integrity sha512-m3Ofv/X/tV8Y3tHXLohcuVuhWKo7BBq62cqY15etqmLxg2DZ34AGGgQDeR+SCta2+zICb1NX83af0GJmbQ1++g== - dependencies: - "@formatjs/ecma402-abstract" "2.3.6" - "@formatjs/fast-memoize" "2.2.7" - "@formatjs/icu-messageformat-parser" "2.11.4" - tslib "^2.8.0" - -ip-address@^10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/ip-address/-/ip-address-10.0.1.tgz#a8180b783ce7788777d796286d61bce4276818ed" - integrity sha512-NWv9YLW4PoW2B7xtzaS3NCot75m6nK7Icdv0o3lfMceJVRfSoQwqD4wEH5rLwoKJwUiZ/rfpiVBhnaF0FK4HoA== - -ip@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105" - integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ== - -ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - -ipaddr.js@^2.0.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.2.0.tgz#d33fa7bac284f4de7af949638c9d68157c6b92e8" - integrity sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA== - -iron-webcrypto@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/iron-webcrypto/-/iron-webcrypto-1.2.1.tgz#aa60ff2aa10550630f4c0b11fd2442becdb35a6f" - integrity sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg== - -is-absolute-url@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" - integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== - -is-accessor-descriptor@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz#3223b10628354644b86260db29b3e693f5ceedd4" - integrity sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA== - dependencies: - hasown "^2.0.0" - -is-alphabetical@1.0.4, is-alphabetical@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" - integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== - -is-alphabetical@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-2.0.1.tgz#01072053ea7c1036df3c7d19a6daaec7f19e789b" - integrity sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ== - -is-alphanumerical@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf" - integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A== - dependencies: - is-alphabetical "^1.0.0" - is-decimal "^1.0.0" - -is-alphanumerical@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz#7c03fbe96e3e931113e57f964b0a368cc2dfd875" - integrity sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw== - dependencies: - is-alphabetical "^2.0.0" - is-decimal "^2.0.0" - -is-arguments@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.2.0.tgz#ad58c6aecf563b78ef2bf04df540da8f5d7d8e1b" - integrity sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA== - dependencies: - call-bound "^1.0.2" - has-tostringtag "^1.0.2" - -is-array-buffer@^3.0.2, is-array-buffer@^3.0.4, is-array-buffer@^3.0.5: - version "3.0.5" - resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.5.tgz#65742e1e687bd2cc666253068fd8707fe4d44280" - integrity sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A== - dependencies: - call-bind "^1.0.8" - call-bound "^1.0.3" - get-intrinsic "^1.2.6" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== - -is-arrayish@^0.3.1: - version "0.3.4" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.4.tgz#1ee5553818511915685d33bb13d31bf854e5059d" - integrity sha512-m6UrgzFVUYawGBh1dUsWR5M2Clqic9RVXC/9f8ceNlv2IcO9j9J/z8UoCLPqtsPBFNzEpfR3xftohbfqDx8EQA== - -is-async-function@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-async-function/-/is-async-function-2.1.1.tgz#3e69018c8e04e73b738793d020bfe884b9fd3523" - integrity sha512-9dgM/cZBnNvjzaMYHVoxxfPj2QXt22Ev7SuuPrs+xav0ukGB0S6d4ydZdEiM48kLx5kDV+QBPrpVnFyefL8kkQ== - dependencies: - async-function "^1.0.0" - call-bound "^1.0.3" - get-proto "^1.0.1" - has-tostringtag "^1.0.2" - safe-regex-test "^1.1.0" - -is-bigint@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.1.0.tgz#dda7a3445df57a42583db4228682eba7c4170672" - integrity sha512-n4ZT37wG78iz03xPRKJrHTdZbe3IicyucEtdRsV5yglwc3GyUfbAfpSeD0FJ41NbUNSt5wbhqfp1fS+BgnvDFQ== - dependencies: - has-bigints "^1.0.2" - -is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - integrity sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q== - dependencies: - binary-extensions "^1.0.0" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-boolean-object@^1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.2.2.tgz#7067f47709809a393c71ff5bb3e135d8a9215d9e" - integrity sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A== - dependencies: - call-bound "^1.0.3" - has-tostringtag "^1.0.2" - -is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - -is-buffer@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" - integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== - -is-bun-module@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-bun-module/-/is-bun-module-2.0.0.tgz#4d7859a87c0fcac950c95e666730e745eae8bddd" - integrity sha512-gNCGbnnnnFAUGKeZ9PdbyeGYJqewpmc2aKHUEMO5nQPWU9lOmv7jcmQIv+qHD8fXW6W7qfuCwX4rY9LNRjXrkQ== - dependencies: - semver "^7.7.1" - -is-callable@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" - integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== - -is-ci@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" - integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== - dependencies: - ci-info "^3.2.0" - -is-ci@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" - integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== - dependencies: - ci-info "^2.0.0" - -is-core-module@^2.13.0, is-core-module@^2.16.1, is-core-module@^2.5.0, is-core-module@^2.8.1: - version "2.16.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.16.1.tgz#2a98801a849f43e2add644fbb6bc6229b19a4ef4" - integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== - dependencies: - hasown "^2.0.2" - -is-data-descriptor@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz#2109164426166d32ea38c405c1e0945d9e6a4eeb" - integrity sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw== - dependencies: - hasown "^2.0.0" - -is-data-view@^1.0.1, is-data-view@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-data-view/-/is-data-view-1.0.2.tgz#bae0a41b9688986c2188dda6657e56b8f9e63b8e" - integrity sha512-RKtWF8pGmS87i2D6gqQu/l7EYRlVdfzemCJN/P3UOs//x1QE7mfhvzHIApBTRf7axvT6DMGwSwBXYCT0nfB9xw== - dependencies: - call-bound "^1.0.2" - get-intrinsic "^1.2.6" - is-typed-array "^1.1.13" - -is-date-object@^1.0.5, is-date-object@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.1.0.tgz#ad85541996fc7aa8b2729701d27b7319f95d82f7" - integrity sha512-PwwhEakHVKTdRNVOw+/Gyh0+MzlCl4R6qKvkhuvLtPMggI1WAHt9sOwZxQLSGpUaDnrdyDsomoRgNnCfKNSXXg== - dependencies: - call-bound "^1.0.2" - has-tostringtag "^1.0.2" - -is-decimal@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" - integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== - -is-decimal@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-2.0.1.tgz#9469d2dc190d0214fd87d78b78caecc0cc14eef7" - integrity sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A== - -is-descriptor@^0.1.0: - version "0.1.7" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.7.tgz#2727eb61fd789dcd5bdf0ed4569f551d2fe3be33" - integrity sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg== - dependencies: - is-accessor-descriptor "^1.0.1" - is-data-descriptor "^1.0.1" - -is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.3.tgz#92d27cb3cd311c4977a4db47df457234a13cb306" - integrity sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw== - dependencies: - is-accessor-descriptor "^1.0.1" - is-data-descriptor "^1.0.1" - -is-docker@^2.0.0, is-docker@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - -is-dom@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-dom/-/is-dom-1.1.0.tgz#af1fced292742443bb59ca3f76ab5e80907b4e8a" - integrity sha512-u82f6mvhYxRPKpw8V1N0W8ce1xXwOrQtgGcxl6UCL5zBmZu3is/18K0rR7uFCnMDuAsS/3W54mGL4vsaFUQlEQ== - dependencies: - is-object "^1.0.1" - is-window "^1.0.2" - -is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== - -is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - -is-extglob@^2.1.0, is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-finalizationregistry@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-finalizationregistry/-/is-finalizationregistry-1.1.1.tgz#eefdcdc6c94ddd0674d9c85887bf93f944a97c90" - integrity sha512-1pC6N8qWJbWoPtEjgcL2xyhQOP491EQjeUo3qTKcmV8YSDDJrOepfG8pcC7h/QgnQHYSv0mJ3Z/ZWxmatVrysg== - dependencies: - call-bound "^1.0.3" - -is-finite@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" - integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-function@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" - integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== - -is-generator-fn@^2.0.0, is-generator-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" - integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== - -is-generator-function@^1.0.10: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.1.2.tgz#ae3b61e3d5ea4e4839b90bad22b02335051a17d5" - integrity sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA== - dependencies: - call-bound "^1.0.4" - generator-function "^2.0.0" - get-proto "^1.0.1" - has-tostringtag "^1.0.2" - safe-regex-test "^1.1.0" - -is-glob@^3.0.0, is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw== - dependencies: - is-extglob "^2.1.0" - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-hexadecimal@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" - integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== - -is-hexadecimal@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz#86b5bf668fca307498d319dfc03289d781a90027" - integrity sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg== - -is-in-browser@^1.0.2, is-in-browser@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.1.3.tgz#56ff4db683a078c6082eb95dad7dc62e1d04f835" - integrity sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g== - -is-interactive@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" - integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== - -is-lambda@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" - integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== - -is-map@^2.0.2, is-map@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.3.tgz#ede96b7fe1e270b3c4465e3a465658764926d62e" - integrity sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw== - -is-negative-zero@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.3.tgz#ced903a027aca6381b777a5743069d7376a49747" - integrity sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw== - -is-number-object@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.1.1.tgz#144b21e95a1bc148205dcc2814a9134ec41b2541" - integrity sha512-lZhclumE1G6VYD8VHe35wFaIif+CTy5SJIi5+3y4psDgWu4wPDoBhF8NxUOinEc7pHgiTsT6MaBb92rKhhD+Xw== - dependencies: - call-bound "^1.0.3" - has-tostringtag "^1.0.2" - -is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== - dependencies: - kind-of "^3.0.2" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-obj@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" - integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== - -is-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" - integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== - -is-path-cwd@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" - integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== - -is-path-in-cwd@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" - integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ== - dependencies: - is-path-inside "^2.1.0" - -is-path-inside@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" - integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg== - dependencies: - path-is-inside "^1.0.2" - -is-path-inside@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - -is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== - -is-plain-obj@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - -is-plain-obj@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" - integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== - -is-plain-obj@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0" - integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== - -is-plain-object@5.0.0, is-plain-object@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" - integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== - -is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - -is-potential-custom-element-name@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" - integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== - -is-regex@^1.1.2, is-regex@^1.1.4, is-regex@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.2.1.tgz#76d70a3ed10ef9be48eb577887d74205bf0cad22" - integrity sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g== - dependencies: - call-bound "^1.0.2" - gopd "^1.2.0" - has-tostringtag "^1.0.2" - hasown "^2.0.2" - -is-set@^2.0.2, is-set@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.3.tgz#8ab209ea424608141372ded6e0cb200ef1d9d01d" - integrity sha512-iPAjerrse27/ygGLxw+EBR9agv9Y6uLeYVJMu+QNCoouJ1/1ri0mGrcWpfCqFZuzzx3WjtwxG098X+n4OuRkPg== - -is-shared-array-buffer@^1.0.2, is-shared-array-buffer@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.4.tgz#9b67844bd9b7f246ba0708c3a93e34269c774f6f" - integrity sha512-ISWac8drv4ZGfwKl5slpHG9OwPNty4jOWPRIhBpxOoD+hqITiwuipOQ2bNthAzwA3B4fIjO4Nln74N0S9byq8A== - dependencies: - call-bound "^1.0.3" - -is-ssh@^1.4.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/is-ssh/-/is-ssh-1.4.1.tgz#76de1cdbe8f92a8b905d1a172b6bc09704c20396" - integrity sha512-JNeu1wQsHjyHgn9NcWTaXq6zWSR6hqE0++zhfZlkFBbScNkyvxCdeV8sRkSBaeLKxmbpR21brail63ACNxJ0Tg== - dependencies: - protocols "^2.0.1" - -is-stream@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" - integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== - -is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-string@^1.0.7, is-string@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.1.1.tgz#92ea3f3d5c5b6e039ca8677e5ac8d07ea773cbb9" - integrity sha512-BtEeSsoaQjlSPBemMQIrY1MY0uM6vnS1g5fmufYOtnxLGUZM2178PKbhsk7Ffv58IX+ZtcvoGwccYsh0PglkAA== - dependencies: - call-bound "^1.0.3" - has-tostringtag "^1.0.2" - -is-symbol@^1.0.3, is-symbol@^1.0.4, is-symbol@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.1.1.tgz#f47761279f532e2b05a7024a7506dbbedacd0634" - integrity sha512-9gGx6GTtCQM73BgmHQXfDmLtfjjTUDSyoxTCbp5WtoixAhfgsDirWIcVQ/IHpvI5Vgd5i/J5F7B9cN/WlVbC/w== - dependencies: - call-bound "^1.0.2" - has-symbols "^1.1.0" - safe-regex-test "^1.1.0" - -is-text-path@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" - integrity sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w== - dependencies: - text-extensions "^1.0.0" - -is-typed-array@^1.1.13, is-typed-array@^1.1.14, is-typed-array@^1.1.15: - version "1.1.15" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.15.tgz#4bfb4a45b61cee83a5a46fba778e4e8d59c0ce0b" - integrity sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ== - dependencies: - which-typed-array "^1.1.16" - -is-typedarray@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== - -is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - -is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== - -is-weakmap@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.2.tgz#bf72615d649dfe5f699079c54b83e47d1ae19cfd" - integrity sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w== - -is-weakref@^1.0.2, is-weakref@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.1.1.tgz#eea430182be8d64174bd96bffbc46f21bf3f9293" - integrity sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew== - dependencies: - call-bound "^1.0.3" - -is-weakset@^2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.4.tgz#c9f5deb0bc1906c6d6f1027f284ddf459249daca" - integrity sha512-mfcwb6IzQyOKTs84CQMrOwW4gQcaTOAWJ0zzJCl2WSPDrWk/OzDaImWFH3djXhb24g4eudZfLRozAvPGw4d9hQ== - dependencies: - call-bound "^1.0.3" - get-intrinsic "^1.2.6" - -is-whitespace-character@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7" - integrity sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w== - -is-window@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-window/-/is-window-1.0.2.tgz#2c896ca53db97de45d3c33133a65d8c9f563480d" - integrity sha512-uj00kdXyZb9t9RcAUAwMZAnkBUwdYGhYlt7djMXhfyhUCzwNba50tIiBKR7q0l7tdoBtFVw/3JmLY6fI3rmZmg== - -is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - -is-word-character@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.4.tgz#ce0e73216f98599060592f62ff31354ddbeb0230" - integrity sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA== - -is-wsl@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw== - -is-wsl@^2.1.1, is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - -isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - -isarray@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== - dependencies: - isarray "1.0.0" - -isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== - -isobject@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" - integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== - -isomorphic-dompurify@^2.21.0: - version "2.30.1" - resolved "https://registry.yarnpkg.com/isomorphic-dompurify/-/isomorphic-dompurify-2.30.1.tgz#4b54854ad9d1fb8e63dd6571f8ffba2606441f46" - integrity sha512-VJFbthRrns7BE+q3qSUJ5zxGNjuq4FqiaWXKCwnMoJbumnoQJoeOeOzP/oejKLPPtENckLWoDxGQiv5OkEFC+Q== - dependencies: - dompurify "^3.3.0" - jsdom "^27.0.1" - -isomorphic-unfetch@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz#87341d5f4f7b63843d468438128cb087b7c3e98f" - integrity sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q== - dependencies: - node-fetch "^2.6.1" - unfetch "^4.2.0" - -isomorphic-ws@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" - integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== - -istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" - integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== - -istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" - integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== - dependencies: - "@babel/core" "^7.12.3" - "@babel/parser" "^7.14.7" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.2.0" - semver "^6.3.0" - -istanbul-lib-instrument@^6.0.0, istanbul-lib-instrument@^6.0.2: - version "6.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz#fa15401df6c15874bcb2105f773325d78c666765" - integrity sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q== - dependencies: - "@babel/core" "^7.23.9" - "@babel/parser" "^7.23.9" - "@istanbuljs/schema" "^0.1.3" - istanbul-lib-coverage "^3.2.0" - semver "^7.5.4" - -istanbul-lib-report@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" - integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== - dependencies: - istanbul-lib-coverage "^3.0.0" - make-dir "^4.0.0" - supports-color "^7.1.0" - -istanbul-lib-source-maps@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" - integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== - dependencies: - debug "^4.1.1" - istanbul-lib-coverage "^3.0.0" - source-map "^0.6.1" - -istanbul-lib-source-maps@^5.0.0: - version "5.0.6" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz#acaef948df7747c8eb5fbf1265cb980f6353a441" - integrity sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A== - dependencies: - "@jridgewell/trace-mapping" "^0.3.23" - debug "^4.1.1" - istanbul-lib-coverage "^3.0.0" - -istanbul-reports@^3.1.3, istanbul-reports@^3.1.4: - version "3.2.0" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.2.0.tgz#cb4535162b5784aa623cee21a7252cf2c807ac93" - integrity sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA== - dependencies: - html-escaper "^2.0.0" - istanbul-lib-report "^3.0.0" - -iterate-iterator@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/iterate-iterator/-/iterate-iterator-1.0.2.tgz#551b804c9eaa15b847ea6a7cdc2f5bf1ec150f91" - integrity sha512-t91HubM4ZDQ70M9wqp+pcNpu8OyJ9UAtXntT/Bcsvp5tZMnz9vRa+IunKXeI8AnfZMTv0jNuVEmGeLSMjVvfPw== - -iterate-value@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/iterate-value/-/iterate-value-1.0.2.tgz#935115bd37d006a52046535ebc8d07e9c9337f57" - integrity sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ== - dependencies: - es-get-iterator "^1.0.2" - iterate-iterator "^1.0.1" - -iterator.prototype@^1.1.4: - version "1.1.5" - resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.5.tgz#12c959a29de32de0aa3bbbb801f4d777066dae39" - integrity sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g== - dependencies: - define-data-property "^1.1.4" - es-object-atoms "^1.0.0" - get-intrinsic "^1.2.6" - get-proto "^1.0.0" - has-symbols "^1.1.0" - set-function-name "^2.0.2" - -jackspeak@^3.1.2: - version "3.4.3" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-3.4.3.tgz#8833a9d89ab4acde6188942bd1c53b6390ed5a8a" - integrity sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw== - dependencies: - "@isaacs/cliui" "^8.0.2" - optionalDependencies: - "@pkgjs/parseargs" "^0.11.0" - -jackspeak@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-4.1.1.tgz#96876030f450502047fc7e8c7fcf8ce8124e43ae" - integrity sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ== - dependencies: - "@isaacs/cliui" "^8.0.2" - -jake@^10.8.5: - version "10.9.4" - resolved "https://registry.yarnpkg.com/jake/-/jake-10.9.4.tgz#d626da108c63d5cfb00ab5c25fadc7e0084af8e6" - integrity sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA== - dependencies: - async "^3.2.6" - filelist "^1.0.4" - picocolors "^1.1.1" - -jest-changed-files@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-30.3.0.tgz#055849df695f9a9fcde0ae44024f815bbc627f3a" - integrity sha512-B/7Cny6cV5At6M25EWDgf9S617lHivamL8vl6KEpJqkStauzcG4e+WPfDgMMF+H4FVH4A2PLRyvgDJan4441QA== - dependencies: - execa "^5.1.1" - jest-util "30.3.0" - p-limit "^3.1.0" - -jest-changed-files@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5" - integrity sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw== - dependencies: - "@jest/types" "^27.5.1" - execa "^5.0.0" - throat "^6.0.1" - -jest-circus@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-30.3.0.tgz#153614c11ab35867f371bd93496ecb9690b92077" - integrity sha512-PyXq5szeSfR/4f1lYqCmmQjh0vqDkURUYi9N6whnHjlRz4IUQfMcXkGLeEoiJtxtyPqgUaUUfyQlApXWBSN1RA== - dependencies: - "@jest/environment" "30.3.0" - "@jest/expect" "30.3.0" - "@jest/test-result" "30.3.0" - "@jest/types" "30.3.0" - "@types/node" "*" - chalk "^4.1.2" - co "^4.6.0" - dedent "^1.6.0" - is-generator-fn "^2.1.0" - jest-each "30.3.0" - jest-matcher-utils "30.3.0" - jest-message-util "30.3.0" - jest-runtime "30.3.0" - jest-snapshot "30.3.0" - jest-util "30.3.0" - p-limit "^3.1.0" - pretty-format "30.3.0" - pure-rand "^7.0.0" - slash "^3.0.0" - stack-utils "^2.0.6" - -jest-circus@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.5.1.tgz#37a5a4459b7bf4406e53d637b49d22c65d125ecc" - integrity sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - dedent "^0.7.0" - expect "^27.5.1" - is-generator-fn "^2.0.0" - jest-each "^27.5.1" - jest-matcher-utils "^27.5.1" - jest-message-util "^27.5.1" - jest-runtime "^27.5.1" - jest-snapshot "^27.5.1" - jest-util "^27.5.1" - pretty-format "^27.5.1" - slash "^3.0.0" - stack-utils "^2.0.3" - throat "^6.0.1" - -jest-cli@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-30.3.0.tgz#5ed75a337f486a1f1c5acbb2de8acddb106ead6c" - integrity sha512-l6Tqx+j1fDXJEW5bqYykDQQ7mQg+9mhWXtnj+tQZrTWYHyHoi6Be8HPumDSA+UiX2/2buEgjA58iJzdj146uCw== - dependencies: - "@jest/core" "30.3.0" - "@jest/test-result" "30.3.0" - "@jest/types" "30.3.0" - chalk "^4.1.2" - exit-x "^0.2.2" - import-local "^3.2.0" - jest-config "30.3.0" - jest-util "30.3.0" - jest-validate "30.3.0" - yargs "^17.7.2" - -jest-cli@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.5.1.tgz#278794a6e6458ea8029547e6c6cbf673bd30b145" - integrity sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw== - dependencies: - "@jest/core" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/types" "^27.5.1" - chalk "^4.0.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - import-local "^3.0.2" - jest-config "^27.5.1" - jest-util "^27.5.1" - jest-validate "^27.5.1" - prompts "^2.0.1" - yargs "^16.2.0" - -jest-config@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-30.3.0.tgz#b969e0aaaf5964419e62953bb712c16d15972425" - integrity sha512-WPMAkMAtNDY9P/oKObtsRG/6KTrhtgPJoBTmk20uDn4Uy6/3EJnnaZJre/FMT1KVRx8cve1r7/FlMIOfRVWL4w== - dependencies: - "@babel/core" "^7.27.4" - "@jest/get-type" "30.1.0" - "@jest/pattern" "30.0.1" - "@jest/test-sequencer" "30.3.0" - "@jest/types" "30.3.0" - babel-jest "30.3.0" - chalk "^4.1.2" - ci-info "^4.2.0" - deepmerge "^4.3.1" - glob "^10.5.0" - graceful-fs "^4.2.11" - jest-circus "30.3.0" - jest-docblock "30.2.0" - jest-environment-node "30.3.0" - jest-regex-util "30.0.1" - jest-resolve "30.3.0" - jest-runner "30.3.0" - jest-util "30.3.0" - jest-validate "30.3.0" - parse-json "^5.2.0" - pretty-format "30.3.0" - slash "^3.0.0" - strip-json-comments "^3.1.1" - -jest-config@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.5.1.tgz#5c387de33dca3f99ad6357ddeccd91bf3a0e4a41" - integrity sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA== - dependencies: - "@babel/core" "^7.8.0" - "@jest/test-sequencer" "^27.5.1" - "@jest/types" "^27.5.1" - babel-jest "^27.5.1" - chalk "^4.0.0" - ci-info "^3.2.0" - deepmerge "^4.2.2" - glob "^7.1.1" - graceful-fs "^4.2.9" - jest-circus "^27.5.1" - jest-environment-jsdom "^27.5.1" - jest-environment-node "^27.5.1" - jest-get-type "^27.5.1" - jest-jasmine2 "^27.5.1" - jest-regex-util "^27.5.1" - jest-resolve "^27.5.1" - jest-runner "^27.5.1" - jest-util "^27.5.1" - jest-validate "^27.5.1" - micromatch "^4.0.4" - parse-json "^5.2.0" - pretty-format "^27.5.1" - slash "^3.0.0" - strip-json-comments "^3.1.1" - -jest-diff@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-30.3.0.tgz#e0a4c84ef350ffd790ffd5b0016acabeecf5f759" - integrity sha512-n3q4PDQjS4LrKxfWB3Z5KNk1XjXtZTBwQp71OP0Jo03Z6V60x++K5L8k6ZrW8MY8pOFylZvHM0zsjS1RqlHJZQ== - dependencies: - "@jest/diff-sequences" "30.3.0" - "@jest/get-type" "30.1.0" - chalk "^4.1.2" - pretty-format "30.3.0" - -"jest-diff@>=29.4.3 < 30", jest-diff@^29.4.1, jest-diff@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" - integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== - dependencies: - chalk "^4.0.0" - diff-sequences "^29.6.3" - jest-get-type "^29.6.3" - pretty-format "^29.7.0" - -jest-diff@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" - integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw== - dependencies: - chalk "^4.0.0" - diff-sequences "^27.5.1" - jest-get-type "^27.5.1" - pretty-format "^27.5.1" - -jest-docblock@30.2.0: - version "30.2.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-30.2.0.tgz#42cd98d69f887e531c7352309542b1ce4ee10256" - integrity sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA== - dependencies: - detect-newline "^3.1.0" - -jest-docblock@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.5.1.tgz#14092f364a42c6108d42c33c8cf30e058e25f6c0" - integrity sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ== - dependencies: - detect-newline "^3.0.0" - -jest-each@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-30.3.0.tgz#faa7229bf7a9fa6426dc604057a7d2a173493b1e" - integrity sha512-V8eMndg/aZ+3LnCJgSm13IxS5XSBM22QSZc9BtPK8Dek6pm+hfUNfwBdvsB3d342bo1q7wnSkC38zjX259qZNA== - dependencies: - "@jest/get-type" "30.1.0" - "@jest/types" "30.3.0" - chalk "^4.1.2" - jest-util "30.3.0" - pretty-format "30.3.0" - -jest-each@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.5.1.tgz#5bc87016f45ed9507fed6e4702a5b468a5b2c44e" - integrity sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ== - dependencies: - "@jest/types" "^27.5.1" - chalk "^4.0.0" - jest-get-type "^27.5.1" - jest-util "^27.5.1" - pretty-format "^27.5.1" - -jest-environment-jsdom@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz#ea9ccd1fc610209655a77898f86b2b559516a546" - integrity sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/fake-timers" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - jest-mock "^27.5.1" - jest-util "^27.5.1" - jsdom "^16.6.0" - -jest-environment-node@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-30.3.0.tgz#aa8a57c5d0c4af0f8b1f7403ba737fec6b3aabbe" - integrity sha512-4i6HItw/JSiJVsC5q0hnKIe/hbYfZLVG9YJ/0pU9Hz2n/9qZe3Rhn5s5CUZA5ORZlcdT/vmAXRMyONXJwPrmYQ== - dependencies: - "@jest/environment" "30.3.0" - "@jest/fake-timers" "30.3.0" - "@jest/types" "30.3.0" - "@types/node" "*" - jest-mock "30.3.0" - jest-util "30.3.0" - jest-validate "30.3.0" - -jest-environment-node@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz#dedc2cfe52fab6b8f5714b4808aefa85357a365e" - integrity sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/fake-timers" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - jest-mock "^27.5.1" - jest-util "^27.5.1" - -jest-get-type@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" - integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== - -jest-get-type@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" - integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== - -jest-haste-map@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-30.3.0.tgz#1ea6843e6e45c077d91270666a4fcba958c24cd5" - integrity sha512-mMi2oqG4KRU0R9QEtscl87JzMXfUhbKaFqOxmjb2CKcbHcUGFrJCBWHmnTiUqi6JcnzoBlO4rWfpdl2k/RfLCA== - dependencies: - "@jest/types" "30.3.0" - "@types/node" "*" - anymatch "^3.1.3" - fb-watchman "^2.0.2" - graceful-fs "^4.2.11" - jest-regex-util "30.0.1" - jest-util "30.3.0" - jest-worker "30.3.0" - picomatch "^4.0.3" - walker "^1.0.8" - optionalDependencies: - fsevents "^2.3.3" - -jest-haste-map@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa" - integrity sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w== - dependencies: - "@jest/types" "^26.6.2" - "@types/graceful-fs" "^4.1.2" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.4" - jest-regex-util "^26.0.0" - jest-serializer "^26.6.2" - jest-util "^26.6.2" - jest-worker "^26.6.2" - micromatch "^4.0.2" - sane "^4.0.3" - walker "^1.0.7" - optionalDependencies: - fsevents "^2.1.2" - -jest-haste-map@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz#9fd8bd7e7b4fa502d9c6164c5640512b4e811e7f" - integrity sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng== - dependencies: - "@jest/types" "^27.5.1" - "@types/graceful-fs" "^4.1.2" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.9" - jest-regex-util "^27.5.1" - jest-serializer "^27.5.1" - jest-util "^27.5.1" - jest-worker "^27.5.1" - micromatch "^4.0.4" - walker "^1.0.7" - optionalDependencies: - fsevents "^2.3.2" - -jest-jasmine2@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz#a037b0034ef49a9f3d71c4375a796f3b230d1ac4" - integrity sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/source-map" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - expect "^27.5.1" - is-generator-fn "^2.0.0" - jest-each "^27.5.1" - jest-matcher-utils "^27.5.1" - jest-message-util "^27.5.1" - jest-runtime "^27.5.1" - jest-snapshot "^27.5.1" - jest-util "^27.5.1" - pretty-format "^27.5.1" - throat "^6.0.1" - -jest-leak-detector@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-30.3.0.tgz#a695a851e353f517a554a2f5c91c2742fc131c98" - integrity sha512-cuKmUUGIjfXZAiGJ7TbEMx0bcqNdPPI6P1V+7aF+m/FUJqFDxkFR4JqkTu8ZOiU5AaX/x0hZ20KaaIPXQzbMGQ== - dependencies: - "@jest/get-type" "30.1.0" - pretty-format "30.3.0" - -jest-leak-detector@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz#6ec9d54c3579dd6e3e66d70e3498adf80fde3fb8" - integrity sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ== - dependencies: - jest-get-type "^27.5.1" - pretty-format "^27.5.1" - -jest-matcher-utils@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-30.3.0.tgz#d6c739fec1ecd33809f2d2b1348f6ab01d2f2493" - integrity sha512-HEtc9uFQgaUHkC7nLSlQL3Tph4Pjxt/yiPvkIrrDCt9jhoLIgxaubo1G+CFOnmHYMxHwwdaSN7mkIFs6ZK8OhA== - dependencies: - "@jest/get-type" "30.1.0" - chalk "^4.1.2" - jest-diff "30.3.0" - pretty-format "30.3.0" - -jest-matcher-utils@^27.0.0, jest-matcher-utils@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" - integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== - dependencies: - chalk "^4.0.0" - jest-diff "^27.5.1" - jest-get-type "^27.5.1" - pretty-format "^27.5.1" - -jest-matcher-utils@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" - integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== - dependencies: - chalk "^4.0.0" - jest-diff "^29.7.0" - jest-get-type "^29.6.3" - pretty-format "^29.7.0" - -jest-message-util@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-30.3.0.tgz#4d723544d36890ba862ac3961db52db5b0d1ba39" - integrity sha512-Z/j4Bo+4ySJ+JPJN3b2Qbl9hDq3VrXmnjjGEWD/x0BCXeOXPTV1iZYYzl2X8c1MaCOL+ewMyNBcm88sboE6YWw== - dependencies: - "@babel/code-frame" "^7.27.1" - "@jest/types" "30.3.0" - "@types/stack-utils" "^2.0.3" - chalk "^4.1.2" - graceful-fs "^4.2.11" - picomatch "^4.0.3" - pretty-format "30.3.0" - slash "^3.0.0" - stack-utils "^2.0.6" - -jest-message-util@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf" - integrity sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g== - dependencies: - "@babel/code-frame" "^7.12.13" - "@jest/types" "^27.5.1" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - micromatch "^4.0.4" - pretty-format "^27.5.1" - slash "^3.0.0" - stack-utils "^2.0.3" - -jest-message-util@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" - integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== - dependencies: - "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.6.3" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - micromatch "^4.0.4" - pretty-format "^29.7.0" - slash "^3.0.0" - stack-utils "^2.0.3" - -jest-mock@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-30.3.0.tgz#e0fa4184a596a6c4fdec53d4f412158418923747" - integrity sha512-OTzICK8CpE+t4ndhKrwlIdbM6Pn8j00lvmSmq5ejiO+KxukbLjgOflKWMn3KE34EZdQm5RqTuKj+5RIEniYhog== - dependencies: - "@jest/types" "30.3.0" - "@types/node" "*" - jest-util "30.3.0" - -jest-mock@^27.0.6, jest-mock@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" - integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og== - dependencies: - "@jest/types" "^27.5.1" - "@types/node" "*" - -jest-pnp-resolver@^1.2.2, jest-pnp-resolver@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" - integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== - -jest-regex-util@30.0.1: - version "30.0.1" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-30.0.1.tgz#f17c1de3958b67dfe485354f5a10093298f2a49b" - integrity sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA== - -jest-regex-util@^26.0.0: - version "26.0.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" - integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== - -jest-regex-util@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" - integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== - -jest-resolve-dependencies@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-30.3.0.tgz#4d638c9f0d93a62a6ed25dec874bfd7e756c8ce5" - integrity sha512-9ev8s3YN6Hsyz9LV75XUwkCVFlwPbaFn6Wp75qnI0wzAINYWY8Fb3+6y59Rwd3QaS3kKXffHXsZMziMavfz/nw== - dependencies: - jest-regex-util "30.0.1" - jest-snapshot "30.3.0" - -jest-resolve-dependencies@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8" - integrity sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg== - dependencies: - "@jest/types" "^27.5.1" - jest-regex-util "^27.5.1" - jest-snapshot "^27.5.1" - -jest-resolve@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-30.3.0.tgz#b7bee9927279805b1b50715d2170a545553b87ff" - integrity sha512-NRtTAHQlpd15F9rUR36jqwelbrDV/dY4vzNte3S2kxCKUJRYNd5/6nTSbYiak1VX5g8IoFF23Uj5TURkUW8O5g== - dependencies: - chalk "^4.1.2" - graceful-fs "^4.2.11" - jest-haste-map "30.3.0" - jest-pnp-resolver "^1.2.3" - jest-util "30.3.0" - jest-validate "30.3.0" - slash "^3.0.0" - unrs-resolver "^1.7.11" - -jest-resolve@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.5.1.tgz#a2f1c5a0796ec18fe9eb1536ac3814c23617b384" - integrity sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw== - dependencies: - "@jest/types" "^27.5.1" - chalk "^4.0.0" - graceful-fs "^4.2.9" - jest-haste-map "^27.5.1" - jest-pnp-resolver "^1.2.2" - jest-util "^27.5.1" - jest-validate "^27.5.1" - resolve "^1.20.0" - resolve.exports "^1.1.0" - slash "^3.0.0" - -jest-runner@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-30.3.0.tgz#fa970fc4e45d418ad7e7d581b24cac7af5944cb7" - integrity sha512-gDv6C9LGKWDPLia9TSzZwf4h3kMQCqyTpq+95PODnTRDO0g9os48XIYYkS6D236vjpBir2fF63YmJFtqkS5Duw== - dependencies: - "@jest/console" "30.3.0" - "@jest/environment" "30.3.0" - "@jest/test-result" "30.3.0" - "@jest/transform" "30.3.0" - "@jest/types" "30.3.0" - "@types/node" "*" - chalk "^4.1.2" - emittery "^0.13.1" - exit-x "^0.2.2" - graceful-fs "^4.2.11" - jest-docblock "30.2.0" - jest-environment-node "30.3.0" - jest-haste-map "30.3.0" - jest-leak-detector "30.3.0" - jest-message-util "30.3.0" - jest-resolve "30.3.0" - jest-runtime "30.3.0" - jest-util "30.3.0" - jest-watcher "30.3.0" - jest-worker "30.3.0" - p-limit "^3.1.0" - source-map-support "0.5.13" - -jest-runner@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.5.1.tgz#071b27c1fa30d90540805c5645a0ec167c7b62e5" - integrity sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ== - dependencies: - "@jest/console" "^27.5.1" - "@jest/environment" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - emittery "^0.8.1" - graceful-fs "^4.2.9" - jest-docblock "^27.5.1" - jest-environment-jsdom "^27.5.1" - jest-environment-node "^27.5.1" - jest-haste-map "^27.5.1" - jest-leak-detector "^27.5.1" - jest-message-util "^27.5.1" - jest-resolve "^27.5.1" - jest-runtime "^27.5.1" - jest-util "^27.5.1" - jest-worker "^27.5.1" - source-map-support "^0.5.6" - throat "^6.0.1" - -jest-runtime@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-30.3.0.tgz#1a9bec7a9b68db12dfe4136bbe41ab883ea2c996" - integrity sha512-CgC+hIBJbuh78HEffkhNKcbXAytQViplcl8xupqeIWyKQF50kCQA8J7GeJCkjisC6hpnC9Muf8jV5RdtdFbGng== - dependencies: - "@jest/environment" "30.3.0" - "@jest/fake-timers" "30.3.0" - "@jest/globals" "30.3.0" - "@jest/source-map" "30.0.1" - "@jest/test-result" "30.3.0" - "@jest/transform" "30.3.0" - "@jest/types" "30.3.0" - "@types/node" "*" - chalk "^4.1.2" - cjs-module-lexer "^2.1.0" - collect-v8-coverage "^1.0.2" - glob "^10.5.0" - graceful-fs "^4.2.11" - jest-haste-map "30.3.0" - jest-message-util "30.3.0" - jest-mock "30.3.0" - jest-regex-util "30.0.1" - jest-resolve "30.3.0" - jest-snapshot "30.3.0" - jest-util "30.3.0" - slash "^3.0.0" - strip-bom "^4.0.0" - -jest-runtime@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.5.1.tgz#4896003d7a334f7e8e4a53ba93fb9bcd3db0a1af" - integrity sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/fake-timers" "^27.5.1" - "@jest/globals" "^27.5.1" - "@jest/source-map" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - chalk "^4.0.0" - cjs-module-lexer "^1.0.0" - collect-v8-coverage "^1.0.0" - execa "^5.0.0" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-haste-map "^27.5.1" - jest-message-util "^27.5.1" - jest-mock "^27.5.1" - jest-regex-util "^27.5.1" - jest-resolve "^27.5.1" - jest-snapshot "^27.5.1" - jest-util "^27.5.1" - slash "^3.0.0" - strip-bom "^4.0.0" - -jest-serializer@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1" - integrity sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g== - dependencies: - "@types/node" "*" - graceful-fs "^4.2.4" - -jest-serializer@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.5.1.tgz#81438410a30ea66fd57ff730835123dea1fb1f64" - integrity sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w== - dependencies: - "@types/node" "*" - graceful-fs "^4.2.9" - -jest-snapshot@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-30.3.0.tgz#6e7ea75069dda86e36311a0f73189e830d4f51ad" - integrity sha512-f14c7atpb4O2DeNhwcvS810Y63wEn8O1HqK/luJ4F6M4NjvxmAKQwBUWjbExUtMxWJQ0wVgmCKymeJK6NZMnfQ== - dependencies: - "@babel/core" "^7.27.4" - "@babel/generator" "^7.27.5" - "@babel/plugin-syntax-jsx" "^7.27.1" - "@babel/plugin-syntax-typescript" "^7.27.1" - "@babel/types" "^7.27.3" - "@jest/expect-utils" "30.3.0" - "@jest/get-type" "30.1.0" - "@jest/snapshot-utils" "30.3.0" - "@jest/transform" "30.3.0" - "@jest/types" "30.3.0" - babel-preset-current-node-syntax "^1.2.0" - chalk "^4.1.2" - expect "30.3.0" - graceful-fs "^4.2.11" - jest-diff "30.3.0" - jest-matcher-utils "30.3.0" - jest-message-util "30.3.0" - jest-util "30.3.0" - pretty-format "30.3.0" - semver "^7.7.2" - synckit "^0.11.8" - -jest-snapshot@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz#b668d50d23d38054a51b42c4039cab59ae6eb6a1" - integrity sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA== - dependencies: - "@babel/core" "^7.7.2" - "@babel/generator" "^7.7.2" - "@babel/plugin-syntax-typescript" "^7.7.2" - "@babel/traverse" "^7.7.2" - "@babel/types" "^7.0.0" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/babel__traverse" "^7.0.4" - "@types/prettier" "^2.1.5" - babel-preset-current-node-syntax "^1.0.0" - chalk "^4.0.0" - expect "^27.5.1" - graceful-fs "^4.2.9" - jest-diff "^27.5.1" - jest-get-type "^27.5.1" - jest-haste-map "^27.5.1" - jest-matcher-utils "^27.5.1" - jest-message-util "^27.5.1" - jest-util "^27.5.1" - natural-compare "^1.4.0" - pretty-format "^27.5.1" - semver "^7.3.2" - -jest-util@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-30.3.0.tgz#95a4fbacf2dac20e768e2f1744b70519f2ba7980" - integrity sha512-/jZDa00a3Sz7rdyu55NLrQCIrbyIkbBxareejQI315f/i8HjYN+ZWsDLLpoQSiUIEIyZF/R8fDg3BmB8AtHttg== - dependencies: - "@jest/types" "30.3.0" - "@types/node" "*" - chalk "^4.1.2" - ci-info "^4.2.0" - graceful-fs "^4.2.11" - picomatch "^4.0.3" - -jest-util@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" - integrity sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q== - dependencies: - "@jest/types" "^26.6.2" - "@types/node" "*" - chalk "^4.0.0" - graceful-fs "^4.2.4" - is-ci "^2.0.0" - micromatch "^4.0.2" - -jest-util@^27.0.0, jest-util@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9" - integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw== - dependencies: - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" - -jest-util@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" - integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== - dependencies: - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" - -jest-validate@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-30.3.0.tgz#215e11b8fcc5e2ca4b99ea5d730a5b4c969e4355" - integrity sha512-I/xzC8h5G+SHCb2P2gWkJYrNiTbeL47KvKeW5EzplkyxzBRBw1ssSHlI/jXec0ukH2q7x2zAWQm7015iusg62Q== - dependencies: - "@jest/get-type" "30.1.0" - "@jest/types" "30.3.0" - camelcase "^6.3.0" - chalk "^4.1.2" - leven "^3.1.0" - pretty-format "30.3.0" - -jest-validate@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067" - integrity sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ== - dependencies: - "@jest/types" "^27.5.1" - camelcase "^6.2.0" - chalk "^4.0.0" - jest-get-type "^27.5.1" - leven "^3.1.0" - pretty-format "^27.5.1" - -jest-watcher@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-30.3.0.tgz#3afa1af355b9fe80f0261eb8a23981a315858596" - integrity sha512-PJ1d9ThtTR8aMiBWUdcownq9mDdLXsQzJayTk4kmaBRHKvwNQn+ANveuhEBUyNI2hR1TVhvQ8D5kHubbzBHR/w== - dependencies: - "@jest/test-result" "30.3.0" - "@jest/types" "30.3.0" - "@types/node" "*" - ansi-escapes "^4.3.2" - chalk "^4.1.2" - emittery "^0.13.1" - jest-util "30.3.0" - string-length "^4.0.2" - -jest-watcher@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2" - integrity sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw== - dependencies: - "@jest/test-result" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - jest-util "^27.5.1" - string-length "^4.0.1" - -jest-worker@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-30.3.0.tgz#ae4dc1f1d93d0cba1415624fcedaec40ea764f14" - integrity sha512-DrCKkaQwHexjRUFTmPzs7sHQe0TSj9nvDALKGdwmK5mW9v7j90BudWirKAJHt3QQ9Dhrg1F7DogPzhChppkJpQ== - dependencies: - "@types/node" "*" - "@ungap/structured-clone" "^1.3.0" - jest-util "30.3.0" - merge-stream "^2.0.0" - supports-color "^8.1.1" - -jest-worker@^26.5.0, jest-worker@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" - integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^7.0.0" - -jest-worker@^27.0.2, jest-worker@^27.4.5, jest-worker@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" - integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jest-worker@^29.4.3: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" - integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== - dependencies: - "@types/node" "*" - jest-util "^29.7.0" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jest@^27.1.0: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc" - integrity sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ== - dependencies: - "@jest/core" "^27.5.1" - import-local "^3.0.2" - jest-cli "^27.5.1" - -jest@^30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-30.3.0.tgz#6460b889dd805e9677400505f16f1d9b14c285a3" - integrity sha512-AkXIIFcaazymvey2i/+F94XRnM6TsVLZDhBMLsd1Sf/W0wzsvvpjeyUrCZD6HGG4SDYPgDJDBKeiJTBb10WzMg== - dependencies: - "@jest/core" "30.3.0" - "@jest/types" "30.3.0" - import-local "^3.2.0" - jest-cli "30.3.0" - -joi@^17.11.0: - version "17.13.3" - resolved "https://registry.yarnpkg.com/joi/-/joi-17.13.3.tgz#0f5cc1169c999b30d344366d384b12d92558bcec" - integrity sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA== - dependencies: - "@hapi/hoek" "^9.3.0" - "@hapi/topo" "^5.1.0" - "@sideway/address" "^4.1.5" - "@sideway/formula" "^3.0.1" - "@sideway/pinpoint" "^2.0.0" - -js-sha3@0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" - integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== - -js-string-escape@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" - integrity sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg== - -"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@4.1.0, js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -js-yaml@^3.10.0, js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.1.tgz#854c292467705b699476e1a2decc0c8a3458806b" - integrity sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA== - dependencies: - argparse "^2.0.1" - -jsdom@^16.6.0: - version "16.7.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" - integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== - dependencies: - abab "^2.0.5" - acorn "^8.2.4" - acorn-globals "^6.0.0" - cssom "^0.4.4" - cssstyle "^2.3.0" - data-urls "^2.0.0" - decimal.js "^10.2.1" - domexception "^2.0.1" - escodegen "^2.0.0" - form-data "^3.0.0" - html-encoding-sniffer "^2.0.1" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - is-potential-custom-element-name "^1.0.1" - nwsapi "^2.2.0" - parse5 "6.0.1" - saxes "^5.0.1" - symbol-tree "^3.2.4" - tough-cookie "^4.0.0" - w3c-hr-time "^1.0.2" - w3c-xmlserializer "^2.0.0" - webidl-conversions "^6.1.0" - whatwg-encoding "^1.0.5" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.5.0" - ws "^7.4.6" - xml-name-validator "^3.0.0" - -jsdom@^27.0.1: - version "27.0.1" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-27.0.1.tgz#72f3ff263ccc128da40d8526943a7df253eeea93" - integrity sha512-SNSQteBL1IlV2zqhwwolaG9CwhIhTvVHWg3kTss/cLE7H/X4644mtPQqYvCfsSrGQWt9hSZcgOXX8bOZaMN+kA== - dependencies: - "@asamuzakjp/dom-selector" "^6.7.2" - cssstyle "^5.3.1" - data-urls "^6.0.0" - decimal.js "^10.6.0" - html-encoding-sniffer "^4.0.0" - http-proxy-agent "^7.0.2" - https-proxy-agent "^7.0.6" - is-potential-custom-element-name "^1.0.1" - parse5 "^8.0.0" - rrweb-cssom "^0.8.0" - saxes "^6.0.0" - symbol-tree "^3.2.4" - tough-cookie "^6.0.0" - w3c-xmlserializer "^5.0.0" - webidl-conversions "^8.0.0" - whatwg-encoding "^3.1.1" - whatwg-mimetype "^4.0.0" - whatwg-url "^15.1.0" - ws "^8.18.3" - xml-name-validator "^5.0.0" - -jsesc@^3.0.2, jsesc@~3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.1.0.tgz#74d335a234f67ed19907fdadfac7ccf9d409825d" - integrity sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA== - -json-buffer@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" - integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== - -json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - -json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-parse-even-better-errors@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz#b43d35e89c0f3be6b5fbbe9dc6c82467b30c28da" - integrity sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== - -json-stringify-safe@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== - -json5@2.x, json5@^2.1.0, json5@^2.1.2, json5@^2.2.2, json5@^2.2.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" - integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== - -json5@^1.0.1, json5@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" - integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== - dependencies: - minimist "^1.2.0" - -jsonc-parser@3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" - integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== - -jsonfile@^6.0.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.2.0.tgz#7c265bd1b65de6977478300087c99f1c84383f62" - integrity sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - -jsonparse@^1.2.0, jsonparse@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== - -jss-plugin-camel-case@^10.10.0: - version "10.10.0" - resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.10.0.tgz#27ea159bab67eb4837fa0260204eb7925d4daa1c" - integrity sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw== - dependencies: - "@babel/runtime" "^7.3.1" - hyphenate-style-name "^1.0.3" - jss "10.10.0" - -jss-plugin-default-unit@^10.10.0: - version "10.10.0" - resolved "https://registry.yarnpkg.com/jss-plugin-default-unit/-/jss-plugin-default-unit-10.10.0.tgz#db3925cf6a07f8e1dd459549d9c8aadff9804293" - integrity sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ== - dependencies: - "@babel/runtime" "^7.3.1" - jss "10.10.0" - -jss-plugin-global@^10.10.0: - version "10.10.0" - resolved "https://registry.yarnpkg.com/jss-plugin-global/-/jss-plugin-global-10.10.0.tgz#1c55d3c35821fab67a538a38918292fc9c567efd" - integrity sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A== - dependencies: - "@babel/runtime" "^7.3.1" - jss "10.10.0" - -jss-plugin-nested@^10.10.0: - version "10.10.0" - resolved "https://registry.yarnpkg.com/jss-plugin-nested/-/jss-plugin-nested-10.10.0.tgz#db872ed8925688806e77f1fc87f6e62264513219" - integrity sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA== - dependencies: - "@babel/runtime" "^7.3.1" - jss "10.10.0" - tiny-warning "^1.0.2" - -jss-plugin-props-sort@^10.10.0: - version "10.10.0" - resolved "https://registry.yarnpkg.com/jss-plugin-props-sort/-/jss-plugin-props-sort-10.10.0.tgz#67f4dd4c70830c126f4ec49b4b37ccddb680a5d7" - integrity sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg== - dependencies: - "@babel/runtime" "^7.3.1" - jss "10.10.0" - -jss-plugin-rule-value-function@^10.10.0: - version "10.10.0" - resolved "https://registry.yarnpkg.com/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.10.0.tgz#7d99e3229e78a3712f78ba50ab342e881d26a24b" - integrity sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g== - dependencies: - "@babel/runtime" "^7.3.1" - jss "10.10.0" - tiny-warning "^1.0.2" - -jss-plugin-vendor-prefixer@^10.10.0: - version "10.10.0" - resolved "https://registry.yarnpkg.com/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.10.0.tgz#c01428ef5a89f2b128ec0af87a314d0c767931c7" - integrity sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg== - dependencies: - "@babel/runtime" "^7.3.1" - css-vendor "^2.0.8" - jss "10.10.0" - -jss@10.10.0, jss@^10.10.0: - version "10.10.0" - resolved "https://registry.yarnpkg.com/jss/-/jss-10.10.0.tgz#a75cc85b0108c7ac8c7b7d296c520a3e4fbc6ccc" - integrity sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw== - dependencies: - "@babel/runtime" "^7.3.1" - csstype "^3.0.2" - is-in-browser "^1.1.3" - tiny-warning "^1.0.2" - -"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.5: - version "3.3.5" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" - integrity sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ== - dependencies: - array-includes "^3.1.6" - array.prototype.flat "^1.3.1" - object.assign "^4.1.4" - object.values "^1.1.6" - -junk@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/junk/-/junk-3.1.0.tgz#31499098d902b7e98c5d9b9c80f43457a88abfa1" - integrity sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ== - -keyv@^4.5.3, keyv@^4.5.4: - version "4.5.4" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" - integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== - dependencies: - json-buffer "3.0.1" - -keyvaluestorage-interface@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/keyvaluestorage-interface/-/keyvaluestorage-interface-1.0.0.tgz#13ebdf71f5284ad54be94bd1ad9ed79adad515ff" - integrity sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g== - -kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== - dependencies: - is-buffer "^1.1.5" - -kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== - dependencies: - is-buffer "^1.1.5" - -kind-of@^6.0.2, kind-of@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - -kleur@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" - integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== - -klona@^2.0.4: - version "2.0.6" - resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22" - integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== - -language-subtag-registry@^0.3.20: - version "0.3.23" - resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.23.tgz#23529e04d9e3b74679d70142df3fd2eb6ec572e7" - integrity sha512-0K65Lea881pHotoGEa5gDlMxt3pctLi2RplBb7Ezh4rRdLEOtgi7n4EwK9lamnUCkKBqaeKRVebTq6BAxSkpXQ== - -language-tags@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.9.tgz#1ffdcd0ec0fafb4b1be7f8b11f306ad0f9c08777" - integrity sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA== - dependencies: - language-subtag-registry "^0.3.20" - -launch-editor@^2.6.0: - version "2.11.1" - resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.11.1.tgz#61a0b7314a42fd84a6cbb564573d9e9ffcf3d72b" - integrity sha512-SEET7oNfgSaB6Ym0jufAdCeo3meJVeCaaDyzRygy0xsp2BFKCprcfHljTq4QkzTLUxEKkFK6OK4811YM2oSrRg== - dependencies: - picocolors "^1.1.1" - shell-quote "^1.8.3" - -lazy-universal-dotenv@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lazy-universal-dotenv/-/lazy-universal-dotenv-3.0.1.tgz#a6c8938414bca426ab8c9463940da451a911db38" - integrity sha512-prXSYk799h3GY3iOWnC6ZigYzMPjxN2svgjJ9shk7oMadSNX3wXy0B6F32PMJv7qtMnrIbUxoEHzbutvxR2LBQ== - dependencies: - "@babel/runtime" "^7.5.0" - app-root-dir "^1.0.2" - core-js "^3.0.4" - dotenv "^8.0.0" - dotenv-expand "^5.1.0" - -lefthook-darwin-arm64@1.13.6: - version "1.13.6" - resolved "https://registry.yarnpkg.com/lefthook-darwin-arm64/-/lefthook-darwin-arm64-1.13.6.tgz#8b07763fc93aa3dc4d0744337f2dcbb3b87a496f" - integrity sha512-m6Lb77VGc84/Qo21Lhq576pEvcgFCnvloEiP02HbAHcIXD0RTLy9u2yAInrixqZeaz13HYtdDaI7OBYAAdVt8A== - -lefthook-darwin-x64@1.13.6: - version "1.13.6" - resolved "https://registry.yarnpkg.com/lefthook-darwin-x64/-/lefthook-darwin-x64-1.13.6.tgz#454e09ff19b837de1346c6c64d53c4aa8795a68e" - integrity sha512-CoRpdzanu9RK3oXR1vbEJA5LN7iB+c7hP+sONeQJzoOXuq4PNKVtEaN84Gl1BrVtCNLHWFAvCQaZPPiiXSy8qg== - -lefthook-freebsd-arm64@1.13.6: - version "1.13.6" - resolved "https://registry.yarnpkg.com/lefthook-freebsd-arm64/-/lefthook-freebsd-arm64-1.13.6.tgz#873ad77e0f041fa13c541964505a5af028cc7f62" - integrity sha512-X4A7yfvAJ68CoHTqP+XvQzdKbyd935sYy0bQT6Ajz7FL1g7hFiro8dqHSdPdkwei9hs8hXeV7feyTXbYmfjKQQ== - -lefthook-freebsd-x64@1.13.6: - version "1.13.6" - resolved "https://registry.yarnpkg.com/lefthook-freebsd-x64/-/lefthook-freebsd-x64-1.13.6.tgz#bc04ad430fe45eaa1b5282639d435605921e374b" - integrity sha512-ai2m+Sj2kGdY46USfBrCqLKe9GYhzeq01nuyDYCrdGISePeZ6udOlD1k3lQKJGQCHb0bRz4St0r5nKDSh1x/2A== - -lefthook-linux-arm64@1.13.6: - version "1.13.6" - resolved "https://registry.yarnpkg.com/lefthook-linux-arm64/-/lefthook-linux-arm64-1.13.6.tgz#efbe267da03a634a28ff273b1b4cfa784b9c9bee" - integrity sha512-cbo4Wtdq81GTABvikLORJsAWPKAJXE8Q5RXsICFUVznh5PHigS9dFW/4NXywo0+jfFPCT6SYds2zz4tCx6DA0Q== - -lefthook-linux-x64@1.13.6: - version "1.13.6" - resolved "https://registry.yarnpkg.com/lefthook-linux-x64/-/lefthook-linux-x64-1.13.6.tgz#32fc5398f21e220f8ea6223e7434392d41d54afc" - integrity sha512-uJl9vjCIIBTBvMZkemxCE+3zrZHlRO7Oc+nZJ+o9Oea3fu+W82jwX7a7clw8jqNfaeBS+8+ZEQgiMHWCloTsGw== - -lefthook-openbsd-arm64@1.13.6: - version "1.13.6" - resolved "https://registry.yarnpkg.com/lefthook-openbsd-arm64/-/lefthook-openbsd-arm64-1.13.6.tgz#2294ca7378e4455e8325f873b520de53939b84e2" - integrity sha512-7r153dxrNRQ9ytRs2PmGKKkYdvZYFPre7My7XToSTiRu5jNCq++++eAKVkoyWPduk97dGIA+YWiEr5Noe0TK2A== - -lefthook-openbsd-x64@1.13.6: - version "1.13.6" - resolved "https://registry.yarnpkg.com/lefthook-openbsd-x64/-/lefthook-openbsd-x64-1.13.6.tgz#19216354cddbce1e7f84045cc473d5a808357306" - integrity sha512-Z+UhLlcg1xrXOidK3aLLpgH7KrwNyWYE3yb7ITYnzJSEV8qXnePtVu8lvMBHs/myzemjBzeIr/U/+ipjclR06g== - -lefthook-windows-arm64@1.13.6: - version "1.13.6" - resolved "https://registry.yarnpkg.com/lefthook-windows-arm64/-/lefthook-windows-arm64-1.13.6.tgz#e7c92dd0cabf7d7e1e50d11532e61efe9f76c629" - integrity sha512-Uxef6qoDxCmUNQwk8eBvddYJKSBFglfwAY9Y9+NnnmiHpWTjjYiObE9gT2mvGVpEgZRJVAatBXc+Ha5oDD/OgQ== - -lefthook-windows-x64@1.13.6: - version "1.13.6" - resolved "https://registry.yarnpkg.com/lefthook-windows-x64/-/lefthook-windows-x64-1.13.6.tgz#f9654bcef01597ff45cc616864e7e2505902e108" - integrity sha512-mOZoM3FQh3o08M8PQ/b3IYuL5oo36D9ehczIw1dAgp1Ly+Tr4fJ96A+4SEJrQuYeRD4mex9bR7Ps56I73sBSZA== - -lefthook@^1.8.5: - version "1.13.6" - resolved "https://registry.yarnpkg.com/lefthook/-/lefthook-1.13.6.tgz#880484d4ee13900ce75bfb7ec204bbbfd611f7fa" - integrity sha512-ojj4/4IJ29Xn4drd5emqVgilegAPN3Kf0FQM2p/9+lwSTpU+SZ1v4Ig++NF+9MOa99UKY8bElmVrLhnUUNFh5g== - optionalDependencies: - lefthook-darwin-arm64 "1.13.6" - lefthook-darwin-x64 "1.13.6" - lefthook-freebsd-arm64 "1.13.6" - lefthook-freebsd-x64 "1.13.6" - lefthook-linux-arm64 "1.13.6" - lefthook-linux-x64 "1.13.6" - lefthook-openbsd-arm64 "1.13.6" - lefthook-openbsd-x64 "1.13.6" - lefthook-windows-arm64 "1.13.6" - lefthook-windows-x64 "1.13.6" - -lerna@^7.3.0: - version "7.4.2" - resolved "https://registry.yarnpkg.com/lerna/-/lerna-7.4.2.tgz#03497125d7b7c8d463eebfe17a701b16bde2ad09" - integrity sha512-gxavfzHfJ4JL30OvMunmlm4Anw7d7Tq6tdVHzUukLdS9nWnxCN/QB21qR+VJYp5tcyXogHKbdUEGh6qmeyzxSA== - dependencies: - "@lerna/child-process" "7.4.2" - "@lerna/create" "7.4.2" - "@npmcli/run-script" "6.0.2" - "@nx/devkit" ">=16.5.1 < 17" - "@octokit/plugin-enterprise-rest" "6.0.1" - "@octokit/rest" "19.0.11" - byte-size "8.1.1" - chalk "4.1.0" - clone-deep "4.0.1" - cmd-shim "6.0.1" - columnify "1.6.0" - conventional-changelog-angular "7.0.0" - conventional-changelog-core "5.0.1" - conventional-recommended-bump "7.0.1" - cosmiconfig "^8.2.0" - dedent "0.7.0" - envinfo "7.8.1" - execa "5.0.0" - fs-extra "^11.1.1" - get-port "5.1.1" - get-stream "6.0.0" - git-url-parse "13.1.0" - glob-parent "5.1.2" - globby "11.1.0" - graceful-fs "4.2.11" - has-unicode "2.0.1" - import-local "3.1.0" - ini "^1.3.8" - init-package-json "5.0.0" - inquirer "^8.2.4" - is-ci "3.0.1" - is-stream "2.0.0" - jest-diff ">=29.4.3 < 30" - js-yaml "4.1.0" - libnpmaccess "7.0.2" - libnpmpublish "7.3.0" - load-json-file "6.2.0" - lodash "^4.17.21" - make-dir "4.0.0" - minimatch "3.0.5" - multimatch "5.0.0" - node-fetch "2.6.7" - npm-package-arg "8.1.1" - npm-packlist "5.1.1" - npm-registry-fetch "^14.0.5" - npmlog "^6.0.2" - nx ">=16.5.1 < 17" - p-map "4.0.0" - p-map-series "2.1.0" - p-pipe "3.1.0" - p-queue "6.6.2" - p-reduce "2.1.0" - p-waterfall "2.1.1" - pacote "^15.2.0" - pify "5.0.0" - read-cmd-shim "4.0.0" - read-package-json "6.0.4" - resolve-from "5.0.0" - rimraf "^4.4.1" - semver "^7.3.8" - signal-exit "3.0.7" - slash "3.0.0" - ssri "^9.0.1" - strong-log-transformer "2.1.0" - tar "6.1.11" - temp-dir "1.0.0" - typescript ">=3 < 6" - upath "2.0.1" - uuid "^9.0.0" - validate-npm-package-license "3.0.4" - validate-npm-package-name "5.0.0" - write-file-atomic "5.0.1" - write-pkg "4.0.0" - yargs "16.2.0" - yargs-parser "20.2.4" - -leven@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" - integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -libnpmaccess@7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-7.0.2.tgz#7f056c8c933dd9c8ba771fa6493556b53c5aac52" - integrity sha512-vHBVMw1JFMTgEk15zRsJuSAg7QtGGHpUSEfnbcRL1/gTBag9iEfJbyjpDmdJmwMhvpoLoNBtdAUCdGnaP32hhw== - dependencies: - npm-package-arg "^10.1.0" - npm-registry-fetch "^14.0.3" - -libnpmpublish@7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-7.3.0.tgz#2ceb2b36866d75a6cd7b4aa748808169f4d17e37" - integrity sha512-fHUxw5VJhZCNSls0KLNEG0mCD2PN1i14gH5elGOgiVnU3VgTcRahagYP2LKI1m0tFCJ+XrAm0zVYyF5RCbXzcg== - dependencies: - ci-info "^3.6.1" - normalize-package-data "^5.0.0" - npm-package-arg "^10.1.0" - npm-registry-fetch "^14.0.3" - proc-log "^3.0.0" - semver "^7.3.7" - sigstore "^1.4.0" - ssri "^10.0.1" - -libsodium-sumo@^0.7.15: - version "0.7.15" - resolved "https://registry.yarnpkg.com/libsodium-sumo/-/libsodium-sumo-0.7.15.tgz#91c1d863fe3fbce6d6b9db1aadaa622733a1d007" - integrity sha512-5tPmqPmq8T8Nikpm1Nqj0hBHvsLFCXvdhBFV7SGOitQPZAA6jso8XoL0r4L7vmfKXr486fiQInvErHtEvizFMw== - -libsodium-wrappers-sumo@^0.7.11: - version "0.7.15" - resolved "https://registry.yarnpkg.com/libsodium-wrappers-sumo/-/libsodium-wrappers-sumo-0.7.15.tgz#0ef2a99b4b17e8385aa7e6850593660dbaf5fb40" - integrity sha512-aSWY8wKDZh5TC7rMvEdTHoyppVq/1dTSAeAR7H6pzd6QRT3vQWcT5pGwCotLcpPEOLXX6VvqihSPkpEhYAjANA== - dependencies: - libsodium-sumo "^0.7.15" - -lie@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" - integrity sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw== - dependencies: - immediate "~3.0.5" - -lilconfig@^2.0.3: - version "2.1.0" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" - integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== - -lilconfig@^3.1.1: - version "3.1.3" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.3.tgz#a1bcfd6257f9585bf5ae14ceeebb7b559025e4c4" - integrity sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw== - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -lines-and-columns@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.4.tgz#d00318855905d2660d8c0822e3f5a4715855fc42" - integrity sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A== - -load-json-file@6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-6.2.0.tgz#5c7770b42cafa97074ca2848707c61662f4251a1" - integrity sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ== - dependencies: - graceful-fs "^4.1.15" - parse-json "^5.0.0" - strip-bom "^4.0.0" - type-fest "^0.6.0" - -load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - integrity sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A== - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - -load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw== - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - -loader-runner@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" - integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== - -loader-runner@^4.1.0, loader-runner@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.1.tgz#6c76ed29b0ccce9af379208299f07f876de737e3" - integrity sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q== - -loader-utils@^1.2.3: - version "1.4.2" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.2.tgz#29a957f3a63973883eb684f10ffd3d151fec01a3" - integrity sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^1.0.1" - -loader-utils@^2.0.0, loader-utils@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" - integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^2.1.2" - -localforage@^1.7.3: - version "1.10.0" - resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.10.0.tgz#5c465dc5f62b2807c3a84c0c6a1b1b3212781dd4" - integrity sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg== - dependencies: - lie "3.1.1" - -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - -locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -locate-path@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-7.2.0.tgz#69cb1779bd90b35ab1e771e1f2f89a202c2a8a8a" - integrity sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA== - dependencies: - p-locate "^6.0.0" - -lodash-es@^4.17.21: - version "4.17.23" - resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.23.tgz#58c4360fd1b5d33afc6c0bbd3d1149349b1138e0" - integrity sha512-kVI48u3PZr38HdYz98UmfPnXl2DXrpdctLrFLCd3kOx1xUkOmpFPx7gCWWM5MPkL/fD8zb+Ph0QzjGFs4+hHWg== - -lodash.debounce@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== - -lodash.ismatch@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" - integrity sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g== - -lodash.memoize@4.x, lodash.memoize@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lodash.padend@^4.6.1: - version "4.6.1" - resolved "https://registry.yarnpkg.com/lodash.padend/-/lodash.padend-4.6.1.tgz#53ccba047d06e158d311f45da625f4e49e6f166e" - integrity sha512-sOQs2aqGpbl27tmCS1QNZA09Uqp01ZzWfDUoD+xzTii0E7dSQfRKcRetFwa+uXaxaqL+TKm7CgD2JdKP7aZBSw== - -lodash.trimstart@^4.5.1: - version "4.5.1" - resolved "https://registry.yarnpkg.com/lodash.trimstart/-/lodash.trimstart-4.5.1.tgz#8ff4dec532d82486af59573c39445914e944a7f1" - integrity sha512-b/+D6La8tU76L/61/aN0jULWHkT0EeJCmVstPBn/K9MtD2qBW83AsBNrr63dKuWYwVMO7ucv13QNO/Ek/2RKaQ== - -lodash.uniq@4.5.0, lodash.uniq@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" - integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== - -lodash.words@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.words/-/lodash.words-4.2.0.tgz#5ecfeaf8ecf8acaa8e0c8386295f1993c9cf4036" - integrity sha512-mXxqd8Yx9BGPij3lZKFSdOsjOTbL4krbCCp9slEozaN4EMppA2dFmK/f8HeohodprY6W0vOdiQ5WFgPaTI75xQ== - -lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: - version "4.17.23" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.23.tgz#f113b0378386103be4f6893388c73d0bde7f2c5a" - integrity sha512-LgVTMpQtIopCi79SJeDiP0TfWi5CNEc/L/aRdTh3yIvmZXTnheWpKjSZhnvMl8iXbC1tFg9gdHHDMLoV7CnG+w== - -log-symbols@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - -long@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" - integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== - -longest-streak@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.1.0.tgz#62fa67cd958742a1574af9f39866364102d90cd4" - integrity sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g== - -loose-envify@^1.1.0, loose-envify@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - -loud-rejection@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" - integrity sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ== - dependencies: - currently-unhandled "^0.4.1" - signal-exit "^3.0.0" - -loupe@^3.1.2: - version "3.2.1" - resolved "https://registry.yarnpkg.com/loupe/-/loupe-3.2.1.tgz#0095cf56dc5b7a9a7c08ff5b1a8796ec8ad17e76" - integrity sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ== - -lower-case@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" - integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== - dependencies: - tslib "^2.0.3" - -lru-cache@^10.2.0, lru-cache@^10.4.3: - version "10.4.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" - integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== - -lru-cache@^11.0.0, lru-cache@^11.2.1, lru-cache@^11.2.2: - version "11.2.2" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.2.2.tgz#40fd37edffcfae4b2940379c0722dc6eeaa75f24" - integrity sha512-F9ODfyqML2coTIsQpSkRHnLSZMtkU8Q+mSfcaIyKwy58u+8k5nvAYeiNhsyMARvzNcXJ9QfWVrcPsC9e9rAxtg== - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1: - version "7.18.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" - integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== - -lucide-react@^0.453.0: - version "0.453.0" - resolved "https://registry.yarnpkg.com/lucide-react/-/lucide-react-0.453.0.tgz#d37909a45a29d89680383a202ee861224b05ba6a" - integrity sha512-kL+RGZCcJi9BvJtzg2kshO192Ddy9hv3ij+cPrVPWSRzgCWCVazoQJxOjAwgK53NomL07HB7GPHW120FimjNhQ== - -lz-string@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" - integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== - -make-dir@4.0.0, make-dir@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" - integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== - dependencies: - semver "^7.5.3" - -make-dir@^2.0.0, make-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" - integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== - dependencies: - pify "^4.0.1" - semver "^5.6.0" - -make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - -make-error@1.x, make-error@^1.3.6: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -make-fetch-happen@^10.0.3: - version "10.2.1" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz#f5e3835c5e9817b617f2770870d9492d28678164" - integrity sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w== - dependencies: - agentkeepalive "^4.2.1" - cacache "^16.1.0" - http-cache-semantics "^4.1.0" - http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^7.7.1" - minipass "^3.1.6" - minipass-collect "^1.0.2" - minipass-fetch "^2.0.3" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^0.6.3" - promise-retry "^2.0.1" - socks-proxy-agent "^7.0.0" - ssri "^9.0.0" - -make-fetch-happen@^11.0.0, make-fetch-happen@^11.0.1, make-fetch-happen@^11.1.1: - version "11.1.1" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz#85ceb98079584a9523d4bf71d32996e7e208549f" - integrity sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w== - dependencies: - agentkeepalive "^4.2.1" - cacache "^17.0.0" - http-cache-semantics "^4.1.1" - http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^7.7.1" - minipass "^5.0.0" - minipass-fetch "^3.0.0" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^0.6.3" - promise-retry "^2.0.1" - socks-proxy-agent "^7.0.0" - ssri "^10.0.0" - -makeerror@1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" - integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== - dependencies: - tmpl "1.0.5" - -map-age-cleaner@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== - dependencies: - p-defer "^1.0.0" - -map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== - -map-obj@^1.0.0, map-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - integrity sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg== - -map-obj@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a" - integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== - -map-or-similar@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/map-or-similar/-/map-or-similar-1.5.0.tgz#6de2653174adfb5d9edc33c69d3e92a1b76faf08" - integrity sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg== - -map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== - dependencies: - object-visit "^1.0.0" - -markdown-escapes@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535" - integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg== - -material-react-table@^3.0.3: - version "3.2.1" - resolved "https://registry.yarnpkg.com/material-react-table/-/material-react-table-3.2.1.tgz#56f595755cab3b669b399999fed9eb305fbb6dd7" - integrity sha512-sQtTf7bETpkPN2Hm5BVtz89wrfXCVQguz6XlwMChSnfKFO5QCKAJJC5aSIKnUc3S0AvTz/k/ILi00FnnY1Gixw== - dependencies: - "@tanstack/match-sorter-utils" "8.19.4" - "@tanstack/react-table" "8.20.6" - "@tanstack/react-virtual" "3.11.2" - highlight-words "2.0.0" - -math-intrinsics@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz#a0dd74be81e2aa5c2f27e65ce283605ee4e2b7f9" - integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== - -md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - -mdast-squeeze-paragraphs@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz#7c4c114679c3bee27ef10b58e2e015be79f1ef97" - integrity sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ== - dependencies: - unist-util-remove "^2.0.0" - -mdast-util-definitions@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz#c5c1a84db799173b4dcf7643cda999e440c24db2" - integrity sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ== - dependencies: - unist-util-visit "^2.0.0" - -mdast-util-from-markdown@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.2.tgz#4850390ca7cf17413a9b9a0fbefcd1bc0eb4160a" - integrity sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA== - dependencies: - "@types/mdast" "^4.0.0" - "@types/unist" "^3.0.0" - decode-named-character-reference "^1.0.0" - devlop "^1.0.0" - mdast-util-to-string "^4.0.0" - micromark "^4.0.0" - micromark-util-decode-numeric-character-reference "^2.0.0" - micromark-util-decode-string "^2.0.0" - micromark-util-normalize-identifier "^2.0.0" - micromark-util-symbol "^2.0.0" - micromark-util-types "^2.0.0" - unist-util-stringify-position "^4.0.0" - -mdast-util-mdx-expression@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz#43f0abac9adc756e2086f63822a38c8d3c3a5096" - integrity sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ== - dependencies: - "@types/estree-jsx" "^1.0.0" - "@types/hast" "^3.0.0" - "@types/mdast" "^4.0.0" - devlop "^1.0.0" - mdast-util-from-markdown "^2.0.0" - mdast-util-to-markdown "^2.0.0" - -mdast-util-mdx-jsx@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz#fd04c67a2a7499efb905a8a5c578dddc9fdada0d" - integrity sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q== - dependencies: - "@types/estree-jsx" "^1.0.0" - "@types/hast" "^3.0.0" - "@types/mdast" "^4.0.0" - "@types/unist" "^3.0.0" - ccount "^2.0.0" - devlop "^1.1.0" - mdast-util-from-markdown "^2.0.0" - mdast-util-to-markdown "^2.0.0" - parse-entities "^4.0.0" - stringify-entities "^4.0.0" - unist-util-stringify-position "^4.0.0" - vfile-message "^4.0.0" - -mdast-util-mdxjs-esm@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz#019cfbe757ad62dd557db35a695e7314bcc9fa97" - integrity sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg== - dependencies: - "@types/estree-jsx" "^1.0.0" - "@types/hast" "^3.0.0" - "@types/mdast" "^4.0.0" - devlop "^1.0.0" - mdast-util-from-markdown "^2.0.0" - mdast-util-to-markdown "^2.0.0" - -mdast-util-phrasing@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz#7cc0a8dec30eaf04b7b1a9661a92adb3382aa6e3" - integrity sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w== - dependencies: - "@types/mdast" "^4.0.0" - unist-util-is "^6.0.0" - -mdast-util-to-hast@10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-10.0.1.tgz#0cfc82089494c52d46eb0e3edb7a4eb2aea021eb" - integrity sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA== - dependencies: - "@types/mdast" "^3.0.0" - "@types/unist" "^2.0.0" - mdast-util-definitions "^4.0.0" - mdurl "^1.0.0" - unist-builder "^2.0.0" - unist-util-generated "^1.0.0" - unist-util-position "^3.0.0" - unist-util-visit "^2.0.0" - -mdast-util-to-hast@^13.0.0: - version "13.2.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-13.2.0.tgz#5ca58e5b921cc0a3ded1bc02eed79a4fe4fe41f4" - integrity sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA== - dependencies: - "@types/hast" "^3.0.0" - "@types/mdast" "^4.0.0" - "@ungap/structured-clone" "^1.0.0" - devlop "^1.0.0" - micromark-util-sanitize-uri "^2.0.0" - trim-lines "^3.0.0" - unist-util-position "^5.0.0" - unist-util-visit "^5.0.0" - vfile "^6.0.0" - -mdast-util-to-markdown@^2.0.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz#f910ffe60897f04bb4b7e7ee434486f76288361b" - integrity sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA== - dependencies: - "@types/mdast" "^4.0.0" - "@types/unist" "^3.0.0" - longest-streak "^3.0.0" - mdast-util-phrasing "^4.0.0" - mdast-util-to-string "^4.0.0" - micromark-util-classify-character "^2.0.0" - micromark-util-decode-string "^2.0.0" - unist-util-visit "^5.0.0" - zwitch "^2.0.0" - -mdast-util-to-string@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz#27055500103f51637bd07d01da01eb1967a43527" - integrity sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A== - -mdast-util-to-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz#7a5121475556a04e7eddeb67b264aae79d312814" - integrity sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg== - dependencies: - "@types/mdast" "^4.0.0" - -mdn-data@2.0.14: - version "2.0.14" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" - integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== - -mdn-data@2.0.28: - version "2.0.28" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.28.tgz#5ec48e7bef120654539069e1ae4ddc81ca490eba" - integrity sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g== - -mdn-data@2.0.30: - version "2.0.30" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc" - integrity sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA== - -mdn-data@2.12.2: - version "2.12.2" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.12.2.tgz#9ae6c41a9e65adf61318b32bff7b64fbfb13f8cf" - integrity sha512-IEn+pegP1aManZuckezWCO+XZQDplx1366JoVhTpMpBB1sPey/SbveZQUosKiKiGYjg1wH4pMlNgXbCiYgihQA== - -mdurl@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" - integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== - -media-query-parser@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/media-query-parser/-/media-query-parser-2.0.2.tgz#ff79e56cee92615a304a1c2fa4f2bd056c0a1d29" - integrity sha512-1N4qp+jE0pL5Xv4uEcwVUhIkwdUO3S/9gML90nqKA7v7FcOS5vUtatfzok9S9U1EJU8dHWlcv95WLnKmmxZI9w== - dependencies: - "@babel/runtime" "^7.12.5" - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== - -mem@^8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/mem/-/mem-8.1.1.tgz#cf118b357c65ab7b7e0817bdf00c8062297c0122" - integrity sha512-qFCFUDs7U3b8mBDPyz5EToEKoAkgCzqquIgi9nkkR9bixxOVOre+09lbuH7+9Kn2NFpm56M3GUWVbU2hQgdACA== - dependencies: - map-age-cleaner "^0.1.3" - mimic-fn "^3.1.0" - -memfs@^3.1.2, memfs@^3.2.2, memfs@^3.4.1, memfs@^3.4.3: - version "3.6.0" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6" - integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ== - dependencies: - fs-monkey "^1.0.4" - -memoizerific@^1.11.3: - version "1.11.3" - resolved "https://registry.yarnpkg.com/memoizerific/-/memoizerific-1.11.3.tgz#7c87a4646444c32d75438570905f2dbd1b1a805a" - integrity sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog== - dependencies: - map-or-similar "^1.5.0" - -memory-fs@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" - integrity sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ== - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -memory-fs@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" - integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - -memorystream@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" - integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== - -meow@^3.1.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" - integrity sha512-TNdwZs0skRlpPpCUK25StC4VH+tP5GgeY1HQOOGP+lQ2xtdkN2VtT/5tiX9k3IWpkBPV9b3LsAWXn4GGi/PrSA== - dependencies: - camelcase-keys "^2.0.0" - decamelize "^1.1.2" - loud-rejection "^1.0.0" - map-obj "^1.0.1" - minimist "^1.1.3" - normalize-package-data "^2.3.4" - object-assign "^4.0.1" - read-pkg-up "^1.0.1" - redent "^1.0.0" - trim-newlines "^1.0.0" - -meow@^8.1.2: - version "8.1.2" - resolved "https://registry.yarnpkg.com/meow/-/meow-8.1.2.tgz#bcbe45bda0ee1729d350c03cffc8395a36c4e897" - integrity sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q== - dependencies: - "@types/minimist" "^1.2.0" - camelcase-keys "^6.2.2" - decamelize-keys "^1.1.0" - hard-rejection "^2.1.0" - minimist-options "4.1.0" - normalize-package-data "^3.0.0" - read-pkg-up "^7.0.1" - redent "^3.0.0" - trim-newlines "^3.0.0" - type-fest "^0.18.0" - yargs-parser "^20.2.3" - -merge-descriptors@1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.3.tgz#d80319a65f3c7935351e5cfdac8f9318504dbed5" - integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== - -microevent.ts@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.1.tgz#70b09b83f43df5172d0205a63025bce0f7357fa0" - integrity sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g== - -micromark-core-commonmark@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz#c691630e485021a68cf28dbc2b2ca27ebf678cd4" - integrity sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg== - dependencies: - decode-named-character-reference "^1.0.0" - devlop "^1.0.0" - micromark-factory-destination "^2.0.0" - micromark-factory-label "^2.0.0" - micromark-factory-space "^2.0.0" - micromark-factory-title "^2.0.0" - micromark-factory-whitespace "^2.0.0" - micromark-util-character "^2.0.0" - micromark-util-chunked "^2.0.0" - micromark-util-classify-character "^2.0.0" - micromark-util-html-tag-name "^2.0.0" - micromark-util-normalize-identifier "^2.0.0" - micromark-util-resolve-all "^2.0.0" - micromark-util-subtokenize "^2.0.0" - micromark-util-symbol "^2.0.0" - micromark-util-types "^2.0.0" - -micromark-factory-destination@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz#8fef8e0f7081f0474fbdd92deb50c990a0264639" - integrity sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA== - dependencies: - micromark-util-character "^2.0.0" - micromark-util-symbol "^2.0.0" - micromark-util-types "^2.0.0" - -micromark-factory-label@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz#5267efa97f1e5254efc7f20b459a38cb21058ba1" - integrity sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg== - dependencies: - devlop "^1.0.0" - micromark-util-character "^2.0.0" - micromark-util-symbol "^2.0.0" - micromark-util-types "^2.0.0" - -micromark-factory-space@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz#36d0212e962b2b3121f8525fc7a3c7c029f334fc" - integrity sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg== - dependencies: - micromark-util-character "^2.0.0" - micromark-util-types "^2.0.0" - -micromark-factory-title@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz#237e4aa5d58a95863f01032d9ee9b090f1de6e94" - integrity sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw== - dependencies: - micromark-factory-space "^2.0.0" - micromark-util-character "^2.0.0" - micromark-util-symbol "^2.0.0" - micromark-util-types "^2.0.0" - -micromark-factory-whitespace@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz#06b26b2983c4d27bfcc657b33e25134d4868b0b1" - integrity sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ== - dependencies: - micromark-factory-space "^2.0.0" - micromark-util-character "^2.0.0" - micromark-util-symbol "^2.0.0" - micromark-util-types "^2.0.0" - -micromark-util-character@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-2.1.1.tgz#2f987831a40d4c510ac261e89852c4e9703ccda6" - integrity sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q== - dependencies: - micromark-util-symbol "^2.0.0" - micromark-util-types "^2.0.0" - -micromark-util-chunked@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz#47fbcd93471a3fccab86cff03847fc3552db1051" - integrity sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA== - dependencies: - micromark-util-symbol "^2.0.0" - -micromark-util-classify-character@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz#d399faf9c45ca14c8b4be98b1ea481bced87b629" - integrity sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q== - dependencies: - micromark-util-character "^2.0.0" - micromark-util-symbol "^2.0.0" - micromark-util-types "^2.0.0" - -micromark-util-combine-extensions@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz#2a0f490ab08bff5cc2fd5eec6dd0ca04f89b30a9" - integrity sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg== - dependencies: - micromark-util-chunked "^2.0.0" - micromark-util-types "^2.0.0" - -micromark-util-decode-numeric-character-reference@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz#fcf15b660979388e6f118cdb6bf7d79d73d26fe5" - integrity sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw== - dependencies: - micromark-util-symbol "^2.0.0" - -micromark-util-decode-string@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz#6cb99582e5d271e84efca8e61a807994d7161eb2" - integrity sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ== - dependencies: - decode-named-character-reference "^1.0.0" - micromark-util-character "^2.0.0" - micromark-util-decode-numeric-character-reference "^2.0.0" - micromark-util-symbol "^2.0.0" - -micromark-util-encode@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz#0d51d1c095551cfaac368326963cf55f15f540b8" - integrity sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw== - -micromark-util-html-tag-name@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz#e40403096481986b41c106627f98f72d4d10b825" - integrity sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA== - -micromark-util-normalize-identifier@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz#c30d77b2e832acf6526f8bf1aa47bc9c9438c16d" - integrity sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q== - dependencies: - micromark-util-symbol "^2.0.0" - -micromark-util-resolve-all@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz#e1a2d62cdd237230a2ae11839027b19381e31e8b" - integrity sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg== - dependencies: - micromark-util-types "^2.0.0" - -micromark-util-sanitize-uri@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz#ab89789b818a58752b73d6b55238621b7faa8fd7" - integrity sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ== - dependencies: - micromark-util-character "^2.0.0" - micromark-util-encode "^2.0.0" - micromark-util-symbol "^2.0.0" - -micromark-util-subtokenize@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz#d8ade5ba0f3197a1cf6a2999fbbfe6357a1a19ee" - integrity sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA== - dependencies: - devlop "^1.0.0" - micromark-util-chunked "^2.0.0" - micromark-util-symbol "^2.0.0" - micromark-util-types "^2.0.0" - -micromark-util-symbol@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz#e5da494e8eb2b071a0d08fb34f6cefec6c0a19b8" - integrity sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q== - -micromark-util-types@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-2.0.2.tgz#f00225f5f5a0ebc3254f96c36b6605c4b393908e" - integrity sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA== - -micromark@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/micromark/-/micromark-4.0.2.tgz#91395a3e1884a198e62116e33c9c568e39936fdb" - integrity sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA== - dependencies: - "@types/debug" "^4.0.0" - debug "^4.0.0" - decode-named-character-reference "^1.0.0" - devlop "^1.0.0" - micromark-core-commonmark "^2.0.0" - micromark-factory-space "^2.0.0" - micromark-util-character "^2.0.0" - micromark-util-chunked "^2.0.0" - micromark-util-combine-extensions "^2.0.0" - micromark-util-decode-numeric-character-reference "^2.0.0" - micromark-util-encode "^2.0.0" - micromark-util-normalize-identifier "^2.0.0" - micromark-util-resolve-all "^2.0.0" - micromark-util-sanitize-uri "^2.0.0" - micromark-util-subtokenize "^2.0.0" - micromark-util-symbol "^2.0.0" - micromark-util-types "^2.0.0" - -micromatch@^3.1.10, micromatch@^3.1.4: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - -micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" - integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== - dependencies: - braces "^3.0.3" - picomatch "^2.3.1" - -miller-rabin@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" - integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== - dependencies: - bn.js "^4.0.0" - brorand "^1.0.1" - -mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -"mime-db@>= 1.43.0 < 2": - version "1.54.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.54.0.tgz#cddb3ee4f9c64530dff640236661d42cb6a314f5" - integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== - -mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.30, mime-types@^2.1.31, mime-types@^2.1.35, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -mime@^2.4.4: - version "2.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" - integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -mimic-fn@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-3.1.0.tgz#65755145bbf3e36954b949c16450427451d5ca74" - integrity sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ== - -min-document@^2.19.0: - version "2.19.1" - resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.1.tgz#7083ad4bc8879a6eba6516688e9f5d91d32e2d23" - integrity sha512-8lqe85PkqQJzIcs2iD7xW/WSxcncC3/DPVbTOafKNJDIMXwGfwXS350mH4SJslomntN2iYtFBuC0yNO3CEap6g== - dependencies: - dom-walk "^0.1.0" - -min-indent@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" - integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== - -mini-css-extract-plugin@^2.2.2, mini-css-extract-plugin@^2.7.6: - version "2.9.4" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.4.tgz#cafa1a42f8c71357f49cd1566810d74ff1cb0200" - integrity sha512-ZWYT7ln73Hptxqxk2DxPU9MmapXRhxkJD6tkSR04dnQxm8BGu2hzgKLugK5yySD97u/8yy7Ma7E76k9ZdvtjkQ== - dependencies: - schema-utils "^4.0.0" - tapable "^2.2.1" - -minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== - -minimatch@3.0.5: - version "3.0.5" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.5.tgz#4da8f1290ee0f0f8e83d60ca69f8f134068604a3" - integrity sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^10.0.3: - version "10.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.3.tgz#cf7a0314a16c4d9ab73a7730a0e8e3c3502d47aa" - integrity sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw== - dependencies: - "@isaacs/brace-expansion" "^5.0.0" - -minimatch@^10.2.2: - version "10.2.5" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.2.5.tgz#bd48687a0be38ed2961399105600f832095861d1" - integrity sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg== - dependencies: - brace-expansion "^5.0.5" - -minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^3.0.5, minimatch@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.5.tgz#580c88f8d5445f2bd6aa8f3cadefa0de79fbd69e" - integrity sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^5.0.1: - version "5.1.6" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" - integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^8.0.2: - version "8.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-8.0.4.tgz#847c1b25c014d4e9a7f68aaf63dedd668a626229" - integrity sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^9.0.0, minimatch@^9.0.4: - version "9.0.5" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" - integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== - dependencies: - brace-expansion "^2.0.1" - -minimist-options@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" - integrity sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A== - dependencies: - arrify "^1.0.1" - is-plain-obj "^1.1.0" - kind-of "^6.0.3" - -minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: - version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -minipass-collect@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" - integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== - dependencies: - minipass "^3.0.0" - -minipass-fetch@^2.0.3: - version "2.1.2" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-2.1.2.tgz#95560b50c472d81a3bc76f20ede80eaed76d8add" - integrity sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA== - dependencies: - minipass "^3.1.6" - minipass-sized "^1.0.3" - minizlib "^2.1.2" - optionalDependencies: - encoding "^0.1.13" - -minipass-fetch@^3.0.0: - version "3.0.5" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.5.tgz#f0f97e40580affc4a35cc4a1349f05ae36cb1e4c" - integrity sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg== - dependencies: - minipass "^7.0.3" - minipass-sized "^1.0.3" - minizlib "^2.1.2" - optionalDependencies: - encoding "^0.1.13" - -minipass-flush@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" - integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== - dependencies: - minipass "^3.0.0" - -minipass-json-stream@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/minipass-json-stream/-/minipass-json-stream-1.0.2.tgz#5121616c77a11c406c3ffa77509e0b77bb267ec3" - integrity sha512-myxeeTm57lYs8pH2nxPzmEEg8DGIgW+9mv6D4JZD2pa81I/OBjeU7PtICXV6c9eRGTA5JMDsuIPUZRCyBMYNhg== - dependencies: - jsonparse "^1.3.1" - minipass "^3.0.0" - -minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" - integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== - dependencies: - minipass "^3.0.0" - -minipass-sized@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" - integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== - dependencies: - minipass "^3.0.0" - -minipass@^3.0.0, minipass@^3.1.1, minipass@^3.1.6: - version "3.3.6" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" - integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== - dependencies: - yallist "^4.0.0" - -minipass@^4.2.4: - version "4.2.8" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.2.8.tgz#f0010f64393ecfc1d1ccb5f582bcaf45f48e1a3a" - integrity sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ== - -minipass@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" - integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== - -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.3, minipass@^7.1.2: - version "7.1.2" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" - integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== - -minizlib@^2.1.1, minizlib@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" - integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" - -mississippi@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" - integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== - dependencies: - concat-stream "^1.5.0" - duplexify "^3.4.2" - end-of-stream "^1.1.0" - flush-write-stream "^1.0.0" - from2 "^2.1.0" - parallel-transform "^1.1.0" - pump "^3.0.0" - pumpify "^1.3.3" - stream-each "^1.1.0" - through2 "^2.0.0" - -mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - -mkdirp@^0.5.1, mkdirp@^0.5.3: - version "0.5.6" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" - integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== - dependencies: - minimist "^1.2.6" - -mkdirp@^1.0.3, mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -mobx@^6.1.7: - version "6.15.0" - resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.15.0.tgz#78b9b82d383724eebb4b6e50c2eb4ae2da861cb5" - integrity sha512-UczzB+0nnwGotYSgllfARAqWCJ5e/skuV2K/l+Zyck/H6pJIhLXuBnz+6vn2i211o7DtbE78HQtsYEKICHGI+g== - -modern-ahocorasick@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/modern-ahocorasick/-/modern-ahocorasick-1.1.0.tgz#9b1fa15d4f654be20a2ad7ecc44ec9d7645bb420" - integrity sha512-sEKPVl2rM+MNVkGQt3ChdmD8YsigmXdn5NifZn6jiwn9LRJpWm8F3guhaqrJT/JOat6pwpbXEk6kv+b9DMIjsQ== - -modify-values@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" - integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== - -move-concurrently@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" - integrity sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ== - dependencies: - aproba "^1.1.1" - copy-concurrently "^1.0.0" - fs-write-stream-atomic "^1.0.8" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.3" - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - -ms@2.1.3, ms@^2.0.0, ms@^2.1.1, ms@^2.1.3, ms@~2.1.3: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -multicast-dns@^7.2.5: - version "7.2.5" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" - integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== - dependencies: - dns-packet "^5.2.2" - thunky "^1.0.2" - -multimatch@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-5.0.0.tgz#932b800963cea7a31a033328fa1e0c3a1874dbe6" - integrity sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA== - dependencies: - "@types/minimatch" "^3.0.3" - array-differ "^3.0.0" - array-union "^2.1.0" - arrify "^2.0.1" - minimatch "^3.0.4" - -mute-stream@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - -mute-stream@^1.0.0, mute-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" - integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== - -nan@^2.12.1, nan@^2.13.2: - version "2.23.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.23.0.tgz#24aa4ddffcc37613a2d2935b97683c1ec96093c6" - integrity sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ== - -nanoclone@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/nanoclone/-/nanoclone-0.2.1.tgz#dd4090f8f1a110d26bb32c49ed2f5b9235209ed4" - integrity sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA== - -nanoid@^3.3.1, nanoid@^3.3.11, nanoid@^3.3.6: - version "3.3.11" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" - integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== - -nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - -napi-postinstall@^0.3.0: - version "0.3.4" - resolved "https://registry.yarnpkg.com/napi-postinstall/-/napi-postinstall-0.3.4.tgz#7af256d6588b5f8e952b9190965d6b019653bbb9" - integrity sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ== - -natural-compare-lite@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" - integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== - -negotiator@0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - -negotiator@^0.6.3, negotiator@~0.6.4: - version "0.6.4" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.4.tgz#777948e2452651c570b712dd01c23e262713fff7" - integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== - -neo-async@^2.5.0, neo-async@^2.6.1, neo-async@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - -nested-error-stacks@^2.0.0, nested-error-stacks@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.1.tgz#26c8a3cee6cc05fbcf1e333cd2fc3e003326c0b5" - integrity sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw== - -next@^14.2.26: - version "14.2.35" - resolved "https://registry.yarnpkg.com/next/-/next-14.2.35.tgz#7c68873a15fe5a19401f2f993fea535be3366ee9" - integrity sha512-KhYd2Hjt/O1/1aZVX3dCwGXM1QmOV4eNM2UTacK5gipDdPN/oHHK/4oVGy7X8GMfPMsUTUEmGlsy0EY1YGAkig== - dependencies: - "@next/env" "14.2.35" - "@swc/helpers" "0.5.5" - busboy "1.6.0" - caniuse-lite "^1.0.30001579" - graceful-fs "^4.2.11" - postcss "8.4.31" - styled-jsx "5.1.1" - optionalDependencies: - "@next/swc-darwin-arm64" "14.2.33" - "@next/swc-darwin-x64" "14.2.33" - "@next/swc-linux-arm64-gnu" "14.2.33" - "@next/swc-linux-arm64-musl" "14.2.33" - "@next/swc-linux-x64-gnu" "14.2.33" - "@next/swc-linux-x64-musl" "14.2.33" - "@next/swc-win32-arm64-msvc" "14.2.33" - "@next/swc-win32-ia32-msvc" "14.2.33" - "@next/swc-win32-x64-msvc" "14.2.33" - -nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - -no-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" - integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== - dependencies: - lower-case "^2.0.2" - tslib "^2.0.3" - -nock@13.5.4: - version "13.5.4" - resolved "https://registry.yarnpkg.com/nock/-/nock-13.5.4.tgz#8918f0addc70a63736170fef7106a9721e0dc479" - integrity sha512-yAyTfdeNJGGBFxWdzSKCBYxs5FxLbCg5X5Q4ets974hcQzG1+qCxvIyOo4j2Ry6MUlhWVMX4OoYDefAIIwupjw== - dependencies: - debug "^4.1.0" - json-stringify-safe "^5.0.1" - propagate "^2.0.0" - -node-abort-controller@^3.0.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.1.1.tgz#a94377e964a9a37ac3976d848cb5c765833b8548" - integrity sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ== - -node-addon-api@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" - integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== - -node-dir@^0.1.10: - version "0.1.17" - resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5" - integrity sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg== - dependencies: - minimatch "^3.0.2" - -node-fetch-native@^1.6.4, node-fetch-native@^1.6.7: - version "1.6.7" - resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.6.7.tgz#9d09ca63066cc48423211ed4caf5d70075d76a71" - integrity sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q== - -node-fetch@2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - -node-fetch@^2.6.1, node-fetch@^2.6.7, node-fetch@^2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" - integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== - dependencies: - whatwg-url "^5.0.0" - -node-forge@^1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.2.tgz#d0d2659a26eef778bf84d73e7f55c08144ee7750" - integrity sha512-6xKiQ+cph9KImrRh0VsjH2d8/GXA4FIMlgU4B757iI1ApvcyA9VlouP0yZJha01V+huImO+kKMU7ih+2+E14fw== - -node-gyp-build@^4.3.0: - version "4.8.4" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.4.tgz#8a70ee85464ae52327772a90d66c6077a900cfc8" - integrity sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ== - -node-gyp@^9.0.0, node-gyp@^9.3.1: - version "9.4.1" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.1.tgz#8a1023e0d6766ecb52764cc3a734b36ff275e185" - integrity sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ== - dependencies: - env-paths "^2.2.0" - exponential-backoff "^3.1.1" - glob "^7.1.4" - graceful-fs "^4.2.6" - make-fetch-happen "^10.0.3" - nopt "^6.0.0" - npmlog "^6.0.0" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.2" - which "^2.0.2" - -node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== - -node-libs-browser@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" - integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== - dependencies: - assert "^1.1.1" - browserify-zlib "^0.2.0" - buffer "^4.3.0" - console-browserify "^1.1.0" - constants-browserify "^1.0.0" - crypto-browserify "^3.11.0" - domain-browser "^1.1.1" - events "^3.0.0" - https-browserify "^1.0.0" - os-browserify "^0.3.0" - path-browserify "0.0.1" - process "^0.11.10" - punycode "^1.2.4" - querystring-es3 "^0.2.0" - readable-stream "^2.3.3" - stream-browserify "^2.0.1" - stream-http "^2.7.2" - string_decoder "^1.0.0" - timers-browserify "^2.0.4" - tty-browserify "0.0.0" - url "^0.11.0" - util "^0.11.0" - vm-browserify "^1.0.1" - -node-machine-id@1.1.12: - version "1.1.12" - resolved "https://registry.yarnpkg.com/node-machine-id/-/node-machine-id-1.1.12.tgz#37904eee1e59b320bb9c5d6c0a59f3b469cb6267" - integrity sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ== - -node-mock-http@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/node-mock-http/-/node-mock-http-1.0.4.tgz#21f2ab4ce2fe4fbe8a660d7c5195a1db85e042a4" - integrity sha512-8DY+kFsDkNXy1sJglUfuODx1/opAGJGyrTuFqEoN90oRc2Vk0ZbD4K2qmKXBBEhZQzdKHIVfEJpDU8Ak2NJEvQ== - -node-releases@^2.0.27: - version "2.0.27" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.27.tgz#eedca519205cf20f650f61d56b070db111231e4e" - integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== - -nopt@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-6.0.0.tgz#245801d8ebf409c6df22ab9d95b65e1309cdb16d" - integrity sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g== - dependencies: - abbrev "^1.0.0" - -normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - -normalize-package-data@^3.0.0, normalize-package-data@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz#dbcc3e2da59509a0983422884cd172eefdfa525e" - integrity sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA== - dependencies: - hosted-git-info "^4.0.1" - is-core-module "^2.5.0" - semver "^7.3.4" - validate-npm-package-license "^3.0.1" - -normalize-package-data@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-5.0.0.tgz#abcb8d7e724c40d88462b84982f7cbf6859b4588" - integrity sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q== - dependencies: - hosted-git-info "^6.0.0" - is-core-module "^2.8.1" - semver "^7.3.5" - validate-npm-package-license "^3.0.4" - -normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w== - dependencies: - remove-trailing-separator "^1.0.1" - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -normalize-range@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" - integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== - -normalize-url@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" - integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== - -notistack@^2.0.3: - version "2.0.8" - resolved "https://registry.yarnpkg.com/notistack/-/notistack-2.0.8.tgz#78cdf34c64e311bf1d1d71c2123396bcdea5e95b" - integrity sha512-/IY14wkFp5qjPgKNvAdfL5Jp6q90+MjgKTPh4c81r/lW70KeuX6b9pE/4f8L4FG31cNudbN9siiFS5ql1aSLRw== - dependencies: - clsx "^1.1.0" - hoist-non-react-statics "^3.3.0" - -npm-bundled@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.2.tgz#944c78789bd739035b70baa2ca5cc32b8d860bc1" - integrity sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ== - dependencies: - npm-normalize-package-bin "^1.0.1" - -npm-bundled@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-3.0.1.tgz#cca73e15560237696254b10170d8f86dad62da25" - integrity sha512-+AvaheE/ww1JEwRHOrn4WHNzOxGtVp+adrg2AeZS/7KuxGUYFuBta98wYpfHBbJp6Tg6j1NKSEVHNcfZzJHQwQ== - dependencies: - npm-normalize-package-bin "^3.0.0" - -npm-install-checks@^6.0.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-6.3.0.tgz#046552d8920e801fa9f919cad569545d60e826fe" - integrity sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw== - dependencies: - semver "^7.1.1" - -npm-normalize-package-bin@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" - integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== - -npm-normalize-package-bin@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz#25447e32a9a7de1f51362c61a559233b89947832" - integrity sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ== - -npm-package-arg@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.1.tgz#00ebf16ac395c63318e67ce66780a06db6df1b04" - integrity sha512-CsP95FhWQDwNqiYS+Q0mZ7FAEDytDZAkNxQqea6IaAFJTAY9Lhhqyl0irU/6PMc7BGfUmnsbHcqxJD7XuVM/rg== - dependencies: - hosted-git-info "^3.0.6" - semver "^7.0.0" - validate-npm-package-name "^3.0.0" - -npm-package-arg@^10.0.0, npm-package-arg@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-10.1.0.tgz#827d1260a683806685d17193073cc152d3c7e9b1" - integrity sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA== - dependencies: - hosted-git-info "^6.0.0" - proc-log "^3.0.0" - semver "^7.3.5" - validate-npm-package-name "^5.0.0" - -npm-packlist@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-5.1.1.tgz#79bcaf22a26b6c30aa4dd66b976d69cc286800e0" - integrity sha512-UfpSvQ5YKwctmodvPPkK6Fwk603aoVsf8AEbmVKAEECrfvL8SSe1A2YIwrJ6xmTHAITKPwwZsWo7WwEbNk0kxw== - dependencies: - glob "^8.0.1" - ignore-walk "^5.0.1" - npm-bundled "^1.1.2" - npm-normalize-package-bin "^1.0.1" - -npm-packlist@^7.0.0: - version "7.0.4" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-7.0.4.tgz#033bf74110eb74daf2910dc75144411999c5ff32" - integrity sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q== - dependencies: - ignore-walk "^6.0.0" - -npm-pick-manifest@^8.0.0: - version "8.0.2" - resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-8.0.2.tgz#2159778d9c7360420c925c1a2287b5a884c713aa" - integrity sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg== - dependencies: - npm-install-checks "^6.0.0" - npm-normalize-package-bin "^3.0.0" - npm-package-arg "^10.0.0" - semver "^7.3.5" - -npm-registry-fetch@^14.0.0, npm-registry-fetch@^14.0.3, npm-registry-fetch@^14.0.5: - version "14.0.5" - resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz#fe7169957ba4986a4853a650278ee02e568d115d" - integrity sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA== - dependencies: - make-fetch-happen "^11.0.0" - minipass "^5.0.0" - minipass-fetch "^3.0.0" - minipass-json-stream "^1.0.1" - minizlib "^2.1.2" - npm-package-arg "^10.0.0" - proc-log "^3.0.0" - -npm-run-all@^4.1.5: - version "4.1.5" - resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" - integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ== - dependencies: - ansi-styles "^3.2.1" - chalk "^2.4.1" - cross-spawn "^6.0.5" - memorystream "^0.3.1" - minimatch "^3.0.4" - pidtree "^0.3.0" - read-pkg "^3.0.0" - shell-quote "^1.6.1" - string.prototype.padend "^3.0.0" - -npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw== - dependencies: - path-key "^2.0.0" - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -npmlog@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0" - integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== - dependencies: - are-we-there-yet "^2.0.0" - console-control-strings "^1.1.0" - gauge "^3.0.0" - set-blocking "^2.0.0" - -npmlog@^6.0.0, npmlog@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" - integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== - dependencies: - are-we-there-yet "^3.0.0" - console-control-strings "^1.1.0" - gauge "^4.0.3" - set-blocking "^2.0.0" - -nth-check@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" - integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== - dependencies: - boolbase "^1.0.0" - -num2fraction@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" - integrity sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg== - -nwsapi@^2.2.0: - version "2.2.22" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.22.tgz#109f9530cda6c156d6a713cdf5939e9f0de98b9d" - integrity sha512-ujSMe1OWVn55euT1ihwCI1ZcAaAU3nxUiDwfDQldc51ZXaB9m2AyOn6/jh1BLe2t/G8xd6uKG1UBF2aZJeg2SQ== - -nx@16.10.0, "nx@>=16.5.1 < 17": - version "16.10.0" - resolved "https://registry.yarnpkg.com/nx/-/nx-16.10.0.tgz#b070461f7de0a3d7988bd78558ea84cda3543ace" - integrity sha512-gZl4iCC0Hx0Qe1VWmO4Bkeul2nttuXdPpfnlcDKSACGu3ZIo+uySqwOF8yBAxSTIf8xe2JRhgzJN1aFkuezEBg== - dependencies: - "@nrwl/tao" "16.10.0" - "@parcel/watcher" "2.0.4" - "@yarnpkg/lockfile" "^1.1.0" - "@yarnpkg/parsers" "3.0.0-rc.46" - "@zkochan/js-yaml" "0.0.6" - axios "^1.0.0" - chalk "^4.1.0" - cli-cursor "3.1.0" - cli-spinners "2.6.1" - cliui "^8.0.1" - dotenv "~16.3.1" - dotenv-expand "~10.0.0" - enquirer "~2.3.6" - figures "3.2.0" - flat "^5.0.2" - fs-extra "^11.1.0" - glob "7.1.4" - ignore "^5.0.4" - jest-diff "^29.4.1" - js-yaml "4.1.0" - jsonc-parser "3.2.0" - lines-and-columns "~2.0.3" - minimatch "3.0.5" - node-machine-id "1.1.12" - npm-run-path "^4.0.1" - open "^8.4.0" - semver "7.5.3" - string-width "^4.2.3" - strong-log-transformer "^2.1.0" - tar-stream "~2.2.0" - tmp "~0.2.1" - tsconfig-paths "^4.1.2" - tslib "^2.3.0" - v8-compile-cache "2.3.0" - yargs "^17.6.2" - yargs-parser "21.1.1" - optionalDependencies: - "@nx/nx-darwin-arm64" "16.10.0" - "@nx/nx-darwin-x64" "16.10.0" - "@nx/nx-freebsd-x64" "16.10.0" - "@nx/nx-linux-arm-gnueabihf" "16.10.0" - "@nx/nx-linux-arm64-gnu" "16.10.0" - "@nx/nx-linux-arm64-musl" "16.10.0" - "@nx/nx-linux-x64-gnu" "16.10.0" - "@nx/nx-linux-x64-musl" "16.10.0" - "@nx/nx-win32-arm64-msvc" "16.10.0" - "@nx/nx-win32-x64-msvc" "16.10.0" - -object-assign@^4.0.1, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - -object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - -object-inspect@^1.13.3, object-inspect@^1.13.4: - version "1.13.4" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213" - integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== - -object-is@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.6.tgz#1a6a53aed2dd8f7e6775ff870bea58545956ab07" - integrity sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== - dependencies: - isobject "^3.0.0" - -object.assign@^4.1.2, object.assign@^4.1.4, object.assign@^4.1.7: - version "4.1.7" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.7.tgz#8c14ca1a424c6a561b0bb2a22f66f5049a945d3d" - integrity sha512-nK28WOo+QIjBkDduTINE4JkF/UJJKyf2EJxvJKfblDpyg0Q+pkOHNTL0Qwy6NP6FhE/EnzV73BxxqcJaXY9anw== - dependencies: - call-bind "^1.0.8" - call-bound "^1.0.3" - define-properties "^1.2.1" - es-object-atoms "^1.0.0" - has-symbols "^1.1.0" - object-keys "^1.1.1" - -object.entries@^1.1.0, object.entries@^1.1.5, object.entries@^1.1.9: - version "1.1.9" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.9.tgz#e4770a6a1444afb61bd39f984018b5bede25f8b3" - integrity sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw== - dependencies: - call-bind "^1.0.8" - call-bound "^1.0.4" - define-properties "^1.2.1" - es-object-atoms "^1.1.1" - -"object.fromentries@^2.0.0 || ^1.0.0", object.fromentries@^2.0.8: - version "2.0.8" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.8.tgz#f7195d8a9b97bd95cbc1999ea939ecd1a2b00c65" - integrity sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-abstract "^1.23.2" - es-object-atoms "^1.0.0" - -object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.8: - version "2.1.8" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.8.tgz#2f1fe0606ec1a7658154ccd4f728504f69667923" - integrity sha512-qkHIGe4q0lSYMv0XI4SsBTJz3WaURhLvd0lKSgtVuOsJ2krg4SgMw3PIRQFMp07yi++UR3se2mkcLqsBNpBb/A== - dependencies: - array.prototype.reduce "^1.0.6" - call-bind "^1.0.7" - define-properties "^1.2.1" - es-abstract "^1.23.2" - es-object-atoms "^1.0.0" - gopd "^1.0.1" - safe-array-concat "^1.1.2" - -object.groupby@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.3.tgz#9b125c36238129f6f7b61954a1e7176148d5002e" - integrity sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-abstract "^1.23.2" - -object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== - dependencies: - isobject "^3.0.1" - -object.values@^1.1.0, object.values@^1.1.6, object.values@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.2.1.tgz#deed520a50809ff7f75a7cfd4bc64c7a038c6216" - integrity sha512-gXah6aZrcUxjWg2zR2MwouP2eHlCBzdV4pygudehaKXSGW4v2AsRQUK+lwwXhii6KFZcunEnmSUoYp5CXibxtA== - dependencies: - call-bind "^1.0.8" - call-bound "^1.0.3" - define-properties "^1.2.1" - es-object-atoms "^1.0.0" - -objectorarray@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/objectorarray/-/objectorarray-1.0.5.tgz#2c05248bbefabd8f43ad13b41085951aac5e68a5" - integrity sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg== - -obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" - integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== - -ofetch@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/ofetch/-/ofetch-1.4.1.tgz#b6bf6b0d75ba616cef6519dd8b6385a8bae480ec" - integrity sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw== - dependencies: - destr "^2.0.3" - node-fetch-native "^1.6.4" - ufo "^1.5.4" - -on-exit-leak-free@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz#b39c9e3bf7690d890f4861558b0d7b90a442d209" - integrity sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg== - -on-finished@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" - integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== - dependencies: - ee-first "1.1.1" - -on-headers@~1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.1.0.tgz#59da4f91c45f5f989c6e4bcedc5a3b0aed70ff65" - integrity sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A== - -once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -onetime@^5.1.0, onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -open@^7.0.3: - version "7.4.2" - resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" - integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== - dependencies: - is-docker "^2.0.0" - is-wsl "^2.1.1" - -open@^8.0.9, open@^8.4.0: - version "8.4.2" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" - integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== - dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" - -openapi-fetch@^0.13.4: - version "0.13.8" - resolved "https://registry.yarnpkg.com/openapi-fetch/-/openapi-fetch-0.13.8.tgz#1769da06e30d19f7568cd0e60db8ca61ea83a2fa" - integrity sha512-yJ4QKRyNxE44baQ9mY5+r/kAzZ8yXMemtNAOFwOzRXJscdjSxxzWSNlyBAr+o5JjkUw9Lc3W7OIoca0cY3PYnQ== - dependencies: - openapi-typescript-helpers "^0.0.15" - -openapi-typescript-helpers@^0.0.15: - version "0.0.15" - resolved "https://registry.yarnpkg.com/openapi-typescript-helpers/-/openapi-typescript-helpers-0.0.15.tgz#96ffa762a5e01ef66a661b163d5f1109ed1967ed" - integrity sha512-opyTPaunsklCBpTK8JGef6mfPhLSnyy5a0IN9vKtx3+4aExf+KxEqYwIy3hqkedXIB97u357uLMJsOnm3GVjsw== - -optionator@^0.9.3: - version "0.9.4" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.4.tgz#7ea1c1a5d91d764fb282139c88fe11e182a3a734" - integrity sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g== - dependencies: - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - word-wrap "^1.2.5" - -ora@^5.4.1: - version "5.4.1" - resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" - integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== - dependencies: - bl "^4.1.0" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-spinners "^2.5.0" - is-interactive "^1.0.0" - is-unicode-supported "^0.1.0" - log-symbols "^4.1.0" - strip-ansi "^6.0.0" - wcwidth "^1.0.1" - -os-browserify@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" - integrity sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A== - -os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ== - -own-keys@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/own-keys/-/own-keys-1.0.1.tgz#e4006910a2bf913585289676eebd6f390cf51358" - integrity sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg== - dependencies: - get-intrinsic "^1.2.6" - object-keys "^1.1.1" - safe-push-apply "^1.0.0" - -p-all@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-all/-/p-all-2.1.0.tgz#91419be56b7dee8fe4c5db875d55e0da084244a0" - integrity sha512-HbZxz5FONzz/z2gJfk6bFca0BCiSRF8jU3yCsWOen/vR6lZjfPOu/e7L3uFzTW1i0H8TlC3vqQstEJPQL4/uLA== - dependencies: - p-map "^2.0.0" - -p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw== - -p-event@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5" - integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ== - dependencies: - p-timeout "^3.1.0" - -p-filter@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-filter/-/p-filter-2.1.0.tgz#1b1472562ae7a0f742f0f3d3d3718ea66ff9c09c" - integrity sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw== - dependencies: - p-map "^2.0.0" - -p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== - -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - -p-limit@^2.0.0, p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2, p-limit@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-limit@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-4.0.0.tgz#914af6544ed32bfa54670b061cafcbd04984b644" - integrity sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ== - dependencies: - yocto-queue "^1.0.0" - -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== - dependencies: - p-limit "^1.1.0" - -p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-locate@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-6.0.0.tgz#3da9a49d4934b901089dca3302fa65dc5a05c04f" - integrity sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw== - dependencies: - p-limit "^4.0.0" - -p-map-series@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-map-series/-/p-map-series-2.1.0.tgz#7560d4c452d9da0c07e692fdbfe6e2c81a2a91f2" - integrity sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q== - -p-map@4.0.0, p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - -p-map@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" - integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== - -p-map@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" - integrity sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ== - dependencies: - aggregate-error "^3.0.0" - -p-pipe@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-pipe/-/p-pipe-3.1.0.tgz#48b57c922aa2e1af6a6404cb7c6bf0eb9cc8e60e" - integrity sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw== - -p-queue@6.6.2: - version "6.6.2" - resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-6.6.2.tgz#2068a9dcf8e67dd0ec3e7a2bcb76810faa85e426" - integrity sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ== - dependencies: - eventemitter3 "^4.0.4" - p-timeout "^3.2.0" - -p-reduce@2.1.0, p-reduce@^2.0.0, p-reduce@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-2.1.0.tgz#09408da49507c6c274faa31f28df334bc712b64a" - integrity sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw== - -p-retry@^4.5.0: - version "4.6.2" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" - integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== - dependencies: - "@types/retry" "0.12.0" - retry "^0.13.1" - -p-timeout@^3.1.0, p-timeout@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" - integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== - dependencies: - p-finally "^1.0.0" - -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -p-waterfall@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/p-waterfall/-/p-waterfall-2.1.1.tgz#63153a774f472ccdc4eb281cdb2967fcf158b2ee" - integrity sha512-RRTnDb2TBG/epPRI2yYXsimO0v3BXC8Yd3ogr1545IaqKK17VGhbWVeGGN+XfCm/08OK8635nH31c8bATkHuSw== - dependencies: - p-reduce "^2.0.0" - -package-json-from-dist@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" - integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== - -pacote@^15.2.0: - version "15.2.0" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-15.2.0.tgz#0f0dfcc3e60c7b39121b2ac612bf8596e95344d3" - integrity sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA== - dependencies: - "@npmcli/git" "^4.0.0" - "@npmcli/installed-package-contents" "^2.0.1" - "@npmcli/promise-spawn" "^6.0.1" - "@npmcli/run-script" "^6.0.0" - cacache "^17.0.0" - fs-minipass "^3.0.0" - minipass "^5.0.0" - npm-package-arg "^10.0.0" - npm-packlist "^7.0.0" - npm-pick-manifest "^8.0.0" - npm-registry-fetch "^14.0.0" - proc-log "^3.0.0" - promise-retry "^2.0.1" - read-package-json "^6.0.0" - read-package-json-fast "^3.0.0" - sigstore "^1.3.0" - ssri "^10.0.0" - tar "^6.1.11" - -pako@^2.0.2: - version "2.1.0" - resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" - integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== - -pako@~1.0.5: - version "1.0.11" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" - integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== - -parallel-transform@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" - integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== - dependencies: - cyclist "^1.0.1" - inherits "^2.0.3" - readable-stream "^2.1.5" - -param-case@^3.0.3, param-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" - integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== - dependencies: - dot-case "^3.0.4" - tslib "^2.0.3" - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-asn1@^5.0.0, parse-asn1@^5.1.9: - version "5.1.9" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.9.tgz#8dd24c3ea8da77dffbc708d94eaf232fd6156e95" - integrity sha512-fIYNuZ/HastSb80baGOuPRo1O9cf4baWw5WsAp7dBuUzeTD/BoaG8sVTdlPFksBE2lF21dN+A1AnrpIjSWqHHg== - dependencies: - asn1.js "^4.10.1" - browserify-aes "^1.2.0" - evp_bytestokey "^1.0.3" - pbkdf2 "^3.1.5" - safe-buffer "^5.2.1" - -parse-author@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/parse-author/-/parse-author-2.0.0.tgz#d3460bf1ddd0dfaeed42da754242e65fb684a81f" - integrity sha512-yx5DfvkN8JsHL2xk2Os9oTia467qnvRgey4ahSm2X8epehBLx/gWLcy5KI+Y36ful5DzGbCS6RazqZGgy1gHNw== - dependencies: - author-regex "^1.0.0" - -parse-entities@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" - integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ== - dependencies: - character-entities "^1.0.0" - character-entities-legacy "^1.0.0" - character-reference-invalid "^1.0.0" - is-alphanumerical "^1.0.0" - is-decimal "^1.0.0" - is-hexadecimal "^1.0.0" - -parse-entities@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-4.0.2.tgz#61d46f5ed28e4ee62e9ddc43d6b010188443f159" - integrity sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw== - dependencies: - "@types/unist" "^2.0.0" - character-entities-legacy "^3.0.0" - character-reference-invalid "^2.0.0" - decode-named-character-reference "^1.0.0" - is-alphanumerical "^2.0.0" - is-decimal "^2.0.0" - is-hexadecimal "^2.0.0" - -parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ== - dependencies: - error-ex "^1.2.0" - -parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw== - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - -parse-json@^5.0.0, parse-json@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -parse-path@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-7.1.0.tgz#41fb513cb122831807a4c7b29c8727947a09d8c6" - integrity sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw== - dependencies: - protocols "^2.0.0" - -parse-url@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-8.1.0.tgz#972e0827ed4b57fc85f0ea6b0d839f0d8a57a57d" - integrity sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w== - dependencies: - parse-path "^7.0.0" - -parse5@6.0.1, parse5@^6.0.0, parse5@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" - integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== - -parse5@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-8.0.0.tgz#aceb267f6b15f9b6e6ba9e35bfdd481fc2167b12" - integrity sha512-9m4m5GSgXjL4AjumKzq1Fgfp3Z8rsvjRNbnkVwfu2ImRqE5D0LnY2QfDen18FSY9C573YU5XxSapdHZTZ2WolA== - dependencies: - entities "^6.0.0" - -parseurl@~1.3.2, parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -pascal-case@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" - integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - -pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== - -path-browserify@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" - integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== - -path-browserify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" - integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== - -path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q== - -path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ== - dependencies: - pinkie-promise "^2.0.0" - -path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-exists@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-5.0.0.tgz#a6aad9489200b21fab31e49cf09277e5116fb9e7" - integrity sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-is-inside@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w== - -path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-scurry@^1.11.1, path-scurry@^1.6.1: - version "1.11.1" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" - integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== - dependencies: - lru-cache "^10.2.0" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - -path-scurry@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-2.0.0.tgz#9f052289f23ad8bf9397a2a0425e7b8615c58580" - integrity sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg== - dependencies: - lru-cache "^11.0.0" - minipass "^7.1.2" - -path-to-regexp@0.1.12: - version "0.1.12" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.12.tgz#d5e1a12e478a976d432ef3c58d534b9923164bb7" - integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ== - -path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg== - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - -path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -pbkdf2@^3.1.2, pbkdf2@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.5.tgz#444a59d7a259a95536c56e80c89de31cc01ed366" - integrity sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ== - dependencies: - create-hash "^1.2.0" - create-hmac "^1.1.7" - ripemd160 "^2.0.3" - safe-buffer "^5.2.1" - sha.js "^2.4.12" - to-buffer "^1.2.1" - -picocolors@1.1.1, picocolors@^1.0.0, picocolors@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.1.tgz#3d321af3eab939b083c8f929a1d12cda81c26b6b" - integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== - -picocolors@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" - integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.0, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -picomatch@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.3.tgz#796c76136d1eead715db1e7bad785dedd695a042" - integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q== - -picomatch@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.4.tgz#fd6f5e00a143086e074dffe4c924b8fb293b0589" - integrity sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A== - -pidtree@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a" - integrity sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA== - -pify@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f" - integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA== - -pify@^2.0.0, pify@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== - -pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== - -pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - -pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== - dependencies: - pinkie "^2.0.0" - -pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== - -pino-abstract-transport@v0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-0.5.0.tgz#4b54348d8f73713bfd14e3dc44228739aa13d9c0" - integrity sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ== - dependencies: - duplexify "^4.1.2" - split2 "^4.0.0" - -pino-std-serializers@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-4.0.0.tgz#1791ccd2539c091ae49ce9993205e2cd5dbba1e2" - integrity sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q== - -pino@7.11.0: - version "7.11.0" - resolved "https://registry.yarnpkg.com/pino/-/pino-7.11.0.tgz#0f0ea5c4683dc91388081d44bff10c83125066f6" - integrity sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg== - dependencies: - atomic-sleep "^1.0.0" - fast-redact "^3.0.0" - on-exit-leak-free "^0.2.0" - pino-abstract-transport v0.5.0 - pino-std-serializers "^4.0.0" - process-warning "^1.0.0" - quick-format-unescaped "^4.0.3" - real-require "^0.1.0" - safe-stable-stringify "^2.1.0" - sonic-boom "^2.2.1" - thread-stream "^0.15.1" - -pirates@^4.0.1, pirates@^4.0.4, pirates@^4.0.6, pirates@^4.0.7: - version "4.0.7" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.7.tgz#643b4a18c4257c8a65104b73f3049ce9a0a15e22" - integrity sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA== - -pkg-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" - integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== - dependencies: - find-up "^3.0.0" - -pkg-dir@^4.1.0, pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -pkg-dir@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" - integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== - dependencies: - find-up "^5.0.0" - -pkg-dir@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-7.0.0.tgz#8f0c08d6df4476756c5ff29b3282d0bab7517d11" - integrity sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA== - dependencies: - find-up "^6.3.0" - -pnp-webpack-plugin@1.6.4: - version "1.6.4" - resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" - integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg== - dependencies: - ts-pnp "^1.1.6" - -polished@^4.2.2: - version "4.3.1" - resolved "https://registry.yarnpkg.com/polished/-/polished-4.3.1.tgz#5a00ae32715609f83d89f6f31d0f0261c6170548" - integrity sha512-OBatVyC/N7SCW/FaDHrSd+vn0o5cS855TOmYi4OkdWUMSJCET/xip//ch8xGUvtr3i44X9LVyWwQlRMTN3pwSA== - dependencies: - "@babel/runtime" "^7.17.8" - -posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== - -possible-typed-array-names@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz#93e3582bc0e5426586d9d07b79ee40fc841de4ae" - integrity sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg== - -postcss-calc@^8.2.3: - version "8.2.4" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.2.4.tgz#77b9c29bfcbe8a07ff6693dc87050828889739a5" - integrity sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q== - dependencies: - postcss-selector-parser "^6.0.9" - postcss-value-parser "^4.2.0" - -postcss-calc@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-9.0.1.tgz#a744fd592438a93d6de0f1434c572670361eb6c6" - integrity sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ== - dependencies: - postcss-selector-parser "^6.0.11" - postcss-value-parser "^4.2.0" - -postcss-colormin@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.3.1.tgz#86c27c26ed6ba00d96c79e08f3ffb418d1d1988f" - integrity sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ== - dependencies: - browserslist "^4.21.4" - caniuse-api "^3.0.0" - colord "^2.9.1" - postcss-value-parser "^4.2.0" - -postcss-colormin@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-6.1.0.tgz#076e8d3fb291fbff7b10e6b063be9da42ff6488d" - integrity sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw== - dependencies: - browserslist "^4.23.0" - caniuse-api "^3.0.0" - colord "^2.9.3" - postcss-value-parser "^4.2.0" - -postcss-convert-values@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz#04998bb9ba6b65aa31035d669a6af342c5f9d393" - integrity sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA== - dependencies: - browserslist "^4.21.4" - postcss-value-parser "^4.2.0" - -postcss-convert-values@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-6.1.0.tgz#3498387f8efedb817cbc63901d45bd1ceaa40f48" - integrity sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w== - dependencies: - browserslist "^4.23.0" - postcss-value-parser "^4.2.0" - -postcss-discard-comments@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz#8df5e81d2925af2780075840c1526f0660e53696" - integrity sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ== - -postcss-discard-comments@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-6.0.2.tgz#e768dcfdc33e0216380623652b0a4f69f4678b6c" - integrity sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw== - -postcss-discard-duplicates@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz#9eb4fe8456706a4eebd6d3b7b777d07bad03e848" - integrity sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw== - -postcss-discard-duplicates@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-6.0.3.tgz#d121e893c38dc58a67277f75bb58ba43fce4c3eb" - integrity sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw== - -postcss-discard-empty@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz#e57762343ff7f503fe53fca553d18d7f0c369c6c" - integrity sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A== - -postcss-discard-empty@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-6.0.3.tgz#ee39c327219bb70473a066f772621f81435a79d9" - integrity sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ== - -postcss-discard-overridden@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz#7e8c5b53325747e9d90131bb88635282fb4a276e" - integrity sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw== - -postcss-discard-overridden@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-6.0.2.tgz#4e9f9c62ecd2df46e8fdb44dc17e189776572e2d" - integrity sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ== - -postcss-flexbugs-fixes@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.2.1.tgz#9218a65249f30897deab1033aced8578562a6690" - integrity sha512-9SiofaZ9CWpQWxOwRh1b/r85KD5y7GgvsNt1056k6OYLvWUun0czCvogfJgylC22uJTwW1KzY3Gz65NZRlvoiQ== - dependencies: - postcss "^7.0.26" - -postcss-loader@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-4.3.0.tgz#2c4de9657cd4f07af5ab42bd60a673004da1b8cc" - integrity sha512-M/dSoIiNDOo8Rk0mUqoj4kpGq91gcxCfb9PoyZVdZ76/AuhxylHDYZblNE8o+EQ9AMSASeMFEKxZf5aU6wlx1Q== - dependencies: - cosmiconfig "^7.0.0" - klona "^2.0.4" - loader-utils "^2.0.0" - schema-utils "^3.0.0" - semver "^7.3.4" - -postcss-merge-longhand@^5.1.7: - version "5.1.7" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz#24a1bdf402d9ef0e70f568f39bdc0344d568fb16" - integrity sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ== - dependencies: - postcss-value-parser "^4.2.0" - stylehacks "^5.1.1" - -postcss-merge-longhand@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-6.0.5.tgz#ba8a8d473617c34a36abbea8dda2b215750a065a" - integrity sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w== - dependencies: - postcss-value-parser "^4.2.0" - stylehacks "^6.1.1" - -postcss-merge-rules@^5.1.4: - version "5.1.4" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz#2f26fa5cacb75b1402e213789f6766ae5e40313c" - integrity sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g== - dependencies: - browserslist "^4.21.4" - caniuse-api "^3.0.0" - cssnano-utils "^3.1.0" - postcss-selector-parser "^6.0.5" - -postcss-merge-rules@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-6.1.1.tgz#7aa539dceddab56019469c0edd7d22b64c3dea9d" - integrity sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ== - dependencies: - browserslist "^4.23.0" - caniuse-api "^3.0.0" - cssnano-utils "^4.0.2" - postcss-selector-parser "^6.0.16" - -postcss-minify-font-values@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz#f1df0014a726083d260d3bd85d7385fb89d1f01b" - integrity sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-minify-font-values@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-6.1.0.tgz#a0e574c02ee3f299be2846369211f3b957ea4c59" - integrity sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-minify-gradients@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz#f1fe1b4f498134a5068240c2f25d46fcd236ba2c" - integrity sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw== - dependencies: - colord "^2.9.1" - cssnano-utils "^3.1.0" - postcss-value-parser "^4.2.0" - -postcss-minify-gradients@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-6.0.3.tgz#ca3eb55a7bdb48a1e187a55c6377be918743dbd6" - integrity sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q== - dependencies: - colord "^2.9.3" - cssnano-utils "^4.0.2" - postcss-value-parser "^4.2.0" - -postcss-minify-params@^5.1.4: - version "5.1.4" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz#c06a6c787128b3208b38c9364cfc40c8aa5d7352" - integrity sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw== - dependencies: - browserslist "^4.21.4" - cssnano-utils "^3.1.0" - postcss-value-parser "^4.2.0" - -postcss-minify-params@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-6.1.0.tgz#54551dec77b9a45a29c3cb5953bf7325a399ba08" - integrity sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA== - dependencies: - browserslist "^4.23.0" - cssnano-utils "^4.0.2" - postcss-value-parser "^4.2.0" - -postcss-minify-selectors@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz#d4e7e6b46147b8117ea9325a915a801d5fe656c6" - integrity sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg== - dependencies: - postcss-selector-parser "^6.0.5" - -postcss-minify-selectors@^6.0.4: - version "6.0.4" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-6.0.4.tgz#197f7d72e6dd19eed47916d575d69dc38b396aff" - integrity sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ== - dependencies: - postcss-selector-parser "^6.0.16" - -postcss-modules-extract-imports@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" - integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== - dependencies: - postcss "^7.0.5" - -postcss-modules-extract-imports@^3.0.0, postcss-modules-extract-imports@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz#b4497cb85a9c0c4b5aabeb759bb25e8d89f15002" - integrity sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q== - -postcss-modules-local-by-default@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz#bb14e0cc78279d504dbdcbfd7e0ca28993ffbbb0" - integrity sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw== - dependencies: - icss-utils "^4.1.1" - postcss "^7.0.32" - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.1.0" - -postcss-modules-local-by-default@^4.0.0, postcss-modules-local-by-default@^4.0.5: - version "4.2.0" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz#d150f43837831dae25e4085596e84f6f5d6ec368" - integrity sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw== - dependencies: - icss-utils "^5.0.0" - postcss-selector-parser "^7.0.0" - postcss-value-parser "^4.1.0" - -postcss-modules-scope@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" - integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== - dependencies: - postcss "^7.0.6" - postcss-selector-parser "^6.0.0" - -postcss-modules-scope@^3.0.0, postcss-modules-scope@^3.2.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz#1bbccddcb398f1d7a511e0a2d1d047718af4078c" - integrity sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA== - dependencies: - postcss-selector-parser "^7.0.0" - -postcss-modules-values@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" - integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg== - dependencies: - icss-utils "^4.0.0" - postcss "^7.0.6" - -postcss-modules-values@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" - integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== - dependencies: - icss-utils "^5.0.0" - -postcss-normalize-charset@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz#9302de0b29094b52c259e9b2cf8dc0879879f0ed" - integrity sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg== - -postcss-normalize-charset@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-6.0.2.tgz#1ec25c435057a8001dac942942a95ffe66f721e1" - integrity sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ== - -postcss-normalize-display-values@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz#72abbae58081960e9edd7200fcf21ab8325c3da8" - integrity sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-display-values@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-6.0.2.tgz#54f02764fed0b288d5363cbb140d6950dbbdd535" - integrity sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-positions@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz#ef97279d894087b59325b45c47f1e863daefbb92" - integrity sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-positions@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-6.0.2.tgz#e982d284ec878b9b819796266f640852dbbb723a" - integrity sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-repeat-style@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz#e9eb96805204f4766df66fd09ed2e13545420fb2" - integrity sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-repeat-style@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-6.0.2.tgz#f8006942fd0617c73f049dd8b6201c3a3040ecf3" - integrity sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-string@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz#411961169e07308c82c1f8c55f3e8a337757e228" - integrity sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-string@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-6.0.2.tgz#e3cc6ad5c95581acd1fc8774b309dd7c06e5e363" - integrity sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-timing-functions@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz#d5614410f8f0b2388e9f240aa6011ba6f52dafbb" - integrity sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-timing-functions@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-6.0.2.tgz#40cb8726cef999de984527cbd9d1db1f3e9062c0" - integrity sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-unicode@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz#f67297fca3fea7f17e0d2caa40769afc487aa030" - integrity sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA== - dependencies: - browserslist "^4.21.4" - postcss-value-parser "^4.2.0" - -postcss-normalize-unicode@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-6.1.0.tgz#aaf8bbd34c306e230777e80f7f12a4b7d27ce06e" - integrity sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg== - dependencies: - browserslist "^4.23.0" - postcss-value-parser "^4.2.0" - -postcss-normalize-url@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz#ed9d88ca82e21abef99f743457d3729a042adcdc" - integrity sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew== - dependencies: - normalize-url "^6.0.1" - postcss-value-parser "^4.2.0" - -postcss-normalize-url@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-6.0.2.tgz#292792386be51a8de9a454cb7b5c58ae22db0f79" - integrity sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-whitespace@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz#08a1a0d1ffa17a7cc6efe1e6c9da969cc4493cfa" - integrity sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-normalize-whitespace@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-6.0.2.tgz#fbb009e6ebd312f8b2efb225c2fcc7cf32b400cd" - integrity sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-ordered-values@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz#b6fd2bd10f937b23d86bc829c69e7732ce76ea38" - integrity sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ== - dependencies: - cssnano-utils "^3.1.0" - postcss-value-parser "^4.2.0" - -postcss-ordered-values@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-6.0.2.tgz#366bb663919707093451ab70c3f99c05672aaae5" - integrity sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q== - dependencies: - cssnano-utils "^4.0.2" - postcss-value-parser "^4.2.0" - -postcss-reduce-initial@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz#798cd77b3e033eae7105c18c9d371d989e1382d6" - integrity sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg== - dependencies: - browserslist "^4.21.4" - caniuse-api "^3.0.0" - -postcss-reduce-initial@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-6.1.0.tgz#4401297d8e35cb6e92c8e9586963e267105586ba" - integrity sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw== - dependencies: - browserslist "^4.23.0" - caniuse-api "^3.0.0" - -postcss-reduce-transforms@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz#333b70e7758b802f3dd0ddfe98bb1ccfef96b6e9" - integrity sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-reduce-transforms@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-6.0.2.tgz#6fa2c586bdc091a7373caeee4be75a0f3e12965d" - integrity sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA== - dependencies: - postcss-value-parser "^4.2.0" - -postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.16, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: - version "6.1.2" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.1.2.tgz#27ecb41fb0e3b6ba7a1ec84fff347f734c7929de" - integrity sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg== - dependencies: - cssesc "^3.0.0" - util-deprecate "^1.0.2" - -postcss-selector-parser@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz#4d6af97eba65d73bc4d84bcb343e865d7dd16262" - integrity sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA== - dependencies: - cssesc "^3.0.0" - util-deprecate "^1.0.2" - -postcss-svgo@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.1.0.tgz#0a317400ced789f233a28826e77523f15857d80d" - integrity sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA== - dependencies: - postcss-value-parser "^4.2.0" - svgo "^2.7.0" - -postcss-svgo@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-6.0.3.tgz#1d6e180d6df1fa8a3b30b729aaa9161e94f04eaa" - integrity sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g== - dependencies: - postcss-value-parser "^4.2.0" - svgo "^3.2.0" - -postcss-unique-selectors@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz#a9f273d1eacd09e9aa6088f4b0507b18b1b541b6" - integrity sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA== - dependencies: - postcss-selector-parser "^6.0.5" - -postcss-unique-selectors@^6.0.4: - version "6.0.4" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-6.0.4.tgz#983ab308896b4bf3f2baaf2336e14e52c11a2088" - integrity sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg== - dependencies: - postcss-selector-parser "^6.0.16" - -postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" - integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== - -postcss@8.4.31: - version "8.4.31" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d" - integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== - dependencies: - nanoid "^3.3.6" - picocolors "^1.0.0" - source-map-js "^1.0.2" - -postcss@^7.0.14, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.36, postcss@^7.0.5, postcss@^7.0.6: - version "7.0.39" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" - integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== - dependencies: - picocolors "^0.2.1" - source-map "^0.6.1" - -postcss@^8.2.15, postcss@^8.3.5, postcss@^8.4.24, postcss@^8.4.33: - version "8.5.6" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.5.6.tgz#2825006615a619b4f62a9e7426cc120b349a8f3c" - integrity sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg== - dependencies: - nanoid "^3.3.11" - picocolors "^1.1.1" - source-map-js "^1.2.1" - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prettier-linter-helpers@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" - integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== - dependencies: - fast-diff "^1.1.2" - -"prettier@>=2.2.1 <=2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.0.tgz#b6a5bf1284026ae640f17f7ff5658a7567fc0d18" - integrity sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w== - -prettier@^2.8.7: - version "2.8.8" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== - -pretty-error@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.2.tgz#be89f82d81b1c86ec8fdfbc385045882727f93b6" - integrity sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw== - dependencies: - lodash "^4.17.20" - renderkid "^2.0.4" - -pretty-error@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6" - integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw== - dependencies: - lodash "^4.17.20" - renderkid "^3.0.0" - -pretty-format@30.3.0: - version "30.3.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-30.3.0.tgz#e977eed4bcd1b6195faed418af8eac68b9ea1f29" - integrity sha512-oG4T3wCbfeuvljnyAzhBvpN45E8iOTXCU/TD3zXW80HA3dQ4ahdqMkWGiPWZvjpQwlbyHrPTWUAqUzGzv4l1JQ== - dependencies: - "@jest/schemas" "30.0.5" - ansi-styles "^5.2.0" - react-is "^18.3.1" - -pretty-format@^27.0.0, pretty-format@^27.0.2, pretty-format@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" - integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== - dependencies: - ansi-regex "^5.0.1" - ansi-styles "^5.0.0" - react-is "^17.0.1" - -pretty-format@^29.0.0, pretty-format@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" - integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== - dependencies: - "@jest/schemas" "^29.6.3" - ansi-styles "^5.0.0" - react-is "^18.0.0" - -pretty-hrtime@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" - integrity sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A== - -proc-log@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-3.0.0.tgz#fb05ef83ccd64fd7b20bbe9c8c1070fc08338dd8" - integrity sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A== - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - -process-warning@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-1.0.0.tgz#980a0b25dc38cd6034181be4b7726d89066b4616" - integrity sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q== - -process@^0.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== - -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== - -promise-retry@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" - integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== - dependencies: - err-code "^2.0.2" - retry "^0.12.0" - -promise.allsettled@^1.0.0: - version "1.0.7" - resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.7.tgz#b9dd51e9cffe496243f5271515652c468865f2d8" - integrity sha512-hezvKvQQmsFkOdrZfYxUxkyxl8mgFQeT259Ajj9PXdbg9VzBCWrItOev72JyWxkCD5VSSqAeHmlN3tWx4DlmsA== - dependencies: - array.prototype.map "^1.0.5" - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - iterate-value "^1.0.2" - -promise.prototype.finally@^3.1.0: - version "3.1.8" - resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-3.1.8.tgz#b97bc1bbca74dc21b6e978c85a70752a7a0b7c3a" - integrity sha512-aVDtsXOml9iuMJzUco9J1je/UrIT3oMYfWkCTiUhkt+AvZw72q4dUZnR/R/eB3h5GeAagQVXvM1ApoYniJiwoA== - dependencies: - call-bind "^1.0.5" - define-properties "^1.2.1" - es-abstract "^1.22.3" - es-errors "^1.0.0" - set-function-name "^2.0.1" - -prompts@^2.0.1, prompts@^2.4.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" - integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== - dependencies: - kleur "^3.0.3" - sisteransi "^1.0.5" - -promzard@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/promzard/-/promzard-1.0.2.tgz#2226e7c6508b1da3471008ae17066a7c3251e660" - integrity sha512-2FPputGL+mP3jJ3UZg/Dl9YOkovB7DX0oOr+ck5QbZ5MtORtds8k/BZdn+02peDLI8/YWbmzx34k5fA+fHvCVQ== - dependencies: - read "^3.0.1" - -prop-types@^15.0.0, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: - version "15.8.1" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" - integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.13.1" - -propagate@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/propagate/-/propagate-2.0.1.tgz#40cdedab18085c792334e64f0ac17256d38f9a45" - integrity sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag== - -property-expr@^2.0.4: - version "2.0.6" - resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.6.tgz#f77bc00d5928a6c748414ad12882e83f24aec1e8" - integrity sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA== - -property-information@^5.0.0, property-information@^5.3.0: - version "5.6.0" - resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.6.0.tgz#61675545fb23002f245c6540ec46077d4da3ed69" - integrity sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA== - dependencies: - xtend "^4.0.0" - -property-information@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/property-information/-/property-information-7.1.0.tgz#b622e8646e02b580205415586b40804d3e8bfd5d" - integrity sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ== - -protobufjs@^6.11.2, protobufjs@^6.8.8: - version "6.11.4" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.4.tgz#29a412c38bf70d89e537b6d02d904a6f448173aa" - integrity sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw== - dependencies: - "@protobufjs/aspromise" "^1.1.2" - "@protobufjs/base64" "^1.1.2" - "@protobufjs/codegen" "^2.0.4" - "@protobufjs/eventemitter" "^1.1.0" - "@protobufjs/fetch" "^1.1.0" - "@protobufjs/float" "^1.0.2" - "@protobufjs/inquire" "^1.1.0" - "@protobufjs/path" "^1.1.2" - "@protobufjs/pool" "^1.1.0" - "@protobufjs/utf8" "^1.1.0" - "@types/long" "^4.0.1" - "@types/node" ">=13.7.0" - long "^4.0.0" - -protocols@^2.0.0, protocols@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/protocols/-/protocols-2.0.2.tgz#822e8fcdcb3df5356538b3e91bfd890b067fd0a4" - integrity sha512-hHVTzba3wboROl0/aWRRG9dMytgH6ow//STBZh43l/wQgmMhYhOFi0EHWAPtoCz9IAUymsyP0TSBHkhgMEGNnQ== - -proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - -proxy-from-env@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" - integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== - -prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== - -psl@^1.1.33: - version "1.15.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.15.0.tgz#bdace31896f1d97cec6a79e8224898ce93d974c6" - integrity sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w== - dependencies: - punycode "^2.3.1" - -public-encrypt@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" - integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== - dependencies: - bn.js "^4.1.0" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - parse-asn1 "^5.0.0" - randombytes "^2.0.1" - safe-buffer "^5.1.2" - -pump@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pump@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.3.tgz#151d979f1a29668dc0025ec589a455b53282268d" - integrity sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - -pumpify@^1.3.3: - version "1.5.1" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" - integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== - dependencies: - duplexify "^3.6.0" - inherits "^2.0.3" - pump "^2.0.0" - -punycode@^1.2.4, punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== - -punycode@^2.1.0, punycode@^2.1.1, punycode@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" - integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== - -pure-rand@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-7.0.1.tgz#6f53a5a9e3e4a47445822af96821ca509ed37566" - integrity sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ== - -qr.js@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/qr.js/-/qr.js-0.0.0.tgz#cace86386f59a0db8050fa90d9b6b0e88a1e364f" - integrity sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ== - -qrcode.react@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/qrcode.react/-/qrcode.react-1.0.1.tgz#2834bb50e5e275ffe5af6906eff15391fe9e38a5" - integrity sha512-8d3Tackk8IRLXTo67Y+c1rpaiXjoz/Dd2HpcMdW//62/x8J1Nbho14Kh8x974t9prsLHN6XqVgcnRiBGFptQmg== - dependencies: - loose-envify "^1.4.0" - prop-types "^15.6.0" - qr.js "0.0.0" - -qrcode.react@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/qrcode.react/-/qrcode.react-4.2.0.tgz#1bce8363f348197d145c0da640929a24c83cbca3" - integrity sha512-QpgqWi8rD9DsS9EP3z7BT+5lY5SFhsqGjpgW5DY/i3mK4M9DTBNz3ErMi8BWYEfI3L0d8GIbGmcdFAS1uIRGjA== - -qs@6.13.0: - version "6.13.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" - integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== - dependencies: - side-channel "^1.0.6" - -qs@^6.10.0, qs@^6.12.3, qs@^6.14.0: - version "6.14.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.14.0.tgz#c63fa40680d2c5c941412a0e899c89af60c0a930" - integrity sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w== - dependencies: - side-channel "^1.1.0" - -querystring-es3@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" - integrity sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA== - -querystringify@^2.1.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" - integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -quick-format-unescaped@^4.0.3: - version "4.0.4" - resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7" - integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== - -quick-lru@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" - integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== - -radix3@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/radix3/-/radix3-1.1.2.tgz#fd27d2af3896c6bf4bcdfab6427c69c2afc69ec0" - integrity sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA== - -rainbow-sprinkles@^0.17.3: - version "0.17.3" - resolved "https://registry.yarnpkg.com/rainbow-sprinkles/-/rainbow-sprinkles-0.17.3.tgz#0b4a712a6b06247728e2ae6ac8d4805fdc530e3b" - integrity sha512-tu00bbDozceDz/ajL8YzDn5L0mf0uVHR93v2tfGKKbemKeuPk8R4mXUokleKsA24vzrPiw26iMK53HdRy6HLag== - -ramda@^0.26.1: - version "0.26.1" - resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06" - integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ== - -ramda@^0.28.0: - version "0.28.0" - resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.28.0.tgz#acd785690100337e8b063cab3470019be427cc97" - integrity sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA== - -randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -randomfill@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" - integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== - dependencies: - randombytes "^2.0.5" - safe-buffer "^5.1.0" - -range-parser@^1.2.1, range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -raw-body@2.5.2: - version "2.5.2" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" - integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - -raw-loader@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.2.tgz#1aac6b7d1ad1501e66efdac1522c73e59a584eb6" - integrity sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA== - dependencies: - loader-utils "^2.0.0" - schema-utils "^3.0.0" - -react-aria@^3.34.3: - version "3.44.0" - resolved "https://registry.yarnpkg.com/react-aria/-/react-aria-3.44.0.tgz#6b694c704c0d438feb1baad23ab32cc7e8edb68f" - integrity sha512-2Pq3GQxBgM4/2BlpKYXeaZ47a3tdIcYSW/AYvKgypE3XipxOdQMDG5Sr/NBn7zuJq+thzmtfRb0lB9bTbsmaRw== - dependencies: - "@internationalized/string" "^3.2.7" - "@react-aria/breadcrumbs" "^3.5.29" - "@react-aria/button" "^3.14.2" - "@react-aria/calendar" "^3.9.2" - "@react-aria/checkbox" "^3.16.2" - "@react-aria/color" "^3.1.2" - "@react-aria/combobox" "^3.14.0" - "@react-aria/datepicker" "^3.15.2" - "@react-aria/dialog" "^3.5.31" - "@react-aria/disclosure" "^3.1.0" - "@react-aria/dnd" "^3.11.3" - "@react-aria/focus" "^3.21.2" - "@react-aria/gridlist" "^3.14.1" - "@react-aria/i18n" "^3.12.13" - "@react-aria/interactions" "^3.25.6" - "@react-aria/label" "^3.7.22" - "@react-aria/landmark" "^3.0.7" - "@react-aria/link" "^3.8.6" - "@react-aria/listbox" "^3.15.0" - "@react-aria/menu" "^3.19.3" - "@react-aria/meter" "^3.4.27" - "@react-aria/numberfield" "^3.12.2" - "@react-aria/overlays" "^3.30.0" - "@react-aria/progress" "^3.4.27" - "@react-aria/radio" "^3.12.2" - "@react-aria/searchfield" "^3.8.9" - "@react-aria/select" "^3.17.0" - "@react-aria/selection" "^3.26.0" - "@react-aria/separator" "^3.4.13" - "@react-aria/slider" "^3.8.2" - "@react-aria/ssr" "^3.9.10" - "@react-aria/switch" "^3.7.8" - "@react-aria/table" "^3.17.8" - "@react-aria/tabs" "^3.10.8" - "@react-aria/tag" "^3.7.2" - "@react-aria/textfield" "^3.18.2" - "@react-aria/toast" "^3.0.8" - "@react-aria/tooltip" "^3.8.8" - "@react-aria/tree" "^3.1.4" - "@react-aria/utils" "^3.31.0" - "@react-aria/visually-hidden" "^3.8.28" - "@react-types/shared" "^3.32.1" - -react-docgen-typescript@^2.1.1: - version "2.4.0" - resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-2.4.0.tgz#033428b4a6a639d050ac8baf2a5195c596521713" - integrity sha512-ZtAp5XTO5HRzQctjPU0ybY0RRCQO19X/8fxn3w7y2VVTUbGHDKULPTL4ky3vB05euSgG5NpALhEhDPvQ56wvXg== - -react-docgen@^5.0.0: - version "5.4.3" - resolved "https://registry.yarnpkg.com/react-docgen/-/react-docgen-5.4.3.tgz#7d297f73b977d0c7611402e5fc2a168acf332b26" - integrity sha512-xlLJyOlnfr8lLEEeaDZ+X2J/KJoe6Nr9AzxnkdQWush5hz2ZSu66w6iLMOScMmxoSHWpWMn+k3v5ZiyCfcWsOA== - dependencies: - "@babel/core" "^7.7.5" - "@babel/generator" "^7.12.11" - "@babel/runtime" "^7.7.6" - ast-types "^0.14.2" - commander "^2.19.0" - doctrine "^3.0.0" - estree-to-babel "^3.1.0" - neo-async "^2.6.1" - node-dir "^0.1.10" - strip-indent "^3.0.0" - -react-dom@^18.0.0: - version "18.3.1" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" - integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== - dependencies: - loose-envify "^1.1.0" - scheduler "^0.23.2" - -react-dom@^19.2.0: - version "19.2.5" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.2.5.tgz#b8768b10837d0b8e9ca5b9e2d58dff3d880ea25e" - integrity sha512-J5bAZz+DXMMwW/wV3xzKke59Af6CHY7G4uYLN1OvBcKEsWOs4pQExj86BBKamxl/Ik5bx9whOrvBlSDfWzgSag== - dependencies: - scheduler "^0.27.0" - -react-element-to-jsx-string@^14.3.4: - version "14.3.4" - resolved "https://registry.yarnpkg.com/react-element-to-jsx-string/-/react-element-to-jsx-string-14.3.4.tgz#709125bc72f06800b68f9f4db485f2c7d31218a8" - integrity sha512-t4ZwvV6vwNxzujDQ+37bspnLwA4JlgUPWhLjBJWsNIDceAf6ZKUTCjdm08cN6WeZ5pTMKiCJkmAYnpmR4Bm+dg== - dependencies: - "@base2/pretty-print-object" "1.0.1" - is-plain-object "5.0.0" - react-is "17.0.2" - -react-error-boundary@^3.1.3: - version "3.1.4" - resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.4.tgz#255db92b23197108757a888b01e5b729919abde0" - integrity sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA== - dependencies: - "@babel/runtime" "^7.12.5" - -react-hook-form@^7.14.2: - version "7.65.0" - resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.65.0.tgz#6139dac77ed1081d0178b6830dc6f5ff6ff86361" - integrity sha512-xtOzDz063WcXvGWaHgLNrNzlsdFgtUWcb32E6WFaGTd7kPZG3EeDusjdZfUsPwKCKVXy1ZlntifaHZ4l8pAsmw== - -react-i18next@^15.4.0: - version "15.7.4" - resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-15.7.4.tgz#146e50f220d204b842e22c75d1a3d23c6c589a30" - integrity sha512-nyU8iKNrI5uDJch0z9+Y5XEr34b0wkyYj3Rp+tfbahxtlswxSCjcUL9H0nqXo9IR3/t5Y5PKIA3fx3MfUyR9Xw== - dependencies: - "@babel/runtime" "^7.27.6" - html-parse-stringify "^3.0.1" - -react-inspector@^5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-5.1.1.tgz#58476c78fde05d5055646ed8ec02030af42953c8" - integrity sha512-GURDaYzoLbW8pMGXwYPDBIv6nqei4kK7LPRZ9q9HCZF54wqXz/dnylBp/kfE9XmekBhHvLDdcYeyIwSrvtOiWg== - dependencies: - "@babel/runtime" "^7.0.0" - is-dom "^1.0.0" - prop-types "^15.0.0" - -react-is@17.0.2, react-is@^17.0.1: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" - integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== - -react-is@^16.13.1, react-is@^16.7.0: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - -react-is@^18.0.0, react-is@^18.3.1: - version "18.3.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" - integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== - -react-is@^19.0.0, react-is@^19.1.1: - version "19.2.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-19.2.0.tgz#ddc3b4a4e0f3336c3847f18b806506388d7b9973" - integrity sha512-x3Ax3kNSMIIkyVYhWPyO09bu0uttcAIoecO/um/rKGQ4EltYWVYtyiGkS/3xMynrbVQdS69Jhlv8FXUEZehlzA== - -react-markdown@^9.0.3: - version "9.1.0" - resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-9.1.0.tgz#606bd74c6af131ba382a7c1282ff506708ed2e26" - integrity sha512-xaijuJB0kzGiUdG7nc2MOMDUDBWPyGAjZtUrow9XxUeua8IqeP+VlIfAZ3bphpcLTnSZXz6z9jcVC/TCwbfgdw== - dependencies: - "@types/hast" "^3.0.0" - "@types/mdast" "^4.0.0" - devlop "^1.0.0" - hast-util-to-jsx-runtime "^2.0.0" - html-url-attributes "^3.0.0" - mdast-util-to-hast "^13.0.0" - remark-parse "^11.0.0" - remark-rehype "^11.0.0" - unified "^11.0.0" - unist-util-visit "^5.0.0" - vfile "^6.0.0" - -react-merge-refs@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/react-merge-refs/-/react-merge-refs-1.1.0.tgz#73d88b892c6c68cbb7a66e0800faa374f4c38b06" - integrity sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ== - -react-random-avatars@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/react-random-avatars/-/react-random-avatars-1.3.1.tgz#cfea11dd80262939656e4134438fa76eb2d95371" - integrity sha512-HyMGoWniK2D5CRthoA1he4c6LVFIX/yBjp4qarEXN/DsgJ+1R6M5gJwYhTBoATO+3itrGCAGnKZNqimG1sDjAA== - -react-refresh-typescript@^2.0.2: - version "2.0.11" - resolved "https://registry.yarnpkg.com/react-refresh-typescript/-/react-refresh-typescript-2.0.11.tgz#85496b9b9e52d26f90aa226f81cd7bb6288af6b3" - integrity sha512-u6afET6t6NDNcxD67wSVlgazX/CiRuC7qSqALZueMckjmPQnOBajmwibJr2TTU6MtttDNPjBhD8K3AB8i0opJg== - -react-refresh@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.10.0.tgz#2f536c9660c0b9b1d500684d9e52a65e7404f7e3" - integrity sha512-PgidR3wST3dDYKr6b4pJoqQFpPGNKDSCDx4cZoshjXipw3LzO7mG1My2pwEzz2JVkF+inx3xRpDeQLFQGH/hsQ== - -react-refresh@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046" - integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A== - -react-router-dom@6: - version "6.30.1" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.30.1.tgz#da2580c272ddb61325e435478566be9563a4a237" - integrity sha512-llKsgOkZdbPU1Eg3zK8lCn+sjD9wMRZZPuzmdWWX5SUs8OFkN5HnFVC0u5KMeMaC9aoancFI/KoLuKPqN+hxHw== - dependencies: - "@remix-run/router" "1.23.0" - react-router "6.30.1" - -react-router@6.30.1: - version "6.30.1" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.30.1.tgz#ecb3b883c9ba6dbf5d319ddbc996747f4ab9f4c3" - integrity sha512-X1m21aEmxGXqENEPG3T6u0Th7g0aS4ZmoNynhbs+Cn+q+QGTLt+d5IQ2bHAXKzKcxGJjxACpVbnYQSCRcfxHlQ== - dependencies: - "@remix-run/router" "1.23.0" - -react-smooth@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-4.0.4.tgz#a5875f8bb61963ca61b819cedc569dc2453894b4" - integrity sha512-gnGKTpYwqL0Iii09gHobNolvX4Kiq4PKx6eWBCYYix+8cdw+cGo3do906l1NBPKkSWx1DghC1dlWG9L2uGd61Q== - dependencies: - fast-equals "^5.0.1" - prop-types "^15.8.1" - react-transition-group "^4.4.5" - -react-stately@^3.32.2: - version "3.42.0" - resolved "https://registry.yarnpkg.com/react-stately/-/react-stately-3.42.0.tgz#f309e9cb729374cc187c688529a2aa0572ab9408" - integrity sha512-lYt2o1dd6dK8Bb4GRh08RG/2u64bSA1cqtRqtw4jEMgxC7Q17RFcIumBbChErndSdLzafEG/UBwV6shOfig6yw== - dependencies: - "@react-stately/calendar" "^3.9.0" - "@react-stately/checkbox" "^3.7.2" - "@react-stately/collections" "^3.12.8" - "@react-stately/color" "^3.9.2" - "@react-stately/combobox" "^3.12.0" - "@react-stately/data" "^3.14.1" - "@react-stately/datepicker" "^3.15.2" - "@react-stately/disclosure" "^3.0.8" - "@react-stately/dnd" "^3.7.1" - "@react-stately/form" "^3.2.2" - "@react-stately/list" "^3.13.1" - "@react-stately/menu" "^3.9.8" - "@react-stately/numberfield" "^3.10.2" - "@react-stately/overlays" "^3.6.20" - "@react-stately/radio" "^3.11.2" - "@react-stately/searchfield" "^3.5.16" - "@react-stately/select" "^3.8.0" - "@react-stately/selection" "^3.20.6" - "@react-stately/slider" "^3.7.2" - "@react-stately/table" "^3.15.1" - "@react-stately/tabs" "^3.8.6" - "@react-stately/toast" "^3.1.2" - "@react-stately/toggle" "^3.9.2" - "@react-stately/tooltip" "^3.5.8" - "@react-stately/tree" "^3.9.3" - "@react-types/shared" "^3.32.1" - -react-transition-group@^4.4.5: - version "4.4.5" - resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1" - integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g== - dependencies: - "@babel/runtime" "^7.5.5" - dom-helpers "^5.0.1" - loose-envify "^1.4.0" - prop-types "^15.6.2" - -react-world-flags@^1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/react-world-flags/-/react-world-flags-1.6.0.tgz#7b075aa9be8a1b3789451a9df2cf491294e6fbae" - integrity sha512-eutSeAy5YKoVh14js/JUCSlA6EBk1n4k+bDaV+NkNB50VhnG+f4QDTpYycnTUTsZ5cqw/saPmk0Z4Fa0VVZ1Iw== - dependencies: - svg-country-flags "^1.2.10" - svgo "^3.0.2" - world-countries "^5.0.0" - -react@^18.0.0: - version "18.3.1" - resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" - integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== - dependencies: - loose-envify "^1.1.0" - -react@^19.2.0: - version "19.2.5" - resolved "https://registry.yarnpkg.com/react/-/react-19.2.5.tgz#c888ab8b8ef33e2597fae8bdb2d77edbdb42858b" - integrity sha512-llUJLzz1zTUBrskt2pwZgLq59AemifIftw4aB7JxOqf1HY2FDaGDxgwpAPVzHU1kdWabH7FauP4i1oEeer2WCA== - -read-cmd-shim@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz#640a08b473a49043e394ae0c7a34dd822c73b9bb" - integrity sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q== - -read-package-json-fast@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz#394908a9725dc7a5f14e70c8e7556dff1d2b1049" - integrity sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw== - dependencies: - json-parse-even-better-errors "^3.0.0" - npm-normalize-package-bin "^3.0.0" - -read-package-json@6.0.4, read-package-json@^6.0.0: - version "6.0.4" - resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-6.0.4.tgz#90318824ec456c287437ea79595f4c2854708836" - integrity sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw== - dependencies: - glob "^10.2.2" - json-parse-even-better-errors "^3.0.0" - normalize-package-data "^5.0.0" - npm-normalize-package-bin "^3.0.0" - -read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - integrity sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A== - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - -read-pkg-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" - integrity sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw== - dependencies: - find-up "^2.0.0" - read-pkg "^3.0.0" - -read-pkg-up@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" - integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== - dependencies: - find-up "^4.1.0" - read-pkg "^5.2.0" - type-fest "^0.8.1" - -read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ== - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - -read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA== - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - -read-pkg@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" - integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== - dependencies: - "@types/normalize-package-data" "^2.4.0" - normalize-package-data "^2.5.0" - parse-json "^5.0.0" - type-fest "^0.6.0" - -read@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/read/-/read-2.1.0.tgz#69409372c54fe3381092bc363a00650b6ac37218" - integrity sha512-bvxi1QLJHcaywCAEsAk4DG3nVoqiY2Csps3qzWalhj5hFqRn1d/OixkFXtLO1PrgHUcAP0FNaSY/5GYNfENFFQ== - dependencies: - mute-stream "~1.0.0" - -read@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/read/-/read-3.0.1.tgz#926808f0f7c83fa95f1ef33c0e2c09dbb28fd192" - integrity sha512-SLBrDU/Srs/9EoWhU5GdbAoxG1GzpQHo/6qiGItaoLJ1thmYpcNIM1qISEUvyHBzfGlWIyd6p2DNi1oV1VmAuw== - dependencies: - mute-stream "^1.0.0" - -"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@^2.3.8, readable-stream@~2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" - integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" - integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== - dependencies: - graceful-fs "^4.1.11" - micromatch "^3.1.10" - readable-stream "^2.0.2" - -readdirp@^4.0.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.1.2.tgz#eb85801435fbf2a7ee58f19e0921b068fc69948d" - integrity sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg== - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -readonly-date@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/readonly-date/-/readonly-date-1.0.0.tgz#5af785464d8c7d7c40b9d738cbde8c646f97dcd9" - integrity sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ== - -real-require@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.1.0.tgz#736ac214caa20632847b7ca8c1056a0767df9381" - integrity sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg== - -recharts-scale@^0.4.4: - version "0.4.5" - resolved "https://registry.yarnpkg.com/recharts-scale/-/recharts-scale-0.4.5.tgz#0969271f14e732e642fcc5bd4ab270d6e87dd1d9" - integrity sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w== - dependencies: - decimal.js-light "^2.4.1" - -recharts@^2.1.13: - version "2.15.4" - resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.15.4.tgz#0ed3e66c0843bcf2d9f9a172caf97b1d05127a5f" - integrity sha512-UT/q6fwS3c1dHbXv2uFgYJ9BMFHu3fwnd7AYZaEQhXuYQ4hgsxLvsUXzGdKeZrW5xopzDCvuA2N41WJ88I7zIw== - dependencies: - clsx "^2.0.0" - eventemitter3 "^4.0.1" - lodash "^4.17.21" - react-is "^18.3.1" - react-smooth "^4.0.4" - recharts-scale "^0.4.4" - tiny-invariant "^1.3.1" - victory-vendor "^36.6.8" - -rechoir@^0.7.0: - version "0.7.1" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" - integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== - dependencies: - resolve "^1.9.0" - -rechoir@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22" - integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ== - dependencies: - resolve "^1.20.0" - -redent@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" - integrity sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g== - dependencies: - indent-string "^2.1.0" - strip-indent "^1.0.1" - -redent@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" - integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== - dependencies: - indent-string "^4.0.0" - strip-indent "^3.0.0" - -reflect.getprototypeof@^1.0.6, reflect.getprototypeof@^1.0.9: - version "1.0.10" - resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz#c629219e78a3316d8b604c765ef68996964e7bf9" - integrity sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw== - dependencies: - call-bind "^1.0.8" - define-properties "^1.2.1" - es-abstract "^1.23.9" - es-errors "^1.3.0" - es-object-atoms "^1.0.0" - get-intrinsic "^1.2.7" - get-proto "^1.0.1" - which-builtin-type "^1.2.1" - -regenerate-unicode-properties@^10.2.2: - version "10.2.2" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.2.tgz#aa113812ba899b630658c7623466be71e1f86f66" - integrity sha512-m03P+zhBeQd1RGnYxrGyDAPpWX/epKirLrp8e3qevZdVkKtnCrjjWczIbYc8+xd6vcTStVlqfycTx1KR4LOr0g== - dependencies: - regenerate "^1.4.2" - -regenerate@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" - integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== - -regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.7: - version "0.13.11" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" - integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== - -regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - -regexp.prototype.flags@^1.5.1, regexp.prototype.flags@^1.5.3, regexp.prototype.flags@^1.5.4: - version "1.5.4" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.4.tgz#1ad6c62d44a259007e55b3970e00f746efbcaa19" - integrity sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA== - dependencies: - call-bind "^1.0.8" - define-properties "^1.2.1" - es-errors "^1.3.0" - get-proto "^1.0.1" - gopd "^1.2.0" - set-function-name "^2.0.2" - -regexpu-core@^6.3.1: - version "6.4.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-6.4.0.tgz#3580ce0c4faedef599eccb146612436b62a176e5" - integrity sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA== - dependencies: - regenerate "^1.4.2" - regenerate-unicode-properties "^10.2.2" - regjsgen "^0.8.0" - regjsparser "^0.13.0" - unicode-match-property-ecmascript "^2.0.0" - unicode-match-property-value-ecmascript "^2.2.1" - -regjsgen@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.8.0.tgz#df23ff26e0c5b300a6470cad160a9d090c3a37ab" - integrity sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q== - -regjsparser@^0.13.0: - version "0.13.0" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.13.0.tgz#01f8351335cf7898d43686bc74d2dd71c847ecc0" - integrity sha512-NZQZdC5wOE/H3UT28fVGL+ikOZcEzfMGk/c3iN9UGxzWHMa1op7274oyiUVrAG4B2EuFhus8SvkaYnhvW92p9Q== - dependencies: - jsesc "~3.1.0" - -relateurl@^0.2.7: - version "0.2.7" - resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" - integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== - -remark-external-links@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/remark-external-links/-/remark-external-links-8.0.0.tgz#308de69482958b5d1cd3692bc9b725ce0240f345" - integrity sha512-5vPSX0kHoSsqtdftSHhIYofVINC8qmp0nctkeU9YoJwV3YfiBRiI6cbFRJ0oI/1F9xS+bopXG0m2KS8VFscuKA== - dependencies: - extend "^3.0.0" - is-absolute-url "^3.0.0" - mdast-util-definitions "^4.0.0" - space-separated-tokens "^1.0.0" - unist-util-visit "^2.0.0" - -remark-footnotes@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/remark-footnotes/-/remark-footnotes-2.0.0.tgz#9001c4c2ffebba55695d2dd80ffb8b82f7e6303f" - integrity sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ== - -remark-mdx@1.6.22: - version "1.6.22" - resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-1.6.22.tgz#06a8dab07dcfdd57f3373af7f86bd0e992108bbd" - integrity sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ== - dependencies: - "@babel/core" "7.12.9" - "@babel/helper-plugin-utils" "7.10.4" - "@babel/plugin-proposal-object-rest-spread" "7.12.1" - "@babel/plugin-syntax-jsx" "7.12.1" - "@mdx-js/util" "1.6.22" - is-alphabetical "1.0.4" - remark-parse "8.0.3" - unified "9.2.0" - -remark-parse@8.0.3: - version "8.0.3" - resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-8.0.3.tgz#9c62aa3b35b79a486454c690472906075f40c7e1" - integrity sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q== - dependencies: - ccount "^1.0.0" - collapse-white-space "^1.0.2" - is-alphabetical "^1.0.0" - is-decimal "^1.0.0" - is-whitespace-character "^1.0.0" - is-word-character "^1.0.0" - markdown-escapes "^1.0.0" - parse-entities "^2.0.0" - repeat-string "^1.5.4" - state-toggle "^1.0.0" - trim "0.0.1" - trim-trailing-lines "^1.0.0" - unherit "^1.0.4" - unist-util-remove-position "^2.0.0" - vfile-location "^3.0.0" - xtend "^4.0.1" - -remark-parse@^11.0.0: - version "11.0.0" - resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-11.0.0.tgz#aa60743fcb37ebf6b069204eb4da304e40db45a1" - integrity sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA== - dependencies: - "@types/mdast" "^4.0.0" - mdast-util-from-markdown "^2.0.0" - micromark-util-types "^2.0.0" - unified "^11.0.0" - -remark-rehype@^11.0.0: - version "11.1.2" - resolved "https://registry.yarnpkg.com/remark-rehype/-/remark-rehype-11.1.2.tgz#2addaadda80ca9bd9aa0da763e74d16327683b37" - integrity sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw== - dependencies: - "@types/hast" "^3.0.0" - "@types/mdast" "^4.0.0" - mdast-util-to-hast "^13.0.0" - unified "^11.0.0" - vfile "^6.0.0" - -remark-slug@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/remark-slug/-/remark-slug-6.1.0.tgz#0503268d5f0c4ecb1f33315c00465ccdd97923ce" - integrity sha512-oGCxDF9deA8phWvxFuyr3oSJsdyUAxMFbA0mZ7Y1Sas+emILtO+e5WutF9564gDsEN4IXaQXm5pFo6MLH+YmwQ== - dependencies: - github-slugger "^1.0.0" - mdast-util-to-string "^1.0.0" - unist-util-visit "^2.0.0" - -remark-squeeze-paragraphs@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz#76eb0e085295131c84748c8e43810159c5653ead" - integrity sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw== - dependencies: - mdast-squeeze-paragraphs "^4.0.0" - -remove-accents@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/remove-accents/-/remove-accents-0.5.0.tgz#77991f37ba212afba162e375b627631315bed687" - integrity sha512-8g3/Otx1eJaVD12e31UbJj1YzdtVvzH85HV7t+9MJYk/u3XmkOUJ5Ys9wQrf9PCPK8+xn4ymzqYCiZl6QWKn+A== - -remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw== - -renderkid@^2.0.4: - version "2.0.7" - resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.7.tgz#464f276a6bdcee606f4a15993f9b29fc74ca8609" - integrity sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ== - dependencies: - css-select "^4.1.3" - dom-converter "^0.2.0" - htmlparser2 "^6.1.0" - lodash "^4.17.21" - strip-ansi "^3.0.1" - -renderkid@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-3.0.0.tgz#5fd823e4d6951d37358ecc9a58b1f06836b6268a" - integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg== - dependencies: - css-select "^4.1.3" - dom-converter "^0.2.0" - htmlparser2 "^6.1.0" - lodash "^4.17.21" - strip-ansi "^6.0.1" - -repeat-element@^1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" - integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== - -repeat-string@^1.5.4, repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== - -repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - integrity sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A== - dependencies: - is-finite "^1.0.0" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== - -require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - -requireindex@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/requireindex/-/requireindex-1.2.0.tgz#3463cdb22ee151902635aa6c9535d4de9c2ef1ef" - integrity sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww== - -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== - -resolve-cwd@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" - integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== - dependencies: - resolve-from "^5.0.0" - -resolve-from@5.0.0, resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve-pkg-maps@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" - integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== - -resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== - -resolve.exports@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.1.tgz#05cfd5b3edf641571fd46fa608b610dda9ead999" - integrity sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ== - -resolve@^1.10.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.10, resolve@^1.22.4, resolve@^1.3.2, resolve@^1.9.0: - version "1.22.11" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.11.tgz#aad857ce1ffb8bfa9b0b1ac29f1156383f68c262" - integrity sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ== - dependencies: - is-core-module "^2.16.1" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -resolve@^2.0.0-next.5: - version "2.0.0-next.5" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c" - integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== - dependencies: - is-core-module "^2.13.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - -ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== - -retry@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" - integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== - -reusify@^1.0.4: - version "1.1.0" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.1.0.tgz#0fe13b9522e1473f51b558ee796e08f11f9b489f" - integrity sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw== - -rgb-hex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/rgb-hex/-/rgb-hex-3.0.0.tgz#eab0168cc1279563b18a14605315389142e2e487" - integrity sha512-8h7ZcwxCBDKvchSWbWngJuSCqJGQ6nDuLLg+QcRyQDbX9jMWt+PpPeXAhSla0GOooEomk3lCprUpGkMdsLjKyg== - -rimraf@^2.5.4, rimraf@^2.6.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - -rimraf@^3.0.0, rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -rimraf@^4.4.1: - version "4.4.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-4.4.1.tgz#bd33364f67021c5b79e93d7f4fa0568c7c21b755" - integrity sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og== - dependencies: - glob "^9.2.0" - -ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.3.tgz#9be54e4ba5e3559c8eee06a25cd7648bbccdf5a8" - integrity sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA== - dependencies: - hash-base "^3.1.2" - inherits "^2.0.4" - -robust-predicates@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/robust-predicates/-/robust-predicates-3.0.2.tgz#d5b28528c4824d20fc48df1928d41d9efa1ad771" - integrity sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg== - -rrweb-cssom@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz#3021d1b4352fbf3b614aaeed0bc0d5739abe0bc2" - integrity sha512-guoltQEx+9aMf2gDZ0s62EcV8lsXR+0w8915TC3ITdn2YueuNjdAYh/levpU9nFaoChh9RUS5ZdQMrKfVEN9tw== - -rsvp@^4.8.4: - version "4.8.5" - resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" - integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== - -run-async@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -run-queue@^1.0.0, run-queue@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" - integrity sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg== - dependencies: - aproba "^1.1.1" - -rxjs@^7.5.5: - version "7.8.2" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.2.tgz#955bc473ed8af11a002a2be52071bf475638607b" - integrity sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA== - dependencies: - tslib "^2.1.0" - -safe-array-concat@^1.1.2, safe-array-concat@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.3.tgz#c9e54ec4f603b0bbb8e7e5007a5ee7aecd1538c3" - integrity sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q== - dependencies: - call-bind "^1.0.8" - call-bound "^1.0.2" - get-intrinsic "^1.2.6" - has-symbols "^1.1.0" - isarray "^2.0.5" - -safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.1, safe-buffer@~5.2.0, safe-buffer@~5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -safe-push-apply@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/safe-push-apply/-/safe-push-apply-1.0.0.tgz#01850e981c1602d398c85081f360e4e6d03d27f5" - integrity sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA== - dependencies: - es-errors "^1.3.0" - isarray "^2.0.5" - -safe-regex-test@^1.0.3, safe-regex-test@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.1.0.tgz#7f87dfb67a3150782eaaf18583ff5d1711ac10c1" - integrity sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw== - dependencies: - call-bound "^1.0.2" - es-errors "^1.3.0" - is-regex "^1.2.1" - -safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== - dependencies: - ret "~0.1.10" - -safe-stable-stringify@^2.1.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz#4ca2f8e385f2831c432a719b108a3bf7af42a1dd" - integrity sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA== - -"safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -sane@^4.0.3: - version "4.1.0" - resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" - integrity sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA== - dependencies: - "@cnakazawa/watch" "^1.0.3" - anymatch "^2.0.0" - capture-exit "^2.0.0" - exec-sh "^0.3.2" - execa "^1.0.0" - fb-watchman "^2.0.0" - micromatch "^3.1.4" - minimist "^1.1.1" - walker "~1.0.5" - -sax@>=0.6.0: - version "1.4.1" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.4.1.tgz#44cc8988377f126304d3b3fc1010c733b929ef0f" - integrity sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg== - -saxes@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" - integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== - dependencies: - xmlchars "^2.2.0" - -saxes@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/saxes/-/saxes-6.0.0.tgz#fe5b4a4768df4f14a201b1ba6a65c1f3d9988cc5" - integrity sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA== - dependencies: - xmlchars "^2.2.0" - -scheduler@^0.23.2: - version "0.23.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" - integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== - dependencies: - loose-envify "^1.1.0" - -scheduler@^0.27.0: - version "0.27.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.27.0.tgz#0c4ef82d67d1e5c1e359e8fc76d3a87f045fe5bd" - integrity sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q== - -schema-utils@2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" - integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== - dependencies: - "@types/json-schema" "^7.0.4" - ajv "^6.12.2" - ajv-keywords "^3.4.1" - -schema-utils@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" - integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== - dependencies: - ajv "^6.1.0" - ajv-errors "^1.0.0" - ajv-keywords "^3.1.0" - -schema-utils@^2.6.5, schema-utils@^2.7.0: - version "2.7.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" - integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== - dependencies: - "@types/json-schema" "^7.0.5" - ajv "^6.12.4" - ajv-keywords "^3.5.2" - -schema-utils@^3.0.0, schema-utils@^3.1.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" - integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - -schema-utils@^4.0.0, schema-utils@^4.0.1, schema-utils@^4.2.0, schema-utils@^4.3.0, schema-utils@^4.3.3: - version "4.3.3" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.3.tgz#5b1850912fa31df90716963d45d9121fdfc09f46" - integrity sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA== - dependencies: - "@types/json-schema" "^7.0.9" - ajv "^8.9.0" - ajv-formats "^2.1.1" - ajv-keywords "^5.1.0" - -select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" - integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== - -selfsigned@^2.1.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0" - integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q== - dependencies: - "@types/node-forge" "^1.3.0" - node-forge "^1" - -"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: - version "5.7.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - -semver@7.5.3: - version "7.5.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" - integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== - dependencies: - lru-cache "^6.0.0" - -semver@7.x, semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.0, semver@^7.5.3, semver@^7.5.4, semver@^7.6.3, semver@^7.7.1: - version "7.7.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.3.tgz#4b5f4143d007633a8dc671cd0a6ef9147b8bb946" - integrity sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q== - -semver@^6.0.0, semver@^6.1.2, semver@^6.3.0, semver@^6.3.1: - version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^7.7.2, semver@^7.7.3, semver@^7.7.4: - version "7.7.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.4.tgz#28464e36060e991fa7a11d0279d2d3f3b57a7e8a" - integrity sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA== - -send@0.19.0: - version "0.19.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.19.0.tgz#bbc5a388c8ea6c048967049dbeac0e4a3f09d7f8" - integrity sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw== - dependencies: - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "2.0.0" - mime "1.6.0" - ms "2.1.3" - on-finished "2.4.1" - range-parser "~1.2.1" - statuses "2.0.1" - -serialize-javascript@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" - integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== - dependencies: - randombytes "^2.1.0" - -serialize-javascript@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" - integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== - dependencies: - randombytes "^2.1.0" - -serialize-javascript@^6.0.0, serialize-javascript@^6.0.1, serialize-javascript@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.2.tgz#defa1e055c83bf6d59ea805d8da862254eb6a6c2" - integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== - dependencies: - randombytes "^2.1.0" - -serve-favicon@^2.5.0: - version "2.5.1" - resolved "https://registry.yarnpkg.com/serve-favicon/-/serve-favicon-2.5.1.tgz#b6482e81801707d5ed40fa547066e7e44fee47cc" - integrity sha512-JndLBslCLA/ebr7rS3d+/EKkzTsTi1jI2T9l+vHfAaGJ7A7NhtDpSZ0lx81HCNWnnE0yHncG+SSnVf9IMxOwXQ== - dependencies: - etag "~1.8.1" - fresh "~0.5.2" - ms "~2.1.3" - parseurl "~1.3.2" - safe-buffer "~5.2.1" - -serve-index@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" - integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== - dependencies: - accepts "~1.3.4" - batch "0.6.1" - debug "2.6.9" - escape-html "~1.0.3" - http-errors "~1.6.2" - mime-types "~2.1.17" - parseurl "~1.3.2" - -serve-static@1.16.2: - version "1.16.2" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.16.2.tgz#b6a5343da47f6bdd2673848bf45754941e803296" - integrity sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw== - dependencies: - encodeurl "~2.0.0" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.19.0" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== - -set-function-length@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449" - integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg== - dependencies: - define-data-property "^1.1.4" - es-errors "^1.3.0" - function-bind "^1.1.2" - get-intrinsic "^1.2.4" - gopd "^1.0.1" - has-property-descriptors "^1.0.2" - -set-function-name@^2.0.1, set-function-name@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.2.tgz#16a705c5a0dc2f5e638ca96d8a8cd4e1c2b90985" - integrity sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ== - dependencies: - define-data-property "^1.1.4" - es-errors "^1.3.0" - functions-have-names "^1.2.3" - has-property-descriptors "^1.0.2" - -set-proto@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/set-proto/-/set-proto-1.0.0.tgz#0760dbcff30b2d7e801fd6e19983e56da337565e" - integrity sha512-RJRdvCo6IAnPdsvP/7m6bsQqNnn1FCBX5ZNtFL98MmFF/4xAIJTIg1YbHW5DC2W5SKZanrC6i4HsJqlajw/dZw== - dependencies: - dunder-proto "^1.0.1" - es-errors "^1.3.0" - es-object-atoms "^1.0.0" - -set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - -setimmediate@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== - -setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -sha.js@^2.4.0, sha.js@^2.4.11, sha.js@^2.4.12, sha.js@^2.4.8: - version "2.4.12" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.12.tgz#eb8b568bf383dfd1867a32c3f2b74eb52bdbf23f" - integrity sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w== - dependencies: - inherits "^2.0.4" - safe-buffer "^5.2.1" - to-buffer "^1.2.0" - -shallow-clone@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" - integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== - dependencies: - kind-of "^6.0.2" - -sharp@^0.33.1: - version "0.33.5" - resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.33.5.tgz#13e0e4130cc309d6a9497596715240b2ec0c594e" - integrity sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw== - dependencies: - color "^4.2.3" - detect-libc "^2.0.3" - semver "^7.6.3" - optionalDependencies: - "@img/sharp-darwin-arm64" "0.33.5" - "@img/sharp-darwin-x64" "0.33.5" - "@img/sharp-libvips-darwin-arm64" "1.0.4" - "@img/sharp-libvips-darwin-x64" "1.0.4" - "@img/sharp-libvips-linux-arm" "1.0.5" - "@img/sharp-libvips-linux-arm64" "1.0.4" - "@img/sharp-libvips-linux-s390x" "1.0.4" - "@img/sharp-libvips-linux-x64" "1.0.4" - "@img/sharp-libvips-linuxmusl-arm64" "1.0.4" - "@img/sharp-libvips-linuxmusl-x64" "1.0.4" - "@img/sharp-linux-arm" "0.33.5" - "@img/sharp-linux-arm64" "0.33.5" - "@img/sharp-linux-s390x" "0.33.5" - "@img/sharp-linux-x64" "0.33.5" - "@img/sharp-linuxmusl-arm64" "0.33.5" - "@img/sharp-linuxmusl-x64" "0.33.5" - "@img/sharp-wasm32" "0.33.5" - "@img/sharp-win32-ia32" "0.33.5" - "@img/sharp-win32-x64" "0.33.5" - -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== - dependencies: - shebang-regex "^1.0.0" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -shell-quote@^1.6.1, shell-quote@^1.8.3: - version "1.8.3" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.3.tgz#55e40ef33cf5c689902353a3d8cd1a6725f08b4b" - integrity sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw== - -side-channel-list@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/side-channel-list/-/side-channel-list-1.0.0.tgz#10cb5984263115d3b7a0e336591e290a830af8ad" - integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== - dependencies: - es-errors "^1.3.0" - object-inspect "^1.13.3" - -side-channel-map@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/side-channel-map/-/side-channel-map-1.0.1.tgz#d6bb6b37902c6fef5174e5f533fab4c732a26f42" - integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA== - dependencies: - call-bound "^1.0.2" - es-errors "^1.3.0" - get-intrinsic "^1.2.5" - object-inspect "^1.13.3" - -side-channel-weakmap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz#11dda19d5368e40ce9ec2bdc1fb0ecbc0790ecea" - integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A== - dependencies: - call-bound "^1.0.2" - es-errors "^1.3.0" - get-intrinsic "^1.2.5" - object-inspect "^1.13.3" - side-channel-map "^1.0.1" - -side-channel@^1.0.4, side-channel@^1.0.6, side-channel@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.1.0.tgz#c3fcff9c4da932784873335ec9765fa94ff66bc9" - integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== - dependencies: - es-errors "^1.3.0" - object-inspect "^1.13.3" - side-channel-list "^1.0.0" - side-channel-map "^1.0.1" - side-channel-weakmap "^1.0.2" - -signal-exit@3.0.7, signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -signal-exit@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" - integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== - -sigstore@^1.3.0, sigstore@^1.4.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/sigstore/-/sigstore-1.9.0.tgz#1e7ad8933aa99b75c6898ddd0eeebc3eb0d59875" - integrity sha512-0Zjz0oe37d08VeOtBIuB6cRriqXse2e8w+7yIy2XSXjshRKxbc2KkhXjL229jXSxEm7UbcjS76wcJDGQddVI9A== - dependencies: - "@sigstore/bundle" "^1.1.0" - "@sigstore/protobuf-specs" "^0.2.0" - "@sigstore/sign" "^1.0.0" - "@sigstore/tuf" "^1.0.3" - make-fetch-happen "^11.0.1" - -simple-swizzle@^0.2.2: - version "0.2.4" - resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.4.tgz#a8d11a45a11600d6a1ecdff6363329e3648c3667" - integrity sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw== - dependencies: - is-arrayish "^0.3.1" - -sisteransi@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" - integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== - -slash@3.0.0, slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - integrity sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg== - -slash@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" - integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== - -slash@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" - integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== - -smart-buffer@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" - integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== - -snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - -snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - -snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - -sockjs@^0.3.24: - version "0.3.24" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" - integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== - dependencies: - faye-websocket "^0.11.3" - uuid "^8.3.2" - websocket-driver "^0.7.4" - -socks-proxy-agent@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz#dc069ecf34436621acb41e3efa66ca1b5fed15b6" - integrity sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww== - dependencies: - agent-base "^6.0.2" - debug "^4.3.3" - socks "^2.6.2" - -socks@^2.6.2: - version "2.8.7" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.8.7.tgz#e2fb1d9a603add75050a2067db8c381a0b5669ea" - integrity sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A== - dependencies: - ip-address "^10.0.1" - smart-buffer "^4.2.0" - -sonic-boom@^2.2.1: - version "2.8.0" - resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-2.8.0.tgz#c1def62a77425090e6ad7516aad8eb402e047611" - integrity sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg== - dependencies: - atomic-sleep "^1.0.0" - -sort-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" - integrity sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg== - dependencies: - is-plain-obj "^1.0.0" - -source-list-map@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" - integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== - -source-map-js@^1.0.1, source-map-js@^1.0.2, source-map-js@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" - integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== - -source-map-resolve@^0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" - integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - -source-map-support@0.5.13: - version "0.5.13" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" - integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-support@^0.5.16, source-map-support@^0.5.21, source-map-support@^0.5.6, source-map-support@~0.5.12, source-map-support@~0.5.20: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map-url@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" - integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== - -source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== - -source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -source-map@^0.7.3, source-map@^0.7.4: - version "0.7.6" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.6.tgz#a3658ab87e5b6429c8a1f3ba0083d4c61ca3ef02" - integrity sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ== - -space-separated-tokens@^1.0.0: - version "1.1.5" - resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" - integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== - -space-separated-tokens@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz#1ecd9d2350a3844572c3f4a312bceb018348859f" - integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q== - -spdx-correct@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" - integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - -spdx-exceptions@^2.1.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz#5d607d27fc806f66d7b64a766650fa890f04ed66" - integrity sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w== - -spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - -spdx-license-ids@^3.0.0: - version "3.0.22" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz#abf5a08a6f5d7279559b669f47f0a43e8f3464ef" - integrity sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ== - -spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" - integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - -spdy@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" - integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - -split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - -split2@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f" - integrity sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg== - dependencies: - readable-stream "^3.0.0" - -split2@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" - integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== - -split@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" - integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== - dependencies: - through "2" - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== - -ssri@^10.0.0, ssri@^10.0.1: - version "10.0.6" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-10.0.6.tgz#a8aade2de60ba2bce8688e3fa349bad05c7dc1e5" - integrity sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ== - dependencies: - minipass "^7.0.3" - -ssri@^6.0.1: - version "6.0.2" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5" - integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q== - dependencies: - figgy-pudding "^3.5.1" - -ssri@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" - integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== - dependencies: - minipass "^3.1.1" - -ssri@^9.0.0, ssri@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-9.0.1.tgz#544d4c357a8d7b71a19700074b6883fcb4eae057" - integrity sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q== - dependencies: - minipass "^3.1.1" - -stable-hash@^0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/stable-hash/-/stable-hash-0.0.5.tgz#94e8837aaeac5b4d0f631d2972adef2924b40269" - integrity sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA== - -stable@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" - integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== - -stack-utils@^2.0.3, stack-utils@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" - integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== - dependencies: - escape-string-regexp "^2.0.0" - -stackframe@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310" - integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== - -state-toggle@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" - integrity sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ== - -static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - -"statuses@>= 1.4.0 < 2": - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== - -stop-iteration-iterator@^1.0.0, stop-iteration-iterator@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.1.0.tgz#f481ff70a548f6124d0312c3aa14cbfa7aa542ad" - integrity sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ== - dependencies: - es-errors "^1.3.0" - internal-slot "^1.1.0" - -store2@^2.12.0: - version "2.14.4" - resolved "https://registry.yarnpkg.com/store2/-/store2-2.14.4.tgz#81b313abaddade4dcd7570c5cc0e3264a8f7a242" - integrity sha512-srTItn1GOvyvOycgxjAnPA63FZNwy0PTyUBFMHRM+hVFltAeoh0LmNBz9SZqUS9mMqGk8rfyWyXn3GH5ReJ8Zw== - -stream-browserify@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" - integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== - dependencies: - inherits "~2.0.1" - readable-stream "^2.0.2" - -stream-each@^1.1.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" - integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== - dependencies: - end-of-stream "^1.1.0" - stream-shift "^1.0.0" - -stream-http@^2.7.2: - version "2.8.3" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" - integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== - dependencies: - builtin-status-codes "^3.0.0" - inherits "^2.0.1" - readable-stream "^2.3.6" - to-arraybuffer "^1.0.0" - xtend "^4.0.0" - -stream-shift@^1.0.0, stream-shift@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.3.tgz#85b8fab4d71010fc3ba8772e8046cc49b8a3864b" - integrity sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ== - -streamsearch@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" - integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== - -string-length@^4.0.1, string-length@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" - integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== - dependencies: - char-regex "^1.0.2" - strip-ansi "^6.0.0" - -string-to-color@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/string-to-color/-/string-to-color-2.2.2.tgz#46210bf7777dc9198dcdf997bd18ae6749cc9a73" - integrity sha512-XeA2goP7PNsSlz8RRn6KhYswnMf5Tl+38ajfy8n4oZJyMGC4qqKgHNHsZ/3qwvr42NRIjf9eSr721SyetDeMkA== - dependencies: - colornames "^1.1.1" - hex-rgb "^4.1.0" - lodash.padend "^4.6.1" - lodash.trimstart "^4.5.1" - lodash.words "^4.2.0" - rgb-hex "^3.0.0" - -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string-width@^5.0.1, string-width@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== - dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" - -string.prototype.includes@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/string.prototype.includes/-/string.prototype.includes-2.0.1.tgz#eceef21283640761a81dbe16d6c7171a4edf7d92" - integrity sha512-o7+c9bW6zpAdJHTtujeePODAhkuicdAryFsfVKwA+wGw89wJ4GTY484WTucM9hLtDEOpOvI+aHnzqnC5lHp4Rg== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-abstract "^1.23.3" - -"string.prototype.matchall@^4.0.0 || ^3.0.1", string.prototype.matchall@^4.0.12: - version "4.0.12" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz#6c88740e49ad4956b1332a911e949583a275d4c0" - integrity sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA== - dependencies: - call-bind "^1.0.8" - call-bound "^1.0.3" - define-properties "^1.2.1" - es-abstract "^1.23.6" - es-errors "^1.3.0" - es-object-atoms "^1.0.0" - get-intrinsic "^1.2.6" - gopd "^1.2.0" - has-symbols "^1.1.0" - internal-slot "^1.1.0" - regexp.prototype.flags "^1.5.3" - set-function-name "^2.0.2" - side-channel "^1.1.0" - -string.prototype.padend@^3.0.0: - version "3.1.6" - resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.6.tgz#ba79cf8992609a91c872daa47c6bb144ee7f62a5" - integrity sha512-XZpspuSB7vJWhvJc9DLSlrXl1mcA2BdoY5jjnS135ydXqLoqhs96JjDtCkjJEQHvfqZIp9hBuBMgI589peyx9Q== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-abstract "^1.23.2" - es-object-atoms "^1.0.0" - -string.prototype.padstart@^3.0.0: - version "3.1.7" - resolved "https://registry.yarnpkg.com/string.prototype.padstart/-/string.prototype.padstart-3.1.7.tgz#529bae9f07186fb0fc6e0709b7f9b1f942aa09d1" - integrity sha512-hc5ZFzw8H2Bl4AeHxE5s+CniFg+bPcr7lRRS189GCM6KhJQBACNRhtMsdcnpBNbjc1XisnUOqbP0c94RZU4GCw== - dependencies: - call-bind "^1.0.8" - call-bound "^1.0.4" - define-properties "^1.2.1" - es-abstract "^1.23.9" - es-object-atoms "^1.1.1" - -string.prototype.repeat@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz#e90872ee0308b29435aa26275f6e1b762daee01a" - integrity sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - -string.prototype.trim@^1.2.10: - version "1.2.10" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz#40b2dd5ee94c959b4dcfb1d65ce72e90da480c81" - integrity sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA== - dependencies: - call-bind "^1.0.8" - call-bound "^1.0.2" - define-data-property "^1.1.4" - define-properties "^1.2.1" - es-abstract "^1.23.5" - es-object-atoms "^1.0.0" - has-property-descriptors "^1.0.2" - -string.prototype.trimend@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz#62e2731272cd285041b36596054e9f66569b6942" - integrity sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ== - dependencies: - call-bind "^1.0.8" - call-bound "^1.0.2" - define-properties "^1.2.1" - es-object-atoms "^1.0.0" - -string.prototype.trimstart@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz#7ee834dda8c7c17eff3118472bb35bfedaa34dde" - integrity sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg== - dependencies: - call-bind "^1.0.7" - define-properties "^1.2.1" - es-object-atoms "^1.0.0" - -string_decoder@^1.0.0, string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -stringify-entities@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-4.0.4.tgz#b3b79ef5f277cc4ac73caeb0236c5ba939b3a4f3" - integrity sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg== - dependencies: - character-entities-html4 "^2.0.0" - character-entities-legacy "^3.0.0" - -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== - dependencies: - ansi-regex "^2.0.0" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-ansi@^7.0.1: - version "7.1.2" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.2.tgz#132875abde678c7ea8d691533f2e7e22bb744dba" - integrity sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA== - dependencies: - ansi-regex "^6.0.1" - -strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g== - dependencies: - is-utf8 "^0.2.0" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - -strip-bom@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" - integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== - -strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q== - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -strip-indent@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" - integrity sha512-I5iQq6aFMM62fBEAIB/hXzwJD6EEZ0xEGCX2t7oXqaKPIRgt4WruAQ285BISgdkP+HLGWyeGmNJcpIwFeRYRUA== - dependencies: - get-stdin "^4.0.1" - -strip-indent@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" - integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== - dependencies: - min-indent "^1.0.0" - -strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -strong-log-transformer@2.1.0, strong-log-transformer@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz#0f5ed78d325e0421ac6f90f7f10e691d6ae3ae10" - integrity sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA== - dependencies: - duplexer "^0.1.1" - minimist "^1.2.0" - through "^2.3.4" - -style-loader@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.3.0.tgz#828b4a3b3b7e7aa5847ce7bae9e874512114249e" - integrity sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q== - dependencies: - loader-utils "^2.0.0" - schema-utils "^2.7.0" - -style-loader@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-2.0.0.tgz#9669602fd4690740eaaec137799a03addbbc393c" - integrity sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ== - dependencies: - loader-utils "^2.0.0" - schema-utils "^3.0.0" - -style-loader@^3.3.1, style-loader@^3.3.3: - version "3.3.4" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.4.tgz#f30f786c36db03a45cbd55b6a70d930c479090e7" - integrity sha512-0WqXzrsMTyb8yjZJHDqwmnwRJvhALK9LfRtRc6B4UTWe8AijYLZYZ9thuJTZc2VfQWINADW/j+LiJnfy2RoC1w== - -style-to-js@^1.0.0: - version "1.1.18" - resolved "https://registry.yarnpkg.com/style-to-js/-/style-to-js-1.1.18.tgz#3e6c13bd4c4db079bd2c2c94571cce5c758bc2ff" - integrity sha512-JFPn62D4kJaPTnhFUI244MThx+FEGbi+9dw1b9yBBQ+1CZpV7QAT8kUtJ7b7EUNdHajjF/0x8fT+16oLJoojLg== - dependencies: - style-to-object "1.0.11" - -style-to-object@0.3.0, style-to-object@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.3.0.tgz#b1b790d205991cc783801967214979ee19a76e46" - integrity sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA== - dependencies: - inline-style-parser "0.1.1" - -style-to-object@1.0.11: - version "1.0.11" - resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-1.0.11.tgz#cf252c4051758b7acb18a5efb296f91fb79bb9c4" - integrity sha512-5A560JmXr7wDyGLK12Nq/EYS38VkGlglVzkis1JEdbGWSnbQIEhZzTJhzURXN5/8WwwFCs/f/VVcmkTppbXLow== - dependencies: - inline-style-parser "0.2.4" - -styled-jsx@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.1.1.tgz#839a1c3aaacc4e735fed0781b8619ea5d0009d1f" - integrity sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw== - dependencies: - client-only "0.0.1" - -stylehacks@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.1.tgz#7934a34eb59d7152149fa69d6e9e56f2fc34bcc9" - integrity sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw== - dependencies: - browserslist "^4.21.4" - postcss-selector-parser "^6.0.4" - -stylehacks@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-6.1.1.tgz#543f91c10d17d00a440430362d419f79c25545a6" - integrity sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg== - dependencies: - browserslist "^4.23.0" - postcss-selector-parser "^6.0.16" - -stylis@4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" - integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== - -supports-color@^5.3.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.0.0, supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-color@^8.0.0, supports-color@^8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-hyperlinks@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz#3943544347c1ff90b15effb03fc14ae45ec10624" - integrity sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA== - dependencies: - has-flag "^4.0.0" - supports-color "^7.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -svg-country-flags@^1.2.10: - version "1.2.10" - resolved "https://registry.yarnpkg.com/svg-country-flags/-/svg-country-flags-1.2.10.tgz#b1b94e9f08f065d7b3d0ff9ab359898edd4dd3b0" - integrity sha512-xrqwo0TYf/h2cfPvGpjdSuSguUbri4vNNizBnwzoZnX0xGo3O5nGJMlbYEp7NOYcnPGBm6LE2axqDWSB847bLw== - -svg-parser@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" - integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== - -svgo@^2.7.0, svgo@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" - integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== - dependencies: - "@trysound/sax" "0.2.0" - commander "^7.2.0" - css-select "^4.1.3" - css-tree "^1.1.3" - csso "^4.2.0" - picocolors "^1.0.0" - stable "^0.1.8" - -svgo@^3.0.2, svgo@^3.2.0: - version "3.3.2" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-3.3.2.tgz#ad58002652dffbb5986fc9716afe52d869ecbda8" - integrity sha512-OoohrmuUlBs8B8o6MB2Aevn+pRIH9zDALSR+6hhqVfa6fRwG/Qw9VUMSMW9VNg2CFc/MTIfabtdOVl9ODIJjpw== - dependencies: - "@trysound/sax" "0.2.0" - commander "^7.2.0" - css-select "^5.1.0" - css-tree "^2.3.1" - css-what "^6.1.0" - csso "^5.0.5" - picocolors "^1.0.0" - -symbol-observable@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-2.0.3.tgz#5b521d3d07a43c351055fa43b8355b62d33fd16a" - integrity sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA== - -symbol-tree@^3.2.4: - version "3.2.4" - resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" - integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== - -symbol.prototype.description@^1.0.0: - version "1.0.7" - resolved "https://registry.yarnpkg.com/symbol.prototype.description/-/symbol.prototype.description-1.0.7.tgz#853f38d743a835ad2af64c8b0ce332bd50d0b122" - integrity sha512-HHGLabwmDRorfrwBGt3dD6iakQ1gNxbNK1jRb3rvr8XVsHmbAzaMdZGJtzL2W8IXdwfm3GEdw27qG86CWpuqOQ== - dependencies: - call-bind "^1.0.8" - es-errors "^1.3.0" - es-object-atoms "^1.0.0" - get-symbol-description "^1.0.2" - gopd "^1.2.0" - has-symbols "^1.1.0" - object.getownpropertydescriptors "^2.1.8" - -synchronous-promise@^2.0.15: - version "2.0.17" - resolved "https://registry.yarnpkg.com/synchronous-promise/-/synchronous-promise-2.0.17.tgz#38901319632f946c982152586f2caf8ddc25c032" - integrity sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g== - -synckit@^0.11.8: - version "0.11.12" - resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.11.12.tgz#abe74124264fbc00a48011b0d98bdc1cffb64a7b" - integrity sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ== - dependencies: - "@pkgr/core" "^0.2.9" - -tabbable@^6.0.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.3.0.tgz#2e0e6163935387cdeacd44e9334616ca0115a8d3" - integrity sha512-EIHvdY5bPLuWForiR/AN2Bxngzpuwn1is4asboytXtpTgsArc+WmSJKVLlhdh71u7jFcryDqB2A8lQvj78MkyQ== - -tapable@^1.0.0, tapable@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" - integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== - -tapable@^2.0.0, tapable@^2.2.1, tapable@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6" - integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== - -tar-stream@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" - integrity sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ== - dependencies: - bl "^4.0.3" - end-of-stream "^1.4.1" - fs-constants "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.1.1" - -tar@6.1.11: - version "6.1.11" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" - integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^3.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - -tar@^6.0.2, tar@^6.1.11, tar@^6.1.2: - version "6.2.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" - integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^5.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - -telejson@^6.0.8: - version "6.0.8" - resolved "https://registry.yarnpkg.com/telejson/-/telejson-6.0.8.tgz#1c432db7e7a9212c1fbd941c3e5174ec385148f7" - integrity sha512-nerNXi+j8NK1QEfBHtZUN/aLdDcyupA//9kAboYLrtzZlPLpUfqbVGWb9zz91f/mIjRbAYhbgtnJHY8I1b5MBg== - dependencies: - "@types/is-function" "^1.0.0" - global "^4.4.0" - is-function "^1.0.2" - is-regex "^1.1.2" - is-symbol "^1.0.3" - isobject "^4.0.0" - lodash "^4.17.21" - memoizerific "^1.11.3" - -temp-dir@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" - integrity sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ== - -terminal-link@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" - integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== - dependencies: - ansi-escapes "^4.2.1" - supports-hyperlinks "^2.0.0" - -terser-webpack-plugin@^1.4.3: - version "1.4.6" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.6.tgz#87fcb6593fd1c977cd09e56143ecd31404600755" - integrity sha512-2lBVf/VMVIddjSn3GqbT90GvIJ/eYXJkt8cTzU7NbjKqK8fwv18Ftr4PlbF46b/e88743iZFL5Dtr/rC4hjIeA== - dependencies: - cacache "^12.0.2" - find-cache-dir "^2.1.0" - is-wsl "^1.1.0" - schema-utils "^1.0.0" - serialize-javascript "^4.0.0" - source-map "^0.6.1" - terser "^4.1.2" - webpack-sources "^1.4.0" - worker-farm "^1.7.0" - -terser-webpack-plugin@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz#28daef4a83bd17c1db0297070adc07fc8cfc6a9a" - integrity sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ== - dependencies: - cacache "^15.0.5" - find-cache-dir "^3.3.1" - jest-worker "^26.5.0" - p-limit "^3.0.2" - schema-utils "^3.0.0" - serialize-javascript "^5.0.1" - source-map "^0.6.1" - terser "^5.3.4" - webpack-sources "^1.4.3" - -terser-webpack-plugin@^5.0.3, terser-webpack-plugin@^5.3.16: - version "5.3.16" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz#741e448cc3f93d8026ebe4f7ef9e4afacfd56330" - integrity sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q== - dependencies: - "@jridgewell/trace-mapping" "^0.3.25" - jest-worker "^27.4.5" - schema-utils "^4.3.0" - serialize-javascript "^6.0.2" - terser "^5.31.1" - -terser@^4.1.2, terser@^4.6.3: - version "4.8.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.1.tgz#a00e5634562de2239fd404c649051bf6fc21144f" - integrity sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw== - dependencies: - commander "^2.20.0" - source-map "~0.6.1" - source-map-support "~0.5.12" - -terser@^5.10.0, terser@^5.3.4, terser@^5.31.1: - version "5.44.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.44.0.tgz#ebefb8e5b8579d93111bfdfc39d2cf63879f4a82" - integrity sha512-nIVck8DK+GM/0Frwd+nIhZ84pR/BX7rmXMfYwyg+Sri5oGVE99/E3KvXqpC2xHFxyqXyGHTKBSioxxplrO4I4w== - dependencies: - "@jridgewell/source-map" "^0.3.3" - acorn "^8.15.0" - commander "^2.20.0" - source-map-support "~0.5.20" - -test-exclude@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" - integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== - dependencies: - "@istanbuljs/schema" "^0.1.2" - glob "^7.1.4" - minimatch "^3.0.4" - -text-extensions@^1.0.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" - integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -thread-loader@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/thread-loader/-/thread-loader-3.0.4.tgz#c392e4c0241fbc80430eb680e4886819b504a31b" - integrity sha512-ByaL2TPb+m6yArpqQUZvP+5S1mZtXsEP7nWKKlAUTm7fCml8kB5s1uI3+eHRP2bk5mVYfRSBI7FFf+tWEyLZwA== - dependencies: - json-parse-better-errors "^1.0.2" - loader-runner "^4.1.0" - loader-utils "^2.0.0" - neo-async "^2.6.2" - schema-utils "^3.0.0" - -thread-loader@^4.0.2: - version "4.0.4" - resolved "https://registry.yarnpkg.com/thread-loader/-/thread-loader-4.0.4.tgz#954141f6ce6c472b513737252b4729ecad2e4902" - integrity sha512-tXagu6Hivd03wB2tiS1bqvw345sc7mKei32EgpYpq31ZLes9FN0mEK2nKzXLRFgwt3PsBB0E/MZDp159rDoqwg== - dependencies: - json-parse-better-errors "^1.0.2" - loader-runner "^4.1.0" - neo-async "^2.6.2" - schema-utils "^4.2.0" - -thread-stream@^0.15.1: - version "0.15.2" - resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-0.15.2.tgz#fb95ad87d2f1e28f07116eb23d85aba3bc0425f4" - integrity sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA== - dependencies: - real-require "^0.1.0" - -throat@^6.0.1: - version "6.0.2" - resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.2.tgz#51a3fbb5e11ae72e2cf74861ed5c8020f89f29fe" - integrity sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ== - -through2@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - -through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== - -thunky@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" - integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== - -timers-browserify@^2.0.4: - version "2.0.12" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" - integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== - dependencies: - setimmediate "^1.0.4" - -tiny-invariant@^1.3.1: - version "1.3.3" - resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127" - integrity sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg== - -tiny-secp256k1@^1.1.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/tiny-secp256k1/-/tiny-secp256k1-1.1.7.tgz#0c1b6b9d2d93404f9093dc7e287b0aa834480573" - integrity sha512-eb+F6NabSnjbLwNoC+2o5ItbmP1kg7HliWue71JgLegQt6A5mTN8YbvTLCazdlg6e5SV6A+r8OGvZYskdlmhqQ== - dependencies: - bindings "^1.3.0" - bn.js "^4.11.8" - create-hmac "^1.1.7" - elliptic "^6.4.0" - nan "^2.13.2" - -tiny-warning@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" - integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== - -tinyglobby@^0.2.13: - version "0.2.15" - resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.15.tgz#e228dd1e638cea993d2fdb4fcd2d4602a79951c2" - integrity sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ== - dependencies: - fdir "^6.5.0" - picomatch "^4.0.3" - -tinyglobby@^0.2.15: - version "0.2.16" - resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.16.tgz#1c3b7eb953fce42b226bc5a1ee06428281aff3d6" - integrity sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg== - dependencies: - fdir "^6.5.0" - picomatch "^4.0.4" - -tinyrainbow@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/tinyrainbow/-/tinyrainbow-1.2.0.tgz#5c57d2fc0fb3d1afd78465c33ca885d04f02abb5" - integrity sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ== - -tldts-core@^7.0.17: - version "7.0.17" - resolved "https://registry.yarnpkg.com/tldts-core/-/tldts-core-7.0.17.tgz#dadfee3750dd272ed219d7367beb7cbb2ff29eb8" - integrity sha512-DieYoGrP78PWKsrXr8MZwtQ7GLCUeLxihtjC1jZsW1DnvSMdKPitJSe8OSYDM2u5H6g3kWJZpePqkp43TfLh0g== - -tldts@^7.0.5: - version "7.0.17" - resolved "https://registry.yarnpkg.com/tldts/-/tldts-7.0.17.tgz#a6cdc067b9e80ea05f3be471c0ea410688cc78b2" - integrity sha512-Y1KQBgDd/NUc+LfOtKS6mNsC9CCaH+m2P1RoIZy7RAPo3C3/t8X45+zgut31cRZtZ3xKPjfn3TkGTrctC2TQIQ== - dependencies: - tldts-core "^7.0.17" - -tmp@~0.2.1: - version "0.2.5" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.5.tgz#b06bcd23f0f3c8357b426891726d16015abfd8f8" - integrity sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow== - -tmpl@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" - integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== - -to-arraybuffer@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" - integrity sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA== - -to-buffer@^1.2.0, to-buffer@^1.2.1, to-buffer@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.2.2.tgz#ffe59ef7522ada0a2d1cb5dfe03bb8abc3cdc133" - integrity sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw== - dependencies: - isarray "^2.0.5" - safe-buffer "^5.2.1" - typed-array-buffer "^1.0.3" - -to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== - dependencies: - kind-of "^3.0.2" - -to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - -toggle-selection@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" - integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ== - -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - -toposort@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330" - integrity sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg== - -tough-cookie@^4.0.0: - version "4.1.4" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.4.tgz#945f1461b45b5a8c76821c33ea49c3ac192c1b36" - integrity sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag== - dependencies: - psl "^1.1.33" - punycode "^2.1.1" - universalify "^0.2.0" - url-parse "^1.5.3" - -tough-cookie@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-6.0.0.tgz#11e418b7864a2c0d874702bc8ce0f011261940e5" - integrity sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w== - dependencies: - tldts "^7.0.5" - -tr46@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" - integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== - dependencies: - punycode "^2.1.1" - -tr46@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-6.0.0.tgz#f5a1ae546a0adb32a277a2278d0d17fa2f9093e6" - integrity sha512-bLVMLPtstlZ4iMQHpFHTR7GAGj2jxi8Dg0s2h2MafAE4uSWF98FC/3MomU51iQAMf8/qDUbKWf5GxuvvVcXEhw== - dependencies: - punycode "^2.3.1" - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - -trim-lines@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-3.0.1.tgz#d802e332a07df861c48802c04321017b1bd87338" - integrity sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg== - -trim-newlines@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" - integrity sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw== - -trim-newlines@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" - integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== - -trim-trailing-lines@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz#bd4abbec7cc880462f10b2c8b5ce1d8d1ec7c2c0" - integrity sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ== - -trim@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" - integrity sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ== - -trough@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" - integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== - -trough@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/trough/-/trough-2.2.0.tgz#94a60bd6bd375c152c1df911a4b11d5b0256f50f" - integrity sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw== - -ts-api-utils@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-2.5.0.tgz#4acd4a155e22734990a5ed1fe9e97f113bcb37c1" - integrity sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA== - -ts-dedent@^2.0.0, ts-dedent@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5" - integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== - -ts-jest@^27.0.5: - version "27.1.5" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.1.5.tgz#0ddf1b163fbaae3d5b7504a1e65c914a95cff297" - integrity sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA== - dependencies: - bs-logger "0.x" - fast-json-stable-stringify "2.x" - jest-util "^27.0.0" - json5 "2.x" - lodash.memoize "4.x" - make-error "1.x" - semver "7.x" - yargs-parser "20.x" - -ts-jest@^29.4.9: - version "29.4.9" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.4.9.tgz#47dc33d0f5c36bddcedd16afefae285e0b049d2d" - integrity sha512-LTb9496gYPMCqjeDLdPrKuXtncudeV1yRZnF4Wo5l3SFi0RYEnYRNgMrFIdg+FHvfzjCyQk1cLncWVqiSX+EvQ== - dependencies: - bs-logger "^0.2.6" - fast-json-stable-stringify "^2.1.0" - handlebars "^4.7.9" - json5 "^2.2.3" - lodash.memoize "^4.1.2" - make-error "^1.3.6" - semver "^7.7.4" - type-fest "^4.41.0" - yargs-parser "^21.1.1" - -ts-loader@^9.4.2, ts-loader@^9.4.4: - version "9.5.4" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.5.4.tgz#44b571165c10fb5a90744aa5b7e119233c4f4585" - integrity sha512-nCz0rEwunlTZiy6rXFByQU1kVVpCIgUpc/psFiKVrUwrizdnIbRFu8w7bxhUF0X613DYwT4XzrZHpVyMe758hQ== - dependencies: - chalk "^4.1.0" - enhanced-resolve "^5.0.0" - micromatch "^4.0.0" - semver "^7.3.4" - source-map "^0.7.4" - -ts-pnp@^1.1.6: - version "1.2.0" - resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" - integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== - -tsconfig-paths-webpack-plugin@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-3.5.2.tgz#01aafff59130c04a8c4ebc96a3045c43c376449a" - integrity sha512-EhnfjHbzm5IYI9YPNVIxx1moxMI4bpHD2e0zTXeDNQcwjjRaGepP7IhTHJkyDBG0CAOoxRfe7jCG630Ou+C6Pw== - dependencies: - chalk "^4.1.0" - enhanced-resolve "^5.7.0" - tsconfig-paths "^3.9.0" - -tsconfig-paths-webpack-plugin@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.2.0.tgz#f7459a8ed1dd4cf66ad787aefc3d37fff3cf07fc" - integrity sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA== - dependencies: - chalk "^4.1.0" - enhanced-resolve "^5.7.0" - tapable "^2.2.1" - tsconfig-paths "^4.1.2" - -tsconfig-paths@^3.15.0, tsconfig-paths@^3.9.0: - version "3.15.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" - integrity sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tsconfig-paths@^4.1.2: - version "4.2.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" - integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== - dependencies: - json5 "^2.2.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tslib@1.14.1, tslib@^1.8.1, tslib@^1.9.3: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0, tslib@^2.8.0: - version "2.8.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" - integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== - -tslog@3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/tslog/-/tslog-3.3.3.tgz#751a469e0d36841bd7e03676c27e53e7ffe9bc3d" - integrity sha512-lGrkndwpAohZ9ntQpT+xtUw5k9YFV1DjsksiWQlBSf82TTqsSAWBARPRD9juI730r8o3Awpkjp2aXy9k+6vr+g== - dependencies: - source-map-support "^0.5.21" - -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - -tty-browserify@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" - integrity sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw== - -tuf-js@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/tuf-js/-/tuf-js-1.1.7.tgz#21b7ae92a9373015be77dfe0cb282a80ec3bbe43" - integrity sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg== - dependencies: - "@tufjs/models" "1.0.4" - debug "^4.3.4" - make-fetch-happen "^11.1.1" - -tweetnacl-util@^0.15.0: - version "0.15.1" - resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" - integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== - -tweetnacl@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" - integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-detect@4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -type-fest@^0.18.0: - version "0.18.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.18.1.tgz#db4bc151a4a2cf4eebf9add5db75508db6cc841f" - integrity sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw== - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -type-fest@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.4.1.tgz#8bdf77743385d8a4f13ba95f610f5ccd68c728f8" - integrity sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw== - -type-fest@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" - integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== - -type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - -type-fest@^4.41.0: - version "4.41.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-4.41.0.tgz#6ae1c8e5731273c2bf1f58ad39cbae2c91a46c58" - integrity sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA== - -type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -typed-array-buffer@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.3.tgz#a72395450a4869ec033fd549371b47af3a2ee536" - integrity sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw== - dependencies: - call-bound "^1.0.3" - es-errors "^1.3.0" - is-typed-array "^1.1.14" - -typed-array-byte-length@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.3.tgz#8407a04f7d78684f3d252aa1a143d2b77b4160ce" - integrity sha512-BaXgOuIxz8n8pIq3e7Atg/7s+DpiYrxn4vdot3w9KbnBhcRQq6o3xemQdIfynqSeXeDrF32x+WvfzmOjPiY9lg== - dependencies: - call-bind "^1.0.8" - for-each "^0.3.3" - gopd "^1.2.0" - has-proto "^1.2.0" - is-typed-array "^1.1.14" - -typed-array-byte-offset@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.4.tgz#ae3698b8ec91a8ab945016108aef00d5bff12355" - integrity sha512-bTlAFB/FBYMcuX81gbL4OcpH5PmlFHqlCCpAl8AlEzMz5k53oNDvN8p1PNOWLEmI2x4orp3raOFB51tv9X+MFQ== - dependencies: - available-typed-arrays "^1.0.7" - call-bind "^1.0.8" - for-each "^0.3.3" - gopd "^1.2.0" - has-proto "^1.2.0" - is-typed-array "^1.1.15" - reflect.getprototypeof "^1.0.9" - -typed-array-length@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.7.tgz#ee4deff984b64be1e118b0de8c9c877d5ce73d3d" - integrity sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg== - dependencies: - call-bind "^1.0.7" - for-each "^0.3.3" - gopd "^1.0.1" - is-typed-array "^1.1.13" - possible-typed-array-names "^1.0.0" - reflect.getprototypeof "^1.0.6" - -typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - -typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== - -typeforce@^1.11.5: - version "1.18.0" - resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc" - integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g== - -"typescript@>=3 < 6", typescript@^5, typescript@^5.9.3: - version "5.9.3" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.3.tgz#5b4f59e15310ab17a216f5d6cf53ee476ede670f" - integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw== - -typescript@^4.6.2: - version "4.9.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== - -ufo@^1.5.4, ufo@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.6.1.tgz#ac2db1d54614d1b22c1d603e3aef44a85d8f146b" - integrity sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA== - -ufo@^1.6.3: - version "1.6.3" - resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.6.3.tgz#799666e4e88c122a9659805e30b9dc071c3aed4f" - integrity sha512-yDJTmhydvl5lJzBmy/hyOAA0d+aqCBuwl818haVdYCRrWV84o7YyeVm4QlVHStqNrrJSTb6jKuFAVqAFsr+K3Q== - -uglify-js@^3.1.4: - version "3.19.3" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.19.3.tgz#82315e9bbc6f2b25888858acd1fff8441035b77f" - integrity sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ== - -unbox-primitive@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.1.0.tgz#8d9d2c9edeea8460c7f35033a88867944934d1e2" - integrity sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw== - dependencies: - call-bound "^1.0.3" - has-bigints "^1.0.2" - has-symbols "^1.1.0" - which-boxed-primitive "^1.1.1" - -uncrypto@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/uncrypto/-/uncrypto-0.1.3.tgz#e1288d609226f2d02d8d69ee861fa20d8348ef2b" - integrity sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q== - -undici-types@~6.21.0: - version "6.21.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" - integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== - -undici-types@~7.16.0: - version "7.16.0" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.16.0.tgz#ffccdff36aea4884cbfce9a750a0580224f58a46" - integrity sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw== - -unfetch@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" - integrity sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA== - -unherit@^1.0.4: - version "1.1.3" - resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.3.tgz#6c9b503f2b41b262330c80e91c8614abdaa69c22" - integrity sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ== - dependencies: - inherits "^2.0.0" - xtend "^4.0.0" - -unicode-canonical-property-names-ecmascript@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz#cb3173fe47ca743e228216e4a3ddc4c84d628cc2" - integrity sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg== - -unicode-match-property-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" - integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== - dependencies: - unicode-canonical-property-names-ecmascript "^2.0.0" - unicode-property-aliases-ecmascript "^2.0.0" - -unicode-match-property-value-ecmascript@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.1.tgz#65a7adfad8574c219890e219285ce4c64ed67eaa" - integrity sha512-JQ84qTuMg4nVkx8ga4A16a1epI9H6uTXAknqxkGF/aFfRLw1xC/Bp24HNLaZhHSkWd3+84t8iXnp1J0kYcZHhg== - -unicode-property-aliases-ecmascript@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.2.0.tgz#301d4f8a43d2b75c97adfad87c9dd5350c9475d1" - integrity sha512-hpbDzxUY9BFwX+UeBnxv3Sh1q7HFxj48DTmXchNgRa46lO8uj3/1iEn3MiNUYTg1g9ctIqXCCERn8gYZhHC5lQ== - -unified@9.2.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.0.tgz#67a62c627c40589edebbf60f53edfd4d822027f8" - integrity sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg== - dependencies: - bail "^1.0.0" - extend "^3.0.0" - is-buffer "^2.0.0" - is-plain-obj "^2.0.0" - trough "^1.0.0" - vfile "^4.0.0" - -unified@^11.0.0: - version "11.0.5" - resolved "https://registry.yarnpkg.com/unified/-/unified-11.0.5.tgz#f66677610a5c0a9ee90cab2b8d4d66037026d9e1" - integrity sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA== - dependencies: - "@types/unist" "^3.0.0" - bail "^2.0.0" - devlop "^1.0.0" - extend "^3.0.0" - is-plain-obj "^4.0.0" - trough "^2.0.0" - vfile "^6.0.0" - -union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - -unique-filename@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" - integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== - dependencies: - unique-slug "^2.0.0" - -unique-filename@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-2.0.1.tgz#e785f8675a9a7589e0ac77e0b5c34d2eaeac6da2" - integrity sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A== - dependencies: - unique-slug "^3.0.0" - -unique-filename@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-3.0.0.tgz#48ba7a5a16849f5080d26c760c86cf5cf05770ea" - integrity sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g== - dependencies: - unique-slug "^4.0.0" - -unique-slug@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" - integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== - dependencies: - imurmurhash "^0.1.4" - -unique-slug@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-3.0.0.tgz#6d347cf57c8a7a7a6044aabd0e2d74e4d76dc7c9" - integrity sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w== - dependencies: - imurmurhash "^0.1.4" - -unique-slug@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-4.0.0.tgz#6bae6bb16be91351badd24cdce741f892a6532e3" - integrity sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ== - dependencies: - imurmurhash "^0.1.4" - -unist-builder@2.0.3, unist-builder@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-2.0.3.tgz#77648711b5d86af0942f334397a33c5e91516436" - integrity sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw== - -unist-util-generated@^1.0.0: - version "1.1.6" - resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.6.tgz#5ab51f689e2992a472beb1b35f2ce7ff2f324d4b" - integrity sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg== - -unist-util-is@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797" - integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg== - -unist-util-is@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-6.0.1.tgz#d0a3f86f2dd0db7acd7d8c2478080b5c67f9c6a9" - integrity sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g== - dependencies: - "@types/unist" "^3.0.0" - -unist-util-position@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.1.0.tgz#1c42ee6301f8d52f47d14f62bbdb796571fa2d47" - integrity sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA== - -unist-util-position@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-5.0.0.tgz#678f20ab5ca1207a97d7ea8a388373c9cf896be4" - integrity sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA== - dependencies: - "@types/unist" "^3.0.0" - -unist-util-remove-position@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz#5d19ca79fdba712301999b2b73553ca8f3b352cc" - integrity sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA== - dependencies: - unist-util-visit "^2.0.0" - -unist-util-remove@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/unist-util-remove/-/unist-util-remove-2.1.0.tgz#b0b4738aa7ee445c402fda9328d604a02d010588" - integrity sha512-J8NYPyBm4baYLdCbjmf1bhPu45Cr1MWTm77qd9istEkzWpnN6O9tMsEbB2JhNnBCqGENRqEWomQ+He6au0B27Q== - dependencies: - unist-util-is "^4.0.0" - -unist-util-stringify-position@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da" - integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g== - dependencies: - "@types/unist" "^2.0.2" - -unist-util-stringify-position@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz#449c6e21a880e0855bf5aabadeb3a740314abac2" - integrity sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ== - dependencies: - "@types/unist" "^3.0.0" - -unist-util-visit-parents@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz#65a6ce698f78a6b0f56aa0e88f13801886cdaef6" - integrity sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^4.0.0" - -unist-util-visit-parents@^6.0.0: - version "6.0.2" - resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz#777df7fb98652ce16b4b7cd999d0a1a40efa3a02" - integrity sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ== - dependencies: - "@types/unist" "^3.0.0" - unist-util-is "^6.0.0" - -unist-util-visit@2.0.3, unist-util-visit@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" - integrity sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^4.0.0" - unist-util-visit-parents "^3.0.0" - -unist-util-visit@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-5.0.0.tgz#a7de1f31f72ffd3519ea71814cccf5fd6a9217d6" - integrity sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg== - dependencies: - "@types/unist" "^3.0.0" - unist-util-is "^6.0.0" - unist-util-visit-parents "^6.0.0" - -universal-user-agent@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.1.tgz#15f20f55da3c930c57bddbf1734c6654d5fd35aa" - integrity sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ== - -universalify@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" - integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== - -universalify@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" - integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== - -unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== - -unrs-resolver@^1.6.2, unrs-resolver@^1.7.11: - version "1.11.1" - resolved "https://registry.yarnpkg.com/unrs-resolver/-/unrs-resolver-1.11.1.tgz#be9cd8686c99ef53ecb96df2a473c64d304048a9" - integrity sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg== - dependencies: - napi-postinstall "^0.3.0" - optionalDependencies: - "@unrs/resolver-binding-android-arm-eabi" "1.11.1" - "@unrs/resolver-binding-android-arm64" "1.11.1" - "@unrs/resolver-binding-darwin-arm64" "1.11.1" - "@unrs/resolver-binding-darwin-x64" "1.11.1" - "@unrs/resolver-binding-freebsd-x64" "1.11.1" - "@unrs/resolver-binding-linux-arm-gnueabihf" "1.11.1" - "@unrs/resolver-binding-linux-arm-musleabihf" "1.11.1" - "@unrs/resolver-binding-linux-arm64-gnu" "1.11.1" - "@unrs/resolver-binding-linux-arm64-musl" "1.11.1" - "@unrs/resolver-binding-linux-ppc64-gnu" "1.11.1" - "@unrs/resolver-binding-linux-riscv64-gnu" "1.11.1" - "@unrs/resolver-binding-linux-riscv64-musl" "1.11.1" - "@unrs/resolver-binding-linux-s390x-gnu" "1.11.1" - "@unrs/resolver-binding-linux-x64-gnu" "1.11.1" - "@unrs/resolver-binding-linux-x64-musl" "1.11.1" - "@unrs/resolver-binding-wasm32-wasi" "1.11.1" - "@unrs/resolver-binding-win32-arm64-msvc" "1.11.1" - "@unrs/resolver-binding-win32-ia32-msvc" "1.11.1" - "@unrs/resolver-binding-win32-x64-msvc" "1.11.1" - -unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - -unstorage@^1.9.0: - version "1.17.1" - resolved "https://registry.yarnpkg.com/unstorage/-/unstorage-1.17.1.tgz#611519b799d6d9dbecb34364a1f8919d39732e81" - integrity sha512-KKGwRTT0iVBCErKemkJCLs7JdxNVfqTPc/85ae1XES0+bsHbc/sFBfVi5kJp156cc51BHinIH2l3k0EZ24vOBQ== - dependencies: - anymatch "^3.1.3" - chokidar "^4.0.3" - destr "^2.0.5" - h3 "^1.15.4" - lru-cache "^10.4.3" - node-fetch-native "^1.6.7" - ofetch "^1.4.1" - ufo "^1.6.1" - -untildify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0" - integrity sha512-sJjbDp2GodvkB0FZZcn7k6afVisqX5BZD7Yq3xp4nN2O15BBK0cLm3Vwn2vQaF7UDS0UUsrQMkkplmDI5fskig== - dependencies: - os-homedir "^1.0.0" - -upath@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b" - integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w== - -upath@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" - integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== - -update-browserslist-db@^1.2.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz#64d76db58713136acbeb4c49114366cc6cc2e80d" - integrity sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w== - dependencies: - escalade "^3.2.0" - picocolors "^1.1.1" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== - -url-loader@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2" - integrity sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA== - dependencies: - loader-utils "^2.0.0" - mime-types "^2.1.27" - schema-utils "^3.0.0" - -url-parse@^1.5.3: - version "1.5.10" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" - integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== - dependencies: - querystringify "^2.1.1" - requires-port "^1.0.0" - -url@^0.11.0: - version "0.11.4" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.4.tgz#adca77b3562d56b72746e76b330b7f27b6721f3c" - integrity sha512-oCwdVC7mTuWiPyjLUz/COz5TLk6wgp0RCsN+wHZ2Ekneac9w8uuV0njcbbie2ME+Vs+d6duwmYuR3HgQXs1fOg== - dependencies: - punycode "^1.4.1" - qs "^6.12.3" - -use-clipboard-copy@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/use-clipboard-copy/-/use-clipboard-copy-0.2.0.tgz#e1f31f2b21e369bc79b5d7b358e2c8aece6ef264" - integrity sha512-f0PMMwZ2/Hh9/54L12capx4s6ASdd6edNJxg2OcqWVNM8BPvtOSmNFIN1Dg/q//fPp8MpUZceHfr7cnWOS0RxA== - dependencies: - clipboard-copy "^3.0.0" - -use-sync-external-store@^1.2.2, use-sync-external-store@^1.4.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.6.0.tgz#b174bfa65cb2b526732d9f2ac0a408027876f32d" - integrity sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w== - -use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - -util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -util.promisify@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" - integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== - dependencies: - define-properties "^1.1.2" - object.getownpropertydescriptors "^2.0.3" - -util@^0.10.4: - version "0.10.4" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" - integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== - dependencies: - inherits "2.0.3" - -util@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" - integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== - dependencies: - inherits "2.0.3" - -utila@~0.4: - version "0.4.0" - resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" - integrity sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA== - -utility-types@^3.10.0: - version "3.11.0" - resolved "https://registry.yarnpkg.com/utility-types/-/utility-types-3.11.0.tgz#607c40edb4f258915e901ea7995607fdf319424c" - integrity sha512-6Z7Ma2aVEWisaL6TvBCy7P8rm2LQoPv6dJ7ecIaIixHcwfbJ0x7mWdbcwlIM5IGQxPZSFYeqRCqlOOeKoJYMkw== - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== - -uuid-browser@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/uuid-browser/-/uuid-browser-3.1.0.tgz#0f05a40aef74f9e5951e20efbf44b11871e56410" - integrity sha512-dsNgbLaTrd6l3MMxTtouOCFw4CBFc/3a+GgYA2YyrJvyQ1u6q4pcu3ktLoUZ/VN/Aw9WsauazbgsgdfVWgAKQg== - -uuid@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-11.1.0.tgz#9549028be1753bb934fc96e2bca09bb4105ae912" - integrity sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A== - -uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -uuid@^9.0.0, uuid@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" - integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== - -v8-compile-cache@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - -v8-to-istanbul@^8.1.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz#77b752fd3975e31bbcef938f85e9bd1c7a8d60ed" - integrity sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^1.6.0" - source-map "^0.7.3" - -v8-to-istanbul@^9.0.0, v8-to-istanbul@^9.0.1: - version "9.3.0" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz#b9572abfa62bd556c16d75fdebc1a411d5ff3175" - integrity sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA== - dependencies: - "@jridgewell/trace-mapping" "^0.3.12" - "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^2.0.0" - -validate-npm-package-license@3.0.4, validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - -validate-npm-package-name@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz#f16afd48318e6f90a1ec101377fa0384cfc8c713" - integrity sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ== - dependencies: - builtins "^5.0.0" - -validate-npm-package-name@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" - integrity sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw== - dependencies: - builtins "^1.0.3" - -validate-npm-package-name@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz#a316573e9b49f3ccd90dbb6eb52b3f06c6d604e8" - integrity sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ== - -vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== - -vfile-location@^3.0.0, vfile-location@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-3.2.0.tgz#d8e41fbcbd406063669ebf6c33d56ae8721d0f3c" - integrity sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA== - -vfile-message@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a" - integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ== - dependencies: - "@types/unist" "^2.0.0" - unist-util-stringify-position "^2.0.0" - -vfile-message@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-4.0.3.tgz#87b44dddd7b70f0641c2e3ed0864ba73e2ea8df4" - integrity sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw== - dependencies: - "@types/unist" "^3.0.0" - unist-util-stringify-position "^4.0.0" - -vfile@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.2.1.tgz#03f1dce28fc625c625bc6514350fbdb00fa9e624" - integrity sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA== - dependencies: - "@types/unist" "^2.0.0" - is-buffer "^2.0.0" - unist-util-stringify-position "^2.0.0" - vfile-message "^2.0.0" - -vfile@^6.0.0: - version "6.0.3" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-6.0.3.tgz#3652ab1c496531852bf55a6bac57af981ebc38ab" - integrity sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q== - dependencies: - "@types/unist" "^3.0.0" - vfile-message "^4.0.0" - -victory-vendor@^36.6.8: - version "36.9.2" - resolved "https://registry.yarnpkg.com/victory-vendor/-/victory-vendor-36.9.2.tgz#668b02a448fa4ea0f788dbf4228b7e64669ff801" - integrity sha512-PnpQQMuxlwYdocC8fIJqVXvkeViHYzotI+NJrCuav0ZYFoq912ZHBk3mCeuj+5/VpodOjPe1z0Fk2ihgzlXqjQ== - dependencies: - "@types/d3-array" "^3.0.3" - "@types/d3-ease" "^3.0.0" - "@types/d3-interpolate" "^3.0.1" - "@types/d3-scale" "^4.0.2" - "@types/d3-shape" "^3.1.0" - "@types/d3-time" "^3.0.0" - "@types/d3-timer" "^3.0.0" - d3-array "^3.1.6" - d3-ease "^3.0.1" - d3-interpolate "^3.0.1" - d3-scale "^4.0.2" - d3-shape "^3.1.0" - d3-time "^3.0.0" - d3-timer "^3.0.1" - -vm-browserify@^1.0.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" - integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== - -void-elements@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09" - integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w== - -w3c-hr-time@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" - integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== - dependencies: - browser-process-hrtime "^1.0.0" - -w3c-xmlserializer@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" - integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== - dependencies: - xml-name-validator "^3.0.0" - -w3c-xmlserializer@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz#f925ba26855158594d907313cedd1476c5967f6c" - integrity sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA== - dependencies: - xml-name-validator "^5.0.0" - -walker@^1.0.7, walker@^1.0.8, walker@~1.0.5: - version "1.0.8" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" - integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== - dependencies: - makeerror "1.0.12" - -watchpack-chokidar2@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" - integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== - dependencies: - chokidar "^2.1.8" - -watchpack@^1.7.4: - version "1.7.5" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" - integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== - dependencies: - graceful-fs "^4.1.2" - neo-async "^2.5.0" - optionalDependencies: - chokidar "^3.4.1" - watchpack-chokidar2 "^2.0.1" - -watchpack@^2.2.0, watchpack@^2.4.4: - version "2.4.4" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.4.tgz#473bda72f0850453da6425081ea46fc0d7602947" - integrity sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA== - dependencies: - glob-to-regexp "^0.4.1" - graceful-fs "^4.1.2" - -wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" - integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== - dependencies: - minimalistic-assert "^1.0.0" - -wcwidth@^1.0.0, wcwidth@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== - dependencies: - defaults "^1.0.3" - -web-namespaces@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" - integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -webidl-conversions@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" - integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== - -webidl-conversions@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" - integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== - -webidl-conversions@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-8.0.0.tgz#821c92aa4f88d88a31264d887e244cb9655690c6" - integrity sha512-n4W4YFyz5JzOfQeA8oN7dUYpR+MBP3PIUsn2jLjWXwK5ASUzt0Jc/A5sAUZoCYFJRGF0FBKJ+1JjN43rNdsQzA== - -webpack-cli@^4.8.0: - version "4.10.0" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.10.0.tgz#37c1d69c8d85214c5a65e589378f53aec64dab31" - integrity sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w== - dependencies: - "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^1.2.0" - "@webpack-cli/info" "^1.5.0" - "@webpack-cli/serve" "^1.7.0" - colorette "^2.0.14" - commander "^7.0.0" - cross-spawn "^7.0.3" - fastest-levenshtein "^1.0.12" - import-local "^3.0.2" - interpret "^2.2.0" - rechoir "^0.7.0" - webpack-merge "^5.7.3" - -webpack-cli@^5.1.4: - version "5.1.4" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-5.1.4.tgz#c8e046ba7eaae4911d7e71e2b25b776fcc35759b" - integrity sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg== - dependencies: - "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^2.1.1" - "@webpack-cli/info" "^2.0.2" - "@webpack-cli/serve" "^2.0.5" - colorette "^2.0.14" - commander "^10.0.1" - cross-spawn "^7.0.3" - envinfo "^7.7.3" - fastest-levenshtein "^1.0.12" - import-local "^3.0.2" - interpret "^3.1.1" - rechoir "^0.8.0" - webpack-merge "^5.7.3" - -webpack-dev-middleware@^3.7.3: - version "3.7.3" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz#0639372b143262e2b84ab95d3b91a7597061c2c5" - integrity sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ== - dependencies: - memory-fs "^0.4.1" - mime "^2.4.4" - mkdirp "^0.5.1" - range-parser "^1.2.1" - webpack-log "^2.0.0" - -webpack-dev-middleware@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-4.3.0.tgz#179cc40795882cae510b1aa7f3710cbe93c9333e" - integrity sha512-PjwyVY95/bhBh6VUqt6z4THplYcsvQ8YNNBTBM873xLVmw8FLeALn0qurHbs9EmcfhzQis/eoqypSnZeuUz26w== - dependencies: - colorette "^1.2.2" - mem "^8.1.1" - memfs "^3.2.2" - mime-types "^2.1.30" - range-parser "^1.2.1" - schema-utils "^3.0.0" - -webpack-dev-middleware@^5.3.4: - version "5.3.4" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz#eb7b39281cbce10e104eb2b8bf2b63fce49a3517" - integrity sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q== - dependencies: - colorette "^2.0.10" - memfs "^3.4.3" - mime-types "^2.1.31" - range-parser "^1.2.1" - schema-utils "^4.0.0" - -webpack-dev-server@^4.15.1, webpack-dev-server@^4.5.0: - version "4.15.2" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.15.2.tgz#9e0c70a42a012560860adb186986da1248333173" - integrity sha512-0XavAZbNJ5sDrCbkpWL8mia0o5WPOd2YGtxrEiZkBK9FjLppIUK2TgxK6qGD2P3hUXTJNNPVibrerKcx5WkR1g== - dependencies: - "@types/bonjour" "^3.5.9" - "@types/connect-history-api-fallback" "^1.3.5" - "@types/express" "^4.17.13" - "@types/serve-index" "^1.9.1" - "@types/serve-static" "^1.13.10" - "@types/sockjs" "^0.3.33" - "@types/ws" "^8.5.5" - ansi-html-community "^0.0.8" - bonjour-service "^1.0.11" - chokidar "^3.5.3" - colorette "^2.0.10" - compression "^1.7.4" - connect-history-api-fallback "^2.0.0" - default-gateway "^6.0.3" - express "^4.17.3" - graceful-fs "^4.2.6" - html-entities "^2.3.2" - http-proxy-middleware "^2.0.3" - ipaddr.js "^2.0.1" - launch-editor "^2.6.0" - open "^8.0.9" - p-retry "^4.5.0" - rimraf "^3.0.2" - schema-utils "^4.0.0" - selfsigned "^2.1.1" - serve-index "^1.9.1" - sockjs "^0.3.24" - spdy "^4.0.2" - webpack-dev-middleware "^5.3.4" - ws "^8.13.0" - -webpack-favicons@^1.3.8: - version "1.5.43" - resolved "https://registry.yarnpkg.com/webpack-favicons/-/webpack-favicons-1.5.43.tgz#fd80dff225b6b087e2060cfcbd9b3f485e6245ae" - integrity sha512-prAavTPgWzn8c7uc9s6XQEqywdyg5wa1jzmGbd3nn6fE1G2OXMl14PcprYB2xa/+b/Kplndd48oLbt8Nc6MwQw== - dependencies: - favicons "7.2.0" - -webpack-filter-warnings-plugin@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/webpack-filter-warnings-plugin/-/webpack-filter-warnings-plugin-1.2.1.tgz#dc61521cf4f9b4a336fbc89108a75ae1da951cdb" - integrity sha512-Ez6ytc9IseDMLPo0qCuNNYzgtUl8NovOqjIq4uAU8LTD4uoa1w1KpZyyzFtLTEMZpkkOkLfL9eN+KGYdk1Qtwg== - -webpack-hot-middleware@^2.25.1: - version "2.26.1" - resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.26.1.tgz#87214f1e3f9f3acab9271fef9e6ed7b637d719c0" - integrity sha512-khZGfAeJx6I8K9zKohEWWYN6KDlVw2DHownoe+6Vtwj1LP9WFgegXnVMSkZ/dBEBtXFwrkkydsaPFlB7f8wU2A== - dependencies: - ansi-html-community "0.0.8" - html-entities "^2.1.0" - strip-ansi "^6.0.0" - -webpack-log@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" - integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg== - dependencies: - ansi-colors "^3.0.0" - uuid "^3.3.2" - -webpack-merge@^5.7.3, webpack-merge@^5.8.0, webpack-merge@^5.9.0: - version "5.10.0" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.10.0.tgz#a3ad5d773241e9c682803abf628d4cd62b8a4177" - integrity sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA== - dependencies: - clone-deep "^4.0.1" - flat "^5.0.2" - wildcard "^2.0.0" - -webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" - integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== - dependencies: - source-list-map "^2.0.0" - source-map "~0.6.1" - -webpack-sources@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.3.3.tgz#d4bf7f9909675d7a070ff14d0ef2a4f3c982c723" - integrity sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg== - -webpack-virtual-modules@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.2.2.tgz#20863dc3cb6bb2104729fff951fbe14b18bd0299" - integrity sha512-kDUmfm3BZrei0y+1NTHJInejzxfhtU8eDj2M7OKb2IWrPFAeO1SOH2KuQ68MSZu9IGEHcxbkKKR1v18FrUSOmA== - dependencies: - debug "^3.0.0" - -webpack-virtual-modules@^0.4.1: - version "0.4.6" - resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.4.6.tgz#3e4008230731f1db078d9cb6f68baf8571182b45" - integrity sha512-5tyDlKLqPfMqjT3Q9TAqf2YqjwmnUleZwzJi1A5qXnlBCdj2AtOJ6wAWdglTIDOPgOiOrXeBeFcsQ8+aGQ6QbA== - -webpack@4: - version "4.47.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.47.0.tgz#8b8a02152d7076aeb03b61b47dad2eeed9810ebc" - integrity sha512-td7fYwgLSrky3fI1EuU5cneU4+pbH6GgOfuKNS1tNPcfdGinGELAqsb/BP4nnvZyKSG2i/xFGU7+n2PvZA8HJQ== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-module-context" "1.9.0" - "@webassemblyjs/wasm-edit" "1.9.0" - "@webassemblyjs/wasm-parser" "1.9.0" - acorn "^6.4.1" - ajv "^6.10.2" - ajv-keywords "^3.4.1" - chrome-trace-event "^1.0.2" - enhanced-resolve "^4.5.0" - eslint-scope "^4.0.3" - json-parse-better-errors "^1.0.2" - loader-runner "^2.4.0" - loader-utils "^1.2.3" - memory-fs "^0.4.1" - micromatch "^3.1.10" - mkdirp "^0.5.3" - neo-async "^2.6.1" - node-libs-browser "^2.2.1" - schema-utils "^1.0.0" - tapable "^1.1.3" - terser-webpack-plugin "^1.4.3" - watchpack "^1.7.4" - webpack-sources "^1.4.1" - -"webpack@>=4.43.0 <6.0.0", webpack@^5.75.0, webpack@^5.88.2, webpack@^5.9.0: - version "5.104.1" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.104.1.tgz#94bd41eb5dbf06e93be165ba8be41b8260d4fb1a" - integrity sha512-Qphch25abbMNtekmEGJmeRUhLDbe+QfiWTiqpKYkpCOWY64v9eyl+KRRLmqOFA2AvKPpc9DC6+u2n76tQLBoaA== - dependencies: - "@types/eslint-scope" "^3.7.7" - "@types/estree" "^1.0.8" - "@types/json-schema" "^7.0.15" - "@webassemblyjs/ast" "^1.14.1" - "@webassemblyjs/wasm-edit" "^1.14.1" - "@webassemblyjs/wasm-parser" "^1.14.1" - acorn "^8.15.0" - acorn-import-phases "^1.0.3" - browserslist "^4.28.1" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.17.4" - 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.4.4" - webpack-sources "^3.3.3" - -websocket-driver@>=0.5.1, websocket-driver@^0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" - integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== - dependencies: - http-parser-js ">=0.5.1" - safe-buffer ">=5.1.0" - websocket-extensions ">=0.1.1" - -websocket-extensions@>=0.1.1: - version "0.1.4" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" - integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== - -whatwg-encoding@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" - integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== - dependencies: - iconv-lite "0.4.24" - -whatwg-encoding@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz#d0f4ef769905d426e1688f3e34381a99b60b76e5" - integrity sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ== - dependencies: - iconv-lite "0.6.3" - -whatwg-mimetype@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" - integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== - -whatwg-mimetype@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz#bc1bf94a985dc50388d54a9258ac405c3ca2fc0a" - integrity sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg== - -whatwg-url@^15.0.0, whatwg-url@^15.1.0: - version "15.1.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-15.1.0.tgz#5c433439b9a5789eeb3806bbd0da89a8bd40b8d7" - integrity sha512-2ytDk0kiEj/yu90JOAp44PVPUkO9+jVhyf+SybKlRHSDlvOOZhdPIrr7xTH64l4WixO2cP+wQIcgujkGBPPz6g== - dependencies: - tr46 "^6.0.0" - webidl-conversions "^8.0.0" - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -whatwg-url@^8.0.0, whatwg-url@^8.5.0: - version "8.7.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" - integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== - dependencies: - lodash "^4.7.0" - tr46 "^2.1.0" - webidl-conversions "^6.1.0" - -which-boxed-primitive@^1.0.2, which-boxed-primitive@^1.1.0, which-boxed-primitive@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.1.1.tgz#d76ec27df7fa165f18d5808374a5fe23c29b176e" - integrity sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA== - dependencies: - is-bigint "^1.1.0" - is-boolean-object "^1.2.1" - is-number-object "^1.1.1" - is-string "^1.1.1" - is-symbol "^1.1.1" - -which-builtin-type@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/which-builtin-type/-/which-builtin-type-1.2.1.tgz#89183da1b4907ab089a6b02029cc5d8d6574270e" - integrity sha512-6iBczoX+kDQ7a3+YJBnh3T+KZRxM/iYNPXicqk66/Qfm1b93iu+yOImkg0zHbj5LNOcNv1TEADiZ0xa34B4q6Q== - dependencies: - call-bound "^1.0.2" - function.prototype.name "^1.1.6" - has-tostringtag "^1.0.2" - is-async-function "^2.0.0" - is-date-object "^1.1.0" - is-finalizationregistry "^1.1.0" - is-generator-function "^1.0.10" - is-regex "^1.2.1" - is-weakref "^1.0.2" - isarray "^2.0.5" - which-boxed-primitive "^1.1.0" - which-collection "^1.0.2" - which-typed-array "^1.1.16" - -which-collection@^1.0.1, which-collection@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.2.tgz#627ef76243920a107e7ce8e96191debe4b16c2a0" - integrity sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw== - dependencies: - is-map "^2.0.3" - is-set "^2.0.3" - is-weakmap "^2.0.2" - is-weakset "^2.0.3" - -which-typed-array@^1.1.13, which-typed-array@^1.1.16, which-typed-array@^1.1.19: - version "1.1.19" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.19.tgz#df03842e870b6b88e117524a4b364b6fc689f956" - integrity sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw== - dependencies: - available-typed-arrays "^1.0.7" - call-bind "^1.0.8" - call-bound "^1.0.4" - for-each "^0.3.5" - get-proto "^1.0.1" - gopd "^1.2.0" - has-tostringtag "^1.0.2" - -which@^1.2.9: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - -which@^2.0.1, which@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -which@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/which/-/which-3.0.1.tgz#89f1cd0c23f629a8105ffe69b8172791c87b4be1" - integrity sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg== - dependencies: - isexe "^2.0.0" - -wide-align@^1.1.2, wide-align@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" - integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== - dependencies: - string-width "^1.0.2 || 2 || 3 || 4" - -widest-line@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" - integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== - dependencies: - string-width "^4.0.0" - -wif@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/wif/-/wif-2.0.6.tgz#08d3f52056c66679299726fade0d432ae74b4704" - integrity sha512-HIanZn1zmduSF+BQhkE+YXIbEiH0xPr1012QbFEGB0xsKqJii0/SqJjyn8dFv6y36kOznMgMB+LGcbZTJ1xACQ== - dependencies: - bs58check "<3.0.0" - -wildcard@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67" - integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== - -word-wrap@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.5.tgz#d2c45c6dd4fbce621a66f136cbe328afd0410b34" - integrity sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA== - -wordwrap@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== - -worker-farm@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" - integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== - dependencies: - errno "~0.1.7" - -worker-rpc@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/worker-rpc/-/worker-rpc-0.1.1.tgz#cb565bd6d7071a8f16660686051e969ad32f54d5" - integrity sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg== - dependencies: - microevent.ts "~0.1.1" - -world-countries@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/world-countries/-/world-countries-5.1.0.tgz#ea6b6156d9ef80c9ae6ff1e238d11b7ebd90351f" - integrity sha512-CXR6EBvTbArDlDDIWU3gfKb7Qk0ck2WNZ234b/A0vuecPzIfzzxH+O6Ejnvg1sT8XuiZjVlzOH0h08ZtaO7g0w== - -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^6.0.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" - integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== - dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -write-file-atomic@5.0.1, write-file-atomic@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-5.0.1.tgz#68df4717c55c6fa4281a7860b4c2ba0a6d2b11e7" - integrity sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw== - dependencies: - imurmurhash "^0.1.4" - signal-exit "^4.0.1" - -write-file-atomic@^2.4.2: - version "2.4.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" - integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ== - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - signal-exit "^3.0.2" - -write-file-atomic@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" - integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== - dependencies: - imurmurhash "^0.1.4" - is-typedarray "^1.0.0" - signal-exit "^3.0.2" - typedarray-to-buffer "^3.1.5" - -write-json-file@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-3.2.0.tgz#65bbdc9ecd8a1458e15952770ccbadfcff5fe62a" - integrity sha512-3xZqT7Byc2uORAatYiP3DHUUAVEkNOswEWNs9H5KXiicRTvzYzYqKjYc4G7p+8pltvAw641lVByKVtMpf+4sYQ== - dependencies: - detect-indent "^5.0.0" - graceful-fs "^4.1.15" - make-dir "^2.1.0" - pify "^4.0.1" - sort-keys "^2.0.0" - write-file-atomic "^2.4.2" - -write-pkg@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-4.0.0.tgz#675cc04ef6c11faacbbc7771b24c0abbf2a20039" - integrity sha512-v2UQ+50TNf2rNHJ8NyWttfm/EJUBWMJcx6ZTYZr6Qp52uuegWw/lBkCtCbnYZEmPRNL61m+u67dAmGxo+HTULA== - dependencies: - sort-keys "^2.0.0" - type-fest "^0.4.1" - write-json-file "^3.2.0" - -ws@^7, ws@^7.4.6: - version "7.5.10" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.10.tgz#58b5c20dc281633f6c19113f39b349bd8bd558d9" - integrity sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ== - -ws@^8.13.0, ws@^8.18.3, ws@^8.2.3: - version "8.18.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.18.3.tgz#b56b88abffde62791c639170400c93dcb0c95472" - integrity sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg== - -x-default-browser@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/x-default-browser/-/x-default-browser-0.4.0.tgz#70cf0da85da7c0ab5cb0f15a897f2322a6bdd481" - integrity sha512-7LKo7RtWfoFN/rHx1UELv/2zHGMx8MkZKDq1xENmOCTkfIqZJ0zZ26NEJX8czhnPXVcqS0ARjjfJB+eJ0/5Cvw== - optionalDependencies: - default-browser-id "^1.0.4" - -xml-name-validator@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" - integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== - -xml-name-validator@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-5.0.0.tgz#82be9b957f7afdacf961e5980f1bf227c0bf7673" - integrity sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg== - -xml2js@^0.6.1: - version "0.6.2" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.6.2.tgz#dd0b630083aa09c161e25a4d0901e2b2a929b499" - integrity sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA== - dependencies: - sax ">=0.6.0" - xmlbuilder "~11.0.0" - -xmlbuilder@~11.0.0: - version "11.0.1" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" - integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== - -xmlchars@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" - integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== - -xstream@^11.14.0: - version "11.14.0" - resolved "https://registry.yarnpkg.com/xstream/-/xstream-11.14.0.tgz#2c071d26b18310523b6877e86b4e54df068a9ae5" - integrity sha512-1bLb+kKKtKPbgTK6i/BaoAn03g47PpFstlbe1BA+y3pNS/LfvcaghS5BFf9+EE1J+KwSQsEpfJvFN5GqFtiNmw== - dependencies: - globalthis "^1.0.1" - symbol-observable "^2.0.3" - -xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - -y18n@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" - integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: - version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - -yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - -yargs-parser@20.x, yargs-parser@^20.2.2, yargs-parser@^20.2.3, yargs-parser@^20.2.9: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - -yargs-parser@21.1.1, yargs-parser@^21.1.1: - version "21.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" - integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== - -yargs@16.2.0, yargs@^16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - -yargs@^17.6.2, yargs@^17.7.2: - version "17.7.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" - integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== - dependencies: - cliui "^8.0.1" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.3" - y18n "^5.0.5" - yargs-parser "^21.1.1" - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - -yocto-queue@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.2.1.tgz#36d7c4739f775b3cbc28e6136e21aa057adec418" - integrity sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg== - -yup@^0.32.9: - version "0.32.11" - resolved "https://registry.yarnpkg.com/yup/-/yup-0.32.11.tgz#d67fb83eefa4698607982e63f7ca4c5ed3cf18c5" - integrity sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg== - dependencies: - "@babel/runtime" "^7.15.4" - "@types/lodash" "^4.14.175" - lodash "^4.17.21" - lodash-es "^4.17.21" - nanoclone "^0.2.1" - property-expr "^2.0.4" - toposort "^2.0.2" - -zod@^3.24.1: - version "3.25.76" - resolved "https://registry.yarnpkg.com/zod/-/zod-3.25.76.tgz#26841c3f6fd22a6a2760e7ccb719179768471e34" - integrity sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ== - -zustand@^4.5.5: - version "4.5.7" - resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.5.7.tgz#7d6bb2026a142415dd8be8891d7870e6dbe65f55" - integrity sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw== - dependencies: - use-sync-external-store "^1.2.2" - -zwitch@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" - integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw== - -zwitch@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-2.0.4.tgz#c827d4b0acb76fc3e685a4c6ec2902d51070e9d7" - integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A== - -zxcvbn@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/zxcvbn/-/zxcvbn-4.4.2.tgz#28ec17cf09743edcab056ddd8b1b06262cc73c30" - integrity sha512-Bq0B+ixT/DMyG8kgX2xWcI5jUvCwqrMxSFam7m0lAf78nf04hv6lNCsyLYdyYTrCVMqNDY/206K7eExYCeSyUQ== From dc48750271a781b9026cf3924e2fb7fbe3a239fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Sat, 23 May 2026 14:25:05 +0100 Subject: [PATCH 43/94] ensure sufficient number of tickets before performing testrun assignment --- Cargo.lock | 2 +- .../nym-node-status-api/Cargo.toml | 2 +- .../src/http/api/testruns.rs | 26 +++++++++++++++++++ .../nym-node-status-api/src/http/state.rs | 8 +++++- .../src/ticketbook_manager/state.rs | 20 ++++++++++++++ 5 files changed, 55 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 62bab445e4..3c05b1e72c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7768,7 +7768,7 @@ dependencies = [ [[package]] name = "nym-node-status-api" -version = "4.6.1" +version = "4.6.2-rc" dependencies = [ "ammonia", "anyhow", diff --git a/nym-node-status-api/nym-node-status-api/Cargo.toml b/nym-node-status-api/nym-node-status-api/Cargo.toml index 729404d8b6..71e0a4e039 100644 --- a/nym-node-status-api/nym-node-status-api/Cargo.toml +++ b/nym-node-status-api/nym-node-status-api/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node-status-api" -version = "4.6.1" +version = "4.6.2-rc" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs b/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs index d26db1d7df..bc0a74100e 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs @@ -58,6 +58,31 @@ async fn request_testrun( return Err(HttpError::no_testruns_available()); } + // 1. guard against other agents attempting to get testruns so that we would be able to check + // for ticketbook count without cross-interaction + let _guard = state.lock_testrun_assignment().await; + + // 2. check if we have enough ticketbooks of ALL types before assigning the run + match state + .ticketbook_manager_state() + .has_enough_ticketbooks() + .await + { + Err(err) => { + return Err(HttpError::internal_with_logging(format!( + "failed to check ticketbook storage: {err}" + ))); + } + Ok(false) => { + tracing::warn!("not enough ticketbooks available, rejecting testrun assignment"); + return Err(HttpError::internal_with_logging( + "not enough ticketbooks available to assign a testrun", + )); + } + Ok(true) => (), + } + + // 3. attempt to assign the testrun itself match db::queries::testruns::assign_oldest_testrun(&mut conn).await { Ok(res) => { let Some(assignment) = res else { @@ -71,6 +96,7 @@ async fn request_testrun( assignment.gateway_identity_key, ); + // 4. retrieve required ticketbooks (we should always have sufficient number as we hold an exclusive lock) let materials = state .ticketbook_manager_state() .attempt_assign_ticket_materials(assignment.testrun_id) diff --git a/nym-node-status-api/nym-node-status-api/src/http/state.rs b/nym-node-status-api/nym-node-status-api/src/http/state.rs index b630c17d40..c1a635a2d6 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/state.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/state.rs @@ -11,7 +11,7 @@ use semver::Version; use serde::{Deserialize, Serialize}; use std::{collections::HashMap, sync::Arc, time::Duration}; use time::UtcDateTime; -use tokio::sync::RwLock; +use tokio::sync::{Mutex, MutexGuard, RwLock}; use tracing::{error, instrument, trace, warn}; use utoipa::ToSchema; @@ -42,6 +42,7 @@ pub(crate) struct AppState { node_delegations: Arc>, bin_info: BinaryInfo, ticketbook_manager_state: TicketbookManagerState, + testrun_assignment_guard: Arc>, } impl AppState { @@ -66,6 +67,7 @@ impl AppState { node_delegations, bin_info: BinaryInfo::new(), ticketbook_manager_state, + testrun_assignment_guard: Arc::new(Default::default()), } } @@ -81,6 +83,10 @@ impl AppState { self.agent_key_list.contains(agent_pubkey) } + pub(crate) async fn lock_testrun_assignment(&self) -> MutexGuard<'_, ()> { + self.testrun_assignment_guard.lock().await + } + pub(crate) fn agent_max_count(&self) -> i64 { self.agent_max_count } diff --git a/nym-node-status-api/nym-node-status-api/src/ticketbook_manager/state.rs b/nym-node-status-api/nym-node-status-api/src/ticketbook_manager/state.rs index e1e507b272..d6939ad1d9 100644 --- a/nym-node-status-api/nym-node-status-api/src/ticketbook_manager/state.rs +++ b/nym-node-status-api/nym-node-status-api/src/ticketbook_manager/state.rs @@ -53,6 +53,26 @@ impl TicketbookManagerState { } } + pub async fn has_enough_ticketbooks(&self) -> anyhow::Result { + let mut required = HashMap::new(); + for typ in &self.buffered_ticket_types { + let count = required.entry(*typ).or_insert(0); + *count += 1; + } + + for (typ, required_count) in required { + let available = self.storage.available_tickets_of_type(typ).await?; + if available < required_count { + warn!( + "not enough tickets of type {typ} available in storage, required {required_count}, available {available}" + ); + return Ok(false); + } + } + + Ok(true) + } + pub async fn attempt_assign_ticket_materials( &self, testrun_id: i32, From e6dd670b16b0923d18f3c1b2e92c060a65e224e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Sat, 23 May 2026 16:40:43 +0100 Subject: [PATCH 44/94] quroum checker logs + temp: increase of DefaultBodyLimit --- Cargo.lock | 2 +- common/credential-proxy/src/quorum_checker.rs | 25 ++++++++++++++++++- .../nym-node-status-api/Cargo.toml | 2 +- .../src/http/api/testruns.rs | 2 +- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3c05b1e72c..0e1a93311d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7768,7 +7768,7 @@ dependencies = [ [[package]] name = "nym-node-status-api" -version = "4.6.2-rc" +version = "4.6.2-rc2" dependencies = [ "ammonia", "anyhow", diff --git a/common/credential-proxy/src/quorum_checker.rs b/common/credential-proxy/src/quorum_checker.rs index 47a8ba6baf..2c1127fc9e 100644 --- a/common/credential-proxy/src/quorum_checker.rs +++ b/common/credential-proxy/src/quorum_checker.rs @@ -57,6 +57,7 @@ impl QuorumStateChecker { } async fn check_quorum_state(&self) -> Result { + info!("checking the current quorum state"); let client_guard = self.client.query_chain().await; // split the operation as we only need to hold the reference to chain client for the first part @@ -65,6 +66,7 @@ impl QuorumStateChecker { drop(client_guard); let res = check_known_dealers(dkg_details).await?; + info!("there are {} known DKG dealers", res.results.len()); let Some(signing_threshold) = res.threshold else { warn!( @@ -76,12 +78,33 @@ impl QuorumStateChecker { let mut working_issuer = 0; for result in res.results { + let dealer = &result.information; + let info = format!("[id: {}] @ {}", dealer.node_index, dealer.announce_address); if result.chain_available() && result.signing_available() { + info!("✅ {info} is fully available"); working_issuer += 1; + } else if !result.chain_available() && !result.signing_available() { + warn!("❌ {info} is not available for both chain and signing"); + } else if !result.chain_available() { + warn!("❌ {info} is not available for chain"); + } else { + warn!("❌ {info} is not available for signing"); } } - Ok((working_issuer as u64) >= signing_threshold) + let available = (working_issuer as u64) >= signing_threshold; + + if available { + info!( + "✅ Quorum state is available with {working_issuer} out of {signing_threshold} issuers" + ) + } else { + error!( + "❌ Quorum state is not available with {working_issuer} out of {signing_threshold} issuers" + ) + } + + Ok(available) } pub async fn run_forever(self) { diff --git a/nym-node-status-api/nym-node-status-api/Cargo.toml b/nym-node-status-api/nym-node-status-api/Cargo.toml index 71e0a4e039..ce1c9c642d 100644 --- a/nym-node-status-api/nym-node-status-api/Cargo.toml +++ b/nym-node-status-api/nym-node-status-api/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node-status-api" -version = "4.6.2-rc" +version = "4.6.2-rc2" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs b/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs index bc0a74100e..d4a94414e3 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs @@ -28,7 +28,7 @@ pub(crate) fn routes() -> Router { .route("/", axum::routing::get(request_testrun)) .route("/:testrun_id", axum::routing::post(submit_testrun)) .route("/:testrun_id/v2", axum::routing::post(submit_testrun_v2)) - .layer(DefaultBodyLimit::max(1024 * 1024 * 5)) + .layer(DefaultBodyLimit::max(1024 * 1024 * 512)) } #[tracing::instrument(level = "debug", skip_all)] From 4645de3eb52c7f4698bfe0b53c3fccad09c054e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Sat, 23 May 2026 17:18:45 +0100 Subject: [PATCH 45/94] add logs on failure to submit testrun results --- nym-node-status-api/nym-node-status-agent/Cargo.toml | 2 +- nym-node-status-api/nym-node-status-client/src/lib.rs | 10 ++++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/nym-node-status-api/nym-node-status-agent/Cargo.toml b/nym-node-status-api/nym-node-status-agent/Cargo.toml index 6171d7c927..3e8e76ef3e 100644 --- a/nym-node-status-api/nym-node-status-agent/Cargo.toml +++ b/nym-node-status-api/nym-node-status-agent/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node-status-agent" -version = "2.0.0" +version = "2.0.1-rc0" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/nym-node-status-api/nym-node-status-client/src/lib.rs b/nym-node-status-api/nym-node-status-client/src/lib.rs index 182fa8786d..2e9c3eb3fd 100644 --- a/nym-node-status-api/nym-node-status-client/src/lib.rs +++ b/nym-node-status-api/nym-node-status-client/src/lib.rs @@ -2,7 +2,7 @@ use crate::models::{TestrunAssignmentWithTickets, get_testrun, submit_results, s use anyhow::bail; use api::ApiPaths; use nym_crypto::asymmetric::ed25519::{PrivateKey, Signature}; -use tracing::{instrument, warn}; +use tracing::{error, instrument, warn}; mod api; pub mod auth; @@ -101,7 +101,13 @@ impl NsApiClient { .json(&submit_results) .send() .await - .and_then(|response| response.error_for_status())?; + .inspect_err(|err| error!("result submission failure: {err}")) + .and_then(|response| { + if response.status().is_client_error() { + error!("result submission failure: {response:?}") + } + response.error_for_status() + })?; tracing::debug!("Submitted results: {})", res.status()); Ok(()) From 6b98c168fc70dc0a4f19a5ff13c2c00a73b4847f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Sat, 23 May 2026 19:51:49 +0100 Subject: [PATCH 46/94] dont assign nodes with 0 performance --- Cargo.lock | 4 +-- ...05b6af747c3ae6f48bc41e5ec509a2d87abcc.json | 30 ------------------- ...79cf032a5c66b6ce724469ae52d0b39004ec1.json | 30 +++++++++++++++++++ .../nym-node-status-api/Cargo.toml | 2 +- .../src/db/queries/testruns.rs | 10 ++++--- 5 files changed, 39 insertions(+), 37 deletions(-) delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-38439a6c33bf21b90032659797105b6af747c3ae6f48bc41e5ec509a2d87abcc.json create mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-926caffc73fd8d8bd125923537179cf032a5c66b6ce724469ae52d0b39004ec1.json diff --git a/Cargo.lock b/Cargo.lock index 0e1a93311d..cd7657655f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7747,7 +7747,7 @@ dependencies = [ [[package]] name = "nym-node-status-agent" -version = "2.0.0" +version = "2.0.1-rc0" dependencies = [ "anyhow", "clap", @@ -7768,7 +7768,7 @@ dependencies = [ [[package]] name = "nym-node-status-api" -version = "4.6.2-rc2" +version = "4.6.2-rc3" dependencies = [ "ammonia", "anyhow", diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-38439a6c33bf21b90032659797105b6af747c3ae6f48bc41e5ec509a2d87abcc.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-38439a6c33bf21b90032659797105b6af747c3ae6f48bc41e5ec509a2d87abcc.json deleted file mode 100644 index ac921484b9..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-38439a6c33bf21b90032659797105b6af747c3ae6f48bc41e5ec509a2d87abcc.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n WITH oldest_queued AS (\n SELECT id\n FROM testruns\n WHERE status = $1\n ORDER BY created_utc asc\n LIMIT 1\n FOR UPDATE SKIP LOCKED\n )\n UPDATE testruns\n SET\n status = $3,\n last_assigned_utc = $2\n FROM oldest_queued\n WHERE testruns.id = oldest_queued.id\n RETURNING\n testruns.id,\n testruns.gateway_id\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Int4" - }, - { - "ordinal": 1, - "name": "gateway_id", - "type_info": "Int4" - } - ], - "parameters": { - "Left": [ - "Int4", - "Int8", - "Int4" - ] - }, - "nullable": [ - false, - false - ] - }, - "hash": "38439a6c33bf21b90032659797105b6af747c3ae6f48bc41e5ec509a2d87abcc" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-926caffc73fd8d8bd125923537179cf032a5c66b6ce724469ae52d0b39004ec1.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-926caffc73fd8d8bd125923537179cf032a5c66b6ce724469ae52d0b39004ec1.json new file mode 100644 index 0000000000..680be5fb74 --- /dev/null +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-926caffc73fd8d8bd125923537179cf032a5c66b6ce724469ae52d0b39004ec1.json @@ -0,0 +1,30 @@ +{ + "db_name": "PostgreSQL", + "query": "\n WITH oldest_queued AS (\n SELECT testruns.id\n FROM testruns\n JOIN gateways ON gateways.id = testruns.gateway_id\n WHERE testruns.status = $1\n AND gateways.performance > 0\n ORDER BY testruns.created_utc asc\n LIMIT 1\n FOR UPDATE OF testruns SKIP LOCKED\n )\n UPDATE testruns\n SET\n status = $3,\n last_assigned_utc = $2\n FROM oldest_queued\n WHERE testruns.id = oldest_queued.id\n RETURNING\n testruns.id,\n testruns.gateway_id\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int4" + }, + { + "ordinal": 1, + "name": "gateway_id", + "type_info": "Int4" + } + ], + "parameters": { + "Left": [ + "Int4", + "Int8", + "Int4" + ] + }, + "nullable": [ + false, + false + ] + }, + "hash": "926caffc73fd8d8bd125923537179cf032a5c66b6ce724469ae52d0b39004ec1" +} diff --git a/nym-node-status-api/nym-node-status-api/Cargo.toml b/nym-node-status-api/nym-node-status-api/Cargo.toml index ce1c9c642d..500637a000 100644 --- a/nym-node-status-api/nym-node-status-api/Cargo.toml +++ b/nym-node-status-api/nym-node-status-api/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node-status-api" -version = "4.6.2-rc2" +version = "4.6.2-rc3" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs b/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs index 601598fd70..ec0a4b8066 100644 --- a/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs +++ b/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs @@ -97,12 +97,14 @@ pub(crate) async fn assign_oldest_testrun( let returning = sqlx::query!( r#" WITH oldest_queued AS ( - SELECT id + SELECT testruns.id FROM testruns - WHERE status = $1 - ORDER BY created_utc asc + JOIN gateways ON gateways.id = testruns.gateway_id + WHERE testruns.status = $1 + AND gateways.performance > 0 + ORDER BY testruns.created_utc asc LIMIT 1 - FOR UPDATE SKIP LOCKED + FOR UPDATE OF testruns SKIP LOCKED ) UPDATE testruns SET From a39516713988c98f78ac2c834a9253a23a4389f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Sat, 23 May 2026 20:23:39 +0100 Subject: [PATCH 47/94] more logs and going insane --- Cargo.lock | 4 ++-- nym-node-status-api/nym-node-status-agent/Cargo.toml | 2 +- ...823e0fe6d26b5ac23f7f7eabc6b2ba13ccfb8ef14fcfd30.json} | 4 ++-- nym-node-status-api/nym-node-status-api/Cargo.toml | 2 +- .../nym-node-status-api/src/db/queries/testruns.rs | 1 + .../nym-node-status-api/src/http/api/testruns.rs | 3 ++- nym-node-status-api/nym-node-status-client/src/lib.rs | 9 +++++++-- 7 files changed, 16 insertions(+), 9 deletions(-) rename nym-node-status-api/nym-node-status-api/.sqlx/{query-926caffc73fd8d8bd125923537179cf032a5c66b6ce724469ae52d0b39004ec1.json => query-62be5c3a94e6b2e72823e0fe6d26b5ac23f7f7eabc6b2ba13ccfb8ef14fcfd30.json} (50%) diff --git a/Cargo.lock b/Cargo.lock index cd7657655f..b003821fbf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7747,7 +7747,7 @@ dependencies = [ [[package]] name = "nym-node-status-agent" -version = "2.0.1-rc0" +version = "2.0.1-rc1" dependencies = [ "anyhow", "clap", @@ -7768,7 +7768,7 @@ dependencies = [ [[package]] name = "nym-node-status-api" -version = "4.6.2-rc3" +version = "4.6.2-rc4" dependencies = [ "ammonia", "anyhow", diff --git a/nym-node-status-api/nym-node-status-agent/Cargo.toml b/nym-node-status-api/nym-node-status-agent/Cargo.toml index 3e8e76ef3e..19933a500d 100644 --- a/nym-node-status-api/nym-node-status-agent/Cargo.toml +++ b/nym-node-status-api/nym-node-status-agent/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node-status-agent" -version = "2.0.1-rc0" +version = "2.0.1-rc1" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-926caffc73fd8d8bd125923537179cf032a5c66b6ce724469ae52d0b39004ec1.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-62be5c3a94e6b2e72823e0fe6d26b5ac23f7f7eabc6b2ba13ccfb8ef14fcfd30.json similarity index 50% rename from nym-node-status-api/nym-node-status-api/.sqlx/query-926caffc73fd8d8bd125923537179cf032a5c66b6ce724469ae52d0b39004ec1.json rename to nym-node-status-api/nym-node-status-api/.sqlx/query-62be5c3a94e6b2e72823e0fe6d26b5ac23f7f7eabc6b2ba13ccfb8ef14fcfd30.json index 680be5fb74..b1bc6785eb 100644 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-926caffc73fd8d8bd125923537179cf032a5c66b6ce724469ae52d0b39004ec1.json +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-62be5c3a94e6b2e72823e0fe6d26b5ac23f7f7eabc6b2ba13ccfb8ef14fcfd30.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n WITH oldest_queued AS (\n SELECT testruns.id\n FROM testruns\n JOIN gateways ON gateways.id = testruns.gateway_id\n WHERE testruns.status = $1\n AND gateways.performance > 0\n ORDER BY testruns.created_utc asc\n LIMIT 1\n FOR UPDATE OF testruns SKIP LOCKED\n )\n UPDATE testruns\n SET\n status = $3,\n last_assigned_utc = $2\n FROM oldest_queued\n WHERE testruns.id = oldest_queued.id\n RETURNING\n testruns.id,\n testruns.gateway_id\n ", + "query": "\n WITH oldest_queued AS (\n SELECT testruns.id\n FROM testruns\n JOIN gateways ON gateways.id = testruns.gateway_id\n WHERE testruns.status = $1\n AND gateways.bonded = true\n AND gateways.performance > 0\n ORDER BY testruns.created_utc asc\n LIMIT 1\n FOR UPDATE OF testruns SKIP LOCKED\n )\n UPDATE testruns\n SET\n status = $3,\n last_assigned_utc = $2\n FROM oldest_queued\n WHERE testruns.id = oldest_queued.id\n RETURNING\n testruns.id,\n testruns.gateway_id\n ", "describe": { "columns": [ { @@ -26,5 +26,5 @@ false ] }, - "hash": "926caffc73fd8d8bd125923537179cf032a5c66b6ce724469ae52d0b39004ec1" + "hash": "62be5c3a94e6b2e72823e0fe6d26b5ac23f7f7eabc6b2ba13ccfb8ef14fcfd30" } diff --git a/nym-node-status-api/nym-node-status-api/Cargo.toml b/nym-node-status-api/nym-node-status-api/Cargo.toml index 500637a000..1fa2fff49f 100644 --- a/nym-node-status-api/nym-node-status-api/Cargo.toml +++ b/nym-node-status-api/nym-node-status-api/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node-status-api" -version = "4.6.2-rc3" +version = "4.6.2-rc4" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs b/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs index ec0a4b8066..71d5d88e60 100644 --- a/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs +++ b/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs @@ -101,6 +101,7 @@ pub(crate) async fn assign_oldest_testrun( FROM testruns JOIN gateways ON gateways.id = testruns.gateway_id WHERE testruns.status = $1 + AND gateways.bonded = true AND gateways.performance > 0 ORDER BY testruns.created_utc asc LIMIT 1 diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs b/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs index d4a94414e3..b4c11164d1 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs @@ -19,7 +19,7 @@ use nym_node_status_client::models::{ TestrunAssignmentWithTickets, get_testrun, submit_results, submit_results_v2, }; use reqwest::StatusCode; -use tracing::error; +use tracing::{debug, error}; // TODO dz consider adding endpoint to trigger testrun scan for a given gateway_id // like in H< src/http/testruns.rs @@ -123,6 +123,7 @@ async fn submit_testrun( Json(submitted_result): Json, ) -> HttpResult { state.authenticate_agent_submission(&submitted_result)?; + debug!("attempting to submit testrun {submitted_testrun_id} from an authenticated agent"); let db = state.db_pool(); let mut conn = db diff --git a/nym-node-status-api/nym-node-status-client/src/lib.rs b/nym-node-status-api/nym-node-status-client/src/lib.rs index 2e9c3eb3fd..6d118062fc 100644 --- a/nym-node-status-api/nym-node-status-client/src/lib.rs +++ b/nym-node-status-api/nym-node-status-client/src/lib.rs @@ -2,7 +2,7 @@ use crate::models::{TestrunAssignmentWithTickets, get_testrun, submit_results, s use anyhow::bail; use api::ApiPaths; use nym_crypto::asymmetric::ed25519::{PrivateKey, Signature}; -use tracing::{error, instrument, warn}; +use tracing::{debug, error, instrument, warn}; mod api; pub mod auth; @@ -81,11 +81,16 @@ impl NsApiClient { &self, testrun_id: i64, probe_result: nym_gateway_probe::ProbeResult, - probe_log: String, + mut probe_log: String, assigned_at_utc: i64, ) -> anyhow::Result<()> { let target_url = self.api.submit_results(testrun_id); + debug!("the log is {} long", probe_log.len()); + if probe_log.len() > 1024 { + probe_log.truncate(1024) + } + let payload = submit_results::Payload { probe_result, probe_log, From b5a8b9d2835cce96a6b715b87c6db3715a8bc400 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Sat, 23 May 2026 20:50:11 +0100 Subject: [PATCH 48/94] change default netstack download timeout to 30s --- Cargo.lock | 2 +- nym-gateway-probe/src/config/netstack.rs | 10 +++++----- nym-node-status-api/nym-node-status-agent/Cargo.toml | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b003821fbf..375edc2d14 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7747,7 +7747,7 @@ dependencies = [ [[package]] name = "nym-node-status-agent" -version = "2.0.1-rc1" +version = "2.0.1-rc2" dependencies = [ "anyhow", "clap", diff --git a/nym-gateway-probe/src/config/netstack.rs b/nym-gateway-probe/src/config/netstack.rs index 50251e835e..2d8ff10137 100644 --- a/nym-gateway-probe/src/config/netstack.rs +++ b/nym-gateway-probe/src/config/netstack.rs @@ -42,7 +42,7 @@ pub struct NetstackArgs { impl Default for NetstackArgs { fn default() -> Self { Self { - netstack_download_timeout_sec: 180, + netstack_download_timeout_sec: 30, metadata_timeout_sec: 30, netstack_v4_dns: String::from("1.1.1.1"), netstack_v6_dns: String::from("2606:4700:4700::1111"), @@ -72,7 +72,7 @@ mod tests { // Create a default instance to test the values let args = NetstackArgs { - netstack_download_timeout_sec: 180, + netstack_download_timeout_sec: 30, metadata_timeout_sec: 30, netstack_v4_dns: "1.1.1.1".to_string(), netstack_v6_dns: "2606:4700:4700::1111".to_string(), @@ -107,7 +107,7 @@ mod tests { assert_eq!(args.netstack_v6_dns, "2606:4700:4700::1111"); // Test other defaults - assert_eq!(args.netstack_download_timeout_sec, 180); + assert_eq!(args.netstack_download_timeout_sec, 30); assert_eq!(args.netstack_num_ping, 5); assert_eq!(args.netstack_send_timeout_sec, 3); assert_eq!(args.netstack_recv_timeout_sec, 3); @@ -146,7 +146,7 @@ mod tests { fn test_netstack_args_multiple_values() { // Test that multiple hosts and IPs can be stored let args = NetstackArgs { - netstack_download_timeout_sec: 180, + netstack_download_timeout_sec: 30, metadata_timeout_sec: 30, netstack_v4_dns: "1.1.1.1".to_string(), netstack_v6_dns: "2606:4700:4700::1111".to_string(), @@ -208,7 +208,7 @@ mod tests { fn test_netstack_args_domain_validation() { // Test that our domain choices are reasonable let args = NetstackArgs { - netstack_download_timeout_sec: 180, + netstack_download_timeout_sec: 30, metadata_timeout_sec: 30, netstack_v4_dns: "1.1.1.1".to_string(), netstack_v6_dns: "2606:4700:4700::1111".to_string(), diff --git a/nym-node-status-api/nym-node-status-agent/Cargo.toml b/nym-node-status-api/nym-node-status-agent/Cargo.toml index 19933a500d..96031146de 100644 --- a/nym-node-status-api/nym-node-status-agent/Cargo.toml +++ b/nym-node-status-api/nym-node-status-agent/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node-status-agent" -version = "2.0.1-rc1" +version = "2.0.1-rc2" authors.workspace = true edition.workspace = true license.workspace = true From dc0835f1f338bbe383c4c4692c8d46ae6cb47c8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 25 May 2026 11:38:51 +0100 Subject: [PATCH 49/94] more logs, timeouts and general duct taping --- Cargo.lock | 4 +-- nym-gateway-probe/netstack_ping/lib.go | 14 +++++------ nym-gateway-probe/src/common/probe_tests.rs | 25 +++++++++++++------ nym-gateway-probe/src/config/netstack.rs | 2 +- nym-gateway-probe/src/config/socks5.rs | 4 +-- nym-gateway-probe/src/lib.rs | 15 ++++++++++- .../nym-node-status-agent/Cargo.toml | 2 +- .../nym-node-status-agent/src/cli/mod.rs | 14 ++++++++--- .../nym-node-status-api/Cargo.toml | 2 +- .../nym-node-status-api/src/cli/mod.rs | 2 +- .../src/http/api/testruns.rs | 11 +++++++- 11 files changed, 67 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 375edc2d14..c71fe45850 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7747,7 +7747,7 @@ dependencies = [ [[package]] name = "nym-node-status-agent" -version = "2.0.1-rc2" +version = "2.0.1-rc3" dependencies = [ "anyhow", "clap", @@ -7768,7 +7768,7 @@ dependencies = [ [[package]] name = "nym-node-status-api" -version = "4.6.2-rc4" +version = "4.6.2-rc5" dependencies = [ "ammonia", "anyhow", diff --git a/nym-gateway-probe/netstack_ping/lib.go b/nym-gateway-probe/netstack_ping/lib.go index 7d04b7cbf2..a80af4bee5 100644 --- a/nym-gateway-probe/netstack_ping/lib.go +++ b/nym-gateway-probe/netstack_ping/lib.go @@ -330,7 +330,7 @@ func pingTwoHop(req TwoHopNetstackRequest) (NetstackResponse, error) { // Ping hosts (DNS resolution test) for _, host := range req.PingHosts { consecutiveFailures := 0 - maxConsecutiveFailures := 3 + maxConsecutiveFailures := 2 for i := uint8(0); i < req.NumPing; i++ { log.Printf("Pinging %s seq=%d (via two-hop)", host, i) @@ -355,7 +355,7 @@ func pingTwoHop(req TwoHopNetstackRequest) (NetstackResponse, error) { // Ping IPs (direct connectivity test) for _, ip := range req.PingIps { consecutiveFailures := 0 - maxConsecutiveFailures := 3 + maxConsecutiveFailures := 2 for i := uint8(0); i < req.NumPing; i++ { log.Printf("Pinging %s seq=%d (via two-hop)", ip, i) @@ -375,7 +375,7 @@ func pingTwoHop(req TwoHopNetstackRequest) (NetstackResponse, error) { } if i < req.NumPing-1 { - time.Sleep(5 * time.Second) + time.Sleep(1 * time.Second) } } } @@ -481,7 +481,7 @@ func ping(req NetstackRequestGo) (NetstackResponse, error) { for _, host := range req.PingHosts { consecutiveFailures := 0 - maxConsecutiveFailures := 3 + maxConsecutiveFailures := 2 for i := uint8(0); i < req.NumPing; i++ { log.Printf("Pinging %s seq=%d", host, i) @@ -509,7 +509,7 @@ func ping(req NetstackRequestGo) (NetstackResponse, error) { for _, ip := range req.PingIps { consecutiveFailures := 0 - maxConsecutiveFailures := 3 + maxConsecutiveFailures := 2 for i := uint8(0); i < req.NumPing; i++ { log.Printf("Pinging %s seq=%d", ip, i) @@ -533,7 +533,7 @@ func ping(req NetstackRequestGo) (NetstackResponse, error) { // Sleep between ping attempts (except for the last one) if i < req.NumPing-1 { - time.Sleep(5 * time.Second) + time.Sleep(1 * time.Second) } } } @@ -689,7 +689,7 @@ func downloadFileWithRetry(urls []string, timeoutSecs uint64, tnet *netstack.Net maxRetries := 3 baseDelay := 1 * time.Second consecutiveFailures := 0 - maxConsecutiveFailures := 3 + maxConsecutiveFailures := 2 for attempt := 0; attempt < maxRetries; attempt++ { // Shuffle URLs for each attempt to try different ones diff --git a/nym-gateway-probe/src/common/probe_tests.rs b/nym-gateway-probe/src/common/probe_tests.rs index d37a1042d2..c9fc0531b0 100644 --- a/nym-gateway-probe/src/common/probe_tests.rs +++ b/nym-gateway-probe/src/common/probe_tests.rs @@ -26,7 +26,7 @@ use nym_credentials_interface::{CredentialSpendingData, TicketType}; use nym_ip_packet_client::IprClientConnect; use nym_ip_packet_requests::{IpPair, codec::MultiIpPacketCodec}; use nym_lp::peer::DHKeyPair; -use nym_registration_client::LpRegistrationClient; +use nym_registration_client::{LpClientError, LpRegistrationClient}; use nym_sdk::NymNetworkDetails; use nym_sdk::mixnet::{MixnetClient, MixnetClientBuilder, NodeIdentity, Recipient, Socks5}; use nym_topology::HardcodedTopologyProvider; @@ -186,7 +186,11 @@ pub async fn lp_registration_probe( // LpRegistrationClient uses packet-per-connection model - connect() is gone, // connection is established during handshake and registration automatically. info!("Performing LP handshake at {lp_address}..."); - match client.perform_handshake().await { + let handshake_result = + tokio::time::timeout(Duration::from_secs(15), client.perform_handshake()) + .await + .unwrap_or_else(|_| Err(LpClientError::HandshakeTimeout)); + match handshake_result { Ok(_) => { info!("LP handshake completed successfully"); lp_outcome.can_connect = true; // Connection succeeded if handshake succeeded @@ -209,16 +213,23 @@ pub async fn lp_registration_probe( // Register using the new packet-per-connection API (returns GatewayData directly) let ticket_type = TicketType::V1WireguardEntry; - let gateway_data = match client - .register_dvpn( + let register_result = tokio::time::timeout( + Duration::from_secs(15), + client.register_dvpn( &mut rng09, &wg_keypair, &gateway_identity, bandwidth_controller, ticket_type, - ) - .await - { + ), + ) + .await + .unwrap_or_else(|_| { + Err(LpClientError::Other( + "LP registration timed out after 15s".to_string(), + )) + }); + let gateway_data = match register_result { Ok(data) => data, Err(e) => { let error_msg = format!("LP registration failed: {}", e); diff --git a/nym-gateway-probe/src/config/netstack.rs b/nym-gateway-probe/src/config/netstack.rs index 2d8ff10137..5fdd052413 100644 --- a/nym-gateway-probe/src/config/netstack.rs +++ b/nym-gateway-probe/src/config/netstack.rs @@ -43,7 +43,7 @@ impl Default for NetstackArgs { fn default() -> Self { Self { netstack_download_timeout_sec: 30, - metadata_timeout_sec: 30, + metadata_timeout_sec: 10, netstack_v4_dns: String::from("1.1.1.1"), netstack_v6_dns: String::from("2606:4700:4700::1111"), netstack_num_ping: 5, diff --git a/nym-gateway-probe/src/config/socks5.rs b/nym-gateway-probe/src/config/socks5.rs index 04045560ef..0eca0830fd 100644 --- a/nym-gateway-probe/src/config/socks5.rs +++ b/nym-gateway-probe/src/config/socks5.rs @@ -38,9 +38,9 @@ impl Default for Socks5Args { "https://cloudflare-eth.com".to_string(), "https://ethereum-rpc.publicnode.com".to_string(), ], - mixnet_client_timeout_sec: 30, + mixnet_client_timeout_sec: 20, test_count: 10, - failure_count_cutoff: 3, + failure_count_cutoff: 2, } } } diff --git a/nym-gateway-probe/src/lib.rs b/nym-gateway-probe/src/lib.rs index 582c80f89e..fe4dbffc47 100644 --- a/nym-gateway-probe/src/lib.rs +++ b/nym-gateway-probe/src/lib.rs @@ -135,7 +135,20 @@ impl Probe { // Mixnet client start let mixnet_client = if self.config.test_mode.needs_mixnet() { - Some(disconnected_mixnet_client.connect_to_mixnet().await) + Some( + tokio::time::timeout( + std::time::Duration::from_secs(30), + disconnected_mixnet_client.connect_to_mixnet(), + ) + .await + .unwrap_or_else(|_| { + Err(std::io::Error::new( + std::io::ErrorKind::TimedOut, + "mixnet connect timed out after 30s", + ) + .into()) + }), + ) } else { // Make sure keys are generated, in case we don't start the mixnet client let key_store = storage.key_store(); diff --git a/nym-node-status-api/nym-node-status-agent/Cargo.toml b/nym-node-status-api/nym-node-status-agent/Cargo.toml index 96031146de..46d25e8e28 100644 --- a/nym-node-status-api/nym-node-status-agent/Cargo.toml +++ b/nym-node-status-api/nym-node-status-agent/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node-status-agent" -version = "2.0.1-rc2" +version = "2.0.1-rc3" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/nym-node-status-api/nym-node-status-agent/src/cli/mod.rs b/nym-node-status-api/nym-node-status-agent/src/cli/mod.rs index a0cc67ccfb..d9ceaed452 100644 --- a/nym-node-status-api/nym-node-status-agent/src/cli/mod.rs +++ b/nym-node-status-api/nym-node-status-agent/src/cli/mod.rs @@ -3,6 +3,8 @@ use clap::{Parser, Subcommand}; use nym_bin_common::bin_info; use nym_crypto::asymmetric::ed25519::PrivateKey; use std::{env, sync::OnceLock}; +use tokio::time::Instant; +use tracing::info; pub(crate) mod generate_keypair; pub(crate) mod run_probe; @@ -81,17 +83,21 @@ impl Args { match parse_server_config(s) { Ok(config) => servers.push(config), Err(e) => { - tracing::error!("Invalid server config '{}': {}", s, e); - anyhow::bail!("Invalid server config '{}': {}", s, e); + tracing::error!("Invalid server config '{s}': {e}"); + anyhow::bail!("Invalid server config '{s}': {e}"); } } } - run_probe::run_probe(&servers, args.probe_config, log_capture) + let start = Instant::now(); + let res = run_probe::run_probe(&servers, args.probe_config, log_capture) .await .inspect_err(|err| { tracing::error!("{err}"); - })? + }); + info!("Probe completed in {:.2}ms", start.elapsed().as_secs_f32()); + + let _ = res?; } Command::GenerateKeypair { path } => { let path = path diff --git a/nym-node-status-api/nym-node-status-api/Cargo.toml b/nym-node-status-api/nym-node-status-api/Cargo.toml index 1fa2fff49f..783d8c9b8f 100644 --- a/nym-node-status-api/nym-node-status-api/Cargo.toml +++ b/nym-node-status-api/nym-node-status-api/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node-status-api" -version = "4.6.2-rc4" +version = "4.6.2-rc5" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/nym-node-status-api/nym-node-status-api/src/cli/mod.rs b/nym-node-status-api/nym-node-status-api/src/cli/mod.rs index 259b1ef0f4..e52a97ca32 100644 --- a/nym-node-status-api/nym-node-status-api/src/cli/mod.rs +++ b/nym-node-status-api/nym-node-status-api/src/cli/mod.rs @@ -76,7 +76,7 @@ pub(crate) struct Cli { #[clap( long, - default_value = "300", + default_value = "450", env = "NODE_STATUS_API_TESTRUN_REFRESH_INTERVAL" )] #[arg(value_parser = parse_duration_std)] diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs b/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs index b4c11164d1..8aa9160d18 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs @@ -11,6 +11,7 @@ use crate::{ }; use axum::Json; use axum::extract::DefaultBodyLimit; +use axum::extract::rejection::JsonRejection; use axum::{ Router, extract::{Path, State}, @@ -120,8 +121,16 @@ async fn request_testrun( async fn submit_testrun( Path(submitted_testrun_id): Path, State(state): State, - Json(submitted_result): Json, + submitted_result: Result, JsonRejection>, ) -> HttpResult { + let submitted_result = match submitted_result { + Ok(json) => json.0, + Err(err) => { + tracing::error!("json got rejected: {err}"); + return Err(HttpError::invalid_input(err)); + } + }; + state.authenticate_agent_submission(&submitted_result)?; debug!("attempting to submit testrun {submitted_testrun_id} from an authenticated agent"); From cf55e2fe86a3b931e592eaec6e652fb9636431ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 26 May 2026 10:18:39 +0100 Subject: [PATCH 50/94] fix nym-api config deserialisation + clippy --- nym-api/src/support/config/mod.rs | 2 ++ nym-node-status-api/nym-node-status-agent/src/cli/mod.rs | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/nym-api/src/support/config/mod.rs b/nym-api/src/support/config/mod.rs index c56943c573..81fce847f7 100644 --- a/nym-api/src/support/config/mod.rs +++ b/nym-api/src/support/config/mod.rs @@ -428,6 +428,7 @@ impl Default for MixnetContractCacheDebug { } #[derive(Debug, Deserialize, PartialEq, Serialize)] +#[serde(default)] pub struct PerformanceProvider { /// Specifies whether this nym-api should attempt to retrieve node performance /// information from the performance contract. @@ -448,6 +449,7 @@ impl Default for PerformanceProvider { } #[derive(Debug, Deserialize, PartialEq, Serialize)] +#[serde(default)] pub struct PerformanceProviderDebug { /// Specifies interval of polling the performance contract. Note it is only applicable /// if the contract data is being used. diff --git a/nym-node-status-api/nym-node-status-agent/src/cli/mod.rs b/nym-node-status-api/nym-node-status-agent/src/cli/mod.rs index d9ceaed452..8acd095fb9 100644 --- a/nym-node-status-api/nym-node-status-agent/src/cli/mod.rs +++ b/nym-node-status-api/nym-node-status-agent/src/cli/mod.rs @@ -95,9 +95,9 @@ impl Args { .inspect_err(|err| { tracing::error!("{err}"); }); - info!("Probe completed in {:.2}ms", start.elapsed().as_secs_f32()); + info!("Probe completed in {:.2}s", start.elapsed().as_secs_f32()); - let _ = res?; + res?; } Command::GenerateKeypair { path } => { let path = path From 4e52e9bf77f03fc1d94588dd69ab96b9d9e00358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 26 May 2026 10:58:05 +0100 Subject: [PATCH 51/94] fixed invalid ticket rejection --- Cargo.lock | 2 +- .../nym-node-status-api/Cargo.toml | 2 +- .../storage/auxiliary_models.rs | 5 +- nym-wallet/Cargo.lock | 569 +++++++++++++----- 4 files changed, 434 insertions(+), 144 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c71fe45850..edb985322c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7768,7 +7768,7 @@ dependencies = [ [[package]] name = "nym-node-status-api" -version = "4.6.2-rc5" +version = "4.6.2-rc6" dependencies = [ "ammonia", "anyhow", diff --git a/nym-node-status-api/nym-node-status-api/Cargo.toml b/nym-node-status-api/nym-node-status-api/Cargo.toml index 783d8c9b8f..2531e0bfca 100644 --- a/nym-node-status-api/nym-node-status-api/Cargo.toml +++ b/nym-node-status-api/nym-node-status-api/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node-status-api" -version = "4.6.2-rc5" +version = "4.6.2-rc6" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/nym-node-status-api/nym-node-status-api/src/ticketbook_manager/storage/auxiliary_models.rs b/nym-node-status-api/nym-node-status-api/src/ticketbook_manager/storage/auxiliary_models.rs index a40611ea08..3e97d1f67b 100644 --- a/nym-node-status-api/nym-node-status-api/src/ticketbook_manager/storage/auxiliary_models.rs +++ b/nym-node-status-api/nym-node-status-api/src/ticketbook_manager/storage/auxiliary_models.rs @@ -17,14 +17,15 @@ pub(crate) struct RetrievedTicketbook { impl RetrievedTicketbook { pub fn new(ticketbook: IssuedTicketBook) -> anyhow::Result { - let usable_index = ticketbook.spent_tickets() as u32 - 1; // spent_tickets is the post-increment number from the DB: the ticket we're // handing out has already been counted as "used" in the DB, but has NOT YET // been spent yet by the recipient. To get its 0-based index in the ticketbook, // subtract 1 (e.g. spent_tickets=1, the ticket at index 0). - if usable_index < 1 { + let spent = ticketbook.spent_tickets(); + if spent == 0 { bail!("Malformed ticket: cannot convert from ticket with spent_tickets=0"); } + let usable_index = (spent as u32) - 1; Ok(Self { usable_index, ticketbook, diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index cce78b4a2a..6c8d4c2a35 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -90,7 +90,7 @@ checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", - "cpufeatures", + "cpufeatures 0.2.17", ] [[package]] @@ -258,7 +258,7 @@ checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" dependencies = [ "base64ct", "blake2", - "cpufeatures", + "cpufeatures 0.2.17", "password-hash", ] @@ -505,7 +505,7 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -540,7 +540,7 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -1041,6 +1041,17 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" +[[package]] +name = "chacha20" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f8d983286843e49675a4b7a2d174efe136dc93a18d69130dd18198a6c167601" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "rand_core 0.10.1", +] + [[package]] name = "chrono" version = "0.4.40" @@ -1095,7 +1106,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -1343,7 +1354,7 @@ checksum = "a782b93fae93e57ca8ad3e9e994e784583f5933aeaaa5c80a545c4b437be2047" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -1367,7 +1378,7 @@ checksum = "e01c9214319017f6ebd8e299036e1f717fa9bb6724e758f7d6fb2477599d1a29" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -1403,6 +1414,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.4.2" @@ -1499,7 +1519,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -1515,7 +1535,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -1534,7 +1554,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "curve25519-dalek-derive", "digest 0.10.7", "fiat-crypto", @@ -1552,7 +1572,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -1684,7 +1704,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -1695,7 +1715,7 @@ checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -1744,7 +1764,7 @@ checksum = "30542c1ad912e0e3d22a1935c290e12e8a29d704a420177a31faad4a601a0800" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -1757,7 +1777,7 @@ dependencies = [ "proc-macro2", "quote", "rustc_version", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -1777,7 +1797,7 @@ checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", "unicode-xid", ] @@ -1840,7 +1860,7 @@ dependencies = [ "libc", "option-ext", "redox_users 0.5.0", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -1857,7 +1877,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -1880,7 +1900,7 @@ checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -2073,18 +2093,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" -[[package]] -name = "enum-as-inner" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" -dependencies = [ - "heck 0.5.0", - "proc-macro2", - "quote", - "syn 2.0.100", -] - [[package]] name = "enumflags2" version = "0.7.11" @@ -2103,7 +2111,7 @@ checksum = "fc4caf64a58d7a6d65ab00639b046ff54399a39f5f2554728895ace4b297cd79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -2283,6 +2291,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "foreign-types" version = "0.3.2" @@ -2310,7 +2324,7 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -2419,7 +2433,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -2627,11 +2641,25 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "r-efi", + "r-efi 5.2.0", "wasi 0.14.7+wasi-0.2.4", "wasm-bindgen", ] +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi 6.0.0", + "rand_core 0.10.1", + "wasip2", + "wasip3", +] + [[package]] name = "ghash" version = "0.5.1" @@ -2714,7 +2742,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -2804,7 +2832,7 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -2889,6 +2917,9 @@ name = "hashbrown" version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +dependencies = [ + "foldhash", +] [[package]] name = "hax-lib" @@ -2911,7 +2942,7 @@ dependencies = [ "proc-macro-error2", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -2979,28 +3010,25 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" [[package]] -name = "hickory-proto" -version = "0.25.1" +name = "hickory-net" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d844af74f7b799e41c78221be863bade11c430d46042c3b49ca8ae0c6d27287" +checksum = "e2295ed2f9c31e471e1428a8f88a3f0e1f4b27c15049592138d1eebe9c35b183" dependencies = [ - "async-recursion", "async-trait", "bytes", "cfg-if", - "critical-section", "data-encoding", - "enum-as-inner", "futures-channel", "futures-io", "futures-util", "h2 0.4.8", + "hickory-proto", "http 1.3.1", "idna", "ipnet", - "once_cell", - "rand 0.9.2", - "ring", + "jni 0.22.4", + "rand 0.10.1", "rustls 0.23.37", "thiserror 2.0.12", "tinyvec", @@ -3012,22 +3040,47 @@ dependencies = [ ] [[package]] -name = "hickory-resolver" -version = "0.25.2" +name = "hickory-proto" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc62a9a99b0bfb44d2ab95a7208ac952d31060efc16241c87eaf36406fecf87a" +checksum = "0bab31817bfb44672a252e97fe81cd0c18d1b2cf892108922f6818820df8c643" +dependencies = [ + "data-encoding", + "idna", + "ipnet", + "jni 0.22.4", + "once_cell", + "prefix-trie", + "rand 0.10.1", + "ring", + "thiserror 2.0.12", + "tinyvec", + "tracing", + "url", +] + +[[package]] +name = "hickory-resolver" +version = "0.26.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d58d28879ceecde6607729660c2667a081ccdc082e082675042793960f178c" dependencies = [ "cfg-if", "futures-util", + "hickory-net", "hickory-proto", "ipconfig", + "ipnet", + "jni 0.22.4", "moka", + "ndk-context", "once_cell", "parking_lot", - "rand 0.9.2", + "rand 0.10.1", "resolv-conf", "rustls 0.23.37", "smallvec", + "system-configuration 0.7.0", "thiserror 2.0.12", "tokio", "tokio-rustls 0.26.2", @@ -3321,7 +3374,7 @@ dependencies = [ "js-sys", "log", "wasm-bindgen", - "windows-core 0.60.1", + "windows-core 0.61.2", ] [[package]] @@ -3458,9 +3511,15 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + [[package]] name = "ident_case" version = "1.0.1" @@ -3584,6 +3643,9 @@ name = "ipnet" version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +dependencies = [ + "serde", +] [[package]] name = "iri-string" @@ -3687,19 +3749,68 @@ dependencies = [ "cesu8", "cfg-if", "combine", - "jni-sys", + "jni-sys 0.3.0", "log", "thiserror 1.0.69", "walkdir", "windows-sys 0.45.0", ] +[[package]] +name = "jni" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" +dependencies = [ + "cfg-if", + "combine", + "jni-macros", + "jni-sys 0.4.1", + "log", + "simd_cesu8", + "thiserror 2.0.12", + "walkdir", + "windows-link 0.2.1", +] + +[[package]] +name = "jni-macros" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" +dependencies = [ + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.117", +] + [[package]] name = "jni-sys" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.117", +] + [[package]] name = "jobserver" version = "0.1.33" @@ -3822,6 +3933,12 @@ dependencies = [ "spin", ] +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + [[package]] name = "libappindicator" version = "0.9.0" @@ -3978,7 +4095,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ffd6aa2dcd5be681662001b81d493f1569c6d49a32361f470b0c955465cd0338" dependencies = [ "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -4212,7 +4329,7 @@ checksum = "88a9689d8d44bf9964484516275f5cd4c9b59457a6940c1d5d0ecbb94510a36b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -4348,7 +4465,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ "bitflags 2.9.0", - "jni-sys", + "jni-sys 0.3.0", "log", "ndk-sys", "num_enum", @@ -4368,7 +4485,7 @@ version = "0.6.0+11769913" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee6cda3051665f1fb8d9e08fc35c96d5a244fb1be711a03b71118828afc9a873" dependencies = [ - "jni-sys", + "jni-sys 0.3.0", ] [[package]] @@ -4484,7 +4601,7 @@ dependencies = [ "proc-macro-crate 3.3.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -4766,7 +4883,7 @@ dependencies = [ "proc-macro-crate 3.3.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", "uuid", ] @@ -5342,7 +5459,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -5609,7 +5726,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -5737,7 +5854,7 @@ dependencies = [ "phf_shared 0.11.3", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -5784,7 +5901,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -5885,7 +6002,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "opaque-debug", "universal-hash", ] @@ -5917,6 +6034,17 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" +[[package]] +name = "prefix-trie" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cf6e3177f0684016a5c209b00882e15f8bdd3f3bb48f0491df10cd102d0c6e7" +dependencies = [ + "either", + "ipnet", + "num-traits", +] + [[package]] name = "pretty_env_logger" version = "0.4.0" @@ -5927,6 +6055,16 @@ dependencies = [ "log", ] +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn 2.0.117", +] + [[package]] name = "primeorder" version = "0.13.6" @@ -6007,7 +6145,7 @@ dependencies = [ "proc-macro-error-attr2", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -6045,7 +6183,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -6148,6 +6286,12 @@ version = "5.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + [[package]] name = "rand" version = "0.7.3" @@ -6183,6 +6327,17 @@ dependencies = [ "rand_core 0.9.3", ] +[[package]] +name = "rand" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2e8e8bcc7961af1fdac401278c6a831614941f6164ee3bf4ce61b7edb162207" +dependencies = [ + "chacha20", + "getrandom 0.4.2", + "rand_core 0.10.1", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -6240,6 +6395,12 @@ dependencies = [ "getrandom 0.3.3", ] +[[package]] +name = "rand_core" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63b8176103e19a2643978565ca18b50549f6101881c443590420e4dc998a3c69" + [[package]] name = "rand_hc" version = "0.2.0" @@ -6607,7 +6768,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.12.1", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -6698,7 +6859,7 @@ checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" dependencies = [ "core-foundation 0.10.0", "core-foundation-sys", - "jni", + "jni 0.21.1", "log", "once_cell", "rustls 0.23.37", @@ -6708,7 +6869,7 @@ dependencies = [ "security-framework 3.5.1", "security-framework-sys", "webpki-root-certs", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -6793,7 +6954,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -6960,7 +7121,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -6971,7 +7132,7 @@ checksum = "18d26a20a969b9e3fdf2fc2d9f21eda6c40e2de84c9408bb5d3b05d499aae711" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -7003,7 +7164,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -7063,7 +7224,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -7118,7 +7279,7 @@ checksum = "772ee033c0916d670af7860b6e1ef7d658a4629a6d0b4c8c3e67f09b3765b75d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -7139,7 +7300,7 @@ checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" dependencies = [ "block-buffer 0.9.0", "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest 0.9.0", "opaque-debug", ] @@ -7151,7 +7312,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "digest 0.10.7", ] @@ -7195,6 +7356,22 @@ version = "0.3.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" +[[package]] +name = "simd_cesu8" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +dependencies = [ + "rustc_version", + "simdutf8", +] + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + [[package]] name = "siphasher" version = "0.3.11" @@ -7376,7 +7553,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -7388,7 +7565,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -7449,9 +7626,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.100" +version = "2.0.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" dependencies = [ "proc-macro2", "quote", @@ -7481,7 +7658,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -7506,6 +7683,17 @@ dependencies = [ "system-configuration-sys 0.6.0", ] +[[package]] +name = "system-configuration" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a13f3d0daba03132c0aa9767f98351b3488edc2c100cda2d2ec2b04f3d8d3c8b" +dependencies = [ + "bitflags 2.9.0", + "core-foundation 0.9.4", + "system-configuration-sys 0.6.0", +] + [[package]] name = "system-configuration-sys" version = "0.5.0" @@ -7562,7 +7750,7 @@ dependencies = [ "gdkwayland-sys", "gdkx11-sys", "gtk", - "jni", + "jni 0.21.1", "lazy_static", "libc", "log", @@ -7593,7 +7781,7 @@ checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -7636,7 +7824,7 @@ dependencies = [ "gtk", "heck 0.5.0", "http 1.3.1", - "jni", + "jni 0.21.1", "libc", "log", "mime", @@ -7710,7 +7898,7 @@ dependencies = [ "serde", "serde_json", "sha2 0.10.9", - "syn 2.0.100", + "syn 2.0.117", "tauri-utils", "thiserror 2.0.12", "time", @@ -7728,7 +7916,7 @@ dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", "tauri-codegen", "tauri-utils", ] @@ -7840,7 +8028,7 @@ dependencies = [ "dpi", "gtk", "http 1.3.1", - "jni", + "jni 0.21.1", "objc2 0.6.0", "objc2-ui-kit", "objc2-web-kit", @@ -7863,7 +8051,7 @@ checksum = "e11ea2e6f801d275fdd890d6c9603736012742a1c33b96d0db788c9cdebf7f9e" dependencies = [ "gtk", "http 1.3.1", - "jni", + "jni 0.21.1", "log", "objc2 0.6.0", "objc2-app-kit", @@ -7939,7 +8127,7 @@ dependencies = [ "getrandom 0.3.3", "once_cell", "rustix 1.1.4", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -8080,7 +8268,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -8091,7 +8279,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -8191,7 +8379,7 @@ checksum = "2d2e76690929402faae40aebdda620a2c0e25dd6d3b9afe48867dfd95991f4bd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -8222,7 +8410,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -8448,7 +8636,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -8549,7 +8737,7 @@ checksum = "38d90eea51bc7988ef9e674bf80a85ba6804739e535e9cab48e4bb34a8b652aa" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", "termcolor", ] @@ -8740,7 +8928,7 @@ checksum = "a77d306bc75294fd52f3e99b13ece67c02c1a2789190a6f31d32f736624326f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -8861,6 +9049,15 @@ dependencies = [ "wit-bindgen", ] +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen", +] + [[package]] name = "wasix" version = "0.12.21" @@ -8912,7 +9109,7 @@ dependencies = [ "bumpalo", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", "wasm-bindgen-shared", ] @@ -8925,6 +9122,28 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap 2.8.0", + "wasm-encoder", + "wasmparser", +] + [[package]] name = "wasm-streams" version = "0.5.0" @@ -8938,6 +9157,18 @@ dependencies = [ "web-sys", ] +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags 2.9.0", + "hashbrown 0.15.2", + "indexmap 2.8.0", + "semver", +] + [[package]] name = "wasmtimer" version = "0.4.1" @@ -9097,9 +9328,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.8" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9" +checksum = "52f5ee44c96cf55f1b349600768e3ece3a8f26010c05265ab73f945bb1a2eb9d" dependencies = [ "rustls-pki-types", ] @@ -9126,7 +9357,7 @@ checksum = "67a921c1b6914c367b2b823cd4cde6f96beec77d30a939c8199bb377cf9b9b54" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -9262,19 +9493,6 @@ dependencies = [ "windows-targets 0.52.6", ] -[[package]] -name = "windows-core" -version = "0.60.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca21a92a9cae9bf4ccae5cf8368dce0837100ddf6e6d57936749e85f152f6247" -dependencies = [ - "windows-implement 0.59.0", - "windows-interface 0.59.1", - "windows-link 0.1.3", - "windows-result 0.3.4", - "windows-strings 0.3.1", -] - [[package]] name = "windows-core" version = "0.61.2" @@ -9307,18 +9525,7 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", -] - -[[package]] -name = "windows-implement" -version = "0.59.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83577b051e2f49a058c308f17f273b570a6a758386fc291b5f6a934dd84e48c1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -9329,7 +9536,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -9340,7 +9547,7 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -9351,7 +9558,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -9797,6 +10004,88 @@ name = "wit-bindgen" version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck 0.5.0", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck 0.5.0", + "indexmap 2.8.0", + "prettyplease", + "syn 2.0.117", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn 2.0.117", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags 2.9.0", + "indexmap 2.8.0", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap 2.8.0", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] [[package]] name = "wl-clipboard-rs" @@ -9847,7 +10136,7 @@ dependencies = [ "html5ever", "http 1.3.1", "javascriptcore-rs", - "jni", + "jni 0.21.1", "kuchikiki", "libc", "ndk", @@ -9954,7 +10243,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", "synstructure", ] @@ -10002,7 +10291,7 @@ dependencies = [ "proc-macro-crate 3.3.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", "zbus_names", "zvariant", "zvariant_utils", @@ -10045,7 +10334,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -10056,7 +10345,7 @@ checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -10076,7 +10365,7 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", "synstructure", ] @@ -10098,7 +10387,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -10120,7 +10409,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", ] [[package]] @@ -10186,7 +10475,7 @@ dependencies = [ "proc-macro-crate 3.3.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.117", "zvariant_utils", ] @@ -10199,6 +10488,6 @@ dependencies = [ "proc-macro2", "quote", "serde", - "syn 2.0.100", + "syn 2.0.117", "winnow 0.7.10", ] From 343a48c297e46fdcf280adc76f8714435c3fd73d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 26 May 2026 13:38:29 +0100 Subject: [PATCH 52/94] bugfix: fix axum 0.8 migration in mix-stress testing endpoints (#6824) --- nym-api/src/nym_nodes/handlers/v2.rs | 2 +- nym-api/src/nym_nodes/handlers/v3.rs | 2 +- nym-api/src/support/http/router.rs | 14 ++++++++++++++ .../src/lib.rs | 6 +++--- .../src/http/api/v1/mod.rs | 17 +++++++++++++++++ 5 files changed, 36 insertions(+), 5 deletions(-) diff --git a/nym-api/src/nym_nodes/handlers/v2.rs b/nym-api/src/nym_nodes/handlers/v2.rs index 75f60d1316..168c6ebae2 100644 --- a/nym-api/src/nym_nodes/handlers/v2.rs +++ b/nym-api/src/nym_nodes/handlers/v2.rs @@ -15,7 +15,7 @@ use tower_http::compression::CompressionLayer; pub(crate) fn routes() -> Router { Router::new() .route("/described", get(get_described_nodes)) - .route("/annotation/:node_id", get(get_node_annotation)) + .route("/annotation/{node_id}", get(get_node_annotation)) .layer(CompressionLayer::new()) } diff --git a/nym-api/src/nym_nodes/handlers/v3.rs b/nym-api/src/nym_nodes/handlers/v3.rs index 20dbfe9bdc..0e003c1df3 100644 --- a/nym-api/src/nym_nodes/handlers/v3.rs +++ b/nym-api/src/nym_nodes/handlers/v3.rs @@ -169,7 +169,7 @@ async fn known_network_monitor( fn stress_testing_routes() -> Router { Router::new() .route("/batch-submit", post(batch_submit_stress_testing_results)) - .route("/known-monitors/:identity_key", get(known_network_monitor)) + .route("/known-monitors/{identity_key}", get(known_network_monitor)) } /// Build the `/v3/nym-nodes` subtree hosting the v3 network-monitor endpoints. diff --git a/nym-api/src/support/http/router.rs b/nym-api/src/support/http/router.rs index 411aab7345..693cada180 100644 --- a/nym-api/src/support/http/router.rs +++ b/nym-api/src/support/http/router.rs @@ -167,3 +167,17 @@ impl ApiHttpServer { .await } } + +#[cfg(test)] +mod tests { + use super::*; + + /// Axum 0.8 panics inside `.route(...)` when given the legacy `:param` + /// path syntax. That panic never fires at `cargo check` time, so a regression + /// only surfaces when nym-api boots. This test exercises the whole route tree + /// to catch such regressions in CI. + #[test] + fn default_router_builds_without_panic() { + let _ = RouterBuilder::with_default_routes(false, None); + } +} diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/src/lib.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/src/lib.rs index 34b32f9c01..3d688de98a 100644 --- a/nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/src/lib.rs +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator-requests/src/lib.rs @@ -61,9 +61,9 @@ pub mod routes { pub mod results { use super::*; - pub const TESTRUN_BY_ID: &str = "/testrun/:id"; - pub const NYM_NODE_BY_NODE_ID: &str = "/nym-node/:node_id"; - pub const NYM_NODE_TESTRUNS: &str = "/nym-node/:node_id/testruns"; + pub const TESTRUN_BY_ID: &str = "/testrun/{id}"; + pub const NYM_NODE_BY_NODE_ID: &str = "/nym-node/{node_id}"; + pub const NYM_NODE_TESTRUNS: &str = "/nym-node/{node_id}/testruns"; pub const TESTRUNS_IN_PROGRESS: &str = "/testruns-in-progress"; pub const TESTRUNS: &str = "/testruns"; pub const NYM_NODES: &str = "/nym-nodes"; diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/mod.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/mod.rs index 26b039adc3..cf948f6766 100644 --- a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/mod.rs +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/http/api/v1/mod.rs @@ -27,3 +27,20 @@ pub(crate) fn routes( .route_layer(metrics_and_results_auth), ) } + +#[cfg(test)] +mod tests { + use super::*; + use std::sync::Arc; + use zeroize::Zeroizing; + + /// Axum 0.8 panics inside `.route(...)` when given the legacy `:param` + /// path syntax. That panic never fires at `cargo check` time, so a regression + /// only surfaces when the orchestrator boots. This test exercises the whole + /// v1 route tree to catch such regressions in CI. + #[test] + fn v1_router_builds_without_panic() { + let dummy_auth = || AuthLayer::new(Arc::new(Zeroizing::new(String::new()))); + let _ = routes(dummy_auth(), dummy_auth()); + } +} From a8cecb1200dda0555919242cd6a7f13da5020edb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 26 May 2026 14:05:24 +0100 Subject: [PATCH 53/94] additional logs for quorum failures + increase staleness threshold --- Cargo.lock | 2 +- common/ecash-signer-check-types/src/helper_traits.rs | 10 ++++++---- common/ecash-signer-check-types/src/status.rs | 7 +++++-- nym-node-status-api/nym-node-status-api/Cargo.toml | 2 +- 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index edb985322c..df8edbb4ba 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7768,7 +7768,7 @@ dependencies = [ [[package]] name = "nym-node-status-api" -version = "4.6.2-rc6" +version = "4.6.2-rc7" dependencies = [ "ammonia", "anyhow", diff --git a/common/ecash-signer-check-types/src/helper_traits.rs b/common/ecash-signer-check-types/src/helper_traits.rs index c6d6becd33..74ac23fce2 100644 --- a/common/ecash-signer-check-types/src/helper_traits.rs +++ b/common/ecash-signer-check-types/src/helper_traits.rs @@ -36,6 +36,7 @@ pub trait ChainResponse: Verifiable + TimestampedResponse { // we rely on information provided from the api itself AS LONG AS it's not too outdated if self.timestamp() + stale_response_threshold < now { + warn!("chain status response is stale"); return false; } self.chain_synced() @@ -96,26 +97,27 @@ pub trait SignerResponse: Verifiable + TimestampedResponse { // we rely on information provided from the api itself AS LONG AS it's not too outdated if self.timestamp() + stale_response_threshold < now { + warn!("stale signer response"); return false; } if !self.has_signing_keys() { - debug!("missing signing keys"); + warn!("missing signing keys"); return false; } if self.signer_disabled() { - debug!("signer functionalities explicitly disabled"); + warn!("signer functionalities are explicitly disabled"); return false; } if !self.is_ecash_signer() { - debug!("signer doesn't recognise it's a signer for this epoch"); + warn!("signer doesn't recognise it's a signer for this epoch"); return false; } if dkg_epoch_id != self.dkg_ecash_epoch_id() { - debug!( + warn!( "mismatched dkg epoch id. current: {dkg_epoch_id}, signer's: {}", self.dkg_ecash_epoch_id() ); diff --git a/common/ecash-signer-check-types/src/status.rs b/common/ecash-signer-check-types/src/status.rs index ea07862633..8ad6dd949f 100644 --- a/common/ecash-signer-check-types/src/status.rs +++ b/common/ecash-signer-check-types/src/status.rs @@ -11,10 +11,11 @@ use nym_crypto::asymmetric::ed25519; use serde::{Deserialize, Serialize}; use std::time::Duration; use time::OffsetDateTime; +use tracing::warn; use utoipa::ToSchema; -pub(crate) const CHAIN_STALL_THRESHOLD: Duration = Duration::from_secs(5 * 60); -pub(crate) const STALE_RESPONSE_THRESHOLD: Duration = Duration::from_secs(5 * 60); +pub(crate) const CHAIN_STALL_THRESHOLD: Duration = Duration::from_secs(10 * 60); +pub(crate) const STALE_RESPONSE_THRESHOLD: Duration = Duration::from_secs(10 * 60); // the reason for generics is not to remove duplication of code, // but because without them, we'd be having problems with circular dependencies, @@ -188,6 +189,7 @@ where }; let SignerStatus::Tested { result } = &self.status else { + warn!("no valid chain response"); return false; }; result @@ -239,6 +241,7 @@ where }; let SignerStatus::Tested { result } = &self.status else { + warn!("no valid signer response"); return false; }; result.signing_status.signing_available( diff --git a/nym-node-status-api/nym-node-status-api/Cargo.toml b/nym-node-status-api/nym-node-status-api/Cargo.toml index 2531e0bfca..6e90c3cfe7 100644 --- a/nym-node-status-api/nym-node-status-api/Cargo.toml +++ b/nym-node-status-api/nym-node-status-api/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node-status-api" -version = "4.6.2-rc6" +version = "4.6.2-rc7" authors.workspace = true edition.workspace = true license.workspace = true From 25eba09b92cff648cd37bdd7f0921e710eed25f5 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Wed, 27 May 2026 11:00:31 +0200 Subject: [PATCH 54/94] update changelog --- CHANGELOG.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e58f5e8b5f..6842a3435b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,52 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// ## [Unreleased] +## [2026.10-waterloo] (2026-05-27) + +- Re-order default API urls for network details - Waterloo release ([#6799]) +- [bugfix] IPR v8<->v9 mismatch on Waterloo ([#6772]) +- Migrate to hickory 0.26.1 ([#6751]) +- add workflows for NM3 ([#6729]) +- credential proxy pool ([#6726]) +- chore: made sphinx version threshold assertion a compile time check ([#6718]) +- Feat/nmv3 updated performance calculation ([#6714]) +- feat: NMv3: submission of stress testing result into nym-api ([#6709]) +- feat: NMv3: Prometheus metrics for network monitor ([#6693]) +- feat: NMv3: add read-only results API to orchestrator ([#6689]) +- feat: NMv3: Eviction of stale testrun data ([#6685]) +- feat: NMv3: Wire up testrun assignment and result submission flow ([#6680]) +- feat: NMv3: Support multiple network monitor agents per host ([#6679]) +- Feat/nmv3 agent announcement ([#6673]) +- add node refresher for periodic scraping of bonded nym-node details ([#6626]) +- Feat/nmv3 orchestrator queue ([#6597]) +- feat: network monitor agent - standalone node stress-testing ([#6582]) +- [feat] propagate NM agent noise keys to nym-node routing ([#6577]) +- start mix stress testing topic branch ([#6575]) +- Feat/nmv3 agents subscription ([#6567]) +- Feat/nmv3 agents contract ([#6555]) + +[#6799]: https://github.com/nymtech/nym/pull/6799 +[#6772]: https://github.com/nymtech/nym/pull/6772 +[#6751]: https://github.com/nymtech/nym/pull/6751 +[#6729]: https://github.com/nymtech/nym/pull/6729 +[#6726]: https://github.com/nymtech/nym/pull/6726 +[#6718]: https://github.com/nymtech/nym/pull/6718 +[#6714]: https://github.com/nymtech/nym/pull/6714 +[#6709]: https://github.com/nymtech/nym/pull/6709 +[#6693]: https://github.com/nymtech/nym/pull/6693 +[#6689]: https://github.com/nymtech/nym/pull/6689 +[#6685]: https://github.com/nymtech/nym/pull/6685 +[#6680]: https://github.com/nymtech/nym/pull/6680 +[#6679]: https://github.com/nymtech/nym/pull/6679 +[#6673]: https://github.com/nymtech/nym/pull/6673 +[#6626]: https://github.com/nymtech/nym/pull/6626 +[#6597]: https://github.com/nymtech/nym/pull/6597 +[#6582]: https://github.com/nymtech/nym/pull/6582 +[#6577]: https://github.com/nymtech/nym/pull/6577 +[#6575]: https://github.com/nymtech/nym/pull/6575 +[#6567]: https://github.com/nymtech/nym/pull/6567 +[#6555]: https://github.com/nymtech/nym/pull/6555 + ## [2026.9-venaco] (2026-05-06) - Fix for v9 IPR ([#6710]) From 7310d63f1b15f4ded8bbcb0cbf9a9eecc271daa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 27 May 2026 14:17:50 +0100 Subject: [PATCH 55/94] chore: remove unused import --- common/ecash-signer-check-types/src/helper_traits.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/ecash-signer-check-types/src/helper_traits.rs b/common/ecash-signer-check-types/src/helper_traits.rs index 74ac23fce2..814d61f208 100644 --- a/common/ecash-signer-check-types/src/helper_traits.rs +++ b/common/ecash-signer-check-types/src/helper_traits.rs @@ -6,7 +6,7 @@ use nym_coconut_dkg_common::verification_key::VerificationKeyShare; use nym_crypto::asymmetric::ed25519; use std::time::Duration; use time::OffsetDateTime; -use tracing::{debug, warn}; +use tracing::warn; pub trait Verifiable { fn verify_signature(&self, pub_key: &ed25519::PublicKey) -> bool; From 86021937df7ffac22092942b989d196c7da9523b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 28 May 2026 09:12:32 +0100 Subject: [PATCH 56/94] feat: implement UpdateFamily for the node families contract (#6834) --- .../node_families_signing_client.rs | 27 ++ .../node-families-contract/src/constants.rs | 10 + .../node-families-contract/src/msg.rs | 10 + .../node-families/schema/node-families.json | 28 ++ .../node-families/schema/raw/execute.json | 28 ++ contracts/node-families/src/contract.rs | 6 +- contracts/node-families/src/helpers.rs | 76 ++- contracts/node-families/src/storage/mod.rs | 72 ++- contracts/node-families/src/testing.rs | 10 +- contracts/node-families/src/transactions.rs | 437 ++++++++++++++++-- openspec/specs/node-families-contract/spec.md | 53 ++- 11 files changed, 702 insertions(+), 55 deletions(-) diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/node_families_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/node_families_signing_client.rs index 34690c8be5..422b38e335 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/node_families_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/node_families_signing_client.rs @@ -54,6 +54,27 @@ pub trait NodeFamiliesSigningClient { .await } + /// Update the name and/or description of the caller's family. Each + /// argument follows `None = keep` / `Some(_) = replace` semantics; a + /// call with both `None` is a server-side no-op. + async fn update_family( + &self, + updated_name: Option, + updated_description: Option, + fee: Option, + ) -> Result { + self.execute_node_families_contract( + fee, + NodeFamiliesExecuteMsg::UpdateFamily { + updated_name, + updated_description, + }, + "NodeFamiliesContract::UpdateFamily".to_string(), + vec![], + ) + .await + } + async fn disband_family(&self, fee: Option) -> Result { self.execute_node_families_contract( fee, @@ -224,6 +245,12 @@ mod tests { NodeFamiliesExecuteMsg::CreateFamily { name, description } => client .create_family(name, description, None, vec![]) .ignore(), + NodeFamiliesExecuteMsg::UpdateFamily { + updated_name, + updated_description, + } => client + .update_family(updated_name, updated_description, None) + .ignore(), NodeFamiliesExecuteMsg::DisbandFamily {} => client.disband_family(None).ignore(), NodeFamiliesExecuteMsg::InviteToFamily { node_id, diff --git a/common/cosmwasm-smart-contracts/node-families-contract/src/constants.rs b/common/cosmwasm-smart-contracts/node-families-contract/src/constants.rs index 372b2b9d9e..5ef0f48c74 100644 --- a/common/cosmwasm-smart-contracts/node-families-contract/src/constants.rs +++ b/common/cosmwasm-smart-contracts/node-families-contract/src/constants.rs @@ -101,4 +101,14 @@ pub mod events { pub const NODE_UNBOND_CLEANUP_EVENT_NAME: &str = "family_node_unbond_cleanup"; pub const NODE_UNBOND_CLEANUP_EVENT_NODE_ID: &str = "node_id"; + + pub const FAMILY_UPDATE_EVENT_NAME: &str = "family_update"; + pub const FAMILY_UPDATE_EVENT_FAMILY_ID: &str = "family_id"; + pub const FAMILY_UPDATE_EVENT_OWNER_ADDRESS: &str = "owner_address"; + /// Attribute carrying the new family name. Only emitted when the + /// `UpdateFamily` message carried `updated_name = Some(_)`. + pub const FAMILY_UPDATE_EVENT_UPDATED_NAME: &str = "updated_name"; + /// Attribute carrying the new family description. Only emitted when the + /// `UpdateFamily` message carried `updated_description = Some(_)`. + pub const FAMILY_UPDATE_EVENT_UPDATED_DESCRIPTION: &str = "updated_description"; } diff --git a/common/cosmwasm-smart-contracts/node-families-contract/src/msg.rs b/common/cosmwasm-smart-contracts/node-families-contract/src/msg.rs index b5a509edcf..a542a0b707 100644 --- a/common/cosmwasm-smart-contracts/node-families-contract/src/msg.rs +++ b/common/cosmwasm-smart-contracts/node-families-contract/src/msg.rs @@ -38,6 +38,16 @@ pub enum ExecuteMsg { /// `create_family_fee` must be attached as funds. CreateFamily { name: String, description: String }, + /// Update the name and/or description of the family owned by the message + /// sender. Each field is independently optional: `None` leaves the + /// existing value unchanged, `Some(_)` replaces it. Updated values are + /// validated against the same length / normalisation / global-uniqueness + /// rules as [`Self::CreateFamily`]. + UpdateFamily { + updated_name: Option, + updated_description: Option, + }, + /// Disband the family owned by the message sender. The family must have /// no current members; any still-pending invitations are revoked. DisbandFamily {}, diff --git a/contracts/node-families/schema/node-families.json b/contracts/node-families/schema/node-families.json index b9165c7546..9a731548ba 100644 --- a/contracts/node-families/schema/node-families.json +++ b/contracts/node-families/schema/node-families.json @@ -135,6 +135,34 @@ }, "additionalProperties": false }, + { + "description": "Update the name and/or description of the family owned by the message sender. Each field is independently optional: `None` leaves the existing value unchanged, `Some(_)` replaces it. Updated values are validated against the same length / normalisation / global-uniqueness rules as [`Self::CreateFamily`].", + "type": "object", + "required": [ + "update_family" + ], + "properties": { + "update_family": { + "type": "object", + "properties": { + "updated_description": { + "type": [ + "string", + "null" + ] + }, + "updated_name": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, { "description": "Disband the family owned by the message sender. The family must have no current members; any still-pending invitations are revoked.", "type": "object", diff --git a/contracts/node-families/schema/raw/execute.json b/contracts/node-families/schema/raw/execute.json index 7b06d071f0..729559190c 100644 --- a/contracts/node-families/schema/raw/execute.json +++ b/contracts/node-families/schema/raw/execute.json @@ -51,6 +51,34 @@ }, "additionalProperties": false }, + { + "description": "Update the name and/or description of the family owned by the message sender. Each field is independently optional: `None` leaves the existing value unchanged, `Some(_)` replaces it. Updated values are validated against the same length / normalisation / global-uniqueness rules as [`Self::CreateFamily`].", + "type": "object", + "required": [ + "update_family" + ], + "properties": { + "update_family": { + "type": "object", + "properties": { + "updated_description": { + "type": [ + "string", + "null" + ] + }, + "updated_name": { + "type": [ + "string", + "null" + ] + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, { "description": "Disband the family owned by the message sender. The family must have no current members; any still-pending invitations are revoked.", "type": "object", diff --git a/contracts/node-families/src/contract.rs b/contracts/node-families/src/contract.rs index 64d37f6df8..54918514ca 100644 --- a/contracts/node-families/src/contract.rs +++ b/contracts/node-families/src/contract.rs @@ -16,7 +16,7 @@ use crate::storage::NodeFamiliesStorage; use crate::transactions::{ try_accept_family_invitation, try_create_family, try_disband_family, try_handle_node_unbonding, try_invite_to_family, try_kick_from_family, try_leave_family, try_reject_family_invitation, - try_revoke_family_invitation, try_update_config, + try_revoke_family_invitation, try_update_config, try_update_family, }; use cosmwasm_std::{ entry_point, to_json_binary, Binary, Deps, DepsMut, Env, MessageInfo, Response, @@ -69,6 +69,10 @@ pub fn execute( ExecuteMsg::CreateFamily { name, description } => { try_create_family(deps, env, info, name, description) } + ExecuteMsg::UpdateFamily { + updated_name, + updated_description, + } => try_update_family(deps, env, info, updated_name, updated_description), ExecuteMsg::DisbandFamily {} => try_disband_family(deps, env, info), ExecuteMsg::InviteToFamily { node_id, diff --git a/contracts/node-families/src/helpers.rs b/contracts/node-families/src/helpers.rs index 03ba312779..4f62720bff 100644 --- a/contracts/node-families/src/helpers.rs +++ b/contracts/node-families/src/helpers.rs @@ -4,7 +4,7 @@ use crate::storage::NodeFamiliesStorage; use cosmwasm_std::{Addr, Deps}; use nym_mixnet_contract_common::{MixnetContractQuerier, NodeId}; -use nym_node_families_contract_common::NodeFamiliesContractError; +use nym_node_families_contract_common::{Config, NodeFamiliesContractError, NodeFamilyId}; /// Normalise a family name into the canonical form used as the unique-index key. /// @@ -18,6 +18,80 @@ pub fn normalise_family_name(name: &str) -> String { .collect() } +/// A new `(display, normalised)` family name pair that has passed +/// length and non-empty-after-normalisation validation. Constructed by +/// [`validate_family_name`]; consumed by storage write paths that update +/// the family's `name` + `normalised_name` columns together. +pub(crate) struct NewFamilyName { + pub(crate) name: String, + pub(crate) normalised_name: String, +} + +/// Validate a candidate family name against [`Config::family_name_length_limit`] +/// and the non-empty-after-normalisation rule, returning the paired display + +/// normalised forms. The caller is responsible for the uniqueness check +/// against existing families (see [`ensure_normalised_name_unique`]). +pub(crate) fn validate_family_name( + name: String, + config: &Config, +) -> Result { + if name.len() > config.family_name_length_limit { + return Err(NodeFamiliesContractError::FamilyNameTooLong { + length: name.len(), + limit: config.family_name_length_limit, + }); + } + let normalised_name = normalise_family_name(&name); + if normalised_name.is_empty() { + return Err(NodeFamiliesContractError::EmptyFamilyName); + } + Ok(NewFamilyName { + name, + normalised_name, + }) +} + +/// Validate a candidate family description against +/// [`Config::family_description_length_limit`]. +pub(crate) fn validate_family_description( + description: &str, + config: &Config, +) -> Result<(), NodeFamiliesContractError> { + if description.len() > config.family_description_length_limit { + return Err(NodeFamiliesContractError::FamilyDescriptionTooLong { + length: description.len(), + limit: config.family_description_length_limit, + }); + } + Ok(()) +} + +/// Ensure no family other than `excluded_id` has `normalised_name` as its +/// normalised name. `excluded_id = None` is used on the create path (any +/// match is a collision); `excluded_id = Some(family.id)` on the update +/// path lets a family keep its current normalised key. +pub(crate) fn ensure_normalised_name_unique( + storage: &NodeFamiliesStorage, + deps: Deps, + normalised_name: &str, + excluded_id: Option, +) -> Result<(), NodeFamiliesContractError> { + if let Some((_, existing)) = storage + .families + .idx + .normalised_name + .item(deps.storage, normalised_name.to_owned())? + { + if Some(existing.id) != excluded_id { + return Err(NodeFamiliesContractError::FamilyNameAlreadyTaken { + name: normalised_name.to_owned(), + family_id: existing.id, + }); + } + } + Ok(()) +} + /// Ensure no node controlled by `address` is currently a member of any family. pub(crate) fn ensure_address_holds_no_family_membership( storage: &NodeFamiliesStorage, diff --git a/contracts/node-families/src/storage/mod.rs b/contracts/node-families/src/storage/mod.rs index 62ae93c82d..371631bac9 100644 --- a/contracts/node-families/src/storage/mod.rs +++ b/contracts/node-families/src/storage/mod.rs @@ -4,6 +4,7 @@ // storage will be used in subsequent PRs/tickets #![allow(dead_code)] +use crate::helpers::NewFamilyName; use crate::storage::storage_indexes::{ FamilyMembersIndex, NodeFamiliesIndex, NodeFamilyInvitationIndex, PastFamilyInvitationsIndex, PastFamilyMembersIndex, @@ -221,22 +222,20 @@ impl NodeFamiliesStorage<'_> { /// invariants via unique indexes on `owner` and `normalised_name` as a /// defence-in-depth check, so this call will fail if either is already /// taken — but the caller must not rely on it for the membership check. - #[allow(clippy::too_many_arguments)] pub(crate) fn register_new_family( &self, store: &mut dyn Storage, env: &Env, fee: Coin, owner: Addr, - name: String, - normalised_name: String, + name: NewFamilyName, description: String, ) -> Result { let id = self.next_family_id(store)?; let family = NodeFamily { id, - name, - normalised_name, + name: name.name, + normalised_name: name.normalised_name, description, owner, paid_fee: fee, @@ -247,6 +246,38 @@ impl NodeFamiliesStorage<'_> { Ok(family) } + /// Apply name and/or description updates to an existing family, leaving + /// every other field (id, owner, members, paid_fee, created_at) + /// untouched. Each argument follows `None = keep` / `Some = replace` + /// semantics. + /// + /// No validation is performed here — the caller (transaction handler) + /// owns the length / non-empty / global-uniqueness checks before invoking. + /// Errors with [`FamilyNotFound`] if `family_id` does not exist. + /// + /// [`FamilyNotFound`]: NodeFamiliesContractError::FamilyNotFound + pub(crate) fn update_family_details( + &self, + store: &mut dyn Storage, + family_id: NodeFamilyId, + updated_name: Option, + updated_description: Option, + ) -> Result { + let mut family = self + .families + .may_load(store, family_id)? + .ok_or(NodeFamiliesContractError::FamilyNotFound { family_id })?; + if let Some(new_name) = updated_name { + family.name = new_name.name; + family.normalised_name = new_name.normalised_name; + } + if let Some(description) = updated_description { + family.description = description; + } + self.families.save(store, family.id, &family)?; + Ok(family) + } + /// Persist a new pending invitation for `node_id` to join `family_id`. /// /// `expires_at` is taken as a unix-seconds absolute deadline (the caller @@ -703,6 +734,7 @@ impl NodeFamiliesStorage<'_> { #[cfg(test)] mod tests { use super::*; + use crate::helpers::NewFamilyName; use crate::testing::{init_contract_tester, NodeFamiliesContractTesterExt}; use nym_contracts_common_testing::ContractOpts; @@ -780,8 +812,10 @@ mod tests { &env, fee, owner.clone(), - "Fam!".into(), - "fam".into(), + NewFamilyName { + name: "Fam!".into(), + normalised_name: "fam".into(), + }, "desc".into(), ) .unwrap(); @@ -823,8 +857,10 @@ mod tests { &env, fee.clone(), alice, - "Shared".into(), - "shared".into(), + NewFamilyName { + name: "Shared".into(), + normalised_name: "shared".into(), + }, "".into(), ) .unwrap(); @@ -836,8 +872,10 @@ mod tests { &env, fee, bob, - "$$shared$$".into(), - "shared".into(), + NewFamilyName { + name: "$$shared$$".into(), + normalised_name: "shared".into(), + }, "".into(), ); assert!(res.is_err()); @@ -859,8 +897,10 @@ mod tests { &env, fee, alice, - "second".into(), - "second".into(), + NewFamilyName { + name: "second".into(), + normalised_name: "second".into(), + }, "".into(), ); assert!(res.is_err()); @@ -1272,8 +1312,10 @@ mod tests { &env, fee, alice, - "2".into(), - "2".into(), + NewFamilyName { + name: "2".into(), + normalised_name: "2".into(), + }, "".into(), ) .unwrap(); diff --git a/contracts/node-families/src/testing.rs b/contracts/node-families/src/testing.rs index f76bbacf26..d68c357d45 100644 --- a/contracts/node-families/src/testing.rs +++ b/contracts/node-families/src/testing.rs @@ -6,7 +6,7 @@ #![allow(clippy::expect_used)] use crate::contract::{execute, instantiate, migrate, query}; -use crate::helpers::normalise_family_name; +use crate::helpers::{normalise_family_name, NewFamilyName}; use crate::storage::NodeFamiliesStorage; use cosmwasm_std::{coin, Addr, Coin, Storage}; use mixnet_contract::testable_mixnet_contract::{EmbeddedMixnetContractExt, MixnetContract}; @@ -126,7 +126,7 @@ pub trait NodeFamiliesContractTesterExt: } fn make_named_family(&mut self, owner: &Addr, name: &str) -> NodeFamily { - let normalised = normalise_family_name(name); + let normalised_name = normalise_family_name(name); let env = self.env(); let fee = self.family_fee(); NodeFamiliesStorage::new() @@ -135,8 +135,10 @@ pub trait NodeFamiliesContractTesterExt: &env, fee, owner.clone(), - name.to_string(), - normalised, + NewFamilyName { + name: name.to_string(), + normalised_name, + }, "dummy".to_string(), ) .unwrap() diff --git a/contracts/node-families/src/transactions.rs b/contracts/node-families/src/transactions.rs index 0237dcf3ab..e18f84b3d1 100644 --- a/contracts/node-families/src/transactions.rs +++ b/contracts/node-families/src/transactions.rs @@ -5,7 +5,8 @@ use crate::helpers::{ ensure_address_holds_no_family_membership, ensure_has_bonded_node, ensure_node_is_bonded, - ensure_node_not_in_family, normalise_family_name, + ensure_node_not_in_family, ensure_normalised_name_unique, validate_family_description, + validate_family_name, }; use crate::storage::NodeFamiliesStorage; use cosmwasm_std::{BankMsg, DepsMut, Env, Event, MessageInfo, Response}; @@ -60,25 +61,9 @@ pub(crate) fn try_create_family( }); } - // validate family name - if name.len() > config.family_name_length_limit { - return Err(NodeFamiliesContractError::FamilyNameTooLong { - length: name.len(), - limit: config.family_name_length_limit, - }); - } - let normalised = normalise_family_name(&name); - if normalised.is_empty() { - return Err(NodeFamiliesContractError::EmptyFamilyName); - } - - // validate family description - if description.len() > config.family_description_length_limit { - return Err(NodeFamiliesContractError::FamilyDescriptionTooLong { - length: description.len(), - limit: config.family_description_length_limit, - }); - } + // validate name + description (shared with try_update_family) + let validated_name = validate_family_name(name, &config)?; + validate_family_description(&description, &config)?; // check if the sender already owns a family if let Some(existing) = storage.may_get_owned_family(deps.storage, &info.sender)? { @@ -89,17 +74,12 @@ pub(crate) fn try_create_family( } // explicitly verify duplicate family name for a better error message - if let Some((_, existing)) = storage - .families - .idx - .normalised_name - .item(deps.storage, normalised.clone())? - { - return Err(NodeFamiliesContractError::FamilyNameAlreadyTaken { - name: normalised, - family_id: existing.id, - }); - } + ensure_normalised_name_unique( + &storage, + deps.as_ref(), + &validated_name.normalised_name, + None, + )?; // check whether this owner has a bonded node which belongs to a family ensure_address_holds_no_family_membership(&storage, deps.as_ref(), &info.sender)?; @@ -109,8 +89,7 @@ pub(crate) fn try_create_family( &env, config.create_family_fee, info.sender, - name, - normalised, + validated_name, description, )?; @@ -129,6 +108,75 @@ pub(crate) fn try_create_family( )) } +/// Update the name and/or description of the family owned by `info.sender`. +/// Each field is independently optional: `None` keeps the existing value, +/// `Some(_)` replaces it. Updated values are validated against the same +/// length / normalisation / global-uniqueness rules as [`try_create_family`]. +/// A fully-empty call (both arguments `None`) is silently accepted as a +/// no-op — no state change, no event. +pub(crate) fn try_update_family( + deps: DepsMut, + _env: Env, + info: MessageInfo, + updated_name: Option, + updated_description: Option, +) -> Result { + // Short-circuit on the no-op case so we don't load config / storage. + if updated_name.is_none() && updated_description.is_none() { + return Ok(Response::default()); + } + + let storage = NodeFamiliesStorage::new(); + let config = storage.config.load(deps.storage)?; + + // Owner gate — same unique-index lookup used by disband / invite / kick. + let family = storage.must_get_owned_family(deps.storage, &info.sender)?; + + // Validate name + description (shared with try_create_family). + let validated_name = updated_name + .map(|name| validate_family_name(name, &config)) + .transpose()?; + if let Some(ref new) = validated_name { + ensure_normalised_name_unique( + &storage, + deps.as_ref(), + &new.normalised_name, + Some(family.id), + )?; + } + if let Some(ref description) = updated_description { + validate_family_description(description, &config)?; + } + + let name_was_updated = validated_name.is_some(); + let description_was_updated = updated_description.is_some(); + + let updated = storage.update_family_details( + deps.storage, + family.id, + validated_name, + updated_description, + )?; + + let mut event = Event::new(events::FAMILY_UPDATE_EVENT_NAME) + .add_attribute( + events::FAMILY_UPDATE_EVENT_FAMILY_ID, + updated.id.to_string(), + ) + .add_attribute(events::FAMILY_UPDATE_EVENT_OWNER_ADDRESS, &updated.owner); + if name_was_updated { + event = event.add_attribute(events::FAMILY_UPDATE_EVENT_UPDATED_NAME, &updated.name); + } + if description_was_updated { + event = event.add_attribute( + events::FAMILY_UPDATE_EVENT_UPDATED_DESCRIPTION, + &updated.description, + ); + } + + Ok(Response::new().add_event(event)) +} + /// Disband the family owned by `info.sender` and refund the original /// creation fee. /// @@ -844,6 +892,329 @@ mod tests { } } + mod update_family { + use super::*; + use crate::testing::NodeFamiliesContractTesterExt; + use nym_node_families_contract_common::constants::events; + + #[test] + fn happy_path_updates_name_only() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let original = tester.make_named_family(&alice, "Original"); + let env = tester.env(); + let info = message_info(&alice, &[]); + + try_update_family( + tester.deps_mut(), + env, + info, + Some("Renamed".to_string()), + None, + )?; + + let storage = NodeFamiliesStorage::new(); + let updated = storage.families.load(tester.deps().storage, original.id)?; + + assert_eq!(updated.name, "Renamed"); + assert_eq!(updated.normalised_name, "renamed"); + // every other field is preserved + assert_eq!(updated.description, original.description); + assert_eq!(updated.id, original.id); + assert_eq!(updated.owner, original.owner); + assert_eq!(updated.paid_fee, original.paid_fee); + assert_eq!(updated.members, original.members); + assert_eq!(updated.created_at, original.created_at); + + Ok(()) + } + + #[test] + fn happy_path_updates_description_only() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let original = tester.make_named_family(&alice, "Family"); + let env = tester.env(); + let info = message_info(&alice, &[]); + + try_update_family( + tester.deps_mut(), + env, + info, + None, + Some("new description".to_string()), + )?; + + let storage = NodeFamiliesStorage::new(); + let updated = storage.families.load(tester.deps().storage, original.id)?; + + assert_eq!(updated.name, original.name); + assert_eq!(updated.normalised_name, original.normalised_name); + assert_eq!(updated.description, "new description"); + + Ok(()) + } + + #[test] + fn happy_path_updates_both_fields() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let original = tester.make_named_family(&alice, "Original"); + let env = tester.env(); + let info = message_info(&alice, &[]); + + try_update_family( + tester.deps_mut(), + env, + info, + Some("Renamed".to_string()), + Some("new description".to_string()), + )?; + + let storage = NodeFamiliesStorage::new(); + let updated = storage.families.load(tester.deps().storage, original.id)?; + + assert_eq!(updated.name, "Renamed"); + assert_eq!(updated.normalised_name, "renamed"); + assert_eq!(updated.description, "new description"); + + Ok(()) + } + + #[test] + fn noop_when_both_fields_are_none() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let original = tester.make_named_family(&alice, "Original"); + let env = tester.env(); + let info = message_info(&alice, &[]); + + let res = try_update_family(tester.deps_mut(), env, info, None, None)?; + + // no event, no messages + assert!(res.events.is_empty()); + assert!(res.messages.is_empty()); + + // family record untouched + let storage = NodeFamiliesStorage::new(); + let unchanged = storage.families.load(tester.deps().storage, original.id)?; + assert_eq!(unchanged, original); + + Ok(()) + } + + #[test] + fn noop_short_circuits_before_the_owner_lookup() -> anyhow::Result<()> { + // sender owns no family at all; the no-op short-circuit must run + // before the ownership check or this would error with + // SenderDoesntOwnAFamily. + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let info = message_info(&alice, &[]); + let env = tester.env(); + + let res = try_update_family(tester.deps_mut(), env, info, None, None)?; + assert!(res.events.is_empty()); + assert!(res.messages.is_empty()); + + Ok(()) + } + + #[test] + fn rejects_when_sender_owns_no_family() { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let info = message_info(&alice, &[]); + let env = tester.env(); + + let err = try_update_family( + tester.deps_mut(), + env, + info, + Some("Newname".to_string()), + None, + ) + .unwrap_err(); + + assert_eq!( + err, + NodeFamiliesContractError::SenderDoesntOwnAFamily { address: alice } + ); + } + + #[test] + fn rejects_name_too_long() { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + tester.make_named_family(&alice, "Original"); + let info = message_info(&alice, &[]); + let env = tester.env(); + + let limit = NodeFamiliesStorage::new() + .config + .load(tester.deps().storage) + .unwrap() + .family_name_length_limit; + let too_long = "x".repeat(limit + 1); + + let err = try_update_family(tester.deps_mut(), env, info, Some(too_long.clone()), None) + .unwrap_err(); + + assert_eq!( + err, + NodeFamiliesContractError::FamilyNameTooLong { + length: too_long.len(), + limit, + } + ); + } + + #[test] + fn rejects_name_normalising_to_empty() { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + tester.make_named_family(&alice, "Original"); + let info = message_info(&alice, &[]); + let env = tester.env(); + + let err = try_update_family( + tester.deps_mut(), + env, + info, + Some("!!!---".to_string()), + None, + ) + .unwrap_err(); + + assert_eq!(err, NodeFamiliesContractError::EmptyFamilyName); + } + + #[test] + fn rejects_name_already_taken_by_another_family() { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let bob = tester.addr_make("bob"); + tester.make_named_family(&alice, "Alice family"); + let bobs_family = tester.make_named_family(&bob, "Bob family"); + + let info = message_info(&alice, &[]); + let env = tester.env(); + let err = try_update_family( + tester.deps_mut(), + env, + info, + Some("Bob Family".to_string()), + None, + ) + .unwrap_err(); + + assert_eq!( + err, + NodeFamiliesContractError::FamilyNameAlreadyTaken { + name: "bobfamily".to_string(), + family_id: bobs_family.id, + } + ); + } + + #[test] + fn case_only_rename_keeping_normalised_form_is_allowed() -> anyhow::Result<()> { + // a rename whose normalised form matches the family's current + // normalised key must succeed - it's a no-collision change against + // the family's own row, which the uniqueness pre-check skips. + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + let original = tester.make_named_family(&alice, "MyFamily"); + let info = message_info(&alice, &[]); + let env = tester.env(); + + try_update_family( + tester.deps_mut(), + env, + info, + Some("MYFAMILY".to_string()), + None, + )?; + + let updated = NodeFamiliesStorage::new() + .families + .load(tester.deps().storage, original.id)?; + assert_eq!(updated.name, "MYFAMILY"); + assert_eq!(updated.normalised_name, "myfamily"); + + Ok(()) + } + + #[test] + fn rejects_description_too_long() { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + tester.make_named_family(&alice, "Original"); + let info = message_info(&alice, &[]); + let env = tester.env(); + + let limit = NodeFamiliesStorage::new() + .config + .load(tester.deps().storage) + .unwrap() + .family_description_length_limit; + let too_long = "x".repeat(limit + 1); + + let err = try_update_family(tester.deps_mut(), env, info, None, Some(too_long.clone())) + .unwrap_err(); + + assert_eq!( + err, + NodeFamiliesContractError::FamilyDescriptionTooLong { + length: too_long.len(), + limit, + } + ); + } + + #[test] + fn event_only_carries_attributes_for_changed_fields() -> anyhow::Result<()> { + let mut tester = init_contract_tester(); + let alice = tester.addr_make("alice"); + tester.make_named_family(&alice, "Original"); + let env = tester.env(); + + // name-only update: no `updated_description` attribute + let info = message_info(&alice, &[]); + let res = try_update_family( + tester.deps_mut(), + env.clone(), + info, + Some("Renamed".to_string()), + None, + )?; + assert_eq!(res.events.len(), 1); + let event = &res.events[0]; + assert_eq!(event.ty, events::FAMILY_UPDATE_EVENT_NAME); + let keys: Vec<&str> = event.attributes.iter().map(|a| a.key.as_str()).collect(); + assert!(keys.contains(&events::FAMILY_UPDATE_EVENT_FAMILY_ID)); + assert!(keys.contains(&events::FAMILY_UPDATE_EVENT_OWNER_ADDRESS)); + assert!(keys.contains(&events::FAMILY_UPDATE_EVENT_UPDATED_NAME)); + assert!(!keys.contains(&events::FAMILY_UPDATE_EVENT_UPDATED_DESCRIPTION)); + + // description-only update: no `updated_name` attribute + let info = message_info(&alice, &[]); + let res = try_update_family( + tester.deps_mut(), + env, + info, + None, + Some("new desc".to_string()), + )?; + let event = &res.events[0]; + let keys: Vec<&str> = event.attributes.iter().map(|a| a.key.as_str()).collect(); + assert!(!keys.contains(&events::FAMILY_UPDATE_EVENT_UPDATED_NAME)); + assert!(keys.contains(&events::FAMILY_UPDATE_EVENT_UPDATED_DESCRIPTION)); + + Ok(()) + } + } + mod disband_family { use super::*; use crate::testing::NodeFamiliesContractTesterExt; diff --git a/openspec/specs/node-families-contract/spec.md b/openspec/specs/node-families-contract/spec.md index 8446cdcf97..1d7a0ff674 100644 --- a/openspec/specs/node-families-contract/spec.md +++ b/openspec/specs/node-families-contract/spec.md @@ -113,6 +113,52 @@ A given owner address SHALL own at most one family at any time, enforced by the - **WHEN** `CreateFamily` is sent with a `description` whose byte length exceeds `Config::family_description_length_limit` - **THEN** the call fails with `FamilyDescriptionTooLong { length, limit }` +### Requirement: A family's name and/or description can be updated by its owner + +`ExecuteMsg::UpdateFamily { updated_name: Option, updated_description: Option }` SHALL allow the owner of an existing family to replace either or both fields independently. Each argument follows `None = keep` / `Some(_) = replace` semantics; a call carrying `None` for both fields SHALL be a silent no-op (empty `Response`, no event, no state change) and SHALL short-circuit BEFORE the owner-ownership check (so a sender that owns no family can also no-op without error). Otherwise the handler MUST look up the sender's family via the `owner` unique index and fail with `SenderDoesntOwnAFamily { address }` if none exists. Updated values MUST be validated against the same rules as `CreateFamily`: a `Some(name)` MUST satisfy `Config::family_name_length_limit` (else `FamilyNameTooLong { length, limit }`) and MUST normalise to a non-empty string (else `EmptyFamilyName`); a `Some(description)` MUST satisfy `Config::family_description_length_limit` (else `FamilyDescriptionTooLong { length, limit }`). The new normalised name MUST be globally unique against OTHER families (else `FamilyNameAlreadyTaken { name, family_id }`); a name change whose normalised form matches the family's own existing `normalised_name` (a case-only or punctuation-only rename) MUST be allowed. The handler MUST preserve `id`, `owner`, `paid_fee`, `members`, and `created_at`. On a state-changing success the response SHALL include a `family_update` event with `family_id` and `owner_address` attributes plus conditional `updated_name` / `updated_description` attributes for each field actually changed by the call. + +#### Scenario: Owner updates the family name only +- **WHEN** the family owner sends `UpdateFamily { updated_name: Some(n), updated_description: None }` with a valid `n` +- **THEN** the persisted family's `name` and `normalised_name` are replaced with `n` and its normalised form, while `description`, `id`, `owner`, `paid_fee`, `members`, and `created_at` are unchanged +- **AND** the response carries a `family_update` event with `family_id`, `owner_address`, and `updated_name = n` (no `updated_description` attribute) + +#### Scenario: Owner updates the description only +- **WHEN** the family owner sends `UpdateFamily { updated_name: None, updated_description: Some(d) }` with a valid `d` +- **THEN** the persisted family's `description` is replaced with `d` and every other field is unchanged +- **AND** the response carries a `family_update` event with `family_id`, `owner_address`, and `updated_description = d` (no `updated_name` attribute) + +#### Scenario: Owner updates both fields +- **WHEN** the family owner sends `UpdateFamily { updated_name: Some(n), updated_description: Some(d) }` with both values valid +- **THEN** both `name`/`normalised_name` and `description` are replaced, and the event carries both `updated_name` and `updated_description` attributes + +#### Scenario: A fully-empty call is a silent no-op for any sender +- **WHEN** any sender (whether or not they own a family) sends `UpdateFamily { updated_name: None, updated_description: None }` +- **THEN** the response is `Response::default()` (no events, no messages) and storage is unchanged + +#### Scenario: Sender that owns no family is rejected when at least one field is set +- **WHEN** an address that does not own any family sends `UpdateFamily` with at least one `Some(_)` field +- **THEN** the call fails with `SenderDoesntOwnAFamily { address }` + +#### Scenario: Overlong name is rejected +- **WHEN** `UpdateFamily { updated_name: Some(n), .. }` is sent with `n.len() > Config::family_name_length_limit` +- **THEN** the call fails with `FamilyNameTooLong { length, limit }` and storage is unchanged + +#### Scenario: Name normalising to empty is rejected +- **WHEN** `UpdateFamily { updated_name: Some(n), .. }` is sent with an `n` whose normalisation yields the empty string +- **THEN** the call fails with `EmptyFamilyName` and storage is unchanged + +#### Scenario: Renaming to another family's normalised name is rejected +- **WHEN** family `A`'s owner sends `UpdateFamily { updated_name: Some(n), .. }` whose normalisation equals a different family `B`'s `normalised_name` +- **THEN** the call fails with `FamilyNameAlreadyTaken { name, family_id: B.id }` and storage is unchanged + +#### Scenario: Case-only or punctuation-only rename is allowed +- **WHEN** the owner sends `UpdateFamily { updated_name: Some(n), .. }` whose normalisation equals the family's own existing `normalised_name` +- **THEN** the display `name` is replaced with `n`, the `normalised_name` is unchanged, and the call succeeds + +#### Scenario: Overlong description is rejected +- **WHEN** `UpdateFamily { updated_description: Some(d), .. }` is sent with `d.len() > Config::family_description_length_limit` +- **THEN** the call fails with `FamilyDescriptionTooLong { length, limit }` and storage is unchanged + ### Requirement: Family ids are monotonic, never recycled, and start at 1 The contract SHALL assign family ids sequentially starting at `1`. The id counter SHALL be persisted as an `Item` and incremented on each successful family creation. Disbanding a family MUST NOT free or recycle its id. `0` SHALL be reserved as a "no family" sentinel and never assigned. @@ -406,11 +452,12 @@ Every constant exported under `nym_node_families_contract_common::constants::sto ### Requirement: Emitted events form a stable public surface -Every event name and attribute key exported under `nym_node_families_contract_common::constants::events` SHALL be treated as part of the public contract surface. Each successful **state-mutating user-facing execute path** (every variant of `ExecuteMsg` except `UpdateConfig`, which is an admin handler that returns `Response::default()` without an event) SHALL emit exactly one event whose name and attribute keys come from these constants. Renaming an event name constant, renaming an attribute-key constant, or changing the set of attributes a given event carries SHALL be treated as breaking changes. Adding new constants for new events / attributes is non-breaking. +Every event name and attribute key exported under `nym_node_families_contract_common::constants::events` SHALL be treated as part of the public contract surface. Each successful **state-mutating user-facing execute path** (every variant of `ExecuteMsg` except `UpdateConfig`, which is an admin handler that returns `Response::default()` without an event, and the no-op `UpdateFamily { updated_name: None, updated_description: None }` short-circuit, which also returns `Response::default()` because nothing changed) SHALL emit exactly one event whose name and attribute keys come from these constants. Renaming an event name constant, renaming an attribute-key constant, or changing the set of attributes a given event always carries SHALL be treated as breaking changes. Adding new constants for new events / attributes is non-breaking, as is making a previously-always-emitted attribute conditional only by extending the variant set that triggers it (see `family_update` below). At the time of this spec the constant surface comprises (refer to `constants.rs` for the authoritative list): - `family_creation` — attributes: `family_name`, `owner_address`, `family_id`, `paid_fee` +- `family_update` — required attributes: `family_id`, `owner_address`. Conditional attributes: `updated_name` (emitted only when the call carried `updated_name = Some(_)`), `updated_description` (emitted only when the call carried `updated_description = Some(_)`). At least one of the two conditional attributes is always present, because the no-op no-name-no-description case short-circuits to `Response::default()` without emitting any event at all. - `family_disband` — attributes: `family_id`, `owner_address`, `refunded_fee` - `family_invitation` — attributes: `family_id`, `node_id`, `expires_at` - `family_invitation_revoked` — attributes: `family_id`, `node_id` @@ -430,3 +477,7 @@ At the time of this spec the constant surface comprises (refer to `constants.rs` - **WHEN** the admin sends `ExecuteMsg::UpdateConfig` and the call succeeds - **THEN** the response is `Response::default()` and carries no event (this is intentional — `UpdateConfig` is administrative metadata, not a tracked state transition) +#### Scenario: No-op UpdateFamily is the second exception — no event is emitted +- **WHEN** any sender sends `ExecuteMsg::UpdateFamily { updated_name: None, updated_description: None }` and the call succeeds (the no-op short-circuit) +- **THEN** the response is `Response::default()` and carries no event — because nothing in storage changed, there is nothing for indexers to observe + From dc64fb622ccb4c90dc433222ded87bb0e0ee1a7c Mon Sep 17 00:00:00 2001 From: import this <97586125+serinko@users.noreply.github.com> Date: Thu, 28 May 2026 12:54:41 +0200 Subject: [PATCH 57/94] [DOCs/operatos]: Release notes/v2026.10-waterloo (#6827) * release notes * add operators info * node version stubs * bump scraped stats and add a thehosting warning url * add new explorer feat point * fix header character to fix linkchecker error * fix header character to fix linkchecker error * fix header character to fix linkchecker error * syntax fix * bump up node version * ignore pnpm - in the right branch tihs time --------- Co-authored-by: mfahampshire --- documentation/docs/.npmrc | 1 + .../api-scraping-outputs/nodes-count.json | 8 +- .../outputs/api-scraping-outputs/time-now.md | 2 +- .../node-api-check-query-help.md | 2 +- .../nym-node-cli-install-help.md | 3 +- .../command-outputs/nym-node-run-help.md | 194 ++++++++++-------- .../docs/pages/operators/changelog.mdx | 106 +++++++++- .../pages/operators/nodes/nym-node/setup.mdx | 8 +- 8 files changed, 222 insertions(+), 102 deletions(-) create mode 100644 documentation/docs/.npmrc diff --git a/documentation/docs/.npmrc b/documentation/docs/.npmrc new file mode 100644 index 0000000000..1a99418bf0 --- /dev/null +++ b/documentation/docs/.npmrc @@ -0,0 +1 @@ +strict-dep-builds=false diff --git a/documentation/docs/components/outputs/api-scraping-outputs/nodes-count.json b/documentation/docs/components/outputs/api-scraping-outputs/nodes-count.json index afc2a063f8..98ee11e305 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/nodes-count.json +++ b/documentation/docs/components/outputs/api-scraping-outputs/nodes-count.json @@ -1,6 +1,6 @@ { - "nodes": 723, - "locations": 76, - "mixnodes": 249, - "exit_gateways": 466 + "nodes": 682, + "locations": 78, + "mixnodes": 242, + "exit_gateways": 432 } diff --git a/documentation/docs/components/outputs/api-scraping-outputs/time-now.md b/documentation/docs/components/outputs/api-scraping-outputs/time-now.md index 5ecc447407..bab5e7c55f 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/time-now.md +++ b/documentation/docs/components/outputs/api-scraping-outputs/time-now.md @@ -1 +1 @@ -Wednesday, May 20th 2026, 06:27:43 UTC +Wednesday, May 27th 2026, 11:42:58 UTC diff --git a/documentation/docs/components/outputs/command-outputs/node-api-check-query-help.md b/documentation/docs/components/outputs/command-outputs/node-api-check-query-help.md index bfa068ddb0..999f3d4a6f 100644 --- a/documentation/docs/components/outputs/command-outputs/node-api-check-query-help.md +++ b/documentation/docs/components/outputs/command-outputs/node-api-check-query-help.md @@ -11,7 +11,7 @@ options: --no_routing_history Display node stats without routing history --no_verloc_metrics Display node stats without verloc metrics -m, --markdown Display results in markdown format - -o [OUTPUT], --output [OUTPUT] + -o, --output [OUTPUT] Save results to file (in current dir or supply with path without filename) ``` diff --git a/documentation/docs/components/outputs/command-outputs/nym-node-cli-install-help.md b/documentation/docs/components/outputs/command-outputs/nym-node-cli-install-help.md index c4bddbd0d7..a84d0454b7 100644 --- a/documentation/docs/components/outputs/command-outputs/nym-node-cli-install-help.md +++ b/documentation/docs/components/outputs/command-outputs/nym-node-cli-install-help.md @@ -15,8 +15,7 @@ usage: nym-node-cli install [-h] [-V] [-d BRANCH] [-v] options: -h, --help show this help message and exit -V, --version show program's version number and exit - -d BRANCH, --dev BRANCH - Define github branch (default: develop) + -d, --dev BRANCH Define github branch (default: develop) -v, --verbose Show full error tracebacks --mode {mixnode,entry-gateway,exit-gateway} Node mode: 'mixnode', 'entry-gateway', or 'exit- diff --git a/documentation/docs/components/outputs/command-outputs/nym-node-run-help.md b/documentation/docs/components/outputs/command-outputs/nym-node-run-help.md index 67799f0690..fc4636aa82 100644 --- a/documentation/docs/components/outputs/command-outputs/nym-node-run-help.md +++ b/documentation/docs/components/outputs/command-outputs/nym-node-run-help.md @@ -4,87 +4,115 @@ Start this nym-node Usage: nym-node run [OPTIONS] Options: - --id Id of the nym-node to use [env: NYMNODE_ID=] [default: default-nym-node] - --config-file Path to a configuration file of this node [env: NYMNODE_CONFIG=] - --accept-operator-terms-and-conditions Explicitly specify whether you agree with the terms and conditions of a nym node operator as defined at - [env: NYMNODE_ACCEPT_OPERATOR_TERMS=] - --deny-init Forbid a new node from being initialised if configuration file for the provided specification doesn't already exist [env: - NYMNODE_DENY_INIT=] - --init-only If this is a brand new nym-node, specify whether it should only be initialised without actually running the subprocesses [env: - NYMNODE_INIT_ONLY=] - --local Flag specifying this node will be running in a local setting [env: NYMNODE_LOCAL=] - --mode [...] Specifies the current mode(s) of this nym-node [env: NYMNODE_MODE=] [possible values: mixnode, entry-gateway, exit-gateway, - exit-providers-only] - --modes Specifies the current mode(s) of this nym-node as a single flag [env: NYMNODE_MODES=] [possible values: mixnode, entry-gateway, - exit-gateway, exit-providers-only] - -w, --write-changes If this node has been initialised before, specify whether to write any new changes to the config file [env: - NYMNODE_WRITE_CONFIG_CHANGES=] - --bonding-information-output Specify output file for bonding information of this nym-node, i.e. its encoded keys. NOTE: the required bonding information is still a - subject to change and this argument should be treated only as a preview of future features [env: NYMNODE_BONDING_INFORMATION_OUTPUT=] - -o, --output Specify the output format of the bonding information (`text` or `json`) [env: NYMNODE_OUTPUT=] [default: text] [possible values: text, - json] - --public-ips Comma separated list of public ip addresses that will be announced to the nym-api and subsequently to the clients. In nearly all - circumstances, it's going to be identical to the address you're going to use for bonding [env: NYMNODE_PUBLIC_IPS=] - --hostname Optional hostname associated with this gateway that will be announced to the nym-api and subsequently to the clients [env: - NYMNODE_HOSTNAME=] - --location Optional **physical** location of this node's server. Either full country name (e.g. 'Poland'), two-letter alpha2 (e.g. 'PL'), - three-letter alpha3 (e.g. 'POL') or three-digit numeric-3 (e.g. '616') can be provided [env: NYMNODE_LOCATION=] - --http-bind-address Socket address this node will use for binding its http API. default: `[::]:8080` [env: NYMNODE_HTTP_BIND_ADDRESS=] - --landing-page-assets-path Path to assets directory of custom landing page of this node [env: NYMNODE_HTTP_LANDING_ASSETS=] - --http-access-token An optional bearer token for accessing certain http endpoints. Currently only used for prometheus metrics [env: - NYMNODE_HTTP_ACCESS_TOKEN=] - --expose-system-info Specify whether basic system information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_SYSTEM_INFO=] [possible values: - true, false] - --expose-system-hardware Specify whether basic system hardware information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_SYSTEM_HARDWARE=] - [possible values: true, false] - --expose-crypto-hardware Specify whether detailed system crypto hardware information should be exposed. default: true [env: - NYMNODE_HTTP_EXPOSE_CRYPTO_HARDWARE=] [possible values: true, false] - --mixnet-bind-address Address this node will bind to for listening for mixnet packets default: `[::]:1789` [env: NYMNODE_MIXNET_BIND_ADDRESS=] - --mixnet-announce-port If applicable, custom port announced in the self-described API that other clients and nodes will use. Useful when the node is behind a - proxy [env: NYMNODE_MIXNET_ANNOUNCE_PORT=] - --nym-api-urls Addresses to nym APIs from which the node gets the view of the network [env: NYMNODE_NYM_APIS=] - --nyxd-urls Addresses to nyxd chain endpoint which the node will use for chain interactions [env: NYMNODE_NYXD=] - --enable-console-logging Specify whether running statistics of this node should be logged to the console [env: NYMNODE_ENABLE_CONSOLE_LOGGING=] [possible - values: true, false] - --wireguard-enabled Specifies whether the wireguard service is enabled on this node [env: NYMNODE_WG_ENABLED=] [possible values: true, false] - --wireguard-bind-address Socket address this node will use for binding its wireguard interface. default: `[::]:51822` [env: NYMNODE_WG_BIND_ADDRESS=] - --wireguard-tunnel-announced-port Tunnel port announced to external clients wishing to connect to the wireguard interface. Useful in the instances where the node is - behind a proxy [env: NYMNODE_WG_ANNOUNCED_PORT=] - --wireguard-private-network-prefix The prefix denoting the maximum number of the clients that can be connected via Wireguard. The maximum value for IPv4 is 32 and for - IPv6 is 128 [env: NYMNODE_WG_PRIVATE_NETWORK_PREFIX=] - --wireguard-userspace Use userspace implementation of WireGuard (wireguard-go) instead of kernel module. Useful in containerized environments without kernel - WireGuard support [env: NYMNODE_WG_USERSPACE=] [possible values: true, false] - --verloc-bind-address Socket address this node will use for binding its verloc API. default: `[::]:1790` [env: NYMNODE_VERLOC_BIND_ADDRESS=] - --verloc-announce-port If applicable, custom port announced in the self-described API that other clients and nodes will use. Useful when the node is behind a - proxy [env: NYMNODE_VERLOC_ANNOUNCE_PORT=] - --entry-bind-address Socket address this node will use for binding its client websocket API. default: `[::]:9000` [env: NYMNODE_ENTRY_BIND_ADDRESS=] - --announce-ws-port Custom announced port for listening for websocket client traffic. If unspecified, the value from the `bind_address` will be used - instead [env: NYMNODE_ENTRY_ANNOUNCE_WS_PORT=] - --announce-wss-port If applicable, announced port for listening for secure websocket client traffic [env: NYMNODE_ENTRY_ANNOUNCE_WSS_PORT=] - --enforce-zk-nyms Indicates whether this gateway is accepting only coconut credentials for accessing the mixnet or if it also accepts non-paying clients - [env: NYMNODE_ENFORCE_ZK_NYMS=] [possible values: true, false] - --mnemonic Custom cosmos wallet mnemonic used for zk-nym redemption. If no value is provided, a fresh mnemonic is going to be generated [env: - NYMNODE_MNEMONIC=] - --upgrade-mode-attestation-url Endpoint to query to retrieve current upgrade mode attestation. This argument should never be set outside testnets and local networks - [env: NYMNODE_UPGRADE_MODE_ATTESTATION_URL=] - --upgrade-mode-attester-public-key Expected public key of the entity signing the published attestation. This argument should never be set outside testnets and local - networks [env: NYMNODE_UPGRADE_MODE_ATTESTER_PUBKEY=] - --upstream-exit-policy-url Specifies the url for an upstream source of the exit policy used by this node [env: NYMNODE_UPSTREAM_EXIT_POLICY=] - --open-proxy Specifies whether this exit node should run in 'open-proxy' mode and thus would attempt to resolve **ANY** request it receives [env: - NYMNODE_OPEN_PROXY=] [possible values: true, false] - --nr-allow-local-ips Allow the network requester to forward traffic to non-globally-routable addresses. Intended for local development, private-network - deployments, and testnet scenarios. Not recommended on production exit gateway unless you know what you're doing [env: - NYMNODE_NR_ALLOW_LOCAL_IPS=] [possible values: true, false] - --ipr-allow-local-ips Allow the IP packet router to forward traffic to non-globally-routable addresses. Intended for local development, private-network - deployments, and testnet scenarios. Not recommended on production exit gateway unless you know what you're doing [env: - NYMNODE_IPR_ALLOW_LOCAL_IPS=] [possible values: true, false] - --lp-control-bind-address Bind address for the TCP LP control traffic. default: `[::]:41264` [env: NYMNODE_LP_CONTROL_BIND_ADDRESS=] - --lp-control-announce-port Custom announced port for listening for the TCP LP control traffic. If unspecified, the value from the `lp_control_bind_address` will - be used instead [env: NYMNODE_LP_CONTROL_ANNOUNCE_PORT=] - --lp-data-bind-address Bind address for the UDP LP data traffic. default: `[::]:51264` [env: NYMNODE_LP_DATA_BIND_ADDRESS=] - --lp-data-announce-port Custom announced port for listening for the UDP LP data traffic. If unspecified, the value from the `lp_data_bind_address` will be - used instead [env: NYMNODE_LP_DATA_ANNOUNCE_PORT=] - --lp-use-mock-ecash Use mock ecash manager for LP testing. WARNING: Only use this for local testing! Never enable in production. When enabled, the LP - listener will accept any credential without blockchain verification [env: NYMNODE_LP_USE_MOCK_ECASH=] [possible values: true, false] - -h, --help Print help + --id + Id of the nym-node to use [env: NYMNODE_ID=] [default: default-nym-node] + --config-file + Path to a configuration file of this node [env: NYMNODE_CONFIG=] + --accept-operator-terms-and-conditions + Explicitly specify whether you agree with the terms and conditions of a nym node operator as defined at [env: + NYMNODE_ACCEPT_OPERATOR_TERMS=] + --deny-init + Forbid a new node from being initialised if configuration file for the provided specification doesn't already exist [env: NYMNODE_DENY_INIT=] + --init-only + If this is a brand new nym-node, specify whether it should only be initialised without actually running the subprocesses [env: NYMNODE_INIT_ONLY=] + --local + Flag specifying this node will be running in a local setting [env: NYMNODE_LOCAL=] + --mode [...] + Specifies the current mode(s) of this nym-node [env: NYMNODE_MODE=] [possible values: mixnode, entry-gateway, exit-gateway, exit-providers-only] + --modes + Specifies the current mode(s) of this nym-node as a single flag [env: NYMNODE_MODES=] [possible values: mixnode, entry-gateway, exit-gateway, exit-providers-only] + -w, --write-changes + If this node has been initialised before, specify whether to write any new changes to the config file [env: NYMNODE_WRITE_CONFIG_CHANGES=] + --bonding-information-output + Specify output file for bonding information of this nym-node, i.e. its encoded keys. NOTE: the required bonding information is still a subject to change and this argument should be + treated only as a preview of future features [env: NYMNODE_BONDING_INFORMATION_OUTPUT=] + -o, --output + Specify the output format of the bonding information (`text` or `json`) [env: NYMNODE_OUTPUT=] [default: text] [possible values: text, json] + --public-ips + Comma separated list of public ip addresses that will be announced to the nym-api and subsequently to the clients. In nearly all circumstances, it's going to be identical to the + address you're going to use for bonding [env: NYMNODE_PUBLIC_IPS=] + --hostname + Optional hostname associated with this gateway that will be announced to the nym-api and subsequently to the clients [env: NYMNODE_HOSTNAME=] + --location + Optional **physical** location of this node's server. Either full country name (e.g. 'Poland'), two-letter alpha2 (e.g. 'PL'), three-letter alpha3 (e.g. 'POL') or three-digit + numeric-3 (e.g. '616') can be provided [env: NYMNODE_LOCATION=] + --http-bind-address + Socket address this node will use for binding its http API. default: `[::]:8080` [env: NYMNODE_HTTP_BIND_ADDRESS=] + --landing-page-assets-path + Path to assets directory of custom landing page of this node [env: NYMNODE_HTTP_LANDING_ASSETS=] + --http-access-token + An optional bearer token for accessing certain http endpoints. Currently only used for prometheus metrics [env: NYMNODE_HTTP_ACCESS_TOKEN=] + --expose-system-info + Specify whether basic system information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_SYSTEM_INFO=] [possible values: true, false] + --expose-system-hardware + Specify whether basic system hardware information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_SYSTEM_HARDWARE=] [possible values: true, false] + --expose-crypto-hardware + Specify whether detailed system crypto hardware information should be exposed. default: true [env: NYMNODE_HTTP_EXPOSE_CRYPTO_HARDWARE=] [possible values: true, false] + --mixnet-bind-address + Address this node will bind to for listening for mixnet packets default: `[::]:1789` [env: NYMNODE_MIXNET_BIND_ADDRESS=] + --mixnet-announce-port + If applicable, custom port announced in the self-described API that other clients and nodes will use. Useful when the node is behind a proxy [env: NYMNODE_MIXNET_ANNOUNCE_PORT=] + --nym-api-urls + Addresses to nym APIs from which the node gets the view of the network [env: NYMNODE_NYM_APIS=] + --nyxd-urls + Addresses to nyxd chain endpoint which the node will use for chain interactions [env: NYMNODE_NYXD=] + --enable-console-logging + Specify whether running statistics of this node should be logged to the console [env: NYMNODE_ENABLE_CONSOLE_LOGGING=] [possible values: true, false] + --wireguard-enabled + Specifies whether the wireguard service is enabled on this node [env: NYMNODE_WG_ENABLED=] [possible values: true, false] + --wireguard-bind-address + Socket address this node will use for binding its wireguard interface. default: `[::]:51822` [env: NYMNODE_WG_BIND_ADDRESS=] + --wireguard-tunnel-announced-port + Tunnel port announced to external clients wishing to connect to the wireguard interface. Useful in the instances where the node is behind a proxy [env: NYMNODE_WG_ANNOUNCED_PORT=] + --wireguard-private-network-prefix + The prefix denoting the maximum number of the clients that can be connected via Wireguard. The maximum value for IPv4 is 32 and for IPv6 is 128 [env: + NYMNODE_WG_PRIVATE_NETWORK_PREFIX=] + --wireguard-userspace + Use userspace implementation of WireGuard (wireguard-go) instead of kernel module. Useful in containerized environments without kernel WireGuard support [env: NYMNODE_WG_USERSPACE=] + [possible values: true, false] + --verloc-bind-address + Socket address this node will use for binding its verloc API. default: `[::]:1790` [env: NYMNODE_VERLOC_BIND_ADDRESS=] + --verloc-announce-port + If applicable, custom port announced in the self-described API that other clients and nodes will use. Useful when the node is behind a proxy [env: NYMNODE_VERLOC_ANNOUNCE_PORT=] + --entry-bind-address + Socket address this node will use for binding its client websocket API. default: `[::]:9000` [env: NYMNODE_ENTRY_BIND_ADDRESS=] + --announce-ws-port + Custom announced port for listening for websocket client traffic. If unspecified, the value from the `bind_address` will be used instead [env: NYMNODE_ENTRY_ANNOUNCE_WS_PORT=] + --announce-wss-port + If applicable, announced port for listening for secure websocket client traffic [env: NYMNODE_ENTRY_ANNOUNCE_WSS_PORT=] + --enforce-zk-nyms + Indicates whether this gateway is accepting only coconut credentials for accessing the mixnet or if it also accepts non-paying clients [env: NYMNODE_ENFORCE_ZK_NYMS=] [possible + values: true, false] + --mnemonic + Custom cosmos wallet mnemonic used for zk-nym redemption. If no value is provided, a fresh mnemonic is going to be generated [env: NYMNODE_MNEMONIC=] + --upgrade-mode-attestation-url + Endpoint to query to retrieve current upgrade mode attestation. This argument should never be set outside testnets and local networks [env: NYMNODE_UPGRADE_MODE_ATTESTATION_URL=] + --upgrade-mode-attester-public-key + Expected public key of the entity signing the published attestation. This argument should never be set outside testnets and local networks [env: + NYMNODE_UPGRADE_MODE_ATTESTER_PUBKEY=] + --upstream-exit-policy-url + Specifies the url for an upstream source of the exit policy used by this node [env: NYMNODE_UPSTREAM_EXIT_POLICY=] + --open-proxy + Specifies whether this exit node should run in 'open-proxy' mode and thus would attempt to resolve **ANY** request it receives [env: NYMNODE_OPEN_PROXY=] [possible values: true, + false] + --nr-allow-local-ips + Allow the network requester to forward traffic to non-globally-routable addresses. Intended for local development, private-network deployments, and testnet scenarios. Not + recommended on production exit gateway unless you know what you're doing [env: NYMNODE_NR_ALLOW_LOCAL_IPS=] [possible values: true, false] + --ipr-allow-local-ips + Allow the IP packet router to forward traffic to non-globally-routable addresses. Intended for local development, private-network deployments, and testnet scenarios. Not recommended + on production exit gateway unless you know what you're doing [env: NYMNODE_IPR_ALLOW_LOCAL_IPS=] [possible values: true, false] + --lp-control-bind-address + Bind address for the TCP LP control traffic. default: `[::]:41264` [env: NYMNODE_LP_CONTROL_BIND_ADDRESS=] + --lp-control-announce-port + Custom announced port for listening for the TCP LP control traffic. If unspecified, the value from the `lp_control_bind_address` will be used instead [env: + NYMNODE_LP_CONTROL_ANNOUNCE_PORT=] + --lp-data-bind-address + Bind address for the UDP LP data traffic. default: `[::]:51264` [env: NYMNODE_LP_DATA_BIND_ADDRESS=] + --lp-data-announce-port + Custom announced port for listening for the UDP LP data traffic. If unspecified, the value from the `lp_data_bind_address` will be used instead [env: NYMNODE_LP_DATA_ANNOUNCE_PORT=] + --lp-use-mock-ecash + Use mock ecash manager for LP testing. WARNING: Only use this for local testing! Never enable in production. When enabled, the LP listener will accept any credential without + blockchain verification [env: NYMNODE_LP_USE_MOCK_ECASH=] [possible values: true, false] + -h, --help + Print help ``` diff --git a/documentation/docs/pages/operators/changelog.mdx b/documentation/docs/pages/operators/changelog.mdx index 16f72c28ca..27084582fe 100644 --- a/documentation/docs/pages/operators/changelog.mdx +++ b/documentation/docs/pages/operators/changelog.mdx @@ -58,14 +58,37 @@ This page displays a full list of all the changes during our release cycle from -## Operators Tools +## `v2026.10-waterloo` -As the upcoming platform release has been posponed, we prepared this indenpendent release of tools and updates important for node operators. +- [Release Binaries](https://github.com/nymtech/nym/releases/tag/nym-binaries-v2026.10-waterloo) +- [`nym-node`](nodes/nym-node.mdx) version `1.32.0` + +```sh +nym-node +Binary Name: nym-node +Build Timestamp: 2026-05-27T12:46:38.359447083Z +Build Version: 1.32.0 +Commit SHA: 25eba09b92cff648cd37bdd7f0921e710eed25f5 +Commit Date: 2026-05-27T11:00:31.000000000+02:00 +Commit Branch: HEAD +rustc Version: 1.91.1 +rustc Channel: stable +cargo Profile: release +``` + +### Operators Tools -[**Security steps required**](/operators/troubleshooting/vps-isp#security-patch-copyfail--dirtyfrag): Several critical [Linux kernel vulnerabilities](https://ubuntu.com/blog/copy-fail-vulnerability-fixes-available) had been disclosed. Check out your servers and if needed apply required mitigations! +**Two breaking issues requiring attention:** + +1. We ask all operators to **migrate away from WorkTitans B.V. ([AS209847](https://ipinfo.io/AS209847))**, also known as _the.hosting_, _PQ-Hosting_ and _Stark Industries_! Please read the [info below](#migrate-away-from-the-hosting). + +1. [**Security steps required**](/operators/troubleshooting/vps-isp#security-patch-copyfail--dirtyfrag): Several critical [Linux kernel vulnerabilities](https://ubuntu.com/blog/copy-fail-vulnerability-fixes-available) had been disclosed. Check out your servers and if needed apply required mitigations! +- [**New Nym Wallet `v1.2.20`**](https://github.com/nymtech/nym/releases/tag/nym-wallet-v1.2.20) + + - [**NIP-11 - NTM updated: Telegram voice and video call works now!**](https://github.com/nymtech/nym/pull/6807) Please re-run [Nym network tunnel manager](https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/nym-node-setup/network-tunnel-manager.sh) (NTM) on your hosting servers:
@@ -121,13 +144,82 @@ ansible-playbook deploy.yml -t ntm - [**New docs**](https://github.com/nymtech/nym/pull/6716): Max's leg work on [exit services documentation](/network/infrastructure/exit-services), [`Mixfetch`](/developers/mix-fetch) and [`smolmix`](/developers/smolmix) -### Operators UX Improvements +#### Migrate away from The Hosting -- [NTM: Split IPv4 / IPv6 uplinks](https://github.com/nymtech/nym/pull/6640): Now NTM can work with different uplink interfaces for IPv4 and IPv6 +**WorkTitans B.V. ([AS209847](https://ipinfo.io/AS209847))**, also known as _the.hosting_, _PQ-Hosting_ and _Stark Industries_, has been [seized by Dutch authorities](https://securityaffairs.com/192602/intelligence/dutch-authorities-dismantle-hosting-network-allegedly-used-for-cyberattacks-and-disinformation.html). Infrastructure in the United States, Germany, the Netherlands and Austria was permanently lost — **nodes hosted there are gone and cannot be restored.** -- [Nym Node CLI: Split IPv4 / IPv6 uplinks](https://github.com/nymtech/nym/pull/6743): `nym-node-cli.py` uplinks sync up with NTM +This provider had been the most popular choice among Nym node operators for years, combining solid services, broad location coverage, good port speeds, unlimited bandwidth and crypto payments. Despite this, it repeatedly proved unreliable and put operations at risk in terms of reliability, security and privacy. + +##### Action Steps + +- **All operators must move away from [the.hosting](https://the.hosting/en/) (WorkTitans B.V., [AS209847](https://ipinfo.io/AS209847)) as soon as possible** +- **If your nodes are under SGP, this is a requirement — please act within one month** +- **If this affects your locations or grant size, contact us before purchasing new servers** +- When researching alternatives, check [_The ISP List_](/operators/community-counsel/isp-list) and please submit a PR if you find anything outdated +- We are in talks with several providers to establish mission-aligned partnerships and negotiate discounts on dedicated servers, will keep you updated + +This situation is a reminder of why we have [Operator Terms and Conditions with zero logging tolerance](/operators/nodes/nym-node/setup#terms--conditions) and do active steps to reinforce the security model described in our [latest Operators Town Hall](https://www.youtube.com/watch?v=j8WWBY8ewXE). + +#### Operators UX Improvements + +- [**NTM: Split IPv4 / IPv6 uplinks**](https://github.com/nymtech/nym/pull/6640): Now NTM can work with different uplink interfaces for IPv4 and IPv6 + +- [**Nym Node CLI: Split IPv4 / IPv6 uplinks**](https://github.com/nymtech/nym/pull/6743): `nym-node-cli.py` uplinks sync up with NTM + +- [**NTM & Nym Node CLI: Alternative SSH port**](https://github.com/nymtech/nym/pull/6633): Operators can use these tools with `HOST_SSH_PORT` allowing them to define any alternative port instead of only using hard-coded 22 + +- [**Token Rewards SpectreDAO Explorer page**](https://explorer.nym.spectredao.net/rewards): The most favorite Nym explorer of the year is shipping another feature, showing rewards and much more in a nice GUI + +### Features + +- [Re-order default API urls for network details - Waterloo release](https://github.com/nymtech/nym/pull/6799): + +- [Add workflows for NM3](https://github.com/nymtech/nym/pull/6729): Added automated GitHub Actions workflows to streamline deployment of network monitor components to the container registry with optional release versioning + +- [Credential proxy pool](https://github.com/nymtech/nym/pull/6726) + +- [NMv3 updated performance calculation](https://github.com/nymtech/nym/pull/6714): Wire stress-testing scores submitted by the network-monitor orchestrator into nym-api's node performance calculation, behind a config gate and an availability guard so an orchestrator outage cannot silently slash every node's score. + +- [NMv3: submission of stress testing result into nym-api](https://github.com/nymtech/nym/pull/6709): Allow the network monitor orchestrator to submit stress-testing results to the nym-api over a signed, authenticated channel. + +- [NMv3: Prometheus metrics for network monitor](https://github.com/nymtech/nym/pull/6693): Wires up a `/v1/metrics/prometheus` scrape endpoint for the v3 orchestrator, along with the metric variants it exposes and the call-site instrumentation that feeds them. The handle follows the existing nym-node wrapper pattern: a singleton `PROMETHEUS_METRICS` backed by `nym_metrics`, with every variant pre-registered at startup so scrapes never see a missing series. + +- [NMv3: add read-only results API to orchestrator](https://github.com/nymtech/nym/pull/6689): Read in detail summary [here](https://github.com/nymtech/nym/pull/6689) + +- [NMv3: Eviction of stale testrun data](https://github.com/nymtech/nym/pull/6685): Read in detail summary [here](https://github.com/nymtech/nym/pull/6685) + +- [Nym Wallet: deps updates, clipboard/updater/, icon, polishing...](https://github.com/nymtech/nym/pull/6681): Rolls together desktop wallet UX polish, and operational fixes we have been carrying in the branch. The goal is safer defaults, less noisy background behaviour. + +- [NMv3: Wire up testrun assignment and result submission flow](https://github.com/nymtech/nym/pull/6680): Read in detail summary [here](https://github.com/nymtech/nym/pull/6680) + +- [NMv3: Support multiple network monitor agents per host](https://github.com/nymtech/nym/pull/6679): Read in detail summary [here](https://github.com/nymtech/nym/pull/6679) + +- [NMv3 agent announcement](https://github.com/nymtech/nym/pull/6673): Read in detail summary [here](https://github.com/nymtech/nym/pull/6673) + +- [Add node refresher for periodic scraping of bonded nym-node details](https://github.com/nymtech/nym/pull/6626) + +- [NMv3 orchestrator queue](https://github.com/nymtech/nym/pull/6597): This PR bootstraps the orchestrator side of the v3 network monitor. It introduces the persistent storage layer, configuration, CLI wiring, and the initial NetworkMonitorOrchestrator struct - everything needed before the actual scheduling and HTTP server logic lands in follow-up PRs. + +- [Network monitor agent - standalone node stress-testing](https://github.com/nymtech/nym/pull/6582): Introduces the nym-network-monitor-agent binary. The agent can connect to a single mixnode and run a controlled stress test against it without requiring an orchestrator, making it useful for manual diagnostics as well as the foundation for the future automated pipeline. + +- [Propagate NM agent noise keys to `nym-node` routing](https://github.com/nymtech/nym/pull/6577): Network Monitor agents need to perform Noise protocol handshakes with `nym-node`s, just like any other `nym-node` on the network. Previously the contract stored only the agent's IP address, and the noise key map in `nym-node` only tracked keys for `nym-api`-sourced nodes. This PR closes the gap end-to-end: from on-chain registration through to live packet routing. + +- [Start mix stress testing topic branch](https://github.com/nymtech/nym/pull/6575) + +- [NMv3 agents subscription](https://github.com/nymtech/nym/pull/6567): This PR introduces real-time blockchain monitoring for network monitor agent authorizations and implements replay protection bypass for authorized network monitor (NM) agents. This allows NM agents to perform node stress testing, while maintaining security for regular traffic. + +- [NMv3 agents contract](https://github.com/nymtech/nym/pull/6555): This PR introduces the smart contract storing information about ip addresses of the authorised NM agents. + +### Bugfix + +- [IPR v8\<\-\>v9 mismatch on Waterloo](https://github.com/nymtech/nym/pull/6772) + +### Refactors & Maintenance + +- [Migrate to hickory `0.26.1`](https://github.com/nymtech/nym/pull/6751): Migrate to hickory `0.26.1`. Fixes recent CVEs reported over GitHub + +- [Made sphinx version threshold assertion a compile time check](https://github.com/nymtech/nym/pull/6718) -- [NTM & Nym Node CLI: Alternative SSH port](https://github.com/nymtech/nym/pull/6633): Operators can use these tools with `HOST_SSH_PORT` allowing them to define any alternative port instead of only using hard-coded 22 ## `v2026.9-venaco` diff --git a/documentation/docs/pages/operators/nodes/nym-node/setup.mdx b/documentation/docs/pages/operators/nodes/nym-node/setup.mdx index b6e9787cfc..93973076dd 100644 --- a/documentation/docs/pages/operators/nodes/nym-node/setup.mdx +++ b/documentation/docs/pages/operators/nodes/nym-node/setup.mdx @@ -21,10 +21,10 @@ This documentation page provides a guide on how to set up and run a [NYM NODE](. ```sh nym-node Binary Name: nym-node -Build Timestamp: 2026-05-06T05:19:51.973494120Z -Build Version: 1.31.0 -Commit SHA: f84de25302e886d4bd97a898885c569724c002a7 -Commit Date: 2026-05-06T07:16:42.000000000+02:00 +Build Timestamp: 2026-05-27T12:46:38.359447083Z +Build Version: 1.32.0 +Commit SHA: 25eba09b92cff648cd37bdd7f0921e710eed25f5 +Commit Date: 2026-05-27T11:00:31.000000000+02:00 Commit Branch: HEAD rustc Version: 1.91.1 rustc Channel: stable From dd8c0a25217e3e8127767645b004591b4eb1fb20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 28 May 2026 14:03:18 +0100 Subject: [PATCH 58/94] Bugfix/cherry pick/waterloo ns api (#6833) * NS: don't return nodes with 0 performance * reduce concurrency during quorum check tests * add additional leniency in ticketbook requests --- Cargo.lock | 4 +- common/credential-proxy/src/quorum_checker.rs | 26 +++- common/credentials/Cargo.toml | 8 ++ .../src/ecash/bandwidth/issuance.rs | 51 +++++++ common/credentials/src/ecash/utils.rs | 10 +- common/credentials/src/error.rs | 3 + common/ecash-signer-check/src/client_check.rs | 4 +- common/ecash-signer-check/src/lib.rs | 28 ++-- ...cad1c89d9df3ffaf4b5d00db5adfdef854c4.json} | 8 +- .../nym-node-status-api/Cargo.toml | 2 +- .../src/db/queries/ecash_data.rs | 8 +- .../nym-node-status-api/src/http/state.rs | 136 +++++++++--------- .../nym-node-status-api/src/main.rs | 5 + .../src/ticketbook_manager/mod.rs | 5 +- .../src/ticketbook_manager/storage/mod.rs | 4 + .../validator-status-check/Cargo.toml | 2 +- 16 files changed, 208 insertions(+), 96 deletions(-) rename nym-node-status-api/nym-node-status-api/.sqlx/{query-2ee6b058d423a66114d8411e7c287ade31137b30407dc0254d30f60e2d0101cf.json => query-7c2f58e63efd85010408f812692ecad1c89d9df3ffaf4b5d00db5adfdef854c4.json} (56%) diff --git a/Cargo.lock b/Cargo.lock index a78d5bd7d4..d3e0c6b5df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6644,6 +6644,8 @@ dependencies = [ "serde", "thiserror 2.0.18", "time", + "tokio", + "wasmtimer", "zeroize", ] @@ -7879,7 +7881,7 @@ dependencies = [ [[package]] name = "nym-node-status-api" -version = "4.6.2-rc7" +version = "4.6.2-rc10" dependencies = [ "ammonia", "anyhow", diff --git a/common/credential-proxy/src/quorum_checker.rs b/common/credential-proxy/src/quorum_checker.rs index 2c1127fc9e..59e6cc0eaf 100644 --- a/common/credential-proxy/src/quorum_checker.rs +++ b/common/credential-proxy/src/quorum_checker.rs @@ -27,6 +27,9 @@ pub struct QuorumStateChecker { cancellation_token: CancellationToken, check_interval: Duration, quorum_state: QuorumState, + + /// indicates whether the last check has been a failure + last_failed: bool, } impl QuorumStateChecker { @@ -42,6 +45,7 @@ impl QuorumStateChecker { quorum_state: QuorumState { available: Arc::new(Default::default()), }, + last_failed: false, }; // first check MUST succeed, otherwise we shouldn't start @@ -65,7 +69,7 @@ impl QuorumStateChecker { let dkg_details = dkg_details_with_client(client_guard.deref()).await?; drop(client_guard); - let res = check_known_dealers(dkg_details).await?; + let res = check_known_dealers(dkg_details, 4).await?; info!("there are {} known DKG dealers", res.results.len()); let Some(signing_threshold) = res.threshold else { @@ -107,7 +111,7 @@ impl QuorumStateChecker { Ok(available) } - pub async fn run_forever(self) { + pub async fn run_forever(mut self) { info!("starting quorum state checker"); loop { tokio::select! { @@ -117,7 +121,23 @@ impl QuorumStateChecker { } _ = tokio::time::sleep(self.check_interval) => { match self.check_quorum_state().await { - Ok(available) => self.quorum_state.available.store(available, Ordering::SeqCst), + Ok(available) => { + let previous = self.quorum_state.available.load(Ordering::SeqCst); + // only update the quorum state to a failed state if we've had two consecutive failures + if available { + if !previous { + info!("quorum recovered"); + } + self.quorum_state.available.store(true, Ordering::SeqCst); + } else if self.last_failed { + if previous { + warn!("quorum became unavailable after 2 consecutive failed checks"); + } + self.quorum_state.available.store(false, Ordering::SeqCst); + } + + self.last_failed = !available; + }, Err(err) => error!("failed to check current quorum state: {err}"), } } diff --git a/common/credentials/Cargo.toml b/common/credentials/Cargo.toml index ab45bf851f..b73222c612 100644 --- a/common/credentials/Cargo.toml +++ b/common/credentials/Cargo.toml @@ -36,5 +36,13 @@ nym-ecash-contract-common = { workspace = true } nym-network-defaults = { workspace = true } nym-serde-helpers = { workspace = true, features = ["date"] } +[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio] +workspace = true +features = ["time"] + +[target."cfg(target_arch = \"wasm32\")".dependencies.wasmtimer] +workspace = true +features = ["tokio"] + [dev-dependencies] rand = { workspace = true } diff --git a/common/credentials/src/ecash/bandwidth/issuance.rs b/common/credentials/src/ecash/bandwidth/issuance.rs index 6bde4eb9e9..ee84cfb19c 100644 --- a/common/credentials/src/ecash/bandwidth/issuance.rs +++ b/common/credentials/src/ecash/bandwidth/issuance.rs @@ -6,6 +6,7 @@ use crate::ecash::bandwidth::serialiser::VersionedSerialise; use crate::ecash::bandwidth::CredentialSigningData; use crate::ecash::utils::cred_exp_date; use crate::error::Error; +use log::{debug, warn}; use nym_api_requests::ecash::BlindSignRequestBody; use nym_credentials_interface::{ aggregate_wallets, generate_keypair_user_from_seed, issue_verify, withdrawal_request, @@ -17,8 +18,15 @@ use nym_ecash_contract_common::deposit::DepositId; use nym_ecash_time::{ecash_default_expiration_date, ecash_today, EcashTime}; use nym_validator_client::nym_api::{EpochId, NymApiClientExt}; use serde::{Deserialize, Serialize}; +use std::time::Duration; use time::Date; +#[cfg(not(target_arch = "wasm32"))] +use tokio::time::sleep; + +#[cfg(target_arch = "wasm32")] +use wasmtimer::tokio::sleep; + pub use nym_validator_client::nyxd::{Coin, Hash}; #[derive(Serialize, Deserialize)] @@ -192,6 +200,49 @@ impl IssuanceTicketBook { Ok(unblinded_signature) } + // ideally this would have been generic over credential type, but we really don't need secp256k1 keys for bandwidth vouchers + pub async fn obtain_partial_ticketbook_credential_with_retries( + &self, + client: &nym_http_api_client::Client, + signer_index: u64, + validator_vk: &VerificationKeyAuth, + signing_data: CredentialSigningData, + max_attempts: usize, + ) -> Result { + let Some(client_url) = client.base_urls().first() else { + return Err(Error::CredentialShareObtainFailed); + }; + let mut last_err = None; + for attempt in 0..max_attempts { + if attempt > 0 { + sleep(Duration::from_millis(500 * attempt as u64)).await; + } + debug!( + "attempt {} / {max_attempts} to obtain partial ticketbook credential from {client_url}", + attempt + 1, + ); + match self + .obtain_partial_ticketbook_credential( + client, + signer_index, + validator_vk, + signing_data.clone(), + ) + .await + { + Ok(partial_wallet) => return Ok(partial_wallet), + Err(err) => { + warn!( + "attempt {} / {max_attempts} to obtain partial ticketbook credential from {client_url} failed: {err}", + attempt + 1, + ); + last_err = Some(err); + } + } + } + Err(last_err.unwrap_or(Error::CredentialShareObtainFailed)) + } + // ideally this would have been generic over credential type, but we really don't need secp256k1 keys for bandwidth vouchers pub async fn obtain_partial_ticketbook_credential( &self, diff --git a/common/credentials/src/ecash/utils.rs b/common/credentials/src/ecash/utils.rs index b2b1321051..dba3448a45 100644 --- a/common/credentials/src/ecash/utils.rs +++ b/common/credentials/src/ecash/utils.rs @@ -137,6 +137,8 @@ pub async fn obtain_aggregate_wallet( ecash_api_clients: &[EcashApiClient], threshold: u64, ) -> Result { + const MAX_ATTEMPTS: usize = 2; + if ecash_api_clients.len() < threshold as usize { return Err(Error::NoValidatorsAvailable); } @@ -154,11 +156,12 @@ pub async fn obtain_aggregate_wallet( ); match voucher - .obtain_partial_ticketbook_credential( + .obtain_partial_ticketbook_credential_with_retries( &ecash_api_client.api_client, ecash_api_client.node_id, &ecash_api_client.verification_key, request.clone(), + MAX_ATTEMPTS, ) .await { @@ -167,6 +170,11 @@ pub async fn obtain_aggregate_wallet( warn!("failed to obtain partial credential from API {ecash_api_client}: {err}",); } }; + + // we got sufficient number of shares + if wallets.len() >= threshold as usize { + break; + } } if wallets.len() < threshold as usize { return Err(Error::NotEnoughShares); diff --git a/common/credentials/src/error.rs b/common/credentials/src/error.rs index daabbcdb1b..b17aaa4734 100644 --- a/common/credentials/src/error.rs +++ b/common/credentials/src/error.rs @@ -63,6 +63,9 @@ pub enum Error { #[error("failed to create a secp256k1 signature")] Secp256k1SignFailure, + + #[error("failed to obtain a valid credential share")] + CredentialShareObtainFailed, } impl From for Error { diff --git a/common/ecash-signer-check/src/client_check.rs b/common/ecash-signer-check/src/client_check.rs index 4d0026384c..1bb6b72257 100644 --- a/common/ecash-signer-check/src/client_check.rs +++ b/common/ecash-signer-check/src/client_check.rs @@ -195,9 +195,9 @@ impl ClientUnderTest { pub(crate) async fn check_client( dealer_details: DealerDetails, dkg_epoch: u64, - contract_share: Option<&ContractVKShare>, + contract_share: Option, ) -> TypedSignerResult { - let dealer_information = RawDealerInformation::new(&dealer_details, contract_share); + let dealer_information = RawDealerInformation::new(&dealer_details, contract_share.as_ref()); // 7. attempt to construct client instances out of them let Ok(parsed_information) = dealer_information.parse() else { diff --git a/common/ecash-signer-check/src/lib.rs b/common/ecash-signer-check/src/lib.rs index 05a3be5ba5..91deb467e1 100644 --- a/common/ecash-signer-check/src/lib.rs +++ b/common/ecash-signer-check/src/lib.rs @@ -2,7 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 use crate::client_check::check_client; -use futures::stream::{FuturesUnordered, StreamExt}; +use futures::stream; +use futures::stream::StreamExt; use nym_ecash_signer_check_types::status::{SignerResult, Status}; use nym_network_defaults::NymNetworkDetails; use nym_validator_client::QueryHttpRpcNyxdClient; @@ -65,7 +66,7 @@ where C: DkgQueryClient + Sync, { let dkg_details = dkg_details_with_client(client).await?; - check_known_dealers(dkg_details).await + check_known_dealers(dkg_details, None).await } pub async fn dkg_details_with_client(client: &C) -> Result @@ -109,18 +110,21 @@ where pub async fn check_known_dealers( dkg_details: DkgDetails, + concurrency: impl Into>, ) -> Result { // 6. for each dealer attempt to perform the checks - let results = dkg_details - .network_dealers - .into_iter() - .map(|d| { - let share = dkg_details.submitted_shared.get(&d.assigned_index); - check_client(d, dkg_details.dkg_epoch.epoch_id, share) - }) - .collect::>() - .collect::>() - .await; + let epoch_id = dkg_details.dkg_epoch.epoch_id; + let submitted = dkg_details.submitted_shared; + let dealers = dkg_details.network_dealers.len(); + + let tasks = dkg_details.network_dealers.into_iter().map(move |d| { + let share = submitted.get(&d.assigned_index).cloned(); + check_client(d, epoch_id, share) + }); + + let limit = concurrency.into().filter(|&n| n > 0).unwrap_or(dealers); + + let results = stream::iter(tasks).buffer_unordered(limit).collect().await; Ok(SignersTestResult { threshold: dkg_details.threshold, diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-2ee6b058d423a66114d8411e7c287ade31137b30407dc0254d30f60e2d0101cf.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-7c2f58e63efd85010408f812692ecad1c89d9df3ffaf4b5d00db5adfdef854c4.json similarity index 56% rename from nym-node-status-api/nym-node-status-api/.sqlx/query-2ee6b058d423a66114d8411e7c287ade31137b30407dc0254d30f60e2d0101cf.json rename to nym-node-status-api/nym-node-status-api/.sqlx/query-7c2f58e63efd85010408f812692ecad1c89d9df3ffaf4b5d00db5adfdef854c4.json index 4a11df7ad6..9eba21b14b 100644 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-2ee6b058d423a66114d8411e7c287ade31137b30407dc0254d30f60e2d0101cf.json +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-7c2f58e63efd85010408f812692ecad1c89d9df3ffaf4b5d00db5adfdef854c4.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "\n INSERT INTO pending_issuance\n (deposit_id, serialization_revision, pending_ticketbook_data, expiration_date)\n VALUES ($1, $2, $3, $4)\n ", + "query": "\n INSERT INTO pending_issuance\n (deposit_id, serialization_revision, pending_ticketbook_data, expiration_date, epoch_id, failure_message)\n VALUES ($1, $2, $3, $4, $5, $6)\n ", "describe": { "columns": [], "parameters": { @@ -8,10 +8,12 @@ "Int4", "Int2", "Bytea", - "Date" + "Date", + "Int4", + "Text" ] }, "nullable": [] }, - "hash": "2ee6b058d423a66114d8411e7c287ade31137b30407dc0254d30f60e2d0101cf" + "hash": "7c2f58e63efd85010408f812692ecad1c89d9df3ffaf4b5d00db5adfdef854c4" } diff --git a/nym-node-status-api/nym-node-status-api/Cargo.toml b/nym-node-status-api/nym-node-status-api/Cargo.toml index 6a414e3743..2306bc0708 100644 --- a/nym-node-status-api/nym-node-status-api/Cargo.toml +++ b/nym-node-status-api/nym-node-status-api/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node-status-api" -version = "4.6.2-rc7" +version = "4.6.2-rc10" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/nym-node-status-api/nym-node-status-api/src/db/queries/ecash_data.rs b/nym-node-status-api/nym-node-status-api/src/db/queries/ecash_data.rs index 0f90e5884a..02d648edb3 100644 --- a/nym-node-status-api/nym-node-status-api/src/db/queries/ecash_data.rs +++ b/nym-node-status-api/nym-node-status-api/src/db/queries/ecash_data.rs @@ -30,17 +30,21 @@ impl Storage { deposit_id: i32, data: &[u8], expiration_date: Date, + epoch_id: i32, + failure_message: &str, ) -> Result<(), sqlx::Error> { sqlx::query!( r#" INSERT INTO pending_issuance - (deposit_id, serialization_revision, pending_ticketbook_data, expiration_date) - VALUES ($1, $2, $3, $4) + (deposit_id, serialization_revision, pending_ticketbook_data, expiration_date, epoch_id, failure_message) + VALUES ($1, $2, $3, $4, $5, $6) "#, deposit_id, serialisation_revision, data, expiration_date, + epoch_id, + failure_message, ) .execute(&self.pool) .await?; diff --git a/nym-node-status-api/nym-node-status-api/src/http/state.rs b/nym-node-status-api/nym-node-status-api/src/http/state.rs index 317ebba7f6..1776ea23e3 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/state.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/state.rs @@ -384,87 +384,87 @@ impl HttpCache { let socks5_scores = calculate_socks5_percentiles(&gateways); - let res_gws = gateways - .iter() - .filter(|gw| gw.bonded) - .filter_map(|gw| match skimmed_nodes.get(&gw.gateway_identity_key) { - Some(skimmed_node) => Some((gw, skimmed_node)), - None => { - error!( - "CRITICAL: Gateway {} exists in gateways table but not in nym_nodes table! This should not happen.", - gw.gateway_identity_key - ); - None - } - }) - .filter_map(|(gw, skimmed_node)| { - let family = family_lookup.family_for_node(skimmed_node.node_id).cloned(); - let staking = bond_info - .get(&skimmed_node.node_id) - .map(|details| NodeStakeInformation::from(&details.rewarding_details)); - match DVpnGateway::new( - gw.clone(), - skimmed_node, - socks5_scores.get(&gw.gateway_identity_key), - family, - staking, - ) { - Ok(gw) => Some(gw), - Err(err) => { - error!( - "CRITICAL: Failed to create DVpnGateway for node_id={}, identity_key={}: {}", - skimmed_node.node_id, - skimmed_node.ed25519_identity_pubkey.to_base58_string(), - err - ); - // Don't panic here as this might be due to missing fields, but log it loudly - None - } - } - }) - .filter(|gw| { - // gateways must have a country - if gw.location.two_letter_iso_country_code.len() == 2 { - true - } else { - warn!( - "Invalid country code: {}", - gw.location.two_letter_iso_country_code - ); - false - } - }) - // sort by country, then by identity key - .sorted_by_key(|item| { - ( - item.location.two_letter_iso_country_code.clone(), - item.identity_key.clone(), - ) - }) - .collect::>(); - + let mut dvpd_gateways = Vec::new(); let bonded_count = gateways.iter().filter(|gw| gw.bonded).count(); + + for gw in gateways { + let id = gw.gateway_identity_key.clone(); + // 1. reject all gateways that are not bonded + if !gw.bonded { + continue; + } + + // 2. reject all gateways with zero performance + if gw.performance == 0 { + continue; + } + + // 3. get corresponding directory details + let Some(skimmed_node) = skimmed_nodes.get(&id) else { + error!( + "CRITICAL: Gateway {id} exists in gateways table but not in nym_nodes table! This should not happen", + ); + continue; + }; + let node_id = skimmed_node.node_id; + + // 4. get corresponding auxiliary details + let family = family_lookup.family_for_node(skimmed_node.node_id).cloned(); + let staking = bond_info + .get(&skimmed_node.node_id) + .map(|details| NodeStakeInformation::from(&details.rewarding_details)); + let socks5_score = socks5_scores.get(&id); + + // 5. construct the DVpnGateway model + let dvpn_gw = match DVpnGateway::new(gw, skimmed_node, socks5_score, family, staking) { + Ok(gw) => gw, + Err(err) => { + error!( + "CRITICAL: Failed to create DVpnGateway for node_id={node_id}, identity_key={id}: {err}", + ); + // Don't panic here as this might be due to missing fields, but log it loudly + continue; + } + }; + + // 6. filter out nodes without valid country codes + if dvpn_gw.location.two_letter_iso_country_code.len() != 2 { + warn!( + "Invalid country code: {}", + dvpn_gw.location.two_letter_iso_country_code + ); + continue; + } + + dvpd_gateways.push(dvpn_gw); + } + + // 7. finally, sort the nodes by country, then by identity key + dvpd_gateways.sort_by_key(|item| { + ( + item.location.two_letter_iso_country_code.clone(), + item.identity_key.clone(), + ) + }); + tracing::info!( - "DVpn gateway filtering: {} total gateways, {} bonded, {} nym_nodes, {} final DVpn gateways", - started_with, - bonded_count, + "DVpn gateway filtering: {started_with} total gateways, {bonded_count} bonded, {} nym_nodes, {} final DVpn gateways", skimmed_nodes.len(), - res_gws.len() + dvpd_gateways.len() ); - if res_gws.is_empty() && started_with > 0 { + if dvpd_gateways.is_empty() && started_with > 0 { tracing::error!( - "CRITICAL: Started with {} gateways but got 0 DVpn gateways!", - started_with + "CRITICAL: Started with {started_with} gateways but got 0 DVpn gateways!" ); } else { tracing::info!( "Successfully loaded {} DVpn gateways into cache", - res_gws.len() + dvpd_gateways.len() ); } - res_gws + dvpd_gateways } pub async fn get_entry_dvpn_gateways( diff --git a/nym-node-status-api/nym-node-status-api/src/main.rs b/nym-node-status-api/nym-node-status-api/src/main.rs index 0d504638a1..c392edb880 100644 --- a/nym-node-status-api/nym-node-status-api/src/main.rs +++ b/nym-node-status-api/nym-node-status-api/src/main.rs @@ -4,6 +4,7 @@ use crate::node_scraper::helpers::scrape_and_store_description_by_node_id; use crate::ticketbook_manager::TicketbookManager; use crate::ticketbook_manager::state::TicketbookManagerState; use clap::Parser; +use nym_bin_common::bin_info_owned; use nym_credential_proxy_lib::quorum_checker::QuorumStateChecker; use nym_credential_proxy_lib::shared_state::nyxd_client::ChainClient; use nym_crypto::asymmetric::ed25519::PublicKey; @@ -11,6 +12,7 @@ use nym_network_defaults::setup_env; use nym_task::ShutdownManager; use nym_validator_client::nyxd::NyxdClient; use std::sync::Arc; +use tracing::info; mod cli; mod db; @@ -27,6 +29,9 @@ mod utils; async fn main() -> anyhow::Result<()> { logging::setup_tracing_logger()?; + let bin_info = bin_info_owned!(); + info!("using the following version: {bin_info}"); + let args = cli::Cli::parse(); if let Some(env_file) = &args.config_env_file { setup_env(Some(env_file)); diff --git a/nym-node-status-api/nym-node-status-api/src/ticketbook_manager/mod.rs b/nym-node-status-api/nym-node-status-api/src/ticketbook_manager/mod.rs index 0a7f6c8e11..db141ec7c5 100644 --- a/nym-node-status-api/nym-node-status-api/src/ticketbook_manager/mod.rs +++ b/nym-node-status-api/nym-node-status-api/src/ticketbook_manager/mod.rs @@ -121,11 +121,12 @@ impl TicketbookManager { { Err(err) => { error!("failed to obtain aggregated wallet: {err}"); + let failure_message = err.to_string(); self.state .storage() - .insert_pending_ticketbook(&issuance_data).await.inspect_err(|err| { + .insert_pending_ticketbook(&issuance_data, epoch_id, &failure_message).await.inspect_err(|store_err| { let deposit = issuance_data.deposit_id(); - error!("could not save the recovery data for deposit {deposit}: {err}. the data will unfortunately get lost") + error!("could not save the recovery data for deposit {deposit}: {store_err}. the data will unfortunately get lost") })?; return Err(err.into()); } diff --git a/nym-node-status-api/nym-node-status-api/src/ticketbook_manager/storage/mod.rs b/nym-node-status-api/nym-node-status-api/src/ticketbook_manager/storage/mod.rs index f2aebcfafd..73d790964d 100644 --- a/nym-node-status-api/nym-node-status-api/src/ticketbook_manager/storage/mod.rs +++ b/nym-node-status-api/nym-node-status-api/src/ticketbook_manager/storage/mod.rs @@ -43,6 +43,8 @@ impl TicketbookManagerStorage { pub(crate) async fn insert_pending_ticketbook( &self, ticketbook: &IssuanceTicketBook, + epoch_id: EpochId, + failure_message: &str, ) -> anyhow::Result<()> { let ser = ticketbook.pack(); let data = Zeroizing::new(ser.data); @@ -54,6 +56,8 @@ impl TicketbookManagerStorage { ticketbook.deposit_id() as i32, &data, ticketbook.expiration_date(), + epoch_id as i32, + failure_message, ) .await?; diff --git a/tools/internal/validator-status-check/Cargo.toml b/tools/internal/validator-status-check/Cargo.toml index 774b5c4cbb..b61d85193a 100644 --- a/tools/internal/validator-status-check/Cargo.toml +++ b/tools/internal/validator-status-check/Cargo.toml @@ -23,7 +23,7 @@ tracing = { workspace = true } time = { workspace = true } -nym-validator-client = { workspace = true } +nym-validator-client = { workspace = true, features = ["http-client"] } nym-bin-common = { workspace = true, features = ["output_format", "basic_tracing"] } nym-network-defaults = { workspace = true } nym-http-api-client = { workspace = true } From f28b1e2077bde963ce8bf3e4b1255d897cc2034b Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Thu, 28 May 2026 14:21:53 +0000 Subject: [PATCH 59/94] test CI (#6835) --- documentation/docs/.npmrc | 1 - documentation/docs/pnpm-workspace.yaml | 12 ++++++------ 2 files changed, 6 insertions(+), 7 deletions(-) delete mode 100644 documentation/docs/.npmrc diff --git a/documentation/docs/.npmrc b/documentation/docs/.npmrc deleted file mode 100644 index 1a99418bf0..0000000000 --- a/documentation/docs/.npmrc +++ /dev/null @@ -1 +0,0 @@ -strict-dep-builds=false diff --git a/documentation/docs/pnpm-workspace.yaml b/documentation/docs/pnpm-workspace.yaml index 95d8678bce..9bd259ff46 100644 --- a/documentation/docs/pnpm-workspace.yaml +++ b/documentation/docs/pnpm-workspace.yaml @@ -1,9 +1,9 @@ packages: - "." -ignoredBuiltDependencies: - - core-js - - protobufjs - - sharp - - tiny-secp256k1 - - unrs-resolver +allowBuilds: + core-js: false + protobufjs: false + sharp: false + tiny-secp256k1: false + unrs-resolver: false From 43a1bd38e81cec6652f1e6bec0097880d600364d Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Thu, 28 May 2026 15:57:10 +0000 Subject: [PATCH 60/94] Max/smolmix wasm (#6784) * Mod gitignore + license trimming + comment trimming * Big rewrite * SURB inputs + DNS button in internal-dev * Make ipr addr optional * Accidentatly omitted files from rewrite commit * Makefile + readme * Comment rewrite * Optimisation comment * Replace manual waker map with smoltcp built-ins + adaptive poll * Comments * Extract socket creation helpers into stream.rs * Cleanup comments * Comment * Comment notes and restrict ciphersuites wrt rustls-rustcrypto * Dep. hack fix for demo + add clearnet fetch() for contrast * Stripped down devtester * Fix Clippy arg (fatfingered deletion) * CodeRabbit catches * Cargofmt * Review nits: bridge logs, fetch early-return, static port counter, copyright years, README + Cargo + headless.js tidying * PHONY + taskset override, switch internal-dev/tests to pnpm, fix wasm-pack out-dir * Gate codec tests behind the codec feature for no-default-features builds * IPv6 addr/route on smoltcp iface + configurable DNS resolvers via TunnelOpts * DNS GUI inputs, close stale WS on reconnect, worker init guards + ws-send warning, Playwright listener cleanup, pnpm-lock in internal-dev * Fix lp -> lp-data after rebase * Revert nym-lp/nym-lp-data feature-gating left over from rebase * Lift getrandom wasm_js cfg to workspace .cargo/config.toml so cargo check -p smolmix-wasm works from any CWD * temp will amend git message * Auto-discover IPR when none specified + 'Use random IPR' checkbox in internal-dev * smolmix_tracker + State machine + ready_tunnel gate + getTunnelState JS surface * Mirror red display() entries to console.error * Add left out package-lock * Reactor clock + yield_now + atomic seq + gateway-storage errors * setupMixTunnel gate + MTU 1980 + http::Uri cleanup * Review pass + fix test + clippy * restore axum 0.8 bump from borked earlier merge * Feature gating (dns/fetch/socket) + TunnelOptsBuilder + pnpm bypass * Cont. with review comments * tokio Nofity reactor wakes + cancellation + setup polishing * Notify wakes + inner pattern + close_notify + util * Tunable tunnelopts * Fix tired commit * CI prep * Lint + Clippy * coderabbit u32 fix * nits + runtime debugging + expose in internal-dev * remove redudant default-features * Remove more redundant default-features --- .cargo/config.toml | 2 + Cargo.lock | 218 +- Cargo.toml | 21 +- Makefile | 2 + common/ip-packet-requests/Cargo.toml | 5 +- common/ip-packet-requests/src/codec.rs | 22 +- .../src/response_helpers.rs | 3 +- common/nym-connection-monitor/Cargo.toml | 2 +- common/registration/Cargo.toml | 2 +- common/wasm/storage/Cargo.toml | 2 +- common/wasm/utils/src/lib.rs | 65 + nym-gateway-probe/Cargo.toml | 2 +- nym-node/Cargo.toml | 4 +- pnpm-lock.yaml | 569 +-- sdk/rust/nym-sdk/Cargo.toml | 4 +- smolmix/core/Cargo.toml | 4 +- wasm/smolmix/.cargo/config.toml | 6 + wasm/smolmix/.gitignore | 1 + wasm/smolmix/Cargo.toml | 118 + wasm/smolmix/Makefile | 50 + wasm/smolmix/README.md | 192 ++ wasm/smolmix/internal-dev/.npmrc | 13 + wasm/smolmix/internal-dev/bootstrap.js | 4 + .../internal-dev/headless-bootstrap.js | 4 + wasm/smolmix/internal-dev/headless.html | 11 + wasm/smolmix/internal-dev/headless.js | 316 ++ wasm/smolmix/internal-dev/index.html | 239 ++ wasm/smolmix/internal-dev/index.js | 858 +++++ wasm/smolmix/internal-dev/mix-socket.js | 230 ++ wasm/smolmix/internal-dev/package.json | 19 + wasm/smolmix/internal-dev/pnpm-lock.yaml | 3051 +++++++++++++++++ wasm/smolmix/internal-dev/webpack.config.js | 35 + wasm/smolmix/internal-dev/worker.js | 156 + wasm/smolmix/src/bridge.rs | 153 + wasm/smolmix/src/device.rs | 162 + wasm/smolmix/src/dns.rs | 210 ++ wasm/smolmix/src/error.rs | 42 + wasm/smolmix/src/fetch.rs | 372 ++ wasm/smolmix/src/http.rs | 237 ++ wasm/smolmix/src/ipr.rs | 314 ++ wasm/smolmix/src/lib.rs | 280 ++ wasm/smolmix/src/mixdns.rs | 21 + wasm/smolmix/src/mixfetch.rs | 18 + wasm/smolmix/src/mixsocket.rs | 286 ++ wasm/smolmix/src/reactor.rs | 202 ++ wasm/smolmix/src/state.rs | 105 + wasm/smolmix/src/stream.rs | 452 +++ wasm/smolmix/src/tls.rs | 164 + wasm/smolmix/src/tunnel.rs | 623 ++++ wasm/smolmix/src/util.rs | 24 + wasm/smolmix/tests/.gitignore | 4 + wasm/smolmix/tests/README.md | 130 + wasm/smolmix/tests/package-lock.json | 1119 ++++++ wasm/smolmix/tests/package.json | 16 + wasm/smolmix/tests/playwright.config.mjs | 88 + wasm/smolmix/tests/tests/smoke.spec.mjs | 81 + wasm/smolmix/tests/tests/suite.spec.mjs | 152 + 57 files changed, 10844 insertions(+), 641 deletions(-) create mode 100644 .cargo/config.toml create mode 100644 wasm/smolmix/.cargo/config.toml create mode 100644 wasm/smolmix/.gitignore create mode 100644 wasm/smolmix/Cargo.toml create mode 100644 wasm/smolmix/Makefile create mode 100644 wasm/smolmix/README.md create mode 100644 wasm/smolmix/internal-dev/.npmrc create mode 100644 wasm/smolmix/internal-dev/bootstrap.js create mode 100644 wasm/smolmix/internal-dev/headless-bootstrap.js create mode 100644 wasm/smolmix/internal-dev/headless.html create mode 100644 wasm/smolmix/internal-dev/headless.js create mode 100644 wasm/smolmix/internal-dev/index.html create mode 100644 wasm/smolmix/internal-dev/index.js create mode 100644 wasm/smolmix/internal-dev/mix-socket.js create mode 100644 wasm/smolmix/internal-dev/package.json create mode 100644 wasm/smolmix/internal-dev/pnpm-lock.yaml create mode 100644 wasm/smolmix/internal-dev/webpack.config.js create mode 100644 wasm/smolmix/internal-dev/worker.js create mode 100644 wasm/smolmix/src/bridge.rs create mode 100644 wasm/smolmix/src/device.rs create mode 100644 wasm/smolmix/src/dns.rs create mode 100644 wasm/smolmix/src/error.rs create mode 100644 wasm/smolmix/src/fetch.rs create mode 100644 wasm/smolmix/src/http.rs create mode 100644 wasm/smolmix/src/ipr.rs create mode 100644 wasm/smolmix/src/lib.rs create mode 100644 wasm/smolmix/src/mixdns.rs create mode 100644 wasm/smolmix/src/mixfetch.rs create mode 100644 wasm/smolmix/src/mixsocket.rs create mode 100644 wasm/smolmix/src/reactor.rs create mode 100644 wasm/smolmix/src/state.rs create mode 100644 wasm/smolmix/src/stream.rs create mode 100644 wasm/smolmix/src/tls.rs create mode 100644 wasm/smolmix/src/tunnel.rs create mode 100644 wasm/smolmix/src/util.rs create mode 100644 wasm/smolmix/tests/.gitignore create mode 100644 wasm/smolmix/tests/README.md create mode 100644 wasm/smolmix/tests/package-lock.json create mode 100644 wasm/smolmix/tests/package.json create mode 100644 wasm/smolmix/tests/playwright.config.mjs create mode 100644 wasm/smolmix/tests/tests/smoke.spec.mjs create mode 100644 wasm/smolmix/tests/tests/suite.spec.mjs diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000000..861cc80f86 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,2 @@ +[target.wasm32-unknown-unknown] +rustflags = ["--cfg=getrandom_backend=\"wasm_js\""] diff --git a/Cargo.lock b/Cargo.lock index d3e0c6b5df..c606bed85c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -630,7 +630,7 @@ dependencies = [ "bytes", "form_urlencoded", "futures-util", - "http 1.4.0", + "http 1.4.1", "http-body 1.0.1", "http-body-util", "hyper 1.9.0", @@ -672,7 +672,7 @@ checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" dependencies = [ "bytes", "futures-core", - "http 1.4.0", + "http 1.4.1", "http-body 1.0.1", "http-body-util", "mime", @@ -695,7 +695,7 @@ dependencies = [ "futures-core", "futures-util", "headers", - "http 1.4.0", + "http 1.4.1", "http-body 1.0.1", "http-body-util", "mime", @@ -718,9 +718,9 @@ dependencies = [ [[package]] name = "axum-test" -version = "20.0.0" +version = "20.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a86bfe2ef15bee102ac34912f7f4542b0bb37dc464fa55461763999c4d625e7" +checksum = "43c6a2f1d97ee33c39f13dacc0f84ae781a9c2ed373a75bad1129094f5a7c4bd" dependencies = [ "anyhow", "axum", @@ -728,7 +728,7 @@ dependencies = [ "bytesize", "cookie", "expect-json", - "http 1.4.0", + "http 1.4.1", "http-body-util", "hyper 1.9.0", "hyper-util", @@ -1429,7 +1429,7 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39d2056bf065c8b4bce5a8898d40e175211ff4410add2a84d695845d3937c729" dependencies = [ - "http 1.4.0", + "http 1.4.1", ] [[package]] @@ -2331,10 +2331,10 @@ dependencies = [ "ip_network", "ip_network_table", "libc", - "nix 0.31.1", + "nix 0.31.3", "parking_lot", "ring", - "socket2 0.6.0", + "socket2 0.6.3", "thiserror 2.0.18", "tracing", "uniffi 0.31.0", @@ -2938,9 +2938,9 @@ dependencies = [ [[package]] name = "expect-json" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "869f97f4abe8e78fc812a94ad6b721d72c4fb5532877c79610f2c238d7ccf6c4" +checksum = "5e80819dbfe83c8a651f5344b08910d0037dac72988aef27ee4e6bedd7ae2e33" dependencies = [ "chrono", "email_address", @@ -2956,9 +2956,9 @@ dependencies = [ [[package]] name = "expect-json-macros" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e6fdf550180a6c29a28cb9aac262dc0064c25735641d2317f670075e9a469d9" +checksum = "c0637949cd816934f3b7aab44ff98e7ec1fb903c379e07dcb9eac943ec33499e" dependencies = [ "proc-macro2", "quote", @@ -3202,6 +3202,17 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "futures-rustls" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f2f12607f92c69b12ed746fabf9ca4f5c482cba46679c1a75b874ed7c26adb" +dependencies = [ + "futures-io", + "rustls 0.23.37", + "rustls-pki-types", +] + [[package]] name = "futures-sink" version = "0.3.32" @@ -3341,7 +3352,7 @@ dependencies = [ "futures-core", "futures-sink", "gloo-utils 0.2.0", - "http 1.4.0", + "http 1.4.1", "js-sys", "pin-project", "serde", @@ -3442,7 +3453,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http 1.4.0", + "http 1.4.1", "indexmap 2.13.0", "slab", "tokio", @@ -3593,7 +3604,7 @@ dependencies = [ "base64 0.22.1", "bytes", "headers-core", - "http 1.4.0", + "http 1.4.1", "httpdate", "mime", "sha1", @@ -3605,7 +3616,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" dependencies = [ - "http 1.4.0", + "http 1.4.1", ] [[package]] @@ -3678,7 +3689,7 @@ dependencies = [ "futures-util", "h2 0.4.11", "hickory-proto", - "http 1.4.0", + "http 1.4.1", "idna", "ipnet", "jni 0.22.4", @@ -3829,9 +3840,9 @@ dependencies = [ [[package]] name = "http" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "8be7462df143984c4598a256ef469b251d7d7f9e271135073e78fc535414f3d0" dependencies = [ "bytes", "itoa", @@ -3855,7 +3866,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.4.0", + "http 1.4.1", ] [[package]] @@ -3866,7 +3877,7 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", - "http 1.4.0", + "http 1.4.1", "http-body 1.0.1", "pin-project-lite", ] @@ -3966,7 +3977,7 @@ dependencies = [ "futures-channel", "futures-core", "h2 0.4.11", - "http 1.4.0", + "http 1.4.1", "http-body 1.0.1", "httparse", "httpdate", @@ -3997,7 +4008,7 @@ version = "0.27.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ - "http 1.4.0", + "http 1.4.1", "hyper 1.9.0", "hyper-util", "rustls 0.23.37", @@ -4032,14 +4043,14 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.4.0", + "http 1.4.1", "http-body 1.0.1", "hyper 1.9.0", "ipnet", "libc", "percent-encoding", "pin-project-lite", - "socket2 0.6.0", + "socket2 0.5.10", "tokio", "tower-service", "tracing", @@ -4792,9 +4803,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.180" +version = "0.2.186" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" [[package]] name = "libcrux-aesgcm" @@ -5394,13 +5405,13 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.4" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", "wasi 0.11.1+wasi-snapshot-preview1", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -5611,9 +5622,9 @@ dependencies = [ [[package]] name = "nix" -version = "0.31.1" +version = "0.31.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225e7cfe711e0ba79a68baeddb2982723e4235247aefce1482f2f16c27865b66" +checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d" dependencies = [ "bitflags 2.9.1", "cfg-if", @@ -7104,7 +7115,7 @@ dependencies = [ "encoding_rs", "fastrand", "hickory-resolver", - "http 1.4.0", + "http 1.4.1", "inventory", "itertools 0.14.0", "mime", @@ -7229,7 +7240,6 @@ dependencies = [ "serde", "thiserror 2.0.18", "time", - "tokio", "tokio-util", "tracing", ] @@ -8154,7 +8164,7 @@ dependencies = [ "dotenvy", "futures", "hex", - "http 1.4.0", + "http 1.4.1", "httpcodec", "log", "nym-bandwidth-controller", @@ -9260,7 +9270,7 @@ checksum = "d7a6d09a73194e6b66df7c8f1b680f156d916a1a942abf2de06823dd02b7855d" dependencies = [ "async-trait", "bytes", - "http 1.4.0", + "http 1.4.1", "opentelemetry", "reqwest 0.12.22", ] @@ -9271,7 +9281,7 @@ version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a2366db2dca4d2ad033cad11e6ee42844fd727007af5ad04a1730f4cb8163bf" dependencies = [ - "http 1.4.0", + "http 1.4.1", "opentelemetry", "opentelemetry-http", "opentelemetry-proto", @@ -9626,6 +9636,16 @@ dependencies = [ "spki 0.7.3", ] +[[package]] +name = "pkcs5" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e847e2c91a18bfa887dd028ec33f2fe6f25db77db3619024764914affe8b69a6" +dependencies = [ + "der 0.7.10", + "spki 0.7.3", +] + [[package]] name = "pkcs8" version = "0.10.2" @@ -9633,6 +9653,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ "der 0.7.10", + "pkcs5", "spki 0.7.3", ] @@ -10341,7 +10362,7 @@ dependencies = [ "futures-core", "futures-util", "h2 0.4.11", - "http 1.4.0", + "http 1.4.1", "http-body 1.0.1", "http-body-util", "hyper 1.9.0", @@ -10382,7 +10403,7 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http 1.4.0", + "http 1.4.1", "http-body 1.0.1", "http-body-util", "hyper 1.9.0", @@ -10556,7 +10577,7 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http 1.4.0", + "http 1.4.1", "mime", "rand 0.10.1", "thiserror 2.0.18", @@ -10752,6 +10773,36 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" +[[package]] +name = "rustls-rustcrypto" +version = "0.0.2-alpha" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f12052947763ab8515f753315357599e9b0b4dab3b8ba15f30f725fe6d025557" +dependencies = [ + "aead", + "aes-gcm", + "chacha20poly1305", + "crypto-common 0.1.6", + "der 0.7.10", + "digest 0.10.7", + "ecdsa", + "ed25519-dalek", + "hmac", + "p256", + "p384", + "paste", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "rsa", + "rustls 0.23.37", + "rustls-pki-types", + "rustls-webpki 0.102.8", + "sec1", + "sha2 0.10.9", + "signature 2.2.0", + "x25519-dalek", +] + [[package]] name = "rustls-webpki" version = "0.101.7" @@ -11128,9 +11179,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "itoa", "memchr", @@ -11530,6 +11581,45 @@ dependencies = [ "webpki-roots 0.26.11", ] +[[package]] +name = "smolmix-wasm" +version = "1.21.0" +dependencies = [ + "async-tungstenite", + "bytes", + "futures", + "futures-rustls", + "getrandom 0.2.16", + "getrandom 0.4.1", + "hickory-proto", + "http 1.4.1", + "http-body-util", + "hyper 1.9.0", + "js-sys", + "nym-bin-common", + "nym-ip-packet-requests", + "nym-lp-data", + "nym-validator-client", + "nym-wasm-client-core", + "nym-wasm-utils", + "rand 0.8.6", + "rustls 0.23.37", + "rustls-pki-types", + "rustls-rustcrypto", + "semver 1.0.27", + "serde", + "serde-wasm-bindgen 0.6.5", + "smoltcp", + "thiserror 2.0.18", + "tokio", + "tsify", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasmtimer", + "webpki-roots 0.26.11", +] + [[package]] name = "smoltcp" version = "0.12.0" @@ -11596,12 +11686,12 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.0" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.61.2", ] [[package]] @@ -12126,7 +12216,7 @@ dependencies = [ "camino", "crossbeam-channel", "home", - "http 1.4.0", + "http 1.4.1", "libc", "memchr", "rayon", @@ -12459,17 +12549,17 @@ dependencies = [ [[package]] name = "tokio" -version = "1.50.0" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", - "mio 1.0.4", + "mio 1.2.0", "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.6.0", + "socket2 0.6.3", "tokio-macros", "tracing", "windows-sys 0.61.2", @@ -12477,9 +12567,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.6.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", @@ -12770,7 +12860,7 @@ dependencies = [ "base64 0.22.1", "bytes", "h2 0.4.11", - "http 1.4.0", + "http 1.4.1", "http-body 1.0.1", "http-body-util", "hyper 1.9.0", @@ -12799,7 +12889,7 @@ dependencies = [ "base64 0.22.1", "bytes", "h2 0.4.11", - "http 1.4.0", + "http 1.4.1", "http-body 1.0.1", "http-body-util", "hyper 1.9.0", @@ -12808,7 +12898,7 @@ dependencies = [ "percent-encoding", "pin-project", "rustls-native-certs 0.8.3", - "socket2 0.6.0", + "socket2 0.6.3", "sync_wrapper 1.0.2", "tokio", "tokio-rustls 0.26.2", @@ -12860,7 +12950,7 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http 1.4.0", + "http 1.4.1", "http-body 1.0.1", "http-body-util", "http-range-header", @@ -13129,7 +13219,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 1.4.0", + "http 1.4.1", "httparse", "log", "rand 0.8.6", @@ -13181,9 +13271,9 @@ checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" [[package]] name = "typetag" -version = "0.2.21" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be2212c8a9b9bcfca32024de14998494cf9a5dfa59ea1b829de98bac374b86bf" +checksum = "c5a897b12c6c1151ad0b138b8db50252dc301f93bc3b027db05eec82aeed298c" dependencies = [ "erased-serde", "inventory", @@ -13194,9 +13284,9 @@ dependencies = [ [[package]] name = "typetag-impl" -version = "0.2.21" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27a7a9b72ba121f6f1f6c3632b85604cac41aedb5ddc70accbebb6cac83de846" +checksum = "cf808357c6ed7e13ba0f3277ec8d8f21b2d501274895104263985330c726c1c5" dependencies = [ "proc-macro2", "quote", @@ -13668,9 +13758,9 @@ dependencies = [ [[package]] name = "uuid" -version = "1.21.0" +version = "1.23.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b672338555252d43fd2240c714dc444b8c6fb0a5c5335e65a07bba7742735ddb" +checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" dependencies = [ "getrandom 0.4.1", "js-sys", diff --git a/Cargo.toml b/Cargo.toml index e17ffb790a..72e8d59a1f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -175,6 +175,7 @@ members = [ "tools/ts-rs-cli", "wasm/client", "wasm/mix-fetch", + "wasm/smolmix", "wasm/zknym-lib", "nym-network-monitor-v3/nym-network-monitor-orchestrator", "nym-network-monitor-v3/nym-network-monitor-agent", @@ -225,6 +226,7 @@ anyhow = "1.0.98" arc-swap = "1.7.1" argon2 = "0.5.0" async-trait = "0.1.88" +async-tungstenite = { version = "0.24", default-features = false } axum = "0.8.9" axum-client-ip = "1.3.1" axum-extra = "0.12.6" @@ -278,24 +280,27 @@ eyre = "0.6.9" fastrand = "2.1.1" flate2 = "1.1.1" futures = "0.3.31" +futures-rustls = { version = "0.26", default-features = false } futures-util = "0.3" generic-array = "0.14.7" getrandom = "0.2.10" getrandom03 = { package = "getrandom", version = "=0.3.3" } +getrandom04 = { package = "getrandom", version = "0.4" } glob = "0.3" handlebars = "3.5.5" hex = "0.4.3" -hickory-proto = "0.26.1" +hickory-proto = { version = "0.26.1", default-features = false } hickory-resolver = "0.26.1" hkdf = "0.12.3" hmac = "0.12.1" http = "1" http-body-util = "0.1" +httparse = "1.10" httpcodec = "0.2.3" human-repr = "1.1.0" humantime = "2.2.0" humantime-serde = "1.1.1" -hyper = "1.6.0" +hyper = { version = "1.6.0", default-features = false } hyper-util = "0.1" indicatif = "0.18.0" inquire = "0.6.2" @@ -341,6 +346,8 @@ regex = "1.10.6" reqwest = { version = "0.13.1", default-features = false } rs_merkle = "1.5.0" rustls = { version = "0.23.37", default-features = false } +rustls-pki-types = "1" +rustls-rustcrypto = "0.0.2-alpha" schemars = "0.8.22" semver = "1.0.26" serde = "1.0.219" @@ -354,6 +361,7 @@ serde_yaml = "0.9.25" serde_plain = "1.0.2" sha2 = "0.10.3" si-scale = "0.2.3" +simple-dns = "0.7" smoltcp = "0.12" snow = "0.9.6" sphinx-packet = "=0.6.0" @@ -377,7 +385,7 @@ tokio-test = "0.4.4" tokio-tun = "0.11.5" tokio-rustls = "0.26" tokio-smoltcp = "0.5" -tokio-tungstenite = { version = "0.20.1" } +tokio-tungstenite = "0.20.1" tokio-util = "0.7.15" toml = "0.8.22" tower = "0.5.2" @@ -597,12 +605,14 @@ opt-level = 3 # lto = true opt-level = 'z' - - [profile.release.package.mix-fetch-wasm] # lto = true opt-level = 'z' +[profile.release.package.smolmix-wasm] +# lto = true +opt-level = 'z' + [workspace.lints.rust] unexpected_cfgs = { level = "warn", check-cfg = ['cfg(tokio_unstable)'] } @@ -620,4 +630,3 @@ exit = "deny" panic = "deny" unimplemented = "deny" unreachable = "deny" - diff --git a/Makefile b/Makefile index 3ed8a5babc..faef4a4473 100644 --- a/Makefile +++ b/Makefile @@ -106,6 +106,7 @@ sdk-wasm: sdk-wasm-build sdk-wasm-test sdk-wasm-lint sdk-wasm-build: $(MAKE) -C wasm/client $(MAKE) -C wasm/mix-fetch + $(MAKE) -C wasm/smolmix # $(MAKE) -C wasm/zknym-lib # run this from npm/yarn to ensure tools are in the path, e.g. yarn build:sdk from root of repo @@ -124,6 +125,7 @@ sdk-wasm-test: sdk-wasm-lint: RUSTFLAGS='--cfg getrandom_backend="wasm_js"' cargo clippy $(addprefix -p , $(WASM_CRATES)) --target wasm32-unknown-unknown -- -Dwarnings $(MAKE) -C wasm/mix-fetch check-fmt + $(MAKE) -C wasm/smolmix check-fmt # Add to top-level targets build: sdk-wasm-build diff --git a/common/ip-packet-requests/Cargo.toml b/common/ip-packet-requests/Cargo.toml index bd95393c99..a45477a916 100644 --- a/common/ip-packet-requests/Cargo.toml +++ b/common/ip-packet-requests/Cargo.toml @@ -14,6 +14,8 @@ publish = true [features] +default = ["codec"] +codec = ["dep:tokio-util"] test-utils = ["pnet_packet"] [dependencies] @@ -29,6 +31,5 @@ semver = { workspace = true } serde = { workspace = true, features = ["derive"] } thiserror = { workspace = true } time = { workspace = true } -tokio = { workspace = true, features = ["time"] } -tokio-util = { workspace = true, features = ["codec"] } +tokio-util = { workspace = true, features = ["codec"], optional = true } tracing = { workspace = true } diff --git a/common/ip-packet-requests/src/codec.rs b/common/ip-packet-requests/src/codec.rs index 8bd297de8c..a7c5fc915a 100644 --- a/common/ip-packet-requests/src/codec.rs +++ b/common/ip-packet-requests/src/codec.rs @@ -1,6 +1,7 @@ use std::time::Duration; use bytes::{Buf, Bytes, BytesMut}; +#[cfg(feature = "codec")] use tokio_util::codec::{Decoder, Encoder}; #[derive(thiserror::Error, Debug)] @@ -38,6 +39,23 @@ impl MultiIpPacketCodec { bundled_packets.extend_from_slice(&packet); bundled_packets.freeze() } + + /// Decode one length-prefixed packet from `src`, advancing past it. + /// + /// Same logic as the `Decoder` impl but available without the `codec` + /// feature (i.e. without depending on `tokio-util`). + pub fn decode_one(&mut self, src: &mut BytesMut) -> Result, Error> { + if src.len() < LENGTH_PREFIX_SIZE { + return Ok(None); + } + let packet_size = u16::from_be_bytes([src[0], src[1]]) as usize; + if src.len() < packet_size + LENGTH_PREFIX_SIZE { + return Ok(None); + } + src.advance(LENGTH_PREFIX_SIZE); + let packet = src.split_to(packet_size); + Ok(Some(IprPacket::Data(packet.freeze()))) + } } impl Default for MultiIpPacketCodec { @@ -82,6 +100,7 @@ impl From> for IprPacket { } } +#[cfg(feature = "codec")] impl Encoder for MultiIpPacketCodec { type Error = Error; @@ -125,6 +144,7 @@ impl Encoder for MultiIpPacketCodec { } } +#[cfg(feature = "codec")] impl Decoder for MultiIpPacketCodec { type Item = IprPacket; type Error = Error; @@ -152,7 +172,7 @@ impl Decoder for MultiIpPacketCodec { } } -#[cfg(test)] +#[cfg(all(test, feature = "codec"))] mod tests { use super::*; diff --git a/common/ip-packet-requests/src/response_helpers.rs b/common/ip-packet-requests/src/response_helpers.rs index 5caa81ab0d..29c7375026 100644 --- a/common/ip-packet-requests/src/response_helpers.rs +++ b/common/ip-packet-requests/src/response_helpers.rs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 use bytes::{Bytes, BytesMut}; -use tokio_util::codec::Decoder; use tracing::{error, info, warn}; use crate::{ @@ -84,7 +83,7 @@ pub fn handle_ipr_response(data: &[u8]) -> Option { let mut buf = BytesMut::from(data_response.ip_packet.as_ref()); let mut packets = Vec::new(); loop { - match codec.decode(&mut buf) { + match codec.decode_one(&mut buf) { Ok(Some(packet)) => packets.push(packet.into_bytes()), Ok(None) => break, Err(e) => { diff --git a/common/nym-connection-monitor/Cargo.toml b/common/nym-connection-monitor/Cargo.toml index c7ce2c445e..f6dd76954e 100644 --- a/common/nym-connection-monitor/Cargo.toml +++ b/common/nym-connection-monitor/Cargo.toml @@ -18,7 +18,7 @@ bytes.workspace = true futures.workspace = true nym-config = { workspace = true } nym-common = { workspace = true } -nym-ip-packet-requests = { workspace = true } +nym-ip-packet-requests = { workspace = true, default-features = true } nym-sdk = { workspace = true } pnet_packet.workspace = true thiserror.workspace = true diff --git a/common/registration/Cargo.toml b/common/registration/Cargo.toml index 75f882a4f5..910f7059db 100644 --- a/common/registration/Cargo.toml +++ b/common/registration/Cargo.toml @@ -23,7 +23,7 @@ tracing = { workspace = true } nym-authenticator-requests = { workspace = true } nym-credentials-interface = { workspace = true } nym-crypto = { workspace = true } -nym-ip-packet-requests = { workspace = true } +nym-ip-packet-requests = { workspace = true, default-features = true } nym-sphinx = { workspace = true } nym-wireguard-types = { workspace = true } nym-kkt-ciphersuite = { workspace = true } diff --git a/common/wasm/storage/Cargo.toml b/common/wasm/storage/Cargo.toml index 2e4f4430c4..d9d2fb1188 100644 --- a/common/wasm/storage/Cargo.toml +++ b/common/wasm/storage/Cargo.toml @@ -23,4 +23,4 @@ indexed_db_futures = { workspace = true } thiserror = { workspace = true } nym-store-cipher = { workspace = true, features = ["json"] } -nym-wasm-utils = { workspace = true, default-features = false } +nym-wasm-utils = { workspace = true } diff --git a/common/wasm/utils/src/lib.rs b/common/wasm/utils/src/lib.rs index 60f7a53052..d16ffe6e90 100644 --- a/common/wasm/utils/src/lib.rs +++ b/common/wasm/utils/src/lib.rs @@ -1,6 +1,7 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use std::sync::atomic::{AtomicBool, Ordering}; use wasm_bindgen::prelude::*; #[cfg(feature = "websocket")] @@ -11,6 +12,28 @@ pub mod crypto; pub mod error; +#[doc(hidden)] +pub static DEBUG_LOGGING_ENABLED: AtomicBool = AtomicBool::new(false); + +/// Enable or disable `debug_log!` / `debug_error!` output at runtime. +/// +/// Consumers call this from their own init path when their own `debug` +/// (or equivalent) feature is on. The default is `false`, so the macros +/// compile to a single relaxed-load + branch and otherwise no-op. +/// +/// Also exposed to JS as `setDebugLogging(enabled: boolean)` for ad-hoc +/// toggling without rebuilding. +#[wasm_bindgen(js_name = "setDebugLogging")] +pub fn set_debug_logging(enabled: bool) { + DEBUG_LOGGING_ENABLED.store(enabled, Ordering::Relaxed); +} + +/// Read the current debug-logging state. Used by the macros below. +#[inline] +pub fn debug_logging_enabled() -> bool { + DEBUG_LOGGING_ENABLED.load(Ordering::Relaxed) +} + // will cause messages to be written as if console.log("...") was called #[macro_export] macro_rules! console_log { @@ -41,6 +64,48 @@ macro_rules! console_error { ($($t:tt)*) => ($crate::error(&format_args!($($t)*).to_string())) } +/// `console.log` gated behind the runtime [`DEBUG_LOGGING_ENABLED`] flag. +/// +/// Format-args evaluation stays inside the `if` arm, so it's skipped at +/// runtime when logging is off. Consumers turn this on via +/// [`set_debug_logging`] from their own init path (typically when their +/// own `debug` feature is enabled). +#[macro_export] +macro_rules! debug_log { + ($($t:tt)*) => {{ + if $crate::debug_logging_enabled() { + $crate::console_log!($($t)*); + } + }}; +} + +/// `console.error` gated behind the runtime [`DEBUG_LOGGING_ENABLED`] flag. +/// See [`debug_log!`] for semantics. +#[macro_export] +macro_rules! debug_error { + ($($t:tt)*) => {{ + if $crate::debug_logging_enabled() { + $crate::console_error!($($t)*); + } + }}; +} + +/// Hex preview of a buffer, truncated with ` ...` when over `max_bytes`. +/// Useful for `console.log`-style binary debug output. +pub fn hex_preview(buf: &[u8], max_bytes: usize) -> String { + let len = buf.len().min(max_bytes); + let hex: String = buf[..len] + .iter() + .map(|b| format!("{b:02x}")) + .collect::>() + .join(" "); + if buf.len() > max_bytes { + format!("{hex} ...") + } else { + hex + } +} + #[wasm_bindgen] pub fn set_panic_hook() { // When the `console_error_panic_hook` feature is enabled, we can call the diff --git a/nym-gateway-probe/Cargo.toml b/nym-gateway-probe/Cargo.toml index 18be3c9577..e50f61cf9d 100644 --- a/nym-gateway-probe/Cargo.toml +++ b/nym-gateway-probe/Cargo.toml @@ -57,7 +57,7 @@ nym-crypto = { workspace = true } nym-http-api-client = { path = "../common/http-api-client" } nym-http-api-client-macro = { path = "../common/http-api-client-macro" } nym-ip-packet-client = { workspace = true } -nym-ip-packet-requests = { workspace = true } +nym-ip-packet-requests = { workspace = true, default-features = true } nym-kkt-ciphersuite = { workspace = true } nym-lp = { path = "../common/nym-lp" } nym-lp-data.workspace = true diff --git a/nym-node/Cargo.toml b/nym-node/Cargo.toml index ca56cec4bf..c57cdcc278 100644 --- a/nym-node/Cargo.toml +++ b/nym-node/Cargo.toml @@ -117,7 +117,7 @@ nym-network-requester = { path = "../service-providers/network-requester" } nym-ip-packet-router = { path = "../service-providers/ip-packet-router" } # LP dependencies -nym-lp = { workspace = true } +nym-lp = { workspace = true, default-features = true } nym-lp-data.workspace = true nym-registration-common = { path = "../common/registration" } bincode = { workspace = true } @@ -142,7 +142,7 @@ harness = false cargo_metadata = { workspace = true } [dev-dependencies] -nym-lp = { workspace = true, features = ["mock"] } +nym-lp = { workspace = true, default-features = true, features = ["mock"] } criterion = { workspace = true, features = ["async_tokio"] } nym-test-utils = { workspace = true } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 995a3591b3..2460be7d41 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,549 +4,6 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false -catalogs: - default: - '@babel/core': - specifier: ^7.22.10 - version: 7.29.0 - '@babel/helper-simple-access': - specifier: ^7.25.9 - version: 7.27.1 - '@babel/plugin-transform-async-to-generator': - specifier: ^7.22.5 - version: 7.28.6 - '@babel/preset-env': - specifier: ^7.22.10 - version: 7.29.5 - '@babel/preset-react': - specifier: ^7.14.5 - version: 7.28.5 - '@babel/preset-typescript': - specifier: ^7.22.5 - version: 7.28.5 - '@babel/runtime': - specifier: ^7.29.2 - version: 7.29.2 - '@cosmjs/cosmwasm-stargate': - specifier: ^0.32.4 - version: 0.32.4 - '@cosmjs/math': - specifier: ^0.32.4 - version: 0.32.4 - '@cosmjs/stargate': - specifier: ^0.32.4 - version: 0.32.4 - '@emotion/cache': - specifier: ^11.14.0 - version: 11.14.0 - '@emotion/hash': - specifier: ^0.9.2 - version: 0.9.2 - '@emotion/is-prop-valid': - specifier: ^1.4.0 - version: 1.4.0 - '@emotion/memoize': - specifier: ^0.9.0 - version: 0.9.0 - '@emotion/react': - specifier: ^11.13.5 - version: 11.14.0 - '@emotion/serialize': - specifier: ^1.3.3 - version: 1.3.3 - '@emotion/sheet': - specifier: ^1.4.0 - version: 1.4.0 - '@emotion/styled': - specifier: ^11.13.5 - version: 11.14.1 - '@emotion/unitless': - specifier: ^0.10.0 - version: 0.10.0 - '@emotion/use-insertion-effect-with-fallbacks': - specifier: ^1.2.0 - version: 1.2.0 - '@emotion/utils': - specifier: ^1.4.2 - version: 1.4.2 - '@emotion/weak-memoize': - specifier: ^0.4.0 - version: 0.4.0 - '@hookform/resolvers': - specifier: ^2.8.0 - version: 2.9.11 - '@mui/base': - specifier: 5.0.0-beta.40 - version: 5.0.0-beta.40 - '@mui/icons-material': - specifier: ^5.2.0 - version: 5.18.0 - '@mui/lab': - specifier: 5.0.0-alpha.170 - version: 5.0.0-alpha.170 - '@mui/material': - specifier: ^5.2.2 - version: 5.18.0 - '@mui/private-theming': - specifier: ^5.17.1 - version: 5.17.1 - '@mui/styles': - specifier: ^5.18.0 - version: 5.18.0 - '@mui/system': - specifier: ^5.18.0 - version: 5.18.0 - '@mui/utils': - specifier: ^5.7.0 - version: 5.17.1 - '@mui/x-tree-view': - specifier: ^7.11.1 - version: 7.29.10 - '@pmmmwh/react-refresh-webpack-plugin': - specifier: ^0.5.4 - version: 0.5.17 - '@popperjs/core': - specifier: ^2.11.8 - version: 2.11.8 - '@remix-run/router': - specifier: ^1.23.2 - version: 1.23.2 - '@storybook/addon-actions': - specifier: ^6.5.8 - version: 6.5.16 - '@storybook/addon-docs': - specifier: ^6.5.8 - version: 6.5.16 - '@storybook/addon-essentials': - specifier: ^6.5.8 - version: 6.5.16 - '@storybook/addon-interactions': - specifier: ^6.5.8 - version: 6.5.16 - '@storybook/addon-links': - specifier: ^6.5.8 - version: 6.5.16 - '@storybook/builder-webpack5': - specifier: ^6.5.8 - version: 6.5.16 - '@storybook/manager-webpack5': - specifier: ^6.5.8 - version: 6.5.16 - '@storybook/react': - specifier: ^6.5.15 - version: 6.5.16 - '@storybook/testing-library': - specifier: ^0.0.9 - version: 0.0.9 - '@svgr/webpack': - specifier: ^6.1.1 - version: 6.5.1 - '@tanstack/query-core': - specifier: ^5.64.2 - version: 5.100.10 - '@tanstack/react-query': - specifier: ^5.64.2 - version: 5.100.10 - '@tauri-apps/api': - specifier: ^2.10.1 - version: 2.10.1 - '@tauri-apps/cli': - specifier: ^2.10.1 - version: 2.11.1 - '@tauri-apps/plugin-clipboard-manager': - specifier: ^2.3.2 - version: 2.3.2 - '@tauri-apps/plugin-opener': - specifier: ^2.5.3 - version: 2.5.4 - '@tauri-apps/plugin-process': - specifier: ^2.3.1 - version: 2.3.1 - '@tauri-apps/plugin-updater': - specifier: ^2.10.1 - version: 2.10.1 - '@tauri-apps/tauri-forage': - specifier: ^1.0.0-beta.2 - version: 1.0.0-beta.2 - '@testing-library/dom': - specifier: ^10.4.1 - version: 10.4.1 - '@testing-library/jest-dom': - specifier: ^6.9.1 - version: 6.9.1 - '@testing-library/react': - specifier: ^16.3.2 - version: 16.3.2 - '@types/big.js': - specifier: ^6.1.6 - version: 6.2.2 - '@types/bs58': - specifier: ^4.0.1 - version: 4.0.4 - '@types/flat': - specifier: ^5.0.2 - version: 5.0.5 - '@types/jest': - specifier: ^29.5.14 - version: 29.5.14 - '@types/lodash': - specifier: ^4.17.21 - version: 4.17.24 - '@types/minimatch': - specifier: 5.1.2 - version: 5.1.2 - '@types/qrcode.react': - specifier: ^1.0.2 - version: 1.0.5 - '@types/react': - specifier: ^19.2.14 - version: 19.2.14 - '@types/react-dom': - specifier: ^19.2.3 - version: 19.2.3 - '@types/semver': - specifier: ^7.3.8 - version: 7.7.1 - '@types/uuid': - specifier: ^8.3.4 - version: 8.3.4 - '@types/zxcvbn': - specifier: ^4.4.1 - version: 4.4.5 - '@typescript-eslint/eslint-plugin': - specifier: ^5.13.0 - version: 5.62.0 - '@typescript-eslint/parser': - specifier: ^5.13.0 - version: 5.62.0 - axios: - specifier: ^1.16.0 - version: 1.16.0 - babel-loader: - specifier: ^8.3.0 - version: 8.4.1 - base-x: - specifier: ^3.0.11 - version: 3.0.11 - base64-js: - specifier: ^1.5.1 - version: 1.5.1 - bech32: - specifier: ^1.1.4 - version: 1.1.4 - big.js: - specifier: ^6.2.1 - version: 6.2.2 - bn.js: - specifier: ^5.2.3 - version: 5.2.3 - bs58: - specifier: ^4.0.1 - version: 4.0.1 - buffer: - specifier: ^6.0.3 - version: 6.0.3 - clean-webpack-plugin: - specifier: ^4.0.0 - version: 4.0.0 - clipboard-copy: - specifier: ^3.2.0 - version: 3.2.0 - clsx: - specifier: ^1.1.1 - version: 1.2.1 - colornames: - specifier: ^1.1.1 - version: 1.1.1 - css-loader: - specifier: ^6.8.1 - version: 6.11.0 - css-minimizer-webpack-plugin: - specifier: ^3.0.2 - version: 3.4.1 - d3-array: - specifier: ^3.2.4 - version: 3.2.4 - d3-color: - specifier: ^3.1.0 - version: 3.1.0 - d3-format: - specifier: ^1.4.5 - version: 1.4.5 - d3-interpolate: - specifier: ^3.0.1 - version: 3.0.1 - d3-path: - specifier: ^3.1.0 - version: 3.1.0 - d3-scale: - specifier: ^4.0.2 - version: 4.0.2 - d3-shape: - specifier: ^3.2.0 - version: 3.2.0 - d3-time: - specifier: ^3.1.0 - version: 3.1.0 - d3-time-format: - specifier: ^3.0.0 - version: 3.0.0 - date-fns: - specifier: ^2.28.0 - version: 2.30.0 - decimal.js-light: - specifier: ^2.5.1 - version: 2.5.1 - dom-helpers: - specifier: ^5.2.1 - version: 5.2.1 - dotenv-webpack: - specifier: ^7.0.3 - version: 7.1.1 - eslint: - specifier: ^9.26.0 - version: 9.39.4 - eslint-config-airbnb: - specifier: ^19.0.4 - version: 19.0.4 - eslint-config-airbnb-typescript: - specifier: ^16.1.0 - version: 16.2.0 - eslint-config-prettier: - specifier: ^8.5.0 - version: 8.10.2 - eslint-import-resolver-root-import: - specifier: ^1.0.4 - version: 1.0.4 - eslint-plugin-import: - specifier: ^2.25.4 - version: 2.32.0 - eslint-plugin-jest: - specifier: ^26.1.1 - version: 26.9.0 - eslint-plugin-jsx-a11y: - specifier: ^6.5.1 - version: 6.10.2 - eslint-plugin-prettier: - specifier: ^4.0.0 - version: 4.2.5 - eslint-plugin-react: - specifier: ^7.29.2 - version: 7.37.5 - eslint-plugin-react-hooks: - specifier: ^4.3.0 - version: 4.6.2 - eslint-plugin-storybook: - specifier: ^0.5.12 - version: 0.5.13 - eventemitter3: - specifier: ^4.0.7 - version: 4.0.7 - fast-equals: - specifier: ^5.4.0 - version: 5.4.0 - favicons: - specifier: ^7.0.2 - version: 7.2.0 - favicons-webpack-plugin: - specifier: ^5.0.2 - version: 5.0.2 - file-loader: - specifier: ^6.2.0 - version: 6.2.0 - flat: - specifier: ^5.0.2 - version: 5.0.2 - fork-ts-checker-webpack-plugin: - specifier: ^7.2.1 - version: 7.3.0 - hex-rgb: - specifier: ^4.3.0 - version: 4.3.0 - hoist-non-react-statics: - specifier: ^3.3.2 - version: 3.3.2 - html-webpack-plugin: - specifier: ^5.5.3 - version: 5.6.7 - ieee754: - specifier: ^1.2.1 - version: 1.2.1 - internmap: - specifier: ^2.0.3 - version: 2.0.3 - jest: - specifier: ^27.1.0 - version: 27.5.1 - joi: - specifier: ^17.11.0 - version: 17.13.3 - localforage: - specifier: ^1.10.0 - version: 1.10.0 - lodash: - specifier: ^4.17.21 - version: 4.18.1 - lodash.padend: - specifier: ^4.6.1 - version: 4.6.1 - lodash.trimstart: - specifier: ^4.5.1 - version: 4.5.1 - lodash.words: - specifier: ^4.2.0 - version: 4.2.0 - long: - specifier: ^4.0.0 - version: 4.0.0 - mini-css-extract-plugin: - specifier: ^2.7.6 - version: 2.10.2 - nanoclone: - specifier: ^0.2.1 - version: 0.2.1 - notistack: - specifier: ^2.0.3 - version: 2.0.8 - npm-run-all: - specifier: ^4.1.5 - version: 4.1.5 - prettier: - specifier: ^2.8.7 - version: 2.8.8 - prop-types: - specifier: ^15.8.1 - version: 15.8.1 - property-expr: - specifier: ^2.0.6 - version: 2.0.6 - qr.js: - specifier: 0.0.0 - version: 0.0.0 - ramda: - specifier: ^0.28.0 - version: 0.28.0 - react: - specifier: ^19.2.6 - version: 19.2.6 - react-dom: - specifier: ^19.2.6 - version: 19.2.6 - react-error-boundary: - specifier: ^3.1.3 - version: 3.1.4 - react-hook-form: - specifier: ^7.14.2 - version: 7.75.0 - react-is: - specifier: ^19.2.6 - version: 19.2.6 - react-refresh: - specifier: ^0.10.0 - version: 0.10.0 - react-refresh-typescript: - specifier: ^2.0.2 - version: 2.0.12 - react-router: - specifier: ^6.30.3 - version: 6.30.3 - react-router-dom: - specifier: '6' - version: 6.30.3 - react-smooth: - specifier: ^4.0.4 - version: 4.0.4 - react-transition-group: - specifier: ^4.4.5 - version: 4.4.5 - recharts: - specifier: ^2.1.13 - version: 2.15.4 - recharts-scale: - specifier: ^0.4.5 - version: 0.4.5 - rgb-hex: - specifier: ^3.0.0 - version: 3.0.0 - rimraf: - specifier: ^3.0.2 - version: 3.0.2 - safe-buffer: - specifier: ^5.2.1 - version: 5.2.1 - scheduler: - specifier: ^0.27.0 - version: 0.27.0 - semver: - specifier: ^6.3.0 - version: 6.3.1 - string-to-color: - specifier: ^2.2.2 - version: 2.2.2 - style-loader: - specifier: ^3.3.3 - version: 3.3.4 - stylis: - specifier: ^4.2.0 - version: 4.2.0 - thread-loader: - specifier: ^3.0.4 - version: 3.0.4 - tiny-invariant: - specifier: ^1.3.3 - version: 1.3.3 - toposort: - specifier: ^2.0.2 - version: 2.0.2 - ts-jest: - specifier: ^27.0.5 - version: 27.1.5 - ts-loader: - specifier: ^9.4.4 - version: 9.5.7 - tsconfig-paths-webpack-plugin: - specifier: ^3.5.2 - version: 3.5.2 - tweetnacl: - specifier: ^1.0.3 - version: 1.0.3 - tweetnacl-util: - specifier: ^0.15.1 - version: 0.15.1 - url-loader: - specifier: ^4.1.1 - version: 4.1.1 - use-clipboard-copy: - specifier: ^0.2.0 - version: 0.2.0 - uuid: - specifier: ^8.3.2 - version: 8.3.2 - victory-vendor: - specifier: ^36.9.2 - version: 36.9.2 - webpack: - specifier: ^5.88.2 - version: 5.106.2 - webpack-cli: - specifier: ^4.8.0 - version: 4.10.0 - webpack-dev-server: - specifier: ^4.15.1 - version: 4.15.2 - webpack-favicons: - specifier: ^1.3.8 - version: 1.5.43 - webpack-merge: - specifier: ^5.9.0 - version: 5.10.0 - yup: - specifier: ^0.32.9 - version: 0.32.11 - zxcvbn: - specifier: ^4.4.2 - version: 4.4.2 - importers: .: @@ -563,7 +20,7 @@ importers: version: 5.1.2 lerna: specifier: ^7.3.0 - version: 7.4.2(@types/node@22.19.19)(encoding@0.1.13) + version: 7.4.2(encoding@0.1.13) node-gyp: specifier: ^9.3.1 version: 9.4.1 @@ -16481,12 +15938,10 @@ snapshots: '@img/sharp-win32-x64@0.33.5': optional: true - '@inquirer/external-editor@1.0.3(@types/node@22.19.19)': + '@inquirer/external-editor@1.0.3': dependencies: chardet: 2.1.1 iconv-lite: 0.7.2 - optionalDependencies: - '@types/node': 22.19.19 '@interchain-ui/react@1.26.3(@types/react@19.2.14)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: @@ -16986,7 +16441,7 @@ snapshots: execa: 5.0.0 strong-log-transformer: 2.1.0 - '@lerna/create@7.4.2(@types/node@22.19.19)(encoding@0.1.13)(typescript@5.9.3)': + '@lerna/create@7.4.2(encoding@0.1.13)(typescript@5.9.3)': dependencies: '@lerna/child-process': 7.4.2 '@npmcli/run-script': 6.0.2 @@ -17012,7 +16467,7 @@ snapshots: has-unicode: 2.0.1 ini: 1.3.8 init-package-json: 5.0.0 - inquirer: 8.2.7(@types/node@22.19.19) + inquirer: 8.2.7 is-ci: 3.0.1 is-stream: 2.0.0 js-yaml: 4.1.0 @@ -17585,7 +17040,7 @@ snapshots: lru-cache: 7.18.3 npm-pick-manifest: 8.0.2 proc-log: 3.0.0 - promise-inflight: 1.0.1(bluebird@3.7.2) + promise-inflight: 1.0.1 promise-retry: 2.0.1 semver: 7.8.0 which: 3.0.1 @@ -21372,7 +20827,7 @@ snapshots: minipass-pipeline: 1.2.4 mkdirp: 1.0.4 p-map: 4.0.0 - promise-inflight: 1.0.1(bluebird@3.7.2) + promise-inflight: 1.0.1 rimraf: 3.0.2 ssri: 9.0.1 tar: 6.2.1 @@ -24822,9 +24277,9 @@ snapshots: inline-style-parser@0.2.7: {} - inquirer@8.2.7(@types/node@22.19.19): + inquirer@8.2.7: dependencies: - '@inquirer/external-editor': 1.0.3(@types/node@22.19.19) + '@inquirer/external-editor': 1.0.3 ansi-escapes: 4.3.2 chalk: 4.1.2 cli-cursor: 3.1.0 @@ -26224,10 +25679,10 @@ snapshots: lefthook-windows-arm64: 1.13.6 lefthook-windows-x64: 1.13.6 - lerna@7.4.2(@types/node@22.19.19)(encoding@0.1.13): + lerna@7.4.2(encoding@0.1.13): dependencies: '@lerna/child-process': 7.4.2 - '@lerna/create': 7.4.2(@types/node@22.19.19)(encoding@0.1.13)(typescript@5.9.3) + '@lerna/create': 7.4.2(encoding@0.1.13)(typescript@5.9.3) '@npmcli/run-script': 6.0.2 '@nx/devkit': 16.10.0(nx@16.10.0) '@octokit/plugin-enterprise-rest': 6.0.1 @@ -26255,7 +25710,7 @@ snapshots: import-local: 3.1.0 ini: 1.3.8 init-package-json: 5.0.0 - inquirer: 8.2.7(@types/node@22.19.19) + inquirer: 8.2.7 is-ci: 3.0.1 is-stream: 2.0.0 jest-diff: 29.7.0 @@ -28386,6 +27841,8 @@ snapshots: process@0.11.10: {} + promise-inflight@1.0.1: {} + promise-inflight@1.0.1(bluebird@3.7.2): optionalDependencies: bluebird: 3.7.2 diff --git a/sdk/rust/nym-sdk/Cargo.toml b/sdk/rust/nym-sdk/Cargo.toml index 1391873b51..fd691d0b9f 100644 --- a/sdk/rust/nym-sdk/Cargo.toml +++ b/sdk/rust/nym-sdk/Cargo.toml @@ -71,7 +71,7 @@ url = { workspace = true } toml = { workspace = true } tempfile = { workspace = true } -nym-ip-packet-requests = { workspace = true } +nym-ip-packet-requests = { workspace = true, default-features = true } semver = { workspace = true } # tcpproxy dependencies @@ -104,7 +104,7 @@ tokio-util = { workspace = true, features = ["codec"] } parking_lot = { workspace = true } hex = { workspace = true } pnet_packet = { workspace = true } -nym-ip-packet-requests = { workspace = true, features = ["test-utils"] } +nym-ip-packet-requests = { workspace = true, default-features = true, features = ["test-utils"] } [features] libp2p-vanilla = [] diff --git a/smolmix/core/Cargo.toml b/smolmix/core/Cargo.toml index b8f18e2ff1..9cdd275474 100644 --- a/smolmix/core/Cargo.toml +++ b/smolmix/core/Cargo.toml @@ -25,7 +25,7 @@ tokio-smoltcp = { workspace = true } futures = { workspace = true } tracing = { workspace = true } nym-sdk = { workspace = true } -nym-ip-packet-requests = { workspace = true } +nym-ip-packet-requests = { workspace = true, default-features = true } thiserror.workspace = true [dev-dependencies] @@ -36,8 +36,8 @@ webpki-roots.workspace = true rustls = { workspace = true, features = ["std", "ring"] } tokio-rustls = { workspace = true } nym-bin-common = { workspace = true, features = ["basic_tracing"] } -hickory-proto = { workspace = true } hickory-resolver = { workspace = true, features = ["tokio", "system-config"] } +hickory-proto = { workspace = true } hyper = { workspace = true, features = ["client", "http1"] } hyper-util = { workspace = true, features = ["tokio"] } http-body-util = { workspace = true } diff --git a/wasm/smolmix/.cargo/config.toml b/wasm/smolmix/.cargo/config.toml new file mode 100644 index 0000000000..ed9cba9707 --- /dev/null +++ b/wasm/smolmix/.cargo/config.toml @@ -0,0 +1,6 @@ +[build] +target = "wasm32-unknown-unknown" +rustflags = ["--cfg=getrandom_backend=\"wasm_js\""] + +[target.wasm32-unknown-unknown] +runner = 'wasm-bindgen-test-runner' diff --git a/wasm/smolmix/.gitignore b/wasm/smolmix/.gitignore new file mode 100644 index 0000000000..787c5dd1e9 --- /dev/null +++ b/wasm/smolmix/.gitignore @@ -0,0 +1 @@ +connection-notes.md diff --git a/wasm/smolmix/Cargo.toml b/wasm/smolmix/Cargo.toml new file mode 100644 index 0000000000..4042f32fe0 --- /dev/null +++ b/wasm/smolmix/Cargo.toml @@ -0,0 +1,118 @@ +[package] +name = "smolmix-wasm" +version = "1.21.0" +authors = { workspace = true } +edition = { workspace = true } +license = { workspace = true } +repository = { workspace = true } +rust-version = { workspace = true } +publish = false +keywords = ["nym", "fetch", "wasm", "mixnet", "privacy"] + +[lib] +crate-type = ["cdylib", "rlib"] + +[dependencies] +futures = { workspace = true } +js-sys = { workspace = true } +thiserror = { workspace = true } +# `sync` feature only: gives us `tokio::sync::Notify` (the reactor wake source) +# without pulling in tokio's runtime (wasm32-incompatible). +tokio = { workspace = true, features = ["sync"] } +url = { workspace = true } +wasm-bindgen = { workspace = true } +wasm-bindgen-futures = { workspace = true } +wasmtimer = { workspace = true } + +# DNS wire-format types (always present; internal DNS resolution is needed +# even when only `fetch` or `socket` is enabled, for hostname → IP). +hickory-proto = { workspace = true, features = ["std"] } + +# TLS stack: gated by the `_tls` private feature (pulled by `fetch` or `socket`). +# rustls-rustcrypto is the only viable provider on wasm32-unknown-unknown: +# ring + aws-lc-rs both fail to compile (no OS entropy / no C toolchain in browser). +rustls = { workspace = true, features = ["std"], optional = true } +rustls-pki-types = { workspace = true, features = ["web"], optional = true } +futures-rustls = { workspace = true, features = ["tls12"], optional = true } +webpki-roots = { workspace = true, optional = true } +rustls-rustcrypto = { workspace = true, optional = true } + +# HTTP/1.1 client (tokio-free; workspace declares default-features = false). +# Gated by `fetch`: `mixSocket` does its upgrade handshake via async-tungstenite directly. +hyper = { workspace = true, features = ["client", "http1"], optional = true } +http-body-util = { workspace = true, optional = true } +http = { workspace = true, optional = true } + +# WebSocket (RFC 6455 client over futures::io streams). Gated by `socket`. +async-tungstenite = { workspace = true, features = ["handshake"], optional = true } + +# WASM utils (panic hook, console_log) +nym-wasm-utils = { workspace = true } + +# Tunnel: smoltcp stack + Nym mixnet client + IPR protocol +smoltcp = { workspace = true, features = ["std", "medium-ip", "proto-ipv4", "socket-tcp", "socket-udp", "async"] } +nym-wasm-client-core = { workspace = true } +nym-ip-packet-requests = { workspace = true } +# LP wire types (frame, header, codec) +nym-lp-data = { workspace = true } +bytes = { workspace = true } +rand = { workspace = true } +nym-bin-common = { workspace = true } +# IPR auto-discovery (`NymApiClientExt` + `semver` gate for v9-capable IPRs). +nym-validator-client = { workspace = true } +semver = { workspace = true } + +# JS interop: typed `SetupOpts` deserialisation. +serde = { workspace = true, features = ["derive"] } +serde-wasm-bindgen = { workspace = true } +tsify = { workspace = true, features = ["js"] } + +# crypto.getRandomValues() backend for the 0.2 line. +[target."cfg(target_arch = \"wasm32\")".dependencies.getrandom] +workspace = true +features = ["js"] + +# The 0.4 line is pulled in transitively by hickory-proto via rand_core 0.10; +# its wasm32 feature was renamed from "js" to "wasm_js". +[target."cfg(target_arch = \"wasm32\")".dependencies.getrandom04] +workspace = true +features = ["wasm_js"] + +[features] +# Default: build all three JS entry points (mixFetch, mixSocket, mixResolve). +# TS SDK packages that only need a subset can disable defaults and opt in: +# smolmix-wasm = { ..., default-features = false, features = ["fetch"] } +default = ["dns", "fetch", "socket"] + +# Expose the JS `mixResolve(hostname)` entry point. +# Note: the internal DNS resolver (used by fetch/socket for hostname lookups) +# is always compiled — only the standalone JS export is gated here. +dns = [] + +# Expose the JS `mixFetch(url, init)` HTTP client. Pulls in TLS + the hyper-based +# HTTP/1.1 stack. +fetch = ["_tls", "_http"] + +# Expose the JS `mixSocket(url, protocols, onEvent)` WebSocket client. +# Pulls TLS (for `wss://`) + async-tungstenite. Does not pull `_http` because +# tungstenite handles the WebSocket upgrade handshake itself. +socket = ["_tls", "dep:async-tungstenite"] + +# Internal feature aggregating the rustls-based TLS stack. Shared between +# `fetch` (HTTPS) and `socket` (WSS). +_tls = [ + "dep:rustls", + "dep:rustls-pki-types", + "dep:futures-rustls", + "dep:webpki-roots", + "dep:rustls-rustcrypto", +] + +# Internal feature aggregating hyper + http types. `fetch`-only. +_http = ["dep:hyper", "dep:http-body-util", "dep:http"] + +# Verbose `console.log` tracing (off by default). +debug = [] + +[package.metadata.wasm-pack.profile.release] +wasm-opt = false diff --git a/wasm/smolmix/Makefile b/wasm/smolmix/Makefile new file mode 100644 index 0000000000..0bd2416456 --- /dev/null +++ b/wasm/smolmix/Makefile @@ -0,0 +1,50 @@ +# `taskset -c 0-11` caps cargo to 12 cores so the build does +# not saturate CI runners. Override empty to +# disable on machines without taskset (macOS, BSDs, sandboxes): +# make TASKSET= build-debug +TASKSET ?= taskset -c 0-11 + +.PHONY: build build-rust build-debug build-release-opt check-fmt dev dev-build \ + internal-dev-install test test\:smoke test\:suite + +build: build-rust + +build-rust: + $(TASKSET) wasm-pack build --scope nymproject --target web + +build-debug: + $(TASKSET) wasm-pack build --debug --scope nymproject --target web --features debug + +build-release-opt: + $(TASKSET) wasm-pack build --scope nymproject --target web + $(TASKSET) wasm-opt -Oz -o pkg/smolmix_wasm_bg.wasm pkg/smolmix_wasm_bg.wasm + +check-fmt: + cargo fmt --check + cargo clippy --target wasm32-unknown-unknown -- -Dwarnings + cargo clippy --target wasm32-unknown-unknown --features debug -- -Dwarnings + +dev: build-debug + cd internal-dev && ./node_modules/.bin/webpack serve --open + +# Build the internal-dev webpack bundle for Playwright. +dev-build: build-debug + cd internal-dev && ./node_modules/.bin/webpack --mode production + +# One-time setup for internal-dev. Run this after fresh clone or when +# internal-dev/package.json changes. Standalone install (no workspace walk). +internal-dev-install: + cd internal-dev && pnpm install --ignore-workspace + +# Playwright tests (headless browser). +# Prereqs: make dev-build && cd tests && pnpm install && pnpm exec playwright install +# IPR_ADDRESS env var is optional; tests fall back to the default in +# internal-dev/index.html / internal-dev/headless.js when unset. +test\:smoke: + cd tests && pnpm exec playwright test --project=smoke-chromium --project=smoke-firefox --project=smoke-webkit + +test\:suite: + cd tests && pnpm exec playwright test --project=suite-chromium --project=suite-firefox --project=suite-webkit + +test: + cd tests && pnpm exec playwright test diff --git a/wasm/smolmix/README.md b/wasm/smolmix/README.md new file mode 100644 index 0000000000..5c060822a1 --- /dev/null +++ b/wasm/smolmix/README.md @@ -0,0 +1,192 @@ +# smolmix-wasm + +Drop-in browser networking over the Nym mixnet. Routes HTTP and WebSocket +traffic through a mixnet tunnel, giving web applications network-level +privacy without changing application code. + +## Public API + +Three WASM exports that mirror the browser's native networking surface: + +| Browser API | smolmix export | Description | +|-------------|---------------|-------------| +| `fetch()` | `mixFetch(url, init)` | HTTP/HTTPS request-response | +| `new WebSocket()` | `mixSocket(url, protocols, onEvent)` | WebSocket (WS/WSS) | +| (no direct browser equivalent) | `mixResolve(hostname)` | DNS-only hostname lookup over UDP/IPR (no TCP/TLS) | + +## Arch + +```text + WasmTunnel + +---------- tunnel.rs -----------+ + | | + | Owns: smoltcp stack, Nym | + | client, connection pool, | + | DNS cache, origin locks | + +--------------------------------+ + | | + TCP/UDP sockets | + (futures::io) | + | | + v v + +-----------+ +-----------+ +-----------+ + | Reactor | | Bridge | | Nym Client| + | reactor.rs| | bridge.rs | | (base | + | | | | | client) | + +-----------+ +-----------+ +-----------+ + | | | + v v | + +-----------+ +-------+ | + | smoltcp | | IPR | | + | Interface | |ipr.rs | | + +-----------+ +-------+ | + | | | + v | | + +-----------+ | | + | Device |<----+ | + | device.rs | | | + | (virtual | v | + | NIC) | LP frames | + +-----------+ + SURBs | + rx[] / tx[] | | + +--------->------+ + mixnet +``` + +### Component walkthrough + +- Device (`device.rs`) - the virtual network interface card +- Reactor (`reactor.rs`) - the smoltcp poll loop +- Bridge (`bridge.rs`) - shuttles packets between the device and the mixnet +- IPR (`ipr.rs`) - IP Packet Router protocol layer +- WasmTcpStream / WasmUdpSocket / PooledConn (`stream.rs`) - `futures::io::AsyncRead + AsyncWrite` adapters over smoltcp sockets +- WASM exports (`lib.rs`, `mixfetch.rs`, `mixsocket.rs`) - the surface JS calls into + +### Tuning + +The JS `setupMixTunnel(opts)` shape accepts the following optional fields for +timeouts, buffer sizes, and protocol limits. All have sensible defaults; only +override when you have a concrete reason. + +| Field | Default | Notes | +|-------------------|---------|----------------------------------------------------------------| +| `connectTimeoutMs`| `60000` | IPR connect handshake timeout | +| `dnsTimeoutMs` | `30000` | DNS query timeout (per primary/fallback attempt) | +| `tcpKeepaliveMs` | `10000` | TCP keepalive probe interval | +| `tcpBufferSize` | `65535` | Per-TCP-stream RX/TX buffer; capped at `u16::MAX` | +| `maxRedirects` | `5` | `mixFetch` redirect chain depth before bail | + +On the Rust side these live in `TunnelOpts::tuning: TuningOpts`. The builder +exposes them flat (`.connect_timeout(d)`, `.tcp_buffer_size(n)`, etc.) so +callers don't see the grouping. + +### Feature flags + +The crate is split into three user-facing cargo features matching the JS entry +points. Default builds enable all three; downstream TS SDK packages can opt +into a subset to drop the corresponding implementation + native deps from the +wasm binary. + +| Feature | JS export | Pulls | +|---------|-----------------|----------------------------------------------------| +| `dns` | `mixResolve` | (nothing extra; DNS resolver is always compiled) | +| `fetch` | `mixFetch` | rustls TLS stack + hyper HTTP/1.1 client | +| `socket`| `mixSocket` | rustls TLS stack + async-tungstenite | + +Build a `dns`-only client: + +```sh +cargo build --target wasm32-unknown-unknown --no-default-features --features dns +``` + +Build a `fetch`-only client (no WebSocket, no `mixResolve` JS export): + +```sh +cargo build --target wasm32-unknown-unknown --no-default-features --features fetch +``` + +`fetch` and `socket` share the TLS stack (rustls + rustls-rustcrypto + webpki-roots); +enabling both is roughly the same wasm size as either alone plus the hyper + +async-tungstenite specifics. + +### Debug logging + +`debug_log!` and `debug_error!` (in `util.rs`) wrap `nym_wasm_utils::console_log!` / +`console_error!` behind the `debug` cargo feature. Tunnel start/shutdown and the +IPR connect handshake stay unconditional; everything else is silent in release. + +`make build-debug` enables the feature automatically (it builds with +`--features debug`). `make build-release-opt` leaves it off, so release +artefacts ship no verbose logging. + +### Cryptography + +TLS terminates inside the WASM client, so we need a pure-Rust rustls +crypto provider. [`rustls-rustcrypto`](https://github.com/RustCrypto/rustls-rustcrypto) as +the only viable option: the underlying RustCrypto AEADs were +[audited by NCC Group in 2020](https://www.nccgroup.com/research/public-report-rustcrypto-aesgcm-and-chacha20pluspoly1305-implementation-review/) +with no findings, while the rustls integration glue is `0.0.2-alpha`. +`src/tls.rs` restricts negotiation to AEAD-only suites with forward-secret +key exchange. + +## Build + +```sh +make build # plain release wasm-pack build +make build-debug # dev profile, verbose console logs on +make build-release-opt # release + wasm-opt -Oz +make dev # build-debug then start internal-dev webpack +``` + +## Summary diagram + +```text + JS caller + | + +---------+---------+--------------+ + v v v + mixFetch mixSocket mixResolve + (mixfetch.rs) (mixsocket.rs) (mixdns.rs) + | | | + v v v + fetch::fetch fetch::new_ dns::resolve + connection + (dns.rs) + async_tungst. + \ | / + \ v / + '-> WasmTcpStream / WasmUdpSocket (stream.rs) + | + v smoltcp socket buffer + +-------- smoltcp::Interface::poll() (reactor.rs) + | + v IP packet + WasmDevice.tx_queue (device.rs) + | + v drained 5ms + bridge::start_bridge (bridge.rs) + | + v + ipr::send_ip_packet (ipr.rs) + | + v LP-framed DataRequest + ClientInput::send (upstream, nym-wasm-client-core) + | + v Sphinx-packed + JSWebsocket::new -> WebSocket::open -> web_sys::WebSocket::new + (common/wasm/utils/src/websocket/mod.rs:58) + | + v + Single wss:// to chosen gateway + + (Separately, at startup + on TopologyRefresher tick:) + nym_http_api_client::ClientBuilder + -> reqwest -> web_sys::fetch + (common/client-core/src/init/helpers.rs:155) + | + v + HTTPS GET https://validator.nymtech.net/... +``` + +Everything else (TLS handshakes, HTTP/1.1 requests, WebSocket frames in +`mixSocket`) is content travelling inside that single gateway WSS as +Sphinx-packed bytes. diff --git a/wasm/smolmix/internal-dev/.npmrc b/wasm/smolmix/internal-dev/.npmrc new file mode 100644 index 0000000000..f60243936e --- /dev/null +++ b/wasm/smolmix/internal-dev/.npmrc @@ -0,0 +1,13 @@ +; This is a self-contained dev harness, not part of the root pnpm workspace. +; ignore-workspace=true prevents pnpm from walking up to the monorepo root +; and trying to install every workspace package (which pulls unrelated deps +; like `sharp` that have no business being on the smolmix dev path). +ignore-workspace=true + +; pnpm 11+ runs a "deps status check" before every `pnpm run + + +

+  
+
diff --git a/wasm/smolmix/internal-dev/headless.js b/wasm/smolmix/internal-dev/headless.js
new file mode 100644
index 0000000000..89cb04bbc2
--- /dev/null
+++ b/wasm/smolmix/internal-dev/headless.js
@@ -0,0 +1,316 @@
+// smolmix-wasm headless test runner
+//
+// Auto-runs a battery of tests on page load. Config via URL params:
+//
+//   ?ipr=
IPR address (uses default if omitted) +// ?cover=true Enable cover traffic (default: disabled) +// ?poisson=true Enable Poisson traffic (default: disabled) +// ?count=10 Stress test request count +// +// Two runs needed for the full matrix (OnceLock prevents re-init): +// http://localhost:9000/headless.html +// http://localhost:9000/headless.html?cover=true&poisson=true + +import * as Comlink from "comlink"; + +// Config + +const params = new URLSearchParams(location.search); + +const IPR_ADDRESS = + params.get("ipr") || + "6B6iuWX4bQP4GVA4Yq7XmZencaaGw6BaPY6xJWYSwsbF.6g6LRx1fgU2Q2A4ZPKonYHtfBARh1GPMe1LtXk6vpRR8@q2A2cbooyC16YJzvdYaSMH9X3cSiieZNtfBr8cE8Fi1"; + +const ENABLE_COVER = params.get("cover") === "true"; +const ENABLE_POISSON = params.get("poisson") === "true"; +// Clamp to [1, 500]: parseInt of garbage returns NaN, negative values would +// underflow the test loop, very large values would exhaust browser memory. +const STRESS_COUNT = Math.min(500, Math.max(1, parseInt(params.get("count") || "10", 10) || 10)); + +const CONFIG_LABEL = `cover=${ENABLE_COVER ? "ON" : "OFF"}, poisson=${ + ENABLE_POISSON ? "ON" : "OFF" +}`; + +// Output + +const outputEl = document.getElementById("output"); + +function log(msg) { + const ts = new Date().toISOString().slice(11, 23); + const line = `[${ts}] ${msg}`; + outputEl.textContent += line + "\n"; + outputEl.scrollTop = outputEl.scrollHeight; + console.log(line); +} + +// Worker setup (shared worker.js) + +function createWorker() { + return new Promise((resolve, reject) => { + const worker = new Worker(new URL("./worker.js", import.meta.url)); + worker.addEventListener("error", reject); + worker.addEventListener( + "message", + (msg) => { + if (msg.data?.kind === "Loaded") { + worker.removeEventListener("error", reject); + resolve(Comlink.wrap(worker)); + } + }, + { once: true } + ); + }); +} + +function toResponse(raw) { + return new Response(raw.body, { + status: raw.status, + statusText: raw.statusText, + headers: new Headers(raw.headers), + }); +} + +// Helpers + +async function timedFetch(api, url, init = {}) { + const t0 = performance.now(); + const raw = await api.mixFetch(url, init); + const ms = performance.now() - t0; + const resp = toResponse(raw); + return { ok: resp.ok, status: resp.status, statusText: resp.statusText, ms }; +} + +function fmtMs(ms) { + return (ms / 1000).toFixed(2) + "s"; +} + +// Test: Smoke (cold HTTPS GET) + +async function testSmoke(api) { + log(""); + log("=== Smoke Test (cold HTTPS GET) ==="); + log("GET https://httpbin.org/get"); + + try { + const r = await timedFetch(api, "https://httpbin.org/get"); + log(` ${r.status} ${r.statusText} in ${fmtMs(r.ms)}`); + return { name: "Smoke (cold HTTPS)", ok: true, ms: r.ms }; + } catch (e) { + log(` FAIL: ${e}`); + return { name: "Smoke (cold HTTPS)", ok: false, ms: 0, error: String(e) }; + } +} + +// Test: HTTPS GET (warm, pooled connection) + +async function testHttpsGetWarm(api) { + log(""); + log("=== HTTPS GET (warm) ==="); + log("GET https://httpbin.org/get (pooled connection)"); + + try { + const r = await timedFetch(api, "https://httpbin.org/get"); + log(` ${r.status} ${r.statusText} in ${fmtMs(r.ms)}`); + return { name: "HTTPS GET (warm)", ok: true, ms: r.ms }; + } catch (e) { + log(` FAIL: ${e}`); + return { name: "HTTPS GET (warm)", ok: false, ms: 0, error: String(e) }; + } +} + +// Test: Stress (httpbin mixed sizes) + +const SIZE_PROFILES = [ + { label: "tiny", bytes: 128 }, + { label: "small", bytes: 1024 }, + { label: "medium", bytes: 10240 }, + { label: "large", bytes: 102400 }, +]; + +async function testStressHttpbin(api) { + log(""); + log(`=== Stress Test: httpbin (${STRESS_COUNT} requests, mixed sizes) ===`); + + const requests = []; + for (let i = 0; i < STRESS_COUNT; i++) { + const p = SIZE_PROFILES[Math.floor(Math.random() * SIZE_PROFILES.length)]; + requests.push({ + id: i + 1, + url: `https://httpbin.org/bytes/${p.bytes}`, + label: p.label, + }); + } + + // Log profile distribution + const dist = {}; + for (const r of requests) dist[r.label] = (dist[r.label] || 0) + 1; + log(` Profiles: ${JSON.stringify(dist)}`); + + const t0 = performance.now(); + const perReq = []; + + // Fire all concurrently (origin lock serialises per-host) + const settled = await Promise.allSettled( + requests.map(async (req) => { + const start = performance.now(); + try { + const r = await timedFetch(api, req.url); + const elapsed = performance.now() - start; + log(` #${req.id} ${req.label}: ${r.status} OK ${fmtMs(elapsed)}`); + perReq.push({ id: req.id, label: req.label, ok: true, ms: elapsed }); + } catch (e) { + const elapsed = performance.now() - start; + log(` #${req.id} ${req.label}: FAIL ${fmtMs(elapsed)} — ${e}`); + perReq.push({ id: req.id, label: req.label, ok: false, ms: elapsed }); + } + }) + ); + + const totalMs = performance.now() - t0; + const okCount = perReq.filter((r) => r.ok).length; + const avgMs = + perReq.filter((r) => r.ok).reduce((s, r) => s + r.ms, 0) / (okCount || 1); + + log( + ` Result: ${okCount}/${STRESS_COUNT} OK, total ${fmtMs( + totalMs + )}, avg ${fmtMs(avgMs)}/req` + ); + + return { + name: `Stress httpbin (${STRESS_COUNT})`, + ok: okCount === STRESS_COUNT, + ms: totalMs, + okCount, + total: STRESS_COUNT, + avgMs, + perReq, + }; +} + +// Summary + +function printSummary(results) { + log(""); + log("================================================================"); + log(` smolmix-wasm test results`); + log(` Config: ${CONFIG_LABEL}`); + log(` Date: ${new Date().toISOString()}`); + log("================================================================"); + log(""); + + const nameWidth = 28; + const resultWidth = 10; + + log(` ${"Test".padEnd(nameWidth)}${"Result".padEnd(resultWidth)}Time`); + log( + ` ${"".padEnd(nameWidth, "-")}${"".padEnd(resultWidth, "-")}${"".padEnd( + 20, + "-" + )}` + ); + + for (const r of results) { + let resultStr; + if (r.total !== undefined) { + resultStr = `${r.okCount}/${r.total}`; + } else { + resultStr = r.ok ? "PASS" : "FAIL"; + } + + let timeStr = r.ms ? fmtMs(r.ms) : "N/A"; + if (r.avgMs !== undefined) { + timeStr += ` (avg ${fmtMs(r.avgMs)}/req)`; + } + + log( + ` ${r.name.padEnd(nameWidth)}${resultStr.padEnd(resultWidth)}${timeStr}` + ); + } + + log(""); + log("================================================================"); + + // Also output as JSON for programmatic consumption + const json = { + config: { cover: ENABLE_COVER, poisson: ENABLE_POISSON }, + date: new Date().toISOString(), + results: results.map((r) => ({ + name: r.name, + ok: r.ok, + ms: Math.round(r.ms), + ...(r.okCount !== undefined && { okCount: r.okCount, total: r.total }), + ...(r.avgMs !== undefined && { avgMs: Math.round(r.avgMs) }), + ...(r.error && { error: r.error }), + })), + }; + // Machine-readable output for Playwright (bypasses log() timestamp prefix) + console.log("RESULTS_JSON:" + JSON.stringify(json)); +} + +// Main + +async function runSuite() { + log("smolmix-wasm headless test runner"); + log(`Config: ${CONFIG_LABEL}`); + log(`Stress count: ${STRESS_COUNT}`); + log(`IPR: ${IPR_ADDRESS.slice(0, 40)}...`); + log(""); + + // 1. Start worker + log("Starting worker..."); + let api; + try { + api = await createWorker(); + log("Worker started"); + } catch (e) { + log(`FATAL: Worker creation failed: ${e}`); + printSummary([{ name: "Worker init", ok: false, ms: 0, error: String(e) }]); + return; + } + + // 2. Setup tunnel + log("Setting up tunnel..."); + const setupT0 = performance.now(); + try { + await api.setupMixTunnel({ + preferredIpr: IPR_ADDRESS, + clientId: "headless-" + Math.random().toString(36).slice(2, 8), + forceTls: true, + disablePoissonTraffic: !ENABLE_POISSON, + disableCoverTraffic: !ENABLE_COVER, + }); + const setupMs = performance.now() - setupT0; + log(`Tunnel ready in ${fmtMs(setupMs)}`); + } catch (e) { + log(`FATAL: Tunnel setup failed: ${e}`); + printSummary([ + { name: "Tunnel setup", ok: false, ms: 0, error: String(e) }, + ]); + return; + } + + // 3. Run tests sequentially + const results = []; + + results.push(await testSmoke(api)); + results.push(await testHttpsGetWarm(api)); + results.push(await testStressHttpbin(api)); + + // 4. Summary + printSummary(results); + + // 5. Disconnect + log(""); + log("Disconnecting..."); + try { + await api.disconnectMixTunnel(); + log("Disconnected"); + } catch (e) { + log(`Disconnect error: ${e}`); + } + + log("Done."); +} + +runSuite(); diff --git a/wasm/smolmix/internal-dev/index.html b/wasm/smolmix/internal-dev/index.html new file mode 100644 index 0000000000..a9181b980d --- /dev/null +++ b/wasm/smolmix/internal-dev/index.html @@ -0,0 +1,239 @@ + + + + + + smolmix-wasm dev + + + + + +

smolmix-wasm dev

+ + +
+ Connection +
+ + + +
+
+ Advanced Options +
+
+ +
+
+ + (randomised on load for clean state) +
+
+ +
+
+ +
+
+ + +
+ Optional. Larger pools raise inbound throughput; each outgoing Sphinx packet then carries more reply blocks. +
+
+
+ + +
+ Optional. `host:port`. Leave blank to use the defaults shown. +
+
+
+
+
+ + + + Not started +
+
+ + +
+ DNS Resolve +
+ + + +
+

+    
+ + +
+ GET +
+ + + +
+

+    
+ + +
+ WebSocket +
+ + + + Not connected +
+
+ + +
+
+ + + + + + + bytes + +
+

+    
+ + +
+ Stress Test +
+ + + + +
+ + + +
+ + + + + + +
tiny128 B
small1 KB
medium10 KB
large100 KB
xlarge1 MB
+
+ + + +
+ + +
+

+    
+ + +
+ File Download +
+
+ UTF-8 Demo +
Unicode text (Cambridge CS)
+ + + +
+
+ File Download +
+ +
+ + + + +
+
+
+ + +
+

+    
+ + +
+ Output (master timeline) +

+    
+ + diff --git a/wasm/smolmix/internal-dev/index.js b/wasm/smolmix/internal-dev/index.js new file mode 100644 index 0000000000..97474b34dd --- /dev/null +++ b/wasm/smolmix/internal-dev/index.js @@ -0,0 +1,858 @@ +// smolmix-wasm internal-dev test harness. +// WASM runs in a Web Worker so mixnet I/O stays off the main thread. + +import * as Comlink from "comlink"; +import { MixSocket } from "./mix-socket.js"; + +function createWorker() { + return new Promise((resolve, reject) => { + const worker = new Worker(new URL("./worker.js", import.meta.url)); + worker.addEventListener("error", reject); + worker.addEventListener( + "message", + (msg) => { + if (msg.data?.kind === "Loaded") { + worker.removeEventListener("error", reject); + resolve({ worker, api: Comlink.wrap(worker) }); + } + }, + { once: true }, + ); + }); +} + +let api = null; + +const outputEl = document.getElementById("output"); + +// Global timeline. Per-section feedback goes through logTo() instead. +// Red-coloured entries (the in-page convention for errors) are also +// mirrored to console.error so they show up in the browser dev tools +// alongside the Rust-side `[smolmix] ...` logs. +function display(msg, colour) { + const ts = new Date().toISOString().slice(11, 23); + const line = document.createElement("div"); + if (colour) line.style.color = colour; + line.textContent = `[${ts}] ${msg}`; + outputEl.appendChild(line); + outputEl.scrollTop = outputEl.scrollHeight; + if (colour === "red") console.error("[smolmix-dev]", msg); +} + +function logTo(targetId, msg, colour) { + const target = document.getElementById(targetId); + if (!target) return; + const ts = new Date().toISOString().slice(11, 23); + const line = document.createElement("div"); + if (colour) line.style.color = colour; + line.textContent = `[${ts}] ${msg}`; + target.appendChild(line); + target.scrollTop = target.scrollHeight; + if (colour === "red") console.error(`[smolmix-dev:${targetId}]`, msg); +} + +function hexPreview(data, maxBytes = 64) { + const bytes = data instanceof Uint8Array ? data : new Uint8Array(data); + const len = Math.min(bytes.length, maxBytes); + const hex = Array.from(bytes.slice(0, len), (b) => + b.toString(16).padStart(2, "0"), + ).join(" "); + return bytes.length > maxBytes ? `${hex} ...` : hex; +} + +// Wrap mixFetch's { body, status, statusText, headers } in a native Response +// so callers get .json(), .text(), .arrayBuffer(). +function toResponse(raw) { + return new Response(raw.body, { + status: raw.status, + statusText: raw.statusText, + headers: new Headers(raw.headers), + }); +} + +// Tunnel-gated fieldsets and buttons. GET and DNS fieldsets are excluded: +// their clearnet buttons work without a tunnel, so only the tunnel buttons +// inside them are gated individually. +const GATED_FIELDSETS = [ + "ws-controls", + "stress-controls", + "download-controls", +]; + +const GATED_BUTTONS = ["btn-get-tunnel", "btn-dns-tunnel"]; + +function setTunnelButtonsEnabled(enabled) { + for (const id of GATED_FIELDSETS) { + document.getElementById(id).disabled = !enabled; + } + for (const id of GATED_BUTTONS) { + document.getElementById(id).disabled = !enabled; + } +} + +// Grey out the IPR text input when "Use random IPR" is checked. +document.getElementById("opt-random-ipr").addEventListener("change", (e) => { + document.getElementById("ipr-address").disabled = e.target.checked; +}); + +document.getElementById("btn-setup").addEventListener("click", async () => { + const useRandomIpr = document.getElementById("opt-random-ipr").checked; + const iprAddress = useRandomIpr + ? undefined + : document.getElementById("ipr-address").value.trim(); + if (!useRandomIpr && !iprAddress) { + display("IPR address is required (or check 'Use random IPR')", "red"); + return; + } + + const statusEl = document.getElementById("tunnel-status"); + document.getElementById("btn-setup").disabled = true; + statusEl.textContent = "Starting worker..."; + statusEl.style.color = "orange"; + + try { + const result = await createWorker(); + api = result.api; + MixSocket._initWorker(result.worker); + display("Worker started"); + + // Sync the debug-logging checkbox into WASM so the UI default applies + // from setup time — without this, the checkbox could read `checked` + // while the WASM static stays false until the user re-toggles. + const debugOn = document.getElementById("opt-debug-logging").checked; + await api.setDebugLogging(debugOn); + } catch (e) { + display(`Worker creation failed: ${e}`, "red"); + document.getElementById("btn-setup").disabled = false; + statusEl.textContent = "Failed"; + statusEl.style.color = "red"; + return; + } + + const clientId = document.getElementById("opt-client-id").value; + const forceTls = document.getElementById("opt-force-tls").checked; + const disablePoisson = document.getElementById("opt-disable-poisson").checked; + const disableCover = document.getElementById("opt-disable-cover").checked; + + // Allow 0 for the data slot — the default is "lean entirely on + // nym-client-core's pre-emptive SURB topup" (see SurbsConfig::default + // in wasm/smolmix/src/ipr.rs). + const clampSurbs = (n) => Math.min(50, Math.max(0, n)); + const openReplySurbs = clampSurbs( + parseInt(document.getElementById("opt-open-surbs").value, 10) || 10, + ); + const dataReplySurbs = clampSurbs( + parseInt(document.getElementById("opt-data-surbs").value, 10) || 0, + ); + + // `undefined` (omitted) means "use the Rust default"; see SetupOpts. + const primaryDns = + document.getElementById("opt-primary-dns").value.trim() || undefined; + const fallbackDns = + document.getElementById("opt-fallback-dns").value.trim() || undefined; + + display( + useRandomIpr + ? `setupMixTunnel (clientId=${clientId}, IPR: auto-discover)...` + : `setupMixTunnel (clientId=${clientId}, IPR: ${iprAddress.slice(0, 30)}...)...`, + ); + statusEl.textContent = "Connecting to mixnet..."; + + try { + await api.setupMixTunnel({ + // Omit preferredIpr entirely when auto-discovery is requested. + // Rust SetupOpts treats `null`/undefined as "discover one yourself". + ...(iprAddress ? { preferredIpr: iprAddress } : {}), + clientId, + forceTls, + disablePoissonTraffic: disablePoisson, + disableCoverTraffic: disableCover, + openReplySurbs, + dataReplySurbs, + primaryDns, + fallbackDns, + }); + display("setupMixTunnel OK: tunnel ready", "green"); + statusEl.textContent = "Connected"; + statusEl.style.color = "green"; + setTunnelButtonsEnabled(true); + document.getElementById("btn-disconnect").disabled = false; + } catch (e) { + const msg = String(e); + display(`setupMixTunnel failed: ${msg}`, "red"); + statusEl.textContent = `Failed: ${msg}`; + statusEl.style.color = "red"; + statusEl.title = msg; + document.getElementById("btn-setup").disabled = false; + } +}); + +document + .getElementById("btn-disconnect") + .addEventListener("click", async () => { + display("Disconnecting..."); + try { + await api.disconnectMixTunnel(); + display("Disconnected", "green"); + document.getElementById("tunnel-status").textContent = "Disconnected"; + document.getElementById("tunnel-status").style.color = "gray"; + setTunnelButtonsEnabled(false); + document.getElementById("btn-disconnect").disabled = true; + document.getElementById("btn-setup").disabled = true; // OnceLock: can't reinit + } catch (e) { + display(`Disconnect failed: ${e}`, "red"); + } + }); + +document + .getElementById("opt-debug-logging") + .addEventListener("change", async (e) => { + const enabled = e.target.checked; + // Pre-setup clicks: WASM isn't loaded yet. The checkbox state is read + // again right after the worker boots, so the toggle still takes effect. + if (!api) { + display(`Debug logging queued ${enabled ? "ON" : "OFF"} (applies on setup)`); + return; + } + try { + await api.setDebugLogging(enabled); + display( + `Debug logging ${enabled ? "ON" : "OFF"} (logs in browser console)`, + enabled ? "green" : "gray", + ); + } catch (err) { + display(`setDebugLogging failed: ${err}`, "red"); + } + }); + +document.getElementById("btn-dns-tunnel").addEventListener("click", async () => { + const hostname = document.getElementById("dns-host").value.trim(); + if (!hostname) { + logTo("dns-log", "Hostname is required", "red"); + return; + } + + const btn = document.getElementById("btn-dns-tunnel"); + btn.disabled = true; + logTo("dns-log", `tunnel resolve ${hostname}`); + const t0 = performance.now(); + try { + const ip = await api.mixResolve(hostname); + const ms = (performance.now() - t0).toFixed(0); + logTo("dns-log", `tunnel ${hostname} => ${ip} (${ms} ms)`, "green"); + } catch (e) { + logTo("dns-log", `tunnel resolve failed: ${e}`, "red"); + } finally { + btn.disabled = false; + } +}); + +// The browser exposes no raw DNS API; "clearnet DNS" from JS is DoH (HTTPS) +// to a public resolver. Google's JSON API is CORS-friendly and returns +// { Status, Answer: [{ name, type, TTL, data }] }, where type=1 is an A +// record. The request appears in DevTools Network as an HTTPS fetch. +document.getElementById("btn-dns-clearnet").addEventListener("click", async () => { + const hostname = document.getElementById("dns-host").value.trim(); + if (!hostname) { + logTo("dns-log", "Hostname is required", "red"); + return; + } + + logTo("dns-log", `clearnet DoH resolve ${hostname}`); + const t0 = performance.now(); + try { + const resp = await window.fetch( + `https://dns.google/resolve?name=${encodeURIComponent(hostname)}&type=A`, + { mode: "cors" }, + ); + const json = await resp.json(); + const ms = (performance.now() - t0).toFixed(0); + + if (json.Status !== 0) { + logTo("dns-log", `clearnet DoH error: status=${json.Status} (${ms} ms)`, "red"); + return; + } + const aRecord = json.Answer?.find((a) => a.type === 1); + if (!aRecord) { + logTo("dns-log", `clearnet DoH: no A record (${ms} ms)`, "orange"); + return; + } + logTo( + "dns-log", + `clearnet ${hostname} => ${aRecord.data} (${ms} ms); visible in DevTools Network`, + "green", + ); + } catch (e) { + logTo("dns-log", `clearnet DoH failed: ${e}`, "red"); + } +}); + +// Same URL, two transports. Filter DevTools Network by the target host: +// clearnet produces a row, tunnel does not. + +document.getElementById("btn-get-tunnel").addEventListener("click", async () => { + const url = document.getElementById("get-url").value.trim(); + if (!url) { + logTo("get-log", "URL is required", "red"); + return; + } + + logTo("get-log", `tunnel GET ${url}`); + const t0 = performance.now(); + try { + const raw = await api.mixFetch(url, {}); + const resp = toResponse(raw); + const ms = (performance.now() - t0).toFixed(0); + logTo("get-log", `tunnel ${resp.status} ${resp.statusText} (${ms} ms)`, "green"); + } catch (e) { + logTo("get-log", `tunnel GET failed: ${e}`, "red"); + } +}); + +document.getElementById("btn-get-clearnet").addEventListener("click", async () => { + const url = document.getElementById("get-url").value.trim(); + if (!url) { + logTo("get-log", "URL is required", "red"); + return; + } + + logTo("get-log", `clearnet GET ${url}`); + const t0 = performance.now(); + try { + const resp = await window.fetch(url, { mode: "cors" }); + const ms = (performance.now() - t0).toFixed(0); + logTo( + "get-log", + `clearnet ${resp.status} ${resp.statusText} (${ms} ms); visible in DevTools Network`, + "green", + ); + } catch (e) { + logTo("get-log", `clearnet fetch failed: ${e}`, "red"); + } +}); + +function formatSize(bytes) { + if (bytes >= 1048576) return (bytes / 1048576).toFixed(1) + " MB"; + if (bytes >= 1024) return (bytes / 1024).toFixed(1) + " KB"; + return bytes + " B"; +} + +function formatRate(bytes, ms) { + const kbps = bytes / 1024 / (ms / 1000); + return kbps.toFixed(1) + " KB/s"; +} + +let activeWs = null; +let wsConnectT0 = 0; + +// Queue of send timestamps for RTT tracking. +// WebSocket preserves message order, so each recv pops the oldest send. +const wsSendQueue = []; + +let wsBurstActive = false; +let wsBurstRtts = []; +let wsBurstExpected = 0; +let wsBurstResolve = null; + +function setWsButtonState(state) { + const connected = state === "connected"; + const connecting = state === "connecting"; + document.getElementById("btn-ws-connect").disabled = connected || connecting; + document.getElementById("btn-ws-send").disabled = !connected; + document.getElementById("btn-ws-close").disabled = !connected; + document.getElementById("btn-ws-burst").disabled = !connected; +} + +document.getElementById("btn-ws-connect").addEventListener("click", () => { + const url = document.getElementById("ws-url").value.trim(); + if (!url) { + logTo("ws-log", "WebSocket URL is required", "red"); + return; + } + + // Tear down any prior connection so a rapid double-click doesn't leak it. + if (activeWs && activeWs.readyState !== MixSocket.CLOSED) { + activeWs.close(); + } + + const statusEl = document.getElementById("ws-status"); + statusEl.textContent = "Connecting..."; + statusEl.style.color = "orange"; + setWsButtonState("connecting"); + wsSendQueue.length = 0; + + logTo("ws-log", `connecting to ${url}`); + wsConnectT0 = performance.now(); + + const ws = new MixSocket(url); + + ws.onopen = () => { + const ms = (performance.now() - wsConnectT0).toFixed(0); + logTo("ws-log", `connected in ${ms} ms (protocol=${ws.protocol || "none"})`, "green"); + statusEl.textContent = `Connected (${ms} ms)`; + statusEl.style.color = "green"; + setWsButtonState("connected"); + }; + + ws.onmessage = (e) => { + let preview; + if (typeof e.data === "string") { + preview = e.data.length <= 200 ? e.data : e.data.slice(0, 200) + "..."; + } else if (e.data instanceof ArrayBuffer) { + preview = `[binary ${e.data.byteLength} bytes] ${hexPreview(e.data)}`; + } else if (e.data instanceof Blob) { + preview = `[blob ${e.data.size} bytes]`; + } else { + preview = `[unknown ${typeof e.data}]`; + } + + let rttMs = null; + if (wsSendQueue.length > 0) { + rttMs = performance.now() - wsSendQueue.shift(); + } + + // During burst: collect RTTs silently, don't log each message + if (wsBurstActive) { + if (rttMs != null) wsBurstRtts.push(rttMs); + if (wsBurstRtts.length >= wsBurstExpected && wsBurstResolve) { + wsBurstResolve(); + } + return; + } + + if (rttMs != null) { + logTo("ws-log", `recv (${rttMs.toFixed(0)} ms RTT): ${preview}`, "green"); + } else { + logTo("ws-log", `recv: ${preview}`, "green"); + } + }; + + ws.onclose = (e) => { + logTo( + "ws-log", + `closed: ${e.code} ${e.reason}${e.wasClean ? "" : " (unclean)"}`, + "orange", + ); + statusEl.textContent = "Closed"; + statusEl.style.color = "gray"; + setWsButtonState("disconnected"); + activeWs = null; + }; + + ws.onerror = () => { + logTo("ws-log", "error", "red"); + statusEl.textContent = "Error"; + statusEl.style.color = "red"; + }; + + activeWs = ws; +}); + +document.getElementById("btn-ws-send").addEventListener("click", () => { + if (!activeWs || activeWs.readyState !== MixSocket.OPEN) return; + const msg = document.getElementById("ws-message").value; + wsSendQueue.push(performance.now()); + activeWs.send(msg); + logTo("ws-log", `send: ${msg}`); +}); + +document.getElementById("btn-ws-close").addEventListener("click", () => { + if (!activeWs) return; + const t0 = performance.now(); + activeWs.onclose = (e) => { + const ms = (performance.now() - t0).toFixed(0); + logTo( + "ws-log", + `closed in ${ms} ms: ${e.code} ${e.reason}${e.wasClean ? "" : " (unclean)"}`, + "orange", + ); + document.getElementById("ws-status").textContent = "Closed"; + document.getElementById("ws-status").style.color = "gray"; + setWsButtonState("disconnected"); + activeWs = null; + }; + logTo("ws-log", "closing..."); + activeWs.close(); +}); + +document.getElementById("btn-ws-burst").addEventListener("click", async () => { + if (!activeWs || activeWs.readyState !== MixSocket.OPEN) return; + const count = parseInt(document.getElementById("ws-burst-count").value, 10); + const minSize = parseInt(document.getElementById("ws-burst-min").value, 10); + const maxSize = parseInt(document.getElementById("ws-burst-max").value, 10); + + if (count < 1 || count > 500) { + logTo("ws-log", "burst count must be 1-500", "red"); + return; + } + if (minSize < 1 || maxSize < minSize) { + logTo("ws-log", "invalid size range", "red"); + return; + } + + // Switch to arraybuffer mode for binary round-trip verification + const prevBinaryType = activeWs.binaryType; + activeWs.binaryType = "arraybuffer"; + + document.getElementById("btn-ws-burst").disabled = true; + document.getElementById("btn-ws-send").disabled = true; + + const payloads = []; + let totalBytes = 0; + for (let i = 0; i < count; i++) { + const size = + minSize === maxSize + ? minSize + : minSize + Math.floor(Math.random() * (maxSize - minSize + 1)); + const buf = new Uint8Array(size); + crypto.getRandomValues(buf); + payloads.push(buf); + totalBytes += size; + } + + logTo( + "ws-log", + `echo burst: ${count} msgs, ${formatSize(minSize)}-${formatSize(maxSize)} (${formatSize(totalBytes)} total)`, + ); + + wsBurstActive = true; + wsBurstRtts = []; + wsBurstExpected = count; + + let received = 0; + let verified = 0; + let mismatches = 0; + const sizes = []; + let firstRecvHex = null; + + const burstDone = new Promise((resolve) => { + wsBurstResolve = resolve; + + const origOnmessage = activeWs.onmessage; + activeWs.onmessage = (e) => { + let rttMs = null; + if (wsSendQueue.length > 0) { + rttMs = performance.now() - wsSendQueue.shift(); + wsBurstRtts.push(rttMs); + } + + const sent = payloads[received]; + const recvBuf = new Uint8Array(e.data); + sizes.push(recvBuf.byteLength); + if (firstRecvHex === null) firstRecvHex = hexPreview(recvBuf); + + if (sent && recvBuf.byteLength === sent.byteLength) { + let match = true; + for (let j = 0; j < sent.byteLength; j++) { + if (recvBuf[j] !== sent[j]) { + match = false; + break; + } + } + if (match) verified++; + else mismatches++; + } else { + mismatches++; + } + + received++; + if (received >= count) { + activeWs.onmessage = origOnmessage; + resolve(); + } + }; + }); + + const t0 = performance.now(); + for (let i = 0; i < count; i++) { + wsSendQueue.push(performance.now()); + activeWs.send(payloads[i]); + } + + await burstDone; + const totalMs = performance.now() - t0; + + wsBurstActive = false; + wsBurstResolve = null; + activeWs.binaryType = prevBinaryType; + + const rtts = wsBurstRtts.slice().sort((a, b) => a - b); + const rttMin = rtts[0].toFixed(0); + const rttMax = rtts[rtts.length - 1].toFixed(0); + const rttAvg = (rtts.reduce((a, b) => a + b, 0) / rtts.length).toFixed(0); + const p50 = rtts[Math.floor(rtts.length * 0.5)].toFixed(0); + const p95 = rtts[Math.floor(rtts.length * 0.95)].toFixed(0); + const msgPerSec = (count / (totalMs / 1000)).toFixed(1); + const throughput = formatRate(totalBytes, totalMs); + + const verifyColour = mismatches === 0 ? "green" : "red"; + logTo( + "ws-log", + `burst done: ${count} msgs in ${(totalMs / 1000).toFixed(2)}s (${msgPerSec} msg/s, ${throughput})`, + "green", + ); + logTo( + "ws-log", + `verify: ${verified}/${count} OK` + (mismatches > 0 ? `, ${mismatches} MISMATCH` : ""), + verifyColour, + ); + logTo( + "ws-log", + `RTT: min=${rttMin} avg=${rttAvg} p50=${p50} p95=${p95} max=${rttMax} ms`, + ); + + document.getElementById("btn-ws-burst").disabled = false; + document.getElementById("btn-ws-send").disabled = false; +}); + +const SIZE_PROFILES = [ + { label: "tiny", bytes: 128 }, + { label: "small", bytes: 1024 }, + { label: "medium", bytes: 10240 }, + { label: "large", bytes: 102400 }, + { label: "xlarge", bytes: 1048576 }, +]; + +function buildDripProfiles(timeoutSec) { + return [ + { label: "safe", duration: Math.round(timeoutSec * 0.5), delay: 0, bytes: 100 }, + { label: "boundary", duration: Math.round(timeoutSec * 0.92), delay: 0, bytes: 100 }, + { label: "over", duration: Math.round(timeoutSec * 1.08), delay: 0, bytes: 100 }, + { label: "slow-start", duration: Math.round(timeoutSec * 0.83), delay: Math.round(timeoutSec * 0.17), bytes: 100 }, + ]; +} + +function generateRequests(count, mode, timeoutSec) { + const requests = []; + if (mode === "uniform") { + const baseUrl = document.getElementById("stress-url").value.trim(); + for (let i = 1; i <= count; i++) { + requests.push({ id: i, url: `${baseUrl}${i}`, label: "uniform" }); + } + } else if (mode === "mixed") { + for (let i = 1; i <= count; i++) { + const p = SIZE_PROFILES[Math.floor(Math.random() * SIZE_PROFILES.length)]; + requests.push({ id: i, url: `https://httpbin.org/bytes/${p.bytes}`, label: p.label }); + } + } else if (mode === "drip") { + const profiles = buildDripProfiles(timeoutSec); + for (let i = 1; i <= count; i++) { + const p = profiles[Math.floor(Math.random() * profiles.length)]; + requests.push({ + id: i, + url: `https://httpbin.org/drip?duration=${p.duration}&numbytes=${p.bytes}&delay=${p.delay}&code=200`, + label: p.label, + }); + } + } + return requests; +} + +async function runOneStressRequest(req) { + const tag = `#${req.id} ${req.label}`; + const start = performance.now(); + try { + const raw = await api.mixFetch(req.url, {}); + const resp = toResponse(raw); + const body = await resp.text(); + const elapsed = ((performance.now() - start) / 1000).toFixed(2); + logTo("stress-log", `[${tag}] ${resp.status} OK ${elapsed}s (${body.length}B)`, "green"); + return { id: req.id, label: req.label, ok: true, status: resp.status, elapsed, textLength: body.length }; + } catch (e) { + const elapsed = ((performance.now() - start) / 1000).toFixed(2); + logTo("stress-log", `[${tag}] FAIL ${elapsed}s: ${e}`, "red"); + return { id: req.id, label: req.label, ok: false, elapsed, error: String(e) }; + } +} + +document.getElementById("btn-stress").addEventListener("click", async () => { + const count = parseInt(document.getElementById("stress-count").value, 10); + const mode = document.getElementById("stress-mode").value; + const timeoutSec = parseInt( + (document.getElementById("stress-timeout") || { value: "60" }).value, + 10, + ); + + const statusEl = document.getElementById("stress-status"); + document.getElementById("btn-stress").disabled = true; + statusEl.textContent = "Running..."; + + const requests = generateRequests(count, mode, timeoutSec); + + if (mode === "mixed" || mode === "drip") { + const breakdown = {}; + for (const r of requests) breakdown[r.label] = (breakdown[r.label] || 0) + 1; + logTo("stress-log", `${count} requests, ${mode} mode, profiles: ${JSON.stringify(breakdown)}`); + } else { + logTo("stress-log", `${count} requests, ${mode} mode`); + } + + const t0 = performance.now(); + + const settled = await Promise.allSettled( + requests.map((r) => runOneStressRequest(r)), + ); + + const totalSec = ((performance.now() - t0) / 1000).toFixed(2); + const results = settled.map((s) => + s.status === "fulfilled" ? s.value : { ok: false, error: s.reason }, + ); + const ok = results.filter((r) => r.ok).length; + const fail = results.filter((r) => !r.ok).length; + + const colour = fail === 0 ? "green" : "red"; + logTo("stress-log", `done: ${ok}/${count} OK, ${fail} failed (${totalSec}s total)`, colour); + + if (fail > 0) { + for (const r of results.filter((r) => !r.ok)) { + logTo("stress-log", ` FAIL #${r.id} ${r.label} (${r.elapsed}s): ${r.error}`); + } + } + + statusEl.textContent = `Done: ${ok}/${count} OK, ${fail} failed (${totalSec}s)`; + document.getElementById("btn-stress").disabled = false; +}); + +document.getElementById("stress-mode").addEventListener("change", function () { + document.getElementById("stress-uniform-opts").style.display = + this.value === "uniform" ? "block" : "none"; + document.getElementById("stress-mixed-opts").style.display = + this.value === "mixed" ? "block" : "none"; + document.getElementById("stress-drip-opts").style.display = + this.value === "drip" ? "block" : "none"; +}); + +const VERIFY_TEXT_URL = + "https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-demo.txt"; + +async function sha256hex(bytes) { + const hash = await crypto.subtle.digest("SHA-256", bytes); + return Array.from(new Uint8Array(hash), (b) => + b.toString(16).padStart(2, "0"), + ).join(""); +} + +function saveFile(buf, filename, mimeType) { + const blob = new Blob([buf], { type: mimeType }); + const url = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = filename; + a.click(); + URL.revokeObjectURL(url); +} + +let cachedPdf = null; + +async function verifyText() { + const statusEl = document.getElementById("verify-text-status"); + const outputEl = document.getElementById("verify-text-output"); + document.getElementById("btn-verify-text").disabled = true; + statusEl.textContent = "Fetching..."; + statusEl.style.color = "orange"; + + const t0 = performance.now(); + try { + const raw = await api.mixFetch(VERIFY_TEXT_URL, {}); + const resp = toResponse(raw); + const text = await resp.text(); + const ms = (performance.now() - t0).toFixed(0); + + statusEl.textContent = `${formatSize(text.length)} in ${ms} ms`; + statusEl.style.color = "green"; + outputEl.style.display = "block"; + outputEl.textContent = text; + logTo("download-log", `UTF-8 demo: ${formatSize(text.length)} in ${ms} ms`, "green"); + } catch (e) { + statusEl.textContent = `Failed: ${e}`; + statusEl.style.color = "red"; + logTo("download-log", `UTF-8 demo FAILED: ${e}`, "red"); + } + document.getElementById("btn-verify-text").disabled = false; +} + +async function fetchFile() { + const url = document.getElementById("download-url").value.trim(); + if (!url) { + logTo("download-log", "Download URL is required", "red"); + return; + } + + const statusEl = document.getElementById("verify-pdf-status"); + const outputEl = document.getElementById("verify-pdf-output"); + document.getElementById("btn-verify-pdf").disabled = true; + document.getElementById("btn-save-pdf").disabled = true; + cachedPdf = null; + statusEl.textContent = "Fetching..."; + statusEl.style.color = "orange"; + + const t0 = performance.now(); + try { + const raw = await api.mixFetch(url, {}); + const resp = toResponse(raw); + const buf = await resp.arrayBuffer(); + const ms = (performance.now() - t0).toFixed(0); + const hash = await sha256hex(buf); + + document.getElementById("verify-pdf-size").textContent = + `${buf.byteLength.toLocaleString()} bytes`; + document.getElementById("verify-pdf-sha").textContent = hash; + + statusEl.textContent = `${formatSize(buf.byteLength)} in ${(parseFloat(ms) / 1000).toFixed(1)}s`; + statusEl.style.color = "green"; + outputEl.style.display = "block"; + + cachedPdf = buf; + document.getElementById("btn-save-pdf").disabled = false; + + logTo( + "download-log", + `${formatSize(buf.byteLength)} in ${(parseFloat(ms) / 1000).toFixed(1)}s (${formatRate(buf.byteLength, parseFloat(ms))}); SHA-256: ${hash.slice(0, 16)}...`, + "green", + ); + } catch (e) { + statusEl.textContent = `Failed: ${e}`; + statusEl.style.color = "red"; + logTo("download-log", `FAILED: ${e}`, "red"); + } + document.getElementById("btn-verify-pdf").disabled = false; +} + +document.getElementById("btn-verify-text").addEventListener("click", verifyText); +document.getElementById("btn-verify-pdf").addEventListener("click", fetchFile); + +document.getElementById("btn-save-pdf").addEventListener("click", () => { + if (!cachedPdf) return; + const url = document.getElementById("download-url").value.trim(); + const filename = url.split("/").pop()?.split("?")[0] || "download"; + saveFile(cachedPdf, filename, "application/octet-stream"); +}); + +document + .getElementById("btn-verify-all") + .addEventListener("click", async () => { + const statusEl = document.getElementById("verify-all-status"); + statusEl.textContent = "Running..."; + statusEl.style.color = "orange"; + logTo("download-log", "running both downloads..."); + + const t0 = performance.now(); + await Promise.allSettled([verifyText(), fetchFile()]); + const totalMs = (performance.now() - t0).toFixed(0); + + statusEl.textContent = `Done in ${(parseFloat(totalMs) / 1000).toFixed(1)}s`; + statusEl.style.color = "green"; + logTo( + "download-log", + `both complete in ${(parseFloat(totalMs) / 1000).toFixed(1)}s`, + "green", + ); + }); + +// Randomise client ID on each page load for clean state +document.getElementById("opt-client-id").value = + "smolmix-" + Math.random().toString(36).slice(2, 8); + +display( + "smolmix-wasm dev ready. Enter an IPR address and click setupMixTunnel. The clearnet GET works without setup.", +); diff --git a/wasm/smolmix/internal-dev/mix-socket.js b/wasm/smolmix/internal-dev/mix-socket.js new file mode 100644 index 0000000000..b91fca6f16 --- /dev/null +++ b/wasm/smolmix/internal-dev/mix-socket.js @@ -0,0 +1,230 @@ +// MixSocket — drop-in WebSocket replacement over the Nym mixnet. +// +// Mirrors the standard browser WebSocket API (RFC 6455): +// +// const ws = new MixSocket('wss://echo.example.com/ws'); +// ws.onopen = () => ws.send('hello'); +// ws.onmessage = (e) => console.log(e.data); +// ws.onclose = (e) => console.log(e.code, e.reason); +// +// Communicates with the worker via raw postMessage (not Comlink). +// The worker maps connId → WASM handleId and forwards events back. + +const CONNECTING = 0; +const OPEN = 1; +const CLOSING = 2; +const CLOSED = 3; + +let _worker = null; +let _nextConnId = 1; +const _instances = new Map(); + +function _onWorkerMessage(event) { + const msg = event.data; + if (msg?.kind !== 'ws-event') return; + + const instance = _instances.get(msg.connId); + if (!instance) return; + + instance._handleEvent(msg.type, msg.data); +} + +export class MixSocket extends EventTarget { + static CONNECTING = CONNECTING; + static OPEN = OPEN; + static CLOSING = CLOSING; + static CLOSED = CLOSED; + + /** + * Bind the raw Worker so MixSocket can post messages to it. + * Call once during app setup, after the worker emits 'Loaded'. + */ + static _initWorker(worker) { + _worker = worker; + _worker.addEventListener('message', _onWorkerMessage); + } + + /** + * @param {string} url - WebSocket URL (ws:// or wss://) + * @param {string|string[]} [protocols] - Sub-protocol(s) to negotiate + */ + constructor(url, protocols) { + super(); + + if (!_worker) { + throw new Error( + 'MixSocket: worker not initialised — call MixSocket._initWorker(worker) first', + ); + } + + this._connId = _nextConnId++; + this._url = url; + this._readyState = CONNECTING; + this._protocol = ''; + this._binaryType = 'blob'; + + // Standard event handler properties + this.onopen = null; + this.onmessage = null; + this.onclose = null; + this.onerror = null; + + _instances.set(this._connId, this); + + const protoList = protocols + ? typeof protocols === 'string' + ? [protocols] + : [...protocols] + : []; + + _worker.postMessage({ + kind: 'ws-connect', + connId: this._connId, + url, + protocols: protoList, + }); + } + + get url() { + return this._url; + } + get readyState() { + return this._readyState; + } + get protocol() { + return this._protocol; + } + get extensions() { + return ''; + } + get binaryType() { + return this._binaryType; + } + set binaryType(val) { + if (val === 'blob' || val === 'arraybuffer') this._binaryType = val; + } + get bufferedAmount() { + return 0; + } + + /** + * Send data over the WebSocket. + * @param {string|ArrayBuffer|ArrayBufferView} data + */ + send(data) { + if (this._readyState !== OPEN) { + throw new DOMException('WebSocket is not open', 'InvalidStateError'); + } + + // Normalise typed arrays to Uint8Array for structured clone + let payload = data; + if (data instanceof ArrayBuffer) { + payload = new Uint8Array(data); + } else if (ArrayBuffer.isView(data) && !(data instanceof Uint8Array)) { + payload = new Uint8Array(data.buffer, data.byteOffset, data.byteLength); + } + + _worker.postMessage({ + kind: 'ws-send', + connId: this._connId, + payload, + }); + } + + /** + * Initiate the closing handshake. + * @param {number} [code=1000] - Status code + * @param {string} [reason=''] - Human-readable reason + */ + close(code = 1000, reason = '') { + if (this._readyState === CLOSING || this._readyState === CLOSED) return; + this._readyState = CLOSING; + _worker.postMessage({ + kind: 'ws-close', + connId: this._connId, + code, + reason, + }); + } + + /** @internal Route an event from the worker to the appropriate handler. */ + _handleEvent(type, data) { + switch (type) { + case 'open': { + this._readyState = OPEN; + this._protocol = data || ''; + const ev = new Event('open'); + this.dispatchEvent(ev); + if (this.onopen) this.onopen(ev); + break; + } + + case 'text': { + const ev = new MessageEvent('message', { data }); + this.dispatchEvent(ev); + if (this.onmessage) this.onmessage(ev); + break; + } + + case 'binary': { + let payload; + if (this._binaryType === 'arraybuffer') { + payload = data instanceof Uint8Array ? data.buffer : data; + } else { + // Default: blob + payload = data instanceof Uint8Array ? new Blob([data]) : data; + } + const ev = new MessageEvent('message', { data: payload }); + this.dispatchEvent(ev); + if (this.onmessage) this.onmessage(ev); + break; + } + + case 'close': { + this._readyState = CLOSED; + _instances.delete(this._connId); + + // Parse close info: "1000 normal closure" → code=1000, reason="normal closure" + let code = 1005; + let reason = ''; + if (typeof data === 'string') { + const match = data.match(/^(\d+)\s*(.*)/); + if (match) { + code = parseInt(match[1], 10); + reason = match[2] || ''; + } else { + reason = data; + } + } + + const ev = new CloseEvent('close', { + code, + reason, + wasClean: code === 1000, + }); + this.dispatchEvent(ev); + if (this.onclose) this.onclose(ev); + break; + } + + case 'error': { + this._readyState = CLOSED; + _instances.delete(this._connId); + + const errorEv = new Event('error'); + this.dispatchEvent(errorEv); + if (this.onerror) this.onerror(errorEv); + + // Spec: error is always followed by close (code 1006 = abnormal closure) + const closeEv = new CloseEvent('close', { + code: 1006, + reason: typeof data === 'string' ? data : '', + wasClean: false, + }); + this.dispatchEvent(closeEv); + if (this.onclose) this.onclose(closeEv); + break; + } + } + } +} diff --git a/wasm/smolmix/internal-dev/package.json b/wasm/smolmix/internal-dev/package.json new file mode 100644 index 0000000000..65498313e9 --- /dev/null +++ b/wasm/smolmix/internal-dev/package.json @@ -0,0 +1,19 @@ +{ + "name": "smolmix-wasm-internal-dev", + "version": "0.0.1", + "private": true, + "scripts": { + "start": "webpack serve --open", + "build": "webpack --mode production" + }, + "dependencies": { + "comlink": "^4.3.1", + "smolmix-wasm": "file:../pkg" + }, + "devDependencies": { + "copy-webpack-plugin": "^11.0.0", + "webpack": "^5.98.0", + "webpack-cli": "^5.1.4", + "webpack-dev-server": "^5.2.1" + } +} diff --git a/wasm/smolmix/internal-dev/pnpm-lock.yaml b/wasm/smolmix/internal-dev/pnpm-lock.yaml new file mode 100644 index 0000000000..901ddbfd27 --- /dev/null +++ b/wasm/smolmix/internal-dev/pnpm-lock.yaml @@ -0,0 +1,3051 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + comlink: + specifier: ^4.3.1 + version: 4.4.2 + smolmix-wasm: + specifier: file:../pkg + version: '@nymproject/smolmix-wasm@file:../pkg' + devDependencies: + copy-webpack-plugin: + specifier: ^11.0.0 + version: 11.0.0(webpack@5.107.2) + webpack: + specifier: ^5.98.0 + version: 5.107.2(webpack-cli@5.1.4) + webpack-cli: + specifier: ^5.1.4 + version: 5.1.4(webpack-dev-server@5.2.4)(webpack@5.107.2) + webpack-dev-server: + specifier: ^5.2.1 + version: 5.2.4(tslib@2.8.1)(webpack-cli@5.1.4)(webpack@5.107.2) + +packages: + + '@discoveryjs/json-ext@0.5.7': + resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} + engines: {node: '>=10.0.0'} + + '@jridgewell/gen-mapping@0.3.13': + resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} + + '@jridgewell/resolve-uri@3.1.2': + resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==} + engines: {node: '>=6.0.0'} + + '@jridgewell/source-map@0.3.11': + resolution: {integrity: sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==} + + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + + '@jridgewell/trace-mapping@0.3.31': + resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + + '@jsonjoy.com/base64@1.1.2': + resolution: {integrity: sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/base64@17.67.0': + resolution: {integrity: sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/buffers@1.2.1': + resolution: {integrity: sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/buffers@17.67.0': + resolution: {integrity: sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/codegen@1.0.0': + resolution: {integrity: sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/codegen@17.67.0': + resolution: {integrity: sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-core@4.57.2': + resolution: {integrity: sha512-SVjwklkpIV5wrynpYtuYnfYH1QF4/nDuLBX7VXdb+3miglcAgBVZb/5y0cOsehRV/9Vb+3UqhkMq3/NR3ztdkQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-fsa@4.57.2': + resolution: {integrity: sha512-fhO8+iR2I+OCw668ISDJdn1aArc9zx033sWejIyzQ8RBeXa9bDSaUeA3ix0poYOfrj1KdOzytmYNv2/uLDfV6g==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-node-builtins@4.57.2': + resolution: {integrity: sha512-xhiegylRmhw43Ki2HO1ZBL7DQ5ja/qpRsL29VtQ2xuUHiuDGbgf2uD4p9Qd8hJI5P6RCtGYD50IXHXVq/Ocjcg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-node-to-fsa@4.57.2': + resolution: {integrity: sha512-18LmWTSONhoAPW+IWRuf8w/+zRolPFGPeGwMxlAhhfY11EKzX+5XHDBPAw67dBF5dxDErHJbl40U+3IXSDRXSQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-node-utils@4.57.2': + resolution: {integrity: sha512-rsPSJgekz43IlNbLyAM/Ab+ouYLWGp5DDBfYBNNEqDaSpsbXfthBn29Q4muFA9L0F+Z3mKo+CWlgSCXrf+mOyQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-node@4.57.2': + resolution: {integrity: sha512-nX2AdL6cOFwLdju9G4/nbRnYevmCJbh7N7hvR3gGm97Cs60uEjyd0rpR+YBS7cTg175zzl22pGKXR5USaQMvKg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-print@4.57.2': + resolution: {integrity: sha512-wK9NSow48i4DbDl9F1CQE5TqnyZOJ04elU3WFG5aJ76p+YxO/ulyBBQvKsessPxdo381Bc2pcEoyPujMOhcRqQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/fs-snapshot@4.57.2': + resolution: {integrity: sha512-GdduDZuoP5V/QCgJkx9+BZ6SC0EZ/smXAdTS7PfMqgMTGXLlt/bH/FqMYaqB9JmLf05sJPtO0XRbAwwkEEPbVw==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pack@1.21.0': + resolution: {integrity: sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pack@17.67.0': + resolution: {integrity: sha512-t0ejURcGaZsn1ClbJ/3kFqSOjlryd92eQY465IYrezsXmPcfHPE/av4twRSxf6WE+TkZgLY+71vCZbiIiFKA/w==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pointer@1.0.2': + resolution: {integrity: sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/json-pointer@17.67.0': + resolution: {integrity: sha512-+iqOFInH+QZGmSuaybBUNdh7yvNrXvqR+h3wjXm0N/3JK1EyyFAeGJvqnmQL61d1ARLlk/wJdFKSL+LHJ1eaUA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/util@1.9.0': + resolution: {integrity: sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@jsonjoy.com/util@17.67.0': + resolution: {integrity: sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + '@leichtgewicht/ip-codec@2.0.5': + resolution: {integrity: sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==} + + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + + '@nodelib/fs.scandir@2.1.5': + resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} + engines: {node: '>= 8'} + + '@nodelib/fs.stat@2.0.5': + resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} + engines: {node: '>= 8'} + + '@nodelib/fs.walk@1.2.8': + resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} + engines: {node: '>= 8'} + + '@nymproject/smolmix-wasm@file:../pkg': + resolution: {directory: ../pkg, type: directory} + + '@peculiar/asn1-cms@2.7.0': + resolution: {integrity: sha512-hew63shtzzvBcSHbhm+cyAmKe6AIfinT9hzEqSPjDC6opTTMKmTkQ0gHuN2KsWlvqiKw1S/fS94fhag/FJkioQ==} + + '@peculiar/asn1-csr@2.7.0': + resolution: {integrity: sha512-VVsAyGqErT9D1SY4aEqozThXMVI+ssVRiv2DDeYuvpBKLIgZ3hYs3Ay3u/VSoKq6ESFi9cf6rf3IOOzfwh7oMA==} + + '@peculiar/asn1-ecc@2.7.0': + resolution: {integrity: sha512-n7KEs/Q/wrB415cxy4fHOBhegp4NdJ15fkJPwcB/3/8iNBQC2L/N7SChJPKDJPZGYH0jD4Tg4/0vnHmwghnbKw==} + + '@peculiar/asn1-pfx@2.7.0': + resolution: {integrity: sha512-V/nrlQVmhg7lYAsM7E13UDL5erAwFv6kCIVFqNaMIHSVi7dngcT839JkRTkQBqznMG98l2XjxYk74ZztAohZzA==} + + '@peculiar/asn1-pkcs8@2.7.0': + resolution: {integrity: sha512-9GTl1nE8Mx1kTZ+7QyYatDyKsm34QcWRBFkY1iPvWC3X4Dona5s/tlLiQsx5WzVdZqiMBZNYT0buyw4/vbhnjw==} + + '@peculiar/asn1-pkcs9@2.7.0': + resolution: {integrity: sha512-Bh7m+OuIaSEllPQcSd9OSp93F4ROWH7sbITWV8MI+8dwsjE5111/87VxiWVvYFKyww3vp39geLv9ENqhwWHcew==} + + '@peculiar/asn1-rsa@2.7.0': + resolution: {integrity: sha512-/qvENQrXyTZURjMqSeofHul0JJt2sNSzSwk36pl2olkHbaioMQgrASDZAlHXl0xUlnVbHj0uGgOrBMTb5x2aJQ==} + + '@peculiar/asn1-schema@2.7.0': + resolution: {integrity: sha512-W8ZfWzLmQnrcky+eh3tni4IozMdqBDiHWU0N+vve/UGjMaUs8c0L7A2oEdkBXS8rTpWDpK/aoI3DG/L/hxmxPg==} + + '@peculiar/asn1-x509-attr@2.7.0': + resolution: {integrity: sha512-NS8e7SOgXipkzUPLF/sce7ukpMpWjhxYsH0n6Y+bHYo4TTxOb95Zv7hqwSuL212mj5YxovjdOKQOgH1As3E94w==} + + '@peculiar/asn1-x509@2.7.0': + resolution: {integrity: sha512-mUn9RRrkGDnG4ALfunDmzyRW5dg+sWCj/pfnCCqEHYbkGxEpvUt6iVJv8Yw1cyp6SWZ26ZE5oSmI5SqEaen15g==} + + '@peculiar/utils@2.0.3': + resolution: {integrity: sha512-+oL3HPFRIZ1St2K50lWCXiioIgSoxzz7R1J3uF6neO2yl1sgmpgY6XXJH4BdpoDkMWznQTeYF6oWNDZLCdQ4eQ==} + + '@peculiar/x509@1.14.3': + resolution: {integrity: sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA==} + engines: {node: '>=20.0.0'} + + '@types/body-parser@1.19.6': + resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} + + '@types/bonjour@3.5.13': + resolution: {integrity: sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==} + + '@types/connect-history-api-fallback@1.5.4': + resolution: {integrity: sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==} + + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + + '@types/express-serve-static-core@4.19.8': + resolution: {integrity: sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==} + + '@types/express@4.17.25': + resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==} + + '@types/http-errors@2.0.5': + resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} + + '@types/http-proxy@1.17.17': + resolution: {integrity: sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw==} + + '@types/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/mime@1.3.5': + resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + + '@types/node@25.9.1': + resolution: {integrity: sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==} + + '@types/qs@6.15.1': + resolution: {integrity: sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + + '@types/retry@0.12.2': + resolution: {integrity: sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==} + + '@types/send@0.17.6': + resolution: {integrity: sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==} + + '@types/send@1.2.1': + resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} + + '@types/serve-index@1.9.4': + resolution: {integrity: sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==} + + '@types/serve-static@1.15.10': + resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==} + + '@types/sockjs@0.3.36': + resolution: {integrity: sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==} + + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} + + '@webassemblyjs/ast@1.14.1': + resolution: {integrity: sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==} + + '@webassemblyjs/floating-point-hex-parser@1.13.2': + resolution: {integrity: sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==} + + '@webassemblyjs/helper-api-error@1.13.2': + resolution: {integrity: sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==} + + '@webassemblyjs/helper-buffer@1.14.1': + resolution: {integrity: sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==} + + '@webassemblyjs/helper-numbers@1.13.2': + resolution: {integrity: sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==} + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': + resolution: {integrity: sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==} + + '@webassemblyjs/helper-wasm-section@1.14.1': + resolution: {integrity: sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==} + + '@webassemblyjs/ieee754@1.13.2': + resolution: {integrity: sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==} + + '@webassemblyjs/leb128@1.13.2': + resolution: {integrity: sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==} + + '@webassemblyjs/utf8@1.13.2': + resolution: {integrity: sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==} + + '@webassemblyjs/wasm-edit@1.14.1': + resolution: {integrity: sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==} + + '@webassemblyjs/wasm-gen@1.14.1': + resolution: {integrity: sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==} + + '@webassemblyjs/wasm-opt@1.14.1': + resolution: {integrity: sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==} + + '@webassemblyjs/wasm-parser@1.14.1': + resolution: {integrity: sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==} + + '@webassemblyjs/wast-printer@1.14.1': + resolution: {integrity: sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==} + + '@webpack-cli/configtest@2.1.1': + resolution: {integrity: sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==} + engines: {node: '>=14.15.0'} + peerDependencies: + webpack: 5.x.x + webpack-cli: 5.x.x + + '@webpack-cli/info@2.0.2': + resolution: {integrity: sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==} + engines: {node: '>=14.15.0'} + peerDependencies: + webpack: 5.x.x + webpack-cli: 5.x.x + + '@webpack-cli/serve@2.0.5': + resolution: {integrity: sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==} + engines: {node: '>=14.15.0'} + peerDependencies: + webpack: 5.x.x + webpack-cli: 5.x.x + webpack-dev-server: '*' + peerDependenciesMeta: + webpack-dev-server: + optional: true + + '@xtuc/ieee754@1.2.0': + resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} + + '@xtuc/long@4.2.2': + resolution: {integrity: sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==} + + accepts@1.3.8: + resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} + engines: {node: '>= 0.6'} + + acorn-import-phases@1.0.4: + resolution: {integrity: sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==} + engines: {node: '>=10.13.0'} + peerDependencies: + acorn: ^8.14.0 + + acorn@8.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + ajv-formats@2.1.1: + resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv-keywords@5.1.0: + resolution: {integrity: sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==} + peerDependencies: + ajv: ^8.8.2 + + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} + + ansi-html-community@0.0.8: + resolution: {integrity: sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==} + engines: {'0': node >= 0.8.0} + hasBin: true + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + + asn1js@3.0.10: + resolution: {integrity: sha512-S2s3aOytiKdFRdulw2qPE51MzjzVOisppcVv7jVFR+Kw0kxwvFrDcYA0h7Ndqbmj0HkMIXYWaoj7fli8kgx1eg==} + engines: {node: '>=12.0.0'} + + baseline-browser-mapping@2.10.32: + resolution: {integrity: sha512-wbPvpyjJPC0zdfdKXxqEL3Ea+bOMD/87X4lftiJkkaBiuG6ALQy1SLmEd7BSmVCuwCQsBrCamgBoLyfFDD1EPg==} + engines: {node: '>=6.0.0'} + hasBin: true + + batch@0.6.1: + resolution: {integrity: sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==} + + binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + + body-parser@1.20.5: + resolution: {integrity: sha512-3grm+/2tUOvu2cjJkvsIxrv/wVpfXQW4PsQHYm7yk4vfpu7Ekl6nEsYBoJUL6qDwZUx8wUhQ8tR2qz+ad9c9OA==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + bonjour-service@1.4.0: + resolution: {integrity: sha512-fGQtj1qdR9vIKjFiWPQd52qIqwjaYqhcI40JEiDuvlZ86E7ZBPBwY9fPgHy9r2rYGIjiRfctNPYz6OQU73ww2w==} + + braces@3.0.3: + resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} + engines: {node: '>=8'} + + browserslist@4.28.2: + resolution: {integrity: sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==} + engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} + hasBin: true + + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + bytestreamjs@2.0.1: + resolution: {integrity: sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==} + engines: {node: '>=6.0.0'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + caniuse-lite@1.0.30001793: + resolution: {integrity: sha512-iwSsYWaCOoh26cV8NwNRViHlrfUvYsHDfRVcbtmw0Kg6PJIZZXwMkj1442FYLBGkeUf1juAsU3DTfxW579mrPA==} + + chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + + chrome-trace-event@1.0.4: + resolution: {integrity: sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==} + engines: {node: '>=6.0'} + + clone-deep@4.0.1: + resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} + engines: {node: '>=6'} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + comlink@4.4.2: + resolution: {integrity: sha512-OxGdvBmJuNKSCMO4NTl1L47VRp6xn2wG4F/2hYzB6tiCb709otOxtEYCSvK80PtjODfXXZu8ds+Nw5kVCjqd2g==} + + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + + commander@2.20.3: + resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} + + compressible@2.0.18: + resolution: {integrity: sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==} + engines: {node: '>= 0.6'} + + compression@1.8.1: + resolution: {integrity: sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==} + engines: {node: '>= 0.8.0'} + + connect-history-api-fallback@2.0.0: + resolution: {integrity: sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==} + engines: {node: '>=0.8'} + + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + cookie-signature@1.0.7: + resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + copy-webpack-plugin@11.0.0: + resolution: {integrity: sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==} + engines: {node: '>= 14.15.0'} + peerDependencies: + webpack: ^5.1.0 + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + debug@2.6.9: + resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + default-browser-id@5.0.1: + resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} + engines: {node: '>=18'} + + default-browser@5.5.0: + resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} + engines: {node: '>=18'} + + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + + depd@1.1.2: + resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} + engines: {node: '>= 0.6'} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + destroy@1.2.0: + resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} + engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + + detect-node@2.1.0: + resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} + + dir-glob@3.0.1: + resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} + engines: {node: '>=8'} + + dns-packet@5.6.1: + resolution: {integrity: sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==} + engines: {node: '>=6'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + electron-to-chromium@1.5.362: + resolution: {integrity: sha512-PUY2DrLvkjkUuWqq+KPL2iWshrJsZOcIojzRQ7eXFacc9dWga7MGMJAa15VbiejSZB1PAXaRLAiKgruHP8LB1w==} + + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + enhanced-resolve@5.22.0: + resolution: {integrity: sha512-xYcDWrpELkFzz9SpZ3PlI6Eu6eD93Yf0WLDRxikGhWJ3MAir2SNZTIVCVZqZ/NUyx8AdMc2gT9C0gPiw18kG+A==} + engines: {node: '>=10.13.0'} + + envinfo@7.21.0: + resolution: {integrity: sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==} + engines: {node: '>=4'} + hasBin: true + + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-module-lexer@2.1.0: + resolution: {integrity: sha512-n27zTYMjYu1aj4MjCWzSP7G9r75utsaoc8m61weK+W8JMBGGQybd43GstCXZ3WNmSFtGT9wi59qQTW6mhTR5LQ==} + + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} + engines: {node: '>= 0.4'} + + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + eslint-scope@5.1.1: + resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} + engines: {node: '>=8.0.0'} + + esrecurse@4.3.0: + resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} + engines: {node: '>=4.0'} + + estraverse@4.3.0: + resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} + engines: {node: '>=4.0'} + + estraverse@5.3.0: + resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} + engines: {node: '>=4.0'} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + eventemitter3@4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + + events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + + express@4.22.2: + resolution: {integrity: sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==} + engines: {node: '>= 0.10.0'} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + + fast-glob@3.3.3: + resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} + engines: {node: '>=8.6.0'} + + fast-uri@3.1.2: + resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==} + + fastest-levenshtein@1.0.16: + resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} + engines: {node: '>= 4.9.1'} + + fastq@1.20.1: + resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} + + faye-websocket@0.11.4: + resolution: {integrity: sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==} + engines: {node: '>=0.8.0'} + + fill-range@7.1.1: + resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} + engines: {node: '>=8'} + + finalhandler@1.3.2: + resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} + engines: {node: '>= 0.8'} + + find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + + flat@5.0.2: + resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} + hasBin: true + + follow-redirects@1.16.0: + resolution: {integrity: sha512-y5rN/uOsadFT/JfYwhxRS5R7Qce+g3zG97+JrtFZlC9klX/W5hD7iiLzScI4nZqUS7DNUdhPgw4xI8W2LuXlUw==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + + fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + + glob-to-regex.js@1.2.0: + resolution: {integrity: sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + glob-to-regexp@0.4.1: + resolution: {integrity: sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==} + + globby@13.2.2: + resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + graceful-fs@4.2.11: + resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + + handle-thing@2.0.1: + resolution: {integrity: sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==} + + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + hasown@2.0.3: + resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} + engines: {node: '>= 0.4'} + + hpack.js@2.1.6: + resolution: {integrity: sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==} + + http-deceiver@1.2.7: + resolution: {integrity: sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==} + + http-errors@1.8.1: + resolution: {integrity: sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==} + engines: {node: '>= 0.6'} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + http-parser-js@0.5.10: + resolution: {integrity: sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==} + + http-proxy-middleware@2.0.9: + resolution: {integrity: sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==} + engines: {node: '>=12.0.0'} + peerDependencies: + '@types/express': ^4.17.13 + peerDependenciesMeta: + '@types/express': + optional: true + + http-proxy@1.18.1: + resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} + engines: {node: '>=8.0.0'} + + hyperdyperid@1.2.0: + resolution: {integrity: sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==} + engines: {node: '>=10.18'} + + iconv-lite@0.4.24: + resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} + engines: {node: '>=0.10.0'} + + ignore@5.3.2: + resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} + engines: {node: '>= 4'} + + import-local@3.2.0: + resolution: {integrity: sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==} + engines: {node: '>=8'} + hasBin: true + + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + interpret@3.1.1: + resolution: {integrity: sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==} + engines: {node: '>=10.13.0'} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + ipaddr.js@2.4.0: + resolution: {integrity: sha512-9VGk3HGanVE6JoZXHiCpnGy5X0jYDnN4EA4lntFPj+1vIWlFhIylq2CrrCOJH9EAhc5CYhq18F2Av2tgoAPsYQ==} + engines: {node: '>= 10'} + + is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + + is-core-module@2.16.2: + resolution: {integrity: sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==} + engines: {node: '>= 0.4'} + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + + is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + + is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + + is-network-error@1.3.2: + resolution: {integrity: sha512-PhBY86zaxNZUuWP6h13Vu5oFe0XY6/UlKzQnYFELzGVHygP3MxmvTfYSG7GN3aIab/iWudSMgjSnG9Dq+nHrgA==} + engines: {node: '>=16'} + + is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + + is-plain-obj@3.0.0: + resolution: {integrity: sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==} + engines: {node: '>=10'} + + is-plain-object@2.0.4: + resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} + engines: {node: '>=0.10.0'} + + is-wsl@3.1.1: + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} + engines: {node: '>=16'} + + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isobject@3.0.1: + resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} + engines: {node: '>=0.10.0'} + + jest-worker@27.5.1: + resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} + engines: {node: '>= 10.13.0'} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + kind-of@6.0.3: + resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} + engines: {node: '>=0.10.0'} + + launch-editor@2.13.2: + resolution: {integrity: sha512-4VVDnbOpLXy/s8rdRCSXb+zfMeFR0WlJWpET1iA9CQdlZDfwyLjUuGQzXU4VeOoey6AicSAluWan7Etga6Kcmg==} + + loader-runner@4.3.2: + resolution: {integrity: sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w==} + engines: {node: '>=6.11.5'} + + locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + media-typer@0.3.0: + resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} + engines: {node: '>= 0.6'} + + memfs@4.57.2: + resolution: {integrity: sha512-2nWzSsJzrukurSDna4Z0WywuScK4Id3tSKejgu74u8KCdW4uNrseKRSIDg75C6Yw5ZRqBe0F0EtMNlTbUq8bAQ==} + peerDependencies: + tslib: '2' + + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + + merge2@1.4.1: + resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} + engines: {node: '>= 8'} + + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + + micromatch@4.0.8: + resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} + engines: {node: '>=8.6'} + + mime-db@1.52.0: + resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} + engines: {node: '>= 0.6'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@2.1.35: + resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} + engines: {node: '>= 0.6'} + + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + + minimalistic-assert@1.0.1: + resolution: {integrity: sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==} + + ms@2.0.0: + resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + multicast-dns@7.2.5: + resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} + hasBin: true + + negotiator@0.6.3: + resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} + engines: {node: '>= 0.6'} + + negotiator@0.6.4: + resolution: {integrity: sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==} + engines: {node: '>= 0.6'} + + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + + node-releases@2.0.46: + resolution: {integrity: sha512-GYVXHE2KnrzAfsAjl4uP++evGFCrAU1jta4ubEjIG7YWt/64Gqv66a30yKwWczVjA6j3bM4nBwH7Pk1JmDHaxQ==} + engines: {node: '>=18'} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + obuf@1.1.2: + resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + on-headers@1.1.0: + resolution: {integrity: sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==} + engines: {node: '>= 0.8'} + + open@10.2.0: + resolution: {integrity: sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==} + engines: {node: '>=18'} + + p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + + p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + + p-retry@6.2.1: + resolution: {integrity: sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==} + engines: {node: '>=16.17'} + + p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + + path-to-regexp@0.1.13: + resolution: {integrity: sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==} + + path-type@4.0.0: + resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} + engines: {node: '>=8'} + + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + + pkg-dir@4.2.0: + resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} + engines: {node: '>=8'} + + pkijs@3.4.0: + resolution: {integrity: sha512-emEcLuomt2j03vxD54giVB4SxTjnsqkU692xZOZXHDVoYyypEm+b3jpiTcc+Cf+myooc+/Ly0z01jqeNHVgJGw==} + engines: {node: '>=16.0.0'} + + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + pvtsutils@1.3.6: + resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} + + pvutils@1.1.5: + resolution: {integrity: sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==} + engines: {node: '>=16.0.0'} + + qs@6.15.2: + resolution: {integrity: sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==} + engines: {node: '>=0.6'} + + queue-microtask@1.2.3: + resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + + randombytes@2.1.0: + resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + + range-parser@1.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + engines: {node: '>= 0.6'} + + raw-body@2.5.3: + resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} + engines: {node: '>= 0.8'} + + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + + readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + + readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} + + rechoir@0.8.0: + resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==} + engines: {node: '>= 10.13.0'} + + reflect-metadata@0.2.2: + resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + requires-port@1.0.0: + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} + + resolve-cwd@3.0.0: + resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} + engines: {node: '>=8'} + + resolve-from@5.0.0: + resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} + engines: {node: '>=8'} + + resolve@1.22.12: + resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} + engines: {node: '>= 0.4'} + hasBin: true + + retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + + reusify@1.1.0: + resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} + engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + + run-parallel@1.2.0: + resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + + safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + + safer-buffer@2.1.2: + resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + + schema-utils@4.3.3: + resolution: {integrity: sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==} + engines: {node: '>= 10.13.0'} + + select-hose@2.0.0: + resolution: {integrity: sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==} + + selfsigned@5.5.0: + resolution: {integrity: sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew==} + engines: {node: '>=18'} + + send@0.19.2: + resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} + engines: {node: '>= 0.8.0'} + + serialize-javascript@6.0.2: + resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} + + serve-index@1.9.2: + resolution: {integrity: sha512-KDj11HScOaLmrPxl70KYNW1PksP4Nb/CLL2yvC+Qd2kHMPEEpfc4Re2e4FOay+bC/+XQl/7zAcWON3JVo5v3KQ==} + engines: {node: '>= 0.8.0'} + + serve-static@1.16.3: + resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} + engines: {node: '>= 0.8.0'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + + shallow-clone@3.0.1: + resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} + engines: {node: '>=8'} + + shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} + + shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} + + shell-quote@1.8.4: + resolution: {integrity: sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ==} + engines: {node: '>= 0.4'} + + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + engines: {node: '>= 0.4'} + + slash@4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + + sockjs@0.3.24: + resolution: {integrity: sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==} + + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + + source-map@0.6.1: + resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} + engines: {node: '>=0.10.0'} + + spdy-transport@3.0.0: + resolution: {integrity: sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==} + + spdy@4.0.2: + resolution: {integrity: sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==} + engines: {node: '>=6.0.0'} + + statuses@1.5.0: + resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} + engines: {node: '>= 0.6'} + + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + + string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tapable@2.3.3: + resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} + engines: {node: '>=6'} + + terser-webpack-plugin@5.6.0: + resolution: {integrity: sha512-Eum+5ajkaOhf5KbM26osvv21kLD7BaGqQ1UA4Ami4arYwylmGUQTgHFpHDdmJod1q4QXa66p0to/FBKID+J1vA==} + engines: {node: '>= 10.13.0'} + peerDependencies: + '@minify-html/node': '*' + '@swc/core': '*' + '@swc/css': '*' + '@swc/html': '*' + clean-css: '*' + cssnano: '*' + csso: '*' + esbuild: '*' + html-minifier-terser: '*' + lightningcss: '*' + postcss: '*' + uglify-js: '*' + webpack: ^5.1.0 + peerDependenciesMeta: + '@minify-html/node': + optional: true + '@swc/core': + optional: true + '@swc/css': + optional: true + '@swc/html': + optional: true + clean-css: + optional: true + cssnano: + optional: true + csso: + optional: true + esbuild: + optional: true + html-minifier-terser: + optional: true + lightningcss: + optional: true + postcss: + optional: true + uglify-js: + optional: true + + terser@5.48.0: + resolution: {integrity: sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q==} + engines: {node: '>=10'} + hasBin: true + + thingies@2.6.0: + resolution: {integrity: sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg==} + engines: {node: '>=10.18'} + peerDependencies: + tslib: ^2 + + thunky@1.1.0: + resolution: {integrity: sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==} + + to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} + + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + tree-dump@1.1.0: + resolution: {integrity: sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==} + engines: {node: '>=10.0'} + peerDependencies: + tslib: '2' + + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + + tslib@2.8.1: + resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + + tsyringe@4.10.0: + resolution: {integrity: sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==} + engines: {node: '>= 6.0.0'} + + type-is@1.6.18: + resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} + engines: {node: '>= 0.6'} + + undici-types@7.24.6: + resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + update-browserslist-db@1.2.3: + resolution: {integrity: sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==} + hasBin: true + peerDependencies: + browserslist: '>= 4.21.0' + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + utils-merge@1.0.1: + resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} + engines: {node: '>= 0.4.0'} + + uuid@8.3.2: + resolution: {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). + hasBin: true + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + watchpack@2.5.1: + resolution: {integrity: sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==} + engines: {node: '>=10.13.0'} + + wbuf@1.7.3: + resolution: {integrity: sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==} + + webpack-cli@5.1.4: + resolution: {integrity: sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==} + engines: {node: '>=14.15.0'} + hasBin: true + peerDependencies: + '@webpack-cli/generators': '*' + webpack: 5.x.x + webpack-bundle-analyzer: '*' + webpack-dev-server: '*' + peerDependenciesMeta: + '@webpack-cli/generators': + optional: true + webpack-bundle-analyzer: + optional: true + webpack-dev-server: + optional: true + + webpack-dev-middleware@7.4.5: + resolution: {integrity: sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA==} + engines: {node: '>= 18.12.0'} + peerDependencies: + webpack: ^5.0.0 + peerDependenciesMeta: + webpack: + optional: true + + webpack-dev-server@5.2.4: + resolution: {integrity: sha512-GqDPGZN9bRqKBTkp4aWkobDDHMsrXKoGSdOH56smIri8qR0JG8gfL8/v/f/OZR3/OKXjG8uwJbFVhKm/FNU/UA==} + engines: {node: '>= 18.12.0'} + hasBin: true + peerDependencies: + webpack: ^5.0.0 + webpack-cli: '*' + peerDependenciesMeta: + webpack: + optional: true + webpack-cli: + optional: true + + webpack-merge@5.10.0: + resolution: {integrity: sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==} + engines: {node: '>=10.0.0'} + + webpack-sources@3.5.0: + resolution: {integrity: sha512-HPuy+uuoTCaaoEoI1LQ3JN9+vrPBvEesnnX1jADHy728cHSMlq4wUc4afYqahq2B1mhQVZxCXOkNTnXltr+2vQ==} + engines: {node: '>=10.13.0'} + + webpack@5.107.2: + resolution: {integrity: sha512-v7RhXaJbpMlV0D7hC7lb2EbnxkoeUqf9qhKr6lozx3Q48pmFrqqNRmZFUEGmi7pSwm6fCQ2H1IjvCkHqdpVdjQ==} + engines: {node: '>=10.13.0'} + hasBin: true + peerDependencies: + webpack-cli: '*' + peerDependenciesMeta: + webpack-cli: + optional: true + + websocket-driver@0.7.4: + resolution: {integrity: sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==} + engines: {node: '>=0.8.0'} + + websocket-extensions@0.1.4: + resolution: {integrity: sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==} + engines: {node: '>=0.8.0'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wildcard@2.0.1: + resolution: {integrity: sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==} + + ws@8.21.0: + resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} + 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@0.1.0: + resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} + engines: {node: '>=18'} + +snapshots: + + '@discoveryjs/json-ext@0.5.7': {} + + '@jridgewell/gen-mapping@0.3.13': + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/resolve-uri@3.1.2': {} + + '@jridgewell/source-map@0.3.11': + dependencies: + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + + '@jridgewell/sourcemap-codec@1.5.5': {} + + '@jridgewell/trace-mapping@0.3.31': + dependencies: + '@jridgewell/resolve-uri': 3.1.2 + '@jridgewell/sourcemap-codec': 1.5.5 + + '@jsonjoy.com/base64@1.1.2(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/base64@17.67.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/buffers@1.2.1(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/buffers@17.67.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/codegen@1.0.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/codegen@17.67.0(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/fs-core@4.57.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-fsa@4.57.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-core': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-node-builtins@4.57.2(tslib@2.8.1)': + dependencies: + tslib: 2.8.1 + + '@jsonjoy.com/fs-node-to-fsa@4.57.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-fsa': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-node-utils@4.57.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-node@4.57.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-core': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.57.2(tslib@2.8.1) + glob-to-regex.js: 1.2.0(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-print@4.57.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/fs-snapshot@4.57.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/json-pack': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pack@1.21.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/base64': 1.1.2(tslib@2.8.1) + '@jsonjoy.com/buffers': 1.2.1(tslib@2.8.1) + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + '@jsonjoy.com/json-pointer': 1.0.2(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + hyperdyperid: 1.2.0 + thingies: 2.6.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pack@17.67.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/base64': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/codegen': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/json-pointer': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) + hyperdyperid: 1.2.0 + thingies: 2.6.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pointer@1.0.2(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/json-pointer@17.67.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/util': 17.67.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/util@1.9.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/buffers': 1.2.1(tslib@2.8.1) + '@jsonjoy.com/codegen': 1.0.0(tslib@2.8.1) + tslib: 2.8.1 + + '@jsonjoy.com/util@17.67.0(tslib@2.8.1)': + dependencies: + '@jsonjoy.com/buffers': 17.67.0(tslib@2.8.1) + '@jsonjoy.com/codegen': 17.67.0(tslib@2.8.1) + tslib: 2.8.1 + + '@leichtgewicht/ip-codec@2.0.5': {} + + '@noble/hashes@1.4.0': {} + + '@nodelib/fs.scandir@2.1.5': + dependencies: + '@nodelib/fs.stat': 2.0.5 + run-parallel: 1.2.0 + + '@nodelib/fs.stat@2.0.5': {} + + '@nodelib/fs.walk@1.2.8': + dependencies: + '@nodelib/fs.scandir': 2.1.5 + fastq: 1.20.1 + + '@nymproject/smolmix-wasm@file:../pkg': {} + + '@peculiar/asn1-cms@2.7.0': + dependencies: + '@peculiar/asn1-schema': 2.7.0 + '@peculiar/asn1-x509': 2.7.0 + '@peculiar/asn1-x509-attr': 2.7.0 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/asn1-csr@2.7.0': + dependencies: + '@peculiar/asn1-schema': 2.7.0 + '@peculiar/asn1-x509': 2.7.0 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/asn1-ecc@2.7.0': + dependencies: + '@peculiar/asn1-schema': 2.7.0 + '@peculiar/asn1-x509': 2.7.0 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/asn1-pfx@2.7.0': + dependencies: + '@peculiar/asn1-cms': 2.7.0 + '@peculiar/asn1-pkcs8': 2.7.0 + '@peculiar/asn1-rsa': 2.7.0 + '@peculiar/asn1-schema': 2.7.0 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/asn1-pkcs8@2.7.0': + dependencies: + '@peculiar/asn1-schema': 2.7.0 + '@peculiar/asn1-x509': 2.7.0 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/asn1-pkcs9@2.7.0': + dependencies: + '@peculiar/asn1-cms': 2.7.0 + '@peculiar/asn1-pfx': 2.7.0 + '@peculiar/asn1-pkcs8': 2.7.0 + '@peculiar/asn1-schema': 2.7.0 + '@peculiar/asn1-x509': 2.7.0 + '@peculiar/asn1-x509-attr': 2.7.0 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/asn1-rsa@2.7.0': + dependencies: + '@peculiar/asn1-schema': 2.7.0 + '@peculiar/asn1-x509': 2.7.0 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/asn1-schema@2.7.0': + dependencies: + '@peculiar/utils': 2.0.3 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/asn1-x509-attr@2.7.0': + dependencies: + '@peculiar/asn1-schema': 2.7.0 + '@peculiar/asn1-x509': 2.7.0 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/asn1-x509@2.7.0': + dependencies: + '@peculiar/asn1-schema': 2.7.0 + '@peculiar/utils': 2.0.3 + asn1js: 3.0.10 + tslib: 2.8.1 + + '@peculiar/utils@2.0.3': + dependencies: + tslib: 2.8.1 + + '@peculiar/x509@1.14.3': + dependencies: + '@peculiar/asn1-cms': 2.7.0 + '@peculiar/asn1-csr': 2.7.0 + '@peculiar/asn1-ecc': 2.7.0 + '@peculiar/asn1-pkcs9': 2.7.0 + '@peculiar/asn1-rsa': 2.7.0 + '@peculiar/asn1-schema': 2.7.0 + '@peculiar/asn1-x509': 2.7.0 + pvtsutils: 1.3.6 + reflect-metadata: 0.2.2 + tslib: 2.8.1 + tsyringe: 4.10.0 + + '@types/body-parser@1.19.6': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 25.9.1 + + '@types/bonjour@3.5.13': + dependencies: + '@types/node': 25.9.1 + + '@types/connect-history-api-fallback@1.5.4': + dependencies: + '@types/express-serve-static-core': 4.19.8 + '@types/node': 25.9.1 + + '@types/connect@3.4.38': + dependencies: + '@types/node': 25.9.1 + + '@types/estree@1.0.9': {} + + '@types/express-serve-static-core@4.19.8': + dependencies: + '@types/node': 25.9.1 + '@types/qs': 6.15.1 + '@types/range-parser': 1.2.7 + '@types/send': 1.2.1 + + '@types/express@4.17.25': + dependencies: + '@types/body-parser': 1.19.6 + '@types/express-serve-static-core': 4.19.8 + '@types/qs': 6.15.1 + '@types/serve-static': 1.15.10 + + '@types/http-errors@2.0.5': {} + + '@types/http-proxy@1.17.17': + dependencies: + '@types/node': 25.9.1 + + '@types/json-schema@7.0.15': {} + + '@types/mime@1.3.5': {} + + '@types/node@25.9.1': + dependencies: + undici-types: 7.24.6 + + '@types/qs@6.15.1': {} + + '@types/range-parser@1.2.7': {} + + '@types/retry@0.12.2': {} + + '@types/send@0.17.6': + dependencies: + '@types/mime': 1.3.5 + '@types/node': 25.9.1 + + '@types/send@1.2.1': + dependencies: + '@types/node': 25.9.1 + + '@types/serve-index@1.9.4': + dependencies: + '@types/express': 4.17.25 + + '@types/serve-static@1.15.10': + dependencies: + '@types/http-errors': 2.0.5 + '@types/node': 25.9.1 + '@types/send': 0.17.6 + + '@types/sockjs@0.3.36': + dependencies: + '@types/node': 25.9.1 + + '@types/ws@8.18.1': + dependencies: + '@types/node': 25.9.1 + + '@webassemblyjs/ast@1.14.1': + dependencies: + '@webassemblyjs/helper-numbers': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + + '@webassemblyjs/floating-point-hex-parser@1.13.2': {} + + '@webassemblyjs/helper-api-error@1.13.2': {} + + '@webassemblyjs/helper-buffer@1.14.1': {} + + '@webassemblyjs/helper-numbers@1.13.2': + dependencies: + '@webassemblyjs/floating-point-hex-parser': 1.13.2 + '@webassemblyjs/helper-api-error': 1.13.2 + '@xtuc/long': 4.2.2 + + '@webassemblyjs/helper-wasm-bytecode@1.13.2': {} + + '@webassemblyjs/helper-wasm-section@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/wasm-gen': 1.14.1 + + '@webassemblyjs/ieee754@1.13.2': + dependencies: + '@xtuc/ieee754': 1.2.0 + + '@webassemblyjs/leb128@1.13.2': + dependencies: + '@xtuc/long': 4.2.2 + + '@webassemblyjs/utf8@1.13.2': {} + + '@webassemblyjs/wasm-edit@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-buffer': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/helper-wasm-section': 1.14.1 + '@webassemblyjs/wasm-gen': 1.14.1 + '@webassemblyjs/wasm-opt': 1.14.1 + '@webassemblyjs/wasm-parser': 1.14.1 + '@webassemblyjs/wast-printer': 1.14.1 + + '@webassemblyjs/wasm-gen@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wasm-opt@1.14.1': + dependencies: + '@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@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@webassemblyjs/helper-api-error': 1.13.2 + '@webassemblyjs/helper-wasm-bytecode': 1.13.2 + '@webassemblyjs/ieee754': 1.13.2 + '@webassemblyjs/leb128': 1.13.2 + '@webassemblyjs/utf8': 1.13.2 + + '@webassemblyjs/wast-printer@1.14.1': + dependencies: + '@webassemblyjs/ast': 1.14.1 + '@xtuc/long': 4.2.2 + + '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.107.2)': + dependencies: + webpack: 5.107.2(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack-dev-server@5.2.4)(webpack@5.107.2) + + '@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.107.2)': + dependencies: + webpack: 5.107.2(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack-dev-server@5.2.4)(webpack@5.107.2) + + '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack-dev-server@5.2.4)(webpack@5.107.2)': + dependencies: + webpack: 5.107.2(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack-dev-server@5.2.4)(webpack@5.107.2) + optionalDependencies: + webpack-dev-server: 5.2.4(tslib@2.8.1)(webpack-cli@5.1.4)(webpack@5.107.2) + + '@xtuc/ieee754@1.2.0': {} + + '@xtuc/long@4.2.2': {} + + accepts@1.3.8: + dependencies: + mime-types: 2.1.35 + negotiator: 0.6.3 + + acorn-import-phases@1.0.4(acorn@8.16.0): + dependencies: + acorn: 8.16.0 + + acorn@8.16.0: {} + + ajv-formats@2.1.1(ajv@8.20.0): + optionalDependencies: + ajv: 8.20.0 + + ajv-keywords@5.1.0(ajv@8.20.0): + dependencies: + ajv: 8.20.0 + fast-deep-equal: 3.1.3 + + ajv@8.20.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.2 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + ansi-html-community@0.0.8: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.2 + + array-flatten@1.1.1: {} + + asn1js@3.0.10: + dependencies: + pvtsutils: 1.3.6 + pvutils: 1.1.5 + tslib: 2.8.1 + + baseline-browser-mapping@2.10.32: {} + + batch@0.6.1: {} + + binary-extensions@2.3.0: {} + + body-parser@1.20.5: + 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.2 + raw-body: 2.5.3 + type-is: 1.6.18 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + bonjour-service@1.4.0: + dependencies: + fast-deep-equal: 3.1.3 + multicast-dns: 7.2.5 + + braces@3.0.3: + dependencies: + fill-range: 7.1.1 + + browserslist@4.28.2: + dependencies: + baseline-browser-mapping: 2.10.32 + caniuse-lite: 1.0.30001793 + electron-to-chromium: 1.5.362 + node-releases: 2.0.46 + update-browserslist-db: 1.2.3(browserslist@4.28.2) + + buffer-from@1.1.2: {} + + bundle-name@4.1.0: + dependencies: + run-applescript: 7.1.0 + + bytes@3.1.2: {} + + bytestreamjs@2.0.1: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + caniuse-lite@1.0.30001793: {} + + chokidar@3.6.0: + dependencies: + anymatch: 3.1.3 + braces: 3.0.3 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + + chrome-trace-event@1.0.4: {} + + clone-deep@4.0.1: + dependencies: + is-plain-object: 2.0.4 + kind-of: 6.0.3 + shallow-clone: 3.0.1 + + colorette@2.0.20: {} + + comlink@4.4.2: {} + + commander@10.0.1: {} + + commander@2.20.3: {} + + compressible@2.0.18: + dependencies: + mime-db: 1.54.0 + + compression@1.8.1: + dependencies: + 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 + transitivePeerDependencies: + - supports-color + + connect-history-api-fallback@2.0.0: {} + + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + + content-type@1.0.5: {} + + cookie-signature@1.0.7: {} + + cookie@0.7.2: {} + + copy-webpack-plugin@11.0.0(webpack@5.107.2): + dependencies: + fast-glob: 3.3.3 + glob-parent: 6.0.2 + globby: 13.2.2 + normalize-path: 3.0.0 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + webpack: 5.107.2(webpack-cli@5.1.4) + + core-util-is@1.0.3: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + debug@2.6.9: + dependencies: + ms: 2.0.0 + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + default-browser-id@5.0.1: {} + + default-browser@5.5.0: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.1 + + define-lazy-prop@3.0.0: {} + + depd@1.1.2: {} + + depd@2.0.0: {} + + destroy@1.2.0: {} + + detect-node@2.1.0: {} + + dir-glob@3.0.1: + dependencies: + path-type: 4.0.0 + + dns-packet@5.6.1: + dependencies: + '@leichtgewicht/ip-codec': 2.0.5 + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + ee-first@1.1.1: {} + + electron-to-chromium@1.5.362: {} + + encodeurl@2.0.0: {} + + enhanced-resolve@5.22.0: + dependencies: + graceful-fs: 4.2.11 + tapable: 2.3.3 + + envinfo@7.21.0: {} + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-module-lexer@2.1.0: {} + + es-object-atoms@1.1.2: + dependencies: + es-errors: 1.3.0 + + escalade@3.2.0: {} + + escape-html@1.0.3: {} + + eslint-scope@5.1.1: + dependencies: + esrecurse: 4.3.0 + estraverse: 4.3.0 + + esrecurse@4.3.0: + dependencies: + estraverse: 5.3.0 + + estraverse@4.3.0: {} + + estraverse@5.3.0: {} + + etag@1.8.1: {} + + eventemitter3@4.0.7: {} + + events@3.3.0: {} + + express@4.22.2: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.5 + content-disposition: 0.5.4 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.0.7 + debug: 2.6.9 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 1.3.2 + fresh: 0.5.2 + http-errors: 2.0.1 + merge-descriptors: 1.0.3 + methods: 1.1.2 + on-finished: 2.4.1 + parseurl: 1.3.3 + path-to-regexp: 0.1.13 + proxy-addr: 2.0.7 + qs: 6.15.2 + range-parser: 1.2.1 + safe-buffer: 5.2.1 + send: 0.19.2 + serve-static: 1.16.3 + setprototypeof: 1.2.0 + statuses: 2.0.2 + type-is: 1.6.18 + utils-merge: 1.0.1 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + fast-deep-equal@3.1.3: {} + + fast-glob@3.3.3: + dependencies: + '@nodelib/fs.stat': 2.0.5 + '@nodelib/fs.walk': 1.2.8 + glob-parent: 5.1.2 + merge2: 1.4.1 + micromatch: 4.0.8 + + fast-uri@3.1.2: {} + + fastest-levenshtein@1.0.16: {} + + fastq@1.20.1: + dependencies: + reusify: 1.1.0 + + faye-websocket@0.11.4: + dependencies: + websocket-driver: 0.7.4 + + fill-range@7.1.1: + dependencies: + to-regex-range: 5.0.1 + + finalhandler@1.3.2: + dependencies: + debug: 2.6.9 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + + find-up@4.1.0: + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + + flat@5.0.2: {} + + follow-redirects@1.16.0: {} + + forwarded@0.2.0: {} + + fresh@0.5.2: {} + + fsevents@2.3.3: + optional: true + + function-bind@1.1.2: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.3 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.2 + + glob-parent@5.1.2: + dependencies: + is-glob: 4.0.3 + + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + + glob-to-regex.js@1.2.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + + glob-to-regexp@0.4.1: {} + + globby@13.2.2: + dependencies: + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 4.0.0 + + gopd@1.2.0: {} + + graceful-fs@4.2.11: {} + + handle-thing@2.0.1: {} + + has-flag@4.0.0: {} + + has-symbols@1.1.0: {} + + hasown@2.0.3: + dependencies: + function-bind: 1.1.2 + + hpack.js@2.1.6: + dependencies: + inherits: 2.0.4 + obuf: 1.1.2 + readable-stream: 2.3.8 + wbuf: 1.7.3 + + http-deceiver@1.2.7: {} + + http-errors@1.8.1: + dependencies: + depd: 1.1.2 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 1.5.0 + toidentifier: 1.0.1 + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + + http-parser-js@0.5.10: {} + + http-proxy-middleware@2.0.9(@types/express@4.17.25): + dependencies: + '@types/http-proxy': 1.17.17 + http-proxy: 1.18.1 + is-glob: 4.0.3 + is-plain-obj: 3.0.0 + micromatch: 4.0.8 + optionalDependencies: + '@types/express': 4.17.25 + transitivePeerDependencies: + - debug + + http-proxy@1.18.1: + dependencies: + eventemitter3: 4.0.7 + follow-redirects: 1.16.0 + requires-port: 1.0.0 + transitivePeerDependencies: + - debug + + hyperdyperid@1.2.0: {} + + iconv-lite@0.4.24: + dependencies: + safer-buffer: 2.1.2 + + ignore@5.3.2: {} + + import-local@3.2.0: + dependencies: + pkg-dir: 4.2.0 + resolve-cwd: 3.0.0 + + inherits@2.0.4: {} + + interpret@3.1.1: {} + + ipaddr.js@1.9.1: {} + + ipaddr.js@2.4.0: {} + + is-binary-path@2.1.0: + dependencies: + binary-extensions: 2.3.0 + + is-core-module@2.16.2: + dependencies: + hasown: 2.0.3 + + is-docker@3.0.0: {} + + is-extglob@2.1.1: {} + + is-glob@4.0.3: + dependencies: + is-extglob: 2.1.1 + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + + is-network-error@1.3.2: {} + + is-number@7.0.0: {} + + is-plain-obj@3.0.0: {} + + is-plain-object@2.0.4: + dependencies: + isobject: 3.0.1 + + is-wsl@3.1.1: + dependencies: + is-inside-container: 1.0.0 + + isarray@1.0.0: {} + + isexe@2.0.0: {} + + isobject@3.0.1: {} + + jest-worker@27.5.1: + dependencies: + '@types/node': 25.9.1 + merge-stream: 2.0.0 + supports-color: 8.1.1 + + json-schema-traverse@1.0.0: {} + + kind-of@6.0.3: {} + + launch-editor@2.13.2: + dependencies: + picocolors: 1.1.1 + shell-quote: 1.8.4 + + loader-runner@4.3.2: {} + + locate-path@5.0.0: + dependencies: + p-locate: 4.1.0 + + math-intrinsics@1.1.0: {} + + media-typer@0.3.0: {} + + memfs@4.57.2(tslib@2.8.1): + dependencies: + '@jsonjoy.com/fs-core': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-fsa': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-builtins': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-to-fsa': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-node-utils': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-print': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/fs-snapshot': 4.57.2(tslib@2.8.1) + '@jsonjoy.com/json-pack': 1.21.0(tslib@2.8.1) + '@jsonjoy.com/util': 1.9.0(tslib@2.8.1) + glob-to-regex.js: 1.2.0(tslib@2.8.1) + thingies: 2.6.0(tslib@2.8.1) + tree-dump: 1.1.0(tslib@2.8.1) + tslib: 2.8.1 + + merge-descriptors@1.0.3: {} + + merge-stream@2.0.0: {} + + merge2@1.4.1: {} + + methods@1.1.2: {} + + micromatch@4.0.8: + dependencies: + braces: 3.0.3 + picomatch: 2.3.2 + + mime-db@1.52.0: {} + + mime-db@1.54.0: {} + + mime-types@2.1.35: + dependencies: + mime-db: 1.52.0 + + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + + mime@1.6.0: {} + + minimalistic-assert@1.0.1: {} + + ms@2.0.0: {} + + ms@2.1.3: {} + + multicast-dns@7.2.5: + dependencies: + dns-packet: 5.6.1 + thunky: 1.1.0 + + negotiator@0.6.3: {} + + negotiator@0.6.4: {} + + neo-async@2.6.2: {} + + node-releases@2.0.46: {} + + normalize-path@3.0.0: {} + + object-inspect@1.13.4: {} + + obuf@1.1.2: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + on-headers@1.1.0: {} + + open@10.2.0: + dependencies: + default-browser: 5.5.0 + define-lazy-prop: 3.0.0 + is-inside-container: 1.0.0 + wsl-utils: 0.1.0 + + p-limit@2.3.0: + dependencies: + p-try: 2.2.0 + + p-locate@4.1.0: + dependencies: + p-limit: 2.3.0 + + p-retry@6.2.1: + dependencies: + '@types/retry': 0.12.2 + is-network-error: 1.3.2 + retry: 0.13.1 + + p-try@2.2.0: {} + + parseurl@1.3.3: {} + + path-exists@4.0.0: {} + + path-key@3.1.1: {} + + path-parse@1.0.7: {} + + path-to-regexp@0.1.13: {} + + path-type@4.0.0: {} + + picocolors@1.1.1: {} + + picomatch@2.3.2: {} + + pkg-dir@4.2.0: + dependencies: + find-up: 4.1.0 + + pkijs@3.4.0: + dependencies: + '@noble/hashes': 1.4.0 + asn1js: 3.0.10 + bytestreamjs: 2.0.1 + pvtsutils: 1.3.6 + pvutils: 1.1.5 + tslib: 2.8.1 + + process-nextick-args@2.0.1: {} + + proxy-addr@2.0.7: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + pvtsutils@1.3.6: + dependencies: + tslib: 2.8.1 + + pvutils@1.1.5: {} + + qs@6.15.2: + dependencies: + side-channel: 1.1.0 + + queue-microtask@1.2.3: {} + + randombytes@2.1.0: + dependencies: + safe-buffer: 5.2.1 + + range-parser@1.2.1: {} + + raw-body@2.5.3: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + + readable-stream@3.6.2: + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 + + readdirp@3.6.0: + dependencies: + picomatch: 2.3.2 + + rechoir@0.8.0: + dependencies: + resolve: 1.22.12 + + reflect-metadata@0.2.2: {} + + require-from-string@2.0.2: {} + + requires-port@1.0.0: {} + + resolve-cwd@3.0.0: + dependencies: + resolve-from: 5.0.0 + + resolve-from@5.0.0: {} + + resolve@1.22.12: + dependencies: + es-errors: 1.3.0 + is-core-module: 2.16.2 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + retry@0.13.1: {} + + reusify@1.1.0: {} + + run-applescript@7.1.0: {} + + run-parallel@1.2.0: + dependencies: + queue-microtask: 1.2.3 + + safe-buffer@5.1.2: {} + + safe-buffer@5.2.1: {} + + safer-buffer@2.1.2: {} + + schema-utils@4.3.3: + dependencies: + '@types/json-schema': 7.0.15 + ajv: 8.20.0 + ajv-formats: 2.1.1(ajv@8.20.0) + ajv-keywords: 5.1.0(ajv@8.20.0) + + select-hose@2.0.0: {} + + selfsigned@5.5.0: + dependencies: + '@peculiar/x509': 1.14.3 + pkijs: 3.4.0 + + send@0.19.2: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.1 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serialize-javascript@6.0.2: + dependencies: + randombytes: 2.1.0 + + serve-index@1.9.2: + dependencies: + accepts: 1.3.8 + batch: 0.6.1 + debug: 2.6.9 + escape-html: 1.0.3 + http-errors: 1.8.1 + mime-types: 2.1.35 + parseurl: 1.3.3 + transitivePeerDependencies: + - supports-color + + serve-static@1.16.3: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.2 + transitivePeerDependencies: + - supports-color + + setprototypeof@1.2.0: {} + + shallow-clone@3.0.1: + dependencies: + kind-of: 6.0.3 + + shebang-command@2.0.0: + dependencies: + shebang-regex: 3.0.0 + + shebang-regex@3.0.0: {} + + shell-quote@1.8.4: {} + + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.0: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + + slash@4.0.0: {} + + sockjs@0.3.24: + dependencies: + faye-websocket: 0.11.4 + uuid: 8.3.2 + websocket-driver: 0.7.4 + + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + + source-map@0.6.1: {} + + spdy-transport@3.0.0: + dependencies: + debug: 4.4.3 + detect-node: 2.1.0 + hpack.js: 2.1.6 + obuf: 1.1.2 + readable-stream: 3.6.2 + wbuf: 1.7.3 + transitivePeerDependencies: + - supports-color + + spdy@4.0.2: + dependencies: + debug: 4.4.3 + handle-thing: 2.0.1 + http-deceiver: 1.2.7 + select-hose: 2.0.0 + spdy-transport: 3.0.0 + transitivePeerDependencies: + - supports-color + + statuses@1.5.0: {} + + statuses@2.0.2: {} + + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + supports-color@8.1.1: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + tapable@2.3.3: {} + + terser-webpack-plugin@5.6.0(webpack@5.107.2): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + terser: 5.48.0 + webpack: 5.107.2(webpack-cli@5.1.4) + + terser@5.48.0: + dependencies: + '@jridgewell/source-map': 0.3.11 + acorn: 8.16.0 + commander: 2.20.3 + source-map-support: 0.5.21 + + thingies@2.6.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + + thunky@1.1.0: {} + + to-regex-range@5.0.1: + dependencies: + is-number: 7.0.0 + + toidentifier@1.0.1: {} + + tree-dump@1.1.0(tslib@2.8.1): + dependencies: + tslib: 2.8.1 + + tslib@1.14.1: {} + + tslib@2.8.1: {} + + tsyringe@4.10.0: + dependencies: + tslib: 1.14.1 + + type-is@1.6.18: + dependencies: + media-typer: 0.3.0 + mime-types: 2.1.35 + + undici-types@7.24.6: {} + + unpipe@1.0.0: {} + + update-browserslist-db@1.2.3(browserslist@4.28.2): + dependencies: + browserslist: 4.28.2 + escalade: 3.2.0 + picocolors: 1.1.1 + + util-deprecate@1.0.2: {} + + utils-merge@1.0.1: {} + + uuid@8.3.2: {} + + vary@1.1.2: {} + + watchpack@2.5.1: + dependencies: + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + + wbuf@1.7.3: + dependencies: + minimalistic-assert: 1.0.1 + + webpack-cli@5.1.4(webpack-dev-server@5.2.4)(webpack@5.107.2): + dependencies: + '@discoveryjs/json-ext': 0.5.7 + '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4)(webpack@5.107.2) + '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4)(webpack@5.107.2) + '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4)(webpack-dev-server@5.2.4)(webpack@5.107.2) + colorette: 2.0.20 + commander: 10.0.1 + cross-spawn: 7.0.6 + envinfo: 7.21.0 + fastest-levenshtein: 1.0.16 + import-local: 3.2.0 + interpret: 3.1.1 + rechoir: 0.8.0 + webpack: 5.107.2(webpack-cli@5.1.4) + webpack-merge: 5.10.0 + optionalDependencies: + webpack-dev-server: 5.2.4(tslib@2.8.1)(webpack-cli@5.1.4)(webpack@5.107.2) + + webpack-dev-middleware@7.4.5(tslib@2.8.1)(webpack@5.107.2): + dependencies: + colorette: 2.0.20 + memfs: 4.57.2(tslib@2.8.1) + mime-types: 3.0.2 + on-finished: 2.4.1 + range-parser: 1.2.1 + schema-utils: 4.3.3 + optionalDependencies: + webpack: 5.107.2(webpack-cli@5.1.4) + transitivePeerDependencies: + - tslib + + webpack-dev-server@5.2.4(tslib@2.8.1)(webpack-cli@5.1.4)(webpack@5.107.2): + dependencies: + '@types/bonjour': 3.5.13 + '@types/connect-history-api-fallback': 1.5.4 + '@types/express': 4.17.25 + '@types/express-serve-static-core': 4.19.8 + '@types/serve-index': 1.9.4 + '@types/serve-static': 1.15.10 + '@types/sockjs': 0.3.36 + '@types/ws': 8.18.1 + ansi-html-community: 0.0.8 + bonjour-service: 1.4.0 + chokidar: 3.6.0 + colorette: 2.0.20 + compression: 1.8.1 + connect-history-api-fallback: 2.0.0 + express: 4.22.2 + graceful-fs: 4.2.11 + http-proxy-middleware: 2.0.9(@types/express@4.17.25) + ipaddr.js: 2.4.0 + launch-editor: 2.13.2 + open: 10.2.0 + p-retry: 6.2.1 + schema-utils: 4.3.3 + selfsigned: 5.5.0 + serve-index: 1.9.2 + sockjs: 0.3.24 + spdy: 4.0.2 + webpack-dev-middleware: 7.4.5(tslib@2.8.1)(webpack@5.107.2) + ws: 8.21.0 + optionalDependencies: + webpack: 5.107.2(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack-dev-server@5.2.4)(webpack@5.107.2) + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - tslib + - utf-8-validate + + webpack-merge@5.10.0: + dependencies: + clone-deep: 4.0.1 + flat: 5.0.2 + wildcard: 2.0.1 + + webpack-sources@3.5.0: {} + + webpack@5.107.2(webpack-cli@5.1.4): + dependencies: + '@types/estree': 1.0.9 + '@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.16.0 + acorn-import-phases: 1.0.4(acorn@8.16.0) + browserslist: 4.28.2 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.22.0 + es-module-lexer: 2.1.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + loader-runner: 4.3.2 + mime-db: 1.54.0 + neo-async: 2.6.2 + schema-utils: 4.3.3 + tapable: 2.3.3 + terser-webpack-plugin: 5.6.0(webpack@5.107.2) + watchpack: 2.5.1 + webpack-sources: 3.5.0 + optionalDependencies: + webpack-cli: 5.1.4(webpack-dev-server@5.2.4)(webpack@5.107.2) + transitivePeerDependencies: + - '@minify-html/node' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - esbuild + - html-minifier-terser + - lightningcss + - postcss + - uglify-js + + websocket-driver@0.7.4: + dependencies: + http-parser-js: 0.5.10 + safe-buffer: 5.2.1 + websocket-extensions: 0.1.4 + + websocket-extensions@0.1.4: {} + + which@2.0.2: + dependencies: + isexe: 2.0.0 + + wildcard@2.0.1: {} + + ws@8.21.0: {} + + wsl-utils@0.1.0: + dependencies: + is-wsl: 3.1.1 diff --git a/wasm/smolmix/internal-dev/webpack.config.js b/wasm/smolmix/internal-dev/webpack.config.js new file mode 100644 index 0000000000..f7552c5091 --- /dev/null +++ b/wasm/smolmix/internal-dev/webpack.config.js @@ -0,0 +1,35 @@ +const path = require('path'); +const CopyPlugin = require('copy-webpack-plugin'); + +module.exports = { + entry: { + bundle: './bootstrap.js', + headless: './headless-bootstrap.js', + }, + output: { + path: path.resolve(__dirname, 'dist'), + filename: '[name].js', + }, + plugins: [ + new CopyPlugin({ + patterns: [ + { from: 'index.html', to: '.' }, + { from: 'headless.html', to: '.' }, + { from: '../pkg/smolmix_wasm_bg.wasm', to: '.' }, + ], + }), + ], + experiments: { + asyncWebAssembly: true, + }, + devServer: { + static: { directory: path.resolve(__dirname, 'dist') }, + port: 9000, + // Required for SharedArrayBuffer (if ever needed) and secure context: + headers: { + 'Cross-Origin-Opener-Policy': 'same-origin', + 'Cross-Origin-Embedder-Policy': 'require-corp', + }, + }, + mode: 'development', +}; diff --git a/wasm/smolmix/internal-dev/worker.js b/wasm/smolmix/internal-dev/worker.js new file mode 100644 index 0000000000..e3f5a673aa --- /dev/null +++ b/wasm/smolmix/internal-dev/worker.js @@ -0,0 +1,156 @@ +// smolmix-wasm Web Worker +// +// Loads the WASM module in a dedicated thread. All mixnet I/O +// (smoltcp polling, TLS crypto, DNS resolution, mixnet messaging) +// runs here, keeping the main thread responsive for UI rendering. +// +// Two communication channels: +// 1. Comlink — request/response for fetch (setupMixTunnel, mixFetch, disconnect) +// 2. Raw postMessage — bidirectional events for WebSocket (ws-connect, ws-send, ws-close) +// +// Comlink ignores messages without its internal UUID markers, +// so both channels coexist on the same Worker without conflicts. + +import initWasm, { + setupMixTunnel as wasmSetup, + mixFetch as wasmFetch, + mixResolve as wasmResolve, + disconnectMixTunnel as wasmDisconnect, + mixSocket as wasmMixSocket, + wsSend as wasmWsSend, + wsClose as wasmWsClose, + setDebugLogging as wasmSetDebugLogging, +} from "smolmix-wasm"; +import * as Comlink from "comlink"; + +let wasmReady = false; + +// Comlink API (fetch) + +const api = { + async setupMixTunnel(opts) { + if (!wasmReady) { + await initWasm(); + wasmReady = true; + } + await wasmSetup(opts); + }, + + async mixFetch(url, init) { + if (!wasmReady) { + throw new Error("WASM not initialised; call setupMixTunnel first"); + } + return await wasmFetch(url, init || {}); + }, + + async mixResolve(hostname) { + if (!wasmReady) { + throw new Error("WASM not initialised; call setupMixTunnel first"); + } + return await wasmResolve(hostname); + }, + + async disconnectMixTunnel() { + if (!wasmReady) { + throw new Error("WASM not initialised; call setupMixTunnel first"); + } + await wasmDisconnect(); + }, + + async setDebugLogging(enabled) { + if (!wasmReady) { + await initWasm(); + wasmReady = true; + } + wasmSetDebugLogging(enabled); + }, +}; + +Comlink.expose(api); + +// Raw postMessage API (WebSocket) + +// Maps main-thread connId → WASM handleId +const wsConnMap = new Map(); + +self.addEventListener("message", async (event) => { + const msg = event.data; + if (!msg || typeof msg.kind !== "string") return; + + switch (msg.kind) { + case "ws-connect": { + if (!wasmReady) { + self.postMessage({ + kind: "ws-event", + connId: msg.connId, + type: "error", + data: "WASM not initialised — call setupMixTunnel first", + }); + return; + } + + // WASM callback: fires for open/text/binary/close/error events. + // Captures connId so all events route to the correct MixSocket instance. + const onEvent = (handleId, type, data) => { + if (!wsConnMap.has(msg.connId)) { + wsConnMap.set(msg.connId, handleId); + } + self.postMessage({ kind: "ws-event", connId: msg.connId, type, data }); + }; + + try { + await wasmMixSocket(msg.url, msg.protocols, onEvent); + } catch (e) { + console.error("[ws] connect failed:", e); + self.postMessage({ + kind: "ws-event", + connId: msg.connId, + type: "error", + data: String(e), + }); + } + break; + } + + case "ws-send": { + const handleId = wsConnMap.get(msg.connId); + if (handleId == null) { + console.warn(`[ws] send for connId ${msg.connId} before connection ready`); + return; + } + try { + wasmWsSend(handleId, msg.payload); + } catch (e) { + self.postMessage({ + kind: "ws-event", + connId: msg.connId, + type: "error", + data: String(e), + }); + } + break; + } + + case "ws-close": { + const handleId = wsConnMap.get(msg.connId); + if (handleId == null) { + console.warn(`[ws] close for connId ${msg.connId} before connection ready`); + return; + } + try { + wasmWsClose(handleId, msg.code || 1000, msg.reason || ""); + } catch (e) { + self.postMessage({ + kind: "ws-event", + connId: msg.connId, + type: "error", + data: String(e), + }); + } + wsConnMap.delete(msg.connId); + break; + } + } +}); + +self.postMessage({ kind: "Loaded" }); diff --git a/wasm/smolmix/src/bridge.rs b/wasm/smolmix/src/bridge.rs new file mode 100644 index 0000000000..6b89796a96 --- /dev/null +++ b/wasm/smolmix/src/bridge.rs @@ -0,0 +1,153 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +//! Packet bridge between the smoltcp device and the Nym mixnet. +//! +//! Two concurrent loops in one `spawn_local` task: +//! +//! **Outgoing** (smoltcp → mixnet): on each tick, drain the device tx queue +//! and send each IP packet to the IPR as an LP-framed DataRequest. +//! +//! **Incoming** (mixnet → smoltcp): receive `ReconstructedMessage` batches, +//! LP-decode, parse IPR responses, unbundle IP packets, push to device rx. + +use std::sync::Arc; +use std::time::Duration; + +use futures::{FutureExt, StreamExt}; +use nym_wasm_client_core::Recipient; +use nym_wasm_client_core::client::base_client::ClientInput; +use nym_wasm_client_core::nym_task::ShutdownTracker; + +use crate::ipr::{self, ReconstructedReceiver}; +use crate::reactor::{ReactorNotify, SmoltcpStack}; +use crate::state::{State, TaskName}; + +/// Maximum outgoing packets sent per bridge tick. +/// +/// Limits how long the bridge spends in the serial send loop before +/// returning to check for incoming messages. Remaining packets are +/// picked up on the next tick. +const MAX_OUTGOING_PER_TICK: usize = 8; + +/// Start the bridge as a `spawn_local` background task. +/// +/// Each iteration: +/// 1. Wait for an event (incoming message OR timer tick) +/// 2. Drain all pending incoming messages (non-blocking) +/// 3. Drain outgoing packets (capped at `MAX_OUTGOING_PER_TICK`) +/// +/// Incoming is processed first to prevent starvation; the timer can +/// dominate `select!` if always ready. +#[allow(clippy::too_many_arguments)] +pub fn start_bridge( + stack: SmoltcpStack, + client_input: Arc, + mut msg_receiver: ReconstructedReceiver, + ipr_address: Recipient, + stream_id: u64, + notify_reactor: ReactorNotify, + tracker: &ShutdownTracker, + state: State, + data_surbs: u32, +) { + // Cloned so finalise_task can check is_cancelled() on the way out. + let token = tracker.clone_shutdown_token(); + tracker.try_spawn_named_with_shutdown( + async move { + let mut tx_interval = wasmtimer::tokio::interval(Duration::from_millis(5)); + // Outbound seq starts at 1; seq=0 is reserved for handshake + // frames (see `ipr::open_and_connect`). + let mut seq: u32 = 1; + + loop { + // Block until something happens (incoming message or timer tick). + // `futures::select!` polls pseudo-randomly when both branches are + // ready, so textual order is not a priority guarantee. + // TODO: consider `futures::select_biased!` if a sustained timer + // burst ever shows up as incoming-side latency. + futures::select! { + batch = msg_receiver.next().fuse() => { + let Some(messages) = batch else { + crate::util::debug_error!( + "[bridge] message channel closed" + ); + break; + }; + process_incoming( + &stack, &messages, stream_id, ¬ify_reactor, + ); + } + _ = tx_interval.tick().fuse() => {} + } + + // Non-blockingly drain any remaining incoming messages so we + // never let them queue up while we're sending outgoing packets. + while let Some(Some(messages)) = msg_receiver.next().now_or_never() { + process_incoming(&stack, &messages, stream_id, ¬ify_reactor); + } + + // Drain outgoing packets (capped to avoid starving incoming). + let packets: Vec> = + stack.with(|s| s.device.drain_tx().take(MAX_OUTGOING_PER_TICK).collect()); + + if !packets.is_empty() { + crate::util::debug_log!("[bridge] ▲ tx ({} packets)", packets.len()); + } + for packet in packets { + let current_seq = seq; + // Skip 0 on wrap: it's reserved for handshake frames + // (see `ipr::open_and_connect`). + seq = if seq == u32::MAX { 1 } else { seq + 1 }; + if let Err(e) = ipr::send_ip_packet( + &client_input, + &ipr_address, + stream_id, + current_seq, + &packet, + data_surbs, + ) + .await + { + crate::util::debug_error!("[bridge] send error: {e}"); + } + } + } + + state.finalise_task(TaskName::Bridge, &token); + }, + "smolmix-bridge", + ); +} + +/// Process a batch of incoming mixnet messages: LP-decode, parse IPR +/// responses, push IP packets to the device rx queue, notify reactor. +fn process_incoming( + stack: &SmoltcpStack, + messages: &[nym_wasm_client_core::ReconstructedMessage], + stream_id: u64, + notify_reactor: &ReactorNotify, +) { + let mut pushed = 0usize; + for msg in messages { + match ipr::parse_incoming(msg, stream_id) { + Ok(Some(packets)) => { + stack.with(|s| { + for packet in &packets { + s.device.push_rx(packet.clone()); + pushed += 1; + } + }); + } + Ok(None) => {} + Err(e) => { + crate::util::debug_error!("[bridge] incoming error: {e}"); + } + } + } + + if pushed > 0 { + crate::util::debug_log!("[bridge] ▼ rx ({pushed} packets)"); + notify_reactor.notify_one(); + } +} diff --git a/wasm/smolmix/src/device.rs b/wasm/smolmix/src/device.rs new file mode 100644 index 0000000000..ea8dfc80ca --- /dev/null +++ b/wasm/smolmix/src/device.rs @@ -0,0 +1,162 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +//! smoltcp `Device` implementation backed by in-memory VecDeque buffers. +//! +//! The native smolmix uses `NymAsyncDevice` (Stream/Sink over mpsc channels) fed +//! into `tokio-smoltcp`. On wasm32 we drive smoltcp directly, so we need a sync +//! `Device` impl instead. The bridge pushes incoming IP packets into `rx_queue` +//! and pops outgoing packets from `tx_queue`. + +use std::collections::VecDeque; + +use smoltcp::phy::{Device, DeviceCapabilities, Medium, RxToken, TxToken}; +use smoltcp::time::Instant; + +/// smoltcp device backed by in-memory packet queues. +/// +/// The bridge task feeds incoming IP packets via [`push_rx`](Self::push_rx) and +/// drains outgoing packets via [`drain_tx`](Self::drain_tx). The reactor calls +/// smoltcp's `Interface::poll()` which invokes the `Device` trait methods. +pub struct WasmDevice { + rx_queue: VecDeque>, + tx_queue: VecDeque>, + capabilities: DeviceCapabilities, +} + +impl WasmDevice { + pub fn new() -> Self { + let mut capabilities = DeviceCapabilities::default(); + capabilities.medium = Medium::Ip; + // Sized so one IP packet fits in one sphinx packet payload (no + // chunking-layer fragmentation). Budget in bytes from the 2048 B + // sphinx plaintext: − 344 (SURB-ack) − 32 (x25519 ephemeral key, + // Repliable msgs) − 7 (frag header) − 1 (padding) − 53 (LP+IPR + // framing + AEAD) ≈ 1611. 1600 leaves ~11 B headroom for IPR + // overhead variability. + capabilities.max_transmission_unit = 1600; + // Native smolmix also uses Some(1) in the device, but tokio-smoltcp + // compensates with a burst loop that calls Interface::poll() up to 100 + // times per reactor iteration (each processing 1 packet). Our WASM + // reactor only calls poll() once per tick, so we set a higher burst + // size to let smoltcp drain all pending packets in a single poll(). + capabilities.max_burst_size = Some(100); + + Self { + rx_queue: VecDeque::new(), + tx_queue: VecDeque::new(), + capabilities, + } + } + + /// Push an incoming IP packet (from the mixnet) into the receive queue. + pub fn push_rx(&mut self, packet: Vec) { + self.rx_queue.push_back(packet); + } + + /// Drain all outgoing IP packets (generated by smoltcp) from the transmit queue. + pub fn drain_tx(&mut self) -> impl Iterator> + '_ { + self.tx_queue.drain(..) + } +} + +impl Device for WasmDevice { + type RxToken<'a> = WasmRxToken; + type TxToken<'a> = WasmTxToken<'a>; + + fn receive(&mut self, _timestamp: Instant) -> Option<(Self::RxToken<'_>, Self::TxToken<'_>)> { + let packet = self.rx_queue.pop_front()?; + Some(( + WasmRxToken { buffer: packet }, + WasmTxToken { + queue: &mut self.tx_queue, + }, + )) + } + + fn transmit(&mut self, _timestamp: Instant) -> Option> { + Some(WasmTxToken { + queue: &mut self.tx_queue, + }) + } + + fn capabilities(&self) -> DeviceCapabilities { + self.capabilities.clone() + } +} + +/// Receive token: delivers one packet from the rx queue to smoltcp. +pub struct WasmRxToken { + buffer: Vec, +} + +impl RxToken for WasmRxToken { + fn consume(self, f: F) -> R + where + F: FnOnce(&[u8]) -> R, + { + f(&self.buffer) + } +} + +/// Transmit token: captures one packet from smoltcp into the tx queue. +pub struct WasmTxToken<'a> { + queue: &'a mut VecDeque>, +} + +impl<'a> TxToken for WasmTxToken<'a> { + fn consume(self, len: usize, f: F) -> R + where + F: FnOnce(&mut [u8]) -> R, + { + let mut buffer = vec![0u8; len]; + let result = f(&mut buffer); + self.queue.push_back(buffer); + result + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn push_rx_and_receive() { + let mut dev = WasmDevice::new(); + dev.push_rx(vec![1, 2, 3]); + + let now = Instant::from_millis(0); + let (rx, _tx) = dev.receive(now).expect("should have a packet"); + let data = rx.consume(|buf| buf.to_vec()); + assert_eq!(data, vec![1, 2, 3]); + } + + #[test] + fn transmit_and_drain() { + let mut dev = WasmDevice::new(); + let now = Instant::from_millis(0); + + let tx = dev.transmit(now).expect("should get tx token"); + tx.consume(4, |buf| { + buf.copy_from_slice(&[0xDE, 0xAD, 0xBE, 0xEF]); + }); + + let packets: Vec<_> = dev.drain_tx().collect(); + assert_eq!(packets.len(), 1); + assert_eq!(packets[0], vec![0xDE, 0xAD, 0xBE, 0xEF]); + } + + #[test] + fn empty_receive_returns_none() { + let mut dev = WasmDevice::new(); + assert!(dev.receive(Instant::from_millis(0)).is_none()); + } + + #[test] + fn capabilities_are_ip_mode() { + let dev = WasmDevice::new(); + let caps = dev.capabilities(); + assert_eq!(caps.medium, Medium::Ip); + assert_eq!(caps.max_transmission_unit, 1980); + } +} diff --git a/wasm/smolmix/src/dns.rs b/wasm/smolmix/src/dns.rs new file mode 100644 index 0000000000..bb13b17999 --- /dev/null +++ b/wasm/smolmix/src/dns.rs @@ -0,0 +1,210 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +//! DNS A/AAAA resolution over the tunnel's UDP socket. Defaults are 8.8.8.8 +//! primary with 1.1.1.1 fallback, overridable via `TunnelOpts::primary_dns` +//! / `fallback_dns`. Wire format via `hickory-proto`; results cached per session. + +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; +use std::time::Duration; + +use hickory_proto::op::{Message, Query}; +use hickory_proto::rr::{Name, RData, RecordType}; + +use crate::error::FetchError; +use crate::stream::WasmUdpSocket; +use crate::tunnel::WasmTunnel; + +/// Maximum number of CNAME hops before giving up. +const MAX_CNAME_HOPS: usize = 8; + +pub const DEFAULT_PRIMARY_DNS: SocketAddr = + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(8, 8, 8, 8)), 53); +pub const DEFAULT_FALLBACK_DNS: SocketAddr = + SocketAddr::new(IpAddr::V4(Ipv4Addr::new(1, 1, 1, 1)), 53); + +/// Resolve a hostname to an IP through the mixnet tunnel. +pub async fn resolve(tunnel: &WasmTunnel, hostname: &str) -> Result { + if let Ok(ip) = hostname.parse::() { + return Ok(ip); + } + + // Serialise DNS lookups so concurrent callers coalesce on the cache. + let _guard = tunnel.dns_lock().lock().await; + + if let Some(&ip) = tunnel.dns_cache().lock().unwrap().get(hostname) { + crate::util::debug_log!("[dns] cache hit: '{hostname}' => {ip}"); + return Ok(ip); + } + + crate::util::debug_log!("[dns] resolving '{hostname}'..."); + let udp = tunnel.udp_socket().await.map_err(FetchError::Io)?; + + let timeout = tunnel.dns_timeout(); + let ip = match resolve_with(&udp, hostname, tunnel.dns_primary(), timeout).await { + Ok(ip) => ip, + Err(_) => resolve_with(&udp, hostname, tunnel.dns_fallback(), timeout).await?, + }; + + crate::util::debug_log!("[dns] resolved '{hostname}' => {ip}"); + tunnel + .dns_cache() + .lock() + .unwrap() + .insert(hostname.to_string(), ip); + Ok(ip) +} + +/// Try A then AAAA against a specific DNS server, following CNAME chains. +async fn resolve_with( + udp: &WasmUdpSocket, + hostname: &str, + server: SocketAddr, + timeout: Duration, +) -> Result { + match query_following_cnames(udp, hostname, RecordType::A, server, timeout).await { + Ok(ip) => Ok(ip), + Err(_) => query_following_cnames(udp, hostname, RecordType::AAAA, server, timeout).await, + } +} + +/// Send a DNS query and follow any CNAME chain until we get an IP or exhaust hops. +async fn query_following_cnames( + udp: &WasmUdpSocket, + hostname: &str, + record_type: RecordType, + server: SocketAddr, + timeout: Duration, +) -> Result { + let mut current_name = hostname.to_string(); + + for _ in 0..MAX_CNAME_HOPS { + match query_record(udp, ¤t_name, record_type, server, timeout).await? { + DnsResult::Ip(ip) => return Ok(ip), + DnsResult::Cname(target) => current_name = target, + } + } + + Err(FetchError::Dns(format!( + "CNAME chain too long (>{MAX_CNAME_HOPS} hops) for {hostname}" + ))) +} + +enum DnsResult { + Ip(IpAddr), + Cname(String), +} + +/// Send a single DNS query and parse the response. +/// +/// The `WasmUdpSocket` is shared across PRIMARY → FALLBACK, A → AAAA, and +/// every CNAME hop in one resolve, so leftover datagrams from a prior query +/// can be sitting in the receive buffer. We loop on `recv_from`, dropping +/// any datagram whose transaction ID doesn't match the query we just sent, +/// until either a match arrives or `timeout` elapses. +async fn query_record( + udp: &WasmUdpSocket, + hostname: &str, + record_type: RecordType, + server: SocketAddr, + timeout: Duration, +) -> Result { + let (query_bytes, query_id) = build_query(hostname, record_type)?; + udp.send_to(&query_bytes, server) + .await + .map_err(FetchError::Io)?; + crate::util::debug_log!("[dns] query sent to {server} (id={query_id:#06x}), waiting..."); + + let start = wasmtimer::std::Instant::now(); + + loop { + let remaining = timeout + .checked_sub(start.elapsed()) + .ok_or(FetchError::Timeout)?; + + let mut buf = [0u8; 512]; + let (len, src) = wasmtimer::tokio::timeout(remaining, udp.recv_from(&mut buf)) + .await + .map_err(|_| { + crate::util::debug_error!("[dns] recv_from TIMED OUT after {timeout:?}"); + FetchError::Timeout + })? + .map_err(FetchError::Io)?; + + // Anti-spoof layer 1: source address must match the server we queried. + // The UDP socket is reused across CNAME hops and primary/fallback + // retries, so a late reply from an earlier `server` is a real case, + // not just hypothetical. + if src != server { + crate::util::debug_log!( + "[dns] dropped datagram from unexpected source {src} (expected {server})" + ); + continue; + } + + // Anti-spoof layer 2: parse failures and ID mismatches are also + // "keep reading," not "abort the lookup." A single malformed packet + // from `server` (or an attacker who can spoof the source) shouldn't + // turn a live query into a hard failure. + let response = match Message::from_vec(&buf[..len]) { + Ok(r) => r, + Err(e) => { + crate::util::debug_log!("[dns] dropped malformed datagram from {src}: {e}"); + continue; + } + }; + + // Anti-spoof layer 3: transaction ID must match. The id was filled + // from `rand::random()` (CSPRNG via `getrandom`/js), so the guess + // rate for an off-path attacker is the theoretical 1/65536 per try. + if response.id != query_id { + crate::util::debug_log!( + "[dns] dropped stale datagram (id={:#06x}, expected {query_id:#06x})", + response.id, + ); + continue; + } + + return parse_response(&response, hostname); + } +} + +/// Build a DNS query and return its bytes plus transaction ID. +fn build_query(hostname: &str, record_type: RecordType) -> Result<(Vec, u16), FetchError> { + let mut msg = Message::query(); + msg.metadata.recursion_desired = true; + let id = msg.metadata.id; + + let name = Name::from_ascii(hostname) + .map_err(|e| FetchError::Dns(format!("invalid hostname '{hostname}': {e}")))?; + msg.add_query(Query::query(name, record_type)); + + let bytes = msg + .to_vec() + .map_err(|e| FetchError::Dns(format!("failed to serialise DNS query: {e}")))?; + Ok((bytes, id)) +} + +/// Parse a DNS response message, returning an IP or CNAME target. +fn parse_response(msg: &Message, hostname: &str) -> Result { + let mut cname_target: Option = None; + + for record in &msg.answers { + match &record.data { + RData::A(a) => return Ok(DnsResult::Ip(IpAddr::V4(a.0))), + RData::AAAA(aaaa) => return Ok(DnsResult::Ip(IpAddr::V6(aaaa.0))), + RData::CNAME(cname) if cname_target.is_none() => { + cname_target = Some(cname.0.to_string()); + } + _ => {} + } + } + + if let Some(target) = cname_target { + return Ok(DnsResult::Cname(target)); + } + + Err(FetchError::Dns(format!( + "no A, AAAA, or CNAME records for {hostname}" + ))) +} diff --git a/wasm/smolmix/src/error.rs b/wasm/smolmix/src/error.rs new file mode 100644 index 0000000000..045535832e --- /dev/null +++ b/wasm/smolmix/src/error.rs @@ -0,0 +1,42 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use nym_wasm_utils::wasm_error; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum FetchError { + #[error("URL error: {0}")] + Url(#[from] url::ParseError), + + #[error("DNS error: {0}")] + Dns(String), + + #[error("IO error: {0}")] + Io(#[from] std::io::Error), + + #[cfg(feature = "fetch")] + #[error("hyper error: {0}")] + Hyper(#[from] hyper::Error), + + #[error("HTTP error: {0}")] + Http(String), + + #[cfg(feature = "socket")] + #[error("WebSocket error: {0}")] + WebSocket(#[from] async_tungstenite::tungstenite::Error), + + #[error("JS interop error: {0}")] + Js(String), + + #[error("tunnel error: {0}")] + Tunnel(String), + + #[error("tunnel not connected")] + NotConnected, + + #[error("operation timed out")] + Timeout, +} + +wasm_error!(FetchError); diff --git a/wasm/smolmix/src/fetch.rs b/wasm/smolmix/src/fetch.rs new file mode 100644 index 0000000000..05f93d4e85 --- /dev/null +++ b/wasm/smolmix/src/fetch.rs @@ -0,0 +1,372 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +//! TCP/TLS connection construction shared by `mixFetch` and `mixSocket`, +//! plus (under the `fetch` feature) the HTTP orchestration + JS `RequestInit` shim. + +use std::net::SocketAddr; + +use crate::dns; +use crate::error::FetchError; +use crate::stream::PooledConn; +use crate::tls; +use crate::tunnel::WasmTunnel; + +// HTTP-orchestration imports: only needed when the `fetch` feature is on. +#[cfg(feature = "fetch")] +use crate::http::{self, HttpResponse}; +#[cfg(feature = "fetch")] +use js_sys::{Array, Object, Reflect, Uint8Array}; +#[cfg(feature = "fetch")] +use url::Url; +#[cfg(feature = "fetch")] +use wasm_bindgen::JsCast; +#[cfg(feature = "fetch")] +use wasm_bindgen::JsValue; + +/// Options extracted from a JS `RequestInit` object. +#[cfg(feature = "fetch")] +struct FetchInit { + method: String, + headers: Vec<(String, String)>, + body: Option>, +} + +/// Execute a fetch request through the mixnet tunnel. +#[cfg(feature = "fetch")] +pub async fn fetch( + tunnel: &WasmTunnel, + url_str: &str, + init: &JsValue, +) -> Result { + let mut opts = parse_init(init)?; + let mut url = Url::parse(url_str)?; + if !is_http_scheme(&url) { + return Err(FetchError::Http(format!( + "unsupported scheme '{}' (expected http or https)", + url.scheme() + ))); + } + let mut method = opts.method.clone(); + let mut body = opts.body.clone(); + let max_redirects = tunnel.max_redirects(); + + for redirect_count in 0..=max_redirects { + let host = url + .host_str() + .ok_or_else(|| FetchError::Http("URL has no host".into()))? + .to_string(); + let port = url + .port_or_known_default() + .ok_or_else(|| FetchError::Http("URL has no port and scheme is unknown".into()))?; + let is_https = url.scheme() == "https"; + + if redirect_count == 0 { + crate::util::debug_log!("[fetch] {} {} ({})", method, url.as_str(), url.scheme()); + } else { + crate::util::debug_log!( + "[fetch] redirect #{redirect_count} → {host}:{port} ({})", + url.scheme() + ); + } + + // Per-origin lock: serialise TCP+TLS handshake, release before HTTP. + let (conn, from_pool) = { + let origin_lock = tunnel.origin_lock(&host, port); + crate::util::debug_log!("[fetch] acquiring origin lock for {host}:{port}..."); + let _guard = origin_lock.lock().await; + crate::util::debug_log!("[fetch] origin lock ACQUIRED for {host}:{port}"); + + let result = match tunnel.take_pooled(&host, port) { + Some(c) => { + crate::util::debug_log!("[fetch] pool HIT for {host}:{port}"); + (c, true) + } + None => { + crate::util::debug_log!("[fetch] pool MISS for {host}:{port}, new connection"); + (new_connection(tunnel, &host, port, is_https).await?, false) + } + }; + + crate::util::debug_log!("[fetch] origin lock RELEASED for {host}:{port}"); + result + }; + + // Retry pooled connections once on first-write error; fresh-conn + // errors propagate. We only retry idempotent methods because hyper + // can fail mid-body-write, and we have no reliable way to tell + // whether the server already received and acted on the request. A + // silent retry of POST/PUT/PATCH/DELETE could duplicate side-effects + // (double payment, repeat resource creation, etc.). + let http_result = http::request(conn, &method, &url, &opts.headers, body.as_deref()).await; + + let (response, reusable, conn) = match http_result { + Ok(result) => result, + Err(stale_err) if from_pool && is_idempotent(&method) => { + crate::util::debug_log!( + "[fetch] pooled connection failed ({stale_err}), retrying with fresh connection" + ); + let fresh = new_connection(tunnel, &host, port, is_https).await?; + match http::request(fresh, &method, &url, &opts.headers, body.as_deref()).await { + Ok(result) => result, + Err(e) => { + crate::util::debug_error!( + "[fetch] fresh connection also failed: {e} (pooled failed with: {stale_err})" + ); + return Err(e); + } + } + } + Err(e) => return Err(e), + }; + + crate::util::debug_log!( + "[fetch] {} {} ({} bytes, reusable={})", + response.status, + response.status_text, + response.body.len(), + reusable + ); + + // 3. Return connection to pool if reusable + if reusable { + crate::util::debug_log!("[fetch] returning connection to pool for {host}:{port}"); + tunnel.return_to_pool(host, port, conn); + } + + // 4. Follow redirects (3xx with Location header). Any other status, + // or a 3xx without Location, returns directly. + if !(300..400).contains(&response.status) { + return serialise_response(&response); + } + + let location = response + .headers + .iter() + .find(|(k, _)| k.eq_ignore_ascii_case("location")) + .map(|(_, v)| v.clone()); + + let Some(location) = location else { + return serialise_response(&response); + }; + + crate::util::debug_log!("[fetch] {} → Location: {location}", response.status); + + let prev_url = url.clone(); + url = prev_url + .join(&location) + .map_err(|e| FetchError::Http(format!("invalid redirect URL '{location}': {e}")))?; + + // Reject non-HTTP schemes (javascript:, file:, data:, …) and any + // HTTPS to HTTP downgrade; classic redirect exfiltration shapes. + if !is_http_scheme(&url) { + return Err(FetchError::Http(format!( + "redirect to unsupported scheme '{}' rejected", + url.scheme() + ))); + } + if prev_url.scheme() == "https" && url.scheme() == "http" { + return Err(FetchError::Http( + "redirect from https to http rejected (would leak credentials)".into(), + )); + } + + // Strip credential-bearing headers on cross-origin redirects so + // Authorization / Cookie / Proxy-Authorization never follow a hop + // to a different origin. Same-origin redirects keep them. + if prev_url.origin() != url.origin() { + strip_sensitive_headers(&mut opts.headers); + } + + // 301/302/303: switch to GET and drop body (RFC 7231). + // 307/308: preserve method and body. + if matches!(response.status, 301..=303) { + method = "GET".into(); + body = None; + } + } + + Err(FetchError::Http(format!( + "too many redirects (>{max_redirects})" + ))) +} + +/// Create a fresh connection: DNS resolve → TCP connect → optional TLS. +pub(crate) async fn new_connection( + tunnel: &WasmTunnel, + host: &str, + port: u16, + is_https: bool, +) -> Result { + let ip = dns::resolve(tunnel, host).await?; + let addr = SocketAddr::new(ip, port); + + crate::util::debug_log!("[fetch] TCP connecting to {addr}..."); + let tcp = tunnel.tcp_connect(addr).await.map_err(FetchError::Io)?; + crate::util::debug_log!("[fetch] TCP connected to {addr}"); + + if is_https { + crate::util::debug_log!("[fetch] TLS handshake with '{host}'..."); + let tls_stream = tls::connect(tcp, host).await?; + crate::util::debug_log!("[fetch] TLS handshake complete with '{host}'"); + Ok(PooledConn::Tls(tls_stream)) + } else { + Ok(PooledConn::Plain(tcp)) + } +} + +// RequestInit extraction (via js_sys::Reflect, no serde): `fetch` feature only. + +/// Extract method, headers, and body from a JS `RequestInit` object. +#[cfg(feature = "fetch")] +fn parse_init(init: &JsValue) -> Result { + // Handle undefined/null init (bare GET request) + if init.is_undefined() || init.is_null() { + return Ok(FetchInit { + method: "GET".into(), + headers: Vec::new(), + body: None, + }); + } + + let method = Reflect::get(init, &JsValue::from_str("method")) + .ok() + .and_then(|v| v.as_string()) + .unwrap_or_else(|| "GET".into()); + + let headers = extract_headers(init)?; + let body = extract_body(init)?; + + Ok(FetchInit { + method, + headers, + body, + }) +} + +/// Extract headers from a plain JS object `{ "Header-Name": "value" }`. +#[cfg(feature = "fetch")] +fn extract_headers(init: &JsValue) -> Result, FetchError> { + let headers_val = match Reflect::get(init, &JsValue::from_str("headers")) { + Ok(v) if !v.is_undefined() && !v.is_null() => v, + _ => return Ok(Vec::new()), + }; + + let mut result = Vec::new(); + + if let Some(obj) = headers_val.dyn_ref::() { + let keys = Object::keys(obj); + for i in 0..keys.length() { + let key_val = keys.get(i); + if let Some(key) = key_val.as_string() { + if let Ok(val) = Reflect::get(obj, &key_val) { + if let Some(val_str) = val.as_string() { + result.push((key, val_str)); + } + } + } + } + } + + Ok(result) +} + +/// Extract the request body. Supports string, Uint8Array, and ArrayBuffer. +#[cfg(feature = "fetch")] +fn extract_body(init: &JsValue) -> Result>, FetchError> { + let body_val = match Reflect::get(init, &JsValue::from_str("body")) { + Ok(v) if !v.is_undefined() && !v.is_null() => v, + _ => return Ok(None), + }; + + // String body → UTF-8 bytes + if let Some(s) = body_val.as_string() { + return Ok(Some(s.into_bytes())); + } + + // Uint8Array → copy to Vec + if let Some(arr) = body_val.dyn_ref::() { + return Ok(Some(arr.to_vec())); + } + + // ArrayBuffer → wrap in Uint8Array → copy to Vec + if let Some(buf) = body_val.dyn_ref::() { + let arr = Uint8Array::new(buf); + return Ok(Some(arr.to_vec())); + } + + Err(FetchError::Http( + "unsupported body type (expected string, Uint8Array, or ArrayBuffer)".into(), + )) +} + +// Response serialisation (Rust → JS plain object) + +/// Serialise an `HttpResponse` into a plain JS object for Comlink transfer. +/// +/// Shape: `{ body: Uint8Array, status: number, statusText: string, headers: Array<[string, string]> }` +/// +/// `headers` is a sequence of `[name, value]` pairs (not a record) so that +/// repeated names like `Set-Cookie`, `Vary`, `Link`, or `WWW-Authenticate` +/// survive the hop. The JS layer feeds it straight into `new Headers(raw.headers)`, +/// which accepts both shapes. +/// +/// The TS layer reconstructs a native browser `Response` from this: +/// ```js +/// new Response(raw.body, { +/// status: raw.status, +/// statusText: raw.statusText, +/// headers: new Headers(raw.headers), +/// }) +/// ``` +#[cfg(feature = "fetch")] +fn serialise_response(resp: &HttpResponse) -> Result { + let obj = Object::new(); + let body = Uint8Array::from(resp.body.as_slice()); + + set_prop(&obj, "body", &body)?; + set_prop(&obj, "status", &JsValue::from(resp.status))?; + set_prop(&obj, "statusText", &JsValue::from_str(&resp.status_text))?; + + let headers_arr = Array::new(); + for (k, v) in &resp.headers { + let pair = Array::new(); + pair.push(&JsValue::from_str(k)); + pair.push(&JsValue::from_str(v)); + headers_arr.push(&pair); + } + set_prop(&obj, "headers", &headers_arr)?; + + Ok(obj.into()) +} + +/// Helper: set a property on a JS object via `Reflect.set`. +#[cfg(feature = "fetch")] +fn set_prop(obj: &Object, key: &str, val: &JsValue) -> Result<(), FetchError> { + Reflect::set(obj, &JsValue::from_str(key), val) + .map(|_| ()) + .map_err(|e| FetchError::Js(format!("failed to set '{key}': {e:?}"))) +} + +/// Whether the URL scheme is one we'll forward to. +#[cfg(feature = "fetch")] +fn is_http_scheme(url: &Url) -> bool { + matches!(url.scheme(), "http" | "https") +} + +/// HTTP methods we're willing to retry without operator-visible side-effects. +/// Matches RFC 9110's idempotent set minus TRACE (which we'd never send). +#[cfg(feature = "fetch")] +fn is_idempotent(method: &str) -> bool { + matches!( + method.to_ascii_uppercase().as_str(), + "GET" | "HEAD" | "OPTIONS" | "PUT" | "DELETE" + ) +} + +/// Drop credential-bearing headers when a redirect crosses origins. +#[cfg(feature = "fetch")] +fn strip_sensitive_headers(headers: &mut Vec<(String, String)>) { + const SENSITIVE: &[&str] = &["authorization", "cookie", "proxy-authorization"]; + headers.retain(|(k, _)| !SENSITIVE.iter().any(|name| k.eq_ignore_ascii_case(name))); +} diff --git a/wasm/smolmix/src/http.rs b/wasm/smolmix/src/http.rs new file mode 100644 index 0000000000..f3476b2b0c --- /dev/null +++ b/wasm/smolmix/src/http.rs @@ -0,0 +1,237 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +//! HTTP/1.1 client on hyper 1.x. + +use std::io; +use std::mem::MaybeUninit; +use std::pin::Pin; +use std::task::{Context, Poll}; + +use futures::io::{AsyncRead, AsyncWrite}; +use http_body_util::{BodyExt, Full}; +use hyper::body::Bytes; +use hyper::client::conn::http1; + +use crate::error::FetchError; + +/// Parsed HTTP response. +pub struct HttpResponse { + pub status: u16, + pub status_text: String, + pub headers: Vec<(String, String)>, + pub body: Vec, +} + +/// `futures::io` to `hyper::rt` adapter. hyper hands us uninitialised memory; +/// `futures::io::AsyncRead` needs `&mut [u8]`, so we zero before passing. +struct HyperIoAdapter(T); + +impl hyper::rt::Read for HyperIoAdapter { + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + mut buf: hyper::rt::ReadBufCursor<'_>, + ) -> Poll> { + // SAFETY: `init_slice` initialises every byte before the caller sees it. + let uninit_slice = unsafe { buf.as_mut() }; + let slice = init_slice(uninit_slice); + + match Pin::new(&mut self.get_mut().0).poll_read(cx, slice) { + Poll::Ready(Ok(n)) => { + // SAFETY: poll_read wrote `n` initialised bytes into `slice`, + // which aliases the first `n` bytes of `buf`. + unsafe { buf.advance(n) }; + Poll::Ready(Ok(())) + } + Poll::Ready(Err(e)) => Poll::Ready(Err(e)), + Poll::Pending => Poll::Pending, + } + } +} + +impl hyper::rt::Write for HyperIoAdapter { + fn poll_write( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + Pin::new(&mut self.get_mut().0).poll_write(cx, buf) + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.get_mut().0).poll_flush(cx) + } + + fn poll_shutdown(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.get_mut().0).poll_close(cx) + } +} + +/// Zero a `MaybeUninit` slice and return it as `&mut [u8]`. +fn init_slice(buf: &mut [MaybeUninit]) -> &mut [u8] { + for b in buf.iter_mut() { + b.write(0); + } + // Safety: we just initialised every element. + unsafe { &mut *(buf as *mut [MaybeUninit] as *mut [u8]) } +} + +/// Send an HTTP/1.1 request and read the complete response. +/// The returned `bool` is whether the stream is poolable. +pub async fn request( + stream: S, + method: &str, + url: &url::Url, + headers: &[(String, String)], + body: Option<&[u8]>, +) -> Result<(HttpResponse, bool, S), FetchError> +where + S: AsyncRead + AsyncWrite + Unpin + 'static, +{ + crate::util::debug_log!("[http] sending {method} request via hyper..."); + + let uri: http::Uri = url + .as_str() + .parse() + .map_err(|e| FetchError::Http(format!("URI conversion: {e}")))?; + let path = uri.path_and_query().map(|pq| pq.as_str()).unwrap_or("/"); + let host = uri + .authority() + .ok_or_else(|| FetchError::Http("URL has no authority for Host header".into()))? + .as_str(); + + let body_bytes = body.map(Bytes::copy_from_slice).unwrap_or_default(); + let mut builder = http::Request::builder() + .method(method) + .uri(path) + .header("Host", host) + .header("Connection", "keep-alive"); + + let mut has_content_length = false; + for (name, value) in headers { + builder = builder.header(name.as_str(), value.as_str()); + if name.eq_ignore_ascii_case("content-length") { + has_content_length = true; + } + } + + if body.is_some() && !has_content_length { + builder = builder.header("Content-Length", body_bytes.len().to_string()); + } + + let req = builder + .body(Full::new(body_bytes)) + .map_err(|e| FetchError::Http(format!("failed to build request: {e}")))?; + + // Perform HTTP/1 handshake; hyper takes ownership of the IO + let (mut sender, conn) = http1::handshake(HyperIoAdapter(stream)) + .await + .map_err(FetchError::Hyper)?; + + // Spawn the connection driver. The driver only completes once the + // request/response exchange is over AND the sender is dropped, at which + // point `without_shutdown()` returns the IO so we can pool it. + let (parts_tx, parts_rx) = futures::channel::oneshot::channel(); + wasm_bindgen_futures::spawn_local(async move { + let result = conn.without_shutdown().await; + let _ = parts_tx.send(result); + }); + + // Send the request + let response = sender.send_request(req).await.map_err(FetchError::Hyper)?; + + let status = response.status().as_u16(); + let status_text = response + .status() + .canonical_reason() + .unwrap_or("") + .to_string(); + + // Collect response headers + let response_headers: Vec<(String, String)> = response + .headers() + .iter() + .map(|(k, v)| (k.as_str().to_string(), v.to_str().unwrap_or("").to_string())) + .collect(); + + // Reusable unless the server signals `Connection: close`. + let server_close = response_headers + .iter() + .any(|(k, v)| k.eq_ignore_ascii_case("connection") && v.eq_ignore_ascii_case("close")); + let reusable = !server_close; + + // Log headers immediately so we know the server responded, even if + // the body takes a long time to stream through the mixnet. + let content_length = response_headers + .iter() + .find(|(k, _)| k.eq_ignore_ascii_case("content-length")) + .and_then(|(_, v)| v.parse::().ok()); + + match content_length { + Some(len) => crate::util::debug_log!( + "[http] {status} {status_text}; collecting body ({len} bytes)..." + ), + None => crate::util::debug_log!( + "[http] {status} {status_text}; collecting body (chunked/unknown size)..." + ), + } + + // Dump response headers for diagnostics. + for (k, v) in &response_headers { + crate::util::debug_log!("[http] {k}: {v}"); + } + + // Read body frame-by-frame to log progress (large mixnet downloads + // can take 30s+ with no visible output otherwise). + let mut body = response.into_body(); + let mut body_data = Vec::new(); + let expected = content_length.unwrap_or(0); + let mut next_log_at: usize = 4096; + + loop { + match body.frame().await { + Some(Ok(frame)) => { + if let Ok(data) = frame.into_data() { + let chunk_len = data.len(); + body_data.extend_from_slice(&data); + if body_data.len() >= next_log_at { + crate::util::debug_log!( + "[http] progress: {} / {expected} bytes (chunk={chunk_len})", + body_data.len(), + ); + next_log_at = body_data.len() + 4096; + } + } + } + Some(Err(e)) => return Err(FetchError::Hyper(e)), + None => break, + } + } + + crate::util::debug_log!( + "[http] body complete: {} bytes, reusable={reusable}", + body_data.len() + ); + + // Drop sender to signal the connection driver to complete + drop(sender); + + // Recover the underlying stream from the connection driver + let parts = parts_rx + .await + .map_err(|_| FetchError::Http("connection driver dropped".into()))? + .map_err(FetchError::Hyper)?; + let stream = parts.io.0; + + Ok(( + HttpResponse { + status, + status_text, + headers: response_headers, + body: body_data, + }, + reusable, + stream, + )) +} diff --git a/wasm/smolmix/src/ipr.rs b/wasm/smolmix/src/ipr.rs new file mode 100644 index 0000000000..255e4fd6e8 --- /dev/null +++ b/wasm/smolmix/src/ipr.rs @@ -0,0 +1,314 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +//! IPR (IP Packet Router) protocol layer for the WASM tunnel. +//! +//! Handles the v9 connect handshake and IP packet send/recv, using the +//! upstream `nym_lp_data::packet::frame` wire format directly (no tokio deps). +//! +//! Data flow: +//! ```text +//! Outgoing: IP packet → bundle → DataRequest → to_bytes → LP frame → mixnet +//! Incoming: mixnet → LP decode → IpPacketResponse → unbundle → IP packets +//! ``` + +use bytes::{Bytes, BytesMut}; +use futures::StreamExt; +use futures::channel::mpsc; +use std::sync::Arc; +use std::time::Duration; + +use nym_ip_packet_requests::IpPair; +use nym_ip_packet_requests::v9::{self, response::IpPacketResponse}; +use nym_lp_data::packet::frame::{ + LpFrame, LpFrameKind, SphinxStreamFrameAttributes, SphinxStreamMsgType, +}; +use nym_wasm_client_core::Recipient; +use nym_wasm_client_core::ReconstructedMessage; +use nym_wasm_client_core::client::base_client::ClientInput; +use nym_wasm_client_core::client::inbound_messages::InputMessage; +use nym_wasm_client_core::nym_task::connections::TransmissionLane; + +use crate::error::FetchError; + +/// Reply-SURB counts for Open and Data frames. Defaults: `open=10, data=0`. +/// +/// The Open frame seeds the IPR's SURB bucket; from there, the reply +/// controller's pre-emptive topup refills it when the bucket dips below +/// the `min_surbs_threshold` (10, per nym-client-core), so per-data-packet +/// SURBs are unnecessary in steady state. Override `data` upwards for +/// workloads that burst faster than topup round-trip can keep up. +#[derive(Clone, Copy)] +pub struct SurbsConfig { + pub open: u32, + pub data: u32, +} + +impl Default for SurbsConfig { + fn default() -> Self { + Self { open: 10, data: 0 } + } +} + +/// Type alias for the channel receiving batches of reconstructed messages. +pub type ReconstructedReceiver = mpsc::UnboundedReceiver>; + +/// Open an LP stream to the IPR and perform the v9 connect handshake. +/// +/// Sends an LP Open frame (seq=0, empty payload), then a ConnectRequest +/// (Data seq=0), and waits for a ConnectSuccess response with allocated IPs. +pub async fn open_and_connect( + client_input: &Arc, + receiver: &mut ReconstructedReceiver, + ipr_address: &Recipient, + stream_id: u64, + surbs: SurbsConfig, + connect_timeout: Duration, +) -> Result { + nym_wasm_utils::console_log!("[ipr] sending connect handshake..."); + crate::util::debug_log!("[ipr] stream={stream_id:#018x}"); + + // 1. Send LP Open frame (empty payload, seq=0); establishes the stream + let open_frame = encode_lp_frame(stream_id, SphinxStreamMsgType::Open, 0, &[]); + send_to_ipr(client_input, ipr_address, open_frame, surbs.open).await?; + + // 2. Send v9 ConnectRequest as LP Data frame (seq=0). + // Data frames have their own seq space; Open's seq field is independent. + let (request, request_id) = v9::new_connect_request(None); + let request_bytes = request + .to_bytes() + .map_err(|e| FetchError::Tunnel(format!("failed to serialise connect request: {e}")))?; + let data_frame = encode_lp_frame(stream_id, SphinxStreamMsgType::Data, 0, &request_bytes); + send_to_ipr(client_input, ipr_address, data_frame, surbs.data).await?; + + // 3. Wait for ConnectSuccess response + let ip_pair = wasmtimer::tokio::timeout(connect_timeout, async { + loop { + let batch = receiver + .next() + .await + .ok_or_else(|| FetchError::Tunnel("message channel closed".into()))?; + + for msg in batch { + // nym-client-core's received_buffer filters cover traffic + // before delivery, so an outer LP-decode failure here is a + // "shouldn't happen" signal: either a non-LP straggler or + // garbage. We log and continue rather than bail (bailing + // would open a single-spoofed-message DoS on the handshake); + // tightening to fail-fast belongs with the IPR-auth design. + let Some((attrs, content)) = decode_lp_stream(&msg.message) else { + crate::util::debug_error!( + "[ipr] non-LP-stream message received during handshake (dropped)" + ); + continue; + }; + + if attrs.stream_id != stream_id || attrs.msg_type != SphinxStreamMsgType::Data { + // Late straggler from a different stream/session — expected. + continue; + } + + let response = match IpPacketResponse::from_bytes(&content) { + Ok(r) => r, + Err(e) => { + // Decoded as LP for our stream + msg_type, but content + // didn't parse as an IPR response. Logged for the same + // reason as the outer decode failure above. + crate::util::debug_error!( + "[ipr] malformed IpPacketResponse on our stream (dropped): {e}" + ); + continue; + } + }; + + if response.id() != Some(request_id) { + continue; + } + + return nym_ip_packet_requests::response_helpers::parse_connect_response(response) + .map_err(|e| FetchError::Tunnel(format!("IPR connect denied: {e}"))); + } + } + }) + .await + .map_err(|_| FetchError::Tunnel("IPR connect timed out".into()))??; + + Ok(ip_pair) +} + +/// Bundle an IP packet and send it to the IPR as an LP-framed DataRequest. +/// +/// The bundling uses the `MultiIpPacketCodec` wire format: 2-byte BE length +/// prefix followed by the raw packet. This is what the IPR expects. +pub async fn send_ip_packet( + client_input: &Arc, + ipr_address: &Recipient, + stream_id: u64, + seq: u32, + packet: &[u8], + data_surbs: u32, +) -> Result<(), FetchError> { + let bundled = nym_ip_packet_requests::codec::MultiIpPacketCodec::bundle_one_packet( + Bytes::copy_from_slice(packet), + ); + + // Wrap in v9 DataRequest + let request = v9::new_data_request(bundled); + let request_bytes = request + .to_bytes() + .map_err(|e| FetchError::Tunnel(format!("failed to serialise data request: {e}")))?; + + // LP-frame and send + let frame = encode_lp_frame(stream_id, SphinxStreamMsgType::Data, seq, &request_bytes); + send_to_ipr(client_input, ipr_address, frame, data_surbs).await +} + +/// Parse an incoming ReconstructedMessage into individual IP packets. +/// +/// LP-decodes the message, verifies the stream_id, deserialises the IPR +/// response, and unbundles the contained IP packets. +/// +/// Returns `Ok(None)` for non-data responses (control messages, wrong stream). +/// Returns `Ok(Some(packets))` for data responses. +/// Returns `Err` only for hard errors (disconnect). +pub fn parse_incoming( + msg: &ReconstructedMessage, + expected_stream_id: u64, +) -> Result>>, FetchError> { + let Some((attrs, content)) = decode_lp_stream(&msg.message) else { + return Ok(None); + }; + + if attrs.stream_id != expected_stream_id || attrs.msg_type != SphinxStreamMsgType::Data { + return Ok(None); + } + + match nym_ip_packet_requests::response_helpers::handle_ipr_response(&content) { + Some(nym_ip_packet_requests::response_helpers::MixnetMessageOutcome::IpPackets( + packets, + )) => Ok(Some(packets.into_iter().map(|b| b.to_vec()).collect())), + Some(nym_ip_packet_requests::response_helpers::MixnetMessageOutcome::Disconnect) => { + crate::util::debug_error!("[ipr] IPR sent DISCONNECT"); + Err(FetchError::Tunnel("IPR disconnected".into())) + } + None => Ok(None), + } +} + +// LP frame helpers + +/// Encode a SphinxStream LP frame into bytes. +fn encode_lp_frame( + stream_id: u64, + msg_type: SphinxStreamMsgType, + seq: u32, + payload: &[u8], +) -> Vec { + let frame = LpFrame::new_stream( + SphinxStreamFrameAttributes { + stream_id, + msg_type, + sequence_num: seq, + }, + payload.to_vec(), + ); + let mut buf = BytesMut::with_capacity(16 + payload.len()); + frame.encode(&mut buf); + buf.to_vec() +} + +/// Decode a SphinxStream LP frame, returning (attributes, content). +/// +/// Returns `None` if the data is too short, the frame kind isn't +/// `SphinxStream`, or the attributes can't be parsed. +fn decode_lp_stream(data: &[u8]) -> Option<(SphinxStreamFrameAttributes, Bytes)> { + let frame = LpFrame::decode(data).ok()?; + if frame.kind() != LpFrameKind::SphinxStream { + return None; + } + let attrs = SphinxStreamFrameAttributes::parse(&frame.header.frame_attributes).ok()?; + Some((attrs, frame.content)) +} + +// Mixnet send helper + +/// Send an anonymous mixnet message to the IPR with reply SURBs. +async fn send_to_ipr( + client_input: &Arc, + recipient: &Recipient, + data: Vec, + reply_surbs: u32, +) -> Result<(), FetchError> { + let msg = InputMessage::new_anonymous( + *recipient, + data, + reply_surbs, + TransmissionLane::General, + None, + ); + client_input + .send(msg) + .await + .map_err(|_| FetchError::Tunnel("mixnet input channel closed".into())) +} + +/// Performance-weighted random pick from v9-capable IPRs. Ported from +/// `nym_sdk::ip_packet_client::discovery::get_best_ipr` to keep the +/// SDK out of the wasm dep graph. +pub(crate) async fn discover_ipr(nym_api_urls: &[url::Url]) -> Result { + use nym_validator_client::nym_api::NymApiClientExt; + use rand::seq::SliceRandom; + use std::collections::HashMap; + + let url = nym_api_urls + .first() + .ok_or_else(|| FetchError::Tunnel("no nym-api URLs for IPR discovery".into()))?; + let client = nym_wasm_client_core::ApiClient::builder(url.clone()) + .map_err(|e| FetchError::Tunnel(format!("nym-api builder failed: {e}")))? + .build() + .map_err(|e| FetchError::Tunnel(format!("nym-api build failed: {e}")))?; + + let all_nodes: HashMap<_, _> = client + .get_all_described_nodes_v2() + .await + .map_err(|e| FetchError::Tunnel(format!("describe nodes failed: {e}")))? + .into_iter() + .map(|d| (d.ed25519_identity_key(), d)) + .collect(); + + let exits = client + .get_all_basic_nodes_with_metadata() + .await + .map_err(|e| FetchError::Tunnel(format!("list nodes failed: {e}")))? + .nodes; + + let mut candidates: Vec<(Recipient, u8)> = Vec::new(); + for exit in exits { + let Some(node) = all_nodes.get(&exit.ed25519_identity_pubkey) else { + continue; + }; + let Ok(version) = semver::Version::parse(node.version()) else { + continue; + }; + if version < nym_ip_packet_requests::v9::MIN_RELEASE_VERSION { + continue; + } + let Some(ipr_info) = node.description.ip_packet_router.clone() else { + continue; + }; + let Ok(addr) = ipr_info.address.parse::() else { + continue; + }; + candidates.push((addr, exit.performance.round_to_integer())); + } + + let picked = candidates + .choose_weighted(&mut rand::thread_rng(), |c| c.1 as f64) + .map_err(|_| FetchError::Tunnel("no v9-capable IPRs available".into()))?; + nym_wasm_utils::console_log!( + "[smolmix] auto-discovered IPR (perf={}): {}", + picked.1, + picked.0 + ); + Ok(picked.0) +} diff --git a/wasm/smolmix/src/lib.rs b/wasm/smolmix/src/lib.rs new file mode 100644 index 0000000000..53ca9d4af6 --- /dev/null +++ b/wasm/smolmix/src/lib.rs @@ -0,0 +1,280 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +//! smolmix-wasm: drop-in browser networking over the Nym mixnet. +//! +//! Exposes three APIs that mirror the browser's native networking surface: +//! +//! - **`mixFetch(url, init)`**: drop-in `fetch()` replacement (HTTP/HTTPS) +//! - **`mixSocket(url, protocols, onEvent)`**: drop-in `WebSocket` replacement (WS/WSS) +//! - **`mixResolve(hostname)`**: DNS-only hostname lookup (UDP / IPR path, no TCP/TLS) +//! +//! All three share the same mixnet tunnel (DNS, TCP, TLS), initialised once +//! via `setupMixTunnel(opts)` and torn down with `disconnectMixTunnel()`. + +// All modules gated on wasm32 so `cargo check` on the host triple sees an empty crate. +// Cargo features (`dns` / `fetch` / `socket`) further gate the entry-point modules +// and their heavy deps; see [features] in Cargo.toml. +#[cfg(target_arch = "wasm32")] +mod bridge; +#[cfg(target_arch = "wasm32")] +mod device; +#[cfg(target_arch = "wasm32")] +mod dns; +#[cfg(target_arch = "wasm32")] +mod error; +#[cfg(all(target_arch = "wasm32", any(feature = "fetch", feature = "socket")))] +mod fetch; +#[cfg(all(target_arch = "wasm32", feature = "fetch"))] +mod http; +#[cfg(target_arch = "wasm32")] +mod ipr; +#[cfg(all(target_arch = "wasm32", feature = "dns"))] +mod mixdns; +#[cfg(all(target_arch = "wasm32", feature = "fetch"))] +mod mixfetch; +#[cfg(all(target_arch = "wasm32", feature = "socket"))] +mod mixsocket; +#[cfg(target_arch = "wasm32")] +mod reactor; +#[cfg(target_arch = "wasm32")] +mod state; +#[cfg(target_arch = "wasm32")] +mod stream; +#[cfg(all(target_arch = "wasm32", any(feature = "fetch", feature = "socket")))] +mod tls; +#[cfg(target_arch = "wasm32")] +mod tunnel; +#[cfg(target_arch = "wasm32")] +mod util; + +#[cfg(target_arch = "wasm32")] +pub use error::FetchError; +#[cfg(target_arch = "wasm32")] +pub use tunnel::WasmTunnel; + +#[cfg(target_arch = "wasm32")] +use serde::Deserialize; +#[cfg(target_arch = "wasm32")] +use std::sync::OnceLock; +#[cfg(target_arch = "wasm32")] +use tsify::Tsify; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen::prelude::*; +#[cfg(target_arch = "wasm32")] +use wasm_bindgen_futures::future_to_promise; + +/// Global tunnel singleton, set once by `setupMixTunnel`, stays in the OnceLock after shutdown. +#[cfg(target_arch = "wasm32")] +pub(crate) static TUNNEL: OnceLock = OnceLock::new(); + +/// Resolve the tunnel and gate on readiness. Used by every JS entry point. +#[cfg(target_arch = "wasm32")] +pub(crate) fn ready_tunnel() -> Result<&'static WasmTunnel, FetchError> { + let tunnel = TUNNEL.get().ok_or(FetchError::NotConnected)?; + if !tunnel.is_ready() { + return Err(FetchError::Tunnel(format!( + "tunnel not ready: {:?}", + tunnel.tunnel_state() + ))); + } + Ok(tunnel) +} + +/// Options accepted by `setupMixTunnel`. Deserialised from the JS object via +/// `serde-wasm-bindgen` + `tsify`, which gives us typed access without manual +/// `Reflect::get` plumbing and emits a matching `.d.ts` for the TS side. +#[derive(Tsify, Deserialize)] +#[tsify(from_wasm_abi)] +#[serde(rename_all = "camelCase")] +#[cfg(target_arch = "wasm32")] +pub struct SetupOpts { + /// Nym address of the IPR exit node. Omit (or pass `null`) to let + /// smolmix auto-discover a performance-weighted random IPR via the + /// Nym API directory. + #[serde(default)] + pub preferred_ipr: Option, + /// Client storage namespace; randomise per session for clean state. + #[serde(default)] + pub client_id: Option, + /// Use `wss://` for gateway connections (default: `true`). + #[serde(default = "default_force_tls")] + pub force_tls: bool, + /// Disable Poisson-distributed dummy traffic (default: `false`). + #[serde(default)] + pub disable_poisson_traffic: bool, + /// Disable cover traffic loop (default: `false`). + #[serde(default)] + pub disable_cover_traffic: bool, + /// SURBs attached to the LP Open frame and the v9 ConnectRequest sent + /// during the IPR handshake. `None` falls back to [`ipr::SurbsConfig::default`]. + #[serde(default)] + pub open_reply_surbs: Option, + /// SURBs attached to each LP Data frame the bridge sends. Higher values + /// raise download throughput at the cost of outgoing-packet overhead. + #[serde(default)] + pub data_reply_surbs: Option, + /// Primary DNS resolver (e.g. `"1.1.1.1:53"`). Defaults to `8.8.8.8:53`. + #[serde(default)] + pub primary_dns: Option, + /// Fallback DNS resolver used if the primary times out. Defaults to `1.1.1.1:53`. + #[serde(default)] + pub fallback_dns: Option, + /// Passphrase used to encrypt persistent client storage (identity keys, + /// gateway details). Omit for plaintext storage. The same passphrase + /// must be supplied on subsequent page loads to read the same keys. + #[serde(default)] + pub storage_passphrase: Option, + /// IPR connect handshake timeout in milliseconds. Defaults to 60000. + #[serde(default)] + pub connect_timeout_ms: Option, + /// DNS query timeout in milliseconds (per primary/fallback attempt). + /// Defaults to 30000. + #[serde(default)] + pub dns_timeout_ms: Option, + /// TCP keepalive interval in milliseconds. Defaults to 10000. + #[serde(default)] + pub tcp_keepalive_ms: Option, + /// Per-TCP-stream RX/TX buffer size in bytes (capped at 65535). + /// Defaults to 65535. + #[serde(default)] + pub tcp_buffer_size: Option, + /// Maximum HTTP redirect chain depth before `mixFetch` gives up. + /// Defaults to 5. + #[serde(default)] + pub max_redirects: Option, +} + +#[cfg(target_arch = "wasm32")] +fn default_force_tls() -> bool { + true +} + +/// WASM entry point. Installs the panic hook + state-machine recorder, +/// and flips the runtime debug-log switch on when smolmix's `debug` +/// feature is enabled. +#[wasm_bindgen(start)] +#[cfg(target_arch = "wasm32")] +pub fn main() { + nym_wasm_utils::set_panic_hook(); + #[cfg(feature = "debug")] + nym_wasm_utils::set_debug_logging(true); + state::install_panic_recorder(); +} + +/// Initialise the mixnet tunnel. See [`SetupOpts`] for the JS-side shape. +#[wasm_bindgen(js_name = "setupMixTunnel")] +#[cfg(target_arch = "wasm32")] +pub fn setup_mix_tunnel(opts: SetupOpts) -> js_sys::Promise { + future_to_promise(async move { + let result: Result = async move { + // One-shot: `TUNNEL` is a `OnceLock` so consumers can hold + // `&'static WasmTunnel` refs without lifetime gymnastics. + if TUNNEL.get().is_some() { + return Err(FetchError::Tunnel( + "tunnel already initialised; setupMixTunnel can only be called \ + once per WASM module instance" + .into(), + )); + } + + let ipr_address: Option = opts + .preferred_ipr + .map(|s| { + s.parse::() + .map_err(|e| FetchError::Tunnel(format!("invalid IPR address: {e}"))) + }) + .transpose()?; + + let defaults = ipr::SurbsConfig::default(); + let surbs = ipr::SurbsConfig { + open: opts.open_reply_surbs.unwrap_or(defaults.open), + data: opts.data_reply_surbs.unwrap_or(defaults.data), + }; + + let parse_dns = + |raw: Option| -> Result, FetchError> { + raw.map(|s| { + s.parse().map_err(|e| { + FetchError::Tunnel(format!("invalid DNS resolver '{s}': {e}")) + }) + }) + .transpose() + }; + + let mut builder = tunnel::TunnelOpts::builder() + .client_id(opts.client_id.unwrap_or_else(|| "smolmix-wasm".to_string())) + .force_tls(opts.force_tls) + .disable_poisson_traffic(opts.disable_poisson_traffic) + .disable_cover_traffic(opts.disable_cover_traffic) + .surbs(surbs); + + if let Some(ipr) = ipr_address { + builder = builder.ipr_address(ipr); + } + if let Some(addr) = parse_dns(opts.primary_dns)? { + builder = builder.primary_dns(addr); + } + if let Some(addr) = parse_dns(opts.fallback_dns)? { + builder = builder.fallback_dns(addr); + } + if let Some(p) = opts.storage_passphrase { + builder = builder.storage_passphrase(p); + } + if let Some(ms) = opts.connect_timeout_ms { + builder = builder.connect_timeout(std::time::Duration::from_millis(ms as u64)); + } + if let Some(ms) = opts.dns_timeout_ms { + builder = builder.dns_timeout(std::time::Duration::from_millis(ms as u64)); + } + if let Some(ms) = opts.tcp_keepalive_ms { + builder = + builder.tcp_keepalive_interval(std::time::Duration::from_millis(ms as u64)); + } + if let Some(n) = opts.tcp_buffer_size { + builder = builder.tcp_buffer_size(n as usize); + } + if let Some(n) = opts.max_redirects { + builder = builder.max_redirects(n); + } + + let tunnel_opts = builder.build(); + + let tun = WasmTunnel::new(tunnel_opts).await?; + + TUNNEL.set(tun).map_err(|_| { + FetchError::Tunnel( + "tunnel already initialised by a concurrent setupMixTunnel call".into(), + ) + })?; + + Ok(JsValue::UNDEFINED) + } + .await; + result.map_err(Into::into) + }) +} + +/// Disconnect from the mixnet. The tunnel becomes unusable until page reload. +#[wasm_bindgen(js_name = "disconnectMixTunnel")] +#[cfg(target_arch = "wasm32")] +pub fn disconnect_mix_tunnel() -> js_sys::Promise { + future_to_promise(async { + if let Some(tunnel) = TUNNEL.get() { + tunnel.shutdown().await; + } + Ok(JsValue::UNDEFINED) + }) +} + +/// Returns `{state, reason?}`. See [`state::TunnelState`] serde tags +/// for the exact shape. Pre-`setupMixTunnel` reads as `connecting`. +#[wasm_bindgen(js_name = "getTunnelState")] +#[cfg(target_arch = "wasm32")] +pub fn get_tunnel_state() -> JsValue { + let s = match TUNNEL.get() { + Some(tunnel) => tunnel.tunnel_state(), + None => state::TunnelState::Connecting, + }; + serde_wasm_bindgen::to_value(&s).unwrap_or(JsValue::NULL) +} diff --git a/wasm/smolmix/src/mixdns.rs b/wasm/smolmix/src/mixdns.rs new file mode 100644 index 0000000000..c1a122afaf --- /dev/null +++ b/wasm/smolmix/src/mixdns.rs @@ -0,0 +1,21 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +//! `mixResolve`: hostname lookup over the mixnet tunnel (UDP / IPR path only). + +use wasm_bindgen::prelude::*; +use wasm_bindgen_futures::future_to_promise; + +use crate::dns; + +/// Resolve a hostname to an IP address through the mixnet tunnel. +/// +/// Returns the IP as a string (e.g. `"93.184.216.34"`). +#[wasm_bindgen(js_name = "mixResolve")] +pub fn mix_resolve(hostname: String) -> js_sys::Promise { + future_to_promise(async move { + let tunnel = crate::ready_tunnel()?; + let ip = dns::resolve(tunnel, &hostname).await?; + Ok(JsValue::from_str(&ip.to_string())) + }) +} diff --git a/wasm/smolmix/src/mixfetch.rs b/wasm/smolmix/src/mixfetch.rs new file mode 100644 index 0000000000..51ada1906e --- /dev/null +++ b/wasm/smolmix/src/mixfetch.rs @@ -0,0 +1,18 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +//! `mixFetch`: WASM export, delegates to [`crate::fetch::fetch`]. + +use wasm_bindgen::prelude::*; +use wasm_bindgen_futures::future_to_promise; + +use crate::fetch; + +/// Execute an HTTP request through the mixnet tunnel. +#[wasm_bindgen(js_name = "mixFetch")] +pub fn mix_fetch(url: String, init: JsValue) -> js_sys::Promise { + future_to_promise(async move { + let tunnel = crate::ready_tunnel()?; + fetch::fetch(tunnel, &url, &init).await.map_err(Into::into) + }) +} diff --git a/wasm/smolmix/src/mixsocket.rs b/wasm/smolmix/src/mixsocket.rs new file mode 100644 index 0000000000..d4be74926a --- /dev/null +++ b/wasm/smolmix/src/mixsocket.rs @@ -0,0 +1,286 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +//! WebSocket over the mixnet tunnel; JS holds an integer handle. + +use std::collections::HashMap; +use std::sync::atomic::{AtomicU32, Ordering}; +use std::sync::{Mutex, OnceLock}; + +use wasm_bindgen::JsCast; +use wasm_bindgen::prelude::*; +use wasm_bindgen_futures::{future_to_promise, spawn_local}; + +use crate::error::FetchError; +use crate::fetch; +use crate::stream::PooledConn; +use crate::util; + +/// Active WebSocket handles: sender half of each connection's command channel. +static WS_HANDLES: OnceLock>> = OnceLock::new(); +static WS_NEXT_ID: AtomicU32 = AtomicU32::new(1); + +struct WsHandle { + tx: futures::channel::mpsc::UnboundedSender, +} + +enum WsCommand { + Send(async_tungstenite::tungstenite::Message), + Close(u16, String), +} + +/// Open a WebSocket through the tunnel; resolves to a u32 handle. +/// Events fire on `on_event(handleId, type, data)` with type one of +/// `"open" | "text" | "binary" | "close" | "error"`. +#[wasm_bindgen(js_name = "mixSocket")] +pub fn mix_socket(url: String, protocols: JsValue, on_event: js_sys::Function) -> js_sys::Promise { + future_to_promise(async move { + let result: Result = async { + use async_tungstenite::tungstenite::client::IntoClientRequest; + + let tunnel = crate::ready_tunnel()?; + + let parsed = url::Url::parse(&url) + .map_err(|e| FetchError::Http(format!("invalid WebSocket URL: {e}")))?; + let host = parsed + .host_str() + .ok_or_else(|| FetchError::Http("URL has no host".into()))?; + let port = parsed + .port_or_known_default() + .ok_or_else(|| FetchError::Http("URL has no port and scheme is unknown".into()))?; + let is_tls = parsed.scheme() == "wss"; + let protocol_list = parse_protocols(&protocols); + + util::debug_log!("[ws] connecting to {url}"); + + let conn = fetch::new_connection(tunnel, host, port, is_tls).await?; + + let mut request = url.into_client_request()?; + if !protocol_list.is_empty() { + let header_value = protocol_list.join(", ").parse().map_err(|e| { + FetchError::Http(format!("invalid Sec-WebSocket-Protocol value: {e}")) + })?; + request + .headers_mut() + .insert("Sec-WebSocket-Protocol", header_value); + } + + // HTTP 101 upgrade; tungstenite handles key gen + accept verification + let (ws_stream, response) = async_tungstenite::client_async(request, conn).await?; + + let negotiated = response + .headers() + .get("sec-websocket-protocol") + .and_then(|v| v.to_str().ok()) + .unwrap_or("") + .to_string(); + + util::debug_log!("[ws] upgrade complete (protocol={negotiated:?})"); + + let (tx, rx) = futures::channel::mpsc::unbounded(); + let handle_id = WS_NEXT_ID.fetch_add(1, Ordering::Relaxed); + + let handles = WS_HANDLES.get_or_init(|| Mutex::new(HashMap::new())); + handles.lock().unwrap().insert(handle_id, WsHandle { tx }); + + // Fire "open" before spawning the recv loop so JS sees it first. + fire_ws_event( + &on_event, + handle_id, + "open", + &JsValue::from_str(&negotiated), + ); + + spawn_local(ws_task(handle_id, ws_stream, rx, on_event)); + + Ok(JsValue::from(handle_id)) + } + .await; + + result.map_err(Into::into) + }) +} + +/// Send data over an open WebSocket (string → text, Uint8Array/ArrayBuffer → binary). +#[wasm_bindgen(js_name = "wsSend")] +pub fn ws_send(handle_id: u32, data: JsValue) -> Result<(), JsValue> { + use async_tungstenite::tungstenite::Message; + + let msg = if let Some(s) = data.as_string() { + let preview = if s.len() <= 120 { + &s + } else { + &s[..util::floor_char_boundary(&s, 120)] + }; + util::debug_log!("[ws:{handle_id}] send text ({} bytes): {preview}", s.len()); + Message::Text(s) + } else if let Some(arr) = data.dyn_ref::() { + let v = arr.to_vec(); + util::debug_log!( + "[ws:{handle_id}] send binary ({} bytes): {}", + v.len(), + util::hex_preview(&v, 32) + ); + Message::Binary(v) + } else if let Some(buf) = data.dyn_ref::() { + let v = js_sys::Uint8Array::new(buf).to_vec(); + util::debug_log!( + "[ws:{handle_id}] send binary ({} bytes): {}", + v.len(), + util::hex_preview(&v, 32) + ); + Message::Binary(v) + } else { + return Err(JsValue::from_str( + "unsupported data type (expected string, Uint8Array, or ArrayBuffer)", + )); + }; + + send_ws_command(handle_id, WsCommand::Send(msg)) +} + +/// Close an open WebSocket with a status code and reason. +#[wasm_bindgen(js_name = "wsClose")] +pub fn ws_close(handle_id: u32, code: u16, reason: String) -> Result<(), JsValue> { + send_ws_command(handle_id, WsCommand::Close(code, reason)) +} + +fn send_ws_command(handle_id: u32, cmd: WsCommand) -> Result<(), JsValue> { + let handles = WS_HANDLES + .get() + .ok_or_else(|| JsValue::from_str("no active WebSocket connections"))?; + let guard = handles.lock().unwrap(); + let handle = guard + .get(&handle_id) + .ok_or_else(|| JsValue::from_str(&format!("WebSocket handle {handle_id} not found")))?; + + handle + .tx + .unbounded_send(cmd) + .map_err(|_| JsValue::from_str("WebSocket background task has stopped")) +} + +/// Background task: reads from the WebSocket and dispatches JS commands. +/// Ping/pong is handled automatically by tungstenite. +async fn ws_task( + handle_id: u32, + ws: async_tungstenite::WebSocketStream, + rx: futures::channel::mpsc::UnboundedReceiver, + on_event: js_sys::Function, +) { + use async_tungstenite::tungstenite::Message; + use futures::{SinkExt, StreamExt, select}; + + util::debug_log!("[ws:{handle_id}] background task started"); + + let (mut sink, stream) = ws.split(); + let mut stream = stream.fuse(); + let mut rx = rx.fuse(); + + loop { + select! { + msg = stream.next() => match msg { + Some(Ok(Message::Text(s))) => { + let preview = if s.len() <= 120 { &s } else { &s[..util::floor_char_boundary(&s, 120)] }; + util::debug_log!("[ws:{handle_id}] recv text ({} bytes): {preview}", s.len()); + fire_ws_event(&on_event, handle_id, "text", &JsValue::from_str(&s)); + } + Some(Ok(Message::Binary(b))) => { + util::debug_log!("[ws:{handle_id}] recv binary ({} bytes): {}", b.len(), util::hex_preview(&b, 32)); + fire_ws_event( + &on_event, + handle_id, + "binary", + &js_sys::Uint8Array::from(b.as_slice()).into(), + ); + } + Some(Ok(Message::Close(frame))) => { + let info = frame + .map(|f| format!("{} {}", f.code, f.reason)) + .unwrap_or_else(|| "1005".into()); + util::debug_log!("[ws:{handle_id}] recv close ({info})"); + fire_ws_event(&on_event, handle_id, "close", &JsValue::from_str(&info)); + ws_cleanup(handle_id); + return; + } + Some(Ok(_)) => continue, // Ping/Pong handled internally + Some(Err(e)) => { + util::debug_error!("[ws:{handle_id}] error: {e}"); + fire_ws_event(&on_event, handle_id, "error", &JsValue::from_str(&e.to_string())); + ws_cleanup(handle_id); + return; + } + None => { + util::debug_log!("[ws:{handle_id}] connection lost"); + fire_ws_event(&on_event, handle_id, "close", &JsValue::from_str("1006 connection lost")); + ws_cleanup(handle_id); + return; + } + }, + cmd = rx.next() => match cmd { + Some(WsCommand::Send(msg)) => { + if let Err(e) = sink.send(msg).await { + util::debug_error!("[ws:{handle_id}] send error: {e}"); + fire_ws_event(&on_event, handle_id, "error", &JsValue::from_str(&e.to_string())); + ws_cleanup(handle_id); + return; + } + } + Some(WsCommand::Close(code, reason)) => { + util::debug_log!("[ws:{handle_id}] closing ({code} {reason})"); + let info = format!("{code} {reason}"); + let frame = async_tungstenite::tungstenite::protocol::CloseFrame { + code: code.into(), + reason: reason.into(), + }; + let _ = sink.send(Message::Close(Some(frame))).await; + fire_ws_event(&on_event, handle_id, "close", &JsValue::from_str(&info)); + ws_cleanup(handle_id); + return; + } + None => { + util::debug_log!("[ws:{handle_id}] command channel dropped, closing"); + let _ = sink.close().await; + ws_cleanup(handle_id); + return; + } + } + } + } +} + +/// Parse a JS value into WebSocket sub-protocol strings. +fn parse_protocols(val: &JsValue) -> Vec { + if val.is_undefined() || val.is_null() { + return Vec::new(); + } + if let Some(s) = val.as_string() { + return vec![s]; + } + if let Some(arr) = val.dyn_ref::() { + return (0..arr.length()) + .filter_map(|i| arr.get(i).as_string()) + .collect(); + } + Vec::new() +} + +/// Fire a WebSocket event: `onEvent(handleId, type, data)`. +fn fire_ws_event(on_event: &js_sys::Function, handle_id: u32, event_type: &str, data: &JsValue) { + if let Err(e) = on_event.call3( + &JsValue::NULL, + &JsValue::from(handle_id), + &JsValue::from_str(event_type), + data, + ) { + util::debug_error!("[ws:{handle_id}] callback error: {e:?}"); + } +} + +/// Remove a WebSocket handle from the global map. +fn ws_cleanup(handle_id: u32) { + util::debug_log!("[ws:{handle_id}] cleanup"); + if let Some(handles) = WS_HANDLES.get() { + handles.lock().unwrap().remove(&handle_id); + } +} diff --git a/wasm/smolmix/src/reactor.rs b/wasm/smolmix/src/reactor.rs new file mode 100644 index 0000000000..08608812a1 --- /dev/null +++ b/wasm/smolmix/src/reactor.rs @@ -0,0 +1,202 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +//! smoltcp poll loop for the WASM tunnel. +//! +//! Drives `Interface::poll()` in a single `spawn_local` task. The cadence is +//! adaptive: `poll_delay()` reports smoltcp's next soft deadline, the loop +//! sleeps until that deadline (capped by [`MAX_IDLE`]) or until a notification +//! arrives. smoltcp's per-socket `register_recv_waker`/`register_send_waker` +//! fire automatically on every state change. + +use std::sync::{Arc, Mutex, OnceLock}; +use std::time::Duration; + +use futures::FutureExt; +use nym_wasm_client_core::nym_task::ShutdownTracker; +use smoltcp::iface::{Interface, SocketHandle, SocketSet}; +use smoltcp::socket::tcp as smoltcp_tcp; +use smoltcp::time::Instant; +use tokio::sync::Notify; +use wasmtimer::std::Instant as MonotonicInstant; + +use crate::device::WasmDevice; +use crate::state::{State, TaskName}; + +/// Maximum idle sleep when smoltcp has no pending work. Bounds the latency of +/// TCP retransmit and keepalive timers if `poll_delay` ever returns `None`; on +/// an active connection the wake source is the bridge or a socket write. +const MAX_IDLE: Duration = Duration::from_secs(60); + +/// Shared smoltcp network stack, accessed by the reactor, bridge, and sockets. +/// +/// Inner is reached only via [`SmoltcpStack::with`], which scopes lock +/// acquisition to a single closure and prevents callers from holding the +/// guard across `.await` points. +/// +/// `Arc>` so that `WasmTunnel` can live in a +/// `OnceLock` which requires `Send + Sync`. On wasm32 (single-threaded), +/// `Mutex` is essentially a no-op lock, zero overhead vs `RefCell`. +#[derive(Clone)] +pub struct SmoltcpStack { + inner: Arc>, +} + +/// Inner state of the smoltcp stack. Only reachable inside a `with` closure. +pub(crate) struct SmoltcpStackInner { + pub(crate) iface: Interface, + pub(crate) sockets: SocketSet<'static>, + pub(crate) device: WasmDevice, + /// TCP handles awaiting clean removal: their `Drop` queued a FIN via + /// `socket.close()` but smoltcp hasn't transitioned to `State::Closed` + /// yet. Swept after each `iface.poll()`. + pub(crate) pending_removal: Vec, +} + +impl SmoltcpStack { + /// Construct a fresh stack around the given interface + device. + pub fn new(iface: Interface, device: WasmDevice) -> Self { + Self { + inner: Arc::new(Mutex::new(SmoltcpStackInner { + iface, + sockets: SocketSet::new(Vec::new()), + device, + pending_removal: Vec::new(), + })), + } + } + + /// Acquire the lock for a single bounded scope of work. + /// + /// The lock is held for the duration of the closure only; callers + /// physically cannot hold it across `.await` because the closure is + /// synchronous. + pub(crate) fn with(&self, f: impl FnOnce(&mut SmoltcpStackInner) -> R) -> R { + let mut g = self.inner.lock().unwrap_or_else(|p| p.into_inner()); + f(&mut g) + } +} + +/// Monotonic epoch anchor for `smoltcp_now`. Lazily initialised on first call. +static EPOCH: OnceLock = OnceLock::new(); + +/// Yield once to the JS microtask queue, then resume. +/// +/// `wasm_bindgen_futures` doesn't expose a `yield_now` directly, so we wake the +/// current task from `poll_fn` to give the executor a chance to process other +/// ready tasks (notify channel, socket wakers) before we re-poll smoltcp. +/// Cheaper than `wasmtimer::sleep(1ms)`, which goes through `setTimeout` +/// (browsers clamp to a ~4ms minimum). +async fn yield_now() { + let mut yielded = false; + futures::future::poll_fn(|cx| { + if yielded { + std::task::Poll::Ready(()) + } else { + yielded = true; + cx.waker().wake_by_ref(); + std::task::Poll::Pending + } + }) + .await +} + +/// Get the current smoltcp timestamp from a monotonic clock. +/// +/// smoltcp's `Instant` is an `i64` of microseconds relative to some epoch. +/// We anchor to the first call and report offsets from that. `wasmtimer::std::Instant` +/// is backed by `performance.now()` on wasm32, which is monotonic within the +/// current Worker agent per the W3C HR-Time spec — unlike `Date::now()`, which +/// can step backwards on NTP correction or user clock changes and would corrupt +/// smoltcp's retransmit/timeout maths. +pub fn smoltcp_now() -> Instant { + let epoch = *EPOCH.get_or_init(MonotonicInstant::now); + let elapsed_us = MonotonicInstant::now().duration_since(epoch).as_micros() as i64; + Instant::from_micros(elapsed_us) +} + +/// Wake source for the reactor. Multiple holders call `notify_one()` to ask +/// the reactor to re-poll smoltcp; coalescing is intrinsic to `tokio::sync::Notify` +/// (10 calls before the next iteration are equivalent to 1). +pub type ReactorNotify = Arc; + +/// Start the smoltcp reactor as a `spawn_local` background task. +/// +/// Each iteration: +/// 1. Lock the stack, call `iface.poll()` (which fires socket wakers internally). +/// 2. Ask smoltcp how long it can wait before the next poll (`poll_delay`). +/// 3. Sleep for that duration (capped at [`MAX_IDLE`]) or until a notification. +/// +/// Notifications come from the bridge (new rx packets in the device, needing +/// `iface.poll()` to ingest them) and from socket writes (data queued in +/// smoltcp's tx buffer, needing `iface.poll()` to dispatch it to the device). +pub fn start_reactor( + stack: SmoltcpStack, + notify: Arc, + tracker: &ShutdownTracker, + state: State, +) { + // Cloned so finalise_task can check is_cancelled() on the way out. + let token = tracker.clone_shutdown_token(); + tracker.try_spawn_named_with_shutdown( + async move { + loop { + // Poll smoltcp; built-in socket wakers fire on any state change. + let delay = stack.with(|s| { + let now = smoltcp_now(); + let SmoltcpStackInner { + iface, + sockets, + device, + pending_removal, + } = s; + iface.poll(now, device, sockets); + + // Sweep handles whose FIN/ACK exchange just completed. + pending_removal.retain(|&handle| { + if sockets.get::(handle).state() + == smoltcp_tcp::State::Closed + { + sockets.remove(handle); + false + } else { + true + } + }); + + iface.poll_delay(now, sockets) + }); + + // Translate smoltcp's deadline into a wait. A zero delay means + // "poll again immediately"; yield to the JS event loop via + // `yield_now()` rather than a 1ms `wasmtimer::sleep`, which + // schedules a `setTimeout` and is hit by browsers' ~4ms minimum + // clamp. + match delay { + Some(d) if d.total_micros() == 0 => { + yield_now().await; + } + other => { + let sleep_for = match other { + Some(d) => Duration::from_micros(d.total_micros()).min(MAX_IDLE), + None => MAX_IDLE, + }; + // `Notify` coalesces multiple `notify_one()` calls into + // one pending wake, so no drain loop needed. The + // explicit `token.cancelled()` arm lets us exit the + // loop cleanly into `finalise_task` on shutdown rather + // than being aborted mid-select by the supervisor wrapper. + futures::select! { + _ = wasmtimer::tokio::sleep(sleep_for).fuse() => {}, + _ = notify.notified().fuse() => {}, + _ = token.cancelled().fuse() => break, + } + } + } + } + + state.finalise_task(TaskName::Reactor, &token); + }, + "smolmix-reactor", + ); +} diff --git a/wasm/smolmix/src/state.rs b/wasm/smolmix/src/state.rs new file mode 100644 index 0000000000..8cfcfb0150 --- /dev/null +++ b/wasm/smolmix/src/state.rs @@ -0,0 +1,105 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +//! Tunnel lifecycle state. wasm32 builds with `panic = "abort"`, so +//! panic detection uses a chained hook + static atomic (see +//! [`install_panic_recorder`]) rather than `catch_unwind`. + +use std::sync::atomic::{AtomicBool, Ordering}; +use std::sync::{Arc, Mutex}; + +use serde::Serialize; + +use nym_wasm_client_core::nym_task::ShutdownToken; + +static WASM_PANICKED: AtomicBool = AtomicBool::new(false); + +/// Chain a recorder onto the existing panic hook. Call once after +/// `nym_wasm_utils::set_panic_hook()`. +pub(crate) fn install_panic_recorder() { + let prev = std::panic::take_hook(); + std::panic::set_hook(Box::new(move |info| { + WASM_PANICKED.store(true, Ordering::SeqCst); + prev(info); + })); +} + +#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)] +#[serde(rename_all = "snake_case")] +pub(crate) enum TaskName { + Bridge, + Reactor, +} + +#[derive(Clone, Debug, PartialEq, Eq, Serialize)] +#[serde(tag = "kind", rename_all = "snake_case")] +pub(crate) enum FailureReason { + TaskExited { task: TaskName }, + TaskPanicked, +} + +#[derive(Clone, Debug, PartialEq, Eq, Serialize)] +#[serde(tag = "state", rename_all = "snake_case")] +pub(crate) enum TunnelState { + Connecting, + Ready, + ShuttingDown, + Shutdown, + Failed { reason: FailureReason }, +} + +#[derive(Clone)] +pub(crate) struct State { + inner: Arc>, + /// Cancelled by [`State::fail`]; should point at smolmix_tracker, not base. + cascade: ShutdownToken, +} + +impl State { + pub(crate) fn new(cascade: ShutdownToken) -> Self { + Self { + inner: Arc::new(Mutex::new(TunnelState::Connecting)), + cascade, + } + } + + /// Reads the panic flag first; post-panic always returns Failed. + pub(crate) fn get(&self) -> TunnelState { + if WASM_PANICKED.load(Ordering::SeqCst) { + return TunnelState::Failed { + reason: FailureReason::TaskPanicked, + }; + } + self.inner.lock().unwrap().clone() + } + + pub(crate) fn is_ready(&self) -> bool { + matches!(self.get(), TunnelState::Ready) + } + + pub(crate) fn set(&self, new: TunnelState) { + *self.inner.lock().unwrap() = new; + } + + /// Call at the end of each task body; no-op if the token was cancelled. + pub(crate) fn finalise_task(&self, task: TaskName, token: &ShutdownToken) { + if token.is_cancelled() { + return; + } + self.fail(FailureReason::TaskExited { task }); + } + + /// First-failure-wins. Reads inner state directly (not via `get()`) + /// so the panic short-circuit doesn't suppress the cascade. + pub(crate) fn fail(&self, reason: FailureReason) { + use TunnelState::*; + { + let mut state = self.inner.lock().unwrap(); + if matches!(*state, Shutdown | ShuttingDown | Failed { .. }) { + return; + } + *state = Failed { reason }; + } + self.cascade.cancel(); + } +} diff --git a/wasm/smolmix/src/stream.rs b/wasm/smolmix/src/stream.rs new file mode 100644 index 0000000000..43dcb088bf --- /dev/null +++ b/wasm/smolmix/src/stream.rs @@ -0,0 +1,452 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +//! `futures::io` socket adapters over the smoltcp stack. + +use std::io; +use std::net::{IpAddr, SocketAddr}; +use std::pin::Pin; +use std::sync::atomic::{AtomicU16, Ordering}; +use std::task::{Context, Poll}; +use std::time::Duration; + +use futures::io::{AsyncRead, AsyncWrite}; +use smoltcp::iface::SocketHandle; +use smoltcp::socket::tcp as smoltcp_tcp; +use smoltcp::socket::udp as smoltcp_udp; +use smoltcp::wire::{IpAddress, IpEndpoint}; + +use crate::reactor::{ReactorNotify, SmoltcpStack}; + +/// First port in the ephemeral range. Per IANA, 49152-65535 is the dynamic / +/// private range with no IANA-assigned services, safe for client sockets. +pub(crate) const EPHEMERAL_PORT_START: u16 = 49152; + +/// A pooled connection (TLS or plain TCP). Delegates `AsyncRead + AsyncWrite`. +/// The `Tls` variant compiles in only when `fetch` or `socket` features are +/// enabled, since plaintext-only builds (the `dns`-only TS SDK package) don't +/// need a TLS stack at all. +/// +/// `Tls` is intentionally inlined (~744 B) rather than boxed: the pool holds +/// at most one entry per (host, port), so total memory is bounded by distinct +/// origins visited over the tunnel's lifetime. Boxing would force every match +/// arm into a `Box`-deref dance for no real benefit at typical usage. +#[allow(clippy::large_enum_variant)] +pub(crate) enum PooledConn { + #[cfg(any(feature = "fetch", feature = "socket"))] + Tls(crate::tls::MaybeCloseNotify>), + Plain(WasmTcpStream), +} + +/// TCP stream over the WASM tunnel. Implements `futures::io::{AsyncRead, AsyncWrite}`. +pub struct WasmTcpStream { + pub(crate) stack: SmoltcpStack, + pub(crate) handle: SocketHandle, + pub(crate) notify: ReactorNotify, + /// Set once `socket.close()` has been called (via `poll_close` or + /// `Drop`). Makes the close path idempotent. + closed: bool, +} + +/// UDP socket over the WASM tunnel. Used for DNS queries. +pub struct WasmUdpSocket { + pub(crate) stack: SmoltcpStack, + pub(crate) handle: SocketHandle, + pub(crate) notify: ReactorNotify, +} + +impl AsyncRead for WasmTcpStream { + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + let handle = self.handle; + let notify = &self.notify; + self.stack.with(|s| { + let socket = s.sockets.get_mut::(handle); + + if socket.can_recv() { + let n = socket + .recv_slice(buf) + .map_err(|e| io::Error::other(format!("{e}")))?; + crate::util::debug_log!("[tcp:read] Ready({n})"); + // Notify reactor: recv_slice() frees rx buffer, needs a + // prompt window update ACK to keep the sender flowing. + notify.notify_one(); + Poll::Ready(Ok(n)) + } else if !socket.may_recv() { + // Remote sent FIN (EOF). `may_recv()` is false for CloseWait, + // LastAck, Closed, TimeWait (unlike `is_open()` which misses CloseWait). + Poll::Ready(Ok(0)) + } else { + crate::util::debug_log!( + "[tcp:read] Pending (state={:?}, buf={})", + socket.state(), + buf.len(), + ); + // smoltcp wakes this waker on any state change affecting `recv`, + // including FIN/CloseWait transitions that produce EOF. + socket.register_recv_waker(cx.waker()); + Poll::Pending + } + }) + } +} + +impl AsyncWrite for WasmTcpStream { + fn poll_write( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + let handle = self.handle; + let notify = &self.notify; + self.stack.with(|s| { + let socket = s.sockets.get_mut::(handle); + + if socket.can_send() { + let n = socket + .send_slice(buf) + .map_err(|e| io::Error::other(format!("{e}")))?; + notify.notify_one(); + Poll::Ready(Ok(n)) + } else if !socket.is_open() { + Poll::Ready(Err(io::Error::new( + io::ErrorKind::BrokenPipe, + "socket closed", + ))) + } else { + socket.register_send_waker(cx.waker()); + Poll::Pending + } + }) + } + + fn poll_flush(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll> { + // Nudge the reactor so any queued tx data dispatches promptly rather + // than waiting for the next `poll_delay` deadline. + self.notify.notify_one(); + Poll::Ready(Ok(())) + } + + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + let this = self.get_mut(); + let handle = this.handle; + let notify = &this.notify; + let closed = &mut this.closed; + this.stack.with(|s| { + let socket = s.sockets.get_mut::(handle); + if !*closed { + socket.close(); + *closed = true; + notify.notify_one(); + } + if socket.state() == smoltcp_tcp::State::Closed { + Poll::Ready(Ok(())) + } else { + // Wake on state-change progress through the FIN/ACK exchange. + socket.register_send_waker(cx.waker()); + Poll::Pending + } + }) + } +} + +impl Unpin for WasmTcpStream {} + +impl Drop for WasmTcpStream { + fn drop(&mut self) { + // Queue a FIN (vs `abort()` which sends RST). The + // reactor's pending_removal sweep removes the handle once smoltcp + // transitions through the FIN/ACK exchange to State::Closed. + let handle = self.handle; + self.stack.with(|s| { + s.sockets.get_mut::(handle).close(); + s.pending_removal.push(handle); + }); + self.notify.notify_one(); + } +} + +impl AsyncRead for PooledConn { + fn poll_read( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + match self.get_mut() { + #[cfg(any(feature = "fetch", feature = "socket"))] + PooledConn::Tls(s) => Pin::new(s).poll_read(cx, buf), + PooledConn::Plain(s) => Pin::new(s).poll_read(cx, buf), + } + } +} + +impl AsyncWrite for PooledConn { + fn poll_write( + self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + match self.get_mut() { + #[cfg(any(feature = "fetch", feature = "socket"))] + PooledConn::Tls(s) => Pin::new(s).poll_write(cx, buf), + PooledConn::Plain(s) => Pin::new(s).poll_write(cx, buf), + } + } + + fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.get_mut() { + #[cfg(any(feature = "fetch", feature = "socket"))] + PooledConn::Tls(s) => Pin::new(s).poll_flush(cx), + PooledConn::Plain(s) => Pin::new(s).poll_flush(cx), + } + } + + fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + match self.get_mut() { + #[cfg(any(feature = "fetch", feature = "socket"))] + PooledConn::Tls(s) => Pin::new(s).poll_close(cx), + PooledConn::Plain(s) => Pin::new(s).poll_close(cx), + } + } +} + +impl Unpin for PooledConn {} + +impl WasmUdpSocket { + /// Send a datagram to the given address. + pub async fn send_to(&self, buf: &[u8], target: SocketAddr) -> io::Result { + let endpoint = to_smoltcp_endpoint(target); + let stack = self.stack.clone(); + let handle = self.handle; + let notify = self.notify.clone(); + + futures::future::poll_fn(move |cx| { + stack.with(|s| { + let socket = s.sockets.get_mut::(handle); + + if socket.can_send() { + socket + .send_slice(buf, endpoint) + .map_err(|e| io::Error::other(format!("{e}")))?; + notify.notify_one(); + Poll::Ready(Ok(buf.len())) + } else { + socket.register_send_waker(cx.waker()); + Poll::Pending + } + }) + }) + .await + } + + /// Receive a datagram, returning (bytes_read, source_address). + pub async fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> { + let stack = self.stack.clone(); + let handle = self.handle; + + futures::future::poll_fn(move |cx| { + stack.with(|s| { + let socket = s.sockets.get_mut::(handle); + + if socket.can_recv() { + let (n, meta) = socket + .recv_slice(buf) + .map_err(|e| io::Error::other(format!("{e}")))?; + let src = from_smoltcp_endpoint(meta.endpoint); + Poll::Ready(Ok((n, src))) + } else { + socket.register_recv_waker(cx.waker()); + Poll::Pending + } + }) + }) + .await + } +} + +impl Drop for WasmUdpSocket { + fn drop(&mut self) { + let handle = self.handle; + self.stack.with(|s| { + s.sockets.remove(handle); + }); + } +} + +/// Process-wide ephemeral port counter, seeded at [`EPHEMERAL_PORT_START`]. +static EPHEMERAL_PORT: AtomicU16 = AtomicU16::new(EPHEMERAL_PORT_START); + +/// Allocate the next ephemeral port (wraps at `u16::MAX` back to +/// [`EPHEMERAL_PORT_START`]). Single-threaded wasm32 means a plain +/// load/store is race-free; the atomic exists for `Sync`. +pub(crate) fn allocate_port() -> u16 { + let current = EPHEMERAL_PORT.load(Ordering::Relaxed); + let next = if current == u16::MAX { + EPHEMERAL_PORT_START + } else { + current + 1 + }; + EPHEMERAL_PORT.store(next, Ordering::Relaxed); + current +} + +/// Drop-bomb for a `SocketHandle` mid-flight in `tcp_connect`. If the caller +/// errors out before producing a `WasmTcpStream`, `Drop` removes the handle +/// from the `SocketSet`. On success, `defuse()` disarms the guard and hands +/// back the handle for ownership transfer into `WasmTcpStream`. +struct InflightSocket { + stack: Option, + handle: SocketHandle, +} + +impl InflightSocket { + fn defuse(mut self) -> SocketHandle { + self.stack = None; + self.handle + } +} + +impl Drop for InflightSocket { + fn drop(&mut self) { + if let Some(stack) = self.stack.take() { + let handle = self.handle; + stack.with(|s| { + s.sockets.remove(handle); + }); + } + } +} + +/// Open a TCP connection through the tunnel and wait for `Established`. +/// +/// Used by `WasmTunnel::tcp_connect` and by the DNS resolver provider; both +/// draw from the process-wide [`EPHEMERAL_PORT`] counter so allocations +/// don't collide. +pub(crate) async fn tcp_connect( + stack: SmoltcpStack, + notify: ReactorNotify, + addr: SocketAddr, + keepalive: Duration, + buffer_size: usize, +) -> io::Result { + let remote = to_smoltcp_endpoint(addr); + let local_port = allocate_port(); + // Caller-supplied buffer size, capped at u16::MAX (TCP window field width). + let buf_size = buffer_size.min(u16::MAX as usize); + let tcp_rx = smoltcp_tcp::SocketBuffer::new(vec![0; buf_size]); + let tcp_tx = smoltcp_tcp::SocketBuffer::new(vec![0; buf_size]); + let mut socket = smoltcp_tcp::Socket::new(tcp_rx, tcp_tx); + socket.set_keep_alive(Some(smoltcp::time::Duration::from_millis( + keepalive.as_millis() as u64, + ))); + + // Synchronous phase: add + connect under one lock. If `connect()` errors, + // clean up immediately while we still hold the lock. + let handle = stack.with(|s| -> io::Result { + let handle = s.sockets.add(socket); + let crate::reactor::SmoltcpStackInner { iface, sockets, .. } = s; + if let Err(e) = sockets.get_mut::(handle).connect( + iface.context(), + remote, + local_port, + ) { + sockets.remove(handle); + return Err(io::Error::new( + io::ErrorKind::InvalidInput, + format!("{e:?}"), + )); + } + Ok(handle) + })?; + + notify.notify_one(); + + // Async phase: any error past this point must remove the socket. The + // guard removes it on drop; we defuse it once the stream is constructed. + let guard = InflightSocket { + stack: Some(stack.clone()), + handle, + }; + + { + let stack = stack.clone(); + futures::future::poll_fn(move |cx| { + stack.with(|s| { + let socket = s.sockets.get_mut::(handle); + match socket.state() { + smoltcp_tcp::State::Established | smoltcp_tcp::State::CloseWait => { + Poll::Ready(Ok(())) + } + smoltcp_tcp::State::Closed => { + crate::util::debug_error!("[stream] TCP state: Closed, connection failed"); + Poll::Ready(Err(io::Error::new( + io::ErrorKind::ConnectionRefused, + "TCP connection failed", + ))) + } + _ => { + socket.register_recv_waker(cx.waker()); + Poll::Pending + } + } + }) + }) + .await?; + } + + Ok(WasmTcpStream { + stack, + handle: guard.defuse(), + notify, + closed: false, + }) +} + +/// Create a UDP socket bound to a fresh ephemeral port. +pub(crate) fn create_udp_socket( + stack: SmoltcpStack, + notify: ReactorNotify, +) -> io::Result { + let local_port = allocate_port(); + let udp_rx = smoltcp_udp::PacketBuffer::new( + vec![smoltcp_udp::PacketMetadata::EMPTY; 16], + vec![0; 65535], + ); + let udp_tx = smoltcp_udp::PacketBuffer::new( + vec![smoltcp_udp::PacketMetadata::EMPTY; 16], + vec![0; 65535], + ); + let mut socket = smoltcp_udp::Socket::new(udp_rx, udp_tx); + socket + .bind(local_port) + .map_err(|_| io::Error::new(io::ErrorKind::AddrInUse, "UDP bind failed"))?; + + let handle = stack.with(|s| s.sockets.add(socket)); + + Ok(WasmUdpSocket { + stack, + handle, + notify, + }) +} + +// Address conversion helpers + +pub(crate) fn to_smoltcp_endpoint(addr: SocketAddr) -> IpEndpoint { + let ip = match addr.ip() { + IpAddr::V4(v4) => IpAddress::Ipv4(v4), + IpAddr::V6(v6) => IpAddress::Ipv6(v6), + }; + IpEndpoint::new(ip, addr.port()) +} + +pub(crate) fn from_smoltcp_endpoint(ep: IpEndpoint) -> SocketAddr { + let ip = match ep.addr { + IpAddress::Ipv4(v4) => IpAddr::V4(v4), + IpAddress::Ipv6(v6) => IpAddr::V6(v6), + }; + SocketAddr::new(ip, ep.port) +} diff --git a/wasm/smolmix/src/tls.rs b/wasm/smolmix/src/tls.rs new file mode 100644 index 0000000000..c9ac8604f1 --- /dev/null +++ b/wasm/smolmix/src/tls.rs @@ -0,0 +1,164 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +//! TLS connector using futures-rustls (futures::io traits, NOT tokio). +//! +//! Crypto provider: rustls-rustcrypto (RustCrypto-backed pure-Rust primitives). +//! + +use std::io; +use std::pin::Pin; +use std::sync::{Arc, OnceLock}; +use std::task::{Context, Poll}; + +use futures::io::{AsyncRead, AsyncWrite}; +use futures_rustls::TlsConnector; +use rustls::pki_types::ServerName; +use rustls::{CipherSuite, ClientConfig}; + +use crate::error::FetchError; + +/// Cached TLS client config: built once, reused for all connections. +static TLS_CONFIG: OnceLock> = OnceLock::new(); + +/// TLS stream wrapper that tolerates a missing `close_notify` from the peer. +/// +/// rustls reports a peer closing the underlying TCP connection without sending +/// the TLS `close_notify` alert as `io::ErrorKind::UnexpectedEof`. Many CDNs +/// (and older servers) do this routinely, and hyper then surfaces it as a body +/// framing error even when the HTTP response was completely received per its +/// Content-Length / chunked terminator. +/// +/// This wrapper translates `UnexpectedEof` on `poll_read` to a clean `Ok(0)` +/// (EOF). hyper's body framing is authoritative for whether the message is +/// complete — if it isn't, hyper will report truncation on its own terms. The +/// only attack surface this opens is for HTTP/1.0-style "read to EOF" bodies, +/// which were already truncatable and which modern frameworks don't use. +/// +/// Writes pass through unchanged. +pub struct MaybeCloseNotify { + inner: S, +} + +impl MaybeCloseNotify { + pub fn new(inner: S) -> Self { + Self { inner } + } +} + +impl AsyncRead for MaybeCloseNotify { + fn poll_read( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &mut [u8], + ) -> Poll> { + match Pin::new(&mut self.inner).poll_read(cx, buf) { + Poll::Ready(Err(e)) if e.kind() == io::ErrorKind::UnexpectedEof => { + crate::util::debug_log!("[tls] peer closed without close_notify, treating as EOF"); + Poll::Ready(Ok(0)) + } + other => other, + } + } +} + +impl AsyncWrite for MaybeCloseNotify { + fn poll_write( + mut self: Pin<&mut Self>, + cx: &mut Context<'_>, + buf: &[u8], + ) -> Poll> { + Pin::new(&mut self.inner).poll_write(cx, buf) + } + + fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.inner).poll_flush(cx) + } + + fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { + Pin::new(&mut self.inner).poll_close(cx) + } +} + +/// Perform a TLS handshake over the given stream. +/// +/// Returns a `MaybeCloseNotify`-wrapped TLS stream so that peers omitting +/// the TLS `close_notify` shutdown alert don't cause spurious body-framing +/// errors at the hyper layer. +pub async fn connect( + stream: S, + hostname: &str, +) -> Result>, FetchError> +where + S: AsyncRead + AsyncWrite + Unpin, +{ + let config = make_client_config()?; + let connector = TlsConnector::from(config); + + // ServerName::try_from(String) gives ServerName<'static> (owned), + // which is what futures-rustls::TlsConnector::connect requires. + let server_name = ServerName::try_from(hostname.to_string()) + .map_err(|e| FetchError::Dns(format!("invalid TLS server name '{hostname}': {e}")))?; + + let result = connector + .connect(server_name, stream) + .await + .map(MaybeCloseNotify::new) + .map_err(FetchError::Io); + + if let Err(e) = &result { + crate::util::debug_error!("[tls] handshake FAILED with '{hostname}': {e}"); + } + + result +} + +/// Get or build the cached rustls ClientConfig with the webpki-roots CA bundle. +/// +/// The config (crypto provider, root CA store, protocol versions) is identical +/// for every connection, so we build it once and reuse the `Arc`. +fn make_client_config() -> Result, FetchError> { + if let Some(config) = TLS_CONFIG.get() { + return Ok(config.clone()); + } + + // Restrict cipher suites to only what is explicity implemented as + // per https://github.com/RustCrypto/rustls-rustcrypto#rustls-rustcrypto. + let mut provider = rustls_rustcrypto::provider(); + provider.cipher_suites.retain(|s| { + matches!( + s.suite(), + CipherSuite::TLS13_AES_128_GCM_SHA256 + | CipherSuite::TLS13_AES_256_GCM_SHA384 + | CipherSuite::TLS13_CHACHA20_POLY1305_SHA256 + | CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 + | CipherSuite::TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 + | CipherSuite::TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 + | CipherSuite::TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 + | CipherSuite::TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 + | CipherSuite::TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 + ) + }); + let provider = Arc::new(provider); + + let mut root_store = rustls::RootCertStore::empty(); + root_store.extend(webpki_roots::TLS_SERVER_ROOTS.iter().cloned()); + + let mut config = ClientConfig::builder_with_provider(provider) + .with_safe_default_protocol_versions() + .map_err(|e| FetchError::Http(format!("TLS config error: {e}")))? + .with_root_certificates(root_store) + .with_no_client_auth(); + + // ALPN: advertise HTTP/1.1 so CDNs (GitHub, Cloudflare) that require + // protocol negotiation don't abort the handshake with an EOF. + config.alpn_protocols = vec![b"http/1.1".to_vec()]; + + // Disable session resumption: TLS session tickets and PSK identities are + // long-lived correlators a server can use to link separate mixnet circuits + // back to the same client, defeating per-request unlinkability. + config.resumption = rustls::client::Resumption::disabled(); + + let config = Arc::new(config); + Ok(TLS_CONFIG.get_or_init(|| config.clone()).clone()) +} diff --git a/wasm/smolmix/src/tunnel.rs b/wasm/smolmix/src/tunnel.rs new file mode 100644 index 0000000000..ad2be993f2 --- /dev/null +++ b/wasm/smolmix/src/tunnel.rs @@ -0,0 +1,623 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +//! WASM mixnet tunnel. Manages a smoltcp TCP/IP stack connected to the Nym +//! mixnet via an IPR (IP Packet Router), running in a browser Web Worker. +//! +//! Data flow: +//! ```text +//! poll_write → smoltcp → device tx → bridge → LP frame → mixnet → IPR → internet +//! internet → IPR → mixnet → bridge → LP decode → device rx → smoltcp → poll_read +//! ``` + +use std::collections::HashMap; +use std::io; +use std::net::{IpAddr, SocketAddr}; +use std::sync::{Arc, Mutex}; +use std::time::Duration; + +use futures::channel::mpsc; +use smoltcp::iface::Config; +use smoltcp::wire::{HardwareAddress, IpAddress, IpCidr, Ipv4Address, Ipv6Address}; +use tokio::sync::Notify; + +use nym_ip_packet_requests::IpPair; +use nym_wasm_client_core::client::base_client::{BaseClientBuilder, ClientInput}; +use nym_wasm_client_core::client::received_buffer::ReceivedBufferMessage; +use nym_wasm_client_core::config::new_base_client_config; +use nym_wasm_client_core::helpers::{add_gateway, generate_new_client_keys}; +use nym_wasm_client_core::nym_task::ShutdownTracker; +use nym_wasm_client_core::storage::ClientStorage; +use nym_wasm_client_core::storage::core_client_traits::FullWasmClientStorage; +use nym_wasm_client_core::storage::wasm_client_traits::WasmClientStorage; +use nym_wasm_client_core::{QueryReqwestRpcNyxdClient, Recipient}; + +use crate::bridge; +use crate::device::WasmDevice; +use crate::error::FetchError; +use crate::ipr; +use crate::reactor::{self, ReactorNotify, SmoltcpStack, smoltcp_now}; +use crate::state; +use crate::stream::{self, PooledConn, WasmTcpStream, WasmUdpSocket}; + +/// Configuration for `setupMixTunnel(opts)`. +/// +/// Construct directly or via [`TunnelOpts::builder`] for chainable configuration. +/// Performance/timeout tuning lives in [`TuningOpts`] under the `tuning` field. +pub struct TunnelOpts { + /// `None` triggers performance-weighted auto-discovery via `ipr::discover_ipr`. + pub ipr_address: Option, + /// Client storage ID. Randomise per session to get a clean client. + pub client_id: String, + /// Use `wss://` for gateway connections (default: `true`). + pub force_tls: bool, + /// Disable Poisson-distributed dummy traffic (default: `false`). + pub disable_poisson_traffic: bool, + /// Disable cover traffic loop (default: `false`). + pub disable_cover_traffic: bool, + /// Reply-SURB counts for the LP Open frame and each Data frame the + /// bridge sends. See [`ipr::SurbsConfig`]. Defaults to open=5, data=2. + pub surbs: ipr::SurbsConfig, + /// Primary DNS resolver. `None` falls back to [`dns::DEFAULT_PRIMARY_DNS`]. + pub primary_dns: Option, + /// Fallback DNS resolver. `None` falls back to [`dns::DEFAULT_FALLBACK_DNS`]. + pub fallback_dns: Option, + /// Passphrase used to encrypt the client's persistent storage (identity + /// keys, gateway details, etc). `None` means plaintext storage. The same + /// passphrase must be supplied on subsequent loads to read the same keys. + pub storage_passphrase: Option, + /// Timeouts + buffer sizes + redirect limits. See [`TuningOpts`]. + pub tuning: TuningOpts, +} + +/// Performance + protocol-limit tuning knobs. +/// +/// All fields have sensible defaults via [`TuningOpts::default`]; consumers +/// override via the chainable builder methods on [`TunnelOptsBuilder`]. +pub struct TuningOpts { + /// IPR connect handshake timeout. + pub connect_timeout: Duration, + /// DNS query timeout (per attempt, primary or fallback). + pub dns_timeout: Duration, + /// TCP keepalive interval; smoltcp probes the peer at this cadence. + pub tcp_keepalive_interval: Duration, + /// Per-TCP-stream RX/TX buffer size in bytes. Trades memory for throughput. + /// Capped to `u16::MAX` (65535) to fit the TCP window field width. + pub tcp_buffer_size: usize, + /// Maximum HTTP redirect chain depth before `mixFetch` gives up. + pub max_redirects: u8, +} + +impl Default for TuningOpts { + fn default() -> Self { + Self { + connect_timeout: Duration::from_secs(60), + dns_timeout: Duration::from_secs(30), + tcp_keepalive_interval: Duration::from_secs(10), + tcp_buffer_size: 65535, + max_redirects: 5, + } + } +} + +impl TunnelOpts { + /// Start a chainable builder. + pub fn builder() -> TunnelOptsBuilder { + TunnelOptsBuilder::default() + } +} + +/// Chainable builder for [`TunnelOpts`]. Setters for tuning fields delegate +/// into the nested [`TuningOpts`] at `build()` time, so callers see a flat API. +#[derive(Default)] +pub struct TunnelOptsBuilder { + ipr_address: Option, + client_id: Option, + force_tls: Option, + disable_poisson_traffic: Option, + disable_cover_traffic: Option, + surbs: Option, + primary_dns: Option, + fallback_dns: Option, + storage_passphrase: Option, + connect_timeout: Option, + dns_timeout: Option, + tcp_keepalive_interval: Option, + tcp_buffer_size: Option, + max_redirects: Option, +} + +impl TunnelOptsBuilder { + pub fn ipr_address(mut self, v: Recipient) -> Self { + self.ipr_address = Some(v); + self + } + pub fn client_id(mut self, v: impl Into) -> Self { + self.client_id = Some(v.into()); + self + } + pub fn force_tls(mut self, v: bool) -> Self { + self.force_tls = Some(v); + self + } + pub fn disable_poisson_traffic(mut self, v: bool) -> Self { + self.disable_poisson_traffic = Some(v); + self + } + pub fn disable_cover_traffic(mut self, v: bool) -> Self { + self.disable_cover_traffic = Some(v); + self + } + pub fn surbs(mut self, v: ipr::SurbsConfig) -> Self { + self.surbs = Some(v); + self + } + pub fn primary_dns(mut self, v: SocketAddr) -> Self { + self.primary_dns = Some(v); + self + } + pub fn fallback_dns(mut self, v: SocketAddr) -> Self { + self.fallback_dns = Some(v); + self + } + pub fn storage_passphrase(mut self, v: impl Into) -> Self { + self.storage_passphrase = Some(v.into()); + self + } + pub fn connect_timeout(mut self, v: Duration) -> Self { + self.connect_timeout = Some(v); + self + } + pub fn dns_timeout(mut self, v: Duration) -> Self { + self.dns_timeout = Some(v); + self + } + pub fn tcp_keepalive_interval(mut self, v: Duration) -> Self { + self.tcp_keepalive_interval = Some(v); + self + } + pub fn tcp_buffer_size(mut self, v: usize) -> Self { + self.tcp_buffer_size = Some(v); + self + } + pub fn max_redirects(mut self, v: u8) -> Self { + self.max_redirects = Some(v); + self + } + + pub fn build(self) -> TunnelOpts { + let defaults = TuningOpts::default(); + TunnelOpts { + ipr_address: self.ipr_address, + client_id: self.client_id.unwrap_or_else(|| "smolmix-wasm".to_string()), + force_tls: self.force_tls.unwrap_or(true), + disable_poisson_traffic: self.disable_poisson_traffic.unwrap_or(false), + disable_cover_traffic: self.disable_cover_traffic.unwrap_or(false), + surbs: self.surbs.unwrap_or_default(), + primary_dns: self.primary_dns, + fallback_dns: self.fallback_dns, + storage_passphrase: self.storage_passphrase, + tuning: TuningOpts { + connect_timeout: self.connect_timeout.unwrap_or(defaults.connect_timeout), + dns_timeout: self.dns_timeout.unwrap_or(defaults.dns_timeout), + tcp_keepalive_interval: self + .tcp_keepalive_interval + .unwrap_or(defaults.tcp_keepalive_interval), + tcp_buffer_size: self.tcp_buffer_size.unwrap_or(defaults.tcp_buffer_size), + max_redirects: self.max_redirects.unwrap_or(defaults.max_redirects), + }, + } + } +} + +/// The mixnet tunnel. Owns the smoltcp stack, base client, and connection pool. +pub struct WasmTunnel { + stack: SmoltcpStack, + notify: ReactorNotify, + allocated_ips: IpPair, + /// Resolved per-tunnel DNS endpoints (primary, fallback). Either falls + /// back to the constants in [`dns`] when the caller didn't override. + dns_primary: SocketAddr, + dns_fallback: SocketAddr, + /// All timeouts + buffer sizes + redirect limits; populated from + /// [`TunnelOpts::tuning`] at construction. + tuning: TuningOpts, + /// Plain per-session DNS cache. No TTL respect (cache lives until tunnel + /// shutdown). See [`dns::resolve`] for usage. + dns_cache: Mutex>, + /// Serialises DNS lookups so concurrent callers coalesce on the cache. + dns_lock: futures::lock::Mutex<()>, + /// One idle connection per (host, port). + conn_pool: Mutex>, + /// Per-origin locks to avoid stampeding parallel TCP+TLS handshakes. + #[allow(clippy::type_complexity)] + origin_locks: Mutex>>>, + /// `Mutex>` because `ShutdownTracker::shutdown(self).await` + /// takes ownership, but `WasmTunnel` lives in a `OnceLock`. + base_tracker: Mutex>, + /// Child of `base_tracker`; bridge + reactor spawn through it. + smolmix_tracker: Mutex>, + state: state::State, +} + +/// Handles the Nym base client hands back after `start_base()`. +struct ClientHandles { + client_input: Arc, + reconstructed_receiver: ipr::ReconstructedReceiver, + shutdown_handle: ShutdownTracker, + /// Lifted out so `ipr::discover_ipr` reuses the same URLs the base client did. + nym_api_urls: Vec, +} + +/// smoltcp handles returned by `init_network_stack` (reactor + bridge already spawned). +struct NetworkStack { + stack: SmoltcpStack, + notify: ReactorNotify, +} + +impl WasmTunnel { + /// Connect to the mixnet and establish an IPR tunnel. + pub async fn new(opts: TunnelOpts) -> Result { + nym_wasm_utils::console_log!("[smolmix] starting tunnel..."); + + let ClientHandles { + client_input, + mut reconstructed_receiver, + shutdown_handle, + nym_api_urls, + } = Self::start_nym_client(&opts).await?; + + // Cascade points at smolmix_tracker so state.fail() only kills + // smolmix tasks; shutdown() handles the base client. + let smolmix_tracker = shutdown_handle.child_tracker(); + let state = state::State::new(smolmix_tracker.clone_shutdown_token()); + + let ipr_address = match opts.ipr_address { + Some(addr) => addr, + None => { + nym_wasm_utils::console_log!("[smolmix] no IPR specified, auto-discovering..."); + ipr::discover_ipr(&nym_api_urls).await? + } + }; + + let stream_id: u64 = rand::random(); + let allocated_ips = Self::ipr_handshake( + &client_input, + &mut reconstructed_receiver, + &ipr_address, + stream_id, + opts.surbs, + opts.tuning.connect_timeout, + ) + .await?; + + let NetworkStack { stack, notify } = Self::init_network_stack( + allocated_ips, + client_input.clone(), + reconstructed_receiver, + ipr_address, + stream_id, + &smolmix_tracker, + &state, + opts.surbs.data, + ); + + state.set(state::TunnelState::Ready); + nym_wasm_utils::console_log!("[smolmix] tunnel ready"); + + Ok(Self { + stack, + notify, + allocated_ips, + dns_primary: opts.primary_dns.unwrap_or(crate::dns::DEFAULT_PRIMARY_DNS), + dns_fallback: opts + .fallback_dns + .unwrap_or(crate::dns::DEFAULT_FALLBACK_DNS), + tuning: opts.tuning, + dns_cache: Mutex::new(HashMap::new()), + dns_lock: futures::lock::Mutex::new(()), + conn_pool: Mutex::new(HashMap::new()), + origin_locks: Mutex::new(HashMap::new()), + base_tracker: Mutex::new(Some(shutdown_handle)), + smolmix_tracker: Mutex::new(Some(smolmix_tracker)), + state, + }) + } + + /// Configure storage, generate identity keys if needed, register a gateway, + /// and start the Nym base client. Returns the producer/consumer channels. + async fn start_nym_client(opts: &TunnelOpts) -> Result { + let mut config = new_base_client_config( + opts.client_id.clone(), + env!("CARGO_PKG_VERSION").to_string(), + None, // nym_api: use default + None, // nyxd: use default + None, // debug: use default + ) + .map_err(|e| FetchError::Tunnel(format!("config error: {e}")))?; + + config.debug.topology.ignore_egress_epoch_role = true; + config + .debug + .traffic + .disable_main_poisson_packet_distribution = opts.disable_poisson_traffic; + config.debug.cover_traffic.disable_loop_cover_traffic_stream = opts.disable_cover_traffic; + + let client_store = + ClientStorage::new_async(&opts.client_id, opts.storage_passphrase.clone()) + .await + .map_err(|e| FetchError::Tunnel(format!("storage error: {e}")))?; + + if !client_store + .has_identity_key() + .await + .map_err(|e| FetchError::Tunnel(format!("storage error: {e}")))? + { + generate_new_client_keys(&client_store) + .await + .map_err(|e| FetchError::Tunnel(format!("keygen error: {e}")))?; + } + + let has_gateway = client_store + .get_active_gateway_id() + .await + .map_err(|e| FetchError::Tunnel(format!("gateway-storage error: {e}")))? + .active_gateway_id_bs58 + .is_some(); + + if !has_gateway { + let user_agent = nym_bin_common::bin_info!().into(); + add_gateway( + None, // preferred_gateway + None, // latency_based_selection + opts.force_tls, + &config.client.nym_api_urls, + user_agent, + config.debug.topology.minimum_gateway_performance, + config.debug.topology.ignore_ingress_epoch_role, + &client_store, + ) + .await + .map_err(|e| FetchError::Tunnel(format!("gateway selection error: {e}")))?; + } + + let storage = FullWasmClientStorage::new(&config, client_store); + let base_builder = + BaseClientBuilder::::new(config.clone(), storage, None); + + let mut started_client = base_builder + .start_base() + .await + .map_err(|e| FetchError::Tunnel(format!("client start error: {e}")))?; + + let client_input = Arc::new(started_client.client_input.register_producer()); + let client_output = started_client.client_output.register_consumer(); + + let (reconstructed_sender, reconstructed_receiver) = mpsc::unbounded(); + client_output + .received_buffer_request_sender + .unbounded_send(ReceivedBufferMessage::ReceiverAnnounce( + reconstructed_sender, + )) + .map_err(|_| FetchError::Tunnel("failed to register message receiver".into()))?; + + Ok(ClientHandles { + client_input, + reconstructed_receiver, + shutdown_handle: started_client.shutdown_handle, + nym_api_urls: config.client.nym_api_urls.clone(), + }) + } + + /// Open the LP stream + run the IPR v9 connect handshake. Returns the + /// IPs the IPR allocated for this tunnel. + async fn ipr_handshake( + client_input: &Arc, + receiver: &mut ipr::ReconstructedReceiver, + ipr_address: &Recipient, + stream_id: u64, + surbs: ipr::SurbsConfig, + connect_timeout: Duration, + ) -> Result { + nym_wasm_utils::console_log!("[smolmix] connecting to IPR..."); + let allocated_ips = ipr::open_and_connect( + client_input, + receiver, + ipr_address, + stream_id, + surbs, + connect_timeout, + ) + .await?; + nym_wasm_utils::console_log!("[smolmix] IPR connected"); + crate::util::debug_log!( + "[smolmix] allocated IPv4: {}, IPv6: {}", + allocated_ips.ipv4, + allocated_ips.ipv6, + ); + Ok(allocated_ips) + } + + /// Build the smoltcp interface, spawn the reactor + bridge, and return + /// the shared handles the tunnel keeps to drive the stack. + #[allow(clippy::too_many_arguments)] + fn init_network_stack( + allocated_ips: IpPair, + client_input: Arc, + reconstructed_receiver: ipr::ReconstructedReceiver, + ipr_address: Recipient, + stream_id: u64, + tracker: &ShutdownTracker, + state: &state::State, + data_surbs: u32, + ) -> NetworkStack { + let mut device = WasmDevice::new(); + let iface_config = Config::new(HardwareAddress::Ip); + let mut iface = smoltcp::iface::Interface::new(iface_config, &mut device, smoltcp_now()); + + // smoltcp's address + route tables are heapless vecs with capacity + // IFACE_MAX_ADDR_COUNT / IFACE_MAX_ROUTE_COUNT (default 8 each). + // We add 2 of each on a fresh interface; capacity is the only failure + // mode, so an .expect is fine here. + iface.update_ip_addrs(|addrs| { + addrs + .push(IpCidr::new(IpAddress::from(allocated_ips.ipv4), 32)) + .expect("smoltcp address vec full"); + addrs + .push(IpCidr::new(IpAddress::from(allocated_ips.ipv6), 128)) + .expect("smoltcp address vec full"); + }); + iface + .routes_mut() + .add_default_ipv4_route(Ipv4Address::UNSPECIFIED) + .expect("smoltcp routes table full"); + iface + .routes_mut() + .add_default_ipv6_route(Ipv6Address::UNSPECIFIED) + .expect("smoltcp routes table full"); + + let stack = SmoltcpStack::new(iface, device); + let notify = Arc::new(Notify::new()); + + reactor::start_reactor(stack.clone(), notify.clone(), tracker, state.clone()); + bridge::start_bridge( + stack.clone(), + client_input, + reconstructed_receiver, + ipr_address, + stream_id, + notify.clone(), + tracker, + state.clone(), + data_surbs, + ); + + NetworkStack { stack, notify } + } + + /// Open a TCP connection through the tunnel (SYN -> established). + pub async fn tcp_connect(&self, addr: SocketAddr) -> io::Result { + stream::tcp_connect( + self.stack.clone(), + self.notify.clone(), + addr, + self.tcp_keepalive_interval(), + self.tcp_buffer_size(), + ) + .await + } + + /// Create a UDP socket bound to an ephemeral port. + pub async fn udp_socket(&self) -> io::Result { + stream::create_udp_socket(self.stack.clone(), self.notify.clone()) + } + + /// Gracefully disconnect from the Nym mixnet. + /// + /// Signals the bridge and reactor to stop, then drops the base-client + /// handles so the Nym client stops consuming cover/Poisson traffic and + /// closes its gateway WebSocket. `WasmTunnel` itself lives in a + /// `OnceLock` for the lifetime of the worker, so dropping `self` is not + /// an option; we drop the inner handles instead. + pub async fn shutdown(&self) { + use state::TunnelState; + if matches!( + self.state.get(), + TunnelState::ShuttingDown | TunnelState::Shutdown + ) { + return; + } + self.state.set(TunnelState::ShuttingDown); + + // Cancel + wait, child first. The base token cancels the whole + // subtree, but each level's TaskTracker only waits on its own + // tasks, so both need an explicit `.shutdown().await`. + // Take the trackers out of their Mutexes first so the sync guards drop + // before the async `.shutdown().await` (clippy::await_holding_lock). + let smolmix_tracker = self.smolmix_tracker.lock().unwrap().take(); + let base_tracker = self.base_tracker.lock().unwrap().take(); + if let Some(tracker) = smolmix_tracker { + tracker.shutdown().await; + } + if let Some(tracker) = base_tracker { + tracker.shutdown().await; + } + + // Don't overwrite a Failed state that was set during teardown. + if !matches!(self.state.get(), TunnelState::Failed { .. }) { + self.state.set(TunnelState::Shutdown); + } + nym_wasm_utils::console_log!("[smolmix] tunnel shut down"); + } + + /// The IP addresses allocated to this tunnel by the IPR. + pub fn allocated_ips(&self) -> IpPair { + self.allocated_ips + } + + /// Panic-aware via `State::get`'s short-circuit. + pub(crate) fn is_ready(&self) -> bool { + self.state.is_ready() + } + + pub(crate) fn tunnel_state(&self) -> state::TunnelState { + self.state.get() + } + + /// DNS resolution cache, checked by `dns::resolve` before querying. + pub(crate) fn dns_cache(&self) -> &Mutex> { + &self.dns_cache + } + + /// Async lock that serialises DNS lookups for request coalescing. + pub(crate) fn dns_lock(&self) -> &futures::lock::Mutex<()> { + &self.dns_lock + } + + /// Resolver endpoints used by `dns::resolve` (primary tried first). + pub(crate) fn dns_primary(&self) -> SocketAddr { + self.dns_primary + } + pub(crate) fn dns_fallback(&self) -> SocketAddr { + self.dns_fallback + } + /// Per-query DNS timeout (used in `dns::resolve_with`). + pub(crate) fn dns_timeout(&self) -> Duration { + self.tuning.dns_timeout + } + /// TCP keepalive interval applied to every new `WasmTcpStream`. + pub(crate) fn tcp_keepalive_interval(&self) -> Duration { + self.tuning.tcp_keepalive_interval + } + /// TCP RX/TX buffer size in bytes applied to every new `WasmTcpStream`. + pub(crate) fn tcp_buffer_size(&self) -> usize { + self.tuning.tcp_buffer_size + } + /// Maximum HTTP redirect chain depth before `mixFetch` gives up. + pub(crate) fn max_redirects(&self) -> u8 { + self.tuning.max_redirects + } + + /// Get (or create) the per-origin lock for serialising concurrent requests. + pub(crate) fn origin_lock(&self, host: &str, port: u16) -> Arc> { + self.origin_locks + .lock() + .unwrap() + .entry((host.to_string(), port)) + .or_insert_with(|| Arc::new(futures::lock::Mutex::new(()))) + .clone() + } + + /// Take an idle connection from the pool (if one exists for this origin). + pub(crate) fn take_pooled(&self, host: &str, port: u16) -> Option { + self.conn_pool + .lock() + .unwrap() + .remove(&(host.to_string(), port)) + } + + /// Return a reusable connection to the pool for later use. + pub(crate) fn return_to_pool(&self, host: String, port: u16, conn: PooledConn) { + self.conn_pool.lock().unwrap().insert((host, port), conn); + } +} diff --git a/wasm/smolmix/src/util.rs b/wasm/smolmix/src/util.rs new file mode 100644 index 0000000000..5502ebcd46 --- /dev/null +++ b/wasm/smolmix/src/util.rs @@ -0,0 +1,24 @@ +// Copyright 2026 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +//! Re-exports of the shared debug-logging helpers from `nym-wasm-utils`. +//! +//! Both macros gate on a runtime flag in `nym-wasm-utils`, which smolmix +//! flips on in `lib.rs::main()` when its own `debug` feature is enabled +//! (see `nym_wasm_utils::set_debug_logging`). `hex_preview` is the +//! binary-buffer formatter used inside those macros. + +pub(crate) use nym_wasm_utils::debug_error; +pub(crate) use nym_wasm_utils::debug_log; +pub(crate) use nym_wasm_utils::hex_preview; + +/// MSRV-safe equivalent of `str::floor_char_boundary` (stable in 1.91; workspace +/// MSRV is 1.87). Returns the largest byte index `≤ target` where `s.is_char_boundary(i)` +/// holds; useful for truncating a string at a safe UTF-8 boundary. +pub(crate) fn floor_char_boundary(s: &str, target: usize) -> usize { + let mut i = target.min(s.len()); + while !s.is_char_boundary(i) { + i -= 1; + } + i +} diff --git a/wasm/smolmix/tests/.gitignore b/wasm/smolmix/tests/.gitignore new file mode 100644 index 0000000000..7e0f9045c0 --- /dev/null +++ b/wasm/smolmix/tests/.gitignore @@ -0,0 +1,4 @@ +node_modules/ +test-results/ +playwright-report/ +blob-report/ diff --git a/wasm/smolmix/tests/README.md b/wasm/smolmix/tests/README.md new file mode 100644 index 0000000000..0dd7b94033 --- /dev/null +++ b/wasm/smolmix/tests/README.md @@ -0,0 +1,130 @@ +# smolmix-wasm Playwright Tests + +Automated browser tests for the smolmix-wasm mixnet tunnel. Runs smoke tests and a full test suite (HTTPS cold/warm, stress httpbin) across Chromium, Firefox, and WebKit. + +## Prerequisites + +1. Build the WASM package and internal-dev harness: + +```bash +# from repo root +make build-debug +cd wasm/smolmix/internal-dev && pnpm run build +``` + +2. Install test dependencies and browser engines (first time only): + +```bash +cd wasm/smolmix/tests +pnpm install +pnpm exec playwright install +``` + +## Running Tests + +Both suites use a hardcoded default IPR (see `internal-dev/index.html` and +`internal-dev/headless.js`); no env var is required to run them. Override +the default by exporting `IPR_ADDRESS` if you want to point at a different +exit node: + +```bash +export IPR_ADDRESS="6B6iuWX4bQP4GVA4Yq7XmZencaaGw6BaPY6xJWYSwsbF.6g6LRx1fgU2Q2A4ZPKonYHtfBARh1GPMe1LtXk6vpRR8@q2A2cbooyC16YJzvdYaSMH9X3cSiieZNtfBr8cE8Fi1" +``` + +Pick any combination of projects to run: + +```bash +pnpm exec playwright test --project=smoke-chromium +pnpm exec playwright test --project=suite-firefox +pnpm exec playwright test --project=smoke-webkit --project=suite-webkit +pnpm exec playwright test # all 6 projects +``` + +Available projects: `smoke-chromium`, `smoke-firefox`, `smoke-webkit`, `suite-chromium`, `suite-firefox`, `suite-webkit`. + +## Test Structure + +### Smoke + +Loads the internal-dev page, fills in the IPR address, clicks setup, and verifies the tunnel connects without errors. Quick connectivity check (~30s). + +### Suite + +Loads `headless.html` which auto-runs three tests in sequence: + +| Test | What it measures | +|------|-----------------| +| Smoke (cold HTTPS) | Full pipeline: DNS + TCP + TLS + HTTP | +| HTTPS GET (warm) | Pooled connection reuse (HTTP only) | +| Stress httpbin | Mixed-size concurrent requests (serialised per-origin) | + +Runs twice — once per traffic configuration: + +1. **No cover traffic, no Poisson** — baseline performance +2. **With cover traffic + Poisson distribution** — realistic mixnet conditions + +Pass criteria: +- Smoke and HTTPS warm must pass +- Stress httpbin >= 80% success rate + +## Manual Headless Testing + +Run the headless test runner directly in a browser without Playwright: + +```bash +cd wasm/smolmix/internal-dev && pnpm start +``` + +Then open: +- `http://localhost:9000/headless.html` — no cover, no Poisson (default) +- `http://localhost:9000/headless.html?cover=true&poisson=true` — with cover + Poisson + +URL parameters: + +| Param | Default | Description | +|-------|---------|-------------| +| `ipr` | hardcoded default | IPR exit node address | +| `cover` | `false` | Enable cover traffic | +| `poisson` | `false` | Enable Poisson dummy traffic | +| `count` | `10` | Stress test request count | + +## Timeouts + +- Smoke: 3 minutes (tunnel setup ~10s, connectivity check ~20s) +- Suite: 10 minutes per config (mixnet round-trips are ~1-2s each) + +## Known Issues + +### Playwright Firefox hangs at IPR connect on Arch/Manjaro + +Playwright ships a forked Firefox build (Mozilla's "Juggler" patches) to enable +remote control. On Arch-family hosts (Manjaro confirmed) this bundled Firefox +hangs indefinitely at the IPR connect handshake step, in both headed and +headless modes. The bug is unique to the playwright Firefox build; the same +URL loads fine in the system Firefox installation. + +The smoke and suite tests reach `[ipr] sending connect handshake` and then +stall until the playwright timeout fires. Topology fetches against +`validator.nymtech.net` succeed; the gateway WSS connection or its message +flow is where it dies. Adding `firefoxUserPrefs` for timer throttling, DoH, +captive portal probes, and IndexedDB persistence does not help. + +You cannot point `executablePath` at the system Firefox; playwright's Firefox +binary must speak the Juggler protocol, which mainline Firefox does not. + +**Workaround:** run chromium locally; skip firefox, or run it from a CI image +whose playwright Firefox binary is built for that platform. + +```bash +pnpm exec playwright test --project=smoke-chromium +``` + +### Playwright Webkit missing libraries on Arch/Manjaro + +Playwright bundles `libwebkit2gtk` and a chain of GTK/glib/icu/freetype deps +expecting Ubuntu library layouts. On Arch-family hosts those library versions +or paths differ and webkit fails to launch. Same class of bug as the Firefox +hang, different symptom. + +**Workaround:** run webkit tests from a CI image (or container) with the +Ubuntu-shaped library layout playwright expects. diff --git a/wasm/smolmix/tests/package-lock.json b/wasm/smolmix/tests/package-lock.json new file mode 100644 index 0000000000..e518720716 --- /dev/null +++ b/wasm/smolmix/tests/package-lock.json @@ -0,0 +1,1119 @@ +{ + "name": "smolmix-wasm-playwright-tests", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "smolmix-wasm-playwright-tests", + "devDependencies": { + "@playwright/test": "^1.52.0", + "serve": "^14.2.4" + } + }, + "node_modules/@playwright/test": { + "version": "1.60.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.60.0.tgz", + "integrity": "sha512-O71yZIbAh/PxDMNGns37GHBIfrVkEVyn+AXyIa5dOTfb4/xNvRWV+Vv/NMbNCtODB/pO7vLlF2OTmMVLhmr7Ag==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright": "1.60.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@zeit/schemas": { + "version": "2.36.0", + "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.36.0.tgz", + "integrity": "sha512-7kjMwcChYEzMKjeex9ZFXkt1AyNov9R5HZtjBKVsmVpw7pa7ZtlCGvCBC2vnnXctaYN+aRI61HjIqeetZW5ROg==", + "dev": true, + "license": "MIT" + }, + "node_modules/ajv": { + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", + "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-align": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.1.tgz", + "integrity": "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.1.0" + } + }, + "node_modules/ansi-align/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/ansi-align/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-align/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-regex": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/arch": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz", + "integrity": "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/arg": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/arg/-/arg-5.0.2.tgz", + "integrity": "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==", + "dev": true, + "license": "MIT" + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/boxen": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/boxen/-/boxen-7.0.0.tgz", + "integrity": "sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-align": "^3.0.1", + "camelcase": "^7.0.0", + "chalk": "^5.0.1", + "cli-boxes": "^3.0.0", + "string-width": "^5.1.2", + "type-fest": "^2.13.0", + "widest-line": "^4.0.1", + "wrap-ansi": "^8.0.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.15.tgz", + "integrity": "sha512-EwOCDEex4quD37XhqM3omwtMoJjr//isUZz1JopUNWms+4Z2ViyM/k1YIRePpoVNnQhENnxtFjLaxNHrT7xIUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/camelcase": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-7.0.1.tgz", + "integrity": "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/chalk": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", + "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chalk-template": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/chalk-template/-/chalk-template-0.4.0.tgz", + "integrity": "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/chalk-template?sponsor=1" + } + }, + "node_modules/chalk-template/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/chalk-template/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/cli-boxes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-3.0.0.tgz", + "integrity": "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clipboardy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-3.0.0.tgz", + "integrity": "sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==", + "dev": true, + "license": "MIT", + "dependencies": { + "arch": "^2.2.0", + "execa": "^5.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", + "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", + "dev": true, + "license": "MIT", + "dependencies": { + "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" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", + "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "license": "MIT", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.2.tgz", + "integrity": "sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "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/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true, + "license": "ISC" + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-port-reachable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-port-reachable/-/is-port-reachable-4.0.0.tgz", + "integrity": "sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/mime-db": { + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.18", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", + "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "~1.33.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types/node_modules/mime-db": { + "version": "1.33.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", + "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/on-headers": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", + "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==", + "dev": true, + "license": "(WTFPL OR MIT)" + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-to-regexp": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-3.3.0.tgz", + "integrity": "sha512-qyCH421YQPS2WFDxDjftfc1ZR5WKQzVzqsp4n9M2kQhVOo/ByahFoUNJfl58kOcEGfQ//7weFTDhm+ss8Ecxgw==", + "dev": true, + "license": "MIT" + }, + "node_modules/playwright": { + "version": "1.60.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.60.0.tgz", + "integrity": "sha512-hheHdokM8cdqCb0lcE3s+zT4t4W+vvjpGxsZlDnikarzx8tSzMebh3UiFtgqwFwnTnjYQcsyMF8ei2mCO/tpeA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "playwright-core": "1.60.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.60.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.60.0.tgz", + "integrity": "sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/range-parser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", + "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/registry-auth-token": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", + "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "rc": "^1.1.6", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/registry-url": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", + "integrity": "sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "rc": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/serve": { + "version": "14.2.6", + "resolved": "https://registry.npmjs.org/serve/-/serve-14.2.6.tgz", + "integrity": "sha512-QEjUSA+sD4Rotm1znR8s50YqA3kYpRGPmtd5GlFxbaL9n/FdUNbqMhxClqdditSk0LlZyA/dhud6XNRTOC9x2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@zeit/schemas": "2.36.0", + "ajv": "8.18.0", + "arg": "5.0.2", + "boxen": "7.0.0", + "chalk": "5.0.1", + "chalk-template": "0.4.0", + "clipboardy": "3.0.0", + "compression": "1.8.1", + "is-port-reachable": "4.0.0", + "serve-handler": "6.1.7", + "update-check": "1.5.4" + }, + "bin": { + "serve": "build/main.js" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/serve-handler": { + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.7.tgz", + "integrity": "sha512-CinAq1xWb0vR3twAv9evEU8cNWkXCb9kd5ePAHUKJBkOsUpR1wt/CvGdeca7vqumL1U5cSaeVQ6zZMxiJ3yWsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.0.0", + "content-disposition": "0.5.2", + "mime-types": "2.1.18", + "minimatch": "3.1.5", + "path-is-inside": "1.0.2", + "path-to-regexp": "3.3.0", + "range-parser": "1.2.0" + } + }, + "node_modules/serve-handler/node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.2.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/update-check": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.4.tgz", + "integrity": "sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "registry-auth-token": "3.3.2", + "registry-url": "3.1.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/widest-line": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-4.0.1.tgz", + "integrity": "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==", + "dev": true, + "license": "MIT", + "dependencies": { + "string-width": "^5.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + } + } +} diff --git a/wasm/smolmix/tests/package.json b/wasm/smolmix/tests/package.json new file mode 100644 index 0000000000..ecb3131178 --- /dev/null +++ b/wasm/smolmix/tests/package.json @@ -0,0 +1,16 @@ +{ + "name": "smolmix-wasm-playwright-tests", + "private": true, + "scripts": { + "test": "playwright test", + "test:smoke": "playwright test --project=smoke-chromium --project=smoke-firefox --project=smoke-webkit", + "test:suite": "playwright test --project=suite-chromium --project=suite-firefox --project=suite-webkit", + "test:chromium": "playwright test --project=smoke-chromium --project=suite-chromium", + "test:firefox": "playwright test --project=smoke-firefox --project=suite-firefox", + "test:webkit": "playwright test --project=smoke-webkit --project=suite-webkit" + }, + "devDependencies": { + "@playwright/test": "^1.52.0", + "serve": "^14.2.4" + } +} diff --git a/wasm/smolmix/tests/playwright.config.mjs b/wasm/smolmix/tests/playwright.config.mjs new file mode 100644 index 0000000000..6af4e47381 --- /dev/null +++ b/wasm/smolmix/tests/playwright.config.mjs @@ -0,0 +1,88 @@ +import { defineConfig } from "@playwright/test"; + +// Headless Firefox on non-Ubuntu hosts (Arch/Manjaro fallback build) needs +// these prefs to behave like headed Firefox: keep IndexedDB persistent across +// the test session, raise the wss:// open timeout above the 20 s default +// (mixnet handshake + WSS upgrade can take longer on a cold load), and skip +// the captive-portal probe that adds spurious DNS noise. +const firefoxUserPrefs = { + "dom.indexedDB.enabled": true, + "dom.storage.next_gen": true, + "browser.privatebrowsing.autostart": false, + "network.websocket.timeout.open": 60, + "network.captive-portal-service.enabled": false, + "network.connectivity-service.enabled": false, + // Force the OS resolver rather than Mozilla's DoH. Headless Firefox on + // non-Ubuntu hosts sometimes can't reach mozilla.cloudflare-dns.com from + // the bundled NSS context, which stalls gateway hostname resolution. + "network.trr.mode": 0, + "network.dns.disablePrefetch": true, + // Headless Firefox has no visible window so it treats itself as backgrounded + // and clamps timers (default 1 s minimum via dom.min_background_timeout_value). + // Our reactor ticks every 5 ms and the Nym base client uses many short + // timers in its WS keepalive/retry logic; clamping those to 1 s stalls the + // gateway handshake. Disable every timer-throttling knob. + "dom.min_background_timeout_value": 4, + "dom.workers.timeoutThrottling": false, + "dom.timeout.foreground_budget_regeneration_rate": -1, + "dom.timeout.background_budget_regeneration_rate": -1, +}; + +const firefoxUse = { + browserName: "firefox", + launchOptions: { firefoxUserPrefs }, +}; + +export default defineConfig({ + testDir: "./tests", + timeout: 180_000, + retries: 1, + use: { + trace: "on-first-retry", + }, + webServer: { + command: "npx serve ../internal-dev/dist -l 9001 --no-clipboard", + port: 9001, + reuseExistingServer: true, + }, + projects: [ + // Smoke: all three browsers + { + name: "smoke-chromium", + testMatch: "smoke.spec.mjs", + use: { browserName: "chromium" }, + }, + { + name: "smoke-firefox", + testMatch: "smoke.spec.mjs", + use: firefoxUse, + }, + { + name: "smoke-webkit", + testMatch: "smoke.spec.mjs", + use: { browserName: "webkit" }, + }, + // Suite: all three browsers + { + name: "suite-chromium", + testMatch: "suite.spec.mjs", + timeout: 600_000, + retries: 0, + use: { browserName: "chromium" }, + }, + { + name: "suite-firefox", + testMatch: "suite.spec.mjs", + timeout: 600_000, + retries: 0, + use: firefoxUse, + }, + { + name: "suite-webkit", + testMatch: "suite.spec.mjs", + timeout: 600_000, + retries: 0, + use: { browserName: "webkit" }, + }, + ], +}); diff --git a/wasm/smolmix/tests/tests/smoke.spec.mjs b/wasm/smolmix/tests/tests/smoke.spec.mjs new file mode 100644 index 0000000000..df5ea70038 --- /dev/null +++ b/wasm/smolmix/tests/tests/smoke.spec.mjs @@ -0,0 +1,81 @@ +// Smoke test: verify the internal-dev harness loads WASM and connects +// to the mixnet via an IPR. +// +// Env: IPR_ADDRESS (optional). Without it, the page's pre-filled default +// (internal-dev/index.html `#ipr-address` value attribute) is used. + +import { test, expect } from "@playwright/test"; + +const IPR_ADDRESS = process.env.IPR_ADDRESS; + +function waitForConsole(page, predicate, timeoutMs = 120_000) { + return new Promise((resolve, reject) => { + function handler(msg) { + if (predicate(msg.text())) { + clearTimeout(timer); + page.removeListener("console", handler); + resolve(msg.text()); + } + } + const timer = setTimeout(() => { + page.removeListener("console", handler); + reject( + new Error(`Timed out waiting for console message (${timeoutMs}ms)`) + ); + }, timeoutMs); + page.on("console", handler); + }); +} + +test("WASM loads and tunnel connects to IPR", async ({ page }) => { + const errors = []; + + page.on("console", (msg) => { + const text = msg.text(); + if (text.startsWith("[")) { + console.log(text); + } + if (msg.type() === "error" && !text.includes("favicon.ico")) { + errors.push(text); + console.log(`[ERROR] ${text}`); + } + }); + + page.on("pageerror", (err) => { + errors.push(`pageerror: ${err.message}`); + }); + + await page.goto("http://localhost:9001"); + await page.waitForSelector("#btn-setup"); + + // The input is pre-filled with a working default; only override when the + // caller passed an explicit IPR_ADDRESS env var. + if (IPR_ADDRESS) { + await page.fill("#ipr-address", IPR_ADDRESS); + } + + // Race: tunnel ready OR fatal error — whichever comes first. + const tunnelReady = waitForConsole( + page, + (text) => + text.includes("setupMixTunnel OK") || text.includes("tunnel ready"), + 120_000 + ); + const fatalError = waitForConsole( + page, + (text) => text.includes("FATAL") || text.includes("tunnel error"), + 120_000 + ); + await page.click("#btn-setup"); + + const result = await Promise.race([ + tunnelReady.then((msg) => ({ ok: true, msg })), + fatalError.then((msg) => ({ ok: false, msg })), + ]); + expect(result.ok, `Tunnel setup failed: ${result.msg}`).toBeTruthy(); + + const hardErrors = errors.filter( + (e) => !e.includes("favicon") && !e.includes("DevTools") + ); + expect(hardErrors).toEqual([]); +}); diff --git a/wasm/smolmix/tests/tests/suite.spec.mjs b/wasm/smolmix/tests/tests/suite.spec.mjs new file mode 100644 index 0000000000..35c61287ae --- /dev/null +++ b/wasm/smolmix/tests/tests/suite.spec.mjs @@ -0,0 +1,152 @@ +// Full test suite: runs the headless test runner for both traffic configs. +// +// Each config gets its own page load (OnceLock prevents tunnel re-init). +// The headless.js runner auto-executes: smoke, HTTPS warm, stress httpbin, +// stress drip — then outputs RESULTS_JSON for parsing. +// +// Env: IPR_ADDRESS (optional, uses default if omitted) + +import { test, expect } from "@playwright/test"; + +const BASE_URL = "http://localhost:9001/headless.html"; +const IPR_ADDRESS = process.env.IPR_ADDRESS; + +const CONFIGS = [ + { + name: "no cover, no Poisson", + params: "count=5", + }, + { + name: "with cover + Poisson", + params: "cover=true&poisson=true&count=5", + }, +]; + +function waitForConsole(page, predicate, timeoutMs) { + return new Promise((resolve, reject) => { + function handler(msg) { + if (predicate(msg.text())) { + clearTimeout(timer); + page.removeListener("console", handler); + resolve(msg.text()); + } + } + const timer = setTimeout(() => { + page.removeListener("console", handler); + reject( + new Error(`Timed out waiting for console message (${timeoutMs}ms)`) + ); + }, timeoutMs); + page.on("console", handler); + }); +} + +for (const cfg of CONFIGS) { + test.describe(cfg.name, () => { + test("full suite", async ({ page }) => { + // Forward all logs to test output for debugging. + page.on("console", (msg) => { + const text = msg.text(); + if ( + text.startsWith("[") || + text.includes("===") || + text.includes("Config:") || + text.includes("FATAL") || + text.includes("RESULTS_JSON") + ) { + console.log(text); + } + }); + + page.on("pageerror", (err) => { + console.log(`[PAGEERROR] ${err.message}`); + }); + + // Build URL with config params + optional IPR override. + let url = `${BASE_URL}?${cfg.params}`; + if (IPR_ADDRESS) { + url += `&ipr=${encodeURIComponent(IPR_ADDRESS)}`; + } + + // Wait for the RESULTS_JSON console message (the suite auto-runs). + const jsonPromise = waitForConsole( + page, + (text) => text.startsWith("RESULTS_JSON:"), + 540_000 // 9 minutes — generous for mixnet latency + ); + + await page.goto(url); + const resultLine = await jsonPromise; + const json = JSON.parse(resultLine.replace("RESULTS_JSON:", "")); + + // --- Timing summary --- + console.log(""); + console.log("================================================================"); + console.log(` Config: ${cfg.name}`); + console.log(` Date: ${json.date}`); + console.log("================================================================"); + console.log(""); + console.log( + ` ${"Test".padEnd(28)}${"Result".padEnd(10)}${"Time".padEnd(10)}Details` + ); + console.log(` ${"".padEnd(28, "-")}${"".padEnd(10, "-")}${"".padEnd(10, "-")}${"".padEnd(20, "-")}`); + + for (const r of json.results) { + let resultStr = + r.total !== undefined ? `${r.okCount}/${r.total}` : r.ok ? "PASS" : "FAIL"; + let timeStr = r.ms ? `${(r.ms / 1000).toFixed(2)}s` : "N/A"; + let details = ""; + if (r.avgMs !== undefined) { + details = `avg ${(r.avgMs / 1000).toFixed(2)}s/req`; + } + if (r.error) { + details = r.error.slice(0, 60); + } + console.log( + ` ${r.name.padEnd(28)}${resultStr.padEnd(10)}${timeStr.padEnd(10)}${details}` + ); + } + + console.log(""); + console.log("================================================================"); + + // --- Assertions --- + + // Check for fatal setup errors first. + const fatal = json.results.find((r) => r.error && !r.ok && r.ms === 0); + if (fatal) { + expect.soft(false, `Fatal error: ${fatal.error}`).toBeTruthy(); + return; + } + + // Smoke must pass. + const smoke = json.results.find((r) => r.name.includes("Smoke")); + expect(smoke, "Smoke test result should exist").toBeTruthy(); + expect(smoke.ok, "Smoke test (cold HTTPS GET) should pass").toBeTruthy(); + + // HTTPS warm must pass. + const warm = json.results.find((r) => r.name.includes("warm")); + expect(warm, "HTTPS warm result should exist").toBeTruthy(); + expect(warm.ok, "HTTPS GET (warm) should pass").toBeTruthy(); + + // Warm should be significantly faster than cold. + if (smoke.ok && warm.ok) { + console.log( + ` Cold vs warm: ${(smoke.ms / 1000).toFixed(1)}s -> ${(warm.ms / 1000).toFixed(1)}s ` + + `(${(smoke.ms / warm.ms).toFixed(1)}x speedup from connection pooling)` + ); + } + + // Stress httpbin: >= 80% success. + const stress = json.results.find((r) => r.name.includes("httpbin")); + if (stress?.total) { + const rate = stress.okCount / stress.total; + console.log( + ` Stress httpbin success rate: ${(rate * 100).toFixed(0)}%` + ); + expect(rate).toBeGreaterThanOrEqual(0.8); + } + + }); + }); +} From d37b4226d09777296ce923680216ce389ac941d7 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Fri, 13 Feb 2026 10:31:55 +0100 Subject: [PATCH 61/94] testing port checks add no-log to anywhere add support for not registered nodes ... address comments remove unregistered nodes testing port checks add support for not registered nodes ... address comments test port check in probe results migration update probe arg fix bump NS versions cleanup and remove unannounced node option bugsfixes Remove in-prove remove in-probe test, it isn't needed. add multiple target host options cleanup change default target, and use batch only for portquiz Revert "change default target, and use batch only for portquiz" This reverts commit 8b38969964e7808b9c4e50a920ee5bc51438c7bf. ded line bugfixes batch fix batch limits force ipv4 --- nym-gateway-probe/Cargo.toml | 2 +- nym-gateway-probe/build.rs | 92 ++++ nym-gateway-probe/netstack_ping/lib.go | 162 ++++++- nym-gateway-probe/src/common/netstack.rs | 29 ++ nym-gateway-probe/src/common/probe_tests.rs | 2 + nym-gateway-probe/src/common/types.rs | 67 +++ nym-gateway-probe/src/common/wireguard.rs | 17 +- nym-gateway-probe/src/config/mod.rs | 4 +- nym-gateway-probe/src/config/netstack.rs | 67 +++ nym-gateway-probe/src/config/test_mode.rs | 3 + nym-gateway-probe/src/lib.rs | 454 +++++++++++++++++- nym-gateway-probe/src/run.rs | 149 +++++- .../nym-node-status-agent/Cargo.toml | 2 +- .../nym-node-status-agent/src/cli/common.rs | 42 ++ .../nym-node-status-agent/src/cli/mod.rs | 40 +- .../src/cli/run_ports_check.rs | 131 +++++ .../src/cli/run_probe.rs | 42 +- ...2a66aae5be1c37af2eca521bf75261cecf28.json} | 19 +- ...2b71a1a91ef114ffdd0572a738b577fab15d.json} | 5 +- ...d8ea15b957dd19b097101dcda2c05aee21d20.json | 15 + ...a57fb24f6b21655039a9bfa21c44409c87910.json | 18 + ...783249a03f2ae04ec89f734e67ceb897a385.json} | 16 +- ...4cb8bf8ebb1c26839f915780d0fc0d1939973.json | 31 ++ ...1614edc4e967f348c57f485f736b8f2f03e8.json} | 16 +- ...087af53e9504a8bb13280dde5c37b9b418370.json | 22 + .../nym-node-status-api/Cargo.toml | 2 +- .../nym-node-status-api/Makefile | 13 + ...0260414000000_ports_check_testrun_kind.sql | 8 + .../20260415000000_gateways_ports_check.sql | 14 + .../nym-node-status-api/src/cli/mod.rs | 9 + .../nym-node-status-api/src/db/models.rs | 124 ++++- .../src/db/queries/gateways.rs | 9 +- .../src/db/queries/testruns.rs | 154 +++++- .../nym-node-status-api/src/db/tests.rs | 99 ++++ .../src/http/api/gateways.rs | 4 + .../src/http/api/services/json_path.rs | 2 + .../src/http/api/services/mod.rs | 2 + .../src/http/api/testruns.rs | 220 ++++++++- .../src/http/models/gw_probe/test.rs | 4 + .../src/http/models/mod.rs | 6 + .../nym-node-status-api/src/http/server.rs | 30 ++ .../nym-node-status-api/src/http/state.rs | 6 +- .../nym-node-status-api/src/main.rs | 7 +- .../src/test_helpers/mod.rs | 3 + .../nym-node-status-api/src/testruns/mod.rs | 8 +- .../nym-node-status-api/src/testruns/queue.rs | 8 +- .../nym-node-status-client/src/api.rs | 11 + .../nym-node-status-client/src/lib.rs | 87 +++- .../nym-node-status-client/src/models.rs | 39 ++ 49 files changed, 2195 insertions(+), 121 deletions(-) create mode 100644 nym-node-status-api/nym-node-status-agent/src/cli/common.rs create mode 100644 nym-node-status-api/nym-node-status-agent/src/cli/run_ports_check.rs rename nym-node-status-api/nym-node-status-api/.sqlx/{query-f343df183767af9815847cb94ccbd484010a7346de03f1e0959a09a964344de8.json => query-0c635c539930c10a9be35a12ba3f2a66aae5be1c37af2eca521bf75261cecf28.json} (66%) rename nym-node-status-api/nym-node-status-api/.sqlx/{query-88a4554c2857288c314768c56648a5f1811d2053582380ca602335a122cef8db.json => query-1dc7d1e6c2173cd1ca70d699124c2b71a1a91ef114ffdd0572a738b577fab15d.json} (51%) create mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-3c6da5c1faace026222bbb28553d8ea15b957dd19b097101dcda2c05aee21d20.json create mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-65b5a3ed9a73f1304badfa8d9bba57fb24f6b21655039a9bfa21c44409c87910.json rename nym-node-status-api/nym-node-status-api/.sqlx/{query-d41cafc76cb49c03df7452c405a4e2e5e3951c41dc35c20261c1d959c0d6403f.json => query-75bdccbff8ea6a59d56230075163783249a03f2ae04ec89f734e67ceb897a385.json} (67%) create mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-ad78bf2f7ed4666b4e5f60811f04cb8bf8ebb1c26839f915780d0fc0d1939973.json rename nym-node-status-api/nym-node-status-api/.sqlx/{query-ddf003e7e13653388f487e3adfc1aad0a285e29c797f99ec00bcccb063f76b64.json => query-b32d29ca3cedae93fa2fcd44cc301614edc4e967f348c57f485f736b8f2f03e8.json} (72%) create mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-cc84f8a284c9aba4494152ff4e6087af53e9504a8bb13280dde5c37b9b418370.json create mode 100644 nym-node-status-api/nym-node-status-api/migrations_pg/20260414000000_ports_check_testrun_kind.sql create mode 100644 nym-node-status-api/nym-node-status-api/migrations_pg/20260415000000_gateways_ports_check.sql diff --git a/nym-gateway-probe/Cargo.toml b/nym-gateway-probe/Cargo.toml index e50f61cf9d..d7db904a5c 100644 --- a/nym-gateway-probe/Cargo.toml +++ b/nym-gateway-probe/Cargo.toml @@ -17,7 +17,7 @@ anyhow = { workspace = true } base64 = { workspace = true } bs58 = { workspace = true } bytes = { workspace = true } -clap = { workspace = true, features = ["cargo", "derive"] } +clap = { workspace = true, features = ["cargo", "derive", "env"] } futures = { workspace = true } hex = { workspace = true } tracing = { workspace = true } diff --git a/nym-gateway-probe/build.rs b/nym-gateway-probe/build.rs index 43af675650..97a8d14c7c 100644 --- a/nym-gateway-probe/build.rs +++ b/nym-gateway-probe/build.rs @@ -9,6 +9,7 @@ use vergen_gitcl::{BuildBuilder, CargoBuilder, Emitter, GitclBuilder, RustcBuild fn main() -> anyhow::Result<()> { build_go()?; + generate_exit_policy_ports()?; Emitter::default() .add_instructions(&BuildBuilder::all_build()?)? @@ -18,6 +19,97 @@ fn main() -> anyhow::Result<()> { .emit() } +/// Parse PORT_MAPPINGS from network-tunnel-manager.sh and generate a sorted +/// Rust const with every unique port. Ranges are represented by their start +/// and end values so a single TCP check can confirm the iptables rule exists. +/// TODO: consider runtime fetch from NS API exit policy endpoint instead of parsing the script +fn generate_exit_policy_ports() -> anyhow::Result<()> { + use std::collections::BTreeMap; + + let script_path = PathBuf::from("../scripts/nym-node-setup/network-tunnel-manager.sh"); + let out_dir = PathBuf::from(std::env::var("OUT_DIR").context("OUT_DIR not set")?); + + println!("cargo::rerun-if-changed={}", script_path.display()); + + let content = std::fs::read_to_string(&script_path).context( + "failed to read network-tunnel-manager.sh — is it present at ../scripts/nym-node-setup/ ?", + )?; + + // port → service name (BTreeMap keeps them sorted) + let mut port_map: BTreeMap = BTreeMap::new(); + let mut in_mappings = false; + + for line in content.lines() { + let trimmed = line.trim(); + + if trimmed.starts_with("declare -A PORT_MAPPINGS=(") { + in_mappings = true; + continue; + } + if in_mappings && trimmed == ")" { + break; + } + if !in_mappings { + continue; + } + + // strip comment prefix so we still pick up ports that are opened + // via a separate mechanism (e.g. SMTP/465 with rate limiting) + let stripped = trimmed.trim_start_matches('#').trim(); + + // match ["ServiceName"]="port-or-range" + let Some(name_start) = stripped.find("[\"") else { + continue; + }; + let Some(name_end) = stripped.find("\"]=") else { + continue; + }; + let service = &stripped[name_start + 2..name_end]; + let value = stripped[name_end + 3..].trim_matches('"'); + + if value.contains('-') { + let parts: Vec<&str> = value.split('-').collect(); + if parts.len() == 2 { + if let (Ok(lo), Ok(hi)) = (parts[0].parse::(), parts[1].parse::()) { + port_map + .entry(lo) + .or_insert_with(|| format!("{service} (range start)")); + port_map + .entry(hi) + .or_insert_with(|| format!("{service} (range end)")); + } + } + } else if let Ok(port) = value.parse::() { + port_map.entry(port).or_insert_with(|| service.to_string()); + } + } + + if port_map.is_empty() { + bail!("No ports found in PORT_MAPPINGS — is network-tunnel-manager.sh correct?"); + } + + // write generated Rust source + let mut out = String::new(); + out.push_str( + "// Auto-generated from scripts/nym-node-setup/network-tunnel-manager.sh PORT_MAPPINGS.\n", + ); + out.push_str("// Do not edit — changes are overwritten on rebuild.\n"); + out.push_str("// To add or remove ports, update PORT_MAPPINGS in the shell script.\n\n"); + out.push_str(&format!( + "/// {} unique ports parsed from the canonical exit policy at build time.\n", + port_map.len() + )); + out.push_str("pub const EXIT_POLICY_PORTS: &[u16] = &[\n"); + for (port, service) in &port_map { + let entry = format!("{port},"); + out.push_str(&format!(" {entry:<7}// {service}\n")); + } + out.push_str("];\n"); + + std::fs::write(out_dir.join("exit_policy_ports.rs"), out)?; + Ok(()) +} + fn build_go() -> anyhow::Result<()> { const LIB_NAME: &str = "netstack_ping"; diff --git a/nym-gateway-probe/netstack_ping/lib.go b/nym-gateway-probe/netstack_ping/lib.go index a80af4bee5..bcbf738368 100644 --- a/nym-gateway-probe/netstack_ping/lib.go +++ b/nym-gateway-probe/netstack_ping/lib.go @@ -23,6 +23,7 @@ import ( netUrl "net/url" "os" "strings" + "sync" "time" "unsafe" @@ -62,21 +63,27 @@ type NetstackRequestGo struct { DownloadTimeoutSec uint64 `json:"download_timeout_sec"` MetadataTimeoutSec uint64 `json:"metadata_timeout_sec"` AwgArgs string `json:"awg_args"` + // exit policy port check + PortCheckTarget string `json:"port_check_target"` + PortCheckPorts []uint16 `json:"port_check_ports"` + PortCheckOnly bool `json:"port_check_only"` + PortCheckTimeoutSec uint64 `json:"port_check_timeout_sec"` } type NetstackResponse struct { - CanHandshake bool `json:"can_handshake"` - CanQueryMetadata bool `json:"can_query_metadata"` - SentIps uint16 `json:"sent_ips"` - ReceivedIps uint16 `json:"received_ips"` - SentHosts uint16 `json:"sent_hosts"` - ReceivedHosts uint16 `json:"received_hosts"` - CanResolveDns bool `json:"can_resolve_dns"` - DownloadedFile string `json:"downloaded_file"` - DownloadedFileSizeBytes uint64 `json:"downloaded_file_size_bytes"` - DownloadDurationSec uint64 `json:"download_duration_sec"` - DownloadDurationMilliseconds uint64 `json:"download_duration_milliseconds"` - DownloadError string `json:"download_error"` + CanHandshake bool `json:"can_handshake"` + CanQueryMetadata bool `json:"can_query_metadata"` + SentIps uint16 `json:"sent_ips"` + ReceivedIps uint16 `json:"received_ips"` + SentHosts uint16 `json:"sent_hosts"` + ReceivedHosts uint16 `json:"received_hosts"` + CanResolveDns bool `json:"can_resolve_dns"` + DownloadedFile string `json:"downloaded_file"` + DownloadedFileSizeBytes uint64 `json:"downloaded_file_size_bytes"` + DownloadDurationSec uint64 `json:"download_duration_sec"` + DownloadDurationMilliseconds uint64 `json:"download_duration_milliseconds"` + DownloadError string `json:"download_error"` + PortCheckResults map[string]bool `json:"port_check_results,omitempty"` } type SuccessResult = struct { @@ -201,7 +208,7 @@ func pingTwoHop(req TwoHopNetstackRequest) (NetstackResponse, error) { log.Printf("Exit WG IP: %s", req.ExitWgIp) log.Printf("IP version: %d", req.IpVersion) - response := NetstackResponse{false, false, 0, 0, 0, 0, false, "", 0, 0, 0, ""} + response := NetstackResponse{} // Parse the exit endpoint to determine IP version for forwarder exitEndpoint, err := netip.ParseAddrPort(req.ExitEndpoint) @@ -439,7 +446,7 @@ func ping(req NetstackRequestGo) (NetstackResponse, error) { ipc.WriteString("\nallowed_ip=::/0\n") } - response := NetstackResponse{false, false, 0, 0, 0, 0, false, "", 0, 0, 0, ""} + response := NetstackResponse{} err = dev.IpcSet(ipc.String()) if err != nil { @@ -463,6 +470,19 @@ func ping(req NetstackRequestGo) (NetstackResponse, error) { response.CanHandshake = true + // port-check-only mode: skip pings/download, only test TCP port reachability + if req.PortCheckOnly && len(req.PortCheckPorts) > 0 { + log.Printf("=== Port Check Only Mode ===") + response.PortCheckResults = checkPorts(req.PortCheckTarget, req.PortCheckPorts, req.PortCheckTimeoutSec, tnet) + return response, nil + } + + // run port checks alongside normal tests if ports were requested + if len(req.PortCheckPorts) > 0 { + log.Printf("=== Running Port Checks (alongside normal tests) ===") + response.PortCheckResults = checkPorts(req.PortCheckTarget, req.PortCheckPorts, req.PortCheckTimeoutSec, tnet) + } + // Skip metadata query if endpoint is empty (e.g., for IPv6 where the IPv4 metadata endpoint is not reachable) if req.MetadataEndpoint != "" { version, duration, err := queryMetadata(req.MetadataEndpoint, req.MetadataTimeoutSec, tnet) @@ -569,6 +589,120 @@ func ping(req NetstackRequestGo) (NetstackResponse, error) { return response, nil } +const portquizBatchSize = 20 +const portquizBatchDelay = 25 * time.Second +const portquizDialGap = 20 * time.Millisecond + +func checkPorts(target string, ports []uint16, timeoutSec uint64, tnet *netstack.Net) map[string]bool { + if target == "" { + target = "portquiz.net" + } + if timeoutSec == 0 { + timeoutSec = 5 + } + + targetIP := target + if net.ParseIP(target) == nil { + addrs, err := net.LookupHost(target) + if err != nil || len(addrs) == 0 { + log.Printf("Port check: DNS lookup for %s failed (%v), using hostname as-is", target, err) + } else { + chosen := addrs[0] + for _, a := range addrs { + if net.ParseIP(a).To4() != nil { + chosen = a + break + } + } + targetIP = chosen + log.Printf("Port check: resolved %s -> %s", target, targetIP) + } + } + + timeout := time.Duration(timeoutSec) * time.Second + results := make(map[string]bool, len(ports)) + + if strings.Contains(target, "portquiz.net") { + // portquiz.net rate-limits after ~29 connections per window; use large batches with a long cooldown + log.Printf("Port check: testing %d ports on %s in batches of %d with %v cooldown (timeout %v each)", + len(ports), target, portquizBatchSize, portquizBatchDelay, timeout) + + for batchIdx := 0; batchIdx < len(ports); batchIdx += portquizBatchSize { + end := batchIdx + portquizBatchSize + if end > len(ports) { + end = len(ports) + } + batch := ports[batchIdx:end] + + for i, p := range batch { + addr := net.JoinHostPort(targetIP, fmt.Sprintf("%d", p)) + ctx, cancel := context.WithTimeout(context.Background(), timeout) + c, err := tnet.DialContext(ctx, "tcp", addr) + cancel() + key := fmt.Sprintf("%d", p) + if err != nil { + log.Printf("Port %d: CLOSED (%v)", p, err) + results[key] = false + } else { + c.Close() + log.Printf("Port %d: OPEN", p) + results[key] = true + } + if i < len(batch)-1 { + time.Sleep(portquizDialGap) + } + } + + if batchIdx+portquizBatchSize < len(ports) { + time.Sleep(portquizBatchDelay) + } + } + } else { + // All other targets can handle concurrent connections, probably + log.Printf("Port check: testing %d ports on %s concurrently (timeout %v each)", + len(ports), target, timeout) + + var ( + mu sync.Mutex + wg sync.WaitGroup + ) + for _, p := range ports { + wg.Add(1) + go func(port uint16) { + defer wg.Done() + addr := net.JoinHostPort(targetIP, fmt.Sprintf("%d", port)) + ctx, cancel := context.WithTimeout(context.Background(), timeout) + c, err := tnet.DialContext(ctx, "tcp", addr) + cancel() + key := fmt.Sprintf("%d", port) + if err != nil { + log.Printf("Port %d: CLOSED (%v)", port, err) + mu.Lock() + results[key] = false + mu.Unlock() + } else { + c.Close() + log.Printf("Port %d: OPEN", port) + mu.Lock() + results[key] = true + mu.Unlock() + } + }(p) + } + wg.Wait() + } + + openCount := 0 + for _, open := range results { + if open { + openCount++ + } + } + log.Printf("Port check complete: %d/%d ports open", openCount, len(ports)) + + return results +} + func sendPing(address string, seq uint8, sendTtimeoutSecs uint64, receiveTimoutSecs uint64, tnet *netstack.Net, ipVersion uint8) (time.Duration, error) { maxPingRetries := 2 baseTimeout := receiveTimoutSecs diff --git a/nym-gateway-probe/src/common/netstack.rs b/nym-gateway-probe/src/common/netstack.rs index 761b6713f0..d76bdffd13 100644 --- a/nym-gateway-probe/src/common/netstack.rs +++ b/nym-gateway-probe/src/common/netstack.rs @@ -4,6 +4,7 @@ use crate::config::NetstackArgs; use anyhow::Context; use serde::Deserialize; +use std::collections::BTreeMap; use std::ffi::{CStr, CString}; mod sys { @@ -15,6 +16,19 @@ mod sys { } } +/// Port-check fields shared between `NetstackRequest` and `NetstackRequestGo` +#[derive(Clone, Debug, serde::Serialize, serde::Deserialize)] +pub struct PortCheckConfig { + #[serde(rename = "port_check_target")] + pub target: String, + #[serde(rename = "port_check_ports")] + pub ports: Vec, + #[serde(rename = "port_check_only")] + pub only: bool, + #[serde(rename = "port_check_timeout_sec")] + pub timeout_sec: u64, +} + #[derive(serde::Serialize)] pub struct NetstackRequest { private_key: String, @@ -25,6 +39,8 @@ pub struct NetstackRequest { v6_ping_config: PingConfig, download_timeout_sec: u64, awg_args: String, + #[serde(flatten)] + pub port_check: PortCheckConfig, } #[derive(serde::Serialize)] @@ -76,6 +92,7 @@ impl NetstackRequest { download_timeout_sec: u64, awg_args: &str, netstack_args: NetstackArgs, + port_check_only: bool, ) -> Self { Self { private_key: private_key.to_string(), @@ -86,6 +103,12 @@ impl NetstackRequest { v4_ping_config: PingConfig::from_netstack_args_v4(wg_ip4, &netstack_args), v6_ping_config: PingConfig::from_netstack_args_v6(wg_ip6, &netstack_args), download_timeout_sec, + port_check: PortCheckConfig { + target: netstack_args.port_check_target.clone(), + ports: netstack_args.port_check_ports.clone(), + only: port_check_only, + timeout_sec: netstack_args.port_check_timeout_sec, + }, } } @@ -116,6 +139,8 @@ pub struct NetstackRequestGo { recv_timeout_sec: u64, download_timeout_sec: u64, awg_args: String, + #[serde(flatten)] + pub port_check: PortCheckConfig, } impl NetstackRequestGo { @@ -135,6 +160,7 @@ impl NetstackRequestGo { recv_timeout_sec: req.v4_ping_config.recv_timeout_sec, download_timeout_sec: req.download_timeout_sec, awg_args: req.awg_args.clone(), + port_check: req.port_check.clone(), } } @@ -155,6 +181,7 @@ impl NetstackRequestGo { recv_timeout_sec: req.v6_ping_config.recv_timeout_sec, download_timeout_sec: req.download_timeout_sec, awg_args: req.awg_args.clone(), + port_check: req.port_check.clone(), } } } @@ -173,6 +200,8 @@ pub struct NetstackResponse { pub downloaded_file_size_bytes: u64, pub download_duration_milliseconds: u64, pub download_error: String, + #[serde(default)] + pub port_check_results: Option>, } #[derive(Clone, Debug, serde::Deserialize)] diff --git a/nym-gateway-probe/src/common/probe_tests.rs b/nym-gateway-probe/src/common/probe_tests.rs index c9fc0531b0..30b14345d0 100644 --- a/nym-gateway-probe/src/common/probe_tests.rs +++ b/nym-gateway-probe/src/common/probe_tests.rs @@ -46,6 +46,7 @@ pub async fn wg_probe( auth_version: AuthenticatorVersion, awg_args: Option, netstack_args: NetstackArgs, + port_check_only: bool, // TODO: update type credential: CredentialSpendingData, ) -> anyhow::Result { @@ -149,6 +150,7 @@ pub async fn wg_probe( &tunnel_config, &netstack_args, &awg_args.unwrap_or_default(), + port_check_only, &mut wg_outcome, ); diff --git a/nym-gateway-probe/src/common/types.rs b/nym-gateway-probe/src/common/types.rs index 8541a57421..99190df348 100644 --- a/nym-gateway-probe/src/common/types.rs +++ b/nym-gateway-probe/src/common/types.rs @@ -1,10 +1,50 @@ use nym_connection_monitor::ConnectionStatusEvent; use serde::{Deserialize, Serialize}; +use std::collections::BTreeMap; pub use super::bandwidth_helpers::{AttachedTicket, AttachedTicketMaterials}; pub use super::socks5_test::HttpsConnectivityResult; pub use nym_credentials::ecash::bandwidth::serialiser::VersionedSerialise; +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct PortsCheckSummary { + pub all_pass: bool, + pub error: Option, + pub port_check_target: String, + pub failed_ports: Vec, +} + +impl PortsCheckSummary { + pub fn from_port_map( + can_register: bool, + port_check_target: impl Into, + ports: &BTreeMap, + ) -> Self { + let failed_ports: Vec = ports + .iter() + .filter_map(|(port, open)| if *open { None } else { Some(port.clone()) }) + .collect(); + + let all_pass = can_register && failed_ports.is_empty() && !ports.is_empty(); + + Self { + all_pass, + error: None, + port_check_target: port_check_target.into(), + failed_ports, + } + } + + pub fn probe_error(port_check_target: impl Into, message: impl Into) -> Self { + Self { + all_pass: false, + error: Some(message.into()), + port_check_target: port_check_target.into(), + failed_ports: vec![], + } + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ProbeResult { pub node: String, @@ -50,6 +90,10 @@ pub struct WgProbeResults { pub download_duration_milliseconds_v6: u64, pub downloaded_file_v6: String, pub download_error_v6: String, + + /// Per-port exit-policy check + #[serde(default, skip_serializing_if = "Option::is_none")] + pub port_check_results: Option>, } #[cfg_attr(feature = "utoipa", derive(utoipa::ToSchema))] @@ -195,6 +239,29 @@ impl Socks5ProbeResults { } } +/// Output of the `run-ports` subcommand — per-port TCP reachability through +/// the WG exit tunnel, without the full probe outcome. +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct PortCheckResult { + pub gateway: String, + pub can_register: bool, + pub port_check_target: String, + /// port → open/closed (BTreeMap for deterministic bincode serialization in signed requests) + pub ports: BTreeMap, + #[serde(default, skip_serializing_if = "Option::is_none")] + pub error: Option, +} + +impl PortCheckResult { + /// Returns the list of ports that were found **closed** on this gateway. + pub fn closed_ports(&self) -> Vec { + self.ports + .iter() + .filter_map(|(k, &open)| if !open { k.parse().ok() } else { None }) + .collect() + } +} + #[derive(Debug, Clone, Default)] pub struct IpPingReplies { pub ipr_tun_ip_v4: bool, diff --git a/nym-gateway-probe/src/common/wireguard.rs b/nym-gateway-probe/src/common/wireguard.rs index 3439a4bb5f..a2cb783433 100644 --- a/nym-gateway-probe/src/common/wireguard.rs +++ b/nym-gateway-probe/src/common/wireguard.rs @@ -63,6 +63,7 @@ impl WgTunnelConfig { /// - DNS resolution /// - ICMP ping to specified hosts and IPs /// - Optional download test +/// - Optional exit policy port check (TCP connect through tunnel) /// /// Results are written directly into the provided `wg_outcome` to avoid field-by-field /// copying at call sites. @@ -71,6 +72,7 @@ impl WgTunnelConfig { /// * `config` - WireGuard tunnel configuration /// * `netstack_args` - Netstack test parameters (DNS, hosts to ping, timeouts, etc.) /// * `awg_args` - Amnezia WireGuard arguments (empty string for standard WG) +/// * `port_check_only` - If true, skip pings/download and only run TCP port checks /// * `wg_outcome` - Mutable reference to write test results into // This function extracts the shared netstack testing logic from // wg_probe() and wg_probe_lp() to eliminate code duplication. @@ -78,6 +80,7 @@ pub fn run_tunnel_tests( config: &WgTunnelConfig, netstack_args: &NetstackArgs, awg_args: &str, + port_check_only: bool, wg_outcome: &mut WgProbeResults, ) { // Build the netstack request @@ -91,9 +94,10 @@ pub fn run_tunnel_tests( netstack_args.netstack_download_timeout_sec, awg_args, netstack_args.clone(), + port_check_only, ); - // Perform IPv4 ping test + // Perform IPv4 ping test (also carries port check results in port-check-only mode) info!("Testing IPv4 tunnel connectivity..."); let ipv4_request = NetstackRequestGo::from_rust_v4(&netstack_request); @@ -122,6 +126,11 @@ pub fn run_tunnel_tests( netstack_response_v4.downloaded_file_size_bytes; wg_outcome.downloaded_file_v4 = netstack_response_v4.downloaded_file; wg_outcome.download_error_v4 = netstack_response_v4.download_error; + + // capture port check results (present when ports were requested) + if netstack_response_v4.port_check_results.is_some() { + wg_outcome.port_check_results = netstack_response_v4.port_check_results; + } } Ok(NetstackResult::Error { error }) => { error!("Netstack runtime error (IPv4): {error}") @@ -131,6 +140,12 @@ pub fn run_tunnel_tests( } } + // in port-check-only mode, skip IPv6 tests — port checks ran through IPv4 above + if port_check_only { + info!("Port-check-only mode: skipping IPv6 tunnel tests"); + return; + } + // Perform IPv6 ping test info!("Testing IPv6 tunnel connectivity..."); let ipv6_request = NetstackRequestGo::from_rust_v6(&netstack_request); diff --git a/nym-gateway-probe/src/config/mod.rs b/nym-gateway-probe/src/config/mod.rs index e110823cbf..c54e8897fd 100644 --- a/nym-gateway-probe/src/config/mod.rs +++ b/nym-gateway-probe/src/config/mod.rs @@ -9,7 +9,7 @@ mod socks5; mod test_mode; pub use credentials::{CredentialArgs, CredentialMode}; -pub use netstack::NetstackArgs; +pub use netstack::{EXIT_POLICY_PORTS, NetstackArgs}; pub use socks5::Socks5Args; pub use test_mode::TestMode; @@ -22,7 +22,7 @@ pub struct ProbeConfig { /// Test mode - explicitly specify which tests to run /// /// Modes: - /// core. - Traditional mixnet testing (entry/exit pings + WireGuard via authenticator) + /// core - Traditional mixnet testing (entry/exit pings + WireGuard via authenticator) /// wg-mix - Wireguard via authenticator /// wg-lp - Entry LP + Exit LP (nested forwarding) + WireGuard /// lp-only - LP registration only (no WireGuard) diff --git a/nym-gateway-probe/src/config/netstack.rs b/nym-gateway-probe/src/config/netstack.rs index 5fdd052413..080e7bd31b 100644 --- a/nym-gateway-probe/src/config/netstack.rs +++ b/nym-gateway-probe/src/config/netstack.rs @@ -3,6 +3,11 @@ use clap::Args; +// EXIT_POLICY_PORTS is generated at build time by parsing PORT_MAPPINGS +// from scripts/nym-node-setup/network-tunnel-manager.sh. +// To add or remove ports, update PORT_MAPPINGS in the shell script and rebuild. +include!(concat!(env!("OUT_DIR"), "/exit_policy_ports.rs")); + #[derive(Args, Clone, Debug)] pub struct NetstackArgs { #[arg(long, hide = true, env = "PROBE_NETSTACK_DOWNLOAD_TIMEOUT_SEC", default_value_t = NetstackArgs::default().netstack_download_timeout_sec)] @@ -37,6 +42,22 @@ pub struct NetstackArgs { #[arg(long, hide = true, env = "PROBE_NETSTACK_PING_IPS_V6", default_values_t = NetstackArgs::default().netstack_ping_ips_v6)] pub netstack_ping_ips_v6: Vec, + + /// Target host for exit policy port checks (must listen on all tested ports) + #[arg( + long = "use-target", + env = "PROBE_NETSTACK_PORT_CHECK_TARGET", + default_value = "portquiz.net" + )] + pub port_check_target: String, + + /// List ports to check, separated by a comma. + #[arg(long = "check-ports", value_delimiter = ',', default_values_t = Vec::::new())] + pub port_check_ports: Vec, + + /// Timeout in seconds for each individual port check attempt + #[arg(long, default_value_t = NetstackArgs::default().port_check_timeout_sec)] + pub port_check_timeout_sec: u64, } impl Default for NetstackArgs { @@ -57,6 +78,9 @@ impl Default for NetstackArgs { "2606:4700:4700::1111".to_string(), "2620:fe::fe".to_string(), ], + port_check_target: "portquiz.net".to_string(), + port_check_ports: vec![], + port_check_timeout_sec: 5, } } } @@ -87,6 +111,9 @@ mod tests { "2606:4700:4700::1111".to_string(), "2620:fe::fe".to_string(), ], + port_check_target: "portquiz.net".to_string(), + port_check_ports: vec![], + port_check_timeout_sec: 5, }; // Test IPv4 defaults @@ -111,6 +138,11 @@ mod tests { assert_eq!(args.netstack_num_ping, 5); assert_eq!(args.netstack_send_timeout_sec, 3); assert_eq!(args.netstack_recv_timeout_sec, 3); + + // Test port check defaults + assert_eq!(args.port_check_target, "portquiz.net"); + assert!(args.port_check_ports.is_empty()); + assert_eq!(args.port_check_timeout_sec, 5); } #[test] @@ -128,6 +160,9 @@ mod tests { netstack_ping_ips_v4: vec!["8.8.8.8".to_string()], netstack_ping_hosts_v6: vec!["ipv6.example.com".to_string()], netstack_ping_ips_v6: vec!["2001:4860:4860::8888".to_string()], + port_check_target: "portquiz.net".to_string(), + port_check_ports: vec![80, 443, 8332], + port_check_timeout_sec: 10, }; assert_eq!(args.netstack_ping_hosts_v4, vec!["example.com"]); @@ -163,6 +198,9 @@ mod tests { "2001:4860:4860::8888".to_string(), "2606:4700:4700::1111".to_string(), ], + port_check_target: "portquiz.net".to_string(), + port_check_ports: vec![], + port_check_timeout_sec: 5, }; assert_eq!(args.netstack_ping_hosts_v4, vec!["nym.com", "example.com"]); @@ -192,6 +230,9 @@ mod tests { netstack_ping_ips_v4: vec![], netstack_ping_hosts_v6: vec![], netstack_ping_ips_v6: vec![], + port_check_target: "portquiz.net".to_string(), + port_check_ports: vec![], + port_check_timeout_sec: 0, }; assert_eq!(args.netstack_num_ping, 0); @@ -219,6 +260,9 @@ mod tests { netstack_ping_ips_v4: vec!["1.1.1.1".to_string()], netstack_ping_hosts_v6: vec!["cloudflare.com".to_string()], netstack_ping_ips_v6: vec!["2001:4860:4860::8888".to_string()], + port_check_target: "portquiz.net".to_string(), + port_check_ports: vec![], + port_check_timeout_sec: 5, }; assert!(args.netstack_ping_hosts_v4[0].contains("nym")); @@ -228,4 +272,27 @@ mod tests { assert_eq!(args.netstack_v4_dns, "1.1.1.1"); assert_eq!(args.netstack_v6_dns, "2606:4700:4700::1111"); } + + #[test] + fn test_exit_policy_ports_no_duplicates_and_sorted() { + let ports = EXIT_POLICY_PORTS; + assert!(!ports.is_empty(), "EXIT_POLICY_PORTS should not be empty"); + + // verify sorted + for window in ports.windows(2) { + assert!( + window[0] < window[1], + "EXIT_POLICY_PORTS out of order or duplicate: {} >= {}", + window[0], + window[1] + ); + } + + // spot-check a few well-known ports + assert!(ports.contains(&22), "should contain SSH (22)"); + assert!(ports.contains(&443), "should contain HTTPS (443)"); + assert!(ports.contains(&22021), "should contain Session (22021)"); + assert!(ports.contains(&8332), "should contain Bitcoin (8332)"); + assert!(ports.contains(&9735), "should contain Lightning (9735)"); + } } diff --git a/nym-gateway-probe/src/config/test_mode.rs b/nym-gateway-probe/src/config/test_mode.rs index eec509f0e9..a1a200404a 100644 --- a/nym-gateway-probe/src/config/test_mode.rs +++ b/nym-gateway-probe/src/config/test_mode.rs @@ -10,6 +10,9 @@ //! - LpOnly: LP registration only, no WireGuard //! - Socks5Only: Socks5 test //! - All: Mixnet, wireguard over authenticator and LP registration +//! +//! Note: Exit policy port checking is handled by the `run-ports` subcommand, +//! not via a test mode. /// Test mode for the gateway probe. /// diff --git a/nym-gateway-probe/src/lib.rs b/nym-gateway-probe/src/lib.rs index fe4dbffc47..bc9af69858 100644 --- a/nym-gateway-probe/src/lib.rs +++ b/nym-gateway-probe/src/lib.rs @@ -9,7 +9,9 @@ use crate::common::probe_tests::{ }; use crate::common::types::{Entry, LpProbeResults}; use crate::config::{CredentialArgs, CredentialMode, NetstackArgs, ProbeConfig}; -use nym_authenticator_client::{AuthClientMixnetListener, AuthenticatorClient}; +use nym_authenticator_client::{ + AuthClientMixnetListener, AuthClientMixnetListenerHandle, AuthenticatorClient, +}; use nym_bandwidth_controller::BandwidthTicketProvider; use nym_client_core::config::ForgetMe; use nym_config::defaults::NymNetworkDetails; @@ -20,13 +22,16 @@ use nym_sdk::mixnet::{ }; use nym_topology::{HardcodedTopologyProvider, NymTopology}; use rand::rngs::OsRng; +use std::collections::BTreeMap; +use std::net::IpAddr; use std::path::PathBuf; use std::sync::Arc; +use std::time::Duration; use tokio_util::sync::CancellationToken; use tracing::*; pub use crate::common::nodes::{NymApiDirectory, query_gateway_by_ip}; -pub use crate::common::types::{ProbeOutcome, ProbeResult}; +pub use crate::common::types::{PortCheckResult, PortsCheckSummary, ProbeOutcome, ProbeResult}; mod common; pub use common::types; @@ -45,7 +50,280 @@ pub struct Probe { topology: Option, } +#[derive(Debug, Clone)] +pub struct RunPortsConfig { + pub min_gateway_mixnet_performance: Option, + pub ignore_egress_epoch_role: bool, + pub netstack_args: NetstackArgs, +} + +// Port checks always target a bonded gateway. There are two entry points: +// - `run_ports` : local CLI, on-disk storage + mnemonic. +// - `run_ports_for_agent`: NS agent, ephemeral storage + ticket materials. + +struct PortScanRun { + can_register: bool, + port_results: BTreeMap, + last_error: Option, +} + +/// Validated info needed to run a WG port-check via the mixnet. +struct PortCheckSetup { + exit_node: TestedNodeDetails, + exit_identity: String, + authenticator: nym_sdk::mixnet::Recipient, + ip_address: IpAddr, + port_check_target: String, + ports_count: usize, +} + +impl PortCheckSetup { + fn new(exit_node: TestedNodeDetails, config: &RunPortsConfig) -> anyhow::Result { + let exit_identity = exit_node.identity.to_string(); + + let (authenticator, ip_address) = + match (exit_node.authenticator_address, exit_node.ip_address) { + (Some(auth), Some(ip)) => (auth, ip), + _ => anyhow::bail!( + "Gateway {} missing authenticator address or IP — not a functional exit", + exit_identity + ), + }; + + let ports_count = config.netstack_args.port_check_ports.len(); + if ports_count == 0 { + anyhow::bail!( + "No ports specified. Use --check-ports 80,443,22021 or --check-all-ports" + ); + } + + Ok(Self { + exit_node, + exit_identity, + authenticator, + ip_address, + port_check_target: config.netstack_args.port_check_target.clone(), + ports_count, + }) + } + + fn failed_to_connect(&self, err: impl std::fmt::Display) -> PortCheckResult { + PortCheckResult { + gateway: self.exit_identity.clone(), + can_register: false, + port_check_target: self.port_check_target.clone(), + ports: BTreeMap::new(), + error: Some(format!("Failed to connect to mixnet: {err}")), + } + } +} + impl Probe { + fn parse_port_check_targets(raw: &str) -> Vec { + raw.split(',') + .map(str::trim) + .filter(|s| !s.is_empty()) + .map(ToOwned::to_owned) + .collect() + } + + async fn is_target_reachable(host: &str) -> bool { + let timeout = Duration::from_secs(2); + + for port in [80u16, 443u16] { + if tokio::time::timeout(timeout, tokio::net::TcpStream::connect((host, port))) + .await + .is_ok_and(|res| res.is_ok()) + { + return true; + } + } + + false + } + + async fn run_port_scan_with_retries( + mixnet_listener_task: &AuthClientMixnetListenerHandle, + nym_address: nym_sdk::mixnet::Recipient, + authenticator: nym_sdk::mixnet::Recipient, + authenticator_version: nym_authenticator_requests::AuthenticatorVersion, + ip_address: IpAddr, + bandwidth_provider: &dyn BandwidthTicketProvider, + wg_ticket_type: TicketType, + credential_provider: nym_sdk::mixnet::NodeIdentity, + netstack_args: NetstackArgs, + awg_args: Option, + ) -> PortScanRun { + let mut port_results: BTreeMap = BTreeMap::new(); + let mut can_register = false; + let mut last_error = None; + let max_attempts = 3; + + for attempt in 1..=max_attempts { + if attempt > 1 { + info!("Retrying authenticator registration (attempt {attempt}/{max_attempts})..."); + tokio::time::sleep(std::time::Duration::from_secs(5)).await; + } + + let credential = match bandwidth_provider + .get_ecash_ticket(wg_ticket_type, credential_provider, 1) + .await + { + Ok(ticket) => ticket.data, + Err(e) => { + error!("Failed to get ecash ticket: {e}"); + last_error = Some(format!("Failed to get ecash ticket: {e}")); + break; + } + }; + + let mut rng = rand::thread_rng(); + let auth_client = AuthenticatorClient::new( + mixnet_listener_task.subscribe(), + mixnet_listener_task.mixnet_sender(), + nym_address, + authenticator, + authenticator_version, + Arc::new(x25519::KeyPair::new(&mut rng)), + ip_address, + ); + + match wg_probe( + auth_client, + ip_address, + authenticator_version, + awg_args.clone(), + netstack_args.clone(), + true, // port_check_only + credential, + ) + .await + { + Ok(outcome) => { + if outcome.can_register { + can_register = true; + port_results = outcome + .port_check_results + .unwrap_or_default() + .into_iter() + .collect(); + let open = port_results.values().filter(|&&v| v).count(); + info!( + "Port check complete: {}/{} ports open", + open, + port_results.len() + ); + break; + } + warn!( + "Auth registration returned but can_register=false (attempt {attempt}/{max_attempts})" + ); + last_error = Some("Auth registration did not complete".into()); + } + Err(e) => { + warn!("WG probe error: {e} (attempt {attempt}/{max_attempts})"); + last_error = Some(format!("WG probe error: {e}")); + } + } + } + + PortScanRun { + can_register, + port_results, + last_error, + } + } + + /// Warm up routes, register with the authenticator, run the port scan and tear down. + async fn port_check_after_connect( + mixnet_client: MixnetClient, + setup: PortCheckSetup, + bandwidth_provider: &dyn BandwidthTicketProvider, + netstack_args: NetstackArgs, + ) -> PortCheckResult { + let targets = Self::parse_port_check_targets(&setup.port_check_target); + let mut selected_target = targets + .first() + .cloned() + .unwrap_or_else(|| setup.port_check_target.clone()); + + if targets.len() > 1 { + let mut found = false; + for candidate in &targets { + if Self::is_target_reachable(candidate).await { + selected_target = candidate.clone(); + found = true; + break; + } + warn!( + "Port-check target '{}' is unreachable, trying next", + candidate + ); + } + if !found { + warn!( + "All port-check targets unreachable; falling back to first: '{}'", + selected_target + ); + } else if selected_target != *targets.first().unwrap() { + info!( + "Port check: selected target '{}' (first reachable from list)", + selected_target + ); + } + } + + let mut netstack_args = netstack_args; + netstack_args.port_check_target = selected_target.clone(); + + info!("Warming up mixnet routes..."); + let nym_address = *mixnet_client.nym_address(); + let (warmup_result, mixnet_client) = do_ping( + mixnet_client, + nym_address, + setup.exit_node.exit_router_address, + false, + ) + .await; + + match warmup_result { + Ok(_) => info!("Mixnet warmup done"), + Err(e) => warn!("Warmup had issues ({e}), auth may be less reliable"), + } + + let nym_address = *mixnet_client.nym_address(); + let mixnet_listener_task = + AuthClientMixnetListener::new(mixnet_client, CancellationToken::new()).start(); + + let scan = Self::run_port_scan_with_retries( + &mixnet_listener_task, + nym_address, + setup.authenticator, + setup.exit_node.authenticator_version, + setup.ip_address, + bandwidth_provider, + TicketType::V1WireguardExit, + setup.exit_node.identity, + netstack_args, + None, + ) + .await; + + mixnet_listener_task.stop().await; + + PortCheckResult { + gateway: setup.exit_identity, + can_register: scan.can_register, + port_check_target: selected_target, + ports: scan.port_results, + error: if scan.can_register { + None + } else { + scan.last_error + }, + } + } + /// Create a probe with pre-queried gateway nodes pub fn new( entry_node: TestedNodeDetails, @@ -90,7 +368,6 @@ impl Probe { }) } - /// Run a probe as an NS agent (orchestrator for multiple probe runs for NS API) pub async fn probe_run_agent( mut self, credential_args: CredentialArgs, @@ -269,6 +546,174 @@ impl Probe { self.do_probe_test(mixnet_client, bandwidth_provider).await } + pub async fn run_ports( + entry_node: TestedNodeDetails, + exit_node: Option, + network: NymNetworkDetails, + config: &RunPortsConfig, + config_dir: &PathBuf, + credential: CredentialMode, + ) -> anyhow::Result { + let exit_node = exit_node.unwrap_or(entry_node.clone()); + let setup = PortCheckSetup::new(exit_node, config)?; + + info!( + "Port check: testing {} ports on gateway {} via {}", + setup.ports_count, setup.exit_identity, setup.port_check_target + ); + + let storage_paths = StoragePaths::new_from_dir(config_dir)?; + let storage = storage_paths + .initialise_default_persistent_storage() + .await?; + + let mixnet_debug_config = helpers::mixnet_debug_config( + config.min_gateway_mixnet_performance, + config.ignore_egress_epoch_role, + ); + + let topology = helpers::fetch_topology(&network, &mixnet_debug_config) + .await + .inspect_err(|e| warn!("Failed to fetch topology: {e}")) + .ok(); + + let mut mixnet_client_builder = MixnetClientBuilder::new_with_storage(storage.clone()) + .request_gateway(entry_node.identity.to_string()) + .network_details(network.clone()) + .debug_config(mixnet_debug_config) + .with_forget_me(ForgetMe::new_stats()) + .credentials_mode(!credential.use_mock_ecash); + + if let Some(topology) = &topology { + mixnet_client_builder = mixnet_client_builder.custom_topology_provider(Box::new( + HardcodedTopologyProvider::new(topology.clone()), + )); + } + + let disconnected_mixnet_client = mixnet_client_builder.build()?; + + // make sure identity keys exist before credential acquisition + // (acquire_bandwidth → create_bandwidth_client needs them on disk) + let key_store = storage.key_store(); + if key_store.load_keys().await.is_err() { + debug!("Generating new client keys"); + let mut rng = OsRng; + nym_client_core::init::generate_new_client_keys(&mut rng, key_store).await?; + } + + credential + .acquire(&disconnected_mixnet_client, &storage) + .await?; + + let bandwidth_provider = build_bandwidth_controller( + &network, + storage.credential_store().clone(), + credential.use_mock_ecash, + )?; + + let mixnet_client = match disconnected_mixnet_client.connect_to_mixnet().await { + Ok(client) => { + info!( + "Connected to mixnet via entry gateway: {}", + entry_node.identity + ); + info!("Our nym address: {}", *client.nym_address()); + client + } + Err(e) => return Ok(setup.failed_to_connect(e)), + }; + + Ok(Self::port_check_after_connect( + mixnet_client, + setup, + bandwidth_provider.as_ref(), + config.netstack_args.clone(), + ) + .await) + } + + /// Bonded gateway port-check, run by the NS agent. Uses ephemeral storage and ticket + /// materials provided by the NS API instead of mnemonic-based acquisition. + pub async fn run_ports_for_agent( + entry_gateway: nym_sdk::mixnet::ed25519::PublicKey, + network: NymNetworkDetails, + config: &RunPortsConfig, + credential_args: CredentialArgs, + ) -> anyhow::Result { + let api_url = network + .endpoints + .first() + .and_then(|ep| ep.api_url()) + .ok_or(anyhow::anyhow!("missing api url"))?; + + let directory = NymApiDirectory::new(api_url).await?; + let entry_node = directory + .entry_gateway(&entry_gateway)? + .to_testable_node()?; + + // agent always uses the entry gateway as the exit + let setup = PortCheckSetup::new(entry_node.clone(), config)?; + + info!( + "Port check (agent): testing {} ports on gateway {} via {}", + setup.ports_count, setup.exit_identity, setup.port_check_target + ); + + let storage = Ephemeral::default(); + + let mixnet_debug_config = helpers::mixnet_debug_config( + config.min_gateway_mixnet_performance, + config.ignore_egress_epoch_role, + ); + + let topology = helpers::fetch_topology(&network, &mixnet_debug_config) + .await + .inspect_err(|e| warn!("Failed to fetch topology: {e}")) + .ok(); + + let mut mixnet_client_builder = MixnetClientBuilder::new_with_storage(storage.clone()) + .request_gateway(entry_node.identity.to_string()) + .network_details(network.clone()) + .debug_config(mixnet_debug_config) + .with_forget_me(ForgetMe::new_stats()) + .credentials_mode(true); + + if let Some(topology) = &topology { + mixnet_client_builder = mixnet_client_builder.custom_topology_provider(Box::new( + HardcodedTopologyProvider::new(topology.clone()), + )); + } + + let disconnected_mixnet_client = mixnet_client_builder.build()?; + + credential_args + .import_credential(&disconnected_mixnet_client) + .await?; + + let bandwidth_provider = + build_bandwidth_controller(&network, storage.credential_store().clone(), false)?; + + let mixnet_client = match disconnected_mixnet_client.connect_to_mixnet().await { + Ok(client) => { + info!( + "Connected to mixnet via entry gateway: {}", + entry_node.identity + ); + info!("Our nym address: {}", *client.nym_address()); + client + } + Err(e) => return Ok(setup.failed_to_connect(e)), + }; + + Ok(Self::port_check_after_connect( + mixnet_client, + setup, + bandwidth_provider.as_ref(), + config.netstack_args.clone(), + ) + .await) + } + #[allow(clippy::too_many_arguments)] pub async fn do_probe_test( self, @@ -369,6 +814,7 @@ impl Probe { let mixnet_listener_task = AuthClientMixnetListener::new(mixnet_client, CancellationToken::new()) .start(); + let mut rng = rand::thread_rng(); let auth_client = AuthenticatorClient::new( mixnet_listener_task.subscribe(), @@ -397,6 +843,7 @@ impl Probe { exit_node.authenticator_version, self.config.amnezia_args.clone(), self.config.netstack_args.clone(), + false, credential, ) .await @@ -404,6 +851,7 @@ impl Probe { // Add wg results to probe result probe_result.outcome.wg = Some(outcome); + mixnet_listener_task.stop().await; } else { warn!("Not enough information to run WireGuard via mixnet registration tests"); diff --git a/nym-gateway-probe/src/run.rs b/nym-gateway-probe/src/run.rs index d1c15e22b2..06fcbbb1d8 100644 --- a/nym-gateway-probe/src/run.rs +++ b/nym-gateway-probe/src/run.rs @@ -1,12 +1,15 @@ // Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use clap::{Parser, Subcommand}; +use clap::{Args, Parser, Subcommand}; use nym_bin_common::bin_info; use nym_config::defaults::setup_env; -use nym_gateway_probe::config::{CredentialArgs, CredentialMode, ProbeConfig}; -use nym_gateway_probe::{NymApiDirectory, ProbeResult, query_gateway_by_ip}; +use nym_gateway_probe::config::{CredentialArgs, CredentialMode, NetstackArgs, ProbeConfig}; +use nym_gateway_probe::{ + NymApiDirectory, PortCheckResult, ProbeResult, RunPortsConfig, query_gateway_by_ip, +}; use nym_sdk::mixnet::NodeIdentity; +use serde::Serialize; use std::path::Path; use std::{path::PathBuf, sync::OnceLock}; use tracing::*; @@ -28,7 +31,7 @@ struct CliArgs { config_env_file: Option, /// Disable logging during probe - #[arg(long)] + #[arg(long, global = true)] no_log: bool, } @@ -81,6 +84,35 @@ enum Commands { probe_config: ProbeConfig, }, + /// Check WG exit policy ports on a bonded gateway. + /// Tests TCP connectivity through the WG tunnel for each port. + /// Use --check-ports to pick specific ports, or --check-all-ports for the full exit policy list. + RunPorts { + /// Directory for credential and mixnet storage + #[arg(long)] + config_dir: Option, + + /// Bonded gateway identity. + #[arg(long, short = 'g', alias = "gateway")] + entry_gateway: NodeIdentity, + + /// Separate exit gateway to test (entry_gateway is used for mixnet entry). + #[arg(long)] + exit_gateway: Option, + + /// Test every port in the canonical exit policy (network-tunnel-manager.sh PORT_MAPPINGS). + /// Overrides --check-ports. + #[arg(long)] + check_all_ports: bool, + + /// Arguments to manage credentials + #[command(flatten)] + credential_mode: CredentialMode, + + #[command(flatten)] + probe_config: RunPortsProbeConfig, + }, + /// Run the probe by NS agents RunAgent { /// The specific gateway specified by ID. @@ -96,6 +128,29 @@ enum Commands { }, } +#[derive(Debug, Args, Clone)] +struct RunPortsProbeConfig { + /// Only choose gateway with that minimum performance + #[arg(long)] + min_gateway_mixnet_performance: Option, + + /// Ignore egress epoch role constraints + #[arg(long, global = true)] + ignore_egress_epoch_role: bool, + + /// Arguments to manage netstack downloads and port checks + #[command(flatten)] + netstack_args: NetstackArgs, +} + +/// CLI output wrapper — either a standard probe result or a port-check result +#[derive(Serialize)] +#[serde(untagged)] +pub(crate) enum ProbeOutput { + Standard(ProbeResult), + PortCheck(PortCheckResult), +} + fn setup_logging() { // SAFETY: those are valid directives #[allow(clippy::unwrap_used)] @@ -112,7 +167,7 @@ fn setup_logging() { .init(); } -pub(crate) async fn run() -> anyhow::Result { +pub(crate) async fn run() -> anyhow::Result { let args = CliArgs::parse(); if !args.no_log { setup_logging(); @@ -122,7 +177,7 @@ pub(crate) async fn run() -> anyhow::Result { setup_env(args.config_env_file.as_ref()); let network = nym_sdk::NymNetworkDetails::new_from_env(); - info!("{:#?}", network); + debug!("{:#?}", network); match args.command { Commands::RunLocal { @@ -165,7 +220,9 @@ pub(crate) async fn run() -> anyhow::Result { let trial = nym_gateway_probe::Probe::new(entry_details, exit_details, network, probe_config); - Box::pin(trial.probe_run_locally(&config_dir, credential_mode)).await + Box::pin(trial.probe_run_locally(&config_dir, credential_mode)) + .await + .map(ProbeOutput::Standard) } Commands::Run { entry_gateway, @@ -209,7 +266,79 @@ pub(crate) async fn run() -> anyhow::Result { let trial = nym_gateway_probe::Probe::new(entry_details, exit_details, network, probe_config); - Box::pin(trial.probe_run(&config_dir, credential_mode)).await + Box::pin(trial.probe_run(&config_dir, credential_mode)) + .await + .map(ProbeOutput::Standard) + } + Commands::RunPorts { + entry_gateway, + exit_gateway, + config_dir, + check_all_ports, + credential_mode, + probe_config, + } => { + let mut run_ports_config = RunPortsConfig { + min_gateway_mixnet_performance: probe_config.min_gateway_mixnet_performance, + ignore_egress_epoch_role: probe_config.ignore_egress_epoch_role, + netstack_args: probe_config.netstack_args, + }; + + // --check-all-ports overrides --check-ports with the full exit policy list + if check_all_ports { + use nym_gateway_probe::config::EXIT_POLICY_PORTS; + run_ports_config.netstack_args.port_check_ports = EXIT_POLICY_PORTS.to_vec(); + info!( + "Using full exit policy port list ({} ports)", + EXIT_POLICY_PORTS.len() + ); + } + + let api_url = network + .endpoints + .first() + .and_then(|ep| ep.api_url()) + .ok_or(anyhow::anyhow!("missing api url"))?; + + let directory = NymApiDirectory::new(api_url).await?; + + let entry_details = directory + .entry_gateway(&entry_gateway)? + .to_testable_node()?; + + let exit_details = exit_gateway + .map(|id_key| directory.exit_gateway(&id_key)) + .transpose()? + .map(|node| node.to_testable_node()) + .transpose()?; + + let config_dir = config_dir + .clone() + .unwrap_or_else(|| Path::new(DEFAULT_CONFIG_DIR).join(&network.network_name)); + + if config_dir.is_file() { + anyhow::bail!("provided configuration directory is a file"); + } + + if !config_dir.exists() { + std::fs::create_dir_all(config_dir.clone())?; + } + + info!( + "using the following directory for the probe config: {}", + config_dir.display() + ); + + Box::pin(nym_gateway_probe::Probe::run_ports( + entry_details, + exit_details, + network, + &run_ports_config, + &config_dir, + credential_mode, + )) + .await + .map(ProbeOutput::PortCheck) } Commands::RunAgent { entry_gateway, @@ -219,7 +348,9 @@ pub(crate) async fn run() -> anyhow::Result { let trial = nym_gateway_probe::Probe::new_for_agent(entry_gateway, network, probe_config) .await?; - Box::pin(trial.probe_run_agent(credential_args)).await + Box::pin(trial.probe_run_agent(credential_args)) + .await + .map(ProbeOutput::Standard) } } } diff --git a/nym-node-status-api/nym-node-status-agent/Cargo.toml b/nym-node-status-api/nym-node-status-agent/Cargo.toml index 46d25e8e28..5750036c26 100644 --- a/nym-node-status-api/nym-node-status-agent/Cargo.toml +++ b/nym-node-status-api/nym-node-status-agent/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node-status-agent" -version = "2.0.1-rc3" +version = "2.0.1" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/nym-node-status-api/nym-node-status-agent/src/cli/common.rs b/nym-node-status-api/nym-node-status-agent/src/cli/common.rs new file mode 100644 index 0000000000..95d3277bc0 --- /dev/null +++ b/nym-node-status-api/nym-node-status-agent/src/cli/common.rs @@ -0,0 +1,42 @@ +use crate::cli::{ServerConfig, parse_server_config}; +use anyhow::anyhow; +use nym_gateway_probe::config::CredentialArgs; +use nym_gateway_probe::types::{AttachedTicketMaterials, VersionedSerialise}; +use nym_node_status_client::NsApiClient; +use nym_sdk::mixnet::ed25519::PublicKey; + +pub(crate) fn parse_servers(raw: &[String]) -> anyhow::Result> { + raw.iter() + .map(|s| { + parse_server_config(s).map_err(|e| { + tracing::error!("Invalid server config '{}': {}", s, e); + anyhow!("Invalid server config '{}': {}", s, e) + }) + }) + .collect() +} + +pub(crate) fn primary(servers: &[ServerConfig]) -> anyhow::Result<&ServerConfig> { + servers + .first() + .ok_or_else(|| anyhow!("No servers configured")) +} + +pub(crate) fn build_client(server: &ServerConfig) -> NsApiClient { + let auth_key = + nym_crypto::asymmetric::ed25519::PrivateKey::from_bytes(&server.auth_key.to_bytes()) + .expect("Failed to clone auth key"); + NsApiClient::new(&server.address, server.port, auth_key) +} + +pub(crate) fn parse_gateway_pubkey(key: &str) -> anyhow::Result { + PublicKey::from_base58_string(key).map_err(|e| anyhow!("Failed to parse GW identity key: {e}")) +} + +pub(crate) fn credential_args_from(materials: AttachedTicketMaterials) -> CredentialArgs { + CredentialArgs { + ticket_materials: materials.to_serialised_string(), + ticket_materials_revision: + ::CURRENT_SERIALISATION_REVISION, + } +} diff --git a/nym-node-status-api/nym-node-status-agent/src/cli/mod.rs b/nym-node-status-api/nym-node-status-agent/src/cli/mod.rs index 8acd095fb9..5fbe2ae62d 100644 --- a/nym-node-status-api/nym-node-status-agent/src/cli/mod.rs +++ b/nym-node-status-api/nym-node-status-agent/src/cli/mod.rs @@ -6,7 +6,9 @@ use std::{env, sync::OnceLock}; use tokio::time::Instant; use tracing::info; +pub(crate) mod common; pub(crate) mod generate_keypair; +pub(crate) mod run_ports_check; pub(crate) mod run_probe; #[derive(Debug)] @@ -22,7 +24,7 @@ fn pretty_build_info_static() -> &'static str { PRETTY_BUILD_INFORMATION.get_or_init(|| bin_info!().pretty_print()) } -fn parse_server_config(s: &str) -> Result { +pub(super) fn parse_server_config(s: &str) -> Result { let parts: Vec<&str> = s.split('|').collect(); if parts.len() != 2 { return Err("Server config must be in format 'address|port'".to_string()); @@ -53,6 +55,7 @@ pub(crate) struct Args { #[derive(Subcommand, Debug)] pub(crate) enum Command { RunProbe(RunProbeArgs), + RunPortsCheck(RunPortsCheckArgs), GenerateKeypair { #[arg(long)] @@ -73,6 +76,26 @@ pub(crate) struct RunProbeArgs { pub probe_config: nym_gateway_probe::config::ProbeConfig, } +#[derive(clap::Args, Debug)] +pub(crate) struct RunPortsCheckArgs { + /// Server configurations in format "address|port" + /// Can be specified multiple times for multiple servers + #[arg(short, long, required = true)] + pub server: Vec, + + /// Only choose gateway with that minimum performance + #[arg(long)] + pub min_gateway_mixnet_performance: Option, + + /// Ignore egress epoch role constraints + #[arg(long)] + pub ignore_egress_epoch_role: bool, + + /// Arguments to manage netstack downloads and port checks + #[command(flatten)] + pub netstack_args: nym_gateway_probe::config::NetstackArgs, +} + impl Args { pub(crate) async fn execute(self, log_capture: LogCapture) -> anyhow::Result<()> { match self.command { @@ -99,6 +122,21 @@ impl Args { res?; } + Command::RunPortsCheck(args) => { + let servers = common::parse_servers(&args.server)?; + + run_ports_check::run_ports_check( + &servers, + args.min_gateway_mixnet_performance, + args.ignore_egress_epoch_role, + args.netstack_args, + log_capture, + ) + .await + .inspect_err(|err| { + tracing::error!("{err}"); + })? + } Command::GenerateKeypair { path } => { let path = path .to_owned() diff --git a/nym-node-status-api/nym-node-status-agent/src/cli/run_ports_check.rs b/nym-node-status-api/nym-node-status-agent/src/cli/run_ports_check.rs new file mode 100644 index 0000000000..3fa6b2f2bf --- /dev/null +++ b/nym-node-status-api/nym-node-status-agent/src/cli/run_ports_check.rs @@ -0,0 +1,131 @@ +use crate::cli::ServerConfig; +use crate::cli::common; +use crate::log_capture::LogCapture; +use nym_gateway_probe::RunPortsConfig; +use tracing::instrument; + +pub(crate) async fn run_ports_check( + servers: &[ServerConfig], + min_gateway_mixnet_performance: Option, + ignore_egress_epoch_role: bool, + mut netstack_args: nym_gateway_probe::config::NetstackArgs, + log_capture: LogCapture, +) -> anyhow::Result<()> { + let primary_server = common::primary(servers)?; + tracing::info!( + "Requesting ports-check testrun from primary server: {}:{}", + primary_server.address, + primary_server.port + ); + + let ns_api_client = common::build_client(primary_server); + + let testrun = match ns_api_client.request_ports_check_testrun().await { + Ok(Some(testrun)) => testrun, + Ok(None) => { + tracing::info!("No ports-check testruns available from primary server"); + return Ok(()); + } + Err(err) => { + tracing::error!("Failed to contact primary server: {err}"); + return Err(err); + } + }; + + let testrun_id = testrun.assignment.testrun_id; + let testrun_assigned_at = testrun.assignment.assigned_at_utc; + let gateway_identity_key = testrun.assignment.gateway_identity_key.clone(); + let gateway_identity_pubkey = common::parse_gateway_pubkey(&gateway_identity_key)?; + + tracing::info!( + "Received ports-check testrun {testrun_id} for gateway {gateway_identity_key} from primary", + ); + + let network = nym_sdk::NymNetworkDetails::new_from_env(); + + // Force full exit policy list for this job kind + netstack_args.port_check_ports = nym_gateway_probe::config::EXIT_POLICY_PORTS.to_vec(); + + let run_ports_config = RunPortsConfig { + min_gateway_mixnet_performance, + ignore_egress_epoch_role, + netstack_args, + }; + + let credentials_args = common::credential_args_from(testrun.ticket_materials); + + log_capture.start(); + let port_check_result = nym_gateway_probe::Probe::run_ports_for_agent( + gateway_identity_pubkey, + network, + &run_ports_config, + credentials_args, + ) + .await?; + let probe_log = log_capture.stop_and_drain(); + + submit_ports_check_results_to_servers( + servers, + testrun_id, + testrun_assigned_at, + &gateway_identity_key, + port_check_result, + probe_log, + ) + .await; + + Ok(()) +} + +#[instrument(level = "info", skip_all, fields(gateway_id = %gateway_identity_key, testrun = testrun_id))] +async fn submit_ports_check_results_to_servers( + servers: &[ServerConfig], + testrun_id: i32, + testrun_assigned_at: i64, + gateway_identity_key: &str, + port_check_result: nym_gateway_probe::PortCheckResult, + probe_log: String, +) { + let handles = servers + .iter() + .enumerate() + .map(|(idx, server)| { + let port_check_result = port_check_result.clone(); + let probe_log = probe_log.clone(); + let gateway_identity_key = gateway_identity_key.to_string(); + + async move { + let client = common::build_client(server); + + let result = client + .submit_ports_check_results_with_context( + testrun_id, + port_check_result, + probe_log, + testrun_assigned_at, + gateway_identity_key, + ) + .await; + + (idx, server.address.clone(), server.port, result) + } + }) + .collect::>(); + + let results = futures::future::join_all(handles).await; + + for (index, server_address, server_port, result) in results { + match result { + Ok(()) => { + tracing::info!( + "✅ Successfully submitted ports-check to server[{index}] {server_address}:{server_port}", + ); + } + Err(e) => { + tracing::warn!( + "❌ Failed to submit ports-check to server[{index}] {server_address}:{server_port} - {e}" + ); + } + } + } +} diff --git a/nym-node-status-api/nym-node-status-agent/src/cli/run_probe.rs b/nym-node-status-api/nym-node-status-agent/src/cli/run_probe.rs index 216329fa78..6e4da33cab 100644 --- a/nym-node-status-api/nym-node-status-agent/src/cli/run_probe.rs +++ b/nym-node-status-api/nym-node-status-agent/src/cli/run_probe.rs @@ -1,9 +1,6 @@ use crate::cli::ServerConfig; +use crate::cli::common; use crate::log_capture::LogCapture; -use anyhow::anyhow; -use nym_gateway_probe::config::CredentialArgs; -use nym_gateway_probe::types::{AttachedTicketMaterials, VersionedSerialise}; -use nym_sdk::mixnet::ed25519::PublicKey; use tracing::instrument; pub(crate) async fn run_probe( @@ -11,27 +8,14 @@ pub(crate) async fn run_probe( probe_config: nym_gateway_probe::config::ProbeConfig, log_capture: LogCapture, ) -> anyhow::Result<()> { - if servers.is_empty() { - anyhow::bail!("No servers configured"); - } - - // Always use first server as primary - let primary_server = &servers[0]; + let primary_server = common::primary(servers)?; tracing::info!( "Requesting testrun from primary server: {}:{}", primary_server.address, primary_server.port ); - let auth_key = nym_crypto::asymmetric::ed25519::PrivateKey::from_bytes( - &primary_server.auth_key.to_bytes(), - ) - .expect("Failed to clone auth key"); - let ns_api_client = nym_node_status_client::NsApiClient::new( - &primary_server.address, - primary_server.port, - auth_key, - ); + let ns_api_client = common::build_client(primary_server); let testrun = match ns_api_client.request_testrun().await { Ok(Some(testrun)) => testrun, @@ -48,8 +32,7 @@ pub(crate) async fn run_probe( let testrun_id = testrun.assignment.testrun_id; let testrun_assigned_at = testrun.assignment.assigned_at_utc; let gateway_identity_key = testrun.assignment.gateway_identity_key.clone(); - let gateway_identity_pubkey = PublicKey::from_base58_string(gateway_identity_key.clone()) - .map_err(|e| anyhow!("Failed to parse GW identity key: {e}"))?; + let gateway_identity_pubkey = common::parse_gateway_pubkey(&gateway_identity_key)?; tracing::info!("Received testrun {testrun_id} for gateway {gateway_identity_key} from primary",); @@ -61,12 +44,7 @@ pub(crate) async fn run_probe( // probe constructor might modify config to suit the testing mode, so log afterwards tracing::info!("Using probe config:\n{:#?}", &probe.config()); - let serialized_ticket_materials = testrun.ticket_materials.to_serialised_string(); - let credentials_args = CredentialArgs { - ticket_materials: serialized_ticket_materials, - ticket_materials_revision: - ::CURRENT_SERIALISATION_REVISION, - }; + let credentials_args = common::credential_args_from(testrun.ticket_materials); // Run the probe, capturing all tracing output log_capture.start(); @@ -110,15 +88,7 @@ async fn submit_results_to_servers( let gateway_identity_key = gateway_identity_key.to_string(); async move { - let auth_key = nym_crypto::asymmetric::ed25519::PrivateKey::from_bytes( - &server.auth_key.to_bytes(), - ) - .expect("Failed to clone auth key"); - let client = nym_node_status_client::NsApiClient::new( - &server.address, - server.port, - auth_key, - ); + let client = common::build_client(server); let result = if idx == 0 { // Primary server: submit regular results without context diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-f343df183767af9815847cb94ccbd484010a7346de03f1e0959a09a964344de8.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-0c635c539930c10a9be35a12ba3f2a66aae5be1c37af2eca521bf75261cecf28.json similarity index 66% rename from nym-node-status-api/nym-node-status-api/.sqlx/query-f343df183767af9815847cb94ccbd484010a7346de03f1e0959a09a964344de8.json rename to nym-node-status-api/nym-node-status-api/.sqlx/query-0c635c539930c10a9be35a12ba3f2a66aae5be1c37af2eca521bf75261cecf28.json index b6dd6ac8a9..53756614d0 100644 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-f343df183767af9815847cb94ccbd484010a7346de03f1e0959a09a964344de8.json +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-0c635c539930c10a9be35a12ba3f2a66aae5be1c37af2eca521bf75261cecf28.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT\n id,\n gateway_id,\n status,\n created_utc,\n ip_address,\n log,\n last_assigned_utc\n FROM testruns\n WHERE gateway_id = $1 AND status != 2\n ORDER BY id DESC\n LIMIT 1", + "query": "SELECT\n id,\n gateway_id,\n status,\n kind,\n created_utc,\n ip_address,\n log,\n last_assigned_utc\n FROM testruns\n WHERE gateway_id = $1 AND status != 2 AND kind = $2\n ORDER BY id DESC\n LIMIT 1", "describe": { "columns": [ { @@ -20,28 +20,34 @@ }, { "ordinal": 3, + "name": "kind", + "type_info": "Int2" + }, + { + "ordinal": 4, "name": "created_utc", "type_info": "Int8" }, { - "ordinal": 4, + "ordinal": 5, "name": "ip_address", "type_info": "Varchar" }, { - "ordinal": 5, + "ordinal": 6, "name": "log", "type_info": "Varchar" }, { - "ordinal": 6, + "ordinal": 7, "name": "last_assigned_utc", "type_info": "Int8" } ], "parameters": { "Left": [ - "Int4" + "Int4", + "Int2" ] }, "nullable": [ @@ -51,8 +57,9 @@ false, false, false, + false, true ] }, - "hash": "f343df183767af9815847cb94ccbd484010a7346de03f1e0959a09a964344de8" + "hash": "0c635c539930c10a9be35a12ba3f2a66aae5be1c37af2eca521bf75261cecf28" } diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-88a4554c2857288c314768c56648a5f1811d2053582380ca602335a122cef8db.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-1dc7d1e6c2173cd1ca70d699124c2b71a1a91ef114ffdd0572a738b577fab15d.json similarity index 51% rename from nym-node-status-api/nym-node-status-api/.sqlx/query-88a4554c2857288c314768c56648a5f1811d2053582380ca602335a122cef8db.json rename to nym-node-status-api/nym-node-status-api/.sqlx/query-1dc7d1e6c2173cd1ca70d699124c2b71a1a91ef114ffdd0572a738b577fab15d.json index 174d528667..656a892089 100644 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-88a4554c2857288c314768c56648a5f1811d2053582380ca602335a122cef8db.json +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-1dc7d1e6c2173cd1ca70d699124c2b71a1a91ef114ffdd0572a738b577fab15d.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "INSERT INTO testruns (\n id,\n gateway_id,\n status,\n created_utc,\n last_assigned_utc,\n ip_address,\n log\n ) VALUES ($1, $2, $3, $4, $5, $6, $7)", + "query": "INSERT INTO testruns (\n id,\n gateway_id,\n status,\n kind,\n created_utc,\n last_assigned_utc,\n ip_address,\n log\n ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)", "describe": { "columns": [], "parameters": { @@ -8,6 +8,7 @@ "Int4", "Int4", "Int4", + "Int2", "Int8", "Int8", "Varchar", @@ -16,5 +17,5 @@ }, "nullable": [] }, - "hash": "88a4554c2857288c314768c56648a5f1811d2053582380ca602335a122cef8db" + "hash": "1dc7d1e6c2173cd1ca70d699124c2b71a1a91ef114ffdd0572a738b577fab15d" } diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-3c6da5c1faace026222bbb28553d8ea15b957dd19b097101dcda2c05aee21d20.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-3c6da5c1faace026222bbb28553d8ea15b957dd19b097101dcda2c05aee21d20.json new file mode 100644 index 0000000000..bd975d3146 --- /dev/null +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-3c6da5c1faace026222bbb28553d8ea15b957dd19b097101dcda2c05aee21d20.json @@ -0,0 +1,15 @@ +{ + "db_name": "PostgreSQL", + "query": "UPDATE gateways SET last_ports_check_utc = $1, last_updated_utc = $1 WHERE id = $2", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int8", + "Int4" + ] + }, + "nullable": [] + }, + "hash": "3c6da5c1faace026222bbb28553d8ea15b957dd19b097101dcda2c05aee21d20" +} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-65b5a3ed9a73f1304badfa8d9bba57fb24f6b21655039a9bfa21c44409c87910.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-65b5a3ed9a73f1304badfa8d9bba57fb24f6b21655039a9bfa21c44409c87910.json new file mode 100644 index 0000000000..fa226820d2 --- /dev/null +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-65b5a3ed9a73f1304badfa8d9bba57fb24f6b21655039a9bfa21c44409c87910.json @@ -0,0 +1,18 @@ +{ + "db_name": "PostgreSQL", + "query": "\n INSERT INTO testruns (gateway_id, status, kind, created_utc, last_assigned_utc, ip_address, log)\n SELECT\n gw.id,\n $1,\n $2,\n $3,\n NULL,\n 'ports_check_scheduler',\n ''\n FROM gateways gw\n WHERE gw.bonded = true\n AND (gw.last_ports_check_utc IS NULL OR gw.last_ports_check_utc < $4)\n AND NOT EXISTS (\n SELECT 1\n FROM testruns t\n WHERE t.gateway_id = gw.id\n AND t.kind = $2\n AND t.status IN ($1, $5)\n )\n ", + "describe": { + "columns": [], + "parameters": { + "Left": [ + "Int4", + "Int2", + "Int8", + "Int8", + "Int4" + ] + }, + "nullable": [] + }, + "hash": "65b5a3ed9a73f1304badfa8d9bba57fb24f6b21655039a9bfa21c44409c87910" +} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-d41cafc76cb49c03df7452c405a4e2e5e3951c41dc35c20261c1d959c0d6403f.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-75bdccbff8ea6a59d56230075163783249a03f2ae04ec89f734e67ceb897a385.json similarity index 67% rename from nym-node-status-api/nym-node-status-api/.sqlx/query-d41cafc76cb49c03df7452c405a4e2e5e3951c41dc35c20261c1d959c0d6403f.json rename to nym-node-status-api/nym-node-status-api/.sqlx/query-75bdccbff8ea6a59d56230075163783249a03f2ae04ec89f734e67ceb897a385.json index 7eafc8e67d..a99e7bebdc 100644 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-d41cafc76cb49c03df7452c405a4e2e5e3951c41dc35c20261c1d959c0d6403f.json +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-75bdccbff8ea6a59d56230075163783249a03f2ae04ec89f734e67ceb897a385.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT\n id as \"id!\",\n gateway_id as \"gateway_id!\",\n status as \"status!\",\n created_utc as \"created_utc!\",\n ip_address as \"ip_address!\",\n log as \"log!\",\n last_assigned_utc\n FROM testruns\n WHERE\n id = $1\n AND\n status = $2\n ORDER BY created_utc\n LIMIT 1", + "query": "SELECT\n id as \"id!\",\n gateway_id as \"gateway_id!\",\n status as \"status!\",\n kind as \"kind!\",\n created_utc as \"created_utc!\",\n ip_address as \"ip_address!\",\n log as \"log!\",\n last_assigned_utc\n FROM testruns\n WHERE\n id = $1\n AND\n status = $2\n ORDER BY created_utc\n LIMIT 1", "describe": { "columns": [ { @@ -20,21 +20,26 @@ }, { "ordinal": 3, + "name": "kind!", + "type_info": "Int2" + }, + { + "ordinal": 4, "name": "created_utc!", "type_info": "Int8" }, { - "ordinal": 4, + "ordinal": 5, "name": "ip_address!", "type_info": "Varchar" }, { - "ordinal": 5, + "ordinal": 6, "name": "log!", "type_info": "Varchar" }, { - "ordinal": 6, + "ordinal": 7, "name": "last_assigned_utc", "type_info": "Int8" } @@ -52,8 +57,9 @@ false, false, false, + false, true ] }, - "hash": "d41cafc76cb49c03df7452c405a4e2e5e3951c41dc35c20261c1d959c0d6403f" + "hash": "75bdccbff8ea6a59d56230075163783249a03f2ae04ec89f734e67ceb897a385" } diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-ad78bf2f7ed4666b4e5f60811f04cb8bf8ebb1c26839f915780d0fc0d1939973.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-ad78bf2f7ed4666b4e5f60811f04cb8bf8ebb1c26839f915780d0fc0d1939973.json new file mode 100644 index 0000000000..9d0d9105ef --- /dev/null +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-ad78bf2f7ed4666b4e5f60811f04cb8bf8ebb1c26839f915780d0fc0d1939973.json @@ -0,0 +1,31 @@ +{ + "db_name": "PostgreSQL", + "query": "\n WITH oldest_queued AS (\n SELECT id\n FROM testruns\n WHERE status = $1 AND kind = $4\n ORDER BY created_utc asc\n LIMIT 1\n FOR UPDATE SKIP LOCKED\n )\n UPDATE testruns\n SET\n status = $3,\n last_assigned_utc = $2\n FROM oldest_queued\n WHERE testruns.id = oldest_queued.id\n RETURNING\n testruns.id,\n testruns.gateway_id\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int4" + }, + { + "ordinal": 1, + "name": "gateway_id", + "type_info": "Int4" + } + ], + "parameters": { + "Left": [ + "Int4", + "Int8", + "Int4", + "Int2" + ] + }, + "nullable": [ + false, + false + ] + }, + "hash": "ad78bf2f7ed4666b4e5f60811f04cb8bf8ebb1c26839f915780d0fc0d1939973" +} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-ddf003e7e13653388f487e3adfc1aad0a285e29c797f99ec00bcccb063f76b64.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-b32d29ca3cedae93fa2fcd44cc301614edc4e967f348c57f485f736b8f2f03e8.json similarity index 72% rename from nym-node-status-api/nym-node-status-api/.sqlx/query-ddf003e7e13653388f487e3adfc1aad0a285e29c797f99ec00bcccb063f76b64.json rename to nym-node-status-api/nym-node-status-api/.sqlx/query-b32d29ca3cedae93fa2fcd44cc301614edc4e967f348c57f485f736b8f2f03e8.json index 59962eb2ed..f543ada553 100644 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-ddf003e7e13653388f487e3adfc1aad0a285e29c797f99ec00bcccb063f76b64.json +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-b32d29ca3cedae93fa2fcd44cc301614edc4e967f348c57f485f736b8f2f03e8.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT\n id,\n gateway_id,\n status,\n created_utc,\n ip_address,\n log,\n last_assigned_utc\n FROM testruns\n WHERE id = $1", + "query": "SELECT\n id,\n gateway_id,\n status,\n kind,\n created_utc,\n ip_address,\n log,\n last_assigned_utc\n FROM testruns\n WHERE id = $1", "describe": { "columns": [ { @@ -20,21 +20,26 @@ }, { "ordinal": 3, + "name": "kind", + "type_info": "Int2" + }, + { + "ordinal": 4, "name": "created_utc", "type_info": "Int8" }, { - "ordinal": 4, + "ordinal": 5, "name": "ip_address", "type_info": "Varchar" }, { - "ordinal": 5, + "ordinal": 6, "name": "log", "type_info": "Varchar" }, { - "ordinal": 6, + "ordinal": 7, "name": "last_assigned_utc", "type_info": "Int8" } @@ -51,8 +56,9 @@ false, false, false, + false, true ] }, - "hash": "ddf003e7e13653388f487e3adfc1aad0a285e29c797f99ec00bcccb063f76b64" + "hash": "b32d29ca3cedae93fa2fcd44cc301614edc4e967f348c57f485f736b8f2f03e8" } diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-cc84f8a284c9aba4494152ff4e6087af53e9504a8bb13280dde5c37b9b418370.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-cc84f8a284c9aba4494152ff4e6087af53e9504a8bb13280dde5c37b9b418370.json new file mode 100644 index 0000000000..5e76c4c3cc --- /dev/null +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-cc84f8a284c9aba4494152ff4e6087af53e9504a8bb13280dde5c37b9b418370.json @@ -0,0 +1,22 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT last_probe_result FROM gateways WHERE id = $1", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "last_probe_result", + "type_info": "Varchar" + } + ], + "parameters": { + "Left": [ + "Int4" + ] + }, + "nullable": [ + true + ] + }, + "hash": "cc84f8a284c9aba4494152ff4e6087af53e9504a8bb13280dde5c37b9b418370" +} diff --git a/nym-node-status-api/nym-node-status-api/Cargo.toml b/nym-node-status-api/nym-node-status-api/Cargo.toml index 2306bc0708..aaf21e044b 100644 --- a/nym-node-status-api/nym-node-status-api/Cargo.toml +++ b/nym-node-status-api/nym-node-status-api/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node-status-api" -version = "4.6.2-rc10" +version = "4.6.2" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/nym-node-status-api/nym-node-status-api/Makefile b/nym-node-status-api/nym-node-status-api/Makefile index f0ae2fe951..5b410e2468 100644 --- a/nym-node-status-api/nym-node-status-api/Makefile +++ b/nym-node-status-api/nym-node-status-api/Makefile @@ -39,6 +39,19 @@ test-db-wait: ## Wait for the PostgreSQL database to be healthy sleep 1; \ done; \ echo " Database is healthy!" + @echo "Waiting for host port to be ready..." + @for i in $$(seq 1 30); do \ + if pg_isready -h localhost -p 5433 -U testuser -d nym_node_status_api_test >/dev/null 2>&1; then \ + echo " Host port is ready!"; \ + break; \ + fi; \ + if [ $$i -eq 30 ]; then \ + echo " Timed out waiting for host port"; \ + exit 1; \ + fi; \ + echo -n "."; \ + sleep 1; \ + done .PHONY: test-db-down test-db-down: ## Stop and remove the test database diff --git a/nym-node-status-api/nym-node-status-api/migrations_pg/20260414000000_ports_check_testrun_kind.sql b/nym-node-status-api/nym-node-status-api/migrations_pg/20260414000000_ports_check_testrun_kind.sql new file mode 100644 index 0000000000..ea013b2c52 --- /dev/null +++ b/nym-node-status-api/nym-node-status-api/migrations_pg/20260414000000_ports_check_testrun_kind.sql @@ -0,0 +1,8 @@ +ALTER TABLE gateways + ADD COLUMN IF NOT EXISTS last_ports_check_utc BIGINT; + +ALTER TABLE testruns + ADD COLUMN IF NOT EXISTS kind SMALLINT NOT NULL DEFAULT 0; + +CREATE INDEX IF NOT EXISTS idx_testruns_kind_status_created + ON testruns (kind, status, created_utc); diff --git a/nym-node-status-api/nym-node-status-api/migrations_pg/20260415000000_gateways_ports_check.sql b/nym-node-status-api/nym-node-status-api/migrations_pg/20260415000000_gateways_ports_check.sql new file mode 100644 index 0000000000..e521cb2aa5 --- /dev/null +++ b/nym-node-status-api/nym-node-status-api/migrations_pg/20260415000000_gateways_ports_check.sql @@ -0,0 +1,14 @@ +ALTER TABLE gateways ADD COLUMN IF NOT EXISTS ports_check JSONB; + +UPDATE gateways +SET ports_check = (last_probe_result::jsonb -> 'ports_check') +WHERE last_probe_result IS NOT NULL + AND btrim(last_probe_result) <> '' + AND last_probe_result::jsonb ? 'ports_check' + AND ports_check IS NULL; + +UPDATE gateways +SET last_probe_result = (last_probe_result::jsonb - 'ports_check')::text +WHERE last_probe_result IS NOT NULL + AND btrim(last_probe_result) <> '' + AND last_probe_result::jsonb ? 'ports_check'; \ No newline at end of file diff --git a/nym-node-status-api/nym-node-status-api/src/cli/mod.rs b/nym-node-status-api/nym-node-status-api/src/cli/mod.rs index e52a97ca32..29b5b30657 100644 --- a/nym-node-status-api/nym-node-status-api/src/cli/mod.rs +++ b/nym-node-status-api/nym-node-status-api/src/cli/mod.rs @@ -82,6 +82,15 @@ pub(crate) struct Cli { #[arg(value_parser = parse_duration_std)] pub(crate) testruns_refresh_interval: Duration, + /// 2 hour safety net for test runs which include a port check + #[clap( + long, + default_value = "7200", + env = "NODE_STATUS_API_TESTRUN_STALE_IN_PROGRESS" + )] + #[arg(value_parser = parse_duration_std)] + pub(crate) testruns_stale_in_progress: Duration, + #[clap(long, default_value = "86400", env = "NODE_STATUS_API_GEODATA_TTL")] #[arg(value_parser = parse_duration_std)] pub(crate) geodata_ttl: Duration, diff --git a/nym-node-status-api/nym-node-status-api/src/db/models.rs b/nym-node-status-api/nym-node-status-api/src/db/models.rs index d9291462af..567fc34a18 100644 --- a/nym-node-status-api/nym-node-status-api/src/db/models.rs +++ b/nym-node-status-api/nym-node-status-api/src/db/models.rs @@ -18,6 +18,103 @@ use strum_macros::{EnumString, FromRepr}; use time::{Date, OffsetDateTime, UtcDateTime}; use utoipa::ToSchema; +fn build_ports_check_summary_json( + can_register: bool, + port_check_target: Option, + ports: Option<&serde_json::Map>, + error: Option, +) -> serde_json::Value { + let failed_ports = ports + .map(|ports| { + ports + .iter() + .filter_map(|(port, open)| open.as_bool().filter(|is_open| !is_open).map(|_| port)) + .cloned() + .collect::>() + }) + .unwrap_or_default(); + + let has_ports = ports.is_some_and(|p| !p.is_empty()); + let all_pass = can_register && failed_ports.is_empty() && has_ports; + + serde_json::json!({ + "all_pass": all_pass, + "error": error, + "port_check_target": port_check_target, + "failed_ports": failed_ports, + }) +} + +pub(crate) fn ports_check_summary_json_from_result( + result: &nym_gateway_probe::PortCheckResult, +) -> serde_json::Value { + let ports = result + .ports + .iter() + .map(|(k, v)| (k.clone(), serde_json::Value::Bool(*v))) + .collect::>(); + + build_ports_check_summary_json( + result.can_register, + Some(result.port_check_target.clone()), + Some(&ports), + result.error.clone(), + ) +} + +pub(crate) fn normalize_ports_check_payload(value: serde_json::Value) -> Option { + let serde_json::Value::Object(map) = value else { + return None; + }; + + // New shape is already in place; pass through untouched. + if map.contains_key("all_pass") + && map.contains_key("error") + && map.contains_key("port_check_target") + && map.contains_key("failed_ports") + { + return Some(serde_json::Value::Object(map)); + } + + // Legacy dedicated shape: { gateway, can_register, port_check_target, ports, error } + if map.contains_key("can_register") && map.contains_key("ports") { + let can_register = map + .get("can_register") + .and_then(serde_json::Value::as_bool) + .unwrap_or(false); + let port_check_target = map + .get("port_check_target") + .and_then(serde_json::Value::as_str) + .map(ToOwned::to_owned); + let ports = map.get("ports").and_then(serde_json::Value::as_object); + let error = map + .get("error") + .and_then(serde_json::Value::as_str) + .map(ToOwned::to_owned); + + return Some(build_ports_check_summary_json( + can_register, + port_check_target, + ports, + error, + )); + } + + if map.contains_key("all_pass") && map.contains_key("failed_ports") { + let mut normalized = map; + normalized.remove("ports_tested"); + normalized + .entry("port_check_target".to_string()) + .or_insert(serde_json::Value::Null); + normalized + .entry("error".to_string()) + .or_insert(serde_json::Value::Null); + return Some(serde_json::Value::Object(normalized)); + } + + Some(serde_json::Value::Object(map)) +} + macro_rules! serialize_opt_to_value { ($var:expr) => {{ match $var { @@ -48,6 +145,8 @@ pub(crate) struct GatewayDto { pub(crate) explorer_pretty_bond: Option, pub(crate) last_probe_result: Option, pub(crate) last_probe_log: Option, + pub(crate) ports_check: Option, + pub(crate) last_ports_check_utc: Option, pub(crate) last_testrun_utc: Option, pub(crate) last_updated_utc: i64, pub(crate) moniker: String, @@ -73,7 +172,7 @@ impl TryFrom for http::models::Gateway { .explorer_pretty_bond .clone() .unwrap_or("null".to_string()); - let last_probe_result = value + let last_probe_result_raw = value .last_probe_result .clone() .unwrap_or("null".to_string()); @@ -81,7 +180,18 @@ impl TryFrom for http::models::Gateway { let self_described = serde_json::from_str(&self_described).unwrap_or(None); let explorer_pretty_bond = serde_json::from_str(&explorer_pretty_bond).unwrap_or(None); - let last_probe_result = serde_json::from_str(&last_probe_result).unwrap_or(None); + let last_probe_result = serde_json::from_str::(&last_probe_result_raw) + .ok() + .and_then(|v| (!v.is_null()).then_some(v)); + + let ports_check = value + .ports_check + .clone() + .filter(|v| !v.is_null()) + .and_then(normalize_ports_check_payload); + let last_ports_check_utc = value + .last_ports_check_utc + .map(unix_timestamp_to_utc_rfc3339); let bonded = value.bonded; let performance = value.performance as u8; @@ -104,6 +214,8 @@ impl TryFrom for http::models::Gateway { description, last_probe_result, last_probe_log, + ports_check, + last_ports_check_utc, routing_score, config_score, last_testrun_utc, @@ -292,6 +404,7 @@ pub struct TestRunDto { pub id: i32, pub gateway_id: i32, pub status: i32, + pub kind: i16, pub created_utc: i64, pub ip_address: String, pub log: String, @@ -306,6 +419,13 @@ pub(crate) enum TestRunStatus { Queued = 0, } +#[derive(Debug, Clone, Copy, strum_macros::Display, EnumString, FromRepr, PartialEq, Eq)] +#[repr(i16)] +pub(crate) enum TestRunKind { + Probe = 0, + PortsCheck = 1, +} + #[derive(Debug, Clone)] pub struct GatewayIdentityDto { pub gateway_identity_key: String, diff --git a/nym-node-status-api/nym-node-status-api/src/db/queries/gateways.rs b/nym-node-status-api/nym-node-status-api/src/db/queries/gateways.rs index 99e178086a..2b7c33da9b 100644 --- a/nym-node-status-api/nym-node-status-api/src/db/queries/gateways.rs +++ b/nym-node-status-api/nym-node-status-api/src/db/queries/gateways.rs @@ -76,6 +76,12 @@ impl Storage { Ok(()) } + gw.last_probe_log as "last_probe_log?", + gw.ports_check as "ports_check?", + + gw.last_testrun_utc as "last_testrun_utc?", + .await?; + .await?; pub(crate) async fn get_all_gateways(&self) -> anyhow::Result> { let items = sqlx::query_as!( GatewayDto, @@ -87,6 +93,8 @@ impl Storage { gw.explorer_pretty_bond as "explorer_pretty_bond?", gw.last_probe_result as "last_probe_result?", gw.last_probe_log as "last_probe_log?", + gw.ports_check as "ports_check?", + gw.last_ports_check_utc as "last_ports_check_utc?", gw.last_testrun_utc as "last_testrun_utc?", gw.last_updated_utc as "last_updated_utc!", gw.bridges as "bridges?: serde_json::Value", @@ -102,7 +110,6 @@ impl Storage { .fetch(&self.pool) .try_collect::>() .await?; - let items: Vec = items .into_iter() .map(|item| item.try_into()) diff --git a/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs b/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs index 71d5d88e60..bc2719cea6 100644 --- a/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs +++ b/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs @@ -1,8 +1,10 @@ use crate::db::DbConnection; use crate::db::DbPool; -use crate::db::models::{TestRunDto, TestRunStatus}; +use crate::db::models::{TestRunDto, TestRunKind, TestRunStatus}; use crate::http::models::TestrunAssignment; use crate::utils::now_utc; +use sqlx::Row; +use sqlx::types::Json; use time::Duration; pub(crate) async fn count_testruns_in_progress( @@ -32,6 +34,7 @@ pub(crate) async fn get_in_progress_testrun_by_id( id as "id!", gateway_id as "gateway_id!", status as "status!", + kind as "kind!", created_utc as "created_utc!", ip_address as "ip_address!", log as "log!", @@ -90,6 +93,19 @@ pub(crate) async fn update_testruns_assigned_before( pub(crate) async fn assign_oldest_testrun( conn: &mut DbConnection, +) -> anyhow::Result> { + assign_oldest_testrun_by_kind(conn, TestRunKind::Probe).await +} + +pub(crate) async fn assign_oldest_ports_check_testrun( + conn: &mut DbConnection, +) -> anyhow::Result> { + assign_oldest_testrun_by_kind(conn, TestRunKind::PortsCheck).await +} + +async fn assign_oldest_testrun_by_kind( + conn: &mut DbConnection, + kind: TestRunKind, ) -> anyhow::Result> { let now = now_utc().unix_timestamp(); // find & mark as "In progress" in the same transaction to avoid race conditions @@ -120,28 +136,27 @@ pub(crate) async fn assign_oldest_testrun( TestRunStatus::Queued as i32, now, TestRunStatus::InProgress as i32, + kind as i16, ) .fetch_optional(conn.as_mut()) .await?; if let Some(testrun) = returning { - let gw_identity = sqlx::query!( - r#" - SELECT - id, - gateway_identity_key - FROM gateways - WHERE id = $1 - LIMIT 1"#, - testrun.gateway_id + let row = sqlx::query( + r#"SELECT gateway_identity_key, last_ports_check_utc FROM gateways WHERE id = $1 LIMIT 1"#, ) + .bind(testrun.gateway_id) .fetch_one(conn.as_mut()) .await?; + let gateway_identity_key: String = row.try_get("gateway_identity_key")?; + let last_ports_check_utc: Option = row.try_get("last_ports_check_utc")?; + Ok(Some(TestrunAssignment { testrun_id: testrun.id, - gateway_identity_key: gw_identity.gateway_identity_key, + gateway_identity_key, assigned_at_utc: now, + last_ports_check_utc, })) } else { Ok(None) @@ -186,17 +201,121 @@ pub(crate) async fn update_gateway_last_probe_result( gateway_pk: i32, result: &str, ) -> anyhow::Result<()> { - sqlx::query!( - "UPDATE gateways SET last_probe_result = $1 WHERE id = $2", - result, - gateway_pk, + sqlx::query("UPDATE gateways SET last_probe_result = $1 WHERE id = $2") + .bind(result) + .bind(gateway_pk) + .execute(conn.as_mut()) + .await + .map(drop) + .map_err(From::from) +} + +// NOTE: port-check submissions must not re-embed `ports_check` into `last_probe_result`. + +pub(crate) async fn update_gateway_ports_check_only( + conn: &mut DbConnection, + gateway_pk: i32, + port_check_result: &nym_gateway_probe::PortCheckResult, +) -> anyhow::Result<()> { + use crate::db::models::ports_check_summary_json_from_result; + + let now_ts = now_utc().unix_timestamp(); + let value = ports_check_summary_json_from_result(port_check_result); + + sqlx::query( + r#"UPDATE gateways SET + ports_check = $1, + last_ports_check_utc = $2 + WHERE id = $3"#, ) + .bind(Json(value)) + .bind(now_ts) + .bind(gateway_pk) .execute(conn.as_mut()) .await .map(drop) .map_err(From::from) } +pub(crate) async fn insert_external_ports_check_testrun( + conn: &mut DbConnection, + testrun_id: i32, + gateway_id: i32, + assigned_at_utc: i64, +) -> anyhow::Result<()> { + let now = now_utc().unix_timestamp(); + + sqlx::query!( + r#"INSERT INTO testruns ( + id, + gateway_id, + status, + kind, + created_utc, + last_assigned_utc, + ip_address, + log + ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)"#, + testrun_id, + gateway_id, + TestRunStatus::InProgress as i32, + TestRunKind::PortsCheck as i16, + now, + assigned_at_utc, + "external", + "" + ) + .execute(conn.as_mut()) + .await?; + + tracing::debug!( + "Created external ports-check testrun {} for gateway {}", + testrun_id, + gateway_id + ); + Ok(()) +} + +pub(crate) async fn enqueue_due_ports_check_testruns(db: &DbPool) -> anyhow::Result { + let mut conn = db.acquire().await?; + let now = now_utc().unix_timestamp(); + // 14 days soft TTL for dedicated ports-check queueing. + let cutoff = now - time::Duration::days(14).whole_seconds(); + + let res = sqlx::query!( + r#" + INSERT INTO testruns (gateway_id, status, kind, created_utc, last_assigned_utc, ip_address, log) + SELECT + gw.id, + $1, + $2, + $3, + NULL, + 'ports_check_scheduler', + '' + FROM gateways gw + WHERE gw.bonded = true + AND (gw.last_ports_check_utc IS NULL OR gw.last_ports_check_utc < $4) + AND NOT EXISTS ( + SELECT 1 + FROM testruns t + WHERE t.gateway_id = gw.id + AND t.kind = $2 + AND t.status IN ($1, $5) + ) + "#, + TestRunStatus::Queued as i32, + TestRunKind::PortsCheck as i16, + now, + cutoff, + TestRunStatus::InProgress as i32, + ) + .execute(conn.as_mut()) + .await?; + + Ok(res.rows_affected()) +} + pub(crate) async fn update_gateway_score( conn: &mut DbConnection, gateway_pk: i32, @@ -224,6 +343,7 @@ pub(crate) async fn get_testrun_by_id( id, gateway_id, status, + kind, created_utc, ip_address, log, @@ -250,14 +370,16 @@ pub(crate) async fn insert_external_testrun( id, gateway_id, status, + kind, created_utc, last_assigned_utc, ip_address, log - ) VALUES ($1, $2, $3, $4, $5, $6, $7)"#, + ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)"#, testrun_id, gateway_id, TestRunStatus::InProgress as i32, + TestRunKind::Probe as i16, now, assigned_at_utc, "external", // Marker for external origin diff --git a/nym-node-status-api/nym-node-status-api/src/db/tests.rs b/nym-node-status-api/nym-node-status-api/src/db/tests.rs index 5fbb6ac712..2734612da2 100644 --- a/nym-node-status-api/nym-node-status-api/src/db/tests.rs +++ b/nym-node-status-api/nym-node-status-api/src/db/tests.rs @@ -11,6 +11,8 @@ mod db_tests { explorer_pretty_bond: Some("{\"key\":\"value\"}".to_string()), last_probe_result: Some("{\"key\":\"value\"}".to_string()), last_probe_log: Some("log".to_string()), + ports_check: None, + last_ports_check_utc: None, last_testrun_utc: Some(1672531200), last_updated_utc: 1672531200, moniker: "moniker".to_string(), @@ -37,6 +39,101 @@ mod db_tests { assert_eq!(http_gateway.description.details, "details"); } + #[test] + fn test_gateway_dto_normalizes_legacy_dedicated_ports_check_shape() { + let legacy_ports = serde_json::json!({ + "gateway": "gw1", + "can_register": true, + "port_check_target": "portquiz.net", + "ports": { + "20": false, + "21": true, + "43": false + }, + "error": null + }); + let gateway_dto = crate::db::models::GatewayDto { + gateway_identity_key: "id1".to_string(), + bonded: true, + performance: 50, + self_described: Some("{}".to_string()), + explorer_pretty_bond: Some("{}".to_string()), + last_probe_result: None, + last_probe_log: None, + ports_check: Some(legacy_ports), + last_ports_check_utc: Some(1672531200), + last_testrun_utc: None, + last_updated_utc: 1672531200, + moniker: "m".to_string(), + security_contact: "c".to_string(), + details: "d".to_string(), + website: "w".to_string(), + bridges: None, + }; + + let http_gateway: crate::http::models::Gateway = gateway_dto.try_into().unwrap(); + let normalized = http_gateway.ports_check.unwrap(); + + assert_eq!( + normalized.get("all_pass"), + Some(&serde_json::Value::Bool(false)) + ); + assert_eq!( + normalized.get("port_check_target"), + Some(&serde_json::Value::String("portquiz.net".to_string())) + ); + assert_eq!(normalized.get("error"), Some(&serde_json::Value::Null)); + assert_eq!( + normalized.get("failed_ports"), + Some(&serde_json::json!(["20", "43"])) + ); + assert!(normalized.get("gateway").is_none()); + assert!(normalized.get("ports").is_none()); + } + + #[test] + fn test_gateway_dto_normalizes_legacy_in_probe_summary_shape() { + let legacy_summary = serde_json::json!({ + "all_pass": true, + "failed_ports": [], + "error": null, + "ports_tested": 32 + }); + let gateway_dto = crate::db::models::GatewayDto { + gateway_identity_key: "id2".to_string(), + bonded: true, + performance: 50, + self_described: Some("{}".to_string()), + explorer_pretty_bond: Some("{}".to_string()), + last_probe_result: None, + last_probe_log: None, + ports_check: Some(legacy_summary), + last_ports_check_utc: Some(1672531200), + last_testrun_utc: None, + last_updated_utc: 1672531200, + moniker: "m".to_string(), + security_contact: "c".to_string(), + details: "d".to_string(), + website: "w".to_string(), + bridges: None, + }; + + let http_gateway: crate::http::models::Gateway = gateway_dto.try_into().unwrap(); + let normalized = http_gateway.ports_check.unwrap(); + + assert_eq!( + normalized.get("all_pass"), + Some(&serde_json::Value::Bool(true)) + ); + assert_eq!(normalized.get("failed_ports"), Some(&serde_json::json!([]))); + assert_eq!(normalized.get("error"), Some(&serde_json::Value::Null)); + assert_eq!( + normalized.get("port_check_target"), + Some(&serde_json::Value::Null) + ); + assert!(normalized.get("ports_tested").is_none()); + } + #[test] fn test_mixnode_dto_try_from() { let mixnode_dto = crate::db::models::MixnodeDto { @@ -267,6 +364,8 @@ fn test_gateway_dto_with_null_values() { explorer_pretty_bond: None, last_probe_result: None, last_probe_log: None, + ports_check: None, + last_ports_check_utc: None, last_testrun_utc: None, last_updated_utc: 0, moniker: "".to_string(), diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/gateways.rs b/nym-node-status-api/nym-node-status-api/src/http/api/gateways.rs index 0270de9abf..f52df6bbad 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/gateways.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/gateways.rs @@ -106,6 +106,8 @@ fn filter_bonded_gateways_to_skinny(gateways: Vec) -> Vec Router { Router::new() .route("/", axum::routing::get(request_testrun)) - .route("/{testrun_id}", axum::routing::post(submit_testrun)) - .route("/{testrun_id}/v2", axum::routing::post(submit_testrun_v2)) + .route( + "/ports-check", + axum::routing::get(request_ports_check_testrun), + ) + .route("/:testrun_id", axum::routing::post(submit_testrun)) + .route("/:testrun_id/v2", axum::routing::post(submit_testrun_v2)) + .route( + "/:testrun_id/ports-check/v2", + axum::routing::post(submit_ports_check_testrun_v2), + ) .layer(DefaultBodyLimit::max(1024 * 1024 * 5)) } @@ -117,6 +126,64 @@ async fn request_testrun( } } +#[tracing::instrument(level = "debug", skip_all)] +async fn request_ports_check_testrun( + State(state): State, + Json(request): Json, +) -> HttpResult> { + state.authenticate_agent_submission(&request)?; + state.is_fresh(&request.payload.timestamp)?; + + tracing::debug!("Agent requested ports-check testrun"); + + let db = state.db_pool(); + let mut conn = db + .acquire() + .await + .map_err(HttpError::internal_with_logging)?; + + let active_testruns = db::queries::testruns::count_testruns_in_progress(&mut conn) + .await + .map_err(HttpError::internal_with_logging)? + .unwrap_or_default(); + let max_count = state.agent_max_count(); + if active_testruns >= max_count { + tracing::warn!("{active_testruns}/{max_count} testruns in progress, rejecting",); + return Err(HttpError::no_testruns_available()); + } + + match db::queries::testruns::assign_oldest_ports_check_testrun(&mut conn).await { + Ok(res) => { + let Some(assignment) = res else { + tracing::debug!("No ports-check testruns available"); + return Err(HttpError::no_testruns_available()); + }; + + tracing::info!( + "🏃‍ Assigned ports-check testrun row_id {} gateway {} to agent", + &assignment.testrun_id, + assignment.gateway_identity_key, + ); + + let materials = state + .ticketbook_manager_state() + .attempt_assign_ticket_materials(assignment.testrun_id) + .await + .map_err(|err| { + error!( + "failed to get ticket materials for runner {}: {err}", + assignment.testrun_id + ); + HttpError::internal_with_logging(format!( + "could not retrieve needed tickets: {err}" + )) + })?; + Ok(Json(assignment.with_ticket_materials(materials))) + } + Err(err) => Err(HttpError::internal_with_logging(err)), + } +} + #[tracing::instrument(level = "debug", skip_all)] async fn submit_testrun( Path(submitted_testrun_id): Path, @@ -374,3 +441,148 @@ async fn process_testrun_submission_by_gateway( Ok(StatusCode::CREATED) } + +#[tracing::instrument(level = "debug", skip_all)] +async fn submit_ports_check_testrun_v2( + Path(submitted_testrun_id): Path, + State(state): State, + Json(submission): Json, +) -> HttpResult { + state.authenticate_agent_submission(&submission)?; + + let db = state.db_pool(); + let mut conn = db + .acquire() + .await + .map_err(HttpError::internal_with_logging)?; + + match queries::testruns::get_testrun_by_id(&mut conn, submitted_testrun_id).await { + Ok(testrun) => { + if testrun.kind != TestRunKind::PortsCheck as i16 { + tracing::warn!( + "Testrun {} has wrong kind for ports-check submit: {}", + submitted_testrun_id, + testrun.kind + ); + return Err(HttpError::invalid_input(format!( + "Testrun {} is not a ports-check run", + submitted_testrun_id + ))); + } + + let gw_identity = queries::select_gateway_identity(&mut conn, testrun.gateway_id) + .await + .map_err(HttpError::internal_with_logging)?; + + if gw_identity != submission.payload.gateway_identity_key { + tracing::warn!( + "Gateway mismatch for ports-check testrun {}: expected {}, got {}", + submitted_testrun_id, + gw_identity, + submission.payload.gateway_identity_key + ); + return Err(HttpError::invalid_input("Gateway identity mismatch")); + } + + if Some(submission.payload.assigned_at_utc) != testrun.last_assigned_utc { + tracing::warn!( + "Submitted ports-check testrun timestamp mismatch: {} != {:?}, rejecting", + submission.payload.assigned_at_utc, + testrun.last_assigned_utc + ); + return Err(HttpError::invalid_input(format!( + "Ports-check testrun {} timestamp mismatch: expected {:?}, got {}", + submitted_testrun_id, + testrun.last_assigned_utc, + submission.payload.assigned_at_utc + ))); + } + + process_ports_check_submission( + submitted_testrun_id, + testrun.gateway_id, + submission.payload, + &mut conn, + ) + .await + } + Err(_) => { + tracing::info!( + "Creating external ports-check testrun {} for gateway {}", + submitted_testrun_id, + submission.payload.gateway_identity_key + ); + + let gateway_id = + queries::get_or_create_gateway(&mut conn, &submission.payload.gateway_identity_key) + .await + .map_err(HttpError::internal_with_logging)?; + + queries::testruns::insert_external_ports_check_testrun( + &mut conn, + submitted_testrun_id, + gateway_id, + submission.payload.assigned_at_utc, + ) + .await + .map_err(HttpError::internal_with_logging)?; + + process_ports_check_submission( + submitted_testrun_id, + gateway_id, + submission.payload, + &mut conn, + ) + .await + } + } +} + +async fn process_ports_check_submission( + testrun_id: i32, + gateway_id: i32, + payload: submit_ports_check_results_v2::Payload, + conn: &mut DbConnection, +) -> HttpResult { + let gw_identity = &payload.gateway_identity_key; + let open_ports = payload + .port_check_result + .ports + .values() + .filter(|&&v| v) + .count(); + let total_ports = payload.port_check_result.ports.len(); + + tracing::debug!( + "Processing ports-check submission for gateway {} ({} bytes, {}/{} ports open, can_register={})", + gw_identity, + payload.probe_log.len(), + open_ports, + total_ports, + payload.port_check_result.can_register, + ); + + queries::testruns::update_gateway_ports_check_only( + conn, + gateway_id, + &payload.port_check_result, + ) + .await + .map_err(HttpError::internal_with_logging)?; + + queries::testruns::update_testrun_status(conn, testrun_id, TestRunStatus::Complete) + .await + .map_err(HttpError::internal_with_logging)?; + + let assigned_at = unix_timestamp_to_utc_rfc3339(payload.assigned_at_utc); + let now = now_utc(); + tracing::info!( + "✅ Ports-check testrun {} for gateway {} complete (assigned at {}, current time {})", + testrun_id, + gw_identity, + assigned_at, + now + ); + + Ok(StatusCode::CREATED) +} diff --git a/nym-node-status-api/nym-node-status-api/src/http/models/gw_probe/test.rs b/nym-node-status-api/nym-node-status-api/src/http/models/gw_probe/test.rs index e88512b5d3..dd06ce0450 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/models/gw_probe/test.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/models/gw_probe/test.rs @@ -20,6 +20,8 @@ fn test_weighted_score_calculation() { }, last_probe_result: None, last_probe_log: None, + ports_check: None, + last_ports_check_utc: None, last_testrun_utc: None, last_updated_utc: "2025-10-10T00:00:00Z".to_string(), routing_score: 0.0, @@ -163,10 +165,12 @@ fn conversion_from_gw_probe_latest() { downloaded_file_size_bytes_v6: 20971520, downloaded_file_v6: "test-file-v6.bin".to_string(), download_error_v6: "none-v6".to_string(), + port_check_results: None, }; let probe_latest = ProbeResultLatest { node: "test-node-identity-key".to_string(), used_entry: "test-entry-node".to_string(), + ports_check: None, outcome: ProbeOutcomeLatest { as_entry: EntryLatest::Tested(EntryTestResultLatest { can_connect: true, diff --git a/nym-node-status-api/nym-node-status-api/src/http/models/mod.rs b/nym-node-status-api/nym-node-status-api/src/http/models/mod.rs index dfb93f9c52..fb3f354fa2 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/models/mod.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/models/mod.rs @@ -44,6 +44,8 @@ pub struct Gateway { pub description: NodeDescription, pub last_probe_result: Option, pub last_probe_log: Option, + pub ports_check: Option, + pub last_ports_check_utc: Option, pub last_testrun_utc: Option, pub last_updated_utc: String, pub routing_score: f32, @@ -676,6 +678,8 @@ mod test { self_described: Some(serde_json::json!({"test": "value"})), explorer_pretty_bond: None, last_probe_result: Some(serde_json::json!({"status": "ok"})), + ports_check: None, + last_ports_check_utc: None, last_testrun_utc: Some("2024-01-20T10:00:00Z".to_string()), last_updated_utc: "2024-01-20T11:00:00Z".to_string(), routing_score: 0.95, @@ -738,6 +742,8 @@ pub struct GatewaySkinny { pub self_described: Option, pub explorer_pretty_bond: Option, pub last_probe_result: Option, + pub ports_check: Option, + pub last_ports_check_utc: Option, pub last_testrun_utc: Option, pub last_updated_utc: String, pub routing_score: f32, diff --git a/nym-node-status-api/nym-node-status-api/src/http/server.rs b/nym-node-status-api/nym-node-status-api/src/http/server.rs index 0127cc0fc1..13011a3472 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/server.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/server.rs @@ -9,6 +9,7 @@ use core::net::SocketAddr; use nym_crypto::asymmetric::ed25519::PublicKey; use nym_task::ShutdownTracker; use std::sync::Arc; +use tokio::time::MissedTickBehavior; use tokio::{net::TcpListener, sync::RwLock}; /// Return handles that allow for graceful shutdown of server + awaiting its @@ -27,6 +28,7 @@ pub(crate) async fn start_http_api( shutdown_tracker: &ShutdownTracker, ) -> anyhow::Result<()> { let router_builder = RouterBuilder::with_default_routes(); + let db_pool_for_scheduler = db_pool.clone(); let state = AppState::new( storage, @@ -46,6 +48,34 @@ pub(crate) async fn start_http_api( let server = router.build_server(bind_addr).await?; let shutdown = shutdown_tracker.clone_shutdown_token().cancelled_owned(); + let ports_check_scheduler_enabled = std::env::var("PORTS_CHECK_SCHEDULER_ENABLED") + .ok() + .map(|v| matches!(v.as_str(), "1" | "true" | "TRUE" | "yes" | "YES")) + .unwrap_or(true); + + if ports_check_scheduler_enabled { + let mut interval = tokio::time::interval(std::time::Duration::from_secs(60 * 10)); + interval.set_missed_tick_behavior(MissedTickBehavior::Skip); + let scheduler_shutdown = shutdown_tracker.clone_shutdown_token().cancelled_owned(); + shutdown_tracker.spawn(async move { + tokio::select! { + _ = async { + loop { + interval.tick().await; + match crate::db::queries::testruns::enqueue_due_ports_check_testruns(&db_pool_for_scheduler).await { + Ok(enqueued) if enqueued > 0 => tracing::info!("Enqueued {enqueued} due ports-check testruns"), + Ok(_) => {} + Err(e) => tracing::warn!("Failed to enqueue due ports-check testruns: {e}"), + } + } + } => {}, + _ = scheduler_shutdown => {} + } + }); + } else { + tracing::info!("Ports-check scheduler disabled (PORTS_CHECK_SCHEDULER_ENABLED=false)"); + } + shutdown_tracker.spawn(async move { axum::serve( server.listener, diff --git a/nym-node-status-api/nym-node-status-api/src/http/state.rs b/nym-node-status-api/nym-node-status-api/src/http/state.rs index 1776ea23e3..1d8affed94 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/state.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/state.rs @@ -134,10 +134,10 @@ impl AppState { return Err(HttpError::unauthorized()); }; - request.verify_signature().map_err(|_| { + if request.verify_signature().is_err() { tracing::warn!("Signature verification failed, rejecting"); - HttpError::unauthorized() - })?; + return Err(HttpError::unauthorized()); + } Ok(()) } diff --git a/nym-node-status-api/nym-node-status-api/src/main.rs b/nym-node-status-api/nym-node-status-api/src/main.rs index c392edb880..e8ae6b6954 100644 --- a/nym-node-status-api/nym-node-status-api/src/main.rs +++ b/nym-node-status-api/nym-node-status-api/src/main.rs @@ -130,7 +130,12 @@ async fn main() -> anyhow::Result<()> { let pool = storage.pool_owned(); shutdown_manager.spawn_with_shutdown(async move { - testruns::start(pool, args.testruns_refresh_interval).await + testruns::start( + pool, + args.testruns_refresh_interval, + args.testruns_stale_in_progress, + ) + .await }); let db_pool_scraper = storage.pool_owned(); diff --git a/nym-node-status-api/nym-node-status-api/src/test_helpers/mod.rs b/nym-node-status-api/nym-node-status-api/src/test_helpers/mod.rs index ee201d555d..8173a6647c 100644 --- a/nym-node-status-api/nym-node-status-api/src/test_helpers/mod.rs +++ b/nym-node-status-api/nym-node-status-api/src/test_helpers/mod.rs @@ -29,10 +29,13 @@ pub mod builders { }, last_probe_result: None, last_probe_log: None, + ports_check: None, + last_ports_check_utc: None, last_testrun_utc: None, last_updated_utc: "2024-01-01T00:00:00Z".to_string(), routing_score: 0.95, config_score: 100, + bridges: None, }, } } diff --git a/nym-node-status-api/nym-node-status-api/src/testruns/mod.rs b/nym-node-status-api/nym-node-status-api/src/testruns/mod.rs index eb212a2b11..e17f44c2a8 100644 --- a/nym-node-status-api/nym-node-status-api/src/testruns/mod.rs +++ b/nym-node-status-api/nym-node-status-api/src/testruns/mod.rs @@ -8,9 +8,13 @@ use tracing::instrument; pub(crate) mod models; mod queue; -pub(crate) async fn start(pool: DbPool, refresh_interval: Duration) { +pub(crate) async fn start( + pool: DbPool, + refresh_interval: Duration, + stale_in_progress_after: Duration, +) { loop { - if let Err(e) = refresh_stale_testruns(&pool, refresh_interval).await { + if let Err(e) = refresh_stale_testruns(&pool, stale_in_progress_after).await { tracing::error!("{e}"); } diff --git a/nym-node-status-api/nym-node-status-api/src/testruns/queue.rs b/nym-node-status-api/nym-node-status-api/src/testruns/queue.rs index 8a283f3464..f64164972d 100644 --- a/nym-node-status-api/nym-node-status-api/src/testruns/queue.rs +++ b/nym-node-status-api/nym-node-status-api/src/testruns/queue.rs @@ -1,5 +1,5 @@ use crate::db::DbConnection; -use crate::db::models::{GatewayInfoDto, TestRunDto, TestRunStatus}; +use crate::db::models::{GatewayInfoDto, TestRunDto, TestRunKind, TestRunStatus}; use crate::testruns::models::TestRun; use crate::utils::now_utc; use anyhow::anyhow; @@ -53,15 +53,17 @@ pub(crate) async fn try_queue_testrun( id, gateway_id, status, + kind, created_utc, ip_address, log, last_assigned_utc FROM testruns - WHERE gateway_id = $1 AND status != 2 + WHERE gateway_id = $1 AND status != 2 AND kind = $2 ORDER BY id DESC LIMIT 1"#, - gateway_id + gateway_id, + TestRunKind::Probe as i16 ) .fetch(conn.as_mut()) .try_collect::>() diff --git a/nym-node-status-api/nym-node-status-client/src/api.rs b/nym-node-status-api/nym-node-status-client/src/api.rs index c41b25bf89..4f1c1029ea 100644 --- a/nym-node-status-api/nym-node-status-client/src/api.rs +++ b/nym-node-status-api/nym-node-status-client/src/api.rs @@ -12,6 +12,10 @@ impl ApiPaths { format!("{}/internal/testruns", self.server_address) } + pub(super) fn request_ports_check_testrun(&self) -> String { + format!("{}/internal/testruns/ports-check", self.server_address) + } + pub(super) fn submit_results(&self, testrun_id: impl Display) -> String { format!("{}/internal/testruns/{}", self.server_address, testrun_id) } @@ -22,4 +26,11 @@ impl ApiPaths { self.server_address, testrun_id ) } + + pub(super) fn submit_ports_check_results_v2(&self, testrun_id: impl Display) -> String { + format!( + "{}/internal/testruns/{}/ports-check/v2", + self.server_address, testrun_id + ) + } } diff --git a/nym-node-status-api/nym-node-status-client/src/lib.rs b/nym-node-status-api/nym-node-status-client/src/lib.rs index 6d118062fc..73de44b361 100644 --- a/nym-node-status-api/nym-node-status-client/src/lib.rs +++ b/nym-node-status-api/nym-node-status-client/src/lib.rs @@ -1,4 +1,7 @@ -use crate::models::{TestrunAssignmentWithTickets, get_testrun, submit_results, submit_results_v2}; +use crate::models::{ + TestrunAssignmentWithTickets, get_testrun, submit_ports_check_results_v2, submit_results, + submit_results_v2, +}; use anyhow::bail; use api::ApiPaths; use nym_crypto::asymmetric::ed25519::{PrivateKey, Signature}; @@ -71,7 +74,53 @@ impl NsApiClient { testrun }) .map_err(|err| { - tracing::error!("err"); + tracing::error!("{err}"); + err.into() + }) + } + + #[instrument(level = "info", skip_all)] + pub async fn request_ports_check_testrun( + &self, + ) -> anyhow::Result> { + let target_url = self.api.request_ports_check_testrun(); + + let payload = get_testrun::Payload { + agent_public_key: self.auth_key.public_key(), + timestamp: time::UtcDateTime::now().unix_timestamp(), + }; + let signature = self.sign_message(&payload)?; + let request = get_testrun::GetTestrunRequest { payload, signature }; + + let res = self.client.get(target_url).json(&request).send().await?; + let status = res.status(); + let response_text = res.text().await?; + + if status.is_client_error() { + if matches!(status, reqwest::StatusCode::NOT_FOUND) { + tracing::warn!( + "Ports-check request endpoint not available on server (404), skipping iteration" + ); + return Ok(None); + } + bail!("{}: {}", status, response_text); + } else if status.is_server_error() { + if matches!(status, reqwest::StatusCode::SERVICE_UNAVAILABLE) + && response_text.contains("No testruns available") + { + return Ok(None); + } else { + bail!("{}: {}", status, response_text); + } + } + + serde_json::from_str(&response_text) + .map(|testrun| { + tracing::info!("Received ports-check testrun assignment: {:?}", testrun); + testrun + }) + .map_err(|err| { + tracing::error!("{err}"); err.into() }) } @@ -151,6 +200,40 @@ impl NsApiClient { Ok(()) } + #[instrument(level = "info", skip(self, port_check_result))] + pub async fn submit_ports_check_results_with_context( + &self, + testrun_id: i32, + port_check_result: nym_gateway_probe::PortCheckResult, + probe_log: String, + assigned_at_utc: i64, + gateway_identity_key: String, + ) -> anyhow::Result<()> { + let target_url = self.api.submit_ports_check_results_v2(testrun_id); + + let payload = submit_ports_check_results_v2::Payload { + port_check_result, + probe_log, + agent_public_key: self.auth_key.public_key(), + assigned_at_utc, + gateway_identity_key, + }; + let signature = self.sign_message(&payload)?; + let submit = + submit_ports_check_results_v2::SubmitPortsCheckResultsV2 { payload, signature }; + + let res = self + .client + .post(target_url) + .json(&submit) + .send() + .await + .and_then(|response| response.error_for_status())?; + + tracing::debug!("Submitted ports-check results: {})", res.status()); + Ok(()) + } + fn sign_message(&self, message: &T) -> anyhow::Result where T: serde::Serialize, diff --git a/nym-node-status-api/nym-node-status-client/src/models.rs b/nym-node-status-api/nym-node-status-client/src/models.rs index 4b362f24fc..00935c5a17 100644 --- a/nym-node-status-api/nym-node-status-client/src/models.rs +++ b/nym-node-status-api/nym-node-status-client/src/models.rs @@ -41,6 +41,9 @@ pub struct TestrunAssignment { pub testrun_id: i32, pub assigned_at_utc: i64, pub gateway_identity_key: String, + /// Unix timestamp (seconds) of the last persisted exit-policy port check for this gateway. + #[serde(default)] + pub last_ports_check_utc: Option, } impl TestrunAssignment { @@ -143,3 +146,39 @@ pub mod submit_results_v2 { } } } + +pub mod submit_ports_check_results_v2 { + use crate::auth::SignedRequest; + + use super::*; + #[derive(Debug, Clone, Deserialize, Serialize)] + pub struct Payload { + pub port_check_result: nym_gateway_probe::PortCheckResult, + pub probe_log: String, + pub agent_public_key: PublicKey, + pub assigned_at_utc: i64, + pub gateway_identity_key: String, + } + + #[derive(Debug, Clone, Deserialize, Serialize)] + pub struct SubmitPortsCheckResultsV2 { + pub payload: Payload, + pub signature: Signature, + } + + impl SignedRequest for SubmitPortsCheckResultsV2 { + type Payload = Payload; + + fn public_key(&self) -> &PublicKey { + &self.payload.agent_public_key + } + + fn signature(&self) -> &Signature { + &self.signature + } + + fn payload(&self) -> &Self::Payload { + &self.payload + } + } +} From 1532c0c16e3345402c7ff67562ec25d3227a73df Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Mon, 11 May 2026 09:34:44 +0200 Subject: [PATCH 62/94] addressing ai comments --- .../src/cli/run_ports_check.rs | 5 +++-- .../nym-node-status-agent/src/cli/run_probe.rs | 3 ++- .../20260415000000_gateways_ports_check.sql | 2 ++ .../nym-node-status-api/src/cli/mod.rs | 2 +- .../nym-node-status-client/src/lib.rs | 16 ++++++++++++---- 5 files changed, 20 insertions(+), 8 deletions(-) diff --git a/nym-node-status-api/nym-node-status-agent/src/cli/run_ports_check.rs b/nym-node-status-api/nym-node-status-agent/src/cli/run_ports_check.rs index 3fa6b2f2bf..c4bc641b6f 100644 --- a/nym-node-status-api/nym-node-status-agent/src/cli/run_ports_check.rs +++ b/nym-node-status-api/nym-node-status-agent/src/cli/run_ports_check.rs @@ -55,14 +55,15 @@ pub(crate) async fn run_ports_check( let credentials_args = common::credential_args_from(testrun.ticket_materials); log_capture.start(); - let port_check_result = nym_gateway_probe::Probe::run_ports_for_agent( + let port_check_result_res = nym_gateway_probe::Probe::run_ports_for_agent( gateway_identity_pubkey, network, &run_ports_config, credentials_args, ) - .await?; + .await; let probe_log = log_capture.stop_and_drain(); + let port_check_result = port_check_result_res?; submit_ports_check_results_to_servers( servers, diff --git a/nym-node-status-api/nym-node-status-agent/src/cli/run_probe.rs b/nym-node-status-api/nym-node-status-agent/src/cli/run_probe.rs index 6e4da33cab..2e5aca47cd 100644 --- a/nym-node-status-api/nym-node-status-agent/src/cli/run_probe.rs +++ b/nym-node-status-api/nym-node-status-agent/src/cli/run_probe.rs @@ -48,8 +48,9 @@ pub(crate) async fn run_probe( // Run the probe, capturing all tracing output log_capture.start(); - let probe_result = Box::pin(probe.probe_run_agent(credentials_args)).await?; + let probe_result_res = Box::pin(probe.probe_run_agent(credentials_args)).await; let probe_log = log_capture.stop_and_drain(); + let probe_result = probe_result_res?; // Inspect the probe output for socks5 field match probe_result.outcome.socks5.as_ref() { diff --git a/nym-node-status-api/nym-node-status-api/migrations_pg/20260415000000_gateways_ports_check.sql b/nym-node-status-api/nym-node-status-api/migrations_pg/20260415000000_gateways_ports_check.sql index e521cb2aa5..f506b093f5 100644 --- a/nym-node-status-api/nym-node-status-api/migrations_pg/20260415000000_gateways_ports_check.sql +++ b/nym-node-status-api/nym-node-status-api/migrations_pg/20260415000000_gateways_ports_check.sql @@ -4,6 +4,7 @@ UPDATE gateways SET ports_check = (last_probe_result::jsonb -> 'ports_check') WHERE last_probe_result IS NOT NULL AND btrim(last_probe_result) <> '' + AND last_probe_result ~ '^[\[{]' AND last_probe_result::jsonb ? 'ports_check' AND ports_check IS NULL; @@ -11,4 +12,5 @@ UPDATE gateways SET last_probe_result = (last_probe_result::jsonb - 'ports_check')::text WHERE last_probe_result IS NOT NULL AND btrim(last_probe_result) <> '' + AND last_probe_result ~ '^[\[{]' AND last_probe_result::jsonb ? 'ports_check'; \ No newline at end of file diff --git a/nym-node-status-api/nym-node-status-api/src/cli/mod.rs b/nym-node-status-api/nym-node-status-api/src/cli/mod.rs index 29b5b30657..18bc84f48b 100644 --- a/nym-node-status-api/nym-node-status-api/src/cli/mod.rs +++ b/nym-node-status-api/nym-node-status-api/src/cli/mod.rs @@ -82,7 +82,7 @@ pub(crate) struct Cli { #[arg(value_parser = parse_duration_std)] pub(crate) testruns_refresh_interval: Duration, - /// 2 hour safety net for test runs which include a port check + /// Safety net for stale in-progress testruns (whole seconds, es. 7200). #[clap( long, default_value = "7200", diff --git a/nym-node-status-api/nym-node-status-client/src/lib.rs b/nym-node-status-api/nym-node-status-client/src/lib.rs index 73de44b361..27aac8b538 100644 --- a/nym-node-status-api/nym-node-status-client/src/lib.rs +++ b/nym-node-status-api/nym-node-status-client/src/lib.rs @@ -69,8 +69,12 @@ impl NsApiClient { } serde_json::from_str(&response_text) - .map(|testrun| { - tracing::info!("Received testrun assignment: {:?}", testrun); + .map(|testrun: TestrunAssignmentWithTickets| { + tracing::info!( + testrun_id = testrun.assignment.testrun_id, + gateway = %testrun.assignment.gateway_identity_key, + "Received testrun assignment", + ); testrun }) .map_err(|err| { @@ -115,8 +119,12 @@ impl NsApiClient { } serde_json::from_str(&response_text) - .map(|testrun| { - tracing::info!("Received ports-check testrun assignment: {:?}", testrun); + .map(|testrun: TestrunAssignmentWithTickets| { + tracing::info!( + testrun_id = testrun.assignment.testrun_id, + gateway = %testrun.assignment.gateway_identity_key, + "Received ports-check testrun assignment", + ); testrun }) .map_err(|err| { From d791e08fac56dc34858ec8753afdba9985c36a6e Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Mon, 18 May 2026 11:37:37 +0200 Subject: [PATCH 63/94] add port check to dvpn endpoint --- .../nym-node-status-api/src/http/models/mod.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/nym-node-status-api/nym-node-status-api/src/http/models/mod.rs b/nym-node-status-api/nym-node-status-api/src/http/models/mod.rs index fb3f354fa2..750f564df4 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/models/mod.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/models/mod.rs @@ -357,21 +357,20 @@ pub struct DVpnGateway { pub role: NodeRole, pub entry: Option, pub bridges: Option, - // The performance data here originates from the nym-api, and is effectively mixnet performance // at the time of writing this pub performance: String, - // Node performance information needed by the NymVPN UI / Explorer to show more information // about the node in a user-friendly way pub performance_v2: Option, - pub lewes_protocol_details: Option, pub family_data: Option, pub staking_data: Option, pub build_information: BinaryBuildInformationOwned, + pub ports_check: Option, + pub last_ports_check_utc: Option, } impl DVpnGateway { @@ -434,6 +433,8 @@ impl DVpnGateway { family_data: family_details, staking_data: staking_details, build_information: self_described.build_information, + ports_check: gateway.ports_check, + last_ports_check_utc: gateway.last_ports_check_utc, }) } } From ff0ecc95fb114abd8c61ff605b11be63f6814962 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Tue, 19 May 2026 15:21:00 +0200 Subject: [PATCH 64/94] fix compile error --- .../nym-node-status-client/src/lib.rs | 54 +++++++++---------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/nym-node-status-api/nym-node-status-client/src/lib.rs b/nym-node-status-api/nym-node-status-client/src/lib.rs index 27aac8b538..20370a5d63 100644 --- a/nym-node-status-api/nym-node-status-client/src/lib.rs +++ b/nym-node-status-api/nym-node-status-client/src/lib.rs @@ -68,19 +68,19 @@ impl NsApiClient { } } - serde_json::from_str(&response_text) - .map(|testrun: TestrunAssignmentWithTickets| { - tracing::info!( - testrun_id = testrun.assignment.testrun_id, - gateway = %testrun.assignment.gateway_identity_key, - "Received testrun assignment", - ); - testrun - }) - .map_err(|err| { + let testrun: TestrunAssignmentWithTickets = + serde_json::from_str(&response_text).map_err(|err| { tracing::error!("{err}"); - err.into() - }) + anyhow::Error::from(err) + })?; + + tracing::info!( + testrun_id = testrun.assignment.testrun_id, + gateway = %testrun.assignment.gateway_identity_key, + "Received testrun assignment", + ); + + Ok(Some(testrun)) } #[instrument(level = "info", skip_all)] @@ -118,19 +118,19 @@ impl NsApiClient { } } - serde_json::from_str(&response_text) - .map(|testrun: TestrunAssignmentWithTickets| { - tracing::info!( - testrun_id = testrun.assignment.testrun_id, - gateway = %testrun.assignment.gateway_identity_key, - "Received ports-check testrun assignment", - ); - testrun - }) - .map_err(|err| { + let testrun: TestrunAssignmentWithTickets = + serde_json::from_str(&response_text).map_err(|err| { tracing::error!("{err}"); - err.into() - }) + anyhow::Error::from(err) + })?; + + tracing::info!( + testrun_id = testrun.assignment.testrun_id, + gateway = %testrun.assignment.gateway_identity_key, + "Received ports-check testrun assignment", + ); + + Ok(Some(testrun)) } #[instrument(level = "info", fields(testrun_id, assigned_at_utc), skip_all)] @@ -171,7 +171,7 @@ impl NsApiClient { response.error_for_status() })?; - tracing::debug!("Submitted results: {})", res.status()); + tracing::debug!("Submitted results: {}", res.status()); Ok(()) } @@ -204,7 +204,7 @@ impl NsApiClient { .await .and_then(|response| response.error_for_status())?; - tracing::debug!("Submitted results with context: {})", res.status()); + tracing::debug!("Submitted results with context: {}", res.status()); Ok(()) } @@ -238,7 +238,7 @@ impl NsApiClient { .await .and_then(|response| response.error_for_status())?; - tracing::debug!("Submitted ports-check results: {})", res.status()); + tracing::debug!("Submitted ports-check results: {}", res.status()); Ok(()) } From c9a9940cb9210e29af683898b147dd3c656de4cf Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Tue, 19 May 2026 15:34:58 +0200 Subject: [PATCH 65/94] migration fix --- .../20260415000000_gateways_ports_check.sql | 2 -- ...60519133000_gateways_ports_check_json_guard.sql | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 2 deletions(-) create mode 100644 nym-node-status-api/nym-node-status-api/migrations_pg/20260519133000_gateways_ports_check_json_guard.sql diff --git a/nym-node-status-api/nym-node-status-api/migrations_pg/20260415000000_gateways_ports_check.sql b/nym-node-status-api/nym-node-status-api/migrations_pg/20260415000000_gateways_ports_check.sql index f506b093f5..e521cb2aa5 100644 --- a/nym-node-status-api/nym-node-status-api/migrations_pg/20260415000000_gateways_ports_check.sql +++ b/nym-node-status-api/nym-node-status-api/migrations_pg/20260415000000_gateways_ports_check.sql @@ -4,7 +4,6 @@ UPDATE gateways SET ports_check = (last_probe_result::jsonb -> 'ports_check') WHERE last_probe_result IS NOT NULL AND btrim(last_probe_result) <> '' - AND last_probe_result ~ '^[\[{]' AND last_probe_result::jsonb ? 'ports_check' AND ports_check IS NULL; @@ -12,5 +11,4 @@ UPDATE gateways SET last_probe_result = (last_probe_result::jsonb - 'ports_check')::text WHERE last_probe_result IS NOT NULL AND btrim(last_probe_result) <> '' - AND last_probe_result ~ '^[\[{]' AND last_probe_result::jsonb ? 'ports_check'; \ No newline at end of file diff --git a/nym-node-status-api/nym-node-status-api/migrations_pg/20260519133000_gateways_ports_check_json_guard.sql b/nym-node-status-api/nym-node-status-api/migrations_pg/20260519133000_gateways_ports_check_json_guard.sql new file mode 100644 index 0000000000..bcdb3b4b7d --- /dev/null +++ b/nym-node-status-api/nym-node-status-api/migrations_pg/20260519133000_gateways_ports_check_json_guard.sql @@ -0,0 +1,14 @@ +UPDATE gateways +SET ports_check = (last_probe_result::jsonb -> 'ports_check') +WHERE last_probe_result IS NOT NULL + AND btrim(last_probe_result) <> '' + AND last_probe_result ~ '^[\[{]' + AND last_probe_result::jsonb ? 'ports_check' + AND ports_check IS NULL; + +UPDATE gateways +SET last_probe_result = (last_probe_result::jsonb - 'ports_check')::text +WHERE last_probe_result IS NOT NULL + AND btrim(last_probe_result) <> '' + AND last_probe_result ~ '^[\[{]' + AND last_probe_result::jsonb ? 'ports_check'; From 17d3791b8e90a032f7f91a69c71c4f1bea6e43f3 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Wed, 20 May 2026 09:36:47 +0200 Subject: [PATCH 66/94] typo --- .../nym-node-status-api/src/db/queries/gateways.rs | 6 ------ .../nym-node-status-api/src/http/models/gw_probe/test.rs | 1 - nym-node-status-api/nym-node-status-api/src/http/server.rs | 2 +- 3 files changed, 1 insertion(+), 8 deletions(-) diff --git a/nym-node-status-api/nym-node-status-api/src/db/queries/gateways.rs b/nym-node-status-api/nym-node-status-api/src/db/queries/gateways.rs index 2b7c33da9b..055498fa1c 100644 --- a/nym-node-status-api/nym-node-status-api/src/db/queries/gateways.rs +++ b/nym-node-status-api/nym-node-status-api/src/db/queries/gateways.rs @@ -76,12 +76,6 @@ impl Storage { Ok(()) } - gw.last_probe_log as "last_probe_log?", - gw.ports_check as "ports_check?", - - gw.last_testrun_utc as "last_testrun_utc?", - .await?; - .await?; pub(crate) async fn get_all_gateways(&self) -> anyhow::Result> { let items = sqlx::query_as!( GatewayDto, diff --git a/nym-node-status-api/nym-node-status-api/src/http/models/gw_probe/test.rs b/nym-node-status-api/nym-node-status-api/src/http/models/gw_probe/test.rs index dd06ce0450..d244fbfaa3 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/models/gw_probe/test.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/models/gw_probe/test.rs @@ -170,7 +170,6 @@ fn conversion_from_gw_probe_latest() { let probe_latest = ProbeResultLatest { node: "test-node-identity-key".to_string(), used_entry: "test-entry-node".to_string(), - ports_check: None, outcome: ProbeOutcomeLatest { as_entry: EntryLatest::Tested(EntryTestResultLatest { can_connect: true, diff --git a/nym-node-status-api/nym-node-status-api/src/http/server.rs b/nym-node-status-api/nym-node-status-api/src/http/server.rs index 13011a3472..356fb7cdc9 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/server.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/server.rs @@ -28,7 +28,7 @@ pub(crate) async fn start_http_api( shutdown_tracker: &ShutdownTracker, ) -> anyhow::Result<()> { let router_builder = RouterBuilder::with_default_routes(); - let db_pool_for_scheduler = db_pool.clone(); + let db_pool_for_scheduler = storage.pool().clone(); let state = AppState::new( storage, From 23e6169c020b735311b5bf11c64c88051e417999 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Wed, 20 May 2026 10:16:55 +0200 Subject: [PATCH 67/94] update sqlx --- ...671cd0c8c28b3f1ed049f008d14b711ef788.json} | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) rename nym-node-status-api/nym-node-status-api/.sqlx/{query-1668f5a5a0abc8a73454953c3f5b61d2afb1b37720f5756b9c6fb3aef55a3027.json => query-9c077a2322ad141cfae4c81d1046671cd0c8c28b3f1ed049f008d14b711ef788.json} (67%) diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-1668f5a5a0abc8a73454953c3f5b61d2afb1b37720f5756b9c6fb3aef55a3027.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-9c077a2322ad141cfae4c81d1046671cd0c8c28b3f1ed049f008d14b711ef788.json similarity index 67% rename from nym-node-status-api/nym-node-status-api/.sqlx/query-1668f5a5a0abc8a73454953c3f5b61d2afb1b37720f5756b9c6fb3aef55a3027.json rename to nym-node-status-api/nym-node-status-api/.sqlx/query-9c077a2322ad141cfae4c81d1046671cd0c8c28b3f1ed049f008d14b711ef788.json index 1fee9eb103..77dfd2f4bc 100644 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-1668f5a5a0abc8a73454953c3f5b61d2afb1b37720f5756b9c6fb3aef55a3027.json +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-9c077a2322ad141cfae4c81d1046671cd0c8c28b3f1ed049f008d14b711ef788.json @@ -1,6 +1,6 @@ { "db_name": "PostgreSQL", - "query": "SELECT\n gw.gateway_identity_key as \"gateway_identity_key!\",\n gw.bonded as \"bonded: bool\",\n gw.performance as \"performance!\",\n gw.self_described as \"self_described?\",\n gw.explorer_pretty_bond as \"explorer_pretty_bond?\",\n gw.last_probe_result as \"last_probe_result?\",\n gw.last_probe_log as \"last_probe_log?\",\n gw.last_testrun_utc as \"last_testrun_utc?\",\n gw.last_updated_utc as \"last_updated_utc!\",\n gw.bridges as \"bridges?: serde_json::Value\",\n COALESCE(gd.moniker, 'NA') as \"moniker!\",\n COALESCE(gd.website, 'NA') as \"website!\",\n COALESCE(gd.security_contact, 'NA') as \"security_contact!\",\n COALESCE(gd.details, 'NA') as \"details!\"\n FROM gateways gw\n LEFT JOIN gateway_description gd\n ON gw.gateway_identity_key = gd.gateway_identity_key\n ORDER BY gw.gateway_identity_key", + "query": "SELECT\n gw.gateway_identity_key as \"gateway_identity_key!\",\n gw.bonded as \"bonded: bool\",\n gw.performance as \"performance!\",\n gw.self_described as \"self_described?\",\n gw.explorer_pretty_bond as \"explorer_pretty_bond?\",\n gw.last_probe_result as \"last_probe_result?\",\n gw.last_probe_log as \"last_probe_log?\",\n gw.ports_check as \"ports_check?\",\n gw.last_ports_check_utc as \"last_ports_check_utc?\",\n gw.last_testrun_utc as \"last_testrun_utc?\",\n gw.last_updated_utc as \"last_updated_utc!\",\n gw.bridges as \"bridges?: serde_json::Value\",\n COALESCE(gd.moniker, 'NA') as \"moniker!\",\n COALESCE(gd.website, 'NA') as \"website!\",\n COALESCE(gd.security_contact, 'NA') as \"security_contact!\",\n COALESCE(gd.details, 'NA') as \"details!\"\n FROM gateways gw\n LEFT JOIN gateway_description gd\n ON gw.gateway_identity_key = gd.gateway_identity_key\n ORDER BY gw.gateway_identity_key", "describe": { "columns": [ { @@ -40,36 +40,46 @@ }, { "ordinal": 7, - "name": "last_testrun_utc?", - "type_info": "Int8" + "name": "ports_check?", + "type_info": "Jsonb" }, { "ordinal": 8, - "name": "last_updated_utc!", + "name": "last_ports_check_utc?", "type_info": "Int8" }, { "ordinal": 9, + "name": "last_testrun_utc?", + "type_info": "Int8" + }, + { + "ordinal": 10, + "name": "last_updated_utc!", + "type_info": "Int8" + }, + { + "ordinal": 11, "name": "bridges?: serde_json::Value", "type_info": "Jsonb" }, { - "ordinal": 10, + "ordinal": 12, "name": "moniker!", "type_info": "Varchar" }, { - "ordinal": 11, + "ordinal": 13, "name": "website!", "type_info": "Varchar" }, { - "ordinal": 12, + "ordinal": 14, "name": "security_contact!", "type_info": "Varchar" }, { - "ordinal": 13, + "ordinal": 15, "name": "details!", "type_info": "Varchar" } @@ -86,6 +96,8 @@ true, true, true, + true, + true, false, true, null, @@ -94,5 +106,5 @@ null ] }, - "hash": "1668f5a5a0abc8a73454953c3f5b61d2afb1b37720f5756b9c6fb3aef55a3027" + "hash": "9c077a2322ad141cfae4c81d1046671cd0c8c28b3f1ed049f008d14b711ef788" } From a52a8c3e8112f1943d9f969fd8e15ea63ae57f46 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Wed, 27 May 2026 09:08:25 +0200 Subject: [PATCH 68/94] fix --- Cargo.lock | 4 +-- ...528594a84f560130a6956507ef8c4500e4bb9.json | 31 +++++++++++++++++++ ...6b5ac23f7f7eabc6b2ba13ccfb8ef14fcfd30.json | 30 ------------------ .../src/db/queries/testruns.rs | 1 + .../src/http/api/testruns.rs | 6 ++-- 5 files changed, 37 insertions(+), 35 deletions(-) create mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-2e825cb61d34ed7b41d622743b4528594a84f560130a6956507ef8c4500e4bb9.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-62be5c3a94e6b2e72823e0fe6d26b5ac23f7f7eabc6b2ba13ccfb8ef14fcfd30.json diff --git a/Cargo.lock b/Cargo.lock index c606bed85c..0a1fe54aab 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7870,7 +7870,7 @@ dependencies = [ [[package]] name = "nym-node-status-agent" -version = "2.0.1-rc3" +version = "2.0.1" dependencies = [ "anyhow", "clap", @@ -7891,7 +7891,7 @@ dependencies = [ [[package]] name = "nym-node-status-api" -version = "4.6.2-rc10" +version = "4.6.2" dependencies = [ "ammonia", "anyhow", diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-2e825cb61d34ed7b41d622743b4528594a84f560130a6956507ef8c4500e4bb9.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-2e825cb61d34ed7b41d622743b4528594a84f560130a6956507ef8c4500e4bb9.json new file mode 100644 index 0000000000..2a8239cd82 --- /dev/null +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-2e825cb61d34ed7b41d622743b4528594a84f560130a6956507ef8c4500e4bb9.json @@ -0,0 +1,31 @@ +{ + "db_name": "PostgreSQL", + "query": "\n WITH oldest_queued AS (\n SELECT testruns.id\n FROM testruns\n JOIN gateways ON gateways.id = testruns.gateway_id\n WHERE testruns.status = $1\n AND testruns.kind = $4\n AND gateways.bonded = true\n AND gateways.performance > 0\n ORDER BY testruns.created_utc asc\n LIMIT 1\n FOR UPDATE OF testruns SKIP LOCKED\n )\n UPDATE testruns\n SET\n status = $3,\n last_assigned_utc = $2\n FROM oldest_queued\n WHERE testruns.id = oldest_queued.id\n RETURNING\n testruns.id,\n testruns.gateway_id\n ", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "id", + "type_info": "Int4" + }, + { + "ordinal": 1, + "name": "gateway_id", + "type_info": "Int4" + } + ], + "parameters": { + "Left": [ + "Int4", + "Int8", + "Int4", + "Int2" + ] + }, + "nullable": [ + false, + false + ] + }, + "hash": "2e825cb61d34ed7b41d622743b4528594a84f560130a6956507ef8c4500e4bb9" +} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-62be5c3a94e6b2e72823e0fe6d26b5ac23f7f7eabc6b2ba13ccfb8ef14fcfd30.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-62be5c3a94e6b2e72823e0fe6d26b5ac23f7f7eabc6b2ba13ccfb8ef14fcfd30.json deleted file mode 100644 index b1bc6785eb..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-62be5c3a94e6b2e72823e0fe6d26b5ac23f7f7eabc6b2ba13ccfb8ef14fcfd30.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n WITH oldest_queued AS (\n SELECT testruns.id\n FROM testruns\n JOIN gateways ON gateways.id = testruns.gateway_id\n WHERE testruns.status = $1\n AND gateways.bonded = true\n AND gateways.performance > 0\n ORDER BY testruns.created_utc asc\n LIMIT 1\n FOR UPDATE OF testruns SKIP LOCKED\n )\n UPDATE testruns\n SET\n status = $3,\n last_assigned_utc = $2\n FROM oldest_queued\n WHERE testruns.id = oldest_queued.id\n RETURNING\n testruns.id,\n testruns.gateway_id\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Int4" - }, - { - "ordinal": 1, - "name": "gateway_id", - "type_info": "Int4" - } - ], - "parameters": { - "Left": [ - "Int4", - "Int8", - "Int4" - ] - }, - "nullable": [ - false, - false - ] - }, - "hash": "62be5c3a94e6b2e72823e0fe6d26b5ac23f7f7eabc6b2ba13ccfb8ef14fcfd30" -} diff --git a/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs b/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs index bc2719cea6..fa7d726389 100644 --- a/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs +++ b/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs @@ -117,6 +117,7 @@ async fn assign_oldest_testrun_by_kind( FROM testruns JOIN gateways ON gateways.id = testruns.gateway_id WHERE testruns.status = $1 + AND testruns.kind = $4 AND gateways.bonded = true AND gateways.performance > 0 ORDER BY testruns.created_utc asc diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs b/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs index aa706d161c..add6ab2f1d 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs @@ -32,10 +32,10 @@ pub(crate) fn routes() -> Router { "/ports-check", axum::routing::get(request_ports_check_testrun), ) - .route("/:testrun_id", axum::routing::post(submit_testrun)) - .route("/:testrun_id/v2", axum::routing::post(submit_testrun_v2)) + .route("/{testrun_id}", axum::routing::post(submit_testrun)) + .route("/{testrun_id}/v2", axum::routing::post(submit_testrun_v2)) .route( - "/:testrun_id/ports-check/v2", + "/{testrun_id}/ports-check/v2", axum::routing::post(submit_ports_check_testrun_v2), ) .layer(DefaultBodyLimit::max(1024 * 1024 * 5)) From 11320e3f6af24a5a298d87481320d389f3798a49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 29 May 2026 14:30:59 +0100 Subject: [PATCH 69/94] bugfix: NMv3 race condition (#6837) * fixed race condition in mixnet listener creation notification * reduced log severity for retrieving self-described node information * chore: bump up version number --- Cargo.lock | 4 ++-- nym-network-monitor-v3/nym-network-monitor-agent/Cargo.toml | 2 +- .../nym-network-monitor-agent/src/listener/mod.rs | 2 +- .../nym-network-monitor-orchestrator/Cargo.toml | 2 +- .../src/orchestrator/node_refresher.rs | 6 +++--- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c606bed85c..6e2f149a0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7571,7 +7571,7 @@ dependencies = [ [[package]] name = "nym-network-monitor-agent" -version = "1.0.2" +version = "1.0.3" dependencies = [ "anyhow", "arrayref", @@ -7604,7 +7604,7 @@ dependencies = [ [[package]] name = "nym-network-monitor-orchestrator" -version = "1.0.2" +version = "1.0.3" dependencies = [ "anyhow", "axum", diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/Cargo.toml b/nym-network-monitor-v3/nym-network-monitor-agent/Cargo.toml index 97d0adccef..9500df46f1 100644 --- a/nym-network-monitor-v3/nym-network-monitor-agent/Cargo.toml +++ b/nym-network-monitor-v3/nym-network-monitor-agent/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "nym-network-monitor-agent" description = "Agent used for stress testing Nym mixnodes" -version = "1.0.2" +version = "1.0.3" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/listener/mod.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/listener/mod.rs index 90817f277c..822341d50e 100644 --- a/nym-network-monitor-v3/nym-network-monitor-agent/src/listener/mod.rs +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/listener/mod.rs @@ -144,7 +144,7 @@ impl MixnetListener { /// Returns `self` so that the caller can inspect fields such as /// [`last_noise_handshake_duration`](Self::last_noise_handshake_duration) after the run. pub(crate) async fn run(mut self, on_start: Arc) -> Self { - on_start.notify_waiters(); + on_start.notify_one(); // only handle a single connection at once // (we don't need more than that) loop { diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/Cargo.toml b/nym-network-monitor-v3/nym-network-monitor-orchestrator/Cargo.toml index a93df645e7..e0b2516158 100644 --- a/nym-network-monitor-v3/nym-network-monitor-orchestrator/Cargo.toml +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "nym-network-monitor-orchestrator" description = "Orchestrator for performing Nym network stress testing" -version = "1.0.2" +version = "1.0.3" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/node_refresher.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/node_refresher.rs index b11bfbdc4e..9f8e19ad6f 100644 --- a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/node_refresher.rs +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/node_refresher.rs @@ -23,7 +23,7 @@ use std::collections::HashMap; use std::net::SocketAddr; use std::time::Duration; use tokio::time::{Instant, interval}; -use tracing::{error, info, warn}; +use tracing::{debug, error, info}; pub(crate) struct NodeRefresher { pub(crate) client: QueryHttpRpcNyxdClient, @@ -142,13 +142,13 @@ impl NodeRefresher { .await { Err(_timeout) => { - warn!( + debug!( "timed out while attempting to retrieve self-described node details for node {node_id}" ); return node_update; } Ok(Err(err)) => { - error!("failed to retrieve self-described node details for node {node_id}: {err}"); + debug!("failed to retrieve self-described node details for node {node_id}: {err}"); return node_update; } Ok(Ok(info)) => info, From a98a65c16d2d8893f3e0d4e055838d91327d713b Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Mon, 1 Jun 2026 11:59:43 +0200 Subject: [PATCH 70/94] addressing coderabbit comments --- nym-gateway-probe/netstack_ping/lib.go | 16 +++++++++----- nym-gateway-probe/src/common/types.rs | 16 +++++++++++++- .../nym-node-status-agent/src/cli/mod.rs | 6 ++++-- .../src/db/queries/gateways.rs | 20 +++++++++++++----- .../src/db/queries/testruns.rs | 21 +++++++++++++++++++ .../src/http/api/testruns.rs | 21 +++++++++++++------ .../nym-node-status-api/src/http/server.rs | 3 ++- .../nym-node-status-api/src/http/state.rs | 3 ++- 8 files changed, 85 insertions(+), 21 deletions(-) diff --git a/nym-gateway-probe/netstack_ping/lib.go b/nym-gateway-probe/netstack_ping/lib.go index bcbf738368..fc36d93367 100644 --- a/nym-gateway-probe/netstack_ping/lib.go +++ b/nym-gateway-probe/netstack_ping/lib.go @@ -658,18 +658,24 @@ func checkPorts(target string, ports []uint16, timeoutSec uint64, tnet *netstack } } } else { - // All other targets can handle concurrent connections, probably - log.Printf("Port check: testing %d ports on %s concurrently (timeout %v each)", - len(ports), target, timeout) + // All other targets can handle concurrent connections, probably. + // A semaphore caps concurrent tnet.DialContext calls to avoid + // overwhelming the single userspace netstack instance. + const maxConcurrentDials = 64 + log.Printf("Port check: testing %d ports on %s concurrently (max %d at a time, timeout %v each)", + len(ports), target, maxConcurrentDials, timeout) var ( - mu sync.Mutex - wg sync.WaitGroup + mu sync.Mutex + wg sync.WaitGroup + sem = make(chan struct{}, maxConcurrentDials) ) for _, p := range ports { wg.Add(1) go func(port uint16) { defer wg.Done() + sem <- struct{}{} + defer func() { <-sem }() addr := net.JoinHostPort(targetIP, fmt.Sprintf("%d", port)) ctx, cancel := context.WithTimeout(context.Background(), timeout) c, err := tnet.DialContext(ctx, "tcp", addr) diff --git a/nym-gateway-probe/src/common/types.rs b/nym-gateway-probe/src/common/types.rs index 99190df348..72953cfcb9 100644 --- a/nym-gateway-probe/src/common/types.rs +++ b/nym-gateway-probe/src/common/types.rs @@ -257,7 +257,21 @@ impl PortCheckResult { pub fn closed_ports(&self) -> Vec { self.ports .iter() - .filter_map(|(k, &open)| if !open { k.parse().ok() } else { None }) + .filter_map(|(k, &open)| { + if open { + return None; + } + match k.parse::() { + Ok(port) => Some(port), + Err(e) => { + tracing::warn!( + "Skipping port key {:?} that could not be parsed as u16: {e}", + k + ); + None + } + } + }) .collect() } } diff --git a/nym-node-status-api/nym-node-status-agent/src/cli/mod.rs b/nym-node-status-api/nym-node-status-agent/src/cli/mod.rs index 5fbe2ae62d..d0a3625840 100644 --- a/nym-node-status-api/nym-node-status-agent/src/cli/mod.rs +++ b/nym-node-status-api/nym-node-status-agent/src/cli/mod.rs @@ -34,8 +34,10 @@ pub(super) fn parse_server_config(s: &str) -> Result { let port = parts[1] .parse::() .map_err(|_| "Invalid port number".to_string())?; - let auth_key = - PrivateKey::from_base58_string(env::var("NODE_STATUS_AGENT_AUTH_KEY").unwrap()).unwrap(); + let raw_key = env::var("NODE_STATUS_AGENT_AUTH_KEY") + .map_err(|_| "NODE_STATUS_AGENT_AUTH_KEY environment variable is not set".to_string())?; + let auth_key = PrivateKey::from_base58_string(raw_key) + .map_err(|e| format!("Failed to decode NODE_STATUS_AGENT_AUTH_KEY as base58: {e}"))?; Ok(ServerConfig { address, diff --git a/nym-node-status-api/nym-node-status-api/src/db/queries/gateways.rs b/nym-node-status-api/nym-node-status-api/src/db/queries/gateways.rs index 055498fa1c..5049163317 100644 --- a/nym-node-status-api/nym-node-status-api/src/db/queries/gateways.rs +++ b/nym-node-status-api/nym-node-status-api/src/db/queries/gateways.rs @@ -104,11 +104,21 @@ impl Storage { .fetch(&self.pool) .try_collect::>() .await?; - let items: Vec = items - .into_iter() - .map(|item| item.try_into()) - .collect::>>() - .inspect_err(|e| error!("Conversion from DTO failed: {e}. Invalidly stored data?"))?; + let mut gateways: Vec = Vec::with_capacity(items.len()); + let mut failed = 0usize; + for item in items { + match item.try_into() { + Ok(gw) => gateways.push(gw), + Err(e) => { + error!("Conversion from DTO failed: {e}. Invalidly stored data?"); + failed += 1; + } + } + } + if failed > 0 { + tracing::warn!("{failed} gateway DTO(s) failed conversion and were skipped"); + } + let items = gateways; tracing::trace!("Fetched {} gateways from DB", items.len()); Ok(items) } diff --git a/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs b/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs index fa7d726389..238d51be31 100644 --- a/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs +++ b/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs @@ -24,6 +24,27 @@ pub(crate) async fn count_testruns_in_progress( .map_err(anyhow::Error::from) } +pub(crate) async fn count_testruns_in_progress_by_kind( + conn: &mut DbConnection, + kind: TestRunKind, +) -> anyhow::Result> { + sqlx::query_scalar!( + r#"SELECT + COUNT(id) as "count: i64" + FROM testruns + WHERE + status = $1 + AND + kind = $2 + "#, + TestRunStatus::InProgress as i64, + kind as i16, + ) + .fetch_one(conn.as_mut()) + .await + .map_err(anyhow::Error::from) +} + pub(crate) async fn get_in_progress_testrun_by_id( conn: &mut DbConnection, testrun_id: i32, diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs b/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs index add6ab2f1d..a9c421d395 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs @@ -142,13 +142,18 @@ async fn request_ports_check_testrun( .await .map_err(HttpError::internal_with_logging)?; - let active_testruns = db::queries::testruns::count_testruns_in_progress(&mut conn) - .await - .map_err(HttpError::internal_with_logging)? - .unwrap_or_default(); + let active_ports_check_testruns = db::queries::testruns::count_testruns_in_progress_by_kind( + &mut conn, + TestRunKind::PortsCheck, + ) + .await + .map_err(HttpError::internal_with_logging)? + .unwrap_or_default(); let max_count = state.agent_max_count(); - if active_testruns >= max_count { - tracing::warn!("{active_testruns}/{max_count} testruns in progress, rejecting",); + if active_ports_check_testruns >= max_count { + tracing::warn!( + "{active_ports_check_testruns}/{max_count} ports-check testruns in progress, rejecting", + ); return Err(HttpError::no_testruns_available()); } @@ -562,6 +567,10 @@ async fn process_ports_check_submission( payload.port_check_result.can_register, ); + // probe_log is intentionally not persisted for ports-check submissions: + // the ports-check result is a lightweight JSONB record and does not warrant + // the storage overhead of a full probe log. Full logs are retained only for + // regular probe testruns via update_gateway_last_probe_log. queries::testruns::update_gateway_ports_check_only( conn, gateway_id, diff --git a/nym-node-status-api/nym-node-status-api/src/http/server.rs b/nym-node-status-api/nym-node-status-api/src/http/server.rs index 356fb7cdc9..01048d192c 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/server.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/server.rs @@ -54,7 +54,8 @@ pub(crate) async fn start_http_api( .unwrap_or(true); if ports_check_scheduler_enabled { - let mut interval = tokio::time::interval(std::time::Duration::from_secs(60 * 10)); + let period = std::time::Duration::from_secs(60 * 10); + let mut interval = tokio::time::interval_at(tokio::time::Instant::now() + period, period); interval.set_missed_tick_behavior(MissedTickBehavior::Skip); let scheduler_shutdown = shutdown_tracker.clone_shutdown_token().cancelled_owned(); shutdown_tracker.spawn(async move { diff --git a/nym-node-status-api/nym-node-status-api/src/http/state.rs b/nym-node-status-api/nym-node-status-api/src/http/state.rs index 1d8affed94..a05980a69b 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/state.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/state.rs @@ -134,7 +134,8 @@ impl AppState { return Err(HttpError::unauthorized()); }; - if request.verify_signature().is_err() { + if let Err(err) = request.verify_signature() { + tracing::debug!("Signature verification error: {:?}", err); tracing::warn!("Signature verification failed, rejecting"); return Err(HttpError::unauthorized()); } From 0796e9e0a68992151e189148cc47c79cc4661db0 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Mon, 1 Jun 2026 12:40:26 +0200 Subject: [PATCH 71/94] build fix --- .../src/db/queries/testruns.rs | 23 +++++++------------ .../nym-node-status-api/src/http/state.rs | 3 +-- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs b/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs index 238d51be31..2535838e58 100644 --- a/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs +++ b/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs @@ -28,21 +28,14 @@ pub(crate) async fn count_testruns_in_progress_by_kind( conn: &mut DbConnection, kind: TestRunKind, ) -> anyhow::Result> { - sqlx::query_scalar!( - r#"SELECT - COUNT(id) as "count: i64" - FROM testruns - WHERE - status = $1 - AND - kind = $2 - "#, - TestRunStatus::InProgress as i64, - kind as i16, - ) - .fetch_one(conn.as_mut()) - .await - .map_err(anyhow::Error::from) + let count: i64 = + sqlx::query_scalar(r#"SELECT COUNT(id) FROM testruns WHERE status = $1 AND kind = $2"#) + .bind(TestRunStatus::InProgress as i64) + .bind(kind as i16) + .fetch_one(conn.as_mut()) + .await + .map_err(anyhow::Error::from)?; + Ok(Some(count)) } pub(crate) async fn get_in_progress_testrun_by_id( diff --git a/nym-node-status-api/nym-node-status-api/src/http/state.rs b/nym-node-status-api/nym-node-status-api/src/http/state.rs index a05980a69b..1d8affed94 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/state.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/state.rs @@ -134,8 +134,7 @@ impl AppState { return Err(HttpError::unauthorized()); }; - if let Err(err) = request.verify_signature() { - tracing::debug!("Signature verification error: {:?}", err); + if request.verify_signature().is_err() { tracing::warn!("Signature verification failed, rejecting"); return Err(HttpError::unauthorized()); } From 14a85901b4752ff221f2a4ab786384c279e022d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 1 Jun 2026 11:44:31 +0100 Subject: [PATCH 72/94] Bugfix/cherry pick/waterloo stres testing floats (#6841) * add additional information upon stress testing data submission failure * split stress testing result submission into batches of maximum size * enable 'float_roundtrip' serde_json feature to ensure consistent float serialisation --- Cargo.lock | 4 +- Cargo.toml | 2 +- nym-api/Cargo.toml | 2 +- .../src/models/network_monitor.rs | 164 ++++++++++++++++++ .../Cargo.toml | 2 +- .../src/cli/env.rs | 3 + .../src/cli/run_orchestrator.rs | 7 +- .../src/orchestrator/config.rs | 3 + .../src/orchestrator/result_submitter.rs | 69 ++++++-- .../src/storage/models.rs | 8 + 10 files changed, 239 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6e2f149a0b..ce22ac9bcf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5819,7 +5819,7 @@ dependencies = [ [[package]] name = "nym-api" -version = "1.1.80" +version = "1.1.80-fixed-floats" dependencies = [ "anyhow", "async-trait", @@ -7604,7 +7604,7 @@ dependencies = [ [[package]] name = "nym-network-monitor-orchestrator" -version = "1.0.3" +version = "1.0.5" dependencies = [ "anyhow", "axum", diff --git a/Cargo.toml b/Cargo.toml index 72e8d59a1f..b5798320e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -353,7 +353,7 @@ semver = "1.0.26" serde = "1.0.219" serde_bytes = "0.11.17" serde_derive = "1.0" -serde_json = "1.0.140" +serde_json = { version = "1.0.140", features = ["float_roundtrip"] } serde_json_path = "0.7.2" serde_repr = "0.1" serde_with = "3.9.0" diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index 29dc4d67b9..2316433f77 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-api" -version = "1.1.80" +version = "1.1.80-fixed-floats" authors.workspace = true edition = "2021" license = "GPL-3.0" diff --git a/nym-api/nym-api-requests/src/models/network_monitor.rs b/nym-api/nym-api-requests/src/models/network_monitor.rs index 3075a76e88..824a0a2165 100644 --- a/nym-api/nym-api-requests/src/models/network_monitor.rs +++ b/nym-api/nym-api-requests/src/models/network_monitor.rs @@ -181,4 +181,168 @@ pub mod v3 { /// as an authorised network monitor permitted to submit stress testing results. pub authorised: bool, } + + #[cfg(test)] + mod tests { + use super::*; + use crate::signable::SignableMessageBody; + use nym_test_utils::helpers::deterministic_rng; + use time::macros::datetime; + + fn dummy_results() -> Vec { + // Order-distinguishable entries: if deserialisation ever permuted the array, the + // re-serialised body would no longer match the signed bytes, and `verify_signature` + // would return false. `testrun_id` is the order witness. + vec![ + StressTestResult { + testrun_id: 1, + node_id: 42, + is_mixnode: true, + test_timestamp: datetime!(2026-06-01 12:34:56.123456789 UTC), + test_performance: 0.6666666666666666, + was_reachable: true, + }, + StressTestResult { + testrun_id: 2, + node_id: 7, + is_mixnode: true, + test_timestamp: datetime!(2026-06-01 12:34:56 UTC), + test_performance: 0.0, + was_reachable: false, + }, + StressTestResult { + testrun_id: 3, + node_id: u32::MAX, + is_mixnode: true, + test_timestamp: datetime!(2026-06-01 12:34:56.999999999 UTC), + test_performance: 1.0, + was_reachable: true, + }, + ] + } + + // Integrity check on the wire is `serde_json::to_vec(deserialize(serde_json::to_vec(body))) + // == serde_json::to_vec(body)`. If JSON serialisation isn't a fixed point, every batch + // submission would fail nym-api's signature verification. Cover the timestamp shapes the + // orchestrator actually produces, including the `+1ns` bump from the monotonicity safeguard. + #[test] + fn signed_batch_submission_roundtrips_through_json() { + let mut rng = deterministic_rng(); + let keys = ed25519::KeyPair::new(&mut rng); + + let timestamps = [ + datetime!(2026-06-01 12:34:56 UTC), + datetime!(2026-06-01 12:34:56.000000001 UTC), + datetime!(2026-06-01 12:34:56.999999999 UTC), + datetime!(2026-06-01 12:34:56.123456789 UTC), + OffsetDateTime::now_utc(), + OffsetDateTime::now_utc() + time::Duration::NANOSECOND, + ]; + + for timestamp in timestamps { + let body = StressTestBatchSubmissionContent { + signer: *keys.public_key(), + timestamp, + results: dummy_results(), + }; + let signed = body.clone().sign(keys.private_key()); + + let bytes = serde_json::to_vec(&signed).unwrap(); + let deserialised: StressTestBatchSubmission = + serde_json::from_slice(&bytes).unwrap(); + + // The handler verifies against `body.body.signer` — match that exactly. + assert!( + deserialised.verify_signature(&deserialised.body.signer), + "signature failed to verify after JSON round-trip for timestamp {timestamp}", + ); + assert_eq!(deserialised.body.timestamp, timestamp); + } + } + + // Every f64 that the orchestrator's `received as f64 / sent as f64` formula can produce + // (storage/models.rs) must round-trip byte-exactly through JSON. Exhaustively cover the + // range and exercise sent values that produce non-terminating fractions (1/3, 1/7, ...). + #[test] + fn computed_test_performance_values_roundtrip() { + for sent in 1u64..=200 { + for received in 0u64..=(sent * 2) { + let perf = received as f64 / sent as f64; + let s = serde_json::to_string(&perf).unwrap(); + let perf2: f64 = serde_json::from_str(&s).unwrap(); + let s2 = serde_json::to_string(&perf2).unwrap(); + assert_eq!( + s, s2, + "f64 round-trip mismatch for {received}/{sent} = {perf}: {s} -> {s2}", + ); + } + } + } + + // serde_json serialises non-finite f64 as `null`. Confirm what the deserialiser does with + // `null` for a struct field typed as f64 - if it succeeds with a default value (rather than + // erroring), a NaN/Infinity test_performance could silently break signature verification + // because the re-serialised body would no longer have `null` at that position. + #[test] + fn non_finite_test_performance_breaks_loudly_not_silently() { + let nan_result = StressTestResult { + testrun_id: 1, + node_id: 1, + is_mixnode: true, + test_timestamp: datetime!(2026-06-01 12:34:56 UTC), + test_performance: f64::NAN, + was_reachable: true, + }; + let json = serde_json::to_string(&nan_result).unwrap(); + // NaN serialises as `null` - this is the dangerous shape + assert!( + json.contains(r#""test_performance":null"#), + "expected NaN to serialise as null: {json}", + ); + // ...and `null` MUST fail to deserialise rather than silently becoming 0.0 / default; + // if this ever changes, NaN would silently corrupt signature verification. + let deserialised: Result = serde_json::from_str(&json); + assert!( + deserialised.is_err(), + "deserialising null into f64 unexpectedly succeeded - signature verification \ + would silently fail for any submission containing a non-finite test_performance", + ); + } + + // Specifically pin the two hypotheses we want to rule out: + // 1. Vec serialisation/deserialisation preserves order. + // 2. The body bytes serialised standalone (= what gets signed) are byte-identical to + // the body sub-object bytes embedded in the outer SignedMessage JSON (= what the + // server sees after parsing). Re-serialising the deserialised body must reproduce + // the signed bytes verbatim, otherwise no signature could ever verify. + #[test] + fn batch_body_serialisation_is_a_byte_exact_fixed_point() { + let mut rng = deterministic_rng(); + let keys = ed25519::KeyPair::new(&mut rng); + + let body = StressTestBatchSubmissionContent { + signer: *keys.public_key(), + timestamp: datetime!(2026-06-01 12:34:56.123456789 UTC), + results: dummy_results(), + }; + + let signed_bytes = body.plaintext(); + let body_str = std::str::from_utf8(&signed_bytes).unwrap(); + + // (1) array order preserved on the wire + let pos1 = body_str.find(r#""testrun_id":1"#).unwrap(); + let pos2 = body_str.find(r#""testrun_id":2"#).unwrap(); + let pos3 = body_str.find(r#""testrun_id":3"#).unwrap(); + assert!(pos1 < pos2 && pos2 < pos3, "JSON: {body_str}"); + + // (2) round-trip is byte-exact + let deserialised: StressTestBatchSubmissionContent = + serde_json::from_slice(&signed_bytes).unwrap(); + let resigned_bytes = deserialised.plaintext(); + assert_eq!( + signed_bytes, resigned_bytes, + "deserialise-then-re-serialise was not a fixed point" + ); + } + } } diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/Cargo.toml b/nym-network-monitor-v3/nym-network-monitor-orchestrator/Cargo.toml index e0b2516158..175721766a 100644 --- a/nym-network-monitor-v3/nym-network-monitor-orchestrator/Cargo.toml +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "nym-network-monitor-orchestrator" description = "Orchestrator for performing Nym network stress testing" -version = "1.0.3" +version = "1.0.5" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/env.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/env.rs index d37292bc8f..6ee20dc7d2 100644 --- a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/env.rs +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/env.rs @@ -37,4 +37,7 @@ pub mod vars { "NYM_NETWORK_MONITOR_CHAIN_AUTH_CHECK_RETRY_DELAY"; pub const NYM_NETWORK_MONITOR_RESULT_SUBMISSION_INTERVAL_ARG: &str = "NYM_NETWORK_MONITOR_RESULT_SUBMISSION_INTERVAL"; + + pub const NYM_NETWORK_MONITOR_RESULT_SUBMISSION_BATCH_SIZE_ARG: &str = + "NYM_NETWORK_MONITOR_RESULT_SUBMISSION_BATCH_SIZE"; } diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/run_orchestrator.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/run_orchestrator.rs index fa85d2aa62..597b65e6bc 100644 --- a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/run_orchestrator.rs +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/cli/run_orchestrator.rs @@ -9,7 +9,7 @@ use nym_crypto::asymmetric::ed25519; use nym_validator_client::nyxd::bip39; use std::mem; use std::net::SocketAddr; -use std::num::NonZeroU32; +use std::num::{NonZeroU32, NonZeroUsize}; use std::path::PathBuf; use std::sync::Arc; use std::time::Duration; @@ -109,6 +109,10 @@ pub(crate) struct Args { /// batch submission (e.g. `15m`, `1h`). #[clap(long, env = NYM_NETWORK_MONITOR_RESULT_SUBMISSION_INTERVAL_ARG, value_parser = humantime::parse_duration, default_value = "15m")] result_submission_interval: Duration, + + /// Maximum number of stress testing results to submit in a single POST request + #[clap(long, env = NYM_NETWORK_MONITOR_RESULT_SUBMISSION_BATCH_SIZE_ARG, default_value = "50")] + result_submission_batch_size: NonZeroUsize, } impl Args { @@ -145,6 +149,7 @@ impl Args { chain_authorisation_check_max_attempts: self.chain_authorisation_check_max_attempts, chain_authorisation_check_retry_delay: self.chain_authorisation_check_retry_delay, result_submission_interval: self.result_submission_interval, + result_submission_batch_size: self.result_submission_batch_size.get(), }) } diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/config.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/config.rs index cad15f3692..5f23be6a9c 100644 --- a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/config.rs +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/config.rs @@ -71,6 +71,9 @@ pub(crate) struct Config { /// How often the orchestrator flushes accumulated test results to the nym-api as a signed /// batch submission (e.g. `15m`, `1h`). pub(crate) result_submission_interval: Duration, + + /// Maximum number of stress testing results to submit in a single POST request + pub(crate) result_submission_batch_size: usize, } impl Config { diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/result_submitter.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/result_submitter.rs index fbb97de233..60d8156f39 100644 --- a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/result_submitter.rs +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/orchestrator/result_submitter.rs @@ -12,8 +12,9 @@ use nym_validator_client::nym_api::NymApiClientExt; use nym_validator_client::signable::SignableMessageBody; use std::sync::Arc; use std::time::Duration; +use time::OffsetDateTime; use tokio::time::{Instant, MissedTickBehavior, interval_at}; -use tracing::{debug, info}; +use tracing::info; /// Background task that periodically drains freshly-completed test run results from the local /// storage, wraps them into a signed [`StressTestBatchSubmission`][batch], and POSTs the batch to @@ -38,6 +39,9 @@ pub(crate) struct ResultSubmitter { /// Cadence at which [`Self::run`] attempts a submission sweep. submission_interval: Duration, + /// Maximum number of stress testing results to submit in a single POST request + result_submission_batch_size: usize, + shutdown_token: ShutdownToken, } @@ -54,6 +58,7 @@ impl ResultSubmitter { storage, identity_keys, submission_interval: config.result_submission_interval, + result_submission_batch_size: config.result_submission_batch_size, shutdown_token, } } @@ -74,7 +79,7 @@ impl ResultSubmitter { /// /// [batch]: nym_api_requests::models::network_monitor::StressTestBatchSubmission async fn submit_pending_results(&self) -> anyhow::Result<()> { - info!("submitting stress-test results to nym-api"); + info!("attempting to submit stress-test results to nym-api"); let last_submitted = self.storage.get_last_submitted_testrun_id().await?; // `None` means "never submitted" - treat as 0, which pulls everything currently in the // table (testrun.id is AUTOINCREMENT, so always >= 1). @@ -82,29 +87,55 @@ impl ResultSubmitter { let pending = self.storage.get_testruns_after(after_id).await?; if pending.is_empty() { - debug!("stress-test result submission sweep: no new results"); + info!("stress-test result submission sweep: no new results"); return Ok(()); } - // `get_testruns_after` returns rows ordered by id ASC, so the last row carries the - // highest id and is what we advance the watermark to once the batch is accepted. - #[allow(clippy::expect_used)] - let max_id = pending.last().expect("pending is non-empty").id; - let batch_size = pending.len(); - - let results: Vec = pending.into_iter().map(Into::into).collect(); + info!("{} pending stress test results to submit", pending.len()); let signer = *self.identity_keys.public_key(); - let body = StressTestBatchSubmissionContent::new(signer, results); - let signed = body.sign(self.identity_keys.private_key()); + // nym-api requires each submission's timestamp to be strictly greater than the previous one + // for a given signer (replay protection). Within a single sweep, two consecutive chunks + // could otherwise share a `now_utc()` reading if the host clock has too-coarse resolution + // or steps backwards, which would get the second chunk rejected. Track the last timestamp + // we used and bump by a nanosecond if `now_utc()` hasn't advanced past it. + let mut last_timestamp = OffsetDateTime::now_utc(); - self.client - .submit_stress_testing_results(&signed) - .await - .context("failed to POST stress-test batch submission to nym-api")?; + for chunk in pending.chunks(self.result_submission_batch_size) { + // `get_testruns_after` returns rows ordered by id ASC, so the last row carries the + // highest id and is what we advance the watermark to once the batch is accepted. + #[allow(clippy::expect_used)] + let max_id = chunk.last().expect("chunk is non-empty").id; + let batch_size = chunk.len(); + + let results: Vec = chunk.iter().map(Into::into).collect(); + + let now = OffsetDateTime::now_utc(); + let timestamp = if now > last_timestamp { + now + } else { + last_timestamp + time::Duration::NANOSECOND + }; + last_timestamp = timestamp; + + let body = StressTestBatchSubmissionContent { + signer, + timestamp, + results, + }; + let signed = body.sign(self.identity_keys.private_key()); + + self.client + .submit_stress_testing_results(&signed) + .await + .context("failed to POST stress-test batch submission to nym-api")?; + + self.storage.set_last_submitted_testrun_id(max_id).await?; + info!( + "submitted {batch_size} stress-test results batch to nym-api (testrun ids up to {max_id})" + ); + } - self.storage.set_last_submitted_testrun_id(max_id).await?; - info!("submitted {batch_size} stress-test results to nym-api (testrun ids up to {max_id})"); Ok(()) } @@ -130,7 +161,7 @@ impl ResultSubmitter { // Submission errors shouldn't kill the task - local storage retains the // pending rows until the retention window expires, so the next tick will // retry and eventually catch up once the nym-api is reachable again. - tracing::error!("failed to submit stress-test results: {err}"); + tracing::error!("failed to submit stress-test results: {err:#}"); } } } diff --git a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/storage/models.rs b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/storage/models.rs index 9da074588a..831dd43f48 100644 --- a/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/storage/models.rs +++ b/nym-network-monitor-v3/nym-network-monitor-orchestrator/src/storage/models.rs @@ -274,6 +274,14 @@ impl From for StressTestResult { } } +impl From<&TestRun> for StressTestResult { + fn from(run: &TestRun) -> Self { + // the data is small enough that cloning is negligible + // (since we're going to be converting at most couple dozen a minute rather than a few billion...) + run.clone().into() + } +} + /// The data required to insert or update a row in `nym_node`. Does not carry `last_testrun` /// since that is managed separately via [`StorageManager::set_node_last_testrun`]. #[derive(Debug, Clone, sqlx::FromRow)] From 4ce136ccf06eda7d340ed0476e6f9edf0248881a Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Mon, 1 Jun 2026 13:12:15 +0200 Subject: [PATCH 73/94] fix clippy --- nym-gateway-probe/build.rs | 18 ++++++------ nym-gateway-probe/src/lib.rs | 55 +++++++++++++++++++++++------------- 2 files changed, 44 insertions(+), 29 deletions(-) diff --git a/nym-gateway-probe/build.rs b/nym-gateway-probe/build.rs index 97a8d14c7c..bd3b21ab13 100644 --- a/nym-gateway-probe/build.rs +++ b/nym-gateway-probe/build.rs @@ -69,15 +69,15 @@ fn generate_exit_policy_ports() -> anyhow::Result<()> { if value.contains('-') { let parts: Vec<&str> = value.split('-').collect(); - if parts.len() == 2 { - if let (Ok(lo), Ok(hi)) = (parts[0].parse::(), parts[1].parse::()) { - port_map - .entry(lo) - .or_insert_with(|| format!("{service} (range start)")); - port_map - .entry(hi) - .or_insert_with(|| format!("{service} (range end)")); - } + if parts.len() == 2 + && let (Ok(lo), Ok(hi)) = (parts[0].parse::(), parts[1].parse::()) + { + port_map + .entry(lo) + .or_insert_with(|| format!("{service} (range start)")); + port_map + .entry(hi) + .or_insert_with(|| format!("{service} (range end)")); } } else if let Ok(port) = value.parse::() { port_map.entry(port).or_insert_with(|| service.to_string()); diff --git a/nym-gateway-probe/src/lib.rs b/nym-gateway-probe/src/lib.rs index bc9af69858..a316666f37 100644 --- a/nym-gateway-probe/src/lib.rs +++ b/nym-gateway-probe/src/lib.rs @@ -67,6 +67,20 @@ struct PortScanRun { last_error: Option, } +/// Auth endpoint to probe during a port scan. +struct PortScanTarget { + authenticator: nym_sdk::mixnet::Recipient, + authenticator_version: nym_authenticator_requests::AuthenticatorVersion, + ip_address: IpAddr, +} + +/// Ticket-acquisition parameters for a single port scan session. +struct PortScanBandwidth<'a> { + provider: &'a dyn BandwidthTicketProvider, + ticket_type: TicketType, + credential_provider: nym_sdk::mixnet::NodeIdentity, +} + /// Validated info needed to run a WG port-check via the mixnet. struct PortCheckSetup { exit_node: TestedNodeDetails, @@ -145,12 +159,8 @@ impl Probe { async fn run_port_scan_with_retries( mixnet_listener_task: &AuthClientMixnetListenerHandle, nym_address: nym_sdk::mixnet::Recipient, - authenticator: nym_sdk::mixnet::Recipient, - authenticator_version: nym_authenticator_requests::AuthenticatorVersion, - ip_address: IpAddr, - bandwidth_provider: &dyn BandwidthTicketProvider, - wg_ticket_type: TicketType, - credential_provider: nym_sdk::mixnet::NodeIdentity, + target: PortScanTarget, + bandwidth: PortScanBandwidth<'_>, netstack_args: NetstackArgs, awg_args: Option, ) -> PortScanRun { @@ -165,8 +175,9 @@ impl Probe { tokio::time::sleep(std::time::Duration::from_secs(5)).await; } - let credential = match bandwidth_provider - .get_ecash_ticket(wg_ticket_type, credential_provider, 1) + let credential = match bandwidth + .provider + .get_ecash_ticket(bandwidth.ticket_type, bandwidth.credential_provider, 1) .await { Ok(ticket) => ticket.data, @@ -182,16 +193,16 @@ impl Probe { mixnet_listener_task.subscribe(), mixnet_listener_task.mixnet_sender(), nym_address, - authenticator, - authenticator_version, + target.authenticator, + target.authenticator_version, Arc::new(x25519::KeyPair::new(&mut rng)), - ip_address, + target.ip_address, ); match wg_probe( auth_client, - ip_address, - authenticator_version, + target.ip_address, + target.authenticator_version, awg_args.clone(), netstack_args.clone(), true, // port_check_only @@ -265,7 +276,7 @@ impl Probe { "All port-check targets unreachable; falling back to first: '{}'", selected_target ); - } else if selected_target != *targets.first().unwrap() { + } else if selected_target != targets[0] { info!( "Port check: selected target '{}' (first reachable from list)", selected_target @@ -298,12 +309,16 @@ impl Probe { let scan = Self::run_port_scan_with_retries( &mixnet_listener_task, nym_address, - setup.authenticator, - setup.exit_node.authenticator_version, - setup.ip_address, - bandwidth_provider, - TicketType::V1WireguardExit, - setup.exit_node.identity, + PortScanTarget { + authenticator: setup.authenticator, + authenticator_version: setup.exit_node.authenticator_version, + ip_address: setup.ip_address, + }, + PortScanBandwidth { + provider: bandwidth_provider, + ticket_type: TicketType::V1WireguardExit, + credential_provider: setup.exit_node.identity, + }, netstack_args, None, ) From 639c7f83a42518e0d4a1ac4cd8a27df81b1c9992 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Mon, 1 Jun 2026 14:02:25 +0200 Subject: [PATCH 74/94] clippy --- nym-gateway-probe/src/run.rs | 8 ++++---- .../nym-node-status-api/src/db/queries/gateways.rs | 5 ++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/nym-gateway-probe/src/run.rs b/nym-gateway-probe/src/run.rs index 06fcbbb1d8..aa961b784b 100644 --- a/nym-gateway-probe/src/run.rs +++ b/nym-gateway-probe/src/run.rs @@ -147,7 +147,7 @@ struct RunPortsProbeConfig { #[derive(Serialize)] #[serde(untagged)] pub(crate) enum ProbeOutput { - Standard(ProbeResult), + Standard(Box), PortCheck(PortCheckResult), } @@ -222,7 +222,7 @@ pub(crate) async fn run() -> anyhow::Result { Box::pin(trial.probe_run_locally(&config_dir, credential_mode)) .await - .map(ProbeOutput::Standard) + .map(|r| ProbeOutput::Standard(Box::new(r))) } Commands::Run { entry_gateway, @@ -268,7 +268,7 @@ pub(crate) async fn run() -> anyhow::Result { nym_gateway_probe::Probe::new(entry_details, exit_details, network, probe_config); Box::pin(trial.probe_run(&config_dir, credential_mode)) .await - .map(ProbeOutput::Standard) + .map(|r| ProbeOutput::Standard(Box::new(r))) } Commands::RunPorts { entry_gateway, @@ -350,7 +350,7 @@ pub(crate) async fn run() -> anyhow::Result { .await?; Box::pin(trial.probe_run_agent(credential_args)) .await - .map(ProbeOutput::Standard) + .map(|r| ProbeOutput::Standard(Box::new(r))) } } } diff --git a/nym-node-status-api/nym-node-status-api/src/db/queries/gateways.rs b/nym-node-status-api/nym-node-status-api/src/db/queries/gateways.rs index 5049163317..57ca705fa4 100644 --- a/nym-node-status-api/nym-node-status-api/src/db/queries/gateways.rs +++ b/nym-node-status-api/nym-node-status-api/src/db/queries/gateways.rs @@ -118,9 +118,8 @@ impl Storage { if failed > 0 { tracing::warn!("{failed} gateway DTO(s) failed conversion and were skipped"); } - let items = gateways; - tracing::trace!("Fetched {} gateways from DB", items.len()); - Ok(items) + tracing::trace!("Fetched {} gateways from DB", gateways.len()); + Ok(gateways) } } From aa7b1e939a31d7d6a5f1a9f0de8301709a9c275b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 1 Jun 2026 14:08:06 +0100 Subject: [PATCH 75/94] fix score inflation for throttled nodes (#6842) --- .../nym-network-monitor-agent/Cargo.toml | 2 +- .../nym-network-monitor-agent/src/agent/tester.rs | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/Cargo.toml b/nym-network-monitor-v3/nym-network-monitor-agent/Cargo.toml index 9500df46f1..b274b18c1f 100644 --- a/nym-network-monitor-v3/nym-network-monitor-agent/Cargo.toml +++ b/nym-network-monitor-v3/nym-network-monitor-agent/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "nym-network-monitor-agent" description = "Agent used for stress testing Nym mixnodes" -version = "1.0.3" +version = "1.0.4" authors.workspace = true edition.workspace = true license.workspace = true diff --git a/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/tester.rs b/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/tester.rs index f4277ce9d4..24862d168f 100644 --- a/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/tester.rs +++ b/nym-network-monitor-v3/nym-network-monitor-agent/src/agent/tester.rs @@ -350,6 +350,13 @@ impl NodeStressTester { "did not manage to send all required packets within the sending window. sent {sent}/{total_packets}" ); } + // Report `total_packets` (= expected) rather than `sent` so the orchestrator's + // `received / sent` score formula effectively becomes `received / expected` - + // a node that throttled us via TCP back-pressure into not pushing all packets + // through is correctly penalised. Per-batch `set_packets_sent(sent)` updates + // above remain in place for the `Ok(false)` early-exit (send error) path, so + // partial-progress visibility is preserved when the test aborts mid-run. + result.set_packets_sent(total_packets); Ok(true) } From 2fd26581eb3da76c695a1f420a59336ab41390da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 1 Jun 2026 16:18:24 +0100 Subject: [PATCH 76/94] fix(ns-api): guard ports-check migration against non-JSON last_probe_result The 20260415 migration cast last_probe_result::jsonb guarded only by a btrim non-empty check, so any row with non-JSON text aborted the whole migration. Add the same last_probe_result ~ '^[\[{]' guard the follow-up 20260519133000 migration uses, directly to both UPDATEs here. --- .../migrations_pg/20260415000000_gateways_ports_check.sql | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nym-node-status-api/nym-node-status-api/migrations_pg/20260415000000_gateways_ports_check.sql b/nym-node-status-api/nym-node-status-api/migrations_pg/20260415000000_gateways_ports_check.sql index e521cb2aa5..f506b093f5 100644 --- a/nym-node-status-api/nym-node-status-api/migrations_pg/20260415000000_gateways_ports_check.sql +++ b/nym-node-status-api/nym-node-status-api/migrations_pg/20260415000000_gateways_ports_check.sql @@ -4,6 +4,7 @@ UPDATE gateways SET ports_check = (last_probe_result::jsonb -> 'ports_check') WHERE last_probe_result IS NOT NULL AND btrim(last_probe_result) <> '' + AND last_probe_result ~ '^[\[{]' AND last_probe_result::jsonb ? 'ports_check' AND ports_check IS NULL; @@ -11,4 +12,5 @@ UPDATE gateways SET last_probe_result = (last_probe_result::jsonb - 'ports_check')::text WHERE last_probe_result IS NOT NULL AND btrim(last_probe_result) <> '' + AND last_probe_result ~ '^[\[{]' AND last_probe_result::jsonb ? 'ports_check'; \ No newline at end of file From 3dd6b907fe43b7165c2ebbe2bf9549202e69fcf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 1 Jun 2026 16:18:25 +0100 Subject: [PATCH 77/94] fix(nym-gateway-probe): anchor exit-policy script path to CARGO_MANIFEST_DIR The build read network-tunnel-manager.sh via a CWD-relative path, coupling the build to the invocation directory. Anchor it to CARGO_MANIFEST_DIR. --- nym-gateway-probe/build.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nym-gateway-probe/build.rs b/nym-gateway-probe/build.rs index bd3b21ab13..e1947f2277 100644 --- a/nym-gateway-probe/build.rs +++ b/nym-gateway-probe/build.rs @@ -26,7 +26,9 @@ fn main() -> anyhow::Result<()> { fn generate_exit_policy_ports() -> anyhow::Result<()> { use std::collections::BTreeMap; - let script_path = PathBuf::from("../scripts/nym-node-setup/network-tunnel-manager.sh"); + let manifest_dir = + PathBuf::from(std::env::var("CARGO_MANIFEST_DIR").context("CARGO_MANIFEST_DIR not set")?); + let script_path = manifest_dir.join("../scripts/nym-node-setup/network-tunnel-manager.sh"); let out_dir = PathBuf::from(std::env::var("OUT_DIR").context("OUT_DIR not set")?); println!("cargo::rerun-if-changed={}", script_path.display()); From cc405cc802608c3db4a0b591cbbd8a1b555a7d98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 1 Jun 2026 16:21:14 +0100 Subject: [PATCH 78/94] refactor(ns-api): compile-time-check count_testruns_in_progress_by_kind Switch from runtime sqlx::query_scalar to the checked query_scalar! macro (consistent with the rest of the file), returning i64 instead of an always-Some Option and dropping the unwrap_or_default() at the call site. Regenerates the .sqlx cache, adding the new query and pruning accumulated orphans. --- ...afa2525da6c0b871633aad80ad555db9cf47c.json | 32 ---------------- ...b19f15d22fff72490473587a14cdc046fda32.json | 20 ---------- ...3797a6a9ee7db2aab9f1b5e55f7c13c53bcc1.json | 12 ------ ...4c270fd5dd7f00eaab0fe82e6fe927e604294.json | 12 ------ ...af7974d7795b4cbdba234273345fe161df233.json | 12 ------ ...b5905d4dd6b7ac0e20f1cf100a51a1a40b35d.json | 12 ------ ...82b4dc00ba6a580de1faf83b137365f44b36d.json | 12 ------ ...105614dea7fd301f0ec38bfe85bfe546dad40.json | 12 ------ ...997139172411b10c7444dea74a1438de4f343.json | 12 ------ ...08cb6c3b99c6b808ba50c67b066fc3f36073b.json | 12 ------ ...765854899103fd3c0fa670eb6809492270e02.json | 12 ------ ...a317aabce063a650be362d3a8ed83cc7c3549.json | 12 ------ ...9f166ad7f57681f76a1d0c7723d007c1f2c1e.json | 12 ------ ...38edcdf149acfd38c56a4db3bbf97bdb13210.json | 12 ------ ...15212a6f526f78258e173c96ec177988696ef.json | 12 ------ ...2038a77ec37cca9f9aef18008dcd03030c2c4.json | 12 ------ ...bd97845350f4fb9f806c60b93c7cebd5e410d.json | 20 ---------- ...d8ea15b957dd19b097101dcda2c05aee21d20.json | 15 -------- ...91d2a2af57656b405212af414d765b2263347.json | 26 ------------- ...1bbace1bcf110e048e594e8bd03fa45290732.json | 12 ------ ...7cec1442967e53764b83ba0a66cd9a72494f9.json | 12 ------ ...6b2a5bec1c191993ff58f0c71c03e3ef6d92d.json | 12 ------ ...11e5732ece0bf84ea98f2328b20add8f2b5ef.json | 12 ------ ...5e03504afa58e345ae16a128629d8e76f0a11.json | 26 ------------- ...a8787133ee41814bd3efdd501f9ee0c050f2b.json | 20 ---------- ...e38b7f6ceb8e9191a7b9201922efcf6b07966.json | 12 ------ ...751a5ca340ac9c6dd86da1a5e9a3e65ea589f.json | 26 ------------- ...0fd083e87cc9a18d798b2cf8d6774224aebed.json | 20 ---------- ...6067dbf82d0dc376ad3f0df835b77dfcc3c37.json | 20 ---------- ...0d5ebd37d62612b65b8ac4c9eb5d7b67a8884.json | 26 ------------- ...8d18a0c6792d7a4244a65243d4b22d578a1e5.json | 20 ---------- ...7fca89d80869484f2f3c66cabb898f0298c62.json | 12 ------ ...2b60ccb76d6468f359891428c0bfb96ddd7ef.json | 12 ------ ...de04e5ece789fb0b0cd27ad09858fbf5c5e27.json | 12 ------ ...682169b87f488b6927fa67fade6bf5abf7582.json | 12 ------ ...6156311713d2e9f69d39c868cd16296b56326.json | 12 ------ ...4d63462e9ea0049e2edafea1dc3f8476b33e4.json | 12 ------ ...de3eb76fed954b7336530401db72cd008aff3.json | 12 ------ ...b57e6ea8685e9473a3a8bd635552810493a58.json | 32 ---------------- ...57f91a11f5057273cb70bd0e629712d17dd41.json | 12 ------ ...9db66d1dc1307c0873627b39cb22a245b5a8c.json | 12 ------ ...15dcfcffb502ba8398caefd56c481f44eb84e.json | 12 ------ ...13ab15fed747fb0cee1c9f949fb58461b3f79.json | 32 ---------------- ...4cb8bf8ebb1c26839f915780d0fc0d1939973.json | 31 --------------- ...a8ed4e9a64884ac5619e0abdecb04f2d13a74.json | 28 -------------- ...4adec312abffa604fa805cc362a2c206107b4.json | 12 ------ ...6a811c593aea8febf1f891117e5e84213f147.json | 12 ------ ...eafc9b5f64061b6c9a829e2912945b6cffc82.json | 32 ---------------- ...89dde284b38a3a4960afed758206d03ca1cf4.json | 12 ------ ...b253c071e04eb853d4b0f3b21782ea57c2f68.json | 12 ------ ...5ebe0222a2a0ba96f28e3a3aa58fdc4b689db.json | 12 ------ ...125c24750b523cfcad1e5e9069dbf7050e2a1.json | 20 ---------- ...c9f560017b4da6b0303ea0397d9568229e167.json | 38 ------------------- ...087af53e9504a8bb13280dde5c37b9b418370.json | 22 ----------- ...abd806877ce914b514d4f7cd6be318c4debe6.json | 12 ------ ...1da2809ec4bd66ad49d2e3b8d67b741835475.json | 12 ------ ...8f633a94d18a19b7f0f96935a62560def7d0f.json | 12 ------ ...bcb8900bca7157d3c66c5664386ca2c26e96a.json | 23 +++++++++++ ...9cde3f6f6689a80299b5b6c1d7bd048965e6e.json | 15 -------- ...35677b9d9a1b29e4d89437134e92967fa98d1.json | 12 ------ ...52f2bfed2d918b894ec0f588e38dd5e8ad726.json | 12 ------ ...6a2e314787586a46cffd074abb67f2f4d109e.json | 38 ------------------- ...ac000904bb7fe3934786d652adc80fde78add.json | 20 ---------- ...3d41724666bf92357bf5faf42120a2aab131c.json | 12 ------ ...18a1f62fa67dfe8f130deb876ebee11bf1602.json | 20 ---------- ...bb91cd5046a8c9d4434cf085a4fa2ebf03e93.json | 12 ------ .../src/db/queries/testruns.rs | 18 ++++----- .../src/http/api/testruns.rs | 3 +- 68 files changed, 33 insertions(+), 1102 deletions(-) delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-0112296b190328a3856d1adf51aafa2525da6c0b871633aad80ad555db9cf47c.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-06e743d143fcc4be20ca2af5e99b19f15d22fff72490473587a14cdc046fda32.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-16d10f0ac0ed9ce4239937f46df3797a6a9ee7db2aab9f1b5e55f7c13c53bcc1.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-1b43cc81ce6b6007ccc59172fc64c270fd5dd7f00eaab0fe82e6fe927e604294.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-1da6904e72b5abb9abf75affb13af7974d7795b4cbdba234273345fe161df233.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-1f4fde2cafa3b5fae95ab5fb653b5905d4dd6b7ac0e20f1cf100a51a1a40b35d.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-1fa61c23a1504de280d67c7943282b4dc00ba6a580de1faf83b137365f44b36d.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-1fc72f8ba24039548047e1766c9105614dea7fd301f0ec38bfe85bfe546dad40.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-20797a3e0bb951ed77216a906d7997139172411b10c7444dea74a1438de4f343.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-22bc9c7bcf96ec817c83c26104408cb6c3b99c6b808ba50c67b066fc3f36073b.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-284b3ceae42f9320c30323dde47765854899103fd3c0fa670eb6809492270e02.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-28681fcd8e2d4326f628681b8f2a317aabce063a650be362d3a8ed83cc7c3549.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-2930ca6e3875c74acb7abb9ad889f166ad7f57681f76a1d0c7723d007c1f2c1e.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-2c113b37864f9fec7e64c0f8fdd38edcdf149acfd38c56a4db3bbf97bdb13210.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-2f3c12cb0c48084b569e12ecb0315212a6f526f78258e173c96ec177988696ef.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-37f82c9ec26b53d01601a2d6df82038a77ec37cca9f9aef18008dcd03030c2c4.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-396f40c33f0f62796eb7449d640bd97845350f4fb9f806c60b93c7cebd5e410d.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-3c6da5c1faace026222bbb28553d8ea15b957dd19b097101dcda2c05aee21d20.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-3cc446220668fb3e02f0578104291d2a2af57656b405212af414d765b2263347.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-42dfc51aea793fc60484cff6c481bbace1bcf110e048e594e8bd03fa45290732.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-4a4f3b32b313f7fbc6eb579659e7cec1442967e53764b83ba0a66cd9a72494f9.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-4f78619aca933484cd67cb89a376b2a5bec1c191993ff58f0c71c03e3ef6d92d.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-52b378e282d93db941eff53b5b311e5732ece0bf84ea98f2328b20add8f2b5ef.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-54f552a9dbe95236f946ac2b6615e03504afa58e345ae16a128629d8e76f0a11.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-5661cf1ad8bd5ca062e855e1971a8787133ee41814bd3efdd501f9ee0c050f2b.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-5c5d4bfabf18bc6fa56e76a9b98e38b7f6ceb8e9191a7b9201922efcf6b07966.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-5d3b8ad051ab6f46c702308c2fc751a5ca340ac9c6dd86da1a5e9a3e65ea589f.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-5e51396c534409a4b55c08170e00fd083e87cc9a18d798b2cf8d6774224aebed.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-62f471858c831ac762a0ecf60876067dbf82d0dc376ad3f0df835b77dfcc3c37.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-648fff18c4016fb356c164f813e0d5ebd37d62612b65b8ac4c9eb5d7b67a8884.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-67db5e91bcdc831e0d1659eda358d18a0c6792d7a4244a65243d4b22d578a1e5.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-70d8f240ad6edda6b8c7f2e800e7fca89d80869484f2f3c66cabb898f0298c62.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-727598e516090da6d26e36d09062b60ccb76d6468f359891428c0bfb96ddd7ef.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-74d77a3e15f49bde7b8b17dd638de04e5ece789fb0b0cd27ad09858fbf5c5e27.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-80476cf2906eb0ecf7f66c16bc5682169b87f488b6927fa67fade6bf5abf7582.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-805ad4f26e0234d7f482a263e186156311713d2e9f69d39c868cd16296b56326.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-81a12a8a419c88b1c28a5533fde4d63462e9ea0049e2edafea1dc3f8476b33e4.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-84cad8b1078a4000830835e6349de3eb76fed954b7336530401db72cd008aff3.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-85d542a8cb2e1fbba6142729056b57e6ea8685e9473a3a8bd635552810493a58.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-97d97ebb6bc8f4114fdea9ebc9f57f91a11f5057273cb70bd0e629712d17dd41.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-a5a71e480118639397f7464abb09db66d1dc1307c0873627b39cb22a245b5a8c.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-a5b18e66d77ff802e274623605e15dcfcffb502ba8398caefd56c481f44eb84e.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-a8b7ce0fe4755c28b96d1e503e313ab15fed747fb0cee1c9f949fb58461b3f79.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-ad78bf2f7ed4666b4e5f60811f04cb8bf8ebb1c26839f915780d0fc0d1939973.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-b0c588db5f7be90c6d4cb1b55c3a8ed4e9a64884ac5619e0abdecb04f2d13a74.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-b6ce77fcffda2ee24ba181213e04adec312abffa604fa805cc362a2c206107b4.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-b8257a0832d0124f0a8aaaf81dc6a811c593aea8febf1f891117e5e84213f147.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-ba96344db31b0f2155e2af53eaaeafc9b5f64061b6c9a829e2912945b6cffc82.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-bc823c54143e2dc590b91347cd089dde284b38a3a4960afed758206d03ca1cf4.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-bd1973696121b6128bd75ae80fab253c071e04eb853d4b0f3b21782ea57c2f68.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-bdaf8e8dd711ff420807659456f5ebe0222a2a0ba96f28e3a3aa58fdc4b689db.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-bf249752f08c283bf5942b6ff48125c24750b523cfcad1e5e9069dbf7050e2a1.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-c2b841762bdb963fff337ef5c8ec9f560017b4da6b0303ea0397d9568229e167.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-cc84f8a284c9aba4494152ff4e6087af53e9504a8bb13280dde5c37b9b418370.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-d3510846941fa2525926b9bfbcdabd806877ce914b514d4f7cd6be318c4debe6.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-daa9ffcbe13178d773e538e96971da2809ec4bd66ad49d2e3b8d67b741835475.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-db176e98198fe594d88eb860d918f633a94d18a19b7f0f96935a62560def7d0f.json create mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-decdc7c0e6d279a137a80797cbabcb8900bca7157d3c66c5664386ca2c26e96a.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-dfa035c968534926736adf0e5359cde3f6f6689a80299b5b6c1d7bd048965e6e.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-e29e0c82d034626f9b369348b8e35677b9d9a1b29e4d89437134e92967fa98d1.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-e584253e3856355899537eb8fc152f2bfed2d918b894ec0f588e38dd5e8ad726.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-e77ffab19b099b84470fe5611716a2e314787586a46cffd074abb67f2f4d109e.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-e8717ef6523ef9bcf37a0e81570ac000904bb7fe3934786d652adc80fde78add.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-eded014a5fffbd9c359f8557bcd3d41724666bf92357bf5faf42120a2aab131c.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-ef60c2683211cc4ec2d3e46392518a1f62fa67dfe8f130deb876ebee11bf1602.json delete mode 100644 nym-node-status-api/nym-node-status-api/.sqlx/query-f3ebe259e26c05ecdd33bd9085dbb91cd5046a8c9d4434cf085a4fa2ebf03e93.json diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-0112296b190328a3856d1adf51aafa2525da6c0b871633aad80ad555db9cf47c.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-0112296b190328a3856d1adf51aafa2525da6c0b871633aad80ad555db9cf47c.json deleted file mode 100644 index 068bc54b4b..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-0112296b190328a3856d1adf51aafa2525da6c0b871633aad80ad555db9cf47c.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT epoch_id as \"epoch_id: u32\", serialised_key, serialization_revision as \"serialization_revision: u8\"\n FROM master_verification_key WHERE epoch_id = ?\n ", - "describe": { - "columns": [ - { - "name": "epoch_id: u32", - "ordinal": 0, - "type_info": "Integer" - }, - { - "name": "serialised_key", - "ordinal": 1, - "type_info": "Blob" - }, - { - "name": "serialization_revision: u8", - "ordinal": 2, - "type_info": "Integer" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - false, - false, - false - ] - }, - "hash": "0112296b190328a3856d1adf51aafa2525da6c0b871633aad80ad555db9cf47c" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-06e743d143fcc4be20ca2af5e99b19f15d22fff72490473587a14cdc046fda32.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-06e743d143fcc4be20ca2af5e99b19f15d22fff72490473587a14cdc046fda32.json deleted file mode 100644 index 20c47048d8..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-06e743d143fcc4be20ca2af5e99b19f15d22fff72490473587a14cdc046fda32.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "SQLite", - "query": "SELECT EXISTS (SELECT 1 FROM registered_gateway WHERE gateway_id_bs58 = ?) AS 'exists'", - "describe": { - "columns": [ - { - "name": "exists", - "ordinal": 0, - "type_info": "Integer" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - false - ] - }, - "hash": "06e743d143fcc4be20ca2af5e99b19f15d22fff72490473587a14cdc046fda32" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-16d10f0ac0ed9ce4239937f46df3797a6a9ee7db2aab9f1b5e55f7c13c53bcc1.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-16d10f0ac0ed9ce4239937f46df3797a6a9ee7db2aab9f1b5e55f7c13c53bcc1.json deleted file mode 100644 index e4f26c5053..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-16d10f0ac0ed9ce4239937f46df3797a6a9ee7db2aab9f1b5e55f7c13c53bcc1.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n INSERT OR IGNORE INTO expiration_date_signatures(expiration_date, epoch_id, serialised_signatures, serialization_revision)\n VALUES (?, ?, ?, ?);\n UPDATE expiration_date_signatures\n SET\n serialised_signatures = ?,\n serialization_revision = ?\n WHERE expiration_date = ?\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 7 - }, - "nullable": [] - }, - "hash": "16d10f0ac0ed9ce4239937f46df3797a6a9ee7db2aab9f1b5e55f7c13c53bcc1" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-1b43cc81ce6b6007ccc59172fc64c270fd5dd7f00eaab0fe82e6fe927e604294.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-1b43cc81ce6b6007ccc59172fc64c270fd5dd7f00eaab0fe82e6fe927e604294.json deleted file mode 100644 index 6d2842a9df..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-1b43cc81ce6b6007ccc59172fc64c270fd5dd7f00eaab0fe82e6fe927e604294.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n INSERT INTO remote_gateway_details(gateway_id_bs58, derived_aes256_gcm_siv_key, gateway_listener, fallback_listener, expiration_timestamp)\n VALUES (?, ?, ?, ?, ?)\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 5 - }, - "nullable": [] - }, - "hash": "1b43cc81ce6b6007ccc59172fc64c270fd5dd7f00eaab0fe82e6fe927e604294" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-1da6904e72b5abb9abf75affb13af7974d7795b4cbdba234273345fe161df233.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-1da6904e72b5abb9abf75affb13af7974d7795b4cbdba234273345fe161df233.json deleted file mode 100644 index 9d4281137b..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-1da6904e72b5abb9abf75affb13af7974d7795b4cbdba234273345fe161df233.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "DELETE FROM remote_gateway_details WHERE gateway_id_bs58 = ?", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "1da6904e72b5abb9abf75affb13af7974d7795b4cbdba234273345fe161df233" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-1f4fde2cafa3b5fae95ab5fb653b5905d4dd6b7ac0e20f1cf100a51a1a40b35d.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-1f4fde2cafa3b5fae95ab5fb653b5905d4dd6b7ac0e20f1cf100a51a1a40b35d.json deleted file mode 100644 index d891d0d97a..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-1f4fde2cafa3b5fae95ab5fb653b5905d4dd6b7ac0e20f1cf100a51a1a40b35d.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "DELETE FROM reply_key;", - "describe": { - "columns": [], - "parameters": { - "Right": 0 - }, - "nullable": [] - }, - "hash": "1f4fde2cafa3b5fae95ab5fb653b5905d4dd6b7ac0e20f1cf100a51a1a40b35d" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-1fa61c23a1504de280d67c7943282b4dc00ba6a580de1faf83b137365f44b36d.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-1fa61c23a1504de280d67c7943282b4dc00ba6a580de1faf83b137365f44b36d.json deleted file mode 100644 index 096aa7a892..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-1fa61c23a1504de280d67c7943282b4dc00ba6a580de1faf83b137365f44b36d.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "UPDATE status SET previous_flush = ?", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "1fa61c23a1504de280d67c7943282b4dc00ba6a580de1faf83b137365f44b36d" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-1fc72f8ba24039548047e1766c9105614dea7fd301f0ec38bfe85bfe546dad40.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-1fc72f8ba24039548047e1766c9105614dea7fd301f0ec38bfe85bfe546dad40.json deleted file mode 100644 index cdc057df57..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-1fc72f8ba24039548047e1766c9105614dea7fd301f0ec38bfe85bfe546dad40.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n INSERT INTO ecash_deposit_usage (deposit_id, ticketbooks_requested_on, client_pubkey, request_uuid)\n VALUES (?, ?, ?, ?)\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 4 - }, - "nullable": [] - }, - "hash": "1fc72f8ba24039548047e1766c9105614dea7fd301f0ec38bfe85bfe546dad40" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-20797a3e0bb951ed77216a906d7997139172411b10c7444dea74a1438de4f343.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-20797a3e0bb951ed77216a906d7997139172411b10c7444dea74a1438de4f343.json deleted file mode 100644 index eb6e8b8904..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-20797a3e0bb951ed77216a906d7997139172411b10c7444dea74a1438de4f343.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n UPDATE remote_gateway_details SET gateway_listener = ?, fallback_listener = ?, expiration_timestamp = ? WHERE gateway_id_bs58 = ?\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 4 - }, - "nullable": [] - }, - "hash": "20797a3e0bb951ed77216a906d7997139172411b10c7444dea74a1438de4f343" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-22bc9c7bcf96ec817c83c26104408cb6c3b99c6b808ba50c67b066fc3f36073b.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-22bc9c7bcf96ec817c83c26104408cb6c3b99c6b808ba50c67b066fc3f36073b.json deleted file mode 100644 index 3fbb4e474d..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-22bc9c7bcf96ec817c83c26104408cb6c3b99c6b808ba50c67b066fc3f36073b.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n INSERT INTO reply_surb(reply_surb_sender_id, reply_surb, encoded_key_rotation) VALUES (?, ?, ?);\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 3 - }, - "nullable": [] - }, - "hash": "22bc9c7bcf96ec817c83c26104408cb6c3b99c6b808ba50c67b066fc3f36073b" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-284b3ceae42f9320c30323dde47765854899103fd3c0fa670eb6809492270e02.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-284b3ceae42f9320c30323dde47765854899103fd3c0fa670eb6809492270e02.json deleted file mode 100644 index 6ee25bbc1a..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-284b3ceae42f9320c30323dde47765854899103fd3c0fa670eb6809492270e02.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n INSERT INTO ecash_ticketbook\n (serialization_revision, ticketbook_data, expiration_date, ticketbook_type, epoch_id, total_tickets, used_tickets)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 7 - }, - "nullable": [] - }, - "hash": "284b3ceae42f9320c30323dde47765854899103fd3c0fa670eb6809492270e02" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-28681fcd8e2d4326f628681b8f2a317aabce063a650be362d3a8ed83cc7c3549.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-28681fcd8e2d4326f628681b8f2a317aabce063a650be362d3a8ed83cc7c3549.json deleted file mode 100644 index 32f3f9958c..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-28681fcd8e2d4326f628681b8f2a317aabce063a650be362d3a8ed83cc7c3549.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n DELETE FROM blinded_shares WHERE created < ?\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "28681fcd8e2d4326f628681b8f2a317aabce063a650be362d3a8ed83cc7c3549" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-2930ca6e3875c74acb7abb9ad889f166ad7f57681f76a1d0c7723d007c1f2c1e.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-2930ca6e3875c74acb7abb9ad889f166ad7f57681f76a1d0c7723d007c1f2c1e.json deleted file mode 100644 index 9ef7d96cca..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-2930ca6e3875c74acb7abb9ad889f166ad7f57681f76a1d0c7723d007c1f2c1e.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n INSERT INTO global_expiration_date_signatures(expiration_date, epoch_id, serialised_signatures, serialization_revision)\n VALUES (?, ?, ?, ?)\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 4 - }, - "nullable": [] - }, - "hash": "2930ca6e3875c74acb7abb9ad889f166ad7f57681f76a1d0c7723d007c1f2c1e" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-2c113b37864f9fec7e64c0f8fdd38edcdf149acfd38c56a4db3bbf97bdb13210.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-2c113b37864f9fec7e64c0f8fdd38edcdf149acfd38c56a4db3bbf97bdb13210.json deleted file mode 100644 index 4fd84fdf93..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-2c113b37864f9fec7e64c0f8fdd38edcdf149acfd38c56a4db3bbf97bdb13210.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n INSERT INTO custom_gateway_details(gateway_id_bs58, data)\n VALUES (?, ?)\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 2 - }, - "nullable": [] - }, - "hash": "2c113b37864f9fec7e64c0f8fdd38edcdf149acfd38c56a4db3bbf97bdb13210" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-2f3c12cb0c48084b569e12ecb0315212a6f526f78258e173c96ec177988696ef.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-2f3c12cb0c48084b569e12ecb0315212a6f526f78258e173c96ec177988696ef.json deleted file mode 100644 index 405049043d..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-2f3c12cb0c48084b569e12ecb0315212a6f526f78258e173c96ec177988696ef.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n DELETE FROM emergency_credential\n WHERE id = ?\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "2f3c12cb0c48084b569e12ecb0315212a6f526f78258e173c96ec177988696ef" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-37f82c9ec26b53d01601a2d6df82038a77ec37cca9f9aef18008dcd03030c2c4.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-37f82c9ec26b53d01601a2d6df82038a77ec37cca9f9aef18008dcd03030c2c4.json deleted file mode 100644 index ea79b11bbd..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-37f82c9ec26b53d01601a2d6df82038a77ec37cca9f9aef18008dcd03030c2c4.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "DELETE FROM ecash_ticketbook WHERE expiration_date <= ?", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "37f82c9ec26b53d01601a2d6df82038a77ec37cca9f9aef18008dcd03030c2c4" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-396f40c33f0f62796eb7449d640bd97845350f4fb9f806c60b93c7cebd5e410d.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-396f40c33f0f62796eb7449d640bd97845350f4fb9f806c60b93c7cebd5e410d.json deleted file mode 100644 index 944c86e33e..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-396f40c33f0f62796eb7449d640bd97845350f4fb9f806c60b93c7cebd5e410d.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT error_message\n FROM blinded_shares\n WHERE id = ?;\n ", - "describe": { - "columns": [ - { - "name": "error_message", - "ordinal": 0, - "type_info": "Text" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - true - ] - }, - "hash": "396f40c33f0f62796eb7449d640bd97845350f4fb9f806c60b93c7cebd5e410d" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-3c6da5c1faace026222bbb28553d8ea15b957dd19b097101dcda2c05aee21d20.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-3c6da5c1faace026222bbb28553d8ea15b957dd19b097101dcda2c05aee21d20.json deleted file mode 100644 index bd975d3146..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-3c6da5c1faace026222bbb28553d8ea15b957dd19b097101dcda2c05aee21d20.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "UPDATE gateways SET last_ports_check_utc = $1, last_updated_utc = $1 WHERE id = $2", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Int8", - "Int4" - ] - }, - "nullable": [] - }, - "hash": "3c6da5c1faace026222bbb28553d8ea15b957dd19b097101dcda2c05aee21d20" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-3cc446220668fb3e02f0578104291d2a2af57656b405212af414d765b2263347.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-3cc446220668fb3e02f0578104291d2a2af57656b405212af414d765b2263347.json deleted file mode 100644 index 9d8cff1326..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-3cc446220668fb3e02f0578104291d2a2af57656b405212af414d765b2263347.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT serialised_signatures, serialization_revision as \"serialization_revision: u8\"\n FROM global_expiration_date_signatures\n WHERE expiration_date = ? AND epoch_id = ?\n ", - "describe": { - "columns": [ - { - "name": "serialised_signatures", - "ordinal": 0, - "type_info": "Blob" - }, - { - "name": "serialization_revision: u8", - "ordinal": 1, - "type_info": "Integer" - } - ], - "parameters": { - "Right": 2 - }, - "nullable": [ - false, - false - ] - }, - "hash": "3cc446220668fb3e02f0578104291d2a2af57656b405212af414d765b2263347" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-42dfc51aea793fc60484cff6c481bbace1bcf110e048e594e8bd03fa45290732.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-42dfc51aea793fc60484cff6c481bbace1bcf110e048e594e8bd03fa45290732.json deleted file mode 100644 index d1ea957e7f..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-42dfc51aea793fc60484cff6c481bbace1bcf110e048e594e8bd03fa45290732.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "UPDATE status SET client_in_use = ?", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "42dfc51aea793fc60484cff6c481bbace1bcf110e048e594e8bd03fa45290732" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-4a4f3b32b313f7fbc6eb579659e7cec1442967e53764b83ba0a66cd9a72494f9.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-4a4f3b32b313f7fbc6eb579659e7cec1442967e53764b83ba0a66cd9a72494f9.json deleted file mode 100644 index e71f300174..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-4a4f3b32b313f7fbc6eb579659e7cec1442967e53764b83ba0a66cd9a72494f9.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n DELETE FROM emergency_credential\n WHERE type = ?\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "4a4f3b32b313f7fbc6eb579659e7cec1442967e53764b83ba0a66cd9a72494f9" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-4f78619aca933484cd67cb89a376b2a5bec1c191993ff58f0c71c03e3ef6d92d.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-4f78619aca933484cd67cb89a376b2a5bec1c191993ff58f0c71c03e3ef6d92d.json deleted file mode 100644 index eb2dc28e12..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-4f78619aca933484cd67cb89a376b2a5bec1c191993ff58f0c71c03e3ef6d92d.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "DELETE FROM custom_gateway_details WHERE gateway_id_bs58 = ?", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "4f78619aca933484cd67cb89a376b2a5bec1c191993ff58f0c71c03e3ef6d92d" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-52b378e282d93db941eff53b5b311e5732ece0bf84ea98f2328b20add8f2b5ef.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-52b378e282d93db941eff53b5b311e5732ece0bf84ea98f2328b20add8f2b5ef.json deleted file mode 100644 index 77a99816d4..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-52b378e282d93db941eff53b5b311e5732ece0bf84ea98f2328b20add8f2b5ef.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n DELETE FROM partial_blinded_wallet_failure WHERE created < ?\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "52b378e282d93db941eff53b5b311e5732ece0bf84ea98f2328b20add8f2b5ef" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-54f552a9dbe95236f946ac2b6615e03504afa58e345ae16a128629d8e76f0a11.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-54f552a9dbe95236f946ac2b6615e03504afa58e345ae16a128629d8e76f0a11.json deleted file mode 100644 index b1d46fd96b..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-54f552a9dbe95236f946ac2b6615e03504afa58e345ae16a128629d8e76f0a11.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "db_name": "SQLite", - "query": "SELECT * FROM custom_gateway_details WHERE gateway_id_bs58 = ?", - "describe": { - "columns": [ - { - "name": "gateway_id_bs58", - "ordinal": 0, - "type_info": "Text" - }, - { - "name": "data", - "ordinal": 1, - "type_info": "Blob" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - false, - true - ] - }, - "hash": "54f552a9dbe95236f946ac2b6615e03504afa58e345ae16a128629d8e76f0a11" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-5661cf1ad8bd5ca062e855e1971a8787133ee41814bd3efdd501f9ee0c050f2b.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-5661cf1ad8bd5ca062e855e1971a8787133ee41814bd3efdd501f9ee0c050f2b.json deleted file mode 100644 index ad91647c9a..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-5661cf1ad8bd5ca062e855e1971a8787133ee41814bd3efdd501f9ee0c050f2b.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "SQLite", - "query": "SELECT gateway_id_bs58 FROM registered_gateway", - "describe": { - "columns": [ - { - "name": "gateway_id_bs58", - "ordinal": 0, - "type_info": "Text" - } - ], - "parameters": { - "Right": 0 - }, - "nullable": [ - false - ] - }, - "hash": "5661cf1ad8bd5ca062e855e1971a8787133ee41814bd3efdd501f9ee0c050f2b" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-5c5d4bfabf18bc6fa56e76a9b98e38b7f6ceb8e9191a7b9201922efcf6b07966.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-5c5d4bfabf18bc6fa56e76a9b98e38b7f6ceb8e9191a7b9201922efcf6b07966.json deleted file mode 100644 index ea667b0bc6..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-5c5d4bfabf18bc6fa56e76a9b98e38b7f6ceb8e9191a7b9201922efcf6b07966.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "DELETE FROM pending_issuance WHERE deposit_id = ?", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "5c5d4bfabf18bc6fa56e76a9b98e38b7f6ceb8e9191a7b9201922efcf6b07966" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-5d3b8ad051ab6f46c702308c2fc751a5ca340ac9c6dd86da1a5e9a3e65ea589f.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-5d3b8ad051ab6f46c702308c2fc751a5ca340ac9c6dd86da1a5e9a3e65ea589f.json deleted file mode 100644 index eb6a62ba22..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-5d3b8ad051ab6f46c702308c2fc751a5ca340ac9c6dd86da1a5e9a3e65ea589f.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT serialised_signatures, serialization_revision as \"serialization_revision: u8\"\n FROM expiration_date_signatures\n WHERE expiration_date = ? AND epoch_id = ?\n ", - "describe": { - "columns": [ - { - "name": "serialised_signatures", - "ordinal": 0, - "type_info": "Blob" - }, - { - "name": "serialization_revision: u8", - "ordinal": 1, - "type_info": "Integer" - } - ], - "parameters": { - "Right": 2 - }, - "nullable": [ - false, - false - ] - }, - "hash": "5d3b8ad051ab6f46c702308c2fc751a5ca340ac9c6dd86da1a5e9a3e65ea589f" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-5e51396c534409a4b55c08170e00fd083e87cc9a18d798b2cf8d6774224aebed.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-5e51396c534409a4b55c08170e00fd083e87cc9a18d798b2cf8d6774224aebed.json deleted file mode 100644 index 35fd74e6ee..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-5e51396c534409a4b55c08170e00fd083e87cc9a18d798b2cf8d6774224aebed.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "SQLite", - "query": "SELECT name FROM sqlite_master WHERE type='table' AND name='status'", - "describe": { - "columns": [ - { - "name": "name", - "ordinal": 0, - "type_info": "Text" - } - ], - "parameters": { - "Right": 0 - }, - "nullable": [ - true - ] - }, - "hash": "5e51396c534409a4b55c08170e00fd083e87cc9a18d798b2cf8d6774224aebed" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-62f471858c831ac762a0ecf60876067dbf82d0dc376ad3f0df835b77dfcc3c37.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-62f471858c831ac762a0ecf60876067dbf82d0dc376ad3f0df835b77dfcc3c37.json deleted file mode 100644 index 632b688eeb..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-62f471858c831ac762a0ecf60876067dbf82d0dc376ad3f0df835b77dfcc3c37.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "SQLite", - "query": "SELECT flush_in_progress FROM status;", - "describe": { - "columns": [ - { - "name": "flush_in_progress", - "ordinal": 0, - "type_info": "Integer" - } - ], - "parameters": { - "Right": 0 - }, - "nullable": [ - false - ] - }, - "hash": "62f471858c831ac762a0ecf60876067dbf82d0dc376ad3f0df835b77dfcc3c37" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-648fff18c4016fb356c164f813e0d5ebd37d62612b65b8ac4c9eb5d7b67a8884.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-648fff18c4016fb356c164f813e0d5ebd37d62612b65b8ac4c9eb5d7b67a8884.json deleted file mode 100644 index 974bbd1cd1..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-648fff18c4016fb356c164f813e0d5ebd37d62612b65b8ac4c9eb5d7b67a8884.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT min_reply_surb_threshold as \"min_reply_surb_threshold: u32\", max_reply_surb_threshold as \"max_reply_surb_threshold: u32\" FROM reply_surb_storage_metadata;\n ", - "describe": { - "columns": [ - { - "name": "min_reply_surb_threshold: u32", - "ordinal": 0, - "type_info": "Integer" - }, - { - "name": "max_reply_surb_threshold: u32", - "ordinal": 1, - "type_info": "Integer" - } - ], - "parameters": { - "Right": 0 - }, - "nullable": [ - false, - false - ] - }, - "hash": "648fff18c4016fb356c164f813e0d5ebd37d62612b65b8ac4c9eb5d7b67a8884" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-67db5e91bcdc831e0d1659eda358d18a0c6792d7a4244a65243d4b22d578a1e5.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-67db5e91bcdc831e0d1659eda358d18a0c6792d7a4244a65243d4b22d578a1e5.json deleted file mode 100644 index 01a4ca077c..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-67db5e91bcdc831e0d1659eda358d18a0c6792d7a4244a65243d4b22d578a1e5.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "SQLite", - "query": "SELECT client_in_use FROM status;", - "describe": { - "columns": [ - { - "name": "client_in_use", - "ordinal": 0, - "type_info": "Integer" - } - ], - "parameters": { - "Right": 0 - }, - "nullable": [ - false - ] - }, - "hash": "67db5e91bcdc831e0d1659eda358d18a0c6792d7a4244a65243d4b22d578a1e5" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-70d8f240ad6edda6b8c7f2e800e7fca89d80869484f2f3c66cabb898f0298c62.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-70d8f240ad6edda6b8c7f2e800e7fca89d80869484f2f3c66cabb898f0298c62.json deleted file mode 100644 index 2f22ed93fa..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-70d8f240ad6edda6b8c7f2e800e7fca89d80869484f2f3c66cabb898f0298c62.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "INSERT INTO master_verification_key(epoch_id, serialised_key, serialization_revision) VALUES (?, ?, ?)", - "describe": { - "columns": [], - "parameters": { - "Right": 3 - }, - "nullable": [] - }, - "hash": "70d8f240ad6edda6b8c7f2e800e7fca89d80869484f2f3c66cabb898f0298c62" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-727598e516090da6d26e36d09062b60ccb76d6468f359891428c0bfb96ddd7ef.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-727598e516090da6d26e36d09062b60ccb76d6468f359891428c0bfb96ddd7ef.json deleted file mode 100644 index 389d07c6ea..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-727598e516090da6d26e36d09062b60ccb76d6468f359891428c0bfb96ddd7ef.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n INSERT INTO registered_gateway(gateway_id_bs58, registration_timestamp, gateway_type)\n VALUES (?, ?, ?)\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 3 - }, - "nullable": [] - }, - "hash": "727598e516090da6d26e36d09062b60ccb76d6468f359891428c0bfb96ddd7ef" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-74d77a3e15f49bde7b8b17dd638de04e5ece789fb0b0cd27ad09858fbf5c5e27.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-74d77a3e15f49bde7b8b17dd638de04e5ece789fb0b0cd27ad09858fbf5c5e27.json deleted file mode 100644 index caf7479a75..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-74d77a3e15f49bde7b8b17dd638de04e5ece789fb0b0cd27ad09858fbf5c5e27.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "UPDATE status SET flush_in_progress = ?", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "74d77a3e15f49bde7b8b17dd638de04e5ece789fb0b0cd27ad09858fbf5c5e27" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-80476cf2906eb0ecf7f66c16bc5682169b87f488b6927fa67fade6bf5abf7582.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-80476cf2906eb0ecf7f66c16bc5682169b87f488b6927fa67fade6bf5abf7582.json deleted file mode 100644 index 02b9ef7426..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-80476cf2906eb0ecf7f66c16bc5682169b87f488b6927fa67fade6bf5abf7582.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "UPDATE active_gateway SET active_gateway_id_bs58 = ?", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "80476cf2906eb0ecf7f66c16bc5682169b87f488b6927fa67fade6bf5abf7582" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-805ad4f26e0234d7f482a263e186156311713d2e9f69d39c868cd16296b56326.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-805ad4f26e0234d7f482a263e186156311713d2e9f69d39c868cd16296b56326.json deleted file mode 100644 index e1eb54bb9c..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-805ad4f26e0234d7f482a263e186156311713d2e9f69d39c868cd16296b56326.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n INSERT INTO emergency_credential\n (type, content, expiration)\n VALUES (?, ?, ?)\n ON CONFLICT(type, content) DO NOTHING;\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 3 - }, - "nullable": [] - }, - "hash": "805ad4f26e0234d7f482a263e186156311713d2e9f69d39c868cd16296b56326" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-81a12a8a419c88b1c28a5533fde4d63462e9ea0049e2edafea1dc3f8476b33e4.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-81a12a8a419c88b1c28a5533fde4d63462e9ea0049e2edafea1dc3f8476b33e4.json deleted file mode 100644 index ae81f52d0e..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-81a12a8a419c88b1c28a5533fde4d63462e9ea0049e2edafea1dc3f8476b33e4.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n INSERT INTO pending_issuance\n (deposit_id, serialization_revision, pending_ticketbook_data, expiration_date)\n VALUES (?, ?, ?, ?)\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 4 - }, - "nullable": [] - }, - "hash": "81a12a8a419c88b1c28a5533fde4d63462e9ea0049e2edafea1dc3f8476b33e4" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-84cad8b1078a4000830835e6349de3eb76fed954b7336530401db72cd008aff3.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-84cad8b1078a4000830835e6349de3eb76fed954b7336530401db72cd008aff3.json deleted file mode 100644 index 051c18bba2..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-84cad8b1078a4000830835e6349de3eb76fed954b7336530401db72cd008aff3.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "UPDATE ecash_ticketbook SET used_tickets = used_tickets + ? WHERE id = ?", - "describe": { - "columns": [], - "parameters": { - "Right": 2 - }, - "nullable": [] - }, - "hash": "84cad8b1078a4000830835e6349de3eb76fed954b7336530401db72cd008aff3" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-85d542a8cb2e1fbba6142729056b57e6ea8685e9473a3a8bd635552810493a58.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-85d542a8cb2e1fbba6142729056b57e6ea8685e9473a3a8bd635552810493a58.json deleted file mode 100644 index 12145c00d4..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-85d542a8cb2e1fbba6142729056b57e6ea8685e9473a3a8bd635552810493a58.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT reply_surb_sender_id, reply_surb, encoded_key_rotation as \"encoded_key_rotation: u8\" FROM reply_surb\n WHERE reply_surb_sender_id = ?\n ", - "describe": { - "columns": [ - { - "name": "reply_surb_sender_id", - "ordinal": 0, - "type_info": "Integer" - }, - { - "name": "reply_surb", - "ordinal": 1, - "type_info": "Blob" - }, - { - "name": "encoded_key_rotation: u8", - "ordinal": 2, - "type_info": "Integer" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - false, - false, - false - ] - }, - "hash": "85d542a8cb2e1fbba6142729056b57e6ea8685e9473a3a8bd635552810493a58" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-97d97ebb6bc8f4114fdea9ebc9f57f91a11f5057273cb70bd0e629712d17dd41.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-97d97ebb6bc8f4114fdea9ebc9f57f91a11f5057273cb70bd0e629712d17dd41.json deleted file mode 100644 index 84e8ba9f16..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-97d97ebb6bc8f4114fdea9ebc9f57f91a11f5057273cb70bd0e629712d17dd41.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n INSERT INTO partial_blinded_wallet_failure(corresponding_deposit, epoch_id, expiration_date, node_id, created, failure_message)\n VALUES (?, ?, ?, ?, ?, ?)\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 6 - }, - "nullable": [] - }, - "hash": "97d97ebb6bc8f4114fdea9ebc9f57f91a11f5057273cb70bd0e629712d17dd41" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-a5a71e480118639397f7464abb09db66d1dc1307c0873627b39cb22a245b5a8c.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-a5a71e480118639397f7464abb09db66d1dc1307c0873627b39cb22a245b5a8c.json deleted file mode 100644 index 6cd1eab066..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-a5a71e480118639397f7464abb09db66d1dc1307c0873627b39cb22a245b5a8c.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "INSERT INTO status(flush_in_progress, previous_flush, client_in_use) VALUES (0, 0, 1)", - "describe": { - "columns": [], - "parameters": { - "Right": 0 - }, - "nullable": [] - }, - "hash": "a5a71e480118639397f7464abb09db66d1dc1307c0873627b39cb22a245b5a8c" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-a5b18e66d77ff802e274623605e15dcfcffb502ba8398caefd56c481f44eb84e.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-a5b18e66d77ff802e274623605e15dcfcffb502ba8398caefd56c481f44eb84e.json deleted file mode 100644 index 5fd4e4f2e6..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-a5b18e66d77ff802e274623605e15dcfcffb502ba8398caefd56c481f44eb84e.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n INSERT OR IGNORE INTO master_verification_key(epoch_id, serialised_key, serialization_revision) VALUES (?, ?, ?);\n UPDATE master_verification_key\n SET\n serialised_key = ?,\n serialization_revision = ?\n WHERE epoch_id = ?\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 6 - }, - "nullable": [] - }, - "hash": "a5b18e66d77ff802e274623605e15dcfcffb502ba8398caefd56c481f44eb84e" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-a8b7ce0fe4755c28b96d1e503e313ab15fed747fb0cee1c9f949fb58461b3f79.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-a8b7ce0fe4755c28b96d1e503e313ab15fed747fb0cee1c9f949fb58461b3f79.json deleted file mode 100644 index 6cb8138cc5..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-a8b7ce0fe4755c28b96d1e503e313ab15fed747fb0cee1c9f949fb58461b3f79.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT epoch_id as \"epoch_id: u32\", serialised_signatures, serialization_revision as \"serialization_revision: u8\"\n FROM global_coin_index_signatures WHERE epoch_id = ?\n ", - "describe": { - "columns": [ - { - "name": "epoch_id: u32", - "ordinal": 0, - "type_info": "Integer" - }, - { - "name": "serialised_signatures", - "ordinal": 1, - "type_info": "Blob" - }, - { - "name": "serialization_revision: u8", - "ordinal": 2, - "type_info": "Integer" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - false, - false, - false - ] - }, - "hash": "a8b7ce0fe4755c28b96d1e503e313ab15fed747fb0cee1c9f949fb58461b3f79" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-ad78bf2f7ed4666b4e5f60811f04cb8bf8ebb1c26839f915780d0fc0d1939973.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-ad78bf2f7ed4666b4e5f60811f04cb8bf8ebb1c26839f915780d0fc0d1939973.json deleted file mode 100644 index 9d0d9105ef..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-ad78bf2f7ed4666b4e5f60811f04cb8bf8ebb1c26839f915780d0fc0d1939973.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n WITH oldest_queued AS (\n SELECT id\n FROM testruns\n WHERE status = $1 AND kind = $4\n ORDER BY created_utc asc\n LIMIT 1\n FOR UPDATE SKIP LOCKED\n )\n UPDATE testruns\n SET\n status = $3,\n last_assigned_utc = $2\n FROM oldest_queued\n WHERE testruns.id = oldest_queued.id\n RETURNING\n testruns.id,\n testruns.gateway_id\n ", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Int4" - }, - { - "ordinal": 1, - "name": "gateway_id", - "type_info": "Int4" - } - ], - "parameters": { - "Left": [ - "Int4", - "Int8", - "Int4", - "Int2" - ] - }, - "nullable": [ - false, - false - ] - }, - "hash": "ad78bf2f7ed4666b4e5f60811f04cb8bf8ebb1c26839f915780d0fc0d1939973" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-b0c588db5f7be90c6d4cb1b55c3a8ed4e9a64884ac5619e0abdecb04f2d13a74.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-b0c588db5f7be90c6d4cb1b55c3a8ed4e9a64884ac5619e0abdecb04f2d13a74.json deleted file mode 100644 index 677fc961c0..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-b0c588db5f7be90c6d4cb1b55c3a8ed4e9a64884ac5619e0abdecb04f2d13a74.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "\n SELECT\n id,\n gateway_identity_key\n FROM gateways\n WHERE id = $1\n LIMIT 1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "id", - "type_info": "Int4" - }, - { - "ordinal": 1, - "name": "gateway_identity_key", - "type_info": "Varchar" - } - ], - "parameters": { - "Left": [ - "Int4" - ] - }, - "nullable": [ - false, - false - ] - }, - "hash": "b0c588db5f7be90c6d4cb1b55c3a8ed4e9a64884ac5619e0abdecb04f2d13a74" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-b6ce77fcffda2ee24ba181213e04adec312abffa604fa805cc362a2c206107b4.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-b6ce77fcffda2ee24ba181213e04adec312abffa604fa805cc362a2c206107b4.json deleted file mode 100644 index 7b8a1a92fc..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-b6ce77fcffda2ee24ba181213e04adec312abffa604fa805cc362a2c206107b4.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n INSERT INTO reply_surb_storage_metadata(min_reply_surb_threshold, max_reply_surb_threshold)\n VALUES (?, ?);\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 2 - }, - "nullable": [] - }, - "hash": "b6ce77fcffda2ee24ba181213e04adec312abffa604fa805cc362a2c206107b4" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-b8257a0832d0124f0a8aaaf81dc6a811c593aea8febf1f891117e5e84213f147.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-b8257a0832d0124f0a8aaaf81dc6a811c593aea8febf1f891117e5e84213f147.json deleted file mode 100644 index 03efdc4734..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-b8257a0832d0124f0a8aaaf81dc6a811c593aea8febf1f891117e5e84213f147.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n DELETE FROM partial_blinded_wallet WHERE created < ?\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "b8257a0832d0124f0a8aaaf81dc6a811c593aea8febf1f891117e5e84213f147" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-ba96344db31b0f2155e2af53eaaeafc9b5f64061b6c9a829e2912945b6cffc82.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-ba96344db31b0f2155e2af53eaaeafc9b5f64061b6c9a829e2912945b6cffc82.json deleted file mode 100644 index 7c01c8d1fa..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-ba96344db31b0f2155e2af53eaaeafc9b5f64061b6c9a829e2912945b6cffc82.json +++ /dev/null @@ -1,32 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT epoch_id as \"epoch_id: u32\", serialised_signatures, serialization_revision as \"serialization_revision: u8\"\n FROM coin_indices_signatures WHERE epoch_id = ?\n ", - "describe": { - "columns": [ - { - "name": "epoch_id: u32", - "ordinal": 0, - "type_info": "Integer" - }, - { - "name": "serialised_signatures", - "ordinal": 1, - "type_info": "Blob" - }, - { - "name": "serialization_revision: u8", - "ordinal": 2, - "type_info": "Integer" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - false, - false, - false - ] - }, - "hash": "ba96344db31b0f2155e2af53eaaeafc9b5f64061b6c9a829e2912945b6cffc82" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-bc823c54143e2dc590b91347cd089dde284b38a3a4960afed758206d03ca1cf4.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-bc823c54143e2dc590b91347cd089dde284b38a3a4960afed758206d03ca1cf4.json deleted file mode 100644 index ec7111bc5a..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-bc823c54143e2dc590b91347cd089dde284b38a3a4960afed758206d03ca1cf4.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n UPDATE ecash_ticketbook\n SET used_tickets = used_tickets - ?\n WHERE id = ?\n AND used_tickets = ?\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 3 - }, - "nullable": [] - }, - "hash": "bc823c54143e2dc590b91347cd089dde284b38a3a4960afed758206d03ca1cf4" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-bd1973696121b6128bd75ae80fab253c071e04eb853d4b0f3b21782ea57c2f68.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-bd1973696121b6128bd75ae80fab253c071e04eb853d4b0f3b21782ea57c2f68.json deleted file mode 100644 index a2077f76ae..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-bd1973696121b6128bd75ae80fab253c071e04eb853d4b0f3b21782ea57c2f68.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n INSERT OR IGNORE INTO coin_indices_signatures(epoch_id, serialised_signatures, serialization_revision) VALUES (?, ?, ?);\n UPDATE coin_indices_signatures\n SET\n serialised_signatures = ?,\n serialization_revision = ?\n WHERE epoch_id = ?\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 6 - }, - "nullable": [] - }, - "hash": "bd1973696121b6128bd75ae80fab253c071e04eb853d4b0f3b21782ea57c2f68" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-bdaf8e8dd711ff420807659456f5ebe0222a2a0ba96f28e3a3aa58fdc4b689db.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-bdaf8e8dd711ff420807659456f5ebe0222a2a0ba96f28e3a3aa58fdc4b689db.json deleted file mode 100644 index 383ca24d4e..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-bdaf8e8dd711ff420807659456f5ebe0222a2a0ba96f28e3a3aa58fdc4b689db.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n INSERT INTO reply_surb_sender(tag, last_sent) VALUES (?, ?);\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 2 - }, - "nullable": [] - }, - "hash": "bdaf8e8dd711ff420807659456f5ebe0222a2a0ba96f28e3a3aa58fdc4b689db" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-bf249752f08c283bf5942b6ff48125c24750b523cfcad1e5e9069dbf7050e2a1.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-bf249752f08c283bf5942b6ff48125c24750b523cfcad1e5e9069dbf7050e2a1.json deleted file mode 100644 index a1ae46b595..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-bf249752f08c283bf5942b6ff48125c24750b523cfcad1e5e9069dbf7050e2a1.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "SQLite", - "query": "SELECT active_gateway_id_bs58 FROM active_gateway", - "describe": { - "columns": [ - { - "name": "active_gateway_id_bs58", - "ordinal": 0, - "type_info": "Text" - } - ], - "parameters": { - "Right": 0 - }, - "nullable": [ - true - ] - }, - "hash": "bf249752f08c283bf5942b6ff48125c24750b523cfcad1e5e9069dbf7050e2a1" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-c2b841762bdb963fff337ef5c8ec9f560017b4da6b0303ea0397d9568229e167.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-c2b841762bdb963fff337ef5c8ec9f560017b4da6b0303ea0397d9568229e167.json deleted file mode 100644 index 6b70481c75..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-c2b841762bdb963fff337ef5c8ec9f560017b4da6b0303ea0397d9568229e167.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT\n t1.node_id as \"node_id!\",\n t1.blinded_signature as \"blinded_signature!\",\n t1.epoch_id as \"epoch_id!\",\n t1.expiration_date as \"expiration_date!: Date\"\n FROM partial_blinded_wallet as t1\n JOIN ecash_deposit_usage as t2\n on t1.corresponding_deposit = t2.deposit_id\n JOIN blinded_shares as t3\n ON t2.request_uuid = t3.request_uuid\n WHERE t3.device_id = ? AND t3.credential_id = ?;\n ", - "describe": { - "columns": [ - { - "name": "node_id!", - "ordinal": 0, - "type_info": "Integer" - }, - { - "name": "blinded_signature!", - "ordinal": 1, - "type_info": "Blob" - }, - { - "name": "epoch_id!", - "ordinal": 2, - "type_info": "Integer" - }, - { - "name": "expiration_date!: Date", - "ordinal": 3, - "type_info": "Date" - } - ], - "parameters": { - "Right": 2 - }, - "nullable": [ - true, - true, - true, - true - ] - }, - "hash": "c2b841762bdb963fff337ef5c8ec9f560017b4da6b0303ea0397d9568229e167" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-cc84f8a284c9aba4494152ff4e6087af53e9504a8bb13280dde5c37b9b418370.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-cc84f8a284c9aba4494152ff4e6087af53e9504a8bb13280dde5c37b9b418370.json deleted file mode 100644 index 5e76c4c3cc..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-cc84f8a284c9aba4494152ff4e6087af53e9504a8bb13280dde5c37b9b418370.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "SELECT last_probe_result FROM gateways WHERE id = $1", - "describe": { - "columns": [ - { - "ordinal": 0, - "name": "last_probe_result", - "type_info": "Varchar" - } - ], - "parameters": { - "Left": [ - "Int4" - ] - }, - "nullable": [ - true - ] - }, - "hash": "cc84f8a284c9aba4494152ff4e6087af53e9504a8bb13280dde5c37b9b418370" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-d3510846941fa2525926b9bfbcdabd806877ce914b514d4f7cd6be318c4debe6.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-d3510846941fa2525926b9bfbcdabd806877ce914b514d4f7cd6be318c4debe6.json deleted file mode 100644 index 9de4c7f230..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-d3510846941fa2525926b9bfbcdabd806877ce914b514d4f7cd6be318c4debe6.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "INSERT INTO global_coin_index_signatures(epoch_id, serialised_signatures, serialization_revision) VALUES (?, ?, ?)", - "describe": { - "columns": [], - "parameters": { - "Right": 3 - }, - "nullable": [] - }, - "hash": "d3510846941fa2525926b9bfbcdabd806877ce914b514d4f7cd6be318c4debe6" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-daa9ffcbe13178d773e538e96971da2809ec4bd66ad49d2e3b8d67b741835475.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-daa9ffcbe13178d773e538e96971da2809ec4bd66ad49d2e3b8d67b741835475.json deleted file mode 100644 index 1faa4be465..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-daa9ffcbe13178d773e538e96971da2809ec4bd66ad49d2e3b8d67b741835475.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "DELETE FROM reply_surb_sender;", - "describe": { - "columns": [], - "parameters": { - "Right": 0 - }, - "nullable": [] - }, - "hash": "daa9ffcbe13178d773e538e96971da2809ec4bd66ad49d2e3b8d67b741835475" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-db176e98198fe594d88eb860d918f633a94d18a19b7f0f96935a62560def7d0f.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-db176e98198fe594d88eb860d918f633a94d18a19b7f0f96935a62560def7d0f.json deleted file mode 100644 index e5dd7c8413..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-db176e98198fe594d88eb860d918f633a94d18a19b7f0f96935a62560def7d0f.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n INSERT INTO partial_blinded_wallet(corresponding_deposit, epoch_id, expiration_date, node_id, created, blinded_signature)\n VALUES (?, ?, ?, ?, ?, ?)\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 6 - }, - "nullable": [] - }, - "hash": "db176e98198fe594d88eb860d918f633a94d18a19b7f0f96935a62560def7d0f" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-decdc7c0e6d279a137a80797cbabcb8900bca7157d3c66c5664386ca2c26e96a.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-decdc7c0e6d279a137a80797cbabcb8900bca7157d3c66c5664386ca2c26e96a.json new file mode 100644 index 0000000000..f28a1c1921 --- /dev/null +++ b/nym-node-status-api/nym-node-status-api/.sqlx/query-decdc7c0e6d279a137a80797cbabcb8900bca7157d3c66c5664386ca2c26e96a.json @@ -0,0 +1,23 @@ +{ + "db_name": "PostgreSQL", + "query": "SELECT COUNT(id) as \"count!: i64\" FROM testruns WHERE status = $1 AND kind = $2", + "describe": { + "columns": [ + { + "ordinal": 0, + "name": "count!: i64", + "type_info": "Int8" + } + ], + "parameters": { + "Left": [ + "Int4", + "Int2" + ] + }, + "nullable": [ + null + ] + }, + "hash": "decdc7c0e6d279a137a80797cbabcb8900bca7157d3c66c5664386ca2c26e96a" +} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-dfa035c968534926736adf0e5359cde3f6f6689a80299b5b6c1d7bd048965e6e.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-dfa035c968534926736adf0e5359cde3f6f6689a80299b5b6c1d7bd048965e6e.json deleted file mode 100644 index 2887c3bea6..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-dfa035c968534926736adf0e5359cde3f6f6689a80299b5b6c1d7bd048965e6e.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "db_name": "PostgreSQL", - "query": "UPDATE gateways SET last_probe_result = $1 WHERE id = $2", - "describe": { - "columns": [], - "parameters": { - "Left": [ - "Varchar", - "Int4" - ] - }, - "nullable": [] - }, - "hash": "dfa035c968534926736adf0e5359cde3f6f6689a80299b5b6c1d7bd048965e6e" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-e29e0c82d034626f9b369348b8e35677b9d9a1b29e4d89437134e92967fa98d1.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-e29e0c82d034626f9b369348b8e35677b9d9a1b29e4d89437134e92967fa98d1.json deleted file mode 100644 index ecab96d023..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-e29e0c82d034626f9b369348b8e35677b9d9a1b29e4d89437134e92967fa98d1.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "DELETE FROM reply_surb;", - "describe": { - "columns": [], - "parameters": { - "Right": 0 - }, - "nullable": [] - }, - "hash": "e29e0c82d034626f9b369348b8e35677b9d9a1b29e4d89437134e92967fa98d1" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-e584253e3856355899537eb8fc152f2bfed2d918b894ec0f588e38dd5e8ad726.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-e584253e3856355899537eb8fc152f2bfed2d918b894ec0f588e38dd5e8ad726.json deleted file mode 100644 index 340f83a280..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-e584253e3856355899537eb8fc152f2bfed2d918b894ec0f588e38dd5e8ad726.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n UPDATE ecash_deposit_usage\n SET ticketbook_request_error = ?\n WHERE deposit_id = ?\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 2 - }, - "nullable": [] - }, - "hash": "e584253e3856355899537eb8fc152f2bfed2d918b894ec0f588e38dd5e8ad726" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-e77ffab19b099b84470fe5611716a2e314787586a46cffd074abb67f2f4d109e.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-e77ffab19b099b84470fe5611716a2e314787586a46cffd074abb67f2f4d109e.json deleted file mode 100644 index 449bc6869f..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-e77ffab19b099b84470fe5611716a2e314787586a46cffd074abb67f2f4d109e.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT t1.node_id, t1.blinded_signature, t1.epoch_id, t1.expiration_date as \"expiration_date!: Date\"\n FROM partial_blinded_wallet as t1\n JOIN ecash_deposit_usage as t2\n on t1.corresponding_deposit = t2.deposit_id\n JOIN blinded_shares as t3\n ON t2.request_uuid = t3.request_uuid\n WHERE t3.id = ?;\n ", - "describe": { - "columns": [ - { - "name": "node_id", - "ordinal": 0, - "type_info": "Integer" - }, - { - "name": "blinded_signature", - "ordinal": 1, - "type_info": "Blob" - }, - { - "name": "epoch_id", - "ordinal": 2, - "type_info": "Integer" - }, - { - "name": "expiration_date!: Date", - "ordinal": 3, - "type_info": "Date" - } - ], - "parameters": { - "Right": 1 - }, - "nullable": [ - false, - false, - false, - false - ] - }, - "hash": "e77ffab19b099b84470fe5611716a2e314787586a46cffd074abb67f2f4d109e" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-e8717ef6523ef9bcf37a0e81570ac000904bb7fe3934786d652adc80fde78add.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-e8717ef6523ef9bcf37a0e81570ac000904bb7fe3934786d652adc80fde78add.json deleted file mode 100644 index a7d1dee6ec..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-e8717ef6523ef9bcf37a0e81570ac000904bb7fe3934786d652adc80fde78add.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "SQLite", - "query": "SELECT previous_flush AS \"previous_flush: OffsetDateTime\" FROM status", - "describe": { - "columns": [ - { - "name": "previous_flush: OffsetDateTime", - "ordinal": 0, - "type_info": "Null" - } - ], - "parameters": { - "Right": 0 - }, - "nullable": [ - false - ] - }, - "hash": "e8717ef6523ef9bcf37a0e81570ac000904bb7fe3934786d652adc80fde78add" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-eded014a5fffbd9c359f8557bcd3d41724666bf92357bf5faf42120a2aab131c.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-eded014a5fffbd9c359f8557bcd3d41724666bf92357bf5faf42120a2aab131c.json deleted file mode 100644 index 7e0d68b0db..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-eded014a5fffbd9c359f8557bcd3d41724666bf92357bf5faf42120a2aab131c.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n INSERT INTO reply_key(key_digest, reply_key, sent_at) VALUES (?, ?, ?);\n ", - "describe": { - "columns": [], - "parameters": { - "Right": 3 - }, - "nullable": [] - }, - "hash": "eded014a5fffbd9c359f8557bcd3d41724666bf92357bf5faf42120a2aab131c" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-ef60c2683211cc4ec2d3e46392518a1f62fa67dfe8f130deb876ebee11bf1602.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-ef60c2683211cc4ec2d3e46392518a1f62fa67dfe8f130deb876ebee11bf1602.json deleted file mode 100644 index c78ff30f50..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-ef60c2683211cc4ec2d3e46392518a1f62fa67dfe8f130deb876ebee11bf1602.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "db_name": "SQLite", - "query": "\n SELECT error_message\n FROM blinded_shares\n WHERE device_id = ? AND credential_id = ?;\n ", - "describe": { - "columns": [ - { - "name": "error_message", - "ordinal": 0, - "type_info": "Text" - } - ], - "parameters": { - "Right": 2 - }, - "nullable": [ - true - ] - }, - "hash": "ef60c2683211cc4ec2d3e46392518a1f62fa67dfe8f130deb876ebee11bf1602" -} diff --git a/nym-node-status-api/nym-node-status-api/.sqlx/query-f3ebe259e26c05ecdd33bd9085dbb91cd5046a8c9d4434cf085a4fa2ebf03e93.json b/nym-node-status-api/nym-node-status-api/.sqlx/query-f3ebe259e26c05ecdd33bd9085dbb91cd5046a8c9d4434cf085a4fa2ebf03e93.json deleted file mode 100644 index e2cfa29a82..0000000000 --- a/nym-node-status-api/nym-node-status-api/.sqlx/query-f3ebe259e26c05ecdd33bd9085dbb91cd5046a8c9d4434cf085a4fa2ebf03e93.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "db_name": "SQLite", - "query": "DELETE FROM registered_gateway WHERE gateway_id_bs58 = ?", - "describe": { - "columns": [], - "parameters": { - "Right": 1 - }, - "nullable": [] - }, - "hash": "f3ebe259e26c05ecdd33bd9085dbb91cd5046a8c9d4434cf085a4fa2ebf03e93" -} diff --git a/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs b/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs index 2535838e58..6c6e3e5bda 100644 --- a/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs +++ b/nym-node-status-api/nym-node-status-api/src/db/queries/testruns.rs @@ -27,15 +27,15 @@ pub(crate) async fn count_testruns_in_progress( pub(crate) async fn count_testruns_in_progress_by_kind( conn: &mut DbConnection, kind: TestRunKind, -) -> anyhow::Result> { - let count: i64 = - sqlx::query_scalar(r#"SELECT COUNT(id) FROM testruns WHERE status = $1 AND kind = $2"#) - .bind(TestRunStatus::InProgress as i64) - .bind(kind as i16) - .fetch_one(conn.as_mut()) - .await - .map_err(anyhow::Error::from)?; - Ok(Some(count)) +) -> anyhow::Result { + sqlx::query_scalar!( + r#"SELECT COUNT(id) as "count!: i64" FROM testruns WHERE status = $1 AND kind = $2"#, + TestRunStatus::InProgress as i64, + kind as i16, + ) + .fetch_one(conn.as_mut()) + .await + .map_err(anyhow::Error::from) } pub(crate) async fn get_in_progress_testrun_by_id( diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs b/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs index a9c421d395..98219a8348 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs @@ -147,8 +147,7 @@ async fn request_ports_check_testrun( TestRunKind::PortsCheck, ) .await - .map_err(HttpError::internal_with_logging)? - .unwrap_or_default(); + .map_err(HttpError::internal_with_logging)?; let max_count = state.agent_max_count(); if active_ports_check_testruns >= max_count { tracing::warn!( From 8392f7da9400cfad1cdd7af1bb509dae527f1e03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 1 Jun 2026 16:21:27 +0100 Subject: [PATCH 79/94] fix(ns-api): lock assignment + ticketbook pre-check in ports-check request request_ports_check_testrun skipped the lock_testrun_assignment() guard and has_enough_ticketbooks() pre-check that request_testrun performs, so two concurrent ports-check requests could race on ticket materials and a depleted cache left the run InProgress until stale-refresh. Mirror the probe path. --- .../src/http/api/testruns.rs | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs b/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs index 98219a8348..0e7384866c 100644 --- a/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs +++ b/nym-node-status-api/nym-node-status-api/src/http/api/testruns.rs @@ -156,6 +156,31 @@ async fn request_ports_check_testrun( return Err(HttpError::no_testruns_available()); } + // 1. guard against other agents attempting to get testruns so that we would be able to check + // for ticketbook count without cross-interaction + let _guard = state.lock_testrun_assignment().await; + + // 2. check if we have enough ticketbooks of ALL types before assigning the run + match state + .ticketbook_manager_state() + .has_enough_ticketbooks() + .await + { + Err(err) => { + return Err(HttpError::internal_with_logging(format!( + "failed to check ticketbook storage: {err}" + ))); + } + Ok(false) => { + tracing::warn!("not enough ticketbooks available, rejecting testrun assignment"); + return Err(HttpError::internal_with_logging( + "not enough ticketbooks available to assign a testrun", + )); + } + Ok(true) => (), + } + + // 3. attempt to assign the testrun itself match db::queries::testruns::assign_oldest_ports_check_testrun(&mut conn).await { Ok(res) => { let Some(assignment) = res else { From dad2d3077394e94ae92e2ee982ef03915ab9b450 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Tue, 2 Jun 2026 08:03:27 +0200 Subject: [PATCH 80/94] address comment --- nym-gateway-probe/src/common/probe_tests.rs | 26 +++++++++---------- nym-gateway-probe/src/common/wireguard.rs | 19 ++++++++------ .../src/cli/run_ports_check.rs | 25 +++++++++++++++--- 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/nym-gateway-probe/src/common/probe_tests.rs b/nym-gateway-probe/src/common/probe_tests.rs index 30b14345d0..ee403d6b07 100644 --- a/nym-gateway-probe/src/common/probe_tests.rs +++ b/nym-gateway-probe/src/common/probe_tests.rs @@ -80,8 +80,6 @@ pub async fn wg_probe( AuthenticatorVersion::V1 | AuthenticatorVersion::UNKNOWN => bail!("unknown version number"), }; - let mut wg_outcome = WgProbeResults::default(); - info!( "connecting to authenticator: {}...", auth_client.auth_recipient @@ -135,9 +133,9 @@ pub async fn wg_probe( info!("Successfully registered with the gateway"); - wg_outcome.can_register = true; - - // Run tunnel connectivity tests using shared helper + // Run tunnel connectivity tests using shared helper. + // run_tunnel_tests issues blocking CGo calls into Go, so it must run on + // tokio's dedicated blocking thread pool to avoid stalling the async runtime. let tunnel_config = WgTunnelConfig::new( registered_data.private_ips().ipv4.to_string(), registered_data.private_ips().ipv6.to_string(), @@ -145,16 +143,18 @@ pub async fn wg_probe( public_key_hex, wg_endpoint, ); + let awg_str = awg_args.unwrap_or_default(); - run_tunnel_tests( - &tunnel_config, - &netstack_args, - &awg_args.unwrap_or_default(), - port_check_only, - &mut wg_outcome, - ); + let mut tunnel_result = tokio::task::spawn_blocking(move || { + run_tunnel_tests(&tunnel_config, &netstack_args, &awg_str, port_check_only) + }) + .await + .map_err(|e| anyhow::anyhow!("netstack task panicked: {e}"))?; - Ok(wg_outcome) + // can_register is determined by the auth handshake above, not by netstack + tunnel_result.can_register = true; + + Ok(tunnel_result) } pub async fn lp_registration_probe( diff --git a/nym-gateway-probe/src/common/wireguard.rs b/nym-gateway-probe/src/common/wireguard.rs index a2cb783433..ad20d96693 100644 --- a/nym-gateway-probe/src/common/wireguard.rs +++ b/nym-gateway-probe/src/common/wireguard.rs @@ -65,24 +65,25 @@ impl WgTunnelConfig { /// - Optional download test /// - Optional exit policy port check (TCP connect through tunnel) /// -/// Results are written directly into the provided `wg_outcome` to avoid field-by-field -/// copying at call sites. +/// **Important:** this function issues blocking FFI calls into Go (CGo) and MUST be +/// called via `tokio::task::spawn_blocking` at any async call site. It returns a +/// fresh `WgProbeResults`; the caller sets `can_register` after verifying WG +/// registration succeeded. /// /// # Arguments /// * `config` - WireGuard tunnel configuration /// * `netstack_args` - Netstack test parameters (DNS, hosts to ping, timeouts, etc.) /// * `awg_args` - Amnezia WireGuard arguments (empty string for standard WG) /// * `port_check_only` - If true, skip pings/download and only run TCP port checks -/// * `wg_outcome` - Mutable reference to write test results into -// This function extracts the shared netstack testing logic from -// wg_probe() and wg_probe_lp() to eliminate code duplication. +// This function extracts the shared netstack testing logic from wg_probe() +// to eliminate code duplication across probe modes. pub fn run_tunnel_tests( config: &WgTunnelConfig, netstack_args: &NetstackArgs, awg_args: &str, port_check_only: bool, - wg_outcome: &mut WgProbeResults, -) { +) -> WgProbeResults { + let mut wg_outcome = WgProbeResults::default(); // Build the netstack request let netstack_request = NetstackRequest::new( &config.private_ipv4, @@ -143,7 +144,7 @@ pub fn run_tunnel_tests( // in port-check-only mode, skip IPv6 tests — port checks ran through IPv4 above if port_check_only { info!("Port-check-only mode: skipping IPv6 tunnel tests"); - return; + return wg_outcome; } // Perform IPv6 ping test @@ -182,4 +183,6 @@ pub fn run_tunnel_tests( error!("Internal error (IPv6): {error}") } } + + wg_outcome } diff --git a/nym-node-status-api/nym-node-status-agent/src/cli/run_ports_check.rs b/nym-node-status-api/nym-node-status-agent/src/cli/run_ports_check.rs index c4bc641b6f..aa370ceb15 100644 --- a/nym-node-status-api/nym-node-status-agent/src/cli/run_ports_check.rs +++ b/nym-node-status-api/nym-node-status-agent/src/cli/run_ports_check.rs @@ -3,6 +3,8 @@ use crate::cli::common; use crate::log_capture::LogCapture; use nym_gateway_probe::RunPortsConfig; use tracing::instrument; +// Hard deadline for a single port-scan job. +const PORT_SCAN_HARD_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(5400); pub(crate) async fn run_ports_check( servers: &[ServerConfig], @@ -55,15 +57,30 @@ pub(crate) async fn run_ports_check( let credentials_args = common::credential_args_from(testrun.ticket_materials); log_capture.start(); - let port_check_result_res = nym_gateway_probe::Probe::run_ports_for_agent( + let probe_future = nym_gateway_probe::Probe::run_ports_for_agent( gateway_identity_pubkey, network, &run_ports_config, credentials_args, - ) - .await; + ); + let port_check_result_res = tokio::time::timeout(PORT_SCAN_HARD_TIMEOUT, probe_future).await; let probe_log = log_capture.stop_and_drain(); - let port_check_result = port_check_result_res?; + + let port_check_result = match port_check_result_res { + Ok(inner) => inner?, + Err(_elapsed) => { + tracing::error!( + gateway = %gateway_identity_key, + testrun = testrun_id, + timeout_secs = PORT_SCAN_HARD_TIMEOUT.as_secs(), + "Port scan exceeded hard timeout; aborting to free resources" + ); + return Err(anyhow::anyhow!( + "port scan timed out after {}s", + PORT_SCAN_HARD_TIMEOUT.as_secs() + )); + } + }; submit_ports_check_results_to_servers( servers, From 298b55280e6abf66713c06b5f0447ef9a245d8c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 2 Jun 2026 13:56:58 +0100 Subject: [PATCH 81/94] fix gateways being penalised for no stress testing (#6843) --- Cargo.lock | 4 +- nym-api/Cargo.toml | 3 +- nym-api/nym-api-requests/Cargo.toml | 4 + .../src/models/described/v2.rs | 2 +- .../src/node_status_api/cache/refresher.rs | 155 +++++++++++++++--- 5 files changed, 140 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 836ce887e6..ec3b88bb98 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5819,7 +5819,7 @@ dependencies = [ [[package]] name = "nym-api" -version = "1.1.80-fixed-floats" +version = "1.1.80-no-gw-penalty" dependencies = [ "anyhow", "async-trait", @@ -7571,7 +7571,7 @@ dependencies = [ [[package]] name = "nym-network-monitor-agent" -version = "1.0.3" +version = "1.0.4" dependencies = [ "anyhow", "arrayref", diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index 2316433f77..df3e0f1da4 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-api" -version = "1.1.80-fixed-floats" +version = "1.1.80-no-gw-penalty" authors.workspace = true edition = "2021" license = "GPL-3.0" @@ -123,6 +123,7 @@ sqlx = { workspace = true, features = [ ] } [dev-dependencies] +nym-api-requests = { workspace = true, features = ["mock-fixtures"] } axum-test = { workspace = true } reqwest = { workspace = true, features = ["json", "query"] } tempfile = { workspace = true } diff --git a/nym-api/nym-api-requests/Cargo.toml b/nym-api/nym-api-requests/Cargo.toml index 28d18fc632..3b5749c239 100644 --- a/nym-api/nym-api-requests/Cargo.toml +++ b/nym-api/nym-api-requests/Cargo.toml @@ -54,6 +54,8 @@ nym-network-defaults = { workspace = true } nym-ticketbooks-merkle = { workspace = true } nym-ecash-signer-check-types = { workspace = true } nym-kkt-ciphersuite = { workspace = true } +# only pulled in by the `mock-fixtures` feature; also a dev-dependency for this crate's own tests +nym-test-utils = { workspace = true, optional = true } [dev-dependencies] nym-crypto = { workspace = true, features = ["rand"] } @@ -62,3 +64,5 @@ nym-test-utils = { workspace = true } [features] default = [] generate-ts = ["ts-rs", "nym-mixnet-contract-common/generate-ts"] +# exposes deterministic data mocks (e.g. `mock_nym_node_description`) to downstream crates' tests +mock-fixtures = ["dep:nym-test-utils", "nym-crypto/rand"] diff --git a/nym-api/nym-api-requests/src/models/described/v2.rs b/nym-api/nym-api-requests/src/models/described/v2.rs index 431e5572a1..992373786b 100644 --- a/nym-api/nym-api-requests/src/models/described/v2.rs +++ b/nym-api/nym-api-requests/src/models/described/v2.rs @@ -267,7 +267,7 @@ impl From for NymNodeDescriptionV2 { } } -#[cfg(test)] +#[cfg(any(test, feature = "mock-fixtures"))] pub fn mock_nym_node_description(seed: u64) -> NymNodeDescriptionV2 { use nym_node_requests::api::v1::lewes_protocol::models::{LPHashFunction, LPKEM}; use nym_test_utils::helpers::{u64_seeded_rng, RngCore}; diff --git a/nym-api/src/node_status_api/cache/refresher.rs b/nym-api/src/node_status_api/cache/refresher.rs index 8b56a9ffb1..c677cf946a 100644 --- a/nym-api/src/node_status_api/cache/refresher.rs +++ b/nym-api/src/node_status_api/cache/refresher.rs @@ -16,7 +16,7 @@ use crate::{ node_status_api::cache::NodeStatusCacheError, support::caching::CacheNotification, }; use ::time::OffsetDateTime; -use nym_api_requests::models::{DetailedNodePerformanceV2, NodeAnnotationV2}; +use nym_api_requests::models::{DetailedNodePerformanceV2, NodeAnnotationV2, NymNodeDescriptionV2}; use nym_mixnet_contract_common::{NodeId, NymNodeDetails}; use nym_task::ShutdownToken; use nym_topology::CachedEpochRewardedSet; @@ -218,15 +218,23 @@ impl NodeStatusCacheRefresher { let use_stress_testing_scores = self.config.use_stress_testing_data; let threshold = self.config.minimum_available_stress_testing_results; - let available_ratio = - stress_testing_scores.available_count() as f32 / nym_nodes.len() as f32; - // Guard against an orchestrator outage silently slashing every node's performance: - // if too few nodes have a reachable stress-test sample for the configured window we + // Only mixnodes are currently stress-tested: the orchestrator selects test targets by + // self-described mixnode capability (see `NodeType::from_roles`), so the availability ratio + // must be taken over stress-test-eligible nodes only. Counting gateways in the denominator + // would let the network's mixnode:gateway composition - rather than orchestrator health - + // decide whether the data is used at all. + let eligible_count = nym_nodes + .iter() + .filter(|n| stress_test_eligible(described_nodes.get_node(&n.node_id()))) + .count(); + let available_ratio = + stress_availability_ratio(stress_testing_scores.available_count(), eligible_count); + + // Guard against an orchestrator outage silently slashing every eligible node's performance: + // if too few mixnodes have a reachable stress-test sample for the configured window we // assume the orchestrator (rather than the network) is at fault and fall back to the - // routing × config score alone. The threshold is a network-wide ratio, not per-node — - // once it is met, individual nodes without data still score 0 in the weighted formula - // by design, on the assumption that the orchestrator tried to test them and failed. + // routing × config score alone. let include_stress_testing = use_stress_testing_scores && available_ratio >= threshold; if use_stress_testing_scores && !include_stress_testing { @@ -236,30 +244,28 @@ impl NodeStatusCacheRefresher { ); } - // stress testing - let sw = self.config.stress_testing_score_weight; - - // not stress testing - let nsw = 1.0 - sw; - for nym_node in nym_nodes { let node_id = nym_node.node_id(); + let described = described_nodes.get_node(&node_id); let routing_score = routing_scores.get_or_log(node_id); - let config_score = - calculate_config_score(config_score_data, described_nodes.get_node(&node_id)); + let config_score = calculate_config_score(config_score_data, described); let stress_testing_score = stress_testing_scores.get_or_log(node_id); - let performance = if include_stress_testing { - // use weighted arithmetic mean (we don't want a single 0 to cause the whole thing to be 0) - sw * stress_testing_score.score + nsw * routing_score.score * config_score.score - } else { - routing_score.score * config_score.score - }; + // a node only takes the stress-testing component if it is actually stress-tested (i.e. + // it is a mixnode); gateways have no stress data and must not be penalised for it. + let apply_stress = include_stress_testing && stress_test_eligible(described); + let performance = node_performance( + apply_stress, + self.config.stress_testing_score_weight, + stress_testing_score.score, + routing_score.score, + config_score.score, + ); annotations.insert( - nym_node.node_id(), + node_id, NodeAnnotationV2 { - current_role: rewarded_set.role(nym_node.node_id()).map(|r| r.into()), + current_role: rewarded_set.role(node_id).map(|r| r.into()), detailed_performance: DetailedNodePerformanceV2::new( performance, routing_score, @@ -333,3 +339,104 @@ impl NodeStatusCacheRefresher { Ok(()) } } + +/// Whether `node` is currently in scope for stress testing, and therefore expected to have a +/// stress-test sample. This is the single source of truth for stress-test scope and must stay in +/// sync with the orchestrator's test-target selection (`NodeType::from_roles`, which keys off the +/// self-described role capabilities). +/// +/// A node that is *not* in scope has no stress data by design - not because it failed a test - so +/// it must never have the stress component folded into its performance score (otherwise gateways +/// would be silently penalised for a test they were never subjected to). Conversely, an in-scope +/// node with no sample legitimately scores 0 for stress, guarded network-wide by the availability +/// threshold against orchestrator outages. +/// +/// Today only mixnodes are stress-tested; when gateway stress testing lands, widen this predicate +/// (e.g. to also accept `entry`/`exit` capable nodes) and nothing else in the scoring path needs +/// to change. +fn stress_test_eligible(described: Option<&NymNodeDescriptionV2>) -> bool { + described + .map(|n| n.description.declared_role.mixnode) + .unwrap_or(false) +} + +/// Fraction of stress-test-eligible nodes for which the orchestrator produced a reachable sample. +/// The denominator is the eligible count, not the total node count, so the network's role +/// composition cannot drag the ratio below the orchestrator-health threshold. Returns 0 when there +/// are no eligible nodes (nothing to base a judgement on, so the data is treated as unavailable). +fn stress_availability_ratio(available_count: usize, eligible_count: usize) -> f32 { + if eligible_count == 0 { + 0.0 + } else { + available_count as f32 / eligible_count as f32 + } +} + +/// Overall node performance. When the stress-testing component applies, it is a weighted arithmetic +/// mean of the stress score and routing × config (so a single 0 doesn't zero the whole thing); +/// otherwise it is simply routing × config. +fn node_performance( + apply_stress: bool, + stress_weight: f64, + stress_score: f64, + routing_score: f64, + config_score: f64, +) -> f64 { + if apply_stress { + stress_weight * stress_score + (1.0 - stress_weight) * routing_score * config_score + } else { + routing_score * config_score + } +} + +#[cfg(test)] +mod tests { + use super::*; + use nym_api_requests::models::mock_nym_node_description; + + #[test] + fn ineligible_nodes_are_not_penalised_for_missing_stress_data() { + let sw = 0.2; + let stress = 0.0; // no stress sample -> unreachable() score + let routing = 0.9; + let config = 1.0; + + // an out-of-scope node (e.g. a gateway) is scored on routing × config alone - no haircut + let out_of_scope = node_performance(false, sw, stress, routing, config); + assert_eq!(out_of_scope, routing * config); + + // an in-scope node (a mixnode) with no/zero stress sample does take the weighted hit + let in_scope = node_performance(true, sw, stress, routing, config); + assert_eq!(in_scope, sw * stress + (1.0 - sw) * routing * config); + assert!( + in_scope < out_of_scope, + "in-scope node with a 0 stress score should score strictly lower than an out-of-scope one" + ); + } + + #[test] + fn availability_ratio_uses_eligible_denominator() { + // every eligible node reachable -> full ratio, no matter how many ineligible nodes + // (gateways) also exist in the network. + assert_eq!(stress_availability_ratio(5, 5), 1.0); + // half the eligible nodes reachable + assert_eq!(stress_availability_ratio(3, 6), 0.5); + // no eligible nodes -> 0, never a division by zero / NaN + assert_eq!(stress_availability_ratio(0, 0), 0.0); + } + + #[test] + fn only_in_scope_node_types_are_stress_test_eligible() { + let mut mixnode = mock_nym_node_description(1); + mixnode.description.declared_role.mixnode = true; + assert!(stress_test_eligible(Some(&mixnode))); + + // a gateway-only node (not a mixnode) is currently out of scope + let mut gateway = mock_nym_node_description(2); + gateway.description.declared_role.mixnode = false; + assert!(!stress_test_eligible(Some(&gateway))); + + // a node with no self-described data is out of scope (the orchestrator can't classify it) + assert!(!stress_test_eligible(None)); + } +} From de9fa9712959178471194442c236ba824657a3fe Mon Sep 17 00:00:00 2001 From: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com> Date: Tue, 2 Jun 2026 14:57:07 +0100 Subject: [PATCH 82/94] Add workflow_dispatch trigger to CI workflow --- .github/workflows/ci-nym-wallet-frontend.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci-nym-wallet-frontend.yml b/.github/workflows/ci-nym-wallet-frontend.yml index 3bc746959a..098c1f6f12 100644 --- a/.github/workflows/ci-nym-wallet-frontend.yml +++ b/.github/workflows/ci-nym-wallet-frontend.yml @@ -1,6 +1,7 @@ name: ci-nym-wallet-frontend on: + workflow_dispatch: pull_request: paths: - 'nym-wallet/**' From 7324bb23b69bdd494390a48eaba59132bc2bb073 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 2 Jun 2026 16:28:27 +0100 Subject: [PATCH 83/94] chore: LP registration adjustments (#6845) * remove mixnet fallback for LP registration * change LP registration timeouts and introduce exchange timeout * remove fallback client construction and disable mixnet via LP registration --- nym-registration-client/src/builder/mod.rs | 1 - nym-registration-client/src/clients/lp.rs | 37 +++++--------- .../src/lp_client/config.rs | 51 ++++++++++--------- 3 files changed, 41 insertions(+), 48 deletions(-) diff --git a/nym-registration-client/src/builder/mod.rs b/nym-registration-client/src/builder/mod.rs index e81d0977bc..af64450a24 100644 --- a/nym-registration-client/src/builder/mod.rs +++ b/nym-registration-client/src/builder/mod.rs @@ -143,7 +143,6 @@ impl RegistrationClientBuilder { config, bandwidth_controller, cancel_token: self.config.cancel_token.clone(), - fallback_client_builder: Some(self), }) } } diff --git a/nym-registration-client/src/clients/lp.rs b/nym-registration-client/src/clients/lp.rs index b924a8456f..6216614765 100644 --- a/nym-registration-client/src/clients/lp.rs +++ b/nym-registration-client/src/clients/lp.rs @@ -18,13 +18,12 @@ use rand09::{CryptoRng, RngCore, SeedableRng}; use std::sync::Arc; use tokio::net::TcpStream; use tokio_util::sync::CancellationToken; +use tracing::warn; pub struct LpBasedRegistrationClient { pub(crate) config: RegistrationClientConfig, pub(crate) bandwidth_controller: Box, pub(crate) cancel_token: CancellationToken, - // While we allow a fallback, we need to be able to build it - pub(crate) fallback_client_builder: Option, } impl LpBasedRegistrationClient { @@ -162,15 +161,11 @@ impl LpBasedRegistrationClient { self.register_wg_with_rng(&mut rng).await } - pub(crate) async fn register(mut self) -> Result { - let fallback = self.fallback_client_builder.take(); + async fn register_inner(mut self) -> Result { match &self.config.mode { RegistrationMode::Mixnet => { - if let Some(fallback) = fallback { - register_with_fallback(fallback).await - } else { - Err(RegistrationClientError::UnsupportedMode) - } + // mixnet registration is not supported for LP + Err(RegistrationClientError::UnsupportedMode) } RegistrationMode::Wireguard => { let lp_registration_result = self @@ -182,15 +177,9 @@ impl LpBasedRegistrationClient { // Everything went fine Some(Ok(res)) => Ok(res), - // LP reg failed, try fallback if we have one Some(Err(e)) => { tracing::error!("LP registration failed : {e}"); - if let Some(fallback) = fallback { - tracing::info!("Registering with fallback"); - register_with_fallback(fallback).await - } else { - Err(e) - } + Err(e) } // Cancelled registration @@ -199,12 +188,14 @@ impl LpBasedRegistrationClient { } } } -} -async fn register_with_fallback( - client_builder: RegistrationClientBuilder, -) -> Result { - // This is forcefully building a mixnet based client - let fallback_client = client_builder.build_mixnet().await?; - fallback_client.register().await + pub(crate) async fn register(mut self) -> Result { + let timeout = self.config.lp_registration_config.exchange_timeout; + tokio::time::timeout(timeout, self.register_inner()) + .await + .unwrap_or_else(|timeout| { + warn!("timed out while attempting to complete LP registration"); + Err(RegistrationClientError::Timeout(timeout)) + }) + } } diff --git a/nym-registration-client/src/lp_client/config.rs b/nym-registration-client/src/lp_client/config.rs index 506fc559a2..9684e99118 100644 --- a/nym-registration-client/src/lp_client/config.rs +++ b/nym-registration-client/src/lp_client/config.rs @@ -28,40 +28,43 @@ use std::time::Duration; /// - Optimize for latency over throughput (small messages) #[derive(Clone, Copy, Debug, PartialEq, Eq)] pub struct LpRegistrationConfig { - /// TCP connection timeout (nym-102). + /// TCP connection timeout. /// /// Maximum time to wait for TCP connection establishment. - /// Default: 10 seconds. + /// Default: 5 seconds. pub connect_timeout: Duration, - /// Noise protocol handshake timeout (nym-102). + /// KKT/PSQ protocol handshake timeout. /// - /// Maximum time to wait for Noise handshake completion (all round-trips). - /// Default: 15 seconds. + /// Maximum time to wait for KKT/PSQ handshake completion with the entry (all round-trips). + /// Default: 8 seconds. pub handshake_timeout: Duration, - /// Registration request/response timeout (nym-102). + /// Registration request/response timeout. /// /// Maximum time to wait for registration request send + response receive. /// Includes credential verification on gateway side. - /// Default: 30 seconds. + /// Default: 8 seconds. pub registration_timeout: Duration, + /// Maximum time for the whole exchange (handshake + registration). + /// Default: 20 seconds. + pub exchange_timeout: Duration, + /// Forward packet send/receive timeout. /// - /// Maximum time to wait for forward packet send + response receive via entry gateway. - /// Covers the entire round-trip through entry to exit gateway and back. - /// Default: 30 seconds. + /// Maximum time to wait for forward packet to get sent via entry gateway. + /// Default: 3 seconds. pub forward_timeout: Duration, - /// Enable TCP_NODELAY (disable Nagle's algorithm) (nym-104). + /// Enable TCP_NODELAY (disable Nagle's algorithm). /// /// When true, disables Nagle's algorithm for lower latency. /// Recommended for registration messages which are small and latency-sensitive. /// Default: true. pub tcp_nodelay: bool, - /// TCP keepalive duration (nym-104). + /// TCP keepalive duration. /// /// When Some, enables TCP keepalive with specified interval. /// Since LP is registration-only with short-lived connections, keepalive is not needed. @@ -72,15 +75,14 @@ pub struct LpRegistrationConfig { impl Default for LpRegistrationConfig { fn default() -> Self { Self { - // nym-102: Sane timeout defaults for real network conditions - connect_timeout: Duration::from_secs(10), - handshake_timeout: Duration::from_secs(15), - registration_timeout: Duration::from_secs(30), - forward_timeout: Duration::from_secs(30), + connect_timeout: Duration::from_secs(5), + handshake_timeout: Duration::from_secs(8), + registration_timeout: Duration::from_secs(8), + exchange_timeout: Duration::from_secs(20), + forward_timeout: Duration::from_secs(3), - // nym-104: Optimized for registration-only protocol - tcp_nodelay: true, // Lower latency for small messages - tcp_keepalive: None, // Not needed for ephemeral connections + tcp_nodelay: true, + tcp_keepalive: None, } } } @@ -93,10 +95,11 @@ mod tests { fn test_default_config() { let config = LpRegistrationConfig::default(); - assert_eq!(config.connect_timeout, Duration::from_secs(10)); - assert_eq!(config.handshake_timeout, Duration::from_secs(15)); - assert_eq!(config.registration_timeout, Duration::from_secs(30)); - assert_eq!(config.forward_timeout, Duration::from_secs(30)); + assert_eq!(config.connect_timeout, Duration::from_secs(5)); + assert_eq!(config.handshake_timeout, Duration::from_secs(8)); + assert_eq!(config.registration_timeout, Duration::from_secs(8)); + assert_eq!(config.forward_timeout, Duration::from_secs(3)); + assert_eq!(config.exchange_timeout, Duration::from_secs(20)); assert!(config.tcp_nodelay); assert_eq!(config.tcp_keepalive, None); } From 4ad00dba3da667818aa36e904c1325eb50195471 Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Wed, 3 Jun 2026 17:31:15 +0000 Subject: [PATCH 84/94] Smolmix RTT storm fix (#6846) * RT fix for TLS * Condense comment * Coderabbit nits * Clippy fix? * Clippy 2:electric boogaloo * Logging aggregate for very noisy tcp stuff --- Cargo.lock | 25 +++- wasm/smolmix/Cargo.toml | 9 +- wasm/smolmix/src/device.rs | 261 +++++++++++++++++++++++++++++++++++-- wasm/smolmix/src/fetch.rs | 61 ++++++++- wasm/smolmix/src/ipr.rs | 22 +++- wasm/smolmix/src/stream.rs | 3 +- wasm/smolmix/src/tunnel.rs | 2 +- 7 files changed, 357 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ec3b88bb98..398f693f82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11571,7 +11571,7 @@ dependencies = [ "nym-sdk", "reqwest 0.13.1", "rustls 0.23.37", - "smoltcp", + "smoltcp 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "thiserror 2.0.18", "tokio", "tokio-rustls 0.26.2", @@ -11609,7 +11609,7 @@ dependencies = [ "semver 1.0.27", "serde", "serde-wasm-bindgen 0.6.5", - "smoltcp", + "smoltcp 0.12.0 (git+https://github.com/nymtech/smoltcp?rev=62ac5b8b3287d4773694f19a3b55e4c004354a0b)", "thiserror 2.0.18", "tokio", "tsify", @@ -11636,6 +11636,21 @@ dependencies = [ "managed", ] +[[package]] +name = "smoltcp" +version = "0.12.0" +source = "git+https://github.com/nymtech/smoltcp?rev=62ac5b8b3287d4773694f19a3b55e4c004354a0b#62ac5b8b3287d4773694f19a3b55e4c004354a0b" +dependencies = [ + "bitflags 1.3.2", + "byteorder", + "cfg-if", + "defmt 0.3.100", + "heapless", + "libc", + "log", + "managed", +] + [[package]] name = "snafu" version = "0.7.5" @@ -12642,7 +12657,7 @@ dependencies = [ "futures", "parking_lot", "pin-project-lite", - "smoltcp", + "smoltcp 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", "tokio", "tokio-util", ] @@ -15000,9 +15015,9 @@ dependencies = [ [[package]] name = "zeroize_derive" -version = "1.4.2" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +checksum = "85a5b4158499876c763cb03bc4e49185d3cccbabb15b33c627f7884f43db852e" dependencies = [ "proc-macro2", "quote", diff --git a/wasm/smolmix/Cargo.toml b/wasm/smolmix/Cargo.toml index 4042f32fe0..1c2897ee01 100644 --- a/wasm/smolmix/Cargo.toml +++ b/wasm/smolmix/Cargo.toml @@ -49,8 +49,13 @@ async-tungstenite = { workspace = true, features = ["handshake"], optional = tru # WASM utils (panic hook, console_log) nym-wasm-utils = { workspace = true } -# Tunnel: smoltcp stack + Nym mixnet client + IPR protocol -smoltcp = { workspace = true, features = ["std", "medium-ip", "proto-ipv4", "socket-tcp", "socket-udp", "async"] } +# RTT-patched smoltcp fork, scoped to THIS crate only(not a workspace-wide `[patch.crates-io]`), +# so native `smolmix/core` builds and publishes against vanilla crates.io smoltcp untouched for +# the moment - needs further investigation whether that also suffers the same problem (probably does) +# but makes crates publication more complicated. +# +# This commit is tag `v0.12.0-nym-rtt`. +smoltcp = { git = "https://github.com/nymtech/smoltcp", rev = "62ac5b8b3287d4773694f19a3b55e4c004354a0b", features = ["std", "medium-ip", "proto-ipv4", "socket-tcp", "socket-udp", "async"] } nym-wasm-client-core = { workspace = true } nym-ip-packet-requests = { workspace = true } # LP wire types (frame, header, codec) diff --git a/wasm/smolmix/src/device.rs b/wasm/smolmix/src/device.rs index ea8dfc80ca..3966374cfc 100644 --- a/wasm/smolmix/src/device.rs +++ b/wasm/smolmix/src/device.rs @@ -8,10 +8,12 @@ //! `Device` impl instead. The bridge pushes incoming IP packets into `rx_queue` //! and pops outgoing packets from `tx_queue`. -use std::collections::VecDeque; +use std::collections::{BTreeSet, VecDeque}; use smoltcp::phy::{Device, DeviceCapabilities, Medium, RxToken, TxToken}; use smoltcp::time::Instant; +use smoltcp::wire::{IpAddress, IpProtocol, Ipv4Address, Ipv4Packet, TcpPacket}; +use std::collections::BTreeMap; /// smoltcp device backed by in-memory packet queues. /// @@ -22,19 +24,18 @@ pub struct WasmDevice { rx_queue: VecDeque>, tx_queue: VecDeque>, capabilities: DeviceCapabilities, + rx_stats: RxStats, + tx_stats: TxStats, } impl WasmDevice { pub fn new() -> Self { let mut capabilities = DeviceCapabilities::default(); capabilities.medium = Medium::Ip; - // Sized so one IP packet fits in one sphinx packet payload (no - // chunking-layer fragmentation). Budget in bytes from the 2048 B - // sphinx plaintext: − 344 (SURB-ack) − 32 (x25519 ephemeral key, - // Repliable msgs) − 7 (frag header) − 1 (padding) − 53 (LP+IPR - // framing + AEAD) ≈ 1611. 1600 leaves ~11 B headroom for IPR - // overhead variability. - capabilities.max_transmission_unit = 1600; + // Match the standard Ethernet MTU (1500). 1500 keeps a + // packet (plus its LP/IPR framing and SURB headers) within a single + // Sphinx packet's payload, avoiding LP-layer fragmentation. + capabilities.max_transmission_unit = 1500; // Native smolmix also uses Some(1) in the device, but tokio-smoltcp // compensates with a burst loop that calls Interface::poll() up to 100 // times per reactor iteration (each processing 1 packet). Our WASM @@ -46,11 +47,26 @@ impl WasmDevice { rx_queue: VecDeque::new(), tx_queue: VecDeque::new(), capabilities, + rx_stats: RxStats::default(), + tx_stats: TxStats::default(), } } /// Push an incoming IP packet (from the mixnet) into the receive queue. pub fn push_rx(&mut self, packet: Vec) { + // Aggregate diagnostic (replaces the former per-packet log). Only folds + // when runtime debug logging is on, so the production path stays a bare + // enqueue: one atomic load, no parsing. The window is flushed on a + // connection lifecycle flag or when it fills; see `RxStats`. + if nym_wasm_utils::debug_logging_enabled() { + if let Some(pkt) = parse_inbound_tcp(&packet) { + let lifecycle = pkt.syn || pkt.rst || pkt.fin; + self.rx_stats.record(&pkt); + if lifecycle || self.rx_stats.segments >= RX_STATS_WINDOW { + self.rx_stats.flush(); + } + } + } self.rx_queue.push_back(packet); } @@ -70,6 +86,7 @@ impl Device for WasmDevice { WasmRxToken { buffer: packet }, WasmTxToken { queue: &mut self.tx_queue, + stats: &mut self.tx_stats, }, )) } @@ -77,6 +94,7 @@ impl Device for WasmDevice { fn transmit(&mut self, _timestamp: Instant) -> Option> { Some(WasmTxToken { queue: &mut self.tx_queue, + stats: &mut self.tx_stats, }) } @@ -99,9 +117,223 @@ impl RxToken for WasmRxToken { } } +/// Flush the rx aggregate after this many segments even when no lifecycle flag +/// has appeared, so a long bulk transfer still reports periodically rather than +/// only at teardown. +const RX_STATS_WINDOW: u32 = 256; + +/// Fields aggregated from one inbound TCP packet. +struct InboundTcp { + /// Our local ephemeral port: which client socket this belongs to. It is the + /// discriminator for "one connection or several?". Each tcp_connect (and + /// each connect retry) uses a fresh port, so a window touching several + /// dports means several of our own connections, not one flow. + dport: u16, + payload_len: usize, + cksum_ok: bool, + syn: bool, + rst: bool, + fin: bool, +} + +/// Parse the fields we aggregate from one inbound packet. IPv4/TCP only: +/// IPv6 and non-TCP return `None` and are simply not counted. A bad checksum +/// is recorded (`cksum_ok = false`), not dropped, since seeing it is the point. +fn parse_inbound_tcp(buf: &[u8]) -> Option { + let ip = Ipv4Packet::new_checked(buf).ok()?; + let ip_ok = ip.verify_checksum(); + if ip.next_header() != IpProtocol::Tcp { + return None; + } + let src = IpAddress::Ipv4(ip.src_addr()); + let dst = IpAddress::Ipv4(ip.dst_addr()); + let tcp = TcpPacket::new_checked(ip.payload()).ok()?; + Some(InboundTcp { + dport: tcp.dst_port(), + payload_len: tcp.payload().len(), + cksum_ok: ip_ok && tcp.verify_checksum(&src, &dst), + syn: tcp.syn(), + rst: tcp.rst(), + fin: tcp.fin(), + }) +} + +/// Rolling aggregate of inbound TCP packets, flushed to the debug log on a +/// connection lifecycle flag (SYN/RST/FIN) or when [`RX_STATS_WINDOW`] segments +/// accumulate. Replaces the former per-packet firehose: it keeps the same +/// investigative signal (segment and byte counts, checksum failures, how many +/// distinct local ports, ie how many connections, and the handshake/teardown +/// flags) without a line per packet. +/// +/// Only touched when runtime debug logging is on. A *silent* stall (the flight +/// just stops, no RST) won't flush, since the device has no timer; the RST that +/// usually ends a stalled flight over the mixnet does trigger a flush. +#[derive(Default)] +struct RxStats { + segments: u32, + bytes: usize, + bad_cksum: u32, + syn: u32, + rst: u32, + fin: u32, + dports: BTreeSet, +} + +impl RxStats { + /// Fold one parsed inbound packet into the current window. + fn record(&mut self, pkt: &InboundTcp) { + self.segments += 1; + self.bytes += pkt.payload_len; + if !pkt.cksum_ok { + self.bad_cksum += 1; + } + self.syn += u32::from(pkt.syn); + self.rst += u32::from(pkt.rst); + self.fin += u32::from(pkt.fin); + self.dports.insert(pkt.dport); + } + + /// Emit the window summary and reset. No-op on an empty window. + /// + /// How to read a line: + /// seg inbound TCP segments in this window + /// payload bytes total TCP payload across those segments (no headers); a + /// climbing total with no completion means a stalled flight + /// bad cksum segments that failed IP or TCP checksum; should stay 0. + /// Nonzero means corruption on the path, not just loss + /// dports distinct local ports touched, ie how many of our own + /// connections this window spans (retries open fresh ports) + /// S / R / F SYN / RST / FIN counts. R>0 is the handshake-era failure + /// signature (connection reset); a clean flow is S then F, + /// R=0 throughout + fn flush(&mut self) { + if self.segments == 0 { + return; + } + crate::util::debug_log!( + "[device] rx window: {} seg, {} payload bytes, {} bad cksum, {} dports, S={} R={} F={}", + self.segments, + self.bytes, + self.bad_cksum, + self.dports.len(), + self.syn, + self.rst, + self.fin, + ); + *self = RxStats::default(); + } +} + +/// Flush the tx aggregate after this many segments, mirroring the rx window. +const TX_STATS_WINDOW: u32 = 256; + +/// Fields aggregated from one outbound TCP packet. +struct OutboundTcp { + /// Our local ephemeral port: smoltcp keeps it stable for a connection's + /// life, so it identifies the flow. This is the field an IPR egress capture + /// is correlated against (the exit's NAT may remap it on the way out). + src_port: u16, + /// (destination address, destination port). + dst: (Ipv4Address, u16), + payload_len: usize, + syn: bool, + rst: bool, + fin: bool, +} + +/// Parse the fields we aggregate from one outbound packet. IPv4/TCP only. +/// No checksum check: smoltcp fills those in after we observe the packet. +fn parse_outbound_tcp(buf: &[u8]) -> Option { + let ip = Ipv4Packet::new_checked(buf).ok()?; + if ip.next_header() != IpProtocol::Tcp { + return None; + } + let tcp = TcpPacket::new_checked(ip.payload()).ok()?; + Some(OutboundTcp { + src_port: tcp.src_port(), + dst: (ip.dst_addr(), tcp.dst_port()), + payload_len: tcp.payload().len(), + syn: tcp.syn(), + rst: tcp.rst(), + fin: tcp.fin(), + }) +} + +/// Rolling aggregate of outbound TCP packets, flushed on a connection lifecycle +/// flag (SYN/RST/FIN) or when [`TX_STATS_WINDOW`] segments accumulate. Replaces +/// the former per-packet tx log. +/// +/// The outbound diagnostic is about source-port stability: each flow's +/// `src_port -> dst` mapping is the data an egress capture is correlated +/// against. smoltcp keeps that port stable for us, so this stays quiet, listing +/// the flows seen each window. `port_reuses` counts a `src_port` re-pointing at +/// a different dst within one window: usually a legitimate fast close-and-reopen +/// reusing the port, but a sustained nonzero count is worth a look (the port +/// allocator handing out a still-live port). +/// +/// Only touched when runtime debug logging is on. +#[derive(Default)] +struct TxStats { + segments: u32, + bytes: usize, + syn: u32, + rst: u32, + fin: u32, + /// `src_port -> dst` seen this window: the correlation mapping, and the + /// basis for the reuse check. + flows: BTreeMap, + port_reuses: u32, +} + +impl TxStats { + /// Fold one parsed outbound packet into the current window. + fn record(&mut self, pkt: &OutboundTcp) { + self.segments += 1; + self.bytes += pkt.payload_len; + self.syn += u32::from(pkt.syn); + self.rst += u32::from(pkt.rst); + self.fin += u32::from(pkt.fin); + if let Some(prev) = self.flows.insert(pkt.src_port, pkt.dst) { + if prev != pkt.dst { + self.port_reuses += 1; + } + } + } + + /// Emit the window summary and reset. No-op on an empty window. + /// + /// seg / bytes outbound segments and total payload this window + /// flows `src_port->dst` per flow, for egress-capture correlation + /// port-reuse a src_port re-pointed at a new dst mid-window (see above) + /// S / R / F SYN / RST / FIN counts we sent + fn flush(&mut self) { + if self.segments == 0 { + return; + } + let flows: Vec = self + .flows + .iter() + .map(|(sport, (ip, dport))| format!("{sport}->{ip}:{dport}")) + .collect(); + crate::util::debug_log!( + "[device] tx window: {} seg, {} payload bytes, {} flows [{}], {} port-reuse, S={} R={} F={}", + self.segments, + self.bytes, + self.flows.len(), + flows.join(" "), + self.port_reuses, + self.syn, + self.rst, + self.fin, + ); + *self = TxStats::default(); + } +} + /// Transmit token: captures one packet from smoltcp into the tx queue. pub struct WasmTxToken<'a> { queue: &'a mut VecDeque>, + stats: &'a mut TxStats, } impl<'a> TxToken for WasmTxToken<'a> { @@ -111,6 +343,17 @@ impl<'a> TxToken for WasmTxToken<'a> { { let mut buffer = vec![0u8; len]; let result = f(&mut buffer); + // Aggregate diagnostic (see TxStats). Only folds when runtime debug + // logging is on, so the production path stays a bare enqueue. + if nym_wasm_utils::debug_logging_enabled() { + if let Some(pkt) = parse_outbound_tcp(&buffer) { + let lifecycle = pkt.syn || pkt.rst || pkt.fin; + self.stats.record(&pkt); + if lifecycle || self.stats.segments >= TX_STATS_WINDOW { + self.stats.flush(); + } + } + } self.queue.push_back(buffer); result } @@ -157,6 +400,6 @@ mod tests { let dev = WasmDevice::new(); let caps = dev.capabilities(); assert_eq!(caps.medium, Medium::Ip); - assert_eq!(caps.max_transmission_unit, 1980); + assert_eq!(caps.max_transmission_unit, 1500); } } diff --git a/wasm/smolmix/src/fetch.rs b/wasm/smolmix/src/fetch.rs index 05f93d4e85..58771f5c32 100644 --- a/wasm/smolmix/src/fetch.rs +++ b/wasm/smolmix/src/fetch.rs @@ -5,6 +5,7 @@ //! plus (under the `fetch` feature) the HTTP orchestration + JS `RequestInit` shim. use std::net::SocketAddr; +use std::time::Duration; use crate::dns; use crate::error::FetchError; @@ -191,16 +192,74 @@ pub async fn fetch( ))) } -/// Create a fresh connection: DNS resolve → TCP connect → optional TLS. +/// Connect + TLS-handshake attempts on fresh sockets before giving up. +const CONNECT_ATTEMPTS: u32 = 3; + +/// Base delay between connect retries, multiplied by the attempt number for a +/// mild linear backoff (50ms before the 2nd attempt, 100ms before the 3rd). +/// +/// Kept small on purpose: the transient failure here is a lost handshake +/// segment, not congestion that needs time to clear. +/// The backoff only avoids re-launching a fresh socket the instant +/// the previous one reset. +const CONNECT_BACKOFF_MS: u64 = 50; + +/// Create a fresh connection: DNS resolve → TCP connect → optional TLS, with +/// retry on transient failure. +/// +/// The mixnet reorders and drops packets, so a single multi-segment handshake +/// flight (the server's certificate) can stall on a lost segment and the +/// connection resets with a handshake EOF. A fresh socket (new ephemeral port, +/// new sphinx packets) usually dodges the specific loss. Connect + handshake +/// send no application data, so retrying them carries no idempotency risk for +/// any HTTP method. pub(crate) async fn new_connection( tunnel: &WasmTunnel, host: &str, port: u16, is_https: bool, ) -> Result { + // Resolve once: a DNS failure is not transient the way a lost handshake + // segment is, and re-resolving per attempt would just repeat the lookup. let ip = dns::resolve(tunnel, host).await?; let addr = SocketAddr::new(ip, port); + let mut last_err = None; + for attempt in 1..=CONNECT_ATTEMPTS { + match connect_once(tunnel, addr, host, is_https).await { + Ok(conn) => return Ok(conn), + // Only connect / handshake I/O errors are transient over the + // mixnet. A bad TLS server name or other non-I/O error fails + // identically on retry, so propagate it immediately. + Err(e @ FetchError::Io(_)) => { + if attempt < CONNECT_ATTEMPTS { + crate::util::debug_log!( + "[fetch] connect attempt {attempt}/{CONNECT_ATTEMPTS} to '{host}' failed ({e}), retrying with fresh connection" + ); + wasmtimer::tokio::sleep(Duration::from_millis( + attempt as u64 * CONNECT_BACKOFF_MS, + )) + .await; + } else { + crate::util::debug_error!( + "[fetch] connect to '{host}' failed after {CONNECT_ATTEMPTS} attempts: {e}" + ); + } + last_err = Some(e); + } + Err(e) => return Err(e), + } + } + Err(last_err.expect("loop body runs at least once")) +} + +/// One connect + optional TLS handshake on a fresh socket. +async fn connect_once( + tunnel: &WasmTunnel, + addr: SocketAddr, + host: &str, + is_https: bool, +) -> Result { crate::util::debug_log!("[fetch] TCP connecting to {addr}..."); let tcp = tunnel.tcp_connect(addr).await.map_err(FetchError::Io)?; crate::util::debug_log!("[fetch] TCP connected to {addr}"); diff --git a/wasm/smolmix/src/ipr.rs b/wasm/smolmix/src/ipr.rs index 255e4fd6e8..b5fc242203 100644 --- a/wasm/smolmix/src/ipr.rs +++ b/wasm/smolmix/src/ipr.rs @@ -31,13 +31,21 @@ use nym_wasm_client_core::nym_task::connections::TransmissionLane; use crate::error::FetchError; -/// Reply-SURB counts for Open and Data frames. Defaults: `open=10, data=0`. +/// Reply-SURB counts for the Open and Data frames. Defaults: `open=10, data=2`. /// -/// The Open frame seeds the IPR's SURB bucket; from there, the reply -/// controller's pre-emptive topup refills it when the bucket dips below -/// the `min_surbs_threshold` (10, per nym-client-core), so per-data-packet -/// SURBs are unnecessary in steady state. Override `data` upwards for -/// workloads that burst faster than topup round-trip can keep up. +/// `open` seeds the IPR's SURB bucket on the connect handshake. `data` is the +/// number of reply-SURBs attached to every packet we send (including TCP ACKs); +/// it funds the IPR's return traffic for the connection. +/// +/// `data` is deliberately small, and raising it has a cost that is easy to +/// miss. A reply-SURB is not a flag on the packet: it is a full layer-encrypted +/// return header that travels as forward payload, and each Sphinx packet has a fixed +/// payload budget. +/// +/// Return capacity for downloads does not need a large `data`: every ACK we send +/// during a transfer carries `data` SURBs, so capacity scales with the ACK rate +/// (which scales with the download rate), and the reply controller's pre-emptive +/// topup refills the bucket besides. #[derive(Clone, Copy)] pub struct SurbsConfig { pub open: u32, @@ -46,7 +54,7 @@ pub struct SurbsConfig { impl Default for SurbsConfig { fn default() -> Self { - Self { open: 10, data: 0 } + Self { open: 10, data: 2 } } } diff --git a/wasm/smolmix/src/stream.rs b/wasm/smolmix/src/stream.rs index 43dcb088bf..9affc25997 100644 --- a/wasm/smolmix/src/stream.rs +++ b/wasm/smolmix/src/stream.rs @@ -81,9 +81,10 @@ impl AsyncRead for WasmTcpStream { Poll::Ready(Ok(0)) } else { crate::util::debug_log!( - "[tcp:read] Pending (state={:?}, buf={})", + "[tcp:read] Pending (state={:?}, buf={}, recv_queue={})", socket.state(), buf.len(), + socket.recv_queue(), ); // smoltcp wakes this waker on any state change affecting `recv`, // including FIN/CloseWait transitions that produce EOF. diff --git a/wasm/smolmix/src/tunnel.rs b/wasm/smolmix/src/tunnel.rs index ad2be993f2..7dc4b3c760 100644 --- a/wasm/smolmix/src/tunnel.rs +++ b/wasm/smolmix/src/tunnel.rs @@ -56,7 +56,7 @@ pub struct TunnelOpts { /// Disable cover traffic loop (default: `false`). pub disable_cover_traffic: bool, /// Reply-SURB counts for the LP Open frame and each Data frame the - /// bridge sends. See [`ipr::SurbsConfig`]. Defaults to open=5, data=2. + /// bridge sends. See [`ipr::SurbsConfig`] for the values and rationale. pub surbs: ipr::SurbsConfig, /// Primary DNS resolver. `None` falls back to [`dns::DEFAULT_PRIMARY_DNS`]. pub primary_dns: Option, From c7780d2d3487643414759f659cfac62b3faa1065 Mon Sep 17 00:00:00 2001 From: import this <97586125+serinko@users.noreply.github.com> Date: Thu, 4 Jun 2026 12:59:50 +0200 Subject: [PATCH 85/94] Feat: Node orchestration UX improvements (#6848) * improve nginx playbook * improve configure-vm script * improve initialise-vm script * expand config naming options * provide args docs * syntax fix * address rabbitai comments * cleanup ansible * document ansible changes * fix review comments * update scraed data * fix max comment review --- ansible/nym-node/playbooks/group_vars/all.yml | 70 +++---- ansible/nym-node/playbooks/inventory/all | 51 ++--- ansible/nym-node/roles/nginx/tasks/main.yml | 16 +- ansible/nym-node/roles/nym/defaults/main.yml | 4 +- .../circulating-supply.json | 4 +- .../api-scraping-outputs/nodes-count.json | 6 +- .../nyx-outputs/circulating-supply.md | 2 +- .../nyx-outputs/epoch-reward-budget.md | 2 +- .../nyx-outputs/stake-saturation.md | 2 +- .../nyx-outputs/staking-target.md | 2 +- .../nyx-outputs/staking_supply.md | 2 +- .../nyx-outputs/token-table.md | 6 +- .../api-scraping-outputs/reward-params.json | 8 +- .../outputs/api-scraping-outputs/time-now.md | 2 +- .../preliminary-steps/vps-setup/advanced.mdx | 62 +++++- .../pages/operators/orchestration/ansible.mdx | 59 +++--- scripts/kvm-setup/configure-vm.sh | 165 ++++++++++------ scripts/kvm-setup/initialise-vm.sh | 181 ++++++++++-------- 18 files changed, 376 insertions(+), 268 deletions(-) diff --git a/ansible/nym-node/playbooks/group_vars/all.yml b/ansible/nym-node/playbooks/group_vars/all.yml index aed33fcce3..ea526db82a 100644 --- a/ansible/nym-node/playbooks/group_vars/all.yml +++ b/ansible/nym-node/playbooks/group_vars/all.yml @@ -1,21 +1,4 @@ --- -ansible_ssh_private_key_file: ~/.ssh/ - -cli_url: "https://github.com/nymtech/nym/releases/download/nym-binaries-{{ nym_version }}/nym-cli" -tunnel_manager_url: "https://github.com/nymtech/nym/raw/refs/heads/develop/scripts/nym-node-setup/network-tunnel-manager.sh" -quic_bridge_deployment_url: "https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/nym-node-setup/quic_bridge_deployment.sh" - -############################################################################### -## GLOBAL VARS -## These values will be used globally unless overwritten per node in inventory/all -############################################################################### - -ansible_user: root # used for ssh, like `ssh root@nym-exit.ch-1.mynodes.net` -email: "" # used in certbot, description.toml and landing page -website: "" # it is used in the description.toml -description: "" # or define per node in inventory/all -# operator_name: "" # used in landing page if provided - ############################################################################### ## GLOBAL VARS ## These values will be used globally unless overwritten per node in inventory/all @@ -23,16 +6,41 @@ description: "" # or define per node in inventory/all ## Per node changes in inventory/all will overwrite these global vars ############################################################################### -# moniker: "" # if not setup here not in inventory/all it get's derived from the hostname -# mode: # entry-gateway/exit-gateway/mixnode -# wireguard_enabled: # true/false -hostname: "" # this is a fallback, keep it and setup hostname per node in inventory/all +## MANDATORY - uncomment & define + +## --SSH-- +#ansible_user: root # used for ssh, like `ssh root@nym-exit.ch-1.mynodes.net` +# ansible_ssh_private_key_file: ~/.ssh/ + +## --Operator info-- +# email: "" # used in certbot, description.toml and landing page +# website: "" # it is used in the description.toml +# description: "" # or define per node in inventory/all +# moniker: "" + +## --Node defaults (can override per node in inventory/all)-- +# accept_operator_terms: true # controls --accept-operator-terms-and-conditions, read: https://nym.com/docs/operators/nodes/nym-node/setup#terms--conditions +# mode: exit-gateway # entry-gateway/exit-gateway/mixnode +# wireguard_enabled: true # true/false +hostname: "" # keep this fallback, keep it and setup hostname per node in inventory/all + +## OPTIONAL - uncomment & define + +# operator_name: "" # used in landing page if provided +# nym_version: "nym-binaries-v2026.7-tola" # to use particular version instead of Latest, provide in such form: + +## alternative SSH key var setting, instead of a hardcoded path +## useful if the playbook is shared in a repo by more admins with each having own local key +# ansible_ssh_private_key_file: "{{ lookup('env', '') }}" ############################################################################### -## GLOBAL PACKAGES +## GLOBAL PACKAGES & URLs ## These will be installed during deployment ############################################################################### +nym_cli_url: "https://github.com/nymtech/nym/releases/download/{{ nym_version }}/nym-cli" +tunnel_manager_url: "https://github.com/nymtech/nym/raw/refs/heads/develop/scripts/nym-node-setup/network-tunnel-manager.sh" +quic_bridge_deployment_url: "https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/nym-node-setup/quic_bridge_deployment.sh" packages: - tmux @@ -50,24 +58,6 @@ packages: - ufw -############################################################################### -## OPTIONAL OVERRIDES -## All values below already have defaults in the playbook/roles -## Uncomment only if you want to override them -############################################################################### - -############################################################################### -## SYSTEM MAINTENANCE PLAYBOOK KNOBS -############################################################################### - -# To use particular version instead of Latest, provide in such form: -# nym_version: "nym-binaries-v2026.7-tola" - -## NOTE: -## if you want to pin Nym to a specific version instead of using the -## latest release from GitHub in /tasks/main.yml then -## uncomment the line above and set the tag - ############################################################################### ## SYSTEM MAINTENANCE PLAYBOOK KNOBS ############################################################################### diff --git a/ansible/nym-node/playbooks/inventory/all b/ansible/nym-node/playbooks/inventory/all index d87beccbc0..e99dde3cf8 100644 --- a/ansible/nym-node/playbooks/inventory/all +++ b/ansible/nym-node/playbooks/inventory/all @@ -1,34 +1,39 @@ [nym_nodes] -# READ CONFIGURATION GUIDE: -# https://nym.com//docs/operators/orchestration/ansible#configuration +## READ CONFIGURATION GUIDE: +## https://nym.com/docs/operators/orchestration/ansible#configuration -# VARIABLES INFO -# required vars to set values per node: -# `ansible_host`, `hostname`, `location` +############## +## TEMPLATE ## +############## +## uncomment and exchange the with your real values for each node without the <> brackets -# global vars can be set in the group_vars/all.yml, for example: -# `email`, `ansible_user`, `moniker`, `description`, `mode`, `wireguard_enabled` -# othersise they must be set per node! - -############ -# TEMPLATE # -############ # node1 ansible_host= ansible_user= hostname= location= email= mode= wireguard_enabled= moniker= description= -# remove all comments and exchange the with your real values for each node -# without <> brackets +#################### +## VARIABLES INFO ## +#################### -# PRIORITY ORDER -# anything setup globaly can be overwritten in this file per node -# if provided here, it takes priority over the global setting +## --REQUIRED VARS-- +## required per node: +## ansible_host, hostname, location -# EXAMPLES -# exit + wireguard gateway: +## --OPTIONAL VARS-- +## can be set in the group_vars/all.yml or per node here: +## email, ansible_user, moniker, description, mode, wireguard_enabled + +## --PRIORITY ORDER-- +## anything setup globaly can be overwritten in this file per node +## if provided here, it takes priority over the global setting + +## --EXAMPLES-- +## exit + wireguard gateway: # node2 ansible_host=11.12.13.14 hostname=nym-exit.ch-1.mydomain.net mode=exit-gateway location=CH wireguard_enabled=true -# entry gateway, no wireguard: +## entry gateway, no wireguard: # node3 ansible_host=12.13.14.15 hostname=nym-entry.ch-2.mydomain.net mode=entry-gateway location=CH wireguard_enabled=false -# NOTE: -# all examples above don't have defined user, email nor description as we use the definition from group_vars/main.yml without an attempt of overwriting it -# all examples above don't have moniker defined as there is a function in /templates/description.toml.j2 deriving it from the hostname +## mixnode (comment out tunnel+quic roles in deploy.yml for these) +# mix-de-1 ansible_host=13.14.15.16 hostname=nym-mix.de-1.example.net location=DE mode=mixnode wireguard_enabled=false + +## NOTE: +## all examples above don't have defined user, email nor description as we use global vars from playbooks/group_vars/all.yml diff --git a/ansible/nym-node/roles/nginx/tasks/main.yml b/ansible/nym-node/roles/nginx/tasks/main.yml index 320431718e..58e293fb98 100644 --- a/ansible/nym-node/roles/nginx/tasks/main.yml +++ b/ansible/nym-node/roles/nginx/tasks/main.yml @@ -89,7 +89,6 @@ loop: - "/etc/nginx/sites-enabled/{{ hostname }}-ssl" - "/etc/nginx/sites-enabled/nym-wss-config" - when: not le_cert.stat.exists notify: Restart nginx - name: Ensure nginx is enabled and running (needed for ACME http-01) @@ -111,18 +110,13 @@ - name: Obtain/renew certificate command: cmd: >- - {% if le_cert.stat.exists %} - certbot certonly --webroot - -w /var/www/{{ hostname }} + certbot certonly --nginx --non-interactive --agree-tos --keep-until-expiring -m {{ email }} -d {{ hostname }} - {% else %} - certbot --nginx - --non-interactive --agree-tos --redirect - -m {{ email }} -d {{ hostname }} - {% endif %} register: certbot_result - failed_when: false + failed_when: false + + # re-check cert after certbot attempt - name: Re-check whether certificate exists after certbot @@ -170,4 +164,4 @@ changed_when: false - name: Flush handlers (apply restart after successful tests) - meta: flush_handlers + meta: flush_handlers \ No newline at end of file diff --git a/ansible/nym-node/roles/nym/defaults/main.yml b/ansible/nym-node/roles/nym/defaults/main.yml index e36f6fc140..fcd1eeb4c0 100644 --- a/ansible/nym-node/roles/nym/defaults/main.yml +++ b/ansible/nym-node/roles/nym/defaults/main.yml @@ -10,7 +10,7 @@ mixnet_bind_address: "0.0.0.0:1789" # maps to --mixnet-bind-address landing_page_assets_base_dir: "/var/www" # Flag toggles -# accept_operator_terms: true # controls --accept-operator-terms-and-conditions +accept_operator_terms: false # override in group_vars or inventory nym_write_flag: true # controls -w nym_init_only_flag: true # controls --init-only wss_port: 9001 # controlls --announce-wss-port @@ -18,7 +18,7 @@ wss_port: 9001 # controlls --announce-wss-port # Optional: extra flags if you want to append more later nym_extra_flags: "" -# CLI URL (nym_version can be set elsewhere / via GitHub API) +# CLI URL nym_cli_url: "https://github.com/nymtech/nym/releases/download/{{ nym_version }}/nym-cli" # UFW diff --git a/documentation/docs/components/outputs/api-scraping-outputs/circulating-supply.json b/documentation/docs/components/outputs/api-scraping-outputs/circulating-supply.json index 4be1f2b19c..b6de748826 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/circulating-supply.json +++ b/documentation/docs/components/outputs/api-scraping-outputs/circulating-supply.json @@ -5,7 +5,7 @@ }, "mixmining_reserve": { "denom": "unym", - "amount": "166613455567357" + "amount": "164623226345363" }, "vesting_tokens": { "denom": "unym", @@ -13,6 +13,6 @@ }, "circulating_supply": { "denom": "unym", - "amount": "833386544432643" + "amount": "835376773654637" } } diff --git a/documentation/docs/components/outputs/api-scraping-outputs/nodes-count.json b/documentation/docs/components/outputs/api-scraping-outputs/nodes-count.json index 98ee11e305..9b221d2a82 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/nodes-count.json +++ b/documentation/docs/components/outputs/api-scraping-outputs/nodes-count.json @@ -1,6 +1,6 @@ { "nodes": 682, - "locations": 78, - "mixnodes": 242, - "exit_gateways": 432 + "locations": 76, + "mixnodes": 239, + "exit_gateways": 435 } diff --git a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/circulating-supply.md b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/circulating-supply.md index 6f6c094083..42252b8a5e 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/circulating-supply.md +++ b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/circulating-supply.md @@ -1 +1 @@ -833_386_544 +835_376_773 diff --git a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/epoch-reward-budget.md b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/epoch-reward-budget.md index b72f034b0c..519f583689 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/epoch-reward-budget.md +++ b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/epoch-reward-budget.md @@ -1 +1 @@ -4_628 +4_572 diff --git a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/stake-saturation.md b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/stake-saturation.md index 02acf9bc71..435fbd506f 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/stake-saturation.md +++ b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/stake-saturation.md @@ -1 +1 @@ -254_977 +255_586 diff --git a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/staking-target.md b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/staking-target.md index c5a32267aa..1b5fa7f459 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/staking-target.md +++ b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/staking-target.md @@ -1 +1 @@ -61_194_673 +61_340_814 diff --git a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/staking_supply.md b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/staking_supply.md index aa81fc5ba9..1016ec7ef9 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/staking_supply.md +++ b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/staking_supply.md @@ -1 +1 @@ -61_194_672 +61_340_813 diff --git a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/token-table.md b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/token-table.md index fdf11e42a6..eafb403911 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/token-table.md +++ b/documentation/docs/components/outputs/api-scraping-outputs/nyx-outputs/token-table.md @@ -1,7 +1,7 @@ | **Item** | **Description** | **Amount in NYM** | |:-------------------|:------------------------------------------------------|--------------------:| | Total Supply | Maximum amount of NYM token in existence | 1_000_000_000 | -| Mixmining Reserve | Tokens releasing for operators rewards | 166_613_455 | +| Mixmining Reserve | Tokens releasing for operators rewards | 164_623_226 | | Vesting Tokens | Tokens locked outside of circulation for future claim | 0 | -| Circulating Supply | Amount of unlocked tokens | 833_386_544 | -| Stake Saturation | Optimal size of node self-bond + delegation | 254_977 | +| Circulating Supply | Amount of unlocked tokens | 835_376_773 | +| Stake Saturation | Optimal size of node self-bond + delegation | 255_586 | diff --git a/documentation/docs/components/outputs/api-scraping-outputs/reward-params.json b/documentation/docs/components/outputs/api-scraping-outputs/reward-params.json index 9e7ce9741e..40f531502a 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/reward-params.json +++ b/documentation/docs/components/outputs/api-scraping-outputs/reward-params.json @@ -1,10 +1,10 @@ { "interval": { - "reward_pool": "166613455567357.391753168447944888", - "staking_supply": "61194672938727.325886595653401629", + "reward_pool": "164623226345363.285226429762152046", + "staking_supply": "61340813321050.793375219026221616", "staking_supply_scale_factor": "0.07342892", - "epoch_reward_budget": "4628151543.537705326476901331", - "stake_saturation_point": "254977803911.363857860815222506", + "epoch_reward_budget": "4572867398.482313478511937837", + "stake_saturation_point": "255586722171.04497239674594259", "sybil_resistance": "0.3", "active_set_work_factor": "10", "interval_pool_emission": "0.02" diff --git a/documentation/docs/components/outputs/api-scraping-outputs/time-now.md b/documentation/docs/components/outputs/api-scraping-outputs/time-now.md index bab5e7c55f..de9ba936fc 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/time-now.md +++ b/documentation/docs/components/outputs/api-scraping-outputs/time-now.md @@ -1 +1 @@ -Wednesday, May 27th 2026, 11:42:58 UTC +Thursday, June 4th 2026, 09:20:29 UTC diff --git a/documentation/docs/pages/operators/nodes/preliminary-steps/vps-setup/advanced.mdx b/documentation/docs/pages/operators/nodes/preliminary-steps/vps-setup/advanced.mdx index 9863df4d92..84d3031552 100644 --- a/documentation/docs/pages/operators/nodes/preliminary-steps/vps-setup/advanced.mdx +++ b/documentation/docs/pages/operators/nodes/preliminary-steps/vps-setup/advanced.mdx @@ -291,17 +291,26 @@ KVM network is gone. ##### 3. Setup KVM public bridge for new VMs -To create a KVM network bridge on Ubuntu, edit a config file located in `/etc/netplan/` either called `00-installer.yaml` or `00-installer-config.yaml` and add the bridge details. +To create a KVM network bridge on Ubuntu, edit a config file located in `/etc/netplan/` often called `50-cloud-init.yaml` or `00-installer.yaml` or `00-installer-config.yaml` and add the bridge details. -- Before you edit the file, make a backup to stay on the save side: +- Before you edit the file, make a backup to stay on the save side, the file should be named something like this: ```bash -cp /etc/netplan/00-installer-config.yaml /etc/netplan/00-installer-config.yaml.bak +cp /etc/netplan/50-cloud-init.yaml /etc/netplan/50-cloud-init.yaml.bak # or cp /etc/netplan/00-installer.yaml /etc/netplan/00-installer.yaml.bak +# or +cp /etc/netplan/00-installer-config.yaml /etc/netplan/00-installer-config.yaml.bak ``` -- Open `00-installer-config.yaml` or `00-installer.yaml.`config in a text editor: +- If none of these files existed, simply check the name of your config by this command and apply the same backup logic: +```sh +ls /etc/netplan/ +``` + +- Open the original config in a text editor: ```bash +nano /etc/netplan/50-cloud-init.yaml +# or nano /etc/netplan/00-installer.yaml # or nano /etc/netplan/00-installer-config.yaml @@ -380,12 +389,13 @@ netplan --debug apply ```bash apt install yamllint -y +yamllint /etc/netplan/50-cloud-init.yaml +# or yamllint /etc/netplan/00-installer.yaml # or yamllint /etc/netplan/00-installer-config.yaml - - ``` + - Apply correct permissions: ```bash chmod 600 /etc/netplan/00-installer.yaml @@ -410,9 +420,12 @@ systemctl enable --now systemd-networkd - If things went wrong, you can always revert from the backed up file: ```bash +cp /etc/netplan/50-cloud-init.yaml.bak /etc/netplan/50-cloud-init.yaml +# or cp /etc/netplan/00-installer-config.yaml.bak /etc/netplan/00-installer-config.yaml # or cp /etc/netplan/00-installer.yaml.bak /etc/netplan/00-installer.yaml + # and netplan apply ``` @@ -535,19 +548,50 @@ Using the scripts is a two-step process. First, initialisation part is done from ##### 1. Initialise VM from the host machine - Log in to your host as `root` -- Run this block and follow the prompts carefully: +- Get the script: ```bash wget "https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/kvm-setup/initialise-vm.sh" chmod +x ./initialise-vm.sh -./initialise-vm.sh ``` +- Run this block and follow the prompts carefully or provide with arguments: +```sh +# interactive CLI +./initialise-vm.sh + +# arguments - see --help menu +./initialise-vm.sh --help + +# example +# ./initialise-vm.sh --name ubuntu1 --password topsecretrootpassword --cpus 4 --ram 8192 --size 60 +``` + + ##### 2. Configure VM from within -- After logging into your VM run this block and follow the prompts carefully: +- After logging into your VM, using `login: root` and `password: `, get second script to configure the VM from within: ```bash wget "https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/kvm-setup/configure-vm.sh" chmod +x ./configure-vm.sh +``` + +- Likely your connection won't work and therefore you need to create the script manually, open a text editor: +```sh +nano configure-vm.sh +``` + +- Paste there [this content](https://raw.githubusercontent.com/nymtech/nym/refs/heads/develop/scripts/kvm-setup/configure-vm.sh) +- Save and exit +- Run this block and follow the prompts carefully, or provide with arguments: + +```sh +# interactive CLI ./configure-vm.sh + +# arguments - see --help menu +./configure-vm.sh --help + +# example +# ./configure-vm.sh --interface enp1s0 --ipv4 192.168.1.100 --gateway4 192.168.1.1 --ipv6 2001:db8::1 --gateway6 2001:db8::fffe ``` diff --git a/documentation/docs/pages/operators/orchestration/ansible.mdx b/documentation/docs/pages/operators/orchestration/ansible.mdx index 8d6016bbd7..791b8cf186 100644 --- a/documentation/docs/pages/operators/orchestration/ansible.mdx +++ b/documentation/docs/pages/operators/orchestration/ansible.mdx @@ -3,6 +3,7 @@ import { Tabs } from 'nextra/components'; import { Steps } from 'nextra/components'; import { RunTabs } from 'components/operators/nodes/node-run-command-tabs'; import { VarInfo } from 'components/variable-info.tsx'; +import { AccordionTemplate } from 'components/accordion-template.tsx'; # Orchestrating Nym Nodes with Ansible @@ -95,14 +96,13 @@ Before starting Ansible, ensure that your `A` and `AAAA` records are pointed to ###### 1. Configure global variables: - Open `playbooks/group_vars/all.yml` -- Setup any variables which you want to have propagated on all your nodes globally +- Define all values under the section labeled as `## MANDATORY - uncomment & define` - these values will be propagated on all your nodes globally +- Optionally define values of your choice under the section `## OPTIONAL - uncomment & define` - Note that in the next step we will be setting up a node inventory, where each of the variable can be configured per node, taking priority over the global ones. -- Setup a correct path for your SSH kety to `ansible_ssh_private_key_file:` -- Use these variables or comment them out with `#`: - - `ansible_user` - - `email` - - `website` - - `description` +- Setup a correct path for your SSH kety to `ansible_ssh_private_key_file:`, alternatively export your SSH key as an env var and use this: +```sh +ansible_ssh_private_key_file: "{{ lookup('env', '') }}" +``` - Keep `hostname=""` as a fallback for nodes without a hostname ###### 2. Create node inventory: @@ -111,11 +111,11 @@ Before starting Ansible, ensure that your `A` and `AAAA` records are pointed to ```sh node1 ansible_host= ansible_user= hostname= location= email= mode= wireguard_enabled= moniker= description= ``` -- These are mandatory values specific for each node - must be defined in the inventory: +- Mandatory values specific for each node - must be defined in the inventory: - `ansible_host`: IPv4 host address - `hostname`: node domain, otherwise fallbacks to `""` for nodes without domain - `location`: node server location -- These are mandatory values which can be setup per node or in `group_vars/all` globally: +- Mandatory values which can be setup per node or in `group_vars/all` globally: - `ansible_user` - `email` - `website` @@ -123,6 +123,7 @@ node1 ansible_host= ansible_user= hostname= loca - `description` - `mode` - `wireguard_enabled` + - `accept_operator_terms` - **Make sure to read [Nym Operators Terms & Conditions](/operators/nodes/nym-node/setup#terms--conditions) first!** ###### 3. Test your setup Run this command to check if everything is configured correctly in your inventory: @@ -131,17 +132,12 @@ cd playbooks ansible-inventory --graph ``` -###### 4. Configure `nym-node run` command arguments +###### 4. Optional: remove some of `nym-node run` command arguments +These variables are read by the main task for `nym-node` installation: `roles/nym/tasks/config.yaml` + Open `roles/nym/defaults/main.yml` and have a look on the variables used: -- If you agree with [Terms and conditions](/operators/nodes/nym-node/setup#terms--conditions) uncomment the line: `accept_operator_terms: true` without which your node can never take part in Nym Network. -- The rest is up to your configuration but generally these flags workflows - -These variables are read by the main task for `nym-node` installation: `roles/nym/tasks/config.yaml` -- Open that yaml and have a look on the flags -- In case of not needing some of the, delete them (ie when running `--mode mixnode` you can delete everything from `--hostname` to `--announce-wss-port`) - -###### 5. Configure `deploy.yml` playbook +###### 5. Optional: Configure `deploy.yml` playbook Open `playbooks/deploy.yml` and comment out `tunnel` and `quic` roles in case of running your playbook for nodes in a mode `mixnode`. Save all the files and test with: @@ -159,11 +155,13 @@ This chapter describes fundamental commands for using Ansible playbooks in relat ### Logic + + The main logic of the playbook flow when running with a basic command and playbook like this: ```sh ansible-playbook .yml ``` - + ###### 1. Read inventory Ansible parses `inventory/all` and performs the playbook on all entries in it, unless specified otherwise @@ -175,7 +173,8 @@ Ansible parses `group_vars/all.yml` and asigns global variables to all inventory ###### 3. Follow roles in the playbook Ansible reads the roles defined in `.yml` passed with the command and executes the tasks defined under each role - + + ### Usage @@ -237,6 +236,17 @@ cd playbooks ansible-playbook system-maintenance.yml ``` +###### 5. Mitigate kernel CVE + +This playbook is to mitigate some of the Kernel issues found in April and May 2026. + +This playbook will run roles on all the inventory entries in parallel by default. + +```sh +cd playbooks +ansible-playbook mitigate_kernel_CVE.yml +``` + @@ -248,7 +258,7 @@ ansible-playbook system-maintenance.yml -###### One node at a time +###### Node limit To test new configuration, it's advised to try it on one server at first. Of course you can comment out any entries in the inventory, but there are easier ways to do it. - Provide flag `-l` followed by inventory entry and Ansible will change state only of that entry: @@ -261,11 +271,14 @@ ansible-playbook upgrade.yml -l node1 # point to multiple entries ansible-playbook upgrade.yml -l "node1,node2" -# use regex +# use regex - ie all exit nodes ansible-playbook upgrade.yml -l "*exit*" + +# use group in inventory labeled as [group] +ansible-playbook deploy.yml -l new_nodes ``` -###### Role limit +###### Tag selection To update your exit policy by using the newest [NTM](https://github.com/nymtech/nym/blob/develop/scripts/nym-node-setup/network-tunnel-manager.sh) via Ansible, just run: diff --git a/scripts/kvm-setup/configure-vm.sh b/scripts/kvm-setup/configure-vm.sh index e1904313d5..8369d8564a 100644 --- a/scripts/kvm-setup/configure-vm.sh +++ b/scripts/kvm-setup/configure-vm.sh @@ -1,36 +1,101 @@ - #!/bin/bash -# detect active network interface -INTERFACE=$(ip -o link show | awk -F': ' '{print $2}' | grep -v lo | head -n 1) +usage() { + local code="${1:-0}" + cat < to specify one manually." + exit 1 + fi +else + echo "Using network interface: $INTERFACE" +fi + +# --- resize partition --- echo "Expanding partition and resizing filesystem..." growpart /dev/vda 1 resize2fs /dev/vda1 df -h -# ask before continuing -read -p "Continue with network configuration? (y/n): " CONTINUE -if [[ "$CONTINUE" != "y" ]]; then +if ! confirm "Continue with network configuration?"; then echo "Exiting." exit 1 fi -# generate Netplan config +# --- generate Netplan config --- NETPLAN_CONFIG="/etc/netplan/01-network-config.yaml" echo "Creating Netplan configuration at $NETPLAN_CONFIG..." @@ -45,28 +110,19 @@ network: addresses: EOF -# append IPv4 address if provided -if [[ -n "$IPv4_VM" ]]; then - echo " - $IPv4_VM/24" >> $NETPLAN_CONFIG -fi +[[ -n "$IPv4_VM" ]] && echo " - $IPv4_VM/24" >> $NETPLAN_CONFIG +[[ -n "$IPv6_VM" ]] && echo " - $IPv6_VM/64" >> $NETPLAN_CONFIG -# append IPv6 address if provided -if [[ -n "$IPv6_VM" ]]; then - echo " - $IPv6_VM/64" >> $NETPLAN_CONFIG -fi - -echo " routes:" >> $NETPLAN_CONFIG - -# append IPv4 route if provided -if [[ -n "$IPv4_GATEWAY_HOST_SERVER" ]]; then - echo " - to: default" >> $NETPLAN_CONFIG - echo " via: $IPv4_GATEWAY_HOST_SERVER" >> $NETPLAN_CONFIG -fi - -# append IPv6 route if provided -if [[ -n "$IPv6_GATEWAY_HOST_SERVER" ]]; then - echo " - to: default" >> $NETPLAN_CONFIG - echo " via: $IPv6_GATEWAY_HOST_SERVER" >> $NETPLAN_CONFIG +if [[ -n "$IPv4_GATEWAY_HOST_SERVER" || -n "$IPv6_GATEWAY_HOST_SERVER" ]]; then + echo " routes:" >> $NETPLAN_CONFIG + if [[ -n "$IPv4_GATEWAY_HOST_SERVER" ]]; then + echo " - to: default" >> $NETPLAN_CONFIG + echo " via: $IPv4_GATEWAY_HOST_SERVER" >> $NETPLAN_CONFIG + fi + if [[ -n "$IPv6_GATEWAY_HOST_SERVER" ]]; then + echo " - to: default" >> $NETPLAN_CONFIG + echo " via: $IPv6_GATEWAY_HOST_SERVER" >> $NETPLAN_CONFIG + fi fi cat <> $NETPLAN_CONFIG @@ -78,58 +134,43 @@ cat <> $NETPLAN_CONFIG - 2001:4860:4860::8888 # Google IPv6 DNS EOF -# secure Netplan config chmod 600 $NETPLAN_CONFIG - -# generate Netplan configuration netplan generate -# ask before applying Netplan -read -p "Apply Netplan changes? (y/n): " CONTINUE -if [[ "$CONTINUE" != "y" ]]; then +if ! confirm "Apply Netplan changes?"; then echo "Exiting." exit 1 fi -# apply Netplan and verify settings netplan --debug apply -# show IP configurations ip -4 a ip -6 a ip -4 r ip -6 r -# test network connectivity echo "Testing IPv4 connectivity for 10 seconds..." timeout 10 ping -4 google.com - echo "Testing IPv6 connectivity for 10 seconds..." timeout 10 ping -6 google.com -# ask before updating system -read -p "Proceed with system update and upgrade? (y/n): " CONTINUE -if [[ "$CONTINUE" != "y" ]]; then - echo "Skipping updates." -else +if confirm "Proceed with system update and upgrade?"; then apt update && apt upgrade -y +else + echo "Skipping updates." fi -# generate SSH host keys without password +# --- SSH setup --- echo "Generating SSH host keys..." -ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" -ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N "" -ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N "" +ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" +ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N "" +ssh-keygen -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N "" ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N "" -# restart SSH service systemctl restart ssh.service -# ensure ~/.ssh directory exists mkdir -p ~/.ssh - -# Open authorized_keys file for user input echo "# Add your admin SSH keys here, save and exit!" > ~/.ssh/authorized_keys nano ~/.ssh/authorized_keys -echo "Setup complete! Try to ping and ssh from the outside before killing this console" +echo "Setup complete! Try to ping and ssh from the outside before killing this console" \ No newline at end of file diff --git a/scripts/kvm-setup/initialise-vm.sh b/scripts/kvm-setup/initialise-vm.sh index f8755d50c1..82fb9f46cb 100644 --- a/scripts/kvm-setup/initialise-vm.sh +++ b/scripts/kvm-setup/initialise-vm.sh @@ -1,6 +1,86 @@ #!/bin/bash -# check if noble-server-cloudimg-amd64.img is in working dir - if not, wget it +usage() { + local code="${1:-0}" + cat < Date: Fri, 5 Jun 2026 11:29:04 +0200 Subject: [PATCH 86/94] [DOCs/operators]: Menu v2 (#6853) --- .../outputs/api-scraping-outputs/nodes-count.json | 8 ++++---- .../outputs/api-scraping-outputs/time-now.md | 2 +- documentation/docs/pages/operators/_meta.json | 12 +++++++++--- documentation/docs/pages/styles.css | 12 ++++++++++++ 4 files changed, 26 insertions(+), 8 deletions(-) diff --git a/documentation/docs/components/outputs/api-scraping-outputs/nodes-count.json b/documentation/docs/components/outputs/api-scraping-outputs/nodes-count.json index 9b221d2a82..8ff4c0e502 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/nodes-count.json +++ b/documentation/docs/components/outputs/api-scraping-outputs/nodes-count.json @@ -1,6 +1,6 @@ { - "nodes": 682, - "locations": 76, - "mixnodes": 239, - "exit_gateways": 435 + "nodes": 677, + "locations": 77, + "mixnodes": 240, + "exit_gateways": 429 } diff --git a/documentation/docs/components/outputs/api-scraping-outputs/time-now.md b/documentation/docs/components/outputs/api-scraping-outputs/time-now.md index de9ba936fc..710037c293 100644 --- a/documentation/docs/components/outputs/api-scraping-outputs/time-now.md +++ b/documentation/docs/components/outputs/api-scraping-outputs/time-now.md @@ -1 +1 @@ -Thursday, June 4th 2026, 09:20:29 UTC +Thursday, June 4th 2026, 11:40:35 UTC diff --git a/documentation/docs/pages/operators/_meta.json b/documentation/docs/pages/operators/_meta.json index bc6450a287..cf0d517fe5 100644 --- a/documentation/docs/pages/operators/_meta.json +++ b/documentation/docs/pages/operators/_meta.json @@ -3,17 +3,23 @@ "changelog": "Changelog", "release-cycle": "Release Cycle", "variables": "Variables & Parameters", - "sandbox": "Sandbox Testnet", - "binaries": "Binaries", + "---1": { + "type": "separator" + }, "nodes": "Nodes & Validators Guides", + "binaries": "Binaries", "orchestration" : "Orchestration", "performance-and-testing": "Performance Measurement", "tools": "Tools", "troubleshooting": "Troubleshooting", + "---2": { + "type": "separator" + }, + "sandbox": "Sandbox Testnet", "tokenomics": "Tokenomics", "faq": "FAQ", "community-counsel": "Community Counsel", - "---": { + "---3": { "type": "separator" }, "archive": "Archive", diff --git a/documentation/docs/pages/styles.css b/documentation/docs/pages/styles.css index 35664541ac..a896e7e1f7 100644 --- a/documentation/docs/pages/styles.css +++ b/documentation/docs/pages/styles.css @@ -537,3 +537,15 @@ html:not(.dark) .landing-card { margin-bottom: 1.5rem; } } + + +/* Bold pages/operators/nodes sidebar item */ +html.dark .nextra-sidebar-container a[href="/docs/operators/nodes"] { + color: var(--textPrimary) !important; + font-weight: 700; +} + +html:not(.dark) .nextra-sidebar-container a[href="/docs/operators/nodes"] { + color: #111 !important; + font-weight: 700; +} \ No newline at end of file From 08dc353e82510e592a70927643ac16eab89ce1ee Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Fri, 5 Jun 2026 10:36:36 +0000 Subject: [PATCH 87/94] New TS SDK packages (#6839) * First sweep packages + some minor tweaking * Second sweep * Regenerate lockfile + package.json mods * Regenerate lockfile again * Fix CI * Fix CI again * All building properly * unblock * Tweak examples * Comments + readme + fix rotten unit test --- .github/workflows/ci-docs.yml | 12 +- .github/workflows/ci-lint-typescript.yml | 10 +- .github/workflows/ci-sdk-wasm.yml | 5 - .github/workflows/publish-sdk-npm.yml | 8 - Cargo.lock | 28 +- Cargo.toml | 5 - Makefile | 8 +- package.json | 2 +- pnpm-lock.yaml | 1558 ++---- pnpm-workspace.yaml | 16 +- .../examples/.webpack/webpack.base.js | 14 +- .../examples/mix-dns/browser/README.md | 27 + .../examples/mix-dns/browser/package.json | 16 + .../examples/mix-dns/browser/src/index.html | 24 + .../examples/mix-dns/browser/src/index.ts | 54 + .../examples/mix-fetch/browser/package.json | 4 +- .../examples/mix-fetch/browser/src/index.ts | 79 +- .../examples/mix-fetch/node-js/index.js | 54 - .../examples/mix-fetch/node-js/package.json | 14 - .../examples/mix-fetch/node-js/server.js | 55 - .../examples/mix-websocket/browser/README.md | 37 + .../mix-websocket/browser/package.json | 16 + .../mix-websocket/browser/src/index.html | 32 + .../mix-websocket/browser/src/index.ts | 90 + .../packages/internal-dev/README.md | 72 + .../{mix-fetch => }/internal-dev/package.json | 14 +- .../packages/internal-dev/parcel/package.json | 18 + .../packages/internal-dev/src/index.html | 233 + .../packages/internal-dev/src/index.ts | 680 +++ .../internal-dev/tsconfig.json | 2 +- .../packages/internal-dev/webpack.common.js | 38 + .../internal-dev/webpack.config.js | 0 .../internal-dev/webpack.prod.js | 0 sdk/typescript/packages/mix-dns/README.md | 30 + sdk/typescript/packages/mix-dns/package.json | 52 + sdk/typescript/packages/mix-dns/src/index.ts | 26 + sdk/typescript/packages/mix-dns/tsconfig.json | 20 + .../{mix-fetch-node => mix-dns}/typedoc.json | 5 +- .../packages/mix-fetch-node/.gitignore | 2 - .../packages/mix-fetch-node/README.md | 14 - .../packages/mix-fetch-node/internal/index.js | 54 - .../packages/mix-fetch-node/jest.config.mjs | 16 - .../packages/mix-fetch-node/package.json | 73 - .../mix-fetch-node/rollup-cjs.config.mjs | 31 - .../mix-fetch-node/rollup-worker.config.mjs | 43 - .../scripts/build-prod-docs-collect.sh | 17 - .../mix-fetch-node/scripts/build-prod.sh | 20 - .../packages/mix-fetch-node/scripts/build.sh | 48 - .../scripts/buildPackageJson.mjs | 22 - .../mix-fetch-node/scripts/publish.sh | 17 - .../mix-fetch-node/src/create-mix-fetch.ts | 77 - .../packages/mix-fetch-node/src/index.ts | 56 - .../mix-fetch-node/src/node-adapter.ts | 43 - .../packages/mix-fetch-node/src/types.ts | 98 - .../worker/handle-response-mime-types.test.ts | 73 - .../src/worker/handle-response-mime-types.ts | 111 - .../mix-fetch-node/src/worker/index.ts | 9 - .../mix-fetch-node/src/worker/main.ts | 74 - .../mix-fetch-node/src/worker/polyfill.ts | 37 - .../mix-fetch-node/src/worker/wasm-loading.ts | 69 - .../mix-fetch-node/tsconfig.jest.json | 35 - .../mix-fetch-node/typings/rollup-worker.d.ts | 6 - .../mix-fetch-node/typings/wasm_exec.d.ts | 11 - .../packages/mix-fetch-node/yarn.lock | 4439 --------------- sdk/typescript/packages/mix-fetch/.babelrc | 3 - .../mix-fetch/README-CommonJS-full-fat.md | 14 - .../packages/mix-fetch/README-CommonJS.md | 14 - .../packages/mix-fetch/README-full-fat.md | 14 - sdk/typescript/packages/mix-fetch/README.md | 129 +- .../packages/mix-fetch/internal-dev/README.md | 44 - .../internal-dev/parcel/package.json | 15 - .../mix-fetch/internal-dev/src/index.html | 18 - .../mix-fetch/internal-dev/src/index.ts | 77 - .../mix-fetch/internal-dev/webpack.common.js | 46 - .../packages/mix-fetch/jest.config.mjs | 15 - .../packages/mix-fetch/package.json | 80 +- .../mix-fetch/rollup-cjs-full-fat.config.mjs | 8 - .../packages/mix-fetch/rollup-cjs.config.mjs | 5 - .../mix-fetch/rollup-esm-full-fat.config.mjs | 8 - .../packages/mix-fetch/rollup-esm.config.mjs | 8 - .../rollup-worker-full-fat.config.mjs | 8 - .../packages/mix-fetch/rollup/cjs.mjs | 30 - .../packages/mix-fetch/rollup/esm.mjs | 45 - .../packages/mix-fetch/rollup/worker.mjs | 43 - .../mix-fetch/scripts/build-dev-esm.sh | 46 - .../scripts/build-prod-docs-collect.sh | 17 - .../packages/mix-fetch/scripts/build-prod.sh | 20 - .../packages/mix-fetch/scripts/build.sh | 96 - .../mix-fetch/scripts/buildPackageJson.mjs | 29 - .../mix-fetch/scripts/postBuildReplace.mjs | 45 - .../packages/mix-fetch/scripts/publish.sh | 22 - .../scripts/showDependencyLocation.cjs | 8 - .../mix-fetch/src/create-mix-fetch.ts | 77 - .../packages/mix-fetch/src/index.ts | 118 +- .../packages/mix-fetch/src/types.ts | 98 - .../worker/handle-response-mime-types.test.ts | 73 - .../src/worker/handle-response-mime-types.ts | 111 - .../packages/mix-fetch/src/worker/index.ts | 9 - .../packages/mix-fetch/src/worker/main.ts | 69 - .../mix-fetch/src/worker/wasm-loading.ts | 87 - .../packages/mix-fetch/tsconfig.jest.json | 43 - .../packages/mix-fetch/tsconfig.json | 33 +- .../packages/mix-fetch/typedoc.json | 3 +- .../mix-fetch/typings/rollup-worker.d.ts | 4 - .../packages/mix-fetch/typings/wasm_exec.d.ts | 11 - sdk/typescript/packages/mix-tunnel/.gitignore | 6 + sdk/typescript/packages/mix-tunnel/README.md | 41 + .../packages/mix-tunnel/package.json | 60 + .../packages/mix-tunnel/rollup-esm.config.mjs | 5 + .../rollup-worker.config.mjs | 0 .../packages/mix-tunnel/rollup/esm.mjs | 34 + .../packages/mix-tunnel/rollup/worker.mjs | 47 + .../packages/mix-tunnel/scripts/build.sh | 29 + .../packages/mix-tunnel/src/index.ts | 87 + .../packages/mix-tunnel/src/types.ts | 78 + .../packages/mix-tunnel/src/typings.d.ts | 7 + .../packages/mix-tunnel/src/worker/index.ts | 12 + .../packages/mix-tunnel/src/worker/main.ts | 38 + .../mix-tunnel/src/worker/wasm-loading.ts | 14 + .../tsconfig.json | 22 +- .../packages/mix-tunnel/typedoc.json | 33 + .../packages/mix-websocket/README.md | 42 + .../packages/mix-websocket/package.json | 52 + .../packages/mix-websocket/src/index.ts | 165 + .../packages/mix-websocket/tsconfig.json | 20 + .../packages/mix-websocket/typedoc.json | 32 + sdk/typescript/scripts/dev-mode-add.mjs | 6 + sdk/typescript/scripts/dev-mode-remove.mjs | 1 + sdk/typescript/scripts/publish.sh | 97 +- sdk/typescript/scripts/unpublish.sh | 1 - .../integration-tests/mix-fetch/.gitignore | 1 - .../mix-fetch/generate-tests.mjs | 188 - .../mix-fetch/package-lock.json | 1213 ----- .../integration-tests/mix-fetch/package.json | 8 - .../mix-fetch/template/parcel/package.json | 14 - .../mix-fetch/template/src/index.html | 18 - .../mix-fetch/template/src/index.ts | 59 - .../mix-fetch/template/webpack/package.json | 57 - .../mix-fetch/template/webpack/tsconfig.json | 8 - .../template/webpack/webpack.base.js | 91 - .../template/webpack/webpack.common.js | 30 - .../template/webpack/webpack.config.js | 71 - .../template/webpack/webpack.plugins.js | 19 - .../template/webpack/webpack.prod.js | 44 - .../mix-fetch/template/workspace/package.json | 9 - .../mix-fetch/tests/tests.mjs | 88 - tools/internal/sdk-version-bump/README.md | 63 +- tools/internal/sdk-version-bump/src/json.rs | 12 + tools/internal/sdk-version-bump/src/main.rs | 119 +- wasm/mix-fetch/.cargo/config.toml | 4 - wasm/mix-fetch/Cargo.toml | 41 - wasm/mix-fetch/Makefile | 34 - wasm/mix-fetch/build-node.mjs | 14 - wasm/mix-fetch/build.mjs | 12 - wasm/mix-fetch/go-mix-conn/.gitignore | 3 - wasm/mix-fetch/go-mix-conn/Makefile | 25 - wasm/mix-fetch/go-mix-conn/cmd/wasm/main.go | 31 - wasm/mix-fetch/go-mix-conn/go.mod | 7 - wasm/mix-fetch/go-mix-conn/go.sum | 8 - .../internal/bridge/go_bridge/go_bridge.go | 153 - .../bridge/rust_bridge/rust_bridge.go | 80 - .../internal/external/roundtrip_js.go | 158 - .../go-mix-conn/internal/external/set.go | 26 - .../go-mix-conn/internal/helpers/helpers.go | 121 - .../go-mix-conn/internal/jstypes/async.go | 67 - .../internal/jstypes/conv/request.go | 415 -- .../internal/jstypes/conv/response.go | 350 -- .../go-mix-conn/internal/jstypes/globals.go | 45 - .../go-mix-conn/internal/jstypes/headers.go | 102 - .../go-mix-conn/internal/jstypes/helpers.go | 140 - .../go-mix-conn/internal/jstypes/request.go | 45 - .../go-mix-conn/internal/jstypes/response.go | 16 - .../go-mix-conn/internal/log/logger.go | 100 - .../go-mix-conn/internal/mixfetch/helpers.go | 59 - .../go-mix-conn/internal/mixfetch/mixfetch.go | 405 -- .../internal/sslhelpers/cacert.pem | 3511 ------------ .../internal/sslhelpers/root_certs.go | 41 - .../internal/sslhelpers/ssl_helper.go | 15 - .../internal/state/fake_connection.go | 307 -- .../go-mix-conn/internal/state/state.go | 126 - .../go-mix-conn/internal/types/options.go | 37 - .../go-mix-conn/internal/types/types.go | 6 - .../go-mix-conn/scripts/update-root-certs.sh | 58 - wasm/mix-fetch/internal-dev-node/.gitignore | 1 - .../internal-dev-node/package-lock.json | 1564 ------ wasm/mix-fetch/internal-dev-node/package.json | 17 - .../mix-fetch/internal-dev-node/src/index.mjs | 98 - .../internal-dev-node/src/polyfill.mjs | 59 - .../internal-dev-node/src/worker.mjs | 117 - wasm/mix-fetch/internal-dev-node/yarn.lock | 938 ---- wasm/mix-fetch/internal-dev/.gitignore | 2 - wasm/mix-fetch/internal-dev/bootstrap.js | 5 - wasm/mix-fetch/internal-dev/index.html | 102 - wasm/mix-fetch/internal-dev/index.js | 236 - wasm/mix-fetch/internal-dev/package-lock.json | 4758 ----------------- wasm/mix-fetch/internal-dev/package.json | 41 - wasm/mix-fetch/internal-dev/webpack.config.js | 36 - wasm/mix-fetch/internal-dev/worker.js | 314 -- wasm/mix-fetch/internal-dev/yarn.lock | 2536 --------- wasm/mix-fetch/scripts/clean-build.sh | 38 - wasm/mix-fetch/src/active_requests.rs | 150 - wasm/mix-fetch/src/client.rs | 345 -- wasm/mix-fetch/src/config.rs | 160 - wasm/mix-fetch/src/error.rs | 92 - wasm/mix-fetch/src/fetch.rs | 177 - wasm/mix-fetch/src/go_bridge.rs | 100 - wasm/mix-fetch/src/helpers.rs | 50 - wasm/mix-fetch/src/lib.rs | 38 - wasm/mix-fetch/src/request_writer.rs | 88 - wasm/mix-fetch/src/socks_helpers.rs | 49 - wasm/smolmix/Cargo.toml | 26 +- wasm/smolmix/Makefile | 16 +- wasm/smolmix/README.md | 55 +- wasm/smolmix/internal-dev/index.js | 2 +- wasm/smolmix/internal-dev/worker.js | 10 +- wasm/smolmix/src/error.rs | 2 +- wasm/smolmix/src/fetch.rs | 44 +- wasm/smolmix/src/http.rs | 66 + wasm/smolmix/src/lib.rs | 14 +- wasm/smolmix/src/mixdns.rs | 6 +- .../src/{mixsocket.rs => mixwebsocket.rs} | 8 +- wasm/smolmix/src/stream.rs | 12 +- 222 files changed, 3553 insertions(+), 28918 deletions(-) create mode 100644 sdk/typescript/examples/mix-dns/browser/README.md create mode 100644 sdk/typescript/examples/mix-dns/browser/package.json create mode 100644 sdk/typescript/examples/mix-dns/browser/src/index.html create mode 100644 sdk/typescript/examples/mix-dns/browser/src/index.ts delete mode 100644 sdk/typescript/examples/mix-fetch/node-js/index.js delete mode 100644 sdk/typescript/examples/mix-fetch/node-js/package.json delete mode 100644 sdk/typescript/examples/mix-fetch/node-js/server.js create mode 100644 sdk/typescript/examples/mix-websocket/browser/README.md create mode 100644 sdk/typescript/examples/mix-websocket/browser/package.json create mode 100644 sdk/typescript/examples/mix-websocket/browser/src/index.html create mode 100644 sdk/typescript/examples/mix-websocket/browser/src/index.ts create mode 100644 sdk/typescript/packages/internal-dev/README.md rename sdk/typescript/packages/{mix-fetch => }/internal-dev/package.json (81%) create mode 100644 sdk/typescript/packages/internal-dev/parcel/package.json create mode 100644 sdk/typescript/packages/internal-dev/src/index.html create mode 100644 sdk/typescript/packages/internal-dev/src/index.ts rename sdk/typescript/packages/{mix-fetch => }/internal-dev/tsconfig.json (76%) create mode 100644 sdk/typescript/packages/internal-dev/webpack.common.js rename sdk/typescript/packages/{mix-fetch => }/internal-dev/webpack.config.js (100%) rename sdk/typescript/packages/{mix-fetch => }/internal-dev/webpack.prod.js (100%) create mode 100644 sdk/typescript/packages/mix-dns/README.md create mode 100644 sdk/typescript/packages/mix-dns/package.json create mode 100644 sdk/typescript/packages/mix-dns/src/index.ts create mode 100644 sdk/typescript/packages/mix-dns/tsconfig.json rename sdk/typescript/packages/{mix-fetch-node => mix-dns}/typedoc.json (77%) delete mode 100644 sdk/typescript/packages/mix-fetch-node/.gitignore delete mode 100644 sdk/typescript/packages/mix-fetch-node/README.md delete mode 100644 sdk/typescript/packages/mix-fetch-node/internal/index.js delete mode 100644 sdk/typescript/packages/mix-fetch-node/jest.config.mjs delete mode 100644 sdk/typescript/packages/mix-fetch-node/package.json delete mode 100644 sdk/typescript/packages/mix-fetch-node/rollup-cjs.config.mjs delete mode 100644 sdk/typescript/packages/mix-fetch-node/rollup-worker.config.mjs delete mode 100755 sdk/typescript/packages/mix-fetch-node/scripts/build-prod-docs-collect.sh delete mode 100755 sdk/typescript/packages/mix-fetch-node/scripts/build-prod.sh delete mode 100755 sdk/typescript/packages/mix-fetch-node/scripts/build.sh delete mode 100644 sdk/typescript/packages/mix-fetch-node/scripts/buildPackageJson.mjs delete mode 100755 sdk/typescript/packages/mix-fetch-node/scripts/publish.sh delete mode 100644 sdk/typescript/packages/mix-fetch-node/src/create-mix-fetch.ts delete mode 100644 sdk/typescript/packages/mix-fetch-node/src/index.ts delete mode 100644 sdk/typescript/packages/mix-fetch-node/src/node-adapter.ts delete mode 100644 sdk/typescript/packages/mix-fetch-node/src/types.ts delete mode 100644 sdk/typescript/packages/mix-fetch-node/src/worker/handle-response-mime-types.test.ts delete mode 100644 sdk/typescript/packages/mix-fetch-node/src/worker/handle-response-mime-types.ts delete mode 100644 sdk/typescript/packages/mix-fetch-node/src/worker/index.ts delete mode 100644 sdk/typescript/packages/mix-fetch-node/src/worker/main.ts delete mode 100644 sdk/typescript/packages/mix-fetch-node/src/worker/polyfill.ts delete mode 100644 sdk/typescript/packages/mix-fetch-node/src/worker/wasm-loading.ts delete mode 100644 sdk/typescript/packages/mix-fetch-node/tsconfig.jest.json delete mode 100644 sdk/typescript/packages/mix-fetch-node/typings/rollup-worker.d.ts delete mode 100644 sdk/typescript/packages/mix-fetch-node/typings/wasm_exec.d.ts delete mode 100644 sdk/typescript/packages/mix-fetch-node/yarn.lock delete mode 100644 sdk/typescript/packages/mix-fetch/.babelrc delete mode 100644 sdk/typescript/packages/mix-fetch/README-CommonJS-full-fat.md delete mode 100644 sdk/typescript/packages/mix-fetch/README-CommonJS.md delete mode 100644 sdk/typescript/packages/mix-fetch/README-full-fat.md delete mode 100644 sdk/typescript/packages/mix-fetch/internal-dev/README.md delete mode 100644 sdk/typescript/packages/mix-fetch/internal-dev/parcel/package.json delete mode 100644 sdk/typescript/packages/mix-fetch/internal-dev/src/index.html delete mode 100644 sdk/typescript/packages/mix-fetch/internal-dev/src/index.ts delete mode 100644 sdk/typescript/packages/mix-fetch/internal-dev/webpack.common.js delete mode 100644 sdk/typescript/packages/mix-fetch/jest.config.mjs delete mode 100644 sdk/typescript/packages/mix-fetch/rollup-cjs-full-fat.config.mjs delete mode 100644 sdk/typescript/packages/mix-fetch/rollup-cjs.config.mjs delete mode 100644 sdk/typescript/packages/mix-fetch/rollup-esm-full-fat.config.mjs delete mode 100644 sdk/typescript/packages/mix-fetch/rollup-esm.config.mjs delete mode 100644 sdk/typescript/packages/mix-fetch/rollup-worker-full-fat.config.mjs delete mode 100644 sdk/typescript/packages/mix-fetch/rollup/cjs.mjs delete mode 100644 sdk/typescript/packages/mix-fetch/rollup/esm.mjs delete mode 100644 sdk/typescript/packages/mix-fetch/rollup/worker.mjs delete mode 100755 sdk/typescript/packages/mix-fetch/scripts/build-dev-esm.sh delete mode 100755 sdk/typescript/packages/mix-fetch/scripts/build-prod-docs-collect.sh delete mode 100755 sdk/typescript/packages/mix-fetch/scripts/build-prod.sh delete mode 100755 sdk/typescript/packages/mix-fetch/scripts/build.sh delete mode 100644 sdk/typescript/packages/mix-fetch/scripts/buildPackageJson.mjs delete mode 100644 sdk/typescript/packages/mix-fetch/scripts/postBuildReplace.mjs delete mode 100755 sdk/typescript/packages/mix-fetch/scripts/publish.sh delete mode 100644 sdk/typescript/packages/mix-fetch/scripts/showDependencyLocation.cjs delete mode 100644 sdk/typescript/packages/mix-fetch/src/create-mix-fetch.ts delete mode 100644 sdk/typescript/packages/mix-fetch/src/types.ts delete mode 100644 sdk/typescript/packages/mix-fetch/src/worker/handle-response-mime-types.test.ts delete mode 100644 sdk/typescript/packages/mix-fetch/src/worker/handle-response-mime-types.ts delete mode 100644 sdk/typescript/packages/mix-fetch/src/worker/index.ts delete mode 100644 sdk/typescript/packages/mix-fetch/src/worker/main.ts delete mode 100644 sdk/typescript/packages/mix-fetch/src/worker/wasm-loading.ts delete mode 100644 sdk/typescript/packages/mix-fetch/tsconfig.jest.json delete mode 100644 sdk/typescript/packages/mix-fetch/typings/rollup-worker.d.ts delete mode 100644 sdk/typescript/packages/mix-fetch/typings/wasm_exec.d.ts create mode 100644 sdk/typescript/packages/mix-tunnel/.gitignore create mode 100644 sdk/typescript/packages/mix-tunnel/README.md create mode 100644 sdk/typescript/packages/mix-tunnel/package.json create mode 100644 sdk/typescript/packages/mix-tunnel/rollup-esm.config.mjs rename sdk/typescript/packages/{mix-fetch => mix-tunnel}/rollup-worker.config.mjs (100%) create mode 100644 sdk/typescript/packages/mix-tunnel/rollup/esm.mjs create mode 100644 sdk/typescript/packages/mix-tunnel/rollup/worker.mjs create mode 100755 sdk/typescript/packages/mix-tunnel/scripts/build.sh create mode 100644 sdk/typescript/packages/mix-tunnel/src/index.ts create mode 100644 sdk/typescript/packages/mix-tunnel/src/types.ts create mode 100644 sdk/typescript/packages/mix-tunnel/src/typings.d.ts create mode 100644 sdk/typescript/packages/mix-tunnel/src/worker/index.ts create mode 100644 sdk/typescript/packages/mix-tunnel/src/worker/main.ts create mode 100644 sdk/typescript/packages/mix-tunnel/src/worker/wasm-loading.ts rename sdk/typescript/packages/{mix-fetch-node => mix-tunnel}/tsconfig.json (50%) create mode 100644 sdk/typescript/packages/mix-tunnel/typedoc.json create mode 100644 sdk/typescript/packages/mix-websocket/README.md create mode 100644 sdk/typescript/packages/mix-websocket/package.json create mode 100644 sdk/typescript/packages/mix-websocket/src/index.ts create mode 100644 sdk/typescript/packages/mix-websocket/tsconfig.json create mode 100644 sdk/typescript/packages/mix-websocket/typedoc.json delete mode 100644 sdk/typescript/tests/integration-tests/mix-fetch/.gitignore delete mode 100644 sdk/typescript/tests/integration-tests/mix-fetch/generate-tests.mjs delete mode 100644 sdk/typescript/tests/integration-tests/mix-fetch/package-lock.json delete mode 100644 sdk/typescript/tests/integration-tests/mix-fetch/package.json delete mode 100644 sdk/typescript/tests/integration-tests/mix-fetch/template/parcel/package.json delete mode 100644 sdk/typescript/tests/integration-tests/mix-fetch/template/src/index.html delete mode 100644 sdk/typescript/tests/integration-tests/mix-fetch/template/src/index.ts delete mode 100644 sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/package.json delete mode 100644 sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/tsconfig.json delete mode 100644 sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/webpack.base.js delete mode 100644 sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/webpack.common.js delete mode 100644 sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/webpack.config.js delete mode 100644 sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/webpack.plugins.js delete mode 100644 sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/webpack.prod.js delete mode 100644 sdk/typescript/tests/integration-tests/mix-fetch/template/workspace/package.json delete mode 100644 sdk/typescript/tests/integration-tests/mix-fetch/tests/tests.mjs delete mode 100644 wasm/mix-fetch/.cargo/config.toml delete mode 100644 wasm/mix-fetch/Cargo.toml delete mode 100644 wasm/mix-fetch/Makefile delete mode 100644 wasm/mix-fetch/build-node.mjs delete mode 100644 wasm/mix-fetch/build.mjs delete mode 100644 wasm/mix-fetch/go-mix-conn/.gitignore delete mode 100644 wasm/mix-fetch/go-mix-conn/Makefile delete mode 100644 wasm/mix-fetch/go-mix-conn/cmd/wasm/main.go delete mode 100644 wasm/mix-fetch/go-mix-conn/go.mod delete mode 100644 wasm/mix-fetch/go-mix-conn/go.sum delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/bridge/go_bridge/go_bridge.go delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/bridge/rust_bridge/rust_bridge.go delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/external/roundtrip_js.go delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/external/set.go delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/helpers/helpers.go delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/jstypes/async.go delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/jstypes/conv/request.go delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/jstypes/conv/response.go delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/jstypes/globals.go delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/jstypes/headers.go delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/jstypes/helpers.go delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/jstypes/request.go delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/jstypes/response.go delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/log/logger.go delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/mixfetch/helpers.go delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/mixfetch/mixfetch.go delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/sslhelpers/cacert.pem delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/sslhelpers/root_certs.go delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/sslhelpers/ssl_helper.go delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/state/fake_connection.go delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/state/state.go delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/types/options.go delete mode 100644 wasm/mix-fetch/go-mix-conn/internal/types/types.go delete mode 100755 wasm/mix-fetch/go-mix-conn/scripts/update-root-certs.sh delete mode 100644 wasm/mix-fetch/internal-dev-node/.gitignore delete mode 100644 wasm/mix-fetch/internal-dev-node/package-lock.json delete mode 100644 wasm/mix-fetch/internal-dev-node/package.json delete mode 100644 wasm/mix-fetch/internal-dev-node/src/index.mjs delete mode 100644 wasm/mix-fetch/internal-dev-node/src/polyfill.mjs delete mode 100644 wasm/mix-fetch/internal-dev-node/src/worker.mjs delete mode 100644 wasm/mix-fetch/internal-dev-node/yarn.lock delete mode 100644 wasm/mix-fetch/internal-dev/.gitignore delete mode 100644 wasm/mix-fetch/internal-dev/bootstrap.js delete mode 100644 wasm/mix-fetch/internal-dev/index.html delete mode 100644 wasm/mix-fetch/internal-dev/index.js delete mode 100644 wasm/mix-fetch/internal-dev/package-lock.json delete mode 100644 wasm/mix-fetch/internal-dev/package.json delete mode 100644 wasm/mix-fetch/internal-dev/webpack.config.js delete mode 100644 wasm/mix-fetch/internal-dev/worker.js delete mode 100644 wasm/mix-fetch/internal-dev/yarn.lock delete mode 100755 wasm/mix-fetch/scripts/clean-build.sh delete mode 100644 wasm/mix-fetch/src/active_requests.rs delete mode 100644 wasm/mix-fetch/src/client.rs delete mode 100644 wasm/mix-fetch/src/config.rs delete mode 100644 wasm/mix-fetch/src/error.rs delete mode 100644 wasm/mix-fetch/src/fetch.rs delete mode 100644 wasm/mix-fetch/src/go_bridge.rs delete mode 100644 wasm/mix-fetch/src/helpers.rs delete mode 100644 wasm/mix-fetch/src/lib.rs delete mode 100644 wasm/mix-fetch/src/request_writer.rs delete mode 100644 wasm/mix-fetch/src/socks_helpers.rs rename wasm/smolmix/src/{mixsocket.rs => mixwebsocket.rs} (98%) diff --git a/.github/workflows/ci-docs.yml b/.github/workflows/ci-docs.yml index 7a76619701..4807a41778 100644 --- a/.github/workflows/ci-docs.yml +++ b/.github/workflows/ci-docs.yml @@ -7,7 +7,10 @@ on: paths: - "documentation/docs/**" - "sdk/typescript/packages/sdk/src/**" + - "sdk/typescript/packages/mix-tunnel/src/**" - "sdk/typescript/packages/mix-fetch/src/**" + - "sdk/typescript/packages/mix-dns/src/**" + - "sdk/typescript/packages/mix-websocket/src/**" - ".github/workflows/ci-docs.yml" jobs: @@ -47,7 +50,7 @@ jobs: - name: Check if TypeScript SDK source changed id: check-ts-sdk run: | - if git diff --name-only ${{ github.event.before }} ${{ github.sha }} | grep -qE '^sdk/typescript/packages/(sdk|mix-fetch)/src/'; then + if git diff --name-only ${{ github.event.before }} ${{ github.sha }} | grep -qE '^sdk/typescript/packages/(sdk|mix-tunnel|mix-fetch|mix-dns|mix-websocket)/src/'; then echo "changed=true" >> $GITHUB_OUTPUT else echo "changed=false" >> $GITHUB_OUTPUT @@ -58,8 +61,11 @@ jobs: if: steps.check-ts-sdk.outputs.changed == 'true' run: | npm install -g typedoc@0.25.13 typedoc-plugin-markdown@4.0.3 - cd ${{ github.workspace }}/sdk/typescript/packages/sdk && typedoc --skipErrorChecking - cd ${{ github.workspace }}/sdk/typescript/packages/mix-fetch && typedoc --skipErrorChecking + cd ${{ github.workspace }}/sdk/typescript/packages/sdk && typedoc --skipErrorChecking + cd ${{ github.workspace }}/sdk/typescript/packages/mix-tunnel && typedoc --skipErrorChecking + cd ${{ github.workspace }}/sdk/typescript/packages/mix-fetch && typedoc --skipErrorChecking + cd ${{ github.workspace }}/sdk/typescript/packages/mix-dns && typedoc --skipErrorChecking + cd ${{ github.workspace }}/sdk/typescript/packages/mix-websocket && typedoc --skipErrorChecking - name: Verify doc versions run: ${{ github.workspace }}/documentation/scripts/verify-doc-versions.sh diff --git a/.github/workflows/ci-lint-typescript.yml b/.github/workflows/ci-lint-typescript.yml index ad5ae63fac..4c4aae1e74 100644 --- a/.github/workflows/ci-lint-typescript.yml +++ b/.github/workflows/ci-lint-typescript.yml @@ -40,10 +40,12 @@ jobs: - name: Install wasm-opt run: cargo install wasm-opt - - name: Set up Go - uses: actions/setup-go@v6 - with: - go-version: "1.24.6" + # Produce wasm/smolmix/pkg/package.json before any pnpm step. The + # `pnpm dev:on` in `prebuild:ci` adds wasm/smolmix/pkg to the dynamic + # workspace; mix-tunnel's `workspace:*` lookup against @nymproject/ + # smolmix-wasm needs the package.json to be present. + - name: Build smolmix wasm + run: make -C wasm/smolmix - name: Install run: pnpm i diff --git a/.github/workflows/ci-sdk-wasm.yml b/.github/workflows/ci-sdk-wasm.yml index 94cdca9e22..1d7d3d840b 100644 --- a/.github/workflows/ci-sdk-wasm.yml +++ b/.github/workflows/ci-sdk-wasm.yml @@ -30,11 +30,6 @@ jobs: override: true components: rustfmt, clippy - - name: Set up Go - uses: actions/setup-go@v6 - with: - go-version: "1.24.6" - - name: Install wasm-pack run: curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh diff --git a/.github/workflows/publish-sdk-npm.yml b/.github/workflows/publish-sdk-npm.yml index fa474ae048..c73e70255f 100644 --- a/.github/workflows/publish-sdk-npm.yml +++ b/.github/workflows/publish-sdk-npm.yml @@ -33,14 +33,6 @@ jobs: - name: Install wasm-opt run: cargo install wasm-opt - - name: Set up Go - uses: actions/setup-go@v6 - with: - go-version: "1.24.6" - - - name: Update root CA certificate bundle - run: ./wasm/mix-fetch/go-mix-conn/scripts/update-root-certs.sh - - name: Install dependencies run: pnpm i diff --git a/Cargo.lock b/Cargo.lock index 398f693f82..050695b2d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5414,32 +5414,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "mix-fetch-wasm" -version = "1.4.3" -dependencies = [ - "async-trait", - "futures", - "js-sys", - "nym-bin-common", - "nym-http-api-client", - "nym-ordered-buffer", - "nym-service-providers-common", - "nym-socks5-requests", - "nym-validator-client", - "nym-wasm-client-core", - "nym-wasm-utils", - "rand 0.8.6", - "serde", - "serde-wasm-bindgen 0.6.5", - "thiserror 2.0.18", - "tokio", - "tsify", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", -] - [[package]] name = "mixnet-connectivity-check" version = "0.1.0" @@ -11583,7 +11557,7 @@ dependencies = [ [[package]] name = "smolmix-wasm" -version = "1.21.0" +version = "0.1.0" dependencies = [ "async-tungstenite", "bytes", diff --git a/Cargo.toml b/Cargo.toml index b5798320e3..24062ae693 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -174,7 +174,6 @@ members = [ "tools/nymvisor", "tools/ts-rs-cli", "wasm/client", - "wasm/mix-fetch", "wasm/smolmix", "wasm/zknym-lib", "nym-network-monitor-v3/nym-network-monitor-orchestrator", @@ -605,10 +604,6 @@ opt-level = 3 # lto = true opt-level = 'z' -[profile.release.package.mix-fetch-wasm] -# lto = true -opt-level = 'z' - [profile.release.package.smolmix-wasm] # lto = true opt-level = 'z' diff --git a/Makefile b/Makefile index faef4a4473..3819f1827a 100644 --- a/Makefile +++ b/Makefile @@ -105,14 +105,17 @@ sdk-wasm: sdk-wasm-build sdk-wasm-test sdk-wasm-lint sdk-wasm-build: $(MAKE) -C wasm/client - $(MAKE) -C wasm/mix-fetch $(MAKE) -C wasm/smolmix # $(MAKE) -C wasm/zknym-lib # run this from npm/yarn to ensure tools are in the path, e.g. yarn build:sdk from root of repo +# +# `mix-tunnel` must build before the three feature packages — they import it +# via `workspace:*` and the lerna topological sort will respect that as long +# as we keep them in the same `--scope` invocation. sdk-typescript-build: npx lerna run --scope @nymproject/sdk build --stream - npx lerna run --scope @nymproject/mix-fetch build --stream + npx lerna run --scope '{@nymproject/mix-tunnel,@nymproject/mix-fetch,@nymproject/mix-dns,@nymproject/mix-websocket}' build --stream pnpm --pwd sdk/typescript/codegen/contract-clients build # NOTE: These targets are part of the main workspace (but not as wasm32-unknown-unknown) @@ -124,7 +127,6 @@ sdk-wasm-test: sdk-wasm-lint: RUSTFLAGS='--cfg getrandom_backend="wasm_js"' cargo clippy $(addprefix -p , $(WASM_CRATES)) --target wasm32-unknown-unknown -- -Dwarnings - $(MAKE) -C wasm/mix-fetch check-fmt $(MAKE) -C wasm/smolmix check-fmt # Add to top-level targets diff --git a/package.json b/package.json index e27496154a..afe7678e70 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "audit:fix": "pnpm audit --fix", "build": "run-s build:types build:packages", "build:ci": "run-s build:types build:packages build:wasm build:ci:sdk", - "build:ci:sdk": "lerna run --scope '{@nymproject/sdk,@nymproject/sdk-react,@nymproject/mix-fetch,@nymproject/nodejs-client,@nymproject/mix-fetch-node}' build --stream", + "build:ci:sdk": "lerna run --scope '{@nymproject/mix-tunnel,@nymproject/mix-fetch,@nymproject/mix-dns,@nymproject/mix-websocket}' build --stream", "build:ci:storybook": "pnpm build && pnpm dev:on && run-p build:playground && pnpm build:ci:storybook:collect-artifacts ", "build:ci:storybook:collect-artifacts": "mkdir -p ts-packages/dist && mv sdk/typescript/packages/react-components/storybook-static ts-packages/dist/storybook ", "build:packages": "run-s build:packages:theme build:packages:react", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2460be7d41..3ac0fd419f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,549 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +catalogs: + default: + '@babel/core': + specifier: ^7.22.10 + version: 7.29.0 + '@babel/helper-simple-access': + specifier: ^7.25.9 + version: 7.27.1 + '@babel/plugin-transform-async-to-generator': + specifier: ^7.22.5 + version: 7.28.6 + '@babel/preset-env': + specifier: ^7.22.10 + version: 7.29.5 + '@babel/preset-react': + specifier: ^7.14.5 + version: 7.28.5 + '@babel/preset-typescript': + specifier: ^7.22.5 + version: 7.28.5 + '@babel/runtime': + specifier: ^7.29.2 + version: 7.29.2 + '@cosmjs/cosmwasm-stargate': + specifier: ^0.32.4 + version: 0.32.4 + '@cosmjs/math': + specifier: ^0.32.4 + version: 0.32.4 + '@cosmjs/stargate': + specifier: ^0.32.4 + version: 0.32.4 + '@emotion/cache': + specifier: ^11.14.0 + version: 11.14.0 + '@emotion/hash': + specifier: ^0.9.2 + version: 0.9.2 + '@emotion/is-prop-valid': + specifier: ^1.4.0 + version: 1.4.0 + '@emotion/memoize': + specifier: ^0.9.0 + version: 0.9.0 + '@emotion/react': + specifier: ^11.13.5 + version: 11.14.0 + '@emotion/serialize': + specifier: ^1.3.3 + version: 1.3.3 + '@emotion/sheet': + specifier: ^1.4.0 + version: 1.4.0 + '@emotion/styled': + specifier: ^11.13.5 + version: 11.14.1 + '@emotion/unitless': + specifier: ^0.10.0 + version: 0.10.0 + '@emotion/use-insertion-effect-with-fallbacks': + specifier: ^1.2.0 + version: 1.2.0 + '@emotion/utils': + specifier: ^1.4.2 + version: 1.4.2 + '@emotion/weak-memoize': + specifier: ^0.4.0 + version: 0.4.0 + '@hookform/resolvers': + specifier: ^2.8.0 + version: 2.9.11 + '@mui/base': + specifier: 5.0.0-beta.40 + version: 5.0.0-beta.40 + '@mui/icons-material': + specifier: ^5.2.0 + version: 5.18.0 + '@mui/lab': + specifier: 5.0.0-alpha.170 + version: 5.0.0-alpha.170 + '@mui/material': + specifier: ^5.2.2 + version: 5.18.0 + '@mui/private-theming': + specifier: ^5.17.1 + version: 5.17.1 + '@mui/styles': + specifier: ^5.18.0 + version: 5.18.0 + '@mui/system': + specifier: ^5.18.0 + version: 5.18.0 + '@mui/utils': + specifier: ^5.7.0 + version: 5.17.1 + '@mui/x-tree-view': + specifier: ^7.11.1 + version: 7.29.10 + '@pmmmwh/react-refresh-webpack-plugin': + specifier: ^0.5.4 + version: 0.5.17 + '@popperjs/core': + specifier: ^2.11.8 + version: 2.11.8 + '@remix-run/router': + specifier: ^1.23.2 + version: 1.23.2 + '@storybook/addon-actions': + specifier: ^6.5.8 + version: 6.5.16 + '@storybook/addon-docs': + specifier: ^6.5.8 + version: 6.5.16 + '@storybook/addon-essentials': + specifier: ^6.5.8 + version: 6.5.16 + '@storybook/addon-interactions': + specifier: ^6.5.8 + version: 6.5.16 + '@storybook/addon-links': + specifier: ^6.5.8 + version: 6.5.16 + '@storybook/builder-webpack5': + specifier: ^6.5.8 + version: 6.5.16 + '@storybook/manager-webpack5': + specifier: ^6.5.8 + version: 6.5.16 + '@storybook/react': + specifier: ^6.5.15 + version: 6.5.16 + '@storybook/testing-library': + specifier: ^0.0.9 + version: 0.0.9 + '@svgr/webpack': + specifier: ^6.1.1 + version: 6.5.1 + '@tanstack/query-core': + specifier: ^5.64.2 + version: 5.100.10 + '@tanstack/react-query': + specifier: ^5.64.2 + version: 5.100.10 + '@tauri-apps/api': + specifier: ^2.10.1 + version: 2.11.0 + '@tauri-apps/cli': + specifier: ^2.10.1 + version: 2.11.1 + '@tauri-apps/plugin-clipboard-manager': + specifier: ^2.3.2 + version: 2.3.2 + '@tauri-apps/plugin-opener': + specifier: ^2.5.3 + version: 2.5.4 + '@tauri-apps/plugin-process': + specifier: ^2.3.1 + version: 2.3.1 + '@tauri-apps/plugin-updater': + specifier: ^2.10.1 + version: 2.10.1 + '@tauri-apps/tauri-forage': + specifier: ^1.0.0-beta.2 + version: 1.0.0-beta.2 + '@testing-library/dom': + specifier: ^10.4.1 + version: 10.4.1 + '@testing-library/jest-dom': + specifier: ^6.9.1 + version: 6.9.1 + '@testing-library/react': + specifier: ^16.3.2 + version: 16.3.2 + '@types/big.js': + specifier: ^6.1.6 + version: 6.2.2 + '@types/bs58': + specifier: ^4.0.1 + version: 4.0.4 + '@types/flat': + specifier: ^5.0.2 + version: 5.0.5 + '@types/jest': + specifier: ^29.5.14 + version: 29.5.14 + '@types/lodash': + specifier: ^4.17.21 + version: 4.17.24 + '@types/minimatch': + specifier: 5.1.2 + version: 5.1.2 + '@types/qrcode.react': + specifier: ^1.0.2 + version: 1.0.5 + '@types/react': + specifier: ^19.2.14 + version: 19.2.14 + '@types/react-dom': + specifier: ^19.2.3 + version: 19.2.3 + '@types/semver': + specifier: ^7.3.8 + version: 7.7.1 + '@types/uuid': + specifier: ^8.3.4 + version: 8.3.4 + '@types/zxcvbn': + specifier: ^4.4.1 + version: 4.4.5 + '@typescript-eslint/eslint-plugin': + specifier: ^5.13.0 + version: 5.62.0 + '@typescript-eslint/parser': + specifier: ^5.13.0 + version: 5.62.0 + axios: + specifier: ^1.16.0 + version: 1.16.0 + babel-loader: + specifier: ^8.3.0 + version: 8.4.1 + base-x: + specifier: ^3.0.11 + version: 3.0.11 + base64-js: + specifier: ^1.5.1 + version: 1.5.1 + bech32: + specifier: ^1.1.4 + version: 1.1.4 + big.js: + specifier: ^6.2.1 + version: 6.2.2 + bn.js: + specifier: ^5.2.3 + version: 5.2.3 + bs58: + specifier: ^4.0.1 + version: 4.0.1 + buffer: + specifier: ^6.0.3 + version: 6.0.3 + clean-webpack-plugin: + specifier: ^4.0.0 + version: 4.0.0 + clipboard-copy: + specifier: ^3.2.0 + version: 3.2.0 + clsx: + specifier: ^1.1.1 + version: 1.2.1 + colornames: + specifier: ^1.1.1 + version: 1.1.1 + css-loader: + specifier: ^6.8.1 + version: 6.11.0 + css-minimizer-webpack-plugin: + specifier: ^3.0.2 + version: 3.4.1 + d3-array: + specifier: ^3.2.4 + version: 3.2.4 + d3-color: + specifier: ^3.1.0 + version: 3.1.0 + d3-format: + specifier: ^1.4.5 + version: 1.4.5 + d3-interpolate: + specifier: ^3.0.1 + version: 3.0.1 + d3-path: + specifier: ^3.1.0 + version: 3.1.0 + d3-scale: + specifier: ^4.0.2 + version: 4.0.2 + d3-shape: + specifier: ^3.2.0 + version: 3.2.0 + d3-time: + specifier: ^3.1.0 + version: 3.1.0 + d3-time-format: + specifier: ^3.0.0 + version: 3.0.0 + date-fns: + specifier: ^2.28.0 + version: 2.30.0 + decimal.js-light: + specifier: ^2.5.1 + version: 2.5.1 + dom-helpers: + specifier: ^5.2.1 + version: 5.2.1 + dotenv-webpack: + specifier: ^7.0.3 + version: 7.1.1 + eslint: + specifier: ^9.26.0 + version: 9.39.4 + eslint-config-airbnb: + specifier: ^19.0.4 + version: 19.0.4 + eslint-config-airbnb-typescript: + specifier: ^16.1.0 + version: 16.2.0 + eslint-config-prettier: + specifier: ^8.5.0 + version: 8.10.2 + eslint-import-resolver-root-import: + specifier: ^1.0.4 + version: 1.0.4 + eslint-plugin-import: + specifier: ^2.25.4 + version: 2.32.0 + eslint-plugin-jest: + specifier: ^26.1.1 + version: 26.9.0 + eslint-plugin-jsx-a11y: + specifier: ^6.5.1 + version: 6.10.2 + eslint-plugin-prettier: + specifier: ^4.0.0 + version: 4.2.5 + eslint-plugin-react: + specifier: ^7.29.2 + version: 7.37.5 + eslint-plugin-react-hooks: + specifier: ^4.3.0 + version: 4.6.2 + eslint-plugin-storybook: + specifier: ^0.5.12 + version: 0.5.13 + eventemitter3: + specifier: ^4.0.7 + version: 4.0.7 + fast-equals: + specifier: ^5.4.0 + version: 5.4.0 + favicons: + specifier: ^7.0.2 + version: 7.2.0 + favicons-webpack-plugin: + specifier: ^5.0.2 + version: 5.0.2 + file-loader: + specifier: ^6.2.0 + version: 6.2.0 + flat: + specifier: ^5.0.2 + version: 5.0.2 + fork-ts-checker-webpack-plugin: + specifier: ^7.2.1 + version: 7.3.0 + hex-rgb: + specifier: ^4.3.0 + version: 4.3.0 + hoist-non-react-statics: + specifier: ^3.3.2 + version: 3.3.2 + html-webpack-plugin: + specifier: ^5.5.3 + version: 5.6.7 + ieee754: + specifier: ^1.2.1 + version: 1.2.1 + internmap: + specifier: ^2.0.3 + version: 2.0.3 + jest: + specifier: ^27.1.0 + version: 27.5.1 + joi: + specifier: ^17.11.0 + version: 17.13.3 + localforage: + specifier: ^1.10.0 + version: 1.10.0 + lodash: + specifier: ^4.17.21 + version: 4.18.1 + lodash.padend: + specifier: ^4.6.1 + version: 4.6.1 + lodash.trimstart: + specifier: ^4.5.1 + version: 4.5.1 + lodash.words: + specifier: ^4.2.0 + version: 4.2.0 + long: + specifier: ^4.0.0 + version: 4.0.0 + mini-css-extract-plugin: + specifier: ^2.7.6 + version: 2.10.2 + nanoclone: + specifier: ^0.2.1 + version: 0.2.1 + notistack: + specifier: ^2.0.3 + version: 2.0.8 + npm-run-all: + specifier: ^4.1.5 + version: 4.1.5 + prettier: + specifier: ^2.8.7 + version: 2.8.8 + prop-types: + specifier: ^15.8.1 + version: 15.8.1 + property-expr: + specifier: ^2.0.6 + version: 2.0.6 + qr.js: + specifier: 0.0.0 + version: 0.0.0 + ramda: + specifier: ^0.28.0 + version: 0.28.0 + react: + specifier: ^19.2.6 + version: 19.2.6 + react-dom: + specifier: ^19.2.6 + version: 19.2.6 + react-error-boundary: + specifier: ^3.1.3 + version: 3.1.4 + react-hook-form: + specifier: ^7.14.2 + version: 7.75.0 + react-is: + specifier: ^19.2.6 + version: 19.2.6 + react-refresh: + specifier: ^0.10.0 + version: 0.10.0 + react-refresh-typescript: + specifier: ^2.0.2 + version: 2.0.12 + react-router: + specifier: ^6.30.3 + version: 6.30.3 + react-router-dom: + specifier: '6' + version: 6.30.3 + react-smooth: + specifier: ^4.0.4 + version: 4.0.4 + react-transition-group: + specifier: ^4.4.5 + version: 4.4.5 + recharts: + specifier: ^2.1.13 + version: 2.15.4 + recharts-scale: + specifier: ^0.4.5 + version: 0.4.5 + rgb-hex: + specifier: ^3.0.0 + version: 3.0.0 + rimraf: + specifier: ^3.0.2 + version: 3.0.2 + safe-buffer: + specifier: ^5.2.1 + version: 5.2.1 + scheduler: + specifier: ^0.27.0 + version: 0.27.0 + semver: + specifier: ^6.3.0 + version: 6.3.1 + string-to-color: + specifier: ^2.2.2 + version: 2.2.2 + style-loader: + specifier: ^3.3.3 + version: 3.3.4 + stylis: + specifier: ^4.2.0 + version: 4.2.0 + thread-loader: + specifier: ^3.0.4 + version: 3.0.4 + tiny-invariant: + specifier: ^1.3.3 + version: 1.3.3 + toposort: + specifier: ^2.0.2 + version: 2.0.2 + ts-jest: + specifier: ^27.0.5 + version: 27.1.5 + ts-loader: + specifier: ^9.4.4 + version: 9.5.7 + tsconfig-paths-webpack-plugin: + specifier: ^3.5.2 + version: 3.5.2 + tweetnacl: + specifier: ^1.0.3 + version: 1.0.3 + tweetnacl-util: + specifier: ^0.15.1 + version: 0.15.1 + url-loader: + specifier: ^4.1.1 + version: 4.1.1 + use-clipboard-copy: + specifier: ^0.2.0 + version: 0.2.0 + uuid: + specifier: ^8.3.2 + version: 8.3.2 + victory-vendor: + specifier: ^36.9.2 + version: 36.9.2 + webpack: + specifier: ^5.88.2 + version: 5.106.2 + webpack-cli: + specifier: ^4.8.0 + version: 4.10.0 + webpack-dev-server: + specifier: ^4.15.1 + version: 4.15.2 + webpack-favicons: + specifier: ^1.3.8 + version: 1.5.43 + webpack-merge: + specifier: ^5.9.0 + version: 5.10.0 + yup: + specifier: ^0.32.9 + version: 0.32.11 + zxcvbn: + specifier: ^4.4.2 + version: 4.4.2 + importers: .: @@ -20,7 +563,7 @@ importers: version: 5.1.2 lerna: specifier: ^7.3.0 - version: 7.4.2(encoding@0.1.13) + version: 7.4.2(@types/node@22.19.19)(encoding@0.1.13) node-gyp: specifier: ^9.3.1 version: 9.4.1 @@ -294,7 +837,7 @@ importers: version: 5.100.10(react@19.2.6) '@tauri-apps/api': specifier: 'catalog:' - version: 2.10.1 + version: 2.11.0 '@tauri-apps/plugin-clipboard-manager': specifier: 'catalog:' version: 2.3.2 @@ -714,139 +1257,6 @@ importers: specifier: 'catalog:' version: 5.10.0 - sdk/typescript/packages/mix-fetch/internal-dev: - dependencies: - '@nymproject/mix-fetch': - specifier: '>=1.4.2-rc.0 || ^1' - version: 1.4.4 - devDependencies: - '@babel/core': - specifier: 'catalog:' - version: 7.29.0 - '@babel/plugin-transform-async-to-generator': - specifier: 'catalog:' - version: 7.28.6(@babel/core@7.29.0) - '@babel/preset-env': - specifier: 'catalog:' - version: 7.29.5(@babel/core@7.29.0) - '@babel/preset-typescript': - specifier: 'catalog:' - version: 7.28.5(@babel/core@7.29.0) - '@types/jest': - specifier: ^27.0.1 - version: 27.5.2 - '@types/node': - specifier: ^16.7.13 - version: 16.18.126 - '@typescript-eslint/eslint-plugin': - specifier: 'catalog:' - version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5) - '@typescript-eslint/parser': - specifier: 'catalog:' - version: 5.62.0(eslint@9.39.4)(typescript@4.9.5) - babel-loader: - specifier: ^9.1.3 - version: 9.2.1(@babel/core@7.29.0)(webpack@5.106.2) - babel-plugin-root-import: - specifier: ^6.6.0 - version: 6.6.0 - clean-webpack-plugin: - specifier: 'catalog:' - version: 4.0.0(webpack@5.106.2) - copy-webpack-plugin: - specifier: ^11.0.0 - version: 11.0.0(webpack@5.106.2) - css-loader: - specifier: 'catalog:' - version: 6.11.0(webpack@5.106.2) - css-minimizer-webpack-plugin: - specifier: ^5.0.1 - version: 5.0.1(webpack@5.106.2) - dotenv-webpack: - specifier: ^8.0.1 - version: 8.1.1(webpack@5.106.2) - eslint: - specifier: 'catalog:' - version: 9.39.4 - eslint-config-airbnb: - specifier: 'catalog:' - version: 19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4))(eslint-plugin-react-hooks@5.2.0(eslint@9.39.4))(eslint-plugin-react@7.37.5(eslint@9.39.4))(eslint@9.39.4) - eslint-config-airbnb-typescript: - specifier: 'catalog:' - version: 16.2.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint@9.39.4) - eslint-config-prettier: - specifier: 'catalog:' - version: 8.10.2(eslint@9.39.4) - eslint-import-resolver-root-import: - specifier: 'catalog:' - version: 1.0.4(babel-plugin-root-import@6.6.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)) - eslint-plugin-import: - specifier: 'catalog:' - version: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4) - eslint-plugin-jest: - specifier: 'catalog:' - version: 26.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(jest@27.5.1)(typescript@4.9.5) - eslint-plugin-jsx-a11y: - specifier: 'catalog:' - version: 6.10.2(eslint@9.39.4) - eslint-plugin-prettier: - specifier: 'catalog:' - version: 4.2.5(eslint-config-prettier@8.10.2(eslint@9.39.4))(eslint@9.39.4)(prettier@2.8.8) - file-loader: - specifier: 'catalog:' - version: 6.2.0(webpack@5.106.2) - fork-ts-checker-webpack-plugin: - specifier: ^8.0.0 - version: 8.0.0(typescript@4.9.5)(webpack@5.106.2) - html-webpack-plugin: - specifier: 'catalog:' - version: 5.6.7(webpack@5.106.2) - jest: - specifier: 'catalog:' - version: 27.5.1 - mini-css-extract-plugin: - specifier: 'catalog:' - version: 2.10.2(webpack@5.106.2) - npm-run-all: - specifier: 'catalog:' - version: 4.1.5 - prettier: - specifier: 'catalog:' - version: 2.8.8 - style-loader: - specifier: 'catalog:' - version: 3.3.4(webpack@5.106.2) - thread-loader: - specifier: ^4.0.2 - version: 4.0.4(webpack@5.106.2) - ts-jest: - specifier: 'catalog:' - version: 27.1.5(@babel/core@7.29.0)(@types/jest@27.5.2)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) - ts-loader: - specifier: 'catalog:' - version: 9.5.7(typescript@4.9.5)(webpack@5.106.2) - tsconfig-paths-webpack-plugin: - specifier: ^4.1.0 - version: 4.2.0 - typescript: - specifier: ^4.6.2 - version: 4.9.5 - url-loader: - specifier: 'catalog:' - version: 4.1.1(file-loader@6.2.0(webpack@5.106.2))(webpack@5.106.2) - webpack: - specifier: 'catalog:' - version: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) - webpack-cli: - specifier: ^5.1.4 - version: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.106.2) - webpack-dev-server: - specifier: 'catalog:' - version: 4.15.2(webpack-cli@5.1.4)(webpack@5.106.2) - webpack-merge: - specifier: 'catalog:' - version: 5.10.0 - sdk/typescript/packages/mui-theme: dependencies: '@mui/material': @@ -921,7 +1331,7 @@ importers: version: 3.0.2 ts-jest: specifier: 'catalog:' - version: 27.1.5(@babel/core@7.29.0)(@types/jest@27.5.2)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) + version: 27.1.5(@babel/core@7.29.0)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) typescript: specifier: ^4.6.2 version: 4.9.5 @@ -1087,7 +1497,7 @@ importers: version: 3.0.2 ts-jest: specifier: 'catalog:' - version: 27.1.5(@babel/core@7.29.0)(@types/jest@27.5.2)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) + version: 27.1.5(@babel/core@7.29.0)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) tsconfig-paths-webpack-plugin: specifier: 'catalog:' version: 3.5.2 @@ -1221,7 +1631,7 @@ importers: version: 3.0.2 ts-jest: specifier: 'catalog:' - version: 27.1.5(@babel/core@7.29.0)(@types/jest@27.5.2)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) + version: 27.1.5(@babel/core@7.29.0)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) typescript: specifier: ^4.6.2 version: 4.9.5 @@ -3687,9 +4097,6 @@ packages: '@nymproject/contract-clients@1.4.1': resolution: {integrity: sha512-HuJZ4Hv+Rl6ZZEtCHKgurNLJapM+QQRJlGkevFH2a4UdqUqF9omUkUi3AVes4679dPoSFgvA7plyVSDBdbgV6w==} - '@nymproject/mix-fetch@1.4.4': - resolution: {integrity: sha512-sdyXXJG7sYv2OFOEf6FYm7HglKfMvJmJjrQC3Rbusy5rH5C2ajg2KyuBbZReLgIIbkkx3mK8sc5WRUOKTcKt2Q==} - '@nymproject/nym-validator-client@0.18.0': resolution: {integrity: sha512-FO1T15S2BJVuMoPA2yOaH40aD3hKJPKJVyX5ix7eJEbBWIdsYNoVeVc/soHhaAU1FIy2uU0G/FZQkaUYJGGb7Q==} @@ -4531,9 +4938,6 @@ packages: '@tanstack/virtual-core@3.14.0': resolution: {integrity: sha512-JLANqGy/D6k4Ujmh8Tr25lGimuOXNiaVyXaCAZS0W+1390sADdGnyUdSWNIfd49gebtIxGMij4IktRVzrdr12Q==} - '@tauri-apps/api@2.10.1': - resolution: {integrity: sha512-hKL/jWf293UDSUN09rR69hrToyIXBb8CjGaWC7gfinvnQrBVvnLr08FeFi38gxtugAVyVcTa5/FD/Xnkb1siBw==} - '@tauri-apps/api@2.11.0': resolution: {integrity: sha512-7CinYODhky9lmO23xHnUFv0Xt43fbtWMyxZcLcRBlFkcgXKuEirBvHpmtJ89YMhyeGcq20Wuc47Fa4XjyniywA==} @@ -4832,9 +5236,6 @@ packages: '@types/istanbul-reports@3.0.4': resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} - '@types/jest@27.5.2': - resolution: {integrity: sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==} - '@types/jest@29.5.14': resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} @@ -5400,25 +5801,11 @@ packages: webpack: 4.x.x || 5.x.x webpack-cli: 4.x.x - '@webpack-cli/configtest@2.1.1': - resolution: {integrity: sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==} - engines: {node: '>=14.15.0'} - peerDependencies: - webpack: 5.x.x - webpack-cli: 5.x.x - '@webpack-cli/info@1.5.0': resolution: {integrity: sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==} peerDependencies: webpack-cli: 4.x.x - '@webpack-cli/info@2.0.2': - resolution: {integrity: sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==} - engines: {node: '>=14.15.0'} - peerDependencies: - webpack: 5.x.x - webpack-cli: 5.x.x - '@webpack-cli/serve@1.7.0': resolution: {integrity: sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==} peerDependencies: @@ -5428,17 +5815,6 @@ packages: webpack-dev-server: optional: true - '@webpack-cli/serve@2.0.5': - resolution: {integrity: sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==} - engines: {node: '>=14.15.0'} - peerDependencies: - webpack: 5.x.x - webpack-cli: 5.x.x - webpack-dev-server: '*' - peerDependenciesMeta: - webpack-dev-server: - optional: true - '@xtuc/ieee754@1.2.0': resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} @@ -5855,13 +6231,6 @@ packages: '@babel/core': ^7.0.0 webpack: '>=2' - babel-loader@9.2.1: - resolution: {integrity: sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==} - engines: {node: '>= 14.15.0'} - peerDependencies: - '@babel/core': ^7.12.0 - webpack: '>=5' - babel-plugin-add-react-displayname@0.0.5: resolution: {integrity: sha512-LY3+Y0XVDYcShHHorshrDbt4KFWL4bSeniCtl4SYZbask+Syngk1uMPCeN9+nSiZo6zX5s0RTq/J9Pnaaf/KHw==} @@ -6483,10 +6852,6 @@ packages: comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} - commander@10.0.1: - resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} - engines: {node: '>=14'} - commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -6506,9 +6871,6 @@ packages: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} - common-path-prefix@3.0.0: - resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} - commondir@1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} @@ -6619,12 +6981,6 @@ packages: copy-to-clipboard@3.3.3: resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} - copy-webpack-plugin@11.0.0: - resolution: {integrity: sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==} - engines: {node: '>= 14.15.0'} - peerDependencies: - webpack: ^5.1.0 - core-js-compat@3.49.0: resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==} @@ -6709,12 +7065,6 @@ packages: peerDependencies: postcss: ^8.0.9 - css-declaration-sorter@7.4.0: - resolution: {integrity: sha512-LTuzjPoyA2vMGKKcaOqKSp7Ub2eGrNfKiZH4LpezxpNrsICGCSFvsQOI29psISxNZtaXibkC2CXzrQ5enMeGGw==} - engines: {node: ^14 || ^16 || >=18} - peerDependencies: - postcss: ^8.0.9 - css-loader@3.6.0: resolution: {integrity: sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==} engines: {node: '>= 8.9.0'} @@ -6758,31 +7108,6 @@ packages: esbuild: optional: true - css-minimizer-webpack-plugin@5.0.1: - resolution: {integrity: sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==} - engines: {node: '>= 14.15.0'} - peerDependencies: - '@parcel/css': '*' - '@swc/css': '*' - clean-css: '*' - csso: '*' - esbuild: '*' - lightningcss: '*' - webpack: ^5.0.0 - peerDependenciesMeta: - '@parcel/css': - optional: true - '@swc/css': - optional: true - clean-css: - optional: true - csso: - optional: true - esbuild: - optional: true - lightningcss: - optional: true - css-select@4.3.0: resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} @@ -6826,36 +7151,18 @@ packages: peerDependencies: postcss: ^8.2.15 - cssnano-preset-default@6.1.2: - resolution: {integrity: sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - cssnano-utils@3.1.0: resolution: {integrity: sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - cssnano-utils@4.0.2: - resolution: {integrity: sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - cssnano@5.1.15: resolution: {integrity: sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - cssnano@6.1.2: - resolution: {integrity: sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - csso@4.2.0: resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==} engines: {node: '>=8.0.0'} @@ -7271,12 +7578,6 @@ packages: peerDependencies: webpack: ^4 || ^5 - dotenv-webpack@8.1.1: - resolution: {integrity: sha512-+TY/AJ2k9bU2EML3mxgLmaAvEcqs1Wbv6deCIUSI3eW3Xeo8LBQumYib6puyaSwbjC9JCzg/y5Pwjd/lePX04w==} - engines: {node: '>=10'} - peerDependencies: - webpack: ^4 || ^5 - dotenv@16.3.2: resolution: {integrity: sha512-HTlk5nmhkm8F6JcdXvHIzaorzCoziNQT9mGxLPVXW8wJF1TiGSL60ZGB4gHWabHOaMmWmhvk2/lPHfnBiT78AQ==} engines: {node: '>=12'} @@ -7902,10 +8203,6 @@ packages: resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} engines: {node: '>=8'} - find-cache-dir@4.0.0: - resolution: {integrity: sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==} - engines: {node: '>=14.16'} - find-root@1.1.0: resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} @@ -7929,10 +8226,6 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - find-up@6.3.0: - resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - flat-cache@3.2.0: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} @@ -8019,13 +8312,6 @@ packages: vue-template-compiler: optional: true - fork-ts-checker-webpack-plugin@8.0.0: - resolution: {integrity: sha512-mX3qW3idpueT2klaQXBzrIM/pHw+T0B/V9KHEvNrqijTq9NFnMZU6oreVxDYcf33P8a5cW+67PjodNHthGnNVg==} - engines: {node: '>=12.13.0', yarn: '>=1.0.0'} - peerDependencies: - typescript: '>3.6.0' - webpack: ^5.11.0 - form-data@3.0.4: resolution: {integrity: sha512-f0cRzm6dkyVYV3nPoooP8XlccPQukegwhAnpoLcXy+X+A8KfpGOoXwDr9FLZd3wzgLaBGQBE3lY93Zm/i1JvIQ==} engines: {node: '>= 6'} @@ -8266,10 +8552,6 @@ packages: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} - globby@13.2.2: - resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - globby@6.1.0: resolution: {integrity: sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==} engines: {node: '>=0.10.0'} @@ -8691,10 +8973,6 @@ packages: resolution: {integrity: sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==} engines: {node: '>= 0.10'} - interpret@3.1.1: - resolution: {integrity: sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==} - engines: {node: '>=10.13.0'} - ip-address@10.2.0: resolution: {integrity: sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==} engines: {node: '>= 12'} @@ -9657,10 +9935,6 @@ packages: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} - lilconfig@3.1.3: - resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} - engines: {node: '>=14'} - lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -9715,10 +9989,6 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} - locate-path@7.2.0: - resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - lodash-es@4.18.1: resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} @@ -10638,10 +10908,6 @@ packages: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} - p-limit@4.0.0: - resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - p-locate@2.0.0: resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} engines: {node: '>=4'} @@ -10658,10 +10924,6 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} - p-locate@6.0.0: - resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - p-map-series@2.1.0: resolution: {integrity: sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q==} engines: {node: '>=8'} @@ -10804,10 +11066,6 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} - path-exists@5.0.0: - resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} - engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} @@ -10918,10 +11176,6 @@ packages: resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==} engines: {node: '>=10'} - pkg-dir@7.0.0: - resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==} - engines: {node: '>=14.16'} - pnp-webpack-plugin@1.6.4: resolution: {integrity: sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==} engines: {node: '>=6'} @@ -10943,84 +11197,42 @@ packages: peerDependencies: postcss: ^8.2.2 - postcss-calc@9.0.1: - resolution: {integrity: sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.2.2 - postcss-colormin@5.3.1: resolution: {integrity: sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-colormin@6.1.0: - resolution: {integrity: sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-convert-values@5.1.3: resolution: {integrity: sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-convert-values@6.1.0: - resolution: {integrity: sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-discard-comments@5.1.2: resolution: {integrity: sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-discard-comments@6.0.2: - resolution: {integrity: sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-discard-duplicates@5.1.0: resolution: {integrity: sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-discard-duplicates@6.0.3: - resolution: {integrity: sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-discard-empty@5.1.1: resolution: {integrity: sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-discard-empty@6.0.3: - resolution: {integrity: sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-discard-overridden@5.1.0: resolution: {integrity: sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-discard-overridden@6.0.2: - resolution: {integrity: sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-flexbugs-fixes@4.2.1: resolution: {integrity: sha512-9SiofaZ9CWpQWxOwRh1b/r85KD5y7GgvsNt1056k6OYLvWUun0czCvogfJgylC22uJTwW1KzY3Gz65NZRlvoiQ==} @@ -11037,72 +11249,36 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-merge-longhand@6.0.5: - resolution: {integrity: sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-merge-rules@5.1.4: resolution: {integrity: sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-merge-rules@6.1.1: - resolution: {integrity: sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-minify-font-values@5.1.0: resolution: {integrity: sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-minify-font-values@6.1.0: - resolution: {integrity: sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-minify-gradients@5.1.1: resolution: {integrity: sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-minify-gradients@6.0.3: - resolution: {integrity: sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-minify-params@5.1.4: resolution: {integrity: sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-minify-params@6.1.0: - resolution: {integrity: sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-minify-selectors@5.2.1: resolution: {integrity: sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-minify-selectors@6.0.4: - resolution: {integrity: sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-modules-extract-imports@2.0.0: resolution: {integrity: sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==} engines: {node: '>= 6'} @@ -11148,144 +11324,72 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-normalize-charset@6.0.2: - resolution: {integrity: sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-normalize-display-values@5.1.0: resolution: {integrity: sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-normalize-display-values@6.0.2: - resolution: {integrity: sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-normalize-positions@5.1.1: resolution: {integrity: sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-normalize-positions@6.0.2: - resolution: {integrity: sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-normalize-repeat-style@5.1.1: resolution: {integrity: sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-normalize-repeat-style@6.0.2: - resolution: {integrity: sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-normalize-string@5.1.0: resolution: {integrity: sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-normalize-string@6.0.2: - resolution: {integrity: sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-normalize-timing-functions@5.1.0: resolution: {integrity: sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-normalize-timing-functions@6.0.2: - resolution: {integrity: sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-normalize-unicode@5.1.1: resolution: {integrity: sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-normalize-unicode@6.1.0: - resolution: {integrity: sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-normalize-url@5.1.0: resolution: {integrity: sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-normalize-url@6.0.2: - resolution: {integrity: sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-normalize-whitespace@5.1.1: resolution: {integrity: sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-normalize-whitespace@6.0.2: - resolution: {integrity: sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-ordered-values@5.1.3: resolution: {integrity: sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-ordered-values@6.0.2: - resolution: {integrity: sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-reduce-initial@5.1.2: resolution: {integrity: sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-reduce-initial@6.1.0: - resolution: {integrity: sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-reduce-transforms@5.1.0: resolution: {integrity: sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-reduce-transforms@6.0.2: - resolution: {integrity: sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-selector-parser@6.1.2: resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} engines: {node: '>=4'} @@ -11300,24 +11404,12 @@ packages: peerDependencies: postcss: ^8.2.15 - postcss-svgo@6.0.3: - resolution: {integrity: sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==} - engines: {node: ^14 || ^16 || >= 18} - peerDependencies: - postcss: ^8.4.31 - postcss-unique-selectors@5.1.1: resolution: {integrity: sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 - postcss-unique-selectors@6.0.4: - resolution: {integrity: sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} @@ -11763,6 +11855,7 @@ packages: recharts@2.15.4: resolution: {integrity: sha512-UT/q6fwS3c1dHbXv2uFgYJ9BMFHu3fwnd7AYZaEQhXuYQ4hgsxLvsUXzGdKeZrW5xopzDCvuA2N41WJ88I7zIw==} engines: {node: '>=14'} + deprecated: 1.x and 2.x branches are no longer active. Bump to Recharts v3 to receive latest features and bugfixes. See https://github.com/recharts/recharts/wiki/3.0-migration-guide peerDependencies: react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 @@ -11771,10 +11864,6 @@ packages: resolution: {integrity: sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==} engines: {node: '>= 0.10'} - rechoir@0.8.0: - resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==} - engines: {node: '>= 10.13.0'} - redent@1.0.0: resolution: {integrity: sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g==} engines: {node: '>=0.10.0'} @@ -12209,10 +12298,6 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} - slash@4.0.0: - resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} - engines: {node: '>=12'} - smart-buffer@4.2.0: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} @@ -12553,12 +12638,6 @@ packages: peerDependencies: postcss: ^8.2.15 - stylehacks@6.1.1: - resolution: {integrity: sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==} - engines: {node: ^14 || ^16 || >=18.0} - peerDependencies: - postcss: ^8.4.31 - stylis@4.2.0: resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} @@ -12730,12 +12809,6 @@ packages: peerDependencies: webpack: ^4.27.0 || ^5.0.0 - thread-loader@4.0.4: - resolution: {integrity: sha512-tXagu6Hivd03wB2tiS1bqvw345sc7mKei32EgpYpq31ZLes9FN0mEK2nKzXLRFgwt3PsBB0E/MZDp159rDoqwg==} - engines: {node: '>= 16.10.0'} - peerDependencies: - webpack: ^5.0.0 - thread-stream@0.15.2: resolution: {integrity: sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==} @@ -12943,10 +13016,6 @@ packages: tsconfig-paths-webpack-plugin@3.5.2: resolution: {integrity: sha512-EhnfjHbzm5IYI9YPNVIxx1moxMI4bpHD2e0zTXeDNQcwjjRaGepP7IhTHJkyDBG0CAOoxRfe7jCG630Ou+C6Pw==} - tsconfig-paths-webpack-plugin@4.2.0: - resolution: {integrity: sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA==} - engines: {node: '>=10.13.0'} - tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} @@ -13484,23 +13553,6 @@ packages: webpack-dev-server: optional: true - webpack-cli@5.1.4: - resolution: {integrity: sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==} - engines: {node: '>=14.15.0'} - hasBin: true - peerDependencies: - '@webpack-cli/generators': '*' - webpack: 5.x.x - webpack-bundle-analyzer: '*' - webpack-dev-server: '*' - peerDependenciesMeta: - '@webpack-cli/generators': - optional: true - webpack-bundle-analyzer: - optional: true - webpack-dev-server: - optional: true - webpack-dev-middleware@3.7.3: resolution: {integrity: sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==} engines: {node: '>= 6'} @@ -13809,10 +13861,6 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - yocto-queue@1.2.2: - resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} - engines: {node: '>=12.20'} - yup@0.32.11: resolution: {integrity: sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==} engines: {node: '>=10'} @@ -15938,10 +15986,12 @@ snapshots: '@img/sharp-win32-x64@0.33.5': optional: true - '@inquirer/external-editor@1.0.3': + '@inquirer/external-editor@1.0.3(@types/node@22.19.19)': dependencies: chardet: 2.1.1 iconv-lite: 0.7.2 + optionalDependencies: + '@types/node': 22.19.19 '@interchain-ui/react@1.26.3(@types/react@19.2.14)(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: @@ -16441,7 +16491,7 @@ snapshots: execa: 5.0.0 strong-log-transformer: 2.1.0 - '@lerna/create@7.4.2(encoding@0.1.13)(typescript@5.9.3)': + '@lerna/create@7.4.2(@types/node@22.19.19)(encoding@0.1.13)(typescript@5.9.3)': dependencies: '@lerna/child-process': 7.4.2 '@npmcli/run-script': 6.0.2 @@ -16467,7 +16517,7 @@ snapshots: has-unicode: 2.0.1 ini: 1.3.8 init-package-json: 5.0.0 - inquirer: 8.2.7 + inquirer: 8.2.7(@types/node@22.19.19) is-ci: 3.0.1 is-stream: 2.0.0 js-yaml: 4.1.0 @@ -17040,7 +17090,7 @@ snapshots: lru-cache: 7.18.3 npm-pick-manifest: 8.0.2 proc-log: 3.0.0 - promise-inflight: 1.0.1 + promise-inflight: 1.0.1(bluebird@3.7.2) promise-retry: 2.0.1 semver: 7.8.0 which: 3.0.1 @@ -17137,8 +17187,6 @@ snapshots: '@nymproject/contract-clients@1.4.1': {} - '@nymproject/mix-fetch@1.4.4': {} - '@nymproject/nym-validator-client@0.18.0': dependencies: '@cosmjs/cosmwasm-stargate': 0.25.6 @@ -18726,8 +18774,6 @@ snapshots: '@tanstack/virtual-core@3.14.0': {} - '@tauri-apps/api@2.10.1': {} - '@tauri-apps/api@2.11.0': {} '@tauri-apps/cli-darwin-arm64@2.11.1': @@ -18779,7 +18825,7 @@ snapshots: '@tauri-apps/plugin-clipboard-manager@2.3.2': dependencies: - '@tauri-apps/api': 2.10.1 + '@tauri-apps/api': 2.11.0 '@tauri-apps/plugin-opener@2.5.4': dependencies: @@ -18787,11 +18833,11 @@ snapshots: '@tauri-apps/plugin-process@2.3.1': dependencies: - '@tauri-apps/api': 2.10.1 + '@tauri-apps/api': 2.11.0 '@tauri-apps/plugin-updater@2.10.1': dependencies: - '@tauri-apps/api': 2.10.1 + '@tauri-apps/api': 2.11.0 '@tauri-apps/tauri-forage@1.0.0-beta.2': dependencies: @@ -19038,11 +19084,6 @@ snapshots: dependencies: '@types/istanbul-lib-report': 3.0.3 - '@types/jest@27.5.2': - dependencies: - jest-matcher-utils: 27.5.1 - pretty-format: 27.5.1 - '@types/jest@29.5.14': dependencies: expect: 29.7.0 @@ -19853,34 +19894,17 @@ snapshots: webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.106.2) - '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.106.2)': - dependencies: - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.106.2) - '@webpack-cli/info@1.5.0(webpack-cli@4.10.0)': dependencies: envinfo: 7.21.0 webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.106.2) - '@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.106.2)': - dependencies: - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.106.2) - '@webpack-cli/serve@1.7.0(webpack-cli@4.10.0)(webpack-dev-server@4.15.2)': dependencies: webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.106.2) optionalDependencies: webpack-dev-server: 4.15.2(webpack-cli@4.10.0)(webpack@5.106.2) - '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack-dev-server@4.15.2)(webpack@5.106.2)': - dependencies: - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.106.2) - optionalDependencies: - webpack-dev-server: 4.15.2(webpack-cli@5.1.4)(webpack@5.106.2) - '@xtuc/ieee754@1.2.0': {} '@xtuc/long@4.2.2': {} @@ -20347,13 +20371,6 @@ snapshots: schema-utils: 2.7.1 webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) - babel-loader@9.2.1(@babel/core@7.29.0)(webpack@5.106.2): - dependencies: - '@babel/core': 7.29.0 - find-cache-dir: 4.0.0 - schema-utils: 4.3.3 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) - babel-plugin-add-react-displayname@0.0.5: {} babel-plugin-apply-mdx-type-prop@1.6.22(@babel/core@7.12.9): @@ -20827,7 +20844,7 @@ snapshots: minipass-pipeline: 1.2.4 mkdirp: 1.0.4 p-map: 4.0.0 - promise-inflight: 1.0.1 + promise-inflight: 1.0.1(bluebird@3.7.2) rimraf: 3.0.2 ssri: 9.0.1 tar: 6.2.1 @@ -21154,8 +21171,6 @@ snapshots: comma-separated-tokens@2.0.3: {} - commander@10.0.1: {} - commander@2.20.3: {} commander@4.1.1: {} @@ -21166,8 +21181,6 @@ snapshots: commander@8.3.0: {} - common-path-prefix@3.0.0: {} - commondir@1.0.1: {} compare-func@2.0.0: @@ -21302,16 +21315,6 @@ snapshots: dependencies: toggle-selection: 1.0.6 - copy-webpack-plugin@11.0.0(webpack@5.106.2): - dependencies: - fast-glob: 3.3.3 - glob-parent: 6.0.2 - globby: 13.2.2 - normalize-path: 3.0.0 - schema-utils: 4.3.3 - serialize-javascript: 6.0.2 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) - core-js-compat@3.49.0: dependencies: browserslist: 4.28.2 @@ -21454,10 +21457,6 @@ snapshots: dependencies: postcss: 8.5.14 - css-declaration-sorter@7.4.0(postcss@8.5.14): - dependencies: - postcss: 8.5.14 - css-loader@3.6.0(webpack@4.47.0): dependencies: camelcase: 5.3.1 @@ -21512,16 +21511,6 @@ snapshots: source-map: 0.6.1 webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) - css-minimizer-webpack-plugin@5.0.1(webpack@5.106.2): - dependencies: - '@jridgewell/trace-mapping': 0.3.31 - cssnano: 6.1.2(postcss@8.5.14) - jest-worker: 29.7.0 - postcss: 8.5.14 - schema-utils: 4.3.3 - serialize-javascript: 6.0.2 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) - css-select@4.3.0: dependencies: boolbase: 1.0.0 @@ -21602,48 +21591,10 @@ snapshots: postcss-svgo: 5.1.0(postcss@8.5.14) postcss-unique-selectors: 5.1.1(postcss@8.5.14) - cssnano-preset-default@6.1.2(postcss@8.5.14): - dependencies: - browserslist: 4.28.2 - css-declaration-sorter: 7.4.0(postcss@8.5.14) - cssnano-utils: 4.0.2(postcss@8.5.14) - postcss: 8.5.14 - postcss-calc: 9.0.1(postcss@8.5.14) - postcss-colormin: 6.1.0(postcss@8.5.14) - postcss-convert-values: 6.1.0(postcss@8.5.14) - postcss-discard-comments: 6.0.2(postcss@8.5.14) - postcss-discard-duplicates: 6.0.3(postcss@8.5.14) - postcss-discard-empty: 6.0.3(postcss@8.5.14) - postcss-discard-overridden: 6.0.2(postcss@8.5.14) - postcss-merge-longhand: 6.0.5(postcss@8.5.14) - postcss-merge-rules: 6.1.1(postcss@8.5.14) - postcss-minify-font-values: 6.1.0(postcss@8.5.14) - postcss-minify-gradients: 6.0.3(postcss@8.5.14) - postcss-minify-params: 6.1.0(postcss@8.5.14) - postcss-minify-selectors: 6.0.4(postcss@8.5.14) - postcss-normalize-charset: 6.0.2(postcss@8.5.14) - postcss-normalize-display-values: 6.0.2(postcss@8.5.14) - postcss-normalize-positions: 6.0.2(postcss@8.5.14) - postcss-normalize-repeat-style: 6.0.2(postcss@8.5.14) - postcss-normalize-string: 6.0.2(postcss@8.5.14) - postcss-normalize-timing-functions: 6.0.2(postcss@8.5.14) - postcss-normalize-unicode: 6.1.0(postcss@8.5.14) - postcss-normalize-url: 6.0.2(postcss@8.5.14) - postcss-normalize-whitespace: 6.0.2(postcss@8.5.14) - postcss-ordered-values: 6.0.2(postcss@8.5.14) - postcss-reduce-initial: 6.1.0(postcss@8.5.14) - postcss-reduce-transforms: 6.0.2(postcss@8.5.14) - postcss-svgo: 6.0.3(postcss@8.5.14) - postcss-unique-selectors: 6.0.4(postcss@8.5.14) - cssnano-utils@3.1.0(postcss@8.5.14): dependencies: postcss: 8.5.14 - cssnano-utils@4.0.2(postcss@8.5.14): - dependencies: - postcss: 8.5.14 - cssnano@5.1.15(postcss@8.5.14): dependencies: cssnano-preset-default: 5.2.14(postcss@8.5.14) @@ -21651,12 +21602,6 @@ snapshots: postcss: 8.5.14 yaml: 1.10.3 - cssnano@6.1.2(postcss@8.5.14): - dependencies: - cssnano-preset-default: 6.1.2(postcss@8.5.14) - lilconfig: 3.1.3 - postcss: 8.5.14 - csso@4.2.0: dependencies: css-tree: 1.1.3 @@ -22070,11 +22015,6 @@ snapshots: dotenv-defaults: 2.0.2 webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) - dotenv-webpack@8.1.1(webpack@5.106.2): - dependencies: - dotenv-defaults: 2.0.2 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) - dotenv@16.3.2: {} dotenv@8.6.0: {} @@ -22426,17 +22366,6 @@ snapshots: object.assign: 4.1.7 object.entries: 1.1.9 - eslint-config-airbnb@19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4))(eslint-plugin-react-hooks@5.2.0(eslint@9.39.4))(eslint-plugin-react@7.37.5(eslint@9.39.4))(eslint@9.39.4): - dependencies: - eslint: 9.39.4 - eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint@9.39.4) - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4) - eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.4) - eslint-plugin-react: 7.37.5(eslint@9.39.4) - eslint-plugin-react-hooks: 5.2.0(eslint@9.39.4) - object.assign: 4.1.7 - object.entries: 1.1.9 - eslint-config-airbnb@19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4))(eslint-plugin-react-hooks@4.6.2(eslint@9.39.4))(eslint-plugin-react@7.37.5(eslint@9.39.4))(eslint@9.39.4): dependencies: eslint: 9.39.4 @@ -22504,15 +22433,6 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-root-import@1.0.4(babel-plugin-root-import@6.6.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)): - dependencies: - babel-plugin-root-import: 6.6.0 - eslint-import-resolver-node: 0.3.10 - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4) - json5: 2.2.3 - transitivePeerDependencies: - - supports-color - eslint-import-resolver-root-import@1.0.4(babel-plugin-root-import@6.6.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)): dependencies: babel-plugin-root-import: 6.6.0 @@ -23299,11 +23219,6 @@ snapshots: make-dir: 3.1.0 pkg-dir: 4.2.0 - find-cache-dir@4.0.0: - dependencies: - common-path-prefix: 3.0.0 - pkg-dir: 7.0.0 - find-root@1.1.0: {} find-up@1.1.2: @@ -23330,11 +23245,6 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - find-up@6.3.0: - dependencies: - locate-path: 7.2.0 - path-exists: 5.0.0 - flat-cache@3.2.0: dependencies: flatted: 3.4.2 @@ -23450,23 +23360,6 @@ snapshots: typescript: 5.9.3 webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) - fork-ts-checker-webpack-plugin@8.0.0(typescript@4.9.5)(webpack@5.106.2): - dependencies: - '@babel/code-frame': 7.29.0 - chalk: 4.1.2 - chokidar: 3.6.0 - cosmiconfig: 7.1.0 - deepmerge: 4.3.1 - fs-extra: 10.1.0 - memfs: 3.5.3 - minimatch: 3.1.5 - node-abort-controller: 3.1.1 - schema-utils: 3.3.0 - semver: 7.8.0 - tapable: 2.3.3 - typescript: 4.9.5 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) - form-data@3.0.4: dependencies: asynckit: 0.4.0 @@ -23759,14 +23652,6 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 - globby@13.2.2: - dependencies: - dir-glob: 3.0.1 - fast-glob: 3.3.3 - ignore: 5.3.2 - merge2: 1.4.1 - slash: 4.0.0 - globby@6.1.0: dependencies: array-union: 1.0.2 @@ -24277,9 +24162,9 @@ snapshots: inline-style-parser@0.2.7: {} - inquirer@8.2.7: + inquirer@8.2.7(@types/node@22.19.19): dependencies: - '@inquirer/external-editor': 1.0.3 + '@inquirer/external-editor': 1.0.3(@types/node@22.19.19) ansi-escapes: 4.3.2 chalk: 4.1.2 cli-cursor: 3.1.0 @@ -24309,8 +24194,6 @@ snapshots: interpret@2.2.0: {} - interpret@3.1.1: {} - ip-address@10.2.0: {} ip@2.0.1: {} @@ -25679,10 +25562,10 @@ snapshots: lefthook-windows-arm64: 1.13.6 lefthook-windows-x64: 1.13.6 - lerna@7.4.2(encoding@0.1.13): + lerna@7.4.2(@types/node@22.19.19)(encoding@0.1.13): dependencies: '@lerna/child-process': 7.4.2 - '@lerna/create': 7.4.2(encoding@0.1.13)(typescript@5.9.3) + '@lerna/create': 7.4.2(@types/node@22.19.19)(encoding@0.1.13)(typescript@5.9.3) '@npmcli/run-script': 6.0.2 '@nx/devkit': 16.10.0(nx@16.10.0) '@octokit/plugin-enterprise-rest': 6.0.1 @@ -25710,7 +25593,7 @@ snapshots: import-local: 3.1.0 ini: 1.3.8 init-package-json: 5.0.0 - inquirer: 8.2.7 + inquirer: 8.2.7(@types/node@22.19.19) is-ci: 3.0.1 is-stream: 2.0.0 jest-diff: 29.7.0 @@ -25810,8 +25693,6 @@ snapshots: lilconfig@2.1.0: {} - lilconfig@3.1.3: {} - lines-and-columns@1.2.4: {} lines-and-columns@2.0.4: {} @@ -25877,10 +25758,6 @@ snapshots: dependencies: p-locate: 5.0.0 - locate-path@7.2.0: - dependencies: - p-locate: 6.0.0 - lodash-es@4.18.1: {} lodash.debounce@4.0.8: {} @@ -27108,10 +26985,6 @@ snapshots: dependencies: yocto-queue: 0.1.0 - p-limit@4.0.0: - dependencies: - yocto-queue: 1.2.2 - p-locate@2.0.0: dependencies: p-limit: 1.3.0 @@ -27128,10 +27001,6 @@ snapshots: dependencies: p-limit: 3.1.0 - p-locate@6.0.0: - dependencies: - p-limit: 4.0.0 - p-map-series@2.1.0: {} p-map@2.1.0: {} @@ -27301,8 +27170,6 @@ snapshots: path-exists@4.0.0: {} - path-exists@5.0.0: {} - path-is-absolute@1.0.1: {} path-is-inside@1.0.2: {} @@ -27401,10 +27268,6 @@ snapshots: dependencies: find-up: 5.0.0 - pkg-dir@7.0.0: - dependencies: - find-up: 6.3.0 - pnp-webpack-plugin@1.6.4(typescript@4.9.5): dependencies: ts-pnp: 1.2.0(typescript@4.9.5) @@ -27425,12 +27288,6 @@ snapshots: postcss-selector-parser: 6.1.2 postcss-value-parser: 4.2.0 - postcss-calc@9.0.1(postcss@8.5.14): - dependencies: - postcss: 8.5.14 - postcss-selector-parser: 6.1.2 - postcss-value-parser: 4.2.0 - postcss-colormin@5.3.1(postcss@8.5.14): dependencies: browserslist: 4.28.2 @@ -27439,58 +27296,28 @@ snapshots: postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-colormin@6.1.0(postcss@8.5.14): - dependencies: - browserslist: 4.28.2 - caniuse-api: 3.0.0 - colord: 2.9.3 - postcss: 8.5.14 - postcss-value-parser: 4.2.0 - postcss-convert-values@5.1.3(postcss@8.5.14): dependencies: browserslist: 4.28.2 postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-convert-values@6.1.0(postcss@8.5.14): - dependencies: - browserslist: 4.28.2 - postcss: 8.5.14 - postcss-value-parser: 4.2.0 - postcss-discard-comments@5.1.2(postcss@8.5.14): dependencies: postcss: 8.5.14 - postcss-discard-comments@6.0.2(postcss@8.5.14): - dependencies: - postcss: 8.5.14 - postcss-discard-duplicates@5.1.0(postcss@8.5.14): dependencies: postcss: 8.5.14 - postcss-discard-duplicates@6.0.3(postcss@8.5.14): - dependencies: - postcss: 8.5.14 - postcss-discard-empty@5.1.1(postcss@8.5.14): dependencies: postcss: 8.5.14 - postcss-discard-empty@6.0.3(postcss@8.5.14): - dependencies: - postcss: 8.5.14 - postcss-discard-overridden@5.1.0(postcss@8.5.14): dependencies: postcss: 8.5.14 - postcss-discard-overridden@6.0.2(postcss@8.5.14): - dependencies: - postcss: 8.5.14 - postcss-flexbugs-fixes@4.2.1: dependencies: postcss: 7.0.39 @@ -27511,12 +27338,6 @@ snapshots: postcss-value-parser: 4.2.0 stylehacks: 5.1.1(postcss@8.5.14) - postcss-merge-longhand@6.0.5(postcss@8.5.14): - dependencies: - postcss: 8.5.14 - postcss-value-parser: 4.2.0 - stylehacks: 6.1.1(postcss@8.5.14) - postcss-merge-rules@5.1.4(postcss@8.5.14): dependencies: browserslist: 4.28.2 @@ -27525,24 +27346,11 @@ snapshots: postcss: 8.5.14 postcss-selector-parser: 6.1.2 - postcss-merge-rules@6.1.1(postcss@8.5.14): - dependencies: - browserslist: 4.28.2 - caniuse-api: 3.0.0 - cssnano-utils: 4.0.2(postcss@8.5.14) - postcss: 8.5.14 - postcss-selector-parser: 6.1.2 - postcss-minify-font-values@5.1.0(postcss@8.5.14): dependencies: postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-minify-font-values@6.1.0(postcss@8.5.14): - dependencies: - postcss: 8.5.14 - postcss-value-parser: 4.2.0 - postcss-minify-gradients@5.1.1(postcss@8.5.14): dependencies: colord: 2.9.3 @@ -27550,13 +27358,6 @@ snapshots: postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-minify-gradients@6.0.3(postcss@8.5.14): - dependencies: - colord: 2.9.3 - cssnano-utils: 4.0.2(postcss@8.5.14) - postcss: 8.5.14 - postcss-value-parser: 4.2.0 - postcss-minify-params@5.1.4(postcss@8.5.14): dependencies: browserslist: 4.28.2 @@ -27564,23 +27365,11 @@ snapshots: postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-minify-params@6.1.0(postcss@8.5.14): - dependencies: - browserslist: 4.28.2 - cssnano-utils: 4.0.2(postcss@8.5.14) - postcss: 8.5.14 - postcss-value-parser: 4.2.0 - postcss-minify-selectors@5.2.1(postcss@8.5.14): dependencies: postcss: 8.5.14 postcss-selector-parser: 6.1.2 - postcss-minify-selectors@6.0.4(postcss@8.5.14): - dependencies: - postcss: 8.5.14 - postcss-selector-parser: 6.1.2 - postcss-modules-extract-imports@2.0.0: dependencies: postcss: 7.0.39 @@ -27627,127 +27416,65 @@ snapshots: dependencies: postcss: 8.5.14 - postcss-normalize-charset@6.0.2(postcss@8.5.14): - dependencies: - postcss: 8.5.14 - postcss-normalize-display-values@5.1.0(postcss@8.5.14): dependencies: postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-normalize-display-values@6.0.2(postcss@8.5.14): - dependencies: - postcss: 8.5.14 - postcss-value-parser: 4.2.0 - postcss-normalize-positions@5.1.1(postcss@8.5.14): dependencies: postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-normalize-positions@6.0.2(postcss@8.5.14): - dependencies: - postcss: 8.5.14 - postcss-value-parser: 4.2.0 - postcss-normalize-repeat-style@5.1.1(postcss@8.5.14): dependencies: postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-normalize-repeat-style@6.0.2(postcss@8.5.14): - dependencies: - postcss: 8.5.14 - postcss-value-parser: 4.2.0 - postcss-normalize-string@5.1.0(postcss@8.5.14): dependencies: postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-normalize-string@6.0.2(postcss@8.5.14): - dependencies: - postcss: 8.5.14 - postcss-value-parser: 4.2.0 - postcss-normalize-timing-functions@5.1.0(postcss@8.5.14): dependencies: postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-normalize-timing-functions@6.0.2(postcss@8.5.14): - dependencies: - postcss: 8.5.14 - postcss-value-parser: 4.2.0 - postcss-normalize-unicode@5.1.1(postcss@8.5.14): dependencies: browserslist: 4.28.2 postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-normalize-unicode@6.1.0(postcss@8.5.14): - dependencies: - browserslist: 4.28.2 - postcss: 8.5.14 - postcss-value-parser: 4.2.0 - postcss-normalize-url@5.1.0(postcss@8.5.14): dependencies: normalize-url: 6.1.0 postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-normalize-url@6.0.2(postcss@8.5.14): - dependencies: - postcss: 8.5.14 - postcss-value-parser: 4.2.0 - postcss-normalize-whitespace@5.1.1(postcss@8.5.14): dependencies: postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-normalize-whitespace@6.0.2(postcss@8.5.14): - dependencies: - postcss: 8.5.14 - postcss-value-parser: 4.2.0 - postcss-ordered-values@5.1.3(postcss@8.5.14): dependencies: cssnano-utils: 3.1.0(postcss@8.5.14) postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-ordered-values@6.0.2(postcss@8.5.14): - dependencies: - cssnano-utils: 4.0.2(postcss@8.5.14) - postcss: 8.5.14 - postcss-value-parser: 4.2.0 - postcss-reduce-initial@5.1.2(postcss@8.5.14): dependencies: browserslist: 4.28.2 caniuse-api: 3.0.0 postcss: 8.5.14 - postcss-reduce-initial@6.1.0(postcss@8.5.14): - dependencies: - browserslist: 4.28.2 - caniuse-api: 3.0.0 - postcss: 8.5.14 - postcss-reduce-transforms@5.1.0(postcss@8.5.14): dependencies: postcss: 8.5.14 postcss-value-parser: 4.2.0 - postcss-reduce-transforms@6.0.2(postcss@8.5.14): - dependencies: - postcss: 8.5.14 - postcss-value-parser: 4.2.0 - postcss-selector-parser@6.1.2: dependencies: cssesc: 3.0.0 @@ -27764,22 +27491,11 @@ snapshots: postcss-value-parser: 4.2.0 svgo: 2.8.2 - postcss-svgo@6.0.3(postcss@8.5.14): - dependencies: - postcss: 8.5.14 - postcss-value-parser: 4.2.0 - svgo: 3.3.3 - postcss-unique-selectors@5.1.1(postcss@8.5.14): dependencies: postcss: 8.5.14 postcss-selector-parser: 6.1.2 - postcss-unique-selectors@6.0.4(postcss@8.5.14): - dependencies: - postcss: 8.5.14 - postcss-selector-parser: 6.1.2 - postcss-value-parser@4.2.0: {} postcss@7.0.39: @@ -27841,8 +27557,6 @@ snapshots: process@0.11.10: {} - promise-inflight@1.0.1: {} - promise-inflight@1.0.1(bluebird@3.7.2): optionalDependencies: bluebird: 3.7.2 @@ -28318,10 +28032,6 @@ snapshots: dependencies: resolve: 1.22.12 - rechoir@0.8.0: - dependencies: - resolve: 1.22.12 - redent@1.0.0: dependencies: indent-string: 2.1.0 @@ -28878,8 +28588,6 @@ snapshots: slash@3.0.0: {} - slash@4.0.0: {} - smart-buffer@4.2.0: {} snapdragon-node@2.1.1: @@ -29293,12 +29001,6 @@ snapshots: postcss: 8.5.14 postcss-selector-parser: 6.1.2 - stylehacks@6.1.1(postcss@8.5.14): - dependencies: - browserslist: 4.28.2 - postcss: 8.5.14 - postcss-selector-parser: 6.1.2 - stylis@4.2.0: {} supports-color@5.5.0: @@ -29500,14 +29202,6 @@ snapshots: schema-utils: 3.3.0 webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) - thread-loader@4.0.4(webpack@5.106.2): - dependencies: - json-parse-better-errors: 1.0.2 - loader-runner: 4.3.2 - neo-async: 2.6.2 - schema-utils: 4.3.3 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) - thread-stream@0.15.2: dependencies: real-require: 0.1.0 @@ -29632,7 +29326,7 @@ snapshots: ts-dedent@2.2.0: {} - ts-jest@27.1.5(@babel/core@7.29.0)(@types/jest@27.5.2)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5): + ts-jest@27.1.5(@babel/core@7.29.0)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 @@ -29646,7 +29340,6 @@ snapshots: yargs-parser: 20.2.9 optionalDependencies: '@babel/core': 7.29.0 - '@types/jest': 27.5.2 babel-jest: 27.5.1(@babel/core@7.29.0) esbuild: 0.25.12 @@ -29670,16 +29363,6 @@ snapshots: babel-jest: 29.7.0(@babel/core@7.29.0) jest-util: 29.7.0 - ts-loader@9.5.7(typescript@4.9.5)(webpack@5.106.2): - dependencies: - chalk: 4.1.2 - enhanced-resolve: 5.21.3 - micromatch: 4.0.8 - semver: 7.8.0 - source-map: 0.7.6 - typescript: 4.9.5 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) - ts-loader@9.5.7(typescript@5.9.3)(webpack@5.106.2): dependencies: chalk: 4.1.2 @@ -29702,13 +29385,6 @@ snapshots: enhanced-resolve: 5.21.3 tsconfig-paths: 3.15.0 - tsconfig-paths-webpack-plugin@4.2.0: - dependencies: - chalk: 4.1.2 - enhanced-resolve: 5.21.3 - tapable: 2.3.3 - tsconfig-paths: 4.2.0 - tsconfig-paths@3.15.0: dependencies: '@types/json5': 0.0.29 @@ -30263,25 +29939,6 @@ snapshots: optionalDependencies: webpack-dev-server: 4.15.2(webpack-cli@4.10.0)(webpack@5.106.2) - webpack-cli@5.1.4(webpack-dev-server@4.15.2)(webpack@5.106.2): - dependencies: - '@discoveryjs/json-ext': 0.5.7 - '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4)(webpack@5.106.2) - '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4)(webpack@5.106.2) - '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4)(webpack-dev-server@4.15.2)(webpack@5.106.2) - colorette: 2.0.20 - commander: 10.0.1 - cross-spawn: 7.0.6 - envinfo: 7.21.0 - fastest-levenshtein: 1.0.16 - import-local: 3.2.0 - interpret: 3.1.1 - rechoir: 0.8.0 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) - webpack-merge: 5.10.0 - optionalDependencies: - webpack-dev-server: 4.15.2(webpack-cli@5.1.4)(webpack@5.106.2) - webpack-dev-middleware@3.7.3(webpack@4.47.0): dependencies: memory-fs: 0.4.1 @@ -30361,47 +30018,6 @@ snapshots: - supports-color - utf-8-validate - webpack-dev-server@4.15.2(webpack-cli@5.1.4)(webpack@5.106.2): - dependencies: - '@types/bonjour': 3.5.13 - '@types/connect-history-api-fallback': 1.5.4 - '@types/express': 4.17.25 - '@types/serve-index': 1.9.4 - '@types/serve-static': 1.15.10 - '@types/sockjs': 0.3.36 - '@types/ws': 8.18.1 - ansi-html-community: 0.0.8 - bonjour-service: 1.3.0 - chokidar: 3.6.0 - colorette: 2.0.20 - compression: 1.8.1 - connect-history-api-fallback: 2.0.0 - default-gateway: 6.0.3 - express: 4.22.2 - graceful-fs: 4.2.11 - html-entities: 2.6.0 - http-proxy-middleware: 2.0.9(@types/express@4.17.25) - ipaddr.js: 2.4.0 - launch-editor: 2.13.2 - open: 8.4.2 - p-retry: 4.6.2 - rimraf: 3.0.2 - schema-utils: 4.3.3 - selfsigned: 2.4.1 - serve-index: 1.9.2 - sockjs: 0.3.24 - spdy: 4.0.2 - webpack-dev-middleware: 5.3.4(webpack@5.106.2) - ws: 8.20.1 - optionalDependencies: - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@5.1.4) - webpack-cli: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.106.2) - transitivePeerDependencies: - - bufferutil - - debug - - supports-color - - utf-8-validate - webpack-dev-server@4.15.2(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)): dependencies: '@types/bonjour': 3.5.13 @@ -30593,48 +30209,6 @@ snapshots: - postcss - uglify-js - webpack@5.106.2(postcss@8.5.14)(webpack-cli@5.1.4): - dependencies: - '@types/eslint-scope': 3.7.7 - '@types/estree': 1.0.9 - '@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.16.0 - acorn-import-phases: 1.0.4(acorn@8.16.0) - browserslist: 4.28.2 - chrome-trace-event: 1.0.4 - enhanced-resolve: 5.21.3 - es-module-lexer: 2.1.0 - eslint-scope: 5.1.1 - events: 3.3.0 - glob-to-regexp: 0.4.1 - graceful-fs: 4.2.11 - loader-runner: 4.3.2 - mime-db: 1.54.0 - neo-async: 2.6.2 - schema-utils: 4.3.3 - tapable: 2.3.3 - terser-webpack-plugin: 5.6.0(postcss@8.5.14)(webpack@5.106.2) - watchpack: 2.5.1 - webpack-sources: 3.4.1 - optionalDependencies: - webpack-cli: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.106.2) - transitivePeerDependencies: - - '@minify-html/node' - - '@swc/core' - - '@swc/css' - - '@swc/html' - - clean-css - - cssnano - - csso - - esbuild - - html-minifier-terser - - lightningcss - - postcss - - uglify-js - webpack@5.106.2(webpack-cli@4.10.0): dependencies: '@types/eslint-scope': 3.7.7 @@ -30917,8 +30491,6 @@ snapshots: yocto-queue@0.1.0: {} - yocto-queue@1.2.2: {} - yup@0.32.11: dependencies: '@babel/runtime': 7.29.2 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 0dff613df8..e74dd31858 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,9 +1,15 @@ +# The static workspace below is intentionally minimal. It contains only what +# CI workflows without a Rust toolchain (e.g. ci-build-ts, storybook) need to +# resolve. Anything that depends on `@nymproject/smolmix-wasm` (mix-tunnel + +# mix-fetch + mix-dns + mix-websocket + internal-dev) or the wasm-pack output +# dir itself lives in `dev-mode-add.mjs` and is only injected when `pnpm +# dev:on` runs. Build the wasm first if dev:on will be called: +# `make -C wasm/smolmix` populates wasm/smolmix/pkg/. packages: - 'ts-packages/*' - 'nym-wallet' - 'explorer-v2' - 'types' - - 'sdk/typescript/packages/mix-fetch/internal-dev' - 'sdk/typescript/packages/react-components' - 'sdk/typescript/packages/mui-theme' @@ -21,8 +27,12 @@ allowBuilds: msgpackr-extract: true nx: true protobufjs: true - sharp: true - tiny-secp256k1: true + # Native C++ bindings; both fail to compile against Node 24's node-addon-api. + # Skipping the build leaves the JS shells in place, which is all our SDK + # packages need (only nym-wallet / explorer-v2 image stack actually uses them + # at runtime). Mirrors the fix on `max/fix-pnpm-ci` for documentation/docs/. + sharp: false + tiny-secp256k1: false unrs-resolver: true catalog: diff --git a/sdk/typescript/examples/.webpack/webpack.base.js b/sdk/typescript/examples/.webpack/webpack.base.js index 7725e12bc0..1534cae963 100644 --- a/sdk/typescript/examples/.webpack/webpack.base.js +++ b/sdk/typescript/examples/.webpack/webpack.base.js @@ -10,8 +10,10 @@ const os = require('os'); /** * Creates the default Webpack config * @param baseDir The base directory path, e.g. pass `__dirname` of the webpack config file using this method + * @param htmlPath Path or array of HtmlWebpackPlugin opts + * @param opts Optional flags: `{ skipFavicon: true }` to omit the WebpackFavicons plugin */ -const webpackCommon = (baseDir, htmlPath) => ({ +const webpackCommon = (baseDir, htmlPath, opts = {}) => ({ module: { rules: [ { @@ -80,9 +82,13 @@ const webpackCommon = (baseDir, htmlPath) => ({ }, }), - new WebpackFavicons({ - src: path.resolve(__dirname, '../../assets/favicon/favicon.png'), // the asset directory is relative to THIS file - }), + ...(opts.skipFavicon + ? [] + : [ + new WebpackFavicons({ + src: path.resolve(__dirname, '../../../../assets/favicon/favicon.png'), // repo-root /assets/favicon/favicon.png + }), + ]), new Dotenv(), ], diff --git a/sdk/typescript/examples/mix-dns/browser/README.md b/sdk/typescript/examples/mix-dns/browser/README.md new file mode 100644 index 0000000000..4e53db4de7 --- /dev/null +++ b/sdk/typescript/examples/mix-dns/browser/README.md @@ -0,0 +1,27 @@ +# mixDNS Usage Example + +Shows how to resolve hostnames over the Nym mixnet using +`@nymproject/mix-dns`. Resolution travels the IPR's DNS path (UDP, no TCP/TLS). + +```ts +import { setupMixTunnel, mixDNS } from '@nymproject/mix-dns'; + +await setupMixTunnel(); +const ip = await mixDNS('nymtech.net'); +``` + +## Running the example + +``` +npm install +npm run start +``` + +Open http://localhost:1234. The example resolves three hostnames and prints +the round-trip time for each. + +## Sharing the tunnel + +`setupMixTunnel()` is a no-op after the first call across all three smolmix +SDKs (`mix-fetch`, `mix-dns`, `mix-websocket`). If you already imported one +of the others, you can skip the setup line. diff --git a/sdk/typescript/examples/mix-dns/browser/package.json b/sdk/typescript/examples/mix-dns/browser/package.json new file mode 100644 index 0000000000..ca5c4bc87c --- /dev/null +++ b/sdk/typescript/examples/mix-dns/browser/package.json @@ -0,0 +1,16 @@ +{ + "name": "@nymproject/mix-dns-example-parcel", + "version": "0.1.0", + "license": "Apache-2.0", + "scripts": { + "build": "parcel build --no-cache --no-content-hash", + "serve": "serve dist", + "start": "parcel --no-cache" + }, + "dependencies": { + "@nymproject/mix-dns": "workspace:*", + "parcel": "^2.9.3" + }, + "private": true, + "source": "src/index.html" +} diff --git a/sdk/typescript/examples/mix-dns/browser/src/index.html b/sdk/typescript/examples/mix-dns/browser/src/index.html new file mode 100644 index 0000000000..befef89042 --- /dev/null +++ b/sdk/typescript/examples/mix-dns/browser/src/index.html @@ -0,0 +1,24 @@ + + + + + + + mixDNS + + + + + +

mixDNS

+

Resolves a handful of hostnames over the Nym mixnet using the IPR's DNS path.

+

+
+
+
diff --git a/sdk/typescript/examples/mix-dns/browser/src/index.ts b/sdk/typescript/examples/mix-dns/browser/src/index.ts
new file mode 100644
index 0000000000..3a85bad434
--- /dev/null
+++ b/sdk/typescript/examples/mix-dns/browser/src/index.ts
@@ -0,0 +1,54 @@
+import { setupMixTunnel, mixDNS, type SetupMixTunnelOpts } from '@nymproject/mix-dns';
+
+function append(line: string) {
+  const el = document.getElementById('output') as HTMLPreElement;
+  el.appendChild(document.createTextNode(`${line}\n`));
+}
+
+// Tunnel configuration. Every field is optional.
+//
+// `debug: true` turns on smolmix-wasm's verbose tracing so you can see the
+// UDP DNS query and response in DevTools. Leave it off in production.
+const setupOpts: SetupMixTunnelOpts = {
+  debug: true,
+
+  // Pin a specific exit IPR. Otherwise auto-discovered from the topology.
+  // preferredIpr: 'D1rrUqJY9pesL3pTaMaxLnpZGGYQ4ZpZwpQXCqaeBXTW.6PpFkRvF...',
+
+  // DNS resolver overrides. Defaults: 1.1.1.1 (primary) / 8.8.8.8 (fallback).
+  // Set these to test against a specific resolver, e.g. Quad9 for filtered DNS.
+  // primaryDns: '9.9.9.9',
+  // fallbackDns: '149.112.112.112',
+
+  // Per-query timeout. Default: 30s.
+  // dnsTimeoutMs: 5_000,
+};
+
+// Hostnames cover a mix of cases: the Nym site itself, the de facto smoke
+// test (example.com), a major CDN (cloudflare), and a host that takes
+// several A records.
+const hostnames = ['nymtech.net', 'example.com', 'cloudflare.com', 'github.com'];
+
+async function main() {
+  append('Setting up mixnet tunnel...');
+  await setupMixTunnel(setupOpts);
+  append('Tunnel ready.\n');
+
+  for (const host of hostnames) {
+    const start = performance.now();
+    try {
+      const ip = await mixDNS(host);
+      const ms = Math.round(performance.now() - start);
+      append(`${host} -> ${ip}  (${ms} ms)`);
+    } catch (err) {
+      append(`${host} -> error: ${err instanceof Error ? err.message : String(err)}`);
+    }
+  }
+}
+
+window.addEventListener('DOMContentLoaded', () => {
+  main().catch((err) => {
+    console.error(err);
+    append(`Error: ${err}`);
+  });
+});
diff --git a/sdk/typescript/examples/mix-fetch/browser/package.json b/sdk/typescript/examples/mix-fetch/browser/package.json
index 8b3a7ec042..2d34af0452 100644
--- a/sdk/typescript/examples/mix-fetch/browser/package.json
+++ b/sdk/typescript/examples/mix-fetch/browser/package.json
@@ -8,9 +8,9 @@
     "start": "parcel --no-cache"
   },
   "dependencies": {
-    "@nymproject/mix-fetch": ">=1.4.2-rc.0 || ^1",
+    "@nymproject/mix-fetch": "workspace:*",
     "parcel": "^2.9.3"
   },
-  "private": false,
+  "private": true,
   "source": "src/index.html"
 }
\ No newline at end of file
diff --git a/sdk/typescript/examples/mix-fetch/browser/src/index.ts b/sdk/typescript/examples/mix-fetch/browser/src/index.ts
index bf8fdf1aa8..c9c86a23a5 100644
--- a/sdk/typescript/examples/mix-fetch/browser/src/index.ts
+++ b/sdk/typescript/examples/mix-fetch/browser/src/index.ts
@@ -1,46 +1,71 @@
-import { mixFetch } from '@nymproject/mix-fetch';
+import { setupMixTunnel, mixFetch, type SetupMixTunnelOpts } from '@nymproject/mix-fetch';
 import { appendOutput, appendImageOutput } from './utils';
 
+// Tunnel configuration. Every field is optional; uncomment to tweak.
+//
+// `debug: true` turns on smolmix-wasm's verbose tracing so you can watch the
+// IPR handshake, DNS lookups, and per-request lifecycle in DevTools. Leave
+// it off in production.
+const setupOpts: SetupMixTunnelOpts = {
+  debug: true,
+
+  // Pin a specific exit IPR. Otherwise auto-discovered from the topology.
+  // preferredIpr: 'D1rrUqJY9pesL3pTaMaxLnpZGGYQ4ZpZwpQXCqaeBXTW.6PpFkRvF...',
+
+  // Anonymity / performance trade-off. Cover traffic + Poisson padding
+  // smear timing patterns at the cost of bandwidth. Default: both on.
+  // disableCoverTraffic: true,
+  // disablePoissonTraffic: true,
+
+  // Custom DNS resolvers (over UDP through the IPR). Default: 1.1.1.1 / 8.8.8.8.
+  // primaryDns: '9.9.9.9',
+  // fallbackDns: '149.112.112.112',
+
+  // Connect / DNS budgets. Defaults: 60s / 30s respectively.
+  // connectTimeoutMs: 30_000,
+  // dnsTimeoutMs: 15_000,
+
+  // mixFetch redirect chain depth. Default: 5.
+  // maxRedirects: 10,
+};
+
 async function main() {
-  // options for mixFetch (you can also set these with the `createMixFetch` function
-  const mixFetchOptions = {
-    preferredGateway: '6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B', // with WSS
-    preferredNetworkRequester:
-      '8rRGWy54oC8drFL9DepMegBt2DLrsqQwCoHMXt9nsnTo.2XjCPVbb4FpQ9hNRcXwb9mTzEAVVk1zf1tcch3wdtNEA@6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B',
-    mixFetchOverride: {
-      requestTimeoutMs: 60_000,
-    },
-  };
+  appendOutput('Setting up mixnet tunnel...');
+  await setupMixTunnel(setupOpts);
+  appendOutput('Tunnel ready.\n');
 
-  // disable CORS (in your app, you probably don't want to disable CORS, it is a good thing to leave it enabled)
-  const args = { mode: 'unsafe-ignore-cors' };
-
-  // this is the URL of standard list of allow hosts the you can request data from with mixFetch and the Nym SOCKS5
-  // client - you can request to have more hosts added by getting in touch on Discord or Telegram
+  // Standard allowlist for the Nym network-requester. The IPR enforces its own
+  // exit policy, so the URL must pass that policy regardless of the source.
   let url = 'https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt';
 
   appendOutput('Get a text file:');
   appendOutput(`Downloading ${url}...\n`);
-  let resp = await mixFetch(url, args, mixFetchOptions); // NB: you only need to pass options to the 1st call
-  console.log({ resp });
-
+  let resp = await mixFetch(url);
   const text = await resp.text();
   appendOutput(text);
 
-  // get an image
   appendOutput('\nGet an image:\n');
-  url = 'https://nymtech.net/favicon.svg';
-  resp = await mixFetch(url, args);
-  console.log({ resp });
-
+  url = 'https://httpbin.org/image/png';
+  resp = await mixFetch(url);
   const buffer = await resp.arrayBuffer();
-  const type = resp.headers.get('Content-Type') || 'image/svg';
+  const type = resp.headers.get('Content-Type') || 'image/png';
   const blobUrl = URL.createObjectURL(new Blob([buffer], { type }));
   appendImageOutput(blobUrl);
+
+  // Per-request header override. smolmix-wasm ships a browser-shape header
+  // shim (User-Agent + Accept + Accept-Language + Accept-Encoding); anything
+  // you pass in `init.headers` wins over the shim defaults.
+  appendOutput('\nOverride User-Agent for one request:\n');
+  url = 'https://httpbin.org/headers';
+  resp = await mixFetch(url, {
+    headers: { 'User-Agent': 'mix-fetch-example/0.1' },
+  });
+  appendOutput(await resp.text());
 }
 
-// wait for the html to load
 window.addEventListener('DOMContentLoaded', () => {
-  // let's do this!
-  main();
+  main().catch((err) => {
+    console.error(err);
+    appendOutput(`Error: ${err}`);
+  });
 });
diff --git a/sdk/typescript/examples/mix-fetch/node-js/index.js b/sdk/typescript/examples/mix-fetch/node-js/index.js
deleted file mode 100644
index feaa5770c3..0000000000
--- a/sdk/typescript/examples/mix-fetch/node-js/index.js
+++ /dev/null
@@ -1,54 +0,0 @@
-const { createMixFetch, disconnectMixFetch } = require('@nymproject/mix-fetch-node-commonjs');
-
-/**
- * The main entry point
- */
-(async () => {
-  console.log('Tester is starting up...');
-
-  const addr =
-    'D274yd1h3L3pNJzdxE5VgJ7izAsAVMsDrQtFSkKUegfk.8J67cGbcwvrJKF3Kb16HVWWc9AnrFnEibNCm9zCkuVFu@Emswx6KXyjRfq1c2k4d4uD2e6nBSbH1biorCZUei8UNS';
-
-  console.log('About to set up mixFetch...');
-  const { mixFetch } = await createMixFetch({
-    preferredNetworkRequester: addr,
-    clientId: 'node-client1',
-    clientOverride: {
-      coverTraffic: { disableLoopCoverTrafficStream: true },
-      traffic: { disableMainPoissonPacketDistribution: true },
-    },
-    mixFetchOverride: { requestTimeoutMs: 60000 },
-    responseBodyConfigMap: {},
-    extra: {},
-  });
-
-  globalThis.mixFetch = mixFetch;
-
-  if (!globalThis.mixFetch) {
-    console.error('Oh no! Could not create mixFetch');
-  } else {
-    console.log('Ready!');
-  }
-
-  let url = 'https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt';
-  console.log(`Using mixFetch to get ${url}...`);
-  const args = { mode: 'unsafe-ignore-cors' };
-
-  let resp = await mixFetch(url, args);
-  console.log({ resp });
-  const text = await resp.text();
-
-  console.log('disconnecting');
-  await disconnectMixFetch();
-  console.log('disconnected! all further usages should fail');
-
-  // get an image
-  url = 'https://nymtech.net/favicon.svg';
-  resp = await mixFetch(url, args);
-  console.log({ resp });
-  const buffer = await resp.arrayBuffer();
-  const type = resp.headers.get('Content-Type') || 'image/svg';
-  const blobUrl = URL.createObjectURL(new Blob([buffer], { type }));
-  console.log(JSON.stringify({ bufferBytes: buffer.byteLength, blobUrl }, null, 2));
-  console.log(blobUrl);
-})();
diff --git a/sdk/typescript/examples/mix-fetch/node-js/package.json b/sdk/typescript/examples/mix-fetch/node-js/package.json
deleted file mode 100644
index e8117ef02d..0000000000
--- a/sdk/typescript/examples/mix-fetch/node-js/package.json
+++ /dev/null
@@ -1,14 +0,0 @@
-{
-  "name": "@nymproject/mix-fetch-node-js-example",
-  "version": "1.0.0",
-  "main": "index.js",
-  "license": "MIT",
-  "scripts": {
-    "start": "node index.js",
-    "start:server": "node server.js",
-    "test": "echo \"Error: no test specified\" && exit 1"
-  },
-  "dependencies": {
-    "@nymproject/mix-fetch-node-commonjs": "^1.2.1-rc.2"
-  }
-}
diff --git a/sdk/typescript/examples/mix-fetch/node-js/server.js b/sdk/typescript/examples/mix-fetch/node-js/server.js
deleted file mode 100644
index 7e35bc1804..0000000000
--- a/sdk/typescript/examples/mix-fetch/node-js/server.js
+++ /dev/null
@@ -1,55 +0,0 @@
-const express = require('express');
-const { mixFetch } = require('@nymproject/mix-fetch-node-commonjs');
-
-const app = express();
-app.use(express.static('public'));
-
-app.get('/nym-fetch', async (req, res) => {
-  try {
-    const args = {
-      mode: 'unsafe-ignore-cors',
-      headers: {
-        'Content-Type': 'application/json',
-      },
-    };
-
-    const url = req.query.url;
-
-    if (!url) {
-      return res.status(400).send('input a valid url');
-    }
-
-    const extra = {
-      hiddenGateways: [
-        {
-          owner: 'n1ns3v70ul9gnl9l9fkyz8cyxfq75vjcmx8el0t3',
-          host: 'sandbox-gateway1.nymtech.net',
-          explicitIp: '35.158.238.80',
-          identityKey: 'HjNEDJuotWV8VD4ufeA1jeheTnfNJ7Jorevp57hgaZua',
-          sphinxKey: 'BoXeUD7ERGmzRauMjJD3itVNnQiH42ncUb6kcVLrb3dy',
-        },
-      ],
-    };
-
-    const mixFetchOptions = {
-      nymApiUrl: 'https://sandbox-nym-api1.nymtech.net/api',
-      preferredGateway: 'HjNEDJuotWV8VD4ufeA1jeheTnfNJ7Jorevp57hgaZua',
-      preferredNetworkRequester:
-        'AzGdJ4MU78Ex22NEWfeycbN7bt3PFZr1MtKstAdhfELG.GSxnKnvKPjjQm3FdtsgG5KyhP6adGbPHRmFWDH4XfUpP@HjNEDJuotWV8VD4ufeA1jeheTnfNJ7Jorevp57hgaZua',
-      mixFetchOverride: {
-        requestTimeoutMs: 60_000,
-      },
-      forceTls: false,
-      extra,
-    };
-
-    const response = await mixFetch(url, args, mixFetchOptions);
-    const json = await response.json();
-    res.send(json);
-  } catch (error) {
-    console.log(error);
-    res.status(500).send(error.message);
-  }
-});
-
-app.listen(3000, () => console.log('Server running on port 3000'));
diff --git a/sdk/typescript/examples/mix-websocket/browser/README.md b/sdk/typescript/examples/mix-websocket/browser/README.md
new file mode 100644
index 0000000000..9be3bf909f
--- /dev/null
+++ b/sdk/typescript/examples/mix-websocket/browser/README.md
@@ -0,0 +1,37 @@
+# mixWebSocket Usage Example
+
+Shows how to open a WSS connection over the Nym mixnet using
+`@nymproject/mix-websocket`. The `MixWebSocket` class mirrors the browser
+`WebSocket` API where it makes sense.
+
+```ts
+import { setupMixTunnel, MixWebSocket } from '@nymproject/mix-websocket';
+
+await setupMixTunnel();
+const ws = new MixWebSocket('wss://echo.websocket.events');
+await ws.opened();
+ws.addEventListener('message', (e) => console.log(e.data));
+await ws.send('hello');
+```
+
+## Running the example
+
+```
+npm install
+npm run start
+```
+
+Open http://localhost:1234. The example echoes whatever you send via
+`echo.websocket.events`.
+
+## Differences from the browser WebSocket
+
+- `await ws.opened()` blocks until the upgrade completes.
+- `binaryType` is fixed to `arraybuffer`.
+- No `bufferedAmount`; writes queue through the tunnel worker.
+
+## Sharing the tunnel
+
+`setupMixTunnel()` is shared across `mix-fetch`, `mix-dns`, and
+`mix-websocket`. If another of those is already initialised, you can skip
+the setup line.
diff --git a/sdk/typescript/examples/mix-websocket/browser/package.json b/sdk/typescript/examples/mix-websocket/browser/package.json
new file mode 100644
index 0000000000..e2d520ac83
--- /dev/null
+++ b/sdk/typescript/examples/mix-websocket/browser/package.json
@@ -0,0 +1,16 @@
+{
+  "name": "@nymproject/mix-websocket-example-parcel",
+  "version": "0.1.0",
+  "license": "Apache-2.0",
+  "scripts": {
+    "build": "parcel build --no-cache --no-content-hash",
+    "serve": "serve dist",
+    "start": "parcel --no-cache"
+  },
+  "dependencies": {
+    "@nymproject/mix-websocket": "workspace:*",
+    "parcel": "^2.9.3"
+  },
+  "private": true,
+  "source": "src/index.html"
+}
diff --git a/sdk/typescript/examples/mix-websocket/browser/src/index.html b/sdk/typescript/examples/mix-websocket/browser/src/index.html
new file mode 100644
index 0000000000..856736656e
--- /dev/null
+++ b/sdk/typescript/examples/mix-websocket/browser/src/index.html
@@ -0,0 +1,32 @@
+
+
+
+
+  
+  
+  mixWebSocket
+  
+  
+
+
+
+

mixWebSocket

+

Opens a WSS connection to wss://echo.websocket.events through the Nym mixnet.

+
+ + + +
+

+
+
+
diff --git a/sdk/typescript/examples/mix-websocket/browser/src/index.ts b/sdk/typescript/examples/mix-websocket/browser/src/index.ts
new file mode 100644
index 0000000000..0d4f278482
--- /dev/null
+++ b/sdk/typescript/examples/mix-websocket/browser/src/index.ts
@@ -0,0 +1,90 @@
+import { setupMixTunnel, MixWebSocket, type SetupMixTunnelOpts } from '@nymproject/mix-websocket';
+
+function log(line: string) {
+  const el = document.getElementById('output') as HTMLPreElement;
+  el.appendChild(document.createTextNode(`${line}\n`));
+  el.scrollTop = el.scrollHeight;
+}
+
+// Tunnel configuration. Every field is optional.
+//
+// `debug: true` turns on smolmix-wasm's verbose tracing so you can watch
+// the TLS handshake and WebSocket frame exchange in DevTools. Leave it off
+// in production.
+const setupOpts: SetupMixTunnelOpts = {
+  debug: true,
+
+  // Pin a specific exit IPR. Otherwise auto-discovered from the topology.
+  // preferredIpr: 'D1rrUqJY9pesL3pTaMaxLnpZGGYQ4ZpZwpQXCqaeBXTW.6PpFkRvF...',
+
+  // Anonymity / performance trade-off. Cover traffic + Poisson padding
+  // smear timing patterns at the cost of bandwidth. Default: both on.
+  // disableCoverTraffic: true,
+  // disablePoissonTraffic: true,
+
+  // TCP keepalive cadence for the underlying smoltcp socket. Default: 10s.
+  // Lower it if you need quicker dead-peer detection on idle WebSockets.
+  // tcpKeepaliveMs: 5_000,
+
+  // Connect budget for the TCP + TLS + WS handshake. Default: 60s.
+  // connectTimeoutMs: 30_000,
+};
+
+// Public echo server. Sends each frame back to the client.
+const WS_URL = 'wss://echo.websocket.org';
+
+async function main() {
+  log('Setting up mixnet tunnel...');
+  await setupMixTunnel(setupOpts);
+  log('Tunnel ready.');
+
+  log(`Connecting to ${WS_URL}...`);
+  const ws = new MixWebSocket(WS_URL);
+
+  ws.addEventListener('open', () => log('< open'));
+  ws.addEventListener('message', (e) => {
+    const data = (e as MessageEvent).data;
+    if (typeof data === 'string') {
+      log(`< text: ${data}`);
+    } else if (data instanceof ArrayBuffer) {
+      log(`< binary: ${data.byteLength} bytes`);
+    }
+  });
+  ws.addEventListener('close', (e) => {
+    const ce = e as CloseEvent;
+    log(`< close: code=${ce.code} reason=${ce.reason || '(empty)'}`);
+  });
+  ws.addEventListener('error', (e) => {
+    const evt = e as Event & { message?: string };
+    log(`< error: ${evt.message ?? '(no detail)'}`);
+  });
+
+  await ws.opened();
+
+  const sendBtn = document.getElementById('send') as HTMLButtonElement;
+  const closeBtn = document.getElementById('close') as HTMLButtonElement;
+  const input = document.getElementById('message') as HTMLInputElement;
+
+  sendBtn.disabled = false;
+  closeBtn.disabled = false;
+
+  sendBtn.addEventListener('click', async () => {
+    const value = input.value;
+    if (!value) return;
+    log(`> ${value}`);
+    await ws.send(value);
+  });
+
+  closeBtn.addEventListener('click', async () => {
+    sendBtn.disabled = true;
+    closeBtn.disabled = true;
+    await ws.close(1000, 'user requested');
+  });
+}
+
+window.addEventListener('DOMContentLoaded', () => {
+  main().catch((err) => {
+    console.error(err);
+    log(`Error: ${err instanceof Error ? err.message : String(err)}`);
+  });
+});
diff --git a/sdk/typescript/packages/internal-dev/README.md b/sdk/typescript/packages/internal-dev/README.md
new file mode 100644
index 0000000000..bebfb894ce
--- /dev/null
+++ b/sdk/typescript/packages/internal-dev/README.md
@@ -0,0 +1,72 @@
+# smolmix SDK playground (internal-dev)
+
+Internal-only browser playground that exercises the smolmix-based TS SDK
+family end-to-end against a live mixnet:
+
+- `@nymproject/mix-tunnel` — tunnel lifecycle (setup, state, disconnect)
+- `@nymproject/mix-fetch` — HTTP/HTTPS through the mixnet
+- `@nymproject/mix-dns` — hostname resolution via the IPR
+- `@nymproject/mix-websocket` — WS/WSS through the mixnet
+
+Use at your own risk; this is dev scaffolding, not a polished demo.
+
+## Getting started
+
+From the repo root:
+
+```
+make sdk-wasm-build      # build smolmix-wasm pkg/
+pnpm i                   # install workspace deps (resolves workspace:* refs)
+```
+
+Then build the four TS SDK packages so the playground can resolve them:
+
+```
+pnpm build:ci:sdk
+```
+
+Then start the dev server (webpack):
+
+```
+cd sdk/typescript/packages/internal-dev
+pnpm start
+```
+
+Open . The page has four sections (Tunnel, Fetch,
+DNS, WebSocket); start with **Setup tunnel** and wait for the state to flip
+green. The other three sections are then live.
+
+Alternative: parcel-based playground in `parcel/` — same source, different
+bundler.
+
+## Iterating on the SDKs
+
+If you edit a TS SDK package (e.g. `mix-fetch`) the playground won't see the
+change until the package is rebuilt. From the repo root:
+
+```
+pnpm --filter @nymproject/mix-fetch build
+```
+
+webpack-dev-server picks up the new `dist/` via the workspace symlink and
+hot-reloads.
+
+If you edit `mix-tunnel`'s rollup config or anything touching the inlined
+worker bundle, run the package's own `pnpm build` so the rollup chain
+re-runs:
+
+```
+pnpm --filter @nymproject/mix-tunnel build
+```
+
+If you edit `wasm/smolmix` itself, run `make -C wasm/smolmix build-debug`
+to regenerate `pkg/` — then `pnpm --filter @nymproject/mix-tunnel build`
+to pick up the new wasm bytes.
+
+## Stuck?
+
+```
+rm -rf node_modules && pnpm i && pnpm start
+```
+
+Often resets pnpm-link state if the workspace package symlinks have drifted.
diff --git a/sdk/typescript/packages/mix-fetch/internal-dev/package.json b/sdk/typescript/packages/internal-dev/package.json
similarity index 81%
rename from sdk/typescript/packages/mix-fetch/internal-dev/package.json
rename to sdk/typescript/packages/internal-dev/package.json
index e64aaf611a..e6aff92031 100644
--- a/sdk/typescript/packages/mix-fetch/internal-dev/package.json
+++ b/sdk/typescript/packages/internal-dev/package.json
@@ -1,14 +1,19 @@
 {
-  "name": "@nymproject/mix-fetch-tester-webpack",
-  "version": "1.0.6",
+  "name": "@nymproject/smolmix-internal-dev",
+  "version": "0.0.0",
+  "private": true,
   "license": "Apache-2.0",
+  "description": "Internal playground exercising the smolmix-based TS SDK family (mix-tunnel, mix-fetch, mix-dns, mix-websocket).",
   "scripts": {
     "build": "webpack build --progress --config webpack.prod.js",
     "serve": "npx serve dist",
     "start": "webpack serve --progress --port 3000"
   },
   "dependencies": {
-    "@nymproject/mix-fetch": ">=1.4.2-rc.0 || ^1"
+    "@nymproject/mix-tunnel": "workspace:*",
+    "@nymproject/mix-fetch": "workspace:*",
+    "@nymproject/mix-dns": "workspace:*",
+    "@nymproject/mix-websocket": "workspace:*"
   },
   "devDependencies": {
     "@babel/core": "catalog:",
@@ -53,6 +58,5 @@
     "webpack-cli": "^5.1.4",
     "webpack-dev-server": "catalog:",
     "webpack-merge": "catalog:"
-  },
-  "private": false
+  }
 }
diff --git a/sdk/typescript/packages/internal-dev/parcel/package.json b/sdk/typescript/packages/internal-dev/parcel/package.json
new file mode 100644
index 0000000000..6200fa8a7c
--- /dev/null
+++ b/sdk/typescript/packages/internal-dev/parcel/package.json
@@ -0,0 +1,18 @@
+{
+  "name": "@nymproject/smolmix-internal-dev-parcel",
+  "version": "0.0.0",
+  "license": "Apache-2.0",
+  "scripts": {
+    "build": "npx parcel build --no-cache --no-content-hash",
+    "serve": "npx serve dist",
+    "start": "npx parcel --no-cache"
+  },
+  "dependencies": {
+    "@nymproject/mix-tunnel": "workspace:*",
+    "@nymproject/mix-fetch": "workspace:*",
+    "@nymproject/mix-dns": "workspace:*",
+    "@nymproject/mix-websocket": "workspace:*"
+  },
+  "private": true,
+  "source": "../src/index.html"
+}
\ No newline at end of file
diff --git a/sdk/typescript/packages/internal-dev/src/index.html b/sdk/typescript/packages/internal-dev/src/index.html
new file mode 100644
index 0000000000..2f278f7a84
--- /dev/null
+++ b/sdk/typescript/packages/internal-dev/src/index.html
@@ -0,0 +1,233 @@
+
+
+
+  
+  
+  smolmix TS SDK dev
+  
+  
+  
+
+
+
+  

smolmix TS SDK dev

+

+ Drives @nymproject/mix-tunnel, mix-fetch, + mix-dns, mix-websocket against a live mixnet. + Mirrors wasm/smolmix/internal-dev so you can A/B the SDK + layer against the raw WASM. +

+ + +
+ Connection +
+ + + +
+
+ Advanced Options +
+
+ +
+
+ + (randomised on load for clean state) +
+
+ +
+
+ +
+
+ + +
+
+ + +
+
+ +
+
+
+
+ + + + Not started +
+
+ + +
+ DNS Resolve +
+ + + +
+

+  
+ + +
+ GET +
+ + + +
+
+ presets: + + + +
+

+    
+
+ + +
+ WebSocket +
+ + + + Not connected +
+
+ + +
+
+ + + + + + + bytes + +
+

+  
+ + +
+ Stress Test +
+ + + + +
+ + + +
+ + + + + + +
tiny128 B
small1 KB
medium10 KB
large100 KB
xlarge1 MB
+
+ + + +
+ + +
+

+  
+ + +
+ File Download +
+
+ UTF-8 Demo +
Unicode text (Cambridge CS)
+ + + +
+
+ File Download +
+ +
+ + + + +
+
+

+  
+ + +
+ Output (master timeline) +

+  
+ + diff --git a/sdk/typescript/packages/internal-dev/src/index.ts b/sdk/typescript/packages/internal-dev/src/index.ts new file mode 100644 index 0000000000..b14e302438 --- /dev/null +++ b/sdk/typescript/packages/internal-dev/src/index.ts @@ -0,0 +1,680 @@ +// smolmix TS SDK dev — mirrors wasm/smolmix/internal-dev so the two +// playgrounds run the same scenarios; the SDK layer adds (mostly) nothing +// the raw WASM doesn't already do, so observed behaviour should match. + +import { + setupMixTunnel, + disconnectMixTunnel, + SetupMixTunnelOpts, +} from '@nymproject/mix-tunnel'; +import { mixFetch } from '@nymproject/mix-fetch'; +import { mixDNS } from '@nymproject/mix-dns'; +import { MixWebSocket } from '@nymproject/mix-websocket'; + +// Helpers ============================================================ + +const $ = (id: string): T => { + const el = document.getElementById(id); + if (!el) throw new Error(`#${id} not found`); + return el as T; +}; + +type LogColour = 'green' | 'red' | 'orange' | 'gray' | undefined; + +function display(msg: string, colour?: LogColour) { + const ts = new Date().toISOString().slice(11, 23); + const line = document.createElement('div'); + if (colour) line.style.color = colour; + line.textContent = `[${ts}] ${msg}`; + const out = $('output'); + out.appendChild(line); + out.scrollTop = out.scrollHeight; + if (colour === 'red') console.error('[sdk-dev]', msg); +} + +function logTo(targetId: string, msg: string, colour?: LogColour) { + const target = document.getElementById(targetId); + if (!target) return; + const ts = new Date().toISOString().slice(11, 23); + const line = document.createElement('div'); + if (colour) line.style.color = colour; + line.textContent = `[${ts}] ${msg}`; + target.appendChild(line); + target.scrollTop = target.scrollHeight; + if (colour === 'red') console.error(`[sdk-dev:${targetId}]`, msg); +} + +const formatSize = (bytes: number): string => { + if (bytes >= 1048576) return `${(bytes / 1048576).toFixed(1)} MB`; + if (bytes >= 1024) return `${(bytes / 1024).toFixed(1)} KB`; + return `${bytes} B`; +}; + +const formatRate = (bytes: number, ms: number): string => + `${(bytes / 1024 / (ms / 1000)).toFixed(1)} KB/s`; + +const hexPreview = (data: Uint8Array | ArrayBuffer, maxBytes = 64): string => { + const bytes = data instanceof Uint8Array ? data : new Uint8Array(data); + const len = Math.min(bytes.length, maxBytes); + const hex = Array.from(bytes.slice(0, len), (b) => b.toString(16).padStart(2, '0')).join(' '); + return bytes.length > maxBytes ? `${hex} ...` : hex; +}; + +async function sha256hex(bytes: BufferSource): Promise { + const hash = await crypto.subtle.digest('SHA-256', bytes); + return Array.from(new Uint8Array(hash), (b) => b.toString(16).padStart(2, '0')).join(''); +} + +function saveFile(buf: BlobPart, filename: string, mimeType: string) { + const blob = new Blob([buf], { type: mimeType }); + const url = URL.createObjectURL(blob); + const a = document.createElement('a'); + a.href = url; + a.download = filename; + a.click(); + URL.revokeObjectURL(url); +} + +// Tunnel-gated UI bits. GET + DNS fieldsets stay enabled so their clearnet +// buttons work without a tunnel; only the per-button gates are toggled. +const GATED_FIELDSETS = ['ws-controls', 'stress-controls', 'download-controls']; +const GATED_BUTTONS = ['btn-get-tunnel', 'btn-dns-tunnel']; + +function setTunnelButtonsEnabled(enabled: boolean) { + for (const id of GATED_FIELDSETS) ($(id) as HTMLFieldSetElement).disabled = !enabled; + for (const id of GATED_BUTTONS) ($(id) as HTMLButtonElement).disabled = !enabled; +} + +const strField = (id: string): string | undefined => { + const v = ($(id) as HTMLInputElement).value.trim(); + return v.length === 0 ? undefined : v; +}; +const numField = (id: string): number | undefined => { + const v = ($(id) as HTMLInputElement).value.trim(); + if (!v) return undefined; + const n = Number(v); + return Number.isFinite(n) ? n : undefined; +}; + +// Override the default User-Agent header injected by the wasm-shim. Kept in +// module scope so each fetch can reach it without re-reading the input. +let userAgentOverride: string | undefined; +const fetchInit = (): RequestInit | undefined => + userAgentOverride ? { headers: { 'User-Agent': userAgentOverride } } : undefined; + +// Connection ========================================================= + +$('opt-random-ipr').addEventListener('change', (e) => { + $('ipr-address').toggleAttribute('disabled', (e.target as HTMLInputElement).checked); +}); + +$('btn-setup').addEventListener('click', async () => { + const useRandom = ($('opt-random-ipr') as HTMLInputElement).checked; + const ipr = useRandom ? undefined : ($('ipr-address') as HTMLInputElement).value.trim(); + if (!useRandom && !ipr) { + display('IPR address is required (or check "Use random IPR")', 'red'); + return; + } + + const statusEl = $('tunnel-status'); + ($('btn-setup') as HTMLButtonElement).disabled = true; + statusEl.textContent = 'Connecting...'; + statusEl.style.color = 'orange'; + + userAgentOverride = strField('opt-user-agent'); + + const opts: SetupMixTunnelOpts = { + ...(ipr ? { preferredIpr: ipr } : {}), + clientId: strField('opt-client-id'), + forceTls: ($('opt-force-tls') as HTMLInputElement).checked, + disablePoissonTraffic: ($('opt-disable-poisson') as HTMLInputElement).checked, + disableCoverTraffic: ($('opt-disable-cover') as HTMLInputElement).checked, + openReplySurbs: numField('opt-open-surbs'), + dataReplySurbs: numField('opt-data-surbs'), + primaryDns: strField('opt-primary-dns'), + fallbackDns: strField('opt-fallback-dns'), + debug: ($('opt-debug-logging') as HTMLInputElement).checked, + }; + + display(`setupMixTunnel (clientId=${opts.clientId}, IPR: ${ipr ? `${ipr.slice(0, 30)}...` : 'auto-discover'})`); + + try { + const t0 = performance.now(); + await setupMixTunnel(opts); + const ms = (performance.now() - t0).toFixed(0); + display(`tunnel ready in ${ms} ms`, 'green'); + statusEl.textContent = `Connected (${ms} ms)`; + statusEl.style.color = 'green'; + setTunnelButtonsEnabled(true); + ($('btn-disconnect') as HTMLButtonElement).disabled = false; + } catch (e) { + const msg = String(e); + display(`setupMixTunnel failed: ${msg}`, 'red'); + statusEl.textContent = `Failed: ${msg}`; + statusEl.style.color = 'red'; + statusEl.title = msg; + ($('btn-setup') as HTMLButtonElement).disabled = false; + } +}); + +$('btn-disconnect').addEventListener('click', async () => { + display('Disconnecting...'); + try { + await disconnectMixTunnel(); + display('Disconnected', 'green'); + $('tunnel-status').textContent = 'Disconnected'; + $('tunnel-status').style.color = 'gray'; + setTunnelButtonsEnabled(false); + ($('btn-disconnect') as HTMLButtonElement).disabled = true; + // Tunnel uses OnceLock semantics — no re-setup without page reload. + ($('btn-setup') as HTMLButtonElement).disabled = true; + } catch (e) { + display(`Disconnect failed: ${e}`, 'red'); + } +}); + +// DNS Resolve ======================================================== + +$('btn-dns-tunnel').addEventListener('click', async () => { + const host = ($('dns-host') as HTMLInputElement).value.trim(); + if (!host) { logTo('dns-log', 'Hostname is required', 'red'); return; } + + const btn = $('btn-dns-tunnel') as HTMLButtonElement; + btn.disabled = true; + logTo('dns-log', `tunnel resolve ${host}`); + const t0 = performance.now(); + try { + const ip = await mixDNS(host); + const ms = (performance.now() - t0).toFixed(0); + logTo('dns-log', `tunnel ${host} => ${ip} (${ms} ms)`, 'green'); + } catch (e) { + logTo('dns-log', `tunnel resolve failed: ${e}`, 'red'); + } finally { + btn.disabled = false; + } +}); + +// Browsers expose no raw DNS API; the closest analogue from JS is DoH via +// HTTPS to a public resolver. Google's JSON API is CORS-friendly. +$('btn-dns-clearnet').addEventListener('click', async () => { + const host = ($('dns-host') as HTMLInputElement).value.trim(); + if (!host) { logTo('dns-log', 'Hostname is required', 'red'); return; } + + logTo('dns-log', `clearnet DoH resolve ${host}`); + const t0 = performance.now(); + try { + const resp = await window.fetch( + `https://dns.google/resolve?name=${encodeURIComponent(host)}&type=A`, + { mode: 'cors' }, + ); + const json = (await resp.json()) as { Status: number; Answer?: Array<{ type: number; data: string }> }; + const ms = (performance.now() - t0).toFixed(0); + + if (json.Status !== 0) { + logTo('dns-log', `clearnet DoH error: status=${json.Status} (${ms} ms)`, 'red'); + return; + } + const a = json.Answer?.find((r) => r.type === 1); + if (!a) { logTo('dns-log', `clearnet DoH: no A record (${ms} ms)`, 'orange'); return; } + logTo('dns-log', `clearnet ${host} => ${a.data} (${ms} ms); visible in DevTools Network`, 'green'); + } catch (e) { + logTo('dns-log', `clearnet DoH failed: ${e}`, 'red'); + } +}); + +// GET =============================================================== + +// `asImage` is a per-call argument rather than module state because GET +// requests interleave: a preset-fired image fetch may still be awaiting its +// body when a second preset click arrives. Closing over the flag in the +// caller's scope keeps each invocation's intent isolated. +async function getViaTunnel(url: string, asImage: boolean) { + logTo('get-log', `tunnel GET ${url}`); + const t0 = performance.now(); + try { + const resp = await mixFetch(url, fetchInit()); + const ms = (performance.now() - t0).toFixed(0); + const ct = resp.headers.get('content-type') ?? '?'; + logTo('get-log', `tunnel ${resp.status} ${resp.statusText} (${ms} ms, ${ct})`, 'green'); + + if (!resp.ok) { + const errText = await resp.text(); + logTo('get-log', errText.length > 600 ? `${errText.slice(0, 600)}\n... (${errText.length} bytes total)` : errText); + return; + } + + if (asImage) { + const buf = await resp.arrayBuffer(); + const type = resp.headers.get('content-type') ?? 'image/svg+xml'; + const blobUrl = URL.createObjectURL(new Blob([buf], { type })); + const img = document.createElement('img'); + img.src = blobUrl; + img.style.maxWidth = '120px'; + img.style.marginRight = '4px'; + img.title = url; + $('get-image-output').appendChild(img); + } else { + const text = await resp.text(); + logTo('get-log', text.length > 400 ? `${text.slice(0, 400)}\n... (${text.length} bytes total)` : text); + } + } catch (e) { + logTo('get-log', `tunnel GET failed: ${e}`, 'red'); + } +} + +$('btn-get-tunnel').addEventListener('click', () => { + const url = ($('get-url') as HTMLInputElement).value.trim(); + if (!url) { logTo('get-log', 'URL is required', 'red'); return; } + getViaTunnel(url, false); +}); + +$('btn-get-clearnet').addEventListener('click', async () => { + const url = ($('get-url') as HTMLInputElement).value.trim(); + if (!url) { logTo('get-log', 'URL is required', 'red'); return; } + logTo('get-log', `clearnet GET ${url}`); + const t0 = performance.now(); + try { + const resp = await window.fetch(url, { mode: 'cors' }); + const ms = (performance.now() - t0).toFixed(0); + logTo('get-log', `clearnet ${resp.status} ${resp.statusText} (${ms} ms); visible in DevTools Network`, 'green'); + } catch (e) { + logTo('get-log', `clearnet fetch failed: ${e}`, 'red'); + } +}); + +// Preset buttons fill the URL field and immediately tunnel-fetch. The +// `data-render="image"` hint asks the GET handler to render the body as an +// inline rather than logging the response text. +for (const btn of Array.from(document.querySelectorAll('button.preset'))) { + btn.addEventListener('click', () => { + const url = btn.dataset.url ?? ''; + if (!url) return; + ($('get-url') as HTMLInputElement).value = url; + getViaTunnel(url, btn.dataset.render === 'image'); + }); +} + +// WebSocket ========================================================= + +let activeWs: MixWebSocket | undefined; +let wsConnectT0 = 0; +const wsSendQueue: number[] = []; + +// Burst-mode state: collected silently to avoid log spam during 500-msg runs. +let wsBurstActive = false; +let wsBurstRtts: number[] = []; +let wsBurstExpected = 0; +let wsBurstResolve: (() => void) | null = null; +let wsBurstHashes: string[] = []; +let wsBurstVerified = 0; +let wsBurstMismatches = 0; + +function setWsButtonState(state: 'connected' | 'connecting' | 'disconnected') { + const connected = state === 'connected'; + const connecting = state === 'connecting'; + ($('btn-ws-connect') as HTMLButtonElement).disabled = connected || connecting; + ($('btn-ws-send') as HTMLButtonElement).disabled = !connected; + ($('btn-ws-close') as HTMLButtonElement).disabled = !connected; + ($('btn-ws-burst') as HTMLButtonElement).disabled = !connected; +} + +$('btn-ws-connect').addEventListener('click', () => { + const url = ($('ws-url') as HTMLInputElement).value.trim(); + if (!url) { logTo('ws-log', 'WebSocket URL is required', 'red'); return; } + + // Tear down any prior connection so a rapid double-click doesn't leak it. + if (activeWs && activeWs.readyState !== 3 /* CLOSED */) activeWs.close(); + + const statusEl = $('ws-status'); + statusEl.textContent = 'Connecting...'; + statusEl.style.color = 'orange'; + setWsButtonState('connecting'); + wsSendQueue.length = 0; + + logTo('ws-log', `connecting to ${url}`); + wsConnectT0 = performance.now(); + + const ws = new MixWebSocket(url); + activeWs = ws; + + ws.addEventListener('open', () => { + const ms = (performance.now() - wsConnectT0).toFixed(0); + logTo('ws-log', `connected in ${ms} ms`, 'green'); + statusEl.textContent = `Connected (${ms} ms)`; + statusEl.style.color = 'green'; + setWsButtonState('connected'); + }); + + ws.addEventListener('message', async (ev) => { + const data = (ev as MessageEvent).data; + let preview: string; + let bytes: Uint8Array | undefined; + if (typeof data === 'string') { + preview = data.length <= 200 ? data : `${data.slice(0, 200)}...`; + } else if (data instanceof ArrayBuffer) { + bytes = new Uint8Array(data as ArrayBuffer); + preview = `[binary ${bytes.length} bytes] ${hexPreview(bytes)}`; + } else { + preview = `[unknown ${typeof data}]`; + } + + const rttMs = wsSendQueue.length > 0 ? performance.now() - (wsSendQueue.shift() as number) : null; + + if (wsBurstActive) { + if (rttMs !== null) wsBurstRtts.push(rttMs); + // Verify echo content against the recorded send hash. + if (bytes) { + const hash = await sha256hex(bytes); + if (hash === wsBurstHashes[wsBurstVerified + wsBurstMismatches]) wsBurstVerified += 1; + else wsBurstMismatches += 1; + } + if (wsBurstRtts.length >= wsBurstExpected && wsBurstResolve) wsBurstResolve(); + return; + } + + if (rttMs !== null) logTo('ws-log', `recv (${rttMs.toFixed(0)} ms RTT): ${preview}`, 'green'); + else logTo('ws-log', `recv: ${preview}`, 'green'); + }); + + ws.addEventListener('close', (ev) => { + const ce = ev as CloseEvent; + logTo('ws-log', `closed: ${ce.code} ${ce.reason}`, 'orange'); + statusEl.textContent = 'Closed'; + statusEl.style.color = 'gray'; + setWsButtonState('disconnected'); + activeWs = undefined; + }); + + ws.addEventListener('error', (ev) => { + // MixWebSocket attaches a non-standard `.message` to its error events so + // the playground can surface the underlying cause. + const msg = (ev as Event & { message?: string }).message ?? '(no detail)'; + logTo('ws-log', `error: ${msg}`, 'red'); + statusEl.textContent = 'Error'; + statusEl.style.color = 'red'; + }); +}); + +$('btn-ws-send').addEventListener('click', async () => { + if (!activeWs || activeWs.readyState !== 1 /* OPEN */) return; + const msg = ($('ws-message') as HTMLInputElement).value; + wsSendQueue.push(performance.now()); + try { + await activeWs.send(msg); + logTo('ws-log', `send: ${msg}`); + } catch (e) { + logTo('ws-log', `send failed: ${e}`, 'red'); + } +}); + +$('btn-ws-close').addEventListener('click', async () => { + if (!activeWs) return; + logTo('ws-log', 'closing...'); + try { + await activeWs.close(1000, 'done'); + } catch (e) { + logTo('ws-log', `close failed: ${e}`, 'red'); + } +}); + +$('btn-ws-burst').addEventListener('click', async () => { + if (!activeWs || activeWs.readyState !== 1) return; + const count = parseInt(($('ws-burst-count') as HTMLInputElement).value, 10); + const minSize = parseInt(($('ws-burst-min') as HTMLInputElement).value, 10); + const maxSize = parseInt(($('ws-burst-max') as HTMLInputElement).value, 10); + + if (count < 1 || count > 500) { logTo('ws-log', 'burst count must be 1-500', 'red'); return; } + if (minSize < 1 || maxSize < minSize) { logTo('ws-log', 'invalid size range', 'red'); return; } + + ($('btn-ws-burst') as HTMLButtonElement).disabled = true; + ($('btn-ws-send') as HTMLButtonElement).disabled = true; + + // Generate random payloads + pre-compute their hashes for echo verification. + const payloads: Uint8Array[] = []; + wsBurstHashes = []; + let totalBytes = 0; + for (let i = 0; i < count; i++) { + const size = minSize + Math.floor(Math.random() * (maxSize - minSize + 1)); + const buf = new Uint8Array(size); + crypto.getRandomValues(buf); + payloads.push(buf); + totalBytes += size; + // eslint-disable-next-line no-await-in-loop + wsBurstHashes.push(await sha256hex(buf)); + } + + wsBurstActive = true; + wsBurstRtts = []; + wsBurstExpected = count; + wsBurstVerified = 0; + wsBurstMismatches = 0; + wsSendQueue.length = 0; + + logTo('ws-log', `burst: ${count} msgs, ${formatSize(totalBytes)} total`); + + const burstDone = new Promise((resolve) => { + wsBurstResolve = resolve; + }); + + const t0 = performance.now(); + for (const payload of payloads) { + wsSendQueue.push(performance.now()); + // eslint-disable-next-line no-await-in-loop + await activeWs.send(payload); + } + + await burstDone; + const totalMs = performance.now() - t0; + + wsBurstActive = false; + wsBurstResolve = null; + + const rtts = wsBurstRtts.slice().sort((a, b) => a - b); + const rttMin = rtts[0]?.toFixed(0) ?? '?'; + const rttMax = rtts[rtts.length - 1]?.toFixed(0) ?? '?'; + const rttAvg = rtts.length ? (rtts.reduce((a, b) => a + b, 0) / rtts.length).toFixed(0) : '?'; + const p50 = rtts[Math.floor(rtts.length * 0.5)]?.toFixed(0) ?? '?'; + const p95 = rtts[Math.floor(rtts.length * 0.95)]?.toFixed(0) ?? '?'; + const msgPerSec = (count / (totalMs / 1000)).toFixed(1); + + logTo('ws-log', `burst done: ${count} msgs in ${(totalMs / 1000).toFixed(2)}s (${msgPerSec} msg/s, ${formatRate(totalBytes, totalMs)})`, 'green'); + logTo('ws-log', `verify: ${wsBurstVerified}/${count} OK${wsBurstMismatches > 0 ? `, ${wsBurstMismatches} MISMATCH` : ''}`, wsBurstMismatches === 0 ? 'green' : 'red'); + logTo('ws-log', `RTT: min=${rttMin} avg=${rttAvg} p50=${p50} p95=${p95} max=${rttMax} ms`); + + ($('btn-ws-burst') as HTMLButtonElement).disabled = false; + ($('btn-ws-send') as HTMLButtonElement).disabled = false; +}); + +// Stress Test ======================================================= + +interface SizeProfile { label: string; bytes: number; } +const SIZE_PROFILES: SizeProfile[] = [ + { label: 'tiny', bytes: 128 }, + { label: 'small', bytes: 1024 }, + { label: 'medium', bytes: 10240 }, + { label: 'large', bytes: 102400 }, + { label: 'xlarge', bytes: 1048576 }, +]; + +interface DripProfile { label: string; duration: number; delay: number; bytes: number; } +const buildDripProfiles = (timeoutSec: number): DripProfile[] => [ + { label: 'safe', duration: Math.round(timeoutSec * 0.5), delay: 0, bytes: 100 }, + { label: 'boundary', duration: Math.round(timeoutSec * 0.92), delay: 0, bytes: 100 }, + { label: 'over', duration: Math.round(timeoutSec * 1.08), delay: 0, bytes: 100 }, + { label: 'slow-start', duration: Math.round(timeoutSec * 0.83), delay: Math.round(timeoutSec * 0.17), bytes: 100 }, +]; + +interface StressRequest { id: number; url: string; label: string; } + +function generateRequests(count: number, mode: string, timeoutSec: number): StressRequest[] { + const requests: StressRequest[] = []; + if (mode === 'uniform') { + const baseUrl = ($('stress-url') as HTMLInputElement).value.trim(); + for (let i = 1; i <= count; i++) requests.push({ id: i, url: `${baseUrl}${i}`, label: 'uniform' }); + } else if (mode === 'mixed') { + for (let i = 1; i <= count; i++) { + const p = SIZE_PROFILES[Math.floor(Math.random() * SIZE_PROFILES.length)]; + requests.push({ id: i, url: `https://httpbin.org/bytes/${p.bytes}`, label: p.label }); + } + } else if (mode === 'drip') { + const profiles = buildDripProfiles(timeoutSec); + for (let i = 1; i <= count; i++) { + const p = profiles[Math.floor(Math.random() * profiles.length)]; + requests.push({ + id: i, + url: `https://httpbin.org/drip?duration=${p.duration}&numbytes=${p.bytes}&delay=${p.delay}&code=200`, + label: p.label, + }); + } + } + return requests; +} + +interface StressResult { id: number; label: string; ok: boolean; elapsed: string; status?: number; textLength?: number; error?: string; } + +async function runOneStressRequest(req: StressRequest): Promise { + const tag = `#${req.id} ${req.label}`; + const start = performance.now(); + try { + const resp = await mixFetch(req.url, fetchInit()); + const body = await resp.text(); + const elapsed = ((performance.now() - start) / 1000).toFixed(2); + logTo('stress-log', `[${tag}] ${resp.status} OK ${elapsed}s (${body.length}B)`, 'green'); + return { id: req.id, label: req.label, ok: true, elapsed, status: resp.status, textLength: body.length }; + } catch (e) { + const elapsed = ((performance.now() - start) / 1000).toFixed(2); + logTo('stress-log', `[${tag}] FAIL ${elapsed}s: ${e}`, 'red'); + return { id: req.id, label: req.label, ok: false, elapsed, error: String(e) }; + } +} + +$('stress-mode').addEventListener('change', (ev) => { + const mode = (ev.target as HTMLSelectElement).value; + $('stress-uniform-opts').style.display = mode === 'uniform' ? 'block' : 'none'; + $('stress-mixed-opts').style.display = mode === 'mixed' ? 'block' : 'none'; + $('stress-drip-opts').style.display = mode === 'drip' ? 'block' : 'none'; +}); + +$('btn-stress').addEventListener('click', async () => { + const count = parseInt(($('stress-count') as HTMLInputElement).value, 10); + const mode = ($('stress-mode') as HTMLSelectElement).value; + const timeoutSec = parseInt(($('stress-timeout') as HTMLInputElement)?.value || '60', 10); + + const statusEl = $('stress-status'); + ($('btn-stress') as HTMLButtonElement).disabled = true; + statusEl.textContent = 'Running...'; + + const requests = generateRequests(count, mode, timeoutSec); + + if (mode === 'mixed' || mode === 'drip') { + const breakdown: Record = {}; + for (const r of requests) breakdown[r.label] = (breakdown[r.label] || 0) + 1; + logTo('stress-log', `${count} requests, ${mode} mode, profiles: ${JSON.stringify(breakdown)}`); + } else { + logTo('stress-log', `${count} requests, ${mode} mode`); + } + + const t0 = performance.now(); + const settled = await Promise.allSettled(requests.map((r) => runOneStressRequest(r))); + const totalSec = ((performance.now() - t0) / 1000).toFixed(2); + + const results: StressResult[] = settled.map((s) => + s.status === 'fulfilled' ? s.value : ({ id: -1, label: '?', ok: false, elapsed: '?', error: String(s.reason) } as StressResult), + ); + const ok = results.filter((r) => r.ok).length; + const fail = results.filter((r) => !r.ok).length; + + logTo('stress-log', `done: ${ok}/${count} OK, ${fail} failed (${totalSec}s total)`, fail === 0 ? 'green' : 'red'); + if (fail > 0) { + for (const r of results.filter((r) => !r.ok)) { + logTo('stress-log', ` FAIL #${r.id} ${r.label} (${r.elapsed}s): ${r.error}`); + } + } + + statusEl.textContent = `Done: ${ok}/${count} OK, ${fail} failed (${totalSec}s)`; + ($('btn-stress') as HTMLButtonElement).disabled = false; +}); + +// File Download ===================================================== + +// UCS Cambridge UTF-8 demo file — small, public, character-rich. Good for +// confirming byte-for-byte preservation across the tunnel. +const VERIFY_TEXT_URL = 'https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-demo.txt'; + +let cachedPdf: ArrayBuffer | null = null; + +$('btn-verify-text').addEventListener('click', async () => { + const statusEl = $('verify-text-status'); + const outputEl = $('verify-text-output') as HTMLPreElement; + ($('btn-verify-text') as HTMLButtonElement).disabled = true; + statusEl.textContent = 'Fetching...'; + statusEl.style.color = 'orange'; + + const t0 = performance.now(); + try { + const resp = await mixFetch(VERIFY_TEXT_URL, fetchInit()); + const text = await resp.text(); + const ms = (performance.now() - t0).toFixed(0); + statusEl.textContent = `${resp.status} OK (${ms} ms, ${text.length} chars)`; + statusEl.style.color = 'green'; + outputEl.textContent = text; + outputEl.style.display = 'block'; + logTo('download-log', `UTF-8 demo: ${text.length} chars (${ms} ms)`, 'green'); + } catch (e) { + statusEl.textContent = `Failed: ${e}`; + statusEl.style.color = 'red'; + logTo('download-log', `UTF-8 demo failed: ${e}`, 'red'); + } finally { + ($('btn-verify-text') as HTMLButtonElement).disabled = false; + } +}); + +$('btn-verify-pdf').addEventListener('click', async () => { + const url = ($('download-url') as HTMLInputElement).value.trim(); + if (!url) { logTo('download-log', 'PDF URL is required', 'red'); return; } + + const statusEl = $('verify-pdf-status'); + const outputEl = $('verify-pdf-output'); + ($('btn-verify-pdf') as HTMLButtonElement).disabled = true; + statusEl.textContent = 'Fetching...'; + statusEl.style.color = 'orange'; + + const t0 = performance.now(); + try { + const resp = await mixFetch(url, fetchInit()); + const buf = await resp.arrayBuffer(); + const ms = (performance.now() - t0).toFixed(0); + const hash = await sha256hex(buf); + + cachedPdf = buf; + $('verify-pdf-size').textContent = `${formatSize(buf.byteLength)} (${buf.byteLength} bytes)`; + $('verify-pdf-sha').textContent = hash; + outputEl.style.display = 'block'; + ($('btn-save-pdf') as HTMLButtonElement).disabled = false; + + statusEl.textContent = `${resp.status} OK (${ms} ms)`; + statusEl.style.color = 'green'; + logTo('download-log', `PDF: ${formatSize(buf.byteLength)} (${ms} ms), sha256=${hash.slice(0, 16)}...`, 'green'); + } catch (e) { + statusEl.textContent = `Failed: ${e}`; + statusEl.style.color = 'red'; + logTo('download-log', `PDF failed: ${e}`, 'red'); + } finally { + ($('btn-verify-pdf') as HTMLButtonElement).disabled = false; + } +}); + +$('btn-save-pdf').addEventListener('click', () => { + if (!cachedPdf) return; + const url = ($('download-url') as HTMLInputElement).value.trim(); + const name = url.split('/').pop() || 'download.pdf'; + saveFile(cachedPdf, name, 'application/pdf'); +}); + +// Page load ========================================================== + +window.addEventListener('DOMContentLoaded', () => { + // Pre-populate clientId so each page load uses a fresh keystore slot. + ($('opt-client-id') as HTMLInputElement).value = `sdk-${Math.random().toString(36).slice(2, 8)}`; + display('SDK dev ready. Click setupMixTunnel to connect.'); +}); diff --git a/sdk/typescript/packages/mix-fetch/internal-dev/tsconfig.json b/sdk/typescript/packages/internal-dev/tsconfig.json similarity index 76% rename from sdk/typescript/packages/mix-fetch/internal-dev/tsconfig.json rename to sdk/typescript/packages/internal-dev/tsconfig.json index 4fdd59edbb..347c37339a 100644 --- a/sdk/typescript/packages/mix-fetch/internal-dev/tsconfig.json +++ b/sdk/typescript/packages/internal-dev/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "../../../tsconfig.json", + "extends": "../../tsconfig.json", "compilerOptions": { "module": "ESNext", "outDir": "./dist" diff --git a/sdk/typescript/packages/internal-dev/webpack.common.js b/sdk/typescript/packages/internal-dev/webpack.common.js new file mode 100644 index 0000000000..e84466b39a --- /dev/null +++ b/sdk/typescript/packages/internal-dev/webpack.common.js @@ -0,0 +1,38 @@ +const path = require('path'); +const { mergeWithRules } = require('webpack-merge'); +const { webpackCommon } = require('../../examples/.webpack/webpack.base'); + +// smolmix-wasm is base64-inlined into the @nymproject/mix-tunnel worker bundle +// (see mix-tunnel/rollup/worker.mjs `maxFileSize`), which is itself base64-inlined +// into mix-tunnel/dist/esm/index.js. No sibling .wasm asset to copy. + +module.exports = mergeWithRules({ + module: { + rules: { + test: 'match', + use: 'replace', + }, + }, +})( + webpackCommon( + __dirname, + [ + { + inject: true, + filename: 'index.html', + template: path.resolve(__dirname, 'src/index.html'), + chunks: ['index'], + }, + ], + { skipFavicon: true }, + ), + { + entry: { + index: path.resolve(__dirname, 'src/index.ts'), + }, + output: { + path: path.resolve(__dirname, 'dist'), + publicPath: '/', + }, + }, +); diff --git a/sdk/typescript/packages/mix-fetch/internal-dev/webpack.config.js b/sdk/typescript/packages/internal-dev/webpack.config.js similarity index 100% rename from sdk/typescript/packages/mix-fetch/internal-dev/webpack.config.js rename to sdk/typescript/packages/internal-dev/webpack.config.js diff --git a/sdk/typescript/packages/mix-fetch/internal-dev/webpack.prod.js b/sdk/typescript/packages/internal-dev/webpack.prod.js similarity index 100% rename from sdk/typescript/packages/mix-fetch/internal-dev/webpack.prod.js rename to sdk/typescript/packages/internal-dev/webpack.prod.js diff --git a/sdk/typescript/packages/mix-dns/README.md b/sdk/typescript/packages/mix-dns/README.md new file mode 100644 index 0000000000..71fa1faea0 --- /dev/null +++ b/sdk/typescript/packages/mix-dns/README.md @@ -0,0 +1,30 @@ +# @nymproject/mix-dns + +Hostname-to-IP resolution over the Nym mixnet. Uses the IP Packet Router's +DNS path (UDP), so no TCP socket or TLS handshake is set up. + +## Usage + +```ts +import { setupMixTunnel, mixDNS } from '@nymproject/mix-dns'; + +await setupMixTunnel(); + +const ip = await mixDNS('example.com'); +console.log(ip); // "93.184.216.34" +``` + +The tunnel is shared with `@nymproject/mix-fetch` and +`@nymproject/mix-websocket` via `@nymproject/mix-tunnel`; calling +`setupMixTunnel` once is enough for all three. + +## Consumer build requirements + +Ships as raw ESM with a bare `import` of `@nymproject/mix-tunnel`. Use a +bundler that follows package imports (webpack, rollup, parcel, vite, +esbuild). + +Runs in any environment exposing `Worker`, `WebAssembly`, `Blob`, and +`URL.createObjectURL`. That covers modern browsers, Electron renderers, +and mobile WebViews (Capacitor, Cordova, Ionic, iOS WKWebView, Android +WebView). A Node-direct entry point is not yet ported from v1. diff --git a/sdk/typescript/packages/mix-dns/package.json b/sdk/typescript/packages/mix-dns/package.json new file mode 100644 index 0000000000..b0423542d2 --- /dev/null +++ b/sdk/typescript/packages/mix-dns/package.json @@ -0,0 +1,52 @@ +{ + "name": "@nymproject/mix-dns", + "version": "0.1.0", + "description": "Hostname-to-IP resolution over the Nym mixnet (DNS over UDP/IPR, no TCP/TLS).", + "license": "Apache-2.0", + "author": "Nym Technologies SA", + "homepage": "https://nym.com", + "repository": { + "type": "git", + "url": "https://github.com/nymtech/nym", + "directory": "sdk/typescript/packages/mix-dns" + }, + "bugs": { + "url": "https://github.com/nymtech/nym/issues" + }, + "keywords": ["nym", "mixnet", "privacy", "dns"], + "sideEffects": false, + "files": [ + "dist/**/*" + ], + "main": "dist/index.js", + "module": "dist/index.js", + "browser": "dist/index.js", + "scripts": { + "build": "tsc", + "clean": "rimraf dist", + "docs:generate": "typedoc", + "docs:generate:prod": "typedoc --basePath ./docs/tsdoc/nymproject/mix-dns/", + "lint": "eslint src", + "lint:fix": "eslint src --fix", + "start": "tsc -w", + "tsc": "tsc --noEmit true" + }, + "dependencies": { + "@nymproject/mix-tunnel": "workspace:*" + }, + "devDependencies": { + "@nymproject/eslint-config-react-typescript": "workspace:*", + "@typescript-eslint/eslint-plugin": "catalog:", + "@typescript-eslint/parser": "catalog:", + "eslint": "^8.10.0", + "rimraf": "catalog:", + "tslib": "catalog:", + "typescript": "^4.8.4" + }, + "private": false, + "type": "module", + "types": "./dist/index.d.ts", + "publishConfig": { + "access": "public" + } +} diff --git a/sdk/typescript/packages/mix-dns/src/index.ts b/sdk/typescript/packages/mix-dns/src/index.ts new file mode 100644 index 0000000000..beb5520c93 --- /dev/null +++ b/sdk/typescript/packages/mix-dns/src/index.ts @@ -0,0 +1,26 @@ +// @nymproject/mix-dns +// +// Hostname-to-IP resolution over the Nym mixnet. Travels the IPR's DNS +// path (UDP) without setting up a TCP or TLS connection. + +import { + getMixTunnel, + setupMixTunnel, + disconnectMixTunnel, + getTunnelState, + SetupMixTunnelOpts, +} from '@nymproject/mix-tunnel'; + +export { setupMixTunnel, disconnectMixTunnel, getTunnelState }; +export type { SetupMixTunnelOpts }; + +/** + * Resolve a hostname through the mixnet. Returns the IP as a string + * (e.g. `"93.184.216.34"`). + * + * The tunnel must already be set up via `setupMixTunnel()`. + */ +export const mixDNS = async (hostname: string): Promise => { + const tunnel = await getMixTunnel(); + return tunnel.mixDNS(hostname); +}; diff --git a/sdk/typescript/packages/mix-dns/tsconfig.json b/sdk/typescript/packages/mix-dns/tsconfig.json new file mode 100644 index 0000000000..70c3f2c8d6 --- /dev/null +++ b/sdk/typescript/packages/mix-dns/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "lib": ["es2021", "dom", "esnext"], + "outDir": "./dist/", + "module": "esnext", + "target": "esnext", + "allowJs": false, + "strict": true, + "moduleResolution": "node", + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "declaration": true, + "sourceMap": true, + "baseUrl": ".", + "downlevelIteration": true + }, + "include": ["src/**/*.ts"], + "exclude": ["node_modules", "**/node_modules", "dist", "**/dist"] +} diff --git a/sdk/typescript/packages/mix-fetch-node/typedoc.json b/sdk/typescript/packages/mix-dns/typedoc.json similarity index 77% rename from sdk/typescript/packages/mix-fetch-node/typedoc.json rename to sdk/typescript/packages/mix-dns/typedoc.json index c9f4892a56..045ccc67a6 100644 --- a/sdk/typescript/packages/mix-fetch-node/typedoc.json +++ b/sdk/typescript/packages/mix-dns/typedoc.json @@ -1,8 +1,9 @@ { "sort": ["kind"], "entryPoints": ["./src/index.ts"], - "out": "./docs", - "exclude": ["./src/worker/**"], + "out": "../../../../documentation/docs/pages/developers/mix-dns/api", + "plugin": ["typedoc-plugin-markdown"], + "entryFileName": "globals", "kindSortOrder": [ "Function", "Interface", diff --git a/sdk/typescript/packages/mix-fetch-node/.gitignore b/sdk/typescript/packages/mix-fetch-node/.gitignore deleted file mode 100644 index 71c42dc754..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -src/worker/*.js -docs diff --git a/sdk/typescript/packages/mix-fetch-node/README.md b/sdk/typescript/packages/mix-fetch-node/README.md deleted file mode 100644 index 89050cb4f8..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/README.md +++ /dev/null @@ -1,14 +0,0 @@ -# Nym MixFetch - -This package is a drop-in replacement for `fetch` in NodeJS to send HTTP requests over the Nym Mixnet. - -## Usage - -```js -const { mixFetch } = require('@nymproject/mix-fetch-node-commonjs'); - -... - -const response = await mixFetch('https://nymtech.net'); -const html = await response.text(); -``` diff --git a/sdk/typescript/packages/mix-fetch-node/internal/index.js b/sdk/typescript/packages/mix-fetch-node/internal/index.js deleted file mode 100644 index 5804f8c631..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/internal/index.js +++ /dev/null @@ -1,54 +0,0 @@ -const { createMixFetch, disconnectMixFetch } = require('../dist/cjs/index.js'); - -/** - * The main entry point - */ -(async () => { - console.log('Tester is starting up...'); - - const addr = - 'D274yd1h3L3pNJzdxE5VgJ7izAsAVMsDrQtFSkKUegfk.8J67cGbcwvrJKF3Kb16HVWWc9AnrFnEibNCm9zCkuVFu@Emswx6KXyjRfq1c2k4d4uD2e6nBSbH1biorCZUei8UNS'; - - console.log('About to set up mixFetch...'); - const { mixFetch } = await createMixFetch({ - preferredNetworkRequester: addr, - clientId: 'node-client1', - clientOverride: { - coverTraffic: { disableLoopCoverTrafficStream: true }, - traffic: { disableMainPoissonPacketDistribution: true }, - }, - mixFetchOverride: { requestTimeoutMs: 60000 }, - responseBodyConfigMap: {}, - extra: {}, - }); - - globalThis.mixFetch = mixFetch; - - if (!globalThis.mixFetch) { - console.error('Oh no! Could not create mixFetch'); - } else { - console.log('Ready!'); - } - - let url = 'https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt'; - console.log(`Using mixFetch to get ${url}...`); - const args = { mode: 'unsafe-ignore-cors' }; - - let resp = await mixFetch(url, args); - console.log({ resp }); - const text = await resp.text(); - - console.log('disconnecting'); - await disconnectMixFetch(); - console.log('disconnected! all further usages should fail'); - - // get an image - url = 'https://nymtech.net/favicon.svg'; - resp = await mixFetch(url, args); - console.log({ resp }); - const buffer = await resp.arrayBuffer(); - const type = resp.headers.get('Content-Type') || 'image/svg'; - const blobUrl = URL.createObjectURL(new Blob([buffer], { type })); - console.log(JSON.stringify({ bufferBytes: buffer.byteLength, blobUrl }, null, 2)); - console.log(blobUrl); -})(); diff --git a/sdk/typescript/packages/mix-fetch-node/jest.config.mjs b/sdk/typescript/packages/mix-fetch-node/jest.config.mjs deleted file mode 100644 index 568dd98124..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/jest.config.mjs +++ /dev/null @@ -1,16 +0,0 @@ -import preset from 'ts-jest/presets/index.js'; - -/** @type {import('ts-jest').JestConfigWithTsJest} */ -export default { - ...preset.defaults, - verbose: true, - transform: { - '^.+\\.(ts|tsx)$': [ - 'ts-jest', - { - tsconfig: 'tsconfig.jest.json', - useESM: true, - }, - ], - }, -}; diff --git a/sdk/typescript/packages/mix-fetch-node/package.json b/sdk/typescript/packages/mix-fetch-node/package.json deleted file mode 100644 index 2089653d40..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/package.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "name": "@nymproject/mix-fetch-node", - "version": "1.4.3", - "description": "This package is a drop-in replacement for `fetch` in NodeJS to send HTTP requests over the Nym Mixnet.", - "license": "Apache-2.0", - "author": "Nym Technologies SA", - "files": [ - "dist/cjs/worker.js", - "dist/**/*" - ], - "main": "dist/cjs/index.js", - "scripts": { - "build": "scripts/build-prod.sh", - "build:dev": "scripts/build.sh", - "build:worker": "rollup -c rollup-worker.config.mjs", - "clean": "rimraf dist", - "docs:dev": "run-p docs:watch docs:serve ", - "docs:generate": "typedoc", - "docs:generate:prod": "typedoc --basePath ./docs/tsdoc/nymproject/sdk/", - "docs:prod:build": "scripts/build-prod-docs-collect.sh", - "docs:serve": "reload -b -d ./docs -p 3000", - "docs:watch": "nodemon --ext ts --watch './src/**/*' --watch './typedoc.json' --exec \"pnpm docs:generate\"", - "lint": "eslint src", - "lint:fix": "eslint src --fix", - "start": "tsc -w", - "start:dev": "nodemon --watch src -e ts,json --exec 'pnpm build:dev:esm'", - "test": "node --experimental-fetch --experimental-vm-modules node_modules/jest/bin/jest.js -c=jest.config.mjs --no-cache", - "tsc": "tsc --noEmit true" - }, - "dependencies": { - "@nymproject/mix-fetch-wasm-node": ">=1.4.2-rc.0 || ^1", - "comlink": "^4.3.1", - "fake-indexeddb": "^5.0.0", - "node-fetch": "^3.3.2", - "ws": "^8.14.2" - }, - "devDependencies": { - "@rollup/plugin-commonjs": "^24.0.1", - "@rollup/plugin-node-resolve": "^15.0.1", - "@rollup/plugin-replace": "^5.0.2", - "@rollup/plugin-typescript": "^10.0.1", - "@rollup/plugin-wasm": "^6.1.1", - "@types/jest": "^27.0.1", - "@types/node": "^16.7.13", - "@types/ws": "catalog:", - "@typescript-eslint/eslint-plugin": "catalog:", - "@typescript-eslint/parser": "catalog:", - "eslint": "^8.10.0", - "eslint-config-airbnb": "catalog:", - "eslint-config-airbnb-typescript": "catalog:", - "eslint-config-prettier": "catalog:", - "eslint-import-resolver-root-import": "catalog:", - "eslint-plugin-import": "catalog:", - "eslint-plugin-jest": "catalog:", - "eslint-plugin-jsx-a11y": "catalog:", - "eslint-plugin-prettier": "catalog:", - "jest": "^29.5.0", - "nodemon": "^2.0.21", - "reload": "^3.2.1", - "rimraf": "catalog:", - "rollup": "^3.9.1", - "rollup-plugin-base64": "^1.0.1", - "rollup-plugin-modify": "^3.0.0", - "rollup-plugin-web-worker-loader": "^1.6.1", - "ts-jest": "^29.1.0", - "ts-loader": "catalog:", - "tslib": "catalog:", - "typedoc": "^0.24.8", - "typescript": "^4.8.4" - }, - "private": false, - "types": "./dist/cjs/index.d.ts" -} diff --git a/sdk/typescript/packages/mix-fetch-node/rollup-cjs.config.mjs b/sdk/typescript/packages/mix-fetch-node/rollup-cjs.config.mjs deleted file mode 100644 index 7a4af49fc2..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/rollup-cjs.config.mjs +++ /dev/null @@ -1,31 +0,0 @@ -/* eslint-disable import/no-extraneous-dependencies */ -import replace from '@rollup/plugin-replace'; -import resolve from '@rollup/plugin-node-resolve'; -import typescript from '@rollup/plugin-typescript'; -import webWorkerLoader from 'rollup-plugin-web-worker-loader'; -import { wasm } from '@rollup/plugin-wasm'; - -export default { - input: 'src/index.ts', - output: { - dir: 'dist/cjs', - format: 'cjs', - }, - plugins: [ - webWorkerLoader({ targetPlatform: 'node', inline: false }), - replace({ - values: { - "createURLWorkerFactory('web-worker-0.js')": - "createURLWorkerFactory(require('path').resolve(__dirname, 'web-worker-0.js'))", - }, - delimiters: ['', ''], - preventAssignment: true, - }), - resolve({ browser: false, extensions: ['.js', '.ts'] }), - wasm({ targetEnv: 'node', maxFileSize: 0 }), - typescript({ - compilerOptions: { outDir: 'dist/cjs', target: 'es5' }, - exclude: ['src/worker.ts'], - }), - ], -}; diff --git a/sdk/typescript/packages/mix-fetch-node/rollup-worker.config.mjs b/sdk/typescript/packages/mix-fetch-node/rollup-worker.config.mjs deleted file mode 100644 index a471223521..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/rollup-worker.config.mjs +++ /dev/null @@ -1,43 +0,0 @@ -/* eslint-disable import/no-extraneous-dependencies */ -import commonjs from '@rollup/plugin-commonjs'; -import modify from 'rollup-plugin-modify'; -import resolve from '@rollup/plugin-node-resolve'; -import typescript from '@rollup/plugin-typescript'; -import { wasm } from '@rollup/plugin-wasm'; - -export default { - input: 'src/worker/index.ts', - output: { - dir: 'dist/cjs', - format: 'cjs', - }, - external: ['util', 'fake-indexeddb'], - plugins: [ - resolve({ - browser: false, - preferBuiltins: true, - extensions: ['.js', '.ts'], - }), - commonjs(), - modify({ - find: 'const ret = new WebSocket(getStringFromWasm0(arg0, arg1));', - replace: 'const ws = require("ws"); const ret = new ws.WebSocket(getStringFromWasm0(arg0, arg1));', - }), - // TODO: `getObject(...).require` seems to generate a warning on Webpack but with Rollup we get a panic since it can't require. - // By hard coding the require here, we can workaround that. - // Reference: https://github.com/rust-random/getrandom/issues/224 - modify({ find: 'getObject(arg0).require(getStringFromWasm0(arg1, arg2));', replace: 'require("crypto");' }), - modify({ - find: 'getObject(arg0).getRandomValues(getObject(arg1));', - replace: 'require("crypto").getRandomValues(getObject(arg1));', - }), - wasm({ targetEnv: 'node', maxFileSize: 0, fileName: '[name].wasm' }), - typescript({ - compilerOptions: { - outDir: 'dist/cjs', - declaration: false, - target: 'es5', - }, - }), - ], -}; diff --git a/sdk/typescript/packages/mix-fetch-node/scripts/build-prod-docs-collect.sh b/sdk/typescript/packages/mix-fetch-node/scripts/build-prod-docs-collect.sh deleted file mode 100755 index a40a4a4a90..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/scripts/build-prod-docs-collect.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -rm -rf ../../../../dist/ts/docs/tsdoc/nymproject/mix-fetch-node || true - -# run the build -yarn docs:generate:prod - -# move the output outside of the yarn/npm workspaces -mkdir -p ../../../../dist/ts/docs/tsdoc/nymproject -mv docs ../../../../dist/ts/docs/tsdoc/nymproject/mix-fetch-node - -echo "Output can be found in:" -realpath ../../../../dist/ts/docs/tsdoc/nymproject/mix-fetch-node diff --git a/sdk/typescript/packages/mix-fetch-node/scripts/build-prod.sh b/sdk/typescript/packages/mix-fetch-node/scripts/build-prod.sh deleted file mode 100755 index 61377bdcf7..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/scripts/build-prod.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -rm -rf dist || true -rm -rf ../../../../dist/ts/sdk/mix-fetch-node || true - -# run the build -scripts/build.sh -node scripts/buildPackageJson.mjs - -# move the output outside of the yarn/npm workspaces -mkdir -p ../../../../dist/ts/sdk -mv dist ../../../../dist/ts/sdk -mv ../../../../dist/ts/sdk/dist ../../../../dist/ts/sdk/mix-fetch-node - -echo "Output can be found in:" -realpath ../../../../dist/ts/sdk/mix-fetch-node diff --git a/sdk/typescript/packages/mix-fetch-node/scripts/build.sh b/sdk/typescript/packages/mix-fetch-node/scripts/build.sh deleted file mode 100755 index 45196c1a2a..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/scripts/build.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -rm -rf dist || true - -#------------------------------------------------------- -# WEB WORKER (mix-fetch WASM) -#------------------------------------------------------- -# The web worker needs to be bundled because the WASM bundle needs to be loaded synchronously and all dependencies -# must be included in the worker script (because it is not loaded as an ES Module) - -# build the worker -rollup -c rollup-worker.config.mjs - -# move it next to the Typescript `src/index.ts` so it can be inlined by rollup -rm -f src/worker/*.js -rm -f src/worker/*.wasm -mv dist/cjs/index.js src/worker/worker.js - -# move WASM files out of build area -mkdir -p dist/worker -mv dist/cjs/*.wasm dist/worker - -#------------------------------------------------------- -# COMMON JS -#------------------------------------------------------- -# Some old build systems cannot fully handle ESM or ES2021, so build -# a CommonJS bundle targeting ES5 - -# build the SDK as a CommonJS bundle -rollup -c rollup-cjs.config.mjs - -# move WASM files into place -cp dist/worker/*.wasm dist/cjs - -#------------------------------------------------------- -# CLEAN UP -#------------------------------------------------------- - -rm -rf dist/cjs/worker - -# copy README -cp README.md dist/cjs/README.md - - diff --git a/sdk/typescript/packages/mix-fetch-node/scripts/buildPackageJson.mjs b/sdk/typescript/packages/mix-fetch-node/scripts/buildPackageJson.mjs deleted file mode 100644 index 592b17e1e0..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/scripts/buildPackageJson.mjs +++ /dev/null @@ -1,22 +0,0 @@ -import * as fs from 'fs'; - -// parse the package.json from the SDK, so we can keep fields like the name and version -const json = JSON.parse(fs.readFileSync('package.json').toString()); - -// defaults (NB: these are in the output file locations) -const browser = 'index.js'; -const main = 'index.js'; -const types = 'index.d.ts'; - -const getPackageJson = (type, suffix) => ({ - name: `${json.name}${suffix ? `-${suffix}` : ''}`, - version: json.version, - license: json.license, - author: json.author, - type, - browser, - main, - types, -}); - -fs.writeFileSync('dist/cjs/package.json', JSON.stringify(getPackageJson('commonjs', 'commonjs'), null, 2)); diff --git a/sdk/typescript/packages/mix-fetch-node/scripts/publish.sh b/sdk/typescript/packages/mix-fetch-node/scripts/publish.sh deleted file mode 100755 index a5cb97f78f..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/scripts/publish.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -rm -rf dist || true -rm -rf ../../../../dist || true - -yarn -yarn build -cd ../../../../dist/sdk - -cd cjs -echo "Publishing CommonJS package to NPM.." -npm publish --access=public -cd .. diff --git a/sdk/typescript/packages/mix-fetch-node/src/create-mix-fetch.ts b/sdk/typescript/packages/mix-fetch-node/src/create-mix-fetch.ts deleted file mode 100644 index 08e8811cf7..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/src/create-mix-fetch.ts +++ /dev/null @@ -1,77 +0,0 @@ -/* eslint-disable-next-line no-console */ - -import * as Comlink from 'comlink'; -import InlineWasmWebWorker from 'web-worker:./worker/worker'; -import { Worker } from 'node:worker_threads'; - -import nodeEndpoint from './node-adapter'; -import type { IMixFetchWebWorker } from './types'; -import { EventKinds, IMixFetch } from './types'; - -const createWorker = async () => - new Promise((resolve, reject) => { - // rollup will inline the built worker script, so that when the SDK is used in - // other projects, they will not need to mess around trying to bundle it - // however, it will make this SDK bundle bigger because of Base64 inline data - const worker = new InlineWasmWebWorker(); - - worker.addListener('error', reject); - worker.addListener('message', (msg: any) => { - worker.removeListener('error', reject); - if (msg.kind === EventKinds.Loaded) { - resolve(worker); - } else { - reject(msg); - } - }); - }); - -const convertHeaders = (headers: any): Headers => { - const out = new Headers(); - Object.keys(headers).forEach((key) => { - out.append(key, headers[key]); - }); - return out; -}; - -/** - * Use this method to initialise `mixFetch`. - * - * @returns An instance of `mixFetch` that you can use to make your requests using the same interface as `fetch`. - */ -export const createMixFetch = async (): Promise => { - // start the worker - const worker = await createWorker(); - - // bind with Comlink - const wrappedWorker = Comlink.wrap(nodeEndpoint(worker)); - - // handle the responses - const mixFetchWebWorker: IMixFetch = { - setupMixFetch: wrappedWorker.setupMixFetch, - mixFetch: async (url: string, args: any) => { - const workerResponse = await wrappedWorker.mixFetch(url, args); - if (!workerResponse) { - throw new Error('No response received'); - } - const { headers: headersRaw, status, statusText } = workerResponse; - - // reconstruct the Headers object instance from a plain object - const headers = convertHeaders(headersRaw); - - // handle blobs - if (workerResponse.body.blobUrl) { - const blob = await (await fetch(workerResponse.body.blobUrl)).blob(); - const body = await blob.arrayBuffer(); - return new Response(body, { headers, status, statusText }); - } - - // handle everything else - const body = Object.values(workerResponse.body)[0]; // we are expecting only one value to be set in `.body` - return new Response(body, { headers, status, statusText }); - }, - disconnectMixFetch: wrappedWorker.disconnectMixFetch, - }; - - return mixFetchWebWorker; -}; diff --git a/sdk/typescript/packages/mix-fetch-node/src/index.ts b/sdk/typescript/packages/mix-fetch-node/src/index.ts deleted file mode 100644 index 04a83ea144..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/src/index.ts +++ /dev/null @@ -1,56 +0,0 @@ -/* eslint-disable no-underscore-dangle */ -import type { SetupMixFetchOps, IMixFetchFn } from './types'; -import { createMixFetch as createMixFetchInternal } from './create-mix-fetch'; - -// this is the default timeout for getting a response -const REQUEST_TIMEOUT_MILLISECONDS = 60_000; - -export * from './types'; - -/** - * Create a global mixFetch instance and optionally configure settings. - * - * @param opts Optional settings - */ -export const createMixFetch = async (opts?: SetupMixFetchOps) => { - if (!(globalThis as any).__mixFetchGlobal) { - // load the worker and set up mixFetch with defaults - (globalThis as any).__mixFetchGlobal = await createMixFetchInternal(); - await (globalThis as any).__mixFetchGlobal.setupMixFetch(opts); - } - - return (globalThis as any).__mixFetchGlobal; -}; - -/** - * mixFetch is a drop-in replacement for the standard `fetch` interface. - * - * @param url The URL to fetch from. - * @param args Fetch options. - * @param opts Optionally configure mixFetch when it gets created. This only happens once, the first time it gets used. - */ -export const mixFetch: IMixFetchFn = async (url, args, opts?: SetupMixFetchOps) => { - // ensure mixFetch instance exists - const instance = await createMixFetch({ - mixFetchOverride: { - requestTimeoutMs: REQUEST_TIMEOUT_MILLISECONDS, - }, - ...opts, - }); - - // execute user request - return instance.mixFetch(url, args); -}; - -/** - * Stops the usage of mixFetch and disconnect the client from the mixnet. - */ -export const disconnectMixFetch = async (): Promise => { - // JS: I'm ignoring this lint (no-else-return) because I want to explicitly state - // that `__mixFetchGlobal` is definitely not null in the else branch. - if (!(globalThis as any).__mixFetchGlobal) { - throw new Error("mixFetch hasn't been setup"); - } else { - return (globalThis as any).__mixFetchGlobal.disconnectMixFetch(); - } -}; diff --git a/sdk/typescript/packages/mix-fetch-node/src/node-adapter.ts b/sdk/typescript/packages/mix-fetch-node/src/node-adapter.ts deleted file mode 100644 index aacc0dc6a8..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/src/node-adapter.ts +++ /dev/null @@ -1,43 +0,0 @@ -/** - * @license - * Copyright 2019 Google LLC - * SPDX-License-Identifier: Apache-2.0 - */ - -// Borrowed from https://github.com/GoogleChromeLabs/comlink/blob/main/src/node-adapter.ts - -import { Endpoint } from 'comlink'; - -export interface NodeEndpoint { - postMessage(message: any, transfer?: any[]): void; - on(type: string, listener: EventListenerOrEventListenerObject, options?: {}): void; - off(type: string, listener: EventListenerOrEventListenerObject, options?: {}): void; - start?: () => void; -} - -export default function nodeEndpoint(nep: NodeEndpoint): Endpoint { - const listeners = new WeakMap(); - return { - postMessage: nep.postMessage.bind(nep), - addEventListener: (_, eh) => { - const l = (data: any) => { - if ('handleEvent' in eh) { - eh.handleEvent({ data } as MessageEvent); - } else { - eh({ data } as MessageEvent); - } - }; - nep.on('message', l); - listeners.set(eh, l); - }, - removeEventListener: (_, eh) => { - const l = listeners.get(eh); - if (!l) { - return; - } - nep.off('message', l); - listeners.delete(eh); - }, - start: nep.start && nep.start.bind(nep), - }; -} diff --git a/sdk/typescript/packages/mix-fetch-node/src/types.ts b/sdk/typescript/packages/mix-fetch-node/src/types.ts deleted file mode 100644 index be22b2b80c..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/src/types.ts +++ /dev/null @@ -1,98 +0,0 @@ -import type { MixFetchOpts } from '@nymproject/mix-fetch-wasm-node'; - -type IMixFetchWorkerFn = (url: string, args: any) => Promise; - -// export type IMixFetchFn = typeof fetch; -export type IMixFetchFn = (url: string, args: any, opts?: SetupMixFetchOps) => Promise; - -export type SetupMixFetchOps = MixFetchOpts & { - responseBodyConfigMap?: ResponseBodyConfigMap; -}; - -export interface IMixFetchWebWorker { - mixFetch: IMixFetchWorkerFn; - setupMixFetch: (opts?: SetupMixFetchOps) => Promise; - disconnectMixFetch: () => Promise; -} - -export interface IMixFetch { - mixFetch: IMixFetchFn; - setupMixFetch: (opts?: SetupMixFetchOps) => Promise; - disconnectMixFetch: () => Promise; -} - -export enum EventKinds { - Loaded = 'Loaded', -} - -export interface LoadedEvent { - kind: EventKinds.Loaded; - args: { - loaded: true; - }; -} - -export interface ResponseBody { - uint8array?: Uint8Array; - json?: any; - text?: string; - formData?: any; - blobUrl?: string; -} - -export type ResponseBodyMethod = 'uint8array' | 'json' | 'text' | 'formData' | 'blob'; - -export interface ResponseBodyConfigMap { - /** - * Set the response `Content-Type`s to decode as uint8array. - */ - uint8array?: Array; - - /** - * Set the response `Content-Type`s to decode with the `json()` response body method. - */ - json?: Array; - - /** - * Set the response `Content-Type`s to decode with the `text()` response body method. - */ - text?: Array; - - /** - * Set the response `Content-Type`s to decode with the `formData()` response body method. - */ - formData?: Array; - - /** - * Set the response `Content-Type`s to decode with the `blob()` response body method. - */ - blob?: Array; - /** - * Set this to the default fallback method. Set to `undefined` if you want to ignore unknown types. - */ - - fallback?: ResponseBodyMethod; -} - -/** - * Default values for the handling of response bodies. - */ -export const ResponseBodyConfigMapDefaults: ResponseBodyConfigMap = { - uint8array: ['application/octet-stream'], - json: ['application/json', 'text/json', /application\/json.*/, /text\/json\+.*/], - text: ['text/plain', /text\/plain.*/, 'text/html', /text\/html.*/], - formData: ['application/x-www-form-urlencoded', 'multipart/form-data'], - blob: [/image\/.*/, /video\/.*/], - fallback: 'blob', -}; - -export interface MixFetchWebWorkerResponse { - body: ResponseBody; - url: string; - headers: any; - status: number; - statusText: string; - type: string; - ok: boolean; - redirected: boolean; -} diff --git a/sdk/typescript/packages/mix-fetch-node/src/worker/handle-response-mime-types.test.ts b/sdk/typescript/packages/mix-fetch-node/src/worker/handle-response-mime-types.test.ts deleted file mode 100644 index 747c073b3b..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/src/worker/handle-response-mime-types.test.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { handleResponseMimeTypes } from './handle-response-mime-types'; - -describe('handleResponseMimeTypes', () => { - test('gracefully handles empty values', async () => { - const resp = await handleResponseMimeTypes(new Response()); - expect(Object.values(resp)).toHaveLength(0); - }); - - test('handles text', async () => { - const TEXT = 'This is text'; - const resp = await handleResponseMimeTypes( - new Response(TEXT, { headers: new Headers([['Content-Type', 'text/plain']]) }), - ); - expect(resp.text).toBe(TEXT); - }); - test('handles text (charset=utf-8)', async () => { - const TEXT = 'This is text'; - const resp = await handleResponseMimeTypes( - new Response(TEXT, { headers: new Headers([['Content-Type', 'text/plain; charset=utf-8']]) }), - ); - expect(resp.text).toBe(TEXT); - }); - test('handles html', async () => { - const TEXT = 'This is html'; - const resp = await handleResponseMimeTypes( - new Response(TEXT, { headers: new Headers([['Content-Type', 'text/html']]) }), - ); - expect(resp.text).toBe(TEXT); - }); - test('handles html (charset=utf-8)', async () => { - const TEXT = 'This is html'; - const resp = await handleResponseMimeTypes( - new Response(TEXT, { headers: new Headers([['Content-Type', 'text/html; charset=utf-8']]) }), - ); - expect(resp.text).toBe(TEXT); - }); - test('handles images', async () => { - const DATA = Buffer.from(new Uint8Array([0, 1, 2, 3])); - const resp = await handleResponseMimeTypes( - new Response(DATA, { headers: new Headers([['Content-Type', 'image/jpeg']]) }), - ); - expect(resp.blobUrl).toBeDefined(); - }); - test('handles videos', async () => { - const DATA = Buffer.from(new Uint8Array([0, 1, 2, 3])); - const resp = await handleResponseMimeTypes( - new Response(DATA, { headers: new Headers([['Content-Type', 'video/mpeg4']]) }), - ); - expect(resp.blobUrl).toBeDefined(); - }); - test('handles form data when URL encoded', async () => { - const formData = 'foo=bar&baz=42'; - const resp = await handleResponseMimeTypes( - new Response(formData, { headers: new Headers([['Content-Type', 'application/x-www-form-urlencoded']]) }), - ); - expect(resp.formData.foo).toBe('bar'); - expect(resp.formData.baz).toBe('42'); - }); - test('handles JSON data', async () => { - const json = '{ "foo": "bar", "baz": 42 }'; - const resp = await handleResponseMimeTypes( - new Response(json, { headers: new Headers([['Content-Type', 'application/json']]) }), - ); - expect(resp.text).toBe(json); - }); - test('handles JSON data (charset=utf-8)', async () => { - const json = '{ "foo": "bar", "baz": 42 }'; - const resp = await handleResponseMimeTypes( - new Response(json, { headers: new Headers([['Content-Type', 'application/json; charset=utf-8']]) }), - ); - expect(resp.text).toBe(json); - }); -}); diff --git a/sdk/typescript/packages/mix-fetch-node/src/worker/handle-response-mime-types.ts b/sdk/typescript/packages/mix-fetch-node/src/worker/handle-response-mime-types.ts deleted file mode 100644 index abcaa845f7..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/src/worker/handle-response-mime-types.ts +++ /dev/null @@ -1,111 +0,0 @@ -import type { ResponseBody, ResponseBodyConfigMap, ResponseBodyMethod } from '../types'; -import { ResponseBodyConfigMapDefaults } from '../types'; - -const getContentType = (response?: Response) => { - if (!response) { - return undefined; - } - - // this is what should be returned in the headers - if (response.headers.has('Content-Type')) { - return response.headers.get('Content-Type') as string; - } - - // handle weird servers that use lowercase headers - if (response.headers.has('content-type')) { - return response.headers.get('content-type') as string; - } - - // the Content-Type/content-type header is not part of the response - return undefined; -}; - -const doHandleResponseMethod = async (response: Response, method?: ResponseBodyMethod): Promise => { - switch (method) { - case 'uint8array': - return { - uint8array: new Uint8Array(await response.arrayBuffer()), - }; - case 'json': - case 'text': - return { text: await response.text() }; - case 'blob': { - const blob = await response.blob(); - const blobUrl = URL.createObjectURL(blob); - return { blobUrl }; - } - case 'formData': { - const formData: any = {}; - const data = await response.formData(); - // eslint-disable-next-line no-restricted-syntax - for (const pair of data.entries()) { - const [key, value] = pair; - formData[key] = value; - } - return { formData }; - } - default: - return {}; - } -}; - -const testIfIncluded = (value?: string, tests?: Array): boolean => { - if (!tests) { - return false; - } - if (!value) { - return false; - } - - for (let i = 0; i < tests.length; i += 1) { - const test = tests[i]; - if (typeof test === 'string' && value === test) { - return true; - } - if ((test as RegExp).test && (test as RegExp).test(value)) { - return true; - } - } - - // default return is false, because nothing above matched - return false; -}; - -export const handleResponseMimeTypes = async ( - response: Response, - config?: ResponseBodyConfigMap, -): Promise => { - // combine the user supplied config with the default - const finalConfig: ResponseBodyConfigMap = { ...ResponseBodyConfigMapDefaults, ...config }; - - const contentType = getContentType(response); - - // check if the headers say what the content type are, otherwise return the bytes of the response as a blob - if (!contentType) { - // no content type, or body, so the response is only the status, e.g. GET - if (!response.body) { - return {}; - } - - // handle fallback method - return doHandleResponseMethod(response, config?.fallback || 'blob'); - } - - if (testIfIncluded(contentType, finalConfig.uint8array)) { - return doHandleResponseMethod(response, 'uint8array'); - } - if (testIfIncluded(contentType, finalConfig.json)) { - return doHandleResponseMethod(response, 'json'); - } - if (testIfIncluded(contentType, finalConfig.text)) { - return doHandleResponseMethod(response, 'text'); - } - if (testIfIncluded(contentType, finalConfig.formData)) { - return doHandleResponseMethod(response, 'formData'); - } - if (testIfIncluded(contentType, finalConfig.blob)) { - return doHandleResponseMethod(response, 'blob'); - } - - return {}; -}; diff --git a/sdk/typescript/packages/mix-fetch-node/src/worker/index.ts b/sdk/typescript/packages/mix-fetch-node/src/worker/index.ts deleted file mode 100644 index 24bfded826..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/src/worker/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -import './polyfill'; - -import { loadWasm } from './wasm-loading'; -import { run } from './main'; - -(async function main() { - await loadWasm(); - await run(); -})().catch((e: any) => console.error('Unhandled exception in mixFetch worker', e)); diff --git a/sdk/typescript/packages/mix-fetch-node/src/worker/main.ts b/sdk/typescript/packages/mix-fetch-node/src/worker/main.ts deleted file mode 100644 index ee3a86ad3f..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/src/worker/main.ts +++ /dev/null @@ -1,74 +0,0 @@ -/* eslint-disable no-console */ - -import * as Comlink from 'comlink'; -import { parentPort } from 'node:worker_threads'; -import { setupMixFetch, disconnectMixFetch } from '@nymproject/mix-fetch-wasm-node'; -import type { IMixFetchWebWorker, LoadedEvent } from '../types'; - -import nodeEndpoint from '../node-adapter'; -import { EventKinds, ResponseBodyConfigMap, ResponseBodyConfigMapDefaults } from '../types'; -import { handleResponseMimeTypes } from './handle-response-mime-types'; - -/** - * Helper method to send typed messages. - * @param event The strongly typed message to send back to the calling thread. - */ -const postMessageWithType = (event: E) => parentPort?.postMessage(event); - -export async function run() { - const { mixFetch } = globalThis as any; - let responseBodyConfigMap: ResponseBodyConfigMap = ResponseBodyConfigMapDefaults; - - const mixFetchWebWorker: IMixFetchWebWorker = { - mixFetch: async (url, args) => { - console.log('[Worker] --- mixFetch ---', { url, args }); - - const response: Response = await mixFetch(url, args); - console.log('[Worker]', { response, json: JSON.stringify(response, null, 2) }); - - const bodyResponse = await handleResponseMimeTypes(response, responseBodyConfigMap); - console.log('[Worker]', { bodyResponse }); - - const headers: any = {}; - response.headers.forEach((value, key) => { - headers[key] = value; - }); - - const output = { - body: bodyResponse, - url: response.url, - headers, - status: response.status, - statusText: response.statusText, - type: response.type, - ok: response.ok, - redirected: response.redirected, - }; - - console.log('[Worker]', { output }); - - return output; - }, - setupMixFetch: async (opts) => { - console.log('[Worker] --- setupMixFetch ---', { opts }); - if (opts?.responseBodyConfigMap) { - responseBodyConfigMap = opts.responseBodyConfigMap; - } - await setupMixFetch(opts || {}); - }, - disconnectMixFetch: async () => { - console.log('[Worker] --- disconnectMixFetch ---'); - - await disconnectMixFetch(); - }, - }; - - // start comlink listening for messages and handle them above - if (parentPort) { - Comlink.expose(mixFetchWebWorker, nodeEndpoint(parentPort)); - } - - // notify any listeners that the web worker has loaded - HOWEVER, mixFetch hasn't been setup and the client started - // call `setupMixFetch` from the main thread to start the Nym client - postMessageWithType({ kind: EventKinds.Loaded, args: { loaded: true } }); -} diff --git a/sdk/typescript/packages/mix-fetch-node/src/worker/polyfill.ts b/sdk/typescript/packages/mix-fetch-node/src/worker/polyfill.ts deleted file mode 100644 index 7c88d9b088..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/src/worker/polyfill.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { TextDecoder, TextEncoder } from 'node:util'; -import * as crypto from 'node:crypto'; -import * as fs from 'node:fs'; -import WebSocket from 'ws'; -import fetch, { Headers, Request, Response } from 'node-fetch'; -import { Worker } from 'node:worker_threads'; -import { indexedDB } from 'fake-indexeddb'; - -(globalThis as any).performance = { - now() { - const [sec, nsec] = process.hrtime(); - return sec * 1000 + nsec / 1000000; - }, -}; - -(globalThis as any).TextDecoder = TextDecoder; -(globalThis as any).fetch = fetch; -(globalThis as any).Headers = Headers; -(globalThis as any).Request = Request; -(globalThis as any).Response = Response; -(globalThis as any).fs = fs; -(globalThis as any).crypto = crypto; -(globalThis as any).WebSocket = WebSocket; -(globalThis as any).Worker = Worker; - -globalThis.process = process; -globalThis.TextEncoder = TextEncoder; -globalThis.Reflect = Reflect; -globalThis.Proxy = Proxy; -globalThis.Error = Error; -globalThis.Promise = Promise; -globalThis.Object = Object; -globalThis.indexedDB = indexedDB; - -// has to be loaded after all the polyfill action -// eslint-disable-next-line import/extensions, import/no-extraneous-dependencies -import('@nymproject/mix-fetch-wasm-node/wasm_exec'); diff --git a/sdk/typescript/packages/mix-fetch-node/src/worker/wasm-loading.ts b/sdk/typescript/packages/mix-fetch-node/src/worker/wasm-loading.ts deleted file mode 100644 index 0eb698e0ec..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/src/worker/wasm-loading.ts +++ /dev/null @@ -1,69 +0,0 @@ -/* eslint-disable no-console */ -/// - -// Copyright 2020-2023 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import '@nymproject/mix-fetch-wasm-node/mix_fetch_wasm_bg.wasm'; - -// @ts-ignore -import getGoConnectionWasmBytes from '@nymproject/mix-fetch-wasm-node/go_conn.wasm'; - -import { - send_client_data, - start_new_mixnet_connection, - mix_fetch_initialised, - finish_mixnet_connection, - set_panic_hook, -} from '@nymproject/mix-fetch-wasm-node'; - -export async function loadGoWasm() { - // rollup will provide a function to get the Go connection WASM bytes here - const bytes = await getGoConnectionWasmBytes(); - - const go = new Go(); // Defined in wasm_exec.js - - // the WebAssembly runtime will parse the bytes and then start the Go runtime - const wasmObj = await WebAssembly.instantiate(bytes, go.importObject); - // eslint-disable-next-line no-console - console.log('Loaded GO WASM'); - - go.run(wasmObj); -} - -function setupRsGoBridge() { - const rsGoBridge = { - send_client_data, - start_new_mixnet_connection, - mix_fetch_initialised, - finish_mixnet_connection, - }; - - // and to discourage users from trying to call those methods directly) - // @ts-expect-error globalThis has index signature of any - // eslint-disable-next-line no-underscore-dangle - globalThis.__rs_go_bridge__ = rsGoBridge; -} - -export async function loadWasm() { - // load go WASM package - await loadGoWasm(); - - console.log('Loaded GO WASM'); - - // sets up better stack traces in case of in-rust panics - set_panic_hook(); - - setupRsGoBridge(); -} diff --git a/sdk/typescript/packages/mix-fetch-node/tsconfig.jest.json b/sdk/typescript/packages/mix-fetch-node/tsconfig.jest.json deleted file mode 100644 index 90ad46a57b..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/tsconfig.jest.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "compileOnSave": false, - "compilerOptions": { - "lib": ["es2021", "dom", "dom.iterable", "esnext", "webworker"], - "module": "esnext", - "target": "esnext", - "strict": true, - "moduleResolution": "node", - "skipLibCheck": true, - "skipDefaultLibCheck": true, - "declaration": true, - "baseUrl": ".", - "esModuleInterop": true, - "allowJs": true, - "downlevelIteration": true - }, - "include": ["src/**/*.ts"], - "exclude": [ - "jest.*", - "webpack.config.js", - "webpack.prod.js", - "webpack.common.js", - "node_modules", - "**/node_modules", - "dist", - "**/dist", - "scripts", - "jest", - "__tests__", - "**/__tests__", - "__jest__", - "**/__jest__", - "config/*" - ] -} diff --git a/sdk/typescript/packages/mix-fetch-node/typings/rollup-worker.d.ts b/sdk/typescript/packages/mix-fetch-node/typings/rollup-worker.d.ts deleted file mode 100644 index d012fe9590..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/typings/rollup-worker.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -declare module 'web-worker:*' { - import { Worker } from 'node:worker_threads'; - - const WorkerFactory: new () => Worker; - export default WorkerFactory; -} diff --git a/sdk/typescript/packages/mix-fetch-node/typings/wasm_exec.d.ts b/sdk/typescript/packages/mix-fetch-node/typings/wasm_exec.d.ts deleted file mode 100644 index 82cee7251a..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/typings/wasm_exec.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -declare module '@nymproject/mix-fetch-wasm-node/wasm_exec' { - export declare global { - class Go { - constructor(); - - importObject: any; - - run(goWasm: any); - } - } -} diff --git a/sdk/typescript/packages/mix-fetch-node/yarn.lock b/sdk/typescript/packages/mix-fetch-node/yarn.lock deleted file mode 100644 index 7a7dd6d6c5..0000000000 --- a/sdk/typescript/packages/mix-fetch-node/yarn.lock +++ /dev/null @@ -1,4439 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@aashutoshrathi/word-wrap@^1.2.3": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" - integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== - -"@ampproject/remapping@^2.2.0": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" - integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== - dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" - -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.22.13": - version "7.22.13" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" - integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== - dependencies: - "@babel/highlight" "^7.22.13" - chalk "^2.4.2" - -"@babel/compat-data@^7.22.9": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.2.tgz#6a12ced93455827037bfb5ed8492820d60fc32cc" - integrity sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ== - -"@babel/core@^7.11.6", "@babel/core@^7.12.3": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.2.tgz#ed10df0d580fff67c5f3ee70fd22e2e4c90a9f94" - integrity sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.22.13" - "@babel/generator" "^7.23.0" - "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-module-transforms" "^7.23.0" - "@babel/helpers" "^7.23.2" - "@babel/parser" "^7.23.0" - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.2" - "@babel/types" "^7.23.0" - convert-source-map "^2.0.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.3" - semver "^6.3.1" - -"@babel/generator@^7.23.0", "@babel/generator@^7.7.2": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420" - integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g== - dependencies: - "@babel/types" "^7.23.0" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" - -"@babel/helper-compilation-targets@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52" - integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw== - dependencies: - "@babel/compat-data" "^7.22.9" - "@babel/helper-validator-option" "^7.22.15" - browserslist "^4.21.9" - lru-cache "^5.1.1" - semver "^6.3.1" - -"@babel/helper-environment-visitor@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" - integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== - -"@babel/helper-function-name@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" - integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== - dependencies: - "@babel/template" "^7.22.15" - "@babel/types" "^7.23.0" - -"@babel/helper-hoist-variables@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" - integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-module-imports@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" - integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== - dependencies: - "@babel/types" "^7.22.15" - -"@babel/helper-module-transforms@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz#3ec246457f6c842c0aee62a01f60739906f7047e" - integrity sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw== - dependencies: - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-module-imports" "^7.22.15" - "@babel/helper-simple-access" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/helper-validator-identifier" "^7.22.20" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" - integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== - -"@babel/helper-simple-access@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" - integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-split-export-declaration@^7.22.6": - version "7.22.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" - integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== - dependencies: - "@babel/types" "^7.22.5" - -"@babel/helper-string-parser@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" - integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== - -"@babel/helper-validator-identifier@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" - integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== - -"@babel/helper-validator-option@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" - integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA== - -"@babel/helpers@^7.23.2": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.2.tgz#2832549a6e37d484286e15ba36a5330483cac767" - integrity sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ== - dependencies: - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.2" - "@babel/types" "^7.23.0" - -"@babel/highlight@^7.22.13": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" - integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== - dependencies: - "@babel/helper-validator-identifier" "^7.22.20" - chalk "^2.4.2" - js-tokens "^4.0.0" - -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" - integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== - -"@babel/plugin-syntax-async-generators@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" - integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-bigint@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" - integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-class-properties@^7.8.3": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" - integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== - dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - -"@babel/plugin-syntax-import-meta@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" - integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-json-strings@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" - integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-jsx@^7.7.2": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz#a6b68e84fb76e759fc3b93e901876ffabbe1d918" - integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/plugin-syntax-logical-assignment-operators@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" - integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-numeric-separator@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" - integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-object-rest-spread@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-top-level-await@^7.8.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" - integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-typescript@^7.7.2": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz#aac8d383b062c5072c647a31ef990c1d0af90272" - integrity sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - -"@babel/runtime@^7.20.7": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885" - integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg== - dependencies: - regenerator-runtime "^0.14.0" - -"@babel/template@^7.22.15", "@babel/template@^7.3.3": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" - integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== - dependencies: - "@babel/code-frame" "^7.22.13" - "@babel/parser" "^7.22.15" - "@babel/types" "^7.22.15" - -"@babel/traverse@^7.23.2": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8" - integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw== - dependencies: - "@babel/code-frame" "^7.22.13" - "@babel/generator" "^7.23.0" - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-function-name" "^7.23.0" - "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/parser" "^7.23.0" - "@babel/types" "^7.23.0" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/types@^7.0.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.3.3": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" - integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== - dependencies: - "@babel/helper-string-parser" "^7.22.5" - "@babel/helper-validator-identifier" "^7.22.20" - to-fast-properties "^2.0.0" - -"@bcoe/v8-coverage@^0.2.3": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" - integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== - -"@eslint-community/eslint-utils@^4.2.0": - version "4.4.0" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== - dependencies: - eslint-visitor-keys "^3.3.0" - -"@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1": - version "4.9.1" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.9.1.tgz#449dfa81a57a1d755b09aa58d826c1262e4283b4" - integrity sha512-Y27x+MBLjXa+0JWDhykM3+JE+il3kHKAEqabfEWq3SDhZjLYb6/BHL/JKFnH3fe207JaXkyDo685Oc2Glt6ifA== - -"@eslint/eslintrc@^2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.2.tgz#c6936b4b328c64496692f76944e755738be62396" - integrity sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.6.0" - globals "^13.19.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - -"@eslint/js@8.51.0": - version "8.51.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.51.0.tgz#6d419c240cfb2b66da37df230f7e7eef801c32fa" - integrity sha512-HxjQ8Qn+4SI3/AFv6sOrDB+g6PpUTDwSJiQqOrnneEk8L71161srI9gjzzZvYVbzHiVg/BvcH95+cK/zfIt4pg== - -"@humanwhocodes/config-array@^0.11.11": - version "0.11.11" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.11.tgz#88a04c570dbbc7dd943e4712429c3df09bc32844" - integrity sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA== - dependencies: - "@humanwhocodes/object-schema" "^1.2.1" - debug "^4.1.1" - minimatch "^3.0.5" - -"@humanwhocodes/module-importer@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" - integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== - -"@humanwhocodes/object-schema@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== - -"@istanbuljs/load-nyc-config@^1.0.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" - integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== - dependencies: - camelcase "^5.3.1" - find-up "^4.1.0" - get-package-type "^0.1.0" - js-yaml "^3.13.1" - resolve-from "^5.0.0" - -"@istanbuljs/schema@^0.1.2": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" - integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== - -"@jest/console@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.7.0.tgz#cd4822dbdb84529265c5a2bdb529a3c9cc950ffc" - integrity sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg== - dependencies: - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - jest-message-util "^29.7.0" - jest-util "^29.7.0" - slash "^3.0.0" - -"@jest/core@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.7.0.tgz#b6cccc239f30ff36609658c5a5e2291757ce448f" - integrity sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg== - dependencies: - "@jest/console" "^29.7.0" - "@jest/reporters" "^29.7.0" - "@jest/test-result" "^29.7.0" - "@jest/transform" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - ci-info "^3.2.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - jest-changed-files "^29.7.0" - jest-config "^29.7.0" - jest-haste-map "^29.7.0" - jest-message-util "^29.7.0" - jest-regex-util "^29.6.3" - jest-resolve "^29.7.0" - jest-resolve-dependencies "^29.7.0" - jest-runner "^29.7.0" - jest-runtime "^29.7.0" - jest-snapshot "^29.7.0" - jest-util "^29.7.0" - jest-validate "^29.7.0" - jest-watcher "^29.7.0" - micromatch "^4.0.4" - pretty-format "^29.7.0" - slash "^3.0.0" - strip-ansi "^6.0.0" - -"@jest/environment@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.7.0.tgz#24d61f54ff1f786f3cd4073b4b94416383baf2a7" - integrity sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw== - dependencies: - "@jest/fake-timers" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - jest-mock "^29.7.0" - -"@jest/expect-utils@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" - integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== - dependencies: - jest-get-type "^29.6.3" - -"@jest/expect@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.7.0.tgz#76a3edb0cb753b70dfbfe23283510d3d45432bf2" - integrity sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ== - dependencies: - expect "^29.7.0" - jest-snapshot "^29.7.0" - -"@jest/fake-timers@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.7.0.tgz#fd91bf1fffb16d7d0d24a426ab1a47a49881a565" - integrity sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ== - dependencies: - "@jest/types" "^29.6.3" - "@sinonjs/fake-timers" "^10.0.2" - "@types/node" "*" - jest-message-util "^29.7.0" - jest-mock "^29.7.0" - jest-util "^29.7.0" - -"@jest/globals@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.7.0.tgz#8d9290f9ec47ff772607fa864ca1d5a2efae1d4d" - integrity sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ== - dependencies: - "@jest/environment" "^29.7.0" - "@jest/expect" "^29.7.0" - "@jest/types" "^29.6.3" - jest-mock "^29.7.0" - -"@jest/reporters@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.7.0.tgz#04b262ecb3b8faa83b0b3d321623972393e8f4c7" - integrity sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg== - dependencies: - "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^29.7.0" - "@jest/test-result" "^29.7.0" - "@jest/transform" "^29.7.0" - "@jest/types" "^29.6.3" - "@jridgewell/trace-mapping" "^0.3.18" - "@types/node" "*" - chalk "^4.0.0" - collect-v8-coverage "^1.0.0" - exit "^0.1.2" - glob "^7.1.3" - graceful-fs "^4.2.9" - istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^6.0.0" - istanbul-lib-report "^3.0.0" - istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.1.3" - jest-message-util "^29.7.0" - jest-util "^29.7.0" - jest-worker "^29.7.0" - slash "^3.0.0" - string-length "^4.0.1" - strip-ansi "^6.0.0" - v8-to-istanbul "^9.0.1" - -"@jest/schemas@^29.6.3": - version "29.6.3" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" - integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== - dependencies: - "@sinclair/typebox" "^0.27.8" - -"@jest/source-map@^29.6.3": - version "29.6.3" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.6.3.tgz#d90ba772095cf37a34a5eb9413f1b562a08554c4" - integrity sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw== - dependencies: - "@jridgewell/trace-mapping" "^0.3.18" - callsites "^3.0.0" - graceful-fs "^4.2.9" - -"@jest/test-result@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.7.0.tgz#8db9a80aa1a097bb2262572686734baed9b1657c" - integrity sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA== - dependencies: - "@jest/console" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/istanbul-lib-coverage" "^2.0.0" - collect-v8-coverage "^1.0.0" - -"@jest/test-sequencer@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz#6cef977ce1d39834a3aea887a1726628a6f072ce" - integrity sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw== - dependencies: - "@jest/test-result" "^29.7.0" - graceful-fs "^4.2.9" - jest-haste-map "^29.7.0" - slash "^3.0.0" - -"@jest/transform@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.7.0.tgz#df2dd9c346c7d7768b8a06639994640c642e284c" - integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw== - dependencies: - "@babel/core" "^7.11.6" - "@jest/types" "^29.6.3" - "@jridgewell/trace-mapping" "^0.3.18" - babel-plugin-istanbul "^6.1.1" - chalk "^4.0.0" - convert-source-map "^2.0.0" - fast-json-stable-stringify "^2.1.0" - graceful-fs "^4.2.9" - jest-haste-map "^29.7.0" - jest-regex-util "^29.6.3" - jest-util "^29.7.0" - micromatch "^4.0.4" - pirates "^4.0.4" - slash "^3.0.0" - write-file-atomic "^4.0.2" - -"@jest/types@^29.6.3": - version "29.6.3" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" - integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== - dependencies: - "@jest/schemas" "^29.6.3" - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^17.0.8" - chalk "^4.0.0" - -"@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" - integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/resolve-uri@^3.1.0": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" - integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== - -"@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== - -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15": - version "1.4.15" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== - -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.19" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811" - integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - -"@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@nymproject/mix-fetch-wasm-node@>=1.2.4-rc.2 || ^1": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@nymproject/mix-fetch-wasm-node/-/mix-fetch-wasm-node-1.2.3.tgz#f600df714782e6eb691faa14683e44c2507a8e53" - integrity sha512-J9mj52WSpsGpuCeW65zEj8RWJ3GvWG0VqVWIDD6w1RK4SesXiGb7ghD7F1rChRMlSbl9rP9reYkmAHz63Sb6Cw== - -"@rollup/plugin-commonjs@^24.0.1": - version "24.1.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-24.1.0.tgz#79e54bd83bb64396761431eee6c44152ef322100" - integrity sha512-eSL45hjhCWI0jCCXcNtLVqM5N1JlBGvlFfY0m6oOYnLCJ6N0qEXoZql4sY2MOUArzhH4SA/qBpTxvvZp2Sc+DQ== - dependencies: - "@rollup/pluginutils" "^5.0.1" - commondir "^1.0.1" - estree-walker "^2.0.2" - glob "^8.0.3" - is-reference "1.2.1" - magic-string "^0.27.0" - -"@rollup/plugin-node-resolve@^15.0.1": - version "15.2.3" - resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz#e5e0b059bd85ca57489492f295ce88c2d4b0daf9" - integrity sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ== - dependencies: - "@rollup/pluginutils" "^5.0.1" - "@types/resolve" "1.20.2" - deepmerge "^4.2.2" - is-builtin-module "^3.2.1" - is-module "^1.0.0" - resolve "^1.22.1" - -"@rollup/plugin-replace@^5.0.2": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@rollup/plugin-replace/-/plugin-replace-5.0.4.tgz#fef548dc751d06747e8dca5b0e8e1fbf647ac7e1" - integrity sha512-E2hmRnlh09K8HGT0rOnnri9OTh+BILGr7NVJGB30S4E3cLRn3J0xjdiyOZ74adPs4NiAMgrjUMGAZNJDBgsdmQ== - dependencies: - "@rollup/pluginutils" "^5.0.1" - magic-string "^0.30.3" - -"@rollup/plugin-typescript@^10.0.1": - version "10.0.1" - resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-10.0.1.tgz#270b515b116ea28320e6bb62451c4767d49072d6" - integrity sha512-wBykxRLlX7EzL8BmUqMqk5zpx2onnmRMSw/l9M1sVfkJvdwfxogZQVNUM9gVMJbjRLDR5H6U0OMOrlDGmIV45A== - dependencies: - "@rollup/pluginutils" "^5.0.1" - resolve "^1.22.1" - -"@rollup/plugin-wasm@^6.1.1": - version "6.2.2" - resolved "https://registry.yarnpkg.com/@rollup/plugin-wasm/-/plugin-wasm-6.2.2.tgz#ea75fd8cc5ddba1e30bdc22e07cdbaf8d6d160bf" - integrity sha512-gpC4R1G9Ni92ZIRTexqbhX7U+9estZrbhP+9SRb0DW9xpB9g7j34r+J2hqrcW/lRI7dJaU84MxZM0Rt82tqYPQ== - dependencies: - "@rollup/pluginutils" "^5.0.2" - -"@rollup/pluginutils@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.1.0.tgz#706b4524ee6dc8b103b3c995533e5ad680c02b9b" - integrity sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg== - dependencies: - "@types/estree" "0.0.39" - estree-walker "^1.0.1" - picomatch "^2.2.2" - -"@rollup/pluginutils@^5.0.1", "@rollup/pluginutils@^5.0.2": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.5.tgz#bbb4c175e19ebfeeb8c132c2eea0ecb89941a66c" - integrity sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q== - dependencies: - "@types/estree" "^1.0.0" - estree-walker "^2.0.2" - picomatch "^2.3.1" - -"@sinclair/typebox@^0.27.8": - version "0.27.8" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" - integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== - -"@sinonjs/commons@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-3.0.0.tgz#beb434fe875d965265e04722ccfc21df7f755d72" - integrity sha512-jXBtWAF4vmdNmZgD5FoKsVLv3rPgDnLgPbU84LIJ3otV44vJlDRokVng5v8NFJdCf/da9legHcKaRuZs4L7faA== - dependencies: - type-detect "4.0.8" - -"@sinonjs/fake-timers@^10.0.2": - version "10.3.0" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz#55fdff1ecab9f354019129daf4df0dd4d923ea66" - integrity sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA== - dependencies: - "@sinonjs/commons" "^3.0.0" - -"@types/babel__core@^7.1.14": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.2.tgz#215db4f4a35d710256579784a548907237728756" - integrity sha512-pNpr1T1xLUc2l3xJKuPtsEky3ybxN3m4fJkknfIpTCTfIZCDW57oAg+EfCgIIp2rvCe0Wn++/FfodDS4YXxBwA== - dependencies: - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" - "@types/babel__generator" "*" - "@types/babel__template" "*" - "@types/babel__traverse" "*" - -"@types/babel__generator@*": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.5.tgz#281f4764bcbbbc51fdded0f25aa587b4ce14da95" - integrity sha512-h9yIuWbJKdOPLJTbmSpPzkF67e659PbQDba7ifWm5BJ8xTv+sDmS7rFmywkWOvXedGTivCdeGSIIX8WLcRTz8w== - dependencies: - "@babel/types" "^7.0.0" - -"@types/babel__template@*": - version "7.4.2" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.2.tgz#843e9f1f47c957553b0c374481dc4772921d6a6b" - integrity sha512-/AVzPICMhMOMYoSx9MoKpGDKdBRsIXMNByh1PXSZoa+v6ZoLa8xxtsT/uLQ/NJm0XVAWl/BvId4MlDeXJaeIZQ== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - -"@types/babel__traverse@*", "@types/babel__traverse@^7.0.6": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.2.tgz#4ddf99d95cfdd946ff35d2b65c978d9c9bf2645d" - integrity sha512-ojlGK1Hsfce93J0+kn3H5R73elidKUaZonirN33GSmgTUMpzI/MIFfSpF3haANe3G1bEBS9/9/QEqwTzwqFsKw== - dependencies: - "@babel/types" "^7.20.7" - -"@types/estree@*", "@types/estree@^1.0.0": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.2.tgz#ff02bc3dc8317cd668dfec247b750ba1f1d62453" - integrity sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA== - -"@types/estree@0.0.39": - version "0.0.39" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f" - integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw== - -"@types/graceful-fs@^4.1.3": - version "4.1.7" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.7.tgz#30443a2e64fd51113bc3e2ba0914d47109695e2a" - integrity sha512-MhzcwU8aUygZroVwL2jeYk6JisJrPl/oov/gsgGCue9mkgl9wjGbzReYQClxiUgFDnib9FuHqTndccKeZKxTRw== - dependencies: - "@types/node" "*" - -"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" - integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== - -"@types/istanbul-lib-report@*": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#412e0725ef41cde73bfa03e0e833eaff41e0fd63" - integrity sha512-gPQuzaPR5h/djlAv2apEG1HVOyj1IUs7GpfMZixU0/0KXT3pm64ylHuMUI1/Akh+sq/iikxg6Z2j+fcMDXaaTQ== - dependencies: - "@types/istanbul-lib-coverage" "*" - -"@types/istanbul-reports@^3.0.0": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.2.tgz#edc8e421991a3b4df875036d381fc0a5a982f549" - integrity sha512-kv43F9eb3Lhj+lr/Hn6OcLCs/sSM8bt+fIaP11rCYngfV6NVjzWXJ17owQtDQTL9tQ8WSLUrGsSJ6rJz0F1w1A== - dependencies: - "@types/istanbul-lib-report" "*" - -"@types/jest@^27.0.1": - version "27.5.2" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.5.2.tgz#ec49d29d926500ffb9fd22b84262e862049c026c" - integrity sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA== - dependencies: - jest-matcher-utils "^27.0.0" - pretty-format "^27.0.0" - -"@types/json-schema@^7.0.9": - version "7.0.13" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.13.tgz#02c24f4363176d2d18fc8b70b9f3c54aba178a85" - integrity sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ== - -"@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== - -"@types/node@*": - version "20.8.6" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.6.tgz#0dbd4ebcc82ad0128df05d0e6f57e05359ee47fa" - integrity sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ== - dependencies: - undici-types "~5.25.1" - -"@types/node@^16.7.13": - version "16.18.58" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.58.tgz#bf66f63983104ed57c754f4e84ccaf16f8235adb" - integrity sha512-YGncyA25/MaVtQkjWW9r0EFBukZ+JulsLcVZBlGUfIb96OBMjkoRWwQo5IEWJ8Fj06Go3GHw+bjYDitv6BaGsA== - -"@types/resolve@1.20.2": - version "1.20.2" - resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975" - integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q== - -"@types/semver@^7.3.12": - version "7.5.3" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.3.tgz#9a726e116beb26c24f1ccd6850201e1246122e04" - integrity sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw== - -"@types/stack-utils@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" - integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== - -"@types/yargs-parser@*": - version "21.0.1" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.1.tgz#07773d7160494d56aa882d7531aac7319ea67c3b" - integrity sha512-axdPBuLuEJt0c4yI5OZssC19K2Mq1uKdrfZBzuxLvaztgqUtFYZUNw7lETExPYJR9jdEoIg4mb7RQKRQzOkeGQ== - -"@types/yargs@^17.0.8": - version "17.0.28" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.28.tgz#d106e4301fbacde3d1796ab27374dd16588ec851" - integrity sha512-N3e3fkS86hNhtk6BEnc0rj3zcehaxx8QWhCROJkqpl5Zaoi7nAic3jH8q94jVD3zu5LGk+PUB6KAiDmimYOEQw== - dependencies: - "@types/yargs-parser" "*" - -"@typescript-eslint/eslint-plugin@^5.13.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db" - integrity sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag== - dependencies: - "@eslint-community/regexpp" "^4.4.0" - "@typescript-eslint/scope-manager" "5.62.0" - "@typescript-eslint/type-utils" "5.62.0" - "@typescript-eslint/utils" "5.62.0" - debug "^4.3.4" - graphemer "^1.4.0" - ignore "^5.2.0" - natural-compare-lite "^1.4.0" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/parser@^5.13.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7" - integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== - dependencies: - "@typescript-eslint/scope-manager" "5.62.0" - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/typescript-estree" "5.62.0" - debug "^4.3.4" - -"@typescript-eslint/scope-manager@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" - integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== - dependencies: - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/visitor-keys" "5.62.0" - -"@typescript-eslint/type-utils@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz#286f0389c41681376cdad96b309cedd17d70346a" - integrity sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew== - dependencies: - "@typescript-eslint/typescript-estree" "5.62.0" - "@typescript-eslint/utils" "5.62.0" - debug "^4.3.4" - tsutils "^3.21.0" - -"@typescript-eslint/types@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" - integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== - -"@typescript-eslint/typescript-estree@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" - integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== - dependencies: - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/visitor-keys" "5.62.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" - -"@typescript-eslint/utils@5.62.0", "@typescript-eslint/utils@^5.10.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" - integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@types/json-schema" "^7.0.9" - "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.62.0" - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/typescript-estree" "5.62.0" - eslint-scope "^5.1.1" - semver "^7.3.7" - -"@typescript-eslint/visitor-keys@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" - integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== - dependencies: - "@typescript-eslint/types" "5.62.0" - eslint-visitor-keys "^3.3.0" - -abbrev@1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -acorn-jsx@^5.3.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - -acorn@^8.9.0: - version "8.10.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" - integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== - -ajv@^6.12.4: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== - dependencies: - fast-deep-equal "^3.1.1" - fast-json-stable-stringify "^2.0.0" - json-schema-traverse "^0.4.1" - uri-js "^4.2.2" - -ansi-escapes@^4.2.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -ansi-sequence-parser@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ansi-sequence-parser/-/ansi-sequence-parser-1.1.1.tgz#e0aa1cdcbc8f8bb0b5bca625aac41f5f056973cf" - integrity sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg== - -ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - -ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - -ansi-styles@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" - integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== - -anymatch@^3.0.3, anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - -argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - -aria-query@^5.1.3: - version "5.3.0" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" - integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== - dependencies: - dequal "^2.0.3" - -array-buffer-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" - integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== - dependencies: - call-bind "^1.0.2" - is-array-buffer "^3.0.1" - -array-includes@^3.1.6: - version "3.1.7" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.7.tgz#8cd2e01b26f7a3086cbc87271593fe921c62abda" - integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - is-string "^1.0.7" - -array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - -array.prototype.findlastindex@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz#b37598438f97b579166940814e2c0493a4f50207" - integrity sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - get-intrinsic "^1.2.1" - -array.prototype.flat@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" - integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - -array.prototype.flatmap@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" - integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - -arraybuffer.prototype.slice@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz#98bd561953e3e74bb34938e77647179dfe6e9f12" - integrity sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw== - dependencies: - array-buffer-byte-length "^1.0.0" - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - is-array-buffer "^3.0.2" - is-shared-array-buffer "^1.0.2" - -ast-types-flow@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" - integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag== - -available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== - -axe-core@^4.6.2: - version "4.8.2" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.8.2.tgz#2f6f3cde40935825cf4465e3c1c9e77b240ff6ae" - integrity sha512-/dlp0fxyM3R8YW7MFzaHWXrf4zzbr0vaYb23VBFCl83R7nWNPg/yaQw2Dc8jzCMmDVLhSdzH8MjrsuIUuvX+6g== - -axobject-query@^3.1.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.2.1.tgz#39c378a6e3b06ca679f29138151e45b2b32da62a" - integrity sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg== - dependencies: - dequal "^2.0.3" - -babel-jest@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.7.0.tgz#f4369919225b684c56085998ac63dbd05be020d5" - integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg== - dependencies: - "@jest/transform" "^29.7.0" - "@types/babel__core" "^7.1.14" - babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^29.6.3" - chalk "^4.0.0" - graceful-fs "^4.2.9" - slash "^3.0.0" - -babel-plugin-istanbul@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" - integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@istanbuljs/load-nyc-config" "^1.0.0" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-instrument "^5.0.4" - test-exclude "^6.0.0" - -babel-plugin-jest-hoist@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz#aadbe943464182a8922c3c927c3067ff40d24626" - integrity sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg== - dependencies: - "@babel/template" "^7.3.3" - "@babel/types" "^7.3.3" - "@types/babel__core" "^7.1.14" - "@types/babel__traverse" "^7.0.6" - -babel-preset-current-node-syntax@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" - integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== - dependencies: - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-bigint" "^7.8.3" - "@babel/plugin-syntax-class-properties" "^7.8.3" - "@babel/plugin-syntax-import-meta" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.8.3" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-top-level-await" "^7.8.3" - -babel-preset-jest@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz#fa05fa510e7d493896d7b0dd2033601c840f171c" - integrity sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA== - dependencies: - babel-plugin-jest-hoist "^29.6.3" - babel-preset-current-node-syntax "^1.0.0" - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - -braces@^3.0.2, braces@~3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" - integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== - dependencies: - fill-range "^7.1.1" - -browserslist@^4.21.9: - version "4.22.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.1.tgz#ba91958d1a59b87dab6fed8dfbcb3da5e2e9c619" - integrity sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ== - dependencies: - caniuse-lite "^1.0.30001541" - electron-to-chromium "^1.4.535" - node-releases "^2.0.13" - update-browserslist-db "^1.0.13" - -bs-logger@0.x: - version "0.2.6" - resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" - integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== - dependencies: - fast-json-stable-stringify "2.x" - -bser@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" - integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== - dependencies: - node-int64 "^0.4.0" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -builtin-modules@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" - integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== - -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== - dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" - -callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - -camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - -camelcase@^6.2.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - -caniuse-lite@^1.0.30001541: - version "1.0.30001549" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001549.tgz#7d1a3dce7ea78c06ed72c32c2743ea364b3615aa" - integrity sha512-qRp48dPYSCYaP+KurZLhDYdVE+yEyht/3NlmcJgVQ2VMGt6JL36ndQ/7rgspdZsJuxDPFIo/OzBT2+GmIJ53BA== - -chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - -chalk@^4.0.0, chalk@^4.1.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -char-regex@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" - integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== - -chokidar@^3.5.2: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -ci-info@^3.2.0: - version "3.9.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" - integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== - -cjs-module-lexer@^1.0.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" - integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== - -cli-color@~2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/cli-color/-/cli-color-2.0.3.tgz#73769ba969080629670f3f2ef69a4bf4e7cc1879" - integrity sha512-OkoZnxyC4ERN3zLzZaY9Emb7f/MhBOIpePv0Ycok0fJYT+Ouo00UBEIwsVsr0yoow++n5YWlSUgST9GKhNHiRQ== - dependencies: - d "^1.0.1" - es5-ext "^0.10.61" - es6-iterator "^2.0.3" - memoizee "^0.4.15" - timers-ext "^0.1.7" - -cliui@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" - integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.1" - wrap-ansi "^7.0.0" - -co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== - -collect-v8-coverage@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" - integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== - -color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - -color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - -color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - -color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - -comlink@^4.3.1: - version "4.4.1" - resolved "https://registry.yarnpkg.com/comlink/-/comlink-4.4.1.tgz#e568b8e86410b809e8600eb2cf40c189371ef981" - integrity sha512-+1dlx0aY5Jo1vHy/tSsIGpSkN4tS9rZSW8FIhG0JH/crs9wwweswIo/POr451r7bZww3hFbPAKnTpimzL/mm4Q== - -commander@~9.4.0: - version "9.4.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.1.tgz#d1dd8f2ce6faf93147295c0df13c7c21141cfbdd" - integrity sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw== - -commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -confusing-browser-globals@^1.0.10: - version "1.0.11" - resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81" - integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA== - -convert-source-map@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" - integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== - -create-jest@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/create-jest/-/create-jest-29.7.0.tgz#a355c5b3cb1e1af02ba177fe7afd7feee49a5320" - integrity sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q== - dependencies: - "@jest/types" "^29.6.3" - chalk "^4.0.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - jest-config "^29.7.0" - jest-util "^29.7.0" - prompts "^2.0.1" - -cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -d@1, d@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" - integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== - dependencies: - es5-ext "^0.10.50" - type "^1.0.1" - -damerau-levenshtein@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" - integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== - -data-uri-to-buffer@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz#d8feb2b2881e6a4f58c2e08acfd0e2834e26222e" - integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A== - -debug@2.6.9: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - -debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -dedent@^1.0.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-1.5.1.tgz#4f3fc94c8b711e9bb2800d185cd6ad20f2a90aff" - integrity sha512-+LxW+KLWxu3HW3M2w2ympwtqPrqYRzU8fqi6Fhd18fBALe15blJPI/I4+UHveMVG6lJqB4JNd4UG0S5cnVHwIg== - -deep-is@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - -deepmerge@^4.2.2: - version "4.3.1" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" - integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== - -define-data-property@^1.0.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" - integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== - dependencies: - get-intrinsic "^1.2.1" - gopd "^1.0.1" - has-property-descriptors "^1.0.0" - -define-lazy-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" - integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== - -define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" - integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== - dependencies: - define-data-property "^1.0.1" - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - -depd@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - -dequal@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" - integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== - -destroy@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" - integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== - -detect-newline@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" - integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== - -diff-sequences@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" - integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== - -diff-sequences@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" - integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - -doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== - -electron-to-chromium@^1.4.535: - version "1.4.556" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.556.tgz#97385917eb6ea3ac6a3378cf87bb39ee1db96e76" - integrity sha512-6RPN0hHfzDU8D56E72YkDvnLw5Cj2NMXZGg3UkgyoHxjVhG99KZpsKgBWMmTy0Ei89xwan+rbRsVB9yzATmYzQ== - -emittery@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.13.1.tgz#c04b8c3457490e0847ae51fced3af52d338e3dad" - integrity sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - -encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== - -enhanced-resolve@^5.0.0: - version "5.15.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" - integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - -error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - -es-abstract@^1.22.1: - version "1.22.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.2.tgz#90f7282d91d0ad577f505e423e52d4c1d93c1b8a" - integrity sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA== - dependencies: - array-buffer-byte-length "^1.0.0" - arraybuffer.prototype.slice "^1.0.2" - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - es-set-tostringtag "^2.0.1" - es-to-primitive "^1.2.1" - function.prototype.name "^1.1.6" - get-intrinsic "^1.2.1" - get-symbol-description "^1.0.0" - globalthis "^1.0.3" - gopd "^1.0.1" - has "^1.0.3" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" - has-symbols "^1.0.3" - internal-slot "^1.0.5" - is-array-buffer "^3.0.2" - is-callable "^1.2.7" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-typed-array "^1.1.12" - is-weakref "^1.0.2" - object-inspect "^1.12.3" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.5.1" - safe-array-concat "^1.0.1" - safe-regex-test "^1.0.0" - string.prototype.trim "^1.2.8" - string.prototype.trimend "^1.0.7" - string.prototype.trimstart "^1.0.7" - typed-array-buffer "^1.0.0" - typed-array-byte-length "^1.0.0" - typed-array-byte-offset "^1.0.0" - typed-array-length "^1.0.4" - unbox-primitive "^1.0.2" - which-typed-array "^1.1.11" - -es-set-tostringtag@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" - integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== - dependencies: - get-intrinsic "^1.1.3" - has "^1.0.3" - has-tostringtag "^1.0.0" - -es-shim-unscopables@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" - integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== - dependencies: - has "^1.0.3" - -es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - -es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@^0.10.62, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: - version "0.10.64" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714" - integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg== - dependencies: - es6-iterator "^2.0.3" - es6-symbol "^3.1.3" - esniff "^2.0.1" - next-tick "^1.1.0" - -es6-iterator@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" - integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== - dependencies: - d "1" - es5-ext "^0.10.35" - es6-symbol "^3.1.1" - -es6-symbol@^3.1.1, es6-symbol@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" - integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== - dependencies: - d "^1.0.1" - ext "^1.1.2" - -es6-weak-map@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/es6-weak-map/-/es6-weak-map-2.0.3.tgz#b6da1f16cc2cc0d9be43e6bdbfc5e7dfcdf31d53" - integrity sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA== - dependencies: - d "1" - es5-ext "^0.10.46" - es6-iterator "^2.0.3" - es6-symbol "^3.1.1" - -escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== - -escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - -escape-string-regexp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== - -escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - -eslint-config-airbnb-base@^15.0.0: - version "15.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz#6b09add90ac79c2f8d723a2580e07f3925afd236" - integrity sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig== - dependencies: - confusing-browser-globals "^1.0.10" - object.assign "^4.1.2" - object.entries "^1.1.5" - semver "^6.3.0" - -eslint-config-airbnb-typescript@^16.1.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-16.2.0.tgz#9193fafd62f1cbf444895f4495eae334baf3265b" - integrity sha512-OUaMPZpTOZGKd5tXOjJ9PRU4iYNW/Z5DoHIynjsVK/FpkWdiY5+nxQW6TiJAlLwVI1l53xUOrnlZWtVBVQzuWA== - dependencies: - eslint-config-airbnb-base "^15.0.0" - -eslint-config-airbnb@^19.0.4: - version "19.0.4" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz#84d4c3490ad70a0ffa571138ebcdea6ab085fdc3" - integrity sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew== - dependencies: - eslint-config-airbnb-base "^15.0.0" - object.assign "^4.1.2" - object.entries "^1.1.5" - -eslint-config-prettier@^8.5.0: - version "8.10.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz#3a06a662130807e2502fc3ff8b4143d8a0658e11" - integrity sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg== - -eslint-import-resolver-node@^0.3.2, eslint-import-resolver-node@^0.3.7: - version "0.3.9" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" - integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== - dependencies: - debug "^3.2.7" - is-core-module "^2.13.0" - resolve "^1.22.4" - -eslint-import-resolver-root-import@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-root-import/-/eslint-import-resolver-root-import-1.0.4.tgz#82991138d8014b5e2283b27622ad1ba21f535609" - integrity sha512-c8cUQcELRBe0mnblBZJKEfL+jIUGR8pctK5gdru5N7bBOIve2WZ0R3KoO5GOksXJ4WzZhtcBS2xPaTJYEe4IdQ== - dependencies: - eslint-import-resolver-node "^0.3.2" - json5 "^2.1.0" - -eslint-module-utils@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" - integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== - dependencies: - debug "^3.2.7" - -eslint-plugin-import@^2.25.4: - version "2.28.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz#63b8b5b3c409bfc75ebaf8fb206b07ab435482c4" - integrity sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A== - dependencies: - array-includes "^3.1.6" - array.prototype.findlastindex "^1.2.2" - array.prototype.flat "^1.3.1" - array.prototype.flatmap "^1.3.1" - debug "^3.2.7" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.7" - eslint-module-utils "^2.8.0" - has "^1.0.3" - is-core-module "^2.13.0" - is-glob "^4.0.3" - minimatch "^3.1.2" - object.fromentries "^2.0.6" - object.groupby "^1.0.0" - object.values "^1.1.6" - semver "^6.3.1" - tsconfig-paths "^3.14.2" - -eslint-plugin-jest@^26.1.1: - version "26.9.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-26.9.0.tgz#7931c31000b1c19e57dbfb71bbf71b817d1bf949" - integrity sha512-TWJxWGp1J628gxh2KhaH1H1paEdgE2J61BBF1I59c6xWeL5+D1BzMxGDN/nXAfX+aSkR5u80K+XhskK6Gwq9ng== - dependencies: - "@typescript-eslint/utils" "^5.10.0" - -eslint-plugin-jsx-a11y@^6.5.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz#fca5e02d115f48c9a597a6894d5bcec2f7a76976" - integrity sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA== - dependencies: - "@babel/runtime" "^7.20.7" - aria-query "^5.1.3" - array-includes "^3.1.6" - array.prototype.flatmap "^1.3.1" - ast-types-flow "^0.0.7" - axe-core "^4.6.2" - axobject-query "^3.1.1" - damerau-levenshtein "^1.0.8" - emoji-regex "^9.2.2" - has "^1.0.3" - jsx-ast-utils "^3.3.3" - language-tags "=1.0.5" - minimatch "^3.1.2" - object.entries "^1.1.6" - object.fromentries "^2.0.6" - semver "^6.3.0" - -eslint-plugin-prettier@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" - integrity sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ== - dependencies: - prettier-linter-helpers "^1.0.0" - -eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -eslint-scope@^7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" - integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - -eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: - version "3.4.3" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" - integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== - -eslint@^8.10.0: - version "8.51.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.51.0.tgz#4a82dae60d209ac89a5cff1604fea978ba4950f3" - integrity sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.6.1" - "@eslint/eslintrc" "^2.1.2" - "@eslint/js" "8.51.0" - "@humanwhocodes/config-array" "^0.11.11" - "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" - ajv "^6.12.4" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.2.2" - eslint-visitor-keys "^3.4.3" - espree "^9.6.1" - esquery "^1.4.2" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - glob-parent "^6.0.2" - globals "^13.19.0" - graphemer "^1.4.0" - ignore "^5.2.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - is-path-inside "^3.0.3" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.3" - strip-ansi "^6.0.1" - text-table "^0.2.0" - -esniff@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308" - integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg== - dependencies: - d "^1.0.1" - es5-ext "^0.10.62" - event-emitter "^0.3.5" - type "^2.7.2" - -espree@^9.6.0, espree@^9.6.1: - version "9.6.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" - integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== - dependencies: - acorn "^8.9.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" - -esprima@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - -esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== - dependencies: - estraverse "^5.1.0" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.1.0, estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -estree-walker@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-1.0.1.tgz#31bc5d612c96b704106b477e6dd5d8aa138cb700" - integrity sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg== - -estree-walker@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" - integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== - -esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== - -event-emitter@^0.3.5: - version "0.3.5" - resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" - integrity sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA== - dependencies: - d "1" - es5-ext "~0.10.14" - -execa@^5.0.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - -exit@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" - integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== - -expect@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" - integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== - dependencies: - "@jest/expect-utils" "^29.7.0" - jest-get-type "^29.6.3" - jest-matcher-utils "^29.7.0" - jest-message-util "^29.7.0" - jest-util "^29.7.0" - -ext@^1.1.2: - version "1.7.0" - resolved "https://registry.yarnpkg.com/ext/-/ext-1.7.0.tgz#0ea4383c0103d60e70be99e9a7f11027a33c4f5f" - integrity sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw== - dependencies: - type "^2.7.2" - -fake-indexeddb@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/fake-indexeddb/-/fake-indexeddb-5.0.0.tgz#c9f394d6d36db62760ad596ebec97ba3d700c95b" - integrity sha512-hGMsl73XgJAk5OtC8hFDSLUVzJ3Z1/C06YpFwI7DzCsEsmH5Mvkxplv3PK6uUL7XCYVBTzayp/4gD+cp7Qi8xQ== - -fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - -fast-diff@^1.1.2: - version "1.3.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" - integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== - -fast-glob@^3.2.9: - version "3.3.1" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" - integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - -fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - -fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== - -fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== - dependencies: - reusify "^1.0.4" - -fb-watchman@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" - integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== - dependencies: - bser "2.1.1" - -fetch-blob@^3.1.2, fetch-blob@^3.1.4: - version "3.2.0" - resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.2.0.tgz#f09b8d4bbd45adc6f0c20b7e787e793e309dcce9" - integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ== - dependencies: - node-domexception "^1.0.0" - web-streams-polyfill "^3.0.3" - -file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - -fill-range@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.1.1.tgz#44265d3cac07e3ea7dc247516380643754a05292" - integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== - dependencies: - to-regex-range "^5.0.1" - -finalhandler@~1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" - integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "2.4.1" - parseurl "~1.3.3" - statuses "2.0.1" - unpipe "~1.0.0" - -find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - -flat-cache@^3.0.4: - version "3.1.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.1.1.tgz#a02a15fdec25a8f844ff7cc658f03dd99eb4609b" - integrity sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q== - dependencies: - flatted "^3.2.9" - keyv "^4.5.3" - rimraf "^3.0.2" - -flatted@^3.2.9: - version "3.2.9" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" - integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== - -for-each@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== - dependencies: - is-callable "^1.1.3" - -formdata-polyfill@^4.0.10: - version "4.0.10" - resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423" - integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== - dependencies: - fetch-blob "^3.1.2" - -fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -fsevents@^2.3.2, fsevents@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - -function-bind@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" - integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== - -function.prototype.name@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" - integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - functions-have-names "^1.2.3" - -functions-have-names@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== - -gensync@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" - integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== - -get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" - integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== - dependencies: - function-bind "^1.1.1" - has "^1.0.3" - has-proto "^1.0.1" - has-symbols "^1.0.3" - -get-package-type@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" - integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== - -get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - -get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - -glob-parent@^5.1.2, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-parent@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob@^7.1.3, glob@^7.1.4: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -glob@^8.0.3: - version "8.1.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" - integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^5.0.1" - once "^1.3.0" - -globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - -globals@^13.19.0: - version "13.23.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.23.0.tgz#ef31673c926a0976e1f61dab4dca57e0c0a8af02" - integrity sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA== - dependencies: - type-fest "^0.20.2" - -globalthis@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" - integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== - dependencies: - define-properties "^1.1.3" - -globby@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - -gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" - -graceful-fs@^4.2.4, graceful-fs@^4.2.9: - version "4.2.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" - integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== - -graphemer@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" - integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== - -has-bigints@^1.0.1, has-bigints@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== - -has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - -has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== - dependencies: - get-intrinsic "^1.1.1" - -has-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" - integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== - -has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - -has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - -has@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.4.tgz#2eb2860e000011dae4f1406a86fe80e530fb2ec6" - integrity sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ== - -html-escaper@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" - integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== - -http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== - dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" - -human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - -ignore-by-default@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" - integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== - -ignore@^5.2.0: - version "5.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== - -import-fresh@^3.2.1: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - -import-local@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" - integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -internal-slot@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" - integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== - dependencies: - get-intrinsic "^1.2.0" - has "^1.0.3" - side-channel "^1.0.4" - -is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" - integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.0" - is-typed-array "^1.1.10" - -is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== - -is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - -is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-builtin-module@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169" - integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== - dependencies: - builtin-modules "^3.3.0" - -is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" - integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== - -is-core-module@^2.13.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" - integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== - dependencies: - has "^1.0.3" - -is-date-object@^1.0.1: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - -is-docker@^2.0.0, is-docker@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - -is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - -is-generator-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" - integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== - -is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" - integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== - -is-negative-zero@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== - -is-number-object@^1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== - dependencies: - has-tostringtag "^1.0.0" - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-path-inside@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - -is-promise@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" - integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== - -is-reference@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" - integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== - dependencies: - "@types/estree" "*" - -is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - -is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== - dependencies: - call-bind "^1.0.2" - -is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - -is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - -is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - -is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: - version "1.1.12" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" - integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== - dependencies: - which-typed-array "^1.1.11" - -is-weakref@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== - dependencies: - call-bind "^1.0.2" - -is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - -isarray@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" - integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== - -istanbul-lib-instrument@^5.0.4: - version "5.2.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" - integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== - dependencies: - "@babel/core" "^7.12.3" - "@babel/parser" "^7.14.7" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.2.0" - semver "^6.3.0" - -istanbul-lib-instrument@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.1.tgz#71e87707e8041428732518c6fb5211761753fbdf" - integrity sha512-EAMEJBsYuyyztxMxW3g7ugGPkrZsV57v0Hmv3mm1uQsmB+QnZuepg731CRaIgeUVSdmsTngOkSnauNF8p7FIhA== - dependencies: - "@babel/core" "^7.12.3" - "@babel/parser" "^7.14.7" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.2.0" - semver "^7.5.4" - -istanbul-lib-report@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" - integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== - dependencies: - istanbul-lib-coverage "^3.0.0" - make-dir "^4.0.0" - supports-color "^7.1.0" - -istanbul-lib-source-maps@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" - integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== - dependencies: - debug "^4.1.1" - istanbul-lib-coverage "^3.0.0" - source-map "^0.6.1" - -istanbul-reports@^3.1.3: - version "3.1.6" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.6.tgz#2544bcab4768154281a2f0870471902704ccaa1a" - integrity sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg== - dependencies: - html-escaper "^2.0.0" - istanbul-lib-report "^3.0.0" - -jest-changed-files@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.7.0.tgz#1c06d07e77c78e1585d020424dedc10d6e17ac3a" - integrity sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w== - dependencies: - execa "^5.0.0" - jest-util "^29.7.0" - p-limit "^3.1.0" - -jest-circus@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.7.0.tgz#b6817a45fcc835d8b16d5962d0c026473ee3668a" - integrity sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw== - dependencies: - "@jest/environment" "^29.7.0" - "@jest/expect" "^29.7.0" - "@jest/test-result" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - dedent "^1.0.0" - is-generator-fn "^2.0.0" - jest-each "^29.7.0" - jest-matcher-utils "^29.7.0" - jest-message-util "^29.7.0" - jest-runtime "^29.7.0" - jest-snapshot "^29.7.0" - jest-util "^29.7.0" - p-limit "^3.1.0" - pretty-format "^29.7.0" - pure-rand "^6.0.0" - slash "^3.0.0" - stack-utils "^2.0.3" - -jest-cli@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.7.0.tgz#5592c940798e0cae677eec169264f2d839a37995" - integrity sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg== - dependencies: - "@jest/core" "^29.7.0" - "@jest/test-result" "^29.7.0" - "@jest/types" "^29.6.3" - chalk "^4.0.0" - create-jest "^29.7.0" - exit "^0.1.2" - import-local "^3.0.2" - jest-config "^29.7.0" - jest-util "^29.7.0" - jest-validate "^29.7.0" - yargs "^17.3.1" - -jest-config@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.7.0.tgz#bcbda8806dbcc01b1e316a46bb74085a84b0245f" - integrity sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ== - dependencies: - "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^29.7.0" - "@jest/types" "^29.6.3" - babel-jest "^29.7.0" - chalk "^4.0.0" - ci-info "^3.2.0" - deepmerge "^4.2.2" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-circus "^29.7.0" - jest-environment-node "^29.7.0" - jest-get-type "^29.6.3" - jest-regex-util "^29.6.3" - jest-resolve "^29.7.0" - jest-runner "^29.7.0" - jest-util "^29.7.0" - jest-validate "^29.7.0" - micromatch "^4.0.4" - parse-json "^5.2.0" - pretty-format "^29.7.0" - slash "^3.0.0" - strip-json-comments "^3.1.1" - -jest-diff@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" - integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw== - dependencies: - chalk "^4.0.0" - diff-sequences "^27.5.1" - jest-get-type "^27.5.1" - pretty-format "^27.5.1" - -jest-diff@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" - integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== - dependencies: - chalk "^4.0.0" - diff-sequences "^29.6.3" - jest-get-type "^29.6.3" - pretty-format "^29.7.0" - -jest-docblock@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.7.0.tgz#8fddb6adc3cdc955c93e2a87f61cfd350d5d119a" - integrity sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g== - dependencies: - detect-newline "^3.0.0" - -jest-each@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.7.0.tgz#162a9b3f2328bdd991beaabffbb74745e56577d1" - integrity sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ== - dependencies: - "@jest/types" "^29.6.3" - chalk "^4.0.0" - jest-get-type "^29.6.3" - jest-util "^29.7.0" - pretty-format "^29.7.0" - -jest-environment-node@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.7.0.tgz#0b93e111dda8ec120bc8300e6d1fb9576e164376" - integrity sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw== - dependencies: - "@jest/environment" "^29.7.0" - "@jest/fake-timers" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - jest-mock "^29.7.0" - jest-util "^29.7.0" - -jest-get-type@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" - integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== - -jest-get-type@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" - integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== - -jest-haste-map@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.7.0.tgz#3c2396524482f5a0506376e6c858c3bbcc17b104" - integrity sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA== - dependencies: - "@jest/types" "^29.6.3" - "@types/graceful-fs" "^4.1.3" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.9" - jest-regex-util "^29.6.3" - jest-util "^29.7.0" - jest-worker "^29.7.0" - micromatch "^4.0.4" - walker "^1.0.8" - optionalDependencies: - fsevents "^2.3.2" - -jest-leak-detector@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz#5b7ec0dadfdfec0ca383dc9aa016d36b5ea4c728" - integrity sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw== - dependencies: - jest-get-type "^29.6.3" - pretty-format "^29.7.0" - -jest-matcher-utils@^27.0.0: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" - integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== - dependencies: - chalk "^4.0.0" - jest-diff "^27.5.1" - jest-get-type "^27.5.1" - pretty-format "^27.5.1" - -jest-matcher-utils@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" - integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== - dependencies: - chalk "^4.0.0" - jest-diff "^29.7.0" - jest-get-type "^29.6.3" - pretty-format "^29.7.0" - -jest-message-util@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" - integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== - dependencies: - "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.6.3" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - micromatch "^4.0.4" - pretty-format "^29.7.0" - slash "^3.0.0" - stack-utils "^2.0.3" - -jest-mock@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.7.0.tgz#4e836cf60e99c6fcfabe9f99d017f3fdd50a6347" - integrity sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw== - dependencies: - "@jest/types" "^29.6.3" - "@types/node" "*" - jest-util "^29.7.0" - -jest-pnp-resolver@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" - integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== - -jest-regex-util@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.6.3.tgz#4a556d9c776af68e1c5f48194f4d0327d24e8a52" - integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg== - -jest-resolve-dependencies@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz#1b04f2c095f37fc776ff40803dc92921b1e88428" - integrity sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA== - dependencies: - jest-regex-util "^29.6.3" - jest-snapshot "^29.7.0" - -jest-resolve@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.7.0.tgz#64d6a8992dd26f635ab0c01e5eef4399c6bcbc30" - integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA== - dependencies: - chalk "^4.0.0" - graceful-fs "^4.2.9" - jest-haste-map "^29.7.0" - jest-pnp-resolver "^1.2.2" - jest-util "^29.7.0" - jest-validate "^29.7.0" - resolve "^1.20.0" - resolve.exports "^2.0.0" - slash "^3.0.0" - -jest-runner@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.7.0.tgz#809af072d408a53dcfd2e849a4c976d3132f718e" - integrity sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ== - dependencies: - "@jest/console" "^29.7.0" - "@jest/environment" "^29.7.0" - "@jest/test-result" "^29.7.0" - "@jest/transform" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - emittery "^0.13.1" - graceful-fs "^4.2.9" - jest-docblock "^29.7.0" - jest-environment-node "^29.7.0" - jest-haste-map "^29.7.0" - jest-leak-detector "^29.7.0" - jest-message-util "^29.7.0" - jest-resolve "^29.7.0" - jest-runtime "^29.7.0" - jest-util "^29.7.0" - jest-watcher "^29.7.0" - jest-worker "^29.7.0" - p-limit "^3.1.0" - source-map-support "0.5.13" - -jest-runtime@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.7.0.tgz#efecb3141cf7d3767a3a0cc8f7c9990587d3d817" - integrity sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ== - dependencies: - "@jest/environment" "^29.7.0" - "@jest/fake-timers" "^29.7.0" - "@jest/globals" "^29.7.0" - "@jest/source-map" "^29.6.3" - "@jest/test-result" "^29.7.0" - "@jest/transform" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - cjs-module-lexer "^1.0.0" - collect-v8-coverage "^1.0.0" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-haste-map "^29.7.0" - jest-message-util "^29.7.0" - jest-mock "^29.7.0" - jest-regex-util "^29.6.3" - jest-resolve "^29.7.0" - jest-snapshot "^29.7.0" - jest-util "^29.7.0" - slash "^3.0.0" - strip-bom "^4.0.0" - -jest-snapshot@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.7.0.tgz#c2c574c3f51865da1bb329036778a69bf88a6be5" - integrity sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw== - dependencies: - "@babel/core" "^7.11.6" - "@babel/generator" "^7.7.2" - "@babel/plugin-syntax-jsx" "^7.7.2" - "@babel/plugin-syntax-typescript" "^7.7.2" - "@babel/types" "^7.3.3" - "@jest/expect-utils" "^29.7.0" - "@jest/transform" "^29.7.0" - "@jest/types" "^29.6.3" - babel-preset-current-node-syntax "^1.0.0" - chalk "^4.0.0" - expect "^29.7.0" - graceful-fs "^4.2.9" - jest-diff "^29.7.0" - jest-get-type "^29.6.3" - jest-matcher-utils "^29.7.0" - jest-message-util "^29.7.0" - jest-util "^29.7.0" - natural-compare "^1.4.0" - pretty-format "^29.7.0" - semver "^7.5.3" - -jest-util@^29.0.0, jest-util@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" - integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== - dependencies: - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" - -jest-validate@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.7.0.tgz#7bf705511c64da591d46b15fce41400d52147d9c" - integrity sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw== - dependencies: - "@jest/types" "^29.6.3" - camelcase "^6.2.0" - chalk "^4.0.0" - jest-get-type "^29.6.3" - leven "^3.1.0" - pretty-format "^29.7.0" - -jest-watcher@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.7.0.tgz#7810d30d619c3a62093223ce6bb359ca1b28a2f2" - integrity sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g== - dependencies: - "@jest/test-result" "^29.7.0" - "@jest/types" "^29.6.3" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - emittery "^0.13.1" - jest-util "^29.7.0" - string-length "^4.0.1" - -jest-worker@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.7.0.tgz#acad073acbbaeb7262bd5389e1bcf43e10058d4a" - integrity sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw== - dependencies: - "@types/node" "*" - jest-util "^29.7.0" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -jest@^29.5.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-29.7.0.tgz#994676fc24177f088f1c5e3737f5697204ff2613" - integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw== - dependencies: - "@jest/core" "^29.7.0" - "@jest/types" "^29.6.3" - import-local "^3.0.2" - jest-cli "^29.7.0" - -js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - -js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - -js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -json-buffer@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" - integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== - -json-parse-even-better-errors@^2.3.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - -json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - -json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== - -json5@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" - integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== - dependencies: - minimist "^1.2.0" - -json5@^2.1.0, json5@^2.2.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" - integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== - -jsonc-parser@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" - integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== - -jsx-ast-utils@^3.3.3: - version "3.3.5" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" - integrity sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ== - dependencies: - array-includes "^3.1.6" - array.prototype.flat "^1.3.1" - object.assign "^4.1.4" - object.values "^1.1.6" - -keyv@^4.5.3: - version "4.5.4" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" - integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== - dependencies: - json-buffer "3.0.1" - -kleur@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" - integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== - -language-subtag-registry@~0.3.2: - version "0.3.22" - resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" - integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== - -language-tags@=1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a" - integrity sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ== - dependencies: - language-subtag-registry "~0.3.2" - -leven@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" - integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== - -levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - -lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - -lodash.memoize@4.x: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== - -lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - -lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -lru-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" - integrity sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ== - dependencies: - es5-ext "~0.10.2" - -lunr@^2.3.9: - version "2.3.9" - resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" - integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== - -magic-string@0.25.2: - version "0.25.2" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.2.tgz#139c3a729515ec55e96e69e82a11fe890a293ad9" - integrity sha512-iLs9mPjh9IuTtRsqqhNGYcZXGei0Nh/A4xirrsqW7c+QhKVFL2vm7U09ru6cHRD22azaP/wMDgI+HCqbETMTtg== - dependencies: - sourcemap-codec "^1.4.4" - -magic-string@^0.27.0: - version "0.27.0" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.27.0.tgz#e4a3413b4bab6d98d2becffd48b4a257effdbbf3" - integrity sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA== - dependencies: - "@jridgewell/sourcemap-codec" "^1.4.13" - -magic-string@^0.30.3: - version "0.30.5" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.5.tgz#1994d980bd1c8835dc6e78db7cbd4ae4f24746f9" - integrity sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA== - dependencies: - "@jridgewell/sourcemap-codec" "^1.4.15" - -make-dir@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" - integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== - dependencies: - semver "^7.5.3" - -make-error@1.x: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - -makeerror@1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" - integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== - dependencies: - tmpl "1.0.5" - -marked@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3" - integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A== - -memoizee@^0.4.15: - version "0.4.15" - resolved "https://registry.yarnpkg.com/memoizee/-/memoizee-0.4.15.tgz#e6f3d2da863f318d02225391829a6c5956555b72" - integrity sha512-UBWmJpLZd5STPm7PMUlOw/TSy972M+z8gcyQ5veOnSDRREz/0bmpyTfKt3/51DhEBqCZQn1udM/5flcSPYhkdQ== - dependencies: - d "^1.0.1" - es5-ext "^0.10.53" - es6-weak-map "^2.0.3" - event-emitter "^0.3.5" - is-promise "^2.2.2" - lru-queue "^0.1.0" - next-tick "^1.1.0" - timers-ext "^0.1.7" - -merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - -merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -micromatch@^4.0.0, micromatch@^4.0.4: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - -minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minimatch@^5.0.1: - version "5.1.6" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" - integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== - dependencies: - brace-expansion "^2.0.1" - -minimatch@^9.0.0: - version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - -minimist@^1.2.0, minimist@^1.2.6, minimist@~1.2.0: - version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@2.1.3, ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -natural-compare-lite@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" - integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== - -natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== - -next-tick@1, next-tick@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" - integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== - -node-domexception@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" - integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== - -node-fetch@^3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.3.2.tgz#d1e889bacdf733b4ff3b2b243eb7a12866a0b78b" - integrity sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA== - dependencies: - data-uri-to-buffer "^4.0.0" - fetch-blob "^3.1.4" - formdata-polyfill "^4.0.10" - -node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== - -node-releases@^2.0.13: - version "2.0.13" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" - integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== - -nodemon@^2.0.21: - version "2.0.22" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.22.tgz#182c45c3a78da486f673d6c1702e00728daf5258" - integrity sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ== - dependencies: - chokidar "^3.5.2" - debug "^3.2.7" - ignore-by-default "^1.0.1" - minimatch "^3.1.2" - pstree.remy "^1.1.8" - semver "^5.7.1" - simple-update-notifier "^1.0.7" - supports-color "^5.5.0" - touch "^3.1.0" - undefsafe "^2.0.5" - -nopt@~1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" - integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg== - dependencies: - abbrev "1" - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - -object-inspect@^1.12.3, object-inspect@^1.9.0: - version "1.13.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.0.tgz#42695d3879e1cd5bda6df5062164d80c996e23e2" - integrity sha512-HQ4J+ic8hKrgIt3mqk6cVOVrW2ozL4KdvHlqpBv9vDYWx9ysAgENAdvy4FoGF+KFdhR7nQTNm5J0ctAeOwn+3g== - -object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - -object.assign@^4.1.2, object.assign@^4.1.4: - version "4.1.4" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" - integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.4" - has-symbols "^1.0.3" - object-keys "^1.1.1" - -object.entries@^1.1.5, object.entries@^1.1.6: - version "1.1.7" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.7.tgz#2b47760e2a2e3a752f39dd874655c61a7f03c131" - integrity sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -object.fromentries@^2.0.6: - version "2.0.7" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.7.tgz#71e95f441e9a0ea6baf682ecaaf37fa2a8d7e616" - integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -object.groupby@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.1.tgz#d41d9f3c8d6c778d9cbac86b4ee9f5af103152ee" - integrity sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - -object.values@^1.1.6: - version "1.1.7" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" - integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -on-finished@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" - integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== - dependencies: - ee-first "1.1.1" - -once@^1.3.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - -open@^8.0.0: - version "8.4.2" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" - integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== - dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" - -optionator@^0.9.3: - version "0.9.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" - integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== - dependencies: - "@aashutoshrathi/word-wrap" "^1.2.3" - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - -ospec@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/ospec/-/ospec-3.1.0.tgz#d36b8e10110f58f63a463df2390a7a73fe9579a8" - integrity sha512-+nGtjV3vlADp+UGfL51miAh/hB4awPBkQrArhcgG4trAaoA2gKt5bf9w0m9ch9zOr555cHWaCHZEDiBOkNZSxw== - dependencies: - glob "^7.1.3" - -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-limit@^3.0.2, p-limit@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - -parse-json@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - -parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.2, picomatch@^2.2.3, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pirates@^4.0.4: - version "4.0.6" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" - integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== - -pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - -prettier-linter-helpers@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" - integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== - dependencies: - fast-diff "^1.1.2" - -pretty-format@^27.0.0, pretty-format@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" - integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== - dependencies: - ansi-regex "^5.0.1" - ansi-styles "^5.0.0" - react-is "^17.0.1" - -pretty-format@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" - integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== - dependencies: - "@jest/schemas" "^29.6.3" - ansi-styles "^5.0.0" - react-is "^18.0.0" - -prompts@^2.0.1: - version "2.4.2" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" - integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== - dependencies: - kleur "^3.0.3" - sisteransi "^1.0.5" - -pstree.remy@^1.1.8: - version "1.1.8" - resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" - integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== - -punycode@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== - -pure-rand@^6.0.0: - version "6.0.4" - resolved "https://registry.yarnpkg.com/pure-rand/-/pure-rand-6.0.4.tgz#50b737f6a925468679bff00ad20eade53f37d5c7" - integrity sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA== - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - -react-is@^17.0.1: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" - integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== - -react-is@^18.0.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" - integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -regenerator-runtime@^0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" - integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== - -regexp.prototype.flags@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e" - integrity sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - set-function-name "^2.0.0" - -reload@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/reload/-/reload-3.2.1.tgz#42d43e33e327efe1348c723272c6835fe333349a" - integrity sha512-ZdM8ZSEeI72zkhh6heMEvJ0vHZoovZXcJI6Zae8CzS7o5vO/WjZsAMMr0y1+3I/fCN7y7ZxABoUwwCswcLHkjQ== - dependencies: - cli-color "~2.0.0" - commander "~9.4.0" - finalhandler "~1.2.0" - minimist "~1.2.0" - open "^8.0.0" - serve-static "~1.15.0" - supervisor "~0.12.0" - ws "~8.11.0" - -require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== - -resolve-cwd@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" - integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== - dependencies: - resolve-from "^5.0.0" - -resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - -resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - -resolve.exports@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800" - integrity sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg== - -resolve@^1.20.0, resolve@^1.22.1, resolve@^1.22.4: - version "1.22.8" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" - integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== - dependencies: - is-core-module "^2.13.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -rollup-plugin-base64@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/rollup-plugin-base64/-/rollup-plugin-base64-1.0.1.tgz#b3529b94d23baeb66e1e3bffd04477fa792985eb" - integrity sha512-IbdX8fjuXO/Op3hYmRPjVo0VwcSenwsQDaDTFdoe+70B5ZGoLMtr96L2yhHXCfxv7HwZVvxZqLsuWj6VwzRt3g== - dependencies: - "@rollup/pluginutils" "^3.1.0" - -rollup-plugin-modify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/rollup-plugin-modify/-/rollup-plugin-modify-3.0.0.tgz#5326e11dfec247e8bbdd9507f3da1da1e5c7818b" - integrity sha512-p/ffs0Y2jz2dEnWjq1oVC7SY37tuS+aP7whoNaQz1EAAOPg+k3vKJo8cMMWx6xpdd0NzhX4y2YF9o/NPu5YR0Q== - dependencies: - magic-string "0.25.2" - ospec "3.1.0" - -rollup-plugin-web-worker-loader@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/rollup-plugin-web-worker-loader/-/rollup-plugin-web-worker-loader-1.6.1.tgz#9d7a27575b64b0780fe4e8b3bc87470d217e485f" - integrity sha512-4QywQSz1NXFHKdyiou16mH3ijpcfLtLGOrAqvAqu1Gx+P8+zj+3gwC2BSL/VW1d+LW4nIHC8F7d7OXhs9UdR2A== - -rollup@^3.9.1: - version "3.29.4" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.4.tgz#4d70c0f9834146df8705bfb69a9a19c9e1109981" - integrity sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw== - optionalDependencies: - fsevents "~2.3.2" - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -safe-array-concat@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.1.tgz#91686a63ce3adbea14d61b14c99572a8ff84754c" - integrity sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" - has-symbols "^1.0.3" - isarray "^2.0.5" - -safe-regex-test@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" - integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - is-regex "^1.1.4" - -semver@^5.7.1: - version "5.7.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - -semver@^6.3.0, semver@^6.3.1: - version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^7.3.4, semver@^7.3.7, semver@^7.5.3, semver@^7.5.4: - version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - -semver@~7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" - integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== - -send@0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" - integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== - dependencies: - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "2.0.0" - mime "1.6.0" - ms "2.1.3" - on-finished "2.4.1" - range-parser "~1.2.1" - statuses "2.0.1" - -serve-static@~1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" - integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.18.0" - -set-function-name@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" - integrity sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA== - dependencies: - define-data-property "^1.0.1" - functions-have-names "^1.2.3" - has-property-descriptors "^1.0.0" - -setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -shiki@^0.14.1: - version "0.14.5" - resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.14.5.tgz#375dd214e57eccb04f0daf35a32aa615861deb93" - integrity sha512-1gCAYOcmCFONmErGTrS1fjzJLA7MGZmKzrBNX7apqSwhyITJg2O102uFzXUeBxNnEkDA9vHIKLyeKq0V083vIw== - dependencies: - ansi-sequence-parser "^1.1.0" - jsonc-parser "^3.2.0" - vscode-oniguruma "^1.7.0" - vscode-textmate "^8.0.0" - -side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - -signal-exit@^3.0.3, signal-exit@^3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -simple-update-notifier@^1.0.7: - version "1.1.0" - resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz#67694c121de354af592b347cdba798463ed49c82" - integrity sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg== - dependencies: - semver "~7.0.0" - -sisteransi@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" - integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== - -slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - -source-map-support@0.5.13: - version "0.5.13" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.13.tgz#31b24a9c2e73c2de85066c0feb7d44767ed52932" - integrity sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0, source-map@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -source-map@^0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" - integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== - -sourcemap-codec@^1.4.4: - version "1.4.8" - resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" - integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== - -sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== - -stack-utils@^2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" - integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== - dependencies: - escape-string-regexp "^2.0.0" - -statuses@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - -string-length@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" - integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== - dependencies: - char-regex "^1.0.2" - strip-ansi "^6.0.0" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string.prototype.trim@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz#f9ac6f8af4bd55ddfa8895e6aea92a96395393bd" - integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -string.prototype.trimend@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz#1bb3afc5008661d73e2dc015cd4853732d6c471e" - integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -string.prototype.trimstart@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298" - integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - -strip-bom@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" - integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== - -strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - -strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - -supervisor@~0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/supervisor/-/supervisor-0.12.0.tgz#de7e6337015b291851c10f3538c4a7f04917ecc1" - integrity sha512-iBYeU5Or4WiiIa3+ns1DpHIiHjNNXSuYUiixKcznewwo4ImBJ8EobktaAo2csOcauhrz4SvKRTou8Z2C3W28+A== - -supports-color@^5.3.0, supports-color@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - -supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - -tapable@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== - -test-exclude@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" - integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== - dependencies: - "@istanbuljs/schema" "^0.1.2" - glob "^7.1.4" - minimatch "^3.0.4" - -text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - -timers-ext@^0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/timers-ext/-/timers-ext-0.1.7.tgz#6f57ad8578e07a3fb9f91d9387d65647555e25c6" - integrity sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ== - dependencies: - es5-ext "~0.10.46" - next-tick "1" - -tmpl@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" - integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== - -to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== - -to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - -toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - -touch@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" - integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== - dependencies: - nopt "~1.0.10" - -ts-jest@^29.1.0: - version "29.1.1" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-29.1.1.tgz#f58fe62c63caf7bfcc5cc6472082f79180f0815b" - integrity sha512-D6xjnnbP17cC85nliwGiL+tpoKN0StpgE0TeOjXQTU6MVCfsB4v7aW05CgQ/1OywGb0x/oy9hHFnN+sczTiRaA== - dependencies: - bs-logger "0.x" - fast-json-stable-stringify "2.x" - jest-util "^29.0.0" - json5 "^2.2.3" - lodash.memoize "4.x" - make-error "1.x" - semver "^7.5.3" - yargs-parser "^21.0.1" - -ts-loader@^9.4.2: - version "9.5.0" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.5.0.tgz#f0a51dda37cc4d8e43e6cb14edebbc599b0c3aa2" - integrity sha512-LLlB/pkB4q9mW2yLdFMnK3dEHbrBjeZTYguaaIfusyojBgAGf5kF+O6KcWqiGzWqHk0LBsoolrp4VftEURhybg== - dependencies: - chalk "^4.1.0" - enhanced-resolve "^5.0.0" - micromatch "^4.0.0" - semver "^7.3.4" - source-map "^0.7.4" - -tsconfig-paths@^3.14.2: - version "3.14.2" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" - integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - -tslib@^1.8.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - -type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - -type-detect@4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - -type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - -type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - -type@^1.0.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" - integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== - -type@^2.7.2: - version "2.7.2" - resolved "https://registry.yarnpkg.com/type/-/type-2.7.2.tgz#2376a15a3a28b1efa0f5350dcf72d24df6ef98d0" - integrity sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw== - -typed-array-buffer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" - integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" - is-typed-array "^1.1.10" - -typed-array-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" - integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== - dependencies: - call-bind "^1.0.2" - for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" - -typed-array-byte-offset@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" - integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" - -typed-array-length@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" - integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== - dependencies: - call-bind "^1.0.2" - for-each "^0.3.3" - is-typed-array "^1.1.9" - -typedoc@^0.24.8: - version "0.24.8" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.24.8.tgz#cce9f47ba6a8d52389f5e583716a2b3b4335b63e" - integrity sha512-ahJ6Cpcvxwaxfu4KtjA8qZNqS43wYt6JL27wYiIgl1vd38WW/KWX11YuAeZhuz9v+ttrutSsgK+XO1CjL1kA3w== - dependencies: - lunr "^2.3.9" - marked "^4.3.0" - minimatch "^9.0.0" - shiki "^0.14.1" - -typescript@^4.8.4: - version "4.9.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== - -unbox-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" - integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== - dependencies: - call-bind "^1.0.2" - has-bigints "^1.0.2" - has-symbols "^1.0.3" - which-boxed-primitive "^1.0.2" - -undefsafe@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" - integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== - -undici-types@~5.25.1: - version "5.25.3" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.25.3.tgz#e044115914c85f0bcbb229f346ab739f064998c3" - integrity sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA== - -unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== - -update-browserslist-db@^1.0.13: - version "1.0.13" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" - integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - -uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - -v8-to-istanbul@^9.0.1: - version "9.1.3" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz#ea456604101cd18005ac2cae3cdd1aa058a6306b" - integrity sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg== - dependencies: - "@jridgewell/trace-mapping" "^0.3.12" - "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^2.0.0" - -vscode-oniguruma@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz#439bfad8fe71abd7798338d1cd3dc53a8beea94b" - integrity sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA== - -vscode-textmate@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-8.0.0.tgz#2c7a3b1163ef0441097e0b5d6389cd5504b59e5d" - integrity sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg== - -walker@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" - integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== - dependencies: - makeerror "1.0.12" - -web-streams-polyfill@^3.0.3: - version "3.2.1" - resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" - integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== - -which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - -which-typed-array@^1.1.11: - version "1.1.11" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.11.tgz#99d691f23c72aab6768680805a271b69761ed61a" - integrity sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - -which@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - -wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -write-file-atomic@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" - integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== - dependencies: - imurmurhash "^0.1.4" - signal-exit "^3.0.7" - -ws@^8.14.2: - version "8.14.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f" - integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g== - -ws@~8.11.0: - version "8.11.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143" - integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== - -y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - -yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - -yargs-parser@^21.0.1, yargs-parser@^21.1.1: - version "21.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" - integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== - -yargs@^17.3.1: - version "17.7.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" - integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== - dependencies: - cliui "^8.0.1" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.3" - y18n "^5.0.5" - yargs-parser "^21.1.1" - -yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/sdk/typescript/packages/mix-fetch/.babelrc b/sdk/typescript/packages/mix-fetch/.babelrc deleted file mode 100644 index 0ef5ffc214..0000000000 --- a/sdk/typescript/packages/mix-fetch/.babelrc +++ /dev/null @@ -1,3 +0,0 @@ -{ - "presets": ["@babel/env"] -} diff --git a/sdk/typescript/packages/mix-fetch/README-CommonJS-full-fat.md b/sdk/typescript/packages/mix-fetch/README-CommonJS-full-fat.md deleted file mode 100644 index a8c0c858dc..0000000000 --- a/sdk/typescript/packages/mix-fetch/README-CommonJS-full-fat.md +++ /dev/null @@ -1,14 +0,0 @@ -# Nym MixFetch - -This package is a drop-in replacement for `fetch` to send HTTP requests over the Nym Mixnet. - -## Usage - -```js -const { mixFetch } = require('@nymproject/mix-fetch'); - -... - -const response = await mixFetch('https://nymtech.net'); -const html = await response.text(); -``` diff --git a/sdk/typescript/packages/mix-fetch/README-CommonJS.md b/sdk/typescript/packages/mix-fetch/README-CommonJS.md deleted file mode 100644 index a8c0c858dc..0000000000 --- a/sdk/typescript/packages/mix-fetch/README-CommonJS.md +++ /dev/null @@ -1,14 +0,0 @@ -# Nym MixFetch - -This package is a drop-in replacement for `fetch` to send HTTP requests over the Nym Mixnet. - -## Usage - -```js -const { mixFetch } = require('@nymproject/mix-fetch'); - -... - -const response = await mixFetch('https://nymtech.net'); -const html = await response.text(); -``` diff --git a/sdk/typescript/packages/mix-fetch/README-full-fat.md b/sdk/typescript/packages/mix-fetch/README-full-fat.md deleted file mode 100644 index afe683d42f..0000000000 --- a/sdk/typescript/packages/mix-fetch/README-full-fat.md +++ /dev/null @@ -1,14 +0,0 @@ -# Nym MixFetch - -This package is a drop-in replacement for `fetch` to send HTTP requests over the Nym Mixnet. - -## Usage - -```js -import { mixFetch } from '@nymproject/mix-fetch'; - -... - -const response = await mixFetch('https://nymtech.net'); -const html = await response.text(); -``` diff --git a/sdk/typescript/packages/mix-fetch/README.md b/sdk/typescript/packages/mix-fetch/README.md index f2f7b92879..e9d573f436 100644 --- a/sdk/typescript/packages/mix-fetch/README.md +++ b/sdk/typescript/packages/mix-fetch/README.md @@ -1,17 +1,128 @@ -# Nym MixFetch +# @nymproject/mix-fetch -This package is a drop-in replacement for `fetch` to send HTTP requests over the Nym Mixnet. +Drop-in replacement for `fetch()` that routes HTTP/HTTPS through the Nym +mixnet. ## Usage -Use `mixFetch` in your own project with: +```ts +import { setupMixTunnel, mixFetch } from '@nymproject/mix-fetch'; -```js -import { mixFetch } from '@nymproject/mix-fetch'; +await setupMixTunnel(); -... - -const response = await mixFetch('https://nymtech.net'); -const html = await response.text(); +const res = await mixFetch('https://example.com/'); +const html = await res.text(); ``` +The `setupMixTunnel` call accepts the full `SetupMixTunnelOpts` surface: IPR +pinning, cover-traffic toggles, SURB budgets, DNS overrides, TCP/connect +timeouts, etc. See `@nymproject/mix-tunnel`'s typings for the complete list. + +### Convenience: setup + fetch in one call + +```ts +import { createMixFetch } from '@nymproject/mix-fetch'; + +const mixFetch = await createMixFetch({ preferredIpr: '...' }); +const res = await mixFetch('https://example.com/'); +``` + +### Shared tunnel + +Setting up the tunnel once unlocks all three smolmix SDKs simultaneously: + +```ts +import { setupMixTunnel, mixFetch } from '@nymproject/mix-fetch'; +import { mixDNS } from '@nymproject/mix-dns'; +import { MixWebSocket } from '@nymproject/mix-websocket'; + +await setupMixTunnel(); + +await mixFetch('https://example.com/'); +await mixDNS('example.com'); +const ws = new MixWebSocket('wss://echo.websocket.events'); +``` + +All three packages delegate to `@nymproject/mix-tunnel`, which owns the single +Web Worker hosting `@nymproject/smolmix-wasm`. + +## Default request headers + +`mixFetch` ships a small browser-shape header shim. If the caller doesn't set +these headers, smolmix-wasm fills them in before the request leaves the +tunnel. Caller-supplied values always win. + +| Header | Injected default | +|--------|------------------| +| `User-Agent` | `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36` | +| `Accept` | `text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8` | +| `Accept-Language` | `en-US,en;q=0.9` | +| `Accept-Encoding` | `identity` (the wasm build has no decompressor) | + +Rationale: many CDNs (cloudflare bot management) and host policies (wikimedia) +reject requests that lack browser-canonical headers. The shim is a floor: +it does not attempt TLS-fingerprint or HTTP/2 impersonation, just the +header-shaped tells. See the smolmix-wasm README "Browser-shape header +shim" section for the full story and the JA3 caveats. + +Override per-request like any other header: + +```ts +const res = await mixFetch('https://example.com', { + headers: { 'User-Agent': 'my-app/1.0' }, +}); +``` + +## Migrating from v1.x + +The legacy v1.x mix-fetch was a thin wrapper around a Go-based wasm network +stack. v2.x is a thin wrapper around the smolmix-wasm Rust stack. The API +surface is **not** identical; if your v1 code looks like the left column, +update it to look like the right: + +| v1.x | v2.x | +|---|---| +| `await createMixFetch({ preferredNetworkRequester, clientId, mixFetchOverride, responseBodyConfigMap })` | `await setupMixTunnel({ preferredIpr, clientId, connectTimeoutMs, ... })` | +| `mixFetch(url, args, opts)` (3-arg) | `mixFetch(url, args)` (2-arg) + `setupMixTunnel(opts)` separately | +| `args.mode = 'unsafe-ignore-cors'` | not needed; the IPR enforces its own egress policy, browser CORS doesn't apply | +| `disconnectMixFetch()` | `disconnectMixTunnel()` | + +Notable differences: + +- **Gateway routing**: v1's `preferredGateway` and `preferredNetworkRequester` + are gone. v2 uses smolmix's IPR auto-discovery by default; pin one with + `preferredIpr` if needed. +- **Response body handling**: v1's `responseBodyConfigMap` (used to opt + particular MIME types into specific body parsers) is gone. v2 returns a + real `Response` object; call `.text()`, `.arrayBuffer()`, `.json()`, + `.blob()` as usual. +- **Cover traffic**: v1's `clientOverride.coverTraffic` is now flat opts + (`disableCoverTraffic`, `disablePoissonTraffic`). +- **Bundle size**: v2 inlines the wasm + worker into a single ESM module. + No sibling assets to ship, at the cost of a large single chunk. Plan + code-splitting around it (dynamic `import('@nymproject/mix-fetch')` is + the usual move). +- **Runtime target**: v2 ships a single ESM bundle that runs in any environment + exposing `Worker`, `WebAssembly`, `Blob`, and `URL.createObjectURL`. That + covers modern browsers, Electron renderers, and mobile WebViews (Capacitor, + Cordova, Ionic, iOS WKWebView, Android WebView). The v1 + `@nymproject/mix-fetch-node` companion for Node is not yet ported to the + smolmix backend. + +See `@nymproject/mix-tunnel`'s `SetupMixTunnelOpts` for the full v2 options +surface. + +## Consumer build requirements + +Ships as raw ESM with a bare `import` of `@nymproject/mix-tunnel`. Use a +bundler that follows package imports (webpack, rollup, parcel, vite, +esbuild). + +Runs in any environment exposing `Worker`, `WebAssembly`, `Blob`, and +`URL.createObjectURL`. That covers modern browsers, Electron renderers, +and mobile WebViews (Capacitor, Cordova, Ionic, iOS WKWebView, Android +WebView). A Node-direct entry point is not yet ported from v1. + +The wasm payload lives inside `@nymproject/mix-tunnel`, so your bundler +will surface a single large chunk. Plan code-splitting around it +(dynamic `import('@nymproject/mix-fetch')` is the usual move). diff --git a/sdk/typescript/packages/mix-fetch/internal-dev/README.md b/sdk/typescript/packages/mix-fetch/internal-dev/README.md deleted file mode 100644 index 3ade7784ec..0000000000 --- a/sdk/typescript/packages/mix-fetch/internal-dev/README.md +++ /dev/null @@ -1,44 +0,0 @@ -# MixFetch Internal Tester - -This project is for use by Nym developers only. Use at your own risk! - -## Getting started - -From the root of this repository run: - -``` -pnpm i -make sdk-wasm-build -``` - -Then: - -``` -cd sdk/typescript/packages/mix-fetch -``` - -You can run in watch mode: - -``` -pnpm start -``` - -Or do a single build: - -``` -pnpm build:dev:esm-no-inline -``` - -Then, in another terminal: - -``` -cd sdk/typescript/packages/mix-fetch/internal-dev/parcel -pnpm i && pnpm start -``` - -If you have trouble with changes not propagating: - -``` -rm -rf node_modules && pnpm i && pnpm start -``` - diff --git a/sdk/typescript/packages/mix-fetch/internal-dev/parcel/package.json b/sdk/typescript/packages/mix-fetch/internal-dev/parcel/package.json deleted file mode 100644 index fcff0ce73e..0000000000 --- a/sdk/typescript/packages/mix-fetch/internal-dev/parcel/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "@nymproject/mix-fetch-tester-parcel", - "version": "1.0.6", - "license": "Apache-2.0", - "scripts": { - "build": "npx parcel build --no-cache --no-content-hash", - "serve": "npx serve dist", - "start": "npx parcel --no-cache" - }, - "dependencies": { - "@nymproject/mix-fetch": ">=1.4.2-rc.0 || ^1" - }, - "private": false, - "source": "../src/index.html" -} \ No newline at end of file diff --git a/sdk/typescript/packages/mix-fetch/internal-dev/src/index.html b/sdk/typescript/packages/mix-fetch/internal-dev/src/index.html deleted file mode 100644 index 7ed4ee38f4..0000000000 --- a/sdk/typescript/packages/mix-fetch/internal-dev/src/index.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - Internal Tester - - - - -

Internal tester

-

Open dev tools to see more output and errors

-

-
- - - diff --git a/sdk/typescript/packages/mix-fetch/internal-dev/src/index.ts b/sdk/typescript/packages/mix-fetch/internal-dev/src/index.ts deleted file mode 100644 index fb256688fa..0000000000 --- a/sdk/typescript/packages/mix-fetch/internal-dev/src/index.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { createMixFetch, disconnectMixFetch } from '@nymproject/mix-fetch'; - -function appendOutput(value: string) { - const el = document.getElementById('output') as HTMLPreElement; - const text = document.createTextNode(`${value}\n`); - el.appendChild(text); -} - -function appendImageOutput(url: string) { - const el = document.getElementById('outputImage') as HTMLPreElement; - const imgNode = document.createElement('img'); - imgNode.src = url; - el.appendChild(imgNode); -} - -/** - * The main entry point - */ -async function main() { - appendOutput('Tester is starting up...'); - - // const addr = - // 'EVdJ66jqpoVzmktVecy5UJxsTCEWo5gMn5zDZR7Hm8jy.GXNpoX7RcYcxKvBkV3dSHqC78WaPuWieweRPWzYqNhh5@GAjhJcrd6f1edaqUkfWCff6zdHoqo756qYrc2TfPuCXJ'; - // const addr = '7Y9eyF1p1JmzHnd7TVZufnQHkh93ASc9sRBCFY57ZGr8.F8KPyVMVqFQ5yJC3LqeP2ZC7fukzj9a1T426rjo432yT@q2A2cbooyC16YJzvdYaSMH9X3cSiieZNtfBr8cE8Fi1'; - const addr = undefined; - - appendOutput('About to set up mixFetch...'); - const { mixFetch } = await createMixFetch({ - preferredNetworkRequester: addr, - clientId: 'my-new-client-16', - clientOverride: { - coverTraffic: { disableLoopCoverTrafficStream: true }, - traffic: { disableMainPoissonPacketDistribution: true }, - }, - mixFetchOverride: { requestTimeoutMs: 60000 }, - responseBodyConfigMap: {}, - }); - (window as any).mixFetch = mixFetch; - - if (!(window as any).mixFetch) { - console.error('Oh no! Could not create mixFetch'); - appendOutput('Oh no! Could not create mixFetch'); - } else { - appendOutput('Ready!'); - } - - let url = 'https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt'; - appendOutput(`Using mixFetch to get ${url}...`); - const args = { mode: 'unsafe-ignore-cors' }; - - let resp = await mixFetch(url, args); - console.log({ resp }); - const text = await resp.text(); - - appendOutput(JSON.stringify(resp, null, 2)); - appendOutput(JSON.stringify({ text }, null, 2)); - - // console.log('disconnecting'); - // await disconnectMixFetch(); - // console.log('disconnected! all further usages should fail'); - - // get an image - url = 'https://matrix.org/assets/frontpage/github-mark.svg'; - resp = await mixFetch(url, args); - console.log({ resp }); - const buffer = await resp.arrayBuffer(); - const type = resp.headers.get('Content-Type') || 'image/svg'; - const blobUrl = URL.createObjectURL(new Blob([buffer], { type })); - appendOutput(JSON.stringify({ bufferBytes: buffer.byteLength, blobUrl }, null, 2)); - appendImageOutput(blobUrl); -} - -// wait for the html to load -window.addEventListener('DOMContentLoaded', () => { - // let's do this! - main(); -}); diff --git a/sdk/typescript/packages/mix-fetch/internal-dev/webpack.common.js b/sdk/typescript/packages/mix-fetch/internal-dev/webpack.common.js deleted file mode 100644 index ec41ca26ca..0000000000 --- a/sdk/typescript/packages/mix-fetch/internal-dev/webpack.common.js +++ /dev/null @@ -1,46 +0,0 @@ -const path = require('path'); -const { mergeWithRules } = require('webpack-merge'); -const CopyPlugin = require('copy-webpack-plugin'); -const { webpackCommon } = require('../../../examples/.webpack/webpack.base'); - -console.log('mix-fetch package path is: ', path.dirname(require.resolve('@nymproject/mix-fetch/package.json'))); - -module.exports = mergeWithRules({ - module: { - rules: { - test: 'match', - use: 'replace', - }, - }, -})( - webpackCommon(__dirname, [ - { - inject: true, - filename: 'index.html', - template: path.resolve(__dirname, 'src/index.html'), - chunks: ['index'], - }, - ]), - { - entry: { - index: path.resolve(__dirname, 'src/index.ts'), - }, - output: { - path: path.resolve(__dirname, 'dist'), - publicPath: '/', - }, - plugins: [ - new CopyPlugin({ - patterns: [ - { - // copy the WASM files, because webpack doesn't do this automatically even though there are - // `new URL(..., import.meta.url)` statements in the web worker -// from: path.resolve(path.dirname(require.resolve('@nymproject/mix-fetch/package.json')), 'dist/esm/*.wasm'), - from: path.resolve(path.dirname(require.resolve('@nymproject/mix-fetch/package.json')), '*.wasm'), - to: '[name][ext]', - }, - ], - }), - ], - }, -); diff --git a/sdk/typescript/packages/mix-fetch/jest.config.mjs b/sdk/typescript/packages/mix-fetch/jest.config.mjs deleted file mode 100644 index ed5b112c72..0000000000 --- a/sdk/typescript/packages/mix-fetch/jest.config.mjs +++ /dev/null @@ -1,15 +0,0 @@ -import preset from 'ts-jest/presets/index.js' - -/** @type {import('ts-jest').JestConfigWithTsJest} */ -export default { - ...preset.defaults, - transform: { - '^.+\\.(ts|tsx)$': [ - 'ts-jest', - { - tsconfig: 'tsconfig.jest.json', - useESM: true, - }, - ], - }, -} diff --git a/sdk/typescript/packages/mix-fetch/package.json b/sdk/typescript/packages/mix-fetch/package.json index 12235ba862..73592e0b3f 100644 --- a/sdk/typescript/packages/mix-fetch/package.json +++ b/sdk/typescript/packages/mix-fetch/package.json @@ -1,86 +1,52 @@ { "name": "@nymproject/mix-fetch", - "version": "1.4.3", - "description": "This package is a drop-in replacement for `fetch` to send HTTP requests over the Nym Mixnet.", + "version": "2.0.0", + "description": "Drop-in `fetch` replacement that routes HTTP/HTTPS requests through the Nym mixnet.", "license": "Apache-2.0", "author": "Nym Technologies SA", + "homepage": "https://nym.com", + "repository": { + "type": "git", + "url": "https://github.com/nymtech/nym", + "directory": "sdk/typescript/packages/mix-fetch" + }, + "bugs": { + "url": "https://github.com/nymtech/nym/issues" + }, + "keywords": ["nym", "mixnet", "privacy", "fetch", "http"], + "sideEffects": false, "files": [ - "dist/esm/worker.js", - "dist/cjs/worker.js", "dist/**/*" ], - "main": "dist/cjs/index.js", - "browser": "dist/esm/index.js", + "main": "dist/index.js", + "module": "dist/index.js", + "browser": "dist/index.js", "scripts": { - "build": "scripts/build-prod.sh", - "build:dev": "scripts/build.sh", - "build:dev:esm": "MIX_FETCH_DEV_MODE=true scripts/build-dev-esm.sh", - "build:dev:esm-no-inline": "scripts/build-dev-esm.sh", - "build:worker": "rollup -c rollup-worker.config.mjs", - "build:worker:full-fat": "rollup -c rollup-worker-full-fat.config.mjs", + "build": "tsc", "clean": "rimraf dist", - "docs:dev": "run-p docs:watch docs:serve ", "docs:generate": "typedoc", - "docs:generate:prod": "typedoc --basePath ./docs/tsdoc/nymproject/sdk/", - "docs:prod:build": "scripts/build-prod-docs-collect.sh", - "docs:serve": "reload -b -d ./docs -p 3000", - "docs:watch": "nodemon --ext ts --watch './src/**/*' --watch './typedoc.json' --exec \"pnpm docs:generate\"", + "docs:generate:prod": "typedoc --basePath ./docs/tsdoc/nymproject/mix-fetch/", "lint": "eslint src", "lint:fix": "eslint src --fix", - "prebuild": "node scripts/showDependencyLocation.cjs", "start": "tsc -w", - "start:dev": "nodemon --watch src -e ts,json --exec 'pnpm build:dev:esm'", - "test": "node --experimental-vm-modules --no-warnings node_modules/jest/bin/jest.js -c=jest.config.mjs --no-cache", "tsc": "tsc --noEmit true" }, "dependencies": { - "@nymproject/mix-fetch-wasm": ">=1.4.2-rc.0 || ^1", - "comlink": "^4.3.1" + "@nymproject/mix-tunnel": "workspace:*" }, "devDependencies": { - "@babel/core": "catalog:", - "@babel/plugin-transform-async-to-generator": "catalog:", - "@babel/preset-env": "catalog:", - "@babel/preset-react": "catalog:", - "@babel/preset-typescript": "catalog:", "@nymproject/eslint-config-react-typescript": "workspace:*", - "@rollup/plugin-commonjs": "^24.0.1", - "@rollup/plugin-inject": "^5.0.3", - "@rollup/plugin-json": "^6.0.0", - "@rollup/plugin-node-resolve": "^15.0.1", - "@rollup/plugin-replace": "^5.0.2", - "@rollup/plugin-terser": "^0.2.1", - "@rollup/plugin-typescript": "^10.0.1", - "@rollup/plugin-wasm": "^6.1.1", - "@types/jest": "^27.0.1", - "@types/node": "^16.7.13", "@typescript-eslint/eslint-plugin": "catalog:", "@typescript-eslint/parser": "catalog:", "eslint": "^8.10.0", - "eslint-config-airbnb": "catalog:", - "eslint-config-airbnb-typescript": "catalog:", - "eslint-config-prettier": "catalog:", - "eslint-import-resolver-root-import": "catalog:", - "eslint-plugin-import": "catalog:", - "eslint-plugin-jest": "catalog:", - "eslint-plugin-jsx-a11y": "catalog:", - "eslint-plugin-prettier": "catalog:", - "eslint-plugin-react": "catalog:", - "eslint-plugin-react-hooks": "catalog:", - "jest": "^29.5.0", - "nodemon": "^2.0.21", - "reload": "^3.2.1", "rimraf": "catalog:", - "rollup": "^3.9.1", - "rollup-plugin-base64": "^1.0.1", - "rollup-plugin-web-worker-loader": "^1.6.1", - "ts-jest": "^29.1.0", - "ts-loader": "catalog:", "tslib": "catalog:", - "typedoc": "^0.24.8", "typescript": "^4.8.4" }, "private": false, "type": "module", - "types": "./dist/esm/index.d.ts" + "types": "./dist/index.d.ts", + "publishConfig": { + "access": "public" + } } diff --git a/sdk/typescript/packages/mix-fetch/rollup-cjs-full-fat.config.mjs b/sdk/typescript/packages/mix-fetch/rollup-cjs-full-fat.config.mjs deleted file mode 100644 index d4c6e39e99..0000000000 --- a/sdk/typescript/packages/mix-fetch/rollup-cjs-full-fat.config.mjs +++ /dev/null @@ -1,8 +0,0 @@ -import { getConfig } from './rollup/cjs.mjs'; - -export default { - ...getConfig({ - inline: true, - outputDir: 'dist/cjs-full-fat', - }), -}; diff --git a/sdk/typescript/packages/mix-fetch/rollup-cjs.config.mjs b/sdk/typescript/packages/mix-fetch/rollup-cjs.config.mjs deleted file mode 100644 index a12e5bdb7a..0000000000 --- a/sdk/typescript/packages/mix-fetch/rollup-cjs.config.mjs +++ /dev/null @@ -1,5 +0,0 @@ -import { getConfig } from './rollup/cjs.mjs'; - -export default { - ...getConfig({ inline: false }), -}; diff --git a/sdk/typescript/packages/mix-fetch/rollup-esm-full-fat.config.mjs b/sdk/typescript/packages/mix-fetch/rollup-esm-full-fat.config.mjs deleted file mode 100644 index ea80b1997b..0000000000 --- a/sdk/typescript/packages/mix-fetch/rollup-esm-full-fat.config.mjs +++ /dev/null @@ -1,8 +0,0 @@ -import { getConfig } from './rollup/esm.mjs'; - -export default { - ...getConfig({ - inline: true, - outputDir: 'dist/esm-full-fat', - }), -}; diff --git a/sdk/typescript/packages/mix-fetch/rollup-esm.config.mjs b/sdk/typescript/packages/mix-fetch/rollup-esm.config.mjs deleted file mode 100644 index fe7b0082bb..0000000000 --- a/sdk/typescript/packages/mix-fetch/rollup-esm.config.mjs +++ /dev/null @@ -1,8 +0,0 @@ -import { getConfig } from './rollup/esm.mjs'; - -export default { - ...getConfig({ - // by default, the web worker will not be inlined, in local development mode it will be - inline: process.env.MIX_FETCH_DEV_MODE === 'true', - }), -}; diff --git a/sdk/typescript/packages/mix-fetch/rollup-worker-full-fat.config.mjs b/sdk/typescript/packages/mix-fetch/rollup-worker-full-fat.config.mjs deleted file mode 100644 index 1c56e076e8..0000000000 --- a/sdk/typescript/packages/mix-fetch/rollup-worker-full-fat.config.mjs +++ /dev/null @@ -1,8 +0,0 @@ -import { getConfig } from './rollup/worker.mjs'; - -export default { - ...getConfig({ - inlineWasm: true, - format: 'cjs', - }), -}; diff --git a/sdk/typescript/packages/mix-fetch/rollup/cjs.mjs b/sdk/typescript/packages/mix-fetch/rollup/cjs.mjs deleted file mode 100644 index 4f76b89648..0000000000 --- a/sdk/typescript/packages/mix-fetch/rollup/cjs.mjs +++ /dev/null @@ -1,30 +0,0 @@ -import typescript from '@rollup/plugin-typescript'; -import resolve from '@rollup/plugin-node-resolve'; -import { wasm } from '@rollup/plugin-wasm'; -import webWorkerLoader from 'rollup-plugin-web-worker-loader'; - -const extensions = ['.js', '.jsx', '.ts', '.tsx']; - -/** - * Gets the config for bundling the package as a CommonJS module. - * - * @param opts Options: - * `{ inline: boolean }` - set inline to true to inline the web worker in the main bundle - * `{ outputDir: string }` - override the destination - */ -export const getConfig = (opts) => ({ - input: 'src/index.ts', - output: { - dir: opts.outputDir || 'dist/cjs', - format: 'cjs', - }, - plugins: [ - webWorkerLoader({ targetPlatform: 'browser', inline: opts.inline }), // the inline param is used here - resolve({ extensions }), - wasm({ maxFileSize: 10000000, targetEnv: 'browser' }), - typescript({ - compilerOptions: { outDir: opts.outputDir || 'dist/cjs', target: 'es5' }, - exclude: ['worker/*'], - }), - ], -}); diff --git a/sdk/typescript/packages/mix-fetch/rollup/esm.mjs b/sdk/typescript/packages/mix-fetch/rollup/esm.mjs deleted file mode 100644 index ebb886839b..0000000000 --- a/sdk/typescript/packages/mix-fetch/rollup/esm.mjs +++ /dev/null @@ -1,45 +0,0 @@ -import typescript from '@rollup/plugin-typescript'; -import resolve from '@rollup/plugin-node-resolve'; -import webWorkerLoader from 'rollup-plugin-web-worker-loader'; -import replace from '@rollup/plugin-replace'; - -const extensions = ['.js', '.jsx', '.ts', '.tsx']; - -/** - * Gets the config for bundling the package as an ES Module. - * - * @param opts Options: - * `{ inline: boolean }` - set inline to true to inline the web worker in the main bundle - * `{ outputDir: string }` - override the destination * - */ -export const getConfig = (opts) => ({ - input: 'src/index.ts', - output: { - dir: opts.outputDir || 'dist/esm', - format: 'es', - }, - plugins: [ - webWorkerLoader({ targetPlatform: 'browser', inline: opts.inline }), // the inline param is used here - replace({ - // when loading the web worker as a full ES module, tell pass `new Worker({ type: 'module'})` to tell - // the browser to load and allow imports inside the worker code. Also load as a URL so relative paths work. - // values: opts.inline - // ? undefined - // : { - // "createURLWorkerFactory('web-worker-0.js')": - // "createURLWorkerFactory(new URL('web-worker-0.js', import.meta.url))", - // }, - values: { - "createURLWorkerFactory('web-worker-0.js')": - "createURLWorkerFactory(new URL('web-worker-0.js', import.meta.url))", - }, - delimiters: ['', ''], - preventAssignment: true, - }), - resolve({ extensions }), - typescript({ - exclude: ['worker/*'], - compilerOptions: { outDir: opts.outputDir || 'dist/esm' }, - }), - ], -}); diff --git a/sdk/typescript/packages/mix-fetch/rollup/worker.mjs b/sdk/typescript/packages/mix-fetch/rollup/worker.mjs deleted file mode 100644 index 82c7761417..0000000000 --- a/sdk/typescript/packages/mix-fetch/rollup/worker.mjs +++ /dev/null @@ -1,43 +0,0 @@ -import typescript from '@rollup/plugin-typescript'; -import resolve from '@rollup/plugin-node-resolve'; -import { wasm } from '@rollup/plugin-wasm'; -import replace from '@rollup/plugin-replace'; - -const extensions = ['.js', '.jsx', '.ts', '.tsx']; - -/** - * Configure worker output - * - * @param opts - * `format`: `es` or `cjs`, - * `inlineWasm`: true or false, - * `tsTarget`: `es5` or `es6` - */ -export const getConfig = (opts) => ({ - input: 'src/worker/index.ts', - output: { - dir: 'dist', - format: opts?.format || 'es', - }, - plugins: [ - resolve({ extensions }), - // this is some nasty monkey patching that removes the WASM URL (because it is handled by the `wasm` plugin) - replace({ - values: { "input = new URL('mix_fetch_wasm_bg.wasm', import.meta.url);": 'input = undefined;' }, - delimiters: ['', ''], - preventAssignment: true, - }), - opts?.inlineWasm === true - ? wasm({ maxFileSize: 10_000_000, targetEnv: 'browser' }) // force the wasm plugin to embed the wasm bundle - this means no downstream bundlers have to worry about handling it - : wasm({ - targetEnv: 'browser', - fileName: '[name].wasm', - }), - typescript({ - compilerOptions: { - declaration: false, - target: opts?.tsTarget || 'es6', - }, - }), - ], -}); diff --git a/sdk/typescript/packages/mix-fetch/scripts/build-dev-esm.sh b/sdk/typescript/packages/mix-fetch/scripts/build-dev-esm.sh deleted file mode 100755 index 60ffc7e90f..0000000000 --- a/sdk/typescript/packages/mix-fetch/scripts/build-dev-esm.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -#------------------------------------------------------- -# WEB WORKER (mix-fetch WASM) -#------------------------------------------------------- -# The web worker needs to be bundled because the WASM bundle needs to be loaded synchronously and all dependencies -# must be included in the worker script (because it is not loaded as an ES Module) - -# build the worker -rollup -c rollup-worker.config.mjs - -# move it next to the Typescript `src/index.ts` so it can be inlined by rollup -rm -f src/worker/*.js -rm -f src/worker/*.wasm -mv dist/index.js src/worker/worker.js - -# move WASM files out of build area -mkdir -p dist/worker -mv dist/*.wasm dist/worker - -#------------------------------------------------------- -# ESM -#------------------------------------------------------- - -# build the SDK as a ESM bundle -rollup -c rollup-esm.config.mjs - -# move WASM files into place -cp dist/worker/*.wasm dist/esm -node scripts/postBuildReplace.mjs dist - -#------------------------------------------------------- -# CLEAN UP -#------------------------------------------------------- - -# remove typings that aren't needed -rm -rf dist/esm/worker - -# clear staging area -rm -rf dist/worker - - diff --git a/sdk/typescript/packages/mix-fetch/scripts/build-prod-docs-collect.sh b/sdk/typescript/packages/mix-fetch/scripts/build-prod-docs-collect.sh deleted file mode 100755 index ce75d65fff..0000000000 --- a/sdk/typescript/packages/mix-fetch/scripts/build-prod-docs-collect.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -rm -rf ../../../../dist/ts/docs/tsdoc/nymproject/mix-fetch || true - -# run the build -pnpm docs:generate:prod - -# move the output outside of the yarn/npm workspaces -mkdir -p ../../../../dist/ts/docs/tsdoc/nymproject -mv docs ../../../../dist/ts/docs/tsdoc/nymproject/mix-fetch - -echo "Output can be found in:" -realpath ../../../../dist/ts/docs/tsdoc/nymproject/mix-fetch diff --git a/sdk/typescript/packages/mix-fetch/scripts/build-prod.sh b/sdk/typescript/packages/mix-fetch/scripts/build-prod.sh deleted file mode 100755 index b56d1e0472..0000000000 --- a/sdk/typescript/packages/mix-fetch/scripts/build-prod.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -rm -rf dist || true -rm -rf ../../../../dist/ts/sdk/mix-fetch || true - -# run the build -scripts/build.sh -node scripts/buildPackageJson.mjs - -# move the output outside of the yarn/npm workspaces -mkdir -p ../../../../dist/ts/sdk -mv dist ../../../../dist/ts/sdk -mv ../../../../dist/ts/sdk/dist ../../../../dist/ts/sdk/mix-fetch - -echo "Output can be found in:" -realpath ../../../../dist/ts/sdk/mix-fetch diff --git a/sdk/typescript/packages/mix-fetch/scripts/build.sh b/sdk/typescript/packages/mix-fetch/scripts/build.sh deleted file mode 100755 index ab9bd0aec8..0000000000 --- a/sdk/typescript/packages/mix-fetch/scripts/build.sh +++ /dev/null @@ -1,96 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -rm -rf dist || true - -#------------------------------------------------------- -# WEB WORKER (mix-fetch WASM) -#------------------------------------------------------- -# The web worker needs to be bundled because the WASM bundle needs to be loaded synchronously and all dependencies -# must be included in the worker script (because it is not loaded as an ES Module) - -# build the worker -rollup -c rollup-worker.config.mjs - -# move it next to the Typescript `src/index.ts` so it can be inlined by rollup -rm -f src/worker/*.js -rm -f src/worker/*.wasm -mv dist/index.js src/worker/worker.js - -# move WASM files out of build area -mkdir -p dist/worker -mv dist/*.wasm dist/worker - -#------------------------------------------------------- -# ESM -#------------------------------------------------------- - -# build the SDK as a ESM bundle -rollup -c rollup-esm.config.mjs - -# move WASM files into place -cp dist/worker/*.wasm dist/esm - -#------------------------------------------------------- -# COMMON JS -#------------------------------------------------------- -# Some old build systems cannot fully handle ESM or ES2021, so build -# a CommonJS bundle targeting ES5 - -# build the SDK as a CommonJS bundle -rollup -c rollup-cjs.config.mjs - -# move WASM files into place -cp dist/worker/*.wasm dist/cjs -node scripts/postBuildReplace.mjs dist - -#------------------------------------------------------- -# WEB WORKER (full-fat) -#------------------------------------------------------- - -# build the worker -rollup -c rollup-worker-full-fat.config.mjs - -# move it next to the Typescript `src/index.ts` so it can be inlined by rollup -rm -f src/worker/*.js -rm -f src/worker/*.wasm -mv dist/index.js src/worker/worker.js - -# move WASM files out of build area -mkdir -p dist/worker - -#------------------------------------------------------- -# ESM (full-fat) -#------------------------------------------------------- - -# build the SDK as a ESM bundle (with worker inlined as a blob) -rollup -c rollup-esm-full-fat.config.mjs - -#------------------------------------------------------- -# COMMON JS (full-fat) -#------------------------------------------------------- -# Some old build systems cannot fully handle ESM or ES2021, so build -# a CommonJS bundle targeting ES5 - -# build the SDK as a CommonJS bundle (with worker inlined as a blob) -rollup -c rollup-cjs-full-fat.config.mjs - -#------------------------------------------------------- -# CLEAN UP -#------------------------------------------------------- - -rm -rf dist/cjs/worker -rm -rf dist/esm/worker -rm -rf dist/cjs-full-fat/worker -rm -rf dist/esm-full-fat/worker - -# copy README -cp README.md dist/esm -cp README-CommonJS.md dist/cjs/README.md -cp README-CommonJS-full-fat.md dist/cjs-full-fat/README.md -cp README-full-fat.md dist/esm-full-fat/README.md - - diff --git a/sdk/typescript/packages/mix-fetch/scripts/buildPackageJson.mjs b/sdk/typescript/packages/mix-fetch/scripts/buildPackageJson.mjs deleted file mode 100644 index 3fc5a7b5b2..0000000000 --- a/sdk/typescript/packages/mix-fetch/scripts/buildPackageJson.mjs +++ /dev/null @@ -1,29 +0,0 @@ -import * as fs from 'fs'; - -// parse the package.json from the SDK, so we can keep fields like the name and version -const json = JSON.parse(fs.readFileSync('package.json').toString()); - -// defaults (NB: these are in the output file locations) -const browser = 'index.js'; -const main = 'index.js'; -const types = 'index.d.ts'; - -const getPackageJson = (type, suffix) => ({ - name: `${json.name}${suffix ? `-${suffix}` : ''}`, - version: json.version, - license: json.license, - author: json.author, - type, - browser, - main, - types, -}); - -fs.writeFileSync('dist/cjs/package.json', JSON.stringify(getPackageJson('commonjs', 'commonjs'), null, 2)); -fs.writeFileSync('dist/esm/package.json', JSON.stringify(getPackageJson('module'), null, 2)); - -fs.writeFileSync( - 'dist/cjs-full-fat/package.json', - JSON.stringify(getPackageJson('commonjs', 'commonjs-full-fat'), null, 2), -); -fs.writeFileSync('dist/esm-full-fat/package.json', JSON.stringify(getPackageJson('module', 'full-fat'), null, 2)); diff --git a/sdk/typescript/packages/mix-fetch/scripts/postBuildReplace.mjs b/sdk/typescript/packages/mix-fetch/scripts/postBuildReplace.mjs deleted file mode 100644 index 39d6546b9f..0000000000 --- a/sdk/typescript/packages/mix-fetch/scripts/postBuildReplace.mjs +++ /dev/null @@ -1,45 +0,0 @@ -import fs from 'fs'; -import path from 'path'; - -// first level is a list of file names to process, then for each copying the @rollup/replace plugin syntax here: -// key is what to search for, value is what to replace it with -const replaceConfig = { - 'esm/web-worker-0.js': { - // add `import.meta.url` to make WASM file relative to the worker JS file - "_loadWasmModule(0, 'mix_fetch_wasm_bg.wasm',": - "_loadWasmModule(0, new URL('mix_fetch_wasm_bg.wasm', import.meta.url),", - "_loadWasmModule(0, 'go_conn.wasm',": "_loadWasmModule(0, new URL('go_conn.wasm', import.meta.url),", - }, - 'esm/index.js': { - // tell the browser the worker is a module, so it should provide `import.meta.url` needed above - 'const worker = new WorkerFactory();': "const worker = new WorkerFactory({ type: 'module' });", - }, -}; - -const basePathToFindFilesIn = process.argv[2]; - -console.log(`Replacing files in "${path.resolve(basePathToFindFilesIn)}"...`); - -Object.keys(replaceConfig).forEach((filename) => { - const absFilename = path.resolve(basePathToFindFilesIn, filename); - - if (!fs.existsSync(absFilename)) { - console.log(`Skipping replacing ${filename} as does not exist`); - return; - } - - const content = fs.readFileSync(absFilename).toString(); - - console.log(`Replacing values in "${absFilename}"...`); - - const replacementMap = replaceConfig[filename]; - - let newContent = content; - Object.keys(replacementMap).forEach((toFind) => { - const toReplace = replacementMap[toFind]; - newContent = newContent.replaceAll(toFind, toReplace); - fs.writeFileSync(absFilename, newContent); - }); - - console.log('Done'); -}); diff --git a/sdk/typescript/packages/mix-fetch/scripts/publish.sh b/sdk/typescript/packages/mix-fetch/scripts/publish.sh deleted file mode 100755 index 94aa4f689b..0000000000 --- a/sdk/typescript/packages/mix-fetch/scripts/publish.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash - -set -o errexit -set -o nounset -set -o pipefail - -rm -rf dist || true -rm -rf ../../../../dist || true - -yarn -yarn build -cd ../../../../dist/sdk - -cd cjs -echo "Publishing CommonJS package to NPM.." -npm publish --access=public -cd .. - -cd esm -echo "Publishing ESM package to NPM.." -npm publish --access=public -cd .. diff --git a/sdk/typescript/packages/mix-fetch/scripts/showDependencyLocation.cjs b/sdk/typescript/packages/mix-fetch/scripts/showDependencyLocation.cjs deleted file mode 100644 index 2843f899e2..0000000000 --- a/sdk/typescript/packages/mix-fetch/scripts/showDependencyLocation.cjs +++ /dev/null @@ -1,8 +0,0 @@ -const fs = require('fs'); - -const packageName = '@nymproject/mix-fetch-wasm'; -const packageJsonPath = require.resolve(packageName + '/package.json'); - -const packageJson = JSON.parse(fs.readFileSync(packageJsonPath).toString()); - -console.log(`🟢🟢🟢 ${packageName} is at ${packageJsonPath} is version ${packageJson.version}`); diff --git a/sdk/typescript/packages/mix-fetch/src/create-mix-fetch.ts b/sdk/typescript/packages/mix-fetch/src/create-mix-fetch.ts deleted file mode 100644 index 9739042932..0000000000 --- a/sdk/typescript/packages/mix-fetch/src/create-mix-fetch.ts +++ /dev/null @@ -1,77 +0,0 @@ -import InlineWasmWebWorker from 'web-worker:./worker/worker'; -import * as Comlink from 'comlink'; -import type { IMixFetchWebWorker } from './types'; -import { EventKinds, IMixFetch } from './types'; - -const createWorker = async () => - new Promise((resolve, reject) => { - // rollup will inline the built worker script, so that when the SDK is used in - // other projects, they will not need to mess around trying to bundle it - // however, it will make this SDK bundle bigger because of Base64 inline data - const worker = new InlineWasmWebWorker(); - - worker.addEventListener('error', reject); - worker.addEventListener( - 'message', - (msg) => { - worker.removeEventListener('error', reject); - if (msg.data?.kind === EventKinds.Loaded) { - resolve(worker); - } else { - reject(msg); - } - }, - { once: true }, - ); - }); - -const convertHeaders = (headers: any): Headers => { - const out = new Headers(); - Object.keys(headers).forEach((key) => { - out.append(key, headers[key]); - }); - return out; -}; - -/** - * Use this method to initialise `mixFetch`. - * - * @returns An instance of `mixFetch` that you can use to make your requests using the same interface as `fetch`. - */ -export const createMixFetch = async (): Promise => { - // start the worker - const worker = await createWorker(); - - // bind with Comlink - const wrappedWorker = Comlink.wrap(worker); - - // handle the responses - const mixFetchWebWorker: IMixFetch = { - setupMixFetch: wrappedWorker.setupMixFetch, - mixFetch: async (url: string, args: any) => { - const workerResponse = await wrappedWorker.mixFetch(url, args); - if (!workerResponse) { - throw new Error('No response received'); - } - console.log({ workerResponse }); - const { headers: headersRaw, status, statusText } = workerResponse; - - // reconstruct the Headers object instance from a plain object - const headers = convertHeaders(headersRaw); - - // handle blobs - if (workerResponse.body.blobUrl) { - const blob = await (await fetch(workerResponse.body.blobUrl)).blob(); - const body = await blob.arrayBuffer(); - return new Response(body, { headers, status, statusText }); - } - - // handle everything else - const body = Object.values(workerResponse.body)[0]; // we are expecting only one value to be set in `.body` - return new Response(body, { headers, status, statusText }); - }, - disconnectMixFetch: wrappedWorker.disconnectMixFetch, - }; - - return mixFetchWebWorker; -}; diff --git a/sdk/typescript/packages/mix-fetch/src/index.ts b/sdk/typescript/packages/mix-fetch/src/index.ts index 9b60a5977e..c54955f4b5 100644 --- a/sdk/typescript/packages/mix-fetch/src/index.ts +++ b/sdk/typescript/packages/mix-fetch/src/index.ts @@ -1,79 +1,65 @@ -/* eslint-disable no-underscore-dangle */ -import type { SetupMixFetchOps, IMixFetchFn, IMixFetch } from './types'; -import { createMixFetch as createMixFetchInternal } from './create-mix-fetch'; +// @nymproject/mix-fetch +// +// Drop-in `fetch()` replacement that routes HTTP/HTTPS through the Nym mixnet. +// Shares a single mixnet tunnel with @nymproject/mix-dns and +// @nymproject/mix-websocket via @nymproject/mix-tunnel. +// +// v2 surface (clean, no legacy shim): +// +// import { setupMixTunnel, mixFetch, disconnectMixTunnel } from '@nymproject/mix-fetch'; +// await setupMixTunnel({ preferredIpr, disableCoverTraffic, ... }); +// const res = await mixFetch('https://example.com'); +// await disconnectMixTunnel(); +// +// Or, for the "setup + fetch" convenience: +// +// const mixFetch = await createMixFetch({ ...opts }); +// const res = await mixFetch('https://example.com'); +// +// See `SetupMixTunnelOpts` (re-exported from @nymproject/mix-tunnel) for the +// full options surface — mirrors smolmix-wasm's SetupOpts. -// this is the default timeout for getting a response -const REQUEST_TIMEOUT_MILLISECONDS = 60_000; +import { + getMixTunnel, + setupMixTunnel, + disconnectMixTunnel, + getTunnelState, + SetupMixTunnelOpts, +} from '@nymproject/mix-tunnel'; -export * from './types'; - -declare global { - interface Window { - /** - * Keep a singleton of the mixFetch interface on the `window` object. - */ - __mixFetchGlobal?: IMixFetch; - } -} +export { setupMixTunnel, disconnectMixTunnel, getTunnelState }; +export type { SetupMixTunnelOpts }; /** - * Create a global mixFetch instance and optionally configure settings. + * Fetch over the mixnet. Drop-in replacement for the browser `fetch()`. * - * @param opts Optional settings + * Requires the tunnel to be up — call `setupMixTunnel(opts)` first, or use + * `createMixFetch(opts)` to combine setup + fetch. */ -export const createMixFetch = async (opts?: SetupMixFetchOps) => { - if (!window) { - throw new Error('`window` is not defined'); - } +export const mixFetch = async (url: string, init?: RequestInit): Promise => { + const tunnel = await getMixTunnel(); + // The wasm-side returns a `{body: Uint8Array, status, statusText, + // headers: [[k,v]...]}` object (see smolmix `serialise_response`). + // The `Headers` constructor accepts the [[k,v]] pair shape directly so + // repeated names like `Set-Cookie` survive. + const raw = await tunnel.mixFetch(url, init ?? {}); - if (!window.__mixFetchGlobal) { - // load the worker and set up mixFetch with defaults - window.__mixFetchGlobal = await createMixFetchInternal(); - await window.__mixFetchGlobal.setupMixFetch(opts); - - window.onunload = async () => { - if (window.__mixFetchGlobal) { - await window.__mixFetchGlobal.disconnectMixFetch(); - } - }; - } - return window.__mixFetchGlobal; -}; - -/** - * mixFetch is a drop-in replacement for the standard `fetch` interface. - * - * @param url The URL to fetch from. - * @param args Fetch options. - * @param opts Optionally configure mixFetch when it gets created. This only happens once, the first time it gets used. - */ -export const mixFetch: IMixFetchFn = async (url, args, opts?: SetupMixFetchOps) => { - // ensure mixFetch instance exists - const instance = await createMixFetch({ - mixFetchOverride: { - requestTimeoutMs: REQUEST_TIMEOUT_MILLISECONDS, - }, - ...opts, + // `raw.body` is `Uint8Array` — the ArrayBufferLike side + // includes SharedArrayBuffer, which the Response constructor's BodyInit + // doesn't accept. The runtime value is always a non-shared array; cast. + return new Response(raw.body as BodyInit, { + status: raw.status, + statusText: raw.statusText, + headers: new Headers(raw.headers), }); - - // execute user request - return instance.mixFetch(url, args); }; /** - * Stops the usage of mixFetch and disconnect the client from the mixnet. + * Convenience: set up the tunnel and return a fetch-bound function. Equivalent + * to `await setupMixTunnel(opts); return mixFetch;`. Safe to call multiple + * times — the underlying tunnel is a singleton. */ -export const disconnectMixFetch = async (): Promise => { - if (!window) { - throw new Error('`window` is not defined'); - } - - // JS: I'm ignoring this lint (no-else-return) because I want to explicitly state - // that `__mixFetchGlobal` is definitely not null in the else branch. - if (!window.__mixFetchGlobal) { - throw new Error("mixFetch hasn't been setup"); - // eslint-disable-next-line no-else-return - } else { - return window.__mixFetchGlobal.disconnectMixFetch(); - } +export const createMixFetch = async (opts?: SetupMixTunnelOpts): Promise => { + await setupMixTunnel(opts); + return mixFetch; }; diff --git a/sdk/typescript/packages/mix-fetch/src/types.ts b/sdk/typescript/packages/mix-fetch/src/types.ts deleted file mode 100644 index 553c02cc09..0000000000 --- a/sdk/typescript/packages/mix-fetch/src/types.ts +++ /dev/null @@ -1,98 +0,0 @@ -import type { MixFetchOpts } from '@nymproject/mix-fetch-wasm'; - -type IMixFetchWorkerFn = (url: string, args: any) => Promise; - -// export type IMixFetchFn = typeof fetch; -export type IMixFetchFn = (url: string, args: any, opts?: SetupMixFetchOps) => Promise; - -export type SetupMixFetchOps = MixFetchOpts & { - responseBodyConfigMap?: ResponseBodyConfigMap; -}; - -export interface IMixFetchWebWorker { - mixFetch: IMixFetchWorkerFn; - setupMixFetch: (opts?: SetupMixFetchOps) => Promise; - disconnectMixFetch: () => Promise; -} - -export interface IMixFetch { - mixFetch: IMixFetchFn; - setupMixFetch: (opts?: SetupMixFetchOps) => Promise; - disconnectMixFetch: () => Promise; -} - -export enum EventKinds { - Loaded = 'Loaded', -} - -export interface LoadedEvent { - kind: EventKinds.Loaded; - args: { - loaded: true; - }; -} - -export interface ResponseBody { - uint8array?: Uint8Array; - json?: any; - text?: string; - formData?: any; - blobUrl?: string; -} - -export type ResponseBodyMethod = 'uint8array' | 'json' | 'text' | 'formData' | 'blob'; - -export interface ResponseBodyConfigMap { - /** - * Set the response `Content-Type`s to decode as uint8array. - */ - uint8array?: Array; - - /** - * Set the response `Content-Type`s to decode with the `json()` response body method. - */ - json?: Array; - - /** - * Set the response `Content-Type`s to decode with the `text()` response body method. - */ - text?: Array; - - /** - * Set the response `Content-Type`s to decode with the `formData()` response body method. - */ - formData?: Array; - - /** - * Set the response `Content-Type`s to decode with the `blob()` response body method. - */ - blob?: Array; - /** - * Set this to the default fallback method. Set to `undefined` if you want to ignore unknown types. - */ - - fallback?: ResponseBodyMethod; -} - -/** - * Default values for the handling of response bodies. - */ -export const ResponseBodyConfigMapDefaults: ResponseBodyConfigMap = { - uint8array: ['application/octet-stream'], - json: ['application/json', 'text/json', /application\/json.*/, /text\/json\+.*/], - text: ['text/plain', /text\/plain.*/, 'text/html', /text\/html.*/], - formData: ['application/x-www-form-urlencoded', 'multipart/form-data'], - blob: [/image\/.*/, /video\/.*/], - fallback: 'blob', -}; - -export interface MixFetchWebWorkerResponse { - body: ResponseBody; - url: string; - headers: any; - status: number; - statusText: string; - type: string; - ok: boolean; - redirected: boolean; -} diff --git a/sdk/typescript/packages/mix-fetch/src/worker/handle-response-mime-types.test.ts b/sdk/typescript/packages/mix-fetch/src/worker/handle-response-mime-types.test.ts deleted file mode 100644 index eb29ae5bba..0000000000 --- a/sdk/typescript/packages/mix-fetch/src/worker/handle-response-mime-types.test.ts +++ /dev/null @@ -1,73 +0,0 @@ -import { handleResponseMimeTypes } from './handle-response-mime-types'; - -describe('handleResponseMimeTypes', () => { - test('gracefully handles empty values', async () => { - const resp = await handleResponseMimeTypes(new Response()); - expect(Object.values(resp)).toHaveLength(0); - }); - - test('handles text', async () => { - const TEXT = 'This is text'; - const resp = await handleResponseMimeTypes( - new Response(TEXT, { headers: new Headers([['Content-Type', 'text/plain']]) }), - ); - expect(resp.text).toBe(TEXT); - }); - test('handles text (charset=utf-8)', async () => { - const TEXT = 'This is text'; - const resp = await handleResponseMimeTypes( - new Response(TEXT, { headers: new Headers([['Content-Type', 'text/plain; charset=utf-8']]) }), - ); - expect(resp.text).toBe(TEXT); - }); - test('handles html', async () => { - const TEXT = 'This is html'; - const resp = await handleResponseMimeTypes( - new Response(TEXT, { headers: new Headers([['Content-Type', 'text/html']]) }), - ); - expect(resp.text).toBe(TEXT); - }); - test('handles html (charset=utf-8)', async () => { - const TEXT = 'This is html'; - const resp = await handleResponseMimeTypes( - new Response(TEXT, { headers: new Headers([['Content-Type', 'text/html; charset=utf-8']]) }), - ); - expect(resp.text).toBe(TEXT); - }); - test('handles images', async () => { - const DATA = new Uint8Array([0, 1, 2, 3]).buffer; - const resp = await handleResponseMimeTypes( - new Response(DATA, { headers: new Headers([['Content-Type', 'image/jpeg']]) }), - ); - expect(resp.blobUrl).toBeDefined(); - }); - test('handles videos', async () => { - const DATA = new Uint8Array([0, 1, 2, 3]).buffer; - const resp = await handleResponseMimeTypes( - new Response(DATA, { headers: new Headers([['Content-Type', 'video/mpeg4']]) }), - ); - expect(resp.blobUrl).toBeDefined(); - }); - test('handles form data when URL encoded', async () => { - const formData = 'foo=bar&baz=42'; - const resp = await handleResponseMimeTypes( - new Response(formData, { headers: new Headers([['Content-Type', 'application/x-www-form-urlencoded']]) }), - ); - expect(resp.formData.foo).toBe('bar'); - expect(resp.formData.baz).toBe('42'); - }); - test('handles JSON data', async () => { - const json = '{ "foo": "bar", "baz": 42 }'; - const resp = await handleResponseMimeTypes( - new Response(json, { headers: new Headers([['Content-Type', 'application/json']]) }), - ); - expect(resp.text).toBe(json); - }); - test('handles JSON data (charset=utf-8)', async () => { - const json = '{ "foo": "bar", "baz": 42 }'; - const resp = await handleResponseMimeTypes( - new Response(json, { headers: new Headers([['Content-Type', 'application/json; charset=utf-8']]) }), - ); - expect(resp.text).toBe(json); - }); -}); diff --git a/sdk/typescript/packages/mix-fetch/src/worker/handle-response-mime-types.ts b/sdk/typescript/packages/mix-fetch/src/worker/handle-response-mime-types.ts deleted file mode 100644 index abcaa845f7..0000000000 --- a/sdk/typescript/packages/mix-fetch/src/worker/handle-response-mime-types.ts +++ /dev/null @@ -1,111 +0,0 @@ -import type { ResponseBody, ResponseBodyConfigMap, ResponseBodyMethod } from '../types'; -import { ResponseBodyConfigMapDefaults } from '../types'; - -const getContentType = (response?: Response) => { - if (!response) { - return undefined; - } - - // this is what should be returned in the headers - if (response.headers.has('Content-Type')) { - return response.headers.get('Content-Type') as string; - } - - // handle weird servers that use lowercase headers - if (response.headers.has('content-type')) { - return response.headers.get('content-type') as string; - } - - // the Content-Type/content-type header is not part of the response - return undefined; -}; - -const doHandleResponseMethod = async (response: Response, method?: ResponseBodyMethod): Promise => { - switch (method) { - case 'uint8array': - return { - uint8array: new Uint8Array(await response.arrayBuffer()), - }; - case 'json': - case 'text': - return { text: await response.text() }; - case 'blob': { - const blob = await response.blob(); - const blobUrl = URL.createObjectURL(blob); - return { blobUrl }; - } - case 'formData': { - const formData: any = {}; - const data = await response.formData(); - // eslint-disable-next-line no-restricted-syntax - for (const pair of data.entries()) { - const [key, value] = pair; - formData[key] = value; - } - return { formData }; - } - default: - return {}; - } -}; - -const testIfIncluded = (value?: string, tests?: Array): boolean => { - if (!tests) { - return false; - } - if (!value) { - return false; - } - - for (let i = 0; i < tests.length; i += 1) { - const test = tests[i]; - if (typeof test === 'string' && value === test) { - return true; - } - if ((test as RegExp).test && (test as RegExp).test(value)) { - return true; - } - } - - // default return is false, because nothing above matched - return false; -}; - -export const handleResponseMimeTypes = async ( - response: Response, - config?: ResponseBodyConfigMap, -): Promise => { - // combine the user supplied config with the default - const finalConfig: ResponseBodyConfigMap = { ...ResponseBodyConfigMapDefaults, ...config }; - - const contentType = getContentType(response); - - // check if the headers say what the content type are, otherwise return the bytes of the response as a blob - if (!contentType) { - // no content type, or body, so the response is only the status, e.g. GET - if (!response.body) { - return {}; - } - - // handle fallback method - return doHandleResponseMethod(response, config?.fallback || 'blob'); - } - - if (testIfIncluded(contentType, finalConfig.uint8array)) { - return doHandleResponseMethod(response, 'uint8array'); - } - if (testIfIncluded(contentType, finalConfig.json)) { - return doHandleResponseMethod(response, 'json'); - } - if (testIfIncluded(contentType, finalConfig.text)) { - return doHandleResponseMethod(response, 'text'); - } - if (testIfIncluded(contentType, finalConfig.formData)) { - return doHandleResponseMethod(response, 'formData'); - } - if (testIfIncluded(contentType, finalConfig.blob)) { - return doHandleResponseMethod(response, 'blob'); - } - - return {}; -}; diff --git a/sdk/typescript/packages/mix-fetch/src/worker/index.ts b/sdk/typescript/packages/mix-fetch/src/worker/index.ts deleted file mode 100644 index 4fd508b348..0000000000 --- a/sdk/typescript/packages/mix-fetch/src/worker/index.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { loadWasm } from './wasm-loading'; -import { run } from './main'; - -async function main() { - await loadWasm(); - await run(); -} - -main().catch((e: any) => console.error('Unhandled exception in mixFetch worker', e)); diff --git a/sdk/typescript/packages/mix-fetch/src/worker/main.ts b/sdk/typescript/packages/mix-fetch/src/worker/main.ts deleted file mode 100644 index f126f68bb8..0000000000 --- a/sdk/typescript/packages/mix-fetch/src/worker/main.ts +++ /dev/null @@ -1,69 +0,0 @@ -/* eslint-disable no-restricted-globals */ -import { setupMixFetch, disconnectMixFetch } from '@nymproject/mix-fetch-wasm'; -import * as Comlink from 'comlink'; -import type { IMixFetchWebWorker, LoadedEvent } from '../types'; -import { EventKinds, ResponseBodyConfigMap, ResponseBodyConfigMapDefaults } from '../types'; -import { handleResponseMimeTypes } from './handle-response-mime-types'; - -/** - * Helper method to send typed messages. - * @param event The strongly typed message to send back to the calling thread. - */ -// eslint-disable-next-line no-restricted-globals -const postMessageWithType = (event: E) => self.postMessage(event); -export async function run() { - const { mixFetch } = self as any; - let responseBodyConfigMap: ResponseBodyConfigMap = ResponseBodyConfigMapDefaults; - - const mixFetchWebWorker: IMixFetchWebWorker = { - mixFetch: async (url, args) => { - console.log('[Worker] --- mixFetch ---', { url, args }); - - const response: Response = await mixFetch(url, args); - - console.log('[Worker]', { response, json: JSON.stringify(response, null, 2) }); - - const bodyResponse = await handleResponseMimeTypes(response, responseBodyConfigMap); - console.log('[Worker]', { bodyResponse }); - - const headers: any = {}; - response.headers.forEach((value, key) => { - headers[key] = value; - }); - - const output = { - body: bodyResponse, - url: response.url, - headers, - status: response.status, - statusText: response.statusText, - type: response.type, - ok: response.ok, - redirected: response.redirected, - }; - - console.log('[Worker]', { output }); - - return output; - }, - setupMixFetch: async (opts) => { - console.log('[Worker] --- setupMixFetch ---', { opts }); - if (opts?.responseBodyConfigMap) { - responseBodyConfigMap = opts.responseBodyConfigMap; - } - await setupMixFetch(opts || {}); - }, - disconnectMixFetch: async () => { - console.log('[Worker] --- disconnectMixFetch ---'); - - await disconnectMixFetch(); - }, - }; - - // start comlink listening for messages and handle them above - Comlink.expose(mixFetchWebWorker); - - // notify any listeners that the web worker has loaded - HOWEVER, mixFetch hasn't been setup and the client started - // call `setupMixFetch` from the main thread to start the Nym client - postMessageWithType({ kind: EventKinds.Loaded, args: { loaded: true } }); -} diff --git a/sdk/typescript/packages/mix-fetch/src/worker/wasm-loading.ts b/sdk/typescript/packages/mix-fetch/src/worker/wasm-loading.ts deleted file mode 100644 index 1fa64b4c5d..0000000000 --- a/sdk/typescript/packages/mix-fetch/src/worker/wasm-loading.ts +++ /dev/null @@ -1,87 +0,0 @@ -/* eslint-disable @typescript-eslint/naming-convention,no-restricted-globals */ -/// - -// Copyright 2020-2023 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// -// Rollup will replace wasmBytes with a function that loads the WASM bundle from a base64 string embedded in the output. -// -// Doing it this way, saves having to support a large variety of bundlers and their quirks. -// -// @ts-ignore -// eslint-disable-next-line import/no-extraneous-dependencies -import getMixFetchWasmBytes from '@nymproject/mix-fetch-wasm/mix_fetch_wasm_bg.wasm'; - -// @ts-ignore -// eslint-disable-next-line import/no-extraneous-dependencies -import getGoConnectionWasmBytes from '@nymproject/mix-fetch-wasm/go_conn.wasm'; - -// wasm_bindgen creates a global variable (with the exports attached) that is in scope after `importScripts` -import init, { - set_panic_hook, - send_client_data, - start_new_mixnet_connection, - mix_fetch_initialised, - finish_mixnet_connection, -} from '@nymproject/mix-fetch-wasm'; - -// see `typings/wasm_exec.d.ts` for the defintion of the `class Go` in global scope -import '@nymproject/mix-fetch-wasm/wasm_exec'; - -async function loadGoWasm() { - // rollup will provide a function to get the Go connection WASM bytes here - const bytes = await getGoConnectionWasmBytes(); - - // @ts-ignore - const go = new Go(); // Defined in wasm_exec.js - - // the WebAssembly runtime will parse the bytes and then start the Go runtime - const wasmObj = await WebAssembly.instantiate(bytes, go.importObject); - go.run(wasmObj); -} - -function setupRsGoBridge() { - const rsGoBridge = { - send_client_data, - start_new_mixnet_connection, - mix_fetch_initialised, - finish_mixnet_connection, - }; - - // (note: reason for intermediate `__rs_go_bridge__` object is to decrease global scope bloat - // and to discourage users from trying to call those methods directly) - // eslint-disable-next-line no-underscore-dangle - (self as any).__rs_go_bridge__ = rsGoBridge; -} - -export async function loadWasm() { - // rollup with provide a function to get the mixFetch WASM bytes - const bytes = await getMixFetchWasmBytes(); - - // load rust WASM package - await init(bytes); - console.log('Loaded RUST WASM'); - - // load go WASM package - await loadGoWasm(); - console.log('Loaded GO WASM'); - - // sets up better stack traces in case of in-rust panics - set_panic_hook(); - - setupRsGoBridge(); - - // goWasmSetLogging('trace'); -} diff --git a/sdk/typescript/packages/mix-fetch/tsconfig.jest.json b/sdk/typescript/packages/mix-fetch/tsconfig.jest.json deleted file mode 100644 index 2e6284589e..0000000000 --- a/sdk/typescript/packages/mix-fetch/tsconfig.jest.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "compileOnSave": false, - "compilerOptions": { - "lib": [ - "es2021", - "dom", - "dom.iterable", - "esnext", - "webworker" - ], - "module": "CommonJS", - "target": "es5", - "strict": true, - "moduleResolution": "node", - "skipLibCheck": true, - "skipDefaultLibCheck": true, - "declaration": true, - "baseUrl": ".", - "esModuleInterop": true, - "allowJs": true, - "downlevelIteration": true - }, - "include": [ - "src/**/*.ts" - ], - "exclude": [ - "jest.*", - "webpack.config.js", - "webpack.prod.js", - "webpack.common.js", - "node_modules", - "**/node_modules", - "dist", - "**/dist", - "scripts", - "jest", - "__tests__", - "**/__tests__", - "__jest__", - "**/__jest__", - "config/*" - ] -} diff --git a/sdk/typescript/packages/mix-fetch/tsconfig.json b/sdk/typescript/packages/mix-fetch/tsconfig.json index de7de44877..8a42212d77 100644 --- a/sdk/typescript/packages/mix-fetch/tsconfig.json +++ b/sdk/typescript/packages/mix-fetch/tsconfig.json @@ -1,13 +1,7 @@ { "compileOnSave": false, "compilerOptions": { - "lib": [ - "es2021", - "dom", - "dom.iterable", - "esnext", - "webworker" - ], + "lib": ["es2021", "dom", "dom.iterable", "esnext"], "outDir": "./dist/", "module": "esnext", "target": "esnext", @@ -17,29 +11,10 @@ "skipLibCheck": true, "skipDefaultLibCheck": true, "declaration": true, + "sourceMap": true, "baseUrl": ".", "downlevelIteration": true }, - "include": [ - "src/**/*.ts", - "src/*.ts", - "typings" - ], - "exclude": [ - "jest.config.js", - "webpack.config.js", - "webpack.prod.js", - "webpack.common.js", - "node_modules", - "**/node_modules", - "dist", - "**/dist", - "scripts", - "jest", - "__tests__", - "**/__tests__", - "__jest__", - "**/__jest__", - "config/*", - ] + "include": ["src/**/*.ts"], + "exclude": ["node_modules", "**/node_modules", "dist", "**/dist", "internal-dev"] } diff --git a/sdk/typescript/packages/mix-fetch/typedoc.json b/sdk/typescript/packages/mix-fetch/typedoc.json index fd122c4af2..943efadcc2 100644 --- a/sdk/typescript/packages/mix-fetch/typedoc.json +++ b/sdk/typescript/packages/mix-fetch/typedoc.json @@ -1,10 +1,9 @@ { "sort": ["kind"], "entryPoints": ["./src/index.ts"], - "out": "../../../../documentation/docs/pages/developers/typescript/api/mix-fetch", + "out": "../../../../documentation/docs/pages/developers/mix-fetch/api", "plugin": ["typedoc-plugin-markdown"], "entryFileName": "globals", - "exclude": ["./src/worker/**"], "kindSortOrder": [ "Function", "Interface", diff --git a/sdk/typescript/packages/mix-fetch/typings/rollup-worker.d.ts b/sdk/typescript/packages/mix-fetch/typings/rollup-worker.d.ts deleted file mode 100644 index ead3d9e1f4..0000000000 --- a/sdk/typescript/packages/mix-fetch/typings/rollup-worker.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module 'web-worker:*' { - const WorkerFactory: new () => Worker; - export default WorkerFactory; -} diff --git a/sdk/typescript/packages/mix-fetch/typings/wasm_exec.d.ts b/sdk/typescript/packages/mix-fetch/typings/wasm_exec.d.ts deleted file mode 100644 index 9424fd386b..0000000000 --- a/sdk/typescript/packages/mix-fetch/typings/wasm_exec.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -declare module '@nymproject/mix-fetch-wasm/wasm_exec' { - export declare global { - class Go { - constructor(); - - importObject: any; - - run(goWasm: any); - } - } -} diff --git a/sdk/typescript/packages/mix-tunnel/.gitignore b/sdk/typescript/packages/mix-tunnel/.gitignore new file mode 100644 index 0000000000..fc521b3b1f --- /dev/null +++ b/sdk/typescript/packages/mix-tunnel/.gitignore @@ -0,0 +1,6 @@ +# Build artefact emitted by the first rollup pass (scripts/build.sh:13) and +# moved here for the second pass to inline. ~9 MB and changes every wasm +# rebuild; tracking it in git pollutes every diff that touches the wasm. +src/worker/worker.js +src/worker/*.wasm +dist/ diff --git a/sdk/typescript/packages/mix-tunnel/README.md b/sdk/typescript/packages/mix-tunnel/README.md new file mode 100644 index 0000000000..3a1691f5b3 --- /dev/null +++ b/sdk/typescript/packages/mix-tunnel/README.md @@ -0,0 +1,41 @@ +# @nymproject/mix-tunnel + +Shared mixnet tunnel lifecycle for the smolmix-based SDKs. + +This package owns the single Web Worker that hosts `@nymproject/smolmix-wasm`, +so that `@nymproject/mix-fetch`, `@nymproject/mix-dns`, and +`@nymproject/mix-websocket` all share one IPR connection, one smoltcp stack, +and one DNS cache. + +Most consumers will not import this directly: import a feature package and +the tunnel comes along. + +## Direct usage + +```ts +import { setupMixTunnel, disconnectMixTunnel, getTunnelState } from '@nymproject/mix-tunnel'; + +await setupMixTunnel({ debug: true }); + +const state = await getTunnelState(); // { state: 'ready' } + +// ... use mix-fetch / mix-dns / mix-websocket here ... + +await disconnectMixTunnel(); +``` + +## Layout + +``` +mix-tunnel + + (owns the Web Worker) + + (loads smolmix-wasm) + + exposes Comlink API to: + | + +---+--------+----------+ + | | | + mix-fetch mix-dns mix-websocket +``` + +The feature packages call `getMixTunnel()` and invoke the same Comlinked +handle, so the underlying tunnel is shared. diff --git a/sdk/typescript/packages/mix-tunnel/package.json b/sdk/typescript/packages/mix-tunnel/package.json new file mode 100644 index 0000000000..2a39da860b --- /dev/null +++ b/sdk/typescript/packages/mix-tunnel/package.json @@ -0,0 +1,60 @@ +{ + "name": "@nymproject/mix-tunnel", + "version": "0.1.0", + "description": "Shared mixnet tunnel lifecycle for smolmix-based SDKs (mix-fetch, mix-dns, mix-websocket).", + "license": "Apache-2.0", + "author": "Nym Technologies SA", + "homepage": "https://nym.com", + "repository": { + "type": "git", + "url": "https://github.com/nymtech/nym", + "directory": "sdk/typescript/packages/mix-tunnel" + }, + "bugs": { + "url": "https://github.com/nymtech/nym/issues" + }, + "keywords": ["nym", "mixnet", "privacy", "wasm", "webworker"], + "sideEffects": false, + "files": [ + "dist/**/*" + ], + "main": "dist/esm/index.js", + "module": "dist/esm/index.js", + "browser": "dist/esm/index.js", + "scripts": { + "build": "scripts/build.sh", + "build:worker": "rollup -c rollup-worker.config.mjs", + "clean": "rimraf dist", + "docs:generate": "typedoc", + "docs:generate:prod": "typedoc --basePath ./docs/tsdoc/nymproject/mix-tunnel/", + "lint": "eslint src", + "lint:fix": "eslint src --fix", + "start": "tsc -w", + "tsc": "tsc --noEmit true" + }, + "devDependencies": { + "@nymproject/smolmix-wasm": "workspace:*", + "@nymproject/eslint-config-react-typescript": "workspace:*", + "@rollup/plugin-commonjs": "^24.0.1", + "@rollup/plugin-node-resolve": "^15.0.1", + "@rollup/plugin-replace": "^5.0.2", + "@rollup/plugin-typescript": "^10.0.1", + "@rollup/plugin-wasm": "^6.1.1", + "@typescript-eslint/eslint-plugin": "catalog:", + "@typescript-eslint/parser": "catalog:", + "comlink": "^4.3.1", + "eslint": "^8.10.0", + "rimraf": "catalog:", + "rollup": "^3.9.1", + "rollup-plugin-base64": "^1.0.1", + "rollup-plugin-web-worker-loader": "^1.6.1", + "tslib": "catalog:", + "typescript": "^4.8.4" + }, + "private": false, + "type": "module", + "types": "./dist/esm/index.d.ts", + "publishConfig": { + "access": "public" + } +} diff --git a/sdk/typescript/packages/mix-tunnel/rollup-esm.config.mjs b/sdk/typescript/packages/mix-tunnel/rollup-esm.config.mjs new file mode 100644 index 0000000000..7a81d76f45 --- /dev/null +++ b/sdk/typescript/packages/mix-tunnel/rollup-esm.config.mjs @@ -0,0 +1,5 @@ +import { getConfig } from './rollup/esm.mjs'; + +export default { + ...getConfig(), +}; diff --git a/sdk/typescript/packages/mix-fetch/rollup-worker.config.mjs b/sdk/typescript/packages/mix-tunnel/rollup-worker.config.mjs similarity index 100% rename from sdk/typescript/packages/mix-fetch/rollup-worker.config.mjs rename to sdk/typescript/packages/mix-tunnel/rollup-worker.config.mjs diff --git a/sdk/typescript/packages/mix-tunnel/rollup/esm.mjs b/sdk/typescript/packages/mix-tunnel/rollup/esm.mjs new file mode 100644 index 0000000000..5bcc7d7451 --- /dev/null +++ b/sdk/typescript/packages/mix-tunnel/rollup/esm.mjs @@ -0,0 +1,34 @@ +import typescript from '@rollup/plugin-typescript'; +import resolve from '@rollup/plugin-node-resolve'; +import webWorkerLoader from 'rollup-plugin-web-worker-loader'; +import replace from '@rollup/plugin-replace'; + +const extensions = ['.js', '.jsx', '.ts', '.tsx']; + +/** + * ESM bundle. The worker is inlined as a base64 blob; the worker bundle itself + * carries the smolmix-wasm bytes (see rollup/worker.mjs). + */ +export const getConfig = (opts = {}) => ({ + input: 'src/index.ts', + output: { + dir: opts.outputDir || 'dist/esm', + format: 'es', + }, + plugins: [ + webWorkerLoader({ targetPlatform: 'browser', inline: true }), + replace({ + values: { + "createURLWorkerFactory('web-worker-0.js')": + "createURLWorkerFactory(new URL('web-worker-0.js', import.meta.url))", + }, + delimiters: ['', ''], + preventAssignment: true, + }), + resolve({ extensions }), + typescript({ + exclude: ['worker/*'], + compilerOptions: { outDir: opts.outputDir || 'dist/esm' }, + }), + ], +}); diff --git a/sdk/typescript/packages/mix-tunnel/rollup/worker.mjs b/sdk/typescript/packages/mix-tunnel/rollup/worker.mjs new file mode 100644 index 0000000000..7db3e1429f --- /dev/null +++ b/sdk/typescript/packages/mix-tunnel/rollup/worker.mjs @@ -0,0 +1,47 @@ +import typescript from '@rollup/plugin-typescript'; +import resolve from '@rollup/plugin-node-resolve'; +import { wasm } from '@rollup/plugin-wasm'; +import replace from '@rollup/plugin-replace'; + +const extensions = ['.js', '.jsx', '.ts', '.tsx']; + +/** + * Worker bundle. `@rollup/plugin-wasm` inlines the smolmix-wasm bytes; the + * worker is then base64-inlined into the main ESM bundle by rollup/esm.mjs. + */ +export const getConfig = () => ({ + input: 'src/worker/index.ts', + output: { + dir: 'dist', + format: 'es', + }, + plugins: [ + resolve({ extensions }), + // smolmix-wasm's wasm-pack glue auto-generates a `new URL(...)` reference + // for the .wasm at the path the bundler is expected to resolve. The wasm + // plugin injects bytes directly via `init(bytes)`, so we null out the URL + // assignment to keep the runtime from trying to fetch a file we don't ship. + // NB: the variable name (`module_or_path`) matches current wasm-bindgen + // output; older versions called it `input` — check pkg/smolmix_wasm.js if + // the replace stops matching after a wasm-pack upgrade. + replace({ + values: { + "module_or_path = new URL('smolmix_wasm_bg.wasm', import.meta.url);": 'module_or_path = undefined;', + }, + delimiters: ['', ''], + preventAssignment: true, + }), + // Set maxFileSize above the smolmix-wasm size so the plugin inlines the + // bytes as base64 rather than emitting a sibling .wasm asset. The cost is + // a fat bundle (~28 MB for the worker, base64 overhead); the benefit is + // zero-config consumer deployment — no need to teach every downstream + // bundler how to copy the .wasm next to the JS. + wasm({ maxFileSize: 50_000_000, targetEnv: 'browser' }), + typescript({ + compilerOptions: { + declaration: false, + target: 'es2020', + }, + }), + ], +}); diff --git a/sdk/typescript/packages/mix-tunnel/scripts/build.sh b/sdk/typescript/packages/mix-tunnel/scripts/build.sh new file mode 100755 index 0000000000..58681cbbb2 --- /dev/null +++ b/sdk/typescript/packages/mix-tunnel/scripts/build.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +set -o errexit +set -o nounset +set -o pipefail + +rm -rf dist || true + +# Build the worker (which inlines smolmix-wasm bytes via @rollup/plugin-wasm), +# then move the result next to src/index.ts so rollup-plugin-web-worker-loader +# can pick it up and base64-inline it into the main ESM bundle. +# +# The resulting `dist/esm/index.js` carries the wasm payload base64-encoded +# twice (once into the worker bundle, again when the worker is inlined into +# the main bundle). That's a deliberate consumer-ergonomics trade-off; see +# `~/.claude/plans/ts-sdk-packages-new.md` § "Future work: bundle size +# optimisation" for the unwind options and why we deferred them. + +rollup -c rollup-worker.config.mjs + +rm -f src/worker/*.wasm +mv dist/index.js src/worker/worker.js + +mkdir -p dist/worker +mv dist/*.wasm dist/worker 2>/dev/null || true + +rollup -c rollup-esm.config.mjs + +cp README.md dist/esm 2>/dev/null || true diff --git a/sdk/typescript/packages/mix-tunnel/src/index.ts b/sdk/typescript/packages/mix-tunnel/src/index.ts new file mode 100644 index 0000000000..ab9655af62 --- /dev/null +++ b/sdk/typescript/packages/mix-tunnel/src/index.ts @@ -0,0 +1,87 @@ +// Public entry point for @nymproject/mix-tunnel. +// +// Owns the single Web Worker that hosts smolmix-wasm. Feature packages +// (@nymproject/mix-fetch, @nymproject/mix-dns, @nymproject/mix-websocket) +// import `getMixTunnel()` and call into the same worker, so they share +// one IPR connection + one smoltcp stack + one DNS cache. + +import InlineWasmWebWorker from 'web-worker:./worker/worker'; +import * as Comlink from 'comlink'; +import { EventKinds, IMixTunnelWorker } from './types'; + +export * from './types'; + +let tunnelPromise: Promise> | undefined; + +const createWorker = async (): Promise => + new Promise((resolve, reject) => { + const worker = new InlineWasmWebWorker(); + worker.addEventListener('error', reject); + worker.addEventListener( + 'message', + (msg: MessageEvent) => { + worker.removeEventListener('error', reject); + if (msg.data?.kind === EventKinds.Loaded) { + resolve(worker); + } else { + reject(msg); + } + }, + { once: true }, + ); + }); + +const createTunnel = async (): Promise> => { + const worker = await createWorker(); + return Comlink.wrap(worker); +}; + +/** + * Get the singleton tunnel worker handle. The first call spawns the worker + * and loads smolmix-wasm; subsequent calls return the same handle. + * + * Note: this does NOT call `setupMixTunnel` automatically — call it on the + * returned handle (or use the top-level `setupMixTunnel` helper) before + * issuing fetch/dns/websocket requests. + */ +export const getMixTunnel = async (): Promise> => { + if (!tunnelPromise) { + tunnelPromise = createTunnel(); + } + return tunnelPromise; +}; + +/** Initialise the mixnet tunnel. Idempotent; safe to call from multiple feature packages. */ +export const setupMixTunnel = async (opts?: import('./types').SetupMixTunnelOpts): Promise => { + const tunnel = await getMixTunnel(); + await tunnel.setupMixTunnel(opts); +}; + +/** Tear the tunnel down. After this, the WASM is unusable until page reload. */ +export const disconnectMixTunnel = async (): Promise => { + if (!tunnelPromise) return; + const tunnel = await tunnelPromise; + await tunnel.disconnectMixTunnel(); +}; + +/** Inspect the current tunnel state. Pre-setup reads as `connecting`. */ +export const getTunnelState = async (): Promise => { + const tunnel = await getMixTunnel(); + return tunnel.getTunnelState(); +}; + +/** + * Re-export of `Comlink.proxy` so feature packages (mix-websocket etc.) can + * mark callbacks for proxy-transfer using THIS module's Comlink instance. + * + * Why: Comlink detects proxy-marked values via a `Symbol('Comlink.proxy')`. + * That symbol is created per module instance, so if mix-websocket bundled its + * own Comlink, `mix-websocket.Comlink.proxy(fn)` would mark `fn` with a + * symbol that mix-tunnel's serializer doesn't recognise — fall-through to + * structured-clone, which can't clone functions, throws DOMException. + * + * By exposing this re-export, mix-websocket's `import { proxy } from + * '@nymproject/mix-tunnel'` returns the same function backed by the same + * Comlink instance, so the marker symbol matches. + */ +export { proxy } from 'comlink'; diff --git a/sdk/typescript/packages/mix-tunnel/src/types.ts b/sdk/typescript/packages/mix-tunnel/src/types.ts new file mode 100644 index 0000000000..48d0f37595 --- /dev/null +++ b/sdk/typescript/packages/mix-tunnel/src/types.ts @@ -0,0 +1,78 @@ +// Public types for the shared mixnet tunnel. +// +// The tunnel is a single WASM instance with one IPR + smoltcp stack; +// mix-fetch, mix-dns, and mix-websocket all route through it. +// +// The fields below mirror smolmix-wasm's `SetupOpts`. Kept inline (not +// imported) so consumers don't take a transitive type-only dep on +// `@nymproject/smolmix-wasm`, which never publishes to npm. + +export interface SetupMixTunnelOpts { + preferredIpr?: string | undefined; + clientId?: string | undefined; + forceTls?: boolean; + disablePoissonTraffic?: boolean; + disableCoverTraffic?: boolean; + openReplySurbs?: number | undefined; + dataReplySurbs?: number | undefined; + primaryDns?: string | undefined; + fallbackDns?: string | undefined; + storagePassphrase?: string | undefined; + connectTimeoutMs?: number | undefined; + dnsTimeoutMs?: number | undefined; + tcpKeepaliveMs?: number | undefined; + tcpBufferSize?: number | undefined; + maxRedirects?: number | undefined; + debug?: boolean; +} + +export type TunnelStateName = 'connecting' | 'ready' | 'disconnecting' | 'disconnected' | 'failed'; + +export interface TunnelState { + state: TunnelStateName; + reason?: string; +} + +/** + * Pre-serialised response shape produced by `smolmix-wasm::mixFetch`. Designed + * for Comlink transfer (Uint8Array + primitive arrays survive structured clone). + * + * `headers` is a sequence of `[name, value]` pairs rather than a record so that + * repeated names like `Set-Cookie`, `Vary`, `Link`, `WWW-Authenticate` survive. + * The TS facade reconstructs a real `Response` via: + * + * new Response(raw.body, { + * status: raw.status, + * statusText: raw.statusText, + * headers: new Headers(raw.headers), + * }) + */ +export interface MixFetchResponseInit { + body: Uint8Array; + status: number; + statusText: string; + headers: Array<[string, string]>; +} + +export type WsEventType = 'open' | 'text' | 'binary' | 'close' | 'error'; +export type WsEventCallback = (handleId: number, type: WsEventType, data: unknown) => void; + +export interface IMixTunnelWorker { + setupMixTunnel(opts?: SetupMixTunnelOpts): Promise; + disconnectMixTunnel(): Promise; + getTunnelState(): Promise; + mixFetch(url: string, init: unknown): Promise; + mixDNS(hostname: string): Promise; + mixWebSocket(url: string, protocols: string[] | undefined, onEvent: WsEventCallback): Promise; + wsSend(handleId: number, data: string | Uint8Array | ArrayBuffer): Promise; + wsClose(handleId: number, code: number, reason: string): Promise; +} + +export enum EventKinds { + Loaded = 'Loaded', +} + +export interface LoadedEvent { + kind: EventKinds.Loaded; + args: { loaded: true }; +} diff --git a/sdk/typescript/packages/mix-tunnel/src/typings.d.ts b/sdk/typescript/packages/mix-tunnel/src/typings.d.ts new file mode 100644 index 0000000000..8a3e6424fd --- /dev/null +++ b/sdk/typescript/packages/mix-tunnel/src/typings.d.ts @@ -0,0 +1,7 @@ +// `web-worker:` virtual modules emitted by `rollup-plugin-web-worker-loader`. +// Script-style ambient declaration (no imports/exports in this file) so the +// wildcard pattern works — module augmentations don't support wildcards. +declare module 'web-worker:*' { + const WorkerCtor: new () => Worker; + export default WorkerCtor; +} diff --git a/sdk/typescript/packages/mix-tunnel/src/worker/index.ts b/sdk/typescript/packages/mix-tunnel/src/worker/index.ts new file mode 100644 index 0000000000..5328b1fa36 --- /dev/null +++ b/sdk/typescript/packages/mix-tunnel/src/worker/index.ts @@ -0,0 +1,12 @@ +import { loadWasm } from './wasm-loading'; +import { run } from './main'; + +async function main() { + await loadWasm(); + await run(); +} + +main().catch((e: unknown) => { + // eslint-disable-next-line no-console + console.error('Unhandled exception in mix-tunnel worker', e); +}); diff --git a/sdk/typescript/packages/mix-tunnel/src/worker/main.ts b/sdk/typescript/packages/mix-tunnel/src/worker/main.ts new file mode 100644 index 0000000000..01b279e28d --- /dev/null +++ b/sdk/typescript/packages/mix-tunnel/src/worker/main.ts @@ -0,0 +1,38 @@ +/* eslint-disable no-restricted-globals */ +import { + setupMixTunnel, + disconnectMixTunnel, + getTunnelState, + mixFetch, + mixDNS, + mixWebSocket, + wsSend, + wsClose, + setDebugLogging, +} from '@nymproject/smolmix-wasm'; +import * as Comlink from 'comlink'; +import { EventKinds, IMixTunnelWorker, LoadedEvent } from '../types'; + +const postMessageWithType = (event: E) => self.postMessage(event); + +export async function run() { + const api: IMixTunnelWorker = { + setupMixTunnel: async (opts) => { + // `debug` is a TS-only convenience; smolmix exposes it as a separate + // runtime toggle. Apply before setup so start-up logs appear. + const { debug, ...wasmOpts } = opts ?? {}; + if (debug !== undefined) setDebugLogging(debug); + await setupMixTunnel(wasmOpts); + }, + disconnectMixTunnel: () => disconnectMixTunnel(), + getTunnelState: async () => getTunnelState(), + mixFetch: (url, init) => mixFetch(url, init), + mixDNS: (hostname) => mixDNS(hostname), + mixWebSocket: (url, protocols, onEvent) => mixWebSocket(url, protocols, onEvent), + wsSend: async (handleId, data) => wsSend(handleId, data), + wsClose: async (handleId, code, reason) => wsClose(handleId, code, reason), + }; + + Comlink.expose(api); + postMessageWithType({ kind: EventKinds.Loaded, args: { loaded: true } }); +} diff --git a/sdk/typescript/packages/mix-tunnel/src/worker/wasm-loading.ts b/sdk/typescript/packages/mix-tunnel/src/worker/wasm-loading.ts new file mode 100644 index 0000000000..58614f426a --- /dev/null +++ b/sdk/typescript/packages/mix-tunnel/src/worker/wasm-loading.ts @@ -0,0 +1,14 @@ +/// +/* eslint-disable import/no-extraneous-dependencies */ + +// Rollup's @rollup/plugin-wasm rewrites this import to a function returning +// the smolmix-wasm bytes (base64-inlined into this worker bundle at build time). +// @ts-ignore - resolved by @rollup/plugin-wasm +import getSmolmixWasmBytes from '@nymproject/smolmix-wasm/smolmix_wasm_bg.wasm'; +import init, { main } from '@nymproject/smolmix-wasm'; + +export async function loadWasm() { + const bytes = await getSmolmixWasmBytes(); + await init(bytes); + main(); +} diff --git a/sdk/typescript/packages/mix-fetch-node/tsconfig.json b/sdk/typescript/packages/mix-tunnel/tsconfig.json similarity index 50% rename from sdk/typescript/packages/mix-fetch-node/tsconfig.json rename to sdk/typescript/packages/mix-tunnel/tsconfig.json index 8598dd51d0..932a382780 100644 --- a/sdk/typescript/packages/mix-fetch-node/tsconfig.json +++ b/sdk/typescript/packages/mix-tunnel/tsconfig.json @@ -7,30 +7,14 @@ "target": "esnext", "allowJs": false, "strict": true, - "allowSyntheticDefaultImports": true, "moduleResolution": "node", "skipLibCheck": true, "skipDefaultLibCheck": true, "declaration": true, + "sourceMap": true, "baseUrl": ".", "downlevelIteration": true }, - "include": ["src/**/*.ts", "src/*.ts", "typings"], - "exclude": [ - "jest.config.js", - "webpack.config.js", - "webpack.prod.js", - "webpack.common.js", - "node_modules", - "**/node_modules", - "dist", - "**/dist", - "scripts", - "jest", - "__tests__", - "**/__tests__", - "__jest__", - "**/__jest__", - "config/*" - ] + "include": ["src/**/*.ts", "src/**/*.d.ts"], + "exclude": ["node_modules", "**/node_modules", "dist", "**/dist", "scripts"] } diff --git a/sdk/typescript/packages/mix-tunnel/typedoc.json b/sdk/typescript/packages/mix-tunnel/typedoc.json new file mode 100644 index 0000000000..f5d86e6ee1 --- /dev/null +++ b/sdk/typescript/packages/mix-tunnel/typedoc.json @@ -0,0 +1,33 @@ +{ + "sort": ["kind"], + "entryPoints": ["./src/index.ts"], + "out": "../../../../documentation/docs/pages/developers/mix-tunnel/api", + "plugin": ["typedoc-plugin-markdown"], + "entryFileName": "globals", + "exclude": ["./src/worker/**", "./src/typings.d.ts"], + "kindSortOrder": [ + "Function", + "Interface", + "TypeAlias", + "Reference", + "Project", + "Module", + "Namespace", + "Enum", + "EnumMember", + "Class", + "Constructor", + "Property", + "Variable", + "Accessor", + "Method", + "Parameter", + "TypeParameter", + "TypeLiteral", + "CallSignature", + "ConstructorSignature", + "IndexSignature", + "GetSignature", + "SetSignature" + ] +} diff --git a/sdk/typescript/packages/mix-websocket/README.md b/sdk/typescript/packages/mix-websocket/README.md new file mode 100644 index 0000000000..7f6b1fc2c2 --- /dev/null +++ b/sdk/typescript/packages/mix-websocket/README.md @@ -0,0 +1,42 @@ +# @nymproject/mix-websocket + +WebSocket-like class for sending WS/WSS traffic through the Nym mixnet. + +## Usage + +```ts +import { setupMixTunnel, MixWebSocket } from '@nymproject/mix-websocket'; + +await setupMixTunnel(); + +const ws = new MixWebSocket('wss://echo.websocket.events'); +await ws.opened(); + +ws.addEventListener('message', (event) => { + console.log('received', event.data); +}); + +await ws.send('hello'); +await ws.close(1000, 'done'); +``` + +## Differences from the browser WebSocket + +- The constructor returns immediately, but the upgrade happens asynchronously. + Use `await ws.opened()` if you need to block until the handshake completes. +- `binaryType` is fixed to `arraybuffer`; there is no Blob mode. +- There is no `bufferedAmount`; writes queue through the tunnel worker. + +The tunnel is shared with `@nymproject/mix-fetch` and `@nymproject/mix-dns` +via `@nymproject/mix-tunnel`; calling `setupMixTunnel` once is enough. + +## Consumer build requirements + +Ships as raw ESM with a bare `import` of `@nymproject/mix-tunnel`. Use a +bundler that follows package imports (webpack, rollup, parcel, vite, +esbuild). + +Runs in any environment exposing `Worker`, `WebAssembly`, `Blob`, and +`URL.createObjectURL`. That covers modern browsers, Electron renderers, +and mobile WebViews (Capacitor, Cordova, Ionic, iOS WKWebView, Android +WebView). A Node-direct entry point is not yet ported from v1. diff --git a/sdk/typescript/packages/mix-websocket/package.json b/sdk/typescript/packages/mix-websocket/package.json new file mode 100644 index 0000000000..9125a3af36 --- /dev/null +++ b/sdk/typescript/packages/mix-websocket/package.json @@ -0,0 +1,52 @@ +{ + "name": "@nymproject/mix-websocket", + "version": "0.1.0", + "description": "WebSocket-like class that routes WS/WSS traffic through the Nym mixnet.", + "license": "Apache-2.0", + "author": "Nym Technologies SA", + "homepage": "https://nym.com", + "repository": { + "type": "git", + "url": "https://github.com/nymtech/nym", + "directory": "sdk/typescript/packages/mix-websocket" + }, + "bugs": { + "url": "https://github.com/nymtech/nym/issues" + }, + "keywords": ["nym", "mixnet", "privacy", "websocket"], + "sideEffects": false, + "files": [ + "dist/**/*" + ], + "main": "dist/index.js", + "module": "dist/index.js", + "browser": "dist/index.js", + "scripts": { + "build": "tsc", + "clean": "rimraf dist", + "docs:generate": "typedoc", + "docs:generate:prod": "typedoc --basePath ./docs/tsdoc/nymproject/mix-websocket/", + "lint": "eslint src", + "lint:fix": "eslint src --fix", + "start": "tsc -w", + "tsc": "tsc --noEmit true" + }, + "dependencies": { + "@nymproject/mix-tunnel": "workspace:*" + }, + "devDependencies": { + "@nymproject/eslint-config-react-typescript": "workspace:*", + "@typescript-eslint/eslint-plugin": "catalog:", + "@typescript-eslint/parser": "catalog:", + "eslint": "^8.10.0", + "rimraf": "catalog:", + "tslib": "catalog:", + "typescript": "^4.8.4" + }, + "private": false, + "type": "module", + "types": "./dist/index.d.ts", + "publishConfig": { + "access": "public" + } +} diff --git a/sdk/typescript/packages/mix-websocket/src/index.ts b/sdk/typescript/packages/mix-websocket/src/index.ts new file mode 100644 index 0000000000..098e37ec0d --- /dev/null +++ b/sdk/typescript/packages/mix-websocket/src/index.ts @@ -0,0 +1,165 @@ +// @nymproject/mix-websocket +// +// WebSocket-like class for sending WS/WSS traffic through the Nym mixnet. +// The exposed `MixWebSocket` mirrors the browser `WebSocket` API where it +// makes sense (open/message/close/error events, send/close methods). + +import { + getMixTunnel, + setupMixTunnel, + disconnectMixTunnel, + getTunnelState, + proxy, + SetupMixTunnelOpts, + WsEventType, +} from '@nymproject/mix-tunnel'; + +export { setupMixTunnel, disconnectMixTunnel, getTunnelState }; +export type { SetupMixTunnelOpts }; + +export type MixWebSocketReadyState = 0 | 1 | 2 | 3; // CONNECTING | OPEN | CLOSING | CLOSED + +const CONNECTING: MixWebSocketReadyState = 0; +const OPEN: MixWebSocketReadyState = 1; +const CLOSING: MixWebSocketReadyState = 2; +const CLOSED: MixWebSocketReadyState = 3; + +/** + * WebSocket-like channel over the Nym mixnet. The tunnel must already be + * set up (`setupMixTunnel()`) before constructing one. + * + * Differences from the browser `WebSocket`: + * - Constructor resolves asynchronously; use `await ws.opened()` if you + * need to block until the upgrade completes. + * - `binaryType` is fixed to `arraybuffer` (no Blob support). + * - No `bufferedAmount`; the tunnel queues writes through the worker. + */ +export class MixWebSocket extends EventTarget { + readonly url: string; + readonly protocols: string[]; + + private handleIdPromise: Promise; + private state: MixWebSocketReadyState = CONNECTING; + + constructor(url: string, protocols?: string | string[]) { + super(); + this.url = url; + const protocolList = Array.isArray(protocols) ? protocols : protocols ? [protocols] : []; + this.protocols = protocolList; + + this.handleIdPromise = (async () => { + const tunnel = await getMixTunnel(); + // Use mix-tunnel's `proxy` re-export so the marker Symbol matches the + // Comlink instance that serialises the call. A locally-bundled Comlink + // would mark with a different Symbol → fall-through to structured-clone + // → "Function object could not be cloned" DOMException. + const onEvent = proxy((_handle: number, type: WsEventType, data: unknown) => { + this.handleEvent(type, data); + }); + return tunnel.mixWebSocket(url, protocolList, onEvent); + })(); + + // If the upgrade fails before `open` fires, transition to CLOSED and + // dispatch `error`. `opened()` listens for both events so callers don't hang. + this.handleIdPromise.catch((err) => { + this.state = CLOSED; + // Surface the underlying cause to console so playground / consumer code + // can diagnose; the standard `error` Event itself carries no payload. + // eslint-disable-next-line no-console + console.error('[MixWebSocket] connection failed:', err); + const evt = new Event('error') as Event & { message?: string }; + evt.message = err instanceof Error ? err.message : String(err); + this.dispatchEvent(evt); + }); + } + + get readyState(): MixWebSocketReadyState { + return this.state; + } + + /** + * Block until the WebSocket transitions out of `CONNECTING`. Resolves when + * `open` fires (or when the connection fails before opening). + */ + opened(): Promise { + if (this.state !== CONNECTING) return Promise.resolve(); + return new Promise((resolve) => { + const listener = () => { + this.removeEventListener('open', listener); + this.removeEventListener('error', listener); + resolve(); + }; + this.addEventListener('open', listener); + this.addEventListener('error', listener); + }); + } + + async send(data: string | ArrayBuffer | Uint8Array): Promise { + if (this.state !== OPEN) { + throw new Error(`MixWebSocket.send: state is ${this.state}, expected OPEN`); + } + const tunnel = await getMixTunnel(); + const handleId = await this.handleIdPromise; + await tunnel.wsSend(handleId, data); + } + + async close(code = 1000, reason = ''): Promise { + if (this.state === CLOSING || this.state === CLOSED) return; + this.state = CLOSING; + const tunnel = await getMixTunnel(); + const handleId = await this.handleIdPromise; + await tunnel.wsClose(handleId, code, reason); + } + + private handleEvent(type: WsEventType, data: unknown) { + switch (type) { + case 'open': + this.state = OPEN; + this.dispatchEvent(new Event('open')); + break; + case 'text': + this.dispatchEvent(new MessageEvent('message', { data })); + break; + case 'binary': + // wasm hands us a Uint8Array view; surface as ArrayBuffer to match the + // standard WebSocket(binaryType=arraybuffer) shape. + this.dispatchEvent(new MessageEvent('message', { data: toArrayBuffer(data) })); + break; + case 'close': + this.state = CLOSED; + this.dispatchEvent(new CloseEvent('close', closeInit(data))); + break; + case 'error': { + this.state = CLOSED; + // Mirror the constructor's catch-handler shape: attach `.message` + // (non-standard but consistent) so application code can read the + // cause without scraping the worker's console.error output. + // smolmix-wasm always fires `error` with the stringified Rust error + // (see `mixwebsocket.rs` `fire_ws_event(..., "error", ...)`). + const evt = new Event('error') as Event & { message?: string }; + evt.message = typeof data === 'string' ? data : String(data ?? ''); + this.dispatchEvent(evt); + break; + } + default: + // Unknown event type; ignore. + break; + } + } +} + +function toArrayBuffer(data: unknown): ArrayBuffer { + if (data instanceof ArrayBuffer) return data; + if (data instanceof Uint8Array) { + return data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength) as ArrayBuffer; + } + return new ArrayBuffer(0); +} + +function closeInit(data: unknown): CloseEventInit { + if (data && typeof data === 'object') { + const obj = data as { code?: number; reason?: string }; + return { code: obj.code, reason: obj.reason }; + } + return {}; +} diff --git a/sdk/typescript/packages/mix-websocket/tsconfig.json b/sdk/typescript/packages/mix-websocket/tsconfig.json new file mode 100644 index 0000000000..cad41015fa --- /dev/null +++ b/sdk/typescript/packages/mix-websocket/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "lib": ["es2021", "dom", "dom.iterable", "esnext"], + "outDir": "./dist/", + "module": "esnext", + "target": "esnext", + "allowJs": false, + "strict": true, + "moduleResolution": "node", + "skipLibCheck": true, + "skipDefaultLibCheck": true, + "declaration": true, + "sourceMap": true, + "baseUrl": ".", + "downlevelIteration": true + }, + "include": ["src/**/*.ts"], + "exclude": ["node_modules", "**/node_modules", "dist", "**/dist"] +} diff --git a/sdk/typescript/packages/mix-websocket/typedoc.json b/sdk/typescript/packages/mix-websocket/typedoc.json new file mode 100644 index 0000000000..e87cb18e58 --- /dev/null +++ b/sdk/typescript/packages/mix-websocket/typedoc.json @@ -0,0 +1,32 @@ +{ + "sort": ["kind"], + "entryPoints": ["./src/index.ts"], + "out": "../../../../documentation/docs/pages/developers/mix-websocket/api", + "plugin": ["typedoc-plugin-markdown"], + "entryFileName": "globals", + "kindSortOrder": [ + "Function", + "Interface", + "TypeAlias", + "Reference", + "Project", + "Module", + "Namespace", + "Enum", + "EnumMember", + "Class", + "Constructor", + "Property", + "Variable", + "Accessor", + "Method", + "Parameter", + "TypeParameter", + "TypeLiteral", + "CallSignature", + "ConstructorSignature", + "IndexSignature", + "GetSignature", + "SetSignature" + ] +} diff --git a/sdk/typescript/scripts/dev-mode-add.mjs b/sdk/typescript/scripts/dev-mode-add.mjs index 5d8bd1099c..d2a15e18d7 100644 --- a/sdk/typescript/scripts/dev-mode-add.mjs +++ b/sdk/typescript/scripts/dev-mode-add.mjs @@ -2,11 +2,17 @@ import fs from 'fs'; const WORKSPACE_FILE = 'pnpm-workspace.yaml'; +// Order matters only for human readability; the script appends missing +// entries to the yaml's `packages:` block. The `wasm/smolmix/pkg` entry +// requires `make -C wasm/smolmix` to have produced pkg/package.json first; +// otherwise `pnpm install` bails with ERR_PNPM_WORKSPACE_PKG_NOT_FOUND from +// mix-tunnel's `workspace:*` lookup. const devWorkspace = [ 'dist/**', 'sdk/typescript/packages/**', 'sdk/typescript/examples/**', 'sdk/typescript/codegen/**', + 'wasm/smolmix/pkg', ]; const content = fs.readFileSync(WORKSPACE_FILE, 'utf-8'); diff --git a/sdk/typescript/scripts/dev-mode-remove.mjs b/sdk/typescript/scripts/dev-mode-remove.mjs index e17c0b8d5e..ed57d47bdd 100644 --- a/sdk/typescript/scripts/dev-mode-remove.mjs +++ b/sdk/typescript/scripts/dev-mode-remove.mjs @@ -7,6 +7,7 @@ const devWorkspace = [ 'sdk/typescript/packages/**', 'sdk/typescript/examples/**', 'sdk/typescript/codegen/**', + 'wasm/smolmix/pkg', ]; const content = fs.readFileSync(WORKSPACE_FILE, 'utf-8'); diff --git a/sdk/typescript/scripts/publish.sh b/sdk/typescript/scripts/publish.sh index d2d1dac7ee..b279c74d3c 100755 --- a/sdk/typescript/scripts/publish.sh +++ b/sdk/typescript/scripts/publish.sh @@ -5,74 +5,73 @@ set -o nounset set -o pipefail # ------------------------------------------------------- -# ✅ NB: Run this from the root of the repository +# NB: Run this from the root of the repository. +# Each smolmix-based SDK package is published in place from +# its source directory after `pnpm build:ci:sdk` produces +# the dist/ output inside each package. +# +# Scope: only the four smolmix-family packages. The legacy +# sdk/typescript/packages/{sdk,sdk-react,nodejs-client} +# directories exist on disk but are not in pnpm-workspace.yaml +# and are not built or published by this flow. +# +# @nymproject/smolmix-wasm is workspace-internal: its bytes +# are base64-inlined into @nymproject/mix-tunnel at build +# time, so it must never be published. The smolmix Makefile +# marks pkg/package.json as `private: true` to enforce this. # ------------------------------------------------------- -cd dist +REPO_ROOT="$(git rev-parse --show-toplevel)" +cd "$REPO_ROOT" -#packages=( -#chat-app/parcel -#chat-app/plain-html -#chat-app/react-webpack-with-theme-example - -#react/mui-theme -#react/sdk-react -#) packages=( -# "wasm/client" -"wasm/mix-fetch" - - -# "node/wasm/client" -#"node/wasm/mix-fetch" - -"ts/sdk/mix-fetch/cjs" -"ts/sdk/mix-fetch/cjs-full-fat" -"ts/sdk/mix-fetch/esm" -"ts/sdk/mix-fetch/esm-full-fat" - -# "ts/sdk/nodejs-client/cjs" -"ts/sdk/mix-fetch-node/cjs" - -# "ts/sdk/sdk/cjs" -# "ts/sdk/sdk/cjs-full-fat" -# "ts/sdk/sdk/esm" -# "ts/sdk/sdk/esm-full-fat" - -#"ts/sdk/contract-clients" + "sdk/typescript/packages/mix-tunnel" + "sdk/typescript/packages/mix-fetch" + "sdk/typescript/packages/mix-dns" + "sdk/typescript/packages/mix-websocket" ) pushd () { - command pushd "$@" > /dev/null + command pushd "$@" > /dev/null } popd () { - command popd > /dev/null + command popd > /dev/null } -echo "Summary of versions of packages to publish:" -echo "" -for item in "${packages[@]}" -do +echo "Summary of versions to publish:" +echo +for item in "${packages[@]}"; do pushd "$item" - jq -r '. | "📦 " + .version + " " +.name' < package.json + jq -r '. | " " + .version + " " + .name' < package.json popd done -echo "" -echo "" +echo +# `pnpm publish` (not `npm publish`) is required because the four packages +# depend on each other via `workspace:*`. pnpm rewrites `workspace:*` to the +# real version in the published tarball at pack time; npm leaves the literal +# string, which produces tarballs that fail to install. +# +# Flags: +# --access=public scoped packages default to private; smolmix-family is public +# --no-git-checks CI runners can have dirty working trees from the build step +# --tag $NPM_DIST_TAG defaults to `latest`; set to `next` for pre-release shipping +NPM_DIST_TAG="${NPM_DIST_TAG:-latest}" +DRY_RUN_FLAG="" +if [[ "${DRY_RUN:-0}" == "1" ]]; then + DRY_RUN_FLAG="--dry-run" + echo "DRY_RUN=1 — running pnpm publish in dry-run mode (no tarballs uploaded)" +fi COUNTER=0 - -for item in "${packages[@]}" -do +for item in "${packages[@]}"; do (( COUNTER+=1 )) pushd "$item" - echo "🚀 Publishing $item... (${COUNTER} of ${#packages[@]})" - cat package.json | jq -r '. | .name + " " +.version' - npm publish --access=public --verbose --workspaces false || true + echo "Publishing $item (${COUNTER}/${#packages[@]}) --tag $NPM_DIST_TAG" + pnpm publish --access=public --no-git-checks --tag "$NPM_DIST_TAG" $DRY_RUN_FLAG popd - echo "" + echo done -echo "" -echo "✅ Done" +echo +echo "Done." diff --git a/sdk/typescript/scripts/unpublish.sh b/sdk/typescript/scripts/unpublish.sh index aa1bf4a8ee..aa935dcc40 100755 --- a/sdk/typescript/scripts/unpublish.sh +++ b/sdk/typescript/scripts/unpublish.sh @@ -8,7 +8,6 @@ cd dist packages=( "ts/sdk/nodejs-client/cjs" -"ts/sdk/mix-fetch-node/cjs" ) pushd () { diff --git a/sdk/typescript/tests/integration-tests/mix-fetch/.gitignore b/sdk/typescript/tests/integration-tests/mix-fetch/.gitignore deleted file mode 100644 index 86d4c2dd38..0000000000 --- a/sdk/typescript/tests/integration-tests/mix-fetch/.gitignore +++ /dev/null @@ -1 +0,0 @@ -generated diff --git a/sdk/typescript/tests/integration-tests/mix-fetch/generate-tests.mjs b/sdk/typescript/tests/integration-tests/mix-fetch/generate-tests.mjs deleted file mode 100644 index 40efab76cb..0000000000 --- a/sdk/typescript/tests/integration-tests/mix-fetch/generate-tests.mjs +++ /dev/null @@ -1,188 +0,0 @@ -/* eslint-disable no-await-in-loop,no-restricted-syntax */ -import fs from 'fs'; -import path from 'path'; -import child_process from 'child_process'; -import http from 'http'; -import handler from 'serve-handler'; -import { runTests } from './tests/tests.mjs'; - -const GENERATED_DIR = 'generated'; -const OUTPUT_DIR = `${GENERATED_DIR}/packages`; -const BASE_DIST_PATH = '../../../../../dist/ts/sdk/mix-fetch'; -const packages = ['cjs', 'cjs-full-fat', 'esm', 'esm-full-fat']; - -const doBuild = true; -const logTests = true; - -// disabling deleting to preserve node_modules -// fs.rmSync(OUTPUT_DIR, { recursive: true, force: true }); - -fs.mkdirSync(OUTPUT_DIR, { recursive: true }); - -async function serve(publicDir) { - const server = http.createServer((request, response) => - // see https://github.com/vercel/serve-handler#options for more options - handler(request, response, { public: publicDir }), - ); - - server.listen(3000, () => { - console.log(` 🌈 Running at http://localhost:3000, serving ${publicDir}...`); - }); - - return server; -} -function changeFileLocation(packageJsonPath, dependencyPath, kind) { - const packageJson = JSON.parse(fs.readFileSync(packageJsonPath).toString()); - packageJson.name = `${packageJson.name}-${kind}`; - delete packageJson.dependencies['@nymproject/mix-fetch']; - packageJson.dependencies[`@nymproject/mix-fetch${kind}`] = `file:${dependencyPath}`; - fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2)); -} - -console.log('🚚 Copying workspace...'); -fs.cpSync('template/workspace/package.json', path.resolve(`${GENERATED_DIR}/package.json`)); - -packages.forEach((p) => { - const dir = `${OUTPUT_DIR}/${p}`; - if (doBuild) { - fs.rmSync(dir, { recursive: true, force: true }); - } - console.log(`🚚 Creating ${dir}...`); - - let kind = p.startsWith('cjs') ? '-commonjs' : ''; - if (p.endsWith('-full-fat')) { - kind += '-full-fat'; - } - - const importScript = ''; - const importStatement = `import { mixFetch } from '@nymproject/mix-fetch${kind}';`; - const pluginPackageJsonName = `@nymproject/mix-fetch${kind}`; - - const src = fs.readFileSync('template/src/index.ts').toString().replace("'$IMPORT_STATEMENT';", importStatement); - const html = fs.readFileSync('template/src/index.html').toString().replace('', importScript); - const plugins = fs - .readFileSync('template/webpack/webpack.plugins.js') - .toString() - .replaceAll('$PACKAGE', pluginPackageJsonName); - - const pluginsEmpty = 'module.exports = { plugins: [] };'; - - fs.cpSync('template/parcel', `${dir}/parcel`, { recursive: true }); - fs.cpSync('template/src', `${dir}/parcel/src`, { recursive: true }); - - fs.cpSync('template/webpack', `${dir}/webpack`, { recursive: true }); - fs.cpSync('template/src', `${dir}/webpack/src`, { recursive: true }); - - fs.writeFileSync(`${dir}/webpack/src/index.ts`, src); - fs.writeFileSync(`${dir}/parcel/src/index.ts`, src); - // fs.writeFileSync(`${dir}/webpack/src/index.html`, html); - fs.writeFileSync(`${dir}/parcel/src/index.html`, html); - fs.writeFileSync(`${dir}/webpack/webpack.plugins.js`, p.endsWith('-full-fat') ? pluginsEmpty : plugins); - - changeFileLocation(`${dir}/parcel/package.json`, path.resolve(`${BASE_DIST_PATH}/${p}`), kind); - changeFileLocation(`${dir}/webpack/package.json`, path.resolve(`${BASE_DIST_PATH}/${p}`), kind); -}); - -console.log('✅ Generated\n'); - -console.log(`🚀 Installing workspace packages in ${path.resolve(OUTPUT_DIR)}...`); -const resultNpmInstall = child_process.spawnSync('npm', ['install'], { cwd: path.resolve(OUTPUT_DIR) }); -if (resultNpmInstall.status !== 0) { - console.log(resultNpmInstall.stdout.toString()); - console.log(resultNpmInstall.stderr.toString()); - console.log('❌ Failed to install dependencies'); - process.exit(-1); -} - -if (doBuild) { - packages.forEach((p) => { - const dir = `${OUTPUT_DIR}/${p}`; - - ['parcel', 'webpack'].forEach((kind) => { - const project = `${dir}/${kind}`; - console.log(`🚀 Building ${path.resolve(project)}...`); - - const result = child_process.spawnSync('npm', ['run', 'build'], { cwd: path.resolve(project) }); - - if (result.status !== 0) { - console.log(`❌ Failed to build ${project}`); - console.log(result.stdout.toString()); - console.log(result.stderr.toString()); - process.exit(-1); - } else { - console.log( - child_process.spawnSync('ls', ['-lah'], { cwd: `${path.resolve(project)}/dist` }).stdout.toString(), - ); - } - }); - }); -} - -console.log('✅ Built\n'); - -console.log('👀 Testing...'); - -const summary = []; -let totalTimeMilliseconds = 0; -let failures = 0; -for (const p of packages) { - const dir = `${OUTPUT_DIR}/${p}`; - - const kinds = [ - 'parcel', // simple parcel project - 'webpack', // webpack, sometimes with the CopyPlugin to add the WASM bundles - ]; - for (const kind of kinds) { - const project = `${dir}/${kind}`; - console.log(`🔎 Testing ${path.resolve(project)}...`); - - const server = await serve(path.resolve(project, 'dist')); - - const start = performance.now(); - let success = false; - let errors = []; - try { - console.log('🚀 About to run tests...'); - errors = await runTests(logTests); - if (errors.length > 0) { - errors.forEach((e) => console.log(e.text)); - } else { - success = true; - } - } catch (e) { - failures += 1; - errors.push({ text: e.message, type: 'error' }); - } finally { - server.closeAllConnections(); - server.close(); - } - const end = performance.now(); - const duration = Math.floor(end - start); - totalTimeMilliseconds += duration; - - if (errors.length) { - console.log(`❌ Tests failed for ${project} with ${errors.length} errors:`); - console.table(errors); - } else { - console.log('✅ OK'); - } - - summary.push({ - variant: p, - bundler: kind, - duration: `${duration}ms`, - success: success ? '✅ OK' : `❌ Failed with ${errors.length} errors`, - errors: errors.map((e) => e.text).join('\n'), - }); - - console.log(); - } -} - -console.log(); -console.log('Summary:'); -console.table(summary); - -console.log(); -console.log(`Tests took ${Math.floor(totalTimeMilliseconds / 1000)} seconds to run`); -console.log(`${failures > 0 ? `❌ Done with ${failures} errors` : '✅ Done'}`); diff --git a/sdk/typescript/tests/integration-tests/mix-fetch/package-lock.json b/sdk/typescript/tests/integration-tests/mix-fetch/package-lock.json deleted file mode 100644 index 02138582d9..0000000000 --- a/sdk/typescript/tests/integration-tests/mix-fetch/package-lock.json +++ /dev/null @@ -1,1213 +0,0 @@ -{ - "name": "mix-fetch-tests-runner", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "mix-fetch-tests-runner", - "version": "1.0.0", - "dependencies": { - "puppeteer": "^24.4.0", - "serve-handler": "^6.1.5" - } - }, - "node_modules/@babel/code-frame": { - "version": "7.26.2", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.26.2.tgz", - "integrity": "sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==", - "license": "MIT", - "dependencies": { - "@babel/helper-validator-identifier": "^7.25.9", - "js-tokens": "^4.0.0", - "picocolors": "^1.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz", - "integrity": "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==", - "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@puppeteer/browsers": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.8.0.tgz", - "integrity": "sha512-yTwt2KWRmCQAfhvbCRjebaSX8pV1//I0Y3g+A7f/eS7gf0l4eRJoUCvcYdVtboeU4CTOZQuqYbZNS8aBYb8ROQ==", - "license": "Apache-2.0", - "dependencies": { - "debug": "^4.4.0", - "extract-zip": "^2.0.1", - "progress": "^2.0.3", - "proxy-agent": "^6.5.0", - "semver": "^7.7.1", - "tar-fs": "^3.0.8", - "yargs": "^17.7.2" - }, - "bin": { - "browsers": "lib/cjs/main-cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/@tootallnate/quickjs-emscripten": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", - "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "22.13.14", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.14.tgz", - "integrity": "sha512-Zs/Ollc1SJ8nKUAgc7ivOEdIBM8JAKgrqqUYi2J997JuKO7/tpQC+WCetQ1sypiKCQWHdvdg9wBNpUPEWZae7w==", - "license": "MIT", - "optional": true, - "dependencies": { - "undici-types": "~6.20.0" - } - }, - "node_modules/@types/yauzl": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", - "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", - "license": "MIT", - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/agent-base": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz", - "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "license": "Python-2.0" - }, - "node_modules/ast-types": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", - "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", - "license": "MIT", - "dependencies": { - "tslib": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/b4a": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", - "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", - "license": "Apache-2.0" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/bare-events": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz", - "integrity": "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==", - "license": "Apache-2.0", - "optional": true - }, - "node_modules/bare-fs": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.0.2.tgz", - "integrity": "sha512-S5mmkMesiduMqnz51Bfh0Et9EX0aTCJxhsI4bvzFFLs8Z1AV8RDHadfY5CyLwdoLHgXbNBEN1gQcbEtGwuvixw==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "bare-events": "^2.5.4", - "bare-path": "^3.0.0", - "bare-stream": "^2.6.4" - }, - "engines": { - "bare": ">=1.16.0" - }, - "peerDependencies": { - "bare-buffer": "*" - }, - "peerDependenciesMeta": { - "bare-buffer": { - "optional": true - } - } - }, - "node_modules/bare-os": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.1.tgz", - "integrity": "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==", - "license": "Apache-2.0", - "optional": true, - "engines": { - "bare": ">=1.14.0" - } - }, - "node_modules/bare-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.0.tgz", - "integrity": "sha512-tyfW2cQcB5NN8Saijrhqn0Zh7AnFNsnczRcuWODH0eYAXBsJ5gVxAUuNr7tsHSC6IZ77cA0SitzT+s47kot8Mw==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "bare-os": "^3.0.1" - } - }, - "node_modules/bare-stream": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.6.5.tgz", - "integrity": "sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==", - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "streamx": "^2.21.0" - }, - "peerDependencies": { - "bare-buffer": "*", - "bare-events": "*" - }, - "peerDependenciesMeta": { - "bare-buffer": { - "optional": true - }, - "bare-events": { - "optional": true - } - } - }, - "node_modules/basic-ftp": { - "version": "5.0.5", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", - "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "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==", - "license": "MIT", - "engines": { - "node": "*" - } - }, - "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/chromium-bidi": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-2.1.2.tgz", - "integrity": "sha512-vtRWBK2uImo5/W2oG6/cDkkHSm+2t6VHgnj+Rcwhb0pP74OoUb4GipyRX/T/y39gYQPhioP0DPShn+A7P6CHNw==", - "license": "Apache-2.0", - "dependencies": { - "mitt": "^3.0.1", - "zod": "^3.24.1" - }, - "peerDependencies": { - "devtools-protocol": "*" - } - }, - "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "license": "MIT" - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" - }, - "node_modules/content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cosmiconfig": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", - "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", - "license": "MIT", - "dependencies": { - "env-paths": "^2.2.1", - "import-fresh": "^3.3.0", - "js-yaml": "^4.1.0", - "parse-json": "^5.2.0" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/d-fischer" - }, - "peerDependencies": { - "typescript": ">=4.9.5" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/data-uri-to-buffer": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", - "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", - "license": "MIT", - "engines": { - "node": ">= 14" - } - }, - "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", - "license": "MIT", - "dependencies": { - "ms": "^2.1.3" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/degenerator": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", - "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", - "license": "MIT", - "dependencies": { - "ast-types": "^0.13.4", - "escodegen": "^2.1.0", - "esprima": "^4.0.1" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/devtools-protocol": { - "version": "0.0.1413902", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1413902.tgz", - "integrity": "sha512-yRtvFD8Oyk7C9Os3GmnFZLu53yAfsnyw1s+mLmHHUK0GQEc9zthHWvS1r67Zqzm5t7v56PILHIVZ7kmFMaL2yQ==", - "license": "BSD-3-Clause" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "license": "MIT", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "license": "MIT", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escodegen": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", - "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", - "license": "BSD-2-Clause", - "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "license": "BSD-2-Clause", - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "license": "BSD-2-Clause", - "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/fast-fifo": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", - "license": "MIT" - }, - "node_modules/fast-url-parser": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", - "integrity": "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==", - "dependencies": { - "punycode": "^1.3.2" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "license": "ISC", - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-uri": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.4.tgz", - "integrity": "sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==", - "license": "MIT", - "dependencies": { - "basic-ftp": "^5.0.2", - "data-uri-to-buffer": "^6.0.2", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/http-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", - "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/https-proxy-agent": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", - "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/import-fresh": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", - "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ip-address": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", - "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", - "license": "MIT", - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, - "engines": { - "node": ">= 12" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "license": "MIT" - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "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==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", - "license": "MIT" - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "license": "MIT" - }, - "node_modules/lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "license": "MIT" - }, - "node_modules/lru-cache": { - "version": "7.18.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", - "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "node_modules/mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dependencies": { - "mime-db": "~1.33.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/mitt": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz", - "integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==", - "license": "MIT" - }, - "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/netmask": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", - "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/pac-proxy-agent": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.2.0.tgz", - "integrity": "sha512-TEB8ESquiLMc0lV8vcd5Ql/JAKAoyzHFXaStwjkzpOpC5Yv+pIzLfHvjTSdf3vpa2bMiUQrg9i6276yn8666aA==", - "license": "MIT", - "dependencies": { - "@tootallnate/quickjs-emscripten": "^0.23.0", - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "get-uri": "^6.0.1", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.6", - "pac-resolver": "^7.0.1", - "socks-proxy-agent": "^8.0.5" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/pac-resolver": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", - "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", - "license": "MIT", - "dependencies": { - "degenerator": "^5.0.0", - "netmask": "^2.0.2" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==" - }, - "node_modules/path-to-regexp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", - "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==" - }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "license": "MIT" - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "license": "ISC" - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "license": "MIT", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/proxy-agent": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz", - "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==", - "license": "MIT", - "dependencies": { - "agent-base": "^7.1.2", - "debug": "^4.3.4", - "http-proxy-agent": "^7.0.1", - "https-proxy-agent": "^7.0.6", - "lru-cache": "^7.14.1", - "pac-proxy-agent": "^7.1.0", - "proxy-from-env": "^1.1.0", - "socks-proxy-agent": "^8.0.5" - }, - "engines": { - "node": ">= 14" - } - }, - "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==", - "license": "MIT" - }, - "node_modules/pump": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", - "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", - "license": "MIT", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==" - }, - "node_modules/puppeteer": { - "version": "24.4.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.4.0.tgz", - "integrity": "sha512-E4JhJzjS8AAI+6N/b+Utwarhz6zWl3+MR725fal+s3UlOlX2eWdsvYYU+Q5bXMjs9eZEGkNQroLkn7j11s2k1Q==", - "hasInstallScript": true, - "license": "Apache-2.0", - "dependencies": { - "@puppeteer/browsers": "2.8.0", - "chromium-bidi": "2.1.2", - "cosmiconfig": "^9.0.0", - "devtools-protocol": "0.0.1413902", - "puppeteer-core": "24.4.0", - "typed-query-selector": "^2.12.0" - }, - "bin": { - "puppeteer": "lib/cjs/puppeteer/node/cli.js" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/puppeteer-core": { - "version": "24.4.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.4.0.tgz", - "integrity": "sha512-eFw66gCnWo0X8Hyf9KxxJtms7a61NJVMiSaWfItsFPzFBsjsWdmcNlBdsA1WVwln6neoHhsG+uTVesKmTREn/g==", - "license": "Apache-2.0", - "dependencies": { - "@puppeteer/browsers": "2.8.0", - "chromium-bidi": "2.1.2", - "debug": "^4.4.0", - "devtools-protocol": "0.0.1413902", - "typed-query-selector": "^2.12.0", - "ws": "^8.18.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "license": "MIT", - "engines": { - "node": ">=4" - } - }, - "node_modules/semver": { - "version": "7.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", - "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/serve-handler": { - "version": "6.1.5", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.5.tgz", - "integrity": "sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg==", - "dependencies": { - "bytes": "3.0.0", - "content-disposition": "0.5.2", - "fast-url-parser": "1.1.3", - "mime-types": "2.1.18", - "minimatch": "3.1.2", - "path-is-inside": "1.0.2", - "path-to-regexp": "2.2.1", - "range-parser": "1.2.0" - } - }, - "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" - } - }, - "node_modules/socks": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.4.tgz", - "integrity": "sha512-D3YaD0aRxR3mEcqnidIs7ReYJFVzWdd6fXJYUM8ixcQcJRGTka/b3saV0KflYhyVJXKhb947GndU35SxYNResQ==", - "license": "MIT", - "dependencies": { - "ip-address": "^9.0.5", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "8.0.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", - "socks": "^2.8.3" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "license": "BSD-3-Clause", - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "license": "BSD-3-Clause" - }, - "node_modules/streamx": { - "version": "2.22.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.0.tgz", - "integrity": "sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==", - "license": "MIT", - "dependencies": { - "fast-fifo": "^1.3.2", - "text-decoder": "^1.1.0" - }, - "optionalDependencies": { - "bare-events": "^2.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tar-fs": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", - "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", - "license": "MIT", - "dependencies": { - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - }, - "optionalDependencies": { - "bare-fs": "^4.0.1", - "bare-path": "^3.0.0" - } - }, - "node_modules/tar-stream": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.7.tgz", - "integrity": "sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==", - "license": "MIT", - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, - "node_modules/text-decoder": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.3.tgz", - "integrity": "sha512-3/o9z3X0X0fTupwsYvR03pJ/DjWuqqrfwBgTQzdWDiQSm9KitAyz/9WqsT2JQW7KV2m+bC2ol/zqpW37NHxLaA==", - "license": "Apache-2.0", - "dependencies": { - "b4a": "^1.6.4" - } - }, - "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/typed-query-selector": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz", - "integrity": "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==", - "license": "MIT" - }, - "node_modules/undici-types": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", - "license": "MIT", - "optional": true - }, - "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==", - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "node_modules/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", - "license": "MIT", - "dependencies": { - "cliui": "^8.0.1", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.3", - "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "license": "ISC", - "engines": { - "node": ">=12" - } - }, - "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==", - "license": "MIT", - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "node_modules/zod": { - "version": "3.24.2", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz", - "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==", - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - } - } -} diff --git a/sdk/typescript/tests/integration-tests/mix-fetch/package.json b/sdk/typescript/tests/integration-tests/mix-fetch/package.json deleted file mode 100644 index f9b50ae5a6..0000000000 --- a/sdk/typescript/tests/integration-tests/mix-fetch/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "mix-fetch-tests-runner", - "version": "1.0.0", - "dependencies": { - "serve-handler": "^6.1.5", - "puppeteer": "^24.4.0" - } -} diff --git a/sdk/typescript/tests/integration-tests/mix-fetch/template/parcel/package.json b/sdk/typescript/tests/integration-tests/mix-fetch/template/parcel/package.json deleted file mode 100644 index ea5e8f909a..0000000000 --- a/sdk/typescript/tests/integration-tests/mix-fetch/template/parcel/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "@nymproject/mix-fetch-tester-parcel", - "version": "1.0.0", - "license": "Apache-2.0", - "source": "src/index.html", - "dependencies": { - "@nymproject/mix-fetch": "file:../../../../../../dist/ts/sdk/mix-fetch/esm" - }, - "scripts": { - "start": "npx parcel --no-cache", - "build": "npx parcel build --no-cache --no-optimize", - "serve": "npx serve dist" - } -} diff --git a/sdk/typescript/tests/integration-tests/mix-fetch/template/src/index.html b/sdk/typescript/tests/integration-tests/mix-fetch/template/src/index.html deleted file mode 100644 index d1c190494a..0000000000 --- a/sdk/typescript/tests/integration-tests/mix-fetch/template/src/index.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - Internal Tester - - - - -

Internal tester

-

Open dev tools to see more output and errors

-

-
- - - diff --git a/sdk/typescript/tests/integration-tests/mix-fetch/template/src/index.ts b/sdk/typescript/tests/integration-tests/mix-fetch/template/src/index.ts deleted file mode 100644 index 35fdf33e59..0000000000 --- a/sdk/typescript/tests/integration-tests/mix-fetch/template/src/index.ts +++ /dev/null @@ -1,59 +0,0 @@ -'$IMPORT_STATEMENT'; - -function appendOutput(value: string, id?: string) { - const el = document.getElementById('output') as HTMLPreElement; - const div = document.createElement('div'); - if (id) { - div.id = id; - } - const text = document.createTextNode(`${value}\n`); - div.appendChild(text); - el.appendChild(div); -} - -function appendImageOutput(url: string) { - const el = document.getElementById('outputImage') as HTMLPreElement; - const imgNode = document.createElement('img'); - imgNode.src = url; - el.appendChild(imgNode); -} - -/** - * The main entry point - */ -async function main() { - appendOutput('Tester is starting up...', 'starting'); - - const url = 'https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt'; - appendOutput(`Using mixFetch to get ${url}...`); - const args = { mode: 'unsafe-ignore-cors' }; - - const resp = await mixFetch(url, args, { - preferredGateway: '6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B', // with WSS - preferredNetworkRequester: - '8rRGWy54oC8drFL9DepMegBt2DLrsqQwCoHMXt9nsnTo.2XjCPVbb4FpQ9hNRcXwb9mTzEAVVk1zf1tcch3wdtNEA@6Gb7ftQdKveMjPyrxDXeAtfYAX7Zg5mVZHtnRC5MmZ1B', - }); - console.log({ resp }); - const text = await resp.text(); - - appendOutput(JSON.stringify(resp, null, 2), 'text-output'); - appendOutput(JSON.stringify({ text }, null, 2)); - - // // get an image - // url = 'https://nymtech.net/favicon.svg'; - // resp = await mixFetch(url, args); - // console.log({ resp }); - // const buffer = await resp.arrayBuffer(); - // const type = resp.headers.get('Content-Type') || 'image/svg'; - // const blobUrl = URL.createObjectURL(new Blob([buffer], { type })); - // appendOutput(JSON.stringify({ bufferBytes: buffer.byteLength, blobUrl }, null, 2), 'image-output'); - // appendImageOutput(blobUrl); - - appendOutput('✅ Done', 'done'); -} - -// wait for the html to load -window.addEventListener('DOMContentLoaded', () => { - // let's do this! - main(); -}); diff --git a/sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/package.json b/sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/package.json deleted file mode 100644 index 47de127c34..0000000000 --- a/sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/package.json +++ /dev/null @@ -1,57 +0,0 @@ -{ - "name": "@nymproject/mix-fetch-tester-webpack", - "version": "1.0.0", - "license": "Apache-2.0", - "dependencies": { - "@nymproject/mix-fetch": "file:../../../../../../dist/ts/sdk/mix-fetch/esm" - }, - "devDependencies": { - "@babel/core": "^7.15.0", - "@babel/plugin-transform-async-to-generator": "^7.14.5", - "@babel/preset-env": "^7.15.0", - "@babel/preset-typescript": "^7.15.0", - "@types/jest": "^27.0.1", - "@types/node": "^16.7.13", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", - "babel-loader": "^8.3.0", - "babel-plugin-root-import": "^5.1.0", - "clean-webpack-plugin": "^4.0.0", - "copy-webpack-plugin": "^11.0.0", - "css-loader": "^6.7.3", - "css-minimizer-webpack-plugin": "^3.0.2", - "dotenv-webpack": "^7.0.3", - "eslint": "^8.10.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^16.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", - "file-loader": "^6.2.0", - "fork-ts-checker-webpack-plugin": "^7.2.1", - "html-webpack-plugin": "^5.3.2", - "jest": "^27.1.0", - "mini-css-extract-plugin": "^2.2.2", - "npm-run-all": "^4.1.5", - "prettier": "^2.8.7", - "style-loader": "^3.3.1", - "thread-loader": "^3.0.4", - "ts-jest": "^27.0.5", - "ts-loader": "^9.4.2", - "tsconfig-paths-webpack-plugin": "^3.5.2", - "typescript": "^4.6.2", - "url-loader": "^4.1.1", - "webpack": "^5.75.0", - "webpack-cli": "^4.8.0", - "webpack-dev-server": "^4.5.0", - "webpack-merge": "^5.8.0" - }, - "scripts": { - "start": "webpack serve --progress --port 3000", - "build": "webpack build --progress --config webpack.prod.js", - "serve": "npx serve dist" - } -} diff --git a/sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/tsconfig.json b/sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/tsconfig.json deleted file mode 100644 index 2d9ec75afa..0000000000 --- a/sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "../../../../../../../tsconfig.json", - "compilerOptions": { - "module": "ESNext", - "outDir": "./dist" - }, - "exclude": ["node_modules", "build", "dist"] -} diff --git a/sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/webpack.base.js b/sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/webpack.base.js deleted file mode 100644 index fb9a7f2f5b..0000000000 --- a/sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/webpack.base.js +++ /dev/null @@ -1,91 +0,0 @@ -const HtmlWebpackPlugin = require('html-webpack-plugin'); -const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); -// const { CleanWebpackPlugin } = require('clean-webpack-plugin'); -const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin'); -const WebpackFavicons = require('webpack-favicons'); -const Dotenv = require('dotenv-webpack'); -const path = require('path'); -const os = require('os'); - -/** - * Creates the default Webpack config - * @param baseDir The base directory path, e.g. pass `__dirname` of the webpack config file using this method - */ -const webpackCommon = (baseDir, htmlPath) => ({ - module: { - rules: [ - { - test: /\.tsx?$/, - use: [ - { - loader: 'thread-loader', - options: { workers: Math.max(2, os.cpus().length - 1) }, - }, - { loader: 'ts-loader', options: { happyPackMode: true } }, - ], - exclude: /node_modules/, - }, - { - test: /\.css$/i, - use: ['style-loader', 'css-loader'], - }, - { - test: /\.svg$/i, - issuer: /\.[jt]sx?$/, - use: ['@svgr/webpack'], - }, - { - test: /\.(png|jpe?g|gif|md|webp)$/i, - // More information here https://webpack.js.org/guides/asset-modules/ - type: 'asset', - }, - { - // See https://webpack.js.org/guides/asset-management/#loading-fonts - test: /\.(woff|woff2|eot|ttf|otf)$/i, - type: 'asset/resource', - }, - { - test: /\.ya?ml$/, - type: 'json', - use: 'yaml-loader', - }, - ], - }, - resolve: { - extensions: ['.tsx', '.ts', '.js'], - plugins: [new TsconfigPathsPlugin()], - alias: { - 'react/jsx-runtime': require.resolve('react/jsx-runtime'), - }, - }, - plugins: [ - // new CleanWebpackPlugin(), - - ...(Array.isArray(htmlPath) - ? htmlPath.map((item) => new HtmlWebpackPlugin(item)) - : [ - new HtmlWebpackPlugin({ - filename: 'index.html', - template: path.resolve(baseDir, htmlPath || 'src/index.html'), - }), - ]), - - new ForkTsCheckerWebpackPlugin({ - typescript: { - mode: 'write-references', - diagnosticOptions: { - semantic: true, - syntactic: true, - }, - }, - }), - ], - output: { - path: path.resolve(baseDir, 'dist'), - publicPath: '/', - }, -}); - -module.exports = { - webpackCommon, -}; diff --git a/sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/webpack.common.js b/sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/webpack.common.js deleted file mode 100644 index 9d86d2bc80..0000000000 --- a/sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/webpack.common.js +++ /dev/null @@ -1,30 +0,0 @@ -const path = require('path'); -const { mergeWithRules } = require('webpack-merge'); -const { webpackCommon } = require('./webpack.base'); - -module.exports = mergeWithRules({ - module: { - rules: { - test: 'match', - use: 'replace', - }, - }, -})( - webpackCommon(__dirname, [ - { - inject: true, - filename: 'index.html', - template: path.resolve(__dirname, 'src/index.html'), - chunks: ['index'], - }, - ]), - { - entry: { - index: path.resolve(__dirname, 'src/index.ts'), - }, - output: { - path: path.resolve(__dirname, 'dist'), - publicPath: '/', - }, - }, -); diff --git a/sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/webpack.config.js b/sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/webpack.config.js deleted file mode 100644 index 3558bfdade..0000000000 --- a/sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/webpack.config.js +++ /dev/null @@ -1,71 +0,0 @@ -const { mergeWithRules } = require('webpack-merge'); -const webpack = require('webpack'); -const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin'); -const ReactRefreshTypeScript = require('react-refresh-typescript'); -const commonConfig = require('./webpack.common'); - -module.exports = mergeWithRules({ - module: { - rules: { - test: 'match', - use: 'replace', - }, - }, -})(commonConfig, { - mode: 'development', - devtool: 'inline-source-map', - module: { - rules: [ - { - test: /\.tsx?$/, - use: 'ts-loader', - exclude: /node_modules/, - options: { - getCustomTransformers: () => ({ - before: [ReactRefreshTypeScript()], - }), - // `ts-loader` does not work with HMR unless `transpileOnly` is used. - // If you need type checking, `ForkTsCheckerWebpackPlugin` is an alternative. - transpileOnly: true, - }, - }, - { - test: /\.wasm$/, - type: 'asset', - }, - ], - }, - plugins: [ - new ReactRefreshWebpackPlugin(), - - // this can be included automatically by the dev server, however build mode fails if missing - new webpack.HotModuleReplacementPlugin(), - ], - - target: 'web', - - devServer: { - headers: { - 'Access-Control-Allow-Origin': '*', - 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, PATCH, OPTIONS', - 'Access-Control-Allow-Headers': 'Content-Type, Authorization', - }, - historyApiFallback: true, - }, - - // recommended for faster rebuild - optimization: { - runtimeChunk: true, - removeAvailableModules: false, - removeEmptyChunks: false, - splitChunks: false, - }, - - cache: { - type: 'filesystem', - buildDependencies: { - // restart on config change - config: ['./webpack.config.js'], - }, - }, -}); diff --git a/sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/webpack.plugins.js b/sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/webpack.plugins.js deleted file mode 100644 index d1d3af9d2b..0000000000 --- a/sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/webpack.plugins.js +++ /dev/null @@ -1,19 +0,0 @@ -const path = require('path'); -const CopyPlugin = require('copy-webpack-plugin'); - -module.exports = { - plugins: [ - new CopyPlugin({ - patterns: [ - { - from: path.resolve(path.dirname(require.resolve('$PACKAGE/package.json')), '*.wasm'), - to: '[name][ext]', - }, - { - from: path.resolve(path.dirname(require.resolve('$PACKAGE/package.json')), '*worker*.js'), - to: '[name][ext]', - }, - ], - }), - ], -}; diff --git a/sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/webpack.prod.js b/sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/webpack.prod.js deleted file mode 100644 index 9bf9d4fdde..0000000000 --- a/sdk/typescript/tests/integration-tests/mix-fetch/template/webpack/webpack.prod.js +++ /dev/null @@ -1,44 +0,0 @@ -const { mergeWithRules } = require('webpack-merge'); -const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); -const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const commonConfig = require('./webpack.common'); -const { plugins } = require('./webpack.plugins'); - -module.exports = mergeWithRules({ - module: { - rules: { - test: 'match', - use: 'replace', - }, - }, -})(commonConfig, { - mode: 'production', - - // TODO: no source maps, add back - devtool: false, - - module: { - rules: [ - { - test: /\.css$/, - use: [MiniCssExtractPlugin.loader, 'css-loader'], - }, - ], - }, - optimization: { - minimizer: ['...', new CssMinimizerPlugin()], - splitChunks: { - chunks: 'all', - }, - }, - plugins: [ - new MiniCssExtractPlugin({ - filename: '[name].[contenthash].css', - }), - ...plugins, - ], - output: { - pathinfo: false, - filename: '[name].[contenthash].js', - }, -}); diff --git a/sdk/typescript/tests/integration-tests/mix-fetch/template/workspace/package.json b/sdk/typescript/tests/integration-tests/mix-fetch/template/workspace/package.json deleted file mode 100644 index c6e6e1f1cb..0000000000 --- a/sdk/typescript/tests/integration-tests/mix-fetch/template/workspace/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "integration-tests-workspace", - "version": "1.0.0", - "private": true, - "license": "Apache 2.0", - "workspaces": [ - "packages/**" - ] -} diff --git a/sdk/typescript/tests/integration-tests/mix-fetch/tests/tests.mjs b/sdk/typescript/tests/integration-tests/mix-fetch/tests/tests.mjs deleted file mode 100644 index d74f89b6c3..0000000000 --- a/sdk/typescript/tests/integration-tests/mix-fetch/tests/tests.mjs +++ /dev/null @@ -1,88 +0,0 @@ -/* eslint-disable no-await-in-loop */ -import puppeteer from 'puppeteer'; - -const TIMEOUT = 30_000; - -function sleep(time) { - return new Promise((resolve) => { - setTimeout(resolve, time); - }); -} - -export async function runTests(log) { - console.log('🟡 Starting puppeteer'); - // launch Chrome and navigate - const browser = await puppeteer.launch({ headless: 'new' }); - const page = await browser.newPage(); - await page.setDefaultNavigationTimeout(TIMEOUT); // timeout 60 seconds now - - const errors = []; - - page.on('console', (message) => { - let isError = false; - if (message.type() === 'error') { - if (!message.location()?.url?.endsWith('favicon.ico')) { - isError = true; - const { url } = message.location(); - const type = message.type(); - const text = message.text ? message.text() : undefined; - errors.push({ type, url, text }); - } - } - if (log || isError) { - console.log(` Message: [${message.type()}] ${message.text()}`); - if (isError) { - message.stackTrace().forEach((args) => console.log(` - ${args.lineNumber}:${args.columnNumber} ${args.url}`)); - } - } - }); - - console.log(' 🟡 Navigating'); - let count = 0; - do { - await sleep(1000); - try { - const res = await page.goto('http://localhost:3000', {}); - if (res.ok()) { - break; - } - } catch (e) { - console.log(' ❌ Error', e.message); - } - count += 1; - } while (count < 5); - if (count > 5) { - await browser.close(); - throw new Error('Failed to navigate'); - } else { - console.log(' 🟡 Navigated'); - } - - // wait for start output - await page.waitForSelector('#starting'); - - if (errors.find((e) => e.url.includes('worker'))) { - console.log(' ❌ Error - worker did not load'); - return errors; - } - if (errors.length) { - console.log(' ❌ Error - worker error'); - return errors; - } - - console.log(' 🟢 Started'); - - await page.waitForSelector('#text-output', { timeout: TIMEOUT }); - console.log(' 🟢 Got text output'); - // await page.waitForSelector('#image-output'); - // console.log(' 🟢 Got image output'); - await page.waitForSelector('#done'); - console.log(' 🟢 Got done'); - - await page.close(); - await browser.close(); - - console.log(' ✅ test complete'); - - return errors; -} diff --git a/tools/internal/sdk-version-bump/README.md b/tools/internal/sdk-version-bump/README.md index 0b161568be..ac95a51f62 100644 --- a/tools/internal/sdk-version-bump/README.md +++ b/tools/internal/sdk-version-bump/README.md @@ -1,19 +1,62 @@ # sdk-version-bump -simple tool to update version numbers of our sdk packages. +Tool to update version numbers across the SDK packages, both Cargo +(`wasm/smolmix`, `wasm/client`) and TS (`@nymproject/mix-tunnel`, +`@nymproject/mix-fetch`, `@nymproject/mix-dns`, `@nymproject/mix-websocket`, +plus the legacy `@nymproject/sdk` family). -## Usage: +## Usage -note: this tool is expected to be run during CI, but if one wants to do it manually: +This tool is expected to be run by CI; the snippets below are for manual use +from the repo root. -### For releases: +### Full release (Rust + TS in parity) -1. run `./sdk-version-bump remove-suffix` that will remove the `-rc.X` suffixes from all relevant packages -2. build everything and publish it to npm -3. run `./sdk-version-bump bump-version` that will update the versions of all relevant packages from `X.Y.Z` into `X.Y.(Z+1)-rc.0`. It will also update the `@nymproject/...` dependencies from `">=X.Y.Z-rc.0 || ^X"` to `">=X.Y.(Z+1)-rc.0 || ^X"` +This is the default. Use it when smolmix-wasm has changed and the TS SDK +must publish a matching version. -### For pre-releases: +1. `cargo run -p sdk-version-bump remove-suffix` +2. Build everything and publish to crates.io / npm. +3. `cargo run -p sdk-version-bump bump-version` — bumps every package from + `X.Y.Z` to `X.Y.(Z+1)-rc.0`, and rewrites every `@nymproject/...` dep + specifier of the form `>=X.Y.Z-rc.W || ^X` accordingly. -1. run `./sdk-version-bump bump-version --pre-release` that will update the release candidate version of all relevant packages from `X.Y.Z-rc.W` to `X.Y.Z-rc.(W+1)` +### TS-only release -To run it from the root, do: `cargo run -p sdk-version-bump` \ No newline at end of file +Use this when the TS SDK needs a bump but smolmix-wasm itself hasn't changed. +The Cargo crates are left untouched, and downstream package.json files keep +their existing dep ranges for `@nymproject/smolmix-wasm` and +`@nymproject/nym-client-wasm` (so they continue to resolve to the last +published wasm version). + +1. `cargo run -p sdk-version-bump remove-suffix --ts-only` +2. Build the TS packages and publish to npm. +3. `cargo run -p sdk-version-bump bump-version --ts-only` + +### Pre-release (rc bump) + +To increment just the `-rc.X` counter (`X.Y.Z-rc.W` → `X.Y.Z-rc.W+1`): + +``` +cargo run -p sdk-version-bump bump-version --pre-release +``` + +Combine with `--ts-only` if you're rc-bumping the TS layer alone. + +## What gets touched + +| What | Where it's declared | Behaviour under `--ts-only` | +|---|---|---| +| `Cargo.toml` `package.version` of each Cargo crate | `register_cargo(...)` | skipped | +| `package.json` `version` of each TS package | `register_json(...)` | bumped | +| `@nymproject/...` dep ranges in `dependencies` / `peerDependencies` / `devDependencies` / `optionalDependencies` / `bundledDependencies` | `register_known_js_dependency(...)` | bumped, except cargo-derived ones | +| Cargo-derived JS dep ranges (`@nymproject/smolmix-wasm`, `@nymproject/nym-client-wasm`) | `register_cargo_derived_js_dependency(...)` | left alone | +| `workspace:*`, `file:..`, `link:..`, `npm:..` specifiers | n/a (skipped at parse time) | always skipped — pnpm rewrites them at publish | + +## Adding a new package + +1. If it's a Cargo crate: `packages.register_cargo("relative/path")`. +2. If it's a TS package: `packages.register_json("relative/path")`. +3. If the package is consumed by other packages as a dep, also add its npm + name to either `register_known_js_dependency` (TS-driven version) or + `register_cargo_derived_js_dependency` (wasm-pack-driven version). diff --git a/tools/internal/sdk-version-bump/src/json.rs b/tools/internal/sdk-version-bump/src/json.rs index f4894db834..381f327fec 100644 --- a/tools/internal/sdk-version-bump/src/json.rs +++ b/tools/internal/sdk-version-bump/src/json.rs @@ -22,6 +22,18 @@ fn update_dependencies( ) -> anyhow::Result<()> { for (package, version) in deps.iter_mut() { if names.contains(package) { + // Locally-linked specifiers (`workspace:*`, `file:..`, `link:..`) + // are managed by pnpm at publish time, not by this tool. Skip them + // so we don't try to parse them as semver ranges and bail. + if version.starts_with("workspace:") + || version.starts_with("file:") + || version.starts_with("link:") + || version.starts_with("npm:") + { + println!("\t\t>>> skipping '{package}' (locally linked: {version})"); + continue; + } + let updated = if pre_release { try_bump_prerelease_version_req(version)? } else { diff --git a/tools/internal/sdk-version-bump/src/main.rs b/tools/internal/sdk-version-bump/src/main.rs index 9c419ad626..c6809acfde 100644 --- a/tools/internal/sdk-version-bump/src/main.rs +++ b/tools/internal/sdk-version-bump/src/main.rs @@ -72,7 +72,13 @@ struct Args { #[derive(Subcommand)] enum Commands { /// Will strip any `-rc.X` suffixes from the package versions - RemoveSuffix, + RemoveSuffix { + /// If set, only TypeScript (package.json) packages are touched and the + /// Rust (Cargo.toml) packages are left alone. Use when shipping a + /// TS-only release without bumping `wasm/smolmix`. + #[arg(long)] + ts_only: bool, + }, /// Will update the versions of all relevant packages from `X.Y.Z` into `X.Y.(Z+1)-rc.0`. /// It will also update the `@nymproject/...` dependencies from `">=X.Y.Z-rc.0 || ^X"` to `">=X.Y.(Z+1)-rc.0 || ^X"` @@ -81,6 +87,13 @@ enum Commands { /// If enabled, the packages will only have their rc version bumped and the dependencies /// will get updated from `">=X.Y.Z-rc.W || ^X"` to `">=X.Y.Z-rc.(W+1) || ^X"` pre_release: bool, + + /// If set, only TypeScript (package.json) packages are bumped and the + /// Rust (Cargo.toml) packages are left alone. Use this when the TS SDK + /// needs a release without an underlying smolmix-wasm change. Default + /// is parity (Rust + TS together). + #[arg(long)] + ts_only: bool, }, } @@ -152,7 +165,16 @@ struct InternalPackages { cargo: HashSet, json: HashSet, + /// All `@nymproject/...` dep names whose specifiers should get bumped + /// alongside the source package versions. internal_js_dependencies: HashSet, + + /// Subset of `internal_js_dependencies` whose source-of-truth is a Cargo + /// crate (the wasm-pack-generated `pkg/package.json`). Under `--ts-only`, + /// the Cargo crate isn't bumped, so its dep specifiers must NOT be bumped + /// either — otherwise downstream package.jsons end up pinning a version + /// that was never published. + cargo_derived_js_dependencies: HashSet, } impl InternalPackages { @@ -162,6 +184,7 @@ impl InternalPackages { cargo: Default::default(), json: Default::default(), internal_js_dependencies: Default::default(), + cargo_derived_js_dependencies: Default::default(), } } @@ -177,11 +200,22 @@ impl InternalPackages { self.internal_js_dependencies.insert(name.into()); } - pub fn remove_suffix(&self) -> Summary { + /// Register a JS dep whose version is driven by a Cargo crate (and thus + /// regenerated from `Cargo.toml` by wasm-pack). Implicitly also adds it to + /// the general known-deps set so it gets bumped during a full release. + pub fn register_cargo_derived_js_dependency>(&mut self, name: S) { + let name = name.into(); + self.internal_js_dependencies.insert(name.clone()); + self.cargo_derived_js_dependencies.insert(name); + } + + pub fn remove_suffix(&self, ts_only: bool) -> Summary { let mut cargo_results = HashMap::new(); - for cargo_package in &self.cargo { - let res = remove_suffix::(&self.root, cargo_package); - cargo_results.insert(cargo_package.clone(), res); + if !ts_only { + for cargo_package in &self.cargo { + let res = remove_suffix::(&self.root, cargo_package); + cargo_results.insert(cargo_package.clone(), res); + } } let mut json_results = HashMap::new(); @@ -193,24 +227,38 @@ impl InternalPackages { Summary::new(cargo_results, json_results) } - pub fn bump_version(&self, pre_release: bool) -> Summary { + pub fn bump_version(&self, pre_release: bool, ts_only: bool) -> Summary { let mut cargo_results = HashMap::new(); - for cargo_package in &self.cargo { - let res = bump_version::( - &self.root, - cargo_package, - &Default::default(), - pre_release, - ); - cargo_results.insert(cargo_package.clone(), res); + if !ts_only { + for cargo_package in &self.cargo { + let res = bump_version::( + &self.root, + cargo_package, + &Default::default(), + pre_release, + ); + cargo_results.insert(cargo_package.clone(), res); + } } + // Under --ts-only the wasm/Cargo crates aren't getting a new version, + // so we must NOT bump downstream `>=X.Y.Z || ^X` specifiers that point + // at them either. + let deps_to_update: HashSet = if ts_only { + self.internal_js_dependencies + .difference(&self.cargo_derived_js_dependencies) + .cloned() + .collect() + } else { + self.internal_js_dependencies.clone() + }; + let mut json_results = HashMap::new(); for package_json in &self.json { let res = bump_version::( &self.root, package_json, - &self.internal_js_dependencies, + &deps_to_update, pre_release, ); json_results.insert(package_json.clone(), res); @@ -223,19 +271,23 @@ impl InternalPackages { fn initialise_internal_packages>(root: P) -> InternalPackages { let mut packages = InternalPackages::new(root); - // cargo packages that will have their Cargo.toml modified - packages.register_cargo("wasm/mix-fetch"); + // cargo packages that will have their Cargo.toml modified. + // `wasm/smolmix` replaces the legacy `wasm/mix-fetch`; smolmix is the + // only wasm crate that ships TS-SDK-facing bindings now. + packages.register_cargo("wasm/smolmix"); packages.register_cargo("wasm/client"); - // js packages that will have their package.json modified + // js packages that will have their package.json modified. packages.register_json("nym-wallet"); packages.register_json("sdk/typescript/docs"); packages.register_json("sdk/typescript/examples/chat-app/parcel"); packages.register_json("sdk/typescript/examples/chat-app/plain-html"); packages.register_json("sdk/typescript/examples/chat-app/react-webpack-with-theme-example"); packages.register_json("sdk/typescript/examples/mix-fetch/browser"); + packages.register_json("sdk/typescript/packages/mix-tunnel"); packages.register_json("sdk/typescript/packages/mix-fetch"); - packages.register_json("sdk/typescript/packages/mix-fetch-node"); + packages.register_json("sdk/typescript/packages/mix-dns"); + packages.register_json("sdk/typescript/packages/mix-websocket"); packages.register_json("sdk/typescript/packages/mix-fetch/internal-dev"); packages.register_json("sdk/typescript/packages/mix-fetch/internal-dev/parcel"); packages.register_json("sdk/typescript/packages/nodejs-client"); @@ -243,22 +295,24 @@ fn initialise_internal_packages>(root: P) -> InternalPackages { packages.register_json("sdk/typescript/packages/sdk-react"); packages.register_json("sdk/typescript/codegen/contract-clients"); - // dependencies that will have their versions adjusted in the above packages + // dependencies that will have their versions adjusted in the above packages. - // WASM NodeJS - packages.register_known_js_dependency("@nymproject/nym-client-wasm-node"); - packages.register_known_js_dependency("@nymproject/mix-fetch-wasm-node"); - - // WASM - packages.register_known_js_dependency("@nymproject/nym-client-wasm"); - packages.register_known_js_dependency("@nymproject/mix-fetch-wasm"); + // WASM packages. Their package.json is generated by wasm-pack from the + // corresponding Cargo crate, so they're tracked as cargo-derived: a + // `--ts-only` bump leaves their dep specifiers alone. + packages.register_cargo_derived_js_dependency("@nymproject/nym-client-wasm"); + packages.register_cargo_derived_js_dependency("@nymproject/smolmix-wasm"); + // smolmix-based TS SDKs. + packages.register_known_js_dependency("@nymproject/mix-tunnel"); packages.register_known_js_dependency("@nymproject/mix-fetch"); - packages.register_known_js_dependency("@nymproject/mix-fetch-full-fat"); + packages.register_known_js_dependency("@nymproject/mix-dns"); + packages.register_known_js_dependency("@nymproject/mix-websocket"); + + // Other SDK packages. packages.register_known_js_dependency("@nymproject/mui-theme"); packages.register_known_js_dependency("@nymproject/react-components"); packages.register_known_js_dependency("@nymproject/sdk"); - packages.register_known_js_dependency("@nymproject/sdk-full-fat"); packages.register_known_js_dependency("@nymproject/sdk-react"); packages.register_known_js_dependency("@nymproject/react"); packages.register_known_js_dependency("@nymproject/nym-validator-client"); @@ -273,8 +327,11 @@ fn main() -> anyhow::Result<()> { let packages = initialise_internal_packages(args.root); let summary = match args.command { - Commands::RemoveSuffix => packages.remove_suffix(), - Commands::BumpVersion { pre_release } => packages.bump_version(pre_release), + Commands::RemoveSuffix { ts_only } => packages.remove_suffix(ts_only), + Commands::BumpVersion { + pre_release, + ts_only, + } => packages.bump_version(pre_release, ts_only), }; summary.print(); diff --git a/wasm/mix-fetch/.cargo/config.toml b/wasm/mix-fetch/.cargo/config.toml deleted file mode 100644 index e9c3438b6e..0000000000 --- a/wasm/mix-fetch/.cargo/config.toml +++ /dev/null @@ -1,4 +0,0 @@ -[build] -target = "wasm32-unknown-unknown" -target_arch = "wasm32" -rustflags = ["--cfg=getrandom_backend=\"wasm_js\""] \ No newline at end of file diff --git a/wasm/mix-fetch/Cargo.toml b/wasm/mix-fetch/Cargo.toml deleted file mode 100644 index 8fca01cdc8..0000000000 --- a/wasm/mix-fetch/Cargo.toml +++ /dev/null @@ -1,41 +0,0 @@ -[package] -name = "mix-fetch-wasm" -version = "1.4.3" -authors = ["Jedrzej Stuczynski "] -edition = "2021" -license = "Apache-2.0" -repository = "https://github.com/nymtech/nym" -rust-version = "1.85" -publish = false -keywords = ["nym", "fetch", "wasm", "webassembly", "privacy"] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[lib] -crate-type = ["cdylib", "rlib"] - -[dependencies] -async-trait = { workspace = true } -futures = { workspace = true } -js-sys = { workspace = true } -rand = { workspace = true } -serde = { workspace = true, features = ["derive"] } -serde-wasm-bindgen = { workspace = true } -tokio = { workspace = true, features = ["sync"] } -url = { workspace = true } -wasm-bindgen = { workspace = true } -wasm-bindgen-futures = { workspace = true } -thiserror = { workspace = true } -tsify = { workspace = true, features = ["js"] } - -nym-bin-common = { workspace = true } -nym-http-api-client = { workspace = true } -nym-socks5-requests = { workspace = true } -nym-ordered-buffer = { workspace = true } -nym-service-providers-common = { workspace = true } -nym-validator-client = { workspace = true, default-features = false } -nym-wasm-client-core = { workspace = true } -nym-wasm-utils = { workspace = true } - -[package.metadata.wasm-pack.profile.release] -wasm-opt = false diff --git a/wasm/mix-fetch/Makefile b/wasm/mix-fetch/Makefile deleted file mode 100644 index 1f55c9846f..0000000000 --- a/wasm/mix-fetch/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -UNAME_S := $(shell uname -s) -ifeq ($(UNAME_S),Linux) - TASKSET := taskset -c 0-11 -else - TASKSET := -endif - -build: build-go-opt build-rust build-package-json - -check-fmt: check-fmt-go check-fmt-rust - -build-go: - $(MAKE) -C go-mix-conn build-go - -build-go-opt: - $(MAKE) -C go-mix-conn build-go-opt - -build-rust: - $(TASKSET) wasm-pack build --scope nymproject --target web --out-dir ../../dist/wasm/mix-fetch - # $(TASKSET) wasm-pack build --scope nymproject --target no-modules --out-dir ../../dist/wasm/mix-fetch - $(TASKSET) wasm-opt -Oz -o ../../dist/wasm/mix-fetch/mix_fetch_wasm_bg.wasm ../../dist/wasm/mix-fetch/mix_fetch_wasm_bg.wasm - -build-rust-debug: - wasm-pack build --debug --scope nymproject --target no-modules - -build-package-json: - node build.mjs - -check-fmt-go: - $(MAKE) -C go-mix-conn check-fmt - -check-fmt-rust: - cargo fmt --check - cargo clippy --target wasm32-unknown-unknown -- -Dwarnings diff --git a/wasm/mix-fetch/build-node.mjs b/wasm/mix-fetch/build-node.mjs deleted file mode 100644 index 5bd3128c04..0000000000 --- a/wasm/mix-fetch/build-node.mjs +++ /dev/null @@ -1,14 +0,0 @@ -import fs from 'fs'; - -const packageJson = JSON.parse(fs.readFileSync('../../dist/node/wasm/mix-fetch/package.json').toString()); - -packageJson.name = `${packageJson.name}-node`; - -if (!packageJson.files.includes('go_conn.wasm')) { - packageJson.files.push('go_conn.wasm'); -} -if (!packageJson.files.includes('wasm_exec.js')) { - packageJson.files.push('wasm_exec.js'); -} - -fs.writeFileSync('../../dist/node/wasm/mix-fetch/package.json', JSON.stringify(packageJson, null, 2)); diff --git a/wasm/mix-fetch/build.mjs b/wasm/mix-fetch/build.mjs deleted file mode 100644 index 5626beb736..0000000000 --- a/wasm/mix-fetch/build.mjs +++ /dev/null @@ -1,12 +0,0 @@ -import fs from 'fs'; - -const packageJson = JSON.parse(fs.readFileSync('../../dist/wasm/mix-fetch/package.json').toString()); - -if (!packageJson.files.includes('go_conn.wasm')) { - packageJson.files.push('go_conn.wasm'); -} -if (!packageJson.files.includes('wasm_exec.js')) { - packageJson.files.push('wasm_exec.js'); -} - -fs.writeFileSync('../../dist/wasm/mix-fetch/package.json', JSON.stringify(packageJson, null, 2)); \ No newline at end of file diff --git a/wasm/mix-fetch/go-mix-conn/.gitignore b/wasm/mix-fetch/go-mix-conn/.gitignore deleted file mode 100644 index 433d6e554e..0000000000 --- a/wasm/mix-fetch/go-mix-conn/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -build/wasm_exec.js -build/main.wasm -build \ No newline at end of file diff --git a/wasm/mix-fetch/go-mix-conn/Makefile b/wasm/mix-fetch/go-mix-conn/Makefile deleted file mode 100644 index b1d0988944..0000000000 --- a/wasm/mix-fetch/go-mix-conn/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -ifndef $(GOROOT) - GOROOT=$(shell go env GOROOT) - export GOROOT -endif - -build-debug-dev: - GOOS=js GOARCH=wasm go build -o build/go_conn.wasm ./cmd/wasm - cp "$(GOROOT)/lib/wasm/wasm_exec.js" build - -build-go: - GOOS=js GOARCH=wasm go build -o ../../../dist/wasm/mix-fetch/go_conn.wasm ./cmd/wasm - cp "$(GOROOT)/lib/wasm/wasm_exec.js" ../../../dist/wasm/mix-fetch - - -build-go-opt: -# use the -s and -w linker flags to strip the debugging information - GOOS=js GOARCH=wasm go build -ldflags="-s -w" -o ../../../dist/wasm/mix-fetch/go_conn.wasm ./cmd/wasm - cp "$(GOROOT)/lib/wasm/wasm_exec.js" ../../../dist/wasm/mix-fetch - -# run wasm-opt to gain few more kb - wasm-opt --enable-bulk-memory -Oz ../../../dist/wasm/mix-fetch/go_conn.wasm -o ../../../dist/wasm/mix-fetch/go_conn.wasm -# finally compress it (... or not?) - -check-fmt: - test -z $(gofmt -l .) diff --git a/wasm/mix-fetch/go-mix-conn/cmd/wasm/main.go b/wasm/mix-fetch/go-mix-conn/cmd/wasm/main.go deleted file mode 100644 index cdd2638cf1..0000000000 --- a/wasm/mix-fetch/go-mix-conn/cmd/wasm/main.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -//go:build js && wasm - -package main - -import ( - "go-mix-conn/internal/bridge/go_bridge" - "go-mix-conn/internal/state" -) - -var done chan struct{} - -func init() { - println("[go init]: go module init") - - done = make(chan struct{}) - state.InitialiseGlobalState() - - println("[go init]: go module init finished") -} - -func main() { - println("[go main]: go module loaded") - - go_bridge.InitialiseGoBridge() - <-done - - println("[go main]: go module finished") -} diff --git a/wasm/mix-fetch/go-mix-conn/go.mod b/wasm/mix-fetch/go-mix-conn/go.mod deleted file mode 100644 index 52d9f2bed5..0000000000 --- a/wasm/mix-fetch/go-mix-conn/go.mod +++ /dev/null @@ -1,7 +0,0 @@ -module go-mix-conn - -go 1.24.0 - -require golang.org/x/net v0.46.0 - -require golang.org/x/text v0.30.0 // indirect diff --git a/wasm/mix-fetch/go-mix-conn/go.sum b/wasm/mix-fetch/go-mix-conn/go.sum deleted file mode 100644 index ee08c3c4fd..0000000000 --- a/wasm/mix-fetch/go-mix-conn/go.sum +++ /dev/null @@ -1,8 +0,0 @@ -golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= -golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= -golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4= -golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= -golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= -golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= diff --git a/wasm/mix-fetch/go-mix-conn/internal/bridge/go_bridge/go_bridge.go b/wasm/mix-fetch/go-mix-conn/internal/bridge/go_bridge/go_bridge.go deleted file mode 100644 index db84d033f3..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/bridge/go_bridge/go_bridge.go +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -package go_bridge - -import ( - "errors" - "fmt" - "go-mix-conn/internal/bridge/rust_bridge" - "go-mix-conn/internal/helpers" - "go-mix-conn/internal/jstypes" - "go-mix-conn/internal/jstypes/conv" - "go-mix-conn/internal/log" - "go-mix-conn/internal/mixfetch" - "syscall/js" - "time" -) - -const ( - // methods exposed by go to rust - goRustBridgeName = "__go_rs_bridge__" -) - -func createGoBridgeObject() js.Value { - js.Global().Set(goRustBridgeName, jstypes.Object.New()) - goBridgeRoot := js.Global().Get(goRustBridgeName) - return goBridgeRoot -} - -func InitialiseGoBridge() { - goBridgeRoot := createGoBridgeObject() - - // user facing methods - js.Global().Set("mixFetch", jstypes.AsyncFunc(mixFetch)) - js.Global().Set("goWasmSetLogging", js.FuncOf(setLoggingLevel)) - - // rust facing methods (don't expose them to the root) - goBridgeRoot.Set("goWasmSetMixFetchRequestTimeout", js.FuncOf(changeRequestTimeout)) - goBridgeRoot.Set("goWasmInjectServerData", js.FuncOf(injectServerData)) - goBridgeRoot.Set("goWasmCloseRemoteSocket", js.FuncOf(closeRemoteSocket)) - goBridgeRoot.Set("goWasmInjectConnError", js.FuncOf(injectConnError)) -} - -func setLoggingLevel(_ js.Value, args []js.Value) any { - if len(args) == 0 { - return errors.New("no arguments passed for `setLoggingLevel`") - } - - if args[0].Type() != js.TypeString { - return errors.New("the provided logging level is not a string") - } - log.SetLoggingLevel(args[0].String()) - return nil -} - -func mixFetch(_ js.Value, args []js.Value) (any, error) { - if !rust_bridge.RsIsInitialised() { - return nil, errors.New("mix fetch is not available") - } - - if len(args) == 0 { - return nil, errors.New("no arguments passed for `mixfetch`") - } - - requestConstructor := jstypes.Request - - jsRequest := js.Null() - unsafeCors := false - // that's bit weird. can't use the spread operator - if len(args) == 1 { - jsRequest = requestConstructor.New(args[0]) - } - if len(args) == 2 { - if !args[1].IsUndefined() && !args[1].IsNull() { - // check for 'MODE_UNSAFE_IGNORE_CORS' - if args[1].Get("mode").String() == jstypes.ModeUnsafeIgnoreCors { - unsafeCors = true - // we need to delete that prop as technically it holds an invalid value to construct `Request` - args[1].Delete("mode") - } - } - - jsRequest = requestConstructor.New(args[0], args[1]) - } - - goRequest, err := conv.ParseJSRequest(jsRequest, unsafeCors) - if err != nil { - return nil, err - } - - return mixfetch.MixFetch(goRequest) -} - -func injectServerData(_ js.Value, args []js.Value) any { - if len(args) != 2 { - return errors.New(fmt.Sprintf("received invalid number of arguments. Got %d but expected 2", len(args))) - } - requestId, err := helpers.ParseRequestId(args[0]) - if err != nil { - return err - } - data, err := helpers.IntoGoBytes(args[1]) - if err != nil { - return err - } - - return mixfetch.InjectServerData(requestId, data) -} - -func injectConnError(_ js.Value, args []js.Value) any { - if len(args) != 2 { - return errors.New(fmt.Sprintf("received invalid number of arguments. Got %d but expected 2", len(args))) - } - - requestId, err := helpers.ParseRequestId(args[0]) - if err != nil { - return err - } - - if args[1].Type() != js.TypeString { - return errors.New("provided error message is not a string") - } - errMsg := args[1].String() - remoteErr := errors.New(errMsg) - - return mixfetch.InjectConnError(requestId, remoteErr) -} - -func closeRemoteSocket(_ js.Value, args []js.Value) any { - if len(args) != 1 { - return errors.New(fmt.Sprintf("received invalid number of arguments. Got %d but expected 1", len(args))) - } - requestId, err := helpers.ParseRequestId(args[0]) - if err != nil { - return err - } - - return mixfetch.CloseRemoteSocket(requestId) -} - -func changeRequestTimeout(_ js.Value, args []js.Value) any { - if len(args) != 1 { - return errors.New(fmt.Sprintf("received invalid number of arguments. Got %d but expected 1", len(args))) - } - - if args[0].Type() != js.TypeNumber { - return errors.New("the provided timeout is not a number") - } - timeoutMs := args[0].Int() - timeout := time.Millisecond * time.Duration(timeoutMs) - - return mixfetch.ChangeRequestTimeout(timeout) -} diff --git a/wasm/mix-fetch/go-mix-conn/internal/bridge/rust_bridge/rust_bridge.go b/wasm/mix-fetch/go-mix-conn/internal/bridge/rust_bridge/rust_bridge.go deleted file mode 100644 index 3c4273eb1a..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/bridge/rust_bridge/rust_bridge.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -// it's not a bridge per se, but it makes it easier to keep track of what rust endpoints we're calling from go - -package rust_bridge - -import ( - "go-mix-conn/internal/helpers" - "go-mix-conn/internal/jstypes" - "go-mix-conn/internal/log" - "go-mix-conn/internal/types" - "strconv" - "syscall/js" -) - -const ( - // methods exposed by rust to go - rustGoBridgeName = "__rs_go_bridge__" -) - -func rsBridge() js.Value { - return js.Global().Get(rustGoBridgeName) -} - -func RsSendClientData(requestId types.RequestId, data []byte) error { - log.Debug("calling rust send_client_data") - - rawRequestId := strconv.FormatUint(requestId, 10) - jsBytes := helpers.IntoJsBytes(data) - - sendPromise := rsBridge().Call("send_client_data", rawRequestId, jsBytes) - _, err := jstypes.Await(sendPromise) - if err != nil { - panic("todo: extract error message") - } - return nil -} - -func RsStartNewMixnetRequest(addr string) (types.RequestId, error) { - log.Debug("calling rust start_new_mixnet_connection") - - requestPromise := rsBridge().Call("start_new_mixnet_connection", addr) - rawRequestId, errRes := jstypes.Await(requestPromise) - if errRes != nil { - panic("todo: extract error message") - } - - if len(rawRequestId) != 1 { - panic("todo: handle error here") - } - - requestId, err := helpers.ParseRequestId(rawRequestId[0]) - if err != nil { - return 0, err - } - - log.Debug("started request has id %d", requestId) - - return requestId, err -} - -func RsIsInitialised() bool { - log.Debug("calling rust mix_fetch_initialised") - - return rsBridge().Call("mix_fetch_initialised").Bool() -} - -func RsFinishMixnetConnection(requestId types.RequestId) error { - log.Debug("calling rust finish_mixnet_connection") - - rawRequestId := strconv.FormatUint(requestId, 10) - - finishPromise := rsBridge().Call("finish_mixnet_connection", rawRequestId) - _, err := jstypes.Await(finishPromise) - if err != nil { - panic("todo: extract error message") - } - return nil -} diff --git a/wasm/mix-fetch/go-mix-conn/internal/external/roundtrip_js.go b/wasm/mix-fetch/go-mix-conn/internal/external/roundtrip_js.go deleted file mode 100644 index 547fdc4b42..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/external/roundtrip_js.go +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file: -// https://github.com/golang/go/blob/release-branch.go1.20/LICENSE - -//go:build js && wasm - -package external - -import ( - "errors" - "io" - "syscall/js" -) - -var errClosed = errors.New("net/http: reader is closed") - -// StreamReader implements an io.ReadCloser wrapper for ReadableStream. -// See https://fetch.spec.whatwg.org/#readablestream for more information. -// SOURCE: https://github.com/golang/go/blob/release-branch.go1.20/src/net/http/roundtrip_js.go -type StreamReader struct { - pending []byte - stream js.Value - err error // sticky read error -} - -func NewStreamReader(stream js.Value) *StreamReader { - return &StreamReader{ - stream: stream, - } -} - -// SOURCE: https://github.com/golang/go/blob/release-branch.go1.20/src/net/http/roundtrip_js.go -func (r *StreamReader) Read(p []byte) (n int, err error) { - if r.err != nil { - return 0, r.err - } - if len(r.pending) == 0 { - var ( - bCh = make(chan []byte, 1) - errCh = make(chan error, 1) - ) - success := js.FuncOf(func(this js.Value, args []js.Value) any { - result := args[0] - if result.Get("done").Bool() { - errCh <- io.EOF - return nil - } - value := make([]byte, result.Get("value").Get("byteLength").Int()) - js.CopyBytesToGo(value, result.Get("value")) - bCh <- value - return nil - }) - defer success.Release() - failure := js.FuncOf(func(this js.Value, args []js.Value) any { - // Assumes it's a TypeError. See - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError - // for more information on this type. See - // https://streams.spec.whatwg.org/#byob-reader-read for the spec on - // the read method. - errCh <- errors.New(args[0].Get("message").String()) - return nil - }) - defer failure.Release() - r.stream.Call("read").Call("then", success, failure) - select { - case b := <-bCh: - r.pending = b - case err := <-errCh: - r.err = err - return 0, err - } - } - n = copy(p, r.pending) - r.pending = r.pending[n:] - return n, nil -} - -// SOURCE: https://github.com/golang/go/blob/release-branch.go1.20/src/net/http/roundtrip_js.go -func (r *StreamReader) Close() error { - // This ignores any error returned from cancel method. So far, I did not encounter any concrete - // situation where reporting the error is meaningful. Most users ignore error from resp.Body.Close(). - // If there's a need to report error here, it can be implemented and tested when that need comes up. - r.stream.Call("cancel") - if r.err == nil { - r.err = errClosed - } - return nil -} - -// ArrayReader implements an io.ReadCloser wrapper for ArrayBuffer. -// https://developer.mozilla.org/en-US/docs/Web/API/Body/arrayBuffer. -// SOURCE: https://github.com/golang/go/blob/release-branch.go1.20/src/net/http/roundtrip_js.go -type ArrayReader struct { - arrayPromise js.Value - pending []byte - read bool - err error // sticky read error -} - -func NewArrayReader(arrayPromise js.Value) *ArrayReader { - return &ArrayReader{ - arrayPromise: arrayPromise, - } -} - -// SOURCE: https://github.com/golang/go/blob/release-branch.go1.20/src/net/http/roundtrip_js.go -func (r *ArrayReader) Read(p []byte) (n int, err error) { - if r.err != nil { - return 0, r.err - } - if !r.read { - r.read = true - var ( - bCh = make(chan []byte, 1) - errCh = make(chan error, 1) - ) - success := js.FuncOf(func(this js.Value, args []js.Value) any { - // Wrap the input ArrayBuffer with a Uint8Array - uint8arrayWrapper := js.Global().Get("Uint8Array").New(args[0]) - value := make([]byte, uint8arrayWrapper.Get("byteLength").Int()) - js.CopyBytesToGo(value, uint8arrayWrapper) - bCh <- value - return nil - }) - defer success.Release() - failure := js.FuncOf(func(this js.Value, args []js.Value) any { - // Assumes it's a TypeError. See - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypeError - // for more information on this type. - // See https://fetch.spec.whatwg.org/#concept-body-consume-body for reasons this might error. - errCh <- errors.New(args[0].Get("message").String()) - return nil - }) - defer failure.Release() - r.arrayPromise.Call("then", success, failure) - select { - case b := <-bCh: - r.pending = b - case err := <-errCh: - return 0, err - } - } - if len(r.pending) == 0 { - return 0, io.EOF - } - n = copy(p, r.pending) - r.pending = r.pending[n:] - return n, nil -} - -// SOURCE: https://github.com/golang/go/blob/release-branch.go1.20/src/net/http/roundtrip_js.go -func (r *ArrayReader) Close() error { - if r.err == nil { - r.err = errClosed - } - return nil -} diff --git a/wasm/mix-fetch/go-mix-conn/internal/external/set.go b/wasm/mix-fetch/go-mix-conn/internal/external/set.go deleted file mode 100644 index d2c3086bab..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/external/set.go +++ /dev/null @@ -1,26 +0,0 @@ -package external - -// SOURCE: https://github.com/jub0bs/fcors/blob/main/internal/util/set.go - -// A Set represents a mathematical set whose elements have type E. -type Set[E comparable] map[E]struct{} - -// NewSet returns a Set that contains all of es (and no other elements). -func NewSet[E comparable](es ...E) Set[E] { - set := make(Set[E], len(es)) - for _, e := range es { - set.Add(e) - } - return set -} - -// Add adds e to s. -func (s Set[E]) Add(e E) { - s[e] = struct{}{} -} - -// Contains returns true if e is an element of s, and false otherwise. -func (s Set[E]) Contains(e E) bool { - _, found := s[e] - return found -} diff --git a/wasm/mix-fetch/go-mix-conn/internal/helpers/helpers.go b/wasm/mix-fetch/go-mix-conn/internal/helpers/helpers.go deleted file mode 100644 index 5e3ef3ebd3..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/helpers/helpers.go +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -package helpers - -import ( - "errors" - "fmt" - "go-mix-conn/internal/external" - "golang.org/x/net/http/httpguts" - "sort" - "strconv" - "strings" - "syscall/js" -) - -func ParseRequestId(raw js.Value) (uint64, error) { - if raw.Type() != js.TypeString { - return 0, errors.New("the received raw request id was not a string") - } - - return strconv.ParseUint(raw.String(), 10, 64) -} - -func IntoGoBytes(raw js.Value) ([]byte, error) { - if raw.Type() != js.TypeObject { - return nil, errors.New("the received 'bytes' are not an object") - } - lenProp := raw.Get("length") - if lenProp.Type() != js.TypeNumber { - return nil, errors.New("the received 'bytes' object does not have a numerical 'length' property") - } - n := lenProp.Int() - bytes := make([]byte, n) - - // TODO: somehow check that the object is an Uint8Array or Uint8ClampedArray - copied := js.CopyBytesToGo(bytes, raw) - if copied != n { - // I don't see how this could ever be reached, thus panic - panic("somehow copied fewer bytes from JavaScript into Go than what we specified as our buffer") - } - - return bytes, nil -} - -func IntoJsBytes(raw []byte) js.Value { - // "data" is a byte slice, so we need to convert it to a JS Uint8Array object - arrayConstructor := js.Global().Get("Uint8Array") - jsBytes := arrayConstructor.New(len(raw)) - js.CopyBytesToJS(jsBytes, raw) - return jsBytes -} - -func GetStringProperty(obj *js.Value, name string) (string, error) { - val := obj.Get(name) - if val.Type() != js.TypeString { - return "", errors.New(fmt.Sprintf("the property %s is not a string", name)) - } - return val.String(), nil -} - -func IsToken(raw string) bool { - if len(raw) == 0 { - return false - } - for _, b := range []byte(raw) { - if !httpguts.IsTokenRune(rune(b)) { - return false - } - } - return true -} - -func ByteLowercase(s string) string { - return strings.Map(byteLowercaseOne, s) -} - -func byteLowercaseOne(asciiRune rune) rune { - const toLower = 'a' - 'A' - if 'A' <= asciiRune && asciiRune <= 'Z' { - return asciiRune + toLower - } - return asciiRune -} - -func SortedByteLowercase(s []string) []string { - lowercase := make([]string, len(s)) - for i := 0; i < len(s); i++ { - lowercase[i] = ByteLowercase(s[i]) - } - sort.Strings(lowercase) - return lowercase -} - -func Contains(s []string, str string) bool { - for _, v := range s { - if v == str { - return true - } - } - - return false -} - -func Unique(s []string) []string { - uniqueSet := external.NewSet(s...) - - uniqueSlice := make([]string, len(uniqueSet)) - for v := range uniqueSet { - uniqueSlice = append(uniqueSlice, v) - } - return uniqueSlice -} - -func IntoAnySlice(v []js.Value) []any { - s := make([]any, len(v)) - for i, x := range v { - s[i] = x - } - return s -} diff --git a/wasm/mix-fetch/go-mix-conn/internal/jstypes/async.go b/wasm/mix-fetch/go-mix-conn/internal/jstypes/async.go deleted file mode 100644 index 3b8bcfc4be..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/jstypes/async.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -package jstypes - -import ( - "fmt" - "syscall/js" -) - -type jsFn func(this js.Value, args []js.Value) (any, error) - -// AsyncFunc converts a Go-JS function into a Promise -func AsyncFunc(innerFunc jsFn) js.Func { - return js.FuncOf(func(this js.Value, args []js.Value) any { - handler := js.FuncOf(func(_ js.Value, promFn []js.Value) any { - resolve, reject := promFn[0], promFn[1] - - go func() { - defer func() { - if r := recover(); r != nil { - reject.Invoke(Error.New(fmt.Sprint("panic:", r))) - } - }() - - res, err := innerFunc(this, args) - if err != nil { - reject.Invoke(Error.New(err.Error())) - } else { - resolve.Invoke(res) - } - }() - - return nil - }) - - return Promise.New(handler) - }) -} - -// https://stackoverflow.com/a/68427221 -func Await(awaitable js.Value) ([]js.Value, []js.Value) { - then := make(chan []js.Value) - defer close(then) - thenFunc := js.FuncOf(func(this js.Value, args []js.Value) any { - then <- args - return nil - }) - defer thenFunc.Release() - - catch := make(chan []js.Value) - defer close(catch) - catchFunc := js.FuncOf(func(this js.Value, args []js.Value) any { - catch <- args - return nil - }) - defer catchFunc.Release() - - awaitable.Call("then", thenFunc).Call("catch", catchFunc) - - select { - case result := <-then: - return result, nil - case err := <-catch: - return nil, err - } -} diff --git a/wasm/mix-fetch/go-mix-conn/internal/jstypes/conv/request.go b/wasm/mix-fetch/go-mix-conn/internal/jstypes/conv/request.go deleted file mode 100644 index 19792dbc06..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/jstypes/conv/request.go +++ /dev/null @@ -1,415 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -package conv - -import ( - "bytes" - "context" - "errors" - "fmt" - "go-mix-conn/internal/external" - "go-mix-conn/internal/helpers" - "go-mix-conn/internal/jstypes" - "go-mix-conn/internal/log" - "go-mix-conn/internal/types" - "io" - "net/http" - "net/url" - "syscall/js" -) - -const ( - fieldRequestMethod = "method" - fieldRequestUrl = "url" - fieldRequestBody = "body" - fieldRequestRedirect = "redirect" - fieldRequestMode = "mode" - fieldRequestCredentials = "credentials" - fieldRequestReferrer = "referrer" - fieldRequestReferrerPolicy = "referrerPolicy" - fieldRequestHeaders = "headers" - fieldRequestCache = "cache" - fieldRequestSignal = "signal" -) - -type ParsedRequest struct { - Request *http.Request - Options *types.RequestOptions -} - -// ParseJSRequest is a reverse of https://github.com/golang/go/blob/release-branch.go1.21/src/net/http/roundtrip_js.go#L91 -// https://developer.mozilla.org/en-US/docs/Web/API/request -// -// Preflight requests: status unknown -/* - Request attributes and their implementation status: - [✅] - supported - [⚠️] - partially supported (some features might be missing) - [❌] - unsupported - [❗] - not applicable / will not support - - [⚠️] body - the current streaming is a bit awkward - [❌] bodyUsed - [❗️] cache - [❌] credentials - [❌] destination - [⚠️] headers - not all headers are properly respected - [❌] integrity - [✅] method - [✅] mode - [✅️] redirect - [❌] referrer - [❌] referrerPolicy - [✅] signal - [✅] url -*/ -func ParseJSRequest(request js.Value, unsafeCors bool) (*ParsedRequest, error) { - // https://github.com/mozilla/gecko-dev/blob/d307d4d9f06dab6d16e963a4318e5e8ff4899141/dom/fetch/Fetch.cpp#L501 - // https://github.com/mozilla/gecko-dev/blob/d307d4d9f06dab6d16e963a4318e5e8ff4899141/dom/fetch/Request.cpp#L270 - - method, err := helpers.GetStringProperty(&request, fieldRequestMethod) - if err != nil { - return nil, err - } - - requestUrl, err := helpers.GetStringProperty(&request, fieldRequestUrl) - if err != nil { - return nil, err - } - - body, err := parseBody(&request) - if err != nil { - return nil, err - } - redirect, err := parseRedirect(&request) - if err != nil { - return nil, err - } - - mode, err := parseMode(&request, unsafeCors) - if err != nil { - return nil, err - } - - credentialsMode, err := parseCredentialsMode(&request) - if err != nil { - return nil, err - } - - referrer, err := parseReferrer(&request) - if err != nil { - return nil, err - } - - referrerPolicy, err := parseRefererPolicy(&request) - if err != nil { - return nil, err - } - - ctx, cancel := context.WithCancel(context.Background()) - if err := dealWithSignal(&request, cancel); err != nil { - return nil, err - } - - // A Request has an associated response tainting, which is "basic", "cors", or "opaque". - // Unless stated otherwise, it is "basic". - // Reference: https://fetch.spec.whatwg.org/#concept-request-response-tainting - responseTainting := jstypes.ResponseTaintingBasic - - options := types.RequestOptions{ - Redirect: redirect, - Mode: mode, - CredentialsMode: credentialsMode, - Referrer: referrer, - ReferrerPolicy: referrerPolicy, - ResponseTainting: responseTainting, - Method: method, - } - - jsHeaders := request.Get(fieldRequestHeaders) - headers, err := parseHeaders(jsHeaders, options, method) - if err != nil { - return nil, err - } - - checkUnsupportedAttributes(&request) - - req, err := http.NewRequestWithContext(ctx, method, requestUrl, body) - if err != nil { - return nil, err - } - req.Header = headers - - log.Debug("constructed Request: %+v", req) - log.Debug("using Options: %s", options) - - return &ParsedRequest{ - Request: req, - Options: &options, - }, nil -} - -func checkUnsupportedAttributes(request *js.Value) { - cache := request.Get(fieldRequestCache) - - if !cache.IsUndefined() { - log.Warn("\"%s\"' attribute is set on the Request - this is not supported by mixFetch", fieldRequestCache) - } - - // TODO: implement more of them -} - -func parseHeaders(headers js.Value, reqOpts types.RequestOptions, method string) (http.Header, error) { - goHeaders := http.Header{} - - if headers.Type() != js.TypeObject { - return nil, errors.New("the Request headers is not an object") - } - headersIter := headers.Call("entries") - - for { - next := headersIter.Call("next") - done := next.Get("done").Bool() - if done { - break - } - keyValue := next.Get("value") - if keyValue.Length() != 2 { - return nil, errors.New("one of the headers has invalid length") - } - key := keyValue.Index(0) - if key.Type() != js.TypeString { - return nil, errors.New("one of the header keys is not a string") - } - - value := keyValue.Index(1) - if value.Type() != js.TypeString { - return nil, errors.New("one of the header values is not a string") - } - ck := http.CanonicalHeaderKey(key.String()) - goHeaders[ck] = append(goHeaders[ck], value.String()) - } - - // add additional headers - - // 3.1.1 - origin := jstypes.Origin() - serializedOrigin := origin - // Reference: https://fetch.spec.whatwg.org/#origin-header - // TODO: 3.1.2: check response tainting - // 3.1.3 - if method != "GET" && method != "HEAD" { - // 3.1.3.1 - if reqOpts.Mode != jstypes.ModeCors { - switch reqOpts.ReferrerPolicy { - case jstypes.ReferrerNoReferrer: - serializedOrigin = nil - case jstypes.ReferrerPolicyNoReferrerWhenDowngrade, jstypes.ReferrerPolicyStrictOrigin, jstypes.ReferrerPolicyStrictOriginWhenCrossOrigin: - panic("unimplemented Referrer policy") - case jstypes.ReferrerPolicySameOrigin: - panic("unimplemented Referrer policy") - } - } - // 3.1.3.2 - if serializedOrigin != nil { - goHeaders.Set(jstypes.HeaderOrigin, *serializedOrigin) - } - } - - return goHeaders, nil -} - -func parseBody(request *js.Value) (io.Reader, error) { - jsBody := request.Get(fieldRequestBody) - var bodyReader io.Reader - - if jsBody.InstanceOf(js.Global().Get("ReadableStream")) && jsBody.Get("getReader").Type() == js.TypeFunction { - // Check to see if getReader is a function - log.Debug("stream body - getReader") - bodyReader = external.NewStreamReader(jsBody.Call("getReader")) - } else { - log.Debug("unstreamable body - fallback to ArrayBuffer") - bodyReader = external.NewArrayReader(request.Call("arrayBuffer")) - } - bodyBytes, err := io.ReadAll(bodyReader) - if err != nil { - return nil, err - } - // Leaving historical notes as reference points - // TODO: that seems super awkward. we're constructing a reader only to fully consume it - // and create it all over again so that we the recipient wouldn't complain about content-length - // surely there must be a better way? - - return bytes.NewReader(bodyBytes), nil -} - -func parseRedirect(request *js.Value) (string, error) { - redirect := request.Get(fieldRequestRedirect) - if redirect.IsUndefined() || redirect.IsNull() { - // "A Request has an associated Redirect Mode, which is "follow", "error", or "manual". Unless stated otherwise, it is "follow"." - // Reference: https://fetch.spec.whatwg.org/#concept-request - return jstypes.RequestRedirectFollow, nil - } - - if redirect.Type() != js.TypeString { - return "", errors.New("the redirect field is not a string") - } - - redirectString := redirect.String() - switch redirect.String() { - case jstypes.RequestRedirectManual: - return jstypes.RequestRedirectManual, nil - case jstypes.RequestRedirectError: - return jstypes.RequestRedirectError, nil - case jstypes.RequestRedirectFollow: - return jstypes.RequestRedirectFollow, nil - } - - return "", errors.New(fmt.Sprintf("%s is not a valid Redirect", redirectString)) -} - -func parseMode(request *js.Value, unsafeCors bool) (jstypes.Mode, error) { - if unsafeCors { - return jstypes.ModeUnsafeIgnoreCors, nil - } - - mode := request.Get(fieldRequestMode) - if mode.IsUndefined() || mode.IsNull() { - // "Even though the default Request Mode is "no-cors", standards are highly discouraged from using it for new features. It is rather unsafe." - // Reference: https://fetch.spec.whatwg.org/#concept-request-mode - return jstypes.ModeNoCors, nil - } - - if mode.Type() != js.TypeString { - return "", errors.New("the mode field is not a string") - } - - modeString := mode.String() - switch modeString { - case jstypes.ModeCors: - return jstypes.ModeCors, nil - case jstypes.ModeSameOrigin: - return jstypes.ModeSameOrigin, nil - case jstypes.ModeNoCors: - return jstypes.ModeNoCors, nil - case jstypes.ModeUnsafeIgnoreCors: - return jstypes.ModeUnsafeIgnoreCors, nil - case jstypes.ModeNavigate: - return "", errors.New(fmt.Sprintf("%s Mode is not supported", jstypes.ModeNavigate)) - case jstypes.ModeWebsocket: - return "", errors.New(fmt.Sprintf("%s Mode is not supported", jstypes.ModeWebsocket)) - } - - return "", errors.New(fmt.Sprintf("%s is not a valid Mode", modeString)) -} - -func parseCredentialsMode(request *js.Value) (jstypes.CredentialsMode, error) { - credentialsMode := request.Get(fieldRequestCredentials) - if credentialsMode.IsUndefined() || credentialsMode.IsNull() { - // A Request has an associated credentials Mode, which is "omit", "same-origin", or "include". Unless stated otherwise, it is "same-origin". - // Reference: https://fetch.spec.whatwg.org/#concept-request-mode - return jstypes.CredentialsModeSameOrigin, nil - } - - if credentialsMode.Type() != js.TypeString { - return "", errors.New("the credentials field is not a string") - } - - credentialsModeString := credentialsMode.String() - switch credentialsModeString { - case jstypes.CredentialsModeOmit: - return jstypes.CredentialsModeOmit, nil - case jstypes.CredentialsModeInclude: - return jstypes.CredentialsModeInclude, nil - case jstypes.CredentialsModeSameOrigin: - return jstypes.CredentialsModeSameOrigin, nil - } - - return "", errors.New(fmt.Sprintf("%s is not a valid credentials Mode", credentialsModeString)) -} - -func parseReferrer(request *js.Value) (jstypes.Referrer, error) { - referrer := request.Get(fieldRequestReferrer) - if referrer.IsUndefined() || referrer.IsNull() { - // A Request has an associated Referrer, which is "no-Referrer", "client", or a URL. Unless stated otherwise it is "client". - // Reference: https://fetch.spec.whatwg.org/#concept-request-referrer - return jstypes.ReferrerClient, nil - } - - if referrer.Type() != js.TypeString { - return "", errors.New("the referrer field is not a string") - } - - referrerString := referrer.String() - if referrerString == jstypes.ReferrerNoReferrer { - return jstypes.ReferrerNoReferrer, nil - } - - if referrerString == jstypes.ReferrerClient { - return jstypes.ReferrerClient, nil - } - - _, err := url.Parse(referrerString) - if err != nil { - return "", errors.New(fmt.Sprintf("\"%s\" is not a valid URL Referrer: \"%s\"", referrerString, err)) - } - return referrerString, nil -} - -func parseRefererPolicy(request *js.Value) (jstypes.ReferrerPolicy, error) { - referrerPolicy := request.Get(fieldRequestReferrerPolicy) - if referrerPolicy.IsUndefined() || referrerPolicy.IsNull() { - // A Request has an associated Referrer policy, which is a Referrer policy. Unless stated otherwise it is the empty string - // Reference: https://fetch.spec.whatwg.org/#concept-request-referrer-policy - return "", nil - } - - if referrerPolicy.Type() != js.TypeString { - return "", errors.New("the referrerPolicy field is not a string") - } - - referrerPolicyString := referrerPolicy.String() - switch referrerPolicyString { - case "": - return "", nil - case jstypes.ReferrerPolicyNoReferrer: - return jstypes.ReferrerPolicyNoReferrer, nil - case jstypes.ReferrerPolicyNoReferrerWhenDowngrade: - return jstypes.ReferrerPolicyNoReferrerWhenDowngrade, nil - case jstypes.ReferrerPolicyOrigin: - return jstypes.ReferrerPolicyOrigin, nil - case jstypes.ReferrerPolicyOriginWhenCrossOrigin: - return jstypes.ReferrerPolicyOriginWhenCrossOrigin, nil - case jstypes.ReferrerPolicySameOrigin: - return jstypes.ReferrerPolicySameOrigin, nil - case jstypes.ReferrerPolicyStrictOrigin: - return jstypes.ReferrerPolicyStrictOrigin, nil - case jstypes.ReferrerPolicyStrictOriginWhenCrossOrigin: - return jstypes.ReferrerPolicyStrictOriginWhenCrossOrigin, nil - case jstypes.ReferrerPolicyUnsafeUrl: - return jstypes.ReferrerPolicyUnsafeUrl, nil - } - - return "", errors.New(fmt.Sprintf("%s is not a valid Referrer policy", referrerPolicyString)) - -} - -func dealWithSignal(request *js.Value, cancel context.CancelFunc) error { - abortSignal := request.Get(fieldRequestSignal) - if abortSignal.IsUndefined() || abortSignal.IsNull() { - log.Debug("no abort signal passed") - return nil - } - if abortSignal.Type() != js.TypeObject { - return errors.New("passed abort signal is not a valid object") - } - - abortSignal.Call("addEventListener", "abort", js.FuncOf(func(this js.Value, args []js.Value) any { - log.Debug("abort signal called") - cancel() - return nil - })) - - return nil -} diff --git a/wasm/mix-fetch/go-mix-conn/internal/jstypes/conv/response.go b/wasm/mix-fetch/go-mix-conn/internal/jstypes/conv/response.go deleted file mode 100644 index b1925a9582..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/jstypes/conv/response.go +++ /dev/null @@ -1,350 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -package conv - -import ( - "fmt" - "go-mix-conn/internal/external" - "go-mix-conn/internal/helpers" - "go-mix-conn/internal/jstypes" - "go-mix-conn/internal/log" - "go-mix-conn/internal/types" - "io" - "net/http" - "net/url" - "syscall/js" -) - -const ( - fieldResponseStatus = "status" - fieldResponseStatusText = "statusText" - fieldResponseRedirected = "redirected" - fieldResponseType = "type" - fieldResponseHeaders = "headers" - fieldResponseUrl = "url" -) - -type ResponseWrapper struct { - inner *http.Response - ctx *types.RequestContext -} - -func NewResponseWrapper(inner *http.Response, ctx *types.RequestContext) ResponseWrapper { - return ResponseWrapper{ - inner: inner, - ctx: ctx, - } -} - -type InternalResponse struct { - inner *http.Response - responseTainting jstypes.ResponseTainting - responseType jstypes.ResponseType - corsExposedHeaderName []string - urlList []*url.URL - wasRedirected bool -} - -func NewInternalResponse(inner *http.Response, reqOpts *types.RequestOptions, reqCtx *types.RequestContext) InternalResponse { - return InternalResponse{ - inner: inner, - responseTainting: reqOpts.ResponseTainting, - wasRedirected: reqCtx.WasRedirected, - } -} - -// Reference: https://fetch.spec.whatwg.org/#null-body-status -func (IR *InternalResponse) isNullBodyStatus() bool { - return IR.inner.StatusCode == 101 || IR.inner.StatusCode == 103 || IR.inner.StatusCode == 204 || IR.inner.StatusCode == 205 || IR.inner.StatusCode == 304 -} - -func (IR *InternalResponse) allHeaderNames() []string { - keys := make([]string, 0, len(IR.inner.Header)) - - for k, _ := range IR.inner.Header { - keys = append(keys, k) - } - return keys -} - -func (IR *InternalResponse) JSBody() (js.Value, error) { - if IR.inner.Body == nil { - return js.Undefined(), nil - } - - defer func(Body io.ReadCloser) { - err := Body.Close() - if err != nil { - log.Error("failed to close the response body: %s", err) - } - }(IR.inner.Body) - - // Read the response body - // TODO: construct streamReader / arrayReader for better compat - data, err := io.ReadAll(IR.inner.Body) - if err != nil { - return js.Undefined(), err - } - - return helpers.IntoJsBytes(data), nil -} - -func (IR *InternalResponse) exposeHeadersNames() []string { - allowed := IR.inner.Header.Values(jstypes.HeaderExposeHeaders) - - allowedSet := external.NewSet(allowed...) - var filtered []string - for key, _ := range IR.inner.Header { - if allowedSet.Contains(key) { - filtered = append(filtered, key) - } - } - - return filtered -} - -// Reference: https://fetch.spec.whatwg.org/#concept-filtered-response-cors -func (IR *InternalResponse) mutIntoBasicResponse() { - IR.responseType = jstypes.ResponseTypeBasic - - newHeaders := http.Header{} - for key, values := range IR.inner.Header { - for _, value := range values { - if !jstypes.ForbiddenResponseHeaderNames.Contains(helpers.ByteLowercase(key)) { - ck := http.CanonicalHeaderKey(key) - newHeaders[ck] = append(newHeaders[ck], value) - } - } - } - IR.inner.Header = newHeaders -} - -// Reference: https://fetch.spec.whatwg.org/#concept-filtered-response-cors -func (IR *InternalResponse) mutIntoCORSResponse() { - IR.responseType = jstypes.ResponseTypeCors - - // TODO: figure out the proper usage of corsExposedHeaderName - - // https://github.com/mozilla/gecko-dev/blob/fabab5d10815c9d7210933379f0357b1cbc9aaaf/dom/fetch/InternalHeaders.cpp#L564 - newHeaders := http.Header{} - //for _, name := range IR.corsExposedHeaderName { - // if safelistedResponseHeaderNames.Contains(byteLowercase(name)) { - // ck := http.CanonicalHeaderKey(name) - // newHeaders[ck] = IR.inner.Header.Values(ck) - // } - //} - - for key, values := range IR.inner.Header { - for _, value := range values { - if jstypes.SafelistedResponseHeaderNames.Contains(helpers.ByteLowercase(key)) { - ck := http.CanonicalHeaderKey(key) - newHeaders[ck] = append(newHeaders[ck], value) - } - } - } - - IR.inner.Header = newHeaders -} - -// Reference: https://fetch.spec.whatwg.org/#concept-filtered-response-opaque -func (IR *InternalResponse) mutIntoOpaqueResponse() { - IR.responseType = jstypes.ResponseTypeOpaque - - // TODO: set URL list to « » - IR.inner.StatusCode = 0 - IR.inner.Status = "" - IR.inner.Header = http.Header{} - IR.inner.Body = nil -} - -// Reference: https://fetch.spec.whatwg.org/#concept-filtered-response-cors -func (IR *InternalResponse) mutIntoOpaqueRedirectResponse() { - IR.responseType = jstypes.ResponseTypeOpaqueRedirect - - IR.inner.StatusCode = 0 - IR.inner.Status = "" - IR.inner.Header = http.Header{} - IR.inner.Body = nil -} - -// OUTSIDE FETCH SPEC -func (IR *InternalResponse) mutIntoUnsafeIgnoreCorsResponse() { - IR.responseType = jstypes.ResponseTypeUnsafeIgnoreCors -} - -func proxyHandlerGet(proxied map[string]any) js.Func { - return js.FuncOf(func(_ js.Value, args []js.Value) any { - // Look at redirecting Method's this: - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy#no_private_property_forwarding - target := args[0] - prop := args[1].String() - receiver := args[2] - - value := target.Get(prop) - if value.Type() == js.TypeFunction { - log.Debug("%s is a function", prop) - return js.FuncOf(func(this js.Value, args []js.Value) any { - if this.Equal(receiver) { - return jstypes.Reflect.Call("apply", value, target, helpers.IntoAnySlice(args)) - } else { - return jstypes.Reflect.Call("apply", value, this, helpers.IntoAnySlice(args)) - } - }) - } - - // we're only proxing "normal" props, not function calls - proxy, ok := proxied[prop] - if ok { - log.Debug("using proxy value for field \"%s\" (changing \"%v\" -> \"%v\")", prop, value, proxy) - - return proxy - } - - return value - }) -} - -func responseProxyHandler(proxied map[string]any) js.Value { - handler := jstypes.Object.New() - handler.Set("get", proxyHandlerGet(proxied)) - return handler -} - -func (IR *InternalResponse) intoJsResponse() (js.Value, error) { - jsBody, err := IR.JSBody() - if err != nil { - return js.Undefined(), err - } - - // Create a Response object and pass the data - // inspired by https://github.com/golang/go/blob/release-branch.go1.21/src/net/http/roundtrip_js.go#L91 - headers := jstypes.Headers.New() - for key, values := range IR.inner.Header { - for _, value := range values { - headers.Call("append", key, value) - } - } - - responseOptions := jstypes.Object.New() - responseOptions.Set(fieldResponseStatus, IR.inner.StatusCode) - responseOptions.Set(fieldResponseStatusText, http.StatusText(IR.inner.StatusCode)) - responseOptions.Set(fieldResponseHeaders, headers) - - proxied := make(map[string]any) - - if IR.responseType != "" { - proxied[fieldResponseType] = IR.responseType - } - - // can't call the constructor properly if the value is outside the "legal" range (i.e. [200, 599]) - // (even though the fetch spec requires something different...) - if IR.inner.StatusCode == 0 { - responseOptions.Set(fieldResponseStatus, 418) - proxied[fieldResponseStatus] = IR.inner.StatusCode - } - - if len(IR.urlList) > 0 { - // "The value of the url property will be the final URL obtained after any redirects." - // source: https://developer.mozilla.org/en-US/docs/Web/API/Response/url - last := IR.urlList[len(IR.urlList)-1] - proxied[fieldResponseUrl] = last.String() - } - - if IR.wasRedirected { - proxied[fieldResponseRedirected] = IR.wasRedirected - } - - responseConstructor := jstypes.Response - response := responseConstructor.New(jsBody, responseOptions) - - for k, v := range proxied { - response.Set(fmt.Sprintf("_%s", k), v) - } - - proxyConstructor := jstypes.Proxy - proxy := proxyConstructor.New(response, responseProxyHandler(proxied)) - - return proxy, nil -} - -// IntoJSResponse is a reverse of https://github.com/golang/go/blob/release-branch.go1.21/src/net/http/roundtrip_js.go#L91 -// https://developer.mozilla.org/en-US/docs/Web/API/response -/* - Response attributes and their implementation status: - [✅] - supported - [⚠️] - partially supported (some features might be missing) - [❌] - unsupported - [❗] - not applicable / will not support - - [⚠️] body - response streaming via ReadableStream is unsupported (TODO: look into https://github.com/golang/go/blob/release-branch.go1.21/src/net/http/roundtrip_js.go#L152-L195 to implement it) - [✅] bodyUsed - [✅] headers - [✅] ok - seems to be handled automagically (presumably via `status`) - [✅] redirected - has to be proxied - [✅] status - has to be proxied when status == 0 - [✅] statusText - [✅] type - has to be proxied - [⚠️] url - not sure if every case is covered -*/ -func IntoJSResponse(resp *ResponseWrapper, opts *types.RequestOptions) (js.Value, error) { - // TODO: check if response is a filtered response - isFilteredResponse := false - - // result of 4.3.6.2.2 - internalResponse := NewInternalResponse(resp.inner, opts, resp.ctx) - if resp.ctx.OverwrittenResponseType == jstypes.ResponseTypeOpaqueRedirect { - isFilteredResponse = true - internalResponse.mutIntoOpaqueRedirectResponse() - } - - // 4.1.14 - if !isFilteredResponse { - // 4.1.14.1 - if opts.ResponseTainting == jstypes.ResponseTaintingCors { - // 4.1.14.1.1 - headerNames := internalResponse.exposeHeadersNames() - if opts.CredentialsMode != jstypes.CredentialsModeInclude && helpers.Contains(headerNames, jstypes.Wildcard) { - // 4.1.14.1.2 - internalResponse.corsExposedHeaderName = helpers.Unique(internalResponse.allHeaderNames()) - } else if len(headerNames) > 0 { - // 4.1.14.1.3 - internalResponse.corsExposedHeaderName = headerNames - } - } - switch opts.ResponseTainting { - case jstypes.ResponseTaintingBasic: - internalResponse.mutIntoBasicResponse() - case jstypes.ResponseTaintingCors: - internalResponse.mutIntoCORSResponse() - case jstypes.ResponseTaintingOpaque: - internalResponse.mutIntoOpaqueResponse() - case jstypes.ResponseTaintingUnsafeIgnoreCors: - internalResponse.mutIntoUnsafeIgnoreCorsResponse() - default: - panic("unreachable") - } - } - - if len(internalResponse.urlList) == 0 { - internalResponse.urlList = []*url.URL{internalResponse.inner.Request.URL} - } - // TODO: 4.1.17 - Redirect-tainted origin - // TODO: 4.1.18 - timing allow flag - - // TODO: 4.1.19 - mixed content check - // TODO: 4.1.19 - Content Security Policy check - // TODO: 4.1.19 - MIME type check - // TODO: 4.1.19 - nosniff check - - // TODO: 4.1.20 - //rangeRequestedFlag := false - //if internalResponse.responseType == types.RESPONSE_TYPE_OPAQUE && internalResponse.inner.Status == 206 - - // 4.1.21 - if (opts.Method == "HEAD" || opts.Method == "CONNECT") || internalResponse.isNullBodyStatus() { - internalResponse.inner.Body = nil - } - - return internalResponse.intoJsResponse() -} diff --git a/wasm/mix-fetch/go-mix-conn/internal/jstypes/globals.go b/wasm/mix-fetch/go-mix-conn/internal/jstypes/globals.go deleted file mode 100644 index 86e7ee3e0e..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/jstypes/globals.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -package jstypes - -import ( - "fmt" - "net/url" - "syscall/js" -) - -var ( - Error = js.Global().Get("Error") - Promise = js.Global().Get("Promise") - Reflect = js.Global().Get("Reflect") - Object = js.Global().Get("Object") - Response = js.Global().Get("Response") - Request = js.Global().Get("Request") - Proxy = js.Global().Get("Proxy") - Headers = js.Global().Get("Headers") -) - -func Origin() *string { - // nodejs doesn't have origin - location := js.Global().Get("location") - if !location.IsUndefined() && !location.IsNull() { - origin := location.Get("origin").String() - return &origin - } else { - return nil - } -} - -func OriginUrl() *url.URL { - origin := Origin() - if origin == nil { - return nil - } else { - originUrl, originErr := url.Parse(*origin) - if originErr != nil { - panic(fmt.Sprintf("could not obtain origin: %s", originErr)) - } - return originUrl - } -} diff --git a/wasm/mix-fetch/go-mix-conn/internal/jstypes/headers.go b/wasm/mix-fetch/go-mix-conn/internal/jstypes/headers.go deleted file mode 100644 index d32ac89bd2..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/jstypes/headers.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -package jstypes - -import ( - "go-mix-conn/internal/external" - "go-mix-conn/internal/helpers" -) - -const ( - HeaderOrigin = "Origin" - - HeaderRequestMethod = "Access-Control-Request-Method" - HeaderRequestHeaders = "Access-Control-Request-Headers" - HeaderRequestLocalNetwork = "Access-Control-Request-Local-Network" - HeaderRequestPrivateNetwork = "Access-Control-Request-Private-Network" - - HeaderAllowMethods = "Access-Control-Allow-Methods" - HeaderAllowHeaders = "Access-Control-Allow-Headers" - HeaderMageAge = "Access-Control-Max-Age" - HeaderAllowLocalNetwork = "Access-Control-Allow-Local-Network" - HeaderAllowPrivateNetwork = "Access-Control-Allow-Private-Network" - - // Indicates whether the response can be shared, via returning the literal value of the `Origin` request header (which can be `null`) or `*` in a response. - HeaderAllowOrigin = "Access-Control-Allow-Origin" - // Indicates whether the response can be shared when request’s credentials mode is "include". - HeaderAllowCredentials = "Access-Control-Allow-Credentials" - - HeaderExposeHeaders = "Access-Control-Expose-Headers" - - Wildcard = "*" -) - -// see https://fetch.spec.whatwg.org/#forbidden-header-name -var DiscreteForbiddenHeaderNames = external.NewSet( - "accept-charset", - "accept-encoding", - helpers.ByteLowercase(HeaderRequestHeaders), - helpers.ByteLowercase(HeaderRequestMethod), - // see https://wicg.github.io/local-network-access/#forbidden-header-names - helpers.ByteLowercase(HeaderRequestLocalNetwork), - helpers.ByteLowercase(HeaderRequestPrivateNetwork), - "connection", - "content-length", - "cookie", - "cookie2", - "date", - "dnt", - "expect", - "host", - "keep-alive", - helpers.ByteLowercase(HeaderOrigin), - "referer", - "set-cookie", - "te", - "trailer", - "transfer-encoding", - "upgrade", - "via", -) - -// almost always a mistake to allow the following as request headers -// as a result of misunderstanding of the CORS protocol. -var DisallowedRequestHeaderNames = external.NewSet( - helpers.ByteLowercase(Wildcard), - helpers.ByteLowercase(HeaderAllowOrigin), - helpers.ByteLowercase(HeaderAllowCredentials), - helpers.ByteLowercase(HeaderAllowMethods), - helpers.ByteLowercase(HeaderAllowHeaders), - helpers.ByteLowercase(HeaderAllowLocalNetwork), - helpers.ByteLowercase(HeaderAllowPrivateNetwork), - helpers.ByteLowercase(HeaderMageAge), - helpers.ByteLowercase(HeaderExposeHeaders), -) - -// almost always a mistake to expose the following as response headers -var DisallowedResponseHeaderNames = external.NewSet( - helpers.ByteLowercase(Wildcard), - helpers.ByteLowercase(HeaderOrigin), - helpers.ByteLowercase(HeaderRequestMethod), - helpers.ByteLowercase(HeaderRequestHeaders), - helpers.ByteLowercase(HeaderRequestLocalNetwork), - helpers.ByteLowercase(HeaderRequestPrivateNetwork), -) - -// see https://fetch.spec.whatwg.org/#forbidden-response-header-name -var ForbiddenResponseHeaderNames = external.NewSet( - "set-cookie", - "set-cookie2", -) - -// see https://fetch.spec.whatwg.org/#cors-safelisted-response-header-name -var SafelistedResponseHeaderNames = external.NewSet( - "cache-control", - "content-language", - "content-length", - "content-type", - "expires", - "last-modified", - "pragma", -) diff --git a/wasm/mix-fetch/go-mix-conn/internal/jstypes/helpers.go b/wasm/mix-fetch/go-mix-conn/internal/jstypes/helpers.go deleted file mode 100644 index ba10a05196..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/jstypes/helpers.go +++ /dev/null @@ -1,140 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -package jstypes - -import ( - "go-mix-conn/internal/helpers" - "go-mix-conn/internal/log" - "net/http" - "net/url" - "strings" -) - -// see https://datatracker.ietf.org/doc/html/rfc7230#section-3.2 -func IsValidHeaderName(raw string) bool { - return helpers.IsToken(raw) -} - -// see https://fetch.spec.whatwg.org/#forbidden-header-name -func IsForbiddenRequestHeaderName(name string) bool { - if DiscreteForbiddenHeaderNames.Contains(name) { - return true - } - return strings.HasPrefix(name, "proxy-") || - strings.HasPrefix(name, "sec-") -} - -// A CORS-unsafe request-header byte is a byte *byte* for which one of the following is true: -// - byte is less than 0x20 and is not 0x09 HT -// - byte is 0x22 ("), 0x28 (left parenthesis), 0x29 (right parenthesis), 0x3A (:), 0x3C (<), 0x3E (>), 0x3F (?), 0x40 (@), 0x5B ([), 0x5C (\), 0x5D (]), 0x7B ({), 0x7D (}), or 0x7F DEL. -// Reference: https://fetch.spec.whatwg.org/#cors-unsafe-request-header-byte -func containsCORSUnsafeRequestHeaderByte(b []byte) bool { - for i := 0; i < len(b); i++ { - v := b[i] - if v < 0x20 && v != 0x09 { - return true - } - if v == 0x22 || v == 0x28 || v == 0x29 || v == 0x3A || v == 0x3C || v == 0x3E || v == 0x3F || v == 0x40 || v == 0x5B || v == 0x5C || v == 0x5D || v == 0x7B || v == 0x7D || v == 0x7F { - return true - } - } - - return false -} - -// Reference: https://fetch.spec.whatwg.org/#cors-safelisted-request-header -func isCorsSafelistedRequestHeader(name string, value string) bool { - // 1 - if len(value) > 128 { - return false - } - - // 2 - switch helpers.ByteLowercase(name) { - case "accept": - if containsCORSUnsafeRequestHeaderByte([]byte(value)) { - return false - } - case "accept-language", "content-language": - valueBytes := []byte(value) - for i := 0; i < len(valueBytes); i++ { - v := valueBytes[i] - if !(0x30 <= v && v <= 0x39) && !(0x41 <= v && v <= 0x5A) && !(0x61 <= v && v <= 0x7A) && v != 0x20 && v != 0x2A && v != 0x2C && v != 0x2D && v != 0x2E && v != 0x3B && v != 0x3D { - return false - } - } - case "content-type": - // 2.1 - if containsCORSUnsafeRequestHeaderByte([]byte(value)) { - return false - } - // 2.4 - if value != "application/x-www-form-urlencoded" && value != "multipart/form-data" && value != "text/plain" { - return false - } - case "range": - log.Error("unimplemented 'range' header") - return false - default: - return false - } - - // 3 - return true -} - -// Reference: https://fetch.spec.whatwg.org/#cors-unsafe-request-header-names -func CorsUnsafeRequestHeaderNames(headers http.Header) []string { - var unsafeNames []string - var potentiallyUnsafeNames []string - safelistValueSize := 0 - - // 4 - for name, value := range headers { - // TODO: is that actually correct? - wasUnsafe := false - for _, v := range value { - // 4.1 - if !isCorsSafelistedRequestHeader(name, v) { - unsafeNames = append(unsafeNames, name) - wasUnsafe = true - break - } - } - if !wasUnsafe { - potentiallyUnsafeNames = append(potentiallyUnsafeNames, name) - safelistValueSize += len(value) - } - } - - // 5 - if safelistValueSize > 1024 { - for _, name := range potentiallyUnsafeNames { - unsafeNames = append(unsafeNames, name) - } - } - - return helpers.SortedByteLowercase(unsafeNames) -} - -// Reference: https://fetch.spec.whatwg.org/#cors-safelisted-method -func IsCorsSafelistedMethod(method string) bool { - if method == "GET" || method == "HEAD" || method == "POST" { - return true - } else { - return false - } -} - -func IsSameOrigin(remoteUrl *url.URL) bool { - originUrl := OriginUrl() - - // Roughly speaking, two URIs are part of the same JsOrigin (i.e., represent the same principal) - // if they have the same scheme, host, and port. - // Reference: https://www.rfc-editor.org/rfc/rfc6454.html#section-3.2 - if originUrl.Scheme != remoteUrl.Scheme || originUrl.Host != remoteUrl.Host || originUrl.Port() != remoteUrl.Port() { - return false - } - return true -} diff --git a/wasm/mix-fetch/go-mix-conn/internal/jstypes/request.go b/wasm/mix-fetch/go-mix-conn/internal/jstypes/request.go deleted file mode 100644 index 79ec5a1e62..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/jstypes/request.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -package jstypes - -type Redirect = string -type Mode = string -type CredentialsMode = string -type ResponseTainting = string -type ReferrerPolicy = string -type Referrer = string - -const ( - RequestRedirectError = "error" - RequestRedirectManual = "manual" - RequestRedirectFollow = "follow" - - ResponseTaintingBasic = "basic" - ResponseTaintingCors = "cors" - ResponseTaintingOpaque = "opaque" - ResponseTaintingUnsafeIgnoreCors = "ignore-cors" - - ModeCors = "cors" - ModeSameOrigin = "same-origin" - ModeNoCors = "no-cors" - ModeNavigate = "navigate" - ModeWebsocket = "websocket" - ModeUnsafeIgnoreCors = "unsafe-ignore-cors" - - CredentialsModeOmit = "omit" - CredentialsModeSameOrigin = "same-origin" - CredentialsModeInclude = "include" - - ReferrerPolicyNoReferrer = "no-referrer" - ReferrerPolicyNoReferrerWhenDowngrade = "no-referrer-when-downgrade" - ReferrerPolicyOrigin = "origin" - ReferrerPolicyOriginWhenCrossOrigin = "origin-when-cross-origin" - ReferrerPolicySameOrigin = "same-origin" - ReferrerPolicyStrictOrigin = "strict-origin" - ReferrerPolicyStrictOriginWhenCrossOrigin = "strict-origin-when-cross-origin" - ReferrerPolicyUnsafeUrl = "unsafe-url" - - ReferrerNoReferrer = "no-referrer" - ReferrerClient = "client" -) diff --git a/wasm/mix-fetch/go-mix-conn/internal/jstypes/response.go b/wasm/mix-fetch/go-mix-conn/internal/jstypes/response.go deleted file mode 100644 index e0f2644347..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/jstypes/response.go +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -package jstypes - -type ResponseType = string - -const ( - ResponseTypeBasic = "basic" - ResponseTypeCors = "cors" - ResponseTypeDefault = "default" - ResponseTypeError = "error" - ResponseTypeOpaque = "opaque" - ResponseTypeOpaqueRedirect = "opaqueredirect" - ResponseTypeUnsafeIgnoreCors = "unsafe-ignore-cors" -) diff --git a/wasm/mix-fetch/go-mix-conn/internal/log/logger.go b/wasm/mix-fetch/go-mix-conn/internal/log/logger.go deleted file mode 100644 index 78aafd0107..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/log/logger.go +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -package log - -import ( - "fmt" - "runtime" - "strings" - "syscall/js" -) - -type LogLevel = int - -const ( - DISABLED LogLevel = iota - ERROR - WARN - INFO - DEBUG - TRACE -) - -var ( - // thanks to the amazing capabilities of this awesome language, - // we couldn't put it in the `jstypes` alongside other globals - // as it created an unresolvable cyclic import - console = js.Global().Get("console") - - GlobalLogLevel = INFO -) - -func SetLoggingLevel(raw string) { - switch strings.ToLower(raw) { - case "disabled": - GlobalLogLevel = DISABLED - case "error": - GlobalLogLevel = ERROR - case "warn", "warning": - GlobalLogLevel = WARN - case "info": - GlobalLogLevel = INFO - case "debug": - GlobalLogLevel = DEBUG - case "trace": - GlobalLogLevel = TRACE - default: - Warn("\"%s\" is not a valid logging level", raw) - } -} - -func makeLogMessage(severity string, format string, a ...any) string { - _, file, line, ok := runtime.Caller(2) - // we should really be using a mutex here... - if !ok { - file = "???" - line = 0 - } - - prefix := fmt.Sprintf("[go] %s: %s:%d: ", severity, file, line) - suffix := fmt.Sprintf(format, a...) - return prefix + suffix -} - -func Error(format string, a ...any) { - if GlobalLogLevel >= ERROR { - msg := makeLogMessage("ERROR", format, a...) - console.Call("error", msg) - } -} - -func Warn(format string, a ...any) { - if GlobalLogLevel >= WARN { - msg := makeLogMessage("WARN", format, a...) - console.Call("warn", msg) - } -} - -func Info(format string, a ...any) { - if GlobalLogLevel >= INFO { - msg := makeLogMessage("INFO", format, a...) - console.Call("info", msg) - } -} - -func Debug(format string, a ...any) { - if GlobalLogLevel >= DEBUG { - msg := makeLogMessage("DEBUG", format, a...) - // too lazy to configure my console : ) - // console.Call("debug", msg) - console.Call("log", msg) - } -} - -func Trace(format string, a ...any) { - if GlobalLogLevel >= TRACE { - msg := makeLogMessage("TRACE", format, a...) - console.Call("log", msg) - } -} diff --git a/wasm/mix-fetch/go-mix-conn/internal/mixfetch/helpers.go b/wasm/mix-fetch/go-mix-conn/internal/mixfetch/helpers.go deleted file mode 100644 index 23a91b725b..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/mixfetch/helpers.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -package mixfetch - -import ( - "golang.org/x/net/idna" - "net" - "net/url" - "unicode" -) - -var portMap = map[string]string{ - "http": "80", - "https": "443", - "socks5": "1080", -} - -// canonicalAddr returns url.Host but always with a ":port" suffix. -// source: https://github.com/golang/go/blob/release-branch.go1.20/src/net/http/transport.go#L2747 -func canonicalAddr(url *url.URL) string { - addr := url.Hostname() - if v, err := idnaASCII(addr); err == nil { - addr = v - } - port := url.Port() - if port == "" { - port = portMap[url.Scheme] - } - return net.JoinHostPort(addr, port) -} - -// source: https://github.com/golang/go/blob/release-branch.go1.20/src/net/http/request.go#L724 -func idnaASCII(v string) (string, error) { - // TODO: Consider removing this check after verifying performance is okay. - // Right now punycode verification, length checks, context checks, and the - // permissible character tests are all omitted. It also prevents the ToASCII - // call from salvaging an invalid IDN, when possible. As a result it may be - // possible to have two IDNs that appear identical to the user where the - // ASCII-only version causes an error downstream whereas the non-ASCII - // version does not. - // Note that for correct ASCII IDNs ToASCII will only do considerably more - // work, but it will not cause an allocation. - if isAscii(v) { - return v, nil - } - return idna.Lookup.ToASCII(v) -} - -// isAscii returns whether s is ASCII. -// source: https://github.com/golang/go/blob/release-branch.go1.20/src/net/http/internal/ascii/print.go#L46 -func isAscii(s string) bool { - for i := 0; i < len(s); i++ { - if s[i] > unicode.MaxASCII { - return false - } - } - return true -} diff --git a/wasm/mix-fetch/go-mix-conn/internal/mixfetch/mixfetch.go b/wasm/mix-fetch/go-mix-conn/internal/mixfetch/mixfetch.go deleted file mode 100644 index 1fad6a8424..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/mixfetch/mixfetch.go +++ /dev/null @@ -1,405 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -package mixfetch - -import ( - "context" - "crypto/rand" - "encoding/hex" - "errors" - "fmt" - "go-mix-conn/internal/bridge/rust_bridge" - "go-mix-conn/internal/jstypes" - "go-mix-conn/internal/jstypes/conv" - "go-mix-conn/internal/log" - "go-mix-conn/internal/state" - "go-mix-conn/internal/types" - "net" - "net/http" - "time" -) - -func inRedirectionLoop(req *http.Request, via []*http.Request) bool { - target := req.URL.String() - - for i := 0; i < len(via); i++ { - if target == via[i].URL.String() { - return true - } - } - return false -} - -func checkRedirect(ctx *types.RequestContext, opts *types.RequestOptions, req *http.Request, via []*http.Request) error { - log.Debug("attempting to perform redirection to %s with our policy set to '%s'", req.URL.String(), opts.Redirect) - - if len(via) > state.MaxRedirections { - return errors.New(fmt.Sprintf("Maximum (%d) redirects followed", state.MaxRedirections)) - } - - if inRedirectionLoop(req, via) { - return errors.New("stuck in redirection loop") - } - - redirectionChain := "" - for i := 0; i < len(via); i++ { - redirectionChain += fmt.Sprintf("%s -> ", via[i].URL.String()) - } - redirectionChain += fmt.Sprintf("[%s]", req.URL.String()) - log.Debug("redirection chain: %s", redirectionChain) - - // Reference: https://fetch.spec.whatwg.org/#http-fetch - // 4.3.6.2 - switch opts.Redirect { - case jstypes.RequestRedirectError: - return errors.New("encountered redirect") - case jstypes.RequestRedirectManual: - if opts.Mode == jstypes.ModeNavigate { - return errors.New("unimplemented 'navigate' + 'manual' redirection") - } - ctx.OverwrittenResponseType = jstypes.ResponseTypeOpaqueRedirect - return http.ErrUseLastResponse - case jstypes.RequestRedirectFollow: - log.Debug("will perform redirection") - // this feels so nasty... - ctx.WasRedirected = true - return nil - default: - // if this was rust that had proper enums and match statements, - // we could have guaranteed that at compile time... - panic("unreachable") - } -} - -// 4.1.12 -// Reference: https://fetch.spec.whatwg.org/#main-fetch -func mainFetchChecks(req *conv.ParsedRequest) error { - // >>> START: NOT INCLUDED IN FETCH SPEC - if req.Options.Mode == jstypes.ModeUnsafeIgnoreCors { - // ignore all checks - everything should be accepted - req.Options.ResponseTainting = jstypes.ResponseTaintingUnsafeIgnoreCors - return nil - } - // >>> END: NOT INCLUDED IN FETCH SPEC - - // no preloading - - if (jstypes.IsSameOrigin(req.Request.URL) && req.Options.ResponseTainting == jstypes.ResponseTaintingBasic) || - req.Request.URL.Scheme == "data" || (req.Options.Mode == jstypes.ModeNavigate || req.Options.Mode == jstypes.ModeWebsocket) { - log.Debug("setting response tainting to basic") - req.Options.ResponseTainting = jstypes.ResponseTaintingBasic - // TODO: scheme fetch here - return nil - } - if req.Options.Mode == jstypes.ModeSameOrigin { - return errors.New(fmt.Sprintf("MixFetch API cannot load %s. Request mode is \"%s\" but the URL's origin is not same as the request origin %v.", req.Request.URL.String(), jstypes.ModeSameOrigin, jstypes.Origin())) - } - if req.Options.Mode == jstypes.ModeNoCors { - if req.Options.Redirect != jstypes.RequestRedirectFollow { - return errors.New(fmt.Sprintf("MixFetch API cannot load %s. Request mode is \"%s\", but the redirect mode is not \"%s\".", req.Request.URL.String(), req.Options.Mode, jstypes.RequestRedirectFollow)) - } - log.Debug("setting response tainting to opaque") - req.Options.ResponseTainting = jstypes.ResponseTaintingOpaque - // TODO: scheme fetch here - return nil - } - if req.Request.URL.Scheme != "http" && req.Request.URL.Scheme != "https" { - return errors.New(fmt.Sprintf("The requested url scheme (\"%s\" is not http(s)", req.Request.URL.Scheme)) - } - - // TODO: CORS-preflight flag - // TODO: unsafe-request flag - // (by default they're unset) - corsPreflightFlag := false - unsafeRequestFlag := false - - if corsPreflightFlag || (unsafeRequestFlag && (jstypes.IsCorsSafelistedMethod(req.Request.Method) || len(jstypes.CorsUnsafeRequestHeaderNames(req.Request.Header)) > 0)) { - req.Options.ResponseTainting = jstypes.ResponseTaintingCors - panic("unimplemented \"corsWithPreflightResponse\"") - } - - req.Options.ResponseTainting = jstypes.ResponseTaintingCors - log.Debug("setting response tainting to cors") - // TODO: HTTP fetch here - return nil -} - -func schemeFetch(req *conv.ParsedRequest) error { - switch req.Request.URL.Scheme { - case "about": - return errors.New("unsupported 'about' scheme") - case "blob": - return errors.New("unsupported 'blob' scheme") - case "data": - return errors.New("unsupported 'data' scheme") - case "file": - return errors.New("unsupported 'file' scheme") - case "http", "https": - // TODO: HTTP fetch here - return nil - default: - return errors.New("unknown url scheme") - } -} - -// dialContext is called by Go's HTTP transport with addr derived from the real -// request URL. mappingKey is only used for tracking in ActiveRequests — it is -// never sent over the wire. -func dialContext(_ctx context.Context, mappingKey string, _network, addr string) (net.Conn, error) { - log.Debug("dialing plain connection to %s", addr) - - requestId, err := rust_bridge.RsStartNewMixnetRequest(addr) - if err != nil { - return nil, err - } - if state.ActiveRequests.Exists(requestId) { - return nil, errors.New(fmt.Sprintf("somehow opened duplicate connection with id %d", requestId)) - } - - conn, inj := state.NewFakeConnection(requestId, addr) - state.ActiveRequests.Insert(requestId, mappingKey, inj) - - return conn, nil -} - -// dialTLSContext is called by Go's HTTP transport with addr derived from the -// real request URL. mappingKey is only used for tracking in ActiveRequests — -// it is never sent over the wire. -func dialTLSContext(_ctx context.Context, mappingKey string, _network, addr string) (net.Conn, error) { - log.Debug("dialing TLS connection to %s", addr) - - requestId, err := rust_bridge.RsStartNewMixnetRequest(addr) - if err != nil { - return nil, err - } - if state.ActiveRequests.Exists(requestId) { - return nil, errors.New(fmt.Sprintf("somehow opened duplicate connection with id %d", requestId)) - } - - conn, inj := state.NewFakeTlsConn(requestId, addr) - state.ActiveRequests.Insert(requestId, mappingKey, inj) - - if err := conn.Handshake(); err != nil { - return nil, err - } - - return conn, nil -} - -// buildHttpClient creates an HTTP client with custom dial functions that route -// connections through the mixnet. mappingKey is captured by the dial closures -// for request tracking only — the actual destination comes from addr, which -// Go's HTTP transport derives from the real request URL. -func buildHttpClient(reqCtx *types.RequestContext, opts *types.RequestOptions, mappingKey string) *http.Client { - return &http.Client{ - CheckRedirect: func(req *http.Request, via []*http.Request) error { - return checkRedirect(reqCtx, opts, req, via) - }, - - Transport: &http.Transport{ - DialContext: func(ctx context.Context, network, addr string) (net.Conn, error) { - return dialContext(ctx, mappingKey, network, addr) - }, - DialTLSContext: func(ctx context.Context, network, addr string) (net.Conn, error) { - return dialTLSContext(ctx, mappingKey, network, addr) - }, - - //TLSClientConfig: &tlsConfig, - DisableKeepAlives: true, - // Allow multiple concurrent connections to the same host. - // Previously set to 1. - MaxIdleConns: 10, - MaxIdleConnsPerHost: 10, - MaxConnsPerHost: 10, - }, - Timeout: state.RequestTimeout, - } -} - -func CloseRemoteSocket(requestId types.RequestId) any { - state.ActiveRequests.CloseRemoteSocket(requestId) - return nil -} - -func InjectServerData(requestId types.RequestId, data []byte) any { - state.ActiveRequests.InjectData(requestId, data) - return nil -} - -func InjectConnError(requestId types.RequestId, err error) any { - state.ActiveRequests.SendError(requestId, err) - return nil -} - -func ChangeRequestTimeout(timeout time.Duration) any { - log.Debug("changing request timeout to %v", timeout) - state.RequestTimeout = timeout - return nil -} - -// Reference: https://fetch.spec.whatwg.org/#cors-check -func doCorsCheck(reqOpts *types.RequestOptions, resp *http.Response) error { - // 4.9.1 - originHeader := resp.Header.Get(jstypes.HeaderAllowOrigin) - // 4.9.2 - if originHeader == "" { - return errors.New(fmt.Sprintf("\"%s\" header not present on remote", jstypes.HeaderAllowOrigin)) - } - - if reqOpts.CredentialsMode != jstypes.CredentialsModeInclude && originHeader == jstypes.Wildcard { - // 4.9.3 - return nil - } - - // 4.9.4 - // TODO: presumably this needs to better account for the wildcard? - - // if origin is null it means 4.9.2 would have failed anyway - origin := jstypes.Origin() - if origin == nil { - // TODO: won't this essentially fail all node requests? - return errors.New("the local origin is null") - } - - // safety: it's fine to dereference the pointer here as we've just checked if it's null - if *origin != originHeader { - return errors.New(fmt.Sprintf("\"%v\" does not match the origin \"%s\" on \"%s\" remote header", jstypes.Origin(), originHeader, jstypes.HeaderAllowOrigin)) - } - - // 4.9.5 - if reqOpts.CredentialsMode != jstypes.CredentialsModeInclude { - return nil - } - - // 4.9.6 - credentials := resp.Header.Get(jstypes.HeaderAllowCredentials) - // 4.9.7 - if credentials == "true" { - return nil - } - - // 4.9.8 - return errors.New("failed cors check") -} - -// performRequest executes the HTTP request. mappingKey is threaded through to -// buildHttpClient for request tracking only. The actual HTTP request is made -// with req.Request (the original, unmodified URL) at reqClient.Do(req.Request). -func performRequest(req *conv.ParsedRequest, mappingKey string) (*conv.ResponseWrapper, error) { - err := mainFetchChecks(req) - if err != nil { - return nil, err - } - - reqCtx := &types.RequestContext{} - - // mappingKey is only captured by the dial closures for ActiveRequests tracking. - reqClient := buildHttpClient(reqCtx, req.Options, mappingKey) - - if req.Options.ReferrerPolicy == "" { - // 4.1.8 - // Reference: https://fetch.spec.whatwg.org/#main-fetch - // TODO: implement - log.Warn("unimplemented: could not obtain referrer policy from the policy container") - } - - if req.Options.Referrer != jstypes.ReferrerNoReferrer { - // 4.1.9 - // Reference: https://fetch.spec.whatwg.org/#main-fetch - // TODO: implement - log.Warn("unimplemented: could not determine request's referrer") - } - - // TODO: this is such a nasty assumption, but assume we're doing a 4.3 HTTP fetch here - - log.Info("Starting the request...") - log.Debug("%v: %v", req.Options, *req.Request) - // TODO: CORS preflight... - - // This is where the actual HTTP request is made. req.Request contains the - // original, unmodified URL — mappingKey is NOT used here. - resp, err := reqClient.Do(req.Request) - if err != nil { - return nil, err - } - - // 4.3.4.4 - if req.Options.ResponseTainting == jstypes.ResponseTaintingCors { - err = doCorsCheck(req.Options, resp) - if err != nil { - return nil, err - } - } - // TODO: policy checks, etc... - - wrapper := conv.NewResponseWrapper(resp, reqCtx) - - return &wrapper, err -} - -func onErrCleanup(mappingKey string) { - // TODO: cancel stuff here.... somehow... - - id := state.ActiveRequests.GetId(mappingKey) - // TODO: can we guarantee that rust is not holding any references to that id (that we don't know on this side)? - if id == 0 { - // if id doesn't exist it [probably] means the error was thrown before the request was properly created - log.Debug("there doesn't seem to exist a request associated with mapping key %s", mappingKey) - return - } - state.ActiveRequests.Remove(id) - err := rust_bridge.RsFinishMixnetConnection(id) - if err != nil { - // TODO: can we do anything else in here? - log.Error("failed to properly abort the request: %s", err) - } -} - -// generateMappingKey creates a unique key for the address mapping by appending -// random bytes to the URL. This allows concurrent requests to the same URL. -func generateMappingKey(rawURL string) string { - b := make([]byte, 8) - _, _ = rand.Read(b) - return rawURL + "#" + hex.EncodeToString(b) -} - -// MixFetch performs an HTTP request over the Mixnet. -// -// Two separate values flow through this function: -// - request.Request: the actual HTTP request (with the real URL). This is -// what gets sent over the wire via reqClient.Do(). It is never modified. -// - mappingKey: a unique internal key (URL + random suffix) used only for -// tracking the request in ActiveRequests.AddressMapping. It is never -// sent over the wire. This allows concurrent requests to the same URL. -func MixFetch(request *conv.ParsedRequest) (any, error) { - log.Info("_mixFetch: start") - - // Generate a unique mapping key for internal request tracking. - mappingKey := generateMappingKey(request.Request.URL.String()) - for state.ActiveRequests.GetId(mappingKey) != 0 { - mappingKey = generateMappingKey(request.Request.URL.String()) - } - - resCh := make(chan *conv.ResponseWrapper) - errCh := make(chan error) - go func(resCh chan *conv.ResponseWrapper, errCh chan error) { - resp, err := performRequest(request, mappingKey) - if err != nil { - errCh <- err - } else { - resCh <- resp - } - }(resCh, errCh) - - select { - case res := <-resCh: - log.Debug("finished performing the request") - log.Trace("response: %+v", *res) - return conv.IntoJSResponse(res, request.Options) - case err := <-errCh: - log.Warn("request failure: %s", err) - onErrCleanup(mappingKey) - return nil, err - } -} diff --git a/wasm/mix-fetch/go-mix-conn/internal/sslhelpers/cacert.pem b/wasm/mix-fetch/go-mix-conn/internal/sslhelpers/cacert.pem deleted file mode 100644 index 65be891eea..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/sslhelpers/cacert.pem +++ /dev/null @@ -1,3511 +0,0 @@ -## -## Bundle of CA Root Certificates -## -## Certificate data from Mozilla as of: Tue Dec 2 04:12:02 2025 GMT -## -## Find updated versions here: https://curl.se/docs/caextract.html -## -## This is a bundle of X.509 certificates of public Certificate Authorities -## (CA). These were automatically extracted from Mozilla's root certificates -## file (certdata.txt). This file can be found in the mozilla source tree: -## https://raw.githubusercontent.com/mozilla-firefox/firefox/refs/heads/release/security/nss/lib/ckfw/builtins/certdata.txt -## -## It contains the certificates in PEM format and therefore -## can be directly used with curl / libcurl / php_curl, or with -## an Apache+mod_ssl webserver for SSL client authentication. -## Just configure this file as the SSLCACertificateFile. -## -## Conversion done with mk-ca-bundle.pl version 1.30. -## SHA256: a903b3cd05231e39332515ef7ebe37e697262f39515a52015c23c62805b73cd0 -## - - -Entrust Root Certification Authority -==================================== ------BEGIN CERTIFICATE----- -MIIEkTCCA3mgAwIBAgIERWtQVDANBgkqhkiG9w0BAQUFADCBsDELMAkGA1UEBhMCVVMxFjAUBgNV -BAoTDUVudHJ1c3QsIEluYy4xOTA3BgNVBAsTMHd3dy5lbnRydXN0Lm5ldC9DUFMgaXMgaW5jb3Jw -b3JhdGVkIGJ5IHJlZmVyZW5jZTEfMB0GA1UECxMWKGMpIDIwMDYgRW50cnVzdCwgSW5jLjEtMCsG -A1UEAxMkRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA2MTEyNzIwMjM0 -MloXDTI2MTEyNzIwNTM0MlowgbAxCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1FbnRydXN0LCBJbmMu -MTkwNwYDVQQLEzB3d3cuZW50cnVzdC5uZXQvQ1BTIGlzIGluY29ycG9yYXRlZCBieSByZWZlcmVu -Y2UxHzAdBgNVBAsTFihjKSAyMDA2IEVudHJ1c3QsIEluYy4xLTArBgNVBAMTJEVudHJ1c3QgUm9v -dCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -ALaVtkNC+sZtKm9I35RMOVcF7sN5EUFoNu3s/poBj6E4KPz3EEZmLk0eGrEaTsbRwJWIsMn/MYsz -A9u3g3s+IIRe7bJWKKf44LlAcTfFy0cOlypowCKVYhXbR9n10Cv/gkvJrT7eTNuQgFA/CYqEAOww -Cj0Yzfv9KlmaI5UXLEWeH25DeW0MXJj+SKfFI0dcXv1u5x609mhF0YaDW6KKjbHjKYD+JXGIrb68 -j6xSlkuqUY3kEzEZ6E5Nn9uss2rVvDlUccp6en+Q3X0dgNmBu1kmwhH+5pPi94DkZfs0Nw4pgHBN -rziGLp5/V6+eF67rHMsoIV+2HNjnogQi+dPa2MsCAwEAAaOBsDCBrTAOBgNVHQ8BAf8EBAMCAQYw -DwYDVR0TAQH/BAUwAwEB/zArBgNVHRAEJDAigA8yMDA2MTEyNzIwMjM0MlqBDzIwMjYxMTI3MjA1 -MzQyWjAfBgNVHSMEGDAWgBRokORnpKZTgMeGZqTx90tD+4S9bTAdBgNVHQ4EFgQUaJDkZ6SmU4DH -hmak8fdLQ/uEvW0wHQYJKoZIhvZ9B0EABBAwDhsIVjcuMTo0LjADAgSQMA0GCSqGSIb3DQEBBQUA -A4IBAQCT1DCw1wMgKtD5Y+iRDAUgqV8ZyntyTtSx29CW+1RaGSwMCPeyvIWonX9tO1KzKtvn1ISM -Y/YPyyYBkVBs9F8U4pN0wBOeMDpQ47RgxRzwIkSNcUesyBrJ6ZuaAGAT/3B+XxFNSRuzFVJ7yVTa -v52Vr2ua2J7p8eRDjeIRRDq/r72DQnNSi6q7pynP9WQcCk3RvKqsnyrQ/39/2n3qse0wJcGE2jTS -W3iDVuycNsMm4hH2Z0kdkquM++v/eu6FSqdQgPCnXEqULl8FmTxSQeDNtGPPAUO6nIPcj2A781q0 -tHuu2guQOHXvgR1m0vdXcDazv/wor3ElhVsT/h5/WrQ8 ------END CERTIFICATE----- - -QuoVadis Root CA 2 -================== ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - -QuoVadis Root CA 3 -================== ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - -DigiCert Assured ID Root CA -=========================== ------BEGIN CERTIFICATE----- -MIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0BAQUFADBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw -IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzEx -MTEwMDAwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL -ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgQ0Ew -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg+XESpa7cJpSIqvTO -9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lTXDGEKvYPmDI2dsze3Tyoou9q+yHy -UmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW -/lmci3Zt1/GiSw0r/wty2p5g0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpy -oeb6pNnVFzF1roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf -GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRF -66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkq -hkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2Bc -EkxY5NM9g0lFWJc1aRqoR+pWxnmrEthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38Fn -SbNd67IJKusm7Xi+fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i -8b5QZ7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu838fYxAe -+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw8g== ------END CERTIFICATE----- - -DigiCert Global Root CA -======================= ------BEGIN CERTIFICATE----- -MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBhMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw -HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBDQTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAw -MDAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 -dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkq -hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsBCSDMAZOn -TjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97nh6Vfe63SKMI2tavegw5 -BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt43C/dxC//AH2hdmoRBBYMql1GNXRor5H -4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7PT19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y -7vrTC0LUq7dBMtoM1O/4gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQAB -o2MwYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbRTLtm -8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUwDQYJKoZIhvcNAQEF -BQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/EsrhMAtudXH/vTBH1jLuG2cenTnmCmr -EbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIt -tep3Sp+dWOIrWcBAI+0tKIJFPnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886 -UAb3LujEV0lsYSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk -CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= ------END CERTIFICATE----- - -DigiCert High Assurance EV Root CA -================================== ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBsMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSsw -KQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5jZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAw -MFoXDTMxMTExMDAwMDAwMFowbDELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ -MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFu -Y2UgRVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm+9S75S0t -Mqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTWPNt0OKRKzE0lgvdKpVMS -OO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEMxChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3 -MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFBIk5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQ -NAQTXKFx01p8VdteZOE3hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUe -h10aUAsgEsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMB -Af8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaAFLE+w2kD+L9HAdSY -JhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3NecnzyIZgYIVyHbIUf4KmeqvxgydkAQ -V8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6zeM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFp -myPInngiK3BD41VHMWEZ71jFhS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkK -mNEVX58Svnw2Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe -vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep+OkuE6N36B9K ------END CERTIFICATE----- - -SwissSign Gold CA - G2 -====================== ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - -SecureTrust CA -============== ------BEGIN CERTIFICATE----- -MIIDuDCCAqCgAwIBAgIQDPCOXAgWpa1Cf/DrJxhZ0DANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQG -EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xFzAVBgNVBAMTDlNlY3VyZVRy -dXN0IENBMB4XDTA2MTEwNzE5MzExOFoXDTI5MTIzMTE5NDA1NVowSDELMAkGA1UEBhMCVVMxIDAe -BgNVBAoTF1NlY3VyZVRydXN0IENvcnBvcmF0aW9uMRcwFQYDVQQDEw5TZWN1cmVUcnVzdCBDQTCC -ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKukgeWVzfX2FI7CT8rU4niVWJxB4Q2ZQCQX -OZEzZum+4YOvYlyJ0fwkW2Gz4BERQRwdbvC4u/jep4G6pkjGnx29vo6pQT64lO0pGtSO0gMdA+9t -DWccV9cGrcrI9f4Or2YlSASWC12juhbDCE/RRvgUXPLIXgGZbf2IzIaowW8xQmxSPmjL8xk037uH -GFaAJsTQ3MBv396gwpEWoGQRS0S8Hvbn+mPeZqx2pHGj7DaUaHp3pLHnDi+BeuK1cobvomuL8A/b -01k/unK8RCSc43Oz969XL0Imnal0ugBS8kvNU3xHCzaFDmapCJcWNFfBZveA4+1wVMeT4C4oFVmH -ursCAwEAAaOBnTCBmjATBgkrBgEEAYI3FAIEBh4EAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQUQjK2FvoE/f5dS3rD/fdMQB1aQ68wNAYDVR0fBC0wKzApoCegJYYj -aHR0cDovL2NybC5zZWN1cmV0cnVzdC5jb20vU1RDQS5jcmwwEAYJKwYBBAGCNxUBBAMCAQAwDQYJ -KoZIhvcNAQEFBQADggEBADDtT0rhWDpSclu1pqNlGKa7UTt36Z3q059c4EVlew3KW+JwULKUBRSu -SceNQQcSc5R+DCMh/bwQf2AQWnL1mA6s7Ll/3XpvXdMc9P+IBWlCqQVxyLesJugutIxq/3HcuLHf -mbx8IVQr5Fiiu1cprp6poxkmD5kuCLDv/WnPmRoJjeOnnyvJNjR7JLN4TJUXpAYmHrZkUjZfYGfZ -nMUFdAvnZyPSCPyI6a6Lf+Ew9Dd+/cYy2i2eRDAwbO4H3tI0/NL/QPZL9GZGBlSm8jIKYyYwa5vR -3ItHuuG51WLQoqD0ZwV4KWMabwTW+MZMo5qxN7SN5ShLHZ4swrhovO0C7jE= ------END CERTIFICATE----- - -Secure Global CA -================ ------BEGIN CERTIFICATE----- -MIIDvDCCAqSgAwIBAgIQB1YipOjUiolN9BPI8PjqpTANBgkqhkiG9w0BAQUFADBKMQswCQYDVQQG -EwJVUzEgMB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBH -bG9iYWwgQ0EwHhcNMDYxMTA3MTk0MjI4WhcNMjkxMjMxMTk1MjA2WjBKMQswCQYDVQQGEwJVUzEg -MB4GA1UEChMXU2VjdXJlVHJ1c3QgQ29ycG9yYXRpb24xGTAXBgNVBAMTEFNlY3VyZSBHbG9iYWwg -Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCvNS7YrGxVaQZx5RNoJLNP2MwhR/jx -YDiJiQPpvepeRlMJ3Fz1Wuj3RSoC6zFh1ykzTM7HfAo3fg+6MpjhHZevj8fcyTiW89sa/FHtaMbQ -bqR8JNGuQsiWUGMu4P51/pinX0kuleM5M2SOHqRfkNJnPLLZ/kG5VacJjnIFHovdRIWCQtBJwB1g -8NEXLJXr9qXBkqPFwqcIYA1gBBCWeZ4WNOaptvolRTnIHmX5k/Wq8VLcmZg9pYYaDDUz+kulBAYV -HDGA76oYa8J719rO+TMg1fW9ajMtgQT7sFzUnKPiXB3jqUJ1XnvUd+85VLrJChgbEplJL4hL/VBi -0XPnj3pDAgMBAAGjgZ0wgZowEwYJKwYBBAGCNxQCBAYeBABDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud -EwEB/wQFMAMBAf8wHQYDVR0OBBYEFK9EBMJBfkiD2045AuzshHrmzsmkMDQGA1UdHwQtMCswKaAn -oCWGI2h0dHA6Ly9jcmwuc2VjdXJldHJ1c3QuY29tL1NHQ0EuY3JsMBAGCSsGAQQBgjcVAQQDAgEA -MA0GCSqGSIb3DQEBBQUAA4IBAQBjGghAfaReUw132HquHw0LURYD7xh8yOOvaliTFGCRsoTciE6+ -OYo68+aCiV0BN7OrJKQVDpI1WkpEXk5X+nXOH0jOZvQ8QCaSmGwb7iRGDBezUqXbpZGRzzfTb+cn -CDpOGR86p1hcF895P4vkp9MmI50mD1hp/Ed+stCNi5O/KU9DaXR2Z0vPB4zmAve14bRDtUstFJ/5 -3CYNv6ZHdAbYiNE6KTCEztI5gGIbqMdXSbxqVVFnFUq+NQfk1XWYN3kwFNspnWzFacxHVaIw98xc -f8LDmBxrThaA63p4ZUWiABqvDA1VZDRIuJK58bRQKfJPIx/abKwfROHdI3hRW8cW ------END CERTIFICATE----- - -COMODO Certification Authority -============================== ------BEGIN CERTIFICATE----- -MIIEHTCCAwWgAwIBAgIQToEtioJl4AsC7j41AkblPTANBgkqhkiG9w0BAQUFADCBgTELMAkGA1UE -BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG -A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxJzAlBgNVBAMTHkNPTU9ETyBDZXJ0aWZpY2F0aW9uIEF1 -dGhvcml0eTAeFw0wNjEyMDEwMDAwMDBaFw0yOTEyMzEyMzU5NTlaMIGBMQswCQYDVQQGEwJHQjEb -MBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFD -T01PRE8gQ0EgTGltaXRlZDEnMCUGA1UEAxMeQ09NT0RPIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0ECLi3LjkRv3UcEbVASY06m/weaKXTuH -+7uIzg3jLz8GlvCiKVCZrts7oVewdFFxze1CkU1B/qnI2GqGd0S7WWaXUF601CxwRM/aN5VCaTww -xHGzUvAhTaHYujl8HJ6jJJ3ygxaYqhZ8Q5sVW7euNJH+1GImGEaaP+vB+fGQV+useg2L23IwambV -4EajcNxo2f8ESIl33rXp+2dtQem8Ob0y2WIC8bGoPW43nOIv4tOiJovGuFVDiOEjPqXSJDlqR6sA -1KGzqSX+DT+nHbrTUcELpNqsOO9VUCQFZUaTNE8tja3G1CEZ0o7KBWFxB3NH5YoZEr0ETc5OnKVI -rLsm9wIDAQABo4GOMIGLMB0GA1UdDgQWBBQLWOWLxkwVN6RAqTCpIb5HNlpW/zAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLmNvbW9k -b2NhLmNvbS9DT01PRE9DZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDANBgkqhkiG9w0BAQUFAAOC -AQEAPpiem/Yb6dc5t3iuHXIYSdOH5EOC6z/JqvWote9VfCFSZfnVDeFs9D6Mk3ORLgLETgdxb8CP -OGEIqB6BCsAvIC9Bi5HcSEW88cbeunZrM8gALTFGTO3nnc+IlP8zwFboJIYmuNg4ON8qa90SzMc/ -RxdMosIGlgnW2/4/PEZB31jiVg88O8EckzXZOFKs7sjsLjBOlDW0JB9LeGna8gI4zJVSk/BwJVmc -IGfE7vmLV2H0knZ9P4SNVbfo5azV8fUZVqZa+5Acr5Pr5RzUZ5ddBA6+C4OmF4O5MBKgxTMVBbkN -+8cFduPYSo38NBejxiEovjBFMR7HeL5YYTisO+IBZQ== ------END CERTIFICATE----- - -COMODO ECC Certification Authority -================================== ------BEGIN CERTIFICATE----- -MIICiTCCAg+gAwIBAgIQH0evqmIAcFBUTAGem2OZKjAKBggqhkjOPQQDAzCBhTELMAkGA1UEBhMC -R0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE -ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBB -dXRob3JpdHkwHhcNMDgwMzA2MDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBhTELMAkGA1UEBhMCR0Ix -GzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMR -Q09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBFQ0MgQ2VydGlmaWNhdGlvbiBBdXRo -b3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQDR3svdcmCFYX7deSRFtSrYpn1PlILBs5BAH+X -4QokPB0BBO490o0JlwzgdeT6+3eKKvUDYEs2ixYjFq0JcfRK9ChQtP6IHG4/bC8vCVlbpVsLM5ni -wz2J+Wos77LTBumjQjBAMB0GA1UdDgQWBBR1cacZSBm8nZ3qQUfflMRId5nTeTAOBgNVHQ8BAf8E -BAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjEA7wNbeqy3eApyt4jf/7VG -FAkK+qDmfQjGGoe9GKhzvSbKYAydzpmfz1wPMOG+FDHqAjAU9JM8SaczepBGR7NjfRObTrdvGDeA -U/7dIOA1mjbRxwG55tzd8/8dLDoWV9mSOdY= ------END CERTIFICATE----- - -Certigna -======== ------BEGIN CERTIFICATE----- -MIIDqDCCApCgAwIBAgIJAP7c4wEPyUj/MA0GCSqGSIb3DQEBBQUAMDQxCzAJBgNVBAYTAkZSMRIw -EAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hMB4XDTA3MDYyOTE1MTMwNVoXDTI3 -MDYyOTE1MTMwNVowNDELMAkGA1UEBhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczERMA8GA1UEAwwI -Q2VydGlnbmEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDIaPHJ1tazNHUmgh7stL7q -XOEm7RFHYeGifBZ4QCHkYJ5ayGPhxLGWkv8YbWkj4Sti993iNi+RB7lIzw7sebYs5zRLcAglozyH -GxnygQcPOJAZ0xH+hrTy0V4eHpbNgGzOOzGTtvKg0KmVEn2lmsxryIRWijOp5yIVUxbwzBfsV1/p -ogqYCd7jX5xv3EjjhQsVWqa6n6xI4wmy9/Qy3l40vhx4XUJbzg4ij02Q130yGLMLLGq/jj8UEYkg -DncUtT2UCIf3JR7VsmAA7G8qKCVuKj4YYxclPz5EIBb2JsglrgVKtOdjLPOMFlN+XPsRGgjBRmKf -Irjxwo1p3Po6WAbfAgMBAAGjgbwwgbkwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUGu3+QTmQ -tCRZvgHyUtVF9lo53BEwZAYDVR0jBF0wW4AUGu3+QTmQtCRZvgHyUtVF9lo53BGhOKQ2MDQxCzAJ -BgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxETAPBgNVBAMMCENlcnRpZ25hggkA/tzjAQ/J -SP8wDgYDVR0PAQH/BAQDAgEGMBEGCWCGSAGG+EIBAQQEAwIABzANBgkqhkiG9w0BAQUFAAOCAQEA -hQMeknH2Qq/ho2Ge6/PAD/Kl1NqV5ta+aDY9fm4fTIrv0Q8hbV6lUmPOEvjvKtpv6zf+EwLHyzs+ -ImvaYS5/1HI93TDhHkxAGYwP15zRgzB7mFncfca5DClMoTOi62c6ZYTTluLtdkVwj7Ur3vkj1klu -PBS1xp81HlDQwY9qcEQCYsuuHWhBp6pX6FOqB9IG9tUUBguRA3UsbHK1YZWaDYu5Def131TN3ubY -1gkIl2PlwS6wt0QmwCbAr1UwnjvVNioZBPRcHv/PLLf/0P2HQBHVESO7SMAhqaQoLf0V+LBOK/Qw -WyH8EZE0vkHve52Xdf+XlcCWWC/qu0bXu+TZLg== ------END CERTIFICATE----- - -ePKI Root Certification Authority -================================= ------BEGIN CERTIFICATE----- -MIIFsDCCA5igAwIBAgIQFci9ZUdcr7iXAF7kBtK8nTANBgkqhkiG9w0BAQUFADBeMQswCQYDVQQG -EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xKjAoBgNVBAsMIWVQS0kg -Um9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0wNDEyMjAwMjMxMjdaFw0zNDEyMjAwMjMx -MjdaMF4xCzAJBgNVBAYTAlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEq -MCgGA1UECwwhZVBLSSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0B -AQEFAAOCAg8AMIICCgKCAgEA4SUP7o3biDN1Z82tH306Tm2d0y8U82N0ywEhajfqhFAHSyZbCUNs -IZ5qyNUD9WBpj8zwIuQf5/dqIjG3LBXy4P4AakP/h2XGtRrBp0xtInAhijHyl3SJCRImHJ7K2RKi -lTza6We/CKBk49ZCt0Xvl/T29de1ShUCWH2YWEtgvM3XDZoTM1PRYfl61dd4s5oz9wCGzh1NlDiv -qOx4UXCKXBCDUSH3ET00hl7lSM2XgYI1TBnsZfZrxQWh7kcT1rMhJ5QQCtkkO7q+RBNGMD+XPNjX -12ruOzjjK9SXDrkb5wdJfzcq+Xd4z1TtW0ado4AOkUPB1ltfFLqfpo0kR0BZv3I4sjZsN/+Z0V0O -WQqraffAsgRFelQArr5T9rXn4fg8ozHSqf4hUmTFpmfwdQcGlBSBVcYn5AGPF8Fqcde+S/uUWH1+ -ETOxQvdibBjWzwloPn9s9h6PYq2lY9sJpx8iQkEeb5mKPtf5P0B6ebClAZLSnT0IFaUQAS2zMnao -lQ2zepr7BxB4EW/hj8e6DyUadCrlHJhBmd8hh+iVBmoKs2pHdmX2Os+PYhcZewoozRrSgx4hxyy/ -vv9haLdnG7t4TY3OZ+XkwY63I2binZB1NJipNiuKmpS5nezMirH4JYlcWrYvjB9teSSnUmjDhDXi -Zo1jDiVN1Rmy5nk3pyKdVDECAwEAAaNqMGgwHQYDVR0OBBYEFB4M97Zn8uGSJglFwFU5Lnc/Qkqi -MAwGA1UdEwQFMAMBAf8wOQYEZyoHAAQxMC8wLQIBADAJBgUrDgMCGgUAMAcGBWcqAwAABBRFsMLH -ClZ87lt4DJX5GFPBphzYEDANBgkqhkiG9w0BAQUFAAOCAgEACbODU1kBPpVJufGBuvl2ICO1J2B0 -1GqZNF5sAFPZn/KmsSQHRGoqxqWOeBLoR9lYGxMqXnmbnwoqZ6YlPwZpVnPDimZI+ymBV3QGypzq -KOg4ZyYr8dW1P2WT+DZdjo2NQCCHGervJ8A9tDkPJXtoUHRVnAxZfVo9QZQlUgjgRywVMRnVvwdV -xrsStZf0X4OFunHB2WyBEXYKCrC/gpf36j36+uwtqSiUO1bd0lEursC9CBWMd1I0ltabrNMdjmEP -NXubrjlpC2JgQCA2j6/7Nu4tCEoduL+bXPjqpRugc6bY+G7gMwRfaKonh+3ZwZCc7b3jajWvY9+r -GNm65ulK6lCKD2GTHuItGeIwlDWSXQ62B68ZgI9HkFFLLk3dheLSClIKF5r8GrBQAuUBo2M3IUxE -xJtRmREOc5wGj1QupyheRDmHVi03vYVElOEMSyycw5KFNGHLD7ibSkNS/jQ6fbjpKdx2qcgw+BRx -gMYeNkh0IkFch4LoGHGLQYlE535YW6i4jRPpp2zDR+2zGp1iro2C6pSe3VkQw63d4k3jMdXH7Ojy -sP6SHhYKGvzZ8/gntsm+HbRsZJB/9OTEW9c3rkIO3aQab3yIVMUWbuF6aC74Or8NpDyJO3inTmOD -BCEIZ43ygknQW/2xzQ+DhNQ+IIX3Sj0rnP0qCglN6oH4EZw= ------END CERTIFICATE----- - -certSIGN ROOT CA -================ ------BEGIN CERTIFICATE----- -MIIDODCCAiCgAwIBAgIGIAYFFnACMA0GCSqGSIb3DQEBBQUAMDsxCzAJBgNVBAYTAlJPMREwDwYD -VQQKEwhjZXJ0U0lHTjEZMBcGA1UECxMQY2VydFNJR04gUk9PVCBDQTAeFw0wNjA3MDQxNzIwMDRa -Fw0zMTA3MDQxNzIwMDRaMDsxCzAJBgNVBAYTAlJPMREwDwYDVQQKEwhjZXJ0U0lHTjEZMBcGA1UE -CxMQY2VydFNJR04gUk9PVCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALczuX7I -JUqOtdu0KBuqV5Do0SLTZLrTk+jUrIZhQGpgV2hUhE28alQCBf/fm5oqrl0Hj0rDKH/v+yv6efHH -rfAQUySQi2bJqIirr1qjAOm+ukbuW3N7LBeCgV5iLKECZbO9xSsAfsT8AzNXDe3i+s5dRdY4zTW2 -ssHQnIFKquSyAVwdj1+ZxLGt24gh65AIgoDzMKND5pCCrlUoSe1b16kQOA7+j0xbm0bqQfWwCHTD -0IgztnzXdN/chNFDDnU5oSVAKOp4yw4sLjmdjItuFhwvJoIQ4uNllAoEwF73XVv4EOLQunpL+943 -AAAaWyjj0pxzPjKHmKHJUS/X3qwzs08CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8B -Af8EBAMCAcYwHQYDVR0OBBYEFOCMm9slSbPxfIbWskKHC9BroNnkMA0GCSqGSIb3DQEBBQUAA4IB -AQA+0hyJLjX8+HXd5n9liPRyTMks1zJO890ZeUe9jjtbkw9QSSQTaxQGcu8J06Gh40CEyecYMnQ8 -SG4Pn0vU9x7Tk4ZkVJdjclDVVc/6IJMCopvDI5NOFlV2oHB5bc0hH88vLbwZ44gx+FkagQnIl6Z0 -x2DEW8xXjrJ1/RsCCdtZb3KTafcxQdaIOL+Hsr0Wefmq5L6IJd1hJyMctTEHBDa0GpC9oHRxUIlt -vBTjD4au8as+x6AJzKNI0eDbZOeStc+vckNwi/nDhDwTqn6Sm1dTk/pwwpEOMfmbZ13pljheX7Nz -TogVZ96edhBiIL5VaZVDADlN9u6wWk5JRFRYX0KD ------END CERTIFICATE----- - -NetLock Arany (Class Gold) Főtanúsítvány -======================================== ------BEGIN CERTIFICATE----- -MIIEFTCCAv2gAwIBAgIGSUEs5AAQMA0GCSqGSIb3DQEBCwUAMIGnMQswCQYDVQQGEwJIVTERMA8G -A1UEBwwIQnVkYXBlc3QxFTATBgNVBAoMDE5ldExvY2sgS2Z0LjE3MDUGA1UECwwuVGFuw7pzw610 -dsOhbnlraWFkw7NrIChDZXJ0aWZpY2F0aW9uIFNlcnZpY2VzKTE1MDMGA1UEAwwsTmV0TG9jayBB -cmFueSAoQ2xhc3MgR29sZCkgRsWRdGFuw7pzw610dsOhbnkwHhcNMDgxMjExMTUwODIxWhcNMjgx -MjA2MTUwODIxWjCBpzELMAkGA1UEBhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRUwEwYDVQQKDAxO -ZXRMb2NrIEtmdC4xNzA1BgNVBAsMLlRhbsO6c8OtdHbDoW55a2lhZMOzayAoQ2VydGlmaWNhdGlv -biBTZXJ2aWNlcykxNTAzBgNVBAMMLE5ldExvY2sgQXJhbnkgKENsYXNzIEdvbGQpIEbFkXRhbsO6 -c8OtdHbDoW55MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxCRec75LbRTDofTjl5Bu -0jBFHjzuZ9lk4BqKf8owyoPjIMHj9DrTlF8afFttvzBPhCf2nx9JvMaZCpDyD/V/Q4Q3Y1GLeqVw -/HpYzY6b7cNGbIRwXdrzAZAj/E4wqX7hJ2Pn7WQ8oLjJM2P+FpD/sLj916jAwJRDC7bVWaaeVtAk -H3B5r9s5VA1lddkVQZQBr17s9o3x/61k/iCa11zr/qYfCGSji3ZVrR47KGAuhyXoqq8fxmRGILdw -fzzeSNuWU7c5d+Qa4scWhHaXWy+7GRWF+GmF9ZmnqfI0p6m2pgP8b4Y9VHx2BJtr+UBdADTHLpl1 -neWIA6pN+APSQnbAGwIDAKiLo0UwQzASBgNVHRMBAf8ECDAGAQH/AgEEMA4GA1UdDwEB/wQEAwIB -BjAdBgNVHQ4EFgQUzPpnk/C2uNClwB7zU/2MU9+D15YwDQYJKoZIhvcNAQELBQADggEBAKt/7hwW -qZw8UQCgwBEIBaeZ5m8BiFRhbvG5GK1Krf6BQCOUL/t1fC8oS2IkgYIL9WHxHG64YTjrgfpioTta -YtOUZcTh5m2C+C8lcLIhJsFyUR+MLMOEkMNaj7rP9KdlpeuY0fsFskZ1FSNqb4VjMIDw1Z4fKRzC -bLBQWV2QWzuoDTDPv31/zvGdg73JRm4gpvlhUbohL3u+pRVjodSVh/GeufOJ8z2FuLjbvrW5Kfna -NwUASZQDhETnv0Mxz3WLJdH0pmT1kvarBes96aULNmLazAZfNou2XjG4Kvte9nHfRCaexOYNkbQu -dZWAUWpLMKawYqGT8ZvYzsRjdT9ZR7E= ------END CERTIFICATE----- - -Microsec e-Szigno Root CA 2009 -============================== ------BEGIN CERTIFICATE----- -MIIECjCCAvKgAwIBAgIJAMJ+QwRORz8ZMA0GCSqGSIb3DQEBCwUAMIGCMQswCQYDVQQGEwJIVTER -MA8GA1UEBwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jv -c2VjIGUtU3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5o -dTAeFw0wOTA2MTYxMTMwMThaFw0yOTEyMzAxMTMwMThaMIGCMQswCQYDVQQGEwJIVTERMA8GA1UE -BwwIQnVkYXBlc3QxFjAUBgNVBAoMDU1pY3Jvc2VjIEx0ZC4xJzAlBgNVBAMMHk1pY3Jvc2VjIGUt -U3ppZ25vIFJvb3QgQ0EgMjAwOTEfMB0GCSqGSIb3DQEJARYQaW5mb0BlLXN6aWduby5odTCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOn4j/NjrdqG2KfgQvvPkd6mJviZpWNwrZuuyjNA -fW2WbqEORO7hE52UQlKavXWFdCyoDh2Tthi3jCyoz/tccbna7P7ofo/kLx2yqHWH2Leh5TvPmUpG -0IMZfcChEhyVbUr02MelTTMuhTlAdX4UfIASmFDHQWe4oIBhVKZsTh/gnQ4H6cm6M+f+wFUoLAKA -pxn1ntxVUwOXewdI/5n7N4okxFnMUBBjjqqpGrCEGob5X7uxUG6k0QrM1XF+H6cbfPVTbiJfyyvm -1HxdrtbCxkzlBQHZ7Vf8wSN5/PrIJIOV87VqUQHQd9bpEqH5GoP7ghu5sJf0dgYzQ0mg/wu1+rUC -AwEAAaOBgDB+MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBTLD8bf -QkPMPcu1SCOhGnqmKrs0aDAfBgNVHSMEGDAWgBTLD8bfQkPMPcu1SCOhGnqmKrs0aDAbBgNVHREE -FDASgRBpbmZvQGUtc3ppZ25vLmh1MA0GCSqGSIb3DQEBCwUAA4IBAQDJ0Q5eLtXMs3w+y/w9/w0o -lZMEyL/azXm4Q5DwpL7v8u8hmLzU1F0G9u5C7DBsoKqpyvGvivo/C3NqPuouQH4frlRheesuCDfX -I/OMn74dseGkddug4lQUsbocKaQY9hK6ohQU4zE1yED/t+AFdlfBHFny+L/k7SViXITwfn4fs775 -tyERzAMBVnCnEJIeGzSBHq2cGsMEPO0CYdYeBvNfOofyK/FFh+U9rNHHV4S9a67c2Pm2G2JwCz02 -yULyMtd6YebS2z3PyKnJm9zbWETXbzivf3jTo60adbocwTZ8jx5tHMN1Rq41Bab2XD0h7lbwyYIi -LXpUq3DDfSJlgnCW ------END CERTIFICATE----- - -GlobalSign Root CA - R3 -======================= ------BEGIN CERTIFICATE----- -MIIDXzCCAkegAwIBAgILBAAAAAABIVhTCKIwDQYJKoZIhvcNAQELBQAwTDEgMB4GA1UECxMXR2xv -YmFsU2lnbiBSb290IENBIC0gUjMxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2Jh -bFNpZ24wHhcNMDkwMzE4MTAwMDAwWhcNMjkwMzE4MTAwMDAwWjBMMSAwHgYDVQQLExdHbG9iYWxT -aWduIFJvb3QgQ0EgLSBSMzETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln -bjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMwldpB5BngiFvXAg7aEyiie/QV2EcWt -iHL8RgJDx7KKnQRfJMsuS+FggkbhUqsMgUdwbN1k0ev1LKMPgj0MK66X17YUhhB5uzsTgHeMCOFJ -0mpiLx9e+pZo34knlTifBtc+ycsmWQ1z3rDI6SYOgxXG71uL0gRgykmmKPZpO/bLyCiR5Z2KYVc3 -rHQU3HTgOu5yLy6c+9C7v/U9AOEGM+iCK65TpjoWc4zdQQ4gOsC0p6Hpsk+QLjJg6VfLuQSSaGjl -OCZgdbKfd/+RFO+uIEn8rUAVSNECMWEZXriX7613t2Saer9fwRPvm2L7DWzgVGkWqQPabumDk3F2 -xmmFghcCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE -FI/wS3+oLkUkrk1Q+mOai97i3Ru8MA0GCSqGSIb3DQEBCwUAA4IBAQBLQNvAUKr+yAzv95ZURUm7 -lgAJQayzE4aGKAczymvmdLm6AC2upArT9fHxD4q/c2dKg8dEe3jgr25sbwMpjjM5RcOO5LlXbKr8 -EpbsU8Yt5CRsuZRj+9xTaGdWPoO4zzUhw8lo/s7awlOqzJCK6fBdRoyV3XpYKBovHd7NADdBj+1E -bddTKJd+82cEHhXXipa0095MJ6RMG3NzdvQXmcIfeg7jLQitChws/zyrVQ4PkX4268NXSb7hLi18 -YIvDQVETI53O9zJrlAGomecsMx86OyXShkDOOyyGeMlhLxS67ttVb9+E7gUJTb0o2HLO02JQZR7r -kpeDMdmztcpHWD9f ------END CERTIFICATE----- - -Izenpe.com -========== ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - -Go Daddy Root Certificate Authority - G2 -======================================== ------BEGIN CERTIFICATE----- -MIIDxTCCAq2gAwIBAgIBADANBgkqhkiG9w0BAQsFADCBgzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT -B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAYBgNVBAoTEUdvRGFkZHkuY29tLCBJbmMu -MTEwLwYDVQQDEyhHbyBEYWRkeSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAtIEcyMB4XDTA5 -MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgYMxCzAJBgNVBAYTAlVTMRAwDgYDVQQIEwdBcml6 -b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMRowGAYDVQQKExFHb0RhZGR5LmNvbSwgSW5jLjExMC8G -A1UEAxMoR28gRGFkZHkgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZI -hvcNAQEBBQADggEPADCCAQoCggEBAL9xYgjx+lk09xvJGKP3gElY6SKDE6bFIEMBO4Tx5oVJnyfq -9oQbTqC023CYxzIBsQU+B07u9PpPL1kwIuerGVZr4oAH/PMWdYA5UXvl+TW2dE6pjYIT5LY/qQOD -+qK+ihVqf94Lw7YZFAXK6sOoBJQ7RnwyDfMAZiLIjWltNowRGLfTshxgtDj6AozO091GB94KPutd -fMh8+7ArU6SSYmlRJQVhGkSBjCypQ5Yj36w6gZoOKcUcqeldHraenjAKOc7xiID7S13MMuyFYkMl -NAJWJwGRtDtwKj9useiciAF9n9T521NtYJ2/LOdYq7hfRvzOxBsDPAnrSTFcaUaz4EcCAwEAAaNC -MEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFDqahQcQZyi27/a9 -BUFuIMGU2g/eMA0GCSqGSIb3DQEBCwUAA4IBAQCZ21151fmXWWcDYfF+OwYxdS2hII5PZYe096ac -vNjpL9DbWu7PdIxztDhC2gV7+AJ1uP2lsdeu9tfeE8tTEH6KRtGX+rcuKxGrkLAngPnon1rpN5+r -5N9ss4UXnT3ZJE95kTXWXwTrgIOrmgIttRD02JDHBHNA7XIloKmf7J6raBKZV8aPEjoJpL1E/QYV -N8Gb5DKj7Tjo2GTzLH4U/ALqn83/B2gX2yKQOC16jdFU8WnjXzPKej17CuPKf1855eJ1usV2GDPO -LPAvTK33sefOT6jEm0pUBsV/fdUID+Ic/n4XuKxe9tQWskMJDE32p2u0mYRlynqI4uJEvlz36hz1 ------END CERTIFICATE----- - -Starfield Root Certificate Authority - G2 -========================================= ------BEGIN CERTIFICATE----- -MIID3TCCAsWgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBjzELMAkGA1UEBhMCVVMxEDAOBgNVBAgT -B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s -b2dpZXMsIEluYy4xMjAwBgNVBAMTKVN0YXJmaWVsZCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0 -eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgY8xCzAJBgNVBAYTAlVTMRAw -DgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxTdGFyZmllbGQg -VGVjaG5vbG9naWVzLCBJbmMuMTIwMAYDVQQDEylTdGFyZmllbGQgUm9vdCBDZXJ0aWZpY2F0ZSBB -dXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL3twQP89o/8ArFv -W59I2Z154qK3A2FWGMNHttfKPTUuiUP3oWmb3ooa/RMgnLRJdzIpVv257IzdIvpy3Cdhl+72WoTs -bhm5iSzchFvVdPtrX8WJpRBSiUZV9Lh1HOZ/5FSuS/hVclcCGfgXcVnrHigHdMWdSL5stPSksPNk -N3mSwOxGXn/hbVNMYq/NHwtjuzqd+/x5AJhhdM8mgkBj87JyahkNmcrUDnXMN/uLicFZ8WJ/X7Nf -ZTD4p7dNdloedl40wOiWVpmKs/B/pM293DIxfJHP4F8R+GuqSVzRmZTRouNjWwl2tVZi4Ut0HZbU -JtQIBFnQmA4O5t78w+wfkPECAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwHQYDVR0OBBYEFHwMMh+n2TB/xH1oo2Kooc6rB1snMA0GCSqGSIb3DQEBCwUAA4IBAQARWfol -TwNvlJk7mh+ChTnUdgWUXuEok21iXQnCoKjUsHU48TRqneSfioYmUeYs0cYtbpUgSpIB7LiKZ3sx -4mcujJUDJi5DnUox9g61DLu34jd/IroAow57UvtruzvE03lRTs2Q9GcHGcg8RnoNAX3FWOdt5oUw -F5okxBDgBPfg8n/Uqgr/Qh037ZTlZFkSIHc40zI+OIF1lnP6aI+xy84fxez6nH7PfrHxBy22/L/K -pL/QlwVKvOoYKAKQvVR4CSFx09F9HdkWsKlhPdAKACL8x3vLCWRFCztAgfd9fDL1mMpYjn0q7pBZ -c2T5NnReJaH1ZgUufzkVqSr7UIuOhWn0 ------END CERTIFICATE----- - -Starfield Services Root Certificate Authority - G2 -================================================== ------BEGIN CERTIFICATE----- -MIID7zCCAtegAwIBAgIBADANBgkqhkiG9w0BAQsFADCBmDELMAkGA1UEBhMCVVMxEDAOBgNVBAgT -B0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxJTAjBgNVBAoTHFN0YXJmaWVsZCBUZWNobm9s -b2dpZXMsIEluYy4xOzA5BgNVBAMTMlN0YXJmaWVsZCBTZXJ2aWNlcyBSb290IENlcnRpZmljYXRl -IEF1dGhvcml0eSAtIEcyMB4XDTA5MDkwMTAwMDAwMFoXDTM3MTIzMTIzNTk1OVowgZgxCzAJBgNV -BAYTAlVTMRAwDgYDVQQIEwdBcml6b25hMRMwEQYDVQQHEwpTY290dHNkYWxlMSUwIwYDVQQKExxT -dGFyZmllbGQgVGVjaG5vbG9naWVzLCBJbmMuMTswOQYDVQQDEzJTdGFyZmllbGQgU2VydmljZXMg -Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgLSBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBANUMOsQq+U7i9b4Zl1+OiFOxHz/Lz58gE20pOsgPfTz3a3Y4Y9k2YKibXlwAgLIvWX/2 -h/klQ4bnaRtSmpDhcePYLQ1Ob/bISdm28xpWriu2dBTrz/sm4xq6HZYuajtYlIlHVv8loJNwU4Pa -hHQUw2eeBGg6345AWh1KTs9DkTvnVtYAcMtS7nt9rjrnvDH5RfbCYM8TWQIrgMw0R9+53pBlbQLP -LJGmpufehRhJfGZOozptqbXuNC66DQO4M99H67FrjSXZm86B0UVGMpZwh94CDklDhbZsc7tk6mFB -rMnUVN+HL8cisibMn1lUaJ/8viovxFUcdUBgF4UCVTmLfwUCAwEAAaNCMEAwDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFJxfAN+qAdcwKziIorhtSpzyEZGDMA0GCSqG -SIb3DQEBCwUAA4IBAQBLNqaEd2ndOxmfZyMIbw5hyf2E3F/YNoHN2BtBLZ9g3ccaaNnRbobhiCPP -E95Dz+I0swSdHynVv/heyNXBve6SbzJ08pGCL72CQnqtKrcgfU28elUSwhXqvfdqlS5sdJ/PHLTy -xQGjhdByPq1zqwubdQxtRbeOlKyWN7Wg0I8VRw7j6IPdj/3vQQF3zCepYoUz8jcI73HPdwbeyBkd -iEDPfUYd/x7H4c7/I9vG+o1VTqkC50cRRj70/b17KSa7qWFiNyi2LSr2EIZkyXCn0q23KXB56jza -YyWf/Wi3MOxw+3WKt21gZ7IeyLnp2KhvAotnDU0mV3HaIPzBSlCNsSi6 ------END CERTIFICATE----- - -AffirmTrust Commercial -====================== ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIId3cGJyapsXwwDQYJKoZIhvcNAQELBQAwRDELMAkGA1UEBhMCVVMxFDAS -BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMB4XDTEw -MDEyOTE0MDYwNloXDTMwMTIzMTE0MDYwNlowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly -bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBDb21tZXJjaWFsMIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEA9htPZwcroRX1BiLLHwGy43NFBkRJLLtJJRTWzsO3qyxPxkEylFf6Eqdb -DuKPHx6GGaeqtS25Xw2Kwq+FNXkyLbscYjfysVtKPcrNcV/pQr6U6Mje+SJIZMblq8Yrba0F8PrV -C8+a5fBQpIs7R6UjW3p6+DM/uO+Zl+MgwdYoic+U+7lF7eNAFxHUdPALMeIrJmqbTFeurCA+ukV6 -BfO9m2kVrn1OIGPENXY6BwLJN/3HR+7o8XYdcxXyl6S1yHp52UKqK39c/s4mT6NmgTWvRLpUHhww -MmWd5jyTXlBOeuM61G7MGvv50jeuJCqrVwMiKA1JdX+3KNp1v47j3A55MQIDAQABo0IwQDAdBgNV -HQ4EFgQUnZPGU4teyq8/nx4P5ZmVvCT2lI8wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwDQYJKoZIhvcNAQELBQADggEBAFis9AQOzcAN/wr91LoWXym9e2iZWEnStB03TX8nfUYGXUPG -hi4+c7ImfU+TqbbEKpqrIZcUsd6M06uJFdhrJNTxFq7YpFzUf1GO7RgBsZNjvbz4YYCanrHOQnDi -qX0GJX0nof5v7LMeJNrjS1UaADs1tDvZ110w/YETifLCBivtZ8SOyUOyXGsViQK8YvxO8rUzqrJv -0wqiUOP2O+guRMLbZjipM1ZI8W0bM40NjD9gN53Tym1+NH4Nn3J2ixufcv1SNUFFApYvHLKac0kh -sUlHRUe072o0EclNmsxZt9YCnlpOZbWUrhvfKbAW8b8Angc6F2S1BLUjIZkKlTuXfO8= ------END CERTIFICATE----- - -AffirmTrust Networking -====================== ------BEGIN CERTIFICATE----- -MIIDTDCCAjSgAwIBAgIIfE8EORzUmS0wDQYJKoZIhvcNAQEFBQAwRDELMAkGA1UEBhMCVVMxFDAS -BgNVBAoMC0FmZmlybVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMB4XDTEw -MDEyOTE0MDgyNFoXDTMwMTIzMTE0MDgyNFowRDELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmly -bVRydXN0MR8wHQYDVQQDDBZBZmZpcm1UcnVzdCBOZXR3b3JraW5nMIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEAtITMMxcua5Rsa2FSoOujz3mUTOWUgJnLVWREZY9nZOIG41w3SfYvm4SE -Hi3yYJ0wTsyEheIszx6e/jarM3c1RNg1lho9Nuh6DtjVR6FqaYvZ/Ls6rnla1fTWcbuakCNrmreI -dIcMHl+5ni36q1Mr3Lt2PpNMCAiMHqIjHNRqrSK6mQEubWXLviRmVSRLQESxG9fhwoXA3hA/Pe24 -/PHxI1Pcv2WXb9n5QHGNfb2V1M6+oF4nI979ptAmDgAp6zxG8D1gvz9Q0twmQVGeFDdCBKNwV6gb -h+0t+nvujArjqWaJGctB+d1ENmHP4ndGyH329JKBNv3bNPFyfvMMFr20FQIDAQABo0IwQDAdBgNV -HQ4EFgQUBx/S55zawm6iQLSwelAQUHTEyL0wDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMC -AQYwDQYJKoZIhvcNAQEFBQADggEBAIlXshZ6qML91tmbmzTCnLQyFE2npN/svqe++EPbkTfOtDIu -UFUaNU52Q3Eg75N3ThVwLofDwR1t3Mu1J9QsVtFSUzpE0nPIxBsFZVpikpzuQY0x2+c06lkh1QF6 -12S4ZDnNye2v7UsDSKegmQGA3GWjNq5lWUhPgkvIZfFXHeVZLgo/bNjR9eUJtGxUAArgFU2HdW23 -WJZa3W3SAKD0m0i+wzekujbgfIeFlxoVot4uolu9rxj5kFDNcFn4J2dHy8egBzp90SxdbBk6ZrV9 -/ZFvgrG+CJPbFEfxojfHRZ48x3evZKiT3/Zpg4Jg8klCNO1aAFSFHBY2kgxc+qatv9s= ------END CERTIFICATE----- - -AffirmTrust Premium -=================== ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIIbYwURrGmCu4wDQYJKoZIhvcNAQEMBQAwQTELMAkGA1UEBhMCVVMxFDAS -BgNVBAoMC0FmZmlybVRydXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMB4XDTEwMDEy -OTE0MTAzNloXDTQwMTIzMTE0MTAzNlowQTELMAkGA1UEBhMCVVMxFDASBgNVBAoMC0FmZmlybVRy -dXN0MRwwGgYDVQQDDBNBZmZpcm1UcnVzdCBQcmVtaXVtMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A -MIICCgKCAgEAxBLfqV/+Qd3d9Z+K4/as4Tx4mrzY8H96oDMq3I0gW64tb+eT2TZwamjPjlGjhVtn -BKAQJG9dKILBl1fYSCkTtuG+kU3fhQxTGJoeJKJPj/CihQvL9Cl/0qRY7iZNyaqoe5rZ+jjeRFcV -5fiMyNlI4g0WJx0eyIOFJbe6qlVBzAMiSy2RjYvmia9mx+n/K+k8rNrSs8PhaJyJ+HoAVt70VZVs -+7pk3WKL3wt3MutizCaam7uqYoNMtAZ6MMgpv+0GTZe5HMQxK9VfvFMSF5yZVylmd2EhMQcuJUmd -GPLu8ytxjLW6OQdJd/zvLpKQBY0tL3d770O/Nbua2Plzpyzy0FfuKE4mX4+QaAkvuPjcBukumj5R -p9EixAqnOEhss/n/fauGV+O61oV4d7pD6kh/9ti+I20ev9E2bFhc8e6kGVQa9QPSdubhjL08s9NI -S+LI+H+SqHZGnEJlPqQewQcDWkYtuJfzt9WyVSHvutxMAJf7FJUnM7/oQ0dG0giZFmA7mn7S5u04 -6uwBHjxIVkkJx0w3AJ6IDsBz4W9m6XJHMD4Q5QsDyZpCAGzFlH5hxIrff4IaC1nEWTJ3s7xgaVY5 -/bQGeyzWZDbZvUjthB9+pSKPKrhC9IK31FOQeE4tGv2Bb0TXOwF0lkLgAOIua+rF7nKsu7/+6qqo -+Nz2snmKtmcCAwEAAaNCMEAwHQYDVR0OBBYEFJ3AZ6YMItkm9UWrpmVSESfYRaxjMA8GA1UdEwEB -/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBDAUAA4ICAQCzV00QYk465KzquByv -MiPIs0laUZx2KI15qldGF9X1Uva3ROgIRL8YhNILgM3FEv0AVQVhh0HctSSePMTYyPtwni94loMg -Nt58D2kTiKV1NpgIpsbfrM7jWNa3Pt668+s0QNiigfV4Py/VpfzZotReBA4Xrf5B8OWycvpEgjNC -6C1Y91aMYj+6QrCcDFx+LmUmXFNPALJ4fqENmS2NuB2OosSw/WDQMKSOyARiqcTtNd56l+0OOF6S -L5Nwpamcb6d9Ex1+xghIsV5n61EIJenmJWtSKZGc0jlzCFfemQa0W50QBuHCAKi4HEoCChTQwUHK -+4w1IX2COPKpVJEZNZOUbWo6xbLQu4mGk+ibyQ86p3q4ofB4Rvr8Ny/lioTz3/4E2aFooC8k4gmV -BtWVyuEklut89pMFu+1z6S3RdTnX5yTb2E5fQ4+e0BQ5v1VwSJlXMbSc7kqYA5YwH2AG7hsj/oFg -IxpHYoWlzBk0gG+zrBrjn/B7SK3VAdlntqlyk+otZrWyuOQ9PLLvTIzq6we/qzWaVYa8GKa1qF60 -g2xraUDTn9zxw2lrueFtCfTxqlB2Cnp9ehehVZZCmTEJ3WARjQUwfuaORtGdFNrHF+QFlozEJLUb -zxQHskD4o55BhrwE0GuWyCqANP2/7waj3VjFhT0+j/6eKeC2uAloGRwYQw== ------END CERTIFICATE----- - -AffirmTrust Premium ECC -======================= ------BEGIN CERTIFICATE----- -MIIB/jCCAYWgAwIBAgIIdJclisc/elQwCgYIKoZIzj0EAwMwRTELMAkGA1UEBhMCVVMxFDASBgNV -BAoMC0FmZmlybVRydXN0MSAwHgYDVQQDDBdBZmZpcm1UcnVzdCBQcmVtaXVtIEVDQzAeFw0xMDAx -MjkxNDIwMjRaFw00MDEyMzExNDIwMjRaMEUxCzAJBgNVBAYTAlVTMRQwEgYDVQQKDAtBZmZpcm1U -cnVzdDEgMB4GA1UEAwwXQWZmaXJtVHJ1c3QgUHJlbWl1bSBFQ0MwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAAQNMF4bFZ0D0KF5Nbc6PJJ6yhUczWLznCZcBz3lVPqj1swS6vQUX+iOGasvLkjmrBhDeKzQ -N8O9ss0s5kfiGuZjuD0uL3jET9v0D6RoTFVya5UdThhClXjMNzyR4ptlKymjQjBAMB0GA1UdDgQW -BBSaryl6wBE1NSZRMADDav5A1a7WPDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAK -BggqhkjOPQQDAwNnADBkAjAXCfOHiFBar8jAQr9HX/VsaobgxCd05DhT1wV/GzTjxi+zygk8N53X -57hG8f2h4nECMEJZh0PUUd+60wkyWs6Iflc9nF9Ca/UHLbXwgpP5WW+uZPpY5Yse42O+tYHNbwKM -eQ== ------END CERTIFICATE----- - -Certum Trusted Network CA -========================= ------BEGIN CERTIFICATE----- -MIIDuzCCAqOgAwIBAgIDBETAMA0GCSqGSIb3DQEBBQUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK -ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5ldHdvcmsgQ0EwHhcNMDgxMDIy -MTIwNzM3WhcNMjkxMjMxMTIwNzM3WjB+MQswCQYDVQQGEwJQTDEiMCAGA1UEChMZVW5pemV0byBU -ZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -MSIwIAYDVQQDExlDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENBMIIBIjANBgkqhkiG9w0BAQEFAAOC -AQ8AMIIBCgKCAQEA4/t9o3K6wvDJFIf1awFO4W5AB7ptJ11/91sts1rHUV+rpDKmYYe2bg+G0jAC -l/jXaVehGDldamR5xgFZrDwxSjh80gTSSyjoIF87B6LMTXPb865Px1bVWqeWifrzq2jUI4ZZJ88J -J7ysbnKDHDBy3+Ci6dLhdHUZvSqeexVUBBvXQzmtVSjF4hq79MDkrjhJM8x2hZ85RdKknvISjFH4 -fOQtf/WsX+sWn7Et0brMkUJ3TCXJkDhv2/DM+44el1k+1WBO5gUo7Ul5E0u6SNsv+XLTOcr+H9g0 -cvW0QM8xAcPs3hEtF10fuFDRXhmnad4HMyjKUJX5p1TLVIZQRan5SQIDAQABo0IwQDAPBgNVHRMB -Af8EBTADAQH/MB0GA1UdDgQWBBQIds3LB/8k9sXN7buQvOKEN0Z19zAOBgNVHQ8BAf8EBAMCAQYw -DQYJKoZIhvcNAQEFBQADggEBAKaorSLOAT2mo/9i0Eidi15ysHhE49wcrwn9I0j6vSrEuVUEtRCj -jSfeC4Jj0O7eDDd5QVsisrCaQVymcODU0HfLI9MA4GxWL+FpDQ3Zqr8hgVDZBqWo/5U30Kr+4rP1 -mS1FhIrlQgnXdAIv94nYmem8J9RHjboNRhx3zxSkHLmkMcScKHQDNP8zGSal6Q10tz6XxnboJ5aj -Zt3hrvJBW8qYVoNzcOSGGtIxQbovvi0TWnZvTuhOgQ4/WwMioBK+ZlgRSssDxLQqKi2WF+A5VLxI -03YnnZotBqbJ7DnSq9ufmgsnAjUpsUCV5/nonFWIGUbWtzT1fs45mtk48VH3Tyw= ------END CERTIFICATE----- - -TWCA Root Certification Authority -================================= ------BEGIN CERTIFICATE----- -MIIDezCCAmOgAwIBAgIBATANBgkqhkiG9w0BAQUFADBfMQswCQYDVQQGEwJUVzESMBAGA1UECgwJ -VEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NBIFJvb3QgQ2VydGlmaWNh -dGlvbiBBdXRob3JpdHkwHhcNMDgwODI4MDcyNDMzWhcNMzAxMjMxMTU1OTU5WjBfMQswCQYDVQQG -EwJUVzESMBAGA1UECgwJVEFJV0FOLUNBMRAwDgYDVQQLDAdSb290IENBMSowKAYDVQQDDCFUV0NB -IFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK -AoIBAQCwfnK4pAOU5qfeCTiRShFAh6d8WWQUe7UREN3+v9XAu1bihSX0NXIP+FPQQeFEAcK0HMMx -QhZHhTMidrIKbw/lJVBPhYa+v5guEGcevhEFhgWQxFnQfHgQsIBct+HHK3XLfJ+utdGdIzdjp9xC -oi2SBBtQwXu4PhvJVgSLL1KbralW6cH/ralYhzC2gfeXRfwZVzsrb+RH9JlF/h3x+JejiB03HFyP -4HYlmlD4oFT/RJB2I9IyxsOrBr/8+7/zrX2SYgJbKdM1o5OaQ2RgXbL6Mv87BK9NQGr5x+PvI/1r -y+UPizgN7gr8/g+YnzAx3WxSZfmLgb4i4RxYA7qRG4kHAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIB -BjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqOFsmjd6LWvJPelSDGRjjCDWmujANBgkqhkiG -9w0BAQUFAAOCAQEAPNV3PdrfibqHDAhUaiBQkr6wQT25JmSDCi/oQMCXKCeCMErJk/9q56YAf4lC -mtYR5VPOL8zy2gXE/uJQxDqGfczafhAJO5I1KlOy/usrBdlsXebQ79NqZp4VKIV66IIArB6nCWlW -QtNoURi+VJq/REG6Sb4gumlc7rh3zc5sH62Dlhh9DrUUOYTxKOkto557HnpyWoOzeW/vtPzQCqVY -T0bf+215WfKEIlKuD8z7fDvnaspHYcN6+NOSBB+4IIThNlQWx0DeO4pz3N/GCUzf7Nr/1FNCocny -Yh0igzyXxfkZYiesZSLX0zzG5Y6yU8xJzrww/nsOM5D77dIUkR8Hrw== ------END CERTIFICATE----- - -Security Communication RootCA2 -============================== ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIBADANBgkqhkiG9w0BAQsFADBdMQswCQYDVQQGEwJKUDElMCMGA1UEChMc -U0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UECxMeU2VjdXJpdHkgQ29tbXVuaWNh -dGlvbiBSb290Q0EyMB4XDTA5MDUyOTA1MDAzOVoXDTI5MDUyOTA1MDAzOVowXTELMAkGA1UEBhMC -SlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xJzAlBgNVBAsTHlNlY3Vy -aXR5IENvbW11bmljYXRpb24gUm9vdENBMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB -ANAVOVKxUrO6xVmCxF1SrjpDZYBLx/KWvNs2l9amZIyoXvDjChz335c9S672XewhtUGrzbl+dp++ -+T42NKA7wfYxEUV0kz1XgMX5iZnK5atq1LXaQZAQwdbWQonCv/Q4EpVMVAX3NuRFg3sUZdbcDE3R -3n4MqzvEFb46VqZab3ZpUql6ucjrappdUtAtCms1FgkQhNBqyjoGADdH5H5XTz+L62e4iKrFvlNV -spHEfbmwhRkGeC7bYRr6hfVKkaHnFtWOojnflLhwHyg/i/xAXmODPIMqGplrz95Zajv8bxbXH/1K -EOtOghY6rCcMU/Gt1SSwawNQwS08Ft1ENCcadfsCAwEAAaNCMEAwHQYDVR0OBBYEFAqFqXdlBZh8 -QIH4D5csOPEK7DzPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEB -CwUAA4IBAQBMOqNErLlFsceTfsgLCkLfZOoc7llsCLqJX2rKSpWeeo8HxdpFcoJxDjrSzG+ntKEj -u/Ykn8sX/oymzsLS28yN/HH8AynBbF0zX2S2ZTuJbxh2ePXcokgfGT+Ok+vx+hfuzU7jBBJV1uXk -3fs+BXziHV7Gp7yXT2g69ekuCkO2r1dcYmh8t/2jioSgrGK+KwmHNPBqAbubKVY8/gA3zyNs8U6q -tnRGEmyR7jTV7JqR50S+kDFy1UkC9gLl9B/rfNmWVan/7Ir5mUf/NVoCqgTLiluHcSmRvaS0eg29 -mvVXIwAHIRc/SjnRBUkLp7Y3gaVdjKozXoEofKd9J+sAro03 ------END CERTIFICATE----- - -Actalis Authentication Root CA -============================== ------BEGIN CERTIFICATE----- -MIIFuzCCA6OgAwIBAgIIVwoRl0LE48wwDQYJKoZIhvcNAQELBQAwazELMAkGA1UEBhMCSVQxDjAM -BgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlzIFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UE -AwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290IENBMB4XDTExMDkyMjExMjIwMloXDTMwMDky -MjExMjIwMlowazELMAkGA1UEBhMCSVQxDjAMBgNVBAcMBU1pbGFuMSMwIQYDVQQKDBpBY3RhbGlz -IFMucC5BLi8wMzM1ODUyMDk2NzEnMCUGA1UEAwweQWN0YWxpcyBBdXRoZW50aWNhdGlvbiBSb290 -IENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAp8bEpSmkLO/lGMWwUKNvUTufClrJ -wkg4CsIcoBh/kbWHuUA/3R1oHwiD1S0eiKD4j1aPbZkCkpAW1V8IbInX4ay8IMKx4INRimlNAJZa -by/ARH6jDuSRzVju3PvHHkVH3Se5CAGfpiEd9UEtL0z9KK3giq0itFZljoZUj5NDKd45RnijMCO6 -zfB9E1fAXdKDa0hMxKufgFpbOr3JpyI/gCczWw63igxdBzcIy2zSekciRDXFzMwujt0q7bd9Zg1f -YVEiVRvjRuPjPdA1YprbrxTIW6HMiRvhMCb8oJsfgadHHwTrozmSBp+Z07/T6k9QnBn+locePGX2 -oxgkg4YQ51Q+qDp2JE+BIcXjDwL4k5RHILv+1A7TaLndxHqEguNTVHnd25zS8gebLra8Pu2Fbe8l -EfKXGkJh90qX6IuxEAf6ZYGyojnP9zz/GPvG8VqLWeICrHuS0E4UT1lF9gxeKF+w6D9Fz8+vm2/7 -hNN3WpVvrJSEnu68wEqPSpP4RCHiMUVhUE4Q2OM1fEwZtN4Fv6MGn8i1zeQf1xcGDXqVdFUNaBr8 -EBtiZJ1t4JWgw5QHVw0U5r0F+7if5t+L4sbnfpb2U8WANFAoWPASUHEXMLrmeGO89LKtmyuy/uE5 -jF66CyCU3nuDuP/jVo23Eek7jPKxwV2dpAtMK9myGPW1n0sCAwEAAaNjMGEwHQYDVR0OBBYEFFLY -iDrIn3hm7YnzezhwlMkCAjbQMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUUtiIOsifeGbt -ifN7OHCUyQICNtAwDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4ICAQALe3KHwGCmSUyI -WOYdiPcUZEim2FgKDk8TNd81HdTtBjHIgT5q1d07GjLukD0R0i70jsNjLiNmsGe+b7bAEzlgqqI0 -JZN1Ut6nna0Oh4lScWoWPBkdg/iaKWW+9D+a2fDzWochcYBNy+A4mz+7+uAwTc+G02UQGRjRlwKx -K3JCaKygvU5a2hi/a5iB0P2avl4VSM0RFbnAKVy06Ij3Pjaut2L9HmLecHgQHEhb2rykOLpn7VU+ -Xlff1ANATIGk0k9jpwlCCRT8AKnCgHNPLsBA2RF7SOp6AsDT6ygBJlh0wcBzIm2Tlf05fbsq4/aC -4yyXX04fkZT6/iyj2HYauE2yOE+b+h1IYHkm4vP9qdCa6HCPSXrW5b0KDtst842/6+OkfcvHlXHo -2qN8xcL4dJIEG4aspCJTQLas/kx2z/uUMsA1n3Y/buWQbqCmJqK4LL7RK4X9p2jIugErsWx0Hbhz -lefut8cl8ABMALJ+tguLHPPAUJ4lueAI3jZm/zel0btUZCzJJ7VLkn5l/9Mt4blOvH+kQSGQQXem -OR/qnuOf0GZvBeyqdn6/axag67XH/JJULysRJyU3eExRarDzzFhdFPFqSBX/wge2sY0PjlxQRrM9 -vwGYT7JZVEc+NHt4bVaTLnPqZih4zR0Uv6CPLy64Lo7yFIrM6bV8+2ydDKXhlg== ------END CERTIFICATE----- - -Buypass Class 2 Root CA -======================= ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU -QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMiBSb290IENBMB4X -DTEwMTAyNjA4MzgwM1oXDTQwMTAyNjA4MzgwM1owTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 -eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDIgUm9vdCBDQTCCAiIw -DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANfHXvfBB9R3+0Mh9PT1aeTuMgHbo4Yf5FkNuud1 -g1Lr6hxhFUi7HQfKjK6w3Jad6sNgkoaCKHOcVgb/S2TwDCo3SbXlzwx87vFKu3MwZfPVL4O2fuPn -9Z6rYPnT8Z2SdIrkHJasW4DptfQxh6NR/Md+oW+OU3fUl8FVM5I+GC911K2GScuVr1QGbNgGE41b -/+EmGVnAJLqBcXmQRFBoJJRfuLMR8SlBYaNByyM21cHxMlAQTn/0hpPshNOOvEu/XAFOBz3cFIqU -CqTqc/sLUegTBxj6DvEr0VQVfTzh97QZQmdiXnfgolXsttlpF9U6r0TtSsWe5HonfOV116rLJeff -awrbD02TTqigzXsu8lkBarcNuAeBfos4GzjmCleZPe4h6KP1DBbdi+w0jpwqHAAVF41og9JwnxgI -zRFo1clrUs3ERo/ctfPYV3Me6ZQ5BL/T3jjetFPsaRyifsSP5BtwrfKi+fv3FmRmaZ9JUaLiFRhn -Bkp/1Wy1TbMz4GHrXb7pmA8y1x1LPC5aAVKRCfLf6o3YBkBjqhHk/sM3nhRSP/TizPJhk9H9Z2vX -Uq6/aKtAQ6BXNVN48FP4YUIHZMbXb5tMOA1jrGKvNouicwoN9SG9dKpN6nIDSdvHXx1iY8f93ZHs -M+71bbRuMGjeyNYmsHVee7QHIJihdjK4TWxPAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD -VR0OBBYEFMmAd+BikoL1RpzzuvdMw964o605MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF -AAOCAgEAU18h9bqwOlI5LJKwbADJ784g7wbylp7ppHR/ehb8t/W2+xUbP6umwHJdELFx7rxP462s -A20ucS6vxOOto70MEae0/0qyexAQH6dXQbLArvQsWdZHEIjzIVEpMMpghq9Gqx3tOluwlN5E40EI -osHsHdb9T7bWR9AUC8rmyrV7d35BH16Dx7aMOZawP5aBQW9gkOLo+fsicdl9sz1Gv7SEr5AcD48S -aq/v7h56rgJKihcrdv6sVIkkLE8/trKnToyokZf7KcZ7XC25y2a2t6hbElGFtQl+Ynhw/qlqYLYd -DnkM/crqJIByw5c/8nerQyIKx+u2DISCLIBrQYoIwOula9+ZEsuK1V6ADJHgJgg2SMX6OBE1/yWD -LfJ6v9r9jv6ly0UsH8SIU653DtmadsWOLB2jutXsMq7Aqqz30XpN69QH4kj3Io6wpJ9qzo6ysmD0 -oyLQI+uUWnpp3Q+/QFesa1lQ2aOZ4W7+jQF5JyMV3pKdewlNWudLSDBaGOYKbeaP4NK75t98biGC -wWg5TbSYWGZizEqQXsP6JwSxeRV0mcy+rSDeJmAc61ZRpqPq5KM/p/9h3PFaTWwyI0PurKju7koS -CTxdccK+efrCh2gdC/1cacwG0Jp9VJkqyTkaGa9LKkPzY11aWOIv4x3kqdbQCtCev9eBCfHJxyYN -rJgWVqA= ------END CERTIFICATE----- - -Buypass Class 3 Root CA -======================= ------BEGIN CERTIFICATE----- -MIIFWTCCA0GgAwIBAgIBAjANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQGEwJOTzEdMBsGA1UECgwU -QnV5cGFzcyBBUy05ODMxNjMzMjcxIDAeBgNVBAMMF0J1eXBhc3MgQ2xhc3MgMyBSb290IENBMB4X -DTEwMTAyNjA4Mjg1OFoXDTQwMTAyNjA4Mjg1OFowTjELMAkGA1UEBhMCTk8xHTAbBgNVBAoMFEJ1 -eXBhc3MgQVMtOTgzMTYzMzI3MSAwHgYDVQQDDBdCdXlwYXNzIENsYXNzIDMgUm9vdCBDQTCCAiIw -DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKXaCpUWUOOV8l6ddjEGMnqb8RB2uACatVI2zSRH -sJ8YZLya9vrVediQYkwiL944PdbgqOkcLNt4EemOaFEVcsfzM4fkoF0LXOBXByow9c3EN3coTRiR -5r/VUv1xLXA+58bEiuPwKAv0dpihi4dVsjoT/Lc+JzeOIuOoTyrvYLs9tznDDgFHmV0ST9tD+leh -7fmdvhFHJlsTmKtdFoqwNxxXnUX/iJY2v7vKB3tvh2PX0DJq1l1sDPGzbjniazEuOQAnFN44wOwZ -ZoYS6J1yFhNkUsepNxz9gjDthBgd9K5c/3ATAOux9TN6S9ZV+AWNS2mw9bMoNlwUxFFzTWsL8TQH -2xc519woe2v1n/MuwU8XKhDzzMro6/1rqy6any2CbgTUUgGTLT2G/H783+9CHaZr77kgxve9oKeV -/afmiSTYzIw0bOIjL9kSGiG5VZFvC5F5GQytQIgLcOJ60g7YaEi7ghM5EFjp2CoHxhLbWNvSO1UQ -RwUVZ2J+GGOmRj8JDlQyXr8NYnon74Do29lLBlo3WiXQCBJ31G8JUJc9yB3D34xFMFbG02SrZvPA -Xpacw8Tvw3xrizp5f7NJzz3iiZ+gMEuFuZyUJHmPfWupRWgPK9Dx2hzLabjKSWJtyNBjYt1gD1iq -j6G8BaVmos8bdrKEZLFMOVLAMLrwjEsCsLa3AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD -VR0OBBYEFEe4zf/lb+74suwvTg75JbCOPGvDMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsF -AAOCAgEAACAjQTUEkMJAYmDv4jVM1z+s4jSQuKFvdvoWFqRINyzpkMLyPPgKn9iB5btb2iUspKdV -cSQy9sgL8rxq+JOssgfCX5/bzMiKqr5qb+FJEMwx14C7u8jYog5kV+qi9cKpMRXSIGrs/CIBKM+G -uIAeqcwRpTzyFrNHnfzSgCHEy9BHcEGhyoMZCCxt8l13nIoUE9Q2HJLw5QY33KbmkJs4j1xrG0aG -Q0JfPgEHU1RdZX33inOhmlRaHylDFCfChQ+1iHsaO5S3HWCntZznKWlXWpuTekMwGwPXYshApqr8 -ZORK15FTAaggiG6cX0S5y2CBNOxv033aSF/rtJC8LakcC6wc1aJoIIAE1vyxjy+7SjENSoYc6+I2 -KSb12tjE8nVhz36udmNKekBlk4f4HoCMhuWG1o8O/FMsYOgWYRqiPkN7zTlgVGr18okmAWiDSKIz -6MkEkbIRNBE+6tBDGR8Dk5AM/1E9V/RBbuHLoL7ryWPNbczk+DaqaJ3tvV2XcEQNtg413OEMXbug -UZTLfhbrES+jkkXITHHZvMmZUldGL1DPvTVp9D0VzgalLA8+9oG6lLvDu79leNKGef9JOxqDDPDe -eOzI8k1MGt6CKfjBWtrt7uYnXuhF0J0cUahoq0Tj0Itq4/g7u9xN12TyUb7mqqta6THuBrxzvxNi -Cp/HuZc= ------END CERTIFICATE----- - -T-TeleSec GlobalRoot Class 3 -============================ ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM -IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU -cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwHhcNMDgx -MDAxMTAyOTU2WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz -dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD -ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDMwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQC9dZPwYiJvJK7genasfb3ZJNW4t/zN8ELg63iIVl6bmlQdTQyK -9tPPcPRStdiTBONGhnFBSivwKixVA9ZIw+A5OO3yXDw/RLyTPWGrTs0NvvAgJ1gORH8EGoel15YU -NpDQSXuhdfsaa3Ox+M6pCSzyU9XDFES4hqX2iys52qMzVNn6chr3IhUciJFrf2blw2qAsCTz34ZF -iP0Zf3WHHx+xGwpzJFu5ZeAsVMhg02YXP+HMVDNzkQI6pn97djmiH5a2OK61yJN0HZ65tOVgnS9W -0eDrXltMEnAMbEQgqxHY9Bn20pxSN+f6tsIxO0rUFJmtxxr1XV/6B7h8DR/Wgx6zAgMBAAGjQjBA -MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS1A/d2O2GCahKqGFPr -AyGUv/7OyjANBgkqhkiG9w0BAQsFAAOCAQEAVj3vlNW92nOyWL6ukK2YJ5f+AbGwUgC4TeQbIXQb -fsDuXmkqJa9c1h3a0nnJ85cp4IaH3gRZD/FZ1GSFS5mvJQQeyUapl96Cshtwn5z2r3Ex3XsFpSzT -ucpH9sry9uetuUg/vBa3wW306gmv7PO15wWeph6KU1HWk4HMdJP2udqmJQV0eVp+QD6CSyYRMG7h -P0HHRwA11fXT91Q+gT3aSWqas+8QPebrb9HIIkfLzM8BMZLZGOMivgkeGj5asuRrDFR6fUNOuIml -e9eiPZaGzPImNC1qkp2aGtAw4l1OBLBfiyB+d8E9lYLRRpo7PHi4b6HQDWSieB4pTpPDpFQUWw== ------END CERTIFICATE----- - -D-TRUST Root Class 3 CA 2 2009 -============================== ------BEGIN CERTIFICATE----- -MIIEMzCCAxugAwIBAgIDCYPzMA0GCSqGSIb3DQEBCwUAME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQK -DAxELVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTAe -Fw0wOTExMDUwODM1NThaFw0yOTExMDUwODM1NThaME0xCzAJBgNVBAYTAkRFMRUwEwYDVQQKDAxE -LVRydXN0IEdtYkgxJzAlBgNVBAMMHkQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgMjAwOTCCASIw -DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANOySs96R+91myP6Oi/WUEWJNTrGa9v+2wBoqOAD -ER03UAifTUpolDWzU9GUY6cgVq/eUXjsKj3zSEhQPgrfRlWLJ23DEE0NkVJD2IfgXU42tSHKXzlA -BF9bfsyjxiupQB7ZNoTWSPOSHjRGICTBpFGOShrvUD9pXRl/RcPHAY9RySPocq60vFYJfxLLHLGv -KZAKyVXMD9O0Gu1HNVpK7ZxzBCHQqr0ME7UAyiZsxGsMlFqVlNpQmvH/pStmMaTJOKDfHR+4CS7z -p+hnUquVH+BGPtikw8paxTGA6Eian5Rp/hnd2HN8gcqW3o7tszIFZYQ05ub9VxC1X3a/L7AQDcUC -AwEAAaOCARowggEWMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFP3aFMSfMN4hvR5COfyrYyNJ -4PGEMA4GA1UdDwEB/wQEAwIBBjCB0wYDVR0fBIHLMIHIMIGAoH6gfIZ6bGRhcDovL2RpcmVjdG9y -eS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwUm9vdCUyMENsYXNzJTIwMyUyMENBJTIwMiUyMDIw -MDksTz1ELVRydXN0JTIwR21iSCxDPURFP2NlcnRpZmljYXRlcmV2b2NhdGlvbmxpc3QwQ6BBoD+G -PWh0dHA6Ly93d3cuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3Rfcm9vdF9jbGFzc18zX2NhXzJfMjAw -OS5jcmwwDQYJKoZIhvcNAQELBQADggEBAH+X2zDI36ScfSF6gHDOFBJpiBSVYEQBrLLpME+bUMJm -2H6NMLVwMeniacfzcNsgFYbQDfC+rAF1hM5+n02/t2A7nPPKHeJeaNijnZflQGDSNiH+0LS4F9p0 -o3/U37CYAqxva2ssJSRyoWXuJVrl5jLn8t+rSfrzkGkj2wTZ51xY/GXUl77M/C4KzCUqNQT4YJEV -dT1B/yMfGchs64JTBKbkTCJNjYy6zltz7GRUUG3RnFX7acM2w4y8PIWmawomDeCTmGCufsYkl4ph -X5GOZpIJhzbNi5stPvZR1FDUWSi9g/LMKHtThm3YJohw1+qRzT65ysCQblrGXnRl11z+o+I= ------END CERTIFICATE----- - -D-TRUST Root Class 3 CA 2 EV 2009 -================================= ------BEGIN CERTIFICATE----- -MIIEQzCCAyugAwIBAgIDCYP0MA0GCSqGSIb3DQEBCwUAMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK -DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw -OTAeFw0wOTExMDUwODUwNDZaFw0yOTExMDUwODUwNDZaMFAxCzAJBgNVBAYTAkRFMRUwEwYDVQQK -DAxELVRydXN0IEdtYkgxKjAoBgNVBAMMIUQtVFJVU1QgUm9vdCBDbGFzcyAzIENBIDIgRVYgMjAw -OTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJnxhDRwui+3MKCOvXwEz75ivJn9gpfS -egpnljgJ9hBOlSJzmY3aFS3nBfwZcyK3jpgAvDw9rKFs+9Z5JUut8Mxk2og+KbgPCdM03TP1YtHh -zRnp7hhPTFiu4h7WDFsVWtg6uMQYZB7jM7K1iXdODL/ZlGsTl28So/6ZqQTMFexgaDbtCHu39b+T -7WYxg4zGcTSHThfqr4uRjRxWQa4iN1438h3Z0S0NL2lRp75mpoo6Kr3HGrHhFPC+Oh25z1uxav60 -sUYgovseO3Dvk5h9jHOW8sXvhXCtKSb8HgQ+HKDYD8tSg2J87otTlZCpV6LqYQXY+U3EJ/pure35 -11H3a6UCAwEAAaOCASQwggEgMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFNOUikxiEyoZLsyv -cop9NteaHNxnMA4GA1UdDwEB/wQEAwIBBjCB3QYDVR0fBIHVMIHSMIGHoIGEoIGBhn9sZGFwOi8v -ZGlyZWN0b3J5LmQtdHJ1c3QubmV0L0NOPUQtVFJVU1QlMjBSb290JTIwQ2xhc3MlMjAzJTIwQ0El -MjAyJTIwRVYlMjAyMDA5LE89RC1UcnVzdCUyMEdtYkgsQz1ERT9jZXJ0aWZpY2F0ZXJldm9jYXRp -b25saXN0MEagRKBChkBodHRwOi8vd3d3LmQtdHJ1c3QubmV0L2NybC9kLXRydXN0X3Jvb3RfY2xh -c3NfM19jYV8yX2V2XzIwMDkuY3JsMA0GCSqGSIb3DQEBCwUAA4IBAQA07XtaPKSUiO8aEXUHL7P+ -PPoeUSbrh/Yp3uDx1MYkCenBz1UbtDDZzhr+BlGmFaQt77JLvyAoJUnRpjZ3NOhk31KxEcdzes05 -nsKtjHEh8lprr988TlWvsoRlFIm5d8sqMb7Po23Pb0iUMkZv53GMoKaEGTcH8gNFCSuGdXzfX2lX -ANtu2KZyIktQ1HWYVt+3GP9DQ1CuekR78HlR10M9p9OB0/DJT7naxpeG0ILD5EJt/rDiZE4OJudA -NCa1CInXCGNjOCd1HjPqbqjdn5lPdE2BiYBL3ZqXKVwvvoFBuYz/6n1gBp7N1z3TLqMVvKjmJuVv -w9y4AyHqnxbxLFS1 ------END CERTIFICATE----- - -CA Disig Root R2 -================ ------BEGIN CERTIFICATE----- -MIIFaTCCA1GgAwIBAgIJAJK4iNuwisFjMA0GCSqGSIb3DQEBCwUAMFIxCzAJBgNVBAYTAlNLMRMw -EQYDVQQHEwpCcmF0aXNsYXZhMRMwEQYDVQQKEwpEaXNpZyBhLnMuMRkwFwYDVQQDExBDQSBEaXNp -ZyBSb290IFIyMB4XDTEyMDcxOTA5MTUzMFoXDTQyMDcxOTA5MTUzMFowUjELMAkGA1UEBhMCU0sx -EzARBgNVBAcTCkJyYXRpc2xhdmExEzARBgNVBAoTCkRpc2lnIGEucy4xGTAXBgNVBAMTEENBIERp -c2lnIFJvb3QgUjIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCio8QACdaFXS1tFPbC -w3OeNcJxVX6B+6tGUODBfEl45qt5WDza/3wcn9iXAng+a0EE6UG9vgMsRfYvZNSrXaNHPWSb6Wia -xswbP7q+sos0Ai6YVRn8jG+qX9pMzk0DIaPY0jSTVpbLTAwAFjxfGs3Ix2ymrdMxp7zo5eFm1tL7 -A7RBZckQrg4FY8aAamkw/dLukO8NJ9+flXP04SXabBbeQTg06ov80egEFGEtQX6sx3dOy1FU+16S -GBsEWmjGycT6txOgmLcRK7fWV8x8nhfRyyX+hk4kLlYMeE2eARKmK6cBZW58Yh2EhN/qwGu1pSqV -g8NTEQxzHQuyRpDRQjrOQG6Vrf/GlK1ul4SOfW+eioANSW1z4nuSHsPzwfPrLgVv2RvPN3YEyLRa -5Beny912H9AZdugsBbPWnDTYltxhh5EF5EQIM8HauQhl1K6yNg3ruji6DOWbnuuNZt2Zz9aJQfYE -koopKW1rOhzndX0CcQ7zwOe9yxndnWCywmZgtrEE7snmhrmaZkCo5xHtgUUDi/ZnWejBBhG93c+A -Ak9lQHhcR1DIm+YfgXvkRKhbhZri3lrVx/k6RGZL5DJUfORsnLMOPReisjQS1n6yqEm70XooQL6i -Fh/f5DcfEXP7kAplQ6INfPgGAVUzfbANuPT1rqVCV3w2EYx7XsQDnYx5nQIDAQABo0IwQDAPBgNV -HRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUtZn4r7CU9eMg1gqtzk5WpC5u -Qu0wDQYJKoZIhvcNAQELBQADggIBACYGXnDnZTPIgm7ZnBc6G3pmsgH2eDtpXi/q/075KMOYKmFM -tCQSin1tERT3nLXK5ryeJ45MGcipvXrA1zYObYVybqjGom32+nNjf7xueQgcnYqfGopTpti72TVV -sRHFqQOzVju5hJMiXn7B9hJSi+osZ7z+Nkz1uM/Rs0mSO9MpDpkblvdhuDvEK7Z4bLQjb/D907Je -dR+Zlais9trhxTF7+9FGs9K8Z7RiVLoJ92Owk6Ka+elSLotgEqv89WBW7xBci8QaQtyDW2QOy7W8 -1k/BfDxujRNt+3vrMNDcTa/F1balTFtxyegxvug4BkihGuLq0t4SOVga/4AOgnXmt8kHbA7v/zjx -mHHEt38OFdAlab0inSvtBfZGR6ztwPDUO+Ls7pZbkBNOHlY667DvlruWIxG68kOGdGSVyCh13x01 -utI3gzhTODY7z2zp+WsO0PsE6E9312UBeIYMej4hYvF/Y3EMyZ9E26gnonW+boE+18DrG5gPcFw0 -sorMwIUY6256s/daoQe/qUKS82Ail+QUoQebTnbAjn39pCXHR+3/H3OszMOl6W8KjptlwlCFtaOg -UxLMVYdh84GuEEZhvUQhuMI9dM9+JDX6HAcOmz0iyu8xL4ysEr3vQCj8KWefshNPZiTEUxnpHikV -7+ZtsH8tZ/3zbBt1RqPlShfppNcL ------END CERTIFICATE----- - -ACCVRAIZ1 -========= ------BEGIN CERTIFICATE----- -MIIH0zCCBbugAwIBAgIIXsO3pkN/pOAwDQYJKoZIhvcNAQEFBQAwQjESMBAGA1UEAwwJQUNDVlJB -SVoxMRAwDgYDVQQLDAdQS0lBQ0NWMQ0wCwYDVQQKDARBQ0NWMQswCQYDVQQGEwJFUzAeFw0xMTA1 -MDUwOTM3MzdaFw0zMDEyMzEwOTM3MzdaMEIxEjAQBgNVBAMMCUFDQ1ZSQUlaMTEQMA4GA1UECwwH -UEtJQUNDVjENMAsGA1UECgwEQUNDVjELMAkGA1UEBhMCRVMwggIiMA0GCSqGSIb3DQEBAQUAA4IC -DwAwggIKAoICAQCbqau/YUqXry+XZpp0X9DZlv3P4uRm7x8fRzPCRKPfmt4ftVTdFXxpNRFvu8gM -jmoYHtiP2Ra8EEg2XPBjs5BaXCQ316PWywlxufEBcoSwfdtNgM3802/J+Nq2DoLSRYWoG2ioPej0 -RGy9ocLLA76MPhMAhN9KSMDjIgro6TenGEyxCQ0jVn8ETdkXhBilyNpAlHPrzg5XPAOBOp0KoVdD -aaxXbXmQeOW1tDvYvEyNKKGno6e6Ak4l0Squ7a4DIrhrIA8wKFSVf+DuzgpmndFALW4ir50awQUZ -0m/A8p/4e7MCQvtQqR0tkw8jq8bBD5L/0KIV9VMJcRz/RROE5iZe+OCIHAr8Fraocwa48GOEAqDG -WuzndN9wrqODJerWx5eHk6fGioozl2A3ED6XPm4pFdahD9GILBKfb6qkxkLrQaLjlUPTAYVtjrs7 -8yM2x/474KElB0iryYl0/wiPgL/AlmXz7uxLaL2diMMxs0Dx6M/2OLuc5NF/1OVYm3z61PMOm3WR -5LpSLhl+0fXNWhn8ugb2+1KoS5kE3fj5tItQo05iifCHJPqDQsGH+tUtKSpacXpkatcnYGMN285J -9Y0fkIkyF/hzQ7jSWpOGYdbhdQrqeWZ2iE9x6wQl1gpaepPluUsXQA+xtrn13k/c4LOsOxFwYIRK -Q26ZIMApcQrAZQIDAQABo4ICyzCCAscwfQYIKwYBBQUHAQEEcTBvMEwGCCsGAQUFBzAChkBodHRw -Oi8vd3d3LmFjY3YuZXMvZmlsZWFkbWluL0FyY2hpdm9zL2NlcnRpZmljYWRvcy9yYWl6YWNjdjEu -Y3J0MB8GCCsGAQUFBzABhhNodHRwOi8vb2NzcC5hY2N2LmVzMB0GA1UdDgQWBBTSh7Tj3zcnk1X2 -VuqB5TbMjB4/vTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNKHtOPfNyeTVfZW6oHlNsyM -Hj+9MIIBcwYDVR0gBIIBajCCAWYwggFiBgRVHSAAMIIBWDCCASIGCCsGAQUFBwICMIIBFB6CARAA -QQB1AHQAbwByAGkAZABhAGQAIABkAGUAIABDAGUAcgB0AGkAZgBpAGMAYQBjAGkA8wBuACAAUgBh -AO0AegAgAGQAZQAgAGwAYQAgAEEAQwBDAFYAIAAoAEEAZwBlAG4AYwBpAGEAIABkAGUAIABUAGUA -YwBuAG8AbABvAGcA7QBhACAAeQAgAEMAZQByAHQAaQBmAGkAYwBhAGMAaQDzAG4AIABFAGwAZQBj -AHQAcgDzAG4AaQBjAGEALAAgAEMASQBGACAAUQA0ADYAMAAxADEANQA2AEUAKQAuACAAQwBQAFMA -IABlAG4AIABoAHQAdABwADoALwAvAHcAdwB3AC4AYQBjAGMAdgAuAGUAczAwBggrBgEFBQcCARYk -aHR0cDovL3d3dy5hY2N2LmVzL2xlZ2lzbGFjaW9uX2MuaHRtMFUGA1UdHwROMEwwSqBIoEaGRGh0 -dHA6Ly93d3cuYWNjdi5lcy9maWxlYWRtaW4vQXJjaGl2b3MvY2VydGlmaWNhZG9zL3JhaXphY2N2 -MV9kZXIuY3JsMA4GA1UdDwEB/wQEAwIBBjAXBgNVHREEEDAOgQxhY2N2QGFjY3YuZXMwDQYJKoZI -hvcNAQEFBQADggIBAJcxAp/n/UNnSEQU5CmH7UwoZtCPNdpNYbdKl02125DgBS4OxnnQ8pdpD70E -R9m+27Up2pvZrqmZ1dM8MJP1jaGo/AaNRPTKFpV8M9xii6g3+CfYCS0b78gUJyCpZET/LtZ1qmxN -YEAZSUNUY9rizLpm5U9EelvZaoErQNV/+QEnWCzI7UiRfD+mAM/EKXMRNt6GGT6d7hmKG9Ww7Y49 -nCrADdg9ZuM8Db3VlFzi4qc1GwQA9j9ajepDvV+JHanBsMyZ4k0ACtrJJ1vnE5Bc5PUzolVt3OAJ -TS+xJlsndQAJxGJ3KQhfnlmstn6tn1QwIgPBHnFk/vk4CpYY3QIUrCPLBhwepH2NDd4nQeit2hW3 -sCPdK6jT2iWH7ehVRE2I9DZ+hJp4rPcOVkkO1jMl1oRQQmwgEh0q1b688nCBpHBgvgW1m54ERL5h -I6zppSSMEYCUWqKiuUnSwdzRp+0xESyeGabu4VXhwOrPDYTkF7eifKXeVSUG7szAh1xA2syVP1Xg -Nce4hL60Xc16gwFy7ofmXx2utYXGJt/mwZrpHgJHnyqobalbz+xFd3+YJ5oyXSrjhO7FmGYvliAd -3djDJ9ew+f7Zfc3Qn48LFFhRny+Lwzgt3uiP1o2HpPVWQxaZLPSkVrQ0uGE3ycJYgBugl6H8WY3p -EfbRD0tVNEYqi4Y7 ------END CERTIFICATE----- - -TWCA Global Root CA -=================== ------BEGIN CERTIFICATE----- -MIIFQTCCAymgAwIBAgICDL4wDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCVFcxEjAQBgNVBAoT -CVRBSVdBTi1DQTEQMA4GA1UECxMHUm9vdCBDQTEcMBoGA1UEAxMTVFdDQSBHbG9iYWwgUm9vdCBD -QTAeFw0xMjA2MjcwNjI4MzNaFw0zMDEyMzExNTU5NTlaMFExCzAJBgNVBAYTAlRXMRIwEAYDVQQK -EwlUQUlXQU4tQ0ExEDAOBgNVBAsTB1Jvb3QgQ0ExHDAaBgNVBAMTE1RXQ0EgR2xvYmFsIFJvb3Qg -Q0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCwBdvI64zEbooh745NnHEKH1Jw7W2C -nJfF10xORUnLQEK1EjRsGcJ0pDFfhQKX7EMzClPSnIyOt7h52yvVavKOZsTuKwEHktSz0ALfUPZV -r2YOy+BHYC8rMjk1Ujoog/h7FsYYuGLWRyWRzvAZEk2tY/XTP3VfKfChMBwqoJimFb3u/Rk28OKR -Q4/6ytYQJ0lM793B8YVwm8rqqFpD/G2Gb3PpN0Wp8DbHzIh1HrtsBv+baz4X7GGqcXzGHaL3SekV -tTzWoWH1EfcFbx39Eb7QMAfCKbAJTibc46KokWofwpFFiFzlmLhxpRUZyXx1EcxwdE8tmx2RRP1W -KKD+u4ZqyPpcC1jcxkt2yKsi2XMPpfRaAok/T54igu6idFMqPVMnaR1sjjIsZAAmY2E2TqNGtz99 -sy2sbZCilaLOz9qC5wc0GZbpuCGqKX6mOL6OKUohZnkfs8O1CWfe1tQHRvMq2uYiN2DLgbYPoA/p -yJV/v1WRBXrPPRXAb94JlAGD1zQbzECl8LibZ9WYkTunhHiVJqRaCPgrdLQABDzfuBSO6N+pjWxn -kjMdwLfS7JLIvgm/LCkFbwJrnu+8vyq8W8BQj0FwcYeyTbcEqYSjMq+u7msXi7Kx/mzhkIyIqJdI -zshNy/MGz19qCkKxHh53L46g5pIOBvwFItIm4TFRfTLcDwIDAQABoyMwITAOBgNVHQ8BAf8EBAMC -AQYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAXzSBdu+WHdXltdkCY4QWwa6g -cFGn90xHNcgL1yg9iXHZqjNB6hQbbCEAwGxCGX6faVsgQt+i0trEfJdLjbDorMjupWkEmQqSpqsn -LhpNgb+E1HAerUf+/UqdM+DyucRFCCEK2mlpc3INvjT+lIutwx4116KD7+U4x6WFH6vPNOw/KP4M -8VeGTslV9xzU2KV9Bnpv1d8Q34FOIWWxtuEXeZVFBs5fzNxGiWNoRI2T9GRwoD2dKAXDOXC4Ynsg -/eTb6QihuJ49CcdP+yz4k3ZB3lLg4VfSnQO8d57+nile98FRYB/e2guyLXW3Q0iT5/Z5xoRdgFlg -lPx4mI88k1HtQJAH32RjJMtOcQWh15QaiDLxInQirqWm2BJpTGCjAu4r7NRjkgtevi92a6O2JryP -A9gK8kxkRr05YuWW6zRjESjMlfGt7+/cgFhI6Uu46mWs6fyAtbXIRfmswZ/ZuepiiI7E8UuDEq3m -i4TWnsLrgxifarsbJGAzcMzs9zLzXNl5fe+epP7JI8Mk7hWSsT2RTyaGvWZzJBPqpK5jwa19hAM8 -EHiGG3njxPPyBJUgriOCxLM6AGK/5jYk4Ve6xx6QddVfP5VhK8E7zeWzaGHQRiapIVJpLesux+t3 -zqY6tQMzT3bR51xUAV3LePTJDL/PEo4XLSNolOer/qmyKwbQBM0= ------END CERTIFICATE----- - -TeliaSonera Root CA v1 -====================== ------BEGIN CERTIFICATE----- -MIIFODCCAyCgAwIBAgIRAJW+FqD3LkbxezmCcvqLzZYwDQYJKoZIhvcNAQEFBQAwNzEUMBIGA1UE -CgwLVGVsaWFTb25lcmExHzAdBgNVBAMMFlRlbGlhU29uZXJhIFJvb3QgQ0EgdjEwHhcNMDcxMDE4 -MTIwMDUwWhcNMzIxMDE4MTIwMDUwWjA3MRQwEgYDVQQKDAtUZWxpYVNvbmVyYTEfMB0GA1UEAwwW -VGVsaWFTb25lcmEgUm9vdCBDQSB2MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMK+ -6yfwIaPzaSZVfp3FVRaRXP3vIb9TgHot0pGMYzHw7CTww6XScnwQbfQ3t+XmfHnqjLWCi65ItqwA -3GV17CpNX8GH9SBlK4GoRz6JI5UwFpB/6FcHSOcZrr9FZ7E3GwYq/t75rH2D+1665I+XZ75Ljo1k -B1c4VWk0Nj0TSO9P4tNmHqTPGrdeNjPUtAa9GAH9d4RQAEX1jF3oI7x+/jXh7VB7qTCNGdMJjmhn -Xb88lxhTuylixcpecsHHltTbLaC0H2kD7OriUPEMPPCs81Mt8Bz17Ww5OXOAFshSsCPN4D7c3TxH -oLs1iuKYaIu+5b9y7tL6pe0S7fyYGKkmdtwoSxAgHNN/Fnct7W+A90m7UwW7XWjH1Mh1Fj+JWov3 -F0fUTPHSiXk+TT2YqGHeOh7S+F4D4MHJHIzTjU3TlTazN19jY5szFPAtJmtTfImMMsJu7D0hADnJ -oWjiUIMusDor8zagrC/kb2HCUQk5PotTubtn2txTuXZZNp1D5SDgPTJghSJRt8czu90VL6R4pgd7 -gUY2BIbdeTXHlSw7sKMXNeVzH7RcWe/a6hBle3rQf5+ztCo3O3CLm1u5K7fsslESl1MpWtTwEhDc -TwK7EpIvYtQ/aUN8Ddb8WHUBiJ1YFkveupD/RwGJBmr2X7KQarMCpgKIv7NHfirZ1fpoeDVNAgMB -AAGjPzA9MA8GA1UdEwEB/wQFMAMBAf8wCwYDVR0PBAQDAgEGMB0GA1UdDgQWBBTwj1k4ALP1j5qW -DNXr+nuqF+gTEjANBgkqhkiG9w0BAQUFAAOCAgEAvuRcYk4k9AwI//DTDGjkk0kiP0Qnb7tt3oNm -zqjMDfz1mgbldxSR651Be5kqhOX//CHBXfDkH1e3damhXwIm/9fH907eT/j3HEbAek9ALCI18Bmx -0GtnLLCo4MBANzX2hFxc469CeP6nyQ1Q6g2EdvZR74NTxnr/DlZJLo961gzmJ1TjTQpgcmLNkQfW -pb/ImWvtxBnmq0wROMVvMeJuScg/doAmAyYp4Db29iBT4xdwNBedY2gea+zDTYa4EzAvXUYNR0PV -G6pZDrlcjQZIrXSHX8f8MVRBE+LHIQ6e4B4N4cB7Q4WQxYpYxmUKeFfyxiMPAdkgS94P+5KFdSpc -c41teyWRyu5FrgZLAMzTsVlQ2jqIOylDRl6XK1TOU2+NSueW+r9xDkKLfP0ooNBIytrEgUy7onOT -JsjrDNYmiLbAJM+7vVvrdX3pCI6GMyx5dwlppYn8s3CQh3aP0yK7Qs69cwsgJirQmz1wHiRszYd2 -qReWt88NkvuOGKmYSdGe/mBEciG5Ge3C9THxOUiIkCR1VBatzvT4aRRkOfujuLpwQMcnHL/EVlP6 -Y2XQ8xwOFvVrhlhNGNTkDY6lnVuR3HYkUD/GKvvZt5y11ubQ2egZixVxSK236thZiNSQvxaz2ems -WWFUyBy6ysHK4bkgTI86k4mloMy/0/Z1pHWWbVY= ------END CERTIFICATE----- - -T-TeleSec GlobalRoot Class 2 -============================ ------BEGIN CERTIFICATE----- -MIIDwzCCAqugAwIBAgIBATANBgkqhkiG9w0BAQsFADCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoM -IlQtU3lzdGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBU -cnVzdCBDZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwHhcNMDgx -MDAxMTA0MDE0WhcNMzMxMDAxMjM1OTU5WjCBgjELMAkGA1UEBhMCREUxKzApBgNVBAoMIlQtU3lz -dGVtcyBFbnRlcnByaXNlIFNlcnZpY2VzIEdtYkgxHzAdBgNVBAsMFlQtU3lzdGVtcyBUcnVzdCBD -ZW50ZXIxJTAjBgNVBAMMHFQtVGVsZVNlYyBHbG9iYWxSb290IENsYXNzIDIwggEiMA0GCSqGSIb3 -DQEBAQUAA4IBDwAwggEKAoIBAQCqX9obX+hzkeXaXPSi5kfl82hVYAUdAqSzm1nzHoqvNK38DcLZ -SBnuaY/JIPwhqgcZ7bBcrGXHX+0CfHt8LRvWurmAwhiCFoT6ZrAIxlQjgeTNuUk/9k9uN0goOA/F -vudocP05l03Sx5iRUKrERLMjfTlH6VJi1hKTXrcxlkIF+3anHqP1wvzpesVsqXFP6st4vGCvx970 -2cu+fjOlbpSD8DT6IavqjnKgP6TeMFvvhk1qlVtDRKgQFRzlAVfFmPHmBiiRqiDFt1MmUUOyCxGV -WOHAD3bZwI18gfNycJ5v/hqO2V81xrJvNHy+SE/iWjnX2J14np+GPgNeGYtEotXHAgMBAAGjQjBA -MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBS/WSA2AHmgoCJrjNXy -YdK4LMuCSjANBgkqhkiG9w0BAQsFAAOCAQEAMQOiYQsfdOhyNsZt+U2e+iKo4YFWz827n+qrkRk4 -r6p8FU3ztqONpfSO9kSpp+ghla0+AGIWiPACuvxhI+YzmzB6azZie60EI4RYZeLbK4rnJVM3YlNf -vNoBYimipidx5joifsFvHZVwIEoHNN/q/xWA5brXethbdXwFeilHfkCoMRN3zUA7tFFHei4R40cR -3p1m0IvVVGb6g1XqfMIpiRvpb7PO4gWEyS8+eIVibslfwXhjdFjASBgMmTnrpMwatXlajRWc2BQN -9noHV8cigwUtPJslJj0Ys6lDfMjIq2SPDqO/nBudMNva0Bkuqjzx+zOAduTNrRlPBSeOE6Fuwg== ------END CERTIFICATE----- - -Atos TrustedRoot 2011 -===================== ------BEGIN CERTIFICATE----- -MIIDdzCCAl+gAwIBAgIIXDPLYixfszIwDQYJKoZIhvcNAQELBQAwPDEeMBwGA1UEAwwVQXRvcyBU -cnVzdGVkUm9vdCAyMDExMQ0wCwYDVQQKDARBdG9zMQswCQYDVQQGEwJERTAeFw0xMTA3MDcxNDU4 -MzBaFw0zMDEyMzEyMzU5NTlaMDwxHjAcBgNVBAMMFUF0b3MgVHJ1c3RlZFJvb3QgMjAxMTENMAsG -A1UECgwEQXRvczELMAkGA1UEBhMCREUwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCV -hTuXbyo7LjvPpvMpNb7PGKw+qtn4TaA+Gke5vJrf8v7MPkfoepbCJI419KkM/IL9bcFyYie96mvr -54rMVD6QUM+A1JX76LWC1BTFtqlVJVfbsVD2sGBkWXppzwO3bw2+yj5vdHLqqjAqc2K+SZFhyBH+ -DgMq92og3AIVDV4VavzjgsG1xZ1kCWyjWZgHJ8cblithdHFsQ/H3NYkQ4J7sVaE3IqKHBAUsR320 -HLliKWYoyrfhk/WklAOZuXCFteZI6o1Q/NnezG8HDt0Lcp2AMBYHlT8oDv3FdU9T1nSatCQujgKR -z3bFmx5VdJx4IbHwLfELn8LVlhgf8FQieowHAgMBAAGjfTB7MB0GA1UdDgQWBBSnpQaxLKYJYO7R -l+lwrrw7GWzbITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFKelBrEspglg7tGX6XCuvDsZ -bNshMBgGA1UdIAQRMA8wDQYLKwYBBAGwLQMEAQEwDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB -CwUAA4IBAQAmdzTblEiGKkGdLD4GkGDEjKwLVLgfuXvTBznk+j57sj1O7Z8jvZfza1zv7v1Apt+h -k6EKhqzvINB5Ab149xnYJDE0BAGmuhWawyfc2E8PzBhj/5kPDpFrdRbhIfzYJsdHt6bPWHJxfrrh -TZVHO8mvbaG0weyJ9rQPOLXiZNwlz6bb65pcmaHFCN795trV1lpFDMS3wrUU77QR/w4VtfX128a9 -61qn8FYiqTxlVMYVqL2Gns2Dlmh6cYGJ4Qvh6hEbaAjMaZ7snkGeRDImeuKHCnE96+RapNLbxc3G -3mB/ufNPRJLvKrcYPqcZ2Qt9sTdBQrC6YB3y/gkRsPCHe6ed ------END CERTIFICATE----- - -QuoVadis Root CA 1 G3 -===================== ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIUeFhfLq0sGUvjNwc1NBMotZbUZZMwDQYJKoZIhvcNAQELBQAwSDELMAkG -A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv -b3QgQ0EgMSBHMzAeFw0xMjAxMTIxNzI3NDRaFw00MjAxMTIxNzI3NDRaMEgxCzAJBgNVBAYTAkJN -MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDEg -RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgvlAQjunybEC0BJyFuTHK3C3kEakE -PBtVwedYMB0ktMPvhd6MLOHBPd+C5k+tR4ds7FtJwUrVu4/sh6x/gpqG7D0DmVIB0jWerNrwU8lm -PNSsAgHaJNM7qAJGr6Qc4/hzWHa39g6QDbXwz8z6+cZM5cOGMAqNF34168Xfuw6cwI2H44g4hWf6 -Pser4BOcBRiYz5P1sZK0/CPTz9XEJ0ngnjybCKOLXSoh4Pw5qlPafX7PGglTvF0FBM+hSo+LdoIN -ofjSxxR3W5A2B4GbPgb6Ul5jxaYA/qXpUhtStZI5cgMJYr2wYBZupt0lwgNm3fME0UDiTouG9G/l -g6AnhF4EwfWQvTA9xO+oabw4m6SkltFi2mnAAZauy8RRNOoMqv8hjlmPSlzkYZqn0ukqeI1RPToV -7qJZjqlc3sX5kCLliEVx3ZGZbHqfPT2YfF72vhZooF6uCyP8Wg+qInYtyaEQHeTTRCOQiJ/GKubX -9ZqzWB4vMIkIG1SitZgj7Ah3HJVdYdHLiZxfokqRmu8hqkkWCKi9YSgxyXSthfbZxbGL0eUQMk1f -iyA6PEkfM4VZDdvLCXVDaXP7a3F98N/ETH3Goy7IlXnLc6KOTk0k+17kBL5yG6YnLUlamXrXXAkg -t3+UuU/xDRxeiEIbEbfnkduebPRq34wGmAOtzCjvpUfzUwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUo5fW816iEOGrRZ88F2Q87gFwnMwwDQYJKoZI -hvcNAQELBQADggIBABj6W3X8PnrHX3fHyt/PX8MSxEBd1DKquGrX1RUVRpgjpeaQWxiZTOOtQqOC -MTaIzen7xASWSIsBx40Bz1szBpZGZnQdT+3Btrm0DWHMY37XLneMlhwqI2hrhVd2cDMT/uFPpiN3 -GPoajOi9ZcnPP/TJF9zrx7zABC4tRi9pZsMbj/7sPtPKlL92CiUNqXsCHKnQO18LwIE6PWThv6ct -Tr1NxNgpxiIY0MWscgKCP6o6ojoilzHdCGPDdRS5YCgtW2jgFqlmgiNR9etT2DGbe+m3nUvriBbP -+V04ikkwj+3x6xn0dxoxGE1nVGwvb2X52z3sIexe9PSLymBlVNFxZPT5pqOBMzYzcfCkeF9OrYMh -3jRJjehZrJ3ydlo28hP0r+AJx2EqbPfgna67hkooby7utHnNkDPDs3b69fBsnQGQ+p6Q9pxyz0fa -wx/kNSBT8lTR32GDpgLiJTjehTItXnOQUl1CxM49S+H5GYQd1aJQzEH7QRTDvdbJWqNjZgKAvQU6 -O0ec7AAmTPWIUb+oI38YB7AL7YsmoWTTYUrrXJ/es69nA7Mf3W1daWhpq1467HxpvMc7hU6eFbm0 -FU/DlXpY18ls6Wy58yljXrQs8C097Vpl4KlbQMJImYFtnh8GKjwStIsPm6Ik8KaN1nrgS7ZklmOV -hMJKzRwuJIczYOXD ------END CERTIFICATE----- - -QuoVadis Root CA 2 G3 -===================== ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIURFc0JFuBiZs18s64KztbpybwdSgwDQYJKoZIhvcNAQELBQAwSDELMAkG -A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv -b3QgQ0EgMiBHMzAeFw0xMjAxMTIxODU5MzJaFw00MjAxMTIxODU5MzJaMEgxCzAJBgNVBAYTAkJN -MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDIg -RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQChriWyARjcV4g/Ruv5r+LrI3HimtFh -ZiFfqq8nUeVuGxbULX1QsFN3vXg6YOJkApt8hpvWGo6t/x8Vf9WVHhLL5hSEBMHfNrMWn4rjyduY -NM7YMxcoRvynyfDStNVNCXJJ+fKH46nafaF9a7I6JaltUkSs+L5u+9ymc5GQYaYDFCDy54ejiK2t -oIz/pgslUiXnFgHVy7g1gQyjO/Dh4fxaXc6AcW34Sas+O7q414AB+6XrW7PFXmAqMaCvN+ggOp+o -MiwMzAkd056OXbxMmO7FGmh77FOm6RQ1o9/NgJ8MSPsc9PG/Srj61YxxSscfrf5BmrODXfKEVu+l -V0POKa2Mq1W/xPtbAd0jIaFYAI7D0GoT7RPjEiuA3GfmlbLNHiJuKvhB1PLKFAeNilUSxmn1uIZo -L1NesNKqIcGY5jDjZ1XHm26sGahVpkUG0CM62+tlXSoREfA7T8pt9DTEceT/AFr2XK4jYIVz8eQQ -sSWu1ZK7E8EM4DnatDlXtas1qnIhO4M15zHfeiFuuDIIfR0ykRVKYnLP43ehvNURG3YBZwjgQQvD -6xVu+KQZ2aKrr+InUlYrAoosFCT5v0ICvybIxo/gbjh9Uy3l7ZizlWNof/k19N+IxWA1ksB8aRxh -lRbQ694Lrz4EEEVlWFA4r0jyWbYW8jwNkALGcC4BrTwV1wIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQU7edvdlq/YOxJW8ald7tyFnGbxD0wDQYJKoZI -hvcNAQELBQADggIBAJHfgD9DCX5xwvfrs4iP4VGyvD11+ShdyLyZm3tdquXK4Qr36LLTn91nMX66 -AarHakE7kNQIXLJgapDwyM4DYvmL7ftuKtwGTTwpD4kWilhMSA/ohGHqPHKmd+RCroijQ1h5fq7K -pVMNqT1wvSAZYaRsOPxDMuHBR//47PERIjKWnML2W2mWeyAMQ0GaW/ZZGYjeVYg3UQt4XAoeo0L9 -x52ID8DyeAIkVJOviYeIyUqAHerQbj5hLja7NQ4nlv1mNDthcnPxFlxHBlRJAHpYErAK74X9sbgz -dWqTHBLmYF5vHX/JHyPLhGGfHoJE+V+tYlUkmlKY7VHnoX6XOuYvHxHaU4AshZ6rNRDbIl9qxV6X -U/IyAgkwo1jwDQHVcsaxfGl7w/U2Rcxhbl5MlMVerugOXou/983g7aEOGzPuVBj+D77vfoRrQ+Nw -mNtddbINWQeFFSM51vHfqSYP1kjHs6Yi9TM3WpVHn3u6GBVv/9YUZINJ0gpnIdsPNWNgKCLjsZWD -zYWm3S8P52dSbrsvhXz1SnPnxT7AvSESBT/8twNJAlvIJebiVDj1eYeMHVOyToV7BjjHLPj4sHKN -JeV3UvQDHEimUF+IIDBu8oJDqz2XhOdT+yHBTw8imoa4WSr2Rz0ZiC3oheGe7IUIarFsNMkd7Egr -O3jtZsSOeWmD3n+M ------END CERTIFICATE----- - -QuoVadis Root CA 3 G3 -===================== ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIULvWbAiin23r/1aOp7r0DoM8Sah0wDQYJKoZIhvcNAQELBQAwSDELMAkG -A1UEBhMCQk0xGTAXBgNVBAoTEFF1b1ZhZGlzIExpbWl0ZWQxHjAcBgNVBAMTFVF1b1ZhZGlzIFJv -b3QgQ0EgMyBHMzAeFw0xMjAxMTIyMDI2MzJaFw00MjAxMTIyMDI2MzJaMEgxCzAJBgNVBAYTAkJN -MRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVkMR4wHAYDVQQDExVRdW9WYWRpcyBSb290IENBIDMg -RzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCzyw4QZ47qFJenMioKVjZ/aEzHs286 -IxSR/xl/pcqs7rN2nXrpixurazHb+gtTTK/FpRp5PIpM/6zfJd5O2YIyC0TeytuMrKNuFoM7pmRL -Mon7FhY4futD4tN0SsJiCnMK3UmzV9KwCoWdcTzeo8vAMvMBOSBDGzXRU7Ox7sWTaYI+FrUoRqHe -6okJ7UO4BUaKhvVZR74bbwEhELn9qdIoyhA5CcoTNs+cra1AdHkrAj80//ogaX3T7mH1urPnMNA3 -I4ZyYUUpSFlob3emLoG+B01vr87ERRORFHAGjx+f+IdpsQ7vw4kZ6+ocYfx6bIrc1gMLnia6Et3U -VDmrJqMz6nWB2i3ND0/kA9HvFZcba5DFApCTZgIhsUfei5pKgLlVj7WiL8DWM2fafsSntARE60f7 -5li59wzweyuxwHApw0BiLTtIadwjPEjrewl5qW3aqDCYz4ByA4imW0aucnl8CAMhZa634RylsSqi -Md5mBPfAdOhx3v89WcyWJhKLhZVXGqtrdQtEPREoPHtht+KPZ0/l7DxMYIBpVzgeAVuNVejH38DM -dyM0SXV89pgR6y3e7UEuFAUCf+D+IOs15xGsIs5XPd7JMG0QA4XN8f+MFrXBsj6IbGB/kE+V9/Yt -rQE5BwT6dYB9v0lQ7e/JxHwc64B+27bQ3RP+ydOc17KXqQIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUxhfQvKjqAkPyGwaZXSuQILnXnOQwDQYJKoZI -hvcNAQELBQADggIBADRh2Va1EodVTd2jNTFGu6QHcrxfYWLopfsLN7E8trP6KZ1/AvWkyaiTt3px -KGmPc+FSkNrVvjrlt3ZqVoAh313m6Tqe5T72omnHKgqwGEfcIHB9UqM+WXzBusnIFUBhynLWcKzS -t/Ac5IYp8M7vaGPQtSCKFWGafoaYtMnCdvvMujAWzKNhxnQT5WvvoxXqA/4Ti2Tk08HS6IT7SdEQ -TXlm66r99I0xHnAUrdzeZxNMgRVhvLfZkXdxGYFgu/BYpbWcC/ePIlUnwEsBbTuZDdQdm2NnL9Du -DcpmvJRPpq3t/O5jrFc/ZSXPsoaP0Aj/uHYUbt7lJ+yreLVTubY/6CD50qi+YUbKh4yE8/nxoGib -Ih6BJpsQBJFxwAYf3KDTuVan45gtf4Od34wrnDKOMpTwATwiKp9Dwi7DmDkHOHv8XgBCH/MyJnmD -hPbl8MFREsALHgQjDFSlTC9JxUrRtm5gDWv8a4uFJGS3iQ6rJUdbPM9+Sb3H6QrG2vd+DhcI00iX -0HGS8A85PjRqHH3Y8iKuu2n0M7SmSFXRDw4m6Oy2Cy2nhTXN/VnIn9HNPlopNLk9hM6xZdRZkZFW -dSHBd575euFgndOtBBj0fOtek49TSiIp+EgrPk2GrFt/ywaZWWDYWGWVjUTR939+J399roD1B0y2 -PpxxVJkES/1Y+Zj0 ------END CERTIFICATE----- - -DigiCert Assured ID Root G2 -=========================== ------BEGIN CERTIFICATE----- -MIIDljCCAn6gAwIBAgIQC5McOtY5Z+pnI7/Dr5r0SzANBgkqhkiG9w0BAQsFADBlMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQw -IgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIwHhcNMTMwODAxMTIwMDAwWhcNMzgw -MTE1MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQL -ExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzIw -ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDZ5ygvUj82ckmIkzTz+GoeMVSAn61UQbVH -35ao1K+ALbkKz3X9iaV9JPrjIgwrvJUXCzO/GU1BBpAAvQxNEP4HteccbiJVMWWXvdMX0h5i89vq -bFCMP4QMls+3ywPgym2hFEwbid3tALBSfK+RbLE4E9HpEgjAALAcKxHad3A2m67OeYfcgnDmCXRw -VWmvo2ifv922ebPynXApVfSr/5Vh88lAbx3RvpO704gqu52/clpWcTs/1PPRCv4o76Pu2ZmvA9OP -YLfykqGxvYmJHzDNw6YuYjOuFgJ3RFrngQo8p0Quebg/BLxcoIfhG69Rjs3sLPr4/m3wOnyqi+Rn -lTGNAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTO -w0q5mVXyuNtgv6l+vVa1lzan1jANBgkqhkiG9w0BAQsFAAOCAQEAyqVVjOPIQW5pJ6d1Ee88hjZv -0p3GeDgdaZaikmkuOGybfQTUiaWxMTeKySHMq2zNixya1r9I0jJmwYrA8y8678Dj1JGG0VDjA9tz -d29KOVPt3ibHtX2vK0LRdWLjSisCx1BL4GnilmwORGYQRI+tBev4eaymG+g3NJ1TyWGqolKvSnAW -hsI6yLETcDbYz+70CjTVW0z9B5yiutkBclzzTcHdDrEcDcRjvq30FPuJ7KJBDkzMyFdA0G4Dqs0M -jomZmWzwPDCvON9vvKO+KSAnq3T/EyJ43pdSVR6DtVQgA+6uwE9W3jfMw3+qBCe703e4YtsXfJwo -IhNzbM8m9Yop5w== ------END CERTIFICATE----- - -DigiCert Assured ID Root G3 -=========================== ------BEGIN CERTIFICATE----- -MIICRjCCAc2gAwIBAgIQC6Fa+h3foLVJRK/NJKBs7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYD -VQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 -MTIwMDAwWjBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3QgRzMwdjAQ -BgcqhkjOPQIBBgUrgQQAIgNiAAQZ57ysRGXtzbg/WPuNsVepRC0FFfLvC/8QdJ+1YlJfZn4f5dwb -RXkLzMZTCp2NXQLZqVneAlr2lSoOjThKiknGvMYDOAdfVdp+CW7if17QRSAPWXYQ1qAk8C3eNvJs -KTmjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTL0L2p4ZgF -UaFNN6KDec6NHSrkhDAKBggqhkjOPQQDAwNnADBkAjAlpIFFAmsSS3V0T8gj43DydXLefInwz5Fy -YZ5eEJJZVrmDxxDnOOlYJjZ91eQ0hjkCMHw2U/Aw5WJjOpnitqM7mzT6HtoQknFekROn3aRukswy -1vUhZscv6pZjamVFkpUBtA== ------END CERTIFICATE----- - -DigiCert Global Root G2 -======================= ------BEGIN CERTIFICATE----- -MIIDjjCCAnagAwIBAgIQAzrx5qcRqaC7KGSxHQn65TANBgkqhkiG9w0BAQsFADBhMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAw -HgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMjAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUx -MjAwMDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 -dy5kaWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEcyMIIBIjANBgkq -hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuzfNNNx7a8myaJCtSnX/RrohCgiN9RlUyfuI2/Ou8jqJ -kTx65qsGGmvPrC3oXgkkRLpimn7Wo6h+4FR1IAWsULecYxpsMNzaHxmx1x7e/dfgy5SDN67sH0NO -3Xss0r0upS/kqbitOtSZpLYl6ZtrAGCSYP9PIUkY92eQq2EGnI/yuum06ZIya7XzV+hdG82MHauV -BJVJ8zUtluNJbd134/tJS7SsVQepj5WztCO7TG1F8PapspUwtP1MVYwnSlcUfIKdzXOS0xZKBgyM -UNGPHgm+F6HmIcr9g+UQvIOlCsRnKPZzFBQ9RnbDhxSJITRNrw9FDKZJobq7nMWxM4MphQIDAQAB -o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUTiJUIBiV5uNu -5g/6+rkS7QYXjzkwDQYJKoZIhvcNAQELBQADggEBAGBnKJRvDkhj6zHd6mcY1Yl9PMWLSn/pvtsr -F9+wX3N3KjITOYFnQoQj8kVnNeyIv/iPsGEMNKSuIEyExtv4NeF22d+mQrvHRAiGfzZ0JFrabA0U -WTW98kndth/Jsw1HKj2ZL7tcu7XUIOGZX1NGFdtom/DzMNU+MeKNhJ7jitralj41E6Vf8PlwUHBH -QRFXGU7Aj64GxJUTFy8bJZ918rGOmaFvE7FBcf6IKshPECBV1/MUReXgRPTqh5Uykw7+U0b6LJ3/ -iyK5S9kJRaTepLiaWN0bfVKfjllDiIGknibVb63dDcY3fe0Dkhvld1927jyNxF1WW6LZZm6zNTfl -MrY= ------END CERTIFICATE----- - -DigiCert Global Root G3 -======================= ------BEGIN CERTIFICATE----- -MIICPzCCAcWgAwIBAgIQBVVWvPJepDU1w6QP1atFcjAKBggqhkjOPQQDAzBhMQswCQYDVQQGEwJV -UzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSAwHgYD -VQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBHMzAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAw -MDBaMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5k -aWdpY2VydC5jb20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMHYwEAYHKoZIzj0C -AQYFK4EEACIDYgAE3afZu4q4C/sLfyHS8L6+c/MzXRq8NOrexpu80JX28MzQC7phW1FGfp4tn+6O -YwwX7Adw9c+ELkCDnOg/QW07rdOkFFk2eJ0DQ+4QE2xy3q6Ip6FrtUPOZ9wj/wMco+I+o0IwQDAP -BgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNVHQ4EFgQUs9tIpPmhxdiuNkHMEWNp -Yim8S8YwCgYIKoZIzj0EAwMDaAAwZQIxAK288mw/EkrRLTnDCgmXc/SINoyIJ7vmiI1Qhadj+Z4y -3maTD/HMsQmP3Wyr+mt/oAIwOWZbwmSNuJ5Q3KjVSaLtx9zRSX8XAbjIho9OjIgrqJqpisXRAL34 -VOKa5Vt8sycX ------END CERTIFICATE----- - -DigiCert Trusted Root G4 -======================== ------BEGIN CERTIFICATE----- -MIIFkDCCA3igAwIBAgIQBZsbV56OITLiOQe9p3d1XDANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQG -EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEw -HwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMTMwODAxMTIwMDAwWhcNMzgwMTE1 -MTIwMDAwWjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0G -CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEp -pz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9o -k3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7Fsa -vOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGY -QJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6 -MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtm -mnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7 -f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFH -dL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8 -oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud -DwEB/wQEAwIBhjAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wDQYJKoZIhvcNAQEMBQAD -ggIBALth2X2pbL4XxJEbw6GiAI3jZGgPVs93rnD5/ZpKmbnJeFwMDF/k5hQpVgs2SV1EY+CtnJYY -ZhsjDT156W1r1lT40jzBQ0CuHVD1UvyQO7uYmWlrx8GnqGikJ9yd+SeuMIW59mdNOj6PWTkiU0Tr -yF0Dyu1Qen1iIQqAyHNm0aAFYF/opbSnr6j3bTWcfFqK1qI4mfN4i/RN0iAL3gTujJtHgXINwBQy -7zBZLq7gcfJW5GqXb5JQbZaNaHqasjYUegbyJLkJEVDXCLG4iXqEI2FCKeWjzaIgQdfRnGTZ6iah -ixTXTBmyUEFxPT9NcCOGDErcgdLMMpSEDQgJlxxPwO5rIHQw0uA5NBCFIRUBCOhVMt5xSdkoF1BN -5r5N0XWs0Mr7QbhDparTwwVETyw2m+L64kW4I1NsBm9nVX9GtUw/bihaeSbSpKhil9Ie4u1Ki7wb -/UdKDd9nZn6yW0HQO+T0O/QEY+nvwlQAUaCKKsnOeMzV6ocEGLPOr0mIr/OSmbaz5mEP0oUA51Aa -5BuVnRmhuZyxm7EAHu/QD09CbMkKvO5D+jpxpchNJqU1/YldvIViHTLSoCtU7ZpXwdv6EM8Zt4tK -G48BtieVU+i2iW1bvGjUI+iLUaJW+fCmgKDWHrO8Dw9TdSmq6hN35N6MgSGtBxBHEa2HPQfRdbzP -82Z+ ------END CERTIFICATE----- - -COMODO RSA Certification Authority -================================== ------BEGIN CERTIFICATE----- -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 -LaZRfyHBNVOFBkpdn627G190 ------END CERTIFICATE----- - -USERTrust RSA Certification Authority -===================================== ------BEGIN CERTIFICATE----- -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 -Q+6IHdfGjjxDah2nGN59PRbxYvnKkKj9 ------END CERTIFICATE----- - -USERTrust ECC Certification Authority -===================================== ------BEGIN CERTIFICATE----- -MIICjzCCAhWgAwIBAgIQXIuZxVqUxdJxVt7NiYDMJjAKBggqhkjOPQQDAzCBiDELMAkGA1UEBhMC -VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU -aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkwHhcNMTAwMjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMC -VVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU -aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBFQ0MgQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQarFRaqfloI+d61SRvU8Za2EurxtW2 -0eZzca7dnNYMYf3boIkDuAUU7FfO7l0/4iGzzvfUinngo4N+LZfQYcTxmdwlkWOrfzCjtHDix6Ez -nPO/LlxTsV+zfTJ/ijTjeXmjQjBAMB0GA1UdDgQWBBQ64QmG1M8ZwpZ2dEl23OA1xmNjmjAOBgNV -HQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNoADBlAjA2Z6EWCNzklwBB -HU6+4WMBzzuqQhFkoJ2UOQIReVx7Hfpkue4WQrO/isIJxOzksU0CMQDpKmFHjFJKS04YcPbWRNZu -9YO6bVi9JNlWSOrvxKJGgYhqOkbRqZtNyWHa0V1Xahg= ------END CERTIFICATE----- - -GlobalSign ECC Root CA - R5 -=========================== ------BEGIN CERTIFICATE----- -MIICHjCCAaSgAwIBAgIRYFlJ4CYuu1X5CneKcflK2GwwCgYIKoZIzj0EAwMwUDEkMCIGA1UECxMb -R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD -EwpHbG9iYWxTaWduMB4XDTEyMTExMzAwMDAwMFoXDTM4MDExOTAzMTQwN1owUDEkMCIGA1UECxMb -R2xvYmFsU2lnbiBFQ0MgUm9vdCBDQSAtIFI1MRMwEQYDVQQKEwpHbG9iYWxTaWduMRMwEQYDVQQD -EwpHbG9iYWxTaWduMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAER0UOlvt9Xb/pOdEh+J8LttV7HpI6 -SFkc8GIxLcB6KP4ap1yztsyX50XUWPrRd21DosCHZTQKH3rd6zwzocWdTaRvQZU4f8kehOvRnkmS -h5SHDDqFSmafnVmTTZdhBoZKo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd -BgNVHQ4EFgQUPeYpSJvqB8ohREom3m7e0oPQn1kwCgYIKoZIzj0EAwMDaAAwZQIxAOVpEslu28Yx -uglB4Zf4+/2a4n0Sye18ZNPLBSWLVtmg515dTguDnFt2KaAJJiFqYgIwcdK1j1zqO+F4CYWodZI7 -yFz9SO8NdCKoCOJuxUnOxwy8p2Fp8fc74SrL+SvzZpA3 ------END CERTIFICATE----- - -IdenTrust Commercial Root CA 1 -============================== ------BEGIN CERTIFICATE----- -MIIFYDCCA0igAwIBAgIQCgFCgAAAAUUjyES1AAAAAjANBgkqhkiG9w0BAQsFADBKMQswCQYDVQQG -EwJVUzESMBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBS -b290IENBIDEwHhcNMTQwMTE2MTgxMjIzWhcNMzQwMTE2MTgxMjIzWjBKMQswCQYDVQQGEwJVUzES -MBAGA1UEChMJSWRlblRydXN0MScwJQYDVQQDEx5JZGVuVHJ1c3QgQ29tbWVyY2lhbCBSb290IENB -IDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCnUBneP5k91DNG8W9RYYKyqU+PZ4ld -hNlT3Qwo2dfw/66VQ3KZ+bVdfIrBQuExUHTRgQ18zZshq0PirK1ehm7zCYofWjK9ouuU+ehcCuz/ -mNKvcbO0U59Oh++SvL3sTzIwiEsXXlfEU8L2ApeN2WIrvyQfYo3fw7gpS0l4PJNgiCL8mdo2yMKi -1CxUAGc1bnO/AljwpN3lsKImesrgNqUZFvX9t++uP0D1bVoE/c40yiTcdCMbXTMTEl3EASX2MN0C -XZ/g1Ue9tOsbobtJSdifWwLziuQkkORiT0/Br4sOdBeo0XKIanoBScy0RnnGF7HamB4HWfp1IYVl -3ZBWzvurpWCdxJ35UrCLvYf5jysjCiN2O/cz4ckA82n5S6LgTrx+kzmEB/dEcH7+B1rlsazRGMzy -NeVJSQjKVsk9+w8YfYs7wRPCTY/JTw436R+hDmrfYi7LNQZReSzIJTj0+kuniVyc0uMNOYZKdHzV -WYfCP04MXFL0PfdSgvHqo6z9STQaKPNBiDoT7uje/5kdX7rL6B7yuVBgwDHTc+XvvqDtMwt0viAg -xGds8AgDelWAf0ZOlqf0Hj7h9tgJ4TNkK2PXMl6f+cB7D3hvl7yTmvmcEpB4eoCHFddydJxVdHix -uuFucAS6T6C6aMN7/zHwcz09lCqxC0EOoP5NiGVreTO01wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC -AQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7UQZwNPwBovupHu+QucmVMiONnYwDQYJKoZI -hvcNAQELBQADggIBAA2ukDL2pkt8RHYZYR4nKM1eVO8lvOMIkPkp165oCOGUAFjvLi5+U1KMtlwH -6oi6mYtQlNeCgN9hCQCTrQ0U5s7B8jeUeLBfnLOic7iPBZM4zY0+sLj7wM+x8uwtLRvM7Kqas6pg -ghstO8OEPVeKlh6cdbjTMM1gCIOQ045U8U1mwF10A0Cj7oV+wh93nAbowacYXVKV7cndJZ5t+qnt -ozo00Fl72u1Q8zW/7esUTTHHYPTa8Yec4kjixsU3+wYQ+nVZZjFHKdp2mhzpgq7vmrlR94gjmmmV -YjzlVYA211QC//G5Xc7UI2/YRYRKW2XviQzdFKcgyxilJbQN+QHwotL0AMh0jqEqSI5l2xPE4iUX -feu+h1sXIFRRk0pTAwvsXcoz7WL9RccvW9xYoIA55vrX/hMUpu09lEpCdNTDd1lzzY9GvlU47/ro -kTLql1gEIt44w8y8bckzOmoKaT+gyOpyj4xjhiO9bTyWnpXgSUyqorkqG5w2gXjtw+hG4iZZRHUe -2XWJUc0QhJ1hYMtd+ZciTY6Y5uN/9lu7rs3KSoFrXgvzUeF0K+l+J6fZmUlO+KWA2yUPHGNiiskz -Z2s8EIPGrd6ozRaOjfAHN3Gf8qv8QfXBi+wAN10J5U6A7/qxXDgGpRtK4dw4LTzcqx+QGtVKnO7R -cGzM7vRX+Bi6hG6H ------END CERTIFICATE----- - -IdenTrust Public Sector Root CA 1 -================================= ------BEGIN CERTIFICATE----- -MIIFZjCCA06gAwIBAgIQCgFCgAAAAUUjz0Z8AAAAAjANBgkqhkiG9w0BAQsFADBNMQswCQYDVQQG -EwJVUzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3Rv -ciBSb290IENBIDEwHhcNMTQwMTE2MTc1MzMyWhcNMzQwMTE2MTc1MzMyWjBNMQswCQYDVQQGEwJV -UzESMBAGA1UEChMJSWRlblRydXN0MSowKAYDVQQDEyFJZGVuVHJ1c3QgUHVibGljIFNlY3RvciBS -b290IENBIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2IpT8pEiv6EdrCvsnduTy -P4o7ekosMSqMjbCpwzFrqHd2hCa2rIFCDQjrVVi7evi8ZX3yoG2LqEfpYnYeEe4IFNGyRBb06tD6 -Hi9e28tzQa68ALBKK0CyrOE7S8ItneShm+waOh7wCLPQ5CQ1B5+ctMlSbdsHyo+1W/CD80/HLaXI -rcuVIKQxKFdYWuSNG5qrng0M8gozOSI5Cpcu81N3uURF/YTLNiCBWS2ab21ISGHKTN9T0a9SvESf -qy9rg3LvdYDaBjMbXcjaY8ZNzaxmMc3R3j6HEDbhuaR672BQssvKplbgN6+rNBM5Jeg5ZuSYeqoS -mJxZZoY+rfGwyj4GD3vwEUs3oERte8uojHH01bWRNszwFcYr3lEXsZdMUD2xlVl8BX0tIdUAvwFn -ol57plzy9yLxkA2T26pEUWbMfXYD62qoKjgZl3YNa4ph+bz27nb9cCvdKTz4Ch5bQhyLVi9VGxyh -LrXHFub4qjySjmm2AcG1hp2JDws4lFTo6tyePSW8Uybt1as5qsVATFSrsrTZ2fjXctscvG29ZV/v -iDUqZi/u9rNl8DONfJhBaUYPQxxp+pu10GFqzcpL2UyQRqsVWaFHVCkugyhfHMKiq3IXAAaOReyL -4jM9f9oZRORicsPfIsbyVtTdX5Vy7W1f90gDW/3FKqD2cyOEEBsB5wIDAQABo0IwQDAOBgNVHQ8B -Af8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU43HgntinQtnbcZFrlJPrw6PRFKMw -DQYJKoZIhvcNAQELBQADggIBAEf63QqwEZE4rU1d9+UOl1QZgkiHVIyqZJnYWv6IAcVYpZmxI1Qj -t2odIFflAWJBF9MJ23XLblSQdf4an4EKwt3X9wnQW3IV5B4Jaj0z8yGa5hV+rVHVDRDtfULAj+7A -mgjVQdZcDiFpboBhDhXAuM/FSRJSzL46zNQuOAXeNf0fb7iAaJg9TaDKQGXSc3z1i9kKlT/YPyNt -GtEqJBnZhbMX73huqVjRI9PHE+1yJX9dsXNw0H8GlwmEKYBhHfpe/3OsoOOJuBxxFcbeMX8S3OFt -m6/n6J91eEyrRjuazr8FGF1NFTwWmhlQBJqymm9li1JfPFgEKCXAZmExfrngdbkaqIHWchezxQMx -NRF4eKLg6TCMf4DfWN88uieW4oA0beOY02QnrEh+KHdcxiVhJfiFDGX6xDIvpZgF5PgLZxYWxoK4 -Mhn5+bl53B/N66+rDt0b20XkeucC4pVd/GnwU2lhlXV5C15V5jgclKlZM57IcXR5f1GJtshquDDI -ajjDbp7hNxbqBWJMWxJH7ae0s1hWx0nzfxJoCTFx8G34Tkf71oXuxVhAGaQdp/lLQzfcaFpPz+vC -ZHTetBXZ9FRUGi8c15dxVJCO2SCdUyt/q4/i6jC8UDfv8Ue1fXwsBOxonbRJRBD0ckscZOf85muQ -3Wl9af0AVqW3rLatt8o+Ae+c ------END CERTIFICATE----- - -Entrust Root Certification Authority - G2 -========================================= ------BEGIN CERTIFICATE----- -MIIEPjCCAyagAwIBAgIESlOMKDANBgkqhkiG9w0BAQsFADCBvjELMAkGA1UEBhMCVVMxFjAUBgNV -BAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVy -bXMxOTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ug -b25seTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIw -HhcNMDkwNzA3MTcyNTU0WhcNMzAxMjA3MTc1NTU0WjCBvjELMAkGA1UEBhMCVVMxFjAUBgNVBAoT -DUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVnYWwtdGVybXMx -OTA3BgNVBAsTMChjKSAyMDA5IEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXplZCB1c2Ugb25s -eTEyMDAGA1UEAxMpRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IC0gRzIwggEi -MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6hLZy254Ma+KZ6TABp3bqMriVQRrJ2mFOWHLP -/vaCeb9zYQYKpSfYs1/TRU4cctZOMvJyig/3gxnQaoCAAEUesMfnmr8SVycco2gvCoe9amsOXmXz -HHfV1IWNcCG0szLni6LVhjkCsbjSR87kyUnEO6fe+1R9V77w6G7CebI6C1XiUJgWMhNcL3hWwcKU -s/Ja5CeanyTXxuzQmyWC48zCxEXFjJd6BmsqEZ+pCm5IO2/b1BEZQvePB7/1U1+cPvQXLOZprE4y -TGJ36rfo5bs0vBmLrpxR57d+tVOxMyLlbc9wPBr64ptntoP0jaWvYkxN4FisZDQSA/i2jZRjJKRx -AgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBRqciZ6 -0B7vfec7aVHUbI2fkBJmqzANBgkqhkiG9w0BAQsFAAOCAQEAeZ8dlsa2eT8ijYfThwMEYGprmi5Z -iXMRrEPR9RP/jTkrwPK9T3CMqS/qF8QLVJ7UG5aYMzyorWKiAHarWWluBh1+xLlEjZivEtRh2woZ -Rkfz6/djwUAFQKXSt/S1mja/qYh2iARVBCuch38aNzx+LaUa2NSJXsq9rD1s2G2v1fN2D807iDgi -nWyTmsQ9v4IbZT+mD12q/OWyFcq1rca8PdCE6OoGcrBNOTJ4vz4RnAuknZoh8/CbCzB428Hch0P+ -vGOaysXCHMnHjf87ElgI5rY97HosTvuDls4MPGmHVHOkc8KT/1EQrBVUAdj8BbGJoX90g5pJ19xO -e4pIb4tF9g== ------END CERTIFICATE----- - -Entrust Root Certification Authority - EC1 -========================================== ------BEGIN CERTIFICATE----- -MIIC+TCCAoCgAwIBAgINAKaLeSkAAAAAUNCR+TAKBggqhkjOPQQDAzCBvzELMAkGA1UEBhMCVVMx -FjAUBgNVBAoTDUVudHJ1c3QsIEluYy4xKDAmBgNVBAsTH1NlZSB3d3cuZW50cnVzdC5uZXQvbGVn -YWwtdGVybXMxOTA3BgNVBAsTMChjKSAyMDEyIEVudHJ1c3QsIEluYy4gLSBmb3IgYXV0aG9yaXpl -ZCB1c2Ugb25seTEzMDEGA1UEAxMqRW50cnVzdCBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5 -IC0gRUMxMB4XDTEyMTIxODE1MjUzNloXDTM3MTIxODE1NTUzNlowgb8xCzAJBgNVBAYTAlVTMRYw -FAYDVQQKEw1FbnRydXN0LCBJbmMuMSgwJgYDVQQLEx9TZWUgd3d3LmVudHJ1c3QubmV0L2xlZ2Fs -LXRlcm1zMTkwNwYDVQQLEzAoYykgMjAxMiBFbnRydXN0LCBJbmMuIC0gZm9yIGF1dGhvcml6ZWQg -dXNlIG9ubHkxMzAxBgNVBAMTKkVudHJ1c3QgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSAt -IEVDMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABIQTydC6bUF74mzQ61VfZgIaJPRbiWlH47jCffHy -AsWfoPZb1YsGGYZPUxBtByQnoaD41UcZYUx9ypMn6nQM72+WCf5j7HBdNq1nd67JnXxVRDqiY1Ef -9eNi1KlHBz7MIKNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYE -FLdj5xrdjekIplWDpOBqUEFlEUJJMAoGCCqGSM49BAMDA2cAMGQCMGF52OVCR98crlOZF7ZvHH3h -vxGU0QOIdeSNiaSKd0bebWHvAvX7td/M/k7//qnmpwIwW5nXhTcGtXsI/esni0qU+eH6p44mCOh8 -kmhtc9hvJqwhAriZtyZBWyVgrtBIGu4G ------END CERTIFICATE----- - -CFCA EV ROOT -============ ------BEGIN CERTIFICATE----- -MIIFjTCCA3WgAwIBAgIEGErM1jANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJDTjEwMC4GA1UE -CgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQDDAxDRkNB -IEVWIFJPT1QwHhcNMTIwODA4MDMwNzAxWhcNMjkxMjMxMDMwNzAxWjBWMQswCQYDVQQGEwJDTjEw -MC4GA1UECgwnQ2hpbmEgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MRUwEwYDVQQD -DAxDRkNBIEVWIFJPT1QwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDXXWvNED8fBVnV -BU03sQ7smCuOFR36k0sXgiFxEFLXUWRwFsJVaU2OFW2fvwwbwuCjZ9YMrM8irq93VCpLTIpTUnrD -7i7es3ElweldPe6hL6P3KjzJIx1qqx2hp/Hz7KDVRM8Vz3IvHWOX6Jn5/ZOkVIBMUtRSqy5J35DN -uF++P96hyk0g1CXohClTt7GIH//62pCfCqktQT+x8Rgp7hZZLDRJGqgG16iI0gNyejLi6mhNbiyW -ZXvKWfry4t3uMCz7zEasxGPrb382KzRzEpR/38wmnvFyXVBlWY9ps4deMm/DGIq1lY+wejfeWkU7 -xzbh72fROdOXW3NiGUgthxwG+3SYIElz8AXSG7Ggo7cbcNOIabla1jj0Ytwli3i/+Oh+uFzJlU9f -py25IGvPa931DfSCt/SyZi4QKPaXWnuWFo8BGS1sbn85WAZkgwGDg8NNkt0yxoekN+kWzqotaK8K -gWU6cMGbrU1tVMoqLUuFG7OA5nBFDWteNfB/O7ic5ARwiRIlk9oKmSJgamNgTnYGmE69g60dWIol -hdLHZR4tjsbftsbhf4oEIRUpdPA+nJCdDC7xij5aqgwJHsfVPKPtl8MeNPo4+QgO48BdK4PRVmrJ -tqhUUy54Mmc9gn900PvhtgVguXDbjgv5E1hvcWAQUhC5wUEJ73IfZzF4/5YFjQIDAQABo2MwYTAf -BgNVHSMEGDAWgBTj/i39KNALtbq2osS/BqoFjJP7LzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB -/wQEAwIBBjAdBgNVHQ4EFgQU4/4t/SjQC7W6tqLEvwaqBYyT+y8wDQYJKoZIhvcNAQELBQADggIB -ACXGumvrh8vegjmWPfBEp2uEcwPenStPuiB/vHiyz5ewG5zz13ku9Ui20vsXiObTej/tUxPQ4i9q -ecsAIyjmHjdXNYmEwnZPNDatZ8POQQaIxffu2Bq41gt/UP+TqhdLjOztUmCypAbqTuv0axn96/Ua -4CUqmtzHQTb3yHQFhDmVOdYLO6Qn+gjYXB74BGBSESgoA//vU2YApUo0FmZ8/Qmkrp5nGm9BC2sG -E5uPhnEFtC+NiWYzKXZUmhH4J/qyP5Hgzg0b8zAarb8iXRvTvyUFTeGSGn+ZnzxEk8rUQElsgIfX -BDrDMlI1Dlb4pd19xIsNER9Tyx6yF7Zod1rg1MvIB671Oi6ON7fQAUtDKXeMOZePglr4UeWJoBjn -aH9dCi77o0cOPaYjesYBx4/IXr9tgFa+iiS6M+qf4TIRnvHST4D2G0CvOJ4RUHlzEhLN5mydLIhy -PDCBBpEi6lmt2hkuIsKNuYyH4Ga8cyNfIWRjgEj1oDwYPZTISEEdQLpe/v5WOaHIz16eGWRGENoX -kbcFgKyLmZJ956LYBws2J+dIeWCKw9cTXPhyQN9Ky8+ZAAoACxGV2lZFA4gKn2fQ1XmxqI1AbQ3C -ekD6819kR5LLU7m7Wc5P/dAVUwHY3+vZ5nbv0CO7O6l5s9UCKc2Jo5YPSjXnTkLAdc0Hz+Ys63su ------END CERTIFICATE----- - -OISTE WISeKey Global Root GB CA -=============================== ------BEGIN CERTIFICATE----- -MIIDtTCCAp2gAwIBAgIQdrEgUnTwhYdGs/gjGvbCwDANBgkqhkiG9w0BAQsFADBtMQswCQYDVQQG -EwJDSDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNl -ZDEoMCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQiBDQTAeFw0xNDEyMDExNTAw -MzJaFw0zOTEyMDExNTEwMzFaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYD -VQQLExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEds -b2JhbCBSb290IEdCIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2Be3HEokKtaX -scriHvt9OO+Y9bI5mE4nuBFde9IllIiCFSZqGzG7qFshISvYD06fWvGxWuR51jIjK+FTzJlFXHtP -rby/h0oLS5daqPZI7H17Dc0hBt+eFf1Biki3IPShehtX1F1Q/7pn2COZH8g/497/b1t3sWtuuMlk -9+HKQUYOKXHQuSP8yYFfTvdv37+ErXNku7dCjmn21HYdfp2nuFeKUWdy19SouJVUQHMD9ur06/4o -Qnc/nSMbsrY9gBQHTC5P99UKFg29ZkM3fiNDecNAhvVMKdqOmq0NpQSHiB6F4+lT1ZvIiwNjeOvg -GUpuuy9rM2RYk61pv48b74JIxwIDAQABo1EwTzALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQUNQ/INmNe4qPs+TtmFc5RUuORmj0wEAYJKwYBBAGCNxUBBAMCAQAwDQYJKoZI -hvcNAQELBQADggEBAEBM+4eymYGQfp3FsLAmzYh7KzKNbrghcViXfa43FK8+5/ea4n32cZiZBKpD -dHij40lhPnOMTZTg+XHEthYOU3gf1qKHLwI5gSk8rxWYITD+KJAAjNHhy/peyP34EEY7onhCkRd0 -VQreUGdNZtGn//3ZwLWoo4rOZvUPQ82nK1d7Y0Zqqi5S2PTt4W2tKZB4SLrhI6qjiey1q5bAtEui -HZeeevJuQHHfaPFlTc58Bd9TZaml8LGXBHAVRgOY1NK/VLSgWH1Sb9pWJmLU2NuJMW8c8CLC02Ic -Nc1MaRVUGpCY3useX8p3x8uOPUNpnJpY0CQ73xtAln41rYHHTnG6iBM= ------END CERTIFICATE----- - -SZAFIR ROOT CA2 -=============== ------BEGIN CERTIFICATE----- -MIIDcjCCAlqgAwIBAgIUPopdB+xV0jLVt+O2XwHrLdzk1uQwDQYJKoZIhvcNAQELBQAwUTELMAkG -A1UEBhMCUEwxKDAmBgNVBAoMH0tyYWpvd2EgSXpiYSBSb3psaWN6ZW5pb3dhIFMuQS4xGDAWBgNV -BAMMD1NaQUZJUiBST09UIENBMjAeFw0xNTEwMTkwNzQzMzBaFw0zNTEwMTkwNzQzMzBaMFExCzAJ -BgNVBAYTAlBMMSgwJgYDVQQKDB9LcmFqb3dhIEl6YmEgUm96bGljemVuaW93YSBTLkEuMRgwFgYD -VQQDDA9TWkFGSVIgUk9PVCBDQTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC3vD5Q -qEvNQLXOYeeWyrSh2gwisPq1e3YAd4wLz32ohswmUeQgPYUM1ljj5/QqGJ3a0a4m7utT3PSQ1hNK -DJA8w/Ta0o4NkjrcsbH/ON7Dui1fgLkCvUqdGw+0w8LBZwPd3BucPbOw3gAeqDRHu5rr/gsUvTaE -2g0gv/pby6kWIK05YO4vdbbnl5z5Pv1+TW9NL++IDWr63fE9biCloBK0TXC5ztdyO4mTp4CEHCdJ -ckm1/zuVnsHMyAHs6A6KCpbns6aH5db5BSsNl0BwPLqsdVqc1U2dAgrSS5tmS0YHF2Wtn2yIANwi -ieDhZNRnvDF5YTy7ykHNXGoAyDw4jlivAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P -AQH/BAQDAgEGMB0GA1UdDgQWBBQuFqlKGLXLzPVvUPMjX/hd56zwyDANBgkqhkiG9w0BAQsFAAOC -AQEAtXP4A9xZWx126aMqe5Aosk3AM0+qmrHUuOQn/6mWmc5G4G18TKI4pAZw8PRBEew/R40/cof5 -O/2kbytTAOD/OblqBw7rHRz2onKQy4I9EYKL0rufKq8h5mOGnXkZ7/e7DDWQw4rtTw/1zBLZpD67 -oPwglV9PJi8RI4NOdQcPv5vRtB3pEAT+ymCPoky4rc/hkA/NrgrHXXu3UNLUYfrVFdvXn4dRVOul -4+vJhaAlIDf7js4MNIThPIGyd05DpYhfhmehPea0XGG2Ptv+tyjFogeutcrKjSoS75ftwjCkySp6 -+/NNIxuZMzSgLvWpCz/UXeHPhJ/iGcJfitYgHuNztw== ------END CERTIFICATE----- - -Certum Trusted Network CA 2 -=========================== ------BEGIN CERTIFICATE----- -MIIF0jCCA7qgAwIBAgIQIdbQSk8lD8kyN/yqXhKN6TANBgkqhkiG9w0BAQ0FADCBgDELMAkGA1UE -BhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAlBgNVBAsTHkNlcnR1 -bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMbQ2VydHVtIFRydXN0ZWQgTmV0d29y -ayBDQSAyMCIYDzIwMTExMDA2MDgzOTU2WhgPMjA0NjEwMDYwODM5NTZaMIGAMQswCQYDVQQGEwJQ -TDEiMCAGA1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENl -cnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBOZXR3b3JrIENB -IDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9+Xj45tWADGSdhhuWZGc/IjoedQF9 -7/tcZ4zJzFxrqZHmuULlIEub2pt7uZld2ZuAS9eEQCsn0+i6MLs+CRqnSZXvK0AkwpfHp+6bJe+o -CgCXhVqqndwpyeI1B+twTUrWwbNWuKFBOJvR+zF/j+Bf4bE/D44WSWDXBo0Y+aomEKsq09DRZ40b -Rr5HMNUuctHFY9rnY3lEfktjJImGLjQ/KUxSiyqnwOKRKIm5wFv5HdnnJ63/mgKXwcZQkpsCLL2p -uTRZCr+ESv/f/rOf69me4Jgj7KZrdxYq28ytOxykh9xGc14ZYmhFV+SQgkK7QtbwYeDBoz1mo130 -GO6IyY0XRSmZMnUCMe4pJshrAua1YkV/NxVaI2iJ1D7eTiew8EAMvE0Xy02isx7QBlrd9pPPV3WZ -9fqGGmd4s7+W/jTcvedSVuWz5XV710GRBdxdaeOVDUO5/IOWOZV7bIBaTxNyxtd9KXpEulKkKtVB -Rgkg/iKgtlswjbyJDNXXcPiHUv3a76xRLgezTv7QCdpw75j6VuZt27VXS9zlLCUVyJ4ueE742pye -hizKV/Ma5ciSixqClnrDvFASadgOWkaLOusm+iPJtrCBvkIApPjW/jAux9JG9uWOdf3yzLnQh1vM -BhBgu4M1t15n3kfsmUjxpKEV/q2MYo45VU85FrmxY53/twIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MB0GA1UdDgQWBBS2oVQ5AsOgP46KvPrU+Bym0ToO/TAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI -hvcNAQENBQADggIBAHGlDs7k6b8/ONWJWsQCYftMxRQXLYtPU2sQF/xlhMcQSZDe28cmk4gmb3DW -Al45oPePq5a1pRNcgRRtDoGCERuKTsZPpd1iHkTfCVn0W3cLN+mLIMb4Ck4uWBzrM9DPhmDJ2vuA -L55MYIR4PSFk1vtBHxgP58l1cb29XN40hz5BsA72udY/CROWFC/emh1auVbONTqwX3BNXuMp8SMo -clm2q8KMZiYcdywmdjWLKKdpoPk79SPdhRB0yZADVpHnr7pH1BKXESLjokmUbOe3lEu6LaTaM4tM -pkT/WjzGHWTYtTHkpjx6qFcL2+1hGsvxznN3Y6SHb0xRONbkX8eftoEq5IVIeVheO/jbAoJnwTnb -w3RLPTYe+SmTiGhbqEQZIfCn6IENLOiTNrQ3ssqwGyZ6miUfmpqAnksqP/ujmv5zMnHCnsZy4Ypo -J/HkD7TETKVhk/iXEAcqMCWpuchxuO9ozC1+9eB+D4Kob7a6bINDd82Kkhehnlt4Fj1F4jNy3eFm -ypnTycUm/Q1oBEauttmbjL4ZvrHG8hnjXALKLNhvSgfZyTXaQHXyxKcZb55CEJh15pWLYLztxRLX -is7VmFxWlgPF7ncGNf/P5O4/E2Hu29othfDNrp2yGAlFw5Khchf8R7agCyzxxN5DaAhqXzvwdmP7 -zAYspsbiDrW5viSP ------END CERTIFICATE----- - -Hellenic Academic and Research Institutions RootCA 2015 -======================================================= ------BEGIN CERTIFICATE----- -MIIGCzCCA/OgAwIBAgIBADANBgkqhkiG9w0BAQsFADCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcT -BkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0 -aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNVBAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNl -YXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIwMTUwHhcNMTUwNzA3MTAxMTIxWhcNNDAwNjMwMTAx -MTIxWjCBpjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0aGVuczFEMEIGA1UEChM7SGVsbGVuaWMg -QWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBDZXJ0LiBBdXRob3JpdHkxQDA+BgNV -BAMTN0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgUm9vdENBIDIw -MTUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDC+Kk/G4n8PDwEXT2QNrCROnk8Zlrv -bTkBSRq0t89/TSNTt5AA4xMqKKYx8ZEA4yjsriFBzh/a/X0SWwGDD7mwX5nh8hKDgE0GPt+sr+eh -iGsxr/CL0BgzuNtFajT0AoAkKAoCFZVedioNmToUW/bLy1O8E00BiDeUJRtCvCLYjqOWXjrZMts+ -6PAQZe104S+nfK8nNLspfZu2zwnI5dMK/IhlZXQK3HMcXM1AsRzUtoSMTFDPaI6oWa7CJ06CojXd -FPQf/7J31Ycvqm59JCfnxssm5uX+Zwdj2EUN3TpZZTlYepKZcj2chF6IIbjV9Cz82XBST3i4vTwr -i5WY9bPRaM8gFH5MXF/ni+X1NYEZN9cRCLdmvtNKzoNXADrDgfgXy5I2XdGj2HUb4Ysn6npIQf1F -GQatJ5lOwXBH3bWfgVMS5bGMSF0xQxfjjMZ6Y5ZLKTBOhE5iGV48zpeQpX8B653g+IuJ3SWYPZK2 -fu/Z8VFRfS0myGlZYeCsargqNhEEelC9MoS+L9xy1dcdFkfkR2YgP/SWxa+OAXqlD3pk9Q0Yh9mu -iNX6hME6wGkoLfINaFGq46V3xqSQDqE3izEjR8EJCOtu93ib14L8hCCZSRm2Ekax+0VVFqmjZayc -Bw/qa9wfLgZy7IaIEuQt218FL+TwA9MmM+eAws1CoRc0CwIDAQABo0IwQDAPBgNVHRMBAf8EBTAD -AQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUcRVnyMjJvXVdctA4GGqd83EkVAswDQYJKoZI -hvcNAQELBQADggIBAHW7bVRLqhBYRjTyYtcWNl0IXtVsyIe9tC5G8jH4fOpCtZMWVdyhDBKg2mF+ -D1hYc2Ryx+hFjtyp8iY/xnmMsVMIM4GwVhO+5lFc2JsKT0ucVlMC6U/2DWDqTUJV6HwbISHTGzrM -d/K4kPFox/la/vot9L/J9UUbzjgQKjeKeaO04wlshYaT/4mWJ3iBj2fjRnRUjtkNaeJK9E10A/+y -d+2VZ5fkscWrv2oj6NSU4kQoYsRL4vDY4ilrGnB+JGGTe08DMiUNRSQrlrRGar9KC/eaj8GsGsVn -82800vpzY4zvFrCopEYq+OsS7HK07/grfoxSwIuEVPkvPuNVqNxmsdnhX9izjFk0WaSrT2y7Hxjb -davYy5LNlDhhDgcGH0tGEPEVvo2FXDtKK4F5D7Rpn0lQl033DlZdwJVqwjbDG2jJ9SrcR5q+ss7F -Jej6A7na+RZukYT1HCjI/CbM1xyQVqdfbzoEvM14iQuODy+jqk+iGxI9FghAD/FGTNeqewjBCvVt -J94Cj8rDtSvK6evIIVM4pcw72Hc3MKJP2W/R8kCtQXoXxdZKNYm3QdV8hn9VTYNKpXMgwDqvkPGa -JI7ZjnHKe7iG2rKPmT4dEw0SEe7Uq/DpFXYC5ODfqiAeW2GFZECpkJcNrVPSWh2HagCXZWK0vm9q -p/UsQu0yrbYhnr68 ------END CERTIFICATE----- - -Hellenic Academic and Research Institutions ECC RootCA 2015 -=========================================================== ------BEGIN CERTIFICATE----- -MIICwzCCAkqgAwIBAgIBADAKBggqhkjOPQQDAjCBqjELMAkGA1UEBhMCR1IxDzANBgNVBAcTBkF0 -aGVuczFEMEIGA1UEChM7SGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u -cyBDZXJ0LiBBdXRob3JpdHkxRDBCBgNVBAMTO0hlbGxlbmljIEFjYWRlbWljIGFuZCBSZXNlYXJj -aCBJbnN0aXR1dGlvbnMgRUNDIFJvb3RDQSAyMDE1MB4XDTE1MDcwNzEwMzcxMloXDTQwMDYzMDEw -MzcxMlowgaoxCzAJBgNVBAYTAkdSMQ8wDQYDVQQHEwZBdGhlbnMxRDBCBgNVBAoTO0hlbGxlbmlj -IEFjYWRlbWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ2VydC4gQXV0aG9yaXR5MUQwQgYD -VQQDEztIZWxsZW5pYyBBY2FkZW1pYyBhbmQgUmVzZWFyY2ggSW5zdGl0dXRpb25zIEVDQyBSb290 -Q0EgMjAxNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABJKgQehLgoRc4vgxEZmGZE4JJS+dQS8KrjVP -dJWyUWRrjWvmP3CV8AVER6ZyOFB2lQJajq4onvktTpnvLEhvTCUp6NFxW98dwXU3tNf6e3pCnGoK -Vlp8aQuqgAkkbH7BRqNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0O -BBYEFLQiC4KZJAEOnLvkDv2/+5cgk5kqMAoGCCqGSM49BAMCA2cAMGQCMGfOFmI4oqxiRaeplSTA -GiecMjvAwNW6qef4BENThe5SId6d9SWDPp5YSy/XZxMOIQIwBeF1Ad5o7SofTUwJCA3sS61kFyjn -dc5FZXIhF8siQQ6ME5g4mlRtm8rifOoCWCKR ------END CERTIFICATE----- - -ISRG Root X1 -============ ------BEGIN CERTIFICATE----- -MIIFazCCA1OgAwIBAgIRAIIQz7DSQONZRGPgu2OCiwAwDQYJKoZIhvcNAQELBQAwTzELMAkGA1UE -BhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2VhcmNoIEdyb3VwMRUwEwYDVQQD -EwxJU1JHIFJvb3QgWDEwHhcNMTUwNjA0MTEwNDM4WhcNMzUwNjA0MTEwNDM4WjBPMQswCQYDVQQG -EwJVUzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMT -DElTUkcgUm9vdCBYMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK3oJHP0FDfzm54r -Vygch77ct984kIxuPOZXoHj3dcKi/vVqbvYATyjb3miGbESTtrFj/RQSa78f0uoxmyF+0TM8ukj1 -3Xnfs7j/EvEhmkvBioZxaUpmZmyPfjxwv60pIgbz5MDmgK7iS4+3mX6UA5/TR5d8mUgjU+g4rk8K -b4Mu0UlXjIB0ttov0DiNewNwIRt18jA8+o+u3dpjq+sWT8KOEUt+zwvo/7V3LvSye0rgTBIlDHCN -Aymg4VMk7BPZ7hm/ELNKjD+Jo2FR3qyHB5T0Y3HsLuJvW5iB4YlcNHlsdu87kGJ55tukmi8mxdAQ -4Q7e2RCOFvu396j3x+UCB5iPNgiV5+I3lg02dZ77DnKxHZu8A/lJBdiB3QW0KtZB6awBdpUKD9jf -1b0SHzUvKBds0pjBqAlkd25HN7rOrFleaJ1/ctaJxQZBKT5ZPt0m9STJEadao0xAH0ahmbWnOlFu -hjuefXKnEgV4We0+UXgVCwOPjdAvBbI+e0ocS3MFEvzG6uBQE3xDk3SzynTnjh8BCNAw1FtxNrQH -usEwMFxIt4I7mKZ9YIqioymCzLq9gwQbooMDQaHWBfEbwrbwqHyGO0aoSCqI3Haadr8faqU9GY/r -OPNk3sgrDQoo//fb4hVC1CLQJ13hef4Y53CIrU7m2Ys6xt0nUW7/vGT1M0NPAgMBAAGjQjBAMA4G -A1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR5tFnme7bl5AFzgAiIyBpY -9umbbjANBgkqhkiG9w0BAQsFAAOCAgEAVR9YqbyyqFDQDLHYGmkgJykIrGF1XIpu+ILlaS/V9lZL -ubhzEFnTIZd+50xx+7LSYK05qAvqFyFWhfFQDlnrzuBZ6brJFe+GnY+EgPbk6ZGQ3BebYhtF8GaV -0nxvwuo77x/Py9auJ/GpsMiu/X1+mvoiBOv/2X/qkSsisRcOj/KKNFtY2PwByVS5uCbMiogziUwt -hDyC3+6WVwW6LLv3xLfHTjuCvjHIInNzktHCgKQ5ORAzI4JMPJ+GslWYHb4phowim57iaztXOoJw -TdwJx4nLCgdNbOhdjsnvzqvHu7UrTkXWStAmzOVyyghqpZXjFaH3pO3JLF+l+/+sKAIuvtd7u+Nx -e5AW0wdeRlN8NwdCjNPElpzVmbUq4JUagEiuTDkHzsxHpFKVK7q4+63SM1N95R1NbdWhscdCb+ZA -JzVcoyi3B43njTOQ5yOf+1CceWxG1bQVs5ZufpsMljq4Ui0/1lvh+wjChP4kqKOJ2qxq4RgqsahD -YVvTH9w7jXbyLeiNdd8XM2w9U/t7y0Ff/9yi0GE44Za4rF2LN9d11TPAmRGunUHBcnWEvgJBQl9n -JEiU0Zsnvgc/ubhPgXRR4Xq37Z0j4r7g1SgEEzwxA57demyPxgcYxn/eR44/KJ4EBs+lVDR3veyJ -m+kXQ99b21/+jh5Xos1AnX5iItreGCc= ------END CERTIFICATE----- - -AC RAIZ FNMT-RCM -================ ------BEGIN CERTIFICATE----- -MIIFgzCCA2ugAwIBAgIPXZONMGc2yAYdGsdUhGkHMA0GCSqGSIb3DQEBCwUAMDsxCzAJBgNVBAYT -AkVTMREwDwYDVQQKDAhGTk1ULVJDTTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTAeFw0wODEw -MjkxNTU5NTZaFw0zMDAxMDEwMDAwMDBaMDsxCzAJBgNVBAYTAkVTMREwDwYDVQQKDAhGTk1ULVJD -TTEZMBcGA1UECwwQQUMgUkFJWiBGTk1ULVJDTTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC -ggIBALpxgHpMhm5/yBNtwMZ9HACXjywMI7sQmkCpGreHiPibVmr75nuOi5KOpyVdWRHbNi63URcf -qQgfBBckWKo3Shjf5TnUV/3XwSyRAZHiItQDwFj8d0fsjz50Q7qsNI1NOHZnjrDIbzAzWHFctPVr -btQBULgTfmxKo0nRIBnuvMApGGWn3v7v3QqQIecaZ5JCEJhfTzC8PhxFtBDXaEAUwED653cXeuYL -j2VbPNmaUtu1vZ5Gzz3rkQUCwJaydkxNEJY7kvqcfw+Z374jNUUeAlz+taibmSXaXvMiwzn15Cou -08YfxGyqxRxqAQVKL9LFwag0Jl1mpdICIfkYtwb1TplvqKtMUejPUBjFd8g5CSxJkjKZqLsXF3mw -WsXmo8RZZUc1g16p6DULmbvkzSDGm0oGObVo/CK67lWMK07q87Hj/LaZmtVC+nFNCM+HHmpxffnT -tOmlcYF7wk5HlqX2doWjKI/pgG6BU6VtX7hI+cL5NqYuSf+4lsKMB7ObiFj86xsc3i1w4peSMKGJ -47xVqCfWS+2QrYv6YyVZLag13cqXM7zlzced0ezvXg5KkAYmY6252TUtB7p2ZSysV4999AeU14EC -ll2jB0nVetBX+RvnU0Z1qrB5QstocQjpYL05ac70r8NWQMetUqIJ5G+GR4of6ygnXYMgrwTJbFaa -i0b1AgMBAAGjgYMwgYAwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYE -FPd9xf3E6Jobd2Sn9R2gzL+HYJptMD4GA1UdIAQ3MDUwMwYEVR0gADArMCkGCCsGAQUFBwIBFh1o -dHRwOi8vd3d3LmNlcnQuZm5tdC5lcy9kcGNzLzANBgkqhkiG9w0BAQsFAAOCAgEAB5BK3/MjTvDD -nFFlm5wioooMhfNzKWtN/gHiqQxjAb8EZ6WdmF/9ARP67Jpi6Yb+tmLSbkyU+8B1RXxlDPiyN8+s -D8+Nb/kZ94/sHvJwnvDKuO+3/3Y3dlv2bojzr2IyIpMNOmqOFGYMLVN0V2Ue1bLdI4E7pWYjJ2cJ -j+F3qkPNZVEI7VFY/uY5+ctHhKQV8Xa7pO6kO8Rf77IzlhEYt8llvhjho6Tc+hj507wTmzl6NLrT -Qfv6MooqtyuGC2mDOL7Nii4LcK2NJpLuHvUBKwrZ1pebbuCoGRw6IYsMHkCtA+fdZn71uSANA+iW -+YJF1DngoABd15jmfZ5nc8OaKveri6E6FO80vFIOiZiaBECEHX5FaZNXzuvO+FB8TxxuBEOb+dY7 -Ixjp6o7RTUaN8Tvkasq6+yO3m/qZASlaWFot4/nUbQ4mrcFuNLwy+AwF+mWj2zs3gyLp1txyM/1d -8iC9djwj2ij3+RvrWWTV3F9yfiD8zYm1kGdNYno/Tq0dwzn+evQoFt9B9kiABdcPUXmsEKvU7ANm -5mqwujGSQkBqvjrTcuFqN1W8rB2Vt2lh8kORdOag0wokRqEIr9baRRmW1FMdW4R58MD3R++Lj8UG -rp1MYp3/RgT408m2ECVAdf4WqslKYIYvuu8wd+RU4riEmViAqhOLUTpPSPaLtrM= ------END CERTIFICATE----- - -Amazon Root CA 1 -================ ------BEGIN CERTIFICATE----- -MIIDQTCCAimgAwIBAgITBmyfz5m/jAo54vB4ikPmljZbyjANBgkqhkiG9w0BAQsFADA5MQswCQYD -VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAxMB4XDTE1 -MDUyNjAwMDAwMFoXDTM4MDExNzAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv -bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC -ggEBALJ4gHHKeNXjca9HgFB0fW7Y14h29Jlo91ghYPl0hAEvrAIthtOgQ3pOsqTQNroBvo3bSMgH -FzZM9O6II8c+6zf1tRn4SWiw3te5djgdYZ6k/oI2peVKVuRF4fn9tBb6dNqcmzU5L/qwIFAGbHrQ -gLKm+a/sRxmPUDgH3KKHOVj4utWp+UhnMJbulHheb4mjUcAwhmahRWa6VOujw5H5SNz/0egwLX0t -dHA114gk957EWW67c4cX8jJGKLhD+rcdqsq08p8kDi1L93FcXmn/6pUCyziKrlA4b9v7LWIbxcce -VOF34GfID5yHI9Y/QCB/IIDEgEw+OyQmjgSubJrIqg0CAwEAAaNCMEAwDwYDVR0TAQH/BAUwAwEB -/zAOBgNVHQ8BAf8EBAMCAYYwHQYDVR0OBBYEFIQYzIU07LwMlJQuCFmcx7IQTgoIMA0GCSqGSIb3 -DQEBCwUAA4IBAQCY8jdaQZChGsV2USggNiMOruYou6r4lK5IpDB/G/wkjUu0yKGX9rbxenDIU5PM -CCjjmCXPI6T53iHTfIUJrU6adTrCC2qJeHZERxhlbI1Bjjt/msv0tadQ1wUsN+gDS63pYaACbvXy -8MWy7Vu33PqUXHeeE6V/Uq2V8viTO96LXFvKWlJbYK8U90vvo/ufQJVtMVT8QtPHRh8jrdkPSHCa -2XV4cdFyQzR1bldZwgJcJmApzyMZFo6IQ6XU5MsI+yMRQ+hDKXJioaldXgjUkK642M4UwtBV8ob2 -xJNDd2ZhwLnoQdeXeGADbkpyrqXRfboQnoZsG4q5WTP468SQvvG5 ------END CERTIFICATE----- - -Amazon Root CA 2 -================ ------BEGIN CERTIFICATE----- -MIIFQTCCAymgAwIBAgITBmyf0pY1hp8KD+WGePhbJruKNzANBgkqhkiG9w0BAQwFADA5MQswCQYD -VQQGEwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAyMB4XDTE1 -MDUyNjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpv -bjEZMBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC -ggIBAK2Wny2cSkxKgXlRmeyKy2tgURO8TW0G/LAIjd0ZEGrHJgw12MBvIITplLGbhQPDW9tK6Mj4 -kHbZW0/jTOgGNk3Mmqw9DJArktQGGWCsN0R5hYGCrVo34A3MnaZMUnbqQ523BNFQ9lXg1dKmSYXp -N+nKfq5clU1Imj+uIFptiJXZNLhSGkOQsL9sBbm2eLfq0OQ6PBJTYv9K8nu+NQWpEjTj82R0Yiw9 -AElaKP4yRLuH3WUnAnE72kr3H9rN9yFVkE8P7K6C4Z9r2UXTu/Bfh+08LDmG2j/e7HJV63mjrdvd -fLC6HM783k81ds8P+HgfajZRRidhW+mez/CiVX18JYpvL7TFz4QuK/0NURBs+18bvBt+xa47mAEx -kv8LV/SasrlX6avvDXbR8O70zoan4G7ptGmh32n2M8ZpLpcTnqWHsFcQgTfJU7O7f/aS0ZzQGPSS -btqDT6ZjmUyl+17vIWR6IF9sZIUVyzfpYgwLKhbcAS4y2j5L9Z469hdAlO+ekQiG+r5jqFoz7Mt0 -Q5X5bGlSNscpb/xVA1wf+5+9R+vnSUeVC06JIglJ4PVhHvG/LopyboBZ/1c6+XUyo05f7O0oYtlN -c/LMgRdg7c3r3NunysV+Ar3yVAhU/bQtCSwXVEqY0VThUWcI0u1ufm8/0i2BWSlmy5A5lREedCf+ -3euvAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSw -DPBMMPQFWAJI/TPlUq9LhONmUjANBgkqhkiG9w0BAQwFAAOCAgEAqqiAjw54o+Ci1M3m9Zh6O+oA -A7CXDpO8Wqj2LIxyh6mx/H9z/WNxeKWHWc8w4Q0QshNabYL1auaAn6AFC2jkR2vHat+2/XcycuUY -+gn0oJMsXdKMdYV2ZZAMA3m3MSNjrXiDCYZohMr/+c8mmpJ5581LxedhpxfL86kSk5Nrp+gvU5LE -YFiwzAJRGFuFjWJZY7attN6a+yb3ACfAXVU3dJnJUH/jWS5E4ywl7uxMMne0nxrpS10gxdr9HIcW -xkPo1LsmmkVwXqkLN1PiRnsn/eBG8om3zEK2yygmbtmlyTrIQRNg91CMFa6ybRoVGld45pIq2WWQ -gj9sAq+uEjonljYE1x2igGOpm/HlurR8FLBOybEfdF849lHqm/osohHUqS0nGkWxr7JOcQ3AWEbW -aQbLU8uz/mtBzUF+fUwPfHJ5elnNXkoOrJupmHN5fLT0zLm4BwyydFy4x2+IoZCn9Kr5v2c69BoV -Yh63n749sSmvZ6ES8lgQGVMDMBu4Gon2nL2XA46jCfMdiyHxtN/kHNGfZQIG6lzWE7OE76KlXIx3 -KadowGuuQNKotOrN8I1LOJwZmhsoVLiJkO/KdYE+HvJkJMcYr07/R54H9jVlpNMKVv/1F2Rs76gi -JUmTtt8AF9pYfl3uxRuw0dFfIRDH+fO6AgonB8Xx1sfT4PsJYGw= ------END CERTIFICATE----- - -Amazon Root CA 3 -================ ------BEGIN CERTIFICATE----- -MIIBtjCCAVugAwIBAgITBmyf1XSXNmY/Owua2eiedgPySjAKBggqhkjOPQQDAjA5MQswCQYDVQQG -EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSAzMB4XDTE1MDUy -NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ -MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCmXp8ZB -f8ANm+gBG1bG8lKlui2yEujSLtf6ycXYqm0fc4E7O5hrOXwzpcVOho6AF2hiRVd9RFgdszflZwjr -Zt6jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBSrttvXBp43 -rDCGB5Fwx5zEGbF4wDAKBggqhkjOPQQDAgNJADBGAiEA4IWSoxe3jfkrBqWTrBqYaGFy+uGh0Psc -eGCmQ5nFuMQCIQCcAu/xlJyzlvnrxir4tiz+OpAUFteMYyRIHN8wfdVoOw== ------END CERTIFICATE----- - -Amazon Root CA 4 -================ ------BEGIN CERTIFICATE----- -MIIB8jCCAXigAwIBAgITBmyf18G7EEwpQ+Vxe3ssyBrBDjAKBggqhkjOPQQDAzA5MQswCQYDVQQG -EwJVUzEPMA0GA1UEChMGQW1hem9uMRkwFwYDVQQDExBBbWF6b24gUm9vdCBDQSA0MB4XDTE1MDUy -NjAwMDAwMFoXDTQwMDUyNjAwMDAwMFowOTELMAkGA1UEBhMCVVMxDzANBgNVBAoTBkFtYXpvbjEZ -MBcGA1UEAxMQQW1hem9uIFJvb3QgQ0EgNDB2MBAGByqGSM49AgEGBSuBBAAiA2IABNKrijdPo1MN -/sGKe0uoe0ZLY7Bi9i0b2whxIdIA6GO9mif78DluXeo9pcmBqqNbIJhFXRbb/egQbeOc4OO9X4Ri -83BkM6DLJC9wuoihKqB1+IGuYgbEgds5bimwHvouXKNCMEAwDwYDVR0TAQH/BAUwAwEB/zAOBgNV -HQ8BAf8EBAMCAYYwHQYDVR0OBBYEFNPsxzplbszh2naaVvuc84ZtV+WBMAoGCCqGSM49BAMDA2gA -MGUCMDqLIfG9fhGt0O9Yli/W651+kI0rz2ZVwyzjKKlwCkcO8DdZEv8tmZQoTipPNU0zWgIxAOp1 -AE47xDqUEpHJWEadIRNyp4iciuRMStuW1KyLa2tJElMzrdfkviT8tQp21KW8EA== ------END CERTIFICATE----- - -TUBITAK Kamu SM SSL Kok Sertifikasi - Surum 1 -============================================= ------BEGIN CERTIFICATE----- -MIIEYzCCA0ugAwIBAgIBATANBgkqhkiG9w0BAQsFADCB0jELMAkGA1UEBhMCVFIxGDAWBgNVBAcT -D0dlYnplIC0gS29jYWVsaTFCMEAGA1UEChM5VHVya2l5ZSBCaWxpbXNlbCB2ZSBUZWtub2xvamlr -IEFyYXN0aXJtYSBLdXJ1bXUgLSBUVUJJVEFLMS0wKwYDVQQLEyRLYW11IFNlcnRpZmlrYXN5b24g -TWVya2V6aSAtIEthbXUgU00xNjA0BgNVBAMTLVRVQklUQUsgS2FtdSBTTSBTU0wgS29rIFNlcnRp -ZmlrYXNpIC0gU3VydW0gMTAeFw0xMzExMjUwODI1NTVaFw00MzEwMjUwODI1NTVaMIHSMQswCQYD -VQQGEwJUUjEYMBYGA1UEBxMPR2ViemUgLSBLb2NhZWxpMUIwQAYDVQQKEzlUdXJraXllIEJpbGlt -c2VsIHZlIFRla25vbG9qaWsgQXJhc3Rpcm1hIEt1cnVtdSAtIFRVQklUQUsxLTArBgNVBAsTJEth -bXUgU2VydGlmaWthc3lvbiBNZXJrZXppIC0gS2FtdSBTTTE2MDQGA1UEAxMtVFVCSVRBSyBLYW11 -IFNNIFNTTCBLb2sgU2VydGlmaWthc2kgLSBTdXJ1bSAxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A -MIIBCgKCAQEAr3UwM6q7a9OZLBI3hNmNe5eA027n/5tQlT6QlVZC1xl8JoSNkvoBHToP4mQ4t4y8 -6Ij5iySrLqP1N+RAjhgleYN1Hzv/bKjFxlb4tO2KRKOrbEz8HdDc72i9z+SqzvBV96I01INrN3wc -wv61A+xXzry0tcXtAA9TNypN9E8Mg/uGz8v+jE69h/mniyFXnHrfA2eJLJ2XYacQuFWQfw4tJzh0 -3+f92k4S400VIgLI4OD8D62K18lUUMw7D8oWgITQUVbDjlZ/iSIzL+aFCr2lqBs23tPcLG07xxO9 -WSMs5uWk99gL7eqQQESolbuT1dCANLZGeA4fAJNG4e7p+exPFwIDAQABo0IwQDAdBgNVHQ4EFgQU -ZT/HiobGPN08VFw1+DrtUgxHV8gwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJ -KoZIhvcNAQELBQADggEBACo/4fEyjq7hmFxLXs9rHmoJ0iKpEsdeV31zVmSAhHqT5Am5EM2fKifh -AHe+SMg1qIGf5LgsyX8OsNJLN13qudULXjS99HMpw+0mFZx+CFOKWI3QSyjfwbPfIPP54+M638yc -lNhOT8NrF7f3cuitZjO1JVOr4PhMqZ398g26rrnZqsZr+ZO7rqu4lzwDGrpDxpa5RXI4s6ehlj2R -e37AIVNMh+3yC1SVUZPVIqUNivGTDj5UDrDYyU7c8jEyVupk+eq1nRZmQnLzf9OxMUP8pI4X8W0j -q5Rm+K37DwhuJi1/FwcJsoz7UMCflo3Ptv0AnVoUmr8CRPXBwp8iXqIPoeM= ------END CERTIFICATE----- - -GDCA TrustAUTH R5 ROOT -====================== ------BEGIN CERTIFICATE----- -MIIFiDCCA3CgAwIBAgIIfQmX/vBH6nowDQYJKoZIhvcNAQELBQAwYjELMAkGA1UEBhMCQ04xMjAw -BgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZIENPLixMVEQuMR8wHQYDVQQD -DBZHRENBIFRydXN0QVVUSCBSNSBST09UMB4XDTE0MTEyNjA1MTMxNVoXDTQwMTIzMTE1NTk1OVow -YjELMAkGA1UEBhMCQ04xMjAwBgNVBAoMKUdVQU5HIERPTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZ -IENPLixMVEQuMR8wHQYDVQQDDBZHRENBIFRydXN0QVVUSCBSNSBST09UMIICIjANBgkqhkiG9w0B -AQEFAAOCAg8AMIICCgKCAgEA2aMW8Mh0dHeb7zMNOwZ+Vfy1YI92hhJCfVZmPoiC7XJjDp6L3TQs -AlFRwxn9WVSEyfFrs0yw6ehGXTjGoqcuEVe6ghWinI9tsJlKCvLriXBjTnnEt1u9ol2x8kECK62p -OqPseQrsXzrj/e+APK00mxqriCZ7VqKChh/rNYmDf1+uKU49tm7srsHwJ5uu4/Ts765/94Y9cnrr -pftZTqfrlYwiOXnhLQiPzLyRuEH3FMEjqcOtmkVEs7LXLM3GKeJQEK5cy4KOFxg2fZfmiJqwTTQJ -9Cy5WmYqsBebnh52nUpmMUHfP/vFBu8btn4aRjb3ZGM74zkYI+dndRTVdVeSN72+ahsmUPI2JgaQ -xXABZG12ZuGR224HwGGALrIuL4xwp9E7PLOR5G62xDtw8mySlwnNR30YwPO7ng/Wi64HtloPzgsM -R6flPri9fcebNaBhlzpBdRfMK5Z3KpIhHtmVdiBnaM8Nvd/WHwlqmuLMc3GkL30SgLdTMEZeS1SZ -D2fJpcjyIMGC7J0R38IC+xo70e0gmu9lZJIQDSri3nDxGGeCjGHeuLzRL5z7D9Ar7Rt2ueQ5Vfj4 -oR24qoAATILnsn8JuLwwoC8N9VKejveSswoAHQBUlwbgsQfZxw9cZX08bVlX5O2ljelAU58VS6Bx -9hoh49pwBiFYFIeFd3mqgnkCAwEAAaNCMEAwHQYDVR0OBBYEFOLJQJ9NzuiaoXzPDj9lxSmIahlR -MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQDRSVfg -p8xoWLoBDysZzY2wYUWsEe1jUGn4H3++Fo/9nesLqjJHdtJnJO29fDMylyrHBYZmDRd9FBUb1Ov9 -H5r2XpdptxolpAqzkT9fNqyL7FeoPueBihhXOYV0GkLH6VsTX4/5COmSdI31R9KrO9b7eGZONn35 -6ZLpBN79SWP8bfsUcZNnL0dKt7n/HipzcEYwv1ryL3ml4Y0M2fmyYzeMN2WFcGpcWwlyua1jPLHd -+PwyvzeG5LuOmCd+uh8W4XAR8gPfJWIyJyYYMoSf/wA6E7qaTfRPuBRwIrHKK5DOKcFw9C+df/KQ -HtZa37dG/OaG+svgIHZ6uqbL9XzeYqWxi+7egmaKTjowHz+Ay60nugxe19CxVsp3cbK1daFQqUBD -F8Io2c9Si1vIY9RCPqAzekYu9wogRlR+ak8x8YF+QnQ4ZXMn7sZ8uI7XpTrXmKGcjBBV09tL7ECQ -8s1uV9JiDnxXk7Gnbc2dg7sq5+W2O3FYrf3RRbxake5TFW/TRQl1brqQXR4EzzffHqhmsYzmIGrv -/EhOdJhCrylvLmrH+33RZjEizIYAfmaDDEL0vTSSwxrqT8p+ck0LcIymSLumoRT2+1hEmRSuqguT -aaApJUqlyyvdimYHFngVV3Eb7PVHhPOeMTd61X8kreS8/f3MboPoDKi3QWwH3b08hpcv0g== ------END CERTIFICATE----- - -SSL.com Root Certification Authority RSA -======================================== ------BEGIN CERTIFICATE----- -MIIF3TCCA8WgAwIBAgIIeyyb0xaAMpkwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxDjAM -BgNVBAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24x -MTAvBgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBSU0EwHhcNMTYw -MjEyMTczOTM5WhcNNDEwMjEyMTczOTM5WjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx -EDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NM -LmNvbSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IFJTQTCCAiIwDQYJKoZIhvcNAQEBBQAD -ggIPADCCAgoCggIBAPkP3aMrfcvQKv7sZ4Wm5y4bunfh4/WvpOz6Sl2RxFdHaxh3a3by/ZPkPQ/C -Fp4LZsNWlJ4Xg4XOVu/yFv0AYvUiCVToZRdOQbngT0aXqhvIuG5iXmmxX9sqAn78bMrzQdjt0Oj8 -P2FI7bADFB0QDksZ4LtO7IZl/zbzXmcCC52GVWH9ejjt/uIZALdvoVBidXQ8oPrIJZK0bnoix/ge -oeOy3ZExqysdBP+lSgQ36YWkMyv94tZVNHwZpEpox7Ko07fKoZOI68GXvIz5HdkihCR0xwQ9aqkp -k8zruFvh/l8lqjRYyMEjVJ0bmBHDOJx+PYZspQ9AhnwC9FwCTyjLrnGfDzrIM/4RJTXq/LrFYD3Z -fBjVsqnTdXgDciLKOsMf7yzlLqn6niy2UUb9rwPW6mBo6oUWNmuF6R7As93EJNyAKoFBbZQ+yODJ -gUEAnl6/f8UImKIYLEJAs/lvOCdLToD0PYFH4Ih86hzOtXVcUS4cK38acijnALXRdMbX5J+tB5O2 -UzU1/Dfkw/ZdFr4hc96SCvigY2q8lpJqPvi8ZVWb3vUNiSYE/CUapiVpy8JtynziWV+XrOvvLsi8 -1xtZPCvM8hnIk2snYxnP/Okm+Mpxm3+T/jRnhE6Z6/yzeAkzcLpmpnbtG3PrGqUNxCITIJRWCk4s -bE6x/c+cCbqiM+2HAgMBAAGjYzBhMB0GA1UdDgQWBBTdBAkHovV6fVJTEpKV7jiAJQ2mWTAPBgNV -HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFN0ECQei9Xp9UlMSkpXuOIAlDaZZMA4GA1UdDwEB/wQE -AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAIBgRlCn7Jp0cHh5wYfGVcpNxJK1ok1iOMq8bs3AD/CUr -dIWQPXhq9LmLpZc7tRiRux6n+UBbkflVma8eEdBcHadm47GUBwwyOabqG7B52B2ccETjit3E+ZUf -ijhDPwGFpUenPUayvOUiaPd7nNgsPgohyC0zrL/FgZkxdMF1ccW+sfAjRfSda/wZY52jvATGGAsl -u1OJD7OAUN5F7kR/q5R4ZJjT9ijdh9hwZXT7DrkT66cPYakylszeu+1jTBi7qUD3oFRuIIhxdRjq -erQ0cuAjJ3dctpDqhiVAq+8zD8ufgr6iIPv2tS0a5sKFsXQP+8hlAqRSAUfdSSLBv9jra6x+3uxj -MxW3IwiPxg+NQVrdjsW5j+VFP3jbutIbQLH+cU0/4IGiul607BXgk90IH37hVZkLId6Tngr75qNJ -vTYw/ud3sqB1l7UtgYgXZSD32pAAn8lSzDLKNXz1PQ/YK9f1JmzJBjSWFupwWRoyeXkLtoh/D1JI -Pb9s2KJELtFOt3JY04kTlf5Eq/jXixtunLwsoFvVagCvXzfh1foQC5ichucmj87w7G6KVwuA406y -wKBjYZC6VWg3dGq2ktufoYYitmUnDuy2n0Jg5GfCtdpBC8TTi2EbvPofkSvXRAdeuims2cXp71NI -WuuA8ShYIc2wBlX7Jz9TkHCpBB5XJ7k= ------END CERTIFICATE----- - -SSL.com Root Certification Authority ECC -======================================== ------BEGIN CERTIFICATE----- -MIICjTCCAhSgAwIBAgIIdebfy8FoW6gwCgYIKoZIzj0EAwIwfDELMAkGA1UEBhMCVVMxDjAMBgNV -BAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xMTAv -BgNVBAMMKFNTTC5jb20gUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYwMjEy -MTgxNDAzWhcNNDEwMjEyMTgxNDAzWjB8MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMxEDAO -BgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjExMC8GA1UEAwwoU1NMLmNv -bSBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuBBAAiA2IA -BEVuqVDEpiM2nl8ojRfLliJkP9x6jh3MCLOicSS6jkm5BBtHllirLZXI7Z4INcgn64mMU1jrYor+ -8FsPazFSY0E7ic3s7LaNGdM0B9y7xgZ/wkWV7Mt/qCPgCemB+vNH06NjMGEwHQYDVR0OBBYEFILR -hXMw5zUE044CkvvlpNHEIejNMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUgtGFczDnNQTT -jgKS++Wk0cQh6M0wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2cAMGQCMG/n61kRpGDPYbCW -e+0F+S8Tkdzt5fxQaxFGRrMcIQBiu77D5+jNB5n5DQtdcj7EqgIwH7y6C+IwJPt8bYBVCpk+gA0z -5Wajs6O7pdWLjwkspl1+4vAHCGht0nxpbl/f5Wpl ------END CERTIFICATE----- - -SSL.com EV Root Certification Authority RSA R2 -============================================== ------BEGIN CERTIFICATE----- -MIIF6zCCA9OgAwIBAgIIVrYpzTS8ePYwDQYJKoZIhvcNAQELBQAwgYIxCzAJBgNVBAYTAlVTMQ4w -DAYDVQQIDAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9u -MTcwNQYDVQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIy -MB4XDTE3MDUzMTE4MTQzN1oXDTQyMDUzMDE4MTQzN1owgYIxCzAJBgNVBAYTAlVTMQ4wDAYDVQQI -DAVUZXhhczEQMA4GA1UEBwwHSG91c3RvbjEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMTcwNQYD -VQQDDC5TU0wuY29tIEVWIFJvb3QgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkgUlNBIFIyMIICIjAN -BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjzZlQOHWTcDXtOlG2mvqM0fNTPl9fb69LT3w23jh -hqXZuglXaO1XPqDQCEGD5yhBJB/jchXQARr7XnAjssufOePPxU7Gkm0mxnu7s9onnQqG6YE3Bf7w -cXHswxzpY6IXFJ3vG2fThVUCAtZJycxa4bH3bzKfydQ7iEGonL3Lq9ttewkfokxykNorCPzPPFTO -Zw+oz12WGQvE43LrrdF9HSfvkusQv1vrO6/PgN3B0pYEW3p+pKk8OHakYo6gOV7qd89dAFmPZiw+ -B6KjBSYRaZfqhbcPlgtLyEDhULouisv3D5oi53+aNxPN8k0TayHRwMwi8qFG9kRpnMphNQcAb9Zh -CBHqurj26bNg5U257J8UZslXWNvNh2n4ioYSA0e/ZhN2rHd9NCSFg83XqpyQGp8hLH94t2S42Oim -9HizVcuE0jLEeK6jj2HdzghTreyI/BXkmg3mnxp3zkyPuBQVPWKchjgGAGYS5Fl2WlPAApiiECto -RHuOec4zSnaqW4EWG7WK2NAAe15itAnWhmMOpgWVSbooi4iTsjQc2KRVbrcc0N6ZVTsj9CLg+Slm -JuwgUHfbSguPvuUCYHBBXtSuUDkiFCbLsjtzdFVHB3mBOagwE0TlBIqulhMlQg+5U8Sb/M3kHN48 -+qvWBkofZ6aYMBzdLNvcGJVXZsb/XItW9XcCAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV -HSMEGDAWgBT5YLvU49U09rj1BoAlp3PbRmmonjAdBgNVHQ4EFgQU+WC71OPVNPa49QaAJadz20Zp -qJ4wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBWs47LCp1Jjr+kxJG7ZhcFUZh1 -++VQLHqe8RT6q9OKPv+RKY9ji9i0qVQBDb6Thi/5Sm3HXvVX+cpVHBK+Rw82xd9qt9t1wkclf7nx -Y/hoLVUE0fKNsKTPvDxeH3jnpaAgcLAExbf3cqfeIg29MyVGjGSSJuM+LmOW2puMPfgYCdcDzH2G -guDKBAdRUNf/ktUM79qGn5nX67evaOI5JpS6aLe/g9Pqemc9YmeuJeVy6OLk7K4S9ksrPJ/psEDz -OFSz/bdoyNrGj1E8svuR3Bznm53htw1yj+KkxKl4+esUrMZDBcJlOSgYAsOCsp0FvmXtll9ldDz7 -CTUue5wT/RsPXcdtgTpWD8w74a8CLyKsRspGPKAcTNZEtF4uXBVmCeEmKf7GUmG6sXP/wwyc5Wxq -lD8UykAWlYTzWamsX0xhk23RO8yilQwipmdnRC652dKKQbNmC1r7fSOl8hqw/96bg5Qu0T/fkreR -rwU7ZcegbLHNYhLDkBvjJc40vG93drEQw/cFGsDWr3RiSBd3kmmQYRzelYB0VI8YHMPzA9C/pEN1 -hlMYegouCRw2n5H9gooiS9EOUCXdywMMF8mDAAhONU2Ki+3wApRmLER/y5UnlhetCTCstnEXbosX -9hwJ1C07mKVx01QT2WDz9UtmT/rx7iASjbSsV7FFY6GsdqnC+w== ------END CERTIFICATE----- - -SSL.com EV Root Certification Authority ECC -=========================================== ------BEGIN CERTIFICATE----- -MIIClDCCAhqgAwIBAgIILCmcWxbtBZUwCgYIKoZIzj0EAwIwfzELMAkGA1UEBhMCVVMxDjAMBgNV -BAgMBVRleGFzMRAwDgYDVQQHDAdIb3VzdG9uMRgwFgYDVQQKDA9TU0wgQ29ycG9yYXRpb24xNDAy -BgNVBAMMK1NTTC5jb20gRVYgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eSBFQ0MwHhcNMTYw -MjEyMTgxNTIzWhcNNDEwMjEyMTgxNTIzWjB/MQswCQYDVQQGEwJVUzEOMAwGA1UECAwFVGV4YXMx -EDAOBgNVBAcMB0hvdXN0b24xGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjE0MDIGA1UEAwwrU1NM -LmNvbSBFViBSb290IENlcnRpZmljYXRpb24gQXV0aG9yaXR5IEVDQzB2MBAGByqGSM49AgEGBSuB -BAAiA2IABKoSR5CYG/vvw0AHgyBO8TCCogbR8pKGYfL2IWjKAMTH6kMAVIbc/R/fALhBYlzccBYy -3h+Z1MzFB8gIH2EWB1E9fVwHU+M1OIzfzZ/ZLg1KthkuWnBaBu2+8KGwytAJKaNjMGEwHQYDVR0O -BBYEFFvKXuXe0oGqzagtZFG22XKbl+ZPMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUW8pe -5d7SgarNqC1kUbbZcpuX5k8wDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMCA2gAMGUCMQCK5kCJ -N+vp1RPZytRrJPOwPYdGWBrssd9v+1a6cGvHOMzosYxPD/fxZ3YOg9AeUY8CMD32IygmTMZgh5Mm -m7I1HrrW9zzRHM76JTymGoEVW/MSD2zuZYrJh6j5B+BimoxcSg== ------END CERTIFICATE----- - -GlobalSign Root CA - R6 -======================= ------BEGIN CERTIFICATE----- -MIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/RVEwDQYJKoZIhvcNAQEMBQAwTDEgMB4GA1UECxMX -R2xvYmFsU2lnbiBSb290IENBIC0gUjYxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkds -b2JhbFNpZ24wHhcNMTQxMjEwMDAwMDAwWhcNMzQxMjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9i -YWxTaWduIFJvb3QgQ0EgLSBSNjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFs -U2lnbjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH6HPKZvnsFMp7PPcNCPG0RQss -grRIxutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay/xTOURQh7ErdG1rG1ofuTToVBu1kZguSgMpE -3nOUTvOniX9PeGMIyBJQbUJmL025eShNUhqKGoC3GYEOfsSKvGRMIRxDaNc9PIrFsmbVkJq3MQbF -vuJtMgamHvm566qjuL++gmNQ0PAYid/kD3n16qIfKtJwLnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqM -PKq0pPbzlUoSB239jLKJz9CgYXfIWHSw1CM69106yqLbnQneXUQtkPGBzVeS+n68UARjNN9rkxi+ -azayOeSsJDa38O+2HBNXk7besvjihbdzorg1qkXy4J02oW9UivFyVm4uiMVRQkQVlO6jxTiWm05O -WgtH8wY2SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQCTXTAFO39OfuD8l4UoQSwC+n+7o/hbguy -CLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdwgQqomnUdnjqGBQCe24DWJfncBZ4nWUx2OVvq+aWh2IMP -0f/fMBH5hc8zSPXKbWQULHpYT9NLCEnFlWQaYw55PfWzjMpYrZxCRXluDocZXFSxZba/jJvcE+kN -b7gu3GduyYsRtYQUigAZcIN5kZeR1BonvzceMgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB/wQE -AwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzWx/B/yGdToDAfBgNV -HSMEGDAWgBSubAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG9w0BAQwFAAOCAgEAgyXt6NH9lVLN -nsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8AorRbrcWc+ZfwFSY1XS+wc3iEZGtIxg93eFyRJa0 -lV7Ae46ZeBZDE1ZXs6KzO7V33EByrKPrmzU+sQghoefEQzd5Mr6155wsTLxDKZmOMNOsIeDjHfrY -BzN2VAAiKrlNIC5waNrlU/yDXNOd8v9EDERm8tLjvUYAGm0CuiVdjaExUd1URhxN25mW7xocBFym -Fe944Hn+Xds+qkxV/ZoVqW/hpvvfcDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54NMMl+68KnyBr -3TsTjxKM4kEaSHpzoHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA/iU3/gKbaKxCXcPu9czc8FB1 -0jZpnOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HHTOwY3WzvUy2MmeFe8nI+z1TIvWfspA9MRf/T -uTAjB0yPEL+GltmZWrSZVxykzLsViVO6LAUP5MSeGbEYNNVMnbrt9x+vJJUEeKgDu+6B5dpffItK -oZB0JaezPkvILFa9x8jvOOJckvB595yEunQtYQEgfn7R8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+t -JDfLRVpOoERIyNiwmcUVhAn21klJwGW45hpxbqCo8YLoRT5s1gLXCmeDBVrJpBA= ------END CERTIFICATE----- - -OISTE WISeKey Global Root GC CA -=============================== ------BEGIN CERTIFICATE----- -MIICaTCCAe+gAwIBAgIQISpWDK7aDKtARb8roi066jAKBggqhkjOPQQDAzBtMQswCQYDVQQGEwJD -SDEQMA4GA1UEChMHV0lTZUtleTEiMCAGA1UECxMZT0lTVEUgRm91bmRhdGlvbiBFbmRvcnNlZDEo -MCYGA1UEAxMfT0lTVEUgV0lTZUtleSBHbG9iYWwgUm9vdCBHQyBDQTAeFw0xNzA1MDkwOTQ4MzRa -Fw00MjA1MDkwOTU4MzNaMG0xCzAJBgNVBAYTAkNIMRAwDgYDVQQKEwdXSVNlS2V5MSIwIAYDVQQL -ExlPSVNURSBGb3VuZGF0aW9uIEVuZG9yc2VkMSgwJgYDVQQDEx9PSVNURSBXSVNlS2V5IEdsb2Jh -bCBSb290IEdDIENBMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAETOlQwMYPchi82PG6s4nieUqjFqdr -VCTbUf/q9Akkwwsin8tqJ4KBDdLArzHkdIJuyiXZjHWd8dvQmqJLIX4Wp2OQ0jnUsYd4XxiWD1Ab -NTcPasbc2RNNpI6QN+a9WzGRo1QwUjAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAd -BgNVHQ4EFgQUSIcUrOPDnpBgOtfKie7TrYy0UGYwEAYJKwYBBAGCNxUBBAMCAQAwCgYIKoZIzj0E -AwMDaAAwZQIwJsdpW9zV57LnyAyMjMPdeYwbY9XJUpROTYJKcx6ygISpJcBMWm1JKWB4E+J+SOtk -AjEA2zQgMgj/mkkCtojeFK9dbJlxjRo/i9fgojaGHAeCOnZT/cKi7e97sIBPWA9LUzm9 ------END CERTIFICATE----- - -UCA Global G2 Root -================== ------BEGIN CERTIFICATE----- -MIIFRjCCAy6gAwIBAgIQXd+x2lqj7V2+WmUgZQOQ7zANBgkqhkiG9w0BAQsFADA9MQswCQYDVQQG -EwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxGzAZBgNVBAMMElVDQSBHbG9iYWwgRzIgUm9vdDAeFw0x -NjAzMTEwMDAwMDBaFw00MDEyMzEwMDAwMDBaMD0xCzAJBgNVBAYTAkNOMREwDwYDVQQKDAhVbmlU -cnVzdDEbMBkGA1UEAwwSVUNBIEdsb2JhbCBHMiBSb290MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A -MIICCgKCAgEAxeYrb3zvJgUno4Ek2m/LAfmZmqkywiKHYUGRO8vDaBsGxUypK8FnFyIdK+35KYmT -oni9kmugow2ifsqTs6bRjDXVdfkX9s9FxeV67HeToI8jrg4aA3++1NDtLnurRiNb/yzmVHqUwCoV -8MmNsHo7JOHXaOIxPAYzRrZUEaalLyJUKlgNAQLx+hVRZ2zA+te2G3/RVogvGjqNO7uCEeBHANBS -h6v7hn4PJGtAnTRnvI3HLYZveT6OqTwXS3+wmeOwcWDcC/Vkw85DvG1xudLeJ1uK6NjGruFZfc8o -LTW4lVYa8bJYS7cSN8h8s+1LgOGN+jIjtm+3SJUIsUROhYw6AlQgL9+/V087OpAh18EmNVQg7Mc/ -R+zvWr9LesGtOxdQXGLYD0tK3Cv6brxzks3sx1DoQZbXqX5t2Okdj4q1uViSukqSKwxW/YDrCPBe -KW4bHAyvj5OJrdu9o54hyokZ7N+1wxrrFv54NkzWbtA+FxyQF2smuvt6L78RHBgOLXMDj6DlNaBa -4kx1HXHhOThTeEDMg5PXCp6dW4+K5OXgSORIskfNTip1KnvyIvbJvgmRlld6iIis7nCs+dwp4wwc -OxJORNanTrAmyPPZGpeRaOrvjUYG0lZFWJo8DA+DuAUlwznPO6Q0ibd5Ei9Hxeepl2n8pndntd97 -8XplFeRhVmUCAwEAAaNCMEAwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0O -BBYEFIHEjMz15DD/pQwIX4wVZyF0Ad/fMA0GCSqGSIb3DQEBCwUAA4ICAQATZSL1jiutROTL/7lo -5sOASD0Ee/ojL3rtNtqyzm325p7lX1iPyzcyochltq44PTUbPrw7tgTQvPlJ9Zv3hcU2tsu8+Mg5 -1eRfB70VVJd0ysrtT7q6ZHafgbiERUlMjW+i67HM0cOU2kTC5uLqGOiiHycFutfl1qnN3e92mI0A -Ds0b+gO3joBYDic/UvuUospeZcnWhNq5NXHzJsBPd+aBJ9J3O5oUb3n09tDh05S60FdRvScFDcH9 -yBIw7m+NESsIndTUv4BFFJqIRNow6rSn4+7vW4LVPtateJLbXDzz2K36uGt/xDYotgIVilQsnLAX -c47QN6MUPJiVAAwpBVueSUmxX8fjy88nZY41F7dXyDDZQVu5FLbowg+UMaeUmMxq67XhJ/UQqAHo -jhJi6IjMtX9Gl8CbEGY4GjZGXyJoPd/JxhMnq1MGrKI8hgZlb7F+sSlEmqO6SWkoaY/X5V+tBIZk -bxqgDMUIYs6Ao9Dz7GjevjPHF1t/gMRMTLGmhIrDO7gJzRSBuhjjVFc2/tsvfEehOjPI+Vg7RE+x -ygKJBJYoaMVLuCaJu9YzL1DV/pqJuhgyklTGW+Cd+V7lDSKb9triyCGyYiGqhkCyLmTTX8jjfhFn -RR8F/uOi77Oos/N9j/gMHyIfLXC0uAE0djAA5SN4p1bXUB+K+wb1whnw0A== ------END CERTIFICATE----- - -UCA Extended Validation Root -============================ ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgIQT9Irj/VkyDOeTzRYZiNwYDANBgkqhkiG9w0BAQsFADBHMQswCQYDVQQG -EwJDTjERMA8GA1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9u -IFJvb3QwHhcNMTUwMzEzMDAwMDAwWhcNMzgxMjMxMDAwMDAwWjBHMQswCQYDVQQGEwJDTjERMA8G -A1UECgwIVW5pVHJ1c3QxJTAjBgNVBAMMHFVDQSBFeHRlbmRlZCBWYWxpZGF0aW9uIFJvb3QwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCpCQcoEwKwmeBkqh5DFnpzsZGgdT6o+uM4AHrs -iWogD4vFsJszA1qGxliG1cGFu0/GnEBNyr7uaZa4rYEwmnySBesFK5pI0Lh2PpbIILvSsPGP2KxF -Rv+qZ2C0d35qHzwaUnoEPQc8hQ2E0B92CvdqFN9y4zR8V05WAT558aopO2z6+I9tTcg1367r3CTu -eUWnhbYFiN6IXSV8l2RnCdm/WhUFhvMJHuxYMjMR83dksHYf5BA1FxvyDrFspCqjc/wJHx4yGVMR -59mzLC52LqGj3n5qiAno8geK+LLNEOfic0CTuwjRP+H8C5SzJe98ptfRr5//lpr1kXuYC3fUfugH -0mK1lTnj8/FtDw5lhIpjVMWAtuCeS31HJqcBCF3RiJ7XwzJE+oJKCmhUfzhTA8ykADNkUVkLo4KR -el7sFsLzKuZi2irbWWIQJUoqgQtHB0MGcIfS+pMRKXpITeuUx3BNr2fVUbGAIAEBtHoIppB/TuDv -B0GHr2qlXov7z1CymlSvw4m6WC31MJixNnI5fkkE/SmnTHnkBVfblLkWU41Gsx2VYVdWf6/wFlth -WG82UBEL2KwrlRYaDh8IzTY0ZRBiZtWAXxQgXy0MoHgKaNYs1+lvK9JKBZP8nm9rZ/+I8U6laUpS -NwXqxhaN0sSZ0YIrO7o1dfdRUVjzyAfd5LQDfwIDAQABo0IwQDAdBgNVHQ4EFgQU2XQ65DA9DfcS -3H5aBZ8eNJr34RQwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQEL -BQADggIBADaNl8xCFWQpN5smLNb7rhVpLGsaGvdftvkHTFnq88nIua7Mui563MD1sC3AO6+fcAUR -ap8lTwEpcOPlDOHqWnzcSbvBHiqB9RZLcpHIojG5qtr8nR/zXUACE/xOHAbKsxSQVBcZEhrxH9cM -aVr2cXj0lH2RC47skFSOvG+hTKv8dGT9cZr4QQehzZHkPJrgmzI5c6sq1WnIeJEmMX3ixzDx/BR4 -dxIOE/TdFpS/S2d7cFOFyrC78zhNLJA5wA3CXWvp4uXViI3WLL+rG761KIcSF3Ru/H38j9CHJrAb -+7lsq+KePRXBOy5nAliRn+/4Qh8st2j1da3Ptfb/EX3C8CSlrdP6oDyp+l3cpaDvRKS+1ujl5BOW -F3sGPjLtx7dCvHaj2GU4Kzg1USEODm8uNBNA4StnDG1KQTAYI1oyVZnJF+A83vbsea0rWBmirSwi -GpWOvpaQXUJXxPkUAzUrHC1RVwinOt4/5Mi0A3PCwSaAuwtCH60NryZy2sy+s6ODWA2CxR9GUeOc -GMyNm43sSet1UNWMKFnKdDTajAshqx7qG+XH/RU+wBeq+yNuJkbL+vmxcmtpzyKEC2IPrNkZAJSi -djzULZrtBJ4tBmIQN1IchXIbJ+XMxjHsN+xjWZsLHXbMfjKaiJUINlK73nZfdklJrX+9ZSCyycEr -dhh2n1ax ------END CERTIFICATE----- - -Certigna Root CA -================ ------BEGIN CERTIFICATE----- -MIIGWzCCBEOgAwIBAgIRAMrpG4nxVQMNo+ZBbcTjpuEwDQYJKoZIhvcNAQELBQAwWjELMAkGA1UE -BhMCRlIxEjAQBgNVBAoMCURoaW15b3RpczEcMBoGA1UECwwTMDAwMiA0ODE0NjMwODEwMDAzNjEZ -MBcGA1UEAwwQQ2VydGlnbmEgUm9vdCBDQTAeFw0xMzEwMDEwODMyMjdaFw0zMzEwMDEwODMyMjda -MFoxCzAJBgNVBAYTAkZSMRIwEAYDVQQKDAlEaGlteW90aXMxHDAaBgNVBAsMEzAwMDIgNDgxNDYz -MDgxMDAwMzYxGTAXBgNVBAMMEENlcnRpZ25hIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4IC -DwAwggIKAoICAQDNGDllGlmx6mQWDoyUJJV8g9PFOSbcDO8WV43X2KyjQn+Cyu3NW9sOty3tRQgX -stmzy9YXUnIo245Onoq2C/mehJpNdt4iKVzSs9IGPjA5qXSjklYcoW9MCiBtnyN6tMbaLOQdLNyz -KNAT8kxOAkmhVECe5uUFoC2EyP+YbNDrihqECB63aCPuI9Vwzm1RaRDuoXrC0SIxwoKF0vJVdlB8 -JXrJhFwLrN1CTivngqIkicuQstDuI7pmTLtipPlTWmR7fJj6o0ieD5Wupxj0auwuA0Wv8HT4Ks16 -XdG+RCYyKfHx9WzMfgIhC59vpD++nVPiz32pLHxYGpfhPTc3GGYo0kDFUYqMwy3OU4gkWGQwFsWq -4NYKpkDfePb1BHxpE4S80dGnBs8B92jAqFe7OmGtBIyT46388NtEbVncSVmurJqZNjBBe3YzIoej -wpKGbvlw7q6Hh5UbxHq9MfPU0uWZ/75I7HX1eBYdpnDBfzwboZL7z8g81sWTCo/1VTp2lc5ZmIoJ -lXcymoO6LAQ6l73UL77XbJuiyn1tJslV1c/DeVIICZkHJC1kJWumIWmbat10TWuXekG9qxf5kBdI -jzb5LdXF2+6qhUVB+s06RbFo5jZMm5BX7CO5hwjCxAnxl4YqKE3idMDaxIzb3+KhF1nOJFl0Mdp/ -/TBt2dzhauH8XwIDAQABo4IBGjCCARYwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw -HQYDVR0OBBYEFBiHVuBud+4kNTxOc5of1uHieX4rMB8GA1UdIwQYMBaAFBiHVuBud+4kNTxOc5of -1uHieX4rMEQGA1UdIAQ9MDswOQYEVR0gADAxMC8GCCsGAQUFBwIBFiNodHRwczovL3d3d3cuY2Vy -dGlnbmEuZnIvYXV0b3JpdGVzLzBtBgNVHR8EZjBkMC+gLaArhilodHRwOi8vY3JsLmNlcnRpZ25h -LmZyL2NlcnRpZ25hcm9vdGNhLmNybDAxoC+gLYYraHR0cDovL2NybC5kaGlteW90aXMuY29tL2Nl -cnRpZ25hcm9vdGNhLmNybDANBgkqhkiG9w0BAQsFAAOCAgEAlLieT/DjlQgi581oQfccVdV8AOIt -OoldaDgvUSILSo3L6btdPrtcPbEo/uRTVRPPoZAbAh1fZkYJMyjhDSSXcNMQH+pkV5a7XdrnxIxP -TGRGHVyH41neQtGbqH6mid2PHMkwgu07nM3A6RngatgCdTer9zQoKJHyBApPNeNgJgH60BGM+RFq -7q89w1DTj18zeTyGqHNFkIwgtnJzFyO+B2XleJINugHA64wcZr+shncBlA2c5uk5jR+mUYyZDDl3 -4bSb+hxnV29qao6pK0xXeXpXIs/NX2NGjVxZOob4Mkdio2cNGJHc+6Zr9UhhcyNZjgKnvETq9Emd -8VRY+WCv2hikLyhF3HqgiIZd8zvn/yk1gPxkQ5Tm4xxvvq0OKmOZK8l+hfZx6AYDlf7ej0gcWtSS -6Cvu5zHbugRqh5jnxV/vfaci9wHYTfmJ0A6aBVmknpjZbyvKcL5kwlWj9Omvw5Ip3IgWJJk8jSaY -tlu3zM63Nwf9JtmYhST/WSMDmu2dnajkXjjO11INb9I/bbEFa0nOipFGc/T2L/Coc3cOZayhjWZS -aX5LaAzHHjcng6WMxwLkFM1JAbBzs/3GkDpv0mztO+7skb6iQ12LAEpmJURw3kAP+HwV96LOPNde -E4yBFxgX0b3xdxA61GU5wSesVywlVP+i2k+KYTlerj1KjL0= ------END CERTIFICATE----- - -emSign Root CA - G1 -=================== ------BEGIN CERTIFICATE----- -MIIDlDCCAnygAwIBAgIKMfXkYgxsWO3W2DANBgkqhkiG9w0BAQsFADBnMQswCQYDVQQGEwJJTjET -MBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRl -ZDEcMBoGA1UEAxMTZW1TaWduIFJvb3QgQ0EgLSBHMTAeFw0xODAyMTgxODMwMDBaFw00MzAyMTgx -ODMwMDBaMGcxCzAJBgNVBAYTAklOMRMwEQYDVQQLEwplbVNpZ24gUEtJMSUwIwYDVQQKExxlTXVk -aHJhIFRlY2hub2xvZ2llcyBMaW1pdGVkMRwwGgYDVQQDExNlbVNpZ24gUm9vdCBDQSAtIEcxMIIB -IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAk0u76WaK7p1b1TST0Bsew+eeuGQzf2N4aLTN -LnF115sgxk0pvLZoYIr3IZpWNVrzdr3YzZr/k1ZLpVkGoZM0Kd0WNHVO8oG0x5ZOrRkVUkr+PHB1 -cM2vK6sVmjM8qrOLqs1D/fXqcP/tzxE7lM5OMhbTI0Aqd7OvPAEsbO2ZLIvZTmmYsvePQbAyeGHW -DV/D+qJAkh1cF+ZwPjXnorfCYuKrpDhMtTk1b+oDafo6VGiFbdbyL0NVHpENDtjVaqSW0RM8LHhQ -6DqS0hdW5TUaQBw+jSztOd9C4INBdN+jzcKGYEho42kLVACL5HZpIQ15TjQIXhTCzLG3rdd8cIrH -hQIDAQABo0IwQDAdBgNVHQ4EFgQU++8Nhp6w492pufEhF38+/PB3KxowDgYDVR0PAQH/BAQDAgEG -MA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAFn/8oz1h31xPaOfG1vR2vjTnGs2 -vZupYeveFix0PZ7mddrXuqe8QhfnPZHr5X3dPpzxz5KsbEjMwiI/aTvFthUvozXGaCocV685743Q -NcMYDHsAVhzNixl03r4PEuDQqqE/AjSxcM6dGNYIAwlG7mDgfrbESQRRfXBgvKqy/3lyeqYdPV8q -+Mri/Tm3R7nrft8EI6/6nAYH6ftjk4BAtcZsCjEozgyfz7MjNYBBjWzEN3uBL4ChQEKF6dk4jeih -U80Bv2noWgbyRQuQ+q7hv53yrlc8pa6yVvSLZUDp/TGBLPQ5Cdjua6e0ph0VpZj3AYHYhX3zUVxx -iN66zB+Afko= ------END CERTIFICATE----- - -emSign ECC Root CA - G3 -======================= ------BEGIN CERTIFICATE----- -MIICTjCCAdOgAwIBAgIKPPYHqWhwDtqLhDAKBggqhkjOPQQDAzBrMQswCQYDVQQGEwJJTjETMBEG -A1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEg -MB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0gRzMwHhcNMTgwMjE4MTgzMDAwWhcNNDMwMjE4 -MTgzMDAwWjBrMQswCQYDVQQGEwJJTjETMBEGA1UECxMKZW1TaWduIFBLSTElMCMGA1UEChMcZU11 -ZGhyYSBUZWNobm9sb2dpZXMgTGltaXRlZDEgMB4GA1UEAxMXZW1TaWduIEVDQyBSb290IENBIC0g -RzMwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQjpQy4LRL1KPOxst3iAhKAnjlfSU2fySU0WXTsuwYc -58Byr+iuL+FBVIcUqEqy6HyC5ltqtdyzdc6LBtCGI79G1Y4PPwT01xySfvalY8L1X44uT6EYGQIr -MgqCZH0Wk9GjQjBAMB0GA1UdDgQWBBR8XQKEE9TMipuBzhccLikenEhjQjAOBgNVHQ8BAf8EBAMC -AQYwDwYDVR0TAQH/BAUwAwEB/zAKBggqhkjOPQQDAwNpADBmAjEAvvNhzwIQHWSVB7gYboiFBS+D -CBeQyh+KTOgNG3qxrdWBCUfvO6wIBHxcmbHtRwfSAjEAnbpV/KlK6O3t5nYBQnvI+GDZjVGLVTv7 -jHvrZQnD+JbNR6iC8hZVdyR+EhCVBCyj ------END CERTIFICATE----- - -emSign Root CA - C1 -=================== ------BEGIN CERTIFICATE----- -MIIDczCCAlugAwIBAgILAK7PALrEzzL4Q7IwDQYJKoZIhvcNAQELBQAwVjELMAkGA1UEBhMCVVMx -EzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQDExNlbVNp -Z24gUm9vdCBDQSAtIEMxMB4XDTE4MDIxODE4MzAwMFoXDTQzMDIxODE4MzAwMFowVjELMAkGA1UE -BhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMRwwGgYDVQQD -ExNlbVNpZ24gUm9vdCBDQSAtIEMxMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAz+up -ufGZBczYKCFK83M0UYRWEPWgTywS4/oTmifQz/l5GnRfHXk5/Fv4cI7gklL35CX5VIPZHdPIWoU/ -Xse2B+4+wM6ar6xWQio5JXDWv7V7Nq2s9nPczdcdioOl+yuQFTdrHCZH3DspVpNqs8FqOp099cGX -OFgFixwR4+S0uF2FHYP+eF8LRWgYSKVGczQ7/g/IdrvHGPMF0Ybzhe3nudkyrVWIzqa2kbBPrH4V -I5b2P/AgNBbeCsbEBEV5f6f9vtKppa+cxSMq9zwhbL2vj07FOrLzNBL834AaSaTUqZX3noleooms -lMuoaJuvimUnzYnu3Yy1aylwQ6BpC+S5DwIDAQABo0IwQDAdBgNVHQ4EFgQU/qHgcB4qAzlSWkK+ -XJGFehiqTbUwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQAD -ggEBAMJKVvoVIXsoounlHfv4LcQ5lkFMOycsxGwYFYDGrK9HWS8mC+M2sO87/kOXSTKZEhVb3xEp -/6tT+LvBeA+snFOvV71ojD1pM/CjoCNjO2RnIkSt1XHLVip4kqNPEjE2NuLe/gDEo2APJ62gsIq1 -NnpSob0n9CAnYuhNlCQT5AoE6TyrLshDCUrGYQTlSTR+08TI9Q/Aqum6VF7zYytPT1DU/rl7mYw9 -wC68AivTxEDkigcxHpvOJpkT+xHqmiIMERnHXhuBUDDIlhJu58tBf5E7oke3VIAb3ADMmpDqw8NQ -BmIMMMAVSKeoWXzhriKi4gp6D/piq1JM4fHfyr6DDUI= ------END CERTIFICATE----- - -emSign ECC Root CA - C3 -======================= ------BEGIN CERTIFICATE----- -MIICKzCCAbGgAwIBAgIKe3G2gla4EnycqDAKBggqhkjOPQQDAzBaMQswCQYDVQQGEwJVUzETMBEG -A1UECxMKZW1TaWduIFBLSTEUMBIGA1UEChMLZU11ZGhyYSBJbmMxIDAeBgNVBAMTF2VtU2lnbiBF -Q0MgUm9vdCBDQSAtIEMzMB4XDTE4MDIxODE4MzAwMFoXDTQzMDIxODE4MzAwMFowWjELMAkGA1UE -BhMCVVMxEzARBgNVBAsTCmVtU2lnbiBQS0kxFDASBgNVBAoTC2VNdWRocmEgSW5jMSAwHgYDVQQD -ExdlbVNpZ24gRUNDIFJvb3QgQ0EgLSBDMzB2MBAGByqGSM49AgEGBSuBBAAiA2IABP2lYa57JhAd -6bciMK4G9IGzsUJxlTm801Ljr6/58pc1kjZGDoeVjbk5Wum739D+yAdBPLtVb4OjavtisIGJAnB9 -SMVK4+kiVCJNk7tCDK93nCOmfddhEc5lx/h//vXyqaNCMEAwHQYDVR0OBBYEFPtaSNCAIEDyqOkA -B2kZd6fmw/TPMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMDA2gA -MGUCMQC02C8Cif22TGK6Q04ThHK1rt0c3ta13FaPWEBaLd4gTCKDypOofu4SQMfWh0/434UCMBwU -ZOR8loMRnLDRWmFLpg9J0wD8ofzkpf9/rdcw0Md3f76BB1UwUCAU9Vc4CqgxUQ== ------END CERTIFICATE----- - -Hongkong Post Root CA 3 -======================= ------BEGIN CERTIFICATE----- -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 -dBb9HxEGmpv0 ------END CERTIFICATE----- - -Microsoft ECC Root Certificate Authority 2017 -============================================= ------BEGIN CERTIFICATE----- -MIICWTCCAd+gAwIBAgIQZvI9r4fei7FK6gxXMQHC7DAKBggqhkjOPQQDAzBlMQswCQYDVQQGEwJV -UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNyb3NvZnQgRUND -IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwHhcNMTkxMjE4MjMwNjQ1WhcNNDIwNzE4 -MjMxNjA0WjBlMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYw -NAYDVQQDEy1NaWNyb3NvZnQgRUNDIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwdjAQ -BgcqhkjOPQIBBgUrgQQAIgNiAATUvD0CQnVBEyPNgASGAlEvaqiBYgtlzPbKnR5vSmZRogPZnZH6 -thaxjG7efM3beaYvzrvOcS/lpaso7GMEZpn4+vKTEAXhgShC48Zo9OYbhGBKia/teQ87zvH2RPUB -eMCjVDBSMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTIy5lycFIM -+Oa+sgRXKSrPQhDtNTAQBgkrBgEEAYI3FQEEAwIBADAKBggqhkjOPQQDAwNoADBlAjBY8k3qDPlf -Xu5gKcs68tvWMoQZP3zVL8KxzJOuULsJMsbG7X7JNpQS5GiFBqIb0C8CMQCZ6Ra0DvpWSNSkMBaR -eNtUjGUBiudQZsIxtzm6uBoiB078a1QWIP8rtedMDE2mT3M= ------END CERTIFICATE----- - -Microsoft RSA Root Certificate Authority 2017 -============================================= ------BEGIN CERTIFICATE----- -MIIFqDCCA5CgAwIBAgIQHtOXCV/YtLNHcB6qvn9FszANBgkqhkiG9w0BAQwFADBlMQswCQYDVQQG -EwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTYwNAYDVQQDEy1NaWNyb3NvZnQg -UlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcwHhcNMTkxMjE4MjI1MTIyWhcNNDIw -NzE4MjMwMDIzWjBlMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u -MTYwNAYDVQQDEy1NaWNyb3NvZnQgUlNBIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTcw -ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKW76UM4wplZEWCpW9R2LBifOZNt9GkMml -7Xhqb0eRaPgnZ1AzHaGm++DlQ6OEAlcBXZxIQIJTELy/xztokLaCLeX0ZdDMbRnMlfl7rEqUrQ7e -S0MdhweSE5CAg2Q1OQT85elss7YfUJQ4ZVBcF0a5toW1HLUX6NZFndiyJrDKxHBKrmCk3bPZ7Pw7 -1VdyvD/IybLeS2v4I2wDwAW9lcfNcztmgGTjGqwu+UcF8ga2m3P1eDNbx6H7JyqhtJqRjJHTOoI+ -dkC0zVJhUXAoP8XFWvLJjEm7FFtNyP9nTUwSlq31/niol4fX/V4ggNyhSyL71Imtus5Hl0dVe49F -yGcohJUcaDDv70ngNXtk55iwlNpNhTs+VcQor1fznhPbRiefHqJeRIOkpcrVE7NLP8TjwuaGYaRS -MLl6IE9vDzhTyzMMEyuP1pq9KsgtsRx9S1HKR9FIJ3Jdh+vVReZIZZ2vUpC6W6IYZVcSn2i51BVr -lMRpIpj0M+Dt+VGOQVDJNE92kKz8OMHY4Xu54+OU4UZpyw4KUGsTuqwPN1q3ErWQgR5WrlcihtnJ -0tHXUeOrO8ZV/R4O03QK0dqq6mm4lyiPSMQH+FJDOvTKVTUssKZqwJz58oHhEmrARdlns87/I6KJ -ClTUFLkqqNfs+avNJVgyeY+QW5g5xAgGwax/Dj0ApQIDAQABo1QwUjAOBgNVHQ8BAf8EBAMCAYYw -DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUCctZf4aycI8awznjwNnpv7tNsiMwEAYJKwYBBAGC -NxUBBAMCAQAwDQYJKoZIhvcNAQEMBQADggIBAKyvPl3CEZaJjqPnktaXFbgToqZCLgLNFgVZJ8og -6Lq46BrsTaiXVq5lQ7GPAJtSzVXNUzltYkyLDVt8LkS/gxCP81OCgMNPOsduET/m4xaRhPtthH80 -dK2Jp86519efhGSSvpWhrQlTM93uCupKUY5vVau6tZRGrox/2KJQJWVggEbbMwSubLWYdFQl3JPk -+ONVFT24bcMKpBLBaYVu32TxU5nhSnUgnZUP5NbcA/FZGOhHibJXWpS2qdgXKxdJ5XbLwVaZOjex -/2kskZGT4d9Mozd2TaGf+G0eHdP67Pv0RR0Tbc/3WeUiJ3IrhvNXuzDtJE3cfVa7o7P4NHmJweDy -AmH3pvwPuxwXC65B2Xy9J6P9LjrRk5Sxcx0ki69bIImtt2dmefU6xqaWM/5TkshGsRGRxpl/j8nW -ZjEgQRCHLQzWwa80mMpkg/sTV9HB8Dx6jKXB/ZUhoHHBk2dxEuqPiAppGWSZI1b7rCoucL5mxAyE -7+WL85MB+GqQk2dLsmijtWKP6T+MejteD+eMuMZ87zf9dOLITzNy4ZQ5bb0Sr74MTnB8G2+NszKT -c0QWbej09+CVgI+WXTik9KveCjCHk9hNAHFiRSdLOkKEW39lt2c0Ui2cFmuqqNh7o0JMcccMyj6D -5KbvtwEwXlGjefVwaaZBRA+GsCyRxj3qrg+E ------END CERTIFICATE----- - -e-Szigno Root CA 2017 -===================== ------BEGIN CERTIFICATE----- -MIICQDCCAeWgAwIBAgIMAVRI7yH9l1kN9QQKMAoGCCqGSM49BAMCMHExCzAJBgNVBAYTAkhVMREw -DwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UECgwNTWljcm9zZWMgTHRkLjEXMBUGA1UEYQwOVkFUSFUt -MjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3ppZ25vIFJvb3QgQ0EgMjAxNzAeFw0xNzA4MjIxMjA3MDZa -Fw00MjA4MjIxMjA3MDZaMHExCzAJBgNVBAYTAkhVMREwDwYDVQQHDAhCdWRhcGVzdDEWMBQGA1UE -CgwNTWljcm9zZWMgTHRkLjEXMBUGA1UEYQwOVkFUSFUtMjM1ODQ0OTcxHjAcBgNVBAMMFWUtU3pp -Z25vIFJvb3QgQ0EgMjAxNzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABJbcPYrYsHtvxie+RJCx -s1YVe45DJH0ahFnuY2iyxl6H0BVIHqiQrb1TotreOpCmYF9oMrWGQd+HWyx7xf58etqjYzBhMA8G -A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBSHERUI0arBeAyxr87GyZDv -vzAEwDAfBgNVHSMEGDAWgBSHERUI0arBeAyxr87GyZDvvzAEwDAKBggqhkjOPQQDAgNJADBGAiEA -tVfd14pVCzbhhkT61NlojbjcI4qKDdQvfepz7L9NbKgCIQDLpbQS+ue16M9+k/zzNY9vTlp8tLxO -svxyqltZ+efcMQ== ------END CERTIFICATE----- - -certSIGN Root CA G2 -=================== ------BEGIN CERTIFICATE----- -MIIFRzCCAy+gAwIBAgIJEQA0tk7GNi02MA0GCSqGSIb3DQEBCwUAMEExCzAJBgNVBAYTAlJPMRQw -EgYDVQQKEwtDRVJUU0lHTiBTQTEcMBoGA1UECxMTY2VydFNJR04gUk9PVCBDQSBHMjAeFw0xNzAy -MDYwOTI3MzVaFw00MjAyMDYwOTI3MzVaMEExCzAJBgNVBAYTAlJPMRQwEgYDVQQKEwtDRVJUU0lH -TiBTQTEcMBoGA1UECxMTY2VydFNJR04gUk9PVCBDQSBHMjCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBAMDFdRmRfUR0dIf+DjuW3NgBFszuY5HnC2/OOwppGnzC46+CjobXXo9X69MhWf05 -N0IwvlDqtg+piNguLWkh59E3GE59kdUWX2tbAMI5Qw02hVK5U2UPHULlj88F0+7cDBrZuIt4Imfk -abBoxTzkbFpG583H+u/E7Eu9aqSs/cwoUe+StCmrqzWaTOTECMYmzPhpn+Sc8CnTXPnGFiWeI8Mg -wT0PPzhAsP6CRDiqWhqKa2NYOLQV07YRaXseVO6MGiKscpc/I1mbySKEwQdPzH/iV8oScLumZfNp -dWO9lfsbl83kqK/20U6o2YpxJM02PbyWxPFsqa7lzw1uKA2wDrXKUXt4FMMgL3/7FFXhEZn91Qqh -ngLjYl/rNUssuHLoPj1PrCy7Lobio3aP5ZMqz6WryFyNSwb/EkaseMsUBzXgqd+L6a8VTxaJW732 -jcZZroiFDsGJ6x9nxUWO/203Nit4ZoORUSs9/1F3dmKh7Gc+PoGD4FapUB8fepmrY7+EF3fxDTvf -95xhszWYijqy7DwaNz9+j5LP2RIUZNoQAhVB/0/E6xyjyfqZ90bp4RjZsbgyLcsUDFDYg2WD7rlc -z8sFWkz6GZdr1l0T08JcVLwyc6B49fFtHsufpaafItzRUZ6CeWRgKRM+o/1Pcmqr4tTluCRVLERL -iohEnMqE0yo7AgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1Ud -DgQWBBSCIS1mxteg4BXrzkwJd8RgnlRuAzANBgkqhkiG9w0BAQsFAAOCAgEAYN4auOfyYILVAzOB -ywaK8SJJ6ejqkX/GM15oGQOGO0MBzwdw5AgeZYWR5hEit/UCI46uuR59H35s5r0l1ZUa8gWmr4UC -b6741jH/JclKyMeKqdmfS0mbEVeZkkMR3rYzpMzXjWR91M08KCy0mpbqTfXERMQlqiCA2ClV9+BB -/AYm/7k29UMUA2Z44RGx2iBfRgB4ACGlHgAoYXhvqAEBj500mv/0OJD7uNGzcgbJceaBxXntC6Z5 -8hMLnPddDnskk7RI24Zf3lCGeOdA5jGokHZwYa+cNywRtYK3qq4kNFtyDGkNzVmf9nGvnAvRCjj5 -BiKDUyUM/FHE5r7iOZULJK2v0ZXkltd0ZGtxTgI8qoXzIKNDOXZbbFD+mpwUHmUUihW9o4JFWklW -atKcsWMy5WHgUyIOpwpJ6st+H6jiYoD2EEVSmAYY3qXNL3+q1Ok+CHLsIwMCPKaq2LxndD0UF/tU -Sxfj03k9bWtJySgOLnRQvwzZRjoQhsmnP+mg7H/rpXdYaXHmgwo38oZJar55CJD2AhZkPuXaTH4M -NMn5X7azKFGnpyuqSfqNZSlO42sTp5SjLVFteAxEy9/eCG/Oo2Sr05WE1LlSVHJ7liXMvGnjSG4N -0MedJ5qq+BOS3R7fY581qRY27Iy4g/Q9iY/NtBde17MXQRBdJ3NghVdJIgc= ------END CERTIFICATE----- - -Trustwave Global Certification Authority -======================================== ------BEGIN CERTIFICATE----- -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 -29FpHOTKyeC2nOnOcXHebD8WpHk= ------END CERTIFICATE----- - -Trustwave Global ECC P256 Certification Authority -================================================= ------BEGIN CERTIFICATE----- -MIICYDCCAgegAwIBAgIMDWpfCD8oXD5Rld9dMAoGCCqGSM49BAMCMIGRMQswCQYDVQQGEwJVUzER -MA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0d2F2ZSBI -b2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDI1NiBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMxOTM1MTBaFw00MjA4MjMxOTM1MTBaMIGRMQswCQYD -VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRy -dXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDI1 -NiBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABH77bOYj -43MyCMpg5lOcunSNGLB4kFKA3TjASh3RqMyTpJcGOMoNFWLGjgEqZZ2q3zSRLoHB5DOSMcT9CTqm -P62jQzBBMA8GA1UdEwEB/wQFMAMBAf8wDwYDVR0PAQH/BAUDAwcGADAdBgNVHQ4EFgQUo0EGrJBt -0UrrdaVKEJmzsaGLSvcwCgYIKoZIzj0EAwIDRwAwRAIgB+ZU2g6gWrKuEZ+Hxbb/ad4lvvigtwjz -RM4q3wghDDcCIC0mA6AFvWvR9lz4ZcyGbbOcNEhjhAnFjXca4syc4XR7 ------END CERTIFICATE----- - -Trustwave Global ECC P384 Certification Authority -================================================= ------BEGIN CERTIFICATE----- -MIICnTCCAiSgAwIBAgIMCL2Fl2yZJ6SAaEc7MAoGCCqGSM49BAMDMIGRMQswCQYDVQQGEwJVUzER -MA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRydXN0d2F2ZSBI -b2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDM4NCBDZXJ0aWZp -Y2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MjMxOTM2NDNaFw00MjA4MjMxOTM2NDNaMIGRMQswCQYD -VQQGEwJVUzERMA8GA1UECBMISWxsaW5vaXMxEDAOBgNVBAcTB0NoaWNhZ28xITAfBgNVBAoTGFRy -dXN0d2F2ZSBIb2xkaW5ncywgSW5jLjE6MDgGA1UEAxMxVHJ1c3R3YXZlIEdsb2JhbCBFQ0MgUDM4 -NCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTB2MBAGByqGSM49AgEGBSuBBAAiA2IABGvaDXU1CDFH -Ba5FmVXxERMuSvgQMSOjfoPTfygIOiYaOs+Xgh+AtycJj9GOMMQKmw6sWASr9zZ9lCOkmwqKi6vr -/TklZvFe/oyujUF5nQlgziip04pt89ZF1PKYhDhloKNDMEEwDwYDVR0TAQH/BAUwAwEB/zAPBgNV -HQ8BAf8EBQMDBwYAMB0GA1UdDgQWBBRVqYSJ0sEyvRjLbKYHTsjnnb6CkDAKBggqhkjOPQQDAwNn -ADBkAjA3AZKXRRJ+oPM+rRk6ct30UJMDEr5E0k9BpIycnR+j9sKS50gU/k6bpZFXrsY3crsCMGcl -CrEMXu6pY5Jv5ZAL/mYiykf9ijH3g/56vxC+GCsej/YpHpRZ744hN8tRmKVuSw== ------END CERTIFICATE----- - -NAVER Global Root Certification Authority -========================================= ------BEGIN CERTIFICATE----- -MIIFojCCA4qgAwIBAgIUAZQwHqIL3fXFMyqxQ0Rx+NZQTQ0wDQYJKoZIhvcNAQEMBQAwaTELMAkG -A1UEBhMCS1IxJjAkBgNVBAoMHU5BVkVSIEJVU0lORVNTIFBMQVRGT1JNIENvcnAuMTIwMAYDVQQD -DClOQVZFUiBHbG9iYWwgUm9vdCBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNzA4MTgwODU4 -NDJaFw0zNzA4MTgyMzU5NTlaMGkxCzAJBgNVBAYTAktSMSYwJAYDVQQKDB1OQVZFUiBCVVNJTkVT -UyBQTEFURk9STSBDb3JwLjEyMDAGA1UEAwwpTkFWRVIgR2xvYmFsIFJvb3QgQ2VydGlmaWNhdGlv -biBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC21PGTXLVAiQqrDZBb -UGOukJR0F0Vy1ntlWilLp1agS7gvQnXp2XskWjFlqxcX0TM62RHcQDaH38dq6SZeWYp34+hInDEW -+j6RscrJo+KfziFTowI2MMtSAuXaMl3Dxeb57hHHi8lEHoSTGEq0n+USZGnQJoViAbbJAh2+g1G7 -XNr4rRVqmfeSVPc0W+m/6imBEtRTkZazkVrd/pBzKPswRrXKCAfHcXLJZtM0l/aM9BhK4dA9WkW2 -aacp+yPOiNgSnABIqKYPszuSjXEOdMWLyEz59JuOuDxp7W87UC9Y7cSw0BwbagzivESq2M0UXZR4 -Yb8ObtoqvC8MC3GmsxY/nOb5zJ9TNeIDoKAYv7vxvvTWjIcNQvcGufFt7QSUqP620wbGQGHfnZ3z -VHbOUzoBppJB7ASjjw2i1QnK1sua8e9DXcCrpUHPXFNwcMmIpi3Ua2FzUCaGYQ5fG8Ir4ozVu53B -A0K6lNpfqbDKzE0K70dpAy8i+/Eozr9dUGWokG2zdLAIx6yo0es+nPxdGoMuK8u180SdOqcXYZai -cdNwlhVNt0xz7hlcxVs+Qf6sdWA7G2POAN3aCJBitOUt7kinaxeZVL6HSuOpXgRM6xBtVNbv8ejy -YhbLgGvtPe31HzClrkvJE+2KAQHJuFFYwGY6sWZLxNUxAmLpdIQM201GLQIDAQABo0IwQDAdBgNV -HQ4EFgQU0p+I36HNLL3s9TsBAZMzJ7LrYEswDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB -Af8wDQYJKoZIhvcNAQEMBQADggIBADLKgLOdPVQG3dLSLvCkASELZ0jKbY7gyKoNqo0hV4/GPnrK -21HUUrPUloSlWGB/5QuOH/XcChWB5Tu2tyIvCZwTFrFsDDUIbatjcu3cvuzHV+YwIHHW1xDBE1UB -jCpD5EHxzzp6U5LOogMFDTjfArsQLtk70pt6wKGm+LUx5vR1yblTmXVHIloUFcd4G7ad6Qz4G3bx -hYTeodoS76TiEJd6eN4MUZeoIUCLhr0N8F5OSza7OyAfikJW4Qsav3vQIkMsRIz75Sq0bBwcupTg -E34h5prCy8VCZLQelHsIJchxzIdFV4XTnyliIoNRlwAYl3dqmJLJfGBs32x9SuRwTMKeuB330DTH -D8z7p/8Dvq1wkNoL3chtl1+afwkyQf3NosxabUzyqkn+Zvjp2DXrDige7kgvOtB5CTh8piKCk5XQ -A76+AqAF3SAi428diDRgxuYKuQl1C/AH6GmWNcf7I4GOODm4RStDeKLRLBT/DShycpWbXgnbiUSY -qqFJu3FS8r/2/yehNq+4tneI3TqkbZs0kNwUXTC/t+sX5Ie3cdCh13cV1ELX8vMxmV2b3RZtP+oG -I/hGoiLtk/bdmuYqh7GYVPEi92tF4+KOdh2ajcQGjTa3FPOdVGm3jjzVpG2Tgbet9r1ke8LJaDmg -kpzNNIaRkPpkUZ3+/uul9XXeifdy ------END CERTIFICATE----- - -AC RAIZ FNMT-RCM SERVIDORES SEGUROS -=================================== ------BEGIN CERTIFICATE----- -MIICbjCCAfOgAwIBAgIQYvYybOXE42hcG2LdnC6dlTAKBggqhkjOPQQDAzB4MQswCQYDVQQGEwJF -UzERMA8GA1UECgwIRk5NVC1SQ00xDjAMBgNVBAsMBUNlcmVzMRgwFgYDVQRhDA9WQVRFUy1RMjgy -NjAwNEoxLDAqBgNVBAMMI0FDIFJBSVogRk5NVC1SQ00gU0VSVklET1JFUyBTRUdVUk9TMB4XDTE4 -MTIyMDA5MzczM1oXDTQzMTIyMDA5MzczM1oweDELMAkGA1UEBhMCRVMxETAPBgNVBAoMCEZOTVQt -UkNNMQ4wDAYDVQQLDAVDZXJlczEYMBYGA1UEYQwPVkFURVMtUTI4MjYwMDRKMSwwKgYDVQQDDCNB -QyBSQUlaIEZOTVQtUkNNIFNFUlZJRE9SRVMgU0VHVVJPUzB2MBAGByqGSM49AgEGBSuBBAAiA2IA -BPa6V1PIyqvfNkpSIeSX0oNnnvBlUdBeh8dHsVnyV0ebAAKTRBdp20LHsbI6GA60XYyzZl2hNPk2 -LEnb80b8s0RpRBNm/dfF/a82Tc4DTQdxz69qBdKiQ1oKUm8BA06Oi6NCMEAwDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFAG5L++/EYZg8k/QQW6rcx/n0m5JMAoGCCqG -SM49BAMDA2kAMGYCMQCuSuMrQMN0EfKVrRYj3k4MGuZdpSRea0R7/DjiT8ucRRcRTBQnJlU5dUoD -zBOQn5ICMQD6SmxgiHPz7riYYqnOK8LZiqZwMR2vsJRM60/G49HzYqc8/5MuB1xJAWdpEgJyv+c= ------END CERTIFICATE----- - -GlobalSign Root R46 -=================== ------BEGIN CERTIFICATE----- -MIIFWjCCA0KgAwIBAgISEdK7udcjGJ5AXwqdLdDfJWfRMA0GCSqGSIb3DQEBDAUAMEYxCzAJBgNV -BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQDExNHbG9iYWxTaWduIFJv -b3QgUjQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAX -BgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBSNDYwggIi -MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCsrHQy6LNl5brtQyYdpokNRbopiLKkHWPd08Es -CVeJOaFV6Wc0dwxu5FUdUiXSE2te4R2pt32JMl8Nnp8semNgQB+msLZ4j5lUlghYruQGvGIFAha/ -r6gjA7aUD7xubMLL1aa7DOn2wQL7Id5m3RerdELv8HQvJfTqa1VbkNud316HCkD7rRlr+/fKYIje -2sGP1q7Vf9Q8g+7XFkyDRTNrJ9CG0Bwta/OrffGFqfUo0q3v84RLHIf8E6M6cqJaESvWJ3En7YEt -bWaBkoe0G1h6zD8K+kZPTXhc+CtI4wSEy132tGqzZfxCnlEmIyDLPRT5ge1lFgBPGmSXZgjPjHvj -K8Cd+RTyG/FWaha/LIWFzXg4mutCagI0GIMXTpRW+LaCtfOW3T3zvn8gdz57GSNrLNRyc0NXfeD4 -12lPFzYE+cCQYDdF3uYM2HSNrpyibXRdQr4G9dlkbgIQrImwTDsHTUB+JMWKmIJ5jqSngiCNI/on -ccnfxkF0oE32kRbcRoxfKWMxWXEM2G/CtjJ9++ZdU6Z+Ffy7dXxd7Pj2Fxzsx2sZy/N78CsHpdls -eVR2bJ0cpm4O6XkMqCNqo98bMDGfsVR7/mrLZqrcZdCinkqaByFrgY/bxFn63iLABJzjqls2k+g9 -vXqhnQt2sQvHnf3PmKgGwvgqo6GDoLclcqUC4wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYD -VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA1yrc4GHqMywptWU4jaWSf8FmSwwDQYJKoZIhvcNAQEM -BQADggIBAHx47PYCLLtbfpIrXTncvtgdokIzTfnvpCo7RGkerNlFo048p9gkUbJUHJNOxO97k4Vg -JuoJSOD1u8fpaNK7ajFxzHmuEajwmf3lH7wvqMxX63bEIaZHU1VNaL8FpO7XJqti2kM3S+LGteWy -gxk6x9PbTZ4IevPuzz5i+6zoYMzRx6Fcg0XERczzF2sUyQQCPtIkpnnpHs6i58FZFZ8d4kuaPp92 -CC1r2LpXFNqD6v6MVenQTqnMdzGxRBF6XLE+0xRFFRhiJBPSy03OXIPBNvIQtQ6IbbjhVp+J3pZm -OUdkLG5NrmJ7v2B0GbhWrJKsFjLtrWhV/pi60zTe9Mlhww6G9kuEYO4Ne7UyWHmRVSyBQ7N0H3qq -JZ4d16GLuc1CLgSkZoNNiTW2bKg2SnkheCLQQrzRQDGQob4Ez8pn7fXwgNNgyYMqIgXQBztSvwye -qiv5u+YfjyW6hY0XHgL+XVAEV8/+LbzvXMAaq7afJMbfc2hIkCwU9D9SGuTSyxTDYWnP4vkYxboz -nxSjBF25cfe1lNj2M8FawTSLfJvdkzrnE6JwYZ+vj+vYxXX4M2bUdGc6N3ec592kD3ZDZopD8p/7 -DEJ4Y9HiD2971KE9dJeFt0g5QdYg/NA6s/rob8SKunE3vouXsXgxT7PntgMTzlSdriVZzH81Xwj3 -QEUxeCp6 ------END CERTIFICATE----- - -GlobalSign Root E46 -=================== ------BEGIN CERTIFICATE----- -MIICCzCCAZGgAwIBAgISEdK7ujNu1LzmJGjFDYQdmOhDMAoGCCqGSM49BAMDMEYxCzAJBgNVBAYT -AkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRwwGgYDVQQDExNHbG9iYWxTaWduIFJvb3Qg -RTQ2MB4XDTE5MDMyMDAwMDAwMFoXDTQ2MDMyMDAwMDAwMFowRjELMAkGA1UEBhMCQkUxGTAXBgNV -BAoTEEdsb2JhbFNpZ24gbnYtc2ExHDAaBgNVBAMTE0dsb2JhbFNpZ24gUm9vdCBFNDYwdjAQBgcq -hkjOPQIBBgUrgQQAIgNiAAScDrHPt+ieUnd1NPqlRqetMhkytAepJ8qUuwzSChDH2omwlwxwEwkB -jtjqR+q+soArzfwoDdusvKSGN+1wCAB16pMLey5SnCNoIwZD7JIvU4Tb+0cUB+hflGddyXqBPCCj -QjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQxCpCPtsad0kRL -gLWi5h+xEk8blTAKBggqhkjOPQQDAwNoADBlAjEA31SQ7Zvvi5QCkxeCmb6zniz2C5GMn0oUsfZk -vLtoURMMA/cVi4RguYv/Uo7njLwcAjA8+RHUjE7AwWHCFUyqqx0LMV87HOIAl0Qx5v5zli/altP+ -CAezNIm8BZ/3Hobui3A= ------END CERTIFICATE----- - -GLOBALTRUST 2020 -================ ------BEGIN CERTIFICATE----- -MIIFgjCCA2qgAwIBAgILWku9WvtPilv6ZeUwDQYJKoZIhvcNAQELBQAwTTELMAkGA1UEBhMCQVQx -IzAhBgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVT -VCAyMDIwMB4XDTIwMDIxMDAwMDAwMFoXDTQwMDYxMDAwMDAwMFowTTELMAkGA1UEBhMCQVQxIzAh -BgNVBAoTGmUtY29tbWVyY2UgbW9uaXRvcmluZyBHbWJIMRkwFwYDVQQDExBHTE9CQUxUUlVTVCAy -MDIwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAri5WrRsc7/aVj6B3GyvTY4+ETUWi -D59bRatZe1E0+eyLinjF3WuvvcTfk0Uev5E4C64OFudBc/jbu9G4UeDLgztzOG53ig9ZYybNpyrO -VPu44sB8R85gfD+yc/LAGbaKkoc1DZAoouQVBGM+uq/ufF7MpotQsjj3QWPKzv9pj2gOlTblzLmM -CcpL3TGQlsjMH/1WljTbjhzqLL6FLmPdqqmV0/0plRPwyJiT2S0WR5ARg6I6IqIoV6Lr/sCMKKCm -fecqQjuCgGOlYx8ZzHyyZqjC0203b+J+BlHZRYQfEs4kUmSFC0iAToexIiIwquuuvuAC4EDosEKA -A1GqtH6qRNdDYfOiaxaJSaSjpCuKAsR49GiKweR6NrFvG5Ybd0mN1MkGco/PU+PcF4UgStyYJ9OR -JitHHmkHr96i5OTUawuzXnzUJIBHKWk7buis/UDr2O1xcSvy6Fgd60GXIsUf1DnQJ4+H4xj04KlG -DfV0OoIu0G4skaMxXDtG6nsEEFZegB31pWXogvziB4xiRfUg3kZwhqG8k9MedKZssCz3AwyIDMvU -clOGvGBG85hqwvG/Q/lwIHfKN0F5VVJjjVsSn8VoxIidrPIwq7ejMZdnrY8XD2zHc+0klGvIg5rQ -mjdJBKuxFshsSUktq6HQjJLyQUp5ISXbY9e2nKd+Qmn7OmMCAwEAAaNjMGEwDwYDVR0TAQH/BAUw -AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFNwuH9FhN3nkq9XVsxJxaD1qaJwiMB8GA1Ud -IwQYMBaAFNwuH9FhN3nkq9XVsxJxaD1qaJwiMA0GCSqGSIb3DQEBCwUAA4ICAQCR8EICaEDuw2jA -VC/f7GLDw56KoDEoqoOOpFaWEhCGVrqXctJUMHytGdUdaG/7FELYjQ7ztdGl4wJCXtzoRlgHNQIw -4Lx0SsFDKv/bGtCwr2zD/cuz9X9tAy5ZVp0tLTWMstZDFyySCstd6IwPS3BD0IL/qMy/pJTAvoe9 -iuOTe8aPmxadJ2W8esVCgmxcB9CpwYhgROmYhRZf+I/KARDOJcP5YBugxZfD0yyIMaK9MOzQ0MAS -8cE54+X1+NZK3TTN+2/BT+MAi1bikvcoskJ3ciNnxz8RFbLEAwW+uxF7Cr+obuf/WEPPm2eggAe2 -HcqtbepBEX4tdJP7wry+UUTF72glJ4DjyKDUEuzZpTcdN3y0kcra1LGWge9oXHYQSa9+pTeAsRxS -vTOBTI/53WXZFM2KJVj04sWDpQmQ1GwUY7VA3+vA/MRYfg0UFodUJ25W5HCEuGwyEn6CMUO+1918 -oa2u1qsgEu8KwxCMSZY13At1XrFP1U80DhEgB3VDRemjEdqso5nCtnkn4rnvyOL2NSl6dPrFf4IF -YqYK6miyeUcGbvJXqBUzxvd4Sj1Ce2t+/vdG6tHrju+IaFvowdlxfv1k7/9nR4hYJS8+hge9+6jl -gqispdNpQ80xiEmEU5LAsTkbOYMBMMTyqfrQA71yN2BWHzZ8vTmR9W0Nv3vXkg== ------END CERTIFICATE----- - -ANF Secure Server Root CA -========================= ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - -Certum EC-384 CA -================ ------BEGIN CERTIFICATE----- -MIICZTCCAeugAwIBAgIQeI8nXIESUiClBNAt3bpz9DAKBggqhkjOPQQDAzB0MQswCQYDVQQGEwJQ -TDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2Vy -dGlmaWNhdGlvbiBBdXRob3JpdHkxGTAXBgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwHhcNMTgwMzI2 -MDcyNDU0WhcNNDMwMzI2MDcyNDU0WjB0MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERh -dGEgU3lzdGVtcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkx -GTAXBgNVBAMTEENlcnR1bSBFQy0zODQgQ0EwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATEKI6rGFtq -vm5kN2PkzeyrOvfMobgOgknXhimfoZTy42B4mIF4Bk3y7JoOV2CDn7TmFy8as10CW4kjPMIRBSqn -iBMY81CE1700LCeJVf/OTOffph8oxPBUw7l8t1Ot68KjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYD -VR0OBBYEFI0GZnQkdjrzife81r1HfS+8EF9LMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNo -ADBlAjADVS2m5hjEfO/JUG7BJw+ch69u1RsIGL2SKcHvlJF40jocVYli5RsJHrpka/F2tNQCMQC0 -QoSZ/6vnnvuRlydd3LBbMHHOXjgaatkl5+r3YZJW+OraNsKHZZYuciUvf9/DE8k= ------END CERTIFICATE----- - -Certum Trusted Root CA -====================== ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - -TunTrust Root CA -================ ------BEGIN CERTIFICATE----- -MIIFszCCA5ugAwIBAgIUEwLV4kBMkkaGFmddtLu7sms+/BMwDQYJKoZIhvcNAQELBQAwYTELMAkG -A1UEBhMCVE4xNzA1BgNVBAoMLkFnZW5jZSBOYXRpb25hbGUgZGUgQ2VydGlmaWNhdGlvbiBFbGVj -dHJvbmlxdWUxGTAXBgNVBAMMEFR1blRydXN0IFJvb3QgQ0EwHhcNMTkwNDI2MDg1NzU2WhcNNDQw -NDI2MDg1NzU2WjBhMQswCQYDVQQGEwJUTjE3MDUGA1UECgwuQWdlbmNlIE5hdGlvbmFsZSBkZSBD -ZXJ0aWZpY2F0aW9uIEVsZWN0cm9uaXF1ZTEZMBcGA1UEAwwQVHVuVHJ1c3QgUm9vdCBDQTCCAiIw -DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMPN0/y9BFPdDCA61YguBUtB9YOCfvdZn56eY+hz -2vYGqU8ftPkLHzmMmiDQfgbU7DTZhrx1W4eI8NLZ1KMKsmwb60ksPqxd2JQDoOw05TDENX37Jk0b -bjBU2PWARZw5rZzJJQRNmpA+TkBuimvNKWfGzC3gdOgFVwpIUPp6Q9p+7FuaDmJ2/uqdHYVy7BG7 -NegfJ7/Boce7SBbdVtfMTqDhuazb1YMZGoXRlJfXyqNlC/M4+QKu3fZnz8k/9YosRxqZbwUN/dAd -gjH8KcwAWJeRTIAAHDOFli/LQcKLEITDCSSJH7UP2dl3RxiSlGBcx5kDPP73lad9UKGAwqmDrViW -VSHbhlnUr8a83YFuB9tgYv7sEG7aaAH0gxupPqJbI9dkxt/con3YS7qC0lH4Zr8GRuR5KiY2eY8f -Tpkdso8MDhz/yV3A/ZAQprE38806JG60hZC/gLkMjNWb1sjxVj8agIl6qeIbMlEsPvLfe/ZdeikZ -juXIvTZxi11Mwh0/rViizz1wTaZQmCXcI/m4WEEIcb9PuISgjwBUFfyRbVinljvrS5YnzWuioYas -DXxU5mZMZl+QviGaAkYt5IPCgLnPSz7ofzwB7I9ezX/SKEIBlYrilz0QIX32nRzFNKHsLA4KUiwS -VXAkPcvCFDVDXSdOvsC9qnyW5/yeYa1E0wCXAgMBAAGjYzBhMB0GA1UdDgQWBBQGmpsfU33x9aTI -04Y+oXNZtPdEITAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFAaamx9TffH1pMjThj6hc1m0 -90QhMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAqgVutt0Vyb+zxiD2BkewhpMl -0425yAA/l/VSJ4hxyXT968pk21vvHl26v9Hr7lxpuhbI87mP0zYuQEkHDVneixCwSQXi/5E/S7fd -Ao74gShczNxtr18UnH1YeA32gAm56Q6XKRm4t+v4FstVEuTGfbvE7Pi1HE4+Z7/FXxttbUcoqgRY -YdZ2vyJ/0Adqp2RT8JeNnYA/u8EH22Wv5psymsNUk8QcCMNE+3tjEUPRahphanltkE8pjkcFwRJp -adbGNjHh/PqAulxPxOu3Mqz4dWEX1xAZufHSCe96Qp1bWgvUxpVOKs7/B9dPfhgGiPEZtdmYu65x -xBzndFlY7wyJz4sfdZMaBBSSSFCp61cpABbjNhzI+L/wM9VBD8TMPN3pM0MBkRArHtG5Xc0yGYuP -jCB31yLEQtyEFpslbei0VXF/sHyz03FJuc9SpAQ/3D2gu68zngowYI7bnV2UqL1g52KAdoGDDIzM -MEZJ4gzSqK/rYXHv5yJiqfdcZGyfFoxnNidF9Ql7v/YQCvGwjVRDjAS6oz/v4jXH+XTgbzRB0L9z -ZVcg+ZtnemZoJE6AZb0QmQZZ8mWvuMZHu/2QeItBcy6vVR/cO5JyboTT0GFMDcx2V+IthSIVNg3r -AZ3r2OvEhJn7wAzMMujjd9qDRIueVSjAi1jTkD5OGwDxFa2DK5o= ------END CERTIFICATE----- - -HARICA TLS RSA Root CA 2021 -=========================== ------BEGIN CERTIFICATE----- -MIIFpDCCA4ygAwIBAgIQOcqTHO9D88aOk8f0ZIk4fjANBgkqhkiG9w0BAQsFADBsMQswCQYDVQQG -EwJHUjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9u -cyBDQTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBSU0EgUm9vdCBDQSAyMDIxMB4XDTIxMDIxOTEwNTUz -OFoXDTQ1MDIxMzEwNTUzN1owbDELMAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRl -bWljIGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgUlNB -IFJvb3QgQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAIvC569lmwVnlskN -JLnQDmT8zuIkGCyEf3dRywQRNrhe7Wlxp57kJQmXZ8FHws+RFjZiPTgE4VGC/6zStGndLuwRo0Xu -a2s7TL+MjaQenRG56Tj5eg4MmOIjHdFOY9TnuEFE+2uva9of08WRiFukiZLRgeaMOVig1mlDqa2Y -Ulhu2wr7a89o+uOkXjpFc5gH6l8Cct4MpbOfrqkdtx2z/IpZ525yZa31MJQjB/OCFks1mJxTuy/K -5FrZx40d/JiZ+yykgmvwKh+OC19xXFyuQnspiYHLA6OZyoieC0AJQTPb5lh6/a6ZcMBaD9YThnEv -dmn8kN3bLW7R8pv1GmuebxWMevBLKKAiOIAkbDakO/IwkfN4E8/BPzWr8R0RI7VDIp4BkrcYAuUR -0YLbFQDMYTfBKnya4dC6s1BG7oKsnTH4+yPiAwBIcKMJJnkVU2DzOFytOOqBAGMUuTNe3QvboEUH -GjMJ+E20pwKmafTCWQWIZYVWrkvL4N48fS0ayOn7H6NhStYqE613TBoYm5EPWNgGVMWX+Ko/IIqm -haZ39qb8HOLubpQzKoNQhArlT4b4UEV4AIHrW2jjJo3Me1xR9BQsQL4aYB16cmEdH2MtiKrOokWQ -CPxrvrNQKlr9qEgYRtaQQJKQCoReaDH46+0N0x3GfZkYVVYnZS6NRcUk7M7jAgMBAAGjQjBAMA8G -A1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFApII6ZgpJIKM+qTW8VX6iVNvRLuMA4GA1UdDwEB/wQE -AwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAPpBIqm5iFSVmewzVjIuJndftTgfvnNAUX15QvWiWkKQU -EapobQk1OUAJ2vQJLDSle1mESSmXdMgHHkdt8s4cUCbjnj1AUz/3f5Z2EMVGpdAgS1D0NTsY9FVq -QRtHBmg8uwkIYtlfVUKqrFOFrJVWNlar5AWMxajaH6NpvVMPxP/cyuN+8kyIhkdGGvMA9YCRotxD -QpSbIPDRzbLrLFPCU3hKTwSUQZqPJzLB5UkZv/HywouoCjkxKLR9YjYsTewfM7Z+d21+UPCfDtcR -j88YxeMn/ibvBZ3PzzfF0HvaO7AWhAw6k9a+F9sPPg4ZeAnHqQJyIkv3N3a6dcSFA1pj1bF1BcK5 -vZStjBWZp5N99sXzqnTPBIWUmAD04vnKJGW/4GKvyMX6ssmeVkjaef2WdhW+o45WxLM0/L5H9MG0 -qPzVMIho7suuyWPEdr6sOBjhXlzPrjoiUevRi7PzKzMHVIf6tLITe7pTBGIBnfHAT+7hOtSLIBD6 -Alfm78ELt5BGnBkpjNxvoEppaZS3JGWg/6w/zgH7IS79aPib8qXPMThcFarmlwDB31qlpzmq6YR/ -PFGoOtmUW4y/Twhx5duoXNTSpv4Ao8YWxw/ogM4cKGR0GQjTQuPOAF1/sdwTsOEFy9EgqoZ0njnn -kf3/W9b3raYvAwtt41dU63ZTGI0RmLo= ------END CERTIFICATE----- - -HARICA TLS ECC Root CA 2021 -=========================== ------BEGIN CERTIFICATE----- -MIICVDCCAdugAwIBAgIQZ3SdjXfYO2rbIvT/WeK/zjAKBggqhkjOPQQDAzBsMQswCQYDVQQGEwJH -UjE3MDUGA1UECgwuSGVsbGVuaWMgQWNhZGVtaWMgYW5kIFJlc2VhcmNoIEluc3RpdHV0aW9ucyBD -QTEkMCIGA1UEAwwbSEFSSUNBIFRMUyBFQ0MgUm9vdCBDQSAyMDIxMB4XDTIxMDIxOTExMDExMFoX -DTQ1MDIxMzExMDEwOVowbDELMAkGA1UEBhMCR1IxNzA1BgNVBAoMLkhlbGxlbmljIEFjYWRlbWlj -IGFuZCBSZXNlYXJjaCBJbnN0aXR1dGlvbnMgQ0ExJDAiBgNVBAMMG0hBUklDQSBUTFMgRUNDIFJv -b3QgQ0EgMjAyMTB2MBAGByqGSM49AgEGBSuBBAAiA2IABDgI/rGgltJ6rK9JOtDA4MM7KKrxcm1l -AEeIhPyaJmuqS7psBAqIXhfyVYf8MLA04jRYVxqEU+kw2anylnTDUR9YSTHMmE5gEYd103KUkE+b -ECUqqHgtvpBBWJAVcqeht6NCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUyRtTgRL+BNUW -0aq8mm+3oJUZbsowDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2cAMGQCMBHervjcToiwqfAi -rcJRQO9gcS3ujwLEXQNwSaSS6sUUiHCm0w2wqsosQJz76YJumgIwK0eaB8bRwoF8yguWGEEbo/Qw -CZ61IygNnxS2PFOiTAZpffpskcYqSUXm7LcT4Tps ------END CERTIFICATE----- - -Autoridad de Certificacion Firmaprofesional CIF A62634068 -========================================================= ------BEGIN CERTIFICATE----- -MIIGFDCCA/ygAwIBAgIIG3Dp0v+ubHEwDQYJKoZIhvcNAQELBQAwUTELMAkGA1UEBhMCRVMxQjBA -BgNVBAMMOUF1dG9yaWRhZCBkZSBDZXJ0aWZpY2FjaW9uIEZpcm1hcHJvZmVzaW9uYWwgQ0lGIEE2 -MjYzNDA2ODAeFw0xNDA5MjMxNTIyMDdaFw0zNjA1MDUxNTIyMDdaMFExCzAJBgNVBAYTAkVTMUIw -QAYDVQQDDDlBdXRvcmlkYWQgZGUgQ2VydGlmaWNhY2lvbiBGaXJtYXByb2Zlc2lvbmFsIENJRiBB -NjI2MzQwNjgwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDKlmuO6vj78aI14H9M2uDD -Utd9thDIAl6zQyrET2qyyhxdKJp4ERppWVevtSBC5IsP5t9bpgOSL/UR5GLXMnE42QQMcas9UX4P -B99jBVzpv5RvwSmCwLTaUbDBPLutN0pcyvFLNg4kq7/DhHf9qFD0sefGL9ItWY16Ck6WaVICqjaY -7Pz6FIMMNx/Jkjd/14Et5cS54D40/mf0PmbR0/RAz15iNA9wBj4gGFrO93IbJWyTdBSTo3OxDqqH -ECNZXyAFGUftaI6SEspd/NYrspI8IM/hX68gvqB2f3bl7BqGYTM+53u0P6APjqK5am+5hyZvQWyI -plD9amML9ZMWGxmPsu2bm8mQ9QEM3xk9Dz44I8kvjwzRAv4bVdZO0I08r0+k8/6vKtMFnXkIoctX -MbScyJCyZ/QYFpM6/EfY0XiWMR+6KwxfXZmtY4laJCB22N/9q06mIqqdXuYnin1oKaPnirjaEbsX -LZmdEyRG98Xi2J+Of8ePdG1asuhy9azuJBCtLxTa/y2aRnFHvkLfuwHb9H/TKI8xWVvTyQKmtFLK -bpf7Q8UIJm+K9Lv9nyiqDdVF8xM6HdjAeI9BZzwelGSuewvF6NkBiDkal4ZkQdU7hwxu+g/GvUgU -vzlN1J5Bto+WHWOWk9mVBngxaJ43BjuAiUVhOSPHG0SjFeUc+JIwuwIDAQABo4HvMIHsMB0GA1Ud -DgQWBBRlzeurNR4APn7VdMActHNHDhpkLzASBgNVHRMBAf8ECDAGAQH/AgEBMIGmBgNVHSAEgZ4w -gZswgZgGBFUdIAAwgY8wLwYIKwYBBQUHAgEWI2h0dHA6Ly93d3cuZmlybWFwcm9mZXNpb25hbC5j -b20vY3BzMFwGCCsGAQUFBwICMFAeTgBQAGEAcwBlAG8AIABkAGUAIABsAGEAIABCAG8AbgBhAG4A -bwB2AGEAIAA0ADcAIABCAGEAcgBjAGUAbABvAG4AYQAgADAAOAAwADEANzAOBgNVHQ8BAf8EBAMC -AQYwDQYJKoZIhvcNAQELBQADggIBAHSHKAIrdx9miWTtj3QuRhy7qPj4Cx2Dtjqn6EWKB7fgPiDL -4QjbEwj4KKE1soCzC1HA01aajTNFSa9J8OA9B3pFE1r/yJfY0xgsfZb43aJlQ3CTkBW6kN/oGbDb -LIpgD7dvlAceHabJhfa9NPhAeGIQcDq+fUs5gakQ1JZBu/hfHAsdCPKxsIl68veg4MSPi3i1O1il -I45PVf42O+AMt8oqMEEgtIDNrvx2ZnOorm7hfNoD6JQg5iKj0B+QXSBTFCZX2lSX3xZEEAEeiGaP -cjiT3SC3NL7X8e5jjkd5KAb881lFJWAiMxujX6i6KtoaPc1A6ozuBRWV1aUsIC+nmCjuRfzxuIgA -LI9C2lHVnOUTaHFFQ4ueCyE8S1wF3BqfmI7avSKecs2tCsvMo2ebKHTEm9caPARYpoKdrcd7b/+A -lun4jWq9GJAd/0kakFI3ky88Al2CdgtR5xbHV/g4+afNmyJU72OwFW1TZQNKXkqgsqeOSQBZONXH -9IBk9W6VULgRfhVwOEqwf9DEMnDAGf/JOC0ULGb0QkTmVXYbgBVX/8Cnp6o5qtjTcNAuuuuUavpf -NIbnYrX9ivAwhZTJryQCL2/W3Wf+47BVTwSYT6RBVuKT0Gro1vP7ZeDOdcQxWQzugsgMYDNKGbqE -ZycPvEJdvSRUDewdcAZfpLz6IHxV ------END CERTIFICATE----- - -vTrus ECC Root CA -================= ------BEGIN CERTIFICATE----- -MIICDzCCAZWgAwIBAgIUbmq8WapTvpg5Z6LSa6Q75m0c1towCgYIKoZIzj0EAwMwRzELMAkGA1UE -BhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBS -b290IENBMB4XDTE4MDczMTA3MjY0NFoXDTQzMDczMTA3MjY0NFowRzELMAkGA1UEBhMCQ04xHDAa -BgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xGjAYBgNVBAMTEXZUcnVzIEVDQyBSb290IENBMHYw -EAYHKoZIzj0CAQYFK4EEACIDYgAEZVBKrox5lkqqHAjDo6LN/llWQXf9JpRCux3NCNtzslt188+c -ToL0v/hhJoVs1oVbcnDS/dtitN9Ti72xRFhiQgnH+n9bEOf+QP3A2MMrMudwpremIFUde4BdS49n -TPEQo0IwQDAdBgNVHQ4EFgQUmDnNvtiyjPeyq+GtJK97fKHbH88wDwYDVR0TAQH/BAUwAwEB/zAO -BgNVHQ8BAf8EBAMCAQYwCgYIKoZIzj0EAwMDaAAwZQIwV53dVvHH4+m4SVBrm2nDb+zDfSXkV5UT -QJtS0zvzQBm8JsctBp61ezaf9SXUY2sAAjEA6dPGnlaaKsyh2j/IZivTWJwghfqrkYpwcBE4YGQL -YgmRWAD5Tfs0aNoJrSEGGJTO ------END CERTIFICATE----- - -vTrus Root CA -============= ------BEGIN CERTIFICATE----- -MIIFVjCCAz6gAwIBAgIUQ+NxE9izWRRdt86M/TX9b7wFjUUwDQYJKoZIhvcNAQELBQAwQzELMAkG -A1UEBhMCQ04xHDAaBgNVBAoTE2lUcnVzQ2hpbmEgQ28uLEx0ZC4xFjAUBgNVBAMTDXZUcnVzIFJv -b3QgQ0EwHhcNMTgwNzMxMDcyNDA1WhcNNDMwNzMxMDcyNDA1WjBDMQswCQYDVQQGEwJDTjEcMBoG -A1UEChMTaVRydXNDaGluYSBDby4sTHRkLjEWMBQGA1UEAxMNdlRydXMgUm9vdCBDQTCCAiIwDQYJ -KoZIhvcNAQEBBQADggIPADCCAgoCggIBAL1VfGHTuB0EYgWgrmy3cLRB6ksDXhA/kFocizuwZots -SKYcIrrVQJLuM7IjWcmOvFjai57QGfIvWcaMY1q6n6MLsLOaXLoRuBLpDLvPbmyAhykUAyyNJJrI -ZIO1aqwTLDPxn9wsYTwaP3BVm60AUn/PBLn+NvqcwBauYv6WTEN+VRS+GrPSbcKvdmaVayqwlHeF -XgQPYh1jdfdr58tbmnDsPmcF8P4HCIDPKNsFxhQnL4Z98Cfe/+Z+M0jnCx5Y0ScrUw5XSmXX+6KA -YPxMvDVTAWqXcoKv8R1w6Jz1717CbMdHflqUhSZNO7rrTOiwCcJlwp2dCZtOtZcFrPUGoPc2BX70 -kLJrxLT5ZOrpGgrIDajtJ8nU57O5q4IikCc9Kuh8kO+8T/3iCiSn3mUkpF3qwHYw03dQ+A0Em5Q2 -AXPKBlim0zvc+gRGE1WKyURHuFE5Gi7oNOJ5y1lKCn+8pu8fA2dqWSslYpPZUxlmPCdiKYZNpGvu -/9ROutW04o5IWgAZCfEF2c6Rsffr6TlP9m8EQ5pV9T4FFL2/s1m02I4zhKOQUqqzApVg+QxMaPnu -1RcN+HFXtSXkKe5lXa/R7jwXC1pDxaWG6iSe4gUH3DRCEpHWOXSuTEGC2/KmSNGzm/MzqvOmwMVO -9fSddmPmAsYiS8GVP1BkLFTltvA8Kc9XAgMBAAGjQjBAMB0GA1UdDgQWBBRUYnBj8XWEQ1iO0RYg -scasGrz2iTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOC -AgEAKbqSSaet8PFww+SX8J+pJdVrnjT+5hpk9jprUrIQeBqfTNqK2uwcN1LgQkv7bHbKJAs5EhWd -nxEt/Hlk3ODg9d3gV8mlsnZwUKT+twpw1aA08XXXTUm6EdGz2OyC/+sOxL9kLX1jbhd47F18iMjr -jld22VkE+rxSH0Ws8HqA7Oxvdq6R2xCOBNyS36D25q5J08FsEhvMKar5CKXiNxTKsbhm7xqC5PD4 -8acWabfbqWE8n/Uxy+QARsIvdLGx14HuqCaVvIivTDUHKgLKeBRtRytAVunLKmChZwOgzoy8sHJn -xDHO2zTlJQNgJXtxmOTAGytfdELSS8VZCAeHvsXDf+eW2eHcKJfWjwXj9ZtOyh1QRwVTsMo554Wg -icEFOwE30z9J4nfrI8iIZjs9OXYhRvHsXyO466JmdXTBQPfYaJqT4i2pLr0cox7IdMakLXogqzu4 -sEb9b91fUlV1YvCXoHzXOP0l382gmxDPi7g4Xl7FtKYCNqEeXxzP4padKar9mK5S4fNBUvupLnKW -nyfjqnN9+BojZns7q2WwMgFLFT49ok8MKzWixtlnEjUwzXYuFrOZnk1PTi07NEPhmg4NpGaXutIc -SkwsKouLgU9xGqndXHt7CMUADTdA43x7VF8vhV929vensBxXVsFy6K2ir40zSbofitzmdHxghm+H -l3s= ------END CERTIFICATE----- - -ISRG Root X2 -============ ------BEGIN CERTIFICATE----- -MIICGzCCAaGgAwIBAgIQQdKd0XLq7qeAwSxs6S+HUjAKBggqhkjOPQQDAzBPMQswCQYDVQQGEwJV -UzEpMCcGA1UEChMgSW50ZXJuZXQgU2VjdXJpdHkgUmVzZWFyY2ggR3JvdXAxFTATBgNVBAMTDElT -UkcgUm9vdCBYMjAeFw0yMDA5MDQwMDAwMDBaFw00MDA5MTcxNjAwMDBaME8xCzAJBgNVBAYTAlVT -MSkwJwYDVQQKEyBJbnRlcm5ldCBTZWN1cml0eSBSZXNlYXJjaCBHcm91cDEVMBMGA1UEAxMMSVNS -RyBSb290IFgyMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEzZvVn4CDCuwJSvMWSj5cz3es3mcFDR0H -ttwW+1qLFNvicWDEukWVEYmO6gbf9yoWHKS5xcUy4APgHoIYOIvXRdgKam7mAHf7AlF9ItgKbppb -d9/w+kHsOdx1ymgHDB/qo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNV -HQ4EFgQUfEKWrt5LSDv6kviejM9ti6lyN5UwCgYIKoZIzj0EAwMDaAAwZQIwe3lORlCEwkSHRhtF -cP9Ymd70/aTSVaYgLXTWNLxBo1BfASdWtL4ndQavEi51mI38AjEAi/V3bNTIZargCyzuFJ0nN6T5 -U6VR5CmD1/iQMVtCnwr1/q4AaOeMSQ+2b1tbFfLn ------END CERTIFICATE----- - -HiPKI Root CA - G1 -================== ------BEGIN CERTIFICATE----- -MIIFajCCA1KgAwIBAgIQLd2szmKXlKFD6LDNdmpeYDANBgkqhkiG9w0BAQsFADBPMQswCQYDVQQG -EwJUVzEjMCEGA1UECgwaQ2h1bmdod2EgVGVsZWNvbSBDby4sIEx0ZC4xGzAZBgNVBAMMEkhpUEtJ -IFJvb3QgQ0EgLSBHMTAeFw0xOTAyMjIwOTQ2MDRaFw0zNzEyMzExNTU5NTlaME8xCzAJBgNVBAYT -AlRXMSMwIQYDVQQKDBpDaHVuZ2h3YSBUZWxlY29tIENvLiwgTHRkLjEbMBkGA1UEAwwSSGlQS0kg -Um9vdCBDQSAtIEcxMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA9B5/UnMyDHPkvRN0 -o9QwqNCuS9i233VHZvR85zkEHmpwINJaR3JnVfSl6J3VHiGh8Ge6zCFovkRTv4354twvVcg3Px+k -wJyz5HdcoEb+d/oaoDjq7Zpy3iu9lFc6uux55199QmQ5eiY29yTw1S+6lZgRZq2XNdZ1AYDgr/SE -YYwNHl98h5ZeQa/rh+r4XfEuiAU+TCK72h8q3VJGZDnzQs7ZngyzsHeXZJzA9KMuH5UHsBffMNsA -GJZMoYFL3QRtU6M9/Aes1MU3guvklQgZKILSQjqj2FPseYlgSGDIcpJQ3AOPgz+yQlda22rpEZfd -hSi8MEyr48KxRURHH+CKFgeW0iEPU8DtqX7UTuybCeyvQqww1r/REEXgphaypcXTT3OUM3ECoWqj -1jOXTyFjHluP2cFeRXF3D4FdXyGarYPM+l7WjSNfGz1BryB1ZlpK9p/7qxj3ccC2HTHsOyDry+K4 -9a6SsvfhhEvyovKTmiKe0xRvNlS9H15ZFblzqMF8b3ti6RZsR1pl8w4Rm0bZ/W3c1pzAtH2lsN0/ -Vm+h+fbkEkj9Bn8SV7apI09bA8PgcSojt/ewsTu8mL3WmKgMa/aOEmem8rJY5AIJEzypuxC00jBF -8ez3ABHfZfjcK0NVvxaXxA/VLGGEqnKG/uY6fsI/fe78LxQ+5oXdUG+3Se0CAwEAAaNCMEAwDwYD -VR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ncX+l6o/vY9cdVouslGDDjYr7AwDgYDVR0PAQH/BAQD -AgGGMA0GCSqGSIb3DQEBCwUAA4ICAQBQUfB13HAE4/+qddRxosuej6ip0691x1TPOhwEmSKsxBHi -7zNKpiMdDg1H2DfHb680f0+BazVP6XKlMeJ45/dOlBhbQH3PayFUhuaVevvGyuqcSE5XCV0vrPSl -tJczWNWseanMX/mF+lLFjfiRFOs6DRfQUsJ748JzjkZ4Bjgs6FzaZsT0pPBWGTMpWmWSBUdGSquE -wx4noR8RkpkndZMPvDY7l1ePJlsMu5wP1G4wB9TcXzZoZjmDlicmisjEOf6aIW/Vcobpf2Lll07Q -JNBAsNB1CI69aO4I1258EHBGG3zgiLKecoaZAeO/n0kZtCW+VmWuF2PlHt/o/0elv+EmBYTksMCv -5wiZqAxeJoBF1PhoL5aPruJKHJwWDBNvOIf2u8g0X5IDUXlwpt/L9ZlNec1OvFefQ05rLisY+Gpz -jLrFNe85akEez3GoorKGB1s6yeHvP2UEgEcyRHCVTjFnanRbEEV16rCf0OY1/k6fi8wrkkVbbiVg -hUbN0aqwdmaTd5a+g744tiROJgvM7XpWGuDpWsZkrUx6AEhEL7lAuxM+vhV4nYWBSipX3tUZQ9rb -yltHhoMLP7YNdnhzeSJesYAfz77RP1YQmCuVh6EfnWQUYDksswBVLuT1sw5XxJFBAJw/6KXf6vb/ -yPCtbVKoF6ubYfwSUTXkJf2vqmqGOQ== ------END CERTIFICATE----- - -GlobalSign ECC Root CA - R4 -=========================== ------BEGIN CERTIFICATE----- -MIIB3DCCAYOgAwIBAgINAgPlfvU/k/2lCSGypjAKBggqhkjOPQQDAjBQMSQwIgYDVQQLExtHbG9i -YWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkds -b2JhbFNpZ24wHhcNMTIxMTEzMDAwMDAwWhcNMzgwMTE5MDMxNDA3WjBQMSQwIgYDVQQLExtHbG9i -YWxTaWduIEVDQyBSb290IENBIC0gUjQxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkds -b2JhbFNpZ24wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAAS4xnnTj2wlDp8uORkcA6SumuU5BwkW -ymOxuYb4ilfBV85C+nOh92VC/x7BALJucw7/xyHlGKSq2XE/qNS5zowdo0IwQDAOBgNVHQ8BAf8E -BAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUVLB7rUW44kB/+wpu+74zyTyjhNUwCgYI -KoZIzj0EAwIDRwAwRAIgIk90crlgr/HmnKAWBVBfw147bmF0774BxL4YSFlhgjICICadVGNA3jdg -UM/I2O2dgq43mLyjj0xMqTQrbO/7lZsm ------END CERTIFICATE----- - -GTS Root R1 -=========== ------BEGIN CERTIFICATE----- -MIIFVzCCAz+gAwIBAgINAgPlk28xsBNJiGuiFzANBgkqhkiG9w0BAQwFADBHMQswCQYDVQQGEwJV -UzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3Qg -UjEwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UE -ChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjEwggIiMA0G -CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC2EQKLHuOhd5s73L+UPreVp0A8of2C+X0yBoJx9vaM -f/vo27xqLpeXo4xL+Sv2sfnOhB2x+cWX3u+58qPpvBKJXqeqUqv4IyfLpLGcY9vXmX7wCl7raKb0 -xlpHDU0QM+NOsROjyBhsS+z8CZDfnWQpJSMHobTSPS5g4M/SCYe7zUjwTcLCeoiKu7rPWRnWr4+w -B7CeMfGCwcDfLqZtbBkOtdh+JhpFAz2weaSUKK0PfyblqAj+lug8aJRT7oM6iCsVlgmy4HqMLnXW -nOunVmSPlk9orj2XwoSPwLxAwAtcvfaHszVsrBhQf4TgTM2S0yDpM7xSma8ytSmzJSq0SPly4cpk -9+aCEI3oncKKiPo4Zor8Y/kB+Xj9e1x3+naH+uzfsQ55lVe0vSbv1gHR6xYKu44LtcXFilWr06zq -kUspzBmkMiVOKvFlRNACzqrOSbTqn3yDsEB750Orp2yjj32JgfpMpf/VjsPOS+C12LOORc92wO1A -K/1TD7Cn1TsNsYqiA94xrcx36m97PtbfkSIS5r762DL8EGMUUXLeXdYWk70paDPvOmbsB4om3xPX -V2V4J95eSRQAogB/mqghtqmxlbCluQ0WEdrHbEg8QOB+DVrNVjzRlwW5y0vtOUucxD/SVRNuJLDW -cfr0wbrM7Rv1/oFB2ACYPTrIrnqYNxgFlQIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0T -AQH/BAUwAwEB/zAdBgNVHQ4EFgQU5K8rJnEaK0gnhS9SZizv8IkTcT4wDQYJKoZIhvcNAQEMBQAD -ggIBAJ+qQibbC5u+/x6Wki4+omVKapi6Ist9wTrYggoGxval3sBOh2Z5ofmmWJyq+bXmYOfg6LEe -QkEzCzc9zolwFcq1JKjPa7XSQCGYzyI0zzvFIoTgxQ6KfF2I5DUkzps+GlQebtuyh6f88/qBVRRi -ClmpIgUxPoLW7ttXNLwzldMXG+gnoot7TiYaelpkttGsN/H9oPM47HLwEXWdyzRSjeZ2axfG34ar -J45JK3VmgRAhpuo+9K4l/3wV3s6MJT/KYnAK9y8JZgfIPxz88NtFMN9iiMG1D53Dn0reWVlHxYci -NuaCp+0KueIHoI17eko8cdLiA6EfMgfdG+RCzgwARWGAtQsgWSl4vflVy2PFPEz0tv/bal8xa5me -LMFrUKTX5hgUvYU/Z6tGn6D/Qqc6f1zLXbBwHSs09dR2CQzreExZBfMzQsNhFRAbd03OIozUhfJF -fbdT6u9AWpQKXCBfTkBdYiJ23//OYb2MI3jSNwLgjt7RETeJ9r/tSQdirpLsQBqvFAnZ0E6yove+ -7u7Y/9waLd64NnHi/Hm3lCXRSHNboTXns5lndcEZOitHTtNCjv0xyBZm2tIMPNuzjsmhDYAPexZ3 -FL//2wmUspO8IFgV6dtxQ/PeEMMA3KgqlbbC1j+Qa3bbbP6MvPJwNQzcmRk13NfIRmPVNnGuV/u3 -gm3c ------END CERTIFICATE----- - -GTS Root R2 -=========== ------BEGIN CERTIFICATE----- -MIIFVzCCAz+gAwIBAgINAgPlrsWNBCUaqxElqjANBgkqhkiG9w0BAQwFADBHMQswCQYDVQQGEwJV -UzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3Qg -UjIwHhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UE -ChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjIwggIiMA0G -CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDO3v2m++zsFDQ8BwZabFn3GTXd98GdVarTzTukk3Lv -CvptnfbwhYBboUhSnznFt+4orO/LdmgUud+tAWyZH8QiHZ/+cnfgLFuv5AS/T3KgGjSY6Dlo7JUl -e3ah5mm5hRm9iYz+re026nO8/4Piy33B0s5Ks40FnotJk9/BW9BuXvAuMC6C/Pq8tBcKSOWIm8Wb -a96wyrQD8Nr0kLhlZPdcTK3ofmZemde4wj7I0BOdre7kRXuJVfeKH2JShBKzwkCX44ofR5GmdFrS -+LFjKBC4swm4VndAoiaYecb+3yXuPuWgf9RhD1FLPD+M2uFwdNjCaKH5wQzpoeJ/u1U8dgbuak7M -kogwTZq9TwtImoS1mKPV+3PBV2HdKFZ1E66HjucMUQkQdYhMvI35ezzUIkgfKtzra7tEscszcTJG -r61K8YzodDqs5xoic4DSMPclQsciOzsSrZYuxsN2B6ogtzVJV+mSSeh2FnIxZyuWfoqjx5RWIr9q -S34BIbIjMt/kmkRtWVtd9QCgHJvGeJeNkP+byKq0rxFROV7Z+2et1VsRnTKaG73VululycslaVNV -J1zgyjbLiGH7HrfQy+4W+9OmTN6SpdTi3/UGVN4unUu0kzCqgc7dGtxRcw1PcOnlthYhGXmy5okL -dWTK1au8CcEYof/UVKGFPP0UJAOyh9OktwIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0T -AQH/BAUwAwEB/zAdBgNVHQ4EFgQUu//KjiOfT5nK2+JopqUVJxce2Q4wDQYJKoZIhvcNAQEMBQAD -ggIBAB/Kzt3HvqGf2SdMC9wXmBFqiN495nFWcrKeGk6c1SuYJF2ba3uwM4IJvd8lRuqYnrYb/oM8 -0mJhwQTtzuDFycgTE1XnqGOtjHsB/ncw4c5omwX4Eu55MaBBRTUoCnGkJE+M3DyCB19m3H0Q/gxh -swWV7uGugQ+o+MePTagjAiZrHYNSVc61LwDKgEDg4XSsYPWHgJ2uNmSRXbBoGOqKYcl3qJfEycel -/FVL8/B/uWU9J2jQzGv6U53hkRrJXRqWbTKH7QMgyALOWr7Z6v2yTcQvG99fevX4i8buMTolUVVn -jWQye+mew4K6Ki3pHrTgSAai/GevHyICc/sgCq+dVEuhzf9gR7A/Xe8bVr2XIZYtCtFenTgCR2y5 -9PYjJbigapordwj6xLEokCZYCDzifqrXPW+6MYgKBesntaFJ7qBFVHvmJ2WZICGoo7z7GJa7Um8M -7YNRTOlZ4iBgxcJlkoKM8xAfDoqXvneCbT+PHV28SSe9zE8P4c52hgQjxcCMElv924SgJPFI/2R8 -0L5cFtHvma3AH/vLrrw4IgYmZNralw4/KBVEqE8AyvCazM90arQ+POuV7LXTWtiBmelDGDfrs7vR -WGJB82bSj6p4lVQgw1oudCvV0b4YacCs1aTPObpRhANl6WLAYv7YTVWW4tAR+kg0Eeye7QUd5MjW -HYbL ------END CERTIFICATE----- - -GTS Root R3 -=========== ------BEGIN CERTIFICATE----- -MIICCTCCAY6gAwIBAgINAgPluILrIPglJ209ZjAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJVUzEi -MCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMw -HhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZ -R29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjMwdjAQBgcqhkjO -PQIBBgUrgQQAIgNiAAQfTzOHMymKoYTey8chWEGJ6ladK0uFxh1MJ7x/JlFyb+Kf1qPKzEUURout -736GjOyxfi//qXGdGIRFBEFVbivqJn+7kAHjSxm65FSWRQmx1WyRRK2EE46ajA2ADDL24CejQjBA -MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTB8Sa6oC2uhYHP0/Eq -Er24Cmf9vDAKBggqhkjOPQQDAwNpADBmAjEA9uEglRR7VKOQFhG/hMjqb2sXnh5GmCCbn9MN2azT -L818+FsuVbu/3ZL3pAzcMeGiAjEA/JdmZuVDFhOD3cffL74UOO0BzrEXGhF16b0DjyZ+hOXJYKaV -11RZt+cRLInUue4X ------END CERTIFICATE----- - -GTS Root R4 -=========== ------BEGIN CERTIFICATE----- -MIICCTCCAY6gAwIBAgINAgPlwGjvYxqccpBQUjAKBggqhkjOPQQDAzBHMQswCQYDVQQGEwJVUzEi -MCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQw -HhcNMTYwNjIyMDAwMDAwWhcNMzYwNjIyMDAwMDAwWjBHMQswCQYDVQQGEwJVUzEiMCAGA1UEChMZ -R29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEUMBIGA1UEAxMLR1RTIFJvb3QgUjQwdjAQBgcqhkjO -PQIBBgUrgQQAIgNiAATzdHOnaItgrkO4NcWBMHtLSZ37wWHO5t5GvWvVYRg1rkDdc/eJkTBa6zzu -hXyiQHY7qca4R9gq55KRanPpsXI5nymfopjTX15YhmUPoYRlBtHci8nHc8iMai/lxKvRHYqjQjBA -MA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSATNbrdP9JNqPV2Py1 -PsVq8JQdjDAKBggqhkjOPQQDAwNpADBmAjEA6ED/g94D9J+uHXqnLrmvT/aDHQ4thQEd0dlq7A/C -r8deVl5c1RxYIigL9zC2L7F8AjEA8GE8p/SgguMh1YQdc4acLa/KNJvxn7kjNuK8YAOdgLOaVsjh -4rsUecrNIdSUtUlD ------END CERTIFICATE----- - -Telia Root CA v2 -================ ------BEGIN CERTIFICATE----- -MIIFdDCCA1ygAwIBAgIPAWdfJ9b+euPkrL4JWwWeMA0GCSqGSIb3DQEBCwUAMEQxCzAJBgNVBAYT -AkZJMRowGAYDVQQKDBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2 -MjAeFw0xODExMjkxMTU1NTRaFw00MzExMjkxMTU1NTRaMEQxCzAJBgNVBAYTAkZJMRowGAYDVQQK -DBFUZWxpYSBGaW5sYW5kIE95ajEZMBcGA1UEAwwQVGVsaWEgUm9vdCBDQSB2MjCCAiIwDQYJKoZI -hvcNAQEBBQADggIPADCCAgoCggIBALLQPwe84nvQa5n44ndp586dpAO8gm2h/oFlH0wnrI4AuhZ7 -6zBqAMCzdGh+sq/H1WKzej9Qyow2RCRj0jbpDIX2Q3bVTKFgcmfiKDOlyzG4OiIjNLh9vVYiQJ3q -9HsDrWj8soFPmNB06o3lfc1jw6P23pLCWBnglrvFxKk9pXSW/q/5iaq9lRdU2HhE8Qx3FZLgmEKn -pNaqIJLNwaCzlrI6hEKNfdWV5Nbb6WLEWLN5xYzTNTODn3WhUidhOPFZPY5Q4L15POdslv5e2QJl -tI5c0BE0312/UqeBAMN/mUWZFdUXyApT7GPzmX3MaRKGwhfwAZ6/hLzRUssbkmbOpFPlob/E2wnW -5olWK8jjfN7j/4nlNW4o6GwLI1GpJQXrSPjdscr6bAhR77cYbETKJuFzxokGgeWKrLDiKca5JLNr -RBH0pUPCTEPlcDaMtjNXepUugqD0XBCzYYP2AgWGLnwtbNwDRm41k9V6lS/eINhbfpSQBGq6WT0E -BXWdN6IOLj3rwaRSg/7Qa9RmjtzG6RJOHSpXqhC8fF6CfaamyfItufUXJ63RDolUK5X6wK0dmBR4 -M0KGCqlztft0DbcbMBnEWg4cJ7faGND/isgFuvGqHKI3t+ZIpEYslOqodmJHixBTB0hXbOKSTbau -BcvcwUpej6w9GU7C7WB1K9vBykLVAgMBAAGjYzBhMB8GA1UdIwQYMBaAFHKs5DN5qkWH9v2sHZ7W -xy+G2CQ5MB0GA1UdDgQWBBRyrOQzeapFh/b9rB2e1scvhtgkOTAOBgNVHQ8BAf8EBAMCAQYwDwYD -VR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAgEAoDtZpwmUPjaE0n4vOaWWl/oRrfxn83EJ -8rKJhGdEr7nv7ZbsnGTbMjBvZ5qsfl+yqwE2foH65IRe0qw24GtixX1LDoJt0nZi0f6X+J8wfBj5 -tFJ3gh1229MdqfDBmgC9bXXYfef6xzijnHDoRnkDry5023X4blMMA8iZGok1GTzTyVR8qPAs5m4H -eW9q4ebqkYJpCh3DflminmtGFZhb069GHWLIzoBSSRE/yQQSwxN8PzuKlts8oB4KtItUsiRnDe+C -y748fdHif64W1lZYudogsYMVoe+KTTJvQS8TUoKU1xrBeKJR3Stwbbca+few4GeXVtt8YVMJAygC -QMez2P2ccGrGKMOF6eLtGpOg3kuYooQ+BXcBlj37tCAPnHICehIv1aO6UXivKitEZU61/Qrowc15 -h2Er3oBXRb9n8ZuRXqWk7FlIEA04x7D6w0RtBPV4UBySllva9bguulvP5fBqnUsvWHMtTy3EHD70 -sz+rFQ47GUGKpMFXEmZxTPpT41frYpUJnlTd0cI8Vzy9OK2YZLe4A5pTVmBds9hCG1xLEooc6+t9 -xnppxyd/pPiL8uSUZodL6ZQHCRJ5irLrdATczvREWeAWysUsWNc8e89ihmpQfTU2Zqf7N+cox9jQ -raVplI/owd8k+BsHMYeB2F326CjYSlKArBPuUBQemMc= ------END CERTIFICATE----- - -D-TRUST BR Root CA 1 2020 -========================= ------BEGIN CERTIFICATE----- -MIIC2zCCAmCgAwIBAgIQfMmPK4TX3+oPyWWa00tNljAKBggqhkjOPQQDAzBIMQswCQYDVQQGEwJE -RTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEJSIFJvb3QgQ0EgMSAy -MDIwMB4XDTIwMDIxMTA5NDUwMFoXDTM1MDIxMTA5NDQ1OVowSDELMAkGA1UEBhMCREUxFTATBgNV -BAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDEgMjAyMDB2MBAG -ByqGSM49AgEGBSuBBAAiA2IABMbLxyjR+4T1mu9CFCDhQ2tuda38KwOE1HaTJddZO0Flax7mNCq7 -dPYSzuht56vkPE4/RAiLzRZxy7+SmfSk1zxQVFKQhYN4lGdnoxwJGT11NIXe7WB9xwy0QVK5buXu -QqOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFHOREKv/VbNafAkl1bK6CKBrqx9t -MA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6gPKA6hjhodHRwOi8vY3JsLmQtdHJ1c3Qu -bmV0L2NybC9kLXRydXN0X2JyX3Jvb3RfY2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVj -dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwQlIlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxP -PUQtVHJ1c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjOPQQD -AwNpADBmAjEAlJAtE/rhY/hhY+ithXhUkZy4kzg+GkHaQBZTQgjKL47xPoFWwKrY7RjEsK70Pvom -AjEA8yjixtsrmfu3Ubgko6SUeho/5jbiA1czijDLgsfWFBHVdWNbFJWcHwHP2NVypw87 ------END CERTIFICATE----- - -D-TRUST EV Root CA 1 2020 -========================= ------BEGIN CERTIFICATE----- -MIIC2zCCAmCgAwIBAgIQXwJB13qHfEwDo6yWjfv/0DAKBggqhkjOPQQDAzBIMQswCQYDVQQGEwJE -RTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEVWIFJvb3QgQ0EgMSAy -MDIwMB4XDTIwMDIxMTEwMDAwMFoXDTM1MDIxMTA5NTk1OVowSDELMAkGA1UEBhMCREUxFTATBgNV -BAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBFViBSb290IENBIDEgMjAyMDB2MBAG -ByqGSM49AgEGBSuBBAAiA2IABPEL3YZDIBnfl4XoIkqbz52Yv7QFJsnL46bSj8WeeHsxiamJrSc8 -ZRCC/N/DnU7wMyPE0jL1HLDfMxddxfCxivnvubcUyilKwg+pf3VlSSowZ/Rk99Yad9rDwpdhQntJ -raOCAQ0wggEJMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFH8QARY3OqQo5FD4pPfsazK2/umL -MA4GA1UdDwEB/wQEAwIBBjCBxgYDVR0fBIG+MIG7MD6gPKA6hjhodHRwOi8vY3JsLmQtdHJ1c3Qu -bmV0L2NybC9kLXRydXN0X2V2X3Jvb3RfY2FfMV8yMDIwLmNybDB5oHegdYZzbGRhcDovL2RpcmVj -dG9yeS5kLXRydXN0Lm5ldC9DTj1ELVRSVVNUJTIwRVYlMjBSb290JTIwQ0ElMjAxJTIwMjAyMCxP -PUQtVHJ1c3QlMjBHbWJILEM9REU/Y2VydGlmaWNhdGVyZXZvY2F0aW9ubGlzdDAKBggqhkjOPQQD -AwNpADBmAjEAyjzGKnXCXnViOTYAYFqLwZOZzNnbQTs7h5kXO9XMT8oi96CAy/m0sRtW9XLS/BnR -AjEAkfcwkz8QRitxpNA7RJvAKQIFskF3UfN5Wp6OFKBOQtJbgfM0agPnIjhQW+0ZT0MW ------END CERTIFICATE----- - -DigiCert TLS ECC P384 Root G5 -============================= ------BEGIN CERTIFICATE----- -MIICGTCCAZ+gAwIBAgIQCeCTZaz32ci5PhwLBCou8zAKBggqhkjOPQQDAzBOMQswCQYDVQQGEwJV -UzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJjAkBgNVBAMTHURpZ2lDZXJ0IFRMUyBFQ0MgUDM4 -NCBSb290IEc1MB4XDTIxMDExNTAwMDAwMFoXDTQ2MDExNDIzNTk1OVowTjELMAkGA1UEBhMCVVMx -FzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMSYwJAYDVQQDEx1EaWdpQ2VydCBUTFMgRUNDIFAzODQg -Um9vdCBHNTB2MBAGByqGSM49AgEGBSuBBAAiA2IABMFEoc8Rl1Ca3iOCNQfN0MsYndLxf3c1Tzvd -lHJS7cI7+Oz6e2tYIOyZrsn8aLN1udsJ7MgT9U7GCh1mMEy7H0cKPGEQQil8pQgO4CLp0zVozptj -n4S1mU1YoI71VOeVyaNCMEAwHQYDVR0OBBYEFMFRRVBZqz7nLFr6ICISB4CIfBFqMA4GA1UdDwEB -/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MAoGCCqGSM49BAMDA2gAMGUCMQCJao1H5+z8blUD2Wds -Jk6Dxv3J+ysTvLd6jLRl0mlpYxNjOyZQLgGheQaRnUi/wr4CMEfDFXuxoJGZSZOoPHzoRgaLLPIx -AJSdYsiJvRmEFOml+wG4DXZDjC5Ty3zfDBeWUA== ------END CERTIFICATE----- - -DigiCert TLS RSA4096 Root G5 -============================ ------BEGIN CERTIFICATE----- -MIIFZjCCA06gAwIBAgIQCPm0eKj6ftpqMzeJ3nzPijANBgkqhkiG9w0BAQwFADBNMQswCQYDVQQG -EwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0 -MDk2IFJvb3QgRzUwHhcNMjEwMTE1MDAwMDAwWhcNNDYwMTE0MjM1OTU5WjBNMQswCQYDVQQGEwJV -UzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xJTAjBgNVBAMTHERpZ2lDZXJ0IFRMUyBSU0E0MDk2 -IFJvb3QgRzUwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCz0PTJeRGd/fxmgefM1eS8 -7IE+ajWOLrfn3q/5B03PMJ3qCQuZvWxX2hhKuHisOjmopkisLnLlvevxGs3npAOpPxG02C+JFvuU -AT27L/gTBaF4HI4o4EXgg/RZG5Wzrn4DReW+wkL+7vI8toUTmDKdFqgpwgscONyfMXdcvyej/Ces -tyu9dJsXLfKB2l2w4SMXPohKEiPQ6s+d3gMXsUJKoBZMpG2T6T867jp8nVid9E6P/DsjyG244gXa -zOvswzH016cpVIDPRFtMbzCe88zdH5RDnU1/cHAN1DrRN/BsnZvAFJNY781BOHW8EwOVfH/jXOnV -DdXifBBiqmvwPXbzP6PosMH976pXTayGpxi0KcEsDr9kvimM2AItzVwv8n/vFfQMFawKsPHTDU9q -TXeXAaDxZre3zu/O7Oyldcqs4+Fj97ihBMi8ez9dLRYiVu1ISf6nL3kwJZu6ay0/nTvEF+cdLvvy -z6b84xQslpghjLSR6Rlgg/IwKwZzUNWYOwbpx4oMYIwo+FKbbuH2TbsGJJvXKyY//SovcfXWJL5/ -MZ4PbeiPT02jP/816t9JXkGPhvnxd3lLG7SjXi/7RgLQZhNeXoVPzthwiHvOAbWWl9fNff2C+MIk -wcoBOU+NosEUQB+cZtUMCUbW8tDRSHZWOkPLtgoRObqME2wGtZ7P6wIDAQABo0IwQDAdBgNVHQ4E -FgQUUTMc7TZArxfTJc1paPKvTiM+s0EwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8w -DQYJKoZIhvcNAQEMBQADggIBAGCmr1tfV9qJ20tQqcQjNSH/0GEwhJG3PxDPJY7Jv0Y02cEhJhxw -GXIeo8mH/qlDZJY6yFMECrZBu8RHANmfGBg7sg7zNOok992vIGCukihfNudd5N7HPNtQOa27PShN -lnx2xlv0wdsUpasZYgcYQF+Xkdycx6u1UQ3maVNVzDl92sURVXLFO4uJ+DQtpBflF+aZfTCIITfN -MBc9uPK8qHWgQ9w+iUuQrm0D4ByjoJYJu32jtyoQREtGBzRj7TG5BO6jm5qu5jF49OokYTurWGT/ -u4cnYiWB39yhL/btp/96j1EuMPikAdKFOV8BmZZvWltwGUb+hmA+rYAQCd05JS9Yf7vSdPD3Rh9G -OUrYU9DzLjtxpdRv/PNn5AeP3SYZ4Y1b+qOTEZvpyDrDVWiakuFSdjjo4bq9+0/V77PnSIMx8IIh -47a+p6tv75/fTM8BuGJqIz3nCU2AG3swpMPdB380vqQmsvZB6Akd4yCYqjdP//fx4ilwMUc/dNAU -FvohigLVigmUdy7yWSiLfFCSCmZ4OIN1xLVaqBHG5cGdZlXPU8Sv13WFqUITVuwhd4GTWgzqltlJ -yqEI8pc7bZsEGCREjnwB8twl2F6GmrE52/WRMmrRpnCKovfepEWFJqgejF0pW8hL2JpqA15w8oVP -bEtoL8pU9ozaMv7Da4M/OMZ+ ------END CERTIFICATE----- - -Certainly Root R1 -================= ------BEGIN CERTIFICATE----- -MIIFRzCCAy+gAwIBAgIRAI4P+UuQcWhlM1T01EQ5t+AwDQYJKoZIhvcNAQELBQAwPTELMAkGA1UE -BhMCVVMxEjAQBgNVBAoTCUNlcnRhaW5seTEaMBgGA1UEAxMRQ2VydGFpbmx5IFJvb3QgUjEwHhcN -MjEwNDAxMDAwMDAwWhcNNDYwNDAxMDAwMDAwWjA9MQswCQYDVQQGEwJVUzESMBAGA1UEChMJQ2Vy -dGFpbmx5MRowGAYDVQQDExFDZXJ0YWlubHkgUm9vdCBSMTCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBANA21B/q3avk0bbm+yLA3RMNansiExyXPGhjZjKcA7WNpIGD2ngwEc/csiu+kr+O -5MQTvqRoTNoCaBZ0vrLdBORrKt03H2As2/X3oXyVtwxwhi7xOu9S98zTm/mLvg7fMbedaFySpvXl -8wo0tf97ouSHocavFwDvA5HtqRxOcT3Si2yJ9HiG5mpJoM610rCrm/b01C7jcvk2xusVtyWMOvwl -DbMicyF0yEqWYZL1LwsYpfSt4u5BvQF5+paMjRcCMLT5r3gajLQ2EBAHBXDQ9DGQilHFhiZ5shGI -XsXwClTNSaa/ApzSRKft43jvRl5tcdF5cBxGX1HpyTfcX35pe0HfNEXgO4T0oYoKNp43zGJS4YkN -KPl6I7ENPT2a/Z2B7yyQwHtETrtJ4A5KVpK8y7XdeReJkd5hiXSSqOMyhb5OhaRLWcsrxXiOcVTQ -AjeZjOVJ6uBUcqQRBi8LjMFbvrWhsFNunLhgkR9Za/kt9JQKl7XsxXYDVBtlUrpMklZRNaBA2Cnb -rlJ2Oy0wQJuK0EJWtLeIAaSHO1OWzaMWj/Nmqhexx2DgwUMFDO6bW2BvBlyHWyf5QBGenDPBt+U1 -VwV/J84XIIwc/PH72jEpSe31C4SnT8H2TsIonPru4K8H+zMReiFPCyEQtkA6qyI6BJyLm4SGcprS -p6XEtHWRqSsjAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud -DgQWBBTgqj8ljZ9EXME66C6ud0yEPmcM9DANBgkqhkiG9w0BAQsFAAOCAgEAuVevuBLaV4OPaAsz -HQNTVfSVcOQrPbA56/qJYv331hgELyE03fFo8NWWWt7CgKPBjcZq91l3rhVkz1t5BXdm6ozTaw3d -8VkswTOlMIAVRQdFGjEitpIAq5lNOo93r6kiyi9jyhXWx8bwPWz8HA2YEGGeEaIi1wrykXprOQ4v -MMM2SZ/g6Q8CRFA3lFV96p/2O7qUpUzpvD5RtOjKkjZUbVwlKNrdrRT90+7iIgXr0PK3aBLXWopB -GsaSpVo7Y0VPv+E6dyIvXL9G+VoDhRNCX8reU9ditaY1BMJH/5n9hN9czulegChB8n3nHpDYT3Y+ -gjwN/KUD+nsa2UUeYNrEjvn8K8l7lcUq/6qJ34IxD3L/DCfXCh5WAFAeDJDBlrXYFIW7pw0WwfgH -JBu6haEaBQmAupVjyTrsJZ9/nbqkRxWbRHDxakvWOF5D8xh+UG7pWijmZeZ3Gzr9Hb4DJqPb1OG7 -fpYnKx3upPvaJVQTA945xsMfTZDsjxtK0hzthZU4UHlG1sGQUDGpXJpuHfUzVounmdLyyCwzk5Iw -x06MZTMQZBf9JBeW0Y3COmor6xOLRPIh80oat3df1+2IpHLlOR+Vnb5nwXARPbv0+Em34yaXOp/S -X3z7wJl8OSngex2/DaeP0ik0biQVy96QXr8axGbqwua6OV+KmalBWQewLK8= ------END CERTIFICATE----- - -Certainly Root E1 -================= ------BEGIN CERTIFICATE----- -MIIB9zCCAX2gAwIBAgIQBiUzsUcDMydc+Y2aub/M+DAKBggqhkjOPQQDAzA9MQswCQYDVQQGEwJV -UzESMBAGA1UEChMJQ2VydGFpbmx5MRowGAYDVQQDExFDZXJ0YWlubHkgUm9vdCBFMTAeFw0yMTA0 -MDEwMDAwMDBaFw00NjA0MDEwMDAwMDBaMD0xCzAJBgNVBAYTAlVTMRIwEAYDVQQKEwlDZXJ0YWlu -bHkxGjAYBgNVBAMTEUNlcnRhaW5seSBSb290IEUxMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE3m/4 -fxzf7flHh4axpMCK+IKXgOqPyEpeKn2IaKcBYhSRJHpcnqMXfYqGITQYUBsQ3tA3SybHGWCA6TS9 -YBk2QNYphwk8kXr2vBMj3VlOBF7PyAIcGFPBMdjaIOlEjeR2o0IwQDAOBgNVHQ8BAf8EBAMCAQYw -DwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU8ygYy2R17ikq6+2uI1g4hevIIgcwCgYIKoZIzj0E -AwMDaAAwZQIxALGOWiDDshliTd6wT99u0nCK8Z9+aozmut6Dacpps6kFtZaSF4fC0urQe87YQVt8 -rgIwRt7qy12a7DLCZRawTDBcMPPaTnOGBtjOiQRINzf43TNRnXCve1XYAS59BWQOhriR ------END CERTIFICATE----- - -Security Communication ECC RootCA1 -================================== ------BEGIN CERTIFICATE----- -MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYTAkpQMSUwIwYD -VQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYDVQQDEyJTZWN1cml0eSBDb21t -dW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYxNjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTEL -MAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNV -BAMTIlNlY3VyaXR5IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQA -IgNiAASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+CnnfdldB9sELLo -5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpKULGjQjBAMB0GA1UdDgQW -BBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAK -BggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3L -snNdo4gIxwwCMQDAqy0Obe0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70e -N9k= ------END CERTIFICATE----- - -BJCA Global Root CA1 -==================== ------BEGIN CERTIFICATE----- -MIIFdDCCA1ygAwIBAgIQVW9l47TZkGobCdFsPsBsIDANBgkqhkiG9w0BAQsFADBUMQswCQYDVQQG -EwJDTjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJVFkxHTAbBgNVBAMMFEJK -Q0EgR2xvYmFsIFJvb3QgQ0ExMB4XDTE5MTIxOTAzMTYxN1oXDTQ0MTIxMjAzMTYxN1owVDELMAkG -A1UEBhMCQ04xJjAkBgNVBAoMHUJFSUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQD -DBRCSkNBIEdsb2JhbCBSb290IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAPFm -CL3ZxRVhy4QEQaVpN3cdwbB7+sN3SJATcmTRuHyQNZ0YeYjjlwE8R4HyDqKYDZ4/N+AZspDyRhyS -sTphzvq3Rp4Dhtczbu33RYx2N95ulpH3134rhxfVizXuhJFyV9xgw8O558dnJCNPYwpj9mZ9S1Wn -P3hkSWkSl+BMDdMJoDIwOvqfwPKcxRIqLhy1BDPapDgRat7GGPZHOiJBhyL8xIkoVNiMpTAK+BcW -yqw3/XmnkRd4OJmtWO2y3syJfQOcs4ll5+M7sSKGjwZteAf9kRJ/sGsciQ35uMt0WwfCyPQ10WRj -eulumijWML3mG90Vr4TqnMfK9Q7q8l0ph49pczm+LiRvRSGsxdRpJQaDrXpIhRMsDQa4bHlW/KNn -MoH1V6XKV0Jp6VwkYe/iMBhORJhVb3rCk9gZtt58R4oRTklH2yiUAguUSiz5EtBP6DF+bHq/pj+b -OT0CFqMYs2esWz8sgytnOYFcuX6U1WTdno9uruh8W7TXakdI136z1C2OVnZOz2nxbkRs1CTqjSSh -GL+9V/6pmTW12xB3uD1IutbB5/EjPtffhZ0nPNRAvQoMvfXnjSXWgXSHRtQpdaJCbPdzied9v3pK -H9MiyRVVz99vfFXQpIsHETdfg6YmV6YBW37+WGgHqel62bno/1Afq8K0wM7o6v0PvY1NuLxxAgMB -AAGjQjBAMB0GA1UdDgQWBBTF7+3M2I0hxkjk49cULqcWk+WYATAPBgNVHRMBAf8EBTADAQH/MA4G -A1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAUoKsITQfI/Ki2Pm4rzc2IInRNwPWaZ+4 -YRC6ojGYWUfo0Q0lHhVBDOAqVdVXUsv45Mdpox1NcQJeXyFFYEhcCY5JEMEE3KliawLwQ8hOnThJ -dMkycFRtwUf8jrQ2ntScvd0g1lPJGKm1Vrl2i5VnZu69mP6u775u+2D2/VnGKhs/I0qUJDAnyIm8 -60Qkmss9vk/Ves6OF8tiwdneHg56/0OGNFK8YT88X7vZdrRTvJez/opMEi4r89fO4aL/3Xtw+zuh -TaRjAv04l5U/BXCga99igUOLtFkNSoxUnMW7gZ/NfaXvCyUeOiDbHPwfmGcCCtRzRBPbUYQaVQNW -4AB+dAb/OMRyHdOoP2gxXdMJxy6MW2Pg6Nwe0uxhHvLe5e/2mXZgLR6UcnHGCyoyx5JO1UbXHfmp -GQrI+pXObSOYqgs4rZpWDW+N8TEAiMEXnM0ZNjX+VVOg4DwzX5Ze4jLp3zO7Bkqp2IRzznfSxqxx -4VyjHQy7Ct9f4qNx2No3WqB4K/TUfet27fJhcKVlmtOJNBir+3I+17Q9eVzYH6Eze9mCUAyTF6ps -3MKCuwJXNq+YJyo5UOGwifUll35HaBC07HPKs5fRJNz2YqAo07WjuGS3iGJCz51TzZm+ZGiPTx4S -SPfSKcOYKMryMguTjClPPGAyzQWWYezyr/6zcCwupvI= ------END CERTIFICATE----- - -BJCA Global Root CA2 -==================== ------BEGIN CERTIFICATE----- -MIICJTCCAaugAwIBAgIQLBcIfWQqwP6FGFkGz7RK6zAKBggqhkjOPQQDAzBUMQswCQYDVQQGEwJD -TjEmMCQGA1UECgwdQkVJSklORyBDRVJUSUZJQ0FURSBBVVRIT1JJVFkxHTAbBgNVBAMMFEJKQ0Eg -R2xvYmFsIFJvb3QgQ0EyMB4XDTE5MTIxOTAzMTgyMVoXDTQ0MTIxMjAzMTgyMVowVDELMAkGA1UE -BhMCQ04xJjAkBgNVBAoMHUJFSUpJTkcgQ0VSVElGSUNBVEUgQVVUSE9SSVRZMR0wGwYDVQQDDBRC -SkNBIEdsb2JhbCBSb290IENBMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABJ3LgJGNU2e1uVCxA/jl -SR9BIgmwUVJY1is0j8USRhTFiy8shP8sbqjV8QnjAyEUxEM9fMEsxEtqSs3ph+B99iK++kpRuDCK -/eHeGBIK9ke35xe/J4rUQUyWPGCWwf0VHKNCMEAwHQYDVR0OBBYEFNJKsVF/BvDRgh9Obl+rg/xI -1LCRMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49BAMDA2gAMGUCMBq8 -W9f+qdJUDkpd0m2xQNz0Q9XSSpkZElaA94M04TVOSG0ED1cxMDAtsaqdAzjbBgIxAMvMh1PLet8g -UXOQwKhbYdDFUDn9hf7B43j4ptZLvZuHjw/l1lOWqzzIQNph91Oj9w== ------END CERTIFICATE----- - -Sectigo Public Server Authentication Root E46 -============================================= ------BEGIN CERTIFICATE----- -MIICOjCCAcGgAwIBAgIQQvLM2htpN0RfFf51KBC49DAKBggqhkjOPQQDAzBfMQswCQYDVQQGEwJH -QjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBTZXJ2 -ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwHhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1OTU5 -WjBfMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0 -aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBFNDYwdjAQBgcqhkjOPQIBBgUr -gQQAIgNiAAR2+pmpbiDt+dd34wc7qNs9Xzjoq1WmVk/WSOrsfy2qw7LFeeyZYX8QeccCWvkEN/U0 -NSt3zn8gj1KjAIns1aeibVvjS5KToID1AZTc8GgHHs3u/iVStSBDHBv+6xnOQ6OjQjBAMB0GA1Ud -DgQWBBTRItpMWfFLXyY4qp3W7usNw/upYTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB -/zAKBggqhkjOPQQDAwNnADBkAjAn7qRaqCG76UeXlImldCBteU/IvZNeWBj7LRoAasm4PdCkT0RH -lAFWovgzJQxC36oCMB3q4S6ILuH5px0CMk7yn2xVdOOurvulGu7t0vzCAxHrRVxgED1cf5kDW21U -SAGKcw== ------END CERTIFICATE----- - -Sectigo Public Server Authentication Root R46 -============================================= ------BEGIN CERTIFICATE----- -MIIFijCCA3KgAwIBAgIQdY39i658BwD6qSWn4cetFDANBgkqhkiG9w0BAQwFADBfMQswCQYDVQQG -EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1TZWN0aWdvIFB1YmxpYyBT -ZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwHhcNMjEwMzIyMDAwMDAwWhcNNDYwMzIxMjM1 -OTU5WjBfMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTYwNAYDVQQDEy1T -ZWN0aWdvIFB1YmxpYyBTZXJ2ZXIgQXV0aGVudGljYXRpb24gUm9vdCBSNDYwggIiMA0GCSqGSIb3 -DQEBAQUAA4ICDwAwggIKAoICAQCTvtU2UnXYASOgHEdCSe5jtrch/cSV1UgrJnwUUxDaef0rty2k -1Cz66jLdScK5vQ9IPXtamFSvnl0xdE8H/FAh3aTPaE8bEmNtJZlMKpnzSDBh+oF8HqcIStw+Kxwf -GExxqjWMrfhu6DtK2eWUAtaJhBOqbchPM8xQljeSM9xfiOefVNlI8JhD1mb9nxc4Q8UBUQvX4yMP -FF1bFOdLvt30yNoDN9HWOaEhUTCDsG3XME6WW5HwcCSrv0WBZEMNvSE6Lzzpng3LILVCJ8zab5vu -ZDCQOc2TZYEhMbUjUDM3IuM47fgxMMxF/mL50V0yeUKH32rMVhlATc6qu/m1dkmU8Sf4kaWD5Qaz -Yw6A3OASVYCmO2a0OYctyPDQ0RTp5A1NDvZdV3LFOxxHVp3i1fuBYYzMTYCQNFu31xR13NgESJ/A -wSiItOkcyqex8Va3e0lMWeUgFaiEAin6OJRpmkkGj80feRQXEgyDet4fsZfu+Zd4KKTIRJLpfSYF -plhym3kT2BFfrsU4YjRosoYwjviQYZ4ybPUHNs2iTG7sijbt8uaZFURww3y8nDnAtOFr94MlI1fZ -EoDlSfB1D++N6xybVCi0ITz8fAr/73trdf+LHaAZBav6+CuBQug4urv7qv094PPK306Xlynt8xhW -6aWWrL3DkJiy4Pmi1KZHQ3xtzwIDAQABo0IwQDAdBgNVHQ4EFgQUVnNYZJX5khqwEioEYnmhQBWI -IUkwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAC9c -mTz8Bl6MlC5w6tIyMY208FHVvArzZJ8HXtXBc2hkeqK5Duj5XYUtqDdFqij0lgVQYKlJfp/imTYp -E0RHap1VIDzYm/EDMrraQKFz6oOht0SmDpkBm+S8f74TlH7Kph52gDY9hAaLMyZlbcp+nv4fjFg4 -exqDsQ+8FxG75gbMY/qB8oFM2gsQa6H61SilzwZAFv97fRheORKkU55+MkIQpiGRqRxOF3yEvJ+M -0ejf5lG5Nkc/kLnHvALcWxxPDkjBJYOcCj+esQMzEhonrPcibCTRAUH4WAP+JWgiH5paPHxsnnVI -84HxZmduTILA7rpXDhjvLpr3Etiga+kFpaHpaPi8TD8SHkXoUsCjvxInebnMMTzD9joiFgOgyY9m -pFuiTdaBJQbpdqQACj7LzTWb4OE4y2BThihCQRxEV+ioratF4yUQvNs+ZUH7G6aXD+u5dHn5Hrwd -Vw1Hr8Mvn4dGp+smWg9WY7ViYG4A++MnESLn/pmPNPW56MORcr3Ywx65LvKRRFHQV80MNNVIIb/b -E/FmJUNS0nAiNs2fxBx1IK1jcmMGDw4nztJqDby1ORrp0XZ60Vzk50lJLVU3aPAaOpg+VBeHVOmm -J1CJeyAvP/+/oYtKR5j/K3tJPsMpRmAYQqszKbrAKbkTidOIijlBO8n9pu0f9GBj39ItVQGL ------END CERTIFICATE----- - -SSL.com TLS RSA Root CA 2022 -============================ ------BEGIN CERTIFICATE----- -MIIFiTCCA3GgAwIBAgIQb77arXO9CEDii02+1PdbkTANBgkqhkiG9w0BAQsFADBOMQswCQYDVQQG -EwJVUzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxTU0wuY29tIFRMUyBSU0Eg -Um9vdCBDQSAyMDIyMB4XDTIyMDgyNTE2MzQyMloXDTQ2MDgxOTE2MzQyMVowTjELMAkGA1UEBhMC -VVMxGDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgUlNBIFJv -b3QgQ0EgMjAyMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANCkCXJPQIgSYT41I57u -9nTPL3tYPc48DRAokC+X94xI2KDYJbFMsBFMF3NQ0CJKY7uB0ylu1bUJPiYYf7ISf5OYt6/wNr/y -7hienDtSxUcZXXTzZGbVXcdotL8bHAajvI9AI7YexoS9UcQbOcGV0insS657Lb85/bRi3pZ7Qcac -oOAGcvvwB5cJOYF0r/c0WRFXCsJbwST0MXMwgsadugL3PnxEX4MN8/HdIGkWCVDi1FW24IBydm5M -R7d1VVm0U3TZlMZBrViKMWYPHqIbKUBOL9975hYsLfy/7PO0+r4Y9ptJ1O4Fbtk085zx7AGL0SDG -D6C1vBdOSHtRwvzpXGk3R2azaPgVKPC506QVzFpPulJwoxJF3ca6TvvC0PeoUidtbnm1jPx7jMEW -TO6Af77wdr5BUxIzrlo4QqvXDz5BjXYHMtWrifZOZ9mxQnUjbvPNQrL8VfVThxc7wDNY8VLS+YCk -8OjwO4s4zKTGkH8PnP2L0aPP2oOnaclQNtVcBdIKQXTbYxE3waWglksejBYSd66UNHsef8JmAOSq -g+qKkK3ONkRN0VHpvB/zagX9wHQfJRlAUW7qglFA35u5CCoGAtUjHBPW6dvbxrB6y3snm/vg1UYk -7RBLY0ulBY+6uB0rpvqR4pJSvezrZ5dtmi2fgTIFZzL7SAg/2SW4BCUvAgMBAAGjYzBhMA8GA1Ud -EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU+y437uOEeicuzRk1sTN8/9REQrkwHQYDVR0OBBYEFPsu -N+7jhHonLs0ZNbEzfP/UREK5MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsFAAOCAgEAjYlt -hEUY8U+zoO9opMAdrDC8Z2awms22qyIZZtM7QbUQnRC6cm4pJCAcAZli05bg4vsMQtfhWsSWTVTN -j8pDU/0quOr4ZcoBwq1gaAafORpR2eCNJvkLTqVTJXojpBzOCBvfR4iyrT7gJ4eLSYwfqUdYe5by -iB0YrrPRpgqU+tvT5TgKa3kSM/tKWTcWQA673vWJDPFs0/dRa1419dvAJuoSc06pkZCmF8NsLzjU -o3KUQyxi4U5cMj29TH0ZR6LDSeeWP4+a0zvkEdiLA9z2tmBVGKaBUfPhqBVq6+AL8BQx1rmMRTqo -ENjwuSfr98t67wVylrXEj5ZzxOhWc5y8aVFjvO9nHEMaX3cZHxj4HCUp+UmZKbaSPaKDN7Egkaib -MOlqbLQjk2UEqxHzDh1TJElTHaE/nUiSEeJ9DU/1172iWD54nR4fK/4huxoTtrEoZP2wAgDHbICi -vRZQIA9ygV/MlP+7mea6kMvq+cYMwq7FGc4zoWtcu358NFcXrfA/rs3qr5nsLFR+jM4uElZI7xc7 -P0peYNLcdDa8pUNjyw9bowJWCZ4kLOGGgYz+qxcs+sjiMho6/4UIyYOf8kpIEFR3N+2ivEC+5BB0 -9+Rbu7nzifmPQdjH5FCQNYA+HLhNkNPU98OwoX6EyneSMSy4kLGCenROmxMmtNVQZlR4rmA= ------END CERTIFICATE----- - -SSL.com TLS ECC Root CA 2022 -============================ ------BEGIN CERTIFICATE----- -MIICOjCCAcCgAwIBAgIQFAP1q/s3ixdAW+JDsqXRxDAKBggqhkjOPQQDAzBOMQswCQYDVQQGEwJV -UzEYMBYGA1UECgwPU1NMIENvcnBvcmF0aW9uMSUwIwYDVQQDDBxTU0wuY29tIFRMUyBFQ0MgUm9v -dCBDQSAyMDIyMB4XDTIyMDgyNTE2MzM0OFoXDTQ2MDgxOTE2MzM0N1owTjELMAkGA1UEBhMCVVMx -GDAWBgNVBAoMD1NTTCBDb3Jwb3JhdGlvbjElMCMGA1UEAwwcU1NMLmNvbSBUTFMgRUNDIFJvb3Qg -Q0EgMjAyMjB2MBAGByqGSM49AgEGBSuBBAAiA2IABEUpNXP6wrgjzhR9qLFNoFs27iosU8NgCTWy -JGYmacCzldZdkkAZDsalE3D07xJRKF3nzL35PIXBz5SQySvOkkJYWWf9lCcQZIxPBLFNSeR7T5v1 -5wj4A4j3p8OSSxlUgaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSJjy+j6CugFFR7 -81a4Jl9nOAuc0DAdBgNVHQ4EFgQUiY8vo+groBRUe/NWuCZfZzgLnNAwDgYDVR0PAQH/BAQDAgGG -MAoGCCqGSM49BAMDA2gAMGUCMFXjIlbp15IkWE8elDIPDAI2wv2sdDJO4fscgIijzPvX6yv/N33w -7deedWo1dlJF4AIxAMeNb0Igj762TVntd00pxCAgRWSGOlDGxK0tk/UYfXLtqc/ErFc2KAhl3zx5 -Zn6g6g== ------END CERTIFICATE----- - -Atos TrustedRoot Root CA ECC TLS 2021 -===================================== ------BEGIN CERTIFICATE----- -MIICFTCCAZugAwIBAgIQPZg7pmY9kGP3fiZXOATvADAKBggqhkjOPQQDAzBMMS4wLAYDVQQDDCVB -dG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgRUNDIFRMUyAyMDIxMQ0wCwYDVQQKDARBdG9zMQswCQYD -VQQGEwJERTAeFw0yMTA0MjIwOTI2MjNaFw00MTA0MTcwOTI2MjJaMEwxLjAsBgNVBAMMJUF0b3Mg -VHJ1c3RlZFJvb3QgUm9vdCBDQSBFQ0MgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNVBAYT -AkRFMHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEloZYKDcKZ9Cg3iQZGeHkBQcfl+3oZIK59sRxUM6K -DP/XtXa7oWyTbIOiaG6l2b4siJVBzV3dscqDY4PMwL502eCdpO5KTlbgmClBk1IQ1SQ4AjJn8ZQS -b+/Xxd4u/RmAo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBR2KCXWfeBmmnoJsmo7jjPX -NtNPojAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwMDaAAwZQIwW5kp85wxtolrbNa9d+F851F+ -uDrNozZffPc8dz7kUK2o59JZDCaOMDtuCCrCp1rIAjEAmeMM56PDr9NJLkaCI2ZdyQAUEv049OGY -a3cpetskz2VAv9LcjBHo9H1/IISpQuQo ------END CERTIFICATE----- - -Atos TrustedRoot Root CA RSA TLS 2021 -===================================== ------BEGIN CERTIFICATE----- -MIIFZDCCA0ygAwIBAgIQU9XP5hmTC/srBRLYwiqipDANBgkqhkiG9w0BAQwFADBMMS4wLAYDVQQD -DCVBdG9zIFRydXN0ZWRSb290IFJvb3QgQ0EgUlNBIFRMUyAyMDIxMQ0wCwYDVQQKDARBdG9zMQsw -CQYDVQQGEwJERTAeFw0yMTA0MjIwOTIxMTBaFw00MTA0MTcwOTIxMDlaMEwxLjAsBgNVBAMMJUF0 -b3MgVHJ1c3RlZFJvb3QgUm9vdCBDQSBSU0EgVExTIDIwMjExDTALBgNVBAoMBEF0b3MxCzAJBgNV -BAYTAkRFMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtoAOxHm9BYx9sKOdTSJNy/BB -l01Z4NH+VoyX8te9j2y3I49f1cTYQcvyAh5x5en2XssIKl4w8i1mx4QbZFc4nXUtVsYvYe+W/CBG -vevUez8/fEc4BKkbqlLfEzfTFRVOvV98r61jx3ncCHvVoOX3W3WsgFWZkmGbzSoXfduP9LVq6hdK -ZChmFSlsAvFr1bqjM9xaZ6cF4r9lthawEO3NUDPJcFDsGY6wx/J0W2tExn2WuZgIWWbeKQGb9Cpt -0xU6kGpn8bRrZtkh68rZYnxGEFzedUlnnkL5/nWpo63/dgpnQOPF943HhZpZnmKaau1Fh5hnstVK -PNe0OwANwI8f4UDErmwh3El+fsqyjW22v5MvoVw+j8rtgI5Y4dtXz4U2OLJxpAmMkokIiEjxQGMY -sluMWuPD0xeqqxmjLBvk1cbiZnrXghmmOxYsL3GHX0WelXOTwkKBIROW1527k2gV+p2kHYzygeBY -Br3JtuP2iV2J+axEoctr+hbxx1A9JNr3w+SH1VbxT5Aw+kUJWdo0zuATHAR8ANSbhqRAvNncTFd+ -rrcztl524WWLZt+NyteYr842mIycg5kDcPOvdO3GDjbnvezBc6eUWsuSZIKmAMFwoW4sKeFYV+xa -fJlrJaSQOoD0IJ2azsct+bJLKZWD6TWNp0lIpw9MGZHQ9b8Q4HECAwEAAaNCMEAwDwYDVR0TAQH/ -BAUwAwEB/zAdBgNVHQ4EFgQUdEmZ0f+0emhFdcN+tNzMzjkz2ggwDgYDVR0PAQH/BAQDAgGGMA0G -CSqGSIb3DQEBDAUAA4ICAQAjQ1MkYlxt/T7Cz1UAbMVWiLkO3TriJQ2VSpfKgInuKs1l+NsW4AmS -4BjHeJi78+xCUvuppILXTdiK/ORO/auQxDh1MoSf/7OwKwIzNsAQkG8dnK/haZPso0UvFJ/1TCpl -Q3IM98P4lYsU84UgYt1UU90s3BiVaU+DR3BAM1h3Egyi61IxHkzJqM7F78PRreBrAwA0JrRUITWX -AdxfG/F851X6LWh3e9NpzNMOa7pNdkTWwhWaJuywxfW70Xp0wmzNxbVe9kzmWy2B27O3Opee7c9G -slA9hGCZcbUztVdF5kJHdWoOsAgMrr3e97sPWD2PAzHoPYJQyi9eDF20l74gNAf0xBLh7tew2Vkt -afcxBPTy+av5EzH4AXcOPUIjJsyacmdRIXrMPIWo6iFqO9taPKU0nprALN+AnCng33eU0aKAQv9q -TFsR0PXNor6uzFFcw9VUewyu1rkGd4Di7wcaaMxZUa1+XGdrudviB0JbuAEFWDlN5LuYo7Ey7Nmj -1m+UI/87tyll5gfp77YZ6ufCOB0yiJA8EytuzO+rdwY0d4RPcuSBhPm5dDTedk+SKlOxJTnbPP/l -PqYO5Wue/9vsL3SD3460s6neFE3/MaNFcyT6lSnMEpcEoji2jbDwN/zIIX8/syQbPYtuzE2wFg2W -HYMfRsCbvUOZ58SWLs5fyQ== ------END CERTIFICATE----- - -TrustAsia Global Root CA G3 -=========================== ------BEGIN CERTIFICATE----- -MIIFpTCCA42gAwIBAgIUZPYOZXdhaqs7tOqFhLuxibhxkw8wDQYJKoZIhvcNAQEMBQAwWjELMAkG -A1UEBhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMsIEluYy4xJDAiBgNVBAMM -G1RydXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHMzAeFw0yMTA1MjAwMjEwMTlaFw00NjA1MTkwMjEw -MTlaMFoxCzAJBgNVBAYTAkNOMSUwIwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMu -MSQwIgYDVQQDDBtUcnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzMwggIiMA0GCSqGSIb3DQEBAQUA -A4ICDwAwggIKAoICAQDAMYJhkuSUGwoqZdC+BqmHO1ES6nBBruL7dOoKjbmzTNyPtxNST1QY4Sxz -lZHFZjtqz6xjbYdT8PfxObegQ2OwxANdV6nnRM7EoYNl9lA+sX4WuDqKAtCWHwDNBSHvBm3dIZwZ -Q0WhxeiAysKtQGIXBsaqvPPW5vxQfmZCHzyLpnl5hkA1nyDvP+uLRx+PjsXUjrYsyUQE49RDdT/V -P68czH5GX6zfZBCK70bwkPAPLfSIC7Epqq+FqklYqL9joDiR5rPmd2jE+SoZhLsO4fWvieylL1Ag -dB4SQXMeJNnKziyhWTXAyB1GJ2Faj/lN03J5Zh6fFZAhLf3ti1ZwA0pJPn9pMRJpxx5cynoTi+jm -9WAPzJMshH/x/Gr8m0ed262IPfN2dTPXS6TIi/n1Q1hPy8gDVI+lhXgEGvNz8teHHUGf59gXzhqc -D0r83ERoVGjiQTz+LISGNzzNPy+i2+f3VANfWdP3kXjHi3dqFuVJhZBFcnAvkV34PmVACxmZySYg -WmjBNb9Pp1Hx2BErW+Canig7CjoKH8GB5S7wprlppYiU5msTf9FkPz2ccEblooV7WIQn3MSAPmea -mseaMQ4w7OYXQJXZRe0Blqq/DPNL0WP3E1jAuPP6Z92bfW1K/zJMtSU7/xxnD4UiWQWRkUF3gdCF -TIcQcf+eQxuulXUtgQIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFEDk5PIj -7zjKsK5Xf/IhMBY027ySMB0GA1UdDgQWBBRA5OTyI+84yrCuV3/yITAWNNu8kjAOBgNVHQ8BAf8E -BAMCAQYwDQYJKoZIhvcNAQEMBQADggIBACY7UeFNOPMyGLS0XuFlXsSUT9SnYaP4wM8zAQLpw6o1 -D/GUE3d3NZ4tVlFEbuHGLige/9rsR82XRBf34EzC4Xx8MnpmyFq2XFNFV1pF1AWZLy4jVe5jaN/T -G3inEpQGAHUNcoTpLrxaatXeL1nHo+zSh2bbt1S1JKv0Q3jbSwTEb93mPmY+KfJLaHEih6D4sTNj -duMNhXJEIlU/HHzp/LgV6FL6qj6jITk1dImmasI5+njPtqzn59ZW/yOSLlALqbUHM/Q4X6RJpstl -cHboCoWASzY9M/eVVHUl2qzEc4Jl6VL1XP04lQJqaTDFHApXB64ipCz5xUG3uOyfT0gA+QEEVcys -+TIxxHWVBqB/0Y0n3bOppHKH/lmLmnp0Ft0WpWIp6zqW3IunaFnT63eROfjXy9mPX1onAX1daBli -2MjN9LdyR75bl87yraKZk62Uy5P2EgmVtqvXO9A/EcswFi55gORngS1d7XB4tmBZrOFdRWOPyN9y -aFvqHbgB8X7754qz41SgOAngPN5C8sLtLpvzHzW2NtjjgKGLzZlkD8Kqq7HK9W+eQ42EVJmzbsAS -ZthwEPEGNTNDqJwuuhQxzhB/HIbjj9LV+Hfsm6vxL2PZQl/gZ4FkkfGXL/xuJvYz+NO1+MRiqzFR -JQJ6+N1rZdVtTTDIZbpoFGWsJwt0ivKH ------END CERTIFICATE----- - -TrustAsia Global Root CA G4 -=========================== ------BEGIN CERTIFICATE----- -MIICVTCCAdygAwIBAgIUTyNkuI6XY57GU4HBdk7LKnQV1tcwCgYIKoZIzj0EAwMwWjELMAkGA1UE -BhMCQ04xJTAjBgNVBAoMHFRydXN0QXNpYSBUZWNobm9sb2dpZXMsIEluYy4xJDAiBgNVBAMMG1Ry -dXN0QXNpYSBHbG9iYWwgUm9vdCBDQSBHNDAeFw0yMTA1MjAwMjEwMjJaFw00NjA1MTkwMjEwMjJa -MFoxCzAJBgNVBAYTAkNOMSUwIwYDVQQKDBxUcnVzdEFzaWEgVGVjaG5vbG9naWVzLCBJbmMuMSQw -IgYDVQQDDBtUcnVzdEFzaWEgR2xvYmFsIFJvb3QgQ0EgRzQwdjAQBgcqhkjOPQIBBgUrgQQAIgNi -AATxs8045CVD5d4ZCbuBeaIVXxVjAd7Cq92zphtnS4CDr5nLrBfbK5bKfFJV4hrhPVbwLxYI+hW8 -m7tH5j/uqOFMjPXTNvk4XatwmkcN4oFBButJ+bAp3TPsUKV/eSm4IJijYzBhMA8GA1UdEwEB/wQF -MAMBAf8wHwYDVR0jBBgwFoAUpbtKl86zK3+kMd6Xg1mDpm9xy94wHQYDVR0OBBYEFKW7SpfOsyt/ -pDHel4NZg6ZvccveMA4GA1UdDwEB/wQEAwIBBjAKBggqhkjOPQQDAwNnADBkAjBe8usGzEkxn0AA -bbd+NvBNEU/zy4k6LHiRUKNbwMp1JvK/kF0LgoxgKJ/GcJpo5PECMFxYDlZ2z1jD1xCMuo6u47xk -dUfFVZDj/bpV6wfEU6s3qe4hsiFbYI89MvHVI5TWWA== ------END CERTIFICATE----- - -Telekom Security TLS ECC Root 2020 -================================== ------BEGIN CERTIFICATE----- -MIICQjCCAcmgAwIBAgIQNjqWjMlcsljN0AFdxeVXADAKBggqhkjOPQQDAzBjMQswCQYDVQQGEwJE -RTEnMCUGA1UECgweRGV1dHNjaGUgVGVsZWtvbSBTZWN1cml0eSBHbWJIMSswKQYDVQQDDCJUZWxl -a29tIFNlY3VyaXR5IFRMUyBFQ0MgUm9vdCAyMDIwMB4XDTIwMDgyNTA3NDgyMFoXDTQ1MDgyNTIz -NTk1OVowYzELMAkGA1UEBhMCREUxJzAlBgNVBAoMHkRldXRzY2hlIFRlbGVrb20gU2VjdXJpdHkg -R21iSDErMCkGA1UEAwwiVGVsZWtvbSBTZWN1cml0eSBUTFMgRUNDIFJvb3QgMjAyMDB2MBAGByqG -SM49AgEGBSuBBAAiA2IABM6//leov9Wq9xCazbzREaK9Z0LMkOsVGJDZos0MKiXrPk/OtdKPD/M1 -2kOLAoC+b1EkHQ9rK8qfwm9QMuU3ILYg/4gND21Ju9sGpIeQkpT0CdDPf8iAC8GXs7s1J8nCG6NC -MEAwHQYDVR0OBBYEFONyzG6VmUex5rNhTNHLq+O6zd6fMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P -AQH/BAQDAgEGMAoGCCqGSM49BAMDA2cAMGQCMHVSi7ekEE+uShCLsoRbQuHmKjYC2qBuGT8lv9pZ -Mo7k+5Dck2TOrbRBR2Diz6fLHgIwN0GMZt9Ba9aDAEH9L1r3ULRn0SyocddDypwnJJGDSA3PzfdU -ga/sf+Rn27iQ7t0l ------END CERTIFICATE----- - -Telekom Security TLS RSA Root 2023 -================================== ------BEGIN CERTIFICATE----- -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 ------END CERTIFICATE----- - -FIRMAPROFESIONAL CA ROOT-A WEB -============================== ------BEGIN CERTIFICATE----- -MIICejCCAgCgAwIBAgIQMZch7a+JQn81QYehZ1ZMbTAKBggqhkjOPQQDAzBuMQswCQYDVQQGEwJF -UzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25hbCBTQTEYMBYGA1UEYQwPVkFURVMtQTYyNjM0MDY4 -MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFMIENBIFJPT1QtQSBXRUIwHhcNMjIwNDA2MDkwMTM2 -WhcNNDcwMzMxMDkwMTM2WjBuMQswCQYDVQQGEwJFUzEcMBoGA1UECgwTRmlybWFwcm9mZXNpb25h -bCBTQTEYMBYGA1UEYQwPVkFURVMtQTYyNjM0MDY4MScwJQYDVQQDDB5GSVJNQVBST0ZFU0lPTkFM -IENBIFJPT1QtQSBXRUIwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAARHU+osEaR3xyrq89Zfe9MEkVz6 -iMYiuYMQYneEMy3pA4jU4DP37XcsSmDq5G+tbbT4TIqk5B/K6k84Si6CcyvHZpsKjECcfIr28jlg -st7L7Ljkb+qbXbdTkBgyVcUgt5SjYzBhMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAUk+FD -Y1w8ndYn81LsF7Kpryz3dvgwHQYDVR0OBBYEFJPhQ2NcPJ3WJ/NS7Beyqa8s93b4MA4GA1UdDwEB -/wQEAwIBBjAKBggqhkjOPQQDAwNoADBlAjAdfKR7w4l1M+E7qUW/Runpod3JIha3RxEL2Jq68cgL -cFBTApFwhVmpHqTm6iMxoAACMQD94vizrxa5HnPEluPBMBnYfubDl94cT7iJLzPrSA8Z94dGXSaQ -pYXFuXqUPoeovQA= ------END CERTIFICATE----- - -TWCA CYBER Root CA -================== ------BEGIN CERTIFICATE----- -MIIFjTCCA3WgAwIBAgIQQAE0jMIAAAAAAAAAATzyxjANBgkqhkiG9w0BAQwFADBQMQswCQYDVQQG -EwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NB -IENZQkVSIFJvb3QgQ0EwHhcNMjIxMTIyMDY1NDI5WhcNNDcxMTIyMTU1OTU5WjBQMQswCQYDVQQG -EwJUVzESMBAGA1UEChMJVEFJV0FOLUNBMRAwDgYDVQQLEwdSb290IENBMRswGQYDVQQDExJUV0NB -IENZQkVSIFJvb3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDG+Moe2Qkgfh1s -Ts6P40czRJzHyWmqOlt47nDSkvgEs1JSHWdyKKHfi12VCv7qze33Kc7wb3+szT3vsxxFavcokPFh -V8UMxKNQXd7UtcsZyoC5dc4pztKFIuwCY8xEMCDa6pFbVuYdHNWdZsc/34bKS1PE2Y2yHer43CdT -o0fhYcx9tbD47nORxc5zb87uEB8aBs/pJ2DFTxnk684iJkXXYJndzk834H/nY62wuFm40AZoNWDT -Nq5xQwTxaWV4fPMf88oon1oglWa0zbfuj3ikRRjpJi+NmykosaS3Om251Bw4ckVYsV7r8Cibt4LK -/c/WMw+f+5eesRycnupfXtuq3VTpMCEobY5583WSjCb+3MX2w7DfRFlDo7YDKPYIMKoNM+HvnKkH -IuNZW0CP2oi3aQiotyMuRAlZN1vH4xfyIutuOVLF3lSnmMlLIJXcRolftBL5hSmO68gnFSDAS9TM -fAxsNAwmmyYxpjyn9tnQS6Jk/zuZQXLB4HCX8SS7K8R0IrGsayIyJNN4KsDAoS/xUgXJP+92ZuJF -2A09rZXIx4kmyA+upwMu+8Ff+iDhcK2wZSA3M2Cw1a/XDBzCkHDXShi8fgGwsOsVHkQGzaRP6AzR -wyAQ4VRlnrZR0Bp2a0JaWHY06rc3Ga4udfmW5cFZ95RXKSWNOkyrTZpB0F8mAwIDAQABo2MwYTAO -BgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSdhWEUfMFib5do5E83 -QOGt4A1WNzAdBgNVHQ4EFgQUnYVhFHzBYm+XaORPN0DhreANVjcwDQYJKoZIhvcNAQEMBQADggIB -AGSPesRiDrWIzLjHhg6hShbNcAu3p4ULs3a2D6f/CIsLJc+o1IN1KriWiLb73y0ttGlTITVX1olN -c79pj3CjYcya2x6a4CD4bLubIp1dhDGaLIrdaqHXKGnK/nZVekZn68xDiBaiA9a5F/gZbG0jAn/x -X9AKKSM70aoK7akXJlQKTcKlTfjF/biBzysseKNnTKkHmvPfXvt89YnNdJdhEGoHK4Fa0o635yDR -IG4kqIQnoVesqlVYL9zZyvpoBJ7tRCT5dEA7IzOrg1oYJkK2bVS1FmAwbLGg+LhBoF1JSdJlBTrq -/p1hvIbZv97Tujqxf36SNI7JAG7cmL3c7IAFrQI932XtCwP39xaEBDG6k5TY8hL4iuO/Qq+n1M0R -FxbIQh0UqEL20kCGoE8jypZFVmAGzbdVAaYBlGX+bgUJurSkquLvWL69J1bY73NxW0Qz8ppy6rBe -Pm6pUlvscG21h483XjyMnM7k8M4MZ0HMzvaAq07MTFb1wWFZk7Q+ptq4NxKfKjLji7gh7MMrZQzv -It6IKTtM1/r+t+FHvpw+PoP7UV31aPcuIYXcv/Fa4nzXxeSDwWrruoBa3lwtcHb4yOWHh8qgnaHl -IhInD0Q9HWzq1MKLL295q39QpsQZp6F6t5b5wR9iWqJDB0BeJsas7a5wFsWqynKKTbDPAYsDP27X ------END CERTIFICATE----- - -SecureSign Root CA12 -==================== ------BEGIN CERTIFICATE----- -MIIDcjCCAlqgAwIBAgIUZvnHwa/swlG07VOX5uaCwysckBYwDQYJKoZIhvcNAQELBQAwUTELMAkG -A1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQDExRT -ZWN1cmVTaWduIFJvb3QgQ0ExMjAeFw0yMDA0MDgwNTM2NDZaFw00MDA0MDgwNTM2NDZaMFExCzAJ -BgNVBAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMU -U2VjdXJlU2lnbiBSb290IENBMTIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC6OcE3 -emhFKxS06+QT61d1I02PJC0W6K6OyX2kVzsqdiUzg2zqMoqUm048luT9Ub+ZyZN+v/mtp7JIKwcc -J/VMvHASd6SFVLX9kHrko+RRWAPNEHl57muTH2SOa2SroxPjcf59q5zdJ1M3s6oYwlkm7Fsf0uZl -fO+TvdhYXAvA42VvPMfKWeP+bl+sg779XSVOKik71gurFzJ4pOE+lEa+Ym6b3kaosRbnhW70CEBF -EaCeVESE99g2zvVQR9wsMJvuwPWW0v4JhscGWa5Pro4RmHvzC1KqYiaqId+OJTN5lxZJjfU+1Uef -NzFJM3IFTQy2VYzxV4+Kh9GtxRESOaCtAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0P -AQH/BAQDAgEGMB0GA1UdDgQWBBRXNPN0zwRL1SXm8UC2LEzZLemgrTANBgkqhkiG9w0BAQsFAAOC -AQEAPrvbFxbS8hQBICw4g0utvsqFepq2m2um4fylOqyttCg6r9cBg0krY6LdmmQOmFxv3Y67ilQi -LUoT865AQ9tPkbeGGuwAtEGBpE/6aouIs3YIcipJQMPTw4WJmBClnW8Zt7vPemVV2zfrPIpyMpce -mik+rY3moxtt9XUa5rBouVui7mlHJzWhhpmA8zNL4WukJsPvdFlseqJkth5Ew1DgDzk9qTPxpfPS -vWKErI4cqc1avTc7bgoitPQV55FYxTpE05Uo2cBl6XLK0A+9H7MV2anjpEcJnuDLN/v9vZfVvhga -aaI5gdka9at/yOPiZwud9AzqVN/Ssq+xIvEg37xEHA== ------END CERTIFICATE----- - -SecureSign Root CA14 -==================== ------BEGIN CERTIFICATE----- -MIIFcjCCA1qgAwIBAgIUZNtaDCBO6Ncpd8hQJ6JaJ90t8sswDQYJKoZIhvcNAQEMBQAwUTELMAkG -A1UEBhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQDExRT -ZWN1cmVTaWduIFJvb3QgQ0ExNDAeFw0yMDA0MDgwNzA2MTlaFw00NTA0MDgwNzA2MTlaMFExCzAJ -BgNVBAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMU -U2VjdXJlU2lnbiBSb290IENBMTQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDF0nqh -1oq/FjHQmNE6lPxauG4iwWL3pwon71D2LrGeaBLwbCRjOfHw3xDG3rdSINVSW0KZnvOgvlIfX8xn -bacuUKLBl422+JX1sLrcneC+y9/3OPJH9aaakpUqYllQC6KxNedlsmGy6pJxaeQp8E+BgQQ8sqVb -1MWoWWd7VRxJq3qdwudzTe/NCcLEVxLbAQ4jeQkHO6Lo/IrPj8BGJJw4J+CDnRugv3gVEOuGTgpa -/d/aLIJ+7sr2KeH6caH3iGicnPCNvg9JkdjqOvn90Ghx2+m1K06Ckm9mH+Dw3EzsytHqunQG+bOE -kJTRX45zGRBdAuVwpcAQ0BB8b8VYSbSwbprafZX1zNoCr7gsfXmPvkPx+SgojQlD+Ajda8iLLCSx -jVIHvXiby8posqTdDEx5YMaZ0ZPxMBoH064iwurO8YQJzOAUbn8/ftKChazcqRZOhaBgy/ac18iz -ju3Gm5h1DVXoX+WViwKkrkMpKBGk5hIwAUt1ax5mnXkvpXYvHUC0bcl9eQjs0Wq2XSqypWa9a4X0 -dFbD9ed1Uigspf9mR6XU/v6eVL9lfgHWMI+lNpyiUBzuOIABSMbHdPTGrMNASRZhdCyvjG817XsY -AFs2PJxQDcqSMxDxJklt33UkN4Ii1+iW/RVLApY+B3KVfqs9TC7XyvDf4Fg/LS8EmjijAQIDAQAB -o0IwQDAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUBpOjCl4oaTeq -YR3r6/wtbyPk86AwDQYJKoZIhvcNAQEMBQADggIBAJaAcgkGfpzMkwQWu6A6jZJOtxEaCnFxEM0E -rX+lRVAQZk5KQaID2RFPeje5S+LGjzJmdSX7684/AykmjbgWHfYfM25I5uj4V7Ibed87hwriZLoA -ymzvftAj63iP/2SbNDefNWWipAA9EiOWWF3KY4fGoweITedpdopTzfFP7ELyk+OZpDc8h7hi2/Ds -Hzc/N19DzFGdtfCXwreFamgLRB7lUe6TzktuhsHSDCRZNhqfLJGP4xjblJUK7ZGqDpncllPjYYPG -FrojutzdfhrGe0K22VoF3Jpf1d+42kd92jjbrDnVHmtsKheMYc2xbXIBw8MgAGJoFjHVdqqGuw6q -nsb58Nn4DSEC5MUoFlkRudlpcyqSeLiSV5sI8jrlL5WwWLdrIBRtFO8KvH7YVdiI2i/6GaX7i+B/ -OfVyK4XELKzvGUWSTLNhB9xNH27SgRNcmvMSZ4PPmz+Ln52kuaiWA3rF7iDeM9ovnhp6dB7h7sxa -OgTdsxoEqBRjrLdHEoOabPXm6RUVkRqEGQ6UROcSjiVbgGcZ3GOTEAtlLor6CZpO2oYofaphNdgO -pygau1LgePhsumywbrmHXumZNTfxPWQrqaA0k89jL9WB365jJ6UeTo3cKXhZ+PmhIIynJkBugnLN -eLLIjzwec+fBH7/PzqUqm9tEZDKgu39cJRNItX+S ------END CERTIFICATE----- - -SecureSign Root CA15 -==================== ------BEGIN CERTIFICATE----- -MIICIzCCAamgAwIBAgIUFhXHw9hJp75pDIqI7fBw+d23PocwCgYIKoZIzj0EAwMwUTELMAkGA1UE -BhMCSlAxIzAhBgNVBAoTGkN5YmVydHJ1c3QgSmFwYW4gQ28uLCBMdGQuMR0wGwYDVQQDExRTZWN1 -cmVTaWduIFJvb3QgQ0ExNTAeFw0yMDA0MDgwODMyNTZaFw00NTA0MDgwODMyNTZaMFExCzAJBgNV -BAYTAkpQMSMwIQYDVQQKExpDeWJlcnRydXN0IEphcGFuIENvLiwgTHRkLjEdMBsGA1UEAxMUU2Vj -dXJlU2lnbiBSb290IENBMTUwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQLUHSNZDKZmbPSYAi4Io5G -dCx4wCtELW1fHcmuS1Iggz24FG1Th2CeX2yF2wYUleDHKP+dX+Sq8bOLbe1PL0vJSpSRZHX+AezB -2Ot6lHhWGENfa4HL9rzatAy2KZMIaY+jQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQD -AgEGMB0GA1UdDgQWBBTrQciu/NWeUUj1vYv0hyCTQSvT9DAKBggqhkjOPQQDAwNoADBlAjEA2S6J -fl5OpBEHvVnCB96rMjhTKkZEBhd6zlHp4P9mLQlO4E/0BdGF9jVg3PVys0Z9AjBEmEYagoUeYWmJ -SwdLZrWeqrqgHkHZAXQ6bkU6iYAZezKYVWOr62Nuk22rGwlgMU4= ------END CERTIFICATE----- - -D-TRUST BR Root CA 2 2023 -========================= ------BEGIN CERTIFICATE----- -MIIFqTCCA5GgAwIBAgIQczswBEhb2U14LnNLyaHcZjANBgkqhkiG9w0BAQ0FADBIMQswCQYDVQQG -EwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEJSIFJvb3QgQ0Eg -MiAyMDIzMB4XDTIzMDUwOTA4NTYzMVoXDTM4MDUwOTA4NTYzMFowSDELMAkGA1UEBhMCREUxFTAT -BgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBCUiBSb290IENBIDIgMjAyMzCC -AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAK7/CVmRgApKaOYkP7in5Mg6CjoWzckjYaCT -cfKri3OPoGdlYNJUa2NRb0kz4HIHE304zQaSBylSa053bATTlfrdTIzZXcFhfUvnKLNEgXtRr90z -sWh81k5M/itoucpmacTsXld/9w3HnDY25QdgrMBM6ghs7wZ8T1soegj8k12b9py0i4a6Ibn08OhZ -WiihNIQaJZG2tY/vsvmA+vk9PBFy2OMvhnbFeSzBqZCTRphny4NqoFAjpzv2gTng7fC5v2Xx2Mt6 -++9zA84A9H3X4F07ZrjcjrqDy4d2A/wl2ecjbwb9Z/Pg/4S8R7+1FhhGaRTMBffb00msa8yr5LUL -QyReS2tNZ9/WtT5PeB+UcSTq3nD88ZP+npNa5JRal1QMNXtfbO4AHyTsA7oC9Xb0n9Sa7YUsOCIv -x9gvdhFP/Wxc6PWOJ4d/GUohR5AdeY0cW/jPSoXk7bNbjb7EZChdQcRurDhaTyN0dKkSw/bSuREV -MweR2Ds3OmMwBtHFIjYoYiMQ4EbMl6zWK11kJNXuHA7e+whadSr2Y23OC0K+0bpwHJwh5Q8xaRfX -/Aq03u2AnMuStIv13lmiWAmlY0cL4UEyNEHZmrHZqLAbWt4NDfTisl01gLmB1IRpkQLLddCNxbU9 -CZEJjxShFHR5PtbJFR2kWVki3PaKRT08EtY+XTIvAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQUZ5Dw1t61GNVGKX5cq/ieCLxklRAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRC -MEAwPqA8oDqGOGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfYnJfcm9vdF9jYV8y -XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQA097N3U9swFrktpSHxQCF16+tIFoE9c+CeJyrr -d6kTpGoKWloUMz1oH4Guaf2Mn2VsNELZLdB/eBaxOqwjMa1ef67nriv6uvw8l5VAk1/DLQOj7aRv -U9f6QA4w9QAgLABMjDu0ox+2v5Eyq6+SmNMW5tTRVFxDWy6u71cqqLRvpO8NVhTaIasgdp4D/Ca4 -nj8+AybmTNudX0KEPUUDAxxZiMrcLmEkWqTqJwtzEr5SswrPMhfiHocaFpVIbVrg0M8JkiZmkdij -YQ6qgYF/6FKC0ULn4B0Y+qSFNueG4A3rvNTJ1jxD8V1Jbn6Bm2m1iWKPiFLY1/4nwSPFyysCu7Ff -/vtDhQNGvl3GyiEm/9cCnnRK3PgTFbGBVzbLZVzRHTF36SXDw7IyN9XxmAnkbWOACKsGkoHU6XCP -pz+y7YaMgmo1yEJagtFSGkUPFaUA8JR7ZSdXOUPPfH/mvTWze/EZTN46ls/pdu4D58JDUjxqgejB -WoC9EV2Ta/vH5mQ/u2kc6d0li690yVRAysuTEwrt+2aSEcr1wPrYg1UDfNPFIkZ1cGt5SAYqgpq/ -5usWDiJFAbzdNpQ0qTUmiteXue4Icr80knCDgKs4qllo3UCkGJCy89UDyibK79XH4I9TjvAA46jt -n/mtd+ArY0+ew+43u3gJhJ65bvspmZDogNOfJA== ------END CERTIFICATE----- - -TrustAsia TLS ECC Root CA -========================= ------BEGIN CERTIFICATE----- -MIICMTCCAbegAwIBAgIUNnThTXxlE8msg1UloD5Sfi9QaMcwCgYIKoZIzj0EAwMwWDELMAkGA1UE -BhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dpZXMsIEluYy4xIjAgBgNVBAMTGVRy -dXN0QXNpYSBUTFMgRUNDIFJvb3QgQ0EwHhcNMjQwNTE1MDU0MTU2WhcNNDQwNTE1MDU0MTU1WjBY -MQswCQYDVQQGEwJDTjElMCMGA1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywgSW5jLjEiMCAG -A1UEAxMZVHJ1c3RBc2lhIFRMUyBFQ0MgUm9vdCBDQTB2MBAGByqGSM49AgEGBSuBBAAiA2IABLh/ -pVs/AT598IhtrimY4ZtcU5nb9wj/1WrgjstEpvDBjL1P1M7UiFPoXlfXTr4sP/MSpwDpguMqWzJ8 -S5sUKZ74LYO1644xST0mYekdcouJtgq7nDM1D9rs3qlKH8kzsaNCMEAwDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQULIVTu7FDzTLqnqOH/qKYqKaT6RAwDgYDVR0PAQH/BAQDAgEGMAoGCCqGSM49 -BAMDA2gAMGUCMFRH18MtYYZI9HlaVQ01L18N9mdsd0AaRuf4aFtOJx24mH1/k78ITcTaRTChD15K -eAIxAKORh/IRM4PDwYqROkwrULG9IpRdNYlzg8WbGf60oenUoWa2AaU2+dhoYSi3dOGiMQ== ------END CERTIFICATE----- - -TrustAsia TLS RSA Root CA -========================= ------BEGIN CERTIFICATE----- -MIIFgDCCA2igAwIBAgIUHBjYz+VTPyI1RlNUJDxsR9FcSpwwDQYJKoZIhvcNAQEMBQAwWDELMAkG -A1UEBhMCQ04xJTAjBgNVBAoTHFRydXN0QXNpYSBUZWNobm9sb2dpZXMsIEluYy4xIjAgBgNVBAMT -GVRydXN0QXNpYSBUTFMgUlNBIFJvb3QgQ0EwHhcNMjQwNTE1MDU0MTU3WhcNNDQwNTE1MDU0MTU2 -WjBYMQswCQYDVQQGEwJDTjElMCMGA1UEChMcVHJ1c3RBc2lhIFRlY2hub2xvZ2llcywgSW5jLjEi -MCAGA1UEAxMZVHJ1c3RBc2lhIFRMUyBSU0EgUm9vdCBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIP -ADCCAgoCggIBAMMWuBtqpERz5dZO9LnPWwvB0ZqB9WOwj0PBuwhaGnrhB3YmH49pVr7+NmDQDIPN -lOrnxS1cLwUWAp4KqC/lYCZUlviYQB2srp10Zy9U+5RjmOMmSoPGlbYJQ1DNDX3eRA5gEk9bNb2/ -mThtfWza4mhzH/kxpRkQcwUqwzIZheo0qt1CHjCNP561HmHVb70AcnKtEj+qpklz8oYVlQwQX1Fk -zv93uMltrOXVmPGZLmzjyUT5tUMnCE32ft5EebuyjBza00tsLtbDeLdM1aTk2tyKjg7/D8OmYCYo -zza/+lcK7Fs/6TAWe8TbxNRkoDD75f0dcZLdKY9BWN4ArTr9PXwaqLEX8E40eFgl1oUh63kd0Nyr -z2I8sMeXi9bQn9P+PN7F4/w6g3CEIR0JwqH8uyghZVNgepBtljhb//HXeltt08lwSUq6HTrQUNoy -IBnkiz/r1RYmNzz7dZ6wB3C4FGB33PYPXFIKvF1tjVEK2sUYyJtt3LCDs3+jTnhMmCWr8n4uIF6C -FabW2I+s5c0yhsj55NqJ4js+k8UTav/H9xj8Z7XvGCxUq0DTbE3txci3OE9kxJRMT6DNrqXGJyV1 -J23G2pyOsAWZ1SgRxSHUuPzHlqtKZFlhaxP8S8ySpg+kUb8OWJDZgoM5pl+z+m6Ss80zDoWo8SnT -q1mt1tve1CuBAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLgHkXlcBvRG/XtZ -ylomkadFK/hTMA4GA1UdDwEB/wQEAwIBBjANBgkqhkiG9w0BAQwFAAOCAgEAIZtqBSBdGBanEqT3 -Rz/NyjuujsCCztxIJXgXbODgcMTWltnZ9r96nBO7U5WS/8+S4PPFJzVXqDuiGev4iqME3mmL5Dw8 -veWv0BIb5Ylrc5tvJQJLkIKvQMKtuppgJFqBTQUYo+IzeXoLH5Pt7DlK9RME7I10nYEKqG/odv6L -TytpEoYKNDbdgptvT+Bz3Ul/KD7JO6NXBNiT2Twp2xIQaOHEibgGIOcberyxk2GaGUARtWqFVwHx -tlotJnMnlvm5P1vQiJ3koP26TpUJg3933FEFlJ0gcXax7PqJtZwuhfG5WyRasQmr2soaB82G39tp -27RIGAAtvKLEiUUjpQ7hRGU+isFqMB3iYPg6qocJQrmBktwliJiJ8Xw18WLK7nn4GS/+X/jbh87q -qA8MpugLoDzga5SYnH+tBuYc6kIQX+ImFTw3OffXvO645e8D7r0i+yiGNFjEWn9hongPXvPKnbwb -PKfILfanIhHKA9jnZwqKDss1jjQ52MjqjZ9k4DewbNfFj8GQYSbbJIweSsCI3zWQzj8C9GRh3sfI -B5XeMhg6j6JCQCTl1jNdfK7vsU1P1FeQNWrcrgSXSYk0ly4wBOeY99sLAZDBHwo/+ML+TvrbmnNz -FrwFuHnYWa8G5z9nODmxfKuU4CkUpijy323imttUQ/hHWKNddBWcwauwxzQ= ------END CERTIFICATE----- - -D-TRUST EV Root CA 2 2023 -========================= ------BEGIN CERTIFICATE----- -MIIFqTCCA5GgAwIBAgIQaSYJfoBLTKCnjHhiU19abzANBgkqhkiG9w0BAQ0FADBIMQswCQYDVQQG -EwJERTEVMBMGA1UEChMMRC1UcnVzdCBHbWJIMSIwIAYDVQQDExlELVRSVVNUIEVWIFJvb3QgQ0Eg -MiAyMDIzMB4XDTIzMDUwOTA5MTAzM1oXDTM4MDUwOTA5MTAzMlowSDELMAkGA1UEBhMCREUxFTAT -BgNVBAoTDEQtVHJ1c3QgR21iSDEiMCAGA1UEAxMZRC1UUlVTVCBFViBSb290IENBIDIgMjAyMzCC -AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANiOo4mAC7JXUtypU0w3uX9jFxPvp1sjW2l1 -sJkKF8GLxNuo4MwxusLyzV3pt/gdr2rElYfXR8mV2IIEUD2BCP/kPbOx1sWy/YgJ25yE7CUXFId/ -MHibaljJtnMoPDT3mfd/06b4HEV8rSyMlD/YZxBTfiLNTiVR8CUkNRFeEMbsh2aJgWi6zCudR3Mf -vc2RpHJqnKIbGKBv7FD0fUDCqDDPvXPIEysQEx6Lmqg6lHPTGGkKSv/BAQP/eX+1SH977ugpbzZM -lWGG2Pmic4ruri+W7mjNPU0oQvlFKzIbRlUWaqZLKfm7lVa/Rh3sHZMdwGWyH6FDrlaeoLGPaxK3 -YG14C8qKXO0elg6DpkiVjTujIcSuWMYAsoS0I6SWhjW42J7YrDRJmGOVxcttSEfi8i4YHtAxq910 -7PncjLgcjmgjutDzUNzPZY9zOjLHfP7KgiJPvo5iR2blzYfi6NUPGJ/lBHJLRjwQ8kTCZFZxTnXo -nMkmdMV9WdEKWw9t/p51HBjGGjp82A0EzM23RWV6sY+4roRIPrN6TagD4uJ+ARZZaBhDM7DS3LAa -QzXupdqpRlyuhoFBAUp0JuyfBr/CBTdkdXgpaP3F9ev+R/nkhbDhezGdpn9yo7nELC7MmVcOIQxF -AZRl62UJxmMiCzNJkkg8/M3OsD6Onov4/knFNXJHAgMBAAGjgY4wgYswDwYDVR0TAQH/BAUwAwEB -/zAdBgNVHQ4EFgQUqvyREBuHkV8Wub9PS5FeAByxMoAwDgYDVR0PAQH/BAQDAgEGMEkGA1UdHwRC -MEAwPqA8oDqGOGh0dHA6Ly9jcmwuZC10cnVzdC5uZXQvY3JsL2QtdHJ1c3RfZXZfcm9vdF9jYV8y -XzIwMjMuY3JsMA0GCSqGSIb3DQEBDQUAA4ICAQCTy6UfmRHsmg1fLBWTxj++EI14QvBukEdHjqOS -Mo1wj/Zbjb6JzkcBahsgIIlbyIIQbODnmaprxiqgYzWRaoUlrRc4pZt+UPJ26oUFKidBK7GB0aL2 -QHWpDsvxVUjY7NHss+jOFKE17MJeNRqrphYBBo7q3C+jisosketSjl8MmxfPy3MHGcRqwnNU73xD -UmPBEcrCRbH0O1P1aa4846XerOhUt7KR/aypH/KH5BfGSah82ApB9PI+53c0BFLd6IHyTS9URZ0V -4U/M5d40VxDJI3IXcI1QcB9WbMy5/zpaT2N6w25lBx2Eof+pDGOJbbJAiDnXH3dotfyc1dZnaVuo -dNv8ifYbMvekJKZ2t0dT741Jj6m2g1qllpBFYfXeA08mD6iL8AOWsKwV0HFaanuU5nCT2vFp4LJi -TZ6P/4mdm13NRemUAiKN4DV/6PEEeXFsVIP4M7kFMhtYVRFP0OUnR3Hs7dpn1mKmS00PaaLJvOwi -S5THaJQXfuKOKD62xur1NGyfN4gHONuGcfrNlUhDbqNPgofXNJhuS5N5YHVpD/Aa1VP6IQzCP+k/ -HxiMkl14p3ZnGbuy6n/pcAlWVqOwDAstNl7F6cTVg8uGF5csbBNvh1qvSaYd2804BC5f4ko1Di1L -+KIkBI3Y4WNeApI02phhXBxvWHZks/wCuPWdCg== ------END CERTIFICATE----- - -SwissSign RSA TLS Root CA 2022 - 1 -================================== ------BEGIN CERTIFICATE----- -MIIFkzCCA3ugAwIBAgIUQ/oMX04bgBhE79G0TzUfRPSA7cswDQYJKoZIhvcNAQELBQAwUTELMAkG -A1UEBhMCQ0gxFTATBgNVBAoTDFN3aXNzU2lnbiBBRzErMCkGA1UEAxMiU3dpc3NTaWduIFJTQSBU -TFMgUm9vdCBDQSAyMDIyIC0gMTAeFw0yMjA2MDgxMTA4MjJaFw00NzA2MDgxMTA4MjJaMFExCzAJ -BgNVBAYTAkNIMRUwEwYDVQQKEwxTd2lzc1NpZ24gQUcxKzApBgNVBAMTIlN3aXNzU2lnbiBSU0Eg -VExTIFJvb3QgQ0EgMjAyMiAtIDEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDLKmji -C8NXvDVjvHClO/OMPE5Xlm7DTjak9gLKHqquuN6orx122ro10JFwB9+zBvKK8i5VUXu7LCTLf5Im -gKO0lPaCoaTo+nUdWfMHamFk4saMla+ju45vVs9xzF6BYQ1t8qsCLqSX5XH8irCRIFucdFJtrhUn -WXjyCcplDn/L9Ovn3KlMd/YrFgSVrpxxpT8q2kFC5zyEEPThPYxr4iuRR1VPuFa+Rd4iUU1OKNlf -GUEGjw5NBuBwQCMBauTLE5tzrE0USJIt/m2n+IdreXXhvhCxqohAWVTXz8TQm0SzOGlkjIHRI36q -OTw7D59Ke4LKa2/KIj4x0LDQKhySio/YGZxH5D4MucLNvkEM+KRHBdvBFzA4OmnczcNpI/2aDwLO -EGrOyvi5KaM2iYauC8BPY7kGWUleDsFpswrzd34unYyzJ5jSmY0lpx+Gs6ZUcDj8fV3oT4MM0ZPl -EuRU2j7yrTrePjxF8CgPBrnh25d7mUWe3f6VWQQvdT/TromZhqwUtKiE+shdOxtYk8EXlFXIC+OC -eYSf8wCENO7cMdWP8vpPlkwGqnj73mSiI80fPsWMvDdUDrtaclXvyFu1cvh43zcgTFeRc5JzrBh3 -Q4IgaezprClG5QtO+DdziZaKHG29777YtvTKwP1H8K4LWCDFyB02rpeNUIMmJCn3nTsPBQIDAQAB -o2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBBjAfBgNVHSMEGDAWgBRvjmKLk0Ow -4UD2p8P98Q+4DxU4pTAdBgNVHQ4EFgQUb45ii5NDsOFA9qfD/fEPuA8VOKUwDQYJKoZIhvcNAQEL -BQADggIBAKwsKUF9+lz1GpUYvyypiqkkVHX1uECry6gkUSsYP2OprphWKwVDIqO310aewCoSPY6W -lkDfDDOLazeROpW7OSltwAJsipQLBwJNGD77+3v1dj2b9l4wBlgzHqp41eZUBDqyggmNzhYzWUUo -8aWjlw5DI/0LIICQ/+Mmz7hkkeUFjxOgdg3XNwwQiJb0Pr6VvfHDffCjw3lHC1ySFWPtUnWK50Zp -y1FVCypM9fJkT6lc/2cyjlUtMoIcgC9qkfjLvH4YoiaoLqNTKIftV+Vlek4ASltOU8liNr3Cjlvr -zG4ngRhZi0Rjn9UMZfQpZX+RLOV/fuiJz48gy20HQhFRJjKKLjpHE7iNvUcNCfAWpO2Whi4Z2L6M -OuhFLhG6rlrnub+xzI/goP+4s9GFe3lmozm1O2bYQL7Pt2eLSMkZJVX8vY3PXtpOpvJpzv1/THfQ -wUY1mFwjmwJFQ5Ra3bxHrSL+ul4vkSkphnsh3m5kt8sNjzdbowhq6/TdAo9QAwKxuDdollDruF/U -KIqlIgyKhPBZLtU30WHlQnNYKoH3dtvi4k0NX/a3vgW0rk4N3hY9A4GzJl5LuEsAz/+MF7psYC0n -hzck5npgL7XTgwSqT0N1osGDsieYK7EOgLrAhV5Cud+xYJHT6xh+cHiudoO+cVrQkOPKwRYlZ0rw -tnu64ZzZ ------END CERTIFICATE----- - -OISTE Server Root ECC G1 -======================== ------BEGIN CERTIFICATE----- -MIICNTCCAbqgAwIBAgIQI/nD1jWvjyhLH/BU6n6XnTAKBggqhkjOPQQDAzBLMQswCQYDVQQGEwJD -SDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UEAwwYT0lTVEUgU2VydmVyIFJvb3Qg -RUNDIEcxMB4XDTIzMDUzMTE0NDIyOFoXDTQ4MDUyNDE0NDIyN1owSzELMAkGA1UEBhMCQ0gxGTAX -BgNVBAoMEE9JU1RFIEZvdW5kYXRpb24xITAfBgNVBAMMGE9JU1RFIFNlcnZlciBSb290IEVDQyBH -MTB2MBAGByqGSM49AgEGBSuBBAAiA2IABBcv+hK8rBjzCvRE1nZCnrPoH7d5qVi2+GXROiFPqOuj -vqQycvO2Ackr/XeFblPdreqqLiWStukhEaivtUwL85Zgmjvn6hp4LrQ95SjeHIC6XG4N2xml4z+c -KrhAS93mT6NjMGEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBQ3TYhlz/w9itWj8UnATgwQ -b0K0nDAdBgNVHQ4EFgQUN02IZc/8PYrVo/FJwE4MEG9CtJwwDgYDVR0PAQH/BAQDAgGGMAoGCCqG -SM49BAMDA2kAMGYCMQCpKjAd0MKfkFFRQD6VVCHNFmb3U2wIFjnQEnx/Yxvf4zgAOdktUyBFCxxg -ZzFDJe0CMQCSia7pXGKDYmH5LVerVrkR3SW+ak5KGoJr3M/TvEqzPNcum9v4KGm8ay3sMaE641c= ------END CERTIFICATE----- - - OISTE Server Root RSA G1 -========================= ------BEGIN CERTIFICATE----- -MIIFgzCCA2ugAwIBAgIQVaXZZ5Qoxu0M+ifdWwFNGDANBgkqhkiG9w0BAQwFADBLMQswCQYDVQQG -EwJDSDEZMBcGA1UECgwQT0lTVEUgRm91bmRhdGlvbjEhMB8GA1UEAwwYT0lTVEUgU2VydmVyIFJv -b3QgUlNBIEcxMB4XDTIzMDUzMTE0MzcxNloXDTQ4MDUyNDE0MzcxNVowSzELMAkGA1UEBhMCQ0gx -GTAXBgNVBAoMEE9JU1RFIEZvdW5kYXRpb24xITAfBgNVBAMMGE9JU1RFIFNlcnZlciBSb290IFJT -QSBHMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKqu9KuCz/vlNwvn1ZatkOhLKdxV -YOPMvLO8LZK55KN68YG0nnJyQ98/qwsmtO57Gmn7KNByXEptaZnwYx4M0rH/1ow00O7brEi56rAU -jtgHqSSY3ekJvqgiG1k50SeH3BzN+Puz6+mTeO0Pzjd8JnduodgsIUzkik/HEzxux9UTl7Ko2yRp -g1bTacuCErudG/L4NPKYKyqOBGf244ehHa1uzjZ0Dl4zO8vbUZeUapU8zhhabkvG/AePLhq5Svdk -NCncpo1Q4Y2LS+VIG24ugBA/5J8bZT8RtOpXaZ+0AOuFJJkk9SGdl6r7NH8CaxWQrbueWhl/pIzY -+m0o/DjH40ytas7ZTpOSjswMZ78LS5bOZmdTaMsXEY5Z96ycG7mOaES3GK/m5Q9l3JUJsJMStR8+ -lKXHiHUhsd4JJCpM4rzsTGdHwimIuQq6+cF0zowYJmXa92/GjHtoXAvuY8BeS/FOzJ8vD+HomnqT -8eDI278n5mUpezbgMxVz8p1rhAhoKzYHKyfMeNhqhw5HdPSqoBNdZH702xSu+zrkL8Fl47l6QGzw -Brd7KJvX4V84c5Ss2XCTLdyEr0YconosP4EmQufU2MVshGYRi3drVByjtdgQ8K4p92cIiBdcuJd5 -z+orKu5YM+Vt6SmqZQENghPsJQtdLEByFSnTkCz3GkPVavBpAgMBAAGjYzBhMA8GA1UdEwEB/wQF -MAMBAf8wHwYDVR0jBBgwFoAU8snBDw1jALvsRQ5KH7WxszbNDo0wHQYDVR0OBBYEFPLJwQ8NYwC7 -7EUOSh+1sbM2zQ6NMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQwFAAOCAgEANGd5sjrG5T33 -I3K5Ce+SrScfoE4KsvXaFwyihdJ+klH9FWXXXGtkFu6KRcoMQzZENdl//nk6HOjG5D1rd9QhEOP2 -8yBOqb6J8xycqd+8MDoX0TJD0KqKchxRKEzdNsjkLWd9kYccnbz8qyiWXmFcuCIzGEgWUOrKL+ml -Sdx/PKQZvDatkuK59EvV6wit53j+F8Bdh3foZ3dPAGav9LEDOr4SfEE15fSmG0eLy3n31r8Xbk5l -8PjaV8GUgeV6Vg27Rn9vkf195hfkgSe7BYhW3SCl95gtkRlpMV+bMPKZrXJAlszYd2abtNUOshD+ -FKrDgHGdPY3ofRRsYWSGRqbXVMW215AWRqWFyp464+YTFrYVI8ypKVL9AMb2kI5Wj4kI3Zaq5tNq -qYY19tVFeEJKRvwDyF7YZvZFZSS0vod7VSCd9521Kvy5YhnLbDuv0204bKt7ph6N/Ome/msVuduC -msuY33OhkKCgxeDoAaijFJzIwZqsFVAzje18KotzlUBDJvyBpCpfOZC3J8tRd/iWkx7P8nd9H0aT -olkelUTFLXVksNb54Dxp6gS1HAviRkRNQzuXSXERvSS2wq1yVAb+axj5d9spLFKebXd7Yv0PTY6Y -MjAwcRLWJTXjn/hvnLXrahut6hDTlhZyBiElxky8j3C7DOReIoMt0r7+hVu05L0= ------END CERTIFICATE----- diff --git a/wasm/mix-fetch/go-mix-conn/internal/sslhelpers/root_certs.go b/wasm/mix-fetch/go-mix-conn/internal/sslhelpers/root_certs.go deleted file mode 100644 index 2e8daa60a7..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/sslhelpers/root_certs.go +++ /dev/null @@ -1,41 +0,0 @@ -package sslhelpers - -import ( - "crypto/x509" - _ "embed" - "go-mix-conn/internal/log" - "strings" - "sync" -) - -// cacert.pem is the Mozilla CA root certificate bundle from curl.se. -// To update, run: scripts/update-root-certs.sh -// -//go:embed cacert.pem -var caCertPEM []byte - -var ( - rootCertPool *x509.CertPool - rootCertOnce sync.Once -) - -func rootCerts() *x509.CertPool { - rootCertOnce.Do(func() { - // Log the bundle date from the PEM header once at first use. - for _, line := range strings.SplitN(string(caCertPEM), "\n", 20) { - if strings.Contains(line, "Certificate data from Mozilla as of:") { - log.Info("Root CA bundle: %s", strings.TrimPrefix(line, "## ")) - break - } - } - - rootCertPool = x509.NewCertPool() - ok := rootCertPool.AppendCertsFromPEM(caCertPEM) - if !ok { - log.Error("failed to parse any certificates from embedded cacert.pem") - panic("failed to parse root certificates") - } - }) - - return rootCertPool -} diff --git a/wasm/mix-fetch/go-mix-conn/internal/sslhelpers/ssl_helper.go b/wasm/mix-fetch/go-mix-conn/internal/sslhelpers/ssl_helper.go deleted file mode 100644 index 97d118933b..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/sslhelpers/ssl_helper.go +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -package sslhelpers - -import ( - "crypto/tls" -) - -func TlsConfig(serverName string) tls.Config { - return tls.Config{ - ServerName: serverName, - RootCAs: rootCerts(), - } -} diff --git a/wasm/mix-fetch/go-mix-conn/internal/state/fake_connection.go b/wasm/mix-fetch/go-mix-conn/internal/state/fake_connection.go deleted file mode 100644 index b15841e209..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/state/fake_connection.go +++ /dev/null @@ -1,307 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -package state - -import ( - "bytes" - "crypto/tls" - "go-mix-conn/internal/bridge/rust_bridge" - "go-mix-conn/internal/log" - "go-mix-conn/internal/sslhelpers" - "go-mix-conn/internal/types" - "io" - "net" - "os" - "sync" - "time" -) - -// InjectedData is, well, the injected server data that came from the mixnet into this connection -type InjectedData struct { - ServerData <-chan []byte - //RemoteClosed <-chan bool - RemoteDone <-chan struct{} - - RemoteError <-chan error -} - -// ConnectionInjector controls data that goes over corresponding FakeConnection -type ConnectionInjector struct { - ServerData chan<- []byte - RemoteDone chan<- struct{} - //RemoteClosed chan<- bool - RemoteError chan<- error -} - -// FakeConnection is a type implementing net.Conn interface that allows us -// to inspect and control bytes that would normally go onto the wire -type FakeConnection struct { - requestId types.RequestId - remoteAddress string - data *InjectedData - - localDone chan struct{} - - readDeadline connDeadline - writeDeadline connDeadline - - pendingReads chan []byte -} - -// connDeadline is an abstraction for handling timeouts. -// source: https://github.com/golang/go/blob/release-branch.go1.20/src/net/pipe.go#L15 -type connDeadline struct { - mu sync.Mutex // Guards timer and cancel - timer *time.Timer - cancel chan struct{} // Must be non-nil -} - -func makeConnDeadline() connDeadline { - return connDeadline{cancel: make(chan struct{})} -} - -// set sets the point in time when the deadline will time out. -// A timeout event is signaled by closing the channel returned by waiter. -// Once a timeout has occurred, the deadline can be refreshed by specifying a -// t value in the future. -// -// A zero value for t prevents timeout. -// source: https://github.com/golang/go/blob/release-branch.go1.20/src/net/pipe.go#L31 -func (d *connDeadline) set(t time.Time) { - d.mu.Lock() - defer d.mu.Unlock() - - if d.timer != nil && !d.timer.Stop() { - <-d.cancel // Wait for the timer callback to finish and close cancel - } - d.timer = nil - - // Time is zero, then there is no deadline. - closed := isClosedChan(d.cancel) - if t.IsZero() { - if closed { - d.cancel = make(chan struct{}) - } - return - } - - // Time in the future, setup a timer to cancel in the future. - if dur := time.Until(t); dur > 0 { - if closed { - d.cancel = make(chan struct{}) - } - d.timer = time.AfterFunc(dur, func() { - close(d.cancel) - }) - return - } - - // Time in the past, so close immediately. - if !closed { - close(d.cancel) - } -} - -func (d *connDeadline) wait() chan struct{} { - d.mu.Lock() - defer d.mu.Unlock() - return d.cancel -} - -func isClosedChan(c <-chan struct{}) bool { - select { - case <-c: - return true - default: - return false - } -} - -// NewFakeConnection creates a new FakeConnection that implements net.Conn interface alongside -// handlers for injecting data into it -func NewFakeConnection(requestId types.RequestId, remoteAddress string) (*FakeConnection, ConnectionInjector) { - serverData := make(chan []byte, 10) - //remoteClosed := make(chan bool, 1) - remoteError := make(chan error, 1) - - localDone := make(chan struct{}) - remoteDone := make(chan struct{}) - - inj := ConnectionInjector{ - ServerData: serverData, - //RemoteClosed: remoteClosed, - RemoteDone: remoteDone, - RemoteError: remoteError, - } - - conn := &FakeConnection{ - data: &InjectedData{ - ServerData: serverData, - //RemoteClosed: remoteClosed, - RemoteDone: remoteDone, - RemoteError: remoteError, - }, - requestId: requestId, - remoteAddress: remoteAddress, - pendingReads: make(chan []byte, 1), - localDone: localDone, - readDeadline: makeConnDeadline(), - writeDeadline: makeConnDeadline(), - } - - return conn, inj -} - -// NewFakeTlsConn wraps a FakeConnection with all the TLS magic -// note: this returns a tls.Conn in the pre-handshake state -func NewFakeTlsConn(connectionId types.RequestId, remoteAddress string) (*tls.Conn, ConnectionInjector) { - host, _, err := net.SplitHostPort(remoteAddress) - if err != nil { - panic("todo") - } - conn, inj := NewFakeConnection(connectionId, remoteAddress) - tlsConfig := sslhelpers.TlsConfig(host) - tlsConn := tls.Client(conn, &tlsConfig) - return tlsConn, inj -} - -func (conn *FakeConnection) readAndBuffer(in []byte, out []byte) (int, error) { - buf := bytes.NewReader(in) - n, err := buf.Read(out) - - remaining := buf.Len() - if remaining > 0 { - leftover := make([]byte, remaining) - _, _ = buf.Read(leftover) - conn.pendingReads <- leftover - } - - log.Debug("READING INJECTED %d bytes <<<", n) - return n, err -} - -// TODO: so many EOF edge cases here... -func (conn *FakeConnection) Read(p []byte) (int, error) { - switch { - case isClosedChan(conn.localDone): - return 0, io.ErrClosedPipe - //case isClosedChan(conn.data.RemoteDone): - // return 0, io.EOF - case isClosedChan(conn.readDeadline.wait()): - return 0, os.ErrDeadlineExceeded - } - - // TODO: is there really no better way for priority chan reads? - select { - // see if we have any leftover data from the previous read - case incomplete := <-conn.pendingReads: - log.Trace("reading previously incomplete data") - return conn.readAndBuffer(incomplete, p) - default: - // reason for this extra select: - // if we have BOTH server data and closing information - you HAVE TO use up the data first - select { - // if we have any data: do read it - case injectedData := <-conn.data.ServerData: - log.Trace("server data") - return conn.readAndBuffer(injectedData, p) - default: - // we wait for either some data, closing info, an error or timeout - select { - case data := <-conn.data.ServerData: - if len(data) == 0 { - return 0, io.EOF - } - return conn.readAndBuffer(data, p) - case err := <-conn.data.RemoteError: - return 0, err - case <-conn.localDone: - return 0, io.ErrClosedPipe - case <-conn.data.RemoteDone: - return 0, io.EOF - case <-conn.readDeadline.wait(): - return 0, os.ErrDeadlineExceeded - } - } - } -} - -func (conn *FakeConnection) Write(p []byte) (int, error) { - log.Debug("WRITING %d bytes TO 'REMOTE' >>> \n", len(p)) - - switch { - case isClosedChan(conn.localDone): - return 0, io.ErrClosedPipe - //case isClosedChan(conn.data.RemoteDone): - // return 0, io.EOF - case isClosedChan(conn.readDeadline.wait()): - return 0, os.ErrDeadlineExceeded - } - - // TODO: I guess the deadline should take into consideration the recipient actually getting the packet... - err := rust_bridge.RsSendClientData(conn.requestId, p) - if err != nil { - return 0, err - } else { - return len(p), nil - } -} - -func (conn *FakeConnection) Close() error { - log.Debug("closing FakeConnection") - - close(conn.localDone) - ActiveRequests.Remove(conn.requestId) - - // TODO: if we already received information about remote being closed, - // do we have to send a socks5 closing packet? - return rust_bridge.RsFinishMixnetConnection(conn.requestId) -} - -func (conn *FakeConnection) LocalAddr() net.Addr { - log.Warn("TODO: implement LocalAddr FakeConnection") - return nil -} - -func (conn *FakeConnection) RemoteAddr() net.Addr { - log.Warn("TODO: implement RemoteAddr FakeConnection") - return nil -} - -func (conn *FakeConnection) SetDeadline(t time.Time) error { - log.Trace("Setting deadline to %v\n", t) - - if isClosedChan(conn.localDone) || isClosedChan(conn.data.RemoteDone) { - return io.ErrClosedPipe - } - - conn.readDeadline.set(t) - conn.writeDeadline.set(t) - - return nil -} - -func (conn *FakeConnection) SetReadDeadline(t time.Time) error { - log.Trace("Setting read deadline to %v\n", t) - - if isClosedChan(conn.localDone) || isClosedChan(conn.data.RemoteDone) { - return io.ErrClosedPipe - } - - conn.readDeadline.set(t) - - return nil -} - -func (conn *FakeConnection) SetWriteDeadline(t time.Time) error { - log.Trace("Setting write deadline to %v\n", t) - - if isClosedChan(conn.localDone) || isClosedChan(conn.data.RemoteDone) { - return io.ErrClosedPipe - } - - conn.writeDeadline.set(t) - - return nil -} diff --git a/wasm/mix-fetch/go-mix-conn/internal/state/state.go b/wasm/mix-fetch/go-mix-conn/internal/state/state.go deleted file mode 100644 index ca05ff5812..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/state/state.go +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -package state - -import ( - "go-mix-conn/internal/log" - "go-mix-conn/internal/types" - "sync" - "time" -) - -// ALL THE GLOBALS SHOULD GO HERE -var ActiveRequests *CurrentActiveRequests -var RequestTimeout time.Duration = time.Second * 5 - -// 4.4.7 -var MaxRedirections int = 20 - -func InitialiseGlobalState() { - ActiveRequests = &CurrentActiveRequests{ - Mutex: sync.Mutex{}, - Requests: make(map[types.RequestId]*ActiveRequest), - AddressMapping: make(map[string]types.RequestId), - } -} - -// CurrentActiveRequests tracks ongoing requests for thread-safe access. -// The AddressMapping uses unique keys (URL + random suffix) so that -// concurrent requests to the same URL each get their own entry. -type CurrentActiveRequests struct { - sync.Mutex - Requests map[types.RequestId]*ActiveRequest - AddressMapping map[string]types.RequestId // key is URL + random suffix -} - -// GetId returns the request ID associated with the given mapping key. -func (ar *CurrentActiveRequests) GetId(mappingKey string) types.RequestId { - log.Trace("getting id associated with mapping key %s", mappingKey) - ar.Lock() - defer ar.Unlock() - return ar.AddressMapping[mappingKey] -} - -func (ar *CurrentActiveRequests) Exists(id types.RequestId) bool { - log.Trace("checking if request %d exists", id) - ar.Lock() - defer ar.Unlock() - _, exists := ar.Requests[id] - return exists -} - -// Insert adds a new active request to the tracking maps. -// The mappingKey should be a unique key (URL + random suffix) for this request. -func (ar *CurrentActiveRequests) Insert(id types.RequestId, mappingKey string, inj ConnectionInjector) { - log.Trace("inserting request %d with mapping key %s", id, mappingKey) - ar.Lock() - defer ar.Unlock() - _, exists := ar.Requests[id] - if exists { - panic("attempted to overwrite active connection id") - } - _, exists = ar.AddressMapping[mappingKey] - if exists { - panic("attempted to overwrite active connection mapping key") - } - - ar.Requests[id] = &ActiveRequest{injector: inj, mappingKey: mappingKey} - ar.AddressMapping[mappingKey] = id -} - -func (ar *CurrentActiveRequests) Remove(id types.RequestId) { - log.Trace("removing request %d", id) - ar.Lock() - defer ar.Unlock() - req, exists := ar.Requests[id] - if !exists { - panic("attempted to remove active connection id that doesn't exist") - } - _, exists = ar.AddressMapping[req.mappingKey] - if !exists { - panic("attempted to remove active connection mapping key that doesn't exist") - } - - delete(ar.Requests, id) - delete(ar.AddressMapping, req.mappingKey) -} - -func (ar *CurrentActiveRequests) InjectData(id types.RequestId, data []byte) { - log.Trace("injecting data for %d", id) - ar.Lock() - defer ar.Unlock() - _, exists := ar.Requests[id] - if !exists { - panic("attempted to write to connection that doesn't exist") - } - ar.Requests[id].injector.ServerData <- data -} - -func (ar *CurrentActiveRequests) CloseRemoteSocket(id types.RequestId) { - log.Trace("closing remote socket for %d", id) - ar.Lock() - defer ar.Unlock() - _, exists := ar.Requests[id] - if !exists { - log.Warn("attempted to close remote socket of a connection that doesn't exist") - return - } - close(ar.Requests[id].injector.RemoteDone) -} - -func (ar *CurrentActiveRequests) SendError(id types.RequestId, err error) { - log.Trace("injecting error for %d: %s", id, err) - ar.Lock() - defer ar.Unlock() - _, exists := ar.Requests[id] - if !exists { - panic("attempted to inject error data to connection that doesn't exist") - } - ar.Requests[id].injector.RemoteError <- err -} - -type ActiveRequest struct { - injector ConnectionInjector - mappingKey string // Unique key for AddressMapping (URL + random suffix) -} diff --git a/wasm/mix-fetch/go-mix-conn/internal/types/options.go b/wasm/mix-fetch/go-mix-conn/internal/types/options.go deleted file mode 100644 index 6383aa5c5e..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/types/options.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -package types - -import ( - "fmt" - "go-mix-conn/internal/jstypes" -) - -type RequestOptions struct { - Redirect jstypes.Redirect - Mode jstypes.Mode - CredentialsMode jstypes.CredentialsMode - ReferrerPolicy jstypes.ReferrerPolicy - Referrer jstypes.Referrer - ResponseTainting jstypes.ResponseTainting - Method string -} - -func (opts RequestOptions) String() string { - return fmt.Sprintf( - "{ Redirect: %s, Mode: %s, credentials: %s, ReferrerPolicy: %s, Referrer: %s, ResponseTainting: %s, Method: %s }", - opts.Redirect, - opts.Mode, - opts.CredentialsMode, - opts.ReferrerPolicy, - opts.Referrer, - opts.ResponseTainting, - opts.Method, - ) -} - -type RequestContext struct { - WasRedirected bool - OverwrittenResponseType jstypes.ResponseType -} diff --git a/wasm/mix-fetch/go-mix-conn/internal/types/types.go b/wasm/mix-fetch/go-mix-conn/internal/types/types.go deleted file mode 100644 index 5c366af950..0000000000 --- a/wasm/mix-fetch/go-mix-conn/internal/types/types.go +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -package types - -type RequestId = uint64 diff --git a/wasm/mix-fetch/go-mix-conn/scripts/update-root-certs.sh b/wasm/mix-fetch/go-mix-conn/scripts/update-root-certs.sh deleted file mode 100755 index 47d54b9f2c..0000000000 --- a/wasm/mix-fetch/go-mix-conn/scripts/update-root-certs.sh +++ /dev/null @@ -1,58 +0,0 @@ -#!/usr/bin/env bash -# -# Downloads the latest timestamped Mozilla CA root certificate bundle from -# curl.se and places it in the sslhelpers package for embedding into the binary. -# -# Usage: -# ./scripts/update-root-certs.sh # uses latest available bundle -# ./scripts/update-root-certs.sh 2025-12-02 # uses a specific dated bundle -# -# Run this before the SDK version bump script. - -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -OUTPUT_DIR="${SCRIPT_DIR}/../internal/sslhelpers" -OUTPUT_FILE="${OUTPUT_DIR}/cacert.pem" - -# Determine which bundle to fetch -if [[ $# -ge 1 ]]; then - DATE="$1" -else - # Fetch the main page to find the latest dated bundle - LATEST_DATE=$(curl -sL https://curl.se/docs/caextract.html \ - | grep -oP 'cacert-\K[0-9]{4}-[0-9]{2}-[0-9]{2}(?=\.pem)' \ - | sort -r | head -1) - if [[ -z "$LATEST_DATE" ]]; then - echo "ERROR: Could not determine latest bundle date from curl.se" - exit 1 - fi - DATE="$LATEST_DATE" - echo "Latest bundle date: ${DATE}" -fi - -PEM_URL="https://curl.se/ca/cacert-${DATE}.pem" -SHA_URL="${PEM_URL}.sha256" - -echo "Downloading ${PEM_URL} ..." -TMPFILE=$(mktemp /tmp/cacert-XXXXXX.pem) -trap "rm -f ${TMPFILE}" EXIT - -curl -sL -o "${TMPFILE}" "${PEM_URL}" - -# Verify SHA256 -EXPECTED_SHA=$(curl -sL "${SHA_URL}" | awk '{print $1}') -ACTUAL_SHA=$(sha256sum "${TMPFILE}" | awk '{print $1}') - -if [[ "${EXPECTED_SHA}" != "${ACTUAL_SHA}" ]]; then - echo "ERROR: SHA256 mismatch!" - echo " expected: ${EXPECTED_SHA}" - echo " actual: ${ACTUAL_SHA}" - exit 1 -fi -echo "SHA256 verified: ${ACTUAL_SHA}" - -CERT_COUNT=$(grep -c 'BEGIN CERTIFICATE' "${TMPFILE}") - -cp "${TMPFILE}" "${OUTPUT_FILE}" -echo "Done. Placed ${CERT_COUNT} certificates (bundle date: ${DATE}) at ${OUTPUT_FILE}" diff --git a/wasm/mix-fetch/internal-dev-node/.gitignore b/wasm/mix-fetch/internal-dev-node/.gitignore deleted file mode 100644 index 6a91a439ea..0000000000 --- a/wasm/mix-fetch/internal-dev-node/.gitignore +++ /dev/null @@ -1 +0,0 @@ -*.sqlite \ No newline at end of file diff --git a/wasm/mix-fetch/internal-dev-node/package-lock.json b/wasm/mix-fetch/internal-dev-node/package-lock.json deleted file mode 100644 index 7bdb1add75..0000000000 --- a/wasm/mix-fetch/internal-dev-node/package-lock.json +++ /dev/null @@ -1,1564 +0,0 @@ -{ - "name": "internal-dev-node", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "internal-dev-node", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "@nymproject/mix-fetch-wasm": "file:../../../dist/node/wasm/mix-fetch", - "indexeddbshim": "^13.0.0-pre.1", - "node-fetch": "^3.3.2", - "ws": "^8.13.0" - } - }, - "../../../dist/node/wasm/mix-fetch": { - "name": "@nymproject/mix-fetch-wasm", - "version": "1.2.0-rc.2" - }, - "node_modules/@gar/promisify": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "license": "MIT", - "optional": true - }, - "node_modules/@mapbox/node-pre-gyp": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz", - "integrity": "sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==", - "license": "BSD-3-Clause", - "dependencies": { - "detect-libc": "^2.0.0", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.7", - "nopt": "^5.0.0", - "npmlog": "^5.0.1", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.11" - }, - "bin": { - "node-pre-gyp": "bin/node-pre-gyp" - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/node-fetch": { - "version": "2.6.12", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz", - "integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/@mapbox/node-pre-gyp/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/@npmcli/fs": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz", - "integrity": "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==", - "license": "ISC", - "optional": true, - "dependencies": { - "@gar/promisify": "^1.0.1", - "semver": "^7.3.5" - } - }, - "node_modules/@npmcli/move-file": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz", - "integrity": "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==", - "license": "MIT", - "optional": true, - "dependencies": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@nymproject/mix-fetch-wasm": { - "resolved": "../../../dist/node/wasm/mix-fetch", - "link": true - }, - "node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "license": "ISC" - }, - "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", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/agentkeepalive": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz", - "integrity": "sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew==", - "license": "MIT", - "optional": true, - "dependencies": { - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "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==", - "license": "MIT", - "optional": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "license": "ISC" - }, - "node_modules/are-we-there-yet": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz", - "integrity": "sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==", - "license": "ISC", - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/argsarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/argsarray/-/argsarray-0.0.1.tgz", - "integrity": "sha512-u96dg2GcAKtpTrBdDoFIM7PjcBA+6rSP0OR94MOReNRyUECL6MtQt5XXmRr4qrftYaef9+l5hcpO5te7sML1Cg==", - "license": "WTFPL" - }, - "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" - }, - "node_modules/base64-arraybuffer-es6": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/base64-arraybuffer-es6/-/base64-arraybuffer-es6-3.0.1.tgz", - "integrity": "sha512-bOxevePlYA8Kba1xVnrQSoktrt12UkP6Jhl2wO+GCGbKAkF4fpDxyg7xRFffZYC0kP2RgMPOSRbzmdHReWnMyg==", - "license": "MIT", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/cacache": { - "version": "15.3.0", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz", - "integrity": "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==", - "license": "ISC", - "optional": true, - "dependencies": { - "@npmcli/fs": "^1.0.0", - "@npmcli/move-file": "^1.0.1", - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "glob": "^7.1.4", - "infer-owner": "^1.0.4", - "lru-cache": "^6.0.0", - "minipass": "^3.1.1", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.2", - "mkdirp": "^1.0.3", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^8.0.1", - "tar": "^6.0.2", - "unique-filename": "^1.1.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/canvas": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/canvas/-/canvas-2.11.2.tgz", - "integrity": "sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.0", - "nan": "^2.17.0", - "simple-get": "^3.0.3" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "license": "ISC", - "engines": { - "node": ">=10" - } - }, - "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==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "license": "ISC", - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "license": "MIT" - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==", - "license": "ISC" - }, - "node_modules/data-uri-to-buffer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", - "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", - "engines": { - "node": ">= 12" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decompress-response": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz", - "integrity": "sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==", - "license": "MIT", - "dependencies": { - "mimic-response": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==", - "license": "MIT" - }, - "node_modules/detect-libc": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", - "integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "license": "MIT" - }, - "node_modules/encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "license": "MIT", - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=6" - } - }, - "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==", - "license": "MIT", - "optional": true - }, - "node_modules/eventtargeter": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/eventtargeter/-/eventtargeter-0.9.0.tgz", - "integrity": "sha512-40f2UpTpS7v2GnXWsMpEUkKoMOlgTDrijhCx4Hq7zvsBhLihA7dn0Ayicb4FO/MOIzD5mLHsLK7/NYqx39LqaA==", - "license": "MIT", - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/fetch-blob": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz", - "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "paypal", - "url": "https://paypal.me/jimmywarting" - } - ], - "dependencies": { - "node-domexception": "^1.0.0", - "web-streams-polyfill": "^3.0.3" - }, - "engines": { - "node": "^12.20 || >= 14.13" - } - }, - "node_modules/formdata-polyfill": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", - "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", - "dependencies": { - "fetch-blob": "^3.1.2" - }, - "engines": { - "node": ">=12.20.0" - } - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "license": "ISC", - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "license": "ISC" - }, - "node_modules/gauge": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", - "integrity": "sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==", - "license": "ISC", - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.2", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.1", - "object-assign": "^4.1.1", - "signal-exit": "^3.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "license": "ISC", - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/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==", - "license": "ISC", - "optional": true - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==", - "license": "ISC" - }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", - "license": "BSD-2-Clause", - "optional": true - }, - "node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "license": "MIT", - "optional": true, - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "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/humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "ms": "^2.0.0" - } - }, - "node_modules/humanize-ms/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", - "optional": true - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "license": "MIT", - "optional": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/immediate": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz", - "integrity": "sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==", - "license": "MIT" - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "license": "MIT", - "optional": true, - "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==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/indexeddbshim": { - "version": "13.0.0-pre.1", - "resolved": "https://registry.npmjs.org/indexeddbshim/-/indexeddbshim-13.0.0-pre.1.tgz", - "integrity": "sha512-Tl0FAiQvp0zdTiWZf267d6MN0cFk64z8oa39zpexIkX3Nk/AY5iYhPqvpQcGOxXJWdY/IWOyZFZb4K2qhRtxng==", - "license": "(MIT OR Apache-2.0)", - "dependencies": { - "canvas": "^2.11.2", - "eventtargeter": "0.9.0", - "sync-promise-expanded": "^1.0.0", - "typeson": "9.0.2", - "typeson-registry": "7.2.1", - "websql-configurable": "^3.0.3" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "license": "ISC", - "optional": true - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "license": "ISC", - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "license": "ISC" - }, - "node_modules/ip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", - "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==", - "optional": true - }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/is-lambda": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==", - "license": "MIT", - "optional": true - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "license": "ISC", - "optional": true - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "license": "ISC", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "license": "MIT", - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/make-fetch-happen": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz", - "integrity": "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==", - "license": "ISC", - "optional": true, - "dependencies": { - "agentkeepalive": "^4.1.3", - "cacache": "^15.2.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^6.0.0", - "minipass": "^3.1.3", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^1.3.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.2", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^6.0.0", - "ssri": "^8.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/mimic-response": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", - "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minipass": { - "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" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "license": "ISC", - "optional": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-fetch": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz", - "integrity": "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==", - "license": "MIT", - "optional": true, - "dependencies": { - "minipass": "^3.1.0", - "minipass-sized": "^1.0.3", - "minizlib": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "optionalDependencies": { - "encoding": "^0.1.12" - } - }, - "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==", - "license": "ISC", - "optional": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "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", - "optional": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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==", - "license": "ISC", - "optional": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "license": "MIT", - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "license": "MIT", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "license": "MIT" - }, - "node_modules/nan": { - "version": "2.17.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz", - "integrity": "sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==", - "license": "MIT" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/node-addon-api": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", - "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==", - "license": "MIT", - "optional": true - }, - "node_modules/node-domexception": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz", - "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/jimmywarting" - }, - { - "type": "github", - "url": "https://paypal.me/jimmywarting" - } - ], - "engines": { - "node": ">=10.5.0" - } - }, - "node_modules/node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } - }, - "node_modules/node-gyp": { - "version": "8.4.1", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz", - "integrity": "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w==", - "license": "MIT", - "optional": true, - "dependencies": { - "env-paths": "^2.2.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^9.1.0", - "nopt": "^5.0.0", - "npmlog": "^6.0.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^2.0.2" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": ">= 10.12.0" - } - }, - "node_modules/node-gyp/node_modules/are-we-there-yet": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz", - "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", - "license": "ISC", - "optional": true, - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/node-gyp/node_modules/gauge": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", - "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", - "license": "ISC", - "optional": true, - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/node-gyp/node_modules/npmlog": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz", - "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", - "license": "ISC", - "optional": true, - "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.3", - "set-blocking": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/noop-fn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/noop-fn/-/noop-fn-1.0.0.tgz", - "integrity": "sha512-pQ8vODlgXt2e7A3mIbFDlizkr46r75V+BJxVAyat8Jl7YmI513gG5cfyRL0FedKraoZ+VAouI1h4/IWpus5pcQ==", - "license": "MIT" - }, - "node_modules/nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "license": "ISC", - "dependencies": { - "abbrev": "1" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/npmlog": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz", - "integrity": "sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==", - "license": "ISC", - "dependencies": { - "are-we-there-yet": "^2.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^3.0.0", - "set-blocking": "^2.0.0" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "license": "ISC", - "dependencies": { - "wrappy": "1" - } - }, - "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==", - "license": "MIT", - "optional": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==", - "license": "ISC", - "optional": true - }, - "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==", - "license": "MIT", - "optional": true, - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "license": "MIT", - "optional": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "license": "MIT", - "optional": true - }, - "node_modules/semver": { - "version": "7.5.4", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", - "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", - "license": "ISC", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "license": "ISC" - }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "license": "ISC" - }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/simple-get": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz", - "integrity": "sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==", - "license": "MIT", - "dependencies": { - "decompress-response": "^4.2.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, - "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", - "optional": true, - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", - "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.13.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/socks-proxy-agent": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz", - "integrity": "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==", - "license": "MIT", - "optional": true, - "dependencies": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/sqlite3": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.6.tgz", - "integrity": "sha512-olYkWoKFVNSSSQNvxVUfjiVbz3YtBwTJj+mfV5zpHmqW3sELx2Cf4QCdirMelhM5Zh+KDVaKgQHqCxrqiWHybw==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "optional": true, - "dependencies": { - "@mapbox/node-pre-gyp": "^1.0.0", - "node-addon-api": "^4.2.0", - "tar": "^6.1.11" - }, - "optionalDependencies": { - "node-gyp": "8.x" - }, - "peerDependencies": { - "node-gyp": "8.x" - }, - "peerDependenciesMeta": { - "node-gyp": { - "optional": true - } - } - }, - "node_modules/ssri": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz", - "integrity": "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==", - "license": "ISC", - "optional": true, - "dependencies": { - "minipass": "^3.1.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "license": "MIT", - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "license": "MIT", - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/sync-promise-expanded": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/sync-promise-expanded/-/sync-promise-expanded-1.0.0.tgz", - "integrity": "sha512-pdxxEOaeKO6LghTz0Fe7yw82fx95gtS0SxVgRvIwvN4h9qTie8oOF/pWuH8PGp+PVduS84RXXxO/xrW93Nno9w==", - "license": "ISC", - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/tar": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", - "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^5.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar/node_modules/minipass": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", - "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", - "license": "ISC", - "engines": { - "node": ">=8" - } - }, - "node_modules/tiny-queue": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tiny-queue/-/tiny-queue-0.2.1.tgz", - "integrity": "sha512-EijGsv7kzd9I9g0ByCl6h42BWNGUZrlCSejfrb3AKeHC33SGbASu1VDf5O3rRiiUOhAC9CHdZxFPbZu0HmR70A==", - "license": "Apache 2" - }, - "node_modules/tr46": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", - "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", - "license": "MIT", - "dependencies": { - "punycode": "^2.3.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/typeson": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/typeson/-/typeson-9.0.2.tgz", - "integrity": "sha512-83w1JVRVt22Kj2bIBo4DyhWYh4RKzbuBW5g89ETlPJOv0+LLX4/hANstDr76srTzULePKSl7DqDAtqHADJOwvQ==", - "license": "MIT", - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/typeson-registry": { - "version": "7.2.1", - "resolved": "https://registry.npmjs.org/typeson-registry/-/typeson-registry-7.2.1.tgz", - "integrity": "sha512-6KBjzf4kK045pPPA6UqC1O3JKhFM4+O9YZf4AtcBX7v/8m8AG1bB3UIJN05PRY9U3E7P7/4Gc4MjPrqwvGq2wQ==", - "license": "MIT", - "dependencies": { - "base64-arraybuffer-es6": "^3.0.0", - "typeson": "^9.0.2", - "whatwg-url": "^12.0.1" - }, - "engines": { - "node": "^14.17.0 || >=16.0.0" - } - }, - "node_modules/typeson-registry/node_modules/typeson": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/typeson/-/typeson-9.0.3.tgz", - "integrity": "sha512-vsOn+VPbIYI3jgj96vwIhAO0BNmlBxEgBKVmuzl1dwXzQe+3XjRi/gK2zYgAansWYlrtvluy4lvWcL8LF01P3Q==", - "license": "MIT", - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "license": "ISC", - "optional": true, - "dependencies": { - "unique-slug": "^2.0.0" - } - }, - "node_modules/unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "license": "ISC", - "optional": true, - "dependencies": { - "imurmurhash": "^0.1.4" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, - "node_modules/web-streams-polyfill": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz", - "integrity": "sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==", - "engines": { - "node": ">= 8" - } - }, - "node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - } - }, - "node_modules/websql-configurable": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/websql-configurable/-/websql-configurable-3.0.3.tgz", - "integrity": "sha512-Fs+3A2BjI3ukkGtvsZcPS4nGoFE0aqors8YKWgICoOt7dcfdeaTdgoMOoFqlEPHc9u/TS9BEFhKP/A9GttB0CQ==", - "license": "Apache-2.0", - "dependencies": { - "argsarray": "^0.0.1", - "immediate": "^3.2.2", - "noop-fn": "^1.0.0", - "tiny-queue": "^0.2.1" - }, - "optionalDependencies": { - "sqlite3": "^5.0.2" - } - }, - "node_modules/whatwg-url": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz", - "integrity": "sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ==", - "license": "MIT", - "dependencies": { - "tr46": "^4.1.1", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=14" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "license": "ISC", - "optional": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "license": "ISC", - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "license": "ISC" - }, - "node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", - "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/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "license": "ISC" - } - } -} diff --git a/wasm/mix-fetch/internal-dev-node/package.json b/wasm/mix-fetch/internal-dev-node/package.json deleted file mode 100644 index 8b2e67d11a..0000000000 --- a/wasm/mix-fetch/internal-dev-node/package.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "name": "internal-dev-node", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "start": "node src/index.mjs" - }, - "author": "", - "license": "ISC", - "dependencies": { - "@nymproject/mix-fetch-wasm": "file:../../../dist/node/wasm/mix-fetch", - "indexeddbshim": "^13.0.0-pre.1", - "node-fetch": "^3.3.2", - "ws": "^8.13.0" - } -} diff --git a/wasm/mix-fetch/internal-dev-node/src/index.mjs b/wasm/mix-fetch/internal-dev-node/src/index.mjs deleted file mode 100644 index 978645136d..0000000000 --- a/wasm/mix-fetch/internal-dev-node/src/index.mjs +++ /dev/null @@ -1,98 +0,0 @@ -import {Worker} from 'worker_threads'; - -function sleep(ms) { - return new Promise((resolve) => { - setTimeout(resolve, ms); - }); -} - -class NodeWorkerClient { - worker = null; - clientInitialised = false; - selfAddress = null - - constructor() { - this.worker = new Worker('./src/worker.mjs'); - - this.worker.on("message", message => { - this.handleMessage(message) - }); - - this.worker.on("error", error => { - console.log(error); - }); - - this.worker.on("exit", exitCode => { - console.log(`It exited with code ${exitCode}`); - }) - - } - - initMixFetch = () => { - this.worker.postMessage({kind: 'initRequest', data: {}}) - } - - fetch = (resource, options) => { - this.worker.postMessage({kind: 'fetchRequest', data: {resource, options}}) - } - - handleResponse = (message, senderTag) => { - // console.log(`received raw message: ${message}`) - // console.log(`with senderTag: ${senderTag}`) - // - // let decoded = new TextDecoder().decode(message); - // console.log(`decoded message: "${decoded}"`) - } - - handleMessage = (message) => { - console.log(`handling "${message.kind}"`) - switch (message.kind) { - case 'initResponse': - this.clientInitialised = message.data.done; - break; - case 'receivedResponse': - this.handleResponse(message.data.response) - break; - default: - console.log("UNKOWN MESSAGE") - break; - } - } - - // hehe, that's so disgusting, but I don't want to spend ages in the JS callback hell - // because that's not the point of this example - waitForMixFetch = async () => { - let start = new Date(); - let pollingRate = 100; - let maxWaitSecs = 5; - while (!this.clientInitialised) { - let now = new Date(); - let diff = (now.getTime() - start.getTime()) / 1000; - if (diff > maxWaitSecs) { - return Promise.reject(new Error('failed to initialise mix fetch')) - } - await sleep(pollingRate) - } - } -} - - -async function main() { - let client = new NodeWorkerClient() - client.initMixFetch() - await client.waitForMixFetch() - - await client.fetch("https://nymtech.net", { mode: "unsafe-ignore-cors" }) -} - -await main() - -process.on('SIGTERM', signal => { - console.log(`Process ${process.pid} received a SIGTERM signal`) - process.exit(0) -}) - -process.on('SIGINT', signal => { - console.log(`Process ${process.pid} has been interrupted`) - process.exit(0) -}) \ No newline at end of file diff --git a/wasm/mix-fetch/internal-dev-node/src/polyfill.mjs b/wasm/mix-fetch/internal-dev-node/src/polyfill.mjs deleted file mode 100644 index 4c62b8e7e6..0000000000 --- a/wasm/mix-fetch/internal-dev-node/src/polyfill.mjs +++ /dev/null @@ -1,59 +0,0 @@ -import crypto from 'node:crypto'; -import fs from 'node:fs'; -import { TextDecoder, TextEncoder } from 'node:util'; -import setGlobalVars from 'indexeddbshim'; -import WebSocket from 'ws'; -import fetch, { - Headers, - Request, - Response, -} from 'node-fetch' - - -if (!globalThis.fs) { - globalThis.fs = fs -} - -if (!globalThis.process) { - globalThis.process = process -} - -if (!globalThis.crypto) { - globalThis.crypto = { - getRandomValues(b) { - crypto.randomFillSync(b); - }, - } -} - -if (!globalThis.performance) { - globalThis.performance = { - now() { - const [sec, nsec] = process.hrtime(); - return sec * 1000 + nsec / 1000000; - }, - }; -} - -if (!globalThis.TextEncoder) { - globalThis.TextEncoder = TextEncoder -} - -if (!globalThis.TextDecoder) { - globalThis.TextDecoder = TextDecoder -} - -if (!globalThis.fetch) { - globalThis.fetch = fetch - globalThis.Headers = Headers - globalThis.Request = Request - globalThis.Response = Response -} - -// checkOrigin:false is required to avoid SecurityError Cannot open -// an IndexedDB database from an opaque origin. -setGlobalVars(globalThis, {checkOrigin: false}) -globalThis.WebSocket = WebSocket - -// has to be loaded after all the polyfill action -import('@nymproject/mix-fetch-wasm/wasm_exec.js') diff --git a/wasm/mix-fetch/internal-dev-node/src/worker.mjs b/wasm/mix-fetch/internal-dev-node/src/worker.mjs deleted file mode 100644 index 95751fec17..0000000000 --- a/wasm/mix-fetch/internal-dev-node/src/worker.mjs +++ /dev/null @@ -1,117 +0,0 @@ -import {parentPort} from 'worker_threads'; -import {setupMixFetch, set_panic_hook, send_client_data, start_new_mixnet_connection, mix_fetch_initialised, finish_mixnet_connection} from '@nymproject/mix-fetch-wasm'; -import fs from 'node:fs'; -import("./polyfill.mjs") - -// Sorry Mark, but I don't want to deal with bundling hell to get this one work via proper import : ( -let goWasmPath = "../../../dist/node/wasm/mix-fetch/go_conn.wasm" -// import goWasm from '@nymproject/mix-fetch-wasm/go_conn.wasm' - - -function sleep(ms) { - return new Promise((resolve) => { - setTimeout(resolve, ms); - }); -} - -function setupRsGoBridge() { - // (note: reason for intermediate `__rs_go_bridge__` object is to decrease global scope bloat - // and to discourage users from trying to call those methods directly) - globalThis.__rs_go_bridge__ = {} - globalThis.__rs_go_bridge__.send_client_data = send_client_data - globalThis.__rs_go_bridge__.start_new_mixnet_connection = start_new_mixnet_connection - globalThis.__rs_go_bridge__.mix_fetch_initialised = mix_fetch_initialised - globalThis.__rs_go_bridge__.finish_mixnet_connection = finish_mixnet_connection -} - -async function loadGoWasm() { - // I... don't even want to know. Javascript (and node) works in mysterious ways... - if (!globalThis.Go) { - await sleep(500) - } - - console.log(globalThis.Origin) - - const go = new Go() - const blob = fs.readFileSync(goWasmPath); - const wasmObj = await WebAssembly.instantiate(blob, go.importObject) - const goWasm = wasmObj.instance - go.run(goWasm) -} - -async function logFetchResult(res) { - let text = await res.text() - console.log("HEADERS: ", ...res.headers) - console.log("STATUS: ", res.status) - console.log("STATUS TEXT: ", res.statusText) - console.log("OK: ", res.ok) - console.log("TYPE: ", res.type) - console.log("URL: ", res.url) - console.log("BODYUSED: ", res.bodyUsed) - console.log("REDIRECTED: ", res.redirected) - console.log("TEXT: ", text) -} - - -let initDone = false - -parentPort.on('message', async message => { - await handleMessage(message) -}); - -async function handleMessage(message) { - console.log(`handling "${message.kind}"`) - switch (message.kind) { - case 'initRequest': - await initialiseMixFetch() - break; - case 'fetchRequest': - await handleFetchRequest(message.data.resource, message.data.options); - break; - default: - console.log("UNKOWN MESSAGE") - break; - } -} - -async function handleFetchRequest(resource, options) { - console.log("will fetch", resource, options) - let res = await mixFetch(resource, options) - await logFetchResult(res) -} - -async function nativeSetup(onMessageHandler) { - const noCoverTrafficOverride = { - traffic: { disableMainPoissonPacketDistribution: true }, - coverTraffic: { disableLoopCoverTrafficStream: true }, - } - const mixFetchOverride = { - requestTimeoutMs: 10000 - } - - await setupMixFetch({ storagePassphrase: "foomp", clientId: "my-client", clientOverride: noCoverTrafficOverride, mixFetchOverride }) - -} - -function finishInit() { - initDone = true - parentPort.postMessage({kind: 'initResponse', data: {done: initDone}}) -} - -async function initialiseMixFetch() { - if (initDone) { - return finishInit() - } - - setupRsGoBridge() - await loadGoWasm() - - // sets up better stack traces in case of in-rust panics - set_panic_hook(); - - console.log('Instantiating mix fetch...'); - await nativeSetup() - console.log('mix fetch client running!'); - - finishInit() -} diff --git a/wasm/mix-fetch/internal-dev-node/yarn.lock b/wasm/mix-fetch/internal-dev-node/yarn.lock deleted file mode 100644 index 0c337ced8f..0000000000 --- a/wasm/mix-fetch/internal-dev-node/yarn.lock +++ /dev/null @@ -1,938 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@gar/promisify@^1.0.1": - version "1.1.3" - resolved "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz" - integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== - -"@mapbox/node-pre-gyp@^1.0.0": - version "1.0.11" - resolved "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.11.tgz" - integrity sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ== - dependencies: - detect-libc "^2.0.0" - https-proxy-agent "^5.0.0" - make-dir "^3.1.0" - node-fetch "^2.6.7" - nopt "^5.0.0" - npmlog "^5.0.1" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.11" - -"@npmcli/fs@^1.0.0": - version "1.1.1" - resolved "https://registry.npmjs.org/@npmcli/fs/-/fs-1.1.1.tgz" - integrity sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ== - dependencies: - "@gar/promisify" "^1.0.1" - semver "^7.3.5" - -"@npmcli/move-file@^1.0.1": - version "1.1.2" - resolved "https://registry.npmjs.org/@npmcli/move-file/-/move-file-1.1.2.tgz" - integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== - dependencies: - mkdirp "^1.0.4" - rimraf "^3.0.2" - -"@nymproject/mix-fetch-wasm@file:../../../dist/node/wasm/mix-fetch": - version "1.2.0-rc.2" - -"@tootallnate/once@1": - version "1.1.2" - resolved "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== - -abbrev@1: - version "1.1.1" - resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - -agent-base@6, agent-base@^6.0.2: - version "6.0.2" - resolved "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - -agentkeepalive@^4.1.3: - version "4.5.0" - resolved "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.5.0.tgz" - integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== - dependencies: - humanize-ms "^1.2.1" - -aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - -ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - -"aproba@^1.0.3 || ^2.0.0": - version "2.0.0" - resolved "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz" - integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== - -are-we-there-yet@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz" - integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== - dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" - -are-we-there-yet@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz" - integrity sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg== - dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" - -argsarray@^0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/argsarray/-/argsarray-0.0.1.tgz" - integrity sha512-u96dg2GcAKtpTrBdDoFIM7PjcBA+6rSP0OR94MOReNRyUECL6MtQt5XXmRr4qrftYaef9+l5hcpO5te7sML1Cg== - -balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - -base64-arraybuffer-es6@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/base64-arraybuffer-es6/-/base64-arraybuffer-es6-3.0.1.tgz" - integrity sha512-bOxevePlYA8Kba1xVnrQSoktrt12UkP6Jhl2wO+GCGbKAkF4fpDxyg7xRFffZYC0kP2RgMPOSRbzmdHReWnMyg== - -brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - -cacache@^15.2.0: - version "15.3.0" - resolved "https://registry.npmjs.org/cacache/-/cacache-15.3.0.tgz" - integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== - dependencies: - "@npmcli/fs" "^1.0.0" - "@npmcli/move-file" "^1.0.1" - chownr "^2.0.0" - fs-minipass "^2.0.0" - glob "^7.1.4" - infer-owner "^1.0.4" - lru-cache "^6.0.0" - minipass "^3.1.1" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.2" - mkdirp "^1.0.3" - p-map "^4.0.0" - promise-inflight "^1.0.1" - rimraf "^3.0.2" - ssri "^8.0.1" - tar "^6.0.2" - unique-filename "^1.1.1" - -canvas@^2.11.2: - version "2.11.2" - resolved "https://registry.npmjs.org/canvas/-/canvas-2.11.2.tgz" - integrity sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw== - dependencies: - "@mapbox/node-pre-gyp" "^1.0.0" - nan "^2.17.0" - simple-get "^3.0.3" - -chownr@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz" - integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== - -clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - -color-support@^1.1.2, color-support@^1.1.3: - version "1.1.3" - resolved "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz" - integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== - -concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - -console-control-strings@^1.0.0, console-control-strings@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" - integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== - -data-uri-to-buffer@^4.0.0: - version "4.0.1" - resolved "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz" - integrity sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A== - -debug@4, debug@^4.3.3: - version "4.3.4" - resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - -decompress-response@^4.2.0: - version "4.2.1" - resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-4.2.1.tgz" - integrity sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw== - dependencies: - mimic-response "^2.0.0" - -delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz" - integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== - -detect-libc@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz" - integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== - -emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - -encoding@^0.1.12: - version "0.1.13" - resolved "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - -env-paths@^2.2.0: - version "2.2.1" - resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz" - integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== - -err-code@^2.0.2: - 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== - -eventtargeter@0.9.0: - version "0.9.0" - resolved "https://registry.npmjs.org/eventtargeter/-/eventtargeter-0.9.0.tgz" - integrity sha512-40f2UpTpS7v2GnXWsMpEUkKoMOlgTDrijhCx4Hq7zvsBhLihA7dn0Ayicb4FO/MOIzD5mLHsLK7/NYqx39LqaA== - -fetch-blob@^3.1.2, fetch-blob@^3.1.4: - version "3.2.0" - resolved "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz" - integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ== - dependencies: - node-domexception "^1.0.0" - web-streams-polyfill "^3.0.3" - -formdata-polyfill@^4.0.10: - version "4.0.10" - resolved "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz" - integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== - dependencies: - fetch-blob "^3.1.2" - -fs-minipass@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz" - integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== - dependencies: - minipass "^3.0.0" - -fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - -gauge@^3.0.0: - version "3.0.2" - resolved "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz" - integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q== - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.2" - console-control-strings "^1.0.0" - has-unicode "^2.0.1" - object-assign "^4.1.1" - signal-exit "^3.0.0" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.2" - -gauge@^4.0.3: - version "4.0.4" - resolved "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz" - integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.3" - console-control-strings "^1.1.0" - has-unicode "^2.0.1" - signal-exit "^3.0.7" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.5" - -glob@^7.1.3, glob@^7.1.4: - version "7.2.3" - resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - -graceful-fs@^4.2.6: - 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== - -has-unicode@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz" - integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== - -http-cache-semantics@^4.1.0: - version "4.1.1" - resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz" - integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== - -http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - -https-proxy-agent@^5.0.0: - 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== - dependencies: - agent-base "6" - debug "4" - -humanize-ms@^1.2.1: - version "1.2.1" - resolved "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz" - integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== - dependencies: - ms "^2.0.0" - -iconv-lite@^0.6.2: - version "0.6.3" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - -immediate@^3.2.2: - version "3.3.0" - resolved "https://registry.npmjs.org/immediate/-/immediate-3.3.0.tgz" - integrity sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q== - -imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - -indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - -indexeddbshim@^13.0.0-pre.1: - version "13.0.0-pre.1" - resolved "https://registry.npmjs.org/indexeddbshim/-/indexeddbshim-13.0.0-pre.1.tgz" - integrity sha512-Tl0FAiQvp0zdTiWZf267d6MN0cFk64z8oa39zpexIkX3Nk/AY5iYhPqvpQcGOxXJWdY/IWOyZFZb4K2qhRtxng== - dependencies: - canvas "^2.11.2" - eventtargeter "0.9.0" - sync-promise-expanded "^1.0.0" - typeson "9.0.2" - typeson-registry "7.2.1" - websql-configurable "^3.0.3" - -infer-owner@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz" - integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== - -inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - -inherits@2, inherits@^2.0.3: - version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -ip@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105" - integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ== - -is-fullwidth-code-point@^3.0.0: - 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-lambda@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz" - integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - -make-dir@^3.1.0: - version "3.1.0" - resolved "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - -make-fetch-happen@^9.1.0: - version "9.1.0" - resolved "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz" - integrity sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg== - dependencies: - agentkeepalive "^4.1.3" - cacache "^15.2.0" - http-cache-semantics "^4.1.0" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^6.0.0" - minipass "^3.1.3" - minipass-collect "^1.0.2" - minipass-fetch "^1.3.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^0.6.2" - promise-retry "^2.0.1" - socks-proxy-agent "^6.0.0" - ssri "^8.0.0" - -mimic-response@^2.0.0: - version "2.1.0" - resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz" - integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA== - -minimatch@^3.1.1: - version "3.1.2" - resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - -minipass-collect@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz" - integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== - dependencies: - minipass "^3.0.0" - -minipass-fetch@^1.3.2: - version "1.4.1" - resolved "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-1.4.1.tgz" - integrity sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw== - dependencies: - minipass "^3.1.0" - minipass-sized "^1.0.3" - minizlib "^2.0.0" - optionalDependencies: - encoding "^0.1.12" - -minipass-flush@^1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz" - integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== - dependencies: - minipass "^3.0.0" - -minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: - version "1.2.4" - resolved "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz" - integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== - dependencies: - minipass "^3.0.0" - -minipass-sized@^1.0.3: - 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" - -minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: - version "3.3.6" - resolved "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz" - integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== - dependencies: - yallist "^4.0.0" - -minipass@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz" - integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== - -minizlib@^2.0.0, minizlib@^2.1.1: - version "2.1.2" - resolved "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz" - integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" - -mkdirp@^1.0.3, mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - -ms@2.1.2: - version "2.1.2" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@^2.0.0: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -nan@^2.17.0: - version "2.17.0" - resolved "https://registry.npmjs.org/nan/-/nan-2.17.0.tgz" - integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== - -negotiator@^0.6.2: - version "0.6.3" - resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - -node-addon-api@^4.2.0: - version "4.3.0" - resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz" - integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ== - -node-domexception@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz" - integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== - -node-fetch@^2.6.7: - version "2.6.12" - resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz" - integrity sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g== - dependencies: - whatwg-url "^5.0.0" - -node-fetch@^3.3.2: - version "3.3.2" - resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz" - integrity sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA== - dependencies: - data-uri-to-buffer "^4.0.0" - fetch-blob "^3.1.4" - formdata-polyfill "^4.0.10" - -node-gyp@8.x: - version "8.4.1" - resolved "https://registry.npmjs.org/node-gyp/-/node-gyp-8.4.1.tgz" - integrity sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w== - dependencies: - env-paths "^2.2.0" - glob "^7.1.4" - graceful-fs "^4.2.6" - make-fetch-happen "^9.1.0" - nopt "^5.0.0" - npmlog "^6.0.0" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.2" - which "^2.0.2" - -noop-fn@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/noop-fn/-/noop-fn-1.0.0.tgz" - integrity sha512-pQ8vODlgXt2e7A3mIbFDlizkr46r75V+BJxVAyat8Jl7YmI513gG5cfyRL0FedKraoZ+VAouI1h4/IWpus5pcQ== - -nopt@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz" - integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== - dependencies: - abbrev "1" - -npmlog@^5.0.1: - version "5.0.1" - resolved "https://registry.npmjs.org/npmlog/-/npmlog-5.0.1.tgz" - integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== - dependencies: - are-we-there-yet "^2.0.0" - console-control-strings "^1.1.0" - gauge "^3.0.0" - set-blocking "^2.0.0" - -npmlog@^6.0.0: - version "6.0.2" - resolved "https://registry.npmjs.org/npmlog/-/npmlog-6.0.2.tgz" - integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== - dependencies: - are-we-there-yet "^3.0.0" - console-control-strings "^1.1.0" - gauge "^4.0.3" - set-blocking "^2.0.0" - -object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - -once@^1.3.0, once@^1.3.1: - version "1.4.0" - resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - -p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - -path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - -promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz" - integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== - -promise-retry@^2.0.1: - 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" - -punycode@^2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== - -readable-stream@^3.6.0: - version "3.6.2" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -retry@^0.12.0: - version "0.12.0" - resolved "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz" - integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== - -rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - -safe-buffer@~5.2.0: - 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@>= 2.1.2 < 3.0.0": - version "2.1.2" - resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -semver@^6.0.0: - version "6.3.1" - resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - -semver@^7.3.5: - version "7.5.4" - resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - -set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz" - integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== - -signal-exit@^3.0.0, signal-exit@^3.0.7: - version "3.0.7" - resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - -simple-concat@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz" - integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== - -simple-get@^3.0.3: - version "3.1.1" - resolved "https://registry.npmjs.org/simple-get/-/simple-get-3.1.1.tgz" - integrity sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA== - dependencies: - decompress-response "^4.2.0" - once "^1.3.1" - simple-concat "^1.0.0" - -smart-buffer@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz" - integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== - -socks-proxy-agent@^6.0.0: - version "6.2.1" - resolved "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-6.2.1.tgz" - integrity sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ== - dependencies: - agent-base "^6.0.2" - debug "^4.3.3" - socks "^2.6.2" - -socks@^2.6.2: - version "2.7.1" - resolved "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz" - integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== - dependencies: - ip "^2.0.0" - smart-buffer "^4.2.0" - -sqlite3@^5.0.2: - version "5.1.6" - resolved "https://registry.npmjs.org/sqlite3/-/sqlite3-5.1.6.tgz" - integrity sha512-olYkWoKFVNSSSQNvxVUfjiVbz3YtBwTJj+mfV5zpHmqW3sELx2Cf4QCdirMelhM5Zh+KDVaKgQHqCxrqiWHybw== - dependencies: - "@mapbox/node-pre-gyp" "^1.0.0" - node-addon-api "^4.2.0" - tar "^6.1.11" - optionalDependencies: - node-gyp "8.x" - -ssri@^8.0.0, ssri@^8.0.1: - version "8.0.1" - resolved "https://registry.npmjs.org/ssri/-/ssri-8.0.1.tgz" - integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== - dependencies: - minipass "^3.1.1" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -string_decoder@^1.1.1: - 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== - dependencies: - safe-buffer "~5.2.0" - -strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - -sync-promise-expanded@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/sync-promise-expanded/-/sync-promise-expanded-1.0.0.tgz" - integrity sha512-pdxxEOaeKO6LghTz0Fe7yw82fx95gtS0SxVgRvIwvN4h9qTie8oOF/pWuH8PGp+PVduS84RXXxO/xrW93Nno9w== - -tar@^6.0.2, tar@^6.1.11, tar@^6.1.2: - version "6.2.1" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" - integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^5.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - -tiny-queue@^0.2.1: - version "0.2.1" - resolved "https://registry.npmjs.org/tiny-queue/-/tiny-queue-0.2.1.tgz" - integrity sha512-EijGsv7kzd9I9g0ByCl6h42BWNGUZrlCSejfrb3AKeHC33SGbASu1VDf5O3rRiiUOhAC9CHdZxFPbZu0HmR70A== - -tr46@^4.1.1: - version "4.1.1" - resolved "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz" - integrity sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw== - dependencies: - punycode "^2.3.0" - -tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - -typeson-registry@7.2.1: - version "7.2.1" - resolved "https://registry.npmjs.org/typeson-registry/-/typeson-registry-7.2.1.tgz" - integrity sha512-6KBjzf4kK045pPPA6UqC1O3JKhFM4+O9YZf4AtcBX7v/8m8AG1bB3UIJN05PRY9U3E7P7/4Gc4MjPrqwvGq2wQ== - dependencies: - base64-arraybuffer-es6 "^3.0.0" - typeson "^9.0.2" - whatwg-url "^12.0.1" - -typeson@9.0.2: - version "9.0.2" - resolved "https://registry.npmjs.org/typeson/-/typeson-9.0.2.tgz" - integrity sha512-83w1JVRVt22Kj2bIBo4DyhWYh4RKzbuBW5g89ETlPJOv0+LLX4/hANstDr76srTzULePKSl7DqDAtqHADJOwvQ== - -typeson@^9.0.2: - version "9.0.3" - resolved "https://registry.npmjs.org/typeson/-/typeson-9.0.3.tgz" - integrity sha512-vsOn+VPbIYI3jgj96vwIhAO0BNmlBxEgBKVmuzl1dwXzQe+3XjRi/gK2zYgAansWYlrtvluy4lvWcL8LF01P3Q== - -unique-filename@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz" - integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== - dependencies: - unique-slug "^2.0.0" - -unique-slug@^2.0.0: - version "2.0.2" - resolved "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz" - integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== - dependencies: - imurmurhash "^0.1.4" - -util-deprecate@^1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -web-streams-polyfill@^3.0.3: - version "3.2.1" - resolved "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz" - integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== - -webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - -webidl-conversions@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz" - integrity sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g== - -websql-configurable@^3.0.3: - version "3.0.3" - resolved "https://registry.npmjs.org/websql-configurable/-/websql-configurable-3.0.3.tgz" - integrity sha512-Fs+3A2BjI3ukkGtvsZcPS4nGoFE0aqors8YKWgICoOt7dcfdeaTdgoMOoFqlEPHc9u/TS9BEFhKP/A9GttB0CQ== - dependencies: - argsarray "^0.0.1" - immediate "^3.2.2" - noop-fn "^1.0.0" - tiny-queue "^0.2.1" - optionalDependencies: - sqlite3 "^5.0.2" - -whatwg-url@^12.0.1: - version "12.0.1" - resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-12.0.1.tgz" - integrity sha512-Ed/LrqB8EPlGxjS+TrsXcpUond1mhccS3pchLhzSgPCnTimUCKj3IZE75pAs5m6heB2U2TMerKFUXheyHY+VDQ== - dependencies: - tr46 "^4.1.1" - webidl-conversions "^7.0.0" - -whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - -which@^2.0.2: - 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" - -wide-align@^1.1.2, wide-align@^1.1.5: - version "1.1.5" - resolved "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz" - integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== - dependencies: - string-width "^1.0.2 || 2 || 3 || 4" - -wrappy@1: - version "1.0.2" - resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - -ws@^8.13.0: - version "8.13.0" - resolved "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz" - integrity sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA== - -yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== diff --git a/wasm/mix-fetch/internal-dev/.gitignore b/wasm/mix-fetch/internal-dev/.gitignore deleted file mode 100644 index f06235c460..0000000000 --- a/wasm/mix-fetch/internal-dev/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules -dist diff --git a/wasm/mix-fetch/internal-dev/bootstrap.js b/wasm/mix-fetch/internal-dev/bootstrap.js deleted file mode 100644 index a017926b28..0000000000 --- a/wasm/mix-fetch/internal-dev/bootstrap.js +++ /dev/null @@ -1,5 +0,0 @@ -// A dependency graph that contains any wasm must all be imported -// asynchronously. This `bootstrap.js` file does the single async import, so -// that no one else needs to worry about it again. -import('./index.js') - .catch(e => console.error('Error importing `index.js`:', e)); diff --git a/wasm/mix-fetch/internal-dev/index.html b/wasm/mix-fetch/internal-dev/index.html deleted file mode 100644 index 558751a743..0000000000 --- a/wasm/mix-fetch/internal-dev/index.html +++ /dev/null @@ -1,102 +0,0 @@ - - - - - - Nym MixFetch Demo - - - - -

Mix Fetch Demo

- -
- MixFetch Configuration -

- You can either use the default Gateway/NR combo run by us, or have - MixFetch choose a random one on startup. -

-
- -
-
- -
- - Not started -
- -
- -
- Fetch Controls -
- - - -
-
- - - -
-

- Note: if you're hammering these endpoints and you start to get timeouts - (or you've been reloading the page a lot) then change the target hosts - to e.g. http://ipv4.icanhazip.com and https://ipv6.icanhazip.com/ -

-
- -

- This does what is says on the tin - sends 10 fetch requests to - https://jsonplaceholder.typicode.com/posts/ 1 through 10 -

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

Do a POST and get it echoed back

-
- -
-

- -

- - diff --git a/wasm/mix-fetch/internal-dev/index.js b/wasm/mix-fetch/internal-dev/index.js deleted file mode 100644 index e2b614ab23..0000000000 --- a/wasm/mix-fetch/internal-dev/index.js +++ /dev/null @@ -1,236 +0,0 @@ -// Copyright 2020-2023 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -class WebWorkerClient { - worker = null; - - constructor() { - this.worker = new Worker('./worker.js'); - - this.worker.onmessage = (ev) => { - if (ev.data && ev.data.kind) { - switch (ev.data.kind) { - case 'DisplayString': - const { rawString } = ev.data.args; - displayReceivedRawString(rawString) - break; - case 'Log': - const { message, level } = ev.data.args; - displayLog(message, level); - break; - case 'MixFetchReady': - onMixFetchReady(); - break; - case 'MixFetchError': - const { error } = ev.data.args; - onMixFetchError(error); - break; - } - } - }; - } - - startMixFetch = (preferredGateway) => { - if (!this.worker) { - console.error('Could not send message because worker does not exist'); - return; - } - - this.worker.postMessage({ - kind: 'StartMixFetch', - args: { - preferredGateway, - }, - }); - } - - doFetch = (target) => { - if (!this.worker) { - console.error('Could not send message because worker does not exist'); - return; - } - - this.worker.postMessage({ - kind: 'FetchPayload', - args: { - target, - }, - }); - } - - doPost = (url, body) => { - if (!this.worker) { - console.error('Could not send message because worker does not exist'); - return; - } - - this.worker.postMessage({ - kind: 'PostPayload', - args: { - url, - body, - }, - }); - } -} - -let client = null; - -const DEFAULT_GATEWAY = "q2A2cbooyC16YJzvdYaSMH9X3cSiieZNtfBr8cE8Fi1"; - -async function main() { - client = new WebWorkerClient(); - - const startButton = document.querySelector('#start-mixfetch'); - startButton.onclick = function () { - const gatewayMode = document.querySelector('input[name="gateway-mode"]:checked').value; - const preferredGateway = gatewayMode === 'default' ? DEFAULT_GATEWAY : undefined; - - startButton.disabled = true; - document.querySelectorAll('input[name="gateway-mode"]').forEach(r => r.disabled = true); - updateStatus('Starting...', 'orange'); - - displayLog(`Starting MixFetch with ${gatewayMode} gateway${preferredGateway ? ` (${preferredGateway})` : ''}...`, 'info'); - client.startMixFetch(preferredGateway); - } - - const fetchButton1 = document.querySelector('#fetch-button-1'); - fetchButton1.onclick = function () { - doFetch(1); - } - - const fetchButton2 = document.querySelector('#fetch-button-2'); - fetchButton2.onclick = function () { - doFetch(2); - } - - const fetch10Button = document.querySelector('#fetch-10-concurrent'); - fetch10Button.onclick = function () { - doFetch10Concurrent(); - } - - const postButton = document.querySelector('#post-button'); - postButton.onclick = function () { - doPost(); - } -} - -function updateStatus(text, color) { - const status = document.getElementById('mixfetch-status'); - status.textContent = text; - status.style.color = color; -} - -function onMixFetchReady() { - updateStatus('Ready', 'green'); - document.getElementById('fetch-controls').disabled = false; - displayLog('MixFetch is ready!', 'info'); -} - -function onMixFetchError(error) { - updateStatus('Error: ' + error, 'red'); - document.querySelector('#start-mixfetch').disabled = false; - document.querySelectorAll('input[name="gateway-mode"]').forEach(r => r.disabled = false); - displayLog('MixFetch error: ' + error, 'error'); -} - - -async function doFetch(id) { - const payload = document.getElementById(`fetch_payload_${id}`).value; - await client.doFetch(payload) - - displaySend(`[${id}] clicked the button and the payload is: ${payload}...`); -} - -async function doFetch10Concurrent() { - const baseUrl = 'https://jsonplaceholder.typicode.com/posts/'; - displaySend('Starting 10 concurrent requests to posts/1-10...'); - - const requests = []; - for (let i = 1; i <= 10; i++) { - const url = `${baseUrl}${i}`; - displaySend(`[${i}] Sending request to ${url}`); - requests.push(client.doFetch(url)); - } - - await Promise.all(requests); - displaySend('All 10 concurrent requests dispatched!'); -} - -async function doPost() { - const url = document.getElementById('post_url').value; - const body = document.getElementById('post_body').value; - - displaySend(`[POST] Sending POST request to ${url}`); - displaySend(`[POST] Body: ${body}`); - - await client.doPost(url, body); -} - -/** - * Display log messages from MixFetch. Colors based on level. - * - * @param {string} message - * @param {string} level - 'info', 'error', 'warn', or 'debug' - */ -function displayLog(message, level) { - let timestamp = new Date().toISOString().substr(11, 12); - - const colors = { - info: 'gray', - error: 'red', - warn: 'orange', - debug: 'purple', - }; - - let logDiv = document.createElement('div'); - let paragraph = document.createElement('p'); - paragraph.setAttribute('style', `color: ${colors[level] || 'gray'}`); - let paragraphContent = document.createTextNode(timestamp + ' [' + level.toUpperCase() + '] ' + message); - paragraph.appendChild(paragraphContent); - - logDiv.appendChild(paragraph); - document.getElementById('output').appendChild(logDiv); -} - -/** - * Display messages that have been sent up the websocket. Colours them blue. - * - * @param {string} message - */ -function displaySend(message) { - let timestamp = new Date().toISOString().substr(11, 12); - - let sendDiv = document.createElement('div'); - let paragraph = document.createElement('p'); - paragraph.setAttribute('style', 'color: blue'); - let paragraphContent = document.createTextNode(timestamp + ' sent >>> ' + message); - paragraph.appendChild(paragraphContent); - - sendDiv.appendChild(paragraph); - document.getElementById('output').appendChild(sendDiv); -} - -function displayReceivedRawString(raw) { - let timestamp = new Date().toISOString().substr(11, 12); - let receivedDiv = document.createElement('div'); - let paragraph = document.createElement('p'); - paragraph.setAttribute('style', 'color: green'); - let paragraphContent = document.createTextNode(timestamp + ' received >>> ' + raw); - paragraph.appendChild(paragraphContent); - receivedDiv.appendChild(paragraph); - document.getElementById('output').appendChild(receivedDiv); -} - -main(); diff --git a/wasm/mix-fetch/internal-dev/package-lock.json b/wasm/mix-fetch/internal-dev/package-lock.json deleted file mode 100644 index d46f8e3e42..0000000000 --- a/wasm/mix-fetch/internal-dev/package-lock.json +++ /dev/null @@ -1,4758 +0,0 @@ -{ - "name": "create-wasm-app", - "version": "0.1.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "create-wasm-app", - "version": "0.1.0", - "license": "Apache-2.0", - "dependencies": { - "@nymproject/mix-fetch-wasm": "file:../pkg", - "go-mix-conn": "file:../go-mix-conn/build" - }, - "bin": { - "create-wasm-app": ".bin/create-wasm-app.js" - }, - "devDependencies": { - "copy-webpack-plugin": "^11.0.0", - "hello-wasm-pack": "^0.1.0", - "webpack": "^5.98.0", - "webpack-cli": "^5.1.4", - "webpack-dev-server": "^5.2.1" - } - }, - "../go-mix-conn/build": {}, - "../pkg": { - "name": "@nymproject/mix-fetch-wasm", - "version": "1.4.2", - "license": "Apache-2.0" - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.11", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz", - "integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.25" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.5", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", - "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" - } - }, - "node_modules/@jsonjoy.com/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@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==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@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==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/fs-core": { - "version": "4.56.10", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.56.10.tgz", - "integrity": "sha512-PyAEA/3cnHhsGcdY+AmIU+ZPqTuZkDhCXQ2wkXypdLitSpd6d5Ivxhnq4wa2ETRWFVJGabYynBWxIijOswSmOw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/fs-node-builtins": "4.56.10", - "@jsonjoy.com/fs-node-utils": "4.56.10", - "thingies": "^2.5.0" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/fs-fsa": { - "version": "4.56.10", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.56.10.tgz", - "integrity": "sha512-/FVK63ysNzTPOnCCcPoPHt77TOmachdMS422txM4KhxddLdbW1fIbFMYH0AM0ow/YchCyS5gqEjKLNyv71j/5Q==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/fs-core": "4.56.10", - "@jsonjoy.com/fs-node-builtins": "4.56.10", - "@jsonjoy.com/fs-node-utils": "4.56.10", - "thingies": "^2.5.0" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/fs-node": { - "version": "4.56.10", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.56.10.tgz", - "integrity": "sha512-7R4Gv3tkUdW3dXfXiOkqxkElxKNVdd8BDOWC0/dbERd0pXpPY+s2s1Mino+aTvkGrFPiY+mmVxA7zhskm4Ue4Q==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/fs-core": "4.56.10", - "@jsonjoy.com/fs-node-builtins": "4.56.10", - "@jsonjoy.com/fs-node-utils": "4.56.10", - "@jsonjoy.com/fs-print": "4.56.10", - "@jsonjoy.com/fs-snapshot": "4.56.10", - "glob-to-regex.js": "^1.0.0", - "thingies": "^2.5.0" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/fs-node-builtins": { - "version": "4.56.10", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.56.10.tgz", - "integrity": "sha512-uUnKz8R0YJyKq5jXpZtkGV9U0pJDt8hmYcLRrPjROheIfjMXsz82kXMgAA/qNg0wrZ1Kv+hrg7azqEZx6XZCVw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/fs-node-to-fsa": { - "version": "4.56.10", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.56.10.tgz", - "integrity": "sha512-oH+O6Y4lhn9NyG6aEoFwIBNKZeYy66toP5LJcDOMBgL99BKQMUf/zWJspdRhMdn/3hbzQsZ8EHHsuekbFLGUWw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/fs-fsa": "4.56.10", - "@jsonjoy.com/fs-node-builtins": "4.56.10", - "@jsonjoy.com/fs-node-utils": "4.56.10" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/fs-node-utils": { - "version": "4.56.10", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.56.10.tgz", - "integrity": "sha512-8EuPBgVI2aDPwFdaNQeNpHsyqPi3rr+85tMNG/lHvQLiVjzoZsvxA//Xd8aB567LUhy4QS03ptT+unkD/DIsNg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/fs-node-builtins": "4.56.10" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/fs-print": { - "version": "4.56.10", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.56.10.tgz", - "integrity": "sha512-JW4fp5mAYepzFsSGrQ48ep8FXxpg4niFWHdF78wDrFGof7F3tKDJln72QFDEn/27M1yHd4v7sKHHVPh78aWcEw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/fs-node-utils": "4.56.10", - "tree-dump": "^1.1.0" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/fs-snapshot": { - "version": "4.56.10", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.56.10.tgz", - "integrity": "sha512-DkR6l5fj7+qj0+fVKm/OOXMGfDFCGXLfyHkORH3DF8hxkpDgIHbhf/DwncBMs2igu/ST7OEkexn1gIqoU6Y+9g==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/buffers": "^17.65.0", - "@jsonjoy.com/fs-node-utils": "4.56.10", - "@jsonjoy.com/json-pack": "^17.65.0", - "@jsonjoy.com/util": "^17.65.0" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@jsonjoy.com/base64": { - "version": "17.67.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-17.67.0.tgz", - "integrity": "sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@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==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@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==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@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" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@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==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/util": "17.67.0" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/fs-snapshot/node_modules/@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==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/buffers": "17.67.0", - "@jsonjoy.com/codegen": "17.67.0" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@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==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@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" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/json-pack/node_modules/@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==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@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==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/codegen": "^1.0.0", - "@jsonjoy.com/util": "^1.9.0" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/util": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.9.0.tgz", - "integrity": "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/buffers": "^1.0.0", - "@jsonjoy.com/codegen": "^1.0.0" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/util/node_modules/@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==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", - "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", - "dev": true, - "license": "MIT" - }, - "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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 16" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - } - }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nymproject/mix-fetch-wasm": { - "resolved": "../pkg", - "link": true - }, - "node_modules/@peculiar/asn1-cms": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.6.1.tgz", - "integrity": "sha512-vdG4fBF6Lkirkcl53q6eOdn3XYKt+kJTG59edgRZORlg/3atWWEReRCx5rYE1ZzTTX6vLK5zDMjHh7vbrcXGtw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.1", - "@peculiar/asn1-x509-attr": "^2.6.1", - "asn1js": "^3.0.6", - "tslib": "^2.8.1" - } - }, - "node_modules/@peculiar/asn1-csr": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.6.1.tgz", - "integrity": "sha512-WRWnKfIocHyzFYQTka8O/tXCiBquAPSrRjXbOkHbO4qdmS6loffCEGs+rby6WxxGdJCuunnhS2duHURhjyio6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.1", - "asn1js": "^3.0.6", - "tslib": "^2.8.1" - } - }, - "node_modules/@peculiar/asn1-ecc": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.6.1.tgz", - "integrity": "sha512-+Vqw8WFxrtDIN5ehUdvlN2m73exS2JVG0UAyfVB31gIfor3zWEAQPD+K9ydCxaj3MLen9k0JhKpu9LqviuCE1g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.1", - "asn1js": "^3.0.6", - "tslib": "^2.8.1" - } - }, - "node_modules/@peculiar/asn1-pfx": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.6.1.tgz", - "integrity": "sha512-nB5jVQy3MAAWvq0KY0R2JUZG8bO/bTLpnwyOzXyEh/e54ynGTatAR+csOnXkkVD9AFZ2uL8Z7EV918+qB1qDvw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@peculiar/asn1-cms": "^2.6.1", - "@peculiar/asn1-pkcs8": "^2.6.1", - "@peculiar/asn1-rsa": "^2.6.1", - "@peculiar/asn1-schema": "^2.6.0", - "asn1js": "^3.0.6", - "tslib": "^2.8.1" - } - }, - "node_modules/@peculiar/asn1-pkcs8": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.6.1.tgz", - "integrity": "sha512-JB5iQ9Izn5yGMw3ZG4Nw3Xn/hb/G38GYF3lf7WmJb8JZUydhVGEjK/ZlFSWhnlB7K/4oqEs8HnfFIKklhR58Tw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.1", - "asn1js": "^3.0.6", - "tslib": "^2.8.1" - } - }, - "node_modules/@peculiar/asn1-pkcs9": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.6.1.tgz", - "integrity": "sha512-5EV8nZoMSxeWmcxWmmcolg22ojZRgJg+Y9MX2fnE2bGRo5KQLqV5IL9kdSQDZxlHz95tHvIq9F//bvL1OeNILw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@peculiar/asn1-cms": "^2.6.1", - "@peculiar/asn1-pfx": "^2.6.1", - "@peculiar/asn1-pkcs8": "^2.6.1", - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.1", - "@peculiar/asn1-x509-attr": "^2.6.1", - "asn1js": "^3.0.6", - "tslib": "^2.8.1" - } - }, - "node_modules/@peculiar/asn1-rsa": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.6.1.tgz", - "integrity": "sha512-1nVMEh46SElUt5CB3RUTV4EG/z7iYc7EoaDY5ECwganibQPkZ/Y2eMsTKB/LeyrUJ+W/tKoD9WUqIy8vB+CEdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.1", - "asn1js": "^3.0.6", - "tslib": "^2.8.1" - } - }, - "node_modules/@peculiar/asn1-schema": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.6.0.tgz", - "integrity": "sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg==", - "dev": true, - "license": "MIT", - "dependencies": { - "asn1js": "^3.0.6", - "pvtsutils": "^1.3.6", - "tslib": "^2.8.1" - } - }, - "node_modules/@peculiar/asn1-x509": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.6.1.tgz", - "integrity": "sha512-O9jT5F1A2+t3r7C4VT7LYGXqkGLK7Kj1xFpz7U0isPrubwU5PbDoyYtx6MiGst29yq7pXN5vZbQFKRCP+lLZlA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "asn1js": "^3.0.6", - "pvtsutils": "^1.3.6", - "tslib": "^2.8.1" - } - }, - "node_modules/@peculiar/asn1-x509-attr": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.6.1.tgz", - "integrity": "sha512-tlW6cxoHwgcQghnJwv3YS+9OO1737zgPogZ+CgWRUK4roEwIPzRH4JEiG770xe5HX2ATfCpmX60gurfWIF9dcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@peculiar/asn1-schema": "^2.6.0", - "@peculiar/asn1-x509": "^2.6.1", - "asn1js": "^3.0.6", - "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==", - "dev": true, - "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/@types/body-parser": { - "version": "1.19.6", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", - "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/bonjour": { - "version": "3.5.13", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", - "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.38", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", - "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect-history-api-fallback": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", - "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "node_modules/@types/eslint": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", - "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.7", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", - "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/express": { - "version": "4.17.25", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz", - "integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.33", - "@types/qs": "*", - "@types/serve-static": "^1" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.19.8", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.8.tgz", - "integrity": "sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*", - "@types/send": "*" - } - }, - "node_modules/@types/http-errors": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", - "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/json-schema": { - "version": "7.0.15", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", - "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/mime": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", - "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/node": { - "version": "25.3.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-25.3.0.tgz", - "integrity": "sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A==", - "dev": true, - "license": "MIT", - "dependencies": { - "undici-types": "~7.18.0" - } - }, - "node_modules/@types/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/range-parser": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", - "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/retry": { - "version": "0.12.2", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", - "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", - "dev": true, - "license": "MIT" - }, - "node_modules/@types/send": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", - "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/serve-index": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", - "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "<1" - } - }, - "node_modules/@types/serve-static/node_modules/@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==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/sockjs": { - "version": "0.3.36", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", - "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/ws": { - "version": "8.18.1", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", - "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", - "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/helper-numbers": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", - "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", - "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", - "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", - "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.13.2", - "@webassemblyjs/helper-api-error": "1.13.2", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", - "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", - "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/wasm-gen": "1.14.1" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", - "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", - "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", - "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", - "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/helper-wasm-section": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-opt": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1", - "@webassemblyjs/wast-printer": "1.14.1" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", - "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", - "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-buffer": "1.14.1", - "@webassemblyjs/wasm-gen": "1.14.1", - "@webassemblyjs/wasm-parser": "1.14.1" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", - "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@webassemblyjs/helper-api-error": "1.13.2", - "@webassemblyjs/helper-wasm-bytecode": "1.13.2", - "@webassemblyjs/ieee754": "1.13.2", - "@webassemblyjs/leb128": "1.13.2", - "@webassemblyjs/utf8": "1.13.2" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", - "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@webassemblyjs/ast": "1.14.1", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webpack-cli/configtest": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", - "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/info": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", - "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - } - }, - "node_modules/@webpack-cli/serve": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", - "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.15.0" - }, - "peerDependencies": { - "webpack": "5.x.x", - "webpack-cli": "5.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true, - "license": "BSD-3-Clause" - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/accepts/node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz", - "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==", - "dev": true, - "license": "MIT", - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-phases": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz", - "integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.13.0" - }, - "peerDependencies": { - "acorn": "^8.14.0" - } - }, - "node_modules/ajv": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "dev": true, - "engines": [ - "node >= 0.8.0" - ], - "license": "Apache-2.0", - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "node_modules/anymatch": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", - "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", - "dev": true, - "license": "ISC", - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", - "dev": true, - "license": "MIT" - }, - "node_modules/asn1js": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.7.tgz", - "integrity": "sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "pvtsutils": "^1.3.6", - "pvutils": "^1.1.3", - "tslib": "^2.8.1" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/baseline-browser-mapping": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz", - "integrity": "sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "baseline-browser-mapping": "dist/cli.cjs" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", - "dev": true, - "license": "MIT" - }, - "node_modules/binary-extensions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", - "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/body-parser": { - "version": "1.20.4", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz", - "integrity": "sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA==", - "dev": true, - "license": "MIT", - "dependencies": { - "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" - } - }, - "node_modules/bonjour-service": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", - "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.5" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, - "license": "MIT", - "dependencies": { - "fill-range": "^7.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/browserslist": { - "version": "4.28.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz", - "integrity": "sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "baseline-browser-mapping": "^2.9.0", - "caniuse-lite": "^1.0.30001759", - "electron-to-chromium": "^1.5.263", - "node-releases": "^2.0.27", - "update-browserslist-db": "^1.2.0" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/bundle-name": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", - "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "run-applescript": "^7.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "license": "MIT", - "engines": { - "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==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/call-bind-apply-helpers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", - "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/call-bound": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", - "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "get-intrinsic": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001774", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001774.tgz", - "integrity": "sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "CC-BY-4.0" - }, - "node_modules/chokidar": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", - "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "glob-parent": "~5.1.2", - "is-binary-path": "~2.1.0", - "is-glob": "~4.0.1", - "normalize-path": "~3.0.0", - "readdirp": "~3.6.0" - }, - "engines": { - "node": ">= 8.10.0" - }, - "funding": { - "url": "https://paulmillr.com/funding/" - }, - "optionalDependencies": { - "fsevents": "~2.3.2" - } - }, - "node_modules/chokidar/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", - "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/colorette": { - "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz", - "integrity": "sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==", - "dev": true, - "license": "MIT", - "dependencies": { - "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" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/connect-history-api-fallback": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", - "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-type": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", - "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", - "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", - "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", - "dev": true, - "license": "MIT" - }, - "node_modules/copy-webpack-plugin": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz", - "integrity": "sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-glob": "^3.2.11", - "glob-parent": "^6.0.1", - "globby": "^13.1.1", - "normalize-path": "^3.0.0", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0" - }, - "engines": { - "node": ">= 14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/cross-spawn": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", - "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "bundle-name": "^4.1.0", - "default-browser-id": "^5.0.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/default-browser-id": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", - "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/define-lazy-prop": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", - "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true, - "license": "MIT" - }, - "node_modules/dir-glob": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", - "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, - "license": "MIT", - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dns-packet": { - "version": "5.6.1", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", - "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true, - "license": "MIT" - }, - "node_modules/electron-to-chromium": { - "version": "1.5.302", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.302.tgz", - "integrity": "sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg==", - "dev": true, - "license": "ISC" - }, - "node_modules/encodeurl": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", - "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "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==", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.3.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/envinfo": { - "version": "7.21.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz", - "integrity": "sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow==", - "dev": true, - "license": "MIT", - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/es-define-property": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", - "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-module-lexer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.0.0.tgz", - "integrity": "sha512-5POEcUuZybH7IdmGsD8wlf0AI55wMecM9rVBTI/qEAy2c1kTOm3DjFYjrBdI2K3BaJjJYfYFeRtM0t9ssnRuxw==", - "dev": true, - "license": "MIT" - }, - "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/escalade": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", - "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true, - "license": "MIT" - }, - "node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esrecurse/node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=4.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true, - "license": "MIT" - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/express": { - "version": "4.22.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.22.1.tgz", - "integrity": "sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g==", - "dev": true, - "license": "MIT", - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "~1.20.3", - "content-disposition": "~0.5.4", - "content-type": "~1.0.4", - "cookie": "~0.7.1", - "cookie-signature": "~1.0.6", - "debug": "2.6.9", - "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" - }, - "engines": { - "node": ">= 0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, - "license": "MIT" - }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fast-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fastify" - }, - { - "type": "opencollective", - "url": "https://opencollective.com/fastify" - } - ], - "license": "BSD-3-Clause" - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4.9.1" - } - }, - "node_modules/fastq": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", - "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", - "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "on-finished": "~2.4.1", - "parseurl": "~1.3.3", - "statuses": "~2.0.2", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/flat": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", - "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", - "dev": true, - "license": "BSD-3-Clause", - "bin": { - "flat": "cli.js" - } - }, - "node_modules/follow-redirects": { - "version": "1.15.11", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", - "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", - "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.2", - "es-define-property": "^1.0.1", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.1.1", - "function-bind": "^1.1.2", - "get-proto": "^1.0.1", - "gopd": "^1.2.0", - "has-symbols": "^1.1.0", - "hasown": "^2.0.2", - "math-intrinsics": "^1.1.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", - "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, - "license": "MIT", - "dependencies": { - "dunder-proto": "^1.0.1", - "es-object-atoms": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob-to-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==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/globby": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz", - "integrity": "sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==", - "dev": true, - "license": "MIT", - "dependencies": { - "dir-glob": "^3.0.1", - "fast-glob": "^3.3.0", - "ignore": "^5.2.4", - "merge2": "^1.4.1", - "slash": "^4.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/go-mix-conn": { - "resolved": "../go-mix-conn/build", - "link": true - }, - "node_modules/gopd": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", - "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "dev": true, - "license": "MIT" - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-symbols": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", - "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/hello-wasm-pack": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/hello-wasm-pack/-/hello-wasm-pack-0.1.0.tgz", - "integrity": "sha512-3hx0GDkDLf/a9ThCMV2qG4mwza8N/MCtm8aeFFc/cdBCL2zMJ1kW1wjNl7xPqD1lz8Yl5+uhnc/cpui4dLwz/w==", - "dev": true - }, - "node_modules/hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "node_modules/hpack.js/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/hpack.js/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "license": "MIT" - }, - "node_modules/hpack.js/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", - "dev": true, - "license": "MIT" - }, - "node_modules/http-errors": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", - "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "depd": "~2.0.0", - "inherits": "~2.0.4", - "setprototypeof": "~1.2.0", - "statuses": "~2.0.2", - "toidentifier": "~1.0.1" - }, - "engines": { - "node": ">= 0.8" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/http-parser-js": { - "version": "0.5.10", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", - "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", - "dev": true, - "license": "MIT" - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/http-proxy-middleware": { - "version": "2.0.9", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", - "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } - } - }, - "node_modules/hyperdyperid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", - "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.18" - } - }, - "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/import-local": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", - "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", - "dev": true, - "license": "MIT", - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/interpret": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", - "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/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==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10" - } - }, - "node_modules/is-binary-path": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", - "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", - "dev": true, - "license": "MIT", - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", - "dev": true, - "license": "MIT", - "dependencies": { - "hasown": "^2.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-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==", - "dev": true, - "license": "MIT", - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-inside-container": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", - "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-docker": "^3.0.0" - }, - "bin": { - "is-inside-container": "cli.js" - }, - "engines": { - "node": ">=14.16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-network-error": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.0.tgz", - "integrity": "sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "license": "MIT", - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-wsl": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz", - "integrity": "sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-inside-container": "^1.0.0" - }, - "engines": { - "node": ">=16" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true, - "license": "ISC" - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "license": "MIT" - }, - "node_modules/kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/launch-editor": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.13.0.tgz", - "integrity": "sha512-u+9asUHMJ99lA15VRMXw5XKfySFR9dGXwgsgS14YTbUq3GITP58mIM32At90P5fZ+MUId5Yw+IwI/yKub7jnCQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "picocolors": "^1.1.1", - "shell-quote": "^1.8.3" - } - }, - "node_modules/loader-runner": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz", - "integrity": "sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.11.5" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/math-intrinsics": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", - "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memfs": { - "version": "4.56.10", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.56.10.tgz", - "integrity": "sha512-eLvzyrwqLHnLYalJP7YZ3wBe79MXktMdfQbvMrVD80K+NhrIukCVBvgP30zTJYEEDh9hZ/ep9z0KOdD7FSHo7w==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@jsonjoy.com/fs-core": "4.56.10", - "@jsonjoy.com/fs-fsa": "4.56.10", - "@jsonjoy.com/fs-node": "4.56.10", - "@jsonjoy.com/fs-node-builtins": "4.56.10", - "@jsonjoy.com/fs-node-to-fsa": "4.56.10", - "@jsonjoy.com/fs-node-utils": "4.56.10", - "@jsonjoy.com/fs-print": "4.56.10", - "@jsonjoy.com/fs-snapshot": "4.56.10", - "@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" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true, - "license": "MIT" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true, - "license": "ISC" - }, - "node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "license": "MIT" - }, - "node_modules/multicast-dns": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", - "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", - "dev": true, - "license": "MIT", - "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" - } - }, - "node_modules/negotiator": { - "version": "0.6.4", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", - "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true, - "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==", - "dev": true, - "license": "MIT" - }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-inspect": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", - "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true, - "license": "MIT" - }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz", - "integrity": "sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/open": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", - "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "default-browser": "^5.2.1", - "define-lazy-prop": "^3.0.0", - "is-inside-container": "^1.0.0", - "wsl-utils": "^0.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-retry": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", - "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/retry": "0.12.2", - "is-network-error": "^1.0.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=16.17" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true, - "license": "MIT" - }, - "node_modules/path-to-regexp": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/picocolors": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", - "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, - "license": "ISC" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "find-up": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkijs": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/pkijs/-/pkijs-3.3.3.tgz", - "integrity": "sha512-+KD8hJtqQMYoTuL1bbGOqxb4z+nZkTAwVdNtWwe8Tc2xNbEmdJYIYoc6Qt0uF55e6YW6KuTHw1DjQ18gMhzepw==", - "dev": true, - "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/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true, - "license": "MIT" - }, - "node_modules/proxy-addr": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, - "license": "MIT", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-addr/node_modules/ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/pvtsutils": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.6.tgz", - "integrity": "sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==", - "dev": true, - "license": "MIT", - "dependencies": { - "tslib": "^2.8.1" - } - }, - "node_modules/pvutils": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.5.tgz", - "integrity": "sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/qs": { - "version": "6.14.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz", - "integrity": "sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.1.0" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "^5.1.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/raw-body": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", - "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", - "dev": true, - "license": "MIT", - "dependencies": { - "bytes": "~3.1.2", - "http-errors": "~2.0.1", - "iconv-lite": "~0.4.24", - "unpipe": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "license": "MIT", - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/reflect-metadata": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", - "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", - "dev": true, - "license": "Apache-2.0" - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/resolve": { - "version": "1.22.11", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", - "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-core-module": "^2.16.1", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/run-applescript": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", - "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/schema-utils": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz", - "integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.9.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.1.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", - "dev": true, - "license": "MIT" - }, - "node_modules/selfsigned": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-5.5.0.tgz", - "integrity": "sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew==", - "dev": true, - "license": "MIT", - "dependencies": { - "@peculiar/x509": "^1.14.2", - "pkijs": "^3.3.3" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/send": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", - "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "~0.5.2", - "http-errors": "~2.0.1", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "~2.4.1", - "range-parser": "~1.2.1", - "statuses": "~2.0.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/serialize-javascript": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", - "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-index": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.2.tgz", - "integrity": "sha512-KDj11HScOaLmrPxl70KYNW1PksP4Nb/CLL2yvC+Qd2kHMPEEpfc4Re2e4FOay+bC/+XQl/7zAcWON3JVo5v3KQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "accepts": "~1.3.8", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.8.0", - "mime-types": "~2.1.35", - "parseurl": "~1.3.3" - }, - "engines": { - "node": ">= 0.8.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/serve-index/node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz", - "integrity": "sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-static": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", - "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "~0.19.1" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true, - "license": "ISC" - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "license": "MIT", - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/shell-quote": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", - "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", - "side-channel-map": "^1.0.1", - "side-channel-weakmap": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-map": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", - "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/side-channel-weakmap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", - "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bound": "^1.0.2", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.5", - "object-inspect": "^1.13.3", - "side-channel-map": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-support": { - "version": "0.5.21", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", - "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "node_modules/spdy-transport/node_modules/debug": { - "version": "4.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/spdy-transport/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/spdy/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/spdy/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/statuses": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", - "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, - "node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/tapable": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz", - "integrity": "sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/terser": { - "version": "5.46.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz", - "integrity": "sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg==", - "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.15.0", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.16", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz", - "integrity": "sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "jest-worker": "^27.4.5", - "schema-utils": "^4.3.0", - "serialize-javascript": "^6.0.2", - "terser": "^5.31.1" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/thingies": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/thingies/-/thingies-2.5.0.tgz", - "integrity": "sha512-s+2Bwztg6PhWUD7XMfeYm5qliDdSiZm7M7n8KjTkIsm3l/2lgVRc2/Gx/v+ZX8lT4FMA+i8aQvhcWylldc+ZNw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "^2" - } - }, - "node_modules/thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "dev": true, - "license": "MIT" - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/tree-dump": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.1.0.tgz", - "integrity": "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, - "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==", - "dev": true, - "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==", - "dev": true, - "license": "0BSD" - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/undici-types": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz", - "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", - "dev": true, - "license": "MIT" - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", - "integrity": "sha512-Js0m9cx+qOgDxo0eMiFGEueWztz+d4+M3rGlmKPT+T4IS/jP4ylw3Nwpu6cpTTP8R1MAC1kF4VbdLt3ARf209w==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - }, - { - "type": "github", - "url": "https://github.com/sponsors/ai" - } - ], - "license": "MIT", - "dependencies": { - "escalade": "^3.2.0", - "picocolors": "^1.1.1" - }, - "bin": { - "update-browserslist-db": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "dev": true, - "license": "MIT" - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "license": "MIT", - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/watchpack": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.1.tgz", - "integrity": "sha512-Zn5uXdcFNIA1+1Ei5McRd+iRzfhENPCe7LeABkJtNulSxjma+l7ltNx55BWZkRlwRnpOgHqxnjyaDgJnNXnqzg==", - "dev": true, - "license": "MIT", - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/webpack": { - "version": "5.105.2", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.105.2.tgz", - "integrity": "sha512-dRXm0a2qcHPUBEzVk8uph0xWSjV/xZxenQQbLwnwP7caQCYpqG1qddwlyEkIDkYn0K8tvmcrZ+bOrzoQ3HxCDw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/eslint-scope": "^3.7.7", - "@types/estree": "^1.0.8", - "@types/json-schema": "^7.0.15", - "@webassemblyjs/ast": "^1.14.1", - "@webassemblyjs/wasm-edit": "^1.14.1", - "@webassemblyjs/wasm-parser": "^1.14.1", - "acorn": "^8.15.0", - "acorn-import-phases": "^1.0.3", - "browserslist": "^4.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" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-cli": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", - "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^2.1.1", - "@webpack-cli/info": "^2.0.2", - "@webpack-cli/serve": "^2.0.5", - "colorette": "^2.0.14", - "commander": "^10.0.1", - "cross-spawn": "^7.0.3", - "envinfo": "^7.7.3", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^3.1.1", - "rechoir": "^0.8.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=14.15.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "5.x.x" - }, - "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/webpack-cli/node_modules/commander": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", - "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=14" - } - }, - "node_modules/webpack-dev-middleware": { - "version": "7.4.5", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.5.tgz", - "integrity": "sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA==", - "dev": true, - "license": "MIT", - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^4.43.1", - "mime-types": "^3.0.1", - "on-finished": "^2.4.1", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - } - } - }, - "node_modules/webpack-dev-middleware/node_modules/mime-db": { - "version": "1.54.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", - "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/webpack-dev-middleware/node_modules/mime-types": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", - "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "^1.54.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/webpack-dev-server": { - "version": "5.2.3", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.3.tgz", - "integrity": "sha512-9Gyu2F7+bg4Vv+pjbovuYDhHX+mqdqITykfzdM9UyKqKHlsE5aAjRhR+oOEfXW5vBeu8tarzlJFIZva4ZjAdrQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/bonjour": "^3.5.13", - "@types/connect-history-api-fallback": "^1.5.4", - "@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", - "@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.8.1", - "connect-history-api-fallback": "^2.0.0", - "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", - "open": "^10.0.3", - "p-retry": "^6.2.0", - "schema-utils": "^4.2.0", - "selfsigned": "^5.5.0", - "serve-index": "^1.9.1", - "sockjs": "^0.3.24", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^7.4.2", - "ws": "^8.18.0" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" - }, - "engines": { - "node": ">= 18.12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "webpack": { - "optional": true - }, - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-merge": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", - "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", - "dev": true, - "license": "MIT", - "dependencies": { - "clone-deep": "^4.0.1", - "flat": "^5.0.2", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.4.tgz", - "integrity": "sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q==", - "dev": true, - "license": "MIT", - "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==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "license": "ISC", - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/wildcard": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", - "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/ws": { - "version": "8.19.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", - "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/wsl-utils": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", - "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-wsl": "^3.1.0" - }, - "engines": { - "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - } - } -} diff --git a/wasm/mix-fetch/internal-dev/package.json b/wasm/mix-fetch/internal-dev/package.json deleted file mode 100644 index 7f837369f4..0000000000 --- a/wasm/mix-fetch/internal-dev/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "create-wasm-app", - "version": "0.1.0", - "description": "create an app to fetch data through the mixnet", - "main": "index.js", - "bin": { - "create-wasm-app": ".bin/create-wasm-app.js" - }, - "scripts": { - "build": "webpack --config webpack.config.js", - "build:wasm": "cd ../ && make wasm-build", - "start": "webpack-dev-server --port 8001" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/rustwasm/create-wasm-app.git" - }, - "keywords": [ - "webassembly", - "wasm", - "rust", - "webpack" - ], - "author": "Dave Hrycyszyn ", - "license": "Apache-2.0", - "bugs": { - "url": "https://github.com/nymtech/nym/issues" - }, - "homepage": "https://nymtech.net/docs", - "devDependencies": { - "copy-webpack-plugin": "^11.0.0", - "hello-wasm-pack": "^0.1.0", - "webpack": "^5.98.0", - "webpack-cli": "^5.1.4", - "webpack-dev-server": "^5.2.1" - }, - "dependencies": { - "@nymproject/mix-fetch-wasm": "file:../pkg", - "go-mix-conn": "file:../go-mix-conn/build" - } -} diff --git a/wasm/mix-fetch/internal-dev/webpack.config.js b/wasm/mix-fetch/internal-dev/webpack.config.js deleted file mode 100644 index dbf1df203a..0000000000 --- a/wasm/mix-fetch/internal-dev/webpack.config.js +++ /dev/null @@ -1,36 +0,0 @@ -const CopyWebpackPlugin = require("copy-webpack-plugin"); -const path = require("path"); - -module.exports = { - performance: { - hints: false, - maxEntrypointSize: 512000, - maxAssetSize: 512000, - }, - entry: { - bootstrap: "./bootstrap.js", - worker: "./worker.js", - }, - output: { - path: path.resolve(__dirname, "dist"), - filename: "[name].js", - }, - mode: "development", - // mode: 'production', - plugins: [ - new CopyWebpackPlugin({ - patterns: [ - "index.html", - { - from: "../pkg/*.(js|wasm)", - to: "[name][ext]", - }, - { - from: "../go-mix-conn/build/*.(js|wasm)", - to: "[name][ext]", - }, - ], - }), - ], - experiments: { syncWebAssembly: true }, -}; diff --git a/wasm/mix-fetch/internal-dev/worker.js b/wasm/mix-fetch/internal-dev/worker.js deleted file mode 100644 index 3ccc2cb5a6..0000000000 --- a/wasm/mix-fetch/internal-dev/worker.js +++ /dev/null @@ -1,314 +0,0 @@ -// Copyright 2020-2023 Nym Technologies SA -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -const RUST_WASM_URL = "mix_fetch_wasm_bg.wasm" -const GO_WASM_URL = "go_conn.wasm" - -importScripts('mix_fetch_wasm.js'); -importScripts('wasm_exec.js'); - -console.log('Initializing worker'); - -// wasm_bindgen creates a global variable (with the exports attached) that is in scope after `importScripts` -const { - default_debug, - no_cover_debug, - NymClient, - set_panic_hook, - Config, - GatewayEndpointConfig, - ClientStorage, - MixFetchConfig, - send_client_data, - start_new_mixnet_connection, - setupMixFetch, - disconnectMixFetch, - setupMixFetchWithConfig, - mix_fetch_initialised, - finish_mixnet_connection -} = wasm_bindgen; - -let client = null; -let tester = null; -const go = new Go(); // Defined in wasm_exec.js -var goWasm; -let mixFetchReady = false; - -function sendLog(message, level = 'info') { - self.postMessage({ - kind: 'Log', - args: { message, level }, - }); -} - -function sendReady() { - self.postMessage({ kind: 'MixFetchReady' }); -} - -function sendError(error) { - self.postMessage({ - kind: 'MixFetchError', - args: { error: String(error) }, - }); -} - -async function logFetchResult(res) { - console.log(res) - let text = await res.text() - console.log("HEADERS: ", ...res.headers) - console.log("STATUS: ", res.status) - console.log("STATUS TEXT: ", res.statusText) - console.log("OK: ", res.ok) - console.log("TYPE: ", res.type) - console.log("URL: ", res.url) - console.log("BODYUSED: ", res.bodyUsed) - console.log("REDIRECTED: ", res.redirected) - console.log("TEXT: ", text) - - self.postMessage({ - kind: 'DisplayString', - args: { - rawString: text, - }, - }); -} - -async function wasm_bindgenSetup() { - const preferredGateway = "6qQYb4ArXANU6HJDxzH4PFCUqYb39Dae2Gem2KpxescM"; - const validator = 'https://qa-nym-api.qa.nymte.ch/api'; - - // local - const mixFetchNetworkRequesterAddress = "2o47bhnXWna6VEyt4mXMGQQAbXfpKmX7BkjkxUz8uQVi.6uQGnCqSczpXwh86NdbsCoDDXuqZQM9Uwko8GE7uC9g8@6qQYb4ArXANU6HJDxzH4PFCUqYb39Dae2Gem2KpxescM"; - // const mixFetchNetworkRequesterAddress= "GqiGWmKRCbGQFSqH88BzLKijvZgipnqhmbNFsmkZw84t.4L8sXFuAUyUYyHZYgMdM3AtiusKnYUft6Pd8e41rrCHA@6qQYb4ArXANU6HJDxzH4PFCUqYb39Dae2Gem2KpxescM"; - - // STEP 1. construct config - // those are just some examples, there are obviously more permutations; - // note, the extra optional argument is of the following type: - // /* - // export interface MixFetchConfigOpts { - // id?: string; - // nymApi?: string; - // nyxd?: string; - // debug?: DebugWasm; - // } - // */ - // - // const debug = no_cover_debug() - // - // #1 - // const config = new MixFetchConfig(mixFetchNetworkRequesterAddress, { id: 'my-awesome-mix-fetch-client', nymApi: validator, debug: debug} ); - // #2 - // const config = new MixFetchConfig(mixFetchNetworkRequesterAddress, { nymApi: validator, debug: debug} ); - // #3 - // const config = new MixFetchConfig(mixFetchNetworkRequesterAddress, { id: 'my-awesome-mix-fetch-client' } ); - // - // #4 - const differentDebug = default_debug() - const updatedTraffic = differentDebug.traffic; - updatedTraffic.use_extended_packet_size = true - updatedTraffic.average_packet_delay_ms = 666; - differentDebug.traffic = updatedTraffic; - - const config = new MixFetchConfig(mixFetchNetworkRequesterAddress, {debug: differentDebug}); - // - // // STEP 2. setup the client - // // note, the extra optional argument is of the following type: - // /* - // export interface MixFetchOptsSimple { - // preferredGateway?: string; - // storagePassphrase?: string; - // } - // */ - // #1 - await setupMixFetchWithConfig(config) - // - // #2 - // await setupMixFetchWithConfig(config, { storagePassphrase: "foomp" }) - // - // #3 - // await setupMixFetchWithConfig(config, { storagePassphrase: "foomp", preferredGateway }) -} - -async function nativeSetup(preferredGateway) { - sendLog('Setting up MixFetch...'); - if (preferredGateway) { - sendLog(`Using preferred gateway: ${preferredGateway}`); - } else { - sendLog('Using random gateway selection'); - } - - const noCoverTrafficOverride = { - traffic: {disableMainPoissonPacketDistribution: true}, - coverTraffic: {disableLoopCoverTrafficStream: true}, - } - const mixFetchOverride = { - requestTimeoutMs: 60000 - } - - const opts = { - forceTls: true, - clientId: "my-client", - clientOverride: noCoverTrafficOverride, - mixFetchOverride, - }; - - if (preferredGateway) { - opts.preferredGateway = preferredGateway; - } - - sendLog('Calling setupMixFetch...'); - await setupMixFetch(opts); - sendLog('setupMixFetch completed'); -} - -async function startMixFetch(preferredGateway) { - sendLog('Instantiating MixFetch...'); - - try { - await nativeSetup(preferredGateway); - mixFetchReady = true; - sendLog('MixFetch client running!'); - sendReady(); - } catch (e) { - sendLog('Failed to start MixFetch: ' + e, 'error'); - sendError(e); - } -} - -async function handleFetchPayload(target) { - if (!mixFetchReady) { - sendLog('MixFetch not ready yet', 'error'); - return; - } - - const url = target; - const args = {mode: "unsafe-ignore-cors"}; - - try { - sendLog(`Fetching: ${url}`); - const mixFetchRes = await mixFetch(url, args); - sendLog('Fetch completed'); - await logFetchResult(mixFetchRes); - } catch (e) { - sendLog('Fetch request failure: ' + e, 'error'); - console.error("mix fetch request failure: ", e); - } -} - -async function handlePostPayload(url, body) { - if (!mixFetchReady) { - sendLog('MixFetch not ready yet', 'error'); - return; - } - - const args = { - method: 'POST', - mode: "unsafe-ignore-cors", - headers: { - 'Content-Type': 'application/json', - }, - body: body, - }; - - try { - sendLog(`POST request to: ${url}`); - sendLog(`POST body: ${body}`); - const mixFetchRes = await mixFetch(url, args); - sendLog('POST completed'); - await logFetchResult(mixFetchRes); - } catch (e) { - sendLog('POST request failure: ' + e, 'error'); - console.error("mix fetch POST request failure: ", e); - } -} - -function setupMessageHandler() { - self.onmessage = async event => { - if (event.data && event.data.kind) { - switch (event.data.kind) { - case 'StartMixFetch': { - const { preferredGateway } = event.data.args; - await startMixFetch(preferredGateway); - break; - } - case 'FetchPayload': { - const { target } = event.data.args; - await handleFetchPayload(target); - break; - } - case 'PostPayload': { - const { url, body } = event.data.args; - await handlePostPayload(url, body); - break; - } - } - } - }; -} - - -// TODO: look into https://www.aaron-powell.com/posts/2019-02-08-golang-wasm-5-compiling-with-webpack/ -async function loadGoWasm() { - const resp = await fetch(GO_WASM_URL); - - if ('instantiateStreaming' in WebAssembly) { - const wasmObj = await WebAssembly.instantiateStreaming(resp, go.importObject) - goWasm = wasmObj.instance - go.run(goWasm) - } else { - const bytes = await resp.arrayBuffer() - const wasmObj = await WebAssembly.instantiate(bytes, go.importObject) - goWasm = wasmObj.instance - go.run(goWasm) - } -} - -function setupRsGoBridge() { - // (note: reason for intermediate `__rs_go_bridge__` object is to decrease global scope bloat - // and to discourage users from trying to call those methods directly) - self.__rs_go_bridge__ = {} - self.__rs_go_bridge__.send_client_data = send_client_data - self.__rs_go_bridge__.start_new_mixnet_connection = start_new_mixnet_connection - self.__rs_go_bridge__.mix_fetch_initialised = mix_fetch_initialised - self.__rs_go_bridge__.finish_mixnet_connection = finish_mixnet_connection -} - -async function main() { - sendLog('Worker starting...'); - - // load rust WASM package - sendLog('Loading Rust WASM...'); - await wasm_bindgen(RUST_WASM_URL); - sendLog('Loaded Rust WASM'); - - // load go WASM package - sendLog('Loading Go WASM...'); - await loadGoWasm(); - sendLog('Loaded Go WASM'); - - // sets up better stack traces in case of in-rust panics - set_panic_hook(); - - setupRsGoBridge(); - - goWasmSetLogging("trace") - - // Set up message handler (MixFetch will be started on demand) - setupMessageHandler(); - - sendLog('Worker ready - click Start MixFetch to begin'); -} - -// Let's get started! -main(); \ No newline at end of file diff --git a/wasm/mix-fetch/internal-dev/yarn.lock b/wasm/mix-fetch/internal-dev/yarn.lock deleted file mode 100644 index 53c976c49e..0000000000 --- a/wasm/mix-fetch/internal-dev/yarn.lock +++ /dev/null @@ -1,2536 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -"@discoveryjs/json-ext@^0.5.0": - version "0.5.7" - resolved "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz" - integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== - -"@jridgewell/gen-mapping@^0.3.5": - 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== - dependencies: - "@jridgewell/sourcemap-codec" "^1.5.0" - "@jridgewell/trace-mapping" "^0.3.24" - -"@jridgewell/resolve-uri@^3.1.0": - version "3.1.2" - resolved "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz" - integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== - -"@jridgewell/source-map@^0.3.3": - version "0.3.11" - resolved "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz" - integrity sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA== - dependencies: - "@jridgewell/gen-mapping" "^0.3.5" - "@jridgewell/trace-mapping" "^0.3.25" - -"@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.5.0": - 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@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": - 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" - -"@jsonjoy.com/base64@^1.1.2": - version "1.1.2" - resolved "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz" - integrity sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA== - -"@jsonjoy.com/base64@17.67.0": - version "17.67.0" - resolved "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-17.67.0.tgz" - integrity sha512-5SEsJGsm15aP8TQGkDfJvz9axgPwAEm98S5DxOuYe8e1EbfajcDmgeXXzccEjh+mLnjqEKrkBdjHWS5vFNwDdw== - -"@jsonjoy.com/buffers@^1.0.0": - version "1.2.1" - resolved "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz" - integrity sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA== - -"@jsonjoy.com/buffers@^1.2.0": - version "1.2.1" - resolved "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz" - integrity sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA== - -"@jsonjoy.com/buffers@^17.65.0", "@jsonjoy.com/buffers@17.67.0": - version "17.67.0" - resolved "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-17.67.0.tgz" - integrity sha512-tfExRpYxBvi32vPs9ZHaTjSP4fHAfzSmcahOfNxtvGHcyJel+aibkPlGeBB+7AoC6hL7lXIE++8okecBxx7lcw== - -"@jsonjoy.com/codegen@^1.0.0": - 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== - -"@jsonjoy.com/codegen@17.67.0": - version "17.67.0" - resolved "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-17.67.0.tgz" - integrity sha512-idnkUplROpdBOV0HMcwhsCUS5TRUi9poagdGs70A6S4ux9+/aPuKbh8+UYRTLYQHtXvAdNfQWXDqZEx5k4Dj2Q== - -"@jsonjoy.com/fs-core@4.56.10": - version "4.56.10" - resolved "https://registry.npmjs.org/@jsonjoy.com/fs-core/-/fs-core-4.56.10.tgz" - integrity sha512-PyAEA/3cnHhsGcdY+AmIU+ZPqTuZkDhCXQ2wkXypdLitSpd6d5Ivxhnq4wa2ETRWFVJGabYynBWxIijOswSmOw== - dependencies: - "@jsonjoy.com/fs-node-builtins" "4.56.10" - "@jsonjoy.com/fs-node-utils" "4.56.10" - thingies "^2.5.0" - -"@jsonjoy.com/fs-fsa@4.56.10": - version "4.56.10" - resolved "https://registry.npmjs.org/@jsonjoy.com/fs-fsa/-/fs-fsa-4.56.10.tgz" - integrity sha512-/FVK63ysNzTPOnCCcPoPHt77TOmachdMS422txM4KhxddLdbW1fIbFMYH0AM0ow/YchCyS5gqEjKLNyv71j/5Q== - dependencies: - "@jsonjoy.com/fs-core" "4.56.10" - "@jsonjoy.com/fs-node-builtins" "4.56.10" - "@jsonjoy.com/fs-node-utils" "4.56.10" - thingies "^2.5.0" - -"@jsonjoy.com/fs-node-builtins@4.56.10": - version "4.56.10" - resolved "https://registry.npmjs.org/@jsonjoy.com/fs-node-builtins/-/fs-node-builtins-4.56.10.tgz" - integrity sha512-uUnKz8R0YJyKq5jXpZtkGV9U0pJDt8hmYcLRrPjROheIfjMXsz82kXMgAA/qNg0wrZ1Kv+hrg7azqEZx6XZCVw== - -"@jsonjoy.com/fs-node-to-fsa@4.56.10": - version "4.56.10" - resolved "https://registry.npmjs.org/@jsonjoy.com/fs-node-to-fsa/-/fs-node-to-fsa-4.56.10.tgz" - integrity sha512-oH+O6Y4lhn9NyG6aEoFwIBNKZeYy66toP5LJcDOMBgL99BKQMUf/zWJspdRhMdn/3hbzQsZ8EHHsuekbFLGUWw== - dependencies: - "@jsonjoy.com/fs-fsa" "4.56.10" - "@jsonjoy.com/fs-node-builtins" "4.56.10" - "@jsonjoy.com/fs-node-utils" "4.56.10" - -"@jsonjoy.com/fs-node-utils@4.56.10": - version "4.56.10" - resolved "https://registry.npmjs.org/@jsonjoy.com/fs-node-utils/-/fs-node-utils-4.56.10.tgz" - integrity sha512-8EuPBgVI2aDPwFdaNQeNpHsyqPi3rr+85tMNG/lHvQLiVjzoZsvxA//Xd8aB567LUhy4QS03ptT+unkD/DIsNg== - dependencies: - "@jsonjoy.com/fs-node-builtins" "4.56.10" - -"@jsonjoy.com/fs-node@4.56.10": - version "4.56.10" - resolved "https://registry.npmjs.org/@jsonjoy.com/fs-node/-/fs-node-4.56.10.tgz" - integrity sha512-7R4Gv3tkUdW3dXfXiOkqxkElxKNVdd8BDOWC0/dbERd0pXpPY+s2s1Mino+aTvkGrFPiY+mmVxA7zhskm4Ue4Q== - dependencies: - "@jsonjoy.com/fs-core" "4.56.10" - "@jsonjoy.com/fs-node-builtins" "4.56.10" - "@jsonjoy.com/fs-node-utils" "4.56.10" - "@jsonjoy.com/fs-print" "4.56.10" - "@jsonjoy.com/fs-snapshot" "4.56.10" - glob-to-regex.js "^1.0.0" - thingies "^2.5.0" - -"@jsonjoy.com/fs-print@4.56.10": - version "4.56.10" - resolved "https://registry.npmjs.org/@jsonjoy.com/fs-print/-/fs-print-4.56.10.tgz" - integrity sha512-JW4fp5mAYepzFsSGrQ48ep8FXxpg4niFWHdF78wDrFGof7F3tKDJln72QFDEn/27M1yHd4v7sKHHVPh78aWcEw== - dependencies: - "@jsonjoy.com/fs-node-utils" "4.56.10" - tree-dump "^1.1.0" - -"@jsonjoy.com/fs-snapshot@4.56.10": - version "4.56.10" - resolved "https://registry.npmjs.org/@jsonjoy.com/fs-snapshot/-/fs-snapshot-4.56.10.tgz" - integrity sha512-DkR6l5fj7+qj0+fVKm/OOXMGfDFCGXLfyHkORH3DF8hxkpDgIHbhf/DwncBMs2igu/ST7OEkexn1gIqoU6Y+9g== - dependencies: - "@jsonjoy.com/buffers" "^17.65.0" - "@jsonjoy.com/fs-node-utils" "4.56.10" - "@jsonjoy.com/json-pack" "^17.65.0" - "@jsonjoy.com/util" "^17.65.0" - -"@jsonjoy.com/json-pack@^1.11.0": - 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== - dependencies: - "@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" - -"@jsonjoy.com/json-pack@^17.65.0": - 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== - dependencies: - "@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@^1.0.2": - version "1.0.2" - resolved "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz" - integrity sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg== - dependencies: - "@jsonjoy.com/codegen" "^1.0.0" - "@jsonjoy.com/util" "^1.9.0" - -"@jsonjoy.com/json-pointer@17.67.0": - 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== - dependencies: - "@jsonjoy.com/util" "17.67.0" - -"@jsonjoy.com/util@^1.9.0": - version "1.9.0" - resolved "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.9.0.tgz" - integrity sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ== - dependencies: - "@jsonjoy.com/buffers" "^1.0.0" - "@jsonjoy.com/codegen" "^1.0.0" - -"@jsonjoy.com/util@^17.65.0", "@jsonjoy.com/util@17.67.0": - version "17.67.0" - resolved "https://registry.npmjs.org/@jsonjoy.com/util/-/util-17.67.0.tgz" - integrity sha512-6+8xBaz1rLSohlGh68D1pdw3AwDi9xydm8QNlAFkvnavCJYSze+pxoW2VKP8p308jtlMRLs5NTHfPlZLd4w7ew== - dependencies: - "@jsonjoy.com/buffers" "17.67.0" - "@jsonjoy.com/codegen" "17.67.0" - -"@leichtgewicht/ip-codec@^2.0.1": - version "2.0.5" - resolved "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz" - integrity sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw== - -"@noble/hashes@1.4.0": - version "1.4.0" - resolved "https://registry.npmjs.org/@noble/hashes/-/hashes-1.4.0.tgz" - integrity sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg== - -"@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - -"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5": - 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@^1.2.3": - version "1.2.8" - resolved "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - -"@nymproject/mix-fetch-wasm@file:../pkg": - version "1.4.2" - resolved "file:../pkg" - -"@peculiar/asn1-cms@^2.6.0", "@peculiar/asn1-cms@^2.6.1": - version "2.6.1" - resolved "https://registry.npmjs.org/@peculiar/asn1-cms/-/asn1-cms-2.6.1.tgz" - integrity sha512-vdG4fBF6Lkirkcl53q6eOdn3XYKt+kJTG59edgRZORlg/3atWWEReRCx5rYE1ZzTTX6vLK5zDMjHh7vbrcXGtw== - dependencies: - "@peculiar/asn1-schema" "^2.6.0" - "@peculiar/asn1-x509" "^2.6.1" - "@peculiar/asn1-x509-attr" "^2.6.1" - asn1js "^3.0.6" - tslib "^2.8.1" - -"@peculiar/asn1-csr@^2.6.0": - version "2.6.1" - resolved "https://registry.npmjs.org/@peculiar/asn1-csr/-/asn1-csr-2.6.1.tgz" - integrity sha512-WRWnKfIocHyzFYQTka8O/tXCiBquAPSrRjXbOkHbO4qdmS6loffCEGs+rby6WxxGdJCuunnhS2duHURhjyio6w== - dependencies: - "@peculiar/asn1-schema" "^2.6.0" - "@peculiar/asn1-x509" "^2.6.1" - asn1js "^3.0.6" - tslib "^2.8.1" - -"@peculiar/asn1-ecc@^2.6.0": - version "2.6.1" - resolved "https://registry.npmjs.org/@peculiar/asn1-ecc/-/asn1-ecc-2.6.1.tgz" - integrity sha512-+Vqw8WFxrtDIN5ehUdvlN2m73exS2JVG0UAyfVB31gIfor3zWEAQPD+K9ydCxaj3MLen9k0JhKpu9LqviuCE1g== - dependencies: - "@peculiar/asn1-schema" "^2.6.0" - "@peculiar/asn1-x509" "^2.6.1" - asn1js "^3.0.6" - tslib "^2.8.1" - -"@peculiar/asn1-pfx@^2.6.1": - version "2.6.1" - resolved "https://registry.npmjs.org/@peculiar/asn1-pfx/-/asn1-pfx-2.6.1.tgz" - integrity sha512-nB5jVQy3MAAWvq0KY0R2JUZG8bO/bTLpnwyOzXyEh/e54ynGTatAR+csOnXkkVD9AFZ2uL8Z7EV918+qB1qDvw== - dependencies: - "@peculiar/asn1-cms" "^2.6.1" - "@peculiar/asn1-pkcs8" "^2.6.1" - "@peculiar/asn1-rsa" "^2.6.1" - "@peculiar/asn1-schema" "^2.6.0" - asn1js "^3.0.6" - tslib "^2.8.1" - -"@peculiar/asn1-pkcs8@^2.6.1": - version "2.6.1" - resolved "https://registry.npmjs.org/@peculiar/asn1-pkcs8/-/asn1-pkcs8-2.6.1.tgz" - integrity sha512-JB5iQ9Izn5yGMw3ZG4Nw3Xn/hb/G38GYF3lf7WmJb8JZUydhVGEjK/ZlFSWhnlB7K/4oqEs8HnfFIKklhR58Tw== - dependencies: - "@peculiar/asn1-schema" "^2.6.0" - "@peculiar/asn1-x509" "^2.6.1" - asn1js "^3.0.6" - tslib "^2.8.1" - -"@peculiar/asn1-pkcs9@^2.6.0": - version "2.6.1" - resolved "https://registry.npmjs.org/@peculiar/asn1-pkcs9/-/asn1-pkcs9-2.6.1.tgz" - integrity sha512-5EV8nZoMSxeWmcxWmmcolg22ojZRgJg+Y9MX2fnE2bGRo5KQLqV5IL9kdSQDZxlHz95tHvIq9F//bvL1OeNILw== - dependencies: - "@peculiar/asn1-cms" "^2.6.1" - "@peculiar/asn1-pfx" "^2.6.1" - "@peculiar/asn1-pkcs8" "^2.6.1" - "@peculiar/asn1-schema" "^2.6.0" - "@peculiar/asn1-x509" "^2.6.1" - "@peculiar/asn1-x509-attr" "^2.6.1" - asn1js "^3.0.6" - tslib "^2.8.1" - -"@peculiar/asn1-rsa@^2.6.0", "@peculiar/asn1-rsa@^2.6.1": - version "2.6.1" - resolved "https://registry.npmjs.org/@peculiar/asn1-rsa/-/asn1-rsa-2.6.1.tgz" - integrity sha512-1nVMEh46SElUt5CB3RUTV4EG/z7iYc7EoaDY5ECwganibQPkZ/Y2eMsTKB/LeyrUJ+W/tKoD9WUqIy8vB+CEdA== - dependencies: - "@peculiar/asn1-schema" "^2.6.0" - "@peculiar/asn1-x509" "^2.6.1" - asn1js "^3.0.6" - tslib "^2.8.1" - -"@peculiar/asn1-schema@^2.6.0": - version "2.6.0" - resolved "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.6.0.tgz" - integrity sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg== - dependencies: - asn1js "^3.0.6" - pvtsutils "^1.3.6" - tslib "^2.8.1" - -"@peculiar/asn1-x509-attr@^2.6.1": - version "2.6.1" - resolved "https://registry.npmjs.org/@peculiar/asn1-x509-attr/-/asn1-x509-attr-2.6.1.tgz" - integrity sha512-tlW6cxoHwgcQghnJwv3YS+9OO1737zgPogZ+CgWRUK4roEwIPzRH4JEiG770xe5HX2ATfCpmX60gurfWIF9dcQ== - dependencies: - "@peculiar/asn1-schema" "^2.6.0" - "@peculiar/asn1-x509" "^2.6.1" - asn1js "^3.0.6" - tslib "^2.8.1" - -"@peculiar/asn1-x509@^2.6.0", "@peculiar/asn1-x509@^2.6.1": - version "2.6.1" - resolved "https://registry.npmjs.org/@peculiar/asn1-x509/-/asn1-x509-2.6.1.tgz" - integrity sha512-O9jT5F1A2+t3r7C4VT7LYGXqkGLK7Kj1xFpz7U0isPrubwU5PbDoyYtx6MiGst29yq7pXN5vZbQFKRCP+lLZlA== - dependencies: - "@peculiar/asn1-schema" "^2.6.0" - asn1js "^3.0.6" - pvtsutils "^1.3.6" - tslib "^2.8.1" - -"@peculiar/x509@^1.14.2": - version "1.14.3" - resolved "https://registry.npmjs.org/@peculiar/x509/-/x509-1.14.3.tgz" - integrity sha512-C2Xj8FZ0uHWeCXXqX5B4/gVFQmtSkiuOolzAgutjTfseNOHT3pUjljDZsTSxXFGgio54bCzVFqmEOUrIVk8RDA== - 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" - -"@types/body-parser@*": - version "1.19.6" - resolved "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz" - integrity sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g== - dependencies: - "@types/connect" "*" - "@types/node" "*" - -"@types/bonjour@^3.5.13": - version "3.5.13" - resolved "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz" - integrity sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ== - dependencies: - "@types/node" "*" - -"@types/connect-history-api-fallback@^1.5.4": - 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== - dependencies: - "@types/express-serve-static-core" "*" - "@types/node" "*" - -"@types/connect@*": - version "3.4.38" - resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz" - integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== - dependencies: - "@types/node" "*" - -"@types/eslint-scope@^3.7.7": - 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== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" - -"@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== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - -"@types/estree@*", "@types/estree@^1.0.8": - version "1.0.8" - resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz" - integrity sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w== - -"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.21", "@types/express-serve-static-core@^4.17.33": - version "4.19.8" - resolved "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.8.tgz" - integrity sha512-02S5fmqeoKzVZCHPZid4b8JH2eM5HzQLZWN2FohQEy/0eXTq8VXZfSN6Pcr3F6N9R/vNrj7cpgbhjie6m/1tCA== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - "@types/send" "*" - -"@types/express@*", "@types/express@^4.17.13", "@types/express@^4.17.25": - version "4.17.25" - resolved "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz" - integrity sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.33" - "@types/qs" "*" - "@types/serve-static" "^1" - -"@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@^1.17.8": - version "1.17.17" - resolved "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.17.tgz" - integrity sha512-ED6LB+Z1AVylNTu7hdzuBqOgMnvG/ld6wGCG8wFnAzKX5uyW2K3WD52v0gnLCTK/VLpXtKckgWuyScYK6cSPaw== - dependencies: - "@types/node" "*" - -"@types/json-schema@*", "@types/json-schema@^7.0.15", "@types/json-schema@^7.0.9": - 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@^1": - 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 "25.3.0" - resolved "https://registry.npmjs.org/@types/node/-/node-25.3.0.tgz" - integrity sha512-4K3bqJpXpqfg2XKGK9bpDTc6xO/xoUP/RBWS7AtRMug6zZFaRekiLzjVtAoZMquxoAbzBvy5nxQ7veS5eYzf8A== - dependencies: - undici-types "~7.18.0" - -"@types/qs@*": - version "6.14.0" - resolved "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz" - integrity sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ== - -"@types/range-parser@*": - version "1.2.7" - resolved "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz" - integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== - -"@types/retry@0.12.2": - 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== - dependencies: - "@types/node" "*" - -"@types/send@<1": - version "0.17.6" - resolved "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz" - integrity sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og== - dependencies: - "@types/mime" "^1" - "@types/node" "*" - -"@types/serve-index@^1.9.4": - 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== - dependencies: - "@types/express" "*" - -"@types/serve-static@^1", "@types/serve-static@^1.15.5": - version "1.15.10" - resolved "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz" - integrity sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw== - dependencies: - "@types/http-errors" "*" - "@types/node" "*" - "@types/send" "<1" - -"@types/sockjs@^0.3.36": - 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== - dependencies: - "@types/node" "*" - -"@types/ws@^8.5.10": - version "8.18.1" - resolved "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz" - integrity sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg== - dependencies: - "@types/node" "*" - -"@webassemblyjs/ast@^1.14.1", "@webassemblyjs/ast@1.14.1": - version "1.14.1" - resolved "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz" - integrity sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ== - dependencies: - "@webassemblyjs/helper-numbers" "1.13.2" - "@webassemblyjs/helper-wasm-bytecode" "1.13.2" - -"@webassemblyjs/floating-point-hex-parser@1.13.2": - 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@1.13.2": - 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@1.14.1": - 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@1.13.2": - version "1.13.2" - resolved "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz" - integrity sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA== - dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.13.2" - "@webassemblyjs/helper-api-error" "1.13.2" - "@xtuc/long" "4.2.2" - -"@webassemblyjs/helper-wasm-bytecode@1.13.2": - 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@1.14.1": - 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== - dependencies: - "@webassemblyjs/ast" "1.14.1" - "@webassemblyjs/helper-buffer" "1.14.1" - "@webassemblyjs/helper-wasm-bytecode" "1.13.2" - "@webassemblyjs/wasm-gen" "1.14.1" - -"@webassemblyjs/ieee754@1.13.2": - version "1.13.2" - resolved "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz" - integrity sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw== - dependencies: - "@xtuc/ieee754" "^1.2.0" - -"@webassemblyjs/leb128@1.13.2": - version "1.13.2" - resolved "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz" - integrity sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw== - dependencies: - "@xtuc/long" "4.2.2" - -"@webassemblyjs/utf8@1.13.2": - 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@^1.14.1": - version "1.14.1" - resolved "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz" - integrity sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ== - dependencies: - "@webassemblyjs/ast" "1.14.1" - "@webassemblyjs/helper-buffer" "1.14.1" - "@webassemblyjs/helper-wasm-bytecode" "1.13.2" - "@webassemblyjs/helper-wasm-section" "1.14.1" - "@webassemblyjs/wasm-gen" "1.14.1" - "@webassemblyjs/wasm-opt" "1.14.1" - "@webassemblyjs/wasm-parser" "1.14.1" - "@webassemblyjs/wast-printer" "1.14.1" - -"@webassemblyjs/wasm-gen@1.14.1": - version "1.14.1" - resolved "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz" - integrity sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg== - dependencies: - "@webassemblyjs/ast" "1.14.1" - "@webassemblyjs/helper-wasm-bytecode" "1.13.2" - "@webassemblyjs/ieee754" "1.13.2" - "@webassemblyjs/leb128" "1.13.2" - "@webassemblyjs/utf8" "1.13.2" - -"@webassemblyjs/wasm-opt@1.14.1": - version "1.14.1" - resolved "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz" - integrity sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw== - dependencies: - "@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@^1.14.1", "@webassemblyjs/wasm-parser@1.14.1": - version "1.14.1" - resolved "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz" - integrity sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ== - dependencies: - "@webassemblyjs/ast" "1.14.1" - "@webassemblyjs/helper-api-error" "1.13.2" - "@webassemblyjs/helper-wasm-bytecode" "1.13.2" - "@webassemblyjs/ieee754" "1.13.2" - "@webassemblyjs/leb128" "1.13.2" - "@webassemblyjs/utf8" "1.13.2" - -"@webassemblyjs/wast-printer@1.14.1": - 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== - dependencies: - "@webassemblyjs/ast" "1.14.1" - "@xtuc/long" "4.2.2" - -"@webpack-cli/configtest@^2.1.1": - version "2.1.1" - resolved "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz" - integrity sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw== - -"@webpack-cli/info@^2.0.2": - version "2.0.2" - resolved "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz" - integrity sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A== - -"@webpack-cli/serve@^2.0.5": - version "2.0.5" - resolved "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz" - integrity sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ== - -"@xtuc/ieee754@^1.2.0": - version "1.2.0" - resolved "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz" - integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== - -"@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz" - integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== - -accepts@~1.3.8: - version "1.3.8" - resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" - integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== - dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" - -acorn-import-phases@^1.0.3: - version "1.0.4" - resolved "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz" - integrity sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ== - -acorn@^8.14.0, acorn@^8.15.0: - version "8.16.0" - resolved "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz" - integrity sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw== - -ajv-formats@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz" - integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== - dependencies: - ajv "^8.0.0" - -ajv-keywords@^5.1.0: - version "5.1.0" - resolved "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz" - integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== - dependencies: - fast-deep-equal "^3.1.3" - -ajv@^8.0.0, ajv@^8.8.2, ajv@^8.9.0: - version "8.18.0" - resolved "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz" - integrity sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A== - dependencies: - fast-deep-equal "^3.1.3" - fast-uri "^3.0.1" - json-schema-traverse "^1.0.0" - require-from-string "^2.0.2" - -ansi-html-community@^0.0.8: - 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== - -anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - -array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz" - integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== - -asn1js@^3.0.6: - version "3.0.7" - resolved "https://registry.npmjs.org/asn1js/-/asn1js-3.0.7.tgz" - integrity sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ== - dependencies: - pvtsutils "^1.3.6" - pvutils "^1.1.3" - tslib "^2.8.1" - -baseline-browser-mapping@^2.9.0: - version "2.10.0" - resolved "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.0.tgz" - integrity sha512-lIyg0szRfYbiy67j9KN8IyeD7q7hcmqnJ1ddWmNt19ItGpNN64mnllmxUNFIOdOm6by97jlL6wfpTTJrmnjWAA== - -batch@0.6.1: - 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== - -binary-extensions@^2.0.0: - version "2.3.0" - resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz" - integrity sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw== - -body-parser@~1.20.3: - version "1.20.4" - resolved "https://registry.npmjs.org/body-parser/-/body-parser-1.20.4.tgz" - integrity sha512-ZTgYYLMOXY9qKU/57FAo8F+HA2dGX7bqGc71txDRC1rS4frdFI5R7NhluHxH6M0YItAP0sHB4uqAOcYKxO6uGA== - 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" - -bonjour-service@^1.2.1: - version "1.3.0" - resolved "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz" - integrity sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA== - dependencies: - fast-deep-equal "^3.1.3" - multicast-dns "^7.2.5" - -braces@^3.0.3, braces@~3.0.2: - version "3.0.3" - resolved "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz" - integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== - dependencies: - fill-range "^7.1.1" - -browserslist@^4.28.1, "browserslist@>= 4.21.0": - version "4.28.1" - resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.28.1.tgz" - integrity sha512-ZC5Bd0LgJXgwGqUknZY/vkUQ04r8NXnJZ3yYi4vDmSiZmC/pdSN0NbNRPxZpbtO4uAfDUAFffO8IZoM3Gj8IkA== - dependencies: - 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" - -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - -bundle-name@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz" - integrity sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q== - dependencies: - run-applescript "^7.0.0" - -bytes@~3.1.2, bytes@3.1.2: - version "3.1.2" - resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" - integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== - -bytestreamjs@^2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/bytestreamjs/-/bytestreamjs-2.0.1.tgz" - integrity sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ== - -call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz" - integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== - dependencies: - es-errors "^1.3.0" - function-bind "^1.1.2" - -call-bound@^1.0.2: - version "1.0.4" - resolved "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz" - integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== - dependencies: - call-bind-apply-helpers "^1.0.2" - get-intrinsic "^1.3.0" - -caniuse-lite@^1.0.30001759: - version "1.0.30001774" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001774.tgz" - integrity sha512-DDdwPGz99nmIEv216hKSgLD+D4ikHQHjBC/seF98N9CPqRX4M5mSxT9eTV6oyisnJcuzxtZy4n17yKKQYmYQOA== - -chokidar@^3.6.0: - version "3.6.0" - resolved "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz" - integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - -chrome-trace-event@^1.0.2: - version "1.0.4" - resolved "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz" - integrity sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ== - -clone-deep@^4.0.1: - version "4.0.1" - resolved "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz" - integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== - dependencies: - is-plain-object "^2.0.4" - kind-of "^6.0.2" - shallow-clone "^3.0.0" - -colorette@^2.0.10, colorette@^2.0.14: - version "2.0.20" - resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz" - integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== - -commander@^10.0.1: - version "10.0.1" - resolved "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz" - integrity sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug== - -commander@^2.20.0: - 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== - -compressible@~2.0.18: - version "2.0.18" - resolved "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz" - integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== - dependencies: - mime-db ">= 1.43.0 < 2" - -compression@^1.8.1: - version "1.8.1" - resolved "https://registry.npmjs.org/compression/-/compression-1.8.1.tgz" - integrity sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w== - dependencies: - 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" - -connect-history-api-fallback@^2.0.0: - 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@~0.5.4: - version "0.5.4" - resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - -content-type@~1.0.4, content-type@~1.0.5: - version "1.0.5" - resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz" - integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== - -cookie-signature@~1.0.6: - version "1.0.7" - resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz" - integrity sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA== - -cookie@~0.7.1: - version "0.7.2" - resolved "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz" - integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== - -copy-webpack-plugin@^11.0.0: - version "11.0.0" - resolved "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-11.0.0.tgz" - integrity sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ== - dependencies: - fast-glob "^3.2.11" - glob-parent "^6.0.1" - globby "^13.1.1" - normalize-path "^3.0.0" - schema-utils "^4.0.0" - serialize-javascript "^6.0.0" - -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - -cross-spawn@^7.0.3: - version "7.0.6" - resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz" - integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - -debug@^4.1.0: - version "4.4.3" - resolved "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz" - integrity sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA== - dependencies: - ms "^2.1.3" - -debug@2.6.9: - version "2.6.9" - resolved "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - -default-browser-id@^5.0.0: - 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== - -default-browser@^5.2.1: - version "5.5.0" - resolved "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz" - integrity sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw== - dependencies: - bundle-name "^4.1.0" - default-browser-id "^5.0.0" - -define-lazy-prop@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz" - integrity sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg== - -depd@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz" - integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== - -depd@~2.0.0, depd@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - -destroy@~1.2.0, destroy@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz" - integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== - -detect-node@^2.0.4: - version "2.1.0" - resolved "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz" - integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== - -dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - -dns-packet@^5.2.2: - version "5.6.1" - resolved "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz" - integrity sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw== - dependencies: - "@leichtgewicht/ip-codec" "^2.0.1" - -dunder-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz" - integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== - dependencies: - call-bind-apply-helpers "^1.0.1" - es-errors "^1.3.0" - gopd "^1.2.0" - -ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" - integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== - -electron-to-chromium@^1.5.263: - version "1.5.302" - resolved "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.302.tgz" - integrity sha512-sM6HAN2LyK82IyPBpznDRqlTQAtuSaO+ShzFiWTvoMJLHyZ+Y39r8VMfHzwbU8MVBzQ4Wdn85+wlZl2TLGIlwg== - -encodeurl@~2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz" - integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== - -enhanced-resolve@^5.19.0: - version "5.19.0" - resolved "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz" - integrity sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.3.0" - -envinfo@^7.7.3: - version "7.21.0" - resolved "https://registry.npmjs.org/envinfo/-/envinfo-7.21.0.tgz" - integrity sha512-Lw7I8Zp5YKHFCXL7+Dz95g4CcbMEpgvqZNNq3AmlT5XAV6CgAAk6gyAMqn2zjw08K9BHfcNuKrMiCPLByGafow== - -es-define-property@^1.0.1: - 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@^1.3.0: - 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@^2.0.0: - 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@^1.0.0, es-object-atoms@^1.1.1: - 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== - dependencies: - es-errors "^1.3.0" - -escalade@^3.2.0: - version "3.2.0" - resolved "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz" - integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== - -escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" - integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== - -eslint-scope@5.1.1: - version "5.1.1" - resolved "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - -esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - -estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - -estraverse@^5.2.0: - version "5.3.0" - resolved "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - -etag@~1.8.1: - version "1.8.1" - resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" - integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== - -eventemitter3@^4.0.0: - version "4.0.7" - resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" - integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== - -events@^3.2.0: - version "3.3.0" - resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - -express@^4.22.1: - version "4.22.1" - resolved "https://registry.npmjs.org/express/-/express-4.22.1.tgz" - integrity sha512-F2X8g9P1X7uCPZMA3MVf9wcTqlyNp7IhH5qPCI0izhaOIYXaW9L535tGA3qmjRzpH+bZczqq7hVKxTR4NWnu+g== - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "~1.20.3" - content-disposition "~0.5.4" - content-type "~1.0.4" - cookie "~0.7.1" - cookie-signature "~1.0.6" - debug "2.6.9" - depd "2.0.0" - encodeurl "~2.0.0" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "~1.3.1" - fresh "~0.5.2" - http-errors "~2.0.0" - merge-descriptors "1.0.3" - methods "~1.1.2" - on-finished "~2.4.1" - parseurl "~1.3.3" - path-to-regexp "~0.1.12" - proxy-addr "~2.0.7" - qs "~6.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" - -fast-deep-equal@^3.1.3: - 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@^3.2.11, fast-glob@^3.3.0: - version "3.3.3" - resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz" - integrity sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.8" - -fast-uri@^3.0.1: - version "3.1.0" - resolved "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz" - integrity sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA== - -fastest-levenshtein@^1.0.12: - version "1.0.16" - resolved "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz" - integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== - -fastq@^1.6.0: - version "1.20.1" - resolved "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz" - integrity sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw== - dependencies: - reusify "^1.0.4" - -faye-websocket@^0.11.3: - version "0.11.4" - resolved "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz" - integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== - dependencies: - websocket-driver ">=0.5.1" - -fill-range@^7.1.1: - version "7.1.1" - resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz" - integrity sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg== - dependencies: - to-regex-range "^5.0.1" - -finalhandler@~1.3.1: - version "1.3.2" - resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz" - integrity sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg== - dependencies: - debug "2.6.9" - encodeurl "~2.0.0" - escape-html "~1.0.3" - on-finished "~2.4.1" - parseurl "~1.3.3" - statuses "~2.0.2" - unpipe "~1.0.0" - -find-up@^4.0.0: - version "4.1.0" - resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - -flat@^5.0.2: - version "5.0.2" - resolved "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - -follow-redirects@^1.0.0: - version "1.15.11" - resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz" - integrity sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ== - -forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - -fresh@~0.5.2: - version "0.5.2" - resolved "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz" - integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== - -function-bind@^1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" - integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== - -get-intrinsic@^1.2.5, get-intrinsic@^1.3.0: - version "1.3.0" - resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz" - integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== - dependencies: - call-bind-apply-helpers "^1.0.2" - es-define-property "^1.0.1" - es-errors "^1.3.0" - es-object-atoms "^1.1.1" - function-bind "^1.1.2" - get-proto "^1.0.1" - gopd "^1.2.0" - has-symbols "^1.1.0" - hasown "^2.0.2" - math-intrinsics "^1.1.0" - -get-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz" - integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== - dependencies: - dunder-proto "^1.0.1" - es-object-atoms "^1.0.0" - -glob-parent@^5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-parent@^6.0.1: - version "6.0.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - -glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - -glob-to-regex.js@^1.0.0, glob-to-regex.js@^1.0.1: - 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== - -glob-to-regexp@^0.4.1: - 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== - -globby@^13.1.1: - version "13.2.2" - resolved "https://registry.npmjs.org/globby/-/globby-13.2.2.tgz" - integrity sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w== - dependencies: - dir-glob "^3.0.1" - fast-glob "^3.3.0" - ignore "^5.2.4" - merge2 "^1.4.1" - slash "^4.0.0" - -"go-mix-conn@file:../go-mix-conn/build": - resolved "file:../go-mix-conn/build" - -gopd@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz" - integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== - -graceful-fs@^4.1.2, graceful-fs@^4.2.11, graceful-fs@^4.2.4, graceful-fs@^4.2.6: - 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== - -handle-thing@^2.0.0: - 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@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - -has-symbols@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz" - integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== - -hasown@^2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz" - integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== - dependencies: - function-bind "^1.1.2" - -hello-wasm-pack@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/hello-wasm-pack/-/hello-wasm-pack-0.1.0.tgz" - integrity sha512-3hx0GDkDLf/a9ThCMV2qG4mwza8N/MCtm8aeFFc/cdBCL2zMJ1kW1wjNl7xPqD1lz8Yl5+uhnc/cpui4dLwz/w== - -hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz" - integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== - dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - -http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz" - integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== - -http-errors@~1.8.0: - version "1.8.1" - resolved "https://registry.npmjs.org/http-errors/-/http-errors-1.8.1.tgz" - integrity sha512-Kpk9Sm7NmI+RHhnj6OIWDI1d6fIoFAtFt9RLaTMRlg/8w49juAStsrBgp0Dp4OdxdVbRIeKhtCUvoi/RuAhO4g== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.1" - -http-errors@~2.0.0, http-errors@~2.0.1: - version "2.0.1" - resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz" - integrity sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ== - dependencies: - depd "~2.0.0" - inherits "~2.0.4" - setprototypeof "~1.2.0" - statuses "~2.0.2" - toidentifier "~1.0.1" - -http-parser-js@>=0.5.1: - 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-middleware@^2.0.9: - 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== - dependencies: - "@types/http-proxy" "^1.17.8" - http-proxy "^1.18.1" - is-glob "^4.0.1" - is-plain-obj "^3.0.0" - micromatch "^4.0.2" - -http-proxy@^1.18.1: - version "1.18.1" - resolved "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz" - integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== - dependencies: - eventemitter3 "^4.0.0" - follow-redirects "^1.0.0" - requires-port "^1.0.0" - -hyperdyperid@^1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz" - integrity sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A== - -iconv-lite@~0.4.24: - version "0.4.24" - resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - -ignore@^5.2.4: - version "5.3.2" - resolved "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz" - integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== - -import-local@^3.0.2: - version "3.2.0" - resolved "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz" - integrity sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - -inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.3, inherits@~2.0.4, inherits@2.0.4: - version "2.0.4" - resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - -interpret@^3.1.1: - version "3.1.1" - resolved "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz" - integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ== - -ipaddr.js@^2.1.0: - version "2.3.0" - resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.3.0.tgz" - integrity sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg== - -ipaddr.js@1.9.1: - 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-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - -is-core-module@^2.16.1: - version "2.16.1" - resolved "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz" - integrity sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w== - dependencies: - hasown "^2.0.2" - -is-docker@^3.0.0: - 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@^2.1.1: - version "2.1.1" - resolved "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - -is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - -is-inside-container@^1.0.0: - 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== - dependencies: - is-docker "^3.0.0" - -is-network-error@^1.0.0: - version "1.3.0" - resolved "https://registry.npmjs.org/is-network-error/-/is-network-error-1.3.0.tgz" - integrity sha512-6oIwpsgRfnDiyEDLMay/GqCl3HoAtH5+RUKW29gYkL0QA+ipzpDLA16yQs7/RHCSu+BwgbJaOUqa4A99qNVQVw== - -is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - -is-plain-obj@^3.0.0: - 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@^2.0.4: - 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== - dependencies: - isobject "^3.0.1" - -is-wsl@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.1.tgz" - integrity sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw== - dependencies: - is-inside-container "^1.0.0" - -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - -isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - -isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz" - integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== - -jest-worker@^27.4.5: - version "27.5.1" - resolved "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz" - integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - -json-parse-even-better-errors@^2.3.1: - 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-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - -kind-of@^6.0.2: - 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@^2.6.1: - version "2.13.0" - resolved "https://registry.npmjs.org/launch-editor/-/launch-editor-2.13.0.tgz" - integrity sha512-u+9asUHMJ99lA15VRMXw5XKfySFR9dGXwgsgS14YTbUq3GITP58mIM32At90P5fZ+MUId5Yw+IwI/yKub7jnCQ== - dependencies: - picocolors "^1.1.1" - shell-quote "^1.8.3" - -loader-runner@^4.3.1: - version "4.3.1" - resolved "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.1.tgz" - integrity sha512-IWqP2SCPhyVFTBtRcgMHdzlf9ul25NwaFx4wCEH/KjAXuuHY4yNjvPXsBokp8jCB936PyWRaPKUNh8NvylLp2Q== - -locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - -math-intrinsics@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz" - integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== - -media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz" - integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== - -memfs@^4.43.1: - version "4.56.10" - resolved "https://registry.npmjs.org/memfs/-/memfs-4.56.10.tgz" - integrity sha512-eLvzyrwqLHnLYalJP7YZ3wBe79MXktMdfQbvMrVD80K+NhrIukCVBvgP30zTJYEEDh9hZ/ep9z0KOdD7FSHo7w== - dependencies: - "@jsonjoy.com/fs-core" "4.56.10" - "@jsonjoy.com/fs-fsa" "4.56.10" - "@jsonjoy.com/fs-node" "4.56.10" - "@jsonjoy.com/fs-node-builtins" "4.56.10" - "@jsonjoy.com/fs-node-to-fsa" "4.56.10" - "@jsonjoy.com/fs-node-utils" "4.56.10" - "@jsonjoy.com/fs-print" "4.56.10" - "@jsonjoy.com/fs-snapshot" "4.56.10" - "@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@1.0.3: - version "1.0.3" - resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz" - integrity sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ== - -merge-stream@^2.0.0: - 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@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - -methods@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz" - integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== - -micromatch@^4.0.2, micromatch@^4.0.8: - version "4.0.8" - resolved "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz" - integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== - dependencies: - braces "^3.0.3" - picomatch "^2.3.1" - -mime-db@^1.54.0: - version "1.54.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz" - integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== - -"mime-db@>= 1.43.0 < 2", mime-db@1.52.0: - version "1.52.0" - resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - -mime-types@^2.1.27, mime-types@~2.1.24, mime-types@~2.1.34, mime-types@~2.1.35: - version "2.1.35" - resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - -mime-types@^3.0.1: - version "3.0.2" - resolved "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz" - integrity sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A== - dependencies: - mime-db "^1.54.0" - -mime@1.6.0: - version "1.6.0" - resolved "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - -minimalistic-assert@^1.0.0: - version "1.0.1" - resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - -ms@^2.1.3: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -ms@2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - -ms@2.1.3: - version "2.1.3" - resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - -multicast-dns@^7.2.5: - version "7.2.5" - resolved "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz" - integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== - dependencies: - dns-packet "^5.2.2" - thunky "^1.0.2" - -negotiator@~0.6.4: - version "0.6.4" - resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz" - integrity sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w== - -negotiator@0.6.3: - version "0.6.3" - resolved "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - -neo-async@^2.6.2: - version "2.6.2" - resolved "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - -node-releases@^2.0.27: - version "2.0.27" - resolved "https://registry.npmjs.org/node-releases/-/node-releases-2.0.27.tgz" - integrity sha512-nmh3lCkYZ3grZvqcCH+fjmQ7X+H0OeZgP40OierEaAptX4XofMh5kwNbWh7lBduUzCcV/8kZ+NDLCwm2iorIlA== - -normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - -object-inspect@^1.13.3: - version "1.13.4" - resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz" - integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== - -obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz" - integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== - -on-finished@^2.4.1, on-finished@~2.4.1: - version "2.4.1" - resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" - integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== - dependencies: - ee-first "1.1.1" - -on-headers@~1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/on-headers/-/on-headers-1.1.0.tgz" - integrity sha512-737ZY3yNnXy37FHkQxPzt4UZ2UWPWiCZWLvFZ4fu5cueciegX0zGPnrlY6bwRg4FdQOe9YU8MkmJwGhoMybl8A== - -open@^10.0.3: - version "10.2.0" - resolved "https://registry.npmjs.org/open/-/open-10.2.0.tgz" - integrity sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA== - dependencies: - default-browser "^5.2.1" - define-lazy-prop "^3.0.0" - is-inside-container "^1.0.0" - wsl-utils "^0.1.0" - -p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - -p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - -p-retry@^6.2.0: - version "6.2.1" - resolved "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz" - integrity sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ== - dependencies: - "@types/retry" "0.12.2" - is-network-error "^1.0.0" - retry "^0.13.1" - -p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - -parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - -path-exists@^4.0.0: - 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@^3.1.0: - version "3.1.1" - resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - -path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - -path-to-regexp@~0.1.12: - version "0.1.12" - resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz" - integrity sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ== - -path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - -picocolors@^1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz" - integrity sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA== - -picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - -pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - -pkijs@^3.3.3: - version "3.3.3" - resolved "https://registry.npmjs.org/pkijs/-/pkijs-3.3.3.tgz" - integrity sha512-+KD8hJtqQMYoTuL1bbGOqxb4z+nZkTAwVdNtWwe8Tc2xNbEmdJYIYoc6Qt0uF55e6YW6KuTHw1DjQ18gMhzepw== - 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" - -process-nextick-args@~2.0.0: - 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== - -proxy-addr@~2.0.7: - 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== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - -pvtsutils@^1.3.6: - version "1.3.6" - resolved "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.6.tgz" - integrity sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg== - dependencies: - tslib "^2.8.1" - -pvutils@^1.1.3: - version "1.1.5" - resolved "https://registry.npmjs.org/pvutils/-/pvutils-1.1.5.tgz" - integrity sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA== - -qs@~6.14.0: - version "6.14.2" - resolved "https://registry.npmjs.org/qs/-/qs-6.14.2.tgz" - integrity sha512-V/yCWTTF7VJ9hIh18Ugr2zhJMP01MY7c5kh4J870L7imm6/DIzBsNLTXzMwUA3yZ5b/KBqLx8Kp3uRvd7xSe3Q== - dependencies: - side-channel "^1.1.0" - -queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - -range-parser@^1.2.1, range-parser@~1.2.1: - 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@~2.5.3: - version "2.5.3" - resolved "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz" - integrity sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA== - dependencies: - bytes "~3.1.2" - http-errors "~2.0.1" - iconv-lite "~0.4.24" - unpipe "~1.0.0" - -readable-stream@^2.0.1: - version "2.3.8" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz" - integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - -readable-stream@^3.0.6: - version "3.6.2" - resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - -readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - -rechoir@^0.8.0: - version "0.8.0" - resolved "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz" - integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ== - dependencies: - resolve "^1.20.0" - -reflect-metadata@^0.2.2: - version "0.2.2" - resolved "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz" - integrity sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q== - -require-from-string@^2.0.2: - 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== - -requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz" - integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== - -resolve-cwd@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz" - integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== - dependencies: - resolve-from "^5.0.0" - -resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - -resolve@^1.20.0: - version "1.22.11" - resolved "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz" - integrity sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ== - dependencies: - is-core-module "^2.16.1" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - -retry@^0.13.1: - version "0.13.1" - resolved "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz" - integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== - -reusify@^1.0.4: - version "1.1.0" - resolved "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz" - integrity sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw== - -run-applescript@^7.0.0: - version "7.1.0" - resolved "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz" - integrity sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q== - -run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - -safe-buffer@^5.1.0, safe-buffer@>=5.1.0, safe-buffer@~5.2.0, safe-buffer@5.2.1: - version "5.2.1" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - -"safer-buffer@>= 2.1.2 < 3": - version "2.1.2" - resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - -schema-utils@^4.0.0, schema-utils@^4.2.0, schema-utils@^4.3.0, schema-utils@^4.3.3: - version "4.3.3" - resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz" - integrity sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA== - dependencies: - "@types/json-schema" "^7.0.9" - ajv "^8.9.0" - ajv-formats "^2.1.1" - ajv-keywords "^5.1.0" - -select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz" - integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== - -selfsigned@^5.5.0: - version "5.5.0" - resolved "https://registry.npmjs.org/selfsigned/-/selfsigned-5.5.0.tgz" - integrity sha512-ftnu3TW4+3eBfLRFnDEkzGxSF/10BJBkaLJuBHZX0kiPS7bRdlpZGu6YGt4KngMkdTwJE6MbjavFpqHvqVt+Ew== - dependencies: - "@peculiar/x509" "^1.14.2" - pkijs "^3.3.3" - -send@~0.19.0, send@~0.19.1: - version "0.19.2" - resolved "https://registry.npmjs.org/send/-/send-0.19.2.tgz" - integrity sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg== - dependencies: - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - encodeurl "~2.0.0" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "~0.5.2" - http-errors "~2.0.1" - mime "1.6.0" - ms "2.1.3" - on-finished "~2.4.1" - range-parser "~1.2.1" - statuses "~2.0.2" - -serialize-javascript@^6.0.0, serialize-javascript@^6.0.2: - version "6.0.2" - resolved "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz" - integrity sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g== - dependencies: - randombytes "^2.1.0" - -serve-index@^1.9.1: - version "1.9.2" - resolved "https://registry.npmjs.org/serve-index/-/serve-index-1.9.2.tgz" - integrity sha512-KDj11HScOaLmrPxl70KYNW1PksP4Nb/CLL2yvC+Qd2kHMPEEpfc4Re2e4FOay+bC/+XQl/7zAcWON3JVo5v3KQ== - dependencies: - accepts "~1.3.8" - batch "0.6.1" - debug "2.6.9" - escape-html "~1.0.3" - http-errors "~1.8.0" - mime-types "~2.1.35" - parseurl "~1.3.3" - -serve-static@~1.16.2: - version "1.16.3" - resolved "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz" - integrity sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA== - dependencies: - encodeurl "~2.0.0" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "~0.19.1" - -setprototypeof@~1.2.0, setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - -shallow-clone@^3.0.0: - version "3.0.1" - resolved "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz" - integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== - dependencies: - kind-of "^6.0.2" - -shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - -shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - -shell-quote@^1.8.3: - version "1.8.3" - resolved "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz" - integrity sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw== - -side-channel-list@^1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz" - integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== - dependencies: - es-errors "^1.3.0" - object-inspect "^1.13.3" - -side-channel-map@^1.0.1: - 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== - dependencies: - call-bound "^1.0.2" - es-errors "^1.3.0" - get-intrinsic "^1.2.5" - object-inspect "^1.13.3" - -side-channel-weakmap@^1.0.2: - version "1.0.2" - resolved "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz" - integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A== - dependencies: - call-bound "^1.0.2" - es-errors "^1.3.0" - get-intrinsic "^1.2.5" - object-inspect "^1.13.3" - side-channel-map "^1.0.1" - -side-channel@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz" - integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== - dependencies: - es-errors "^1.3.0" - object-inspect "^1.13.3" - side-channel-list "^1.0.0" - side-channel-map "^1.0.1" - side-channel-weakmap "^1.0.2" - -slash@^4.0.0: - version "4.0.0" - resolved "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz" - integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== - -sockjs@^0.3.24: - version "0.3.24" - resolved "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz" - integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== - dependencies: - faye-websocket "^0.11.3" - uuid "^8.3.2" - websocket-driver "^0.7.4" - -source-map-support@~0.5.20: - 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== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - -spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz" - integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - -spdy@^4.0.2: - version "4.0.2" - resolved "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz" - integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - -"statuses@>= 1.5.0 < 2": - version "1.5.0" - resolved "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz" - integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== - -statuses@~2.0.1, statuses@~2.0.2: - version "2.0.2" - resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz" - integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== - -string_decoder@^1.1.1: - 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== - dependencies: - safe-buffer "~5.2.0" - -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - -supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - -supports-preserve-symlinks-flag@^1.0.0: - 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== - -tapable@^2.3.0: - version "2.3.0" - resolved "https://registry.npmjs.org/tapable/-/tapable-2.3.0.tgz" - integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== - -terser-webpack-plugin@^5.3.16: - version "5.3.16" - resolved "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.16.tgz" - integrity sha512-h9oBFCWrq78NyWWVcSwZarJkZ01c2AyGrzs1crmHZO3QUg9D61Wu4NPjBy69n7JqylFF5y+CsUZYmYEIZ3mR+Q== - dependencies: - "@jridgewell/trace-mapping" "^0.3.25" - jest-worker "^27.4.5" - schema-utils "^4.3.0" - serialize-javascript "^6.0.2" - terser "^5.31.1" - -terser@^5.31.1: - version "5.46.0" - resolved "https://registry.npmjs.org/terser/-/terser-5.46.0.tgz" - integrity sha512-jTwoImyr/QbOWFFso3YoU3ik0jBBDJ6JTOQiy/J2YxVJdZCc+5u7skhNwiOR3FQIygFqVUPHl7qbbxtjW2K3Qg== - dependencies: - "@jridgewell/source-map" "^0.3.3" - acorn "^8.15.0" - commander "^2.20.0" - source-map-support "~0.5.20" - -thingies@^2.5.0: - version "2.5.0" - resolved "https://registry.npmjs.org/thingies/-/thingies-2.5.0.tgz" - integrity sha512-s+2Bwztg6PhWUD7XMfeYm5qliDdSiZm7M7n8KjTkIsm3l/2lgVRc2/Gx/v+ZX8lT4FMA+i8aQvhcWylldc+ZNw== - -thunky@^1.0.2: - version "1.1.0" - resolved "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz" - integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== - -to-regex-range@^5.0.1: - 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== - dependencies: - is-number "^7.0.0" - -toidentifier@~1.0.1, toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - -tree-dump@^1.0.3, tree-dump@^1.1.0: - version "1.1.0" - resolved "https://registry.npmjs.org/tree-dump/-/tree-dump-1.1.0.tgz" - integrity sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA== - -tslib@^1.9.3: - version "1.14.1" - resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslib@^2, tslib@^2.0.0, tslib@^2.8.1, tslib@2: - version "2.8.1" - resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz" - integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w== - -tsyringe@^4.10.0: - version "4.10.0" - resolved "https://registry.npmjs.org/tsyringe/-/tsyringe-4.10.0.tgz" - integrity sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw== - dependencies: - tslib "^1.9.3" - -type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - -undici-types@~7.18.0: - version "7.18.2" - resolved "https://registry.npmjs.org/undici-types/-/undici-types-7.18.2.tgz" - integrity sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w== - -unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" - integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== - -update-browserslist-db@^1.2.0: - 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== - dependencies: - escalade "^3.2.0" - picocolors "^1.1.1" - -util-deprecate@^1.0.1, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - -utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" - integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== - -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -vary@~1.1.2: - version "1.1.2" - resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" - integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== - -watchpack@^2.5.1: - 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" - -wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz" - integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== - dependencies: - minimalistic-assert "^1.0.0" - -webpack-cli@^5.1.4, webpack-cli@5.x.x: - version "5.1.4" - resolved "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz" - integrity sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg== - dependencies: - "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^2.1.1" - "@webpack-cli/info" "^2.0.2" - "@webpack-cli/serve" "^2.0.5" - colorette "^2.0.14" - commander "^10.0.1" - cross-spawn "^7.0.3" - envinfo "^7.7.3" - fastest-levenshtein "^1.0.12" - import-local "^3.0.2" - interpret "^3.1.1" - rechoir "^0.8.0" - webpack-merge "^5.7.3" - -webpack-dev-middleware@^7.4.2: - version "7.4.5" - resolved "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.5.tgz" - integrity sha512-uxQ6YqGdE4hgDKNf7hUiPXOdtkXvBJXrfEGYSx7P7LC8hnUYGK70X6xQXUvXeNyBDDcsiQXpG2m3G9vxowaEuA== - dependencies: - colorette "^2.0.10" - memfs "^4.43.1" - mime-types "^3.0.1" - on-finished "^2.4.1" - range-parser "^1.2.1" - schema-utils "^4.0.0" - -webpack-dev-server@^5.2.1: - version "5.2.3" - resolved "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.3.tgz" - integrity sha512-9Gyu2F7+bg4Vv+pjbovuYDhHX+mqdqITykfzdM9UyKqKHlsE5aAjRhR+oOEfXW5vBeu8tarzlJFIZva4ZjAdrQ== - dependencies: - "@types/bonjour" "^3.5.13" - "@types/connect-history-api-fallback" "^1.5.4" - "@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" - "@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.8.1" - connect-history-api-fallback "^2.0.0" - 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" - open "^10.0.3" - p-retry "^6.2.0" - schema-utils "^4.2.0" - selfsigned "^5.5.0" - serve-index "^1.9.1" - sockjs "^0.3.24" - spdy "^4.0.2" - webpack-dev-middleware "^7.4.2" - ws "^8.18.0" - -webpack-merge@^5.7.3: - version "5.10.0" - resolved "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz" - integrity sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA== - dependencies: - clone-deep "^4.0.1" - flat "^5.0.2" - wildcard "^2.0.0" - -webpack-sources@^3.3.3: - version "3.3.4" - resolved "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.4.tgz" - integrity sha512-7tP1PdV4vF+lYPnkMR0jMY5/la2ub5Fc/8VQrrU+lXkiM6C4TjVfGw7iKfyhnTQOsD+6Q/iKw0eFciziRgD58Q== - -webpack@^5.0.0, webpack@^5.1.0, webpack@^5.98.0, webpack@5.x.x: - version "5.105.2" - resolved "https://registry.npmjs.org/webpack/-/webpack-5.105.2.tgz" - integrity sha512-dRXm0a2qcHPUBEzVk8uph0xWSjV/xZxenQQbLwnwP7caQCYpqG1qddwlyEkIDkYn0K8tvmcrZ+bOrzoQ3HxCDw== - dependencies: - "@types/eslint-scope" "^3.7.7" - "@types/estree" "^1.0.8" - "@types/json-schema" "^7.0.15" - "@webassemblyjs/ast" "^1.14.1" - "@webassemblyjs/wasm-edit" "^1.14.1" - "@webassemblyjs/wasm-parser" "^1.14.1" - acorn "^8.15.0" - acorn-import-phases "^1.0.3" - browserslist "^4.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" - -websocket-driver@^0.7.4, websocket-driver@>=0.5.1: - version "0.7.4" - resolved "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz" - integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== - dependencies: - http-parser-js ">=0.5.1" - safe-buffer ">=5.1.0" - websocket-extensions ">=0.1.1" - -websocket-extensions@>=0.1.1: - version "0.1.4" - resolved "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz" - integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== - -which@^2.0.1: - 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" - -wildcard@^2.0.0: - version "2.0.1" - resolved "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz" - integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== - -ws@^8.18.0: - version "8.19.0" - resolved "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz" - integrity sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg== - -wsl-utils@^0.1.0: - version "0.1.0" - resolved "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz" - integrity sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw== - dependencies: - is-wsl "^3.1.0" diff --git a/wasm/mix-fetch/scripts/clean-build.sh b/wasm/mix-fetch/scripts/clean-build.sh deleted file mode 100755 index 47ad9df2b4..0000000000 --- a/wasm/mix-fetch/scripts/clean-build.sh +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env bash -# -# Clean build of mix-fetch: removes all build artifacts, rebuilds WASM (debug), -# installs internal-dev dependencies, and starts the webpack dev server. -# -# Usage (from wasm/mix-fetch): -# scripts/clean-build.sh -# -# Or from anywhere: -# ./wasm/mix-fetch/scripts/clean-build.sh - -set -euo pipefail - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -WASM_MIX_FETCH="${SCRIPT_DIR}/.." -REPO_ROOT="${WASM_MIX_FETCH}/../.." -INTERNAL_DEV="${WASM_MIX_FETCH}/internal-dev" - -echo "==> Cleaning build artifacts..." -rm -rf "${WASM_MIX_FETCH}/pkg" -rm -rf "${WASM_MIX_FETCH}/go-mix-conn/build" -rm -rf "${REPO_ROOT}/dist/wasm/mix-fetch" -rm -rf "${INTERNAL_DEV}/node_modules" -rm -rf "${INTERNAL_DEV}/dist" - -echo "==> Building WASM (Go + Rust debug)..." -make -C "${WASM_MIX_FETCH}/go-mix-conn" build-debug-dev -# Touch lib.rs to force Cargo to recompile and pick up a fresh build timestamp -touch "${WASM_MIX_FETCH}/src/lib.rs" -cd "${WASM_MIX_FETCH}" -make build-rust-debug - -echo "==> Installing internal-dev dependencies..." -cd "${INTERNAL_DEV}" -npm install - -echo "==> Starting internal-dev webpack dev server on port 3000..." -npm start diff --git a/wasm/mix-fetch/src/active_requests.rs b/wasm/mix-fetch/src/active_requests.rs deleted file mode 100644 index 72fe6ac9d9..0000000000 --- a/wasm/mix-fetch/src/active_requests.rs +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use crate::error::MixFetchError; -use crate::go_bridge::{goWasmCloseRemoteSocket, goWasmInjectConnError, goWasmInjectServerData}; -use crate::RequestId; -use nym_ordered_buffer::OrderedMessageBuffer; -use nym_socks5_requests::SocketData; -use nym_wasm_utils::{console_error, console_log}; -use rand::{thread_rng, RngCore}; -use std::collections::HashMap; -use std::sync::Arc; -use tokio::sync::Mutex; - -#[derive(Clone, Default)] -pub struct ActiveRequests { - // TODO: think whether we need sync or async mutex here - inner: Arc>>, -} - -impl ActiveRequests { - pub async fn start_new(&self) -> RequestId { - let mut guard = self.inner.lock().await; - let req = ActiveRequest::new(); - let mut rng = thread_rng(); - let request_id = loop { - let candidate = rng.next_u64(); - if !guard.contains_key(&candidate) { - break candidate; - } - }; - - console_log!("starting new request {request_id}"); - - // it's impossible to insert a duplicate entry here since we're holding the lock for the map - // and we've generated an id that must have been unique - guard.insert(request_id, req); - - request_id - } - - pub async fn invalidate_all(&self) { - let mut guard = self.inner.lock().await; - for (id, _req) in guard.drain() { - let err = MixFetchError::AbortedRequest { request_id: id }; - goWasmInjectConnError(id.to_string(), err.to_string()) - } - } - - pub async fn get_sending_sequence(&self, id: RequestId) -> Option { - let mut guard = self.inner.lock().await; - if let Some(req) = guard.get_mut(&id) { - Some(req.next_sending_seq()) - } else { - console_error!("attempted to get sending sequence of request {id}, however it no longer exists. Has it been aborted?"); - None - } - } - - pub async fn finish(&self, id: RequestId) { - let mut guard = self.inner.lock().await; - let old = guard.remove(&id); - if old.is_none() { - console_error!("attempted to finish request {id}, but it seems to have never existed?") - } - } - - pub async fn reject(&self, id: RequestId, err: MixFetchError) { - let mut guard = self.inner.lock().await; - let old = guard.remove(&id); - if old.is_none() { - console_error!("attempted to reject request {id}, but it seems to have never existed?") - } - - goWasmInjectConnError(id.to_string(), err.to_string()) - } - - pub async fn try_send_data_to_go(&self, data: SocketData) { - let id = data.header.connection_id; - let mut guard = self.inner.lock().await; - let Some(req) = guard.get_mut(&id) else { - // if there's no data and the socket is closed, we're all good because our local must have already closed - if !data.data.is_empty() || !data.header.local_socket_closed { - console_error!("attempted to send data for request {id}, however it no longer exists. Has it been aborted?"); - } - - // TODO: if it doesn't exist here, make sure to clear Go's memory too - return; - }; - - if let Err(err) = req.insert_data(data) { - console_error!("failed to insert request data: {err}"); - // this unwrap cannot possibly fail as we're holding an exclusive lock for the data - // and we have just borrowed the content - guard.remove(&id).unwrap(); - return goWasmCloseRemoteSocket(id.to_string()); - } - - // TODO: clean this one up - if let Some(contiguous_data) = req.received_data.read() { - // TODO: deal with closing socket, etc. - if !contiguous_data.data.is_empty() { - goWasmInjectServerData(id.to_string(), contiguous_data.data); - } - // TODO: that's very crappy way of doing it. - if Some(contiguous_data.last_sequence) == req.finished_at { - goWasmCloseRemoteSocket(id.to_string()); - } - } - } -} - -struct ActiveRequest { - received_data: OrderedMessageBuffer, - finished_at: Option, - - sending_seq: u64, -} - -impl ActiveRequest { - fn new() -> Self { - ActiveRequest { - received_data: Default::default(), - finished_at: None, - sending_seq: 0, - } - } - - fn next_sending_seq(&mut self) -> u64 { - let next = self.sending_seq; - self.sending_seq += 1; - next - } - - fn insert_data(&mut self, data: SocketData) -> Result<(), MixFetchError> { - if data.header.local_socket_closed { - if let Some(already_finished) = self.finished_at { - return Err(MixFetchError::DuplicateSocketClosure { - request: data.header.connection_id, - first: already_finished, - other: data.header.seq, - }); - } - self.finished_at = Some(data.header.seq) - } - - self.received_data.write(data.header.seq, data.data)?; - Ok(()) - } -} diff --git a/wasm/mix-fetch/src/client.rs b/wasm/mix-fetch/src/client.rs deleted file mode 100644 index 6fd5d642ac..0000000000 --- a/wasm/mix-fetch/src/client.rs +++ /dev/null @@ -1,345 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use crate::active_requests::ActiveRequests; -use crate::config::MixFetchConfig; -use crate::error::MixFetchError; -use crate::go_bridge::goWasmSetMixFetchRequestTimeout; -use crate::request_writer::RequestWriter; -use crate::socks_helpers::{socks5_connect_request, socks5_data_request}; -use crate::{config, RequestId}; -use js_sys::Promise; -use nym_bin_common::bin_info; -use nym_socks5_requests::RemoteAddress; -use nym_wasm_client_core::client::base_client::storage::GatewaysDetailsStore; -use nym_wasm_client_core::client::base_client::{BaseClientBuilder, ClientInput, ClientOutput}; -use nym_wasm_client_core::client::inbound_messages::InputMessage; -use nym_wasm_client_core::helpers::{add_gateway, generate_new_client_keys}; -use nym_wasm_client_core::nym_task::connections::TransmissionLane; -use nym_wasm_client_core::nym_task::ShutdownTracker; -use nym_wasm_client_core::storage::core_client_traits::FullWasmClientStorage; -use nym_wasm_client_core::storage::wasm_client_traits::WasmClientStorage; -use nym_wasm_client_core::storage::ClientStorage; -use nym_wasm_client_core::{IdentityKey, QueryReqwestRpcNyxdClient, Recipient}; -use nym_wasm_utils::console_log; -use nym_wasm_utils::error::PromisableResult; -use std::sync::atomic::{AtomicBool, Ordering}; -use tokio::sync::Mutex; -use wasm_bindgen::prelude::*; -use wasm_bindgen_futures::future_to_promise; - -#[wasm_bindgen] -pub struct MixFetchClient { - invalidated: AtomicBool, - - mix_fetch_config: config::MixFetch, - - self_address: Recipient, - - client_input: ClientInput, - - requests: ActiveRequests, - - // this has to be guarded by a mutex to be able to disconnect with an immutable reference - _shutdown_manager: Mutex, -} - -#[wasm_bindgen] -pub struct MixFetchClientBuilder { - config: MixFetchConfig, - preferred_gateway: Option, - latency_based_selection: Option, - force_tls: bool, - - storage_passphrase: Option, -} - -#[wasm_bindgen] -impl MixFetchClientBuilder { - #[wasm_bindgen(constructor)] - pub fn new( - config: MixFetchConfig, - force_tls: bool, - preferred_gateway: Option, - storage_passphrase: Option, - ) -> Self { - MixFetchClientBuilder { - config, - preferred_gateway, - latency_based_selection: None, - force_tls, - storage_passphrase, - } - } - - fn initialise_storage( - config: &MixFetchConfig, - base_storage: ClientStorage, - ) -> FullWasmClientStorage { - FullWasmClientStorage::new(&config.base, base_storage) - } - - fn start_reconstructor(client_output: ClientOutput, requests: ActiveRequests) { - RequestWriter::new(client_output, requests).start() - } - - async fn initialise_client_storage(&mut self) -> Result { - let client_store = - ClientStorage::new_async(&self.config.base.client.id, self.storage_passphrase.take()) - .await?; - if !client_store.has_identity_key().await? { - console_log!( - "no prior keys found - a new set will be generated for client {}", - self.config.base.client.id - ); - generate_new_client_keys(&client_store).await?; - } - - Ok(client_store) - } - - async fn try_set_preferred_gateway( - &self, - client_store: &ClientStorage, - ) -> Result { - let Some(preferred) = self.preferred_gateway.as_ref() else { - return Ok(false); - }; - - if client_store - .has_gateway_details(&preferred.to_string()) - .await? - { - GatewaysDetailsStore::set_active_gateway(client_store, &preferred.to_string()).await?; - return Ok(true); - } - - Ok(false) - } - - async fn has_active_gateway( - &self, - client_store: &ClientStorage, - ) -> Result { - Ok(client_store - .get_active_gateway_id() - .await? - .active_gateway_id_bs58 - .is_some()) - } - - // TODO: combine with normal wasm client - async fn start_client_async(mut self) -> Result { - console_log!("Starting the mix fetch client"); - - let timeout_ms = self.config.mix_fetch.debug.request_timeout.as_millis(); - if timeout_ms > u32::MAX as u128 { - return Err(MixFetchError::InvalidTimeoutValue { timeout_ms }); - } - goWasmSetMixFetchRequestTimeout(timeout_ms as u32); - - // TODO: resolve this properly - self.config.base.debug.topology.ignore_egress_epoch_role = true; - - // TODO: this will have to be re-used for surbs. but this is a problem for another PR. - let client_store = self.initialise_client_storage().await?; - - // if we don't have an active gateway (i.e. no gateways), add one - // otherwise, see if we set a preferred gateway and attempt to set its details as active - if !self.has_active_gateway(&client_store).await? - || !self.try_set_preferred_gateway(&client_store).await? - { - add_gateway( - self.preferred_gateway.clone(), - self.latency_based_selection, - self.force_tls, - &self.config.base.client.nym_api_urls, - bin_info!().into(), - self.config.base.debug.topology.minimum_gateway_performance, - self.config.base.debug.topology.ignore_ingress_epoch_role, - &client_store, - ) - .await?; - } - - let storage = Self::initialise_storage(&self.config, client_store); - - let base_builder = - BaseClientBuilder::::new(self.config.base, storage, None); - - // if let Ok(reuse_setup) = GatewaySetup::try_reuse_connection(init_res) { - // base_builder = base_builder.with_gateway_setup(reuse_setup); - // } - let mut started_client = base_builder.start_base().await?; - - let self_address = started_client.address; - - let active_requests = ActiveRequests::default(); - - let client_input = started_client.client_input.register_producer(); - let client_output = started_client.client_output.register_consumer(); - - Self::start_reconstructor(client_output, active_requests.clone()); - - Ok(MixFetchClient { - invalidated: AtomicBool::new(false), - mix_fetch_config: self.config.mix_fetch, - self_address, - client_input, - requests: active_requests, - _shutdown_manager: Mutex::new(started_client.shutdown_handle), - }) - } -} - -#[wasm_bindgen] -impl MixFetchClient { - pub(crate) async fn new_async( - config: MixFetchConfig, - force_tls: bool, - preferred_gateway: Option, - storage_passphrase: Option, - ) -> Result { - MixFetchClientBuilder::new(config, force_tls, preferred_gateway, storage_passphrase) - .start_client_async() - .await - } - - #[wasm_bindgen(constructor)] - #[allow(clippy::new_ret_no_self)] - pub fn new( - config: MixFetchConfig, - force_tls: bool, - preferred_gateway: Option, - storage_passphrase: Option, - ) -> Promise { - future_to_promise(async move { - Self::new_async(config, force_tls, preferred_gateway, storage_passphrase) - .await - .into_promise_result() - }) - } - - pub fn active(&self) -> bool { - !self.invalidated.load(Ordering::Relaxed) - } - - pub async fn disconnect(&self) -> Result<(), MixFetchError> { - self.invalidated.store(true, Ordering::Relaxed); - - console_log!("sending shutdown signal"); - let shutdown_guard = self._shutdown_manager.lock().await; - shutdown_guard.clone_shutdown_token().cancel(); - shutdown_guard.close_tracker(); - console_log!("waiting for shutdown to complete"); - shutdown_guard.wait_for_tracker().await; - - self.requests.invalidate_all().await; - - console_log!("done"); - Ok(()) - } - - pub fn self_address(&self) -> String { - self.self_address.to_string() - } - - async fn send_socks_connect( - &self, - request_id: RequestId, - target: RemoteAddress, - ) -> Result<(), MixFetchError> { - let raw_conn_req = socks5_connect_request(request_id, target, self.self_address); - let lane = TransmissionLane::ConnectionId(request_id); - let input = InputMessage::new_regular( - self.mix_fetch_config.network_requester_address, - raw_conn_req, - lane, - None, - ); - - // the expect here is fine as it implies an unrecoverable failure since one of the client core - // tasks has terminated - self.client_input - .input_sender - .send(input) - .await - .expect("the client has stopped listening for requests"); - - Ok(()) - } - - async fn send_socks_data( - &self, - request_id: RequestId, - local_closed: bool, - message_sequence: u64, - data: Vec, - ) -> Result<(), MixFetchError> { - let raw_send_req = socks5_data_request(request_id, local_closed, message_sequence, data); - let lane = TransmissionLane::ConnectionId(request_id); - let input = InputMessage::new_regular( - self.mix_fetch_config.network_requester_address, - raw_send_req, - lane, - None, - ); - - // the expect here is fine as it implies an unrecoverable failure since one of the client core - // tasks has terminated - self.client_input - .input_sender - .send(input) - .await - .expect("the client has stopped listening for requests"); - - Ok(()) - } - - pub(crate) async fn connect_to_mixnet( - &self, - target: String, - ) -> Result { - let request_id = self.requests.start_new().await; - self.send_socks_connect(request_id, target).await?; - - Ok(request_id) - } - - pub(crate) async fn forward_request_content( - &self, - request_id: RequestId, - data: Vec, - ) -> Result<(), MixFetchError> { - let seq = self - .requests - .get_sending_sequence(request_id) - .await - .ok_or(MixFetchError::AbortedRequest { request_id })?; - - self.send_socks_data(request_id, false, seq, data).await - } - - pub(crate) async fn close_local_socket( - &self, - request_id: RequestId, - ) -> Result<(), MixFetchError> { - let seq = self - .requests - .get_sending_sequence(request_id) - .await - .ok_or(MixFetchError::AbortedRequest { request_id })?; - - self.send_socks_data(request_id, true, seq, Vec::new()) - .await - } - - pub(crate) async fn disconnect_from_mixnet( - &self, - request_id: RequestId, - ) -> Result<(), MixFetchError> { - self.close_local_socket(request_id).await?; - self.requests.finish(request_id).await; - Ok(()) - } -} diff --git a/wasm/mix-fetch/src/config.rs b/wasm/mix-fetch/src/config.rs deleted file mode 100644 index 9d312ac280..0000000000 --- a/wasm/mix-fetch/src/config.rs +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -#![allow(unknown_lints)] -// clippy::empty_docs is not on stable as of 1.77 - -// due to expansion of #[wasm_bindgen] macro on `MixFetch` Config struct -#![allow(clippy::drop_non_drop)] -// due to the code generated by Tsify -#![allow(clippy::empty_docs)] - -use crate::error::MixFetchError; -use nym_wasm_client_core::config::{ - new_base_client_config, BaseClientConfig, ConfigDebug, DebugWasm, -}; -use nym_wasm_client_core::helpers::parse_recipient; -use nym_wasm_client_core::Recipient; -use serde::{Deserialize, Serialize}; -use std::time::Duration; -use tsify::Tsify; -use wasm_bindgen::prelude::*; - -const DEFAULT_MIX_FETCH_TIMEOUT: Duration = Duration::from_secs(5); -const DEFAULT_MIX_FETCH_ID: &str = "_default-nym-mix-fetch"; -const MIX_FETCH_CLIENT_ID_PREFIX: &str = "mix-fetch"; - -fn make_mix_fetch_id(id: Option) -> String { - if let Some(provided) = id { - format!("{MIX_FETCH_CLIENT_ID_PREFIX}-{provided}") - } else { - DEFAULT_MIX_FETCH_ID.to_string() - } -} - -#[wasm_bindgen] -#[derive(Debug, Deserialize, PartialEq, Serialize)] -#[serde(deny_unknown_fields)] -pub struct MixFetchConfig { - pub(crate) base: BaseClientConfig, - - pub(crate) mix_fetch: MixFetch, -} - -#[derive(Tsify, Debug, Clone, Serialize, Deserialize)] -#[tsify(into_wasm_abi, from_wasm_abi)] -#[serde(rename_all = "camelCase")] -pub struct MixFetchConfigOpts { - #[tsify(optional)] - pub id: Option, - - #[tsify(optional)] - pub nym_api: Option, - - #[tsify(optional)] - pub nyxd: Option, - - #[tsify(optional)] - pub debug: Option, -} - -#[wasm_bindgen] -impl MixFetchConfig { - #[wasm_bindgen(constructor)] - pub fn new( - network_requester_address: String, - opts: Option, - ) -> Result { - let version = env!("CARGO_PKG_VERSION").to_string(); - if let Some(opts) = opts { - Ok(MixFetchConfig { - base: new_base_client_config( - make_mix_fetch_id(opts.id), - version, - opts.nym_api, - opts.nyxd, - opts.debug, - )?, - mix_fetch: MixFetch::new(network_requester_address)?, - }) - } else { - Ok(MixFetchConfig { - base: BaseClientConfig::new(make_mix_fetch_id(None), version), - mix_fetch: MixFetch::new(network_requester_address)?, - }) - } - } -} - -#[wasm_bindgen] -impl MixFetchConfig { - pub fn with_mix_fetch_timeout(mut self, timeout_ms: u32) -> Self { - self.mix_fetch.debug.request_timeout = Duration::from_millis(timeout_ms as u64); - self - } -} - -impl MixFetchConfig { - pub fn override_debug>(&mut self, debug: D) { - self.base.debug = debug.into(); - } - - pub fn override_mix_fetch_debug>(&mut self, debug: D) { - self.mix_fetch.debug = debug.into(); - } -} - -#[wasm_bindgen] -#[derive(Debug, Deserialize, PartialEq, Serialize)] -#[serde(deny_unknown_fields)] -pub struct MixFetch { - pub(crate) network_requester_address: Recipient, - - #[serde(default)] - pub(crate) debug: MixFetchDebug, -} - -impl MixFetch { - pub(crate) fn new(network_requester_address: String) -> Result { - Ok(MixFetch { - network_requester_address: parse_recipient(&network_requester_address)?, - debug: Default::default(), - }) - } -} - -#[wasm_bindgen] -#[derive(Debug, Deserialize, PartialEq, Serialize)] -#[serde(deny_unknown_fields)] -pub struct MixFetchDebug { - pub(crate) request_timeout: Duration, -} - -impl Default for MixFetchDebug { - fn default() -> Self { - MixFetchDebug { - request_timeout: DEFAULT_MIX_FETCH_TIMEOUT, - } - } -} - -#[derive(Tsify, Debug, Copy, Clone, Serialize, Deserialize)] -#[tsify(into_wasm_abi, from_wasm_abi)] -#[serde(rename_all = "camelCase")] -pub struct MixFetchDebugOverride { - #[tsify(optional)] - pub request_timeout_ms: Option, -} - -impl From for MixFetchDebug { - fn from(value: MixFetchDebugOverride) -> Self { - let def = MixFetchDebug::default(); - - MixFetchDebug { - request_timeout: value - .request_timeout_ms - .map(|d| Duration::from_millis(d as u64)) - .unwrap_or(def.request_timeout), - } - } -} diff --git a/wasm/mix-fetch/src/error.rs b/wasm/mix-fetch/src/error.rs deleted file mode 100644 index ceb449df04..0000000000 --- a/wasm/mix-fetch/src/error.rs +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use crate::RequestId; -use nym_ordered_buffer::OrderedMessageError; -use nym_socks5_requests::ConnectionError; -use nym_validator_client::nym_api::error::NymAPIError; -use nym_wasm_client_core::error::WasmCoreError; -use nym_wasm_client_core::ClientCoreError; -use nym_wasm_utils::wasm_error; -use thiserror::Error; - -#[derive(Debug, Error)] -pub enum MixFetchError { - #[error(transparent)] - CoreError { - #[from] - source: WasmCoreError, - }, - - #[error("no public network requesters are not available on this network")] - NoNetworkRequesters, - - #[error("could not query for the service providers: {source}")] - ValidatorClientError { - #[from] - source: NymAPIError, - }, - - #[error("failed to parse mix fetch config options: {source}")] - MalformedConfigOptions { - #[from] - source: serde_wasm_bindgen::Error, - }, - - #[error("mix fetch hasn't been initialised")] - Uninitialised, - - #[error("mix fetch has already been initialised before")] - AlreadyInitialised, - - #[error("mix fetch client has already been disconnected")] - Disconnected, - - #[error("provided mix fetch url wasn't a string")] - NotStringMixFetchUrl, - - #[error("request {request_id} has been aborted")] - AbortedRequest { request_id: RequestId }, - - #[error("provided mix fetch url was malformed: {0}")] - MalformedMixFetchUrl(#[from] url::ParseError), - - // the maximum value is u32::MAX which equals to over 49days, which is MORE than enough - #[error("attempted to set request timeout to {timeout_ms}ms")] - InvalidTimeoutValue { timeout_ms: u128 }, - - #[error("network requester has rejected our request: {network_requester_message}")] - ConnectionError { network_requester_message: String }, - - #[error("failed to reconstruct the response: {source}")] - MalformedData { - #[from] - source: OrderedMessageError, - }, - - #[error("received multiple messages about the remote socket being closed for request {request}. The first was on seq {first} and the other on {other}")] - DuplicateSocketClosure { - request: RequestId, - first: u64, - other: u64, - }, -} - -// I dislike this so much - there must be a better way. -impl From for MixFetchError { - fn from(value: ClientCoreError) -> Self { - MixFetchError::CoreError { - source: WasmCoreError::BaseClientError { source: value }, - } - } -} - -impl From for MixFetchError { - fn from(value: ConnectionError) -> Self { - MixFetchError::ConnectionError { - network_requester_message: value.network_requester_error, - } - } -} - -wasm_error!(MixFetchError); diff --git a/wasm/mix-fetch/src/fetch.rs b/wasm/mix-fetch/src/fetch.rs deleted file mode 100644 index a03e8f70fb..0000000000 --- a/wasm/mix-fetch/src/fetch.rs +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -#![allow(unknown_lints)] -// clippy::empty_docs is not on stable as of 1.77 - -// due to the code generated by Tsify -#![allow(clippy::empty_docs)] - -use crate::client::MixFetchClient; -use crate::config::{MixFetchConfig, MixFetchConfigOpts, MixFetchDebugOverride}; -use crate::error::MixFetchError; -use crate::helpers::get_network_requester; -use js_sys::Promise; -use nym_wasm_client_core::config::r#override::DebugWasmOverride; -use nym_wasm_utils::console_log; -use nym_wasm_utils::error::PromisableResultError; -use serde::{Deserialize, Serialize}; -use std::sync::OnceLock; -use tsify::Tsify; -use wasm_bindgen::prelude::wasm_bindgen; -use wasm_bindgen::JsValue; -use wasm_bindgen_futures::future_to_promise; - -pub type RequestId = u64; - -pub(super) static MIX_FETCH: OnceLock = OnceLock::new(); - -#[derive(Tsify, Debug, Clone, Serialize, Deserialize)] -#[tsify(into_wasm_abi, from_wasm_abi)] -#[serde(rename_all = "camelCase")] -pub struct MixFetchOpts { - // ideally we'd have used the `IdentityKey` type alias, but that'd be extremely annoying to get working in TS - #[serde(flatten)] - pub(crate) base: MixFetchOptsSimple, - - #[tsify(optional)] - pub(crate) client_id: Option, - - #[tsify(optional)] - pub(crate) nym_api_url: Option, - - // currently not used, but will be required once we have coconut - #[tsify(optional)] - pub(crate) nyxd_url: Option, - - #[tsify(optional)] - pub(crate) client_override: Option, - - #[tsify(optional)] - pub(crate) mix_fetch_override: Option, -} - -#[derive(Tsify, Debug, Clone, Serialize, Deserialize)] -#[tsify(into_wasm_abi, from_wasm_abi)] -#[serde(rename_all = "camelCase")] -pub struct MixFetchOptsSimple { - // ideally we'd have used the `IdentityKey` type alias, but that'd be extremely annoying to get working in TS - #[tsify(optional)] - pub(crate) preferred_gateway: Option, - - #[tsify(optional)] - pub(crate) preferred_network_requester: Option, - - #[tsify(optional)] - pub(crate) force_tls: Option, - - #[tsify(optional)] - pub(crate) storage_passphrase: Option, -} - -impl<'a> From<&'a MixFetchOpts> for MixFetchConfigOpts { - fn from(value: &'a MixFetchOpts) -> Self { - MixFetchConfigOpts { - id: value.client_id.as_ref().map(|v| v.to_owned()), - nym_api: value.nym_api_url.as_ref().map(|v| v.to_owned()), - nyxd: value.nyxd_url.as_ref().map(|v| v.to_owned()), - debug: value.client_override.as_ref().map(|v| v.clone().into()), - } - } -} - -// TODO: in the future make the network requester address optional once there exists some API for obtaining NR addresses -#[wasm_bindgen(js_name = setupMixFetch)] -pub fn setup_mix_fetch(opts: MixFetchOpts) -> Promise { - if MIX_FETCH.get().is_some() { - return MixFetchError::AlreadyInitialised.into_rejected_promise(); - } - - // if nym api was overridden, it means we're not using mainnet and we don't have harbourmaster url - // for anything that's not mainnet - if opts.nym_api_url.is_some() && opts.base.preferred_network_requester.is_none() { - return MixFetchError::NoNetworkRequesters.into_rejected_promise(); - } - - future_to_promise(async move { - let network_requester_address = get_network_requester( - opts.nym_api_url.clone(), - opts.base.preferred_network_requester.clone(), - ) - .await - .map_promise_err()?; - - console_log!("going to use {network_requester_address} network requester"); - - let mut config = MixFetchConfig::new(network_requester_address, Some((&opts).into())) - .map_promise_err()?; - if let Some(dbg) = opts.client_override { - config.override_debug(dbg); - } - - if let Some(dbg) = opts.mix_fetch_override { - config.override_mix_fetch_debug(dbg) - } - - setup_mix_fetch_async(config, opts.base) - .await - .map(|_| JsValue::undefined()) - .map_promise_err() - }) -} - -#[wasm_bindgen(js_name = setupMixFetchWithConfig)] -pub fn setup_mix_fetch_with_config(config: MixFetchConfig, opts: MixFetchOptsSimple) -> Promise { - if MIX_FETCH.get().is_some() { - return MixFetchError::AlreadyInitialised.into_rejected_promise(); - } - - future_to_promise(async move { - setup_mix_fetch_async(config, opts) - .await - .map(|_| JsValue::undefined()) - .map_promise_err() - }) -} - -#[wasm_bindgen(js_name = disconnectMixFetch)] -pub async fn disconnect_mix_fetch() -> Promise { - future_to_promise(async move { - disconnect_mix_fetch_async() - .await - .map(|_| JsValue::undefined()) - .map_promise_err() - }) -} - -async fn disconnect_mix_fetch_async() -> Result<(), MixFetchError> { - mix_fetch_client()?.disconnect().await -} - -pub(super) fn set_mix_fetch_client(mix_fetch_client: MixFetchClient) -> Result<(), MixFetchError> { - MIX_FETCH - .set(mix_fetch_client) - .map_err(|_| MixFetchError::AlreadyInitialised) -} - -pub(super) fn mix_fetch_client() -> Result<&'static MixFetchClient, MixFetchError> { - let mix_fetch = MIX_FETCH.get().ok_or(MixFetchError::Uninitialised)?; - if !mix_fetch.active() { - return Err(MixFetchError::Disconnected); - } - - Ok(mix_fetch) -} - -async fn setup_mix_fetch_async( - config: MixFetchConfig, - opts: MixFetchOptsSimple, -) -> Result<(), MixFetchError> { - let preferred_gateway = opts.preferred_gateway; - let storage_passphrase = opts.storage_passphrase; - let force_tls = opts.force_tls.unwrap_or_default(); - let client = - MixFetchClient::new_async(config, force_tls, preferred_gateway, storage_passphrase).await?; - set_mix_fetch_client(client)?; - Ok(()) -} diff --git a/wasm/mix-fetch/src/go_bridge.rs b/wasm/mix-fetch/src/go_bridge.rs deleted file mode 100644 index 086001c0a5..0000000000 --- a/wasm/mix-fetch/src/go_bridge.rs +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use crate::error::MixFetchError; -use crate::mix_fetch_client; -use js_sys::Promise; -use nym_wasm_utils::error::{simple_rejected_promise, PromisableResult}; -use wasm_bindgen::prelude::*; -use wasm_bindgen_futures::future_to_promise; - -/// Called by go runtime whenever local connection produces any data that has to be sent to the remote. -// -// TODO: currently this requires weird workaround to put it on the global object inside JS... -// need some help from @MS to fix that up. -// this is not expected to be called but a normal user under any circumstances -// (perhaps it should be moved somewhere outside the global object then? -#[wasm_bindgen] -pub fn send_client_data(stringified_request_id: String, data: Vec) -> Promise { - let request_id = match stringified_request_id.parse() { - Ok(id) => id, - Err(err) => { - return simple_rejected_promise(format!("failed to parse received request: {err}")) - } - }; - - future_to_promise(async move { - // this error should be impossible in normal use - // (unless, of course, user is messing around, but then it's their fault for this panic) - let mix_fetch = mix_fetch_client().map_err(JsValue::from)?; - mix_fetch.forward_request_content(request_id, data).await?; - Ok(JsValue::undefined()) - }) -} - -/// Called by go runtime whenever it establishes new connection -/// (whether the initial one or on any redirection attempt). -// -// TODO: currently this requires weird workaround to put it on the global object inside JS... -// need some help from @MS to fix that up. -// this is not expected to be called but a normal user under any circumstances -// (perhaps it should be moved somewhere outside the global object then? -#[wasm_bindgen] -pub fn start_new_mixnet_connection(target: String) -> Promise { - future_to_promise(async move { - // this error should be impossible in normal use - // (unless, of course, user is messing around, but then it's their fault for this panic) - let mix_fetch = mix_fetch_client().map_err(JsValue::from)?; - mix_fetch - .connect_to_mixnet(target) - .await - .map(|request_id| request_id.to_string()) - .into_promise_result() - }) -} - -#[wasm_bindgen] -pub fn mix_fetch_initialised() -> Result { - mix_fetch_client()?; - Ok(true) -} - -/// Called by go runtime whenever it's done with a connection -// -// TODO: currently this requires weird workaround to put it on the global object inside JS... -// need some help from @MS to fix that up. -// this is not expected to be called but a normal user under any circumstances -// (perhaps it should be moved somewhere outside the global object then? -#[wasm_bindgen] -pub fn finish_mixnet_connection(stringified_request_id: String) -> Promise { - let request_id = match stringified_request_id.parse() { - Ok(id) => id, - Err(err) => { - return simple_rejected_promise(format!("failed to parse received request: {err}")) - } - }; - - future_to_promise(async move { - // this error should be impossible in normal use - // (unless, of course, user is messing around, but then it's their fault for this panic) - let mix_fetch = mix_fetch_client().map_err(JsValue::from)?; - mix_fetch.disconnect_from_mixnet(request_id).await?; - Ok(JsValue::undefined()) - }) -} - -// note the namespace (defined in wasm/main.go) -#[wasm_bindgen] -extern "C" { - #[wasm_bindgen(js_namespace = __go_rs_bridge__)] - pub(crate) fn goWasmInjectServerData(raw_connection_id: String, data: Vec); - - #[wasm_bindgen(js_namespace = __go_rs_bridge__)] - pub(crate) fn goWasmCloseRemoteSocket(raw_connection_id: String); - - #[wasm_bindgen(js_namespace = __go_rs_bridge__)] - pub(crate) fn goWasmInjectConnError(raw_connection_id: String, error_msg: String); - - #[wasm_bindgen(js_namespace = __go_rs_bridge__)] - pub(crate) fn goWasmSetMixFetchRequestTimeout(timeout_ms: u32); -} diff --git a/wasm/mix-fetch/src/helpers.rs b/wasm/mix-fetch/src/helpers.rs deleted file mode 100644 index 719ab64559..0000000000 --- a/wasm/mix-fetch/src/helpers.rs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use crate::error::MixFetchError; -use crate::error::MixFetchError::NoNetworkRequesters; -use nym_http_api_client::Client; -use nym_validator_client::nym_api::NymApiClientExt; -use nym_wasm_utils::console_log; -use rand::seq::SliceRandom; -use rand::thread_rng; - -// since this client is temporary (and will be properly integrated into nym-api eventually), -// we're using hardcoded URL for mainnet -const NYM_API_URL: &str = "https://validator.nymtech.net/api/"; - -pub(crate) async fn get_network_requester( - nym_api_url: Option, - preferred: Option, -) -> Result { - if let Some(sp) = preferred { - return Ok(sp); - } - - let client = Client::new( - url::Url::parse(&nym_api_url.unwrap_or(NYM_API_URL.to_string()))?, - None, - ); - #[allow(deprecated)] - let nodes = client.get_all_described_nodes().await?; - let providers: Vec<_> = nodes - .iter() - .filter_map(|node| { - node.description - .network_requester - .clone() - .map(|n| n.address) - }) - .collect(); - console_log!( - "obtained list of {} service providers on the network", - providers.len() - ); - - // this will only return a `None` if the list is empty - let mut rng = thread_rng(); - providers - .choose(&mut rng) - .ok_or(NoNetworkRequesters) - .cloned() -} diff --git a/wasm/mix-fetch/src/lib.rs b/wasm/mix-fetch/src/lib.rs deleted file mode 100644 index 0018748027..0000000000 --- a/wasm/mix-fetch/src/lib.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -#[cfg(target_arch = "wasm32")] -mod active_requests; -#[cfg(target_arch = "wasm32")] -mod client; -#[cfg(target_arch = "wasm32")] -mod config; -#[cfg(target_arch = "wasm32")] -pub mod error; -#[cfg(target_arch = "wasm32")] -mod fetch; -#[cfg(target_arch = "wasm32")] -mod go_bridge; -#[cfg(target_arch = "wasm32")] -mod helpers; -#[cfg(target_arch = "wasm32")] -mod request_writer; -#[cfg(target_arch = "wasm32")] -mod socks_helpers; - -#[cfg(target_arch = "wasm32")] -pub(crate) use fetch::{mix_fetch_client, RequestId}; -#[cfg(target_arch = "wasm32")] -use wasm_bindgen::prelude::*; - -#[wasm_bindgen(start)] -#[cfg(target_arch = "wasm32")] -pub fn main() { - nym_wasm_utils::console_log!("[rust main]: rust module loaded"); - nym_wasm_utils::console_log!( - "mix fetch version used: {}", - nym_bin_common::bin_info_owned!() - ); - nym_wasm_utils::console_log!("[rust main]: setting panic hook"); - nym_wasm_utils::set_panic_hook(); -} diff --git a/wasm/mix-fetch/src/request_writer.rs b/wasm/mix-fetch/src/request_writer.rs deleted file mode 100644 index 12138bb005..0000000000 --- a/wasm/mix-fetch/src/request_writer.rs +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use crate::active_requests::ActiveRequests; -use futures::channel::mpsc; -use futures::StreamExt; -use nym_service_providers_common::interface::ResponseContent; -use nym_socks5_requests::{Socks5ProviderResponse, Socks5ResponseContent}; -use nym_wasm_client_core::client::base_client::ClientOutput; -use nym_wasm_client_core::client::received_buffer::{ - ReceivedBufferMessage, ReceivedBufferRequestSender, ReconstructedMessagesReceiver, -}; -use nym_wasm_client_core::ReconstructedMessage; -use nym_wasm_utils::console_error; -use wasm_bindgen_futures::spawn_local; - -pub(crate) struct RequestWriter { - reconstructed_receiver: ReconstructedMessagesReceiver, - - // we need to keep that channel alive as not to trigger the shutdown - _received_buffer_request_sender: ReceivedBufferRequestSender, - - requests: ActiveRequests, -} - -impl RequestWriter { - pub(crate) fn new(client_output: ClientOutput, requests: ActiveRequests) -> Self { - // register our output - let (reconstructed_sender, reconstructed_receiver) = mpsc::unbounded(); - - // tell the buffer to start sending stuff to us - client_output - .received_buffer_request_sender - .unbounded_send(ReceivedBufferMessage::ReceiverAnnounce( - reconstructed_sender, - )) - .expect("the buffer request failed!"); - - RequestWriter { - reconstructed_receiver, - _received_buffer_request_sender: client_output.received_buffer_request_sender, - requests, - } - } - - async fn handle_reconstructed(&mut self, reconstructed_message: ReconstructedMessage) { - let (msg, tag) = reconstructed_message.into_inner(); - - if tag.is_some() { - console_error!( - "received a response with an anonymous sender tag - this is highly unexpected!" - ); - } - - match Socks5ProviderResponse::try_from_bytes(&msg) { - Err(err) => { - console_error!("failed to deserialize provider response. it was most likely not a response to our fetch: {err}") - } - Ok(provider_response) => match provider_response.content { - ResponseContent::Control(control) => { - console_error!("received a provider control response even though we didnt send any requests! - {control:#?}") - } - ResponseContent::ProviderData(data_response) => match data_response.content { - Socks5ResponseContent::ConnectionError(err) => { - self.requests.reject(err.connection_id, err.into()).await; - } - Socks5ResponseContent::Query(query) => { - console_error!("received a provider query response even though we didn't send any queries! - {query:#?}") - } - Socks5ResponseContent::NetworkData { content } => { - self.requests.try_send_data_to_go(content).await; - } - }, - }, - } - } - - pub(crate) fn start(mut self) { - spawn_local(async move { - while let Some(reconstructed) = self.reconstructed_receiver.next().await { - for reconstructed_msg in reconstructed { - self.handle_reconstructed(reconstructed_msg).await - } - } - console_error!("we stopped receiving reconstructed messages!") - }) - } -} diff --git a/wasm/mix-fetch/src/socks_helpers.rs b/wasm/mix-fetch/src/socks_helpers.rs deleted file mode 100644 index 8dffb0ad2e..0000000000 --- a/wasm/mix-fetch/src/socks_helpers.rs +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2023 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use nym_service_providers_common::interface::ProviderInterfaceVersion; -use nym_socks5_requests::{ - ConnectionId, RemoteAddress, SocketData, Socks5ProtocolVersion, Socks5ProviderRequest, -}; -use nym_wasm_client_core::Recipient; - -pub(crate) const PROVIDER_INTERFACE_VERSION: ProviderInterfaceVersion = - ProviderInterfaceVersion::new_current(); -pub(crate) const SOCKS5_PROTOCOL_VERSION: Socks5ProtocolVersion = - Socks5ProtocolVersion::new_current(); - -// for now explicitly attach return address, we can worry about surbs later -pub(crate) fn socks5_connect_request( - conn_id: ConnectionId, - remote_addr: RemoteAddress, - return_address: Recipient, -) -> Vec { - // Create SOCKS connect request - let request_content = nym_socks5_requests::request::Socks5Request::new_connect( - SOCKS5_PROTOCOL_VERSION, - conn_id, - remote_addr, - Some(return_address), - ); - - // and wrap it in provider request - Socks5ProviderRequest::new_provider_data(PROVIDER_INTERFACE_VERSION, request_content) - .into_bytes() -} - -pub(crate) fn socks5_data_request( - conn_id: ConnectionId, - local_closed: bool, - message_sequence: u64, - data: Vec, -) -> Vec { - // Create SOCKS send request - let request_content = nym_socks5_requests::request::Socks5Request::new_send( - SOCKS5_PROTOCOL_VERSION, - SocketData::new(message_sequence, conn_id, local_closed, data), - ); - - // and wrap it in provider request - Socks5ProviderRequest::new_provider_data(PROVIDER_INTERFACE_VERSION, request_content) - .into_bytes() -} diff --git a/wasm/smolmix/Cargo.toml b/wasm/smolmix/Cargo.toml index 1c2897ee01..f7919bd107 100644 --- a/wasm/smolmix/Cargo.toml +++ b/wasm/smolmix/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "smolmix-wasm" -version = "1.21.0" +version = "0.1.0" authors = { workspace = true } edition = { workspace = true } license = { workspace = true } @@ -25,10 +25,10 @@ wasm-bindgen-futures = { workspace = true } wasmtimer = { workspace = true } # DNS wire-format types (always present; internal DNS resolution is needed -# even when only `fetch` or `socket` is enabled, for hostname → IP). +# even when only `fetch` or `websocket` is enabled, for hostname → IP). hickory-proto = { workspace = true, features = ["std"] } -# TLS stack: gated by the `_tls` private feature (pulled by `fetch` or `socket`). +# TLS stack: gated by the `_tls` private feature (pulled by `fetch` or `websocket`). # rustls-rustcrypto is the only viable provider on wasm32-unknown-unknown: # ring + aws-lc-rs both fail to compile (no OS entropy / no C toolchain in browser). rustls = { workspace = true, features = ["std"], optional = true } @@ -38,12 +38,12 @@ webpki-roots = { workspace = true, optional = true } rustls-rustcrypto = { workspace = true, optional = true } # HTTP/1.1 client (tokio-free; workspace declares default-features = false). -# Gated by `fetch`: `mixSocket` does its upgrade handshake via async-tungstenite directly. +# Gated by `fetch`: `mixWebSocket` does its upgrade handshake via async-tungstenite directly. hyper = { workspace = true, features = ["client", "http1"], optional = true } http-body-util = { workspace = true, optional = true } http = { workspace = true, optional = true } -# WebSocket (RFC 6455 client over futures::io streams). Gated by `socket`. +# WebSocket (RFC 6455 client over futures::io streams). Gated by `websocket`. async-tungstenite = { workspace = true, features = ["handshake"], optional = true } # WASM utils (panic hook, console_log) @@ -84,27 +84,27 @@ workspace = true features = ["wasm_js"] [features] -# Default: build all three JS entry points (mixFetch, mixSocket, mixResolve). +# Default: build all three JS entry points (mixFetch, mixWebSocket, mixDNS). # TS SDK packages that only need a subset can disable defaults and opt in: # smolmix-wasm = { ..., default-features = false, features = ["fetch"] } -default = ["dns", "fetch", "socket"] +default = ["dns", "fetch", "websocket"] -# Expose the JS `mixResolve(hostname)` entry point. -# Note: the internal DNS resolver (used by fetch/socket for hostname lookups) -# is always compiled — only the standalone JS export is gated here. +# Expose the JS `mixDNS(hostname)` entry point. +# Note: the internal DNS resolver (used by fetch/websocket for hostname lookups) +# is always compiled; only the standalone JS export is gated here. dns = [] # Expose the JS `mixFetch(url, init)` HTTP client. Pulls in TLS + the hyper-based # HTTP/1.1 stack. fetch = ["_tls", "_http"] -# Expose the JS `mixSocket(url, protocols, onEvent)` WebSocket client. +# Expose the JS `mixWebSocket(url, protocols, onEvent)` WebSocket client. # Pulls TLS (for `wss://`) + async-tungstenite. Does not pull `_http` because # tungstenite handles the WebSocket upgrade handshake itself. -socket = ["_tls", "dep:async-tungstenite"] +websocket = ["_tls", "dep:async-tungstenite"] # Internal feature aggregating the rustls-based TLS stack. Shared between -# `fetch` (HTTPS) and `socket` (WSS). +# `fetch` (HTTPS) and `websocket` (WSS). _tls = [ "dep:rustls", "dep:rustls-pki-types", diff --git a/wasm/smolmix/Makefile b/wasm/smolmix/Makefile index 0bd2416456..217fab16a8 100644 --- a/wasm/smolmix/Makefile +++ b/wasm/smolmix/Makefile @@ -5,19 +5,31 @@ TASKSET ?= taskset -c 0-11 .PHONY: build build-rust build-debug build-release-opt check-fmt dev dev-build \ - internal-dev-install test test\:smoke test\:suite + internal-dev-install mark-pkg-private test test\:smoke test\:suite -build: build-rust +build: build-rust mark-pkg-private build-rust: $(TASKSET) wasm-pack build --scope nymproject --target web build-debug: $(TASKSET) wasm-pack build --debug --scope nymproject --target web --features debug + $(MAKE) mark-pkg-private build-release-opt: $(TASKSET) wasm-pack build --scope nymproject --target web $(TASKSET) wasm-opt -Oz -o pkg/smolmix_wasm_bg.wasm pkg/smolmix_wasm_bg.wasm + $(MAKE) mark-pkg-private + +# smolmix-wasm is workspace-internal: its bytes are base64-inlined into +# @nymproject/mix-tunnel at build time, so it must never reach npm. wasm-pack +# does not write `"private": true` itself, so we patch the generated package.json +# in place. Guard against re-application so the target stays idempotent. +mark-pkg-private: + @if [ -f pkg/package.json ]; then \ + jq '. + {private: true}' pkg/package.json > pkg/package.json.tmp \ + && mv pkg/package.json.tmp pkg/package.json; \ + fi check-fmt: cargo fmt --check diff --git a/wasm/smolmix/README.md b/wasm/smolmix/README.md index 5c060822a1..270597f29f 100644 --- a/wasm/smolmix/README.md +++ b/wasm/smolmix/README.md @@ -11,8 +11,37 @@ Three WASM exports that mirror the browser's native networking surface: | Browser API | smolmix export | Description | |-------------|---------------|-------------| | `fetch()` | `mixFetch(url, init)` | HTTP/HTTPS request-response | -| `new WebSocket()` | `mixSocket(url, protocols, onEvent)` | WebSocket (WS/WSS) | -| (no direct browser equivalent) | `mixResolve(hostname)` | DNS-only hostname lookup over UDP/IPR (no TCP/TLS) | +| `new WebSocket()` | `mixWebSocket(url, protocols, onEvent)` | WebSocket (WS/WSS) | +| (no direct browser equivalent) | `mixDNS(hostname)` | DNS-only hostname lookup over UDP/IPR (no TCP/TLS) | + +## Browser-shape header shim + +`mixFetch` injects a small set of default request headers when the caller +hasn't set them. Many CDNs (cloudflare's bot management) and host policies +(wikimedia's User-Agent policy) reject requests that lack browser-canonical +headers. + +| Header | Default | Why | +|--------|---------|-----| +| `User-Agent` | `Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36` | A recent Chrome-on-Linux string. Pinned so it doesn't drift between builds. | +| `Accept` | `text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8` | Matches what Chrome sends for a navigation request. | +| `Accept-Language` | `en-US,en;q=0.9` | Single locale. Set this explicitly per-request if your app is localised. | +| `Accept-Encoding` | `identity` | hyper 1.x in our wasm build has no decompressor; advertising `gzip, deflate, br` would surface compressed bytes to the caller un-decoded. Body-correctness over wire-shape. | + +Canonical strings: `DEFAULT_USER_AGENT`, `DEFAULT_ACCEPT`, +`DEFAULT_ACCEPT_LANGUAGE`, `DEFAULT_ACCEPT_ENCODING` in `src/http.rs`. + +The shim does NOT attempt full browser impersonation. TLS fingerprint (JA3), +HTTP/2 (we're HTTP/1.1 only), and header ordering are all distinguishable +from a real Chrome request. + +To override a default for a single request: + +```ts +await mixFetch('https://example.com', { + headers: { 'User-Agent': 'my-app/1.0' }, +}); +``` ## Arch @@ -60,7 +89,7 @@ Three WASM exports that mirror the browser's native networking surface: - Bridge (`bridge.rs`) - shuttles packets between the device and the mixnet - IPR (`ipr.rs`) - IP Packet Router protocol layer - WasmTcpStream / WasmUdpSocket / PooledConn (`stream.rs`) - `futures::io::AsyncRead + AsyncWrite` adapters over smoltcp sockets -- WASM exports (`lib.rs`, `mixfetch.rs`, `mixsocket.rs`) - the surface JS calls into +- WASM exports (`lib.rs`, `mixfetch.rs`, `mixwebsocket.rs`, `mixdns.rs`) - the surface JS calls into ### Tuning @@ -87,11 +116,11 @@ points. Default builds enable all three; downstream TS SDK packages can opt into a subset to drop the corresponding implementation + native deps from the wasm binary. -| Feature | JS export | Pulls | -|---------|-----------------|----------------------------------------------------| -| `dns` | `mixResolve` | (nothing extra; DNS resolver is always compiled) | -| `fetch` | `mixFetch` | rustls TLS stack + hyper HTTP/1.1 client | -| `socket`| `mixSocket` | rustls TLS stack + async-tungstenite | +| Feature | JS export | Pulls | +|------------|-----------------|----------------------------------------------------| +| `dns` | `mixDNS` | (nothing extra; DNS resolver is always compiled) | +| `fetch` | `mixFetch` | rustls TLS stack + hyper HTTP/1.1 client | +| `websocket`| `mixWebSocket` | rustls TLS stack + async-tungstenite | Build a `dns`-only client: @@ -99,13 +128,13 @@ Build a `dns`-only client: cargo build --target wasm32-unknown-unknown --no-default-features --features dns ``` -Build a `fetch`-only client (no WebSocket, no `mixResolve` JS export): +Build a `fetch`-only client (no WebSocket, no `mixDNS` JS export): ```sh cargo build --target wasm32-unknown-unknown --no-default-features --features fetch ``` -`fetch` and `socket` share the TLS stack (rustls + rustls-rustcrypto + webpki-roots); +`fetch` and `websocket` share the TLS stack (rustls + rustls-rustcrypto + webpki-roots); enabling both is roughly the same wasm size as either alone plus the hyper + async-tungstenite specifics. @@ -145,8 +174,8 @@ make dev # build-debug then start internal-dev webpack | +---------+---------+--------------+ v v v - mixFetch mixSocket mixResolve - (mixfetch.rs) (mixsocket.rs) (mixdns.rs) + mixFetch mixWebSocket mixDNS + (mixfetch.rs) (mixwebsocket.rs) (mixdns.rs) | | | v v v fetch::fetch fetch::new_ dns::resolve @@ -188,5 +217,5 @@ make dev # build-debug then start internal-dev webpack ``` Everything else (TLS handshakes, HTTP/1.1 requests, WebSocket frames in -`mixSocket`) is content travelling inside that single gateway WSS as +`mixWebSocket`) is content travelling inside that single gateway WSS as Sphinx-packed bytes. diff --git a/wasm/smolmix/internal-dev/index.js b/wasm/smolmix/internal-dev/index.js index 97474b34dd..bada40db97 100644 --- a/wasm/smolmix/internal-dev/index.js +++ b/wasm/smolmix/internal-dev/index.js @@ -237,7 +237,7 @@ document.getElementById("btn-dns-tunnel").addEventListener("click", async () => logTo("dns-log", `tunnel resolve ${hostname}`); const t0 = performance.now(); try { - const ip = await api.mixResolve(hostname); + const ip = await api.mixDNS(hostname); const ms = (performance.now() - t0).toFixed(0); logTo("dns-log", `tunnel ${hostname} => ${ip} (${ms} ms)`, "green"); } catch (e) { diff --git a/wasm/smolmix/internal-dev/worker.js b/wasm/smolmix/internal-dev/worker.js index e3f5a673aa..3c24b3601c 100644 --- a/wasm/smolmix/internal-dev/worker.js +++ b/wasm/smolmix/internal-dev/worker.js @@ -14,9 +14,9 @@ import initWasm, { setupMixTunnel as wasmSetup, mixFetch as wasmFetch, - mixResolve as wasmResolve, + mixDNS as wasmDNS, disconnectMixTunnel as wasmDisconnect, - mixSocket as wasmMixSocket, + mixWebSocket as wasmMixWebSocket, wsSend as wasmWsSend, wsClose as wasmWsClose, setDebugLogging as wasmSetDebugLogging, @@ -43,11 +43,11 @@ const api = { return await wasmFetch(url, init || {}); }, - async mixResolve(hostname) { + async mixDNS(hostname) { if (!wasmReady) { throw new Error("WASM not initialised; call setupMixTunnel first"); } - return await wasmResolve(hostname); + return await wasmDNS(hostname); }, async disconnectMixTunnel() { @@ -99,7 +99,7 @@ self.addEventListener("message", async (event) => { }; try { - await wasmMixSocket(msg.url, msg.protocols, onEvent); + await wasmMixWebSocket(msg.url, msg.protocols, onEvent); } catch (e) { console.error("[ws] connect failed:", e); self.postMessage({ diff --git a/wasm/smolmix/src/error.rs b/wasm/smolmix/src/error.rs index 045535832e..5a6aeb335f 100644 --- a/wasm/smolmix/src/error.rs +++ b/wasm/smolmix/src/error.rs @@ -22,7 +22,7 @@ pub enum FetchError { #[error("HTTP error: {0}")] Http(String), - #[cfg(feature = "socket")] + #[cfg(feature = "websocket")] #[error("WebSocket error: {0}")] WebSocket(#[from] async_tungstenite::tungstenite::Error), diff --git a/wasm/smolmix/src/fetch.rs b/wasm/smolmix/src/fetch.rs index 58771f5c32..ddbef3f2c1 100644 --- a/wasm/smolmix/src/fetch.rs +++ b/wasm/smolmix/src/fetch.rs @@ -1,7 +1,7 @@ // Copyright 2026 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -//! TCP/TLS connection construction shared by `mixFetch` and `mixSocket`, +//! TCP/TLS connection construction shared by `mixFetch` and `mixWebSocket`, //! plus (under the `fetch` feature) the HTTP orchestration + JS `RequestInit` shim. use std::net::SocketAddr; @@ -93,26 +93,50 @@ pub async fn fetch( result }; - // Retry pooled connections once on first-write error; fresh-conn - // errors propagate. We only retry idempotent methods because hyper - // can fail mid-body-write, and we have no reliable way to tell - // whether the server already received and acted on the request. A - // silent retry of POST/PUT/PATCH/DELETE could duplicate side-effects - // (double payment, repeat resource creation, etc.). + // Retry idempotent methods once on a fresh connection in two situations: + // 1. The connection came from the pool and failed for any reason + // (typical: server already half-closed the keep-alive socket). + // 2. A fresh connection received the response headers but hyper saw + // the body truncate before `Content-Length` / chunked terminator. + // Cloudflare-fronted hosts do this transiently under load — the + // next attempt usually completes cleanly. + // + // We only retry idempotent methods because hyper can fail mid-body-write + // and we have no reliable way to tell whether the server already received + // and acted on the request. A silent retry of POST/PUT/PATCH/DELETE could + // duplicate side-effects (double payment, repeat resource creation, etc.). let http_result = http::request(conn, &method, &url, &opts.headers, body.as_deref()).await; + let should_retry_fresh = |err: &FetchError| -> bool { + if !is_idempotent(&method) { + return false; + } + if from_pool { + // Any pooled failure is retryable. + return true; + } + // Fresh-conn case: only retry on hyper's incomplete-message, + // i.e. genuine mid-body truncation, not handshake / TLS / IO errors. + matches!(err, FetchError::Hyper(e) if e.is_incomplete_message()) + }; + let (response, reusable, conn) = match http_result { Ok(result) => result, - Err(stale_err) if from_pool && is_idempotent(&method) => { + Err(first_err) if should_retry_fresh(&first_err) => { + let reason = if from_pool { + "pooled connection failed" + } else { + "body truncated mid-stream" + }; crate::util::debug_log!( - "[fetch] pooled connection failed ({stale_err}), retrying with fresh connection" + "[fetch] {reason} ({first_err}), retrying with fresh connection" ); let fresh = new_connection(tunnel, &host, port, is_https).await?; match http::request(fresh, &method, &url, &opts.headers, body.as_deref()).await { Ok(result) => result, Err(e) => { crate::util::debug_error!( - "[fetch] fresh connection also failed: {e} (pooled failed with: {stale_err})" + "[fetch] fresh connection also failed: {e} (first attempt: {first_err})" ); return Err(e); } diff --git a/wasm/smolmix/src/http.rs b/wasm/smolmix/src/http.rs index f3476b2b0c..9aebb02e56 100644 --- a/wasm/smolmix/src/http.rs +++ b/wasm/smolmix/src/http.rs @@ -15,6 +15,31 @@ use hyper::client::conn::http1; use crate::error::FetchError; +// Browser-shape header shim defaults. +// +// `mixFetch` ships these as fallbacks when the caller didn't set the header +// itself; caller-supplied values always win. Many CDNs (cloudflare bot +// management) and host policies (wikimedia's UA policy) reject requests +// that lack browser-canonical headers. See README "Browser-shape header +// shim" for the rationale, limits, and fingerprinting caveats. +// +// `DEFAULT_USER_AGENT` is pinned to a recent Chrome-on-Linux UA. Bump it +// when the Chrome major in the wild drifts far enough that this string +// starts looking suspicious (heuristic: more than 6 majors stale). +pub(crate) const DEFAULT_USER_AGENT: &str = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 \ + (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"; + +pub(crate) const DEFAULT_ACCEPT: &str = "text/html,application/xhtml+xml,application/xml;q=0.9,\ + image/avif,image/webp,*/*;q=0.8"; + +pub(crate) const DEFAULT_ACCEPT_LANGUAGE: &str = "en-US,en;q=0.9"; + +// `identity` rather than `gzip, deflate, br` because hyper 1.x in our wasm +// build doesn't carry a decompressor; advertising compression would surface +// gzip bytes to the caller un-decoded. Trade slightly less browser-shape +// for body-correctness. +pub(crate) const DEFAULT_ACCEPT_ENCODING: &str = "identity"; + /// Parsed HTTP response. pub struct HttpResponse { pub status: u16, @@ -108,11 +133,26 @@ where .header("Host", host) .header("Connection", "keep-alive"); + // Track which browser-shape headers the caller has already set so the + // shim below doesn't clobber explicit intent. let mut has_content_length = false; + let mut has_user_agent = false; + let mut has_accept = false; + let mut has_accept_language = false; + let mut has_accept_encoding = false; + for (name, value) in headers { builder = builder.header(name.as_str(), value.as_str()); if name.eq_ignore_ascii_case("content-length") { has_content_length = true; + } else if name.eq_ignore_ascii_case("user-agent") { + has_user_agent = true; + } else if name.eq_ignore_ascii_case("accept") { + has_accept = true; + } else if name.eq_ignore_ascii_case("accept-language") { + has_accept_language = true; + } else if name.eq_ignore_ascii_case("accept-encoding") { + has_accept_encoding = true; } } @@ -120,10 +160,36 @@ where builder = builder.header("Content-Length", body_bytes.len().to_string()); } + // Browser-shape header shim. Definitions + rationale at the top of + // this file. + if !has_user_agent { + builder = builder.header("User-Agent", DEFAULT_USER_AGENT); + } + if !has_accept { + builder = builder.header("Accept", DEFAULT_ACCEPT); + } + if !has_accept_language { + builder = builder.header("Accept-Language", DEFAULT_ACCEPT_LANGUAGE); + } + if !has_accept_encoding { + builder = builder.header("Accept-Encoding", DEFAULT_ACCEPT_ENCODING); + } + let req = builder .body(Full::new(body_bytes)) .map_err(|e| FetchError::Http(format!("failed to build request: {e}")))?; + // Dump request headers (debug-only) so we can verify the shim and any + // caller-supplied headers actually made it onto the wire. Matches the + // response-header dump below for symmetry. + for (k, v) in req.headers().iter() { + crate::util::debug_log!( + "[http] -> {}: {}", + k.as_str(), + v.to_str().unwrap_or("") + ); + } + // Perform HTTP/1 handshake; hyper takes ownership of the IO let (mut sender, conn) = http1::handshake(HyperIoAdapter(stream)) .await diff --git a/wasm/smolmix/src/lib.rs b/wasm/smolmix/src/lib.rs index 53ca9d4af6..f78701b0c6 100644 --- a/wasm/smolmix/src/lib.rs +++ b/wasm/smolmix/src/lib.rs @@ -6,14 +6,14 @@ //! Exposes three APIs that mirror the browser's native networking surface: //! //! - **`mixFetch(url, init)`**: drop-in `fetch()` replacement (HTTP/HTTPS) -//! - **`mixSocket(url, protocols, onEvent)`**: drop-in `WebSocket` replacement (WS/WSS) -//! - **`mixResolve(hostname)`**: DNS-only hostname lookup (UDP / IPR path, no TCP/TLS) +//! - **`mixWebSocket(url, protocols, onEvent)`**: drop-in `WebSocket` replacement (WS/WSS) +//! - **`mixDNS(hostname)`**: DNS-only hostname lookup (UDP / IPR path, no TCP/TLS) //! //! All three share the same mixnet tunnel (DNS, TCP, TLS), initialised once //! via `setupMixTunnel(opts)` and torn down with `disconnectMixTunnel()`. // All modules gated on wasm32 so `cargo check` on the host triple sees an empty crate. -// Cargo features (`dns` / `fetch` / `socket`) further gate the entry-point modules +// Cargo features (`dns` / `fetch` / `websocket`) further gate the entry-point modules // and their heavy deps; see [features] in Cargo.toml. #[cfg(target_arch = "wasm32")] mod bridge; @@ -23,7 +23,7 @@ mod device; mod dns; #[cfg(target_arch = "wasm32")] mod error; -#[cfg(all(target_arch = "wasm32", any(feature = "fetch", feature = "socket")))] +#[cfg(all(target_arch = "wasm32", any(feature = "fetch", feature = "websocket")))] mod fetch; #[cfg(all(target_arch = "wasm32", feature = "fetch"))] mod http; @@ -33,15 +33,15 @@ mod ipr; mod mixdns; #[cfg(all(target_arch = "wasm32", feature = "fetch"))] mod mixfetch; -#[cfg(all(target_arch = "wasm32", feature = "socket"))] -mod mixsocket; +#[cfg(all(target_arch = "wasm32", feature = "websocket"))] +mod mixwebsocket; #[cfg(target_arch = "wasm32")] mod reactor; #[cfg(target_arch = "wasm32")] mod state; #[cfg(target_arch = "wasm32")] mod stream; -#[cfg(all(target_arch = "wasm32", any(feature = "fetch", feature = "socket")))] +#[cfg(all(target_arch = "wasm32", any(feature = "fetch", feature = "websocket")))] mod tls; #[cfg(target_arch = "wasm32")] mod tunnel; diff --git a/wasm/smolmix/src/mixdns.rs b/wasm/smolmix/src/mixdns.rs index c1a122afaf..d80c621237 100644 --- a/wasm/smolmix/src/mixdns.rs +++ b/wasm/smolmix/src/mixdns.rs @@ -1,7 +1,7 @@ // Copyright 2026 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -//! `mixResolve`: hostname lookup over the mixnet tunnel (UDP / IPR path only). +//! `mixDNS`: hostname lookup over the mixnet tunnel (UDP / IPR path only). use wasm_bindgen::prelude::*; use wasm_bindgen_futures::future_to_promise; @@ -11,8 +11,8 @@ use crate::dns; /// Resolve a hostname to an IP address through the mixnet tunnel. /// /// Returns the IP as a string (e.g. `"93.184.216.34"`). -#[wasm_bindgen(js_name = "mixResolve")] -pub fn mix_resolve(hostname: String) -> js_sys::Promise { +#[wasm_bindgen(js_name = "mixDNS")] +pub fn mix_dns(hostname: String) -> js_sys::Promise { future_to_promise(async move { let tunnel = crate::ready_tunnel()?; let ip = dns::resolve(tunnel, &hostname).await?; diff --git a/wasm/smolmix/src/mixsocket.rs b/wasm/smolmix/src/mixwebsocket.rs similarity index 98% rename from wasm/smolmix/src/mixsocket.rs rename to wasm/smolmix/src/mixwebsocket.rs index d4be74926a..1ac749d69b 100644 --- a/wasm/smolmix/src/mixsocket.rs +++ b/wasm/smolmix/src/mixwebsocket.rs @@ -32,8 +32,12 @@ enum WsCommand { /// Open a WebSocket through the tunnel; resolves to a u32 handle. /// Events fire on `on_event(handleId, type, data)` with type one of /// `"open" | "text" | "binary" | "close" | "error"`. -#[wasm_bindgen(js_name = "mixSocket")] -pub fn mix_socket(url: String, protocols: JsValue, on_event: js_sys::Function) -> js_sys::Promise { +#[wasm_bindgen(js_name = "mixWebSocket")] +pub fn mix_websocket( + url: String, + protocols: JsValue, + on_event: js_sys::Function, +) -> js_sys::Promise { future_to_promise(async move { let result: Result = async { use async_tungstenite::tungstenite::client::IntoClientRequest; diff --git a/wasm/smolmix/src/stream.rs b/wasm/smolmix/src/stream.rs index 9affc25997..de975c1cef 100644 --- a/wasm/smolmix/src/stream.rs +++ b/wasm/smolmix/src/stream.rs @@ -23,7 +23,7 @@ use crate::reactor::{ReactorNotify, SmoltcpStack}; pub(crate) const EPHEMERAL_PORT_START: u16 = 49152; /// A pooled connection (TLS or plain TCP). Delegates `AsyncRead + AsyncWrite`. -/// The `Tls` variant compiles in only when `fetch` or `socket` features are +/// The `Tls` variant compiles in only when `fetch` or `websocket` features are /// enabled, since plaintext-only builds (the `dns`-only TS SDK package) don't /// need a TLS stack at all. /// @@ -33,7 +33,7 @@ pub(crate) const EPHEMERAL_PORT_START: u16 = 49152; /// arm into a `Box`-deref dance for no real benefit at typical usage. #[allow(clippy::large_enum_variant)] pub(crate) enum PooledConn { - #[cfg(any(feature = "fetch", feature = "socket"))] + #[cfg(any(feature = "fetch", feature = "websocket"))] Tls(crate::tls::MaybeCloseNotify>), Plain(WasmTcpStream), } @@ -177,7 +177,7 @@ impl AsyncRead for PooledConn { buf: &mut [u8], ) -> Poll> { match self.get_mut() { - #[cfg(any(feature = "fetch", feature = "socket"))] + #[cfg(any(feature = "fetch", feature = "websocket"))] PooledConn::Tls(s) => Pin::new(s).poll_read(cx, buf), PooledConn::Plain(s) => Pin::new(s).poll_read(cx, buf), } @@ -191,7 +191,7 @@ impl AsyncWrite for PooledConn { buf: &[u8], ) -> Poll> { match self.get_mut() { - #[cfg(any(feature = "fetch", feature = "socket"))] + #[cfg(any(feature = "fetch", feature = "websocket"))] PooledConn::Tls(s) => Pin::new(s).poll_write(cx, buf), PooledConn::Plain(s) => Pin::new(s).poll_write(cx, buf), } @@ -199,7 +199,7 @@ impl AsyncWrite for PooledConn { fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match self.get_mut() { - #[cfg(any(feature = "fetch", feature = "socket"))] + #[cfg(any(feature = "fetch", feature = "websocket"))] PooledConn::Tls(s) => Pin::new(s).poll_flush(cx), PooledConn::Plain(s) => Pin::new(s).poll_flush(cx), } @@ -207,7 +207,7 @@ impl AsyncWrite for PooledConn { fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { match self.get_mut() { - #[cfg(any(feature = "fetch", feature = "socket"))] + #[cfg(any(feature = "fetch", feature = "websocket"))] PooledConn::Tls(s) => Pin::new(s).poll_close(cx), PooledConn::Plain(s) => Pin::new(s).poll_close(cx), } From cff370a9431977a539917cc882fb0d4346cab49b Mon Sep 17 00:00:00 2001 From: mfahampshire Date: Fri, 5 Jun 2026 14:00:04 +0000 Subject: [PATCH 88/94] Update scripts + CI for dryrun + version checking (#6858) * Update scripts + CI for dryrun + version checking * Update publish.sh w trap * Coderabbit --- .github/workflows/publish-sdk-npm.yml | 15 + pnpm-lock.yaml | 8426 +++++++++++++++++++++- sdk/typescript/scripts/build-prod-sdk.sh | 9 +- sdk/typescript/scripts/publish.sh | 117 +- sdk/typescript/scripts/release.sh | 2 +- 5 files changed, 8375 insertions(+), 194 deletions(-) diff --git a/.github/workflows/publish-sdk-npm.yml b/.github/workflows/publish-sdk-npm.yml index c73e70255f..c7ec188e97 100644 --- a/.github/workflows/publish-sdk-npm.yml +++ b/.github/workflows/publish-sdk-npm.yml @@ -1,6 +1,19 @@ name: publish-sdk-npm on: workflow_dispatch: + inputs: + dry_run: + description: "Rehearse the publish (pnpm publish --dry-run, no tarballs uploaded). Untick to publish for real." + type: boolean + default: true + dist_tag: + description: "Tag mode. 'auto' picks per package: new packages and same-major releases -> latest; a breaking major (e.g. mix-fetch v2 over v1) -> next, promote later with `npm dist-tag add`. 'next'/'latest' force that tag on all four." + type: choice + options: + - auto + - next + - latest + default: auto jobs: publish: @@ -42,4 +55,6 @@ jobs: - name: Publish to NPM env: NODE_AUTH_TOKEN: ${{ secrets.NODE_AUTH_TOKEN }} + DRY_RUN: ${{ inputs.dry_run && '1' || '0' }} + NPM_DIST_TAG: ${{ inputs.dist_tag }} run: ./sdk/typescript/scripts/publish.sh diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3ac0fd419f..fbe2c4da3b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -210,6 +210,9 @@ catalogs: '@types/uuid': specifier: ^8.3.4 version: 8.3.4 + '@types/ws': + specifier: ^8.18.1 + version: 8.18.1 '@types/zxcvbn': specifier: ^4.4.1 version: 4.4.5 @@ -360,6 +363,9 @@ catalogs: fork-ts-checker-webpack-plugin: specifier: ^7.2.1 version: 7.3.0 + glob: + specifier: ^10.5.0 + version: 10.5.0 hex-rgb: specifier: ^4.3.0 version: 4.3.0 @@ -507,6 +513,9 @@ catalogs: tsconfig-paths-webpack-plugin: specifier: ^3.5.2 version: 3.5.2 + tslib: + specifier: ^2.8.1 + version: 2.8.1 tweetnacl: specifier: ^1.0.3 version: 1.0.3 @@ -563,7 +572,7 @@ importers: version: 5.1.2 lerna: specifier: ^7.3.0 - version: 7.4.2(@types/node@22.19.19)(encoding@0.1.13) + version: 7.4.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(@types/node@22.19.19)(encoding@0.1.13) node-gyp: specifier: ^9.3.1 version: 9.4.1 @@ -574,6 +583,18 @@ importers: specifier: 3.3.3 version: 3.3.3 + dist/node/wasm/client: {} + + dist/ts/sdk/sdk/cjs: {} + + dist/ts/sdk/sdk/cjs-full-fat: {} + + dist/ts/sdk/sdk/esm: {} + + dist/ts/sdk/sdk/esm-full-fat: {} + + dist/wasm/client: {} + explorer-v2: dependencies: '@chain-registry/types': @@ -1243,7 +1264,7 @@ importers: version: 4.1.1(file-loader@6.2.0(webpack@5.106.2))(webpack@5.106.2) webpack: specifier: 'catalog:' - version: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + version: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0) webpack-cli: specifier: 'catalog:' version: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.106.2) @@ -1257,6 +1278,1002 @@ importers: specifier: 'catalog:' version: 5.10.0 + sdk/typescript/codegen/contract-clients: + devDependencies: + '@cosmwasm/ts-codegen': + specifier: ^1.13.3 + version: 1.14.1(@chain-registry/v2-types@0.53.146) + nodemon: + specifier: 3.0.1 + version: 3.0.1 + npm-run-all: + specifier: 'catalog:' + version: 4.1.5 + reload: + specifier: ^3.2.1 + version: 3.4.3 + typedoc: + specifier: ^0.24.8 + version: 0.24.8(typescript@4.9.5) + typescript: + specifier: ^4.6.2 + version: 4.9.5 + + sdk/typescript/codegen/contract-clients/internal-dev: + dependencies: + '@nymproject/contract-clients': + specifier: workspace:* + version: link:.. + + sdk/typescript/examples/chat-app/parcel: + dependencies: + '@nymproject/sdk': + specifier: '>=1.4.1-rc1 || ^1' + version: 1.4.1 + devDependencies: + '@types/jest': + specifier: ^27.0.1 + version: 27.5.2 + '@types/node': + specifier: ^16.7.13 + version: 16.18.126 + '@typescript-eslint/eslint-plugin': + specifier: 'catalog:' + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: 'catalog:' + version: 5.62.0(eslint@8.57.1)(typescript@4.9.5) + eslint: + specifier: ^8.10.0 + version: 8.57.1 + eslint-config-airbnb: + specifier: 'catalog:' + version: 19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1))(eslint-plugin-react-hooks@5.2.0(eslint@8.57.1))(eslint-plugin-react@7.37.5(eslint@8.57.1))(eslint@8.57.1) + eslint-config-airbnb-typescript: + specifier: 'catalog:' + version: 16.2.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1) + eslint-config-prettier: + specifier: 'catalog:' + version: 8.10.2(eslint@8.57.1) + eslint-import-resolver-root-import: + specifier: 'catalog:' + version: 1.0.4(babel-plugin-root-import@6.6.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)) + eslint-plugin-import: + specifier: 'catalog:' + version: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) + eslint-plugin-jest: + specifier: 'catalog:' + version: 26.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@27.5.1)(typescript@4.9.5) + eslint-plugin-jsx-a11y: + specifier: 'catalog:' + version: 6.10.2(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 'catalog:' + version: 4.2.5(eslint-config-prettier@8.10.2(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8) + jest: + specifier: 'catalog:' + version: 27.5.1 + mini-css-extract-plugin: + specifier: 'catalog:' + version: 2.10.2(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))) + npm-run-all: + specifier: 'catalog:' + version: 4.1.5 + prettier: + specifier: 'catalog:' + version: 2.8.8 + ts-jest: + specifier: 'catalog:' + version: 27.1.5(@babel/core@7.29.0)(@types/jest@27.5.2)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) + typescript: + specifier: ^4.6.2 + version: 4.9.5 + + sdk/typescript/examples/chat-app/plain-html: + dependencies: + '@nymproject/sdk': + specifier: '>=1.4.1-rc1 || ^1' + version: 1.4.1 + devDependencies: + '@babel/core': + specifier: 'catalog:' + version: 7.29.0 + '@babel/plugin-transform-async-to-generator': + specifier: 'catalog:' + version: 7.28.6(@babel/core@7.29.0) + '@babel/preset-env': + specifier: 'catalog:' + version: 7.29.5(@babel/core@7.29.0) + '@babel/preset-typescript': + specifier: 'catalog:' + version: 7.28.5(@babel/core@7.29.0) + '@types/jest': + specifier: ^27.0.1 + version: 27.5.2 + '@types/node': + specifier: ^16.7.13 + version: 16.18.126 + '@typescript-eslint/eslint-plugin': + specifier: 'catalog:' + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: 'catalog:' + version: 5.62.0(eslint@8.57.1)(typescript@4.9.5) + babel-loader: + specifier: 'catalog:' + version: 8.4.1(@babel/core@7.29.0)(webpack@5.106.2) + babel-plugin-root-import: + specifier: ^5.1.0 + version: 5.1.0 + clean-webpack-plugin: + specifier: 'catalog:' + version: 4.0.0(webpack@5.106.2) + css-loader: + specifier: 'catalog:' + version: 6.11.0(webpack@5.106.2) + css-minimizer-webpack-plugin: + specifier: ^3.0.2 + version: 3.4.1(webpack@5.106.2) + dotenv-webpack: + specifier: 'catalog:' + version: 7.1.1(webpack@5.106.2) + eslint: + specifier: ^8.10.0 + version: 8.57.1 + eslint-config-airbnb: + specifier: 'catalog:' + version: 19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1))(eslint-plugin-react-hooks@5.2.0(eslint@8.57.1))(eslint-plugin-react@7.37.5(eslint@8.57.1))(eslint@8.57.1) + eslint-config-airbnb-typescript: + specifier: 'catalog:' + version: 16.2.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1) + eslint-config-prettier: + specifier: 'catalog:' + version: 8.10.2(eslint@8.57.1) + eslint-import-resolver-root-import: + specifier: 'catalog:' + version: 1.0.4(babel-plugin-root-import@5.1.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)) + eslint-plugin-import: + specifier: 'catalog:' + version: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) + eslint-plugin-jest: + specifier: 'catalog:' + version: 26.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@27.5.1)(typescript@4.9.5) + eslint-plugin-jsx-a11y: + specifier: 'catalog:' + version: 6.10.2(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 'catalog:' + version: 4.2.5(eslint-config-prettier@8.10.2(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8) + file-loader: + specifier: 'catalog:' + version: 6.2.0(webpack@5.106.2) + fork-ts-checker-webpack-plugin: + specifier: 'catalog:' + version: 7.3.0(typescript@4.9.5)(webpack@5.106.2) + html-webpack-plugin: + specifier: 'catalog:' + version: 5.6.7(webpack@5.106.2) + jest: + specifier: 'catalog:' + version: 27.5.1 + mini-css-extract-plugin: + specifier: 'catalog:' + version: 2.10.2(webpack@5.106.2) + npm-run-all: + specifier: 'catalog:' + version: 4.1.5 + prettier: + specifier: 'catalog:' + version: 2.8.8 + style-loader: + specifier: 'catalog:' + version: 3.3.4(webpack@5.106.2) + thread-loader: + specifier: ^3.0.4 + version: 3.0.4(webpack@5.106.2) + ts-jest: + specifier: 'catalog:' + version: 27.1.5(@babel/core@7.29.0)(@types/jest@27.5.2)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) + ts-loader: + specifier: 'catalog:' + version: 9.5.7(typescript@4.9.5)(webpack@5.106.2) + tsconfig-paths-webpack-plugin: + specifier: 'catalog:' + version: 3.5.2 + typescript: + specifier: ^4.6.2 + version: 4.9.5 + url-loader: + specifier: 'catalog:' + version: 4.1.1(file-loader@6.2.0(webpack@5.106.2))(webpack@5.106.2) + webpack: + specifier: 'catalog:' + version: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(webpack-cli@4.10.0) + webpack-cli: + specifier: 'catalog:' + version: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.106.2) + webpack-dev-server: + specifier: 'catalog:' + version: 4.15.2(webpack-cli@4.10.0)(webpack@5.106.2) + webpack-merge: + specifier: 'catalog:' + version: 5.10.0 + + sdk/typescript/examples/chat-app/react-webpack-with-theme-example: + dependencies: + '@mui/icons-material': + specifier: 'catalog:' + version: 5.18.0(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@mui/lab': + specifier: ^5.0.0-alpha.72 + version: 5.0.0-alpha.170(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mui/material': + specifier: ^5.0.1 + version: 5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mui/styles': + specifier: ^5.0.1 + version: 5.18.0(@types/react@19.2.14)(react@19.2.6) + '@nymproject/sdk': + specifier: '>=1.4.1-rc1 || ^1' + version: 1.4.1 + react: + specifier: 'catalog:' + version: 19.2.6 + react-dom: + specifier: 'catalog:' + version: 19.2.6(react@19.2.6) + react-dropzone: + specifier: ^14.2.3 + version: 14.4.1(react@19.2.6) + react-mui-dropzone: + specifier: ^4.0.6 + version: 4.0.7(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@mui/icons-material@5.18.0(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mui/styles@5.18.0(@types/react@19.2.14)(react@19.2.6))(prop-types@15.8.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + use-clipboard-copy: + specifier: ^0.2.0 + version: 0.2.0(react@19.2.6) + devDependencies: + '@babel/core': + specifier: 'catalog:' + version: 7.29.0 + '@babel/plugin-transform-async-to-generator': + specifier: 'catalog:' + version: 7.28.6(@babel/core@7.29.0) + '@babel/preset-env': + specifier: 'catalog:' + version: 7.29.5(@babel/core@7.29.0) + '@babel/preset-react': + specifier: 'catalog:' + version: 7.28.5(@babel/core@7.29.0) + '@babel/preset-typescript': + specifier: 'catalog:' + version: 7.28.5(@babel/core@7.29.0) + '@pmmmwh/react-refresh-webpack-plugin': + specifier: ^0.5.4 + version: 0.5.17(@types/webpack@4.41.40)(react-refresh@0.16.0)(type-fest@4.41.0)(webpack-dev-server@4.15.2)(webpack-hot-middleware@2.26.1)(webpack@5.106.2) + '@svgr/webpack': + specifier: 'catalog:' + version: 6.5.1 + '@testing-library/jest-dom': + specifier: ^5.14.1 + version: 5.17.0 + '@testing-library/react': + specifier: ^12.0.0 + version: 12.1.5(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/jest': + specifier: ^27.0.1 + version: 27.5.2 + '@types/node': + specifier: ^16.7.13 + version: 16.18.126 + '@types/react': + specifier: 'catalog:' + version: 19.2.14 + '@types/react-dom': + specifier: 'catalog:' + version: 19.2.3(@types/react@19.2.14) + '@typescript-eslint/eslint-plugin': + specifier: 'catalog:' + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: 'catalog:' + version: 5.62.0(eslint@8.57.1)(typescript@4.9.5) + babel-loader: + specifier: 'catalog:' + version: 8.4.1(@babel/core@7.29.0)(webpack@5.106.2) + babel-plugin-root-import: + specifier: ^5.1.0 + version: 5.1.0 + clean-webpack-plugin: + specifier: 'catalog:' + version: 4.0.0(webpack@5.106.2) + css-loader: + specifier: 'catalog:' + version: 6.11.0(webpack@5.106.2) + css-minimizer-webpack-plugin: + specifier: ^3.0.2 + version: 3.4.1(webpack@5.106.2) + dotenv-webpack: + specifier: 'catalog:' + version: 7.1.1(webpack@5.106.2) + eslint: + specifier: ^8.10.0 + version: 8.57.1 + eslint-config-airbnb: + specifier: 'catalog:' + version: 19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.1))(eslint-plugin-react@7.37.5(eslint@8.57.1))(eslint@8.57.1) + eslint-config-airbnb-typescript: + specifier: 'catalog:' + version: 16.2.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1) + eslint-config-prettier: + specifier: 'catalog:' + version: 8.10.2(eslint@8.57.1) + eslint-import-resolver-root-import: + specifier: 'catalog:' + version: 1.0.4(babel-plugin-root-import@5.1.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)) + eslint-plugin-import: + specifier: 'catalog:' + version: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) + eslint-plugin-jest: + specifier: 'catalog:' + version: 26.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@27.5.1)(typescript@4.9.5) + eslint-plugin-jsx-a11y: + specifier: 'catalog:' + version: 6.10.2(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 'catalog:' + version: 4.2.5(eslint-config-prettier@8.10.2(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8) + eslint-plugin-react: + specifier: 'catalog:' + version: 7.37.5(eslint@8.57.1) + eslint-plugin-react-hooks: + specifier: 'catalog:' + version: 4.6.2(eslint@8.57.1) + favicons: + specifier: 'catalog:' + version: 7.2.0 + favicons-webpack-plugin: + specifier: 'catalog:' + version: 5.0.2(favicons@7.2.0)(webpack@5.106.2) + file-loader: + specifier: 'catalog:' + version: 6.2.0(webpack@5.106.2) + fork-ts-checker-webpack-plugin: + specifier: 'catalog:' + version: 7.3.0(typescript@4.9.5)(webpack@5.106.2) + html-webpack-plugin: + specifier: 'catalog:' + version: 5.6.7(webpack@5.106.2) + jest: + specifier: 'catalog:' + version: 27.5.1 + mini-css-extract-plugin: + specifier: 'catalog:' + version: 2.10.2(webpack@5.106.2) + npm-run-all: + specifier: 'catalog:' + version: 4.1.5 + prettier: + specifier: 'catalog:' + version: 2.8.8 + react-refresh-typescript: + specifier: ^2.0.3 + version: 2.0.12(react-refresh@0.16.0)(typescript@4.9.5) + style-loader: + specifier: 'catalog:' + version: 3.3.4(webpack@5.106.2) + thread-loader: + specifier: ^3.0.4 + version: 3.0.4(webpack@5.106.2) + ts-jest: + specifier: 'catalog:' + version: 27.1.5(@babel/core@7.29.0)(@types/jest@27.5.2)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) + ts-loader: + specifier: 'catalog:' + version: 9.5.7(typescript@4.9.5)(webpack@5.106.2) + tsconfig-paths-webpack-plugin: + specifier: 'catalog:' + version: 3.5.2 + typescript: + specifier: ^4.6.2 + version: 4.9.5 + url-loader: + specifier: 'catalog:' + version: 4.1.1(file-loader@6.2.0(webpack@5.106.2))(webpack@5.106.2) + webpack: + specifier: 'catalog:' + version: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(webpack-cli@4.10.0) + webpack-cli: + specifier: 'catalog:' + version: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.106.2) + webpack-dev-server: + specifier: 'catalog:' + version: 4.15.2(webpack-cli@4.10.0)(webpack@5.106.2) + webpack-favicons: + specifier: 'catalog:' + version: 1.5.43 + webpack-merge: + specifier: 'catalog:' + version: 5.10.0 + + sdk/typescript/examples/mix-dns/browser: + dependencies: + '@nymproject/mix-dns': + specifier: workspace:* + version: link:../../../packages/mix-dns + parcel: + specifier: ^2.9.3 + version: 2.16.4(@swc/helpers@0.5.21) + + sdk/typescript/examples/mix-fetch/browser: + dependencies: + '@nymproject/mix-fetch': + specifier: workspace:* + version: link:../../../packages/mix-fetch + parcel: + specifier: ^2.9.3 + version: 2.16.4(@swc/helpers@0.5.21) + + sdk/typescript/examples/mix-websocket/browser: + dependencies: + '@nymproject/mix-websocket': + specifier: workspace:* + version: link:../../../packages/mix-websocket + parcel: + specifier: ^2.9.3 + version: 2.16.4(@swc/helpers@0.5.21) + + sdk/typescript/examples/react/mui-theme: + dependencies: + '@mui/icons-material': + specifier: 'catalog:' + version: 5.18.0(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@mui/lab': + specifier: ^5.0.0-alpha.72 + version: 5.0.0-alpha.170(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mui/material': + specifier: ^5.0.1 + version: 5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mui/styles': + specifier: ^5.0.1 + version: 5.18.0(@types/react@19.2.14)(react@19.2.6) + '@nymproject/mui-theme': + specifier: workspace:* + version: link:../../../packages/mui-theme + '@nymproject/react': + specifier: workspace:* + version: link:../../../packages/react-components + react: + specifier: 'catalog:' + version: 19.2.6 + react-dom: + specifier: 'catalog:' + version: 19.2.6(react@19.2.6) + devDependencies: + '@babel/core': + specifier: 'catalog:' + version: 7.29.0 + '@babel/plugin-transform-async-to-generator': + specifier: 'catalog:' + version: 7.28.6(@babel/core@7.29.0) + '@babel/preset-env': + specifier: 'catalog:' + version: 7.29.5(@babel/core@7.29.0) + '@babel/preset-react': + specifier: 'catalog:' + version: 7.28.5(@babel/core@7.29.0) + '@babel/preset-typescript': + specifier: 'catalog:' + version: 7.28.5(@babel/core@7.29.0) + '@nymproject/eslint-config-react-typescript': + specifier: workspace:* + version: link:../../../../../ts-packages/eslint-config-react-typescript + '@nymproject/webpack': + specifier: workspace:* + version: link:../../../../../ts-packages/webpack + '@pmmmwh/react-refresh-webpack-plugin': + specifier: ^0.5.4 + version: 0.5.17(@types/webpack@4.41.40)(react-refresh@0.16.0)(type-fest@4.41.0)(webpack-dev-server@4.15.2)(webpack-hot-middleware@2.26.1)(webpack@5.106.2) + '@svgr/webpack': + specifier: 'catalog:' + version: 6.5.1 + '@testing-library/jest-dom': + specifier: ^5.14.1 + version: 5.17.0 + '@testing-library/react': + specifier: ^12.0.0 + version: 12.1.5(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/jest': + specifier: ^27.0.1 + version: 27.5.2 + '@types/node': + specifier: ^16.7.13 + version: 16.18.126 + '@types/react': + specifier: 'catalog:' + version: 19.2.14 + '@typescript-eslint/eslint-plugin': + specifier: 'catalog:' + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: 'catalog:' + version: 5.62.0(eslint@8.57.1)(typescript@4.9.5) + babel-loader: + specifier: 'catalog:' + version: 8.4.1(@babel/core@7.29.0)(webpack@5.106.2) + babel-plugin-root-import: + specifier: ^5.1.0 + version: 5.1.0 + clean-webpack-plugin: + specifier: 'catalog:' + version: 4.0.0(webpack@5.106.2) + css-loader: + specifier: 'catalog:' + version: 6.11.0(webpack@5.106.2) + css-minimizer-webpack-plugin: + specifier: ^3.0.2 + version: 3.4.1(webpack@5.106.2) + dotenv-webpack: + specifier: 'catalog:' + version: 7.1.1(webpack@5.106.2) + eslint: + specifier: ^8.10.0 + version: 8.57.1 + eslint-config-airbnb: + specifier: 'catalog:' + version: 19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.1))(eslint-plugin-react@7.37.5(eslint@8.57.1))(eslint@8.57.1) + eslint-config-airbnb-typescript: + specifier: 'catalog:' + version: 16.2.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1) + eslint-config-prettier: + specifier: 'catalog:' + version: 8.10.2(eslint@8.57.1) + eslint-import-resolver-root-import: + specifier: 'catalog:' + version: 1.0.4(babel-plugin-root-import@5.1.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)) + eslint-plugin-import: + specifier: 'catalog:' + version: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) + eslint-plugin-jest: + specifier: 'catalog:' + version: 26.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@27.5.1)(typescript@4.9.5) + eslint-plugin-jsx-a11y: + specifier: 'catalog:' + version: 6.10.2(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 'catalog:' + version: 4.2.5(eslint-config-prettier@8.10.2(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8) + eslint-plugin-react: + specifier: 'catalog:' + version: 7.37.5(eslint@8.57.1) + eslint-plugin-react-hooks: + specifier: 'catalog:' + version: 4.6.2(eslint@8.57.1) + favicons: + specifier: 'catalog:' + version: 7.2.0 + favicons-webpack-plugin: + specifier: 'catalog:' + version: 5.0.2(favicons@7.2.0)(webpack@5.106.2) + file-loader: + specifier: 'catalog:' + version: 6.2.0(webpack@5.106.2) + fork-ts-checker-webpack-plugin: + specifier: 'catalog:' + version: 7.3.0(typescript@4.9.5)(webpack@5.106.2) + html-webpack-plugin: + specifier: 'catalog:' + version: 5.6.7(webpack@5.106.2) + jest: + specifier: 'catalog:' + version: 27.5.1 + mini-css-extract-plugin: + specifier: 'catalog:' + version: 2.10.2(webpack@5.106.2) + prettier: + specifier: 'catalog:' + version: 2.8.8 + react-refresh-typescript: + specifier: ^2.0.3 + version: 2.0.12(react-refresh@0.16.0)(typescript@4.9.5) + style-loader: + specifier: 'catalog:' + version: 3.3.4(webpack@5.106.2) + thread-loader: + specifier: ^3.0.4 + version: 3.0.4(webpack@5.106.2) + ts-jest: + specifier: 'catalog:' + version: 27.1.5(@babel/core@7.29.0)(@types/jest@27.5.2)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) + ts-loader: + specifier: 'catalog:' + version: 9.5.7(typescript@4.9.5)(webpack@5.106.2) + tsconfig-paths-webpack-plugin: + specifier: 'catalog:' + version: 3.5.2 + typescript: + specifier: ^4.6.2 + version: 4.9.5 + url-loader: + specifier: 'catalog:' + version: 4.1.1(file-loader@6.2.0(webpack@5.106.2))(webpack@5.106.2) + webpack: + specifier: 'catalog:' + version: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(webpack-cli@4.10.0) + webpack-cli: + specifier: 'catalog:' + version: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.106.2) + webpack-dev-server: + specifier: 'catalog:' + version: 4.15.2(webpack-cli@4.10.0)(webpack@5.106.2) + webpack-favicons: + specifier: 'catalog:' + version: 1.5.43 + webpack-merge: + specifier: 'catalog:' + version: 5.10.0 + + sdk/typescript/examples/react/sdk-react: + dependencies: + '@nymproject/sdk': + specifier: file:../../../packages/sdk + version: link:../../../packages/sdk + '@nymproject/sdk-react': + specifier: file:../../../packages/sdk-react + version: link:../../../packages/sdk-react + devDependencies: + '@types/jest': + specifier: ^27.0.1 + version: 27.5.2 + '@types/node': + specifier: ^16.7.13 + version: 16.18.126 + '@typescript-eslint/eslint-plugin': + specifier: 'catalog:' + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: 'catalog:' + version: 5.62.0(eslint@8.57.1)(typescript@4.9.5) + eslint: + specifier: ^8.10.0 + version: 8.57.1 + eslint-config-airbnb: + specifier: 'catalog:' + version: 19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1))(eslint-plugin-react-hooks@5.2.0(eslint@8.57.1))(eslint-plugin-react@7.37.5(eslint@8.57.1))(eslint@8.57.1) + eslint-config-airbnb-typescript: + specifier: 'catalog:' + version: 16.2.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1) + eslint-config-prettier: + specifier: 'catalog:' + version: 8.10.2(eslint@8.57.1) + eslint-import-resolver-root-import: + specifier: 'catalog:' + version: 1.0.4(babel-plugin-root-import@6.6.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)) + eslint-plugin-import: + specifier: 'catalog:' + version: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) + eslint-plugin-jest: + specifier: 'catalog:' + version: 26.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@27.5.1)(typescript@4.9.5) + eslint-plugin-jsx-a11y: + specifier: 'catalog:' + version: 6.10.2(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 'catalog:' + version: 4.2.5(eslint-config-prettier@8.10.2(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8) + jest: + specifier: 'catalog:' + version: 27.5.1 + mini-css-extract-plugin: + specifier: 'catalog:' + version: 2.10.2(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))) + npm-run-all: + specifier: 'catalog:' + version: 4.1.5 + prettier: + specifier: 'catalog:' + version: 2.8.8 + ts-jest: + specifier: 'catalog:' + version: 27.1.5(@babel/core@7.29.0)(@types/jest@27.5.2)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) + typescript: + specifier: ^4.6.2 + version: 4.9.5 + + sdk/typescript/packages/internal-dev: + dependencies: + '@nymproject/mix-dns': + specifier: workspace:* + version: link:../mix-dns + '@nymproject/mix-fetch': + specifier: workspace:* + version: link:../mix-fetch + '@nymproject/mix-tunnel': + specifier: workspace:* + version: link:../mix-tunnel + '@nymproject/mix-websocket': + specifier: workspace:* + version: link:../mix-websocket + devDependencies: + '@babel/core': + specifier: 'catalog:' + version: 7.29.0 + '@babel/plugin-transform-async-to-generator': + specifier: 'catalog:' + version: 7.28.6(@babel/core@7.29.0) + '@babel/preset-env': + specifier: 'catalog:' + version: 7.29.5(@babel/core@7.29.0) + '@babel/preset-typescript': + specifier: 'catalog:' + version: 7.28.5(@babel/core@7.29.0) + '@types/jest': + specifier: ^27.0.1 + version: 27.5.2 + '@types/node': + specifier: ^16.7.13 + version: 16.18.126 + '@typescript-eslint/eslint-plugin': + specifier: 'catalog:' + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: 'catalog:' + version: 5.62.0(eslint@9.39.4)(typescript@4.9.5) + babel-loader: + specifier: ^9.1.3 + version: 9.2.1(@babel/core@7.29.0)(webpack@5.106.2) + babel-plugin-root-import: + specifier: ^6.6.0 + version: 6.6.0 + clean-webpack-plugin: + specifier: 'catalog:' + version: 4.0.0(webpack@5.106.2) + copy-webpack-plugin: + specifier: ^11.0.0 + version: 11.0.0(webpack@5.106.2) + css-loader: + specifier: 'catalog:' + version: 6.11.0(webpack@5.106.2) + css-minimizer-webpack-plugin: + specifier: ^5.0.1 + version: 5.0.1(webpack@5.106.2) + dotenv-webpack: + specifier: ^8.0.1 + version: 8.1.1(webpack@5.106.2) + eslint: + specifier: 'catalog:' + version: 9.39.4 + eslint-config-airbnb: + specifier: 'catalog:' + version: 19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4))(eslint-plugin-react-hooks@5.2.0(eslint@9.39.4))(eslint-plugin-react@7.37.5(eslint@9.39.4))(eslint@9.39.4) + eslint-config-airbnb-typescript: + specifier: 'catalog:' + version: 16.2.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint@9.39.4) + eslint-config-prettier: + specifier: 'catalog:' + version: 8.10.2(eslint@9.39.4) + eslint-import-resolver-root-import: + specifier: 'catalog:' + version: 1.0.4(babel-plugin-root-import@6.6.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)) + eslint-plugin-import: + specifier: 'catalog:' + version: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4) + eslint-plugin-jest: + specifier: 'catalog:' + version: 26.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(jest@27.5.1)(typescript@4.9.5) + eslint-plugin-jsx-a11y: + specifier: 'catalog:' + version: 6.10.2(eslint@9.39.4) + eslint-plugin-prettier: + specifier: 'catalog:' + version: 4.2.5(eslint-config-prettier@8.10.2(eslint@9.39.4))(eslint@9.39.4)(prettier@2.8.8) + file-loader: + specifier: 'catalog:' + version: 6.2.0(webpack@5.106.2) + fork-ts-checker-webpack-plugin: + specifier: ^8.0.0 + version: 8.0.0(typescript@4.9.5)(webpack@5.106.2) + html-webpack-plugin: + specifier: 'catalog:' + version: 5.6.7(webpack@5.106.2) + jest: + specifier: 'catalog:' + version: 27.5.1 + mini-css-extract-plugin: + specifier: 'catalog:' + version: 2.10.2(webpack@5.106.2) + npm-run-all: + specifier: 'catalog:' + version: 4.1.5 + prettier: + specifier: 'catalog:' + version: 2.8.8 + style-loader: + specifier: 'catalog:' + version: 3.3.4(webpack@5.106.2) + thread-loader: + specifier: ^4.0.2 + version: 4.0.4(webpack@5.106.2) + ts-jest: + specifier: 'catalog:' + version: 27.1.5(@babel/core@7.29.0)(@types/jest@27.5.2)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) + ts-loader: + specifier: 'catalog:' + version: 9.5.7(typescript@4.9.5)(webpack@5.106.2) + tsconfig-paths-webpack-plugin: + specifier: ^4.1.0 + version: 4.2.0 + typescript: + specifier: ^4.6.2 + version: 4.9.5 + url-loader: + specifier: 'catalog:' + version: 4.1.1(file-loader@6.2.0(webpack@5.106.2))(webpack@5.106.2) + webpack: + specifier: 'catalog:' + version: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@5.1.4) + webpack-cli: + specifier: ^5.1.4 + version: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.106.2) + webpack-dev-server: + specifier: 'catalog:' + version: 4.15.2(webpack-cli@5.1.4)(webpack@5.106.2) + webpack-merge: + specifier: 'catalog:' + version: 5.10.0 + + sdk/typescript/packages/internal-dev/parcel: + dependencies: + '@nymproject/mix-dns': + specifier: workspace:* + version: link:../../mix-dns + '@nymproject/mix-fetch': + specifier: workspace:* + version: link:../../mix-fetch + '@nymproject/mix-tunnel': + specifier: workspace:* + version: link:../../mix-tunnel + '@nymproject/mix-websocket': + specifier: workspace:* + version: link:../../mix-websocket + + sdk/typescript/packages/mix-dns: + dependencies: + '@nymproject/mix-tunnel': + specifier: workspace:* + version: link:../mix-tunnel + devDependencies: + '@nymproject/eslint-config-react-typescript': + specifier: workspace:* + version: link:../../../../ts-packages/eslint-config-react-typescript + '@typescript-eslint/eslint-plugin': + specifier: 'catalog:' + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: 'catalog:' + version: 5.62.0(eslint@8.57.1)(typescript@4.9.5) + eslint: + specifier: ^8.10.0 + version: 8.57.1 + rimraf: + specifier: 'catalog:' + version: 3.0.2 + tslib: + specifier: 'catalog:' + version: 2.8.1 + typescript: + specifier: ^4.8.4 + version: 4.9.5 + + sdk/typescript/packages/mix-fetch: + dependencies: + '@nymproject/mix-tunnel': + specifier: workspace:* + version: link:../mix-tunnel + devDependencies: + '@nymproject/eslint-config-react-typescript': + specifier: workspace:* + version: link:../../../../ts-packages/eslint-config-react-typescript + '@typescript-eslint/eslint-plugin': + specifier: 'catalog:' + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: 'catalog:' + version: 5.62.0(eslint@8.57.1)(typescript@4.9.5) + eslint: + specifier: ^8.10.0 + version: 8.57.1 + rimraf: + specifier: 'catalog:' + version: 3.0.2 + tslib: + specifier: 'catalog:' + version: 2.8.1 + typescript: + specifier: ^4.8.4 + version: 4.9.5 + + sdk/typescript/packages/mix-tunnel: + devDependencies: + '@nymproject/eslint-config-react-typescript': + specifier: workspace:* + version: link:../../../../ts-packages/eslint-config-react-typescript + '@nymproject/smolmix-wasm': + specifier: workspace:* + version: link:../../../../wasm/smolmix/pkg + '@rollup/plugin-commonjs': + specifier: ^24.0.1 + version: 24.1.0(rollup@3.30.0) + '@rollup/plugin-node-resolve': + specifier: ^15.0.1 + version: 15.3.1(rollup@3.30.0) + '@rollup/plugin-replace': + specifier: ^5.0.2 + version: 5.0.7(rollup@3.30.0) + '@rollup/plugin-typescript': + specifier: ^10.0.1 + version: 10.0.1(rollup@3.30.0)(tslib@2.8.1)(typescript@4.9.5) + '@rollup/plugin-wasm': + specifier: ^6.1.1 + version: 6.2.2(rollup@3.30.0) + '@typescript-eslint/eslint-plugin': + specifier: 'catalog:' + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: 'catalog:' + version: 5.62.0(eslint@8.57.1)(typescript@4.9.5) + comlink: + specifier: ^4.3.1 + version: 4.4.2 + eslint: + specifier: ^8.10.0 + version: 8.57.1 + rimraf: + specifier: 'catalog:' + version: 3.0.2 + rollup: + specifier: ^3.9.1 + version: 3.30.0 + rollup-plugin-base64: + specifier: ^1.0.1 + version: 1.0.1(rollup@3.30.0) + rollup-plugin-web-worker-loader: + specifier: ^1.6.1 + version: 1.7.0(rollup@3.30.0) + tslib: + specifier: 'catalog:' + version: 2.8.1 + typescript: + specifier: ^4.8.4 + version: 4.9.5 + + sdk/typescript/packages/mix-websocket: + dependencies: + '@nymproject/mix-tunnel': + specifier: workspace:* + version: link:../mix-tunnel + devDependencies: + '@nymproject/eslint-config-react-typescript': + specifier: workspace:* + version: link:../../../../ts-packages/eslint-config-react-typescript + '@typescript-eslint/eslint-plugin': + specifier: 'catalog:' + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: 'catalog:' + version: 5.62.0(eslint@8.57.1)(typescript@4.9.5) + eslint: + specifier: ^8.10.0 + version: 8.57.1 + rimraf: + specifier: 'catalog:' + version: 3.0.2 + tslib: + specifier: 'catalog:' + version: 2.8.1 + typescript: + specifier: ^4.8.4 + version: 4.9.5 + sdk/typescript/packages/mui-theme: dependencies: '@mui/material': @@ -1331,11 +2348,129 @@ importers: version: 3.0.2 ts-jest: specifier: 'catalog:' - version: 27.1.5(@babel/core@7.29.0)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) + version: 27.1.5(@babel/core@7.29.0)(@types/jest@27.5.2)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) typescript: specifier: ^4.6.2 version: 4.9.5 + sdk/typescript/packages/nodejs-client: + dependencies: + '@nymproject/nym-client-wasm-node': + specifier: '>=1.4.1-rc.3 || ^1' + version: 1.4.1 + comlink: + specifier: ^4.3.1 + version: 4.4.2 + fake-indexeddb: + specifier: ^4.0.2 + version: 4.0.2 + rollup-plugin-polyfill: + specifier: ^4.2.0 + version: 4.2.0(rollup@3.30.0) + ws: + specifier: ^8.17.1 + version: 8.20.1 + devDependencies: + '@rollup/plugin-commonjs': + specifier: ^24.0.1 + version: 24.1.0(rollup@3.30.0) + '@rollup/plugin-json': + specifier: ^6.0.0 + version: 6.1.0(rollup@3.30.0) + '@rollup/plugin-node-resolve': + specifier: ^15.0.1 + version: 15.3.1(rollup@3.30.0) + '@rollup/plugin-replace': + specifier: ^5.0.2 + version: 5.0.7(rollup@3.30.0) + '@rollup/plugin-typescript': + specifier: ^10.0.1 + version: 10.0.1(rollup@3.30.0)(tslib@2.8.1)(typescript@4.9.5) + '@rollup/plugin-url': + specifier: ^8.0.1 + version: 8.0.2(rollup@3.30.0) + '@rollup/plugin-wasm': + specifier: ^6.1.1 + version: 6.2.2(rollup@3.30.0) + '@types/node': + specifier: ^16.7.13 + version: 16.18.126 + '@types/ws': + specifier: 'catalog:' + version: 8.18.1 + '@typescript-eslint/eslint-plugin': + specifier: 'catalog:' + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: 'catalog:' + version: 5.62.0(eslint@8.57.1)(typescript@4.9.5) + eslint: + specifier: ^8.10.0 + version: 8.57.1 + eslint-config-airbnb: + specifier: 'catalog:' + version: 19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.1))(eslint-plugin-react@7.37.5(eslint@8.57.1))(eslint@8.57.1) + eslint-config-airbnb-typescript: + specifier: 'catalog:' + version: 16.2.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1) + eslint-config-prettier: + specifier: 'catalog:' + version: 8.10.2(eslint@8.57.1) + eslint-import-resolver-root-import: + specifier: 'catalog:' + version: 1.0.4(babel-plugin-root-import@6.6.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)) + eslint-plugin-import: + specifier: 'catalog:' + version: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) + eslint-plugin-jest: + specifier: 'catalog:' + version: 26.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@29.7.0(@types/node@16.18.126)(babel-plugin-macros@3.1.0))(typescript@4.9.5) + eslint-plugin-jsx-a11y: + specifier: 'catalog:' + version: 6.10.2(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 'catalog:' + version: 4.2.5(eslint-config-prettier@8.10.2(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8) + eslint-plugin-react: + specifier: 'catalog:' + version: 7.37.5(eslint@8.57.1) + eslint-plugin-react-hooks: + specifier: 'catalog:' + version: 4.6.2(eslint@8.57.1) + nodemon: + specifier: 3.0.1 + version: 3.0.1 + reload: + specifier: ^3.2.1 + version: 3.4.3 + rimraf: + specifier: 'catalog:' + version: 3.0.2 + rollup: + specifier: ^3.9.1 + version: 3.30.0 + rollup-plugin-base64: + specifier: ^1.0.1 + version: 1.0.1(rollup@3.30.0) + rollup-plugin-modify: + specifier: ^3.0.0 + version: 3.0.0 + rollup-plugin-web-worker-loader: + specifier: ^1.6.1 + version: 1.7.0(rollup@3.30.0) + ts-loader: + specifier: 'catalog:' + version: 9.5.7(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))) + tslib: + specifier: 'catalog:' + version: 2.8.1 + typedoc: + specifier: ^0.24.8 + version: 0.24.8(typescript@4.9.5) + typescript: + specifier: ^4.8.4 + version: 4.9.5 + sdk/typescript/packages/react-components: dependencies: '@cosmjs/math': @@ -1401,10 +2536,10 @@ importers: version: 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@storybook/addon-docs': specifier: 'catalog:' - version: 6.5.16(@babel/core@7.29.0)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + version: 6.5.16(@babel/core@7.29.0)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) '@storybook/addon-essentials': specifier: 'catalog:' - version: 6.5.16(@babel/core@7.29.0)(@storybook/builder-webpack5@6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + version: 6.5.16(@babel/core@7.29.0)(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) '@storybook/addon-interactions': specifier: 'catalog:' version: 6.5.16(@types/react@19.2.14)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) @@ -1413,13 +2548,13 @@ importers: version: 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@storybook/builder-webpack5': specifier: 'catalog:' - version: 6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + version: 6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) '@storybook/manager-webpack5': specifier: 'catalog:' - version: 6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + version: 6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) '@storybook/react': specifier: 'catalog:' - version: 6.5.16(@babel/core@7.29.0)(@storybook/builder-webpack5@6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@types/webpack@4.41.40)(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(require-from-string@2.0.2)(type-fest@4.41.0)(typescript@4.9.5)(webpack-dev-server@4.15.2(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)))(webpack-hot-middleware@2.26.1) + version: 6.5.16(@babel/core@7.29.0)(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@swc/core@1.15.40(@swc/helpers@0.5.21))(@types/webpack@4.41.40)(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(require-from-string@2.0.2)(type-fest@4.41.0)(typescript@4.9.5)(webpack-dev-server@4.15.2(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)))(webpack-hot-middleware@2.26.1) '@storybook/testing-library': specifier: 'catalog:' version: 0.0.9(storybook@8.6.18(prettier@2.8.8)) @@ -1446,7 +2581,7 @@ importers: version: 5.62.0(eslint@9.39.4)(typescript@4.9.5) babel-loader: specifier: 'catalog:' - version: 8.4.1(@babel/core@7.29.0)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + version: 8.4.1(@babel/core@7.29.0)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) babel-plugin-root-import: specifier: ^5.1.0 version: 5.1.0 @@ -1497,7 +2632,7 @@ importers: version: 3.0.2 ts-jest: specifier: 'catalog:' - version: 27.1.5(@babel/core@7.29.0)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) + version: 27.1.5(@babel/core@7.29.0)(@types/jest@27.5.2)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) tsconfig-paths-webpack-plugin: specifier: 'catalog:' version: 3.5.2 @@ -1505,6 +2640,383 @@ importers: specifier: ^4.6.2 version: 4.9.5 + sdk/typescript/packages/sdk: + dependencies: + '@nymproject/nym-client-wasm': + specifier: '>=1.4.1-rc.3 || ^1' + version: 1.4.1 + comlink: + specifier: ^4.3.1 + version: 4.4.2 + devDependencies: + '@babel/core': + specifier: 'catalog:' + version: 7.29.0 + '@babel/plugin-transform-async-to-generator': + specifier: 'catalog:' + version: 7.28.6(@babel/core@7.29.0) + '@babel/preset-env': + specifier: 'catalog:' + version: 7.29.5(@babel/core@7.29.0) + '@babel/preset-react': + specifier: 'catalog:' + version: 7.28.5(@babel/core@7.29.0) + '@babel/preset-typescript': + specifier: 'catalog:' + version: 7.28.5(@babel/core@7.29.0) + '@nymproject/eslint-config-react-typescript': + specifier: workspace:* + version: link:../../../../ts-packages/eslint-config-react-typescript + '@rollup/plugin-commonjs': + specifier: ^24.0.1 + version: 24.1.0(rollup@3.30.0) + '@rollup/plugin-inject': + specifier: ^5.0.3 + version: 5.0.5(rollup@3.30.0) + '@rollup/plugin-json': + specifier: ^6.0.0 + version: 6.1.0(rollup@3.30.0) + '@rollup/plugin-node-resolve': + specifier: ^15.0.1 + version: 15.3.1(rollup@3.30.0) + '@rollup/plugin-replace': + specifier: ^5.0.2 + version: 5.0.7(rollup@3.30.0) + '@rollup/plugin-terser': + specifier: ^0.2.1 + version: 0.2.1(rollup@3.30.0) + '@rollup/plugin-typescript': + specifier: ^10.0.1 + version: 10.0.1(rollup@3.30.0)(tslib@2.8.1)(typescript@4.9.5) + '@rollup/plugin-url': + specifier: ^8.0.1 + version: 8.0.2(rollup@3.30.0) + '@rollup/plugin-wasm': + specifier: ^6.1.1 + version: 6.2.2(rollup@3.30.0) + '@types/jest': + specifier: ^27.0.1 + version: 27.5.2 + '@types/minimatch': + specifier: 5.1.2 + version: 5.1.2 + '@types/node': + specifier: ^16.7.13 + version: 16.18.126 + '@typescript-eslint/eslint-plugin': + specifier: 'catalog:' + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: 'catalog:' + version: 5.62.0(eslint@8.57.1)(typescript@4.9.5) + eslint: + specifier: ^8.10.0 + version: 8.57.1 + eslint-config-airbnb: + specifier: 'catalog:' + version: 19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.1))(eslint-plugin-react@7.37.5(eslint@8.57.1))(eslint@8.57.1) + eslint-config-airbnb-typescript: + specifier: 'catalog:' + version: 16.2.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1) + eslint-config-prettier: + specifier: 'catalog:' + version: 8.10.2(eslint@8.57.1) + eslint-import-resolver-root-import: + specifier: 'catalog:' + version: 1.0.4(babel-plugin-root-import@6.6.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)) + eslint-plugin-import: + specifier: 'catalog:' + version: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) + eslint-plugin-jest: + specifier: 'catalog:' + version: 26.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@29.7.0(@types/node@16.18.126)(babel-plugin-macros@3.1.0))(typescript@4.9.5) + eslint-plugin-jsx-a11y: + specifier: 'catalog:' + version: 6.10.2(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 'catalog:' + version: 4.2.5(eslint-config-prettier@8.10.2(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8) + eslint-plugin-react: + specifier: 'catalog:' + version: 7.37.5(eslint@8.57.1) + eslint-plugin-react-hooks: + specifier: 'catalog:' + version: 4.6.2(eslint@8.57.1) + glob: + specifier: 'catalog:' + version: 10.5.0 + handlebars: + specifier: ^4.7.8 + version: 4.7.9 + jest: + specifier: ^29.5.0 + version: 29.7.0(@types/node@16.18.126)(babel-plugin-macros@3.1.0) + nodemon: + specifier: 3.0.1 + version: 3.0.1 + reload: + specifier: ^3.2.1 + version: 3.4.3 + rimraf: + specifier: 'catalog:' + version: 3.0.2 + rollup: + specifier: ^3.9.1 + version: 3.30.0 + rollup-plugin-base64: + specifier: ^1.0.1 + version: 1.0.1(rollup@3.30.0) + rollup-plugin-web-worker-loader: + specifier: ^1.6.1 + version: 1.7.0(rollup@3.30.0) + ts-jest: + specifier: ^29.1.0 + version: 29.4.9(@babel/core@7.29.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@16.18.126)(babel-plugin-macros@3.1.0))(typescript@4.9.5) + ts-loader: + specifier: 'catalog:' + version: 9.5.7(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))) + tslib: + specifier: 'catalog:' + version: 2.8.1 + typedoc: + specifier: ^0.24.8 + version: 0.24.8(typescript@4.9.5) + typescript: + specifier: ^4.8.4 + version: 4.9.5 + + sdk/typescript/packages/sdk-react: + dependencies: + '@nymproject/sdk': + specifier: '>=1.4.1-rc.3 || ^1' + version: 1.4.1 + react: + specifier: 'catalog:' + version: 19.2.6 + react-dom: + specifier: 'catalog:' + version: 19.2.6(react@19.2.6) + devDependencies: + '@babel/core': + specifier: 'catalog:' + version: 7.29.0 + '@nymproject/eslint-config-react-typescript': + specifier: workspace:* + version: link:../../../../ts-packages/eslint-config-react-typescript + '@storybook/addon-actions': + specifier: 'catalog:' + version: 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/addon-essentials': + specifier: 'catalog:' + version: 6.5.16(@babel/core@7.29.0)(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + '@storybook/addon-interactions': + specifier: 'catalog:' + version: 6.5.16(@types/react@19.2.14)(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/addon-links': + specifier: 'catalog:' + version: 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/builder-webpack5': + specifier: 'catalog:' + version: 6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/manager-webpack5': + specifier: 'catalog:' + version: 6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/react': + specifier: 'catalog:' + version: 6.5.16(@babel/core@7.29.0)(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@swc/core@1.15.40(@swc/helpers@0.5.21))(@types/webpack@4.41.40)(encoding@0.1.13)(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(require-from-string@2.0.2)(type-fest@4.41.0)(typescript@4.9.5)(webpack-dev-server@4.15.2(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)))(webpack-hot-middleware@2.26.1) + '@storybook/testing-library': + specifier: 'catalog:' + version: 0.0.9(storybook@8.6.18(prettier@2.8.8)) + '@svgr/webpack': + specifier: 'catalog:' + version: 6.5.1 + '@types/flat': + specifier: 'catalog:' + version: 5.0.5 + '@types/react': + specifier: 'catalog:' + version: 19.2.14 + '@types/react-dom': + specifier: 'catalog:' + version: 19.2.3(@types/react@19.2.14) + '@typescript-eslint/eslint-plugin': + specifier: 'catalog:' + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: 'catalog:' + version: 5.62.0(eslint@8.57.1)(typescript@4.9.5) + babel-loader: + specifier: 'catalog:' + version: 8.4.1(@babel/core@7.29.0)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + babel-plugin-root-import: + specifier: ^5.1.0 + version: 5.1.0 + eslint: + specifier: ^8.10.0 + version: 8.57.1 + eslint-config-airbnb: + specifier: 'catalog:' + version: 19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.1))(eslint-plugin-react@7.37.5(eslint@8.57.1))(eslint@8.57.1) + eslint-config-airbnb-typescript: + specifier: 'catalog:' + version: 16.2.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1) + eslint-config-prettier: + specifier: 'catalog:' + version: 8.10.2(eslint@8.57.1) + eslint-import-resolver-root-import: + specifier: 'catalog:' + version: 1.0.4(babel-plugin-root-import@5.1.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)) + eslint-plugin-import: + specifier: 'catalog:' + version: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) + eslint-plugin-jest: + specifier: 'catalog:' + version: 26.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@27.5.1)(typescript@4.9.5) + eslint-plugin-jsx-a11y: + specifier: 'catalog:' + version: 6.10.2(eslint@8.57.1) + eslint-plugin-prettier: + specifier: 'catalog:' + version: 4.2.5(eslint-config-prettier@8.10.2(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8) + eslint-plugin-react: + specifier: 'catalog:' + version: 7.37.5(eslint@8.57.1) + eslint-plugin-react-hooks: + specifier: 'catalog:' + version: 4.6.2(eslint@8.57.1) + eslint-plugin-storybook: + specifier: 'catalog:' + version: 0.5.13(eslint@8.57.1)(typescript@4.9.5) + jest: + specifier: 'catalog:' + version: 27.5.1 + prettier: + specifier: 'catalog:' + version: 2.8.8 + rimraf: + specifier: 'catalog:' + version: 3.0.2 + ts-jest: + specifier: 'catalog:' + version: 27.1.5(@babel/core@7.29.0)(@types/jest@27.5.2)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) + tsconfig-paths-webpack-plugin: + specifier: 'catalog:' + version: 3.5.2 + typescript: + specifier: ^4.6.2 + version: 4.9.5 + + sdk/typescript/packages/validator-client: + devDependencies: + '@cosmjs/cosmwasm-stargate': + specifier: ^0.29.5 + version: 0.29.5 + '@cosmjs/crypto': + specifier: ^0.29.5 + version: 0.29.5 + '@cosmjs/math': + specifier: ^0.29.5 + version: 0.29.5 + '@cosmjs/proto-signing': + specifier: ^0.29.5 + version: 0.29.5 + '@cosmjs/stargate': + specifier: ^0.29.5 + version: 0.29.5 + '@cosmjs/tendermint-rpc': + specifier: ^0.29.5 + version: 0.29.5 + '@favware/rollup-type-bundler': + specifier: ^2.0.0 + version: 2.0.0 + '@nymproject/types': + specifier: workspace:* + version: link:../../../../ts-packages/types + '@rollup/plugin-commonjs': + specifier: ^24.0.1 + version: 24.1.0(rollup@3.30.0) + '@rollup/plugin-json': + specifier: ^6.0.0 + version: 6.1.0(rollup@3.30.0) + '@rollup/plugin-node-resolve': + specifier: ^15.0.1 + version: 15.3.1(rollup@3.30.0) + '@rollup/plugin-typescript': + specifier: ^11.0.0 + version: 11.1.6(rollup@3.30.0)(tslib@2.8.1)(typescript@4.9.5) + '@types/minimatch': + specifier: 5.1.2 + version: 5.1.2 + '@typescript-eslint/eslint-plugin': + specifier: 'catalog:' + version: 5.62.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0)(typescript@4.9.5) + '@typescript-eslint/parser': + specifier: 'catalog:' + version: 5.62.0(eslint@7.32.0)(typescript@4.9.5) + axios: + specifier: ^1.3.3 + version: 1.16.0 + cosmjs-types: + specifier: ^0.4.1 + version: 0.4.1 + dotenv: + specifier: ^16.0.3 + version: 16.3.2 + eslint: + specifier: ^7.18.0 + version: 7.32.0 + eslint-config-airbnb: + specifier: 'catalog:' + version: 19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0))(eslint-plugin-jsx-a11y@6.10.2(eslint@7.32.0))(eslint-plugin-react-hooks@5.2.0(eslint@7.32.0))(eslint-plugin-react@7.37.5(eslint@7.32.0))(eslint@7.32.0) + eslint-config-airbnb-typescript: + specifier: 'catalog:' + version: 16.2.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0))(eslint@7.32.0) + eslint-config-prettier: + specifier: 'catalog:' + version: 8.10.2(eslint@7.32.0) + eslint-import-resolver-root-import: + specifier: 'catalog:' + version: 1.0.4(babel-plugin-root-import@6.6.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0)) + eslint-plugin-import: + specifier: 'catalog:' + version: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0) + eslint-plugin-mocha: + specifier: ^10.0.3 + version: 10.5.0(eslint@7.32.0) + eslint-plugin-prettier: + specifier: 'catalog:' + version: 4.2.5(eslint-config-prettier@8.10.2(eslint@7.32.0))(eslint@7.32.0)(prettier@2.8.8) + expect: + specifier: ^28.1.3 + version: 28.1.3 + mocha: + specifier: ^10.0.0 + version: 10.8.2 + moq.ts: + specifier: ^7.3.4 + version: 7.4.1 + prettier: + specifier: 'catalog:' + version: 2.8.8 + rollup: + specifier: ^3.17.2 + version: 3.30.0 + rollup-plugin-dts: + specifier: ^5.2.0 + version: 5.3.1(rollup@3.30.0)(typescript@4.9.5) + rollup-plugin-node-polyfills: + specifier: ^0.2.1 + version: 0.2.1 + ts-mocha: + specifier: ^10.0.0 + version: 10.1.0(mocha@10.8.2) + typedoc: + specifier: ^0.22.13 + version: 0.22.18(typescript@4.9.5) + typescript: + specifier: ^4.6.2 + version: 4.9.5 + ts-packages/eslint-config-react-typescript: dependencies: '@typescript-eslint/eslint-plugin': @@ -1631,7 +3143,7 @@ importers: version: 3.0.2 ts-jest: specifier: 'catalog:' - version: 27.1.5(@babel/core@7.29.0)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) + version: 27.1.5(@babel/core@7.29.0)(@types/jest@27.5.2)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5) typescript: specifier: ^4.6.2 version: 4.9.5 @@ -1713,7 +3225,7 @@ importers: version: 4.1.1(file-loader@6.2.0(webpack@5.106.2))(webpack@5.106.2) webpack: specifier: 'catalog:' - version: 5.106.2(webpack-cli@4.10.0) + version: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(webpack-cli@4.10.0) webpack-cli: specifier: 'catalog:' version: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.106.2) @@ -1727,6 +3239,8 @@ importers: specifier: 'catalog:' version: 5.10.0 + wasm/smolmix/pkg: {} + packages: '@acemir/cssom@0.9.31': @@ -1749,6 +3263,9 @@ packages: '@asamuzakjp/nwsapi@2.3.9': resolution: {integrity: sha512-n8GuYSrI9bF7FFZ/SjhwevlHc8xaVlb/7HmHelnc/PZXBD2ZR49NnN9sMMuDdEGPeeRQ5d0hqlSlEpgCX3Wl0Q==} + '@babel/code-frame@7.12.11': + resolution: {integrity: sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==} + '@babel/code-frame@7.29.0': resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} engines: {node: '>=6.9.0'} @@ -1765,6 +3282,10 @@ packages: resolution: {integrity: sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==} engines: {node: '>=6.9.0'} + '@babel/generator@7.24.4': + resolution: {integrity: sha512-Xd6+v6SnjWVx/nus+y0l1sxMOTOMBkyL4+BIdbALyatQnAe/SRVjANeDPSCYaX+i1iJmuGSKf3Z+E+V/va1Hvw==} + engines: {node: '>=6.9.0'} + '@babel/generator@7.29.1': resolution: {integrity: sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==} engines: {node: '>=6.9.0'} @@ -1799,10 +3320,22 @@ packages: peerDependencies: '@babel/core': ^7.4.0 || ^8.0.0-0 <8.0.0 + '@babel/helper-environment-visitor@7.24.7': + resolution: {integrity: sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==} + engines: {node: '>=6.9.0'} + + '@babel/helper-function-name@7.24.7': + resolution: {integrity: sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==} + engines: {node: '>=6.9.0'} + '@babel/helper-globals@7.28.0': resolution: {integrity: sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==} engines: {node: '>=6.9.0'} + '@babel/helper-hoist-variables@7.24.7': + resolution: {integrity: sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==} + engines: {node: '>=6.9.0'} + '@babel/helper-member-expression-to-functions@7.28.5': resolution: {integrity: sha512-cwM7SBRZcPCLgl8a7cY0soT1SptSzAlMH39vwiRpOQkJlh53r5hdHwLSCZpQdVLT39sZt+CRpNwYG4Y2v77atg==} engines: {node: '>=6.9.0'} @@ -1848,6 +3381,10 @@ packages: resolution: {integrity: sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==} engines: {node: '>=6.9.0'} + '@babel/helper-split-export-declaration@7.24.7': + resolution: {integrity: sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.27.1': resolution: {integrity: sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==} engines: {node: '>=6.9.0'} @@ -1868,6 +3405,10 @@ packages: resolution: {integrity: sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==} engines: {node: '>=6.9.0'} + '@babel/highlight@7.25.9': + resolution: {integrity: sha512-llL88JShoCsth8fF8R4SJnIn+WLvR6ccFxu1H3FlMhDontdcmZWf2HgIZ7AIqV3Xcck1idlohrN4EUBQz6klbw==} + engines: {node: '>=6.9.0'} + '@babel/parser@7.29.3': resolution: {integrity: sha512-b3ctpQwp+PROvU/cttc4OYl4MzfJUWy6FZg+PMXfzmt/+39iHVF0sDfqay8TQM3JA2EUOyKcFZt75jWriQijsA==} engines: {node: '>=6.0.0'} @@ -2497,10 +4038,18 @@ packages: resolution: {integrity: sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ==} engines: {node: '>=6.9.0'} + '@babel/traverse@7.24.1': + resolution: {integrity: sha512-xuU6o9m68KeqZbQuDt2TcKSxUw/mrsvavlEqQ1leZ/B+C9tk6E4sRWy97WaXgvq5E+nU3cXMxv3WKOCanVMCmQ==} + engines: {node: '>=6.9.0'} + '@babel/traverse@7.29.0': resolution: {integrity: sha512-4HPiQr0X7+waHfyXPZpWPfWL/J7dcN1mx9gL6WdQVMbPnF3+ZhSMs8tCxN7oHddJE9fhNE7+lxdnlyemKfJRuA==} engines: {node: '>=6.9.0'} + '@babel/types@7.24.0': + resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} + engines: {node: '>=6.9.0'} + '@babel/types@7.29.0': resolution: {integrity: sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==} engines: {node: '>=6.9.0'} @@ -2578,6 +4127,9 @@ packages: '@chain-registry/keplr@1.74.578': resolution: {integrity: sha512-ma6I7f5JkdNcW89paufIbw+psMs4P8vtsqU3LuZM4uY4KQCnurPeDECoRwVnaCGjrouRMx4wDBoGWLEJkYdulQ==} + '@chain-registry/types@0.17.1': + resolution: {integrity: sha512-O0CgrtJgIlqXvZm1CqDZe/7jZz068O/uuCIoyDXCegFHK03rdHacKcDGwEIUuI0MNUf8YV3jdE4xHQMSAX+79w==} + '@chain-registry/types@0.46.15': resolution: {integrity: sha512-gzf+pkAbEZ7fKuTuwmrEAEcx1K/BNrKuCnB9s+WwSo9Ad/3s+GV5LOXcOOxjjHh9Mrs9kvnxKvzKjOwWu8gDJw==} @@ -2587,6 +4139,12 @@ packages: '@chain-registry/utils@1.51.356': resolution: {integrity: sha512-I8/MJEnBvrXvFcSYnzXAM75UHsBMVdBUSYz/20f3clsTyDQyBiKdZRclO7k59IcrSDkbNYP546uXgfrW5CNuWA==} + '@chain-registry/v2-types@0.53.146': + resolution: {integrity: sha512-GnqdNnEJ+ZTAc/0S9fQbwL5GpIvF3LZ/P3o6qh6EyITSiRA1Y55FXs59eSddltpPX5EgyWDwNpJjY+Q5uYlAkA==} + + '@chain-registry/v2@1.71.237': + resolution: {integrity: sha512-c10uXxFz1+51VR0szeB1phn482O03uJiSQ+mZXpeq7IBtU2Hst6Vj1Ttjbx+nlxekhoSGG1jZ0JQ1ewXWYQ6IA==} + '@cnakazawa/watch@1.0.4': resolution: {integrity: sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ==} engines: {node: '>=0.1.95'} @@ -2603,6 +4161,9 @@ packages: '@cosmjs/amino@0.25.6': resolution: {integrity: sha512-9dXN2W7LHjDtJUGNsQ9ok0DfxeN3ca/TXnxCR3Ikh/5YqBqxI8Gel1J9PQO9L6EheYyh045Wff4bsMaLjyEeqQ==} + '@cosmjs/amino@0.29.5': + resolution: {integrity: sha512-Qo8jpC0BiziTSUqpkNatBcwtKNhCovUnFul9SlT/74JUCdLYaeG5hxr3q1cssQt++l4LvlcpF+OUXL48XjNjLw==} + '@cosmjs/amino@0.32.4': resolution: {integrity: sha512-zKYOt6hPy8obIFtLie/xtygCkH9ZROiQ12UHfKsOkWaZfPQUvVbtgmu6R4Kn1tFLI/SRkw7eqhaogmW/3NYu/Q==} @@ -2615,6 +4176,9 @@ packages: '@cosmjs/cosmwasm-stargate@0.25.6': resolution: {integrity: sha512-STaxur5Xk5hqndLEztpa1TqvpdQyg2xD//2ZNFw2fgxf1JQtP0RfFbA3bnBkYwbGARx5cnng8QeZmSUcXnTVxA==} + '@cosmjs/cosmwasm-stargate@0.29.5': + resolution: {integrity: sha512-TNdSvm2tEE3XMCuxHxquzls56t40hC8qnLeYJWHsY2ECZmRK3KrnpRReEr7N7bLtODToK7X/riYrV0JaYxjrYA==} + '@cosmjs/cosmwasm-stargate@0.32.4': resolution: {integrity: sha512-Fuo9BGEiB+POJ5WeRyBGuhyKR1ordvxZGLPuPosFJOH9U0gKMgcjwKMCgAlWFkMlHaTB+tNdA8AifWiHrI7VgA==} @@ -2625,6 +4189,10 @@ packages: resolution: {integrity: sha512-ec+YcQLrg2ibcxtNrh4FqQnG9kG9IE/Aik2NH6+OXQdFU/qFuBTxSFcKDgzzBOChwlkXwydllM9Jjbp+dgIzRw==} deprecated: This uses elliptic for cryptographic operations, which contains several security-relevant bugs. To what degree this affects your application is something you need to carefully investigate. See https://github.com/cosmos/cosmjs/issues/1708 for further pointers. Starting with version 0.34.0 the cryptographic library has been replaced. However, private keys might still be at risk. + '@cosmjs/crypto@0.29.5': + resolution: {integrity: sha512-2bKkaLGictaNL0UipQCL6C1afaisv6k8Wr/GCLx9FqiyFkh9ZgRHDyetD64ZsjnWV/N/D44s/esI+k6oPREaiQ==} + deprecated: This uses elliptic for cryptographic operations, which contains several security-relevant bugs. To what degree this affects your application is something you need to carefully investigate. See https://github.com/cosmos/cosmjs/issues/1708 for further pointers. Starting with version 0.34.0 the cryptographic library has been replaced. However, private keys might still be at risk. + '@cosmjs/crypto@0.32.4': resolution: {integrity: sha512-zicjGU051LF1V9v7bp8p7ovq+VyC91xlaHdsFOTo2oVry3KQikp8L/81RkXmUIT8FxMwdx1T7DmFwVQikcSDIw==} deprecated: This uses elliptic for cryptographic operations, which contains several security-relevant bugs. To what degree this affects your application is something you need to carefully investigate. See https://github.com/cosmos/cosmjs/issues/1708 for further pointers. Starting with version 0.34.0 the cryptographic library has been replaced. However, private keys might still be at risk. @@ -2635,6 +4203,9 @@ packages: '@cosmjs/encoding@0.25.6': resolution: {integrity: sha512-0imUOB8XkUstI216uznPaX1hqgvLQ2Xso3zJj5IV5oJuNlsfDj9nt/iQxXWbJuettc6gvrFfpf+Vw2vBZSZ75g==} + '@cosmjs/encoding@0.29.5': + resolution: {integrity: sha512-G4rGl/Jg4dMCw5u6PEZHZcoHnUBlukZODHbm/wcL4Uu91fkn5jVo5cXXZcvs4VCkArVGrEj/52eUgTZCmOBGWQ==} + '@cosmjs/encoding@0.32.4': resolution: {integrity: sha512-tjvaEy6ZGxJchiizzTn7HVRiyTg1i4CObRRaTRPknm5EalE13SV+TCHq38gIDfyUeden4fCuaBVEdBR5+ti7Hw==} @@ -2644,6 +4215,9 @@ packages: '@cosmjs/json-rpc@0.25.6': resolution: {integrity: sha512-Mn9og3/IEzC6jWoYXs0ONqFJc8HxVjXzrZPLgaRRdMZEUBvctxdhynau1wbE4LdkYQHbu4aiRu1q1jMYGFAj4A==} + '@cosmjs/json-rpc@0.29.5': + resolution: {integrity: sha512-C78+X06l+r9xwdM1yFWIpGl03LhB9NdM1xvZpQHwgCOl0Ir/WV8pw48y3Ez2awAoUBRfTeejPe4KvrE6NoIi/w==} + '@cosmjs/json-rpc@0.32.4': resolution: {integrity: sha512-/jt4mBl7nYzfJ2J/VJ+r19c92mUKF0Lt0JxM3MXEJl7wlwW5haHAWtzRujHkyYMXOwIR+gBqT2S0vntXVBRyhQ==} @@ -2659,6 +4233,9 @@ packages: '@cosmjs/math@0.27.1': resolution: {integrity: sha512-cHWVjmfIjtRc7f80n7x+J5k8pe+vTVTQ0lA82tIxUgqUvgS6rogPP/TmGtTiZ4+NxWxd11DUISY6gVpr18/VNQ==} + '@cosmjs/math@0.29.5': + resolution: {integrity: sha512-2GjKcv+A9f86MAWYLUkjhw1/WpRl2R1BTb3m9qPG7lzMA7ioYff9jY5SPCfafKdxM4TIQGxXQlYGewQL16O68Q==} + '@cosmjs/math@0.32.4': resolution: {integrity: sha512-++dqq2TJkoB8zsPVYCvrt88oJWsy1vMOuSOKcdlnXuOA/ASheTJuYy4+oZlTQ3Fr8eALDLGGPhJI02W2HyAQaw==} @@ -2668,6 +4245,9 @@ packages: '@cosmjs/proto-signing@0.25.6': resolution: {integrity: sha512-JpQ+Vnv9s6i3x8f3Jo0lJZ3VMnj3R5sMgX+8ti1LtB7qEYRR85qbDrEG9hDGIKqJJabvrAuCHnO6hYi0vJEJHA==} + '@cosmjs/proto-signing@0.29.5': + resolution: {integrity: sha512-QRrS7CiKaoETdgIqvi/7JC2qCwCR7lnWaUsTzh/XfRy3McLkEd+cXbKAW3cygykv7IN0VAEIhZd2lyIfT8KwNA==} + '@cosmjs/proto-signing@0.32.4': resolution: {integrity: sha512-QdyQDbezvdRI4xxSlyM1rSVBO2st5sqtbEIl3IX03uJ7YiZIQHyv6vaHVf1V4mapusCqguiHJzm4N4gsFdLBbQ==} @@ -2677,6 +4257,9 @@ packages: '@cosmjs/socket@0.25.6': resolution: {integrity: sha512-hu+pW3Fy0IuhstXgxnZ2Iq0RUnGYoTWfqrxbTsgXBJge4MpEQs2YwGXgJZPMJXedBQivG0tU3r/Wvam0EWuRkQ==} + '@cosmjs/socket@0.29.5': + resolution: {integrity: sha512-5VYDupIWbIXq3ftPV1LkS5Ya/T7Ol/AzWVhNxZ79hPe/mBfv1bGau/LqIYOm2zxGlgm9hBHOTmWGqNYDwr9LNQ==} + '@cosmjs/socket@0.32.4': resolution: {integrity: sha512-davcyYziBhkzfXQTu1l5NrpDYv0K9GekZCC9apBRvL1dvMc9F/ygM7iemHjUA+z8tJkxKxrt/YPjJ6XNHzLrkw==} @@ -2686,6 +4269,9 @@ packages: '@cosmjs/stargate@0.25.6': resolution: {integrity: sha512-+LM1sK6vGuotJF9fBCBlaDL/yJhfzCV6KbsaWt3teHAKZhKYOd/9mKGiB4H9bfg4h3r+e+FZGiNkH/mdXkcgEw==} + '@cosmjs/stargate@0.29.5': + resolution: {integrity: sha512-hjEv8UUlJruLrYGJcUZXM/CziaINOKwfVm2BoSdUnNTMxGvY/jC1ABHKeZUYt9oXHxEJ1n9+pDqzbKc8pT0nBw==} + '@cosmjs/stargate@0.32.4': resolution: {integrity: sha512-usj08LxBSsPRq9sbpCeVdyLx2guEcOHfJS9mHGCLCXpdAPEIEQEtWLDpEUc0LEhWOx6+k/ChXTc5NpFkdrtGUQ==} @@ -2695,6 +4281,9 @@ packages: '@cosmjs/stream@0.25.6': resolution: {integrity: sha512-2mXIzf+WaFd+GSrRaJJETVXeZoC5sosuKChFERxSY8zXQ/f3OaG9J6m+quHpPbU3nAIEtnF1jgBVqJiD+NKwGQ==} + '@cosmjs/stream@0.29.5': + resolution: {integrity: sha512-TToTDWyH1p05GBtF0Y8jFw2C+4783ueDCmDyxOMM6EU82IqpmIbfwcdMOCAm0JhnyMh+ocdebbFvnX/sGKzRAA==} + '@cosmjs/stream@0.32.4': resolution: {integrity: sha512-Gih++NYHEiP+oyD4jNEUxU9antoC0pFSg+33Hpp0JlHwH0wXhtD3OOKnzSfDB7OIoEbrzLJUpEjOgpCp5Z+W3A==} @@ -2704,6 +4293,9 @@ packages: '@cosmjs/tendermint-rpc@0.25.6': resolution: {integrity: sha512-wsvxTI7DReWJu+SVlXLblzh5NJppnh1mljuaTHodMf7HBxrXdbcCcBAO8oMbMgEqOASEY5G+z51wktxhrn9RtA==} + '@cosmjs/tendermint-rpc@0.29.5': + resolution: {integrity: sha512-ar80twieuAxsy0x2za/aO3kBr2DFPAXDmk2ikDbmkda+qqfXgl35l9CVAAjKRqd9d+cRvbQyb5M4wy6XQpEV6w==} + '@cosmjs/tendermint-rpc@0.32.4': resolution: {integrity: sha512-MWvUUno+4bCb/LmlMIErLypXxy7ckUuzEmpufYYYd9wgbdCXaTaO08SZzyFM5PI8UJ/0S2AmUrgWhldlbxO8mw==} @@ -2713,6 +4305,9 @@ packages: '@cosmjs/utils@0.25.6': resolution: {integrity: sha512-ofOYiuxVKNo238vCPPlaDzqPXy2AQ/5/nashBo5rvPZJkxt9LciGfUEQWPCOb1BIJDNx2Dzu0z4XCf/dwzl0Dg==} + '@cosmjs/utils@0.29.5': + resolution: {integrity: sha512-m7h+RXDUxOzEOGt4P+3OVPX7PuakZT3GBmaM/Y2u+abN3xZkziykD/NvedYFvvCCdQo714XcGl33bwifS9FZPQ==} + '@cosmjs/utils@0.32.4': resolution: {integrity: sha512-D1Yc+Zy8oL/hkUkFUL/bwxvuDBzRGpc4cF7/SkdhxX4iHpSLgdOuTt1mhCh9+kl6NQREy9t7SYZ6xeW5gFe60w==} @@ -2745,6 +4340,16 @@ packages: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 + '@cosmwasm/ts-codegen-ast@1.10.0': + resolution: {integrity: sha512-59CMNTIWJp4FSNibONULZJzHe9hyyMaj/zs7zfXI3pFIDGYqUemOWxwNhs76O17LXPrG8qjU/xVemBWr3H4v7Q==} + + '@cosmwasm/ts-codegen-types@1.5.0': + resolution: {integrity: sha512-Znk0e1/A9q2PS1oRDqNTwH0bGx0J3kmTPH3vcQY5mZc4it6KZzRLH+8aGR2TMHaw6YPReu0wh7s6BaCl63ZLKQ==} + + '@cosmwasm/ts-codegen@1.14.1': + resolution: {integrity: sha512-JYd2NB21eBL9SjZI/lFJrXUWrinfC9aQqP+E/HFrP2KbnP673Uj3SATg0jpLZ/BpUMV/UN2DSmultsQX938mIA==} + hasBin: true + '@csstools/color-helpers@6.0.2': resolution: {integrity: sha512-LMGQLS9EuADloEFkcTBR3BwV/CGHV7zyDxVRtVDTwdI2Ca4it0CCVTT9wCkxSgokjE5Ho41hEPgb8OEUwoXr6Q==} engines: {node: '>=20.19.0'} @@ -3057,6 +4662,10 @@ packages: resolution: {integrity: sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@eslint/eslintrc@0.4.3': + resolution: {integrity: sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==} + engines: {node: ^10.12.0 || >=12.0.0} + '@eslint/eslintrc@2.1.4': resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -3081,24 +4690,57 @@ packages: resolution: {integrity: sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ethersproject/abstract-provider@5.8.0': + resolution: {integrity: sha512-wC9SFcmh4UK0oKuLJQItoQdzS/qZ51EJegK6EmAWlh+OptpQ/npECOR3QqECd8iGHC0RJb4WKbVdSfif4ammrg==} + + '@ethersproject/abstract-signer@5.8.0': + resolution: {integrity: sha512-N0XhZTswXcmIZQdYtUnd79VJzvEwXQw6PK0dTl9VoYrEBxxCPXqS0Eod7q5TNKRxe1/5WUMuR0u0nqTF/avdCA==} + '@ethersproject/address@5.8.0': resolution: {integrity: sha512-GhH/abcC46LJwshoN+uBNoKVFPxUuZm6dA257z0vZkKmU1+t8xTn8oK7B9qrj8W2rFRMch4gbJl6PmVxjxBEBA==} + '@ethersproject/base64@5.8.0': + resolution: {integrity: sha512-lN0oIwfkYj9LbPx4xEkie6rAMJtySbpOAFXSDVQaBnAzYfB4X2Qr+FXJGxMoc3Bxp2Sm8OwvzMrywxyw0gLjIQ==} + '@ethersproject/bignumber@5.8.0': resolution: {integrity: sha512-ZyaT24bHaSeJon2tGPKIiHszWjD/54Sz8t57Toch475lCLljC6MgPmxk7Gtzz+ddNN5LuHea9qhAe0x3D+uYPA==} '@ethersproject/bytes@5.8.0': resolution: {integrity: sha512-vTkeohgJVCPVHu5c25XWaWQOZ4v+DkGoC42/TS2ond+PARCxTJvgTFUNDZovyQ/uAQ4EcpqqowKydcdmRKjg7A==} + '@ethersproject/constants@5.8.0': + resolution: {integrity: sha512-wigX4lrf5Vu+axVTIvNsuL6YrV4O5AXl5ubcURKMEME5TnWBouUh0CDTWxZ2GpnRn1kcCgE7l8O5+VbV9QTTcg==} + + '@ethersproject/hash@5.8.0': + resolution: {integrity: sha512-ac/lBcTbEWW/VGJij0CNSw/wPcw9bSRgCB0AIBz8CvED/jfvDoV9hsIIiWfvWmFEi8RcXtlNwp2jv6ozWOsooA==} + '@ethersproject/keccak256@5.8.0': resolution: {integrity: sha512-A1pkKLZSz8pDaQ1ftutZoaN46I6+jvuqugx5KYNeQOPqq+JZ0Txm7dlWesCHB5cndJSu5vP2VKptKf7cksERng==} '@ethersproject/logger@5.8.0': resolution: {integrity: sha512-Qe6knGmY+zPPWTC+wQrpitodgBfH7XoceCGL5bJVejmH+yCS3R8jJm8iiWuvWbG76RUmyEG53oqv6GMVWqunjA==} + '@ethersproject/networks@5.8.0': + resolution: {integrity: sha512-egPJh3aPVAzbHwq8DD7Po53J4OUSsA1MjQp8Vf/OZPav5rlmWUaFLiq8cvQiGK0Z5K6LYzm29+VA/p4RL1FzNg==} + + '@ethersproject/properties@5.8.0': + resolution: {integrity: sha512-PYuiEoQ+FMaZZNGrStmN7+lWjlsoufGIHdww7454FIaGdbe/p5rnaCXTr5MtBYl3NkeoVhHZuyzChPeGeKIpQw==} + '@ethersproject/rlp@5.8.0': resolution: {integrity: sha512-LqZgAznqDbiEunaUvykH2JAoXTT9NV0Atqk8rQN9nx9SEgThA/WMx5DnW8a9FOufo//6FZOCHZ+XiClzgbqV9Q==} + '@ethersproject/signing-key@5.8.0': + resolution: {integrity: sha512-LrPW2ZxoigFi6U6aVkFN/fa9Yx/+4AtIUe4/HACTvKJdhm0eeb107EVCIQcrLZkxaSIgc/eCrX8Q1GtbH+9n3w==} + + '@ethersproject/strings@5.8.0': + resolution: {integrity: sha512-qWEAk0MAvl0LszjdfnZ2uC8xbR2wdv4cDabyHiBh3Cldq/T8dPH3V4BbBsAYJUeonwD+8afVXld274Ls+Y1xXg==} + + '@ethersproject/transactions@5.8.0': + resolution: {integrity: sha512-UglxSDjByHG0TuU17bDfCemZ3AnKO2vYrL5/2n2oXvKzvb7Cz+W9gOWXKARjp2URVwcWlQlPOEQyAviKwT4AHg==} + + '@ethersproject/web@5.8.0': + resolution: {integrity: sha512-j7+Ksi/9KfGviws6Qtf9Q7KCqRhpwrYKQPs+JBA/rKVFF/yaWLHJEH3zfVP2plVu+eys0d2DlFmhoQJayFewcw==} + '@exodus/bytes@1.15.0': resolution: {integrity: sha512-UY0nlA+feH81UGSHv92sLEPLCeZFjXOuHhrIo0HQydScuQc8s0A7kL/UdgwgDq8g8ilksmuoF35YVTNphV2aBQ==} engines: {node: ^20.19.0 || ^22.12.0 || >=24.0.0} @@ -3108,6 +4750,11 @@ packages: '@noble/hashes': optional: true + '@favware/rollup-type-bundler@2.0.0': + resolution: {integrity: sha512-RTMvx6v3b4D9V9iXHTogYjHa5fCmcUR3Bu0pFreo+80v2tD+7MSJm24nR1P/SkeTCy+zHKC1JOFQa04fcWZozg==} + engines: {node: '>=v14'} + hasBin: true + '@floating-ui/core@1.7.5': resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==} @@ -3163,10 +4810,19 @@ packages: engines: {node: '>=10.10.0'} deprecated: Use @eslint/config-array instead + '@humanwhocodes/config-array@0.5.0': + resolution: {integrity: sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==} + engines: {node: '>=10.10.0'} + deprecated: Use @eslint/config-array instead + '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} + '@humanwhocodes/object-schema@1.2.1': + resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + deprecated: Use @eslint/object-schema instead + '@humanwhocodes/object-schema@2.0.3': resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} deprecated: Use @eslint/object-schema instead @@ -3311,6 +4967,42 @@ packages: react: ^18.0.0 || ^19.0.0 react-dom: ^18.0.0 || ^19.0.0 + '@interchainjs/amino@1.17.1': + resolution: {integrity: sha512-MYEye+V4O7tITc/YofgGbiLT0kdXuK0BvuIYMFfq5+Tybq9tgFu/PYQ6CL3nyD6+S5H/rbgz9sUH31sPj7XaZg==} + + '@interchainjs/auth@1.17.1': + resolution: {integrity: sha512-4khXhRti537vqsSzSPfCwtarFBNvXkc8ISYFvqY43I2j0m0FbzZhNqjrXQn+xnihnjsF9ec/SqckVKdXX2DHFg==} + + '@interchainjs/cosmos-types@1.17.1': + resolution: {integrity: sha512-GU3dfQ2IHTVvClgctjY0RAdErwcG6fQskBh4Iqm6BDpcgpto2+nzES/DoLslx8ds9vBCujjx5zGFwr90fgScHw==} + + '@interchainjs/cosmos@1.17.1': + resolution: {integrity: sha512-Wzjv5VxaiZUD+sY2ErMv6QCTdrmV+Mus1VFHrMZo3T4gex6Z8fOOV1IaesN5+w44XM4YkF8CX+zSCerfqV6Dvg==} + + '@interchainjs/crypto@1.17.1': + resolution: {integrity: sha512-vrKtsRq4YX6pUukD73CbLLOD6tgwHb05GMOVhK0S8lGULiSoW8f76LvhOUgX13v5MSWiBzdSiAaVsAfTvkJePw==} + + '@interchainjs/encoding@1.17.1': + resolution: {integrity: sha512-ALRsvzEtSAHBiBw2z+i9bp9ICGpMN8L6cqS0AIpx+B4mFnuFp0TYi4m7CerklcDeV78ld+G6Xf5PbbQUGI0/hA==} + + '@interchainjs/ethereum@1.17.1': + resolution: {integrity: sha512-EOjB3Q8OusoCk5/zg0PlWJUoepKEOjm18DNEeAxUPmG5wDw8CIAp7wkUHF6lfGkE7ZFedwy74Uinc1eZZSDh1g==} + + '@interchainjs/math@1.17.1': + resolution: {integrity: sha512-4eOj6m95Iy3iNuhqf9F9iLBlV1U2G5L6CqjpROvn9fiO3H8DInXermZFP1CjFXley1Nrd8QfbV7OSkyfa0u8tA==} + + '@interchainjs/pubkey@1.17.1': + resolution: {integrity: sha512-hdfXFsZSVSg6tPzgd3Htw40dSY/nXTVJLrbZt6cKe6BGRiuPSQmOkka6AZn0Ze5Y4ULYfUMxpipFQc0ukfsd1A==} + + '@interchainjs/types@1.17.1': + resolution: {integrity: sha512-EPKa0nFPjYFpgO+a5WUBXrkHbbBeYHyBv8DG55yTFuvvn4Yd6uH86ygQIR9NsEAMgKQSiTD+yQcVj/4fbC/EQg==} + + '@interchainjs/utils@1.17.1': + resolution: {integrity: sha512-46W53v0tRMHiThvF8IZbURqAJsCxNwdxMdKFlL1pDwqAUHxgFzM6IfxemijbNCQd2ST9EYKe9c5zmnxEsHioig==} + peerDependencies: + '@chain-registry/v2': ^1.71.186 + '@chain-registry/v2-types': ^0.53.115 + '@internationalized/date@3.12.1': resolution: {integrity: sha512-6IedsVWXyq4P9Tj+TxuU8WGWM70hYLl12nbYU8jkikVpa6WXapFazPUcHUMDMoWftIDE2ILDkFFte6W2nFCkRQ==} @@ -3366,6 +5058,10 @@ packages: resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/expect-utils@28.1.3': + resolution: {integrity: sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + '@jest/expect-utils@29.7.0': resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -3408,6 +5104,10 @@ packages: node-notifier: optional: true + '@jest/schemas@28.1.3': + resolution: {integrity: sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + '@jest/schemas@29.6.3': resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -3456,6 +5156,10 @@ packages: resolution: {integrity: sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + '@jest/types@28.1.3': + resolution: {integrity: sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + '@jest/types@29.6.3': resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -3479,6 +5183,9 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} + '@jsdevtools/ono@7.1.3': + resolution: {integrity: sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==} + '@keplr-wallet/common@0.12.28': resolution: {integrity: sha512-ESQorPZw8PRiUXhsrxED+E1FEWkAdc6Kwi3Az7ce204gMBQDI2j0XJtTd4uCUp+C24Em9fk0samdHzdoB4caIg==} @@ -3522,6 +5229,42 @@ packages: engines: {node: '>=16.0.0'} deprecated: This package is an implementation detail of Lerna and is no longer published separately. + '@lezer/common@1.5.2': + resolution: {integrity: sha512-sxQE460fPZyU3sdc8lafxiPwJHBzZRy/udNFynGQky1SePYBdhkBl1kOagA9uT3pxR8K09bOrmTUqA9wb/PjSQ==} + + '@lezer/lr@1.4.10': + resolution: {integrity: sha512-rnCpTIBafOx4mRp43xOxDJbFipJm/c0cia/V5TiGlhmMa+wsSdoGmUN3w5Bqrks/09Q/D4tNAmWaT8p6NRi77A==} + + '@lmdb/lmdb-darwin-arm64@2.8.5': + resolution: {integrity: sha512-KPDeVScZgA1oq0CiPBcOa3kHIqU+pTOwRFDIhxvmf8CTNvqdZQYp5cCKW0bUk69VygB2PuTiINFWbY78aR2pQw==} + cpu: [arm64] + os: [darwin] + + '@lmdb/lmdb-darwin-x64@2.8.5': + resolution: {integrity: sha512-w/sLhN4T7MW1nB3R/U8WK5BgQLz904wh+/SmA2jD8NnF7BLLoUgflCNxOeSPOWp8geP6nP/+VjWzZVip7rZ1ug==} + cpu: [x64] + os: [darwin] + + '@lmdb/lmdb-linux-arm64@2.8.5': + resolution: {integrity: sha512-vtbZRHH5UDlL01TT5jB576Zox3+hdyogvpcbvVJlmU5PdL3c5V7cj1EODdh1CHPksRl+cws/58ugEHi8bcj4Ww==} + cpu: [arm64] + os: [linux] + + '@lmdb/lmdb-linux-arm@2.8.5': + resolution: {integrity: sha512-c0TGMbm2M55pwTDIfkDLB6BpIsgxV4PjYck2HiOX+cy/JWiBXz32lYbarPqejKs9Flm7YVAKSILUducU9g2RVg==} + cpu: [arm] + os: [linux] + + '@lmdb/lmdb-linux-x64@2.8.5': + resolution: {integrity: sha512-Xkc8IUx9aEhP0zvgeKy7IQ3ReX2N8N1L0WPcQwnZweWmOuKfwpS3GRIYqLtK5za/w3E60zhFfNdS+3pBZPytqQ==} + cpu: [x64] + os: [linux] + + '@lmdb/lmdb-win32-x64@2.8.5': + resolution: {integrity: sha512-4wvrf5BgnR8RpogHhtpCPJMKBmvyZPhhUtEwMJbXh0ni2BucpfF07jlmyM11zRqQ2XIq6PbC2j7W7UCCcm1rRQ==} + cpu: [x64] + os: [win32] + '@mdx-js/mdx@1.6.22': resolution: {integrity: sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA==} @@ -3533,10 +5276,44 @@ packages: '@mdx-js/util@1.6.22': resolution: {integrity: sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==} + '@mischnic/json-sourcemap@0.1.1': + resolution: {integrity: sha512-iA7+tyVqfrATAIsIRWQG+a7ZLLD0VaOCKV2Wd/v4mqIU3J9c4jx9p7S0nw1XH3gJCKNBOOwACOPYYSUu9pgT+w==} + engines: {node: '>=12.0.0'} + '@mrmlnc/readdir-enhanced@2.2.1': resolution: {integrity: sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==} engines: {node: '>=4'} + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4': + resolution: {integrity: sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ==} + cpu: [arm64] + os: [darwin] + + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4': + resolution: {integrity: sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w==} + cpu: [x64] + os: [darwin] + + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4': + resolution: {integrity: sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw==} + cpu: [arm64] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4': + resolution: {integrity: sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw==} + cpu: [arm] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4': + resolution: {integrity: sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ==} + cpu: [x64] + os: [linux] + + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4': + resolution: {integrity: sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ==} + cpu: [x64] + os: [win32] + '@mui/base@5.0.0-beta.40': resolution: {integrity: sha512-I/lGHztkCzvwlXpjD2+SNmvNQvB4227xBXhISPjEaJUXGImOQ9f3D2Yj/T3KasSI/h0MLWy74X0J6clhPmsRbQ==} engines: {node: '>=12.0.0'} @@ -3940,6 +5717,10 @@ packages: resolution: {integrity: sha512-UTMhXK9SeDhFJVrHeUJ5uZlI6ajXg10O6Ddocf9S6GjbSBVZsJo88HzKwXznNfGpMTRDyJkqMjNDPYgf0qFWnw==} engines: {node: ^14.21.3 || >=16} + '@noble/curves@1.9.0': + resolution: {integrity: sha512-7YDlXiNMdO1YZeH6t/kvopHHbIZzlxrCV9WLqCY6QhcXOoXiNCMDqJIglZ9Yjx5+w7Dz30TITFrlTjnRg7sKEg==} + engines: {node: ^14.21.3 || >=16} + '@noble/curves@1.9.7': resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} engines: {node: ^14.21.3 || >=16} @@ -4097,9 +5878,18 @@ packages: '@nymproject/contract-clients@1.4.1': resolution: {integrity: sha512-HuJZ4Hv+Rl6ZZEtCHKgurNLJapM+QQRJlGkevFH2a4UdqUqF9omUkUi3AVes4679dPoSFgvA7plyVSDBdbgV6w==} + '@nymproject/nym-client-wasm-node@1.4.1': + resolution: {integrity: sha512-+bUIIiZGcv9GPOpKl6Pas2UochIac9EWxT24vmhx+x/Y4B6y4PpFtaVj+TtNwFtCu+/6w2GH0tb7UAJIzpJSQw==} + + '@nymproject/nym-client-wasm@1.4.1': + resolution: {integrity: sha512-7GQD9wSHEZXgBWSNNyJ6l6ur7VIgkX4CzQ08dYfX4P35yiHeR8DasPoryVy+Ed7X5fpoqK5CPxXu89OdXG4JAg==} + '@nymproject/nym-validator-client@0.18.0': resolution: {integrity: sha512-FO1T15S2BJVuMoPA2yOaH40aD3hKJPKJVyX5ix7eJEbBWIdsYNoVeVc/soHhaAU1FIy2uU0G/FZQkaUYJGGb7Q==} + '@nymproject/sdk@1.4.1': + resolution: {integrity: sha512-IsTul8CZPjkKNAxx7trf/cYUrLia3cOxf2ZYX/dZrJsDXqOA3KlLD1dRXaDGUniv/ov9gS3Y0YM+esuzWm9jkg==} + '@octokit/auth-token@3.0.4': resolution: {integrity: sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ==} engines: {node: '>= 14'} @@ -4160,10 +5950,392 @@ packages: '@octokit/types@9.3.2': resolution: {integrity: sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA==} + '@parcel/bundler-default@2.16.4': + resolution: {integrity: sha512-Nb8peNvhfm1+660CLwssWh4weY+Mv6vEGS6GPKqzJmTMw50udi0eS1YuWFzvmhSiu1KsYcUD37mqQ1LuIDtWoA==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/cache@2.16.4': + resolution: {integrity: sha512-+uCyeElSga2MBbmbXpIj/WVKH7TByCrKaxtHbelfKKIJpYMgEHVjO4cuc7GUfTrUAmRUS8ZGvnX7Etgq6/jQhw==} + engines: {node: '>= 16.0.0'} + peerDependencies: + '@parcel/core': ^2.16.4 + + '@parcel/codeframe@2.16.4': + resolution: {integrity: sha512-s64aMfOJoPrXhKH+Y98ahX0O8aXWvTR+uNlOaX4yFkpr4FFDnviLcGngDe/Yo4Qq2FJZ0P6dNswbJTUH9EGxkQ==} + engines: {node: '>= 16.0.0'} + + '@parcel/compressor-raw@2.16.4': + resolution: {integrity: sha512-IK8IpNhw61B2HKgA1JhGhO9y+ZJFRZNTEmvhN1NdLdPqvgEXm2EunT+m6D9z7xeoeT6XnUKqM0eRckEdD0OXbA==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/config-default@2.16.4': + resolution: {integrity: sha512-kBxuTY/5trEVnvXk92l7LVkYjNuz3SaqWymFhPjEnc8GY4ZVdcWrWdXWTB9hUhpmRYJctFCyGvM0nN05JTiM2g==} + peerDependencies: + '@parcel/core': ^2.16.4 + + '@parcel/core@2.16.4': + resolution: {integrity: sha512-a0CgrW5A5kwuSu5J1RFRoMQaMs9yagvfH2jJMYVw56+/7NRI4KOtu612SG9Y1ERWfY55ZwzyFxtLWvD6LO+Anw==} + engines: {node: '>= 16.0.0'} + + '@parcel/diagnostic@2.16.4': + resolution: {integrity: sha512-YN5CfX7lFd6yRLxyZT4Sj3sR6t7nnve4TdXSIqapXzQwL7Bw+sj79D95wTq2rCm3mzk5SofGxFAXul2/nG6gcQ==} + engines: {node: '>= 16.0.0'} + + '@parcel/error-overlay@2.16.4': + resolution: {integrity: sha512-e8KYKnMsfmQnqIhsUWBUZAXlDK30wkxsAGle1tZ0gOdoplaIdVq/WjGPatHLf6igLM76c3tRn2vw8jZFput0jw==} + engines: {node: '>= 16.0.0'} + + '@parcel/events@2.16.4': + resolution: {integrity: sha512-slWQkBRAA7o0cN0BLEd+yCckPmlVRVhBZn5Pn6ktm4EzEtrqoMzMeJOxxH8TXaRzrQDYnTcnYIHFgXWd4kkUfg==} + engines: {node: '>= 16.0.0'} + + '@parcel/feature-flags@2.16.4': + resolution: {integrity: sha512-nYdx53siKPLYikHHxfzgjzzgxdrjquK6DMnuSgOTyIdRG4VHdEN0+NqKijRLuVgiUFo/dtxc2h+amwqFENMw8w==} + engines: {node: '>= 16.0.0'} + + '@parcel/fs@2.16.4': + resolution: {integrity: sha512-maCMOiVn7oJYZlqlfxgLne8n6tSktIT1k0AeyBp4UGWCXyeJUJ+nL7QYShFpKNLtMLeF0cEtgwRAknWzbcDS1g==} + engines: {node: '>= 16.0.0'} + peerDependencies: + '@parcel/core': ^2.16.4 + + '@parcel/graph@3.6.4': + resolution: {integrity: sha512-Cj9yV+/k88kFhE+D+gz0YuNRpvNOCVDskO9pFqkcQhGbsGq6kg2XpZ9V7HlYraih31xf8Vb589bZOwjKIiHixQ==} + engines: {node: '>= 16.0.0'} + + '@parcel/logger@2.16.4': + resolution: {integrity: sha512-QR8QLlKo7xAy9JBpPDAh0RvluaixqPCeyY7Fvo2K7hrU3r85vBNNi06pHiPbWoDmB4x1+QoFwMaGnJOHR+/fMA==} + engines: {node: '>= 16.0.0'} + + '@parcel/markdown-ansi@2.16.4': + resolution: {integrity: sha512-0+oQApAVF3wMcQ6d1ZfZ0JsRzaMUYj9e4U+naj6YEsFsFGOPp+pQYKXBf1bobQeeB7cPKPT3SUHxFqced722Hw==} + engines: {node: '>= 16.0.0'} + + '@parcel/namer-default@2.16.4': + resolution: {integrity: sha512-CE+0lFg881sJq575EXxj2lKUn81tsS5itpNUUErHxit195m3PExyAhoXM6ed/SXxwi+uv+T5FS/jjDLBNuUFDA==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/node-resolver-core@3.7.4': + resolution: {integrity: sha512-b3VDG+um6IWW5CTod6M9hQsTX5mdIelKmam7mzxzgqg4j5hnycgTWqPMc9UxhYoUY/Q/PHfWepccNcKtvP5JiA==} + engines: {node: '>= 16.0.0'} + + '@parcel/optimizer-css@2.16.4': + resolution: {integrity: sha512-aqdXCtmvpcXYgJFGk2DtXF34wuM2TD1fZorKMrJdKB9sSkWVRs1tq6RAXQrbi0ZPDH9wfE/9An3YdkTex7RHuQ==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/optimizer-html@2.16.4': + resolution: {integrity: sha512-vg/R2uuSni+NYYUUV8m+5bz8p5zBv8wc/nNleoBnGuCDwn7uaUwTZ8Gt9CjZO8jjG0xCLILoc/TW+e2FF3pfgQ==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/optimizer-image@2.16.4': + resolution: {integrity: sha512-2RV54WnvMYr18lxSx7Zlx/DXpJwMzOiPxDnoFyvaUoYutvgHO6chtcgFgh1Bvw/PoI95vYzlTkZ8QfUOk5A0JA==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + peerDependencies: + '@parcel/core': ^2.16.4 + + '@parcel/optimizer-svg@2.16.4': + resolution: {integrity: sha512-22+BqIffCrVErg8y2XwhasbTaFNn75OKXZ3KTDBIfOSAZKLUKs1iHfDXETzTRN7cVcS+Q36/6EHd7N/RA8i1fg==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/optimizer-swc@2.16.4': + resolution: {integrity: sha512-+URqwnB6u1gqaLbG1O1DDApH+UVj4WCbK9No1fdxLBxQ9a84jyli25o1kK1hYB9Nb/JMyYNnEBfvYUW6RphOxw==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/package-manager@2.16.4': + resolution: {integrity: sha512-obWv9gZgdnkT3Kd+fBkKjhdNEY7zfOP5gVaox5i4nQstVCaVnDlMv5FwLEXwehL+WbwEcGyEGGxOHHkAFKk7Cg==} + engines: {node: '>= 16.0.0'} + peerDependencies: + '@parcel/core': ^2.16.4 + + '@parcel/packager-css@2.16.4': + resolution: {integrity: sha512-rWRtfiX+VVIOZvq64jpeNUKkvWAbnokfHQsk/js1s5jD4ViNQgPcNLiRaiIANjymqL6+dQqWvGUSW2a5FAZYfg==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/packager-html@2.16.4': + resolution: {integrity: sha512-AWo5f6SSqBsg2uWOsX0gPX8hCx2iE6GYLg2Z4/cDy2mPlwDICN8/bxItEztSZFmObi+ti26eetBKRDxAUivyIQ==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/packager-js@2.16.4': + resolution: {integrity: sha512-L2o39f/fhta+hxto7w8OTUKdstY+te5BmHZREckbQm0KTBg93BG7jB0bfoxLSZF0d8uuAYIVXjzeHNqha+du1g==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/packager-raw@2.16.4': + resolution: {integrity: sha512-A9j60G9OmbTkEeE4WRMXCiErEprHLs9NkUlC4HXCxmSrPMOVaMaMva2LdejE3A9kujZqYtYfuc8+a+jN+Nro4w==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/packager-svg@2.16.4': + resolution: {integrity: sha512-LT9l7eInFrAZJ6w3mYzAUgDq3SIzYbbQyW46Dz26M9lJQbf6uCaATUTac3BEHegW0ikDuw4OOGHK41BVqeeusg==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/packager-wasm@2.16.4': + resolution: {integrity: sha512-AY96Aqu/RpmaSZK2RGkIrZWjAperDw8DAlxLAiaP1D/RPVnikZtl5BmcUt/Wz3PrzG7/q9ZVqqKkWsLmhkjXZQ==} + engines: {node: '>=16.0.0', parcel: ^2.16.4} + + '@parcel/plugin@2.16.4': + resolution: {integrity: sha512-aN2VQoRGC1eB41ZCDbPR/Sp0yKOxe31oemzPx1nJzOuebK2Q6FxSrJ9Bjj9j/YCaLzDtPwelsuLOazzVpXJ6qg==} + engines: {node: '>= 16.0.0'} + + '@parcel/profiler@2.16.4': + resolution: {integrity: sha512-R3JhfcnoReTv2sVFHPR2xKZvs3d3IRrBl9sWmAftbIJFwT4rU70/W7IdwfaJVkD/6PzHq9mcgOh1WKL4KAxPdA==} + engines: {node: '>= 16.0.0'} + + '@parcel/reporter-cli@2.16.4': + resolution: {integrity: sha512-DQx9TwcTZrDv828+tcwEi//xyW7OHTGzGX1+UEVxPp0mSzuOmDn0zfER8qNIqGr1i4D/FXhb5UJQDhGHV8mOpQ==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/reporter-dev-server@2.16.4': + resolution: {integrity: sha512-YWvay25htQDifpDRJ0+yFh6xUxKnbfeJxYkPYyuXdxpEUhq4T0UWW0PbPCN/wFX7StgeUTXq5Poeo/+eys9m3w==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/reporter-tracer@2.16.4': + resolution: {integrity: sha512-JKnlXpPepak0/ZybmZn9JtyjJiDBWYrt7ZUlXQhQb0xzNcd/k+RqfwVkTKIwyFHsWtym0cwibkvsi2bWFzS7tw==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/resolver-default@2.16.4': + resolution: {integrity: sha512-wJe9XQS0hn/t32pntQpJbls3ZL8mGVVhK9L7s7BTmZT9ufnvP2nif1psJz/nbgnP9LF6mLSk43OdMJKpoStsjQ==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/runtime-browser-hmr@2.16.4': + resolution: {integrity: sha512-asx7p3NjUSfibI3bC7+8+jUIGHWVk2Zuq9SjJGCGDt+auT9A4uSGljnsk1BWWPqqZ0WILubq4czSAqm0+wt4cw==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/runtime-js@2.16.4': + resolution: {integrity: sha512-gUKmsjg+PULQBu2QbX0QKll9tXSqHPO8NrfxHwWb2lz5xDKDos1oV0I7BoMWbHhUHkoToXZrm654oGViujtVUA==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/runtime-rsc@2.16.4': + resolution: {integrity: sha512-CHkotYE/cNiUjJmrc5FD9YhlFp1UF5wMNNJmoWaL40eBzsqcaV0sSn5V3bNapwewn3wrMYgdPgvOTHfaZaG73A==} + engines: {node: '>= 12.0.0', parcel: ^2.16.4} + + '@parcel/runtime-service-worker@2.16.4': + resolution: {integrity: sha512-FT0Q58bf5Re+dq5cL2XHbxqHHFZco6qtRijeVpT3TSPMRPlniMArypSytTeZzVNL7h/hxjWsNu7fRuC0yLB5hA==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/rust-darwin-arm64@2.16.4': + resolution: {integrity: sha512-P3Se36H9EO1fOlwXqQNQ+RsVKTGn5ztRSUGbLcT8ba6oOMmU1w7J4R810GgsCbwCuF10TJNUMkuD3Q2Sz15Q3Q==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@parcel/rust-darwin-x64@2.16.4': + resolution: {integrity: sha512-8aNKNyPIx3EthYpmVJevIdHmFsOApXAEYGi3HU69jTxLgSIfyEHDdGE9lEsMvhSrd/SSo4/euAtiV+pqK04wnA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@parcel/rust-linux-arm-gnueabihf@2.16.4': + resolution: {integrity: sha512-QrvqiSHaWRLc0JBHgUHVvDthfWSkA6AFN+ikV1UGENv4j2r/QgvuwJiG0VHrsL6pH5dRqj0vvngHzEgguke9DA==} + engines: {node: '>= 10'} + cpu: [arm] + os: [linux] + + '@parcel/rust-linux-arm64-gnu@2.16.4': + resolution: {integrity: sha512-f3gBWQHLHRUajNZi3SMmDQiEx54RoRbXtZYQNuBQy7+NolfFcgb1ik3QhkT7xovuTF/LBmaqP3UFy0PxvR/iwQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@parcel/rust-linux-arm64-musl@2.16.4': + resolution: {integrity: sha512-cwml18RNKsBwHyZnrZg4jpecXkWjaY/mCArocWUxkFXjjB97L56QWQM9W86f2/Y3HcFcnIGJwx1SDDKJrV6OIA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@parcel/rust-linux-x64-gnu@2.16.4': + resolution: {integrity: sha512-0xIjQaN8hiG0F9R8coPYidHslDIrbfOS/qFy5GJNbGA3S49h61wZRBMQqa7JFW4+2T8R0J9j0SKHhLXpbLXrIg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@parcel/rust-linux-x64-musl@2.16.4': + resolution: {integrity: sha512-fYn21GIecHK9RoZPKwT9NOwxwl3Gy3RYPR6zvsUi0+hpFo19Ph9EzFXN3lT8Pi5KiwQMCU4rsLb5HoWOBM1FeA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@parcel/rust-win32-x64-msvc@2.16.4': + resolution: {integrity: sha512-TcpWC3I1mJpfP2++018lgvM7UX0P8IrzNxceBTHUKEIDMwmAYrUKAQFiaU0j1Ldqk6yP8SPZD3cvphumsYpJOQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@parcel/rust@2.16.4': + resolution: {integrity: sha512-RBMKt9rCdv6jr4vXG6LmHtxzO5TuhQvXo1kSoSIF7fURRZ81D1jzBtLxwLmfxCPsofJNqWwdhy5vIvisX+TLlQ==} + engines: {node: '>= 16.0.0'} + peerDependencies: + napi-wasm: ^1.1.2 + peerDependenciesMeta: + napi-wasm: + optional: true + + '@parcel/source-map@2.1.1': + resolution: {integrity: sha512-Ejx1P/mj+kMjQb8/y5XxDUn4reGdr+WyKYloBljpppUy8gs42T+BNoEOuRYqDVdgPc6NxduzIDoJS9pOFfV5Ew==} + engines: {node: ^12.18.3 || >=14} + + '@parcel/transformer-babel@2.16.4': + resolution: {integrity: sha512-CMDUOQYX7+cmeyHxHSFnoPcwvXNL7rRFE+Q06uVFzsYYiVhbwGF/1J5Bx4cW3Froumqla4YTytTsEteJEybkdA==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/transformer-css@2.16.4': + resolution: {integrity: sha512-VG/+DbDci2HKe20GFRDs65ZQf5GUFfnmZAa1BhVl/MO+ijT3XC3eoVUy5cExRkq4VLcPY4ytL0g/1T2D6x7lBQ==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/transformer-html@2.16.4': + resolution: {integrity: sha512-w6JErYTeNS+KAzUAER18NHFIFFvxiLGd4Fht1UYcb/FDjJdLAMB/FljyEs0Rto/WAhZ2D0MuSL25HQh837R62g==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/transformer-image@2.16.4': + resolution: {integrity: sha512-ZzIn3KvvRqMfcect4Dy+57C9XoQXZhpVJKBdQWMp9wM1qJEgsVgGDcaSBYCs/UYSKMRMP6Wm20pKCt408RkQzg==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + peerDependencies: + '@parcel/core': ^2.16.4 + + '@parcel/transformer-js@2.16.4': + resolution: {integrity: sha512-FD2fdO6URwAGBPidb3x1dDgLBt972mko0LelcSU05aC/pcKaV9mbCtINbPul1MlStzkxDelhuImcCYIyerheVQ==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + peerDependencies: + '@parcel/core': ^2.16.4 + + '@parcel/transformer-json@2.16.4': + resolution: {integrity: sha512-pB3ZNqgokdkBCJ+4G0BrPYcIkyM9K1HVk0GvjzcLEFDKsoAp8BGEM68FzagFM/nVq9anYTshIaoh349GK0M/bg==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/transformer-node@2.16.4': + resolution: {integrity: sha512-7t43CPGfMJk1LqFokwxHSsRi+kKC2QvDXaMtqiMShmk50LCwn81WgzuFvNhMwf6lSiBihWupGwF3Fqksg+aisg==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/transformer-postcss@2.16.4': + resolution: {integrity: sha512-jfmh9ho03H+qwz9S1b/a/oaOmgfMovtHKYDweIGMjKULKIee3AFRqo8RZIOuUMjDuqHWK8SqQmjery4syFV3Xw==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/transformer-posthtml@2.16.4': + resolution: {integrity: sha512-+GXsmGx1L25KQGQnwclgEuQe1t4QU+IoDkgN+Ikj+EnQCOWG4/ts2VpMBeqP5F18ZT4cCSRafj6317o/2lSGJg==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/transformer-raw@2.16.4': + resolution: {integrity: sha512-7WDUPq+bW11G9jKxaQIVL+NPGolV99oq/GXhpjYip0SaGaLzRCW7gEk60cftuk0O7MsDaX5jcAJm3G/AX+LJKg==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/transformer-react-refresh-wrap@2.16.4': + resolution: {integrity: sha512-MiLNZrsGQJTANKKa4lzZyUbGj/en0Hms474mMdQkCBFg6GmjfmXwaMMgtTfPA3ZwSp2+3LeObCyca/f9B2gBZQ==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/transformer-svg@2.16.4': + resolution: {integrity: sha512-0dm4cQr/WpfQP6N0xjFtwdLTxcONDfoLgTOMk4eNUWydHipSgmLtvUk/nOc/FWkwztRScfAObtZXOiPOd3Oy9A==} + engines: {node: '>= 16.0.0', parcel: ^2.16.4} + + '@parcel/types-internal@2.16.4': + resolution: {integrity: sha512-PE6Qmt5cjzBxX+6MPLiF7r+twoC+V9Skt3zyuBQ+H1c0i9o07Bbz2NKX10nvlPukfmW6Fu/1RvTLkzBZR1bU6A==} + + '@parcel/types@2.16.4': + resolution: {integrity: sha512-ctx4mBskZHXeDVHg4OjMwx18jfYH9BzI/7yqbDQVGvd5lyA+/oVVzYdpele2J2i2sSaJ87cA8nb57GDQ8kHAqA==} + + '@parcel/utils@2.16.4': + resolution: {integrity: sha512-lkmxQHcHyOWZLbV8t+h2CGZIkPiBurLm/TS5wNT7+tq0qt9KbVwL7FP2K93TbXhLMGTmpI79Bf3qKniPM167Mw==} + engines: {node: '>= 16.0.0'} + + '@parcel/watcher-android-arm64@2.5.6': + resolution: {integrity: sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + + '@parcel/watcher-darwin-arm64@2.5.6': + resolution: {integrity: sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + + '@parcel/watcher-darwin-x64@2.5.6': + resolution: {integrity: sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + + '@parcel/watcher-freebsd-x64@2.5.6': + resolution: {integrity: sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + + '@parcel/watcher-linux-arm-glibc@2.5.6': + resolution: {integrity: sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-arm-musl@2.5.6': + resolution: {integrity: sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + libc: [musl] + + '@parcel/watcher-linux-arm64-glibc@2.5.6': + resolution: {integrity: sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-arm64-musl@2.5.6': + resolution: {integrity: sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@parcel/watcher-linux-x64-glibc@2.5.6': + resolution: {integrity: sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@parcel/watcher-linux-x64-musl@2.5.6': + resolution: {integrity: sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@parcel/watcher-win32-arm64@2.5.6': + resolution: {integrity: sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + + '@parcel/watcher-win32-ia32@2.5.6': + resolution: {integrity: sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + + '@parcel/watcher-win32-x64@2.5.6': + resolution: {integrity: sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + '@parcel/watcher@2.0.4': resolution: {integrity: sha512-cTDi+FUDBIUOBKEtj+nhiJ71AZVlkAsQFuGQTun5tV9mwQBQgZvhCzG+URPQc8myeN32yRVZEfVAPCs1RW+Jvg==} engines: {node: '>= 10.0.0'} + '@parcel/watcher@2.5.6': + resolution: {integrity: sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==} + engines: {node: '>= 10.0.0'} + + '@parcel/workers@2.16.4': + resolution: {integrity: sha512-dkBEWqnHXDZnRbTZouNt4uEGIslJT+V0c8OH1MPOfjISp1ucD6/u9ET8k9d/PxS9h1hL53og0SpBuuSEPLDl6A==} + engines: {node: '>= 16.0.0'} + peerDependencies: + '@parcel/core': ^2.16.4 + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} @@ -4227,6 +6399,14 @@ packages: '@protobufjs/utf8@1.1.1': resolution: {integrity: sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==} + '@pyramation/json-schema-ref-parser@9.0.6': + resolution: {integrity: sha512-L5kToHAEc1Q87R8ZwWFaNa4tPHr8Hnm+U+DRdUVq3tUtk+EX4pCqSd34Z6EMxNi/bjTzt1syAG9J2Oo1YFlqSg==} + + '@pyramation/json-schema-to-typescript@11.0.4': + resolution: {integrity: sha512-+aSzXDLhMHOEdV2cJ7Tjg/9YenjHU5BCmClVygzwxJZ1R16NOfEn7lTAwVzb/2jivOSnhjHzMJbnSf8b6rd1zg==} + engines: {node: '>=12.0.0'} + hasBin: true + '@react-aria/listbox@3.16.0': resolution: {integrity: sha512-Jv6aTJECRntBvG+0ZQtXniAtHEQjvEi2QSm35FxRcsB8kgv7TmcinUOSZuHe5r8RDY2djILwdrqmfy6ApX0MDA==} peerDependencies: @@ -4286,15 +6466,138 @@ packages: resolution: {integrity: sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==} engines: {node: '>=14.0.0'} + '@rollup/plugin-commonjs@24.1.0': + resolution: {integrity: sha512-eSL45hjhCWI0jCCXcNtLVqM5N1JlBGvlFfY0m6oOYnLCJ6N0qEXoZql4sY2MOUArzhH4SA/qBpTxvvZp2Sc+DQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.68.0||^3.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-inject@5.0.5': + resolution: {integrity: sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-json@6.1.0': + resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-node-resolve@15.3.1': + resolution: {integrity: sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-replace@5.0.7': + resolution: {integrity: sha512-PqxSfuorkHz/SPpyngLyg5GCEkOcee9M1bkxiVDr41Pd61mqP1PLOoDPbpl44SB2mQGKwV/In74gqQmGITOhEQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-terser@0.2.1': + resolution: {integrity: sha512-hV52c8Oo6/cXZZxVVoRNBb4zh+EKSHS4I1sedWV5pf0O+hTLSkrf6w86/V0AZutYtwBguB6HLKwz89WDBfwGOA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.x || ^3.x + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-typescript@10.0.1': + resolution: {integrity: sha512-wBykxRLlX7EzL8BmUqMqk5zpx2onnmRMSw/l9M1sVfkJvdwfxogZQVNUM9gVMJbjRLDR5H6U0OMOrlDGmIV45A==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.14.0||^3.0.0 + tslib: '*' + typescript: '>=3.7.0' + peerDependenciesMeta: + rollup: + optional: true + tslib: + optional: true + + '@rollup/plugin-typescript@11.1.6': + resolution: {integrity: sha512-R92yOmIACgYdJ7dJ97p4K69I8gg6IEHt8M7dUBxN3W6nrO8uUxX5ixl0yU/N3aZTi8WhPuICvOHXQvF6FaykAA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.14.0||^3.0.0||^4.0.0 + tslib: '*' + typescript: '>=3.7.0' + peerDependenciesMeta: + rollup: + optional: true + tslib: + optional: true + + '@rollup/plugin-url@8.0.2': + resolution: {integrity: sha512-5yW2LP5NBEgkvIRSSEdJkmxe5cUNZKG3eenKtfJvSkxVm/xTTu7w+ayBtNwhozl1ZnTUCU0xFaRQR+cBl2H7TQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-wasm@6.2.2': + resolution: {integrity: sha512-gpC4R1G9Ni92ZIRTexqbhX7U+9estZrbhP+9SRb0DW9xpB9g7j34r+J2hqrcW/lRI7dJaU84MxZM0Rt82tqYPQ==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/pluginutils@3.1.0': + resolution: {integrity: sha512-GksZ6pr6TpIjHm8h9lSQ8pi8BE9VeubNT0OMJ3B5uZJ8pz73NPiqOtCog/x2/QzM1ENChPKxMDhiQuRHsqc+lg==} + engines: {node: '>= 8.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0 + + '@rollup/pluginutils@5.4.0': + resolution: {integrity: sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + '@rtsao/scc@1.1.0': resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==} '@rushstack/eslint-patch@1.16.1': resolution: {integrity: sha512-TvZbIpeKqGQQ7X0zSCvPH9riMSFQFSggnfBjFZ1mEoILW+UuXCKwOoPcgjMwiUtRqFZ8jWhPJc4um14vC6I4ag==} + '@sapphire/utilities@3.18.2': + resolution: {integrity: sha512-QGLdC9+pT74Zd7aaObqn0EUfq40c4dyTL65pFnkM6WO1QYN7Yg/s4CdH+CXmx0Zcu6wcfCWILSftXPMosJHP5A==} + engines: {node: '>=v14.0.0'} + '@scure/base@1.2.6': resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} + '@scure/bip32@1.7.0': + resolution: {integrity: sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==} + + '@scure/bip39@1.6.0': + resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} + '@scure/starknet@1.1.0': resolution: {integrity: sha512-83g3M6Ix2qRsPN4wqLDqiRZ2GBNbjVWfboJE/9UjfG+MHr6oDSu/CWgy8hsBSJejr09DkkL+l0Ze4KVrlCIdtQ==} @@ -4323,6 +6626,9 @@ packages: resolution: {integrity: sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + '@sinclair/typebox@0.24.51': + resolution: {integrity: sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==} + '@sinclair/typebox@0.27.10': resolution: {integrity: sha512-MTBk/3jGLNB2tVxv6uLlFh1iu64iYOQ2PbdOSK3NW8JZsmlaOh2q6sdtKowBhfw8QFLmYNzTW4/oK4uATIi6ZA==} @@ -4861,6 +7167,93 @@ packages: resolution: {integrity: sha512-cQ/AsnBkXPkEK8cLbv4Dm7JGXq2XrumKnL1dRpJD9rIO2fTIlJI9a1uCciYG1F2aUsox/hJQyNGbt3soDxSRkA==} engines: {node: '>=10'} + '@swc/core-darwin-arm64@1.15.40': + resolution: {integrity: sha512-PaYyclfmQ++77D8ityYvmmVzHv9aG8ROwt2GfG6/ccloy4Hgf80qtOnzb9VYvPsUT7Ty1uhuDRhv3XYpf62qhQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-x64@1.15.40': + resolution: {integrity: sha512-HbbPzvfLBUXjIB1Ezks+//lNUjmLjfyd63XSwprJgrZaXYdm70kohXPJUWdqKZozolFxbPaO+xtBaiUp6BoueA==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-linux-arm-gnueabihf@1.15.40': + resolution: {integrity: sha512-SlRZsCjOCPR2LvFs0Ri/Xrx/5o5TCt8vl4gW6mX1hEZOG0a625RxzRHpHdAQNGykmAN/7IeaFAJG+QnNmxlHcA==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm64-gnu@1.15.40': + resolution: {integrity: sha512-Q8byxJt2fh8CR3EUX6snBpy47AoBVm+In/+Z3rjDHMjC38ZvR9/gtUUNCT0tfrn4EdVsO8/QPi59nxrxvqxvBQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@swc/core-linux-arm64-musl@1.15.40': + resolution: {integrity: sha512-4z0MgHU+7M0pZDqBN1El7mFXDI1SBwinfcUkAyA4v8QrhOIUOZltySt2aStQLZGrdXVXM4Y4ylfiTC04ED+MoQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@swc/core-linux-ppc64-gnu@1.15.40': + resolution: {integrity: sha512-fLI4iUgeSZu0eRWUXwe6YzPFx9gHbFiPkl8Rp3mJfP8OpNR3nTQCGPvHdDh9xniW7mVvgMY4ni7A4VzqI1KrpA==} + engines: {node: '>=10'} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@swc/core-linux-s390x-gnu@1.15.40': + resolution: {integrity: sha512-YqeKMAb7d4nQSGMJQ454IlaCENpzcDqhvBE9+CPfdnYpnUXxd+BSrB6Xk0YjW8UyoEhUj4p6quATCxbsp6J3jg==} + engines: {node: '>=10'} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@swc/core-linux-x64-gnu@1.15.40': + resolution: {integrity: sha512-7HOuS1iGcme/j/TuL1TfmmLGiMQrjv/GmjyZeydl00FKPtpGXEldwqfI56xgd1YzrzoB2svWjxbGGyQ0TEASxg==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@swc/core-linux-x64-musl@1.15.40': + resolution: {integrity: sha512-h4kZYHc7dpc9P9u4brRJaS8Pl7tPVHAeiLSzw7T5RfIJgAoSdaCMKzI/2Uay9gFhaw8uyCDl0L5q37r0EpAfIA==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@swc/core-win32-arm64-msvc@1.15.40': + resolution: {integrity: sha512-+mQgKZXSj6mV38Zh05QaxSjUDmGP/R2JWlXZTDLSPkDzHU6p3GxN9eeSf5dfyDVU86946fmCvSzyl/ucImx8+A==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/core-win32-ia32-msvc@1.15.40': + resolution: {integrity: sha512-yvwdPLGd25mcj/mNatjNQ0lZujtQD6psH3v9PNmMb+fSzjbNG8KIDxjFWrcV+fsFVLOkyOmdJsFmX7NAFjVyPw==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.15.40': + resolution: {integrity: sha512-OXtKsLU1bVtInzzDEAY2sYiF/rl4tvAnLLLpuMp3HzAOQZ5A+i69AKDhA1YLQTaMAqO3vzyYNVAYVRMPtSYD4w==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core@1.15.40': + resolution: {integrity: sha512-2kwzJikRvgtNAG7MwVZY2vEzZjTxKIq5jXOihuSV/8U+Hej8Va22t65aKnJZs3P+NwojZvR8Mf8kyM7O+V8sQg==} + engines: {node: '>=10'} + peerDependencies: + '@swc/helpers': '>=0.5.17' + peerDependenciesMeta: + '@swc/helpers': + optional: true + '@swc/counter@0.1.3': resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} @@ -4870,6 +7263,9 @@ packages: '@swc/helpers@0.5.5': resolution: {integrity: sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==} + '@swc/types@0.1.26': + resolution: {integrity: sha512-lyMwd7WGgG79RS7EERZV3T8wMdmPq3xwyg+1nmAM64kIhx5yl+juO2PYIHb7vTiPgPCj8LYjsNV2T5wiQHUEaw==} + '@tanstack/match-sorter-utils@8.19.4': resolution: {integrity: sha512-Wo1iKt2b9OT7d+YGhvEPD3DXvPv2etTusIMhMUoG7fbhmxcXCtIjJDEygy91Y2JFlwGyjqiBPRozme7UD8hoqg==} engines: {node: '>=12'} @@ -5041,10 +7437,21 @@ packages: resolution: {integrity: sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g==} engines: {node: '>=12'} + '@testing-library/jest-dom@5.17.0': + resolution: {integrity: sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg==} + engines: {node: '>=8', npm: '>=6', yarn: '>=1'} + '@testing-library/jest-dom@6.9.1': resolution: {integrity: sha512-zIcONa+hVtVSSep9UT3jZ5rizo2BsxgyDYU7WFD5eICBE7no3881HGeb/QkGfsJs6JTkY1aQhT7rIPC7e+0nnA==} engines: {node: '>=14', npm: '>=6', yarn: '>=1'} + '@testing-library/react@12.1.5': + resolution: {integrity: sha512-OfTXCJUFgjd/digLUuPxa0+/3ZxsQmE7ub9kcbW/wi96Bh3o/p5vrETcBGfP17NWPGqeYYl5LTRpwyGoMC4ysg==} + engines: {node: '>=12'} + peerDependencies: + react: <18.0.0 + react-dom: <18.0.0 + '@testing-library/react@16.3.2': resolution: {integrity: sha512-XU5/SytQM+ykqMnAnvB2umaJNIOsLF3PVv//1Ew4CTcpz0/BRyy/af40qqrt7SjKpDdT1saBMc42CUok5gaw+g==} engines: {node: '>=18'} @@ -5175,6 +7582,9 @@ packages: '@types/estree-jsx@1.0.5': resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + '@types/estree@0.0.39': + resolution: {integrity: sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==} + '@types/estree@0.0.51': resolution: {integrity: sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==} @@ -5236,6 +7646,9 @@ packages: '@types/istanbul-reports@3.0.4': resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + '@types/jest@27.5.2': + resolution: {integrity: sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==} + '@types/jest@29.5.14': resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} @@ -5323,6 +7736,11 @@ packages: '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + '@types/react-dom@17.0.26': + resolution: {integrity: sha512-Z+2VcYXJwOqQ79HreLU/1fyQ88eXSSFh6I3JdrEHQIfYSI0kCQpTGvOrbE6jFGGYXKsHuwY9tBa/w5Uo6KzrEg==} + peerDependencies: + '@types/react': ^17.0.0 + '@types/react-dom@19.2.3': resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==} peerDependencies: @@ -5336,9 +7754,15 @@ packages: '@types/react@19.2.14': resolution: {integrity: sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==} + '@types/resolve@1.20.2': + resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + '@types/retry@0.12.0': resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} + '@types/rimraf@3.0.2': + resolution: {integrity: sha512-F3OznnSLAUxFrCEu/L5PY8+ny8DtcFRjx7fZZ9bycvXRi3KPTRS9HOitGZwvPg0juRhXFWIeKX58cnX5YqLohQ==} + '@types/semver@7.7.1': resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} @@ -5354,6 +7778,9 @@ packages: '@types/serve-static@1.15.10': resolution: {integrity: sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==} + '@types/shelljs@0.8.15': + resolution: {integrity: sha512-vzmnCHl6hViPu9GNLQJ+DZFd6BQI2DBTUeOvYHqkWQLMfKAAQYMb/xAmZkTogZI/vqXHCWkqDRymDI5p0QTi5Q==} + '@types/sockjs@0.3.36': resolution: {integrity: sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==} @@ -5366,6 +7793,9 @@ packages: '@types/tapable@1.0.12': resolution: {integrity: sha512-bTHG8fcxEqv1M9+TD14P8ok8hjxoOCkfKc8XXLaaD05kI7ohpeI956jtDOD3XHKBQrlyPughUtzm1jtVhHpA5Q==} + '@types/testing-library__jest-dom@5.14.9': + resolution: {integrity: sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw==} + '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} @@ -5801,11 +8231,25 @@ packages: webpack: 4.x.x || 5.x.x webpack-cli: 4.x.x + '@webpack-cli/configtest@2.1.1': + resolution: {integrity: sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==} + engines: {node: '>=14.15.0'} + peerDependencies: + webpack: 5.x.x + webpack-cli: 5.x.x + '@webpack-cli/info@1.5.0': resolution: {integrity: sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ==} peerDependencies: webpack-cli: 4.x.x + '@webpack-cli/info@2.0.2': + resolution: {integrity: sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==} + engines: {node: '>=14.15.0'} + peerDependencies: + webpack: 5.x.x + webpack-cli: 5.x.x + '@webpack-cli/serve@1.7.0': resolution: {integrity: sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q==} peerDependencies: @@ -5815,6 +8259,17 @@ packages: webpack-dev-server: optional: true + '@webpack-cli/serve@2.0.5': + resolution: {integrity: sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==} + engines: {node: '>=14.15.0'} + peerDependencies: + webpack: 5.x.x + webpack-cli: 5.x.x + webpack-dev-server: '*' + peerDependenciesMeta: + webpack-dev-server: + optional: true + '@xtuc/ieee754@1.2.0': resolution: {integrity: sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==} @@ -5953,6 +8408,14 @@ packages: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} + ansi-escapes@2.0.0: + resolution: {integrity: sha512-tH/fSoQp4DrEodDK3QpdiWiZTSe7sBJ9eOqcQBZ0o9HTM+5M/viSEn+sPMoTuPjQQ8n++w3QJoPEjt8LVPcrCg==} + engines: {node: '>=4'} + + ansi-escapes@3.2.0: + resolution: {integrity: sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==} + engines: {node: '>=4'} + ansi-escapes@4.3.2: resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} engines: {node: '>=8'} @@ -5971,6 +8434,14 @@ packages: resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} engines: {node: '>=0.10.0'} + ansi-regex@3.0.1: + resolution: {integrity: sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==} + engines: {node: '>=4'} + + ansi-regex@4.1.1: + resolution: {integrity: sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==} + engines: {node: '>=6'} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -5979,6 +8450,13 @@ packages: resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} engines: {node: '>=12'} + ansi-sequence-parser@1.1.3: + resolution: {integrity: sha512-+fksAx9eG3Ab6LDnLs3ZqZa8KVJ/jYnX+D4Qe1azX+LFGFAXqynCQLOdLpNYN/l9e7l6hMWwZbrnctqr6eSQSw==} + + ansi-styles@2.2.1: + resolution: {integrity: sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA==} + engines: {node: '>=0.10.0'} + ansi-styles@3.2.1: resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} engines: {node: '>=4'} @@ -6003,6 +8481,9 @@ packages: ansicolors@0.3.2: resolution: {integrity: sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg==} + any-promise@1.3.0: + resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==} + anymatch@2.0.0: resolution: {integrity: sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==} @@ -6149,6 +8630,9 @@ packages: resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} engines: {node: '>=0.10.0'} + ast-stringify@0.2.1: + resolution: {integrity: sha512-wS/5cTSysM/IL1NVAwI2/xhFDI08UEw4PpLsbpDfc1KEPc2ABo94pjvB5p/tIF+Qu7oFOdxx8TdlGhyu4ZOb3A==} + ast-types-flow@0.0.8: resolution: {integrity: sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ==} @@ -6160,6 +8644,10 @@ packages: resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==} engines: {node: '>=4'} + astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + async-each@1.0.6: resolution: {integrity: sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg==} @@ -6186,6 +8674,10 @@ packages: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} + attr-accept@2.2.5: + resolution: {integrity: sha512-0bDNnY/u6pPwHDMoF0FieU354oBi0a8rD9FcsLwzcGWbc8KS8KPIi7y+s13OlVY+gMWc/9xEMUgNE6Qm8ZllYQ==} + engines: {node: '>=4'} + author-regex@1.0.0: resolution: {integrity: sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g==} engines: {node: '>=0.8'} @@ -6231,6 +8723,13 @@ packages: '@babel/core': ^7.0.0 webpack: '>=2' + babel-loader@9.2.1: + resolution: {integrity: sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==} + engines: {node: '>= 14.15.0'} + peerDependencies: + '@babel/core': ^7.12.0 + webpack: '>=5' + babel-plugin-add-react-displayname@0.0.5: resolution: {integrity: sha512-LY3+Y0XVDYcShHHorshrDbt4KFWL4bSeniCtl4SYZbask+Syngk1uMPCeN9+nSiZo6zX5s0RTq/J9Pnaaf/KHw==} @@ -6327,6 +8826,10 @@ packages: resolution: {integrity: sha512-qK6gt2fMSxN2xGOi+btI5oAnXL+vEq0AsHWHhf5jfm2hE6MwmW+2414qF96utV3Xfg3En8hEA9Q4lif4lbXcgw==} engines: {node: '>= 6'} + base64-arraybuffer-es6@0.7.0: + resolution: {integrity: sha512-ESyU/U1CFZDJUdr+neHRhNozeCv72Y7Vm0m1DCbjX3KBjT6eYocvAJlSk6+8+HkVwXlT1FNxhGW6q3UKAlCvvw==} + engines: {node: '>=6.0.0'} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -6345,6 +8848,9 @@ packages: bech32@1.1.4: resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==} + bech32@2.0.0: + resolution: {integrity: sha512-LcknSilhIGatDAsY1ak2I8VtGaHNhgMSYVxFrGLXv+xLHytaKZKcaUJJUE7qmBr7h33o5YQwP55pMI0xmkpJwg==} + before-after-hook@2.2.3: resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} @@ -6455,6 +8961,9 @@ packages: browser-process-hrtime@1.0.0: resolution: {integrity: sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==} + browser-stdout@1.3.1: + resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} + browserify-aes@1.2.0: resolution: {integrity: sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==} @@ -6517,6 +9026,10 @@ packages: builtins@5.1.0: resolution: {integrity: sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==} + bundle-name@4.1.0: + resolution: {integrity: sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==} + engines: {node: '>=18'} + busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} @@ -6617,6 +9130,10 @@ packages: resolution: {integrity: sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw==} engines: {node: '>=4'} + case@1.6.3: + resolution: {integrity: sha512-mzDSXIPaFwVDvZAHqZ9VlbyF4yyXRuX6IvB06WvPYkqJVO24kX1PPhv9bfpKNFZyxYFmmgo03HUiD8iklmJYRQ==} + engines: {node: '>= 0.8.0'} + ccount@1.1.0: resolution: {integrity: sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==} @@ -6626,10 +9143,18 @@ packages: chain-registry@1.69.578: resolution: {integrity: sha512-+e8L9LiKbeY2ixZNwd3zK5betftJfe+ZFl6sWbcmUoKm2vkK0VFnojbUu3aWZqq6FtDHHuaYib/CkUYXWxZHYg==} + chalk@1.1.3: + resolution: {integrity: sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A==} + engines: {node: '>=0.10.0'} + chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} + chalk@3.0.0: + resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==} + engines: {node: '>=8'} + chalk@4.1.0: resolution: {integrity: sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==} engines: {node: '>=10'} @@ -6663,6 +9188,12 @@ packages: character-reference-invalid@2.0.1: resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + chardet@0.4.2: + resolution: {integrity: sha512-j/Toj7f1z98Hh2cYo2BVr85EpIRWqUi7rtRSGxh/cqUjqrnJe9l9UE7IUGd2vQ2p+kSHLkSzObQPZPLUC6TQwg==} + + chardet@0.7.0: + resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + chardet@2.1.1: resolution: {integrity: sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==} @@ -6731,6 +9262,14 @@ packages: resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==} engines: {node: '>=6'} + cli-color@2.0.4: + resolution: {integrity: sha512-zlnpg0jNcibNrO7GG9IeHH7maWFeCz+Ja1wx/7tZNU5ASSSSZ+/qZciM0/LHCYxSdqv5h2sdbQ/PXYdOuetXvA==} + engines: {node: '>=0.10'} + + cli-cursor@2.1.0: + resolution: {integrity: sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==} + engines: {node: '>=4'} + cli-cursor@3.1.0: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} @@ -6747,6 +9286,9 @@ packages: resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} engines: {node: 10.* || >= 12.*} + cli-width@2.2.1: + resolution: {integrity: sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==} + cli-width@3.0.0: resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} engines: {node: '>= 10'} @@ -6772,6 +9314,10 @@ packages: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} + clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + clsx@1.1.0: resolution: {integrity: sha512-3avwM37fSK5oP6M5rQ9CNe99lwxhXDOeSWVPAOYF6OazUTgZCMb0yWlJpmdD74REy1gkEaFiub2ULv4fq9GUhA==} engines: {node: '>=6'} @@ -6838,6 +9384,10 @@ packages: colornames@1.1.1: resolution: {integrity: sha512-/pyV40IrsdulWv+wFPmERh9k/mjsPZ64yUMDmWrtj/k1nmgrzzIENWKdaVKyBbvFdQWqkcaRxr+polCo3VMe7A==} + colors@1.4.0: + resolution: {integrity: sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==} + engines: {node: '>=0.1.90'} + columnify@1.6.0: resolution: {integrity: sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==} engines: {node: '>=8.0.0'} @@ -6846,12 +9396,27 @@ packages: resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} engines: {node: '>= 0.8'} + comlink@4.4.2: + resolution: {integrity: sha512-OxGdvBmJuNKSCMO4NTl1L47VRp6xn2wG4F/2hYzB6tiCb709otOxtEYCSvK80PtjODfXXZu8ds+Nw5kVCjqd2g==} + comma-separated-tokens@1.0.8: resolution: {integrity: sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==} comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + + commander@12.1.0: + resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} + engines: {node: '>=18'} + + commander@14.0.3: + resolution: {integrity: sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==} + engines: {node: '>=20'} + commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -6871,6 +9436,13 @@ packages: resolution: {integrity: sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==} engines: {node: '>= 12'} + commander@9.5.0: + resolution: {integrity: sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==} + engines: {node: ^12.20.0 || >=14} + + common-path-prefix@3.0.0: + resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} + commondir@1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} @@ -6981,6 +9553,12 @@ packages: copy-to-clipboard@3.3.3: resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} + copy-webpack-plugin@11.0.0: + resolution: {integrity: sha512-fX2MWpamkW0hZxMEg0+mYnA40LTosOSa5TqZ9GYIBzyJa9C3QUaMPSE2xAi/buNr8u89SfD9wHSQVBzrRa/SOQ==} + engines: {node: '>= 14.15.0'} + peerDependencies: + webpack: ^5.1.0 + core-js-compat@3.49.0: resolution: {integrity: sha512-VQXt1jr9cBz03b331DFDCCP90b3fanciLkgiOoy8SBHy06gNf+vQ1A3WFLqG7I8TipYIKeYK9wxd0tUrvHcOZA==} @@ -7013,6 +9591,12 @@ packages: cosmjs-types@0.10.1: resolution: {integrity: sha512-CENXb4O5GN+VyB68HYXFT2SOhv126Z59631rZC56m8uMWa6/cSlFeai8BwZGT1NMepw0Ecf+U8XSOnBzZUWh9Q==} + cosmjs-types@0.4.1: + resolution: {integrity: sha512-I7E/cHkIgoJzMNQdFF0YVqPlaTqrqKHrskuSTIqlEyxfB5Lf3WKCajSXVK2yHOfOFfSux/RxEdpMzw/eO4DIog==} + + cosmjs-types@0.5.2: + resolution: {integrity: sha512-zxCtIJj8v3Di7s39uN4LNcN3HIE1z0B9Z0SPE8ZNQR0oSzsuSe1ACgxoFkvhkS7WBasCAFcglS11G2hyfd5tPg==} + cosmjs-types@0.9.0: resolution: {integrity: sha512-MN/yUe6mkJwHnCFfsNPeCfXVhyxHYW6c/xDUzrSbBycYzw++XvWDMJArXp2pLdgD6FQ8DW79vkPjeNKVrXaHeQ==} @@ -7065,6 +9649,12 @@ packages: peerDependencies: postcss: ^8.0.9 + css-declaration-sorter@7.4.0: + resolution: {integrity: sha512-LTuzjPoyA2vMGKKcaOqKSp7Ub2eGrNfKiZH4LpezxpNrsICGCSFvsQOI29psISxNZtaXibkC2CXzrQ5enMeGGw==} + engines: {node: ^14 || ^16 || >=18} + peerDependencies: + postcss: ^8.0.9 + css-loader@3.6.0: resolution: {integrity: sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ==} engines: {node: '>= 8.9.0'} @@ -7108,6 +9698,31 @@ packages: esbuild: optional: true + css-minimizer-webpack-plugin@5.0.1: + resolution: {integrity: sha512-3caImjKFQkS+ws1TGcFn0V1HyDJFq1Euy589JlD6/3rV2kj+w7r5G9WDMgSHvpvXHNZ2calVypZWuEDQd9wfLg==} + engines: {node: '>= 14.15.0'} + peerDependencies: + '@parcel/css': '*' + '@swc/css': '*' + clean-css: '*' + csso: '*' + esbuild: '*' + lightningcss: '*' + webpack: ^5.0.0 + peerDependenciesMeta: + '@parcel/css': + optional: true + '@swc/css': + optional: true + clean-css: + optional: true + csso: + optional: true + esbuild: + optional: true + lightningcss: + optional: true + css-select@4.3.0: resolution: {integrity: sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==} @@ -7151,18 +9766,36 @@ packages: peerDependencies: postcss: ^8.2.15 + cssnano-preset-default@6.1.2: + resolution: {integrity: sha512-1C0C+eNaeN8OcHQa193aRgYexyJtU8XwbdieEjClw+J9d94E41LwT6ivKH0WT+fYwYWB0Zp3I3IZ7tI/BbUbrg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + cssnano-utils@3.1.0: resolution: {integrity: sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + cssnano-utils@4.0.2: + resolution: {integrity: sha512-ZR1jHg+wZ8o4c3zqf1SIUSTIvm/9mU343FMR6Obe/unskbvpGhZOo1J6d/r8D1pzkRQYuwbcH3hToOuoA2G7oQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + cssnano@5.1.15: resolution: {integrity: sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + cssnano@6.1.2: + resolution: {integrity: sha512-rYk5UeX7VAM/u0lNqewCdasdtPK81CgX8wJFLEIXHbV2oldWRgJAsZrdhRXkV1NJzA2g850KiFm9mMU2HxNxMA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + csso@4.2.0: resolution: {integrity: sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==} engines: {node: '>=8.0.0'} @@ -7254,6 +9887,10 @@ packages: resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==} engines: {node: '>=12'} + d@1.0.2: + resolution: {integrity: sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==} + engines: {node: '>=0.12'} + damerau-levenshtein@1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} @@ -7324,6 +9961,10 @@ packages: resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} engines: {node: '>=0.10.0'} + decamelize@4.0.0: + resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} + engines: {node: '>=10'} + decimal.js-light@2.5.1: resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} @@ -7358,6 +9999,10 @@ packages: deep-object-diff@1.1.9: resolution: {integrity: sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==} + deepmerge@4.2.2: + resolution: {integrity: sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==} + engines: {node: '>=0.10.0'} + deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} @@ -7367,6 +10012,14 @@ packages: engines: {node: '>=0.10.0'} hasBin: true + default-browser-id@5.0.1: + resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} + engines: {node: '>=18'} + + default-browser@5.5.0: + resolution: {integrity: sha512-H9LMLr5zwIbSxrmvikGuI/5KGhZ8E2zH3stkMgM5LpOWDutGM2JZaj460Udnf1a+946zc7YBgrqEWwbk7zHvGw==} + engines: {node: '>=18'} + default-gateway@6.0.3: resolution: {integrity: sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==} engines: {node: '>= 10'} @@ -7382,6 +10035,10 @@ packages: resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} engines: {node: '>=8'} + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + define-properties@1.2.1: resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} @@ -7451,6 +10108,11 @@ packages: resolution: {integrity: sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==} engines: {node: '>=4'} + detect-libc@1.0.3: + resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} + engines: {node: '>=0.10'} + hasBin: true + detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} @@ -7478,10 +10140,22 @@ packages: resolution: {integrity: sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + diff-sequences@28.1.1: + resolution: {integrity: sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + diff-sequences@29.6.3: resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + diff@3.5.1: + resolution: {integrity: sha512-Z3u54A8qGyqFOSr2pk0ijYs8mOE9Qz8kTvtKeBI+upoG9j04Sq+oI7W8zAJiQybDcESET8/uIdHzs0p3k4fZlw==} + engines: {node: '>=0.3.1'} + + diff@5.2.2: + resolution: {integrity: sha512-vtcDfH3TOjP8UekytvnHH1o1P4FcUdt4eQ1Y+Abap1tk/OB2MWQvcwS2ClCd1zuIhc3JKOx6p3kod8Vfys3E+A==} + engines: {node: '>=0.3.1'} + diffie-hellman@5.0.3: resolution: {integrity: sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==} @@ -7533,6 +10207,10 @@ packages: domelementtype@2.3.0: resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + domexception@1.0.1: + resolution: {integrity: sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==} + deprecated: Use your platform's native DOMException instead + domexception@2.0.1: resolution: {integrity: sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==} engines: {node: '>=8'} @@ -7569,6 +10247,10 @@ packages: resolution: {integrity: sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==} engines: {node: '>=12'} + dotenv-expand@11.0.7: + resolution: {integrity: sha512-zIHwmZPRshsCdpMDyVsqGmgyP0yT8GAgXUnkdAoJisxvf33k7yO6OuoKmcTGuXPWSsm8Oh88nZicRLA9Y0rUeA==} + engines: {node: '>=12'} + dotenv-expand@5.1.0: resolution: {integrity: sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==} @@ -7578,10 +10260,20 @@ packages: peerDependencies: webpack: ^4 || ^5 + dotenv-webpack@8.1.1: + resolution: {integrity: sha512-+TY/AJ2k9bU2EML3mxgLmaAvEcqs1Wbv6deCIUSI3eW3Xeo8LBQumYib6puyaSwbjC9JCzg/y5Pwjd/lePX04w==} + engines: {node: '>=10'} + peerDependencies: + webpack: ^4 || ^5 + dotenv@16.3.2: resolution: {integrity: sha512-HTlk5nmhkm8F6JcdXvHIzaorzCoziNQT9mGxLPVXW8wJF1TiGSL60ZGB4gHWabHOaMmWmhvk2/lPHfnBiT78AQ==} engines: {node: '>=12'} + dotenv@16.6.1: + resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} + engines: {node: '>=12'} + dotenv@8.6.0: resolution: {integrity: sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g==} engines: {node: '>=10'} @@ -7738,13 +10430,27 @@ packages: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} + es5-ext@0.10.64: + resolution: {integrity: sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==} + engines: {node: '>=0.10'} + es5-shim@4.6.7: resolution: {integrity: sha512-jg21/dmlrNQI7JyyA2w7n+yifSxBng0ZralnSfVZjoCawgNTCnS+yBCyVM9DL5itm7SUnDGgv7hcq2XCZX4iRQ==} engines: {node: '>=0.4.0'} + es6-iterator@2.0.3: + resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} + es6-shim@0.35.8: resolution: {integrity: sha512-Twf7I2v4/1tLoIXMT8HlqaBSS5H2wQTs2wx3MNYCI8K1R1/clXyCazrcVCPm/FuO9cyV8+leEaZOWD5C253NDg==} + es6-symbol@3.1.4: + resolution: {integrity: sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==} + engines: {node: '>=0.12'} + + es6-weak-map@2.0.3: + resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==} + esbuild-register@3.6.0: resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==} peerDependencies: @@ -7891,6 +10597,12 @@ packages: peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9 + eslint-plugin-mocha@10.5.0: + resolution: {integrity: sha512-F2ALmQVPT1GoP27O1JTZGrV9Pqg8k79OeIuvw63UxMtQKREZtmkK1NFgkZQ2TW7L2JSSFKHFPTtHu5z8R9QNRw==} + engines: {node: '>=14.0.0'} + peerDependencies: + eslint: '>=7.0.0' + eslint-plugin-prettier@4.2.5: resolution: {integrity: sha512-9Ni+xgemM2IWLq6aXEpP2+V/V30GeA/46Ar629vcMqVPodFFWC9skHu/D1phvuqtS8bJCFnNf01/qcmqYEwNfg==} engines: {node: '>=12.0.0'} @@ -7942,6 +10654,24 @@ packages: resolution: {integrity: sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + eslint-utils@2.1.0: + resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} + engines: {node: '>=6'} + + eslint-utils@3.0.0: + resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} + engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} + peerDependencies: + eslint: '>=5' + + eslint-visitor-keys@1.3.0: + resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} + engines: {node: '>=4'} + + eslint-visitor-keys@2.1.0: + resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} + engines: {node: '>=10'} + eslint-visitor-keys@3.4.3: resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -7954,6 +10684,12 @@ packages: resolution: {integrity: sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==} engines: {node: ^20.19.0 || ^22.13.0 || >=24} + eslint@7.32.0: + resolution: {integrity: sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==} + engines: {node: ^10.12.0 || >=12.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. + hasBin: true + eslint@8.57.1: resolution: {integrity: sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -7970,10 +10706,18 @@ packages: jiti: optional: true + esniff@2.0.1: + resolution: {integrity: sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==} + engines: {node: '>=0.10'} + espree@10.4.0: resolution: {integrity: sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + espree@7.3.1: + resolution: {integrity: sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==} + engines: {node: ^10.12.0 || >=12.0.0} + espree@9.6.1: resolution: {integrity: sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -8006,6 +10750,15 @@ packages: estree-util-is-identifier-name@3.0.0: resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + estree-walker@0.6.1: + resolution: {integrity: sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==} + + estree-walker@1.0.1: + resolution: {integrity: sha512-1fMXF3YP4pZZVozF8j/ZLfvnR8NSIljt56UhbZ5PeeDmmGHpgpdwQt7ITlGvYaQukCvuBRMLEiKiYC+oeIg4cg==} + + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -8014,6 +10767,13 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} + ethereum-cryptography@3.2.0: + resolution: {integrity: sha512-Urr5YVsalH+Jo0sYkTkv1MyI9bLYZwW8BENZCeE1QYaTHETEYx0Nv/SVsWkSqpYrzweg6d8KMY1wTjH/1m/BIg==} + engines: {node: ^14.21.3 || >=16, npm: '>=9'} + + event-emitter@0.3.5: + resolution: {integrity: sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==} + eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} @@ -8051,6 +10811,10 @@ packages: resolution: {integrity: sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + expect@28.1.3: + resolution: {integrity: sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + expect@29.7.0: resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -8062,6 +10826,9 @@ packages: resolution: {integrity: sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==} engines: {node: '>= 0.10.0'} + ext@1.7.0: + resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} + extend-shallow@2.0.1: resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} engines: {node: '>=0.10.0'} @@ -8073,10 +10840,21 @@ packages: extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + external-editor@2.2.0: + resolution: {integrity: sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==} + engines: {node: '>=0.12'} + + external-editor@3.1.0: + resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} + engines: {node: '>=4'} + extglob@2.0.4: resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} engines: {node: '>=0.10.0'} + fake-indexeddb@4.0.2: + resolution: {integrity: sha512-SdTwEhnakbgazc7W3WUXOJfGmhH0YfG4d+dRPOFoYDRTL6U5t8tvrmkf2W/C3W1jk2ylV7Wrnj44RASqpX/lEw==} + fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -8156,6 +10934,10 @@ packages: resolution: {integrity: sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==} deprecated: This module is no longer supported. + figures@2.0.0: + resolution: {integrity: sha512-Oa2M9atig69ZkfwiApY8F2Yy+tzMbazyvqv21R0NsSC8floSOC09BbT1ITWAdoMGQvJ/aZnR1KMwdx9tvHnTNA==} + engines: {node: '>=4'} + figures@3.2.0: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} engines: {node: '>=8'} @@ -8174,6 +10956,14 @@ packages: peerDependencies: webpack: ^4.0.0 || ^5.0.0 + file-selector@0.1.19: + resolution: {integrity: sha512-kCWw3+Aai8Uox+5tHCNgMFaUdgidxvMnLWO6fM5sZ0hA2wlHP5/DHGF0ECe84BiB95qdJbKNEJhWKVDvMN+JDQ==} + engines: {node: '>= 10'} + + file-selector@2.1.2: + resolution: {integrity: sha512-QgXo+mXTe8ljeqUFaX3QVHc5osSItJ/Km+xpocx0aSqWGMSCf6qYs/VnzZgS864Pjn5iceMRFigeAV7AfTlaig==} + engines: {node: '>= 12'} + file-system-cache@1.1.0: resolution: {integrity: sha512-IzF5MBq+5CR0jXx5RxPe4BICl/oEhBSXKaL9fLhAXrIfIUS77Hr4vzrYyqYMHN6uTt+BOqi3fDCTjjEBCjERKw==} @@ -8195,6 +10985,10 @@ packages: resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} engines: {node: '>= 0.8'} + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} + find-cache-dir@2.1.0: resolution: {integrity: sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==} engines: {node: '>=6'} @@ -8203,6 +10997,10 @@ packages: resolution: {integrity: sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==} engines: {node: '>=8'} + find-cache-dir@4.0.0: + resolution: {integrity: sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==} + engines: {node: '>=14.16'} + find-root@1.1.0: resolution: {integrity: sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==} @@ -8226,6 +11024,10 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} + find-up@6.3.0: + resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + flat-cache@3.2.0: resolution: {integrity: sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==} engines: {node: ^10.12.0 || >=12.0.0} @@ -8312,6 +11114,13 @@ packages: vue-template-compiler: optional: true + fork-ts-checker-webpack-plugin@8.0.0: + resolution: {integrity: sha512-mX3qW3idpueT2klaQXBzrIM/pHw+T0B/V9KHEvNrqijTq9NFnMZU6oreVxDYcf33P8a5cW+67PjodNHthGnNVg==} + engines: {node: '>=12.13.0', yarn: '>=1.0.0'} + peerDependencies: + typescript: '>3.6.0' + webpack: ^5.11.0 + form-data@3.0.4: resolution: {integrity: sha512-f0cRzm6dkyVYV3nPoooP8XlccPQukegwhAnpoLcXy+X+A8KfpGOoXwDr9FLZd3wzgLaBGQBE3lY93Zm/i1JvIQ==} engines: {node: '>= 6'} @@ -8332,6 +11141,10 @@ packages: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + from2@2.3.0: resolution: {integrity: sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g==} @@ -8386,9 +11199,16 @@ packages: resolution: {integrity: sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==} engines: {node: '>= 0.4'} + functional-red-black-tree@1.0.1: + resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} + functions-have-names@1.2.3: resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} + fuzzy@0.1.3: + resolution: {integrity: sha512-/gZffu4ykarLrCiP3Ygsa86UAo1E5vEVlvTrpkKywXSbP9Xhln3oSp9QSV57gEq3JFFpGJ4GZ+5zdEp3FcUh4w==} + engines: {node: '>= 0.6.0'} + gauge@3.0.2: resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==} engines: {node: '>=10'} @@ -8424,6 +11244,10 @@ packages: engines: {node: '>=6.9.0'} hasBin: true + get-port@4.2.0: + resolution: {integrity: sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==} + engines: {node: '>=6'} + get-port@5.1.1: resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} engines: {node: '>=8'} @@ -8436,6 +11260,10 @@ packages: resolution: {integrity: sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==} engines: {node: '>=0.10.0'} + get-stdin@8.0.0: + resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} + engines: {node: '>=10'} + get-stream@4.1.0: resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} engines: {node: '>=6'} @@ -8504,6 +11332,12 @@ packages: peerDependencies: glob: '*' + glob-promise@4.2.2: + resolution: {integrity: sha512-xcUzJ8NWN5bktoTIX7eOclO1Npxd/dyVqUJxlLIDasT4C7KZyqlPIwkdJ0Ypiy3p2ZKahTjK4M9uC3sNSfNMzw==} + engines: {node: '>=12'} + peerDependencies: + glob: ^7.1.6 + glob-to-regexp@0.3.0: resolution: {integrity: sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==} @@ -8536,6 +11370,10 @@ packages: global@4.4.0: resolution: {integrity: sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==} + globals@11.12.0: + resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} + engines: {node: '>=4'} + globals@13.24.0: resolution: {integrity: sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==} engines: {node: '>=8'} @@ -8552,6 +11390,10 @@ packages: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} + globby@13.2.2: + resolution: {integrity: sha512-Y1zNGV+pzQdh7H39l9zgB4PJqjRNqydvdYCDG4HFXM4XuvSaQQlEc91IU1yALL8gUTDomgBAfz3XJdmUS+oo0w==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + globby@6.1.0: resolution: {integrity: sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw==} engines: {node: '>=0.10.0'} @@ -8585,6 +11427,10 @@ packages: resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} engines: {node: '>=6'} + has-ansi@2.0.0: + resolution: {integrity: sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg==} + engines: {node: '>=0.10.0'} + has-bigints@1.1.0: resolution: {integrity: sha512-R3pbpkcIqv2Pm3dUwgjclDRVmWpTJW2DcMzcIhEXEx1oh/CEMObMm3KLmRJOdvhM7o4uQBnwr8pzRK2sJWIqfg==} engines: {node: '>= 0.4'} @@ -8876,6 +11722,9 @@ packages: iferr@0.1.5: resolution: {integrity: sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA==} + ignore-by-default@1.0.1: + resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} + ignore-walk@5.0.1: resolution: {integrity: sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -8954,10 +11803,26 @@ packages: inline-style-parser@0.2.7: resolution: {integrity: sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==} + inquirer-autocomplete-prompt@0.11.1: + resolution: {integrity: sha512-VM4eNiyRD4CeUc2cyKni+F8qgHwL9WC4LdOr+mEC85qP/QNsDV+ysVqUrJYhw1TmDQu1QVhc8hbaL7wfk8SJxw==} + + inquirer@3.1.1: + resolution: {integrity: sha512-H50sHQwgvvaTBd3HpKMVtL/u6LoHDvYym51gd7bGQe/+9HkCE+J0/3N5FJLfd6O6oz44hHewC2Pc2LodzWVafQ==} + + inquirer@6.5.2: + resolution: {integrity: sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==} + engines: {node: '>=6.0.0'} + inquirer@8.2.7: resolution: {integrity: sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==} engines: {node: '>=12.0.0'} + inquirerer@0.1.3: + resolution: {integrity: sha512-yGgLUOqPxTsINBjZNZeLi3cv2zgxXtw9feaAOSJf2j6AqIT5Uxs5ZOqOrfAf+xP65Sicla1FD3iDxa3D6TsCAQ==} + + interchainjs@1.17.1: + resolution: {integrity: sha512-7i22pCVrW+5EKmC16NFoR0lvI0DQ7DQlOLynRY4WeMN5Kc0Y/hZ5M3TzbcE3NXbtv82ygxJYwNIlrL24+xpXpA==} + internal-slot@1.1.0: resolution: {integrity: sha512-4gd7VpWNQNB4UKKCFFVcp1AVv+FMOgs9NKzjHKusc8jTMhd5eL1NqQqOpE0KzMds804/yHlglp3uxgluOqAPLw==} engines: {node: '>= 0.4'} @@ -8969,10 +11834,18 @@ packages: resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} engines: {node: '>=12'} + interpret@1.4.0: + resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} + engines: {node: '>= 0.10'} + interpret@2.2.0: resolution: {integrity: sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==} engines: {node: '>= 0.10'} + interpret@3.1.1: + resolution: {integrity: sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==} + engines: {node: '>=10.13.0'} + ip-address@10.2.0: resolution: {integrity: sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==} engines: {node: '>= 12'} @@ -9102,6 +11975,11 @@ packages: engines: {node: '>=8'} hasBin: true + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + is-dom@1.1.0: resolution: {integrity: sha512-u82f6mvhYxRPKpw8V1N0W8ce1xXwOrQtgGcxl6UCL5zBmZu3is/18K0rR7uFCnMDuAsS/3W54mGL4vsaFUQlEQ==} @@ -9125,6 +12003,10 @@ packages: resolution: {integrity: sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w==} engines: {node: '>=0.10.0'} + is-fullwidth-code-point@2.0.0: + resolution: {integrity: sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==} + engines: {node: '>=4'} + is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} @@ -9157,6 +12039,15 @@ packages: is-in-browser@1.1.3: resolution: {integrity: sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g==} + is-in-ssh@1.0.0: + resolution: {integrity: sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==} + engines: {node: '>=20'} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + is-interactive@1.0.0: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} @@ -9168,6 +12059,9 @@ packages: resolution: {integrity: sha512-1Qed0/Hr2m+YqxnM09CjA2d/i6YZNfF6R2oRAOj36eUdS6qIV/huPJNSEpKbupewFs+ZsJlxsjjPbc0/afW6Lw==} engines: {node: '>= 0.4'} + is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + is-negative-zero@2.0.3: resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} @@ -9234,6 +12128,12 @@ packages: is-potential-custom-element-name@1.0.1: resolution: {integrity: sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==} + is-promise@2.2.2: + resolution: {integrity: sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==} + + is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + is-regex@1.2.1: resolution: {integrity: sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==} engines: {node: '>= 0.4'} @@ -9320,6 +12220,10 @@ packages: resolution: {integrity: sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==} engines: {node: '>=8'} + is-wsl@3.1.1: + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} + engines: {node: '>=16'} + isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} @@ -9456,6 +12360,10 @@ packages: resolution: {integrity: sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + jest-diff@28.1.3: + resolution: {integrity: sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + jest-diff@29.7.0: resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -9492,6 +12400,10 @@ packages: resolution: {integrity: sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + jest-get-type@28.0.2: + resolution: {integrity: sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + jest-get-type@29.6.3: resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -9524,6 +12436,10 @@ packages: resolution: {integrity: sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + jest-matcher-utils@28.1.3: + resolution: {integrity: sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + jest-matcher-utils@29.7.0: resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -9532,6 +12448,10 @@ packages: resolution: {integrity: sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + jest-message-util@28.1.3: + resolution: {integrity: sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + jest-message-util@29.7.0: resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -9621,6 +12541,10 @@ packages: resolution: {integrity: sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + jest-util@28.1.3: + resolution: {integrity: sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + jest-util@29.7.0: resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -9720,6 +12644,11 @@ packages: canvas: optional: true + jsesc@2.5.2: + resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} + engines: {node: '>=4'} + hasBin: true + jsesc@3.1.0: resolution: {integrity: sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==} engines: {node: '>=6'} @@ -9931,10 +12860,88 @@ packages: lie@3.1.1: resolution: {integrity: sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==} + lightningcss-android-arm64@1.32.0: + resolution: {integrity: sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.32.0: + resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.32.0: + resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.32.0: + resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.32.0: + resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.32.0: + resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.32.0: + resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.32.0: + resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.32.0: + resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.32.0: + resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.32.0: + resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.32.0: + resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} + engines: {node: '>= 12.0.0'} + lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} + lilconfig@3.1.3: + resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} + engines: {node: '>=14'} + lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} @@ -9942,6 +12949,10 @@ packages: resolution: {integrity: sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + lmdb@2.8.5: + resolution: {integrity: sha512-9bMdFfc80S+vSldBmG3HOuLVHnxRdNTlpzR6QDnzqCQtCzGUEAGTzBKYMeIM+I/sU4oZfgbcbS7X7F65/z/oxQ==} + hasBin: true + load-json-file@1.1.0: resolution: {integrity: sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==} engines: {node: '>=0.10.0'} @@ -9989,6 +13000,10 @@ packages: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + locate-path@7.2.0: + resolution: {integrity: sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + lodash-es@4.18.1: resolution: {integrity: sha512-J8xewKD/Gk22OZbhpOVSwcs60zhd95ESDwezOFuA3/099925PdHJ7OFHNTGtajL3AlZkykD32HykiMo+BIBI8A==} @@ -10010,6 +13025,9 @@ packages: lodash.trimstart@4.5.1: resolution: {integrity: sha512-b/+D6La8tU76L/61/aN0jULWHkT0EeJCmVstPBn/K9MtD2qBW83AsBNrr63dKuWYwVMO7ucv13QNO/Ek/2RKaQ==} + lodash.truncate@4.4.2: + resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} + lodash.uniq@4.5.0: resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==} @@ -10064,15 +13082,34 @@ packages: resolution: {integrity: sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==} engines: {node: '>=12'} + lru-queue@0.1.0: + resolution: {integrity: sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==} + lucide-react@0.453.0: resolution: {integrity: sha512-kL+RGZCcJi9BvJtzg2kshO192Ddy9hv3ij+cPrVPWSRzgCWCVazoQJxOjAwgK53NomL07HB7GPHW120FimjNhQ==} peerDependencies: react: ^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc + lunr@2.3.9: + resolution: {integrity: sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==} + lz-string@1.5.0: resolution: {integrity: sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==} hasBin: true + magic-string@0.25.2: + resolution: {integrity: sha512-iLs9mPjh9IuTtRsqqhNGYcZXGei0Nh/A4xirrsqW7c+QhKVFL2vm7U09ru6cHRD22azaP/wMDgI+HCqbETMTtg==} + + magic-string@0.25.9: + resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + + magic-string@0.27.0: + resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} + engines: {node: '>=12'} + + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + make-dir@2.1.0: resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} engines: {node: '>=6'} @@ -10125,6 +13162,11 @@ packages: markdown-escapes@1.0.4: resolution: {integrity: sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==} + marked@4.3.0: + resolution: {integrity: sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A==} + engines: {node: '>= 12'} + hasBin: true + material-react-table@3.2.1: resolution: {integrity: sha512-sQtTf7bETpkPN2Hm5BVtz89wrfXCVQguz6XlwMChSnfKFO5QCKAJJC5aSIKnUc3S0AvTz/k/ILi00FnnY1Gixw==} engines: {node: '>=16'} @@ -10210,6 +13252,10 @@ packages: resolution: {integrity: sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==} engines: {node: '>= 4.0.0'} + memoizee@0.4.17: + resolution: {integrity: sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==} + engines: {node: '>=0.12'} + memoizerific@1.11.3: resolution: {integrity: sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog==} @@ -10336,6 +13382,10 @@ packages: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} @@ -10346,6 +13396,15 @@ packages: engines: {node: '>=4.0.0'} hasBin: true + mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + + mimic-fn@1.2.0: + resolution: {integrity: sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==} + engines: {node: '>=4'} + mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} @@ -10399,6 +13458,9 @@ packages: resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} engines: {node: '>= 6'} + minimist@1.2.6: + resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==} + minimist@1.2.8: resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==} @@ -10469,6 +13531,11 @@ packages: mobx@6.15.3: resolution: {integrity: sha512-6+ZSYDs5zgH5CdGfEU2q2Lsa5PztVryL1ys7kAImTU25n2A9LAMj/yneVsQpd03MfwMLDQF+7kakJR9Z+cQxSw==} + mocha@10.8.2: + resolution: {integrity: sha512-VZlYo/WE8t1tstuRmqgeyBgCbJc/lEdopaa+axcKzTBJ+UIdlAB9XnmvTCAH4pwR4ElNInaedhEBmZD8iCSVEg==} + engines: {node: '>= 14.0.0'} + hasBin: true + modern-ahocorasick@1.1.0: resolution: {integrity: sha512-sEKPVl2rM+MNVkGQt3ChdmD8YsigmXdn5NifZn6jiwn9LRJpWm8F3guhaqrJT/JOat6pwpbXEk6kv+b9DMIjsQ==} @@ -10476,6 +13543,9 @@ packages: resolution: {integrity: sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==} engines: {node: '>=0.10.0'} + moq.ts@7.4.1: + resolution: {integrity: sha512-P97MjGUkkMKQrAHbNScyJvSv3S7pMxnuxd3HgaOrPuoC6okwPqru3ZX8W/mTdU7Ms74622MeeWHqoDaGyYKonw==} + move-concurrently@1.0.1: resolution: {integrity: sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ==} deprecated: This package is no longer supported. @@ -10486,6 +13556,13 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + msgpackr-extract@3.0.4: + resolution: {integrity: sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==} + hasBin: true + + msgpackr@1.11.12: + resolution: {integrity: sha512-RBdJ1Un7yGlXWajrkxcSa93nvQ0w4zBf60c0yYv7YtBelP8H2FA7XsfBbMHtXKXUMUxH7zV3Zuozh+kUQWhHvg==} + multicast-dns@7.2.5: resolution: {integrity: sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==} hasBin: true @@ -10494,6 +13571,9 @@ packages: resolution: {integrity: sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==} engines: {node: '>=10'} + mute-stream@0.0.7: + resolution: {integrity: sha512-r65nCZhrbXXb6dXOACihYApHw2Q6pV0M3V0PSxd74N0+D8nzAdEAITq2oAjA1jVnKI+tGvEBUpqiMh0+rW6zDQ==} + mute-stream@0.0.8: resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} @@ -10501,6 +13581,9 @@ packages: resolution: {integrity: sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + mz@2.7.0: + resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + nan@2.27.0: resolution: {integrity: sha512-hC+0LidcL3XE4rp1C4H54KujgXKzbfyTngZTwBByQxsOxCEKZT0MPQ4hOKUH2jU1OYstqdDH4onyHPDzcV0XdQ==} @@ -10541,6 +13624,12 @@ packages: nested-error-stacks@2.1.1: resolution: {integrity: sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw==} + nested-obj@0.2.2: + resolution: {integrity: sha512-M1etu+T6Ai9Bo06L3K3nWD0ytZWltggBGsrxJlOGvMNGlCA4fokUVlbPKoWzsiiRX+PXq6Cb1xFEn4chiyC7MQ==} + + next-tick@1.1.0: + resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} + next@14.2.35: resolution: {integrity: sha512-KhYd2Hjt/O1/1aZVX3dCwGXM1QmOV4eNM2UTacK5gipDdPN/oHHK/4oVGy7X8GMfPMsUTUEmGlsy0EY1YGAkig==} engines: {node: '>=18.17.0'} @@ -10575,6 +13664,12 @@ packages: node-addon-api@3.2.1: resolution: {integrity: sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==} + node-addon-api@6.1.0: + resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} + + node-addon-api@7.1.1: + resolution: {integrity: sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==} + node-dir@0.1.17: resolution: {integrity: sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg==} engines: {node: '>= 0.10.5'} @@ -10608,6 +13703,14 @@ packages: resolution: {integrity: sha512-LarFH0+6VfriEhqMMcLX2F7SwSXeWwnEAJEsYm5QKWchiVYVvJyV9v7UDvUv+w5HO23ZpQTXDv/GxdDdMyOuoQ==} engines: {node: '>= 6.13.0'} + node-gyp-build-optional-packages@5.1.1: + resolution: {integrity: sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==} + hasBin: true + + node-gyp-build-optional-packages@5.2.2: + resolution: {integrity: sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==} + hasBin: true + node-gyp-build@4.8.4: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true @@ -10632,6 +13735,16 @@ packages: node-releases@2.0.44: resolution: {integrity: sha512-5WUyunoPMsvvEhS8AxHtRzP+oA8UCkJ7YRxatWKjngndhDGLiqEVAQKWjFAiAiuL8zMRGzGSJxFnLetoa43qGQ==} + nodemon@3.0.1: + resolution: {integrity: sha512-g9AZ7HmkhQkqXkRc20w+ZfQ73cHLbE8hnPbtaFbFtCumZsjyMhKk9LajQ07U5Ux28lvFjZ5X7HvWR1xzU8jHVw==} + engines: {node: '>=10'} + hasBin: true + + nodemon@3.1.14: + resolution: {integrity: sha512-jakjZi93UtB3jHMWsXL68FXSAosbLfY0In5gtKq3niLSkrWznrVBzXFNOEMJUfc9+Ke7SHWoAZsiMkNP3vq6Jw==} + engines: {node: '>=10'} + hasBin: true + nopt@6.0.0: resolution: {integrity: sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -10746,6 +13859,9 @@ packages: nth-check@2.1.1: resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + nullthrows@1.1.1: + resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} + num2fraction@1.2.2: resolution: {integrity: sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==} @@ -10839,10 +13955,18 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + onetime@2.0.1: + resolution: {integrity: sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==} + engines: {node: '>=4'} + onetime@5.1.2: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} + open@11.0.0: + resolution: {integrity: sha512-smsWv2LzFjP03xmvFoJ331ss6h+jixfA4UUV/Bsiyuu4YJPfN+FIQGOIiv4w9/+MoHkfkJ22UIaQWRVFRfH6Vw==} + engines: {node: '>=20'} + open@7.4.2: resolution: {integrity: sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q==} engines: {node: '>=8'} @@ -10865,6 +13989,9 @@ packages: resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} engines: {node: '>=10'} + ordered-binary@1.6.1: + resolution: {integrity: sha512-QkCdPooczexPLiXIrbVOPYkR3VO3T6v2OyKRkR1Xbhpy7/LAVXwahnRCgRp78Oe/Ehf0C/HATAxfSr6eA1oX+w==} + os-browserify@0.3.0: resolution: {integrity: sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==} @@ -10872,6 +13999,14 @@ packages: resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} engines: {node: '>=0.10.0'} + os-tmpdir@1.0.2: + resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} + engines: {node: '>=0.10.0'} + + ospec@3.1.0: + resolution: {integrity: sha512-+nGtjV3vlADp+UGfL51miAh/hB4awPBkQrArhcgG4trAaoA2gKt5bf9w0m9ch9zOr555cHWaCHZEDiBOkNZSxw==} + hasBin: true + own-keys@1.0.1: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} @@ -10908,6 +14043,10 @@ packages: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} + p-limit@4.0.0: + resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-locate@2.0.0: resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} engines: {node: '>=4'} @@ -10924,6 +14063,10 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + p-locate@6.0.0: + resolution: {integrity: sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + p-map-series@2.1.0: resolution: {integrity: sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q==} engines: {node: '>=8'} @@ -10992,6 +14135,11 @@ packages: param-case@3.0.4: resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} + parcel@2.16.4: + resolution: {integrity: sha512-RQlrqs4ujYNJpTQi+dITqPKNhRWEqpjPd1YBcGp50Wy3FcJHpwu0/iRm7XWz2dKU/Bwp2qCcVYPIeEDYi2uOUw==} + engines: {node: '>= 16.0.0'} + hasBin: true + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -11022,6 +14170,9 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} + parse-package-name@1.0.0: + resolution: {integrity: sha512-kBeTUtcj+SkyfaW4+KBe0HtsloBJ/mKTPoxpVdA57GZiPerREsUWJOhVj9anXweFiJkm5y8FG1sxFZkZ0SN6wg==} + parse-path@7.1.0: resolution: {integrity: sha512-EuCycjZtfPcjWk7KTksnJ5xPMvWGA/6i4zrLYhRG0hGvC3GPU/jGUj3Cy+ZR0v30duV3e23R95T1lE2+lsndSw==} @@ -11066,6 +14217,10 @@ packages: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} + path-exists@5.0.0: + resolution: {integrity: sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} @@ -11176,6 +14331,10 @@ packages: resolution: {integrity: sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==} engines: {node: '>=10'} + pkg-dir@7.0.0: + resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==} + engines: {node: '>=14.16'} + pnp-webpack-plugin@1.6.4: resolution: {integrity: sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg==} engines: {node: '>=6'} @@ -11197,42 +14356,84 @@ packages: peerDependencies: postcss: ^8.2.2 + postcss-calc@9.0.1: + resolution: {integrity: sha512-TipgjGyzP5QzEhsOZUaIkeO5mKeMFpebWzRogWG/ysonUlnHcq5aJe0jOjpfzUU8PeSaBQnrE8ehR0QA5vs8PQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.2.2 + postcss-colormin@5.3.1: resolution: {integrity: sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-colormin@6.1.0: + resolution: {integrity: sha512-x9yX7DOxeMAR+BgGVnNSAxmAj98NX/YxEMNFP+SDCEeNLb2r3i6Hh1ksMsnW8Ub5SLCpbescQqn9YEbE9554Sw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-convert-values@5.1.3: resolution: {integrity: sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-convert-values@6.1.0: + resolution: {integrity: sha512-zx8IwP/ts9WvUM6NkVSkiU902QZL1bwPhaVaLynPtCsOTqp+ZKbNi+s6XJg3rfqpKGA/oc7Oxk5t8pOQJcwl/w==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-discard-comments@5.1.2: resolution: {integrity: sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-discard-comments@6.0.2: + resolution: {integrity: sha512-65w/uIqhSBBfQmYnG92FO1mWZjJ4GL5b8atm5Yw2UgrwD7HiNiSSNwJor1eCFGzUgYnN/iIknhNRVqjrrpuglw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-discard-duplicates@5.1.0: resolution: {integrity: sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-discard-duplicates@6.0.3: + resolution: {integrity: sha512-+JA0DCvc5XvFAxwx6f/e68gQu/7Z9ud584VLmcgto28eB8FqSFZwtrLwB5Kcp70eIoWP/HXqz4wpo8rD8gpsTw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-discard-empty@5.1.1: resolution: {integrity: sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-discard-empty@6.0.3: + resolution: {integrity: sha512-znyno9cHKQsK6PtxL5D19Fj9uwSzC2mB74cpT66fhgOadEUPyXFkbgwm5tvc3bt3NAy8ltE5MrghxovZRVnOjQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-discard-overridden@5.1.0: resolution: {integrity: sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-discard-overridden@6.0.2: + resolution: {integrity: sha512-j87xzI4LUggC5zND7KdjsI25APtyMuynXZSujByMaav2roV6OZX+8AaCUcZSWqckZpjAjRyFDdpqybgjFO0HJQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-flexbugs-fixes@4.2.1: resolution: {integrity: sha512-9SiofaZ9CWpQWxOwRh1b/r85KD5y7GgvsNt1056k6OYLvWUun0czCvogfJgylC22uJTwW1KzY3Gz65NZRlvoiQ==} @@ -11249,36 +14450,72 @@ packages: peerDependencies: postcss: ^8.2.15 + postcss-merge-longhand@6.0.5: + resolution: {integrity: sha512-5LOiordeTfi64QhICp07nzzuTDjNSO8g5Ksdibt44d+uvIIAE1oZdRn8y/W5ZtYgRH/lnLDlvi9F8btZcVzu3w==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-merge-rules@5.1.4: resolution: {integrity: sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-merge-rules@6.1.1: + resolution: {integrity: sha512-KOdWF0gju31AQPZiD+2Ar9Qjowz1LTChSjFFbS+e2sFgc4uHOp3ZvVX4sNeTlk0w2O31ecFGgrFzhO0RSWbWwQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-minify-font-values@5.1.0: resolution: {integrity: sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-minify-font-values@6.1.0: + resolution: {integrity: sha512-gklfI/n+9rTh8nYaSJXlCo3nOKqMNkxuGpTn/Qm0gstL3ywTr9/WRKznE+oy6fvfolH6dF+QM4nCo8yPLdvGJg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-minify-gradients@5.1.1: resolution: {integrity: sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-minify-gradients@6.0.3: + resolution: {integrity: sha512-4KXAHrYlzF0Rr7uc4VrfwDJ2ajrtNEpNEuLxFgwkhFZ56/7gaE4Nr49nLsQDZyUe+ds+kEhf+YAUolJiYXF8+Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-minify-params@5.1.4: resolution: {integrity: sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-minify-params@6.1.0: + resolution: {integrity: sha512-bmSKnDtyyE8ujHQK0RQJDIKhQ20Jq1LYiez54WiaOoBtcSuflfK3Nm596LvbtlFcpipMjgClQGyGr7GAs+H1uA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-minify-selectors@5.2.1: resolution: {integrity: sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-minify-selectors@6.0.4: + resolution: {integrity: sha512-L8dZSwNLgK7pjTto9PzWRoMbnLq5vsZSTu8+j1P/2GB8qdtGQfn+K1uSvFgYvgh83cbyxT5m43ZZhUMTJDSClQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-modules-extract-imports@2.0.0: resolution: {integrity: sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ==} engines: {node: '>= 6'} @@ -11324,72 +14561,144 @@ packages: peerDependencies: postcss: ^8.2.15 + postcss-normalize-charset@6.0.2: + resolution: {integrity: sha512-a8N9czmdnrjPHa3DeFlwqst5eaL5W8jYu3EBbTTkI5FHkfMhFZh1EGbku6jhHhIzTA6tquI2P42NtZ59M/H/kQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-normalize-display-values@5.1.0: resolution: {integrity: sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-normalize-display-values@6.0.2: + resolution: {integrity: sha512-8H04Mxsb82ON/aAkPeq8kcBbAtI5Q2a64X/mnRRfPXBq7XeogoQvReqxEfc0B4WPq1KimjezNC8flUtC3Qz6jg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-normalize-positions@5.1.1: resolution: {integrity: sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-normalize-positions@6.0.2: + resolution: {integrity: sha512-/JFzI441OAB9O7VnLA+RtSNZvQ0NCFZDOtp6QPFo1iIyawyXg0YI3CYM9HBy1WvwCRHnPep/BvI1+dGPKoXx/Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-normalize-repeat-style@5.1.1: resolution: {integrity: sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-normalize-repeat-style@6.0.2: + resolution: {integrity: sha512-YdCgsfHkJ2jEXwR4RR3Tm/iOxSfdRt7jplS6XRh9Js9PyCR/aka/FCb6TuHT2U8gQubbm/mPmF6L7FY9d79VwQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-normalize-string@5.1.0: resolution: {integrity: sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-normalize-string@6.0.2: + resolution: {integrity: sha512-vQZIivlxlfqqMp4L9PZsFE4YUkWniziKjQWUtsxUiVsSSPelQydwS8Wwcuw0+83ZjPWNTl02oxlIvXsmmG+CiQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-normalize-timing-functions@5.1.0: resolution: {integrity: sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-normalize-timing-functions@6.0.2: + resolution: {integrity: sha512-a+YrtMox4TBtId/AEwbA03VcJgtyW4dGBizPl7e88cTFULYsprgHWTbfyjSLyHeBcK/Q9JhXkt2ZXiwaVHoMzA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-normalize-unicode@5.1.1: resolution: {integrity: sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-normalize-unicode@6.1.0: + resolution: {integrity: sha512-QVC5TQHsVj33otj8/JD869Ndr5Xcc/+fwRh4HAsFsAeygQQXm+0PySrKbr/8tkDKzW+EVT3QkqZMfFrGiossDg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-normalize-url@5.1.0: resolution: {integrity: sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-normalize-url@6.0.2: + resolution: {integrity: sha512-kVNcWhCeKAzZ8B4pv/DnrU1wNh458zBNp8dh4y5hhxih5RZQ12QWMuQrDgPRw3LRl8mN9vOVfHl7uhvHYMoXsQ==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-normalize-whitespace@5.1.1: resolution: {integrity: sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-normalize-whitespace@6.0.2: + resolution: {integrity: sha512-sXZ2Nj1icbJOKmdjXVT9pnyHQKiSAyuNQHSgRCUgThn2388Y9cGVDR+E9J9iAYbSbLHI+UUwLVl1Wzco/zgv0Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-ordered-values@5.1.3: resolution: {integrity: sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-ordered-values@6.0.2: + resolution: {integrity: sha512-VRZSOB+JU32RsEAQrO94QPkClGPKJEL/Z9PCBImXMhIeK5KAYo6slP/hBYlLgrCjFxyqvn5VC81tycFEDBLG1Q==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-reduce-initial@5.1.2: resolution: {integrity: sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-reduce-initial@6.1.0: + resolution: {integrity: sha512-RarLgBK/CrL1qZags04oKbVbrrVK2wcxhvta3GCxrZO4zveibqbRPmm2VI8sSgCXwoUHEliRSbOfpR0b/VIoiw==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-reduce-transforms@5.1.0: resolution: {integrity: sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-reduce-transforms@6.0.2: + resolution: {integrity: sha512-sB+Ya++3Xj1WaT9+5LOOdirAxP7dJZms3GRcYheSPi1PiTMigsxHAdkrbItHxwYHr4kt1zL7mmcHstgMYT+aiA==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-selector-parser@6.1.2: resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} engines: {node: '>=4'} @@ -11404,12 +14713,24 @@ packages: peerDependencies: postcss: ^8.2.15 + postcss-svgo@6.0.3: + resolution: {integrity: sha512-dlrahRmxP22bX6iKEjOM+c8/1p+81asjKT+V5lrgOH944ryx/OHpclnIbGsKVd3uWOXFLYJwCVf0eEkJGvO96g==} + engines: {node: ^14 || ^16 || >= 18} + peerDependencies: + postcss: ^8.4.31 + postcss-unique-selectors@5.1.1: resolution: {integrity: sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==} engines: {node: ^10 || ^12 || >=14.0} peerDependencies: postcss: ^8.2.15 + postcss-unique-selectors@6.0.4: + resolution: {integrity: sha512-K38OCaIrO8+PzpArzkLKB42dSARtC2tmG6PvD4b1o1Q2E9Os8jzfWFfSy/rixsHwohtsDdFtAWGjFVFUdwYaMg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + postcss-value-parser@4.2.0: resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} @@ -11425,6 +14746,10 @@ packages: resolution: {integrity: sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==} engines: {node: ^10 || ^12 || >=14} + powershell-utils@0.1.0: + resolution: {integrity: sha512-dM0jVuXJPsDN6DvRpea484tCUaMiXWjuCn++HGTqUWzGDjv5tZkEZldAJ/UMlqRYGFrD/etByo4/xOuC/snX2A==} + engines: {node: '>=20'} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -11453,6 +14778,10 @@ packages: resolution: {integrity: sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} + pretty-format@28.1.3: + resolution: {integrity: sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==} + engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + pretty-format@29.7.0: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -11475,6 +14804,10 @@ packages: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} engines: {node: '>= 0.6.0'} + progress@2.0.3: + resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} + engines: {node: '>=0.4.0'} + promise-inflight@1.0.1: resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} peerDependencies: @@ -11544,6 +14877,9 @@ packages: psl@1.15.0: resolution: {integrity: sha512-JZd3gMVBAVQkSs6HdNZo9Sdo0LNcQeMNP3CozBJb3JYC/QUYZTnKxP+f8oWRX4rHP5EurWxqAHTSwUCjlNKa1w==} + pstree.remy@1.1.8: + resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==} + public-encrypt@4.0.3: resolution: {integrity: sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==} @@ -11609,6 +14945,9 @@ packages: '@vanilla-extract/css': ^1 '@vanilla-extract/dynamic': ^2 + rambda@7.5.0: + resolution: {integrity: sha512-y/M9weqWAH4iopRd7EHDEQQvpFPHj1AA3oHozE9tfITHUtTR7Z9PSlIRRG2l1GuW7sefC1cXFfIcF+cgnShdBA==} + ramda@0.26.1: resolution: {integrity: sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ==} @@ -11656,6 +14995,18 @@ packages: peerDependencies: react: ^19.2.6 + react-dropzone@10.2.2: + resolution: {integrity: sha512-U5EKckXVt6IrEyhMMsgmHQiWTGLudhajPPG77KFSvgsMqNEHSyGpqWvOMc5+DhEah/vH4E1n+J5weBNLd5VtyA==} + engines: {node: '>= 8'} + peerDependencies: + react: '>= 16.8' + + react-dropzone@14.4.1: + resolution: {integrity: sha512-QDuV76v3uKbHiH34SpwifZ+gOLi1+RdsCO1kl5vxMT4wW8R82+sthjvBw4th3NHF/XX6FBsqDYZVNN+pnhaw0g==} + engines: {node: '>= 10.13'} + peerDependencies: + react: '>= 16.8 || 18.0.0' + react-element-to-jsx-string@14.3.4: resolution: {integrity: sha512-t4ZwvV6vwNxzujDQ+37bspnLwA4JlgUPWhLjBJWsNIDceAf6ZKUTCjdm08cN6WeZ5pTMKiCJkmAYnpmR4Bm+dg==} peerDependencies: @@ -11716,6 +15067,19 @@ packages: react-merge-refs@1.1.0: resolution: {integrity: sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ==} + react-mui-dropzone@4.0.7: + resolution: {integrity: sha512-9OPZZ9CxHq+rTZf8aKLDZPaGzWDhAUZ9+6aIUE8ub5fgcXFqXkHuI8GsUPRaIF7WXPaa79HFz00/Xd5ev8I5Kg==} + engines: {node: '>=8', yarn: '>=1'} + peerDependencies: + '@emotion/react': ^11.4.1 + '@emotion/styled': ^11.3.0 + '@mui/icons-material': ^5.0.1 + '@mui/material': ^5.0.2 + '@mui/styles': ^5.0.1 + prop-types: ^15.7.2 + react: ^18.2.0 + react-dom: ^18.2.0 + react-random-avatars@1.3.1: resolution: {integrity: sha512-HyMGoWniK2D5CRthoA1he4c6LVFIX/yBjp4qarEXN/DsgJ+1R6M5gJwYhTBoATO+3itrGCAGnKZNqimG1sDjAA==} peerDependencies: @@ -11735,6 +15099,10 @@ packages: resolution: {integrity: sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==} engines: {node: '>=0.10.0'} + react-refresh@0.16.0: + resolution: {integrity: sha512-FPvF2XxTSikpJxcr+bHut2H4gJ17+18Uy20D5/F+SKzFap62R3cM5wH6b8WN3LyGSYeQilLEcJcR1fjBSI2S1A==} + engines: {node: '>=0.10.0'} + react-router-dom@6.30.3: resolution: {integrity: sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==} engines: {node: '>=14.0.0'} @@ -11845,6 +15213,10 @@ packages: resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} engines: {node: '>= 12.13.0'} + realistic-structured-clone@3.0.0: + resolution: {integrity: sha512-rOjh4nuWkAqf9PWu6JVpOWD4ndI+JHfgiZeMmujYcPi+fvILUu7g6l26TC1K5aBIp34nV+jE1cDO75EKOfHC5Q==} + deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + recast@0.23.11: resolution: {integrity: sha512-YTUo+Flmw4ZXiWfQKGcwwc11KnoRAYgzAE2E7mXKCjSviTKShtxBsN6YUUBB2gtaBzKzeKunxhUwNHQuRryhWA==} engines: {node: '>= 4'} @@ -11860,10 +15232,18 @@ packages: react: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + rechoir@0.6.2: + resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} + engines: {node: '>= 0.10'} + rechoir@0.7.1: resolution: {integrity: sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==} engines: {node: '>= 0.10'} + rechoir@0.8.0: + resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==} + engines: {node: '>= 10.13.0'} + redent@1.0.0: resolution: {integrity: sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g==} engines: {node: '>=0.10.0'} @@ -11889,6 +15269,9 @@ packages: regenerator-runtime@0.13.11: resolution: {integrity: sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==} + regenerator-runtime@0.14.1: + resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} + regex-not@1.0.2: resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} engines: {node: '>=0.10.0'} @@ -11897,6 +15280,10 @@ packages: resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==} engines: {node: '>= 0.4'} + regexpp@3.2.0: + resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} + engines: {node: '>=8'} + regexpu-core@6.4.0: resolution: {integrity: sha512-0ghuzq67LI9bLXpOX/ISfve/Mq33a4aFRzoQYhnnok1JOFpmE/A2TBGkNVenOGEeSBCjIiWcc6MVOG5HEQv0sA==} engines: {node: '>=4'} @@ -11912,6 +15299,10 @@ packages: resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==} engines: {node: '>= 0.10'} + reload@3.4.3: + resolution: {integrity: sha512-zrS+A2p9QQYZCM6/G9ePRcn1KJJZ9Z2KvWhGjBfL8gsn+vMBP0floY5FmAzOyC8xVZGednF/419u/iOdw+JakQ==} + hasBin: true + remark-external-links@8.0.0: resolution: {integrity: sha512-5vPSX0kHoSsqtdftSHhIYofVINC8qmp0nctkeU9YoJwV3YfiBRiI6cbFRJ0oI/1F9xS+bopXG0m2KS8VFscuKA==} @@ -12012,6 +15403,10 @@ packages: engines: {node: '>= 0.4'} hasBin: true + restore-cursor@2.0.0: + resolution: {integrity: sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==} + engines: {node: '>=4'} + restore-cursor@3.1.0: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} @@ -12055,13 +15450,60 @@ packages: resolution: {integrity: sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA==} engines: {node: '>= 0.8'} + rlp@3.0.0: + resolution: {integrity: sha512-PD6U2PGk6Vq2spfgiWZdomLvRGDreBLxi5jv5M8EpRo3pU6VEm31KO+HFxE18Q3vgqfDrQ9pZA3FP95rkijNKw==} + hasBin: true + robust-predicates@3.0.3: resolution: {integrity: sha512-NS3levdsRIUOmiJ8FZWCP7LG3QpJyrs/TE0Zpf1yvZu8cAJJ6QMW92H1c7kWpdIHo8RvmLxN/o2JXTKHp74lUA==} + rollup-plugin-base64@1.0.1: + resolution: {integrity: sha512-IbdX8fjuXO/Op3hYmRPjVo0VwcSenwsQDaDTFdoe+70B5ZGoLMtr96L2yhHXCfxv7HwZVvxZqLsuWj6VwzRt3g==} + + rollup-plugin-dts@5.3.1: + resolution: {integrity: sha512-gusMi+Z4gY/JaEQeXnB0RUdU82h1kF0WYzCWgVmV4p3hWXqelaKuCvcJawfeg+EKn2T1Ie+YWF2OiN1/L8bTVg==} + engines: {node: '>=v14.21.3'} + peerDependencies: + rollup: ^3.0 + typescript: ^4.1 || ^5.0 + + rollup-plugin-inject@3.0.2: + resolution: {integrity: sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w==} + deprecated: This package has been deprecated and is no longer maintained. Please use @rollup/plugin-inject. + + rollup-plugin-modify@3.0.0: + resolution: {integrity: sha512-p/ffs0Y2jz2dEnWjq1oVC7SY37tuS+aP7whoNaQz1EAAOPg+k3vKJo8cMMWx6xpdd0NzhX4y2YF9o/NPu5YR0Q==} + + rollup-plugin-node-polyfills@0.2.1: + resolution: {integrity: sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA==} + + rollup-plugin-polyfill@4.2.0: + resolution: {integrity: sha512-6eeOyn7nr2/xUOtB+MhydvqLrNKcSybGneOuWA+t8Q4rR9NQyeapzwuu5n6nX8OFfY1WI1sHconAofaC44IpuA==} + engines: {node: '>=10.0.0'} + peerDependencies: + rollup: ^2.67.0 || ^3.0.0 || ^4.0.0 + + rollup-plugin-web-worker-loader@1.7.0: + resolution: {integrity: sha512-msfN4FpdoTtfSCbeTZ8yPYmfi2/66Q53gQGmvOrEz/UfqZgCkSkGjaxsZt7TQ1V0s0tLJAe6HL+EdA7IBaUF6w==} + peerDependencies: + rollup: ^1.9.2 || ^2.0.0 || ^3.0.0 || ^4.0.0 + + rollup-pluginutils@2.8.2: + resolution: {integrity: sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==} + + rollup@3.30.0: + resolution: {integrity: sha512-kQvGasUgN+AlWGliFn2POSajRQEsULVYFGTvOZmK06d7vCD+YhZztt70kGk3qaeAXeWYL5eO7zx+rAubBc55eA==} + engines: {node: '>=14.18.0', npm: '>=8.0.0'} + hasBin: true + rsvp@4.8.5: resolution: {integrity: sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==} engines: {node: 6.* || >= 7.*} + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} @@ -12072,6 +15514,16 @@ packages: run-queue@1.0.3: resolution: {integrity: sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg==} + rx-lite-aggregates@4.0.8: + resolution: {integrity: sha512-3xPNZGW93oCjiO7PtKxRK6iOVYBWBvtf9QHDfU23Oc+dLIQmAV//UnyXV/yihv81VS/UqoQPk4NegS8EFi55Hg==} + + rx-lite@4.0.8: + resolution: {integrity: sha512-Cun9QucwK6MIrp3mry/Y7hqD1oFqTYLQ4pGxaHTjIdaFDWRGGLikqp6u8LcWJnzpoALg9hap+JGk8sFIUuEGNA==} + + rxjs@6.6.7: + resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} + engines: {npm: '>=2.0.0'} + rxjs@7.8.2: resolution: {integrity: sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==} @@ -12173,6 +15625,10 @@ packages: resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} engines: {node: '>= 0.8.0'} + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + serialize-javascript@4.0.0: resolution: {integrity: sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw==} @@ -12194,6 +15650,10 @@ packages: resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} engines: {node: '>= 0.8.0'} + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} @@ -12252,6 +15712,17 @@ packages: resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} engines: {node: '>= 0.4'} + shelljs@0.8.5: + resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} + engines: {node: '>=4'} + hasBin: true + + shiki@0.10.1: + resolution: {integrity: sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==} + + shiki@0.14.7: + resolution: {integrity: sha512-dNPAPrxSc87ua2sKJ3H5dQ/6ZaY8RNnaAqK+t0eG7p0Soi2ydiqbGOTaZCqaYvA/uZYfS1LJnemt3Q+mSfcPCg==} + side-channel-list@1.0.1: resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} engines: {node: '>= 0.4'} @@ -12283,6 +15754,10 @@ packages: simple-swizzle@0.2.4: resolution: {integrity: sha512-nAu1WFPQSMNr2Zn9PGSZK9AGn4t/y97lEm+MXTtUDwfP0ksAIX4nO+6ruD9Jwut4C49SB1Ws+fbXsm/yScWOHw==} + simple-update-notifier@2.0.0: + resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} + engines: {node: '>=10'} + sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} @@ -12298,10 +15773,21 @@ packages: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} engines: {node: '>=8'} + slash@4.0.0: + resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} + engines: {node: '>=12'} + + slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + smart-buffer@4.2.0: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} + smob@0.0.6: + resolution: {integrity: sha512-V21+XeNni+tTyiST1MHsa84AQhT1aFZipzPpOFAVB8DkHzwJyjjAmt9bgwnuZiZWnIbMo2duE29wybxv/7HWUw==} + snapdragon-node@2.1.1: resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} engines: {node: '>=0.10.0'} @@ -12365,6 +15851,10 @@ packages: resolution: {integrity: sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==} engines: {node: '>= 12'} + sourcemap-codec@1.4.8: + resolution: {integrity: sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==} + deprecated: Please use @jridgewell/sourcemap-codec instead + space-separated-tokens@1.1.5: resolution: {integrity: sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==} @@ -12494,6 +15984,10 @@ packages: string-to-color@2.2.2: resolution: {integrity: sha512-XeA2goP7PNsSlz8RRn6KhYswnMf5Tl+38ajfy8n4oZJyMGC4qqKgHNHsZ/3qwvr42NRIjf9eSr721SyetDeMkA==} + string-width@2.1.1: + resolution: {integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==} + engines: {node: '>=4'} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -12546,6 +16040,14 @@ packages: resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} engines: {node: '>=0.10.0'} + strip-ansi@4.0.0: + resolution: {integrity: sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==} + engines: {node: '>=4'} + + strip-ansi@5.2.0: + resolution: {integrity: sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==} + engines: {node: '>=6'} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -12638,9 +16140,19 @@ packages: peerDependencies: postcss: ^8.2.15 + stylehacks@6.1.1: + resolution: {integrity: sha512-gSTTEQ670cJNoaeIp9KX6lZmm8LJ3jPB5yJmX8Zq/wQxOsAFXV3qjWzHas3YYk1qesuVIyYWWUpZ0vSE/dTSGg==} + engines: {node: ^14 || ^16 || >=18.0} + peerDependencies: + postcss: ^8.4.31 + stylis@4.2.0: resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} + supports-color@2.0.0: + resolution: {integrity: sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g==} + engines: {node: '>=0.8.0'} + supports-color@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -12694,6 +16206,10 @@ packages: tabbable@6.4.0: resolution: {integrity: sha512-05PUHKSNE8ou2dwIxTngl4EzcnsCDZGJ/iCLtDflR/SHB/ny14rXc+qU5P4mG9JkusiV7EivzY9Mhm55AzAvCg==} + table@6.9.0: + resolution: {integrity: sha512-9kY+CygyYM6j02t5YFHbNz2FN5QmYGv9zAjVp4lCDjlCw7amdckXlEt/bjMhUIfj4ThGRE4gCUH5+yGnNuPo5A==} + engines: {node: '>=10.0.0'} + tapable@1.1.3: resolution: {integrity: sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==} engines: {node: '>=6'} @@ -12723,6 +16239,10 @@ packages: resolution: {integrity: sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==} engines: {node: '>=4'} + term-size@2.2.1: + resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==} + engines: {node: '>=8'} + terminal-link@2.1.1: resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==} engines: {node: '>=8'} @@ -12803,12 +16323,25 @@ packages: text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} + thenify-all@1.6.0: + resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==} + engines: {node: '>=0.8'} + + thenify@3.3.1: + resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + thread-loader@3.0.4: resolution: {integrity: sha512-ByaL2TPb+m6yArpqQUZvP+5S1mZtXsEP7nWKKlAUTm7fCml8kB5s1uI3+eHRP2bk5mVYfRSBI7FFf+tWEyLZwA==} engines: {node: '>= 10.13.0'} peerDependencies: webpack: ^4.27.0 || ^5.0.0 + thread-loader@4.0.4: + resolution: {integrity: sha512-tXagu6Hivd03wB2tiS1bqvw345sc7mKei32EgpYpq31ZLes9FN0mEK2nKzXLRFgwt3PsBB0E/MZDp159rDoqwg==} + engines: {node: '>= 16.10.0'} + peerDependencies: + webpack: ^5.0.0 + thread-stream@0.15.2: resolution: {integrity: sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==} @@ -12828,6 +16361,10 @@ packages: resolution: {integrity: sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==} engines: {node: '>=0.6.0'} + timers-ext@0.1.8: + resolution: {integrity: sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==} + engines: {node: '>=0.12'} + tiny-invariant@1.3.3: resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==} @@ -12853,6 +16390,10 @@ packages: resolution: {integrity: sha512-ELrFxuqsDdHUwoh0XxDbxuLD3Wnz49Z57IFvTtvWy1hJdcMZjXLIuonjilCiWHlT2GbE4Wlv1wKVTzDFnXH1aw==} hasBin: true + tmp@0.0.33: + resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} + engines: {node: '>=0.6.0'} + tmp@0.2.5: resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} engines: {node: '>=14.14'} @@ -12867,6 +16408,10 @@ packages: resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} engines: {node: '>= 0.4'} + to-fast-properties@2.0.0: + resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} + engines: {node: '>=4'} + to-object-path@0.3.0: resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} engines: {node: '>=0.10.0'} @@ -12893,6 +16438,10 @@ packages: toposort@2.0.2: resolution: {integrity: sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==} + touch@3.1.1: + resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==} + hasBin: true + tough-cookie@4.1.4: resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} engines: {node: '>=6'} @@ -13004,6 +16553,18 @@ packages: ts-mixer@6.0.4: resolution: {integrity: sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==} + ts-mocha@10.1.0: + resolution: {integrity: sha512-T0C0Xm3/WqCuF2tpa0GNGESTBoKZaiqdUP8guNv4ZY316AFXlyidnrzQ1LUrCT0Wb1i3J0zFTgOh/55Un44WdA==} + engines: {node: '>= 6.X.X'} + hasBin: true + peerDependencies: + mocha: ^3.X.X || ^4.X.X || ^5.X.X || ^6.X.X || ^7.X.X || ^8.X.X || ^9.X.X || ^10.X.X || ^11.X.X + + ts-node@7.0.1: + resolution: {integrity: sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw==} + engines: {node: '>=4.2.0'} + hasBin: true + ts-pnp@1.2.0: resolution: {integrity: sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw==} engines: {node: '>=6'} @@ -13016,6 +16577,10 @@ packages: tsconfig-paths-webpack-plugin@3.5.2: resolution: {integrity: sha512-EhnfjHbzm5IYI9YPNVIxx1moxMI4bpHD2e0zTXeDNQcwjjRaGepP7IhTHJkyDBG0CAOoxRfe7jCG630Ou+C6Pw==} + tsconfig-paths-webpack-plugin@4.2.0: + resolution: {integrity: sha512-zbem3rfRS8BgeNK50Zz5SIQgXzLafiHjOwUAvk/38/o1jHn/V5QAgVUcz884or7WYcPaH3N2CIfUc2u0ul7UcA==} + engines: {node: '>=10.13.0'} + tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} @@ -13026,6 +16591,9 @@ packages: tslib@1.14.1: resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + tslib@2.1.0: + resolution: {integrity: sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -13092,6 +16660,9 @@ packages: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} + type@2.7.3: + resolution: {integrity: sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==} + typed-array-buffer@1.0.3: resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} engines: {node: '>= 0.4'} @@ -13114,6 +16685,20 @@ packages: typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} + typedoc@0.22.18: + resolution: {integrity: sha512-NK9RlLhRUGMvc6Rw5USEYgT4DVAUFk7IF7Q6MYfpJ88KnTZP7EneEa4RcP+tX1auAcz7QT1Iy0bUSZBYYHdoyA==} + engines: {node: '>= 12.10.0'} + hasBin: true + peerDependencies: + typescript: 4.0.x || 4.1.x || 4.2.x || 4.3.x || 4.4.x || 4.5.x || 4.6.x || 4.7.x + + typedoc@0.24.8: + resolution: {integrity: sha512-ahJ6Cpcvxwaxfu4KtjA8qZNqS43wYt6JL27wYiIgl1vd38WW/KWX11YuAeZhuz9v+ttrutSsgK+XO1CjL1kA3w==} + engines: {node: '>= 14.14'} + hasBin: true + peerDependencies: + typescript: 4.6.x || 4.7.x || 4.8.x || 4.9.x || 5.0.x || 5.1.x + typeforce@1.18.0: resolution: {integrity: sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g==} @@ -13127,6 +16712,14 @@ packages: engines: {node: '>=14.17'} hasBin: true + typeson-registry@1.0.0-alpha.39: + resolution: {integrity: sha512-NeGDEquhw+yfwNhguLPcZ9Oj0fzbADiX4R0WxvoY8nGhy98IbzQy1sezjoEFWOywOboj/DWehI+/aUlRVrJnnw==} + engines: {node: '>=10.0.0'} + + typeson@6.1.0: + resolution: {integrity: sha512-6FTtyGr8ldU0pfbvW/eOZrEtEkczHRUtduBnA90Jh9kMPCiFNnXIon3vF41N0S4tV1HHQt4Hk1j4srpESziCaA==} + engines: {node: '>=0.1.14'} + ufo@1.6.4: resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} @@ -13142,6 +16735,9 @@ packages: uncrypto@0.1.3: resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + undefsafe@2.0.5: + resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==} + undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} @@ -13484,6 +17080,15 @@ packages: resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==} engines: {node: '>=0.10.0'} + vscode-oniguruma@1.7.0: + resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==} + + vscode-textmate@5.2.0: + resolution: {integrity: sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==} + + vscode-textmate@8.0.0: + resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==} + w3c-hr-time@1.0.2: resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} deprecated: Use your platform's native performance.now() and performance.timeOrigin. @@ -13515,12 +17120,18 @@ packages: wcwidth@1.0.1: resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} + weak-lru-cache@1.2.2: + resolution: {integrity: sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==} + web-namespaces@1.1.4: resolution: {integrity: sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==} webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + webidl-conversions@4.0.2: + resolution: {integrity: sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==} + webidl-conversions@5.0.0: resolution: {integrity: sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==} engines: {node: '>=8'} @@ -13553,6 +17164,23 @@ packages: webpack-dev-server: optional: true + webpack-cli@5.1.4: + resolution: {integrity: sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==} + engines: {node: '>=14.15.0'} + hasBin: true + peerDependencies: + '@webpack-cli/generators': '*' + webpack: 5.x.x + webpack-bundle-analyzer: '*' + webpack-dev-server: '*' + peerDependenciesMeta: + '@webpack-cli/generators': + optional: true + webpack-bundle-analyzer: + optional: true + webpack-dev-server: + optional: true + webpack-dev-middleware@3.7.3: resolution: {integrity: sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ==} engines: {node: '>= 6'} @@ -13727,6 +17355,9 @@ packages: worker-rpc@0.1.1: resolution: {integrity: sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg==} + workerpool@6.5.1: + resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==} + world-countries@5.1.0: resolution: {integrity: sha512-CXR6EBvTbArDlDDIWU3gfKb7Qk0ck2WNZ234b/A0vuecPzIfzzxH+O6Ejnvg1sT8XuiZjVlzOH0h08ZtaO7g0w==} @@ -13779,6 +17410,18 @@ packages: utf-8-validate: optional: true + ws@8.19.0: + resolution: {integrity: sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==} + 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 + ws@8.20.1: resolution: {integrity: sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==} engines: {node: '>=10.0.0'} @@ -13791,6 +17434,10 @@ packages: utf-8-validate: optional: true + wsl-utils@0.3.1: + resolution: {integrity: sha512-g/eziiSUNBSsdDJtCLB8bdYEUMj4jR7AGeUo96p/3dTafgjHhpF4RiCFPiRILwjQoDXx5MqkBr4fwWtR3Ky4Wg==} + engines: {node: '>=20'} + x-default-browser@0.4.0: resolution: {integrity: sha512-7LKo7RtWfoFN/rHx1UELv/2zHGMx8MkZKDq1xENmOCTkfIqZJ0zZ26NEJX8czhnPXVcqS0ARjjfJB+eJ0/5Cvw==} hasBin: true @@ -13849,6 +17496,10 @@ packages: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} + yargs-unparser@2.0.0: + resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} + engines: {node: '>=10'} + yargs@16.2.0: resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} engines: {node: '>=10'} @@ -13857,10 +17508,18 @@ packages: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} + yn@2.0.0: + resolution: {integrity: sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ==} + engines: {node: '>=4'} + yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} + engines: {node: '>=12.20'} + yup@0.32.11: resolution: {integrity: sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==} engines: {node: '>=10'} @@ -13918,6 +17577,10 @@ snapshots: '@asamuzakjp/nwsapi@2.3.9': {} + '@babel/code-frame@7.12.11': + dependencies: + '@babel/highlight': 7.25.9 + '@babel/code-frame@7.29.0': dependencies: '@babel/helper-validator-identifier': 7.28.5 @@ -13937,7 +17600,7 @@ snapshots: '@babel/traverse': 7.29.0 '@babel/types': 7.29.0 convert-source-map: 1.9.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 lodash: 4.18.1 @@ -13960,13 +17623,20 @@ snapshots: '@babel/types': 7.29.0 '@jridgewell/remapping': 2.3.5 convert-source-map: 2.0.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 transitivePeerDependencies: - supports-color + '@babel/generator@7.24.4': + dependencies: + '@babel/types': 7.29.0 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + jsesc: 2.5.2 + '@babel/generator@7.29.1': dependencies: '@babel/parser': 7.29.3 @@ -14014,7 +17684,7 @@ snapshots: '@babel/helper-module-imports': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 '@babel/traverse': 7.29.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) lodash.debounce: 4.0.8 resolve: 1.22.12 semver: 6.3.1 @@ -14026,14 +17696,27 @@ snapshots: '@babel/core': 7.29.0 '@babel/helper-compilation-targets': 7.28.6 '@babel/helper-plugin-utils': 7.28.6 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) lodash.debounce: 4.0.8 resolve: 1.22.12 transitivePeerDependencies: - supports-color + '@babel/helper-environment-visitor@7.24.7': + dependencies: + '@babel/types': 7.29.0 + + '@babel/helper-function-name@7.24.7': + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + '@babel/helper-globals@7.28.0': {} + '@babel/helper-hoist-variables@7.24.7': + dependencies: + '@babel/types': 7.29.0 + '@babel/helper-member-expression-to-functions@7.28.5': dependencies: '@babel/traverse': 7.29.0 @@ -14106,6 +17789,10 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/helper-split-export-declaration@7.24.7': + dependencies: + '@babel/types': 7.29.0 + '@babel/helper-string-parser@7.27.1': {} '@babel/helper-validator-identifier@7.28.5': {} @@ -14125,6 +17812,13 @@ snapshots: '@babel/template': 7.28.6 '@babel/types': 7.29.0 + '@babel/highlight@7.25.9': + dependencies: + '@babel/helper-validator-identifier': 7.28.5 + chalk: 2.4.2 + js-tokens: 4.0.0 + picocolors: 1.1.1 + '@babel/parser@7.29.3': dependencies: '@babel/types': 7.29.0 @@ -14896,6 +18590,21 @@ snapshots: '@babel/parser': 7.29.3 '@babel/types': 7.29.0 + '@babel/traverse@7.24.1': + dependencies: + '@babel/code-frame': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/helper-environment-visitor': 7.24.7 + '@babel/helper-function-name': 7.24.7 + '@babel/helper-hoist-variables': 7.24.7 + '@babel/helper-split-export-declaration': 7.24.7 + '@babel/parser': 7.29.3 + '@babel/types': 7.29.0 + debug: 4.4.3(supports-color@8.1.1) + globals: 11.12.0 + transitivePeerDependencies: + - supports-color + '@babel/traverse@7.29.0': dependencies: '@babel/code-frame': 7.29.0 @@ -14904,10 +18613,16 @@ snapshots: '@babel/parser': 7.29.3 '@babel/template': 7.28.6 '@babel/types': 7.29.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color + '@babel/types@7.24.0': + dependencies: + '@babel/helper-string-parser': 7.27.1 + '@babel/helper-validator-identifier': 7.28.5 + to-fast-properties: 2.0.0 + '@babel/types@7.29.0': dependencies: '@babel/helper-string-parser': 7.27.1 @@ -14972,6 +18687,10 @@ snapshots: '@keplr-wallet/crypto': 0.12.28 semver: 7.8.0 + '@chain-registry/types@0.17.1': + dependencies: + '@babel/runtime': 7.29.2 + '@chain-registry/types@0.46.15': {} '@chain-registry/types@0.50.356': {} @@ -14982,6 +18701,12 @@ snapshots: bignumber.js: 9.1.2 sha.js: 2.4.12 + '@chain-registry/v2-types@0.53.146': {} + + '@chain-registry/v2@1.71.237': + dependencies: + '@chain-registry/v2-types': 0.53.146 + '@cnakazawa/watch@1.0.4': dependencies: exec-sh: 0.3.6 @@ -15002,6 +18727,13 @@ snapshots: '@cosmjs/math': 0.25.6 '@cosmjs/utils': 0.25.6 + '@cosmjs/amino@0.29.5': + dependencies: + '@cosmjs/crypto': 0.29.5 + '@cosmjs/encoding': 0.29.5 + '@cosmjs/math': 0.29.5 + '@cosmjs/utils': 0.29.5 + '@cosmjs/amino@0.32.4': dependencies: '@cosmjs/crypto': 0.32.4 @@ -15046,6 +18778,24 @@ snapshots: - debug - utf-8-validate + '@cosmjs/cosmwasm-stargate@0.29.5': + dependencies: + '@cosmjs/amino': 0.29.5 + '@cosmjs/crypto': 0.29.5 + '@cosmjs/encoding': 0.29.5 + '@cosmjs/math': 0.29.5 + '@cosmjs/proto-signing': 0.29.5 + '@cosmjs/stargate': 0.29.5 + '@cosmjs/tendermint-rpc': 0.29.5 + '@cosmjs/utils': 0.29.5 + cosmjs-types: 0.5.2 + long: 4.0.0 + pako: 2.1.0 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + '@cosmjs/cosmwasm-stargate@0.32.4': dependencies: '@cosmjs/amino': 0.32.4 @@ -15092,6 +18842,16 @@ snapshots: ripemd160: 2.0.3 sha.js: 2.4.12 + '@cosmjs/crypto@0.29.5': + dependencies: + '@cosmjs/encoding': 0.29.5 + '@cosmjs/math': 0.29.5 + '@cosmjs/utils': 0.29.5 + '@noble/hashes': 1.8.0 + bn.js: 5.2.3 + elliptic: 6.6.1 + libsodium-wrappers: 0.7.16 + '@cosmjs/crypto@0.32.4': dependencies: '@cosmjs/encoding': 0.32.4 @@ -15118,6 +18878,12 @@ snapshots: bech32: 1.1.4 readonly-date: 1.0.0 + '@cosmjs/encoding@0.29.5': + dependencies: + base64-js: 1.5.1 + bech32: 1.1.4 + readonly-date: 1.0.0 + '@cosmjs/encoding@0.32.4': dependencies: base64-js: 1.5.1 @@ -15135,6 +18901,11 @@ snapshots: '@cosmjs/stream': 0.25.6 xstream: 11.14.0 + '@cosmjs/json-rpc@0.29.5': + dependencies: + '@cosmjs/stream': 0.29.5 + xstream: 11.14.0 + '@cosmjs/json-rpc@0.32.4': dependencies: '@cosmjs/stream': 0.32.4 @@ -15165,6 +18936,10 @@ snapshots: dependencies: bn.js: 5.2.3 + '@cosmjs/math@0.29.5': + dependencies: + bn.js: 5.2.3 + '@cosmjs/math@0.32.4': dependencies: bn.js: 5.2.3 @@ -15177,6 +18952,16 @@ snapshots: long: 4.0.0 protobufjs: 6.10.3 + '@cosmjs/proto-signing@0.29.5': + dependencies: + '@cosmjs/amino': 0.29.5 + '@cosmjs/crypto': 0.29.5 + '@cosmjs/encoding': 0.29.5 + '@cosmjs/math': 0.29.5 + '@cosmjs/utils': 0.29.5 + cosmjs-types: 0.5.2 + long: 4.0.0 + '@cosmjs/proto-signing@0.32.4': dependencies: '@cosmjs/amino': 0.32.4 @@ -15205,6 +18990,16 @@ snapshots: - bufferutil - utf-8-validate + '@cosmjs/socket@0.29.5': + dependencies: + '@cosmjs/stream': 0.29.5 + isomorphic-ws: 4.0.1(ws@7.5.10) + ws: 7.5.10 + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + '@cosmjs/socket@0.32.4': dependencies: '@cosmjs/stream': 0.32.4 @@ -15242,6 +19037,25 @@ snapshots: - debug - utf-8-validate + '@cosmjs/stargate@0.29.5': + dependencies: + '@confio/ics23': 0.6.8 + '@cosmjs/amino': 0.29.5 + '@cosmjs/encoding': 0.29.5 + '@cosmjs/math': 0.29.5 + '@cosmjs/proto-signing': 0.29.5 + '@cosmjs/stream': 0.29.5 + '@cosmjs/tendermint-rpc': 0.29.5 + '@cosmjs/utils': 0.29.5 + cosmjs-types: 0.5.2 + long: 4.0.0 + protobufjs: 6.11.6 + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + '@cosmjs/stargate@0.32.4': dependencies: '@confio/ics23': 0.6.8 @@ -15277,6 +19091,10 @@ snapshots: dependencies: xstream: 11.14.0 + '@cosmjs/stream@0.29.5': + dependencies: + xstream: 11.14.0 + '@cosmjs/stream@0.32.4': dependencies: xstream: 11.14.0 @@ -15301,6 +19119,23 @@ snapshots: - debug - utf-8-validate + '@cosmjs/tendermint-rpc@0.29.5': + dependencies: + '@cosmjs/crypto': 0.29.5 + '@cosmjs/encoding': 0.29.5 + '@cosmjs/json-rpc': 0.29.5 + '@cosmjs/math': 0.29.5 + '@cosmjs/socket': 0.29.5 + '@cosmjs/stream': 0.29.5 + '@cosmjs/utils': 0.29.5 + axios: 0.21.4 + readonly-date: 1.0.0 + xstream: 11.14.0 + transitivePeerDependencies: + - bufferutil + - debug + - utf-8-validate + '@cosmjs/tendermint-rpc@0.32.4': dependencies: '@cosmjs/crypto': 0.32.4 @@ -15335,6 +19170,8 @@ snapshots: '@cosmjs/utils@0.25.6': {} + '@cosmjs/utils@0.29.5': {} + '@cosmjs/utils@0.32.4': {} '@cosmjs/utils@0.36.2': {} @@ -15488,6 +19325,55 @@ snapshots: - uploadthing - utf-8-validate + '@cosmwasm/ts-codegen-ast@1.10.0': + dependencies: + '@babel/types': 7.24.0 + '@cosmwasm/ts-codegen-types': 1.5.0 + ast-stringify: 0.2.1 + case: 1.6.3 + deepmerge: 4.2.2 + minimatch: 10.2.5 + + '@cosmwasm/ts-codegen-types@1.5.0': + dependencies: + minimatch: 10.2.5 + + '@cosmwasm/ts-codegen@1.14.1(@chain-registry/v2-types@0.53.146)': + dependencies: + '@babel/generator': 7.24.4 + '@babel/traverse': 7.24.1 + '@babel/types': 7.24.0 + '@chain-registry/types': 0.17.1 + '@chain-registry/utils': 1.51.356 + '@chain-registry/v2': 1.71.237 + '@cosmwasm/ts-codegen-ast': 1.10.0 + '@cosmwasm/ts-codegen-types': 1.5.0 + '@interchainjs/amino': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + '@interchainjs/cosmos': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + '@interchainjs/types': 1.17.1 + '@pyramation/json-schema-to-typescript': 11.0.4 + '@types/rimraf': 3.0.2 + '@types/shelljs': 0.8.15 + case: 1.6.3 + dargs: 7.0.0 + deepmerge: 4.2.2 + fuzzy: 0.1.3 + glob: 10.5.0 + inquirerer: 0.1.3 + interchainjs: 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + minimatch: 10.2.5 + minimist: 1.2.6 + mkdirp: 1.0.4 + nested-obj: 0.2.2 + parse-package-name: 1.0.0 + rimraf: 3.0.2 + shelljs: 0.8.5 + transitivePeerDependencies: + - '@chain-registry/v2-types' + - bufferutil + - supports-color + - utf-8-validate + '@csstools/color-helpers@6.0.2': {} '@csstools/css-calc@3.2.1(@csstools/css-parser-algorithms@4.0.0(@csstools/css-tokenizer@4.0.0))(@csstools/css-tokenizer@4.0.0)': @@ -15743,6 +19629,11 @@ snapshots: '@esbuild/win32-x64@0.25.12': optional: true + '@eslint-community/eslint-utils@4.9.1(eslint@7.32.0)': + dependencies: + eslint: 7.32.0 + eslint-visitor-keys: 3.4.3 + '@eslint-community/eslint-utils@4.9.1(eslint@8.57.1)': dependencies: eslint: 8.57.1 @@ -15758,7 +19649,7 @@ snapshots: '@eslint/config-array@0.21.2': dependencies: '@eslint/object-schema': 2.1.7 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) minimatch: 3.1.5 transitivePeerDependencies: - supports-color @@ -15771,10 +19662,24 @@ snapshots: dependencies: '@types/json-schema': 7.0.15 + '@eslint/eslintrc@0.4.3': + dependencies: + ajv: 6.15.0 + debug: 4.4.3(supports-color@8.1.1) + espree: 7.3.1 + globals: 13.24.0 + ignore: 4.0.6 + import-fresh: 3.3.1 + js-yaml: 3.14.2 + minimatch: 3.1.5 + strip-json-comments: 3.1.1 + transitivePeerDependencies: + - supports-color + '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.15.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) espree: 9.6.1 globals: 13.24.0 ignore: 5.3.2 @@ -15788,7 +19693,7 @@ snapshots: '@eslint/eslintrc@3.3.5': dependencies: ajv: 6.15.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 @@ -15810,6 +19715,24 @@ snapshots: '@eslint/core': 0.17.0 levn: 0.4.1 + '@ethersproject/abstract-provider@5.8.0': + dependencies: + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/networks': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/transactions': 5.8.0 + '@ethersproject/web': 5.8.0 + + '@ethersproject/abstract-signer@5.8.0': + dependencies: + '@ethersproject/abstract-provider': 5.8.0 + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/address@5.8.0': dependencies: '@ethersproject/bignumber': 5.8.0 @@ -15818,6 +19741,10 @@ snapshots: '@ethersproject/logger': 5.8.0 '@ethersproject/rlp': 5.8.0 + '@ethersproject/base64@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/bignumber@5.8.0': dependencies: '@ethersproject/bytes': 5.8.0 @@ -15828,6 +19755,22 @@ snapshots: dependencies: '@ethersproject/logger': 5.8.0 + '@ethersproject/constants@5.8.0': + dependencies: + '@ethersproject/bignumber': 5.8.0 + + '@ethersproject/hash@5.8.0': + dependencies: + '@ethersproject/abstract-signer': 5.8.0 + '@ethersproject/address': 5.8.0 + '@ethersproject/base64': 5.8.0 + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/strings': 5.8.0 + '@ethersproject/keccak256@5.8.0': dependencies: '@ethersproject/bytes': 5.8.0 @@ -15835,15 +19778,68 @@ snapshots: '@ethersproject/logger@5.8.0': {} + '@ethersproject/networks@5.8.0': + dependencies: + '@ethersproject/logger': 5.8.0 + + '@ethersproject/properties@5.8.0': + dependencies: + '@ethersproject/logger': 5.8.0 + '@ethersproject/rlp@5.8.0': dependencies: '@ethersproject/bytes': 5.8.0 '@ethersproject/logger': 5.8.0 + '@ethersproject/signing-key@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + bn.js: 5.2.3 + elliptic: 6.6.1 + hash.js: 1.1.7 + + '@ethersproject/strings@5.8.0': + dependencies: + '@ethersproject/bytes': 5.8.0 + '@ethersproject/constants': 5.8.0 + '@ethersproject/logger': 5.8.0 + + '@ethersproject/transactions@5.8.0': + dependencies: + '@ethersproject/address': 5.8.0 + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/constants': 5.8.0 + '@ethersproject/keccak256': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/rlp': 5.8.0 + '@ethersproject/signing-key': 5.8.0 + + '@ethersproject/web@5.8.0': + dependencies: + '@ethersproject/base64': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/logger': 5.8.0 + '@ethersproject/properties': 5.8.0 + '@ethersproject/strings': 5.8.0 + '@exodus/bytes@1.15.0(@noble/hashes@1.8.0)': optionalDependencies: '@noble/hashes': 1.8.0 + '@favware/rollup-type-bundler@2.0.0': + dependencies: + '@sapphire/utilities': 3.18.2 + colorette: 2.0.20 + commander: 9.5.0 + js-yaml: 4.1.1 + rollup: 3.30.0 + rollup-plugin-dts: 5.3.1(rollup@3.30.0)(typescript@4.9.5) + typescript: 4.9.5 + '@floating-ui/core@1.7.5': dependencies: '@floating-ui/utils': 0.2.11 @@ -15898,13 +19894,23 @@ snapshots: '@humanwhocodes/config-array@0.13.0': dependencies: '@humanwhocodes/object-schema': 2.0.3 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) + minimatch: 3.1.5 + transitivePeerDependencies: + - supports-color + + '@humanwhocodes/config-array@0.5.0': + dependencies: + '@humanwhocodes/object-schema': 1.2.1 + debug: 4.4.3(supports-color@8.1.1) minimatch: 3.1.5 transitivePeerDependencies: - supports-color '@humanwhocodes/module-importer@1.0.1': {} + '@humanwhocodes/object-schema@1.2.1': {} + '@humanwhocodes/object-schema@2.0.3': {} '@humanwhocodes/retry@0.4.3': {} @@ -16027,6 +20033,128 @@ snapshots: - '@types/react' - babel-plugin-macros + '@interchainjs/amino@1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237)': + dependencies: + '@interchainjs/crypto': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + '@interchainjs/encoding': 1.17.1 + '@interchainjs/math': 1.17.1 + '@interchainjs/utils': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + transitivePeerDependencies: + - '@chain-registry/v2' + - '@chain-registry/v2-types' + + '@interchainjs/auth@1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237)': + dependencies: + '@interchainjs/crypto': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + '@interchainjs/types': 1.17.1 + '@interchainjs/utils': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + bech32: 2.0.0 + elliptic: 6.6.1 + libsodium-wrappers-sumo: 0.7.16 + transitivePeerDependencies: + - '@chain-registry/v2' + - '@chain-registry/v2-types' + + '@interchainjs/cosmos-types@1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237)': + dependencies: + '@interchainjs/math': 1.17.1 + '@interchainjs/types': 1.17.1 + '@interchainjs/utils': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + transitivePeerDependencies: + - '@chain-registry/v2' + - '@chain-registry/v2-types' + + '@interchainjs/cosmos@1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237)': + dependencies: + '@interchainjs/auth': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + '@interchainjs/cosmos-types': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + '@interchainjs/crypto': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + '@interchainjs/encoding': 1.17.1 + '@interchainjs/types': 1.17.1 + '@interchainjs/utils': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + bech32: 1.1.4 + bignumber.js: 9.3.1 + bip39: 3.1.0 + decimal.js: 10.6.0 + deepmerge: 4.2.2 + ws: 8.20.1 + transitivePeerDependencies: + - '@chain-registry/v2' + - '@chain-registry/v2-types' + - bufferutil + - utf-8-validate + + '@interchainjs/crypto@1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237)': + dependencies: + '@interchainjs/encoding': 1.17.1 + '@interchainjs/math': 1.17.1 + '@interchainjs/utils': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + '@noble/hashes': 1.8.0 + bn.js: 5.2.3 + elliptic: 6.6.1 + libsodium-wrappers-sumo: 0.7.16 + transitivePeerDependencies: + - '@chain-registry/v2' + - '@chain-registry/v2-types' + + '@interchainjs/encoding@1.17.1': + dependencies: + '@interchainjs/math': 1.17.1 + base64-js: 1.5.1 + bech32: 1.1.4 + readonly-date: 1.0.0 + + '@interchainjs/ethereum@1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237)': + dependencies: + '@ethersproject/bignumber': 5.8.0 + '@ethersproject/bytes': 5.8.0 + '@ethersproject/hash': 5.8.0 + '@ethersproject/transactions': 5.8.0 + '@interchainjs/auth': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + '@interchainjs/types': 1.17.1 + '@interchainjs/utils': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + bip39: 3.1.0 + deepmerge: 4.2.2 + ethereum-cryptography: 3.2.0 + rlp: 3.0.0 + transitivePeerDependencies: + - '@chain-registry/v2' + - '@chain-registry/v2-types' + + '@interchainjs/math@1.17.1': + dependencies: + bn.js: 5.2.3 + + '@interchainjs/pubkey@1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237)': + dependencies: + '@interchainjs/amino': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + '@interchainjs/cosmos-types': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + '@interchainjs/encoding': 1.17.1 + '@interchainjs/math': 1.17.1 + '@interchainjs/types': 1.17.1 + transitivePeerDependencies: + - '@chain-registry/v2' + - '@chain-registry/v2-types' + + '@interchainjs/types@1.17.1': + dependencies: + decimal.js: 10.6.0 + + '@interchainjs/utils@1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237)': + dependencies: + '@chain-registry/v2': 1.71.237 + '@chain-registry/v2-types': 0.53.146 + '@interchainjs/types': 1.17.1 + bech32: 2.0.0 + decimal.js: 10.6.0 + '@internationalized/date@3.12.1': dependencies: '@swc/helpers': 0.5.21 @@ -16162,6 +20290,10 @@ snapshots: '@types/node': 22.19.19 jest-mock: 29.7.0 + '@jest/expect-utils@28.1.3': + dependencies: + jest-get-type: 28.0.2 + '@jest/expect-utils@29.7.0': dependencies: jest-get-type: 29.6.3 @@ -16265,6 +20397,10 @@ snapshots: transitivePeerDependencies: - supports-color + '@jest/schemas@28.1.3': + dependencies: + '@sinclair/typebox': 0.24.51 + '@jest/schemas@29.6.3': dependencies: '@sinclair/typebox': 0.27.10 @@ -16387,6 +20523,15 @@ snapshots: '@types/yargs': 16.0.11 chalk: 4.1.2 + '@jest/types@28.1.3': + dependencies: + '@jest/schemas': 28.1.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 22.19.19 + '@types/yargs': 17.0.35 + chalk: 4.1.2 + '@jest/types@29.6.3': dependencies: '@jest/schemas': 29.6.3 @@ -16420,6 +20565,8 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 + '@jsdevtools/ono@7.1.3': {} + '@keplr-wallet/common@0.12.28': dependencies: '@keplr-wallet/crypto': 0.12.28 @@ -16491,11 +20638,11 @@ snapshots: execa: 5.0.0 strong-log-transformer: 2.1.0 - '@lerna/create@7.4.2(@types/node@22.19.19)(encoding@0.1.13)(typescript@5.9.3)': + '@lerna/create@7.4.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(@types/node@22.19.19)(encoding@0.1.13)(typescript@5.9.3)': dependencies: '@lerna/child-process': 7.4.2 '@npmcli/run-script': 6.0.2 - '@nx/devkit': 16.10.0(nx@16.10.0) + '@nx/devkit': 16.10.0(nx@16.10.0(@swc/core@1.15.40(@swc/helpers@0.5.21))) '@octokit/plugin-enterprise-rest': 6.0.1 '@octokit/rest': 19.0.11(encoding@0.1.13) byte-size: 8.1.1 @@ -16532,7 +20679,7 @@ snapshots: npm-packlist: 5.1.1 npm-registry-fetch: 14.0.5 npmlog: 6.0.2 - nx: 16.10.0 + nx: 16.10.0(@swc/core@1.15.40(@swc/helpers@0.5.21)) p-map: 4.0.0 p-map-series: 2.1.0 p-queue: 6.6.2 @@ -16568,6 +20715,30 @@ snapshots: - supports-color - typescript + '@lezer/common@1.5.2': {} + + '@lezer/lr@1.4.10': + dependencies: + '@lezer/common': 1.5.2 + + '@lmdb/lmdb-darwin-arm64@2.8.5': + optional: true + + '@lmdb/lmdb-darwin-x64@2.8.5': + optional: true + + '@lmdb/lmdb-linux-arm64@2.8.5': + optional: true + + '@lmdb/lmdb-linux-arm@2.8.5': + optional: true + + '@lmdb/lmdb-linux-x64@2.8.5': + optional: true + + '@lmdb/lmdb-win32-x64@2.8.5': + optional: true + '@mdx-js/mdx@1.6.22': dependencies: '@babel/core': 7.12.9 @@ -16598,11 +20769,35 @@ snapshots: '@mdx-js/util@1.6.22': {} + '@mischnic/json-sourcemap@0.1.1': + dependencies: + '@lezer/common': 1.5.2 + '@lezer/lr': 1.4.10 + json5: 2.2.3 + '@mrmlnc/readdir-enhanced@2.2.1': dependencies: call-me-maybe: 1.0.2 glob-to-regexp: 0.3.0 + '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4': + optional: true + + '@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4': + optional: true + + '@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4': + optional: true + + '@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4': + optional: true + '@mui/base@5.0.0-beta.40(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@babel/runtime': 7.29.2 @@ -17044,6 +21239,10 @@ snapshots: dependencies: '@noble/hashes': 1.6.0 + '@noble/curves@1.9.0': + dependencies: + '@noble/hashes': 1.8.0 + '@noble/curves@1.9.7': dependencies: '@noble/hashes': 1.8.0 @@ -17129,28 +21328,28 @@ snapshots: - bluebird - supports-color - '@nrwl/devkit@16.10.0(nx@16.10.0)': + '@nrwl/devkit@16.10.0(nx@16.10.0(@swc/core@1.15.40(@swc/helpers@0.5.21)))': dependencies: - '@nx/devkit': 16.10.0(nx@16.10.0) + '@nx/devkit': 16.10.0(nx@16.10.0(@swc/core@1.15.40(@swc/helpers@0.5.21))) transitivePeerDependencies: - nx - '@nrwl/tao@16.10.0': + '@nrwl/tao@16.10.0(@swc/core@1.15.40(@swc/helpers@0.5.21))': dependencies: - nx: 16.10.0 + nx: 16.10.0(@swc/core@1.15.40(@swc/helpers@0.5.21)) tslib: 2.8.1 transitivePeerDependencies: - '@swc-node/register' - '@swc/core' - debug - '@nx/devkit@16.10.0(nx@16.10.0)': + '@nx/devkit@16.10.0(nx@16.10.0(@swc/core@1.15.40(@swc/helpers@0.5.21)))': dependencies: - '@nrwl/devkit': 16.10.0(nx@16.10.0) + '@nrwl/devkit': 16.10.0(nx@16.10.0(@swc/core@1.15.40(@swc/helpers@0.5.21))) ejs: 3.1.10 enquirer: 2.3.6 ignore: 5.3.2 - nx: 16.10.0 + nx: 16.10.0(@swc/core@1.15.40(@swc/helpers@0.5.21)) semver: 7.5.3 tmp: 0.2.5 tslib: 2.8.1 @@ -17187,6 +21386,10 @@ snapshots: '@nymproject/contract-clients@1.4.1': {} + '@nymproject/nym-client-wasm-node@1.4.1': {} + + '@nymproject/nym-client-wasm@1.4.1': {} + '@nymproject/nym-validator-client@0.18.0': dependencies: '@cosmjs/cosmwasm-stargate': 0.25.6 @@ -17199,6 +21402,8 @@ snapshots: - debug - utf-8-validate + '@nymproject/sdk@1.4.1': {} + '@octokit/auth-token@3.0.4': {} '@octokit/core@4.2.4(encoding@0.1.13)': @@ -17282,11 +21487,659 @@ snapshots: dependencies: '@octokit/openapi-types': 18.1.1 + '@parcel/bundler-default@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/diagnostic': 2.16.4 + '@parcel/graph': 3.6.4 + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/rust': 2.16.4 + '@parcel/utils': 2.16.4 + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/cache@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/core': 2.16.4(@swc/helpers@0.5.21) + '@parcel/fs': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/logger': 2.16.4 + '@parcel/utils': 2.16.4 + lmdb: 2.8.5 + transitivePeerDependencies: + - napi-wasm + + '@parcel/codeframe@2.16.4': + dependencies: + chalk: 4.1.2 + + '@parcel/compressor-raw@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/config-default@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))(@swc/helpers@0.5.21)': + dependencies: + '@parcel/bundler-default': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/compressor-raw': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/core': 2.16.4(@swc/helpers@0.5.21) + '@parcel/namer-default': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/optimizer-css': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/optimizer-html': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/optimizer-image': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/optimizer-svg': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/optimizer-swc': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))(@swc/helpers@0.5.21) + '@parcel/packager-css': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/packager-html': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/packager-js': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/packager-raw': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/packager-svg': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/packager-wasm': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/reporter-dev-server': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/resolver-default': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/runtime-browser-hmr': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/runtime-js': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/runtime-rsc': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/runtime-service-worker': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/transformer-babel': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/transformer-css': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/transformer-html': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/transformer-image': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/transformer-js': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/transformer-json': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/transformer-node': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/transformer-postcss': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/transformer-posthtml': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/transformer-raw': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/transformer-react-refresh-wrap': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/transformer-svg': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + transitivePeerDependencies: + - '@swc/helpers' + - napi-wasm + + '@parcel/core@2.16.4(@swc/helpers@0.5.21)': + dependencies: + '@mischnic/json-sourcemap': 0.1.1 + '@parcel/cache': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/diagnostic': 2.16.4 + '@parcel/events': 2.16.4 + '@parcel/feature-flags': 2.16.4 + '@parcel/fs': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/graph': 3.6.4 + '@parcel/logger': 2.16.4 + '@parcel/package-manager': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))(@swc/helpers@0.5.21) + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/profiler': 2.16.4 + '@parcel/rust': 2.16.4 + '@parcel/source-map': 2.1.1 + '@parcel/types': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/utils': 2.16.4 + '@parcel/workers': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + base-x: 3.0.11 + browserslist: 4.28.2 + clone: 2.1.2 + dotenv: 16.6.1 + dotenv-expand: 11.0.7 + json5: 2.2.3 + msgpackr: 1.11.12 + nullthrows: 1.1.1 + semver: 7.8.0 + transitivePeerDependencies: + - '@swc/helpers' + - napi-wasm + + '@parcel/diagnostic@2.16.4': + dependencies: + '@mischnic/json-sourcemap': 0.1.1 + nullthrows: 1.1.1 + + '@parcel/error-overlay@2.16.4': {} + + '@parcel/events@2.16.4': {} + + '@parcel/feature-flags@2.16.4': {} + + '@parcel/fs@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/core': 2.16.4(@swc/helpers@0.5.21) + '@parcel/feature-flags': 2.16.4 + '@parcel/rust': 2.16.4 + '@parcel/types-internal': 2.16.4 + '@parcel/utils': 2.16.4 + '@parcel/watcher': 2.5.6 + '@parcel/workers': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + transitivePeerDependencies: + - napi-wasm + + '@parcel/graph@3.6.4': + dependencies: + '@parcel/feature-flags': 2.16.4 + nullthrows: 1.1.1 + + '@parcel/logger@2.16.4': + dependencies: + '@parcel/diagnostic': 2.16.4 + '@parcel/events': 2.16.4 + + '@parcel/markdown-ansi@2.16.4': + dependencies: + chalk: 4.1.2 + + '@parcel/namer-default@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/diagnostic': 2.16.4 + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/node-resolver-core@3.7.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@mischnic/json-sourcemap': 0.1.1 + '@parcel/diagnostic': 2.16.4 + '@parcel/fs': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/rust': 2.16.4 + '@parcel/utils': 2.16.4 + nullthrows: 1.1.1 + semver: 7.8.0 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/optimizer-css@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/diagnostic': 2.16.4 + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/source-map': 2.1.1 + '@parcel/utils': 2.16.4 + browserslist: 4.28.2 + lightningcss: 1.32.0 + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/optimizer-html@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/rust': 2.16.4 + '@parcel/utils': 2.16.4 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/optimizer-image@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/core': 2.16.4(@swc/helpers@0.5.21) + '@parcel/diagnostic': 2.16.4 + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/rust': 2.16.4 + '@parcel/utils': 2.16.4 + '@parcel/workers': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + transitivePeerDependencies: + - napi-wasm + + '@parcel/optimizer-svg@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/rust': 2.16.4 + '@parcel/utils': 2.16.4 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/optimizer-swc@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))(@swc/helpers@0.5.21)': + dependencies: + '@parcel/diagnostic': 2.16.4 + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/source-map': 2.1.1 + '@parcel/utils': 2.16.4 + '@swc/core': 1.15.40(@swc/helpers@0.5.21) + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@parcel/core' + - '@swc/helpers' + - napi-wasm + + '@parcel/package-manager@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))(@swc/helpers@0.5.21)': + dependencies: + '@parcel/core': 2.16.4(@swc/helpers@0.5.21) + '@parcel/diagnostic': 2.16.4 + '@parcel/fs': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/logger': 2.16.4 + '@parcel/node-resolver-core': 3.7.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/types': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/utils': 2.16.4 + '@parcel/workers': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@swc/core': 1.15.40(@swc/helpers@0.5.21) + semver: 7.8.0 + transitivePeerDependencies: + - '@swc/helpers' + - napi-wasm + + '@parcel/packager-css@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/diagnostic': 2.16.4 + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/source-map': 2.1.1 + '@parcel/utils': 2.16.4 + lightningcss: 1.32.0 + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/packager-html@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/rust': 2.16.4 + '@parcel/types': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/utils': 2.16.4 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/packager-js@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/diagnostic': 2.16.4 + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/rust': 2.16.4 + '@parcel/source-map': 2.1.1 + '@parcel/types': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/utils': 2.16.4 + globals: 13.24.0 + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/packager-raw@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/packager-svg@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/rust': 2.16.4 + '@parcel/types': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/utils': 2.16.4 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/packager-wasm@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/plugin@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/types': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/profiler@2.16.4': + dependencies: + '@parcel/diagnostic': 2.16.4 + '@parcel/events': 2.16.4 + '@parcel/types-internal': 2.16.4 + chrome-trace-event: 1.0.4 + + '@parcel/reporter-cli@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/types': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/utils': 2.16.4 + chalk: 4.1.2 + term-size: 2.2.1 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/reporter-dev-server@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/codeframe': 2.16.4 + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/source-map': 2.1.1 + '@parcel/utils': 2.16.4 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/reporter-tracer@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/utils': 2.16.4 + chrome-trace-event: 1.0.4 + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/resolver-default@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/node-resolver-core': 3.7.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/runtime-browser-hmr@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/utils': 2.16.4 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/runtime-js@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/diagnostic': 2.16.4 + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/utils': 2.16.4 + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/runtime-rsc@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/rust': 2.16.4 + '@parcel/utils': 2.16.4 + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/runtime-service-worker@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/utils': 2.16.4 + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/rust-darwin-arm64@2.16.4': + optional: true + + '@parcel/rust-darwin-x64@2.16.4': + optional: true + + '@parcel/rust-linux-arm-gnueabihf@2.16.4': + optional: true + + '@parcel/rust-linux-arm64-gnu@2.16.4': + optional: true + + '@parcel/rust-linux-arm64-musl@2.16.4': + optional: true + + '@parcel/rust-linux-x64-gnu@2.16.4': + optional: true + + '@parcel/rust-linux-x64-musl@2.16.4': + optional: true + + '@parcel/rust-win32-x64-msvc@2.16.4': + optional: true + + '@parcel/rust@2.16.4': + optionalDependencies: + '@parcel/rust-darwin-arm64': 2.16.4 + '@parcel/rust-darwin-x64': 2.16.4 + '@parcel/rust-linux-arm-gnueabihf': 2.16.4 + '@parcel/rust-linux-arm64-gnu': 2.16.4 + '@parcel/rust-linux-arm64-musl': 2.16.4 + '@parcel/rust-linux-x64-gnu': 2.16.4 + '@parcel/rust-linux-x64-musl': 2.16.4 + '@parcel/rust-win32-x64-msvc': 2.16.4 + + '@parcel/source-map@2.1.1': + dependencies: + detect-libc: 1.0.3 + + '@parcel/transformer-babel@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/diagnostic': 2.16.4 + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/source-map': 2.1.1 + '@parcel/utils': 2.16.4 + browserslist: 4.28.2 + json5: 2.2.3 + nullthrows: 1.1.1 + semver: 7.8.0 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/transformer-css@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/diagnostic': 2.16.4 + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/source-map': 2.1.1 + '@parcel/utils': 2.16.4 + browserslist: 4.28.2 + lightningcss: 1.32.0 + nullthrows: 1.1.1 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/transformer-html@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/diagnostic': 2.16.4 + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/rust': 2.16.4 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/transformer-image@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/core': 2.16.4(@swc/helpers@0.5.21) + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/utils': 2.16.4 + '@parcel/workers': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + nullthrows: 1.1.1 + transitivePeerDependencies: + - napi-wasm + + '@parcel/transformer-js@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/core': 2.16.4(@swc/helpers@0.5.21) + '@parcel/diagnostic': 2.16.4 + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/rust': 2.16.4 + '@parcel/source-map': 2.1.1 + '@parcel/utils': 2.16.4 + '@parcel/workers': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@swc/helpers': 0.5.21 + browserslist: 4.28.2 + nullthrows: 1.1.1 + regenerator-runtime: 0.14.1 + semver: 7.8.0 + transitivePeerDependencies: + - napi-wasm + + '@parcel/transformer-json@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + json5: 2.2.3 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/transformer-node@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/transformer-postcss@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/diagnostic': 2.16.4 + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/rust': 2.16.4 + '@parcel/utils': 2.16.4 + clone: 2.1.2 + nullthrows: 1.1.1 + postcss-value-parser: 4.2.0 + semver: 7.8.0 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/transformer-posthtml@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/utils': 2.16.4 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/transformer-raw@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/transformer-react-refresh-wrap@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/error-overlay': 2.16.4 + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/utils': 2.16.4 + react-refresh: 0.16.0 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/transformer-svg@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/diagnostic': 2.16.4 + '@parcel/plugin': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/rust': 2.16.4 + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/types-internal@2.16.4': + dependencies: + '@parcel/diagnostic': 2.16.4 + '@parcel/feature-flags': 2.16.4 + '@parcel/source-map': 2.1.1 + utility-types: 3.11.0 + + '@parcel/types@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/types-internal': 2.16.4 + '@parcel/workers': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + transitivePeerDependencies: + - '@parcel/core' + - napi-wasm + + '@parcel/utils@2.16.4': + dependencies: + '@parcel/codeframe': 2.16.4 + '@parcel/diagnostic': 2.16.4 + '@parcel/logger': 2.16.4 + '@parcel/markdown-ansi': 2.16.4 + '@parcel/rust': 2.16.4 + '@parcel/source-map': 2.1.1 + chalk: 4.1.2 + nullthrows: 1.1.1 + transitivePeerDependencies: + - napi-wasm + + '@parcel/watcher-android-arm64@2.5.6': + optional: true + + '@parcel/watcher-darwin-arm64@2.5.6': + optional: true + + '@parcel/watcher-darwin-x64@2.5.6': + optional: true + + '@parcel/watcher-freebsd-x64@2.5.6': + optional: true + + '@parcel/watcher-linux-arm-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-arm-musl@2.5.6': + optional: true + + '@parcel/watcher-linux-arm64-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-arm64-musl@2.5.6': + optional: true + + '@parcel/watcher-linux-x64-glibc@2.5.6': + optional: true + + '@parcel/watcher-linux-x64-musl@2.5.6': + optional: true + + '@parcel/watcher-win32-arm64@2.5.6': + optional: true + + '@parcel/watcher-win32-ia32@2.5.6': + optional: true + + '@parcel/watcher-win32-x64@2.5.6': + optional: true + '@parcel/watcher@2.0.4': dependencies: node-addon-api: 3.2.1 node-gyp-build: 4.8.4 + '@parcel/watcher@2.5.6': + dependencies: + detect-libc: 2.1.2 + is-glob: 4.0.3 + node-addon-api: 7.1.1 + picomatch: 4.0.4 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.5.6 + '@parcel/watcher-darwin-arm64': 2.5.6 + '@parcel/watcher-darwin-x64': 2.5.6 + '@parcel/watcher-freebsd-x64': 2.5.6 + '@parcel/watcher-linux-arm-glibc': 2.5.6 + '@parcel/watcher-linux-arm-musl': 2.5.6 + '@parcel/watcher-linux-arm64-glibc': 2.5.6 + '@parcel/watcher-linux-arm64-musl': 2.5.6 + '@parcel/watcher-linux-x64-glibc': 2.5.6 + '@parcel/watcher-linux-x64-musl': 2.5.6 + '@parcel/watcher-win32-arm64': 2.5.6 + '@parcel/watcher-win32-ia32': 2.5.6 + '@parcel/watcher-win32-x64': 2.5.6 + + '@parcel/workers@2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))': + dependencies: + '@parcel/core': 2.16.4(@swc/helpers@0.5.21) + '@parcel/diagnostic': 2.16.4 + '@parcel/logger': 2.16.4 + '@parcel/profiler': 2.16.4 + '@parcel/types-internal': 2.16.4 + '@parcel/utils': 2.16.4 + nullthrows: 1.1.1 + transitivePeerDependencies: + - napi-wasm + '@pkgjs/parseargs@0.11.0': optional: true @@ -17300,14 +22153,14 @@ snapshots: react-refresh: 0.10.0 schema-utils: 4.3.3 source-map: 0.7.6 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0) optionalDependencies: '@types/webpack': 4.41.40 type-fest: 4.41.0 webpack-dev-server: 4.15.2(webpack-cli@4.10.0)(webpack@5.106.2) webpack-hot-middleware: 2.26.1 - '@pmmmwh/react-refresh-webpack-plugin@0.5.17(@types/webpack@4.41.40)(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@4.15.2(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)))(webpack-hot-middleware@2.26.1)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14))': + '@pmmmwh/react-refresh-webpack-plugin@0.5.17(@types/webpack@4.41.40)(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@4.15.2(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)))(webpack-hot-middleware@2.26.1)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14))': dependencies: ansi-html: 0.0.9 core-js-pure: 3.49.0 @@ -17317,11 +22170,45 @@ snapshots: react-refresh: 0.11.0 schema-utils: 4.3.3 source-map: 0.7.6 - webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14) optionalDependencies: '@types/webpack': 4.41.40 type-fest: 4.41.0 - webpack-dev-server: 4.15.2(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + webpack-dev-server: 4.15.2(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) + webpack-hot-middleware: 2.26.1 + + '@pmmmwh/react-refresh-webpack-plugin@0.5.17(@types/webpack@4.41.40)(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@4.15.2(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)))(webpack-hot-middleware@2.26.1)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14))': + dependencies: + ansi-html: 0.0.9 + core-js-pure: 3.49.0 + error-stack-parser: 2.1.4 + html-entities: 2.6.0 + loader-utils: 2.0.4 + react-refresh: 0.11.0 + schema-utils: 4.3.3 + source-map: 0.7.6 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14) + optionalDependencies: + '@types/webpack': 4.41.40 + type-fest: 4.41.0 + webpack-dev-server: 4.15.2(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + webpack-hot-middleware: 2.26.1 + + '@pmmmwh/react-refresh-webpack-plugin@0.5.17(@types/webpack@4.41.40)(react-refresh@0.16.0)(type-fest@4.41.0)(webpack-dev-server@4.15.2)(webpack-hot-middleware@2.26.1)(webpack@5.106.2)': + dependencies: + ansi-html: 0.0.9 + core-js-pure: 3.49.0 + error-stack-parser: 2.1.4 + html-entities: 2.6.0 + loader-utils: 2.0.4 + react-refresh: 0.16.0 + schema-utils: 4.3.3 + source-map: 0.7.6 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(webpack-cli@4.10.0) + optionalDependencies: + '@types/webpack': 4.41.40 + type-fest: 4.41.0 + webpack-dev-server: 4.15.2(webpack-cli@4.10.0)(webpack@5.106.2) webpack-hot-middleware: 2.26.1 '@popperjs/core@2.11.8': {} @@ -17349,6 +22236,29 @@ snapshots: '@protobufjs/utf8@1.1.1': {} + '@pyramation/json-schema-ref-parser@9.0.6': + dependencies: + '@jsdevtools/ono': 7.1.3 + call-me-maybe: 1.0.2 + js-yaml: 3.14.2 + + '@pyramation/json-schema-to-typescript@11.0.4': + dependencies: + '@pyramation/json-schema-ref-parser': 9.0.6 + '@types/json-schema': 7.0.15 + '@types/lodash': 4.17.24 + '@types/prettier': 2.7.3 + cli-color: 2.0.4 + get-stdin: 8.0.0 + glob: 7.2.3 + glob-promise: 4.2.2(glob@7.2.3) + is-glob: 4.0.3 + lodash: 4.18.1 + minimist: 1.2.8 + mkdirp: 1.0.4 + mz: 2.7.0 + prettier: 2.8.8 + '@react-aria/listbox@3.16.0(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@swc/helpers': 0.5.21 @@ -17413,12 +22323,122 @@ snapshots: '@remix-run/router@1.23.2': {} + '@rollup/plugin-commonjs@24.1.0(rollup@3.30.0)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@3.30.0) + commondir: 1.0.1 + estree-walker: 2.0.2 + glob: 8.1.0 + is-reference: 1.2.1 + magic-string: 0.27.0 + optionalDependencies: + rollup: 3.30.0 + + '@rollup/plugin-inject@5.0.5(rollup@3.30.0)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@3.30.0) + estree-walker: 2.0.2 + magic-string: 0.30.21 + optionalDependencies: + rollup: 3.30.0 + + '@rollup/plugin-json@6.1.0(rollup@3.30.0)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@3.30.0) + optionalDependencies: + rollup: 3.30.0 + + '@rollup/plugin-node-resolve@15.3.1(rollup@3.30.0)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@3.30.0) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-module: 1.0.0 + resolve: 1.22.12 + optionalDependencies: + rollup: 3.30.0 + + '@rollup/plugin-replace@5.0.7(rollup@3.30.0)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@3.30.0) + magic-string: 0.30.21 + optionalDependencies: + rollup: 3.30.0 + + '@rollup/plugin-terser@0.2.1(rollup@3.30.0)': + dependencies: + serialize-javascript: 6.0.2 + smob: 0.0.6 + terser: 5.47.1 + optionalDependencies: + rollup: 3.30.0 + + '@rollup/plugin-typescript@10.0.1(rollup@3.30.0)(tslib@2.8.1)(typescript@4.9.5)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@3.30.0) + resolve: 1.22.12 + typescript: 4.9.5 + optionalDependencies: + rollup: 3.30.0 + tslib: 2.8.1 + + '@rollup/plugin-typescript@11.1.6(rollup@3.30.0)(tslib@2.8.1)(typescript@4.9.5)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@3.30.0) + resolve: 1.22.12 + typescript: 4.9.5 + optionalDependencies: + rollup: 3.30.0 + tslib: 2.8.1 + + '@rollup/plugin-url@8.0.2(rollup@3.30.0)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@3.30.0) + make-dir: 3.1.0 + mime: 3.0.0 + optionalDependencies: + rollup: 3.30.0 + + '@rollup/plugin-wasm@6.2.2(rollup@3.30.0)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@3.30.0) + optionalDependencies: + rollup: 3.30.0 + + '@rollup/pluginutils@3.1.0(rollup@3.30.0)': + dependencies: + '@types/estree': 0.0.39 + estree-walker: 1.0.1 + picomatch: 2.3.2 + rollup: 3.30.0 + + '@rollup/pluginutils@5.4.0(rollup@3.30.0)': + dependencies: + '@types/estree': 1.0.9 + estree-walker: 2.0.2 + picomatch: 4.0.4 + optionalDependencies: + rollup: 3.30.0 + '@rtsao/scc@1.1.0': {} '@rushstack/eslint-patch@1.16.1': {} + '@sapphire/utilities@3.18.2': {} + '@scure/base@1.2.6': {} + '@scure/bip32@1.7.0': + dependencies: + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@scure/bip39@1.6.0': + dependencies: + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@scure/starknet@1.1.0': dependencies: '@noble/curves': 1.7.0 @@ -17453,6 +22473,8 @@ snapshots: transitivePeerDependencies: - supports-color + '@sinclair/typebox@0.24.51': {} + '@sinclair/typebox@0.27.10': {} '@sinonjs/commons@1.8.6': @@ -17519,6 +22541,31 @@ snapshots: react: 19.2.6 react-dom: 19.2.6(react@19.2.6) + '@storybook/addon-controls@6.5.16(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': + dependencies: + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/components': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-common': 6.5.16(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/node-logger': 6.5.16 + '@storybook/store': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + core-js: 3.49.0 + lodash: 4.18.1 + ts-dedent: 2.2.0 + optionalDependencies: + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + transitivePeerDependencies: + - eslint + - supports-color + - typescript + - vue-template-compiler + - webpack-cli + - webpack-command + '@storybook/addon-controls@6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': dependencies: '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -17544,7 +22591,7 @@ snapshots: - webpack-cli - webpack-command - '@storybook/addon-docs@6.5.16(@babel/core@7.29.0)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14))': + '@storybook/addon-docs@6.5.16(@babel/core@7.29.0)(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14))': dependencies: '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) '@babel/preset-env': 7.29.5(@babel/core@7.29.0) @@ -17553,7 +22600,7 @@ snapshots: '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@storybook/api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@storybook/components': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@storybook/core-common': 6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/core-common': 6.5.16(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) '@storybook/core-events': 6.5.16 '@storybook/csf': 0.0.2--canary.4566f4d.1 '@storybook/docs-tools': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -17564,7 +22611,7 @@ snapshots: '@storybook/source-loader': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@storybook/store': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) core-js: 3.49.0 fast-deep-equal: 3.1.3 global: 4.4.0 @@ -17587,13 +22634,56 @@ snapshots: - webpack-cli - webpack-command - '@storybook/addon-essentials@6.5.16(@babel/core@7.29.0)(@storybook/builder-webpack5@6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14))': + '@storybook/addon-docs@6.5.16(@babel/core@7.29.0)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14))': + dependencies: + '@babel/plugin-transform-react-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/preset-env': 7.29.5(@babel/core@7.29.0) + '@jest/transform': 26.6.2 + '@mdx-js/react': 1.6.22(react@19.2.6) + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/components': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-common': 6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/core-events': 6.5.16 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/docs-tools': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/mdx1-csf': 0.0.1(@babel/core@7.29.0) + '@storybook/node-logger': 6.5.16 + '@storybook/postinstall': 6.5.16 + '@storybook/preview-web': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/source-loader': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/store': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) + core-js: 3.49.0 + fast-deep-equal: 3.1.3 + global: 4.4.0 + lodash: 4.18.1 + regenerator-runtime: 0.13.11 + remark-external-links: 8.0.0 + remark-slug: 6.1.0 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + optionalDependencies: + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + transitivePeerDependencies: + - '@babel/core' + - eslint + - supports-color + - typescript + - vue-template-compiler + - webpack + - webpack-cli + - webpack-command + + '@storybook/addon-essentials@6.5.16(@babel/core@7.29.0)(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14))': dependencies: '@babel/core': 7.29.0 '@storybook/addon-actions': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@storybook/addon-backgrounds': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@storybook/addon-controls': 6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) - '@storybook/addon-docs': 6.5.16(@babel/core@7.29.0)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + '@storybook/addon-docs': 6.5.16(@babel/core@7.29.0)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) '@storybook/addon-measure': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@storybook/addon-outline': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@storybook/addon-toolbars': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -17606,10 +22696,10 @@ snapshots: regenerator-runtime: 0.13.11 ts-dedent: 2.2.0 optionalDependencies: - '@storybook/builder-webpack5': 6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/builder-webpack5': 6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) react: 19.2.6 react-dom: 19.2.6(react@19.2.6) - webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14) transitivePeerDependencies: - '@storybook/mdx2-csf' - eslint @@ -17619,6 +22709,67 @@ snapshots: - webpack-cli - webpack-command + '@storybook/addon-essentials@6.5.16(@babel/core@7.29.0)(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14))': + dependencies: + '@babel/core': 7.29.0 + '@storybook/addon-actions': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/addon-backgrounds': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/addon-controls': 6.5.16(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/addon-docs': 6.5.16(@babel/core@7.29.0)(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + '@storybook/addon-measure': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/addon-outline': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/addon-toolbars': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/addon-viewport': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-common': 6.5.16(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/node-logger': 6.5.16 + core-js: 3.49.0 + regenerator-runtime: 0.13.11 + ts-dedent: 2.2.0 + optionalDependencies: + '@storybook/builder-webpack5': 6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14) + transitivePeerDependencies: + - '@storybook/mdx2-csf' + - eslint + - supports-color + - typescript + - vue-template-compiler + - webpack-cli + - webpack-command + + '@storybook/addon-interactions@6.5.16(@types/react@19.2.14)(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': + dependencies: + '@devtools-ds/object-inspector': 1.2.1(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/components': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-common': 6.5.16(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/core-events': 6.5.16 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/instrumenter': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + core-js: 3.49.0 + global: 4.4.0 + jest-mock: 27.5.1 + polished: 4.3.1 + ts-dedent: 2.2.0 + optionalDependencies: + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + transitivePeerDependencies: + - '@types/react' + - eslint + - supports-color + - typescript + - vue-template-compiler + - webpack-cli + - webpack-command + '@storybook/addon-interactions@6.5.16(@types/react@19.2.14)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': dependencies: '@devtools-ds/object-inspector': 1.2.1(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -17764,6 +22915,67 @@ snapshots: ts-dedent: 2.2.0 util-deprecate: 1.0.2 + '@storybook/builder-webpack4@6.5.16(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': + dependencies: + '@babel/core': 7.29.0 + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/channel-postmessage': 6.5.16 + '@storybook/channels': 6.5.16 + '@storybook/client-api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/components': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-common': 6.5.16(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/core-events': 6.5.16 + '@storybook/node-logger': 6.5.16 + '@storybook/preview-web': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/router': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/semver': 7.3.2 + '@storybook/store': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/ui': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/node': 16.18.126 + '@types/webpack': 4.41.40 + autoprefixer: 9.8.8 + babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@4.47.0) + case-sensitive-paths-webpack-plugin: 2.4.0 + core-js: 3.49.0 + css-loader: 3.6.0(webpack@4.47.0) + file-loader: 6.2.0(webpack@4.47.0) + find-up: 5.0.0 + fork-ts-checker-webpack-plugin: 4.1.6(eslint@8.57.1)(typescript@4.9.5)(webpack@4.47.0) + glob: 7.2.3 + glob-promise: 3.4.0(glob@7.2.3) + global: 4.4.0 + html-webpack-plugin: 4.5.2(webpack@4.47.0) + pnp-webpack-plugin: 1.6.4(typescript@4.9.5) + postcss: 7.0.39 + postcss-flexbugs-fixes: 4.2.1 + postcss-loader: 4.3.0(postcss@7.0.39)(webpack@4.47.0) + raw-loader: 4.0.2(webpack@4.47.0) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + stable: 0.1.8 + style-loader: 1.3.0(webpack@4.47.0) + terser-webpack-plugin: 4.2.3(webpack@4.47.0) + ts-dedent: 2.2.0 + url-loader: 4.1.1(file-loader@6.2.0(webpack@4.47.0))(webpack@4.47.0) + util-deprecate: 1.0.2 + webpack: 4.47.0 + webpack-dev-middleware: 3.7.3(webpack@4.47.0) + webpack-filter-warnings-plugin: 1.2.1(webpack@4.47.0) + webpack-hot-middleware: 2.26.1 + webpack-virtual-modules: 0.2.2 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - bluebird + - eslint + - supports-color + - vue-template-compiler + - webpack-cli + - webpack-command + '@storybook/builder-webpack4@6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': dependencies: '@babel/core': 7.29.0 @@ -17790,7 +23002,7 @@ snapshots: case-sensitive-paths-webpack-plugin: 2.4.0 core-js: 3.49.0 css-loader: 3.6.0(webpack@4.47.0) - file-loader: 6.2.0(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + file-loader: 6.2.0(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) find-up: 5.0.0 fork-ts-checker-webpack-plugin: 4.1.6(eslint@9.39.4)(typescript@4.9.5)(webpack@4.47.0) glob: 7.2.3 @@ -17825,7 +23037,7 @@ snapshots: - webpack-cli - webpack-command - '@storybook/builder-webpack5@6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': + '@storybook/builder-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': dependencies: '@babel/core': 7.29.0 '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) @@ -17844,27 +23056,91 @@ snapshots: '@storybook/store': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@types/node': 16.18.126 - babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) babel-plugin-named-exports-order: 0.0.2 browser-assert: 1.2.1 case-sensitive-paths-webpack-plugin: 2.4.0 core-js: 3.49.0 - css-loader: 5.2.7(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) - fork-ts-checker-webpack-plugin: 6.5.3(eslint@9.39.4)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + css-loader: 5.2.7(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) + fork-ts-checker-webpack-plugin: 6.5.3(eslint@9.39.4)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) glob: 7.2.3 glob-promise: 3.4.0(glob@7.2.3) - html-webpack-plugin: 5.6.7(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + html-webpack-plugin: 5.6.7(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) path-browserify: 1.0.1 process: 0.11.10 react: 19.2.6 react-dom: 19.2.6(react@19.2.6) stable: 0.1.8 - style-loader: 2.0.0(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) - terser-webpack-plugin: 5.6.0(esbuild@0.25.12)(postcss@8.5.14)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + style-loader: 2.0.0(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) + terser-webpack-plugin: 5.6.0(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) ts-dedent: 2.2.0 util-deprecate: 1.0.2 - webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) - webpack-dev-middleware: 4.3.0(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14) + webpack-dev-middleware: 4.3.0(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) + webpack-hot-middleware: 2.26.1 + webpack-virtual-modules: 0.4.6 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - '@minify-html/node' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - esbuild + - eslint + - html-minifier-terser + - lightningcss + - postcss + - supports-color + - uglify-js + - vue-template-compiler + - webpack-cli + - webpack-command + + '@storybook/builder-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': + dependencies: + '@babel/core': 7.29.0 + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/channel-postmessage': 6.5.16 + '@storybook/channels': 6.5.16 + '@storybook/client-api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/components': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-common': 6.5.16(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/core-events': 6.5.16 + '@storybook/node-logger': 6.5.16 + '@storybook/preview-web': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/router': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/semver': 7.3.2 + '@storybook/store': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/node': 16.18.126 + babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + babel-plugin-named-exports-order: 0.0.2 + browser-assert: 1.2.1 + case-sensitive-paths-webpack-plugin: 2.4.0 + core-js: 3.49.0 + css-loader: 5.2.7(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.1)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + glob: 7.2.3 + glob-promise: 3.4.0(glob@7.2.3) + html-webpack-plugin: 5.6.7(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + path-browserify: 1.0.1 + process: 0.11.10 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + stable: 0.1.8 + style-loader: 2.0.0(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + terser-webpack-plugin: 5.6.0(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14) + webpack-dev-middleware: 4.3.0(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) webpack-hot-middleware: 2.26.1 webpack-virtual-modules: 0.4.6 optionalDependencies: @@ -17988,7 +23264,7 @@ snapshots: optionalDependencies: typescript: 4.9.5 - '@storybook/core-client@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14))': + '@storybook/core-client@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14))': dependencies: '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@storybook/channel-postmessage': 6.5.16 @@ -18012,10 +23288,101 @@ snapshots: ts-dedent: 2.2.0 unfetch: 4.2.0 util-deprecate: 1.0.2 - webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14) optionalDependencies: typescript: 4.9.5 + '@storybook/core-client@6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14))': + dependencies: + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/channel-postmessage': 6.5.16 + '@storybook/channel-websocket': 6.5.16 + '@storybook/client-api': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/core-events': 6.5.16 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/preview-web': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/store': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/ui': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + airbnb-js-shims: 2.2.1 + ansi-to-html: 0.6.15 + core-js: 3.49.0 + global: 4.4.0 + lodash: 4.18.1 + qs: 6.15.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + regenerator-runtime: 0.13.11 + ts-dedent: 2.2.0 + unfetch: 4.2.0 + util-deprecate: 1.0.2 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14) + optionalDependencies: + typescript: 4.9.5 + + '@storybook/core-common@6.5.16(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.29.0) + '@babel/plugin-proposal-decorators': 7.29.0(@babel/core@7.29.0) + '@babel/plugin-proposal-export-default-from': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.29.0) + '@babel/plugin-proposal-object-rest-spread': 7.20.7(@babel/core@7.29.0) + '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.29.0) + '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.29.0) + '@babel/plugin-proposal-private-property-in-object': 7.21.11(@babel/core@7.29.0) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.29.0) + '@babel/plugin-transform-arrow-functions': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-block-scoping': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-classes': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-transform-destructuring': 7.28.5(@babel/core@7.29.0) + '@babel/plugin-transform-for-of': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.29.0) + '@babel/plugin-transform-shorthand-properties': 7.27.1(@babel/core@7.29.0) + '@babel/plugin-transform-spread': 7.28.6(@babel/core@7.29.0) + '@babel/preset-env': 7.29.5(@babel/core@7.29.0) + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@babel/preset-typescript': 7.28.5(@babel/core@7.29.0) + '@babel/register': 7.29.3(@babel/core@7.29.0) + '@storybook/node-logger': 6.5.16 + '@storybook/semver': 7.3.2 + '@types/node': 16.18.126 + '@types/pretty-hrtime': 1.0.3 + babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@4.47.0) + babel-plugin-macros: 3.1.0 + babel-plugin-polyfill-corejs3: 0.1.7(@babel/core@7.29.0) + chalk: 4.1.2 + core-js: 3.49.0 + express: 4.22.2 + file-system-cache: 1.1.0 + find-up: 5.0.0 + fork-ts-checker-webpack-plugin: 6.5.3(eslint@8.57.1)(typescript@4.9.5)(webpack@4.47.0) + fs-extra: 9.1.0 + glob: 7.2.3 + handlebars: 4.7.9 + interpret: 2.2.0 + json5: 2.2.3 + lazy-universal-dotenv: 3.0.1 + picomatch: 2.3.2 + pkg-dir: 5.0.0 + pretty-hrtime: 1.0.3 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + resolve-from: 5.0.0 + slash: 3.0.0 + telejson: 6.0.8 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + webpack: 4.47.0 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - eslint + - supports-color + - vue-template-compiler + - webpack-cli + - webpack-command + '@storybook/core-common@6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': dependencies: '@babel/core': 7.29.0 @@ -18083,7 +23450,7 @@ snapshots: dependencies: core-js: 3.49.0 - '@storybook/core-server@6.5.16(@storybook/builder-webpack5@6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(encoding@0.1.13)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': + '@storybook/core-server@6.5.16(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(encoding@0.1.13)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': dependencies: '@discoveryjs/json-ext': 0.5.7 '@storybook/builder-webpack4': 6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) @@ -18133,8 +23500,8 @@ snapshots: ws: 8.20.1 x-default-browser: 0.4.0 optionalDependencies: - '@storybook/builder-webpack5': 6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) - '@storybook/manager-webpack5': 6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/builder-webpack5': 6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/manager-webpack5': 6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) typescript: 4.9.5 transitivePeerDependencies: - '@storybook/mdx2-csf' @@ -18148,16 +23515,104 @@ snapshots: - webpack-cli - webpack-command - '@storybook/core@6.5.16(@storybook/builder-webpack5@6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(encoding@0.1.13)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14))': + '@storybook/core-server@6.5.16(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(encoding@0.1.13)(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': dependencies: - '@storybook/core-client': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) - '@storybook/core-server': 6.5.16(@storybook/builder-webpack5@6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(encoding@0.1.13)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@discoveryjs/json-ext': 0.5.7 + '@storybook/builder-webpack4': 6.5.16(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/core-client': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@4.47.0) + '@storybook/core-common': 6.5.16(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/core-events': 6.5.16 + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/csf-tools': 6.5.16 + '@storybook/manager-webpack4': 6.5.16(encoding@0.1.13)(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/node-logger': 6.5.16 + '@storybook/semver': 7.3.2 + '@storybook/store': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/telemetry': 6.5.16(encoding@0.1.13)(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@types/node': 16.18.126 + '@types/node-fetch': 2.6.13 + '@types/pretty-hrtime': 1.0.3 + '@types/webpack': 4.41.40 + better-opn: 2.1.1 + boxen: 5.1.2 + chalk: 4.1.2 + cli-table3: 0.6.5 + commander: 6.2.1 + compression: 1.8.1 + core-js: 3.49.0 + cpy: 8.1.2 + detect-port: 1.6.1 + express: 4.22.2 + fs-extra: 9.1.0 + global: 4.4.0 + globby: 11.1.0 + ip: 2.0.1 + lodash: 4.18.1 + node-fetch: 2.7.0(encoding@0.1.13) + open: 8.4.2 + pretty-hrtime: 1.0.3 + prompts: 2.4.2 react: 19.2.6 react-dom: 19.2.6(react@19.2.6) - webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + regenerator-runtime: 0.13.11 + serve-favicon: 2.5.1 + slash: 3.0.0 + telejson: 6.0.8 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + watchpack: 2.5.1 + webpack: 4.47.0 + ws: 8.20.1 + x-default-browser: 0.4.0 optionalDependencies: - '@storybook/builder-webpack5': 6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) - '@storybook/manager-webpack5': 6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/builder-webpack5': 6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/manager-webpack5': 6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - '@storybook/mdx2-csf' + - bluebird + - bufferutil + - encoding + - eslint + - supports-color + - utf-8-validate + - vue-template-compiler + - webpack-cli + - webpack-command + + '@storybook/core@6.5.16(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(encoding@0.1.13)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14))': + dependencies: + '@storybook/core-client': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) + '@storybook/core-server': 6.5.16(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(encoding@0.1.13)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14) + optionalDependencies: + '@storybook/builder-webpack5': 6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/manager-webpack5': 6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - '@storybook/mdx2-csf' + - bluebird + - bufferutil + - encoding + - eslint + - supports-color + - utf-8-validate + - vue-template-compiler + - webpack-cli + - webpack-command + + '@storybook/core@6.5.16(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(encoding@0.1.13)(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14))': + dependencies: + '@storybook/core-client': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + '@storybook/core-server': 6.5.16(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(encoding@0.1.13)(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14) + optionalDependencies: + '@storybook/builder-webpack5': 6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/manager-webpack5': 6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) typescript: 4.9.5 transitivePeerDependencies: - '@storybook/mdx2-csf' @@ -18252,6 +23707,56 @@ snapshots: '@vitest/utils': 2.1.9 storybook: 8.6.18(prettier@2.8.8) + '@storybook/manager-webpack4@6.5.16(encoding@0.1.13)(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.29.0) + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-client': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@4.47.0) + '@storybook/core-common': 6.5.16(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/node-logger': 6.5.16 + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/ui': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/node': 16.18.126 + '@types/webpack': 4.41.40 + babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@4.47.0) + case-sensitive-paths-webpack-plugin: 2.4.0 + chalk: 4.1.2 + core-js: 3.49.0 + css-loader: 3.6.0(webpack@4.47.0) + express: 4.22.2 + file-loader: 6.2.0(webpack@4.47.0) + find-up: 5.0.0 + fs-extra: 9.1.0 + html-webpack-plugin: 4.5.2(webpack@4.47.0) + node-fetch: 2.7.0(encoding@0.1.13) + pnp-webpack-plugin: 1.6.4(typescript@4.9.5) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + read-pkg-up: 7.0.1 + regenerator-runtime: 0.13.11 + resolve-from: 5.0.0 + style-loader: 1.3.0(webpack@4.47.0) + telejson: 6.0.8 + terser-webpack-plugin: 4.2.3(webpack@4.47.0) + ts-dedent: 2.2.0 + url-loader: 4.1.1(file-loader@6.2.0(webpack@4.47.0))(webpack@4.47.0) + util-deprecate: 1.0.2 + webpack: 4.47.0 + webpack-dev-middleware: 3.7.3(webpack@4.47.0) + webpack-virtual-modules: 0.2.2 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - bluebird + - encoding + - eslint + - supports-color + - vue-template-compiler + - webpack-cli + - webpack-command + '@storybook/manager-webpack4@6.5.16(encoding@0.1.13)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': dependencies: '@babel/core': 7.29.0 @@ -18302,27 +23807,27 @@ snapshots: - webpack-cli - webpack-command - '@storybook/manager-webpack5@6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': + '@storybook/manager-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': dependencies: '@babel/core': 7.29.0 '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.29.0) '@babel/preset-react': 7.28.5(@babel/core@7.29.0) '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) - '@storybook/core-client': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + '@storybook/core-client': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) '@storybook/core-common': 6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) '@storybook/node-logger': 6.5.16 '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@storybook/ui': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@types/node': 16.18.126 - babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) case-sensitive-paths-webpack-plugin: 2.4.0 chalk: 4.1.2 core-js: 3.49.0 - css-loader: 5.2.7(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + css-loader: 5.2.7(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) express: 4.22.2 find-up: 5.0.0 fs-extra: 9.1.0 - html-webpack-plugin: 5.6.7(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + html-webpack-plugin: 5.6.7(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) node-fetch: 2.7.0(encoding@0.1.13) process: 0.11.10 react: 19.2.6 @@ -18330,13 +23835,72 @@ snapshots: read-pkg-up: 7.0.1 regenerator-runtime: 0.13.11 resolve-from: 5.0.0 - style-loader: 2.0.0(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + style-loader: 2.0.0(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) telejson: 6.0.8 - terser-webpack-plugin: 5.6.0(esbuild@0.25.12)(postcss@8.5.14)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + terser-webpack-plugin: 5.6.0(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) ts-dedent: 2.2.0 util-deprecate: 1.0.2 - webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) - webpack-dev-middleware: 4.3.0(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14) + webpack-dev-middleware: 4.3.0(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) + webpack-virtual-modules: 0.4.6 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - '@minify-html/node' + - '@rspack/core' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - encoding + - esbuild + - eslint + - html-minifier-terser + - lightningcss + - postcss + - supports-color + - uglify-js + - vue-template-compiler + - webpack-cli + - webpack-command + + '@storybook/manager-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': + dependencies: + '@babel/core': 7.29.0 + '@babel/plugin-transform-template-literals': 7.27.1(@babel/core@7.29.0) + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/core-client': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + '@storybook/core-common': 6.5.16(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/node-logger': 6.5.16 + '@storybook/theming': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/ui': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/node': 16.18.126 + babel-loader: 8.4.1(@babel/core@7.29.0)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + case-sensitive-paths-webpack-plugin: 2.4.0 + chalk: 4.1.2 + core-js: 3.49.0 + css-loader: 5.2.7(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + express: 4.22.2 + find-up: 5.0.0 + fs-extra: 9.1.0 + html-webpack-plugin: 5.6.7(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + node-fetch: 2.7.0(encoding@0.1.13) + process: 0.11.10 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + read-pkg-up: 7.0.1 + regenerator-runtime: 0.13.11 + resolve-from: 5.0.0 + style-loader: 2.0.0(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + telejson: 6.0.8 + terser-webpack-plugin: 5.6.0(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14) + webpack-dev-middleware: 4.3.0(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) webpack-virtual-modules: 0.4.6 optionalDependencies: typescript: 4.9.5 @@ -18411,9 +23975,9 @@ snapshots: unfetch: 4.2.0 util-deprecate: 1.0.2 - '@storybook/react-docgen-typescript-plugin@1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14))': + '@storybook/react-docgen-typescript-plugin@1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14))': dependencies: - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) endent: 2.1.0 find-cache-dir: 3.3.2 flat-cache: 3.2.0 @@ -18421,23 +23985,37 @@ snapshots: react-docgen-typescript: 2.4.0(typescript@4.9.5) tslib: 2.8.1 typescript: 4.9.5 - webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14) transitivePeerDependencies: - supports-color - '@storybook/react@6.5.16(@babel/core@7.29.0)(@storybook/builder-webpack5@6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@types/webpack@4.41.40)(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(require-from-string@2.0.2)(type-fest@4.41.0)(typescript@4.9.5)(webpack-dev-server@4.15.2(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)))(webpack-hot-middleware@2.26.1)': + '@storybook/react-docgen-typescript-plugin@1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14))': + dependencies: + debug: 4.4.3(supports-color@8.1.1) + endent: 2.1.0 + find-cache-dir: 3.3.2 + flat-cache: 3.2.0 + micromatch: 4.0.8 + react-docgen-typescript: 2.4.0(typescript@4.9.5) + tslib: 2.8.1 + typescript: 4.9.5 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14) + transitivePeerDependencies: + - supports-color + + '@storybook/react@6.5.16(@babel/core@7.29.0)(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@swc/core@1.15.40(@swc/helpers@0.5.21))(@types/webpack@4.41.40)(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(require-from-string@2.0.2)(type-fest@4.41.0)(typescript@4.9.5)(webpack-dev-server@4.15.2(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)))(webpack-hot-middleware@2.26.1)': dependencies: '@babel/preset-flow': 7.27.1(@babel/core@7.29.0) '@babel/preset-react': 7.28.5(@babel/core@7.29.0) - '@pmmmwh/react-refresh-webpack-plugin': 0.5.17(@types/webpack@4.41.40)(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@4.15.2(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)))(webpack-hot-middleware@2.26.1)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + '@pmmmwh/react-refresh-webpack-plugin': 0.5.17(@types/webpack@4.41.40)(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@4.15.2(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)))(webpack-hot-middleware@2.26.1)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@storybook/client-logger': 6.5.16 - '@storybook/core': 6.5.16(@storybook/builder-webpack5@6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(encoding@0.1.13)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + '@storybook/core': 6.5.16(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(encoding@0.1.13)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) '@storybook/core-common': 6.5.16(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) '@storybook/csf': 0.0.2--canary.4566f4d.1 '@storybook/docs-tools': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@storybook/node-logger': 6.5.16 - '@storybook/react-docgen-typescript-plugin': 1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + '@storybook/react-docgen-typescript-plugin': 1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) '@storybook/semver': 7.3.2 '@storybook/store': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) '@types/estree': 0.0.51 @@ -18464,11 +24042,86 @@ snapshots: require-from-string: 2.0.2 ts-dedent: 2.2.0 util-deprecate: 1.0.2 - webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14) optionalDependencies: '@babel/core': 7.29.0 - '@storybook/builder-webpack5': 6.5.16(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) - '@storybook/manager-webpack5': 6.5.16(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/builder-webpack5': 6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/manager-webpack5': 6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(esbuild@0.25.12)(eslint@9.39.4)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + typescript: 4.9.5 + transitivePeerDependencies: + - '@minify-html/node' + - '@storybook/mdx2-csf' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - '@types/webpack' + - bluebird + - bufferutil + - clean-css + - cssnano + - csso + - encoding + - esbuild + - eslint + - html-minifier-terser + - lightningcss + - postcss + - sockjs-client + - supports-color + - type-fest + - uglify-js + - utf-8-validate + - vue-template-compiler + - webpack-cli + - webpack-command + - webpack-dev-server + - webpack-hot-middleware + - webpack-plugin-serve + + '@storybook/react@6.5.16(@babel/core@7.29.0)(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@swc/core@1.15.40(@swc/helpers@0.5.21))(@types/webpack@4.41.40)(encoding@0.1.13)(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(require-from-string@2.0.2)(type-fest@4.41.0)(typescript@4.9.5)(webpack-dev-server@4.15.2(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)))(webpack-hot-middleware@2.26.1)': + dependencies: + '@babel/preset-flow': 7.27.1(@babel/core@7.29.0) + '@babel/preset-react': 7.28.5(@babel/core@7.29.0) + '@pmmmwh/react-refresh-webpack-plugin': 0.5.17(@types/webpack@4.41.40)(react-refresh@0.11.0)(type-fest@4.41.0)(webpack-dev-server@4.15.2(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)))(webpack-hot-middleware@2.26.1)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + '@storybook/addons': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/client-logger': 6.5.16 + '@storybook/core': 6.5.16(@storybook/builder-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(@storybook/manager-webpack5@6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5))(encoding@0.1.13)(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + '@storybook/core-common': 6.5.16(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/csf': 0.0.2--canary.4566f4d.1 + '@storybook/docs-tools': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@storybook/node-logger': 6.5.16 + '@storybook/react-docgen-typescript-plugin': 1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + '@storybook/semver': 7.3.2 + '@storybook/store': 6.5.16(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@types/estree': 0.0.51 + '@types/node': 16.18.126 + '@types/webpack-env': 1.18.8 + acorn: 7.4.1 + acorn-jsx: 5.3.2(acorn@7.4.1) + acorn-walk: 7.2.0 + babel-plugin-add-react-displayname: 0.0.5 + babel-plugin-react-docgen: 4.2.1 + core-js: 3.49.0 + escodegen: 2.1.0 + fs-extra: 9.1.0 + global: 4.4.0 + html-tags: 3.3.1 + lodash: 4.18.1 + prop-types: 15.8.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-element-to-jsx-string: 14.3.4(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + react-refresh: 0.11.0 + read-pkg-up: 7.0.1 + regenerator-runtime: 0.13.11 + require-from-string: 2.0.2 + ts-dedent: 2.2.0 + util-deprecate: 1.0.2 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14) + optionalDependencies: + '@babel/core': 7.29.0 + '@storybook/builder-webpack5': 6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + '@storybook/manager-webpack5': 6.5.16(@swc/core@1.15.40(@swc/helpers@0.5.21))(encoding@0.1.13)(eslint@8.57.1)(postcss@8.5.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) typescript: 4.9.5 transitivePeerDependencies: - '@minify-html/node' @@ -18550,6 +24203,31 @@ snapshots: ts-dedent: 2.2.0 util-deprecate: 1.0.2 + '@storybook/telemetry@6.5.16(encoding@0.1.13)(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': + dependencies: + '@storybook/client-logger': 6.5.16 + '@storybook/core-common': 6.5.16(eslint@8.57.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5) + chalk: 4.1.2 + core-js: 3.49.0 + detect-package-manager: 2.0.1 + fetch-retry: 5.0.6 + fs-extra: 9.1.0 + global: 4.4.0 + isomorphic-unfetch: 3.1.0(encoding@0.1.13) + nanoid: 3.3.12 + read-pkg-up: 7.0.1 + regenerator-runtime: 0.13.11 + transitivePeerDependencies: + - encoding + - eslint + - react + - react-dom + - supports-color + - typescript + - vue-template-compiler + - webpack-cli + - webpack-command + '@storybook/telemetry@6.5.16(encoding@0.1.13)(eslint@9.39.4)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(typescript@4.9.5)': dependencies: '@storybook/client-logger': 6.5.16 @@ -18706,6 +24384,61 @@ snapshots: transitivePeerDependencies: - supports-color + '@swc/core-darwin-arm64@1.15.40': + optional: true + + '@swc/core-darwin-x64@1.15.40': + optional: true + + '@swc/core-linux-arm-gnueabihf@1.15.40': + optional: true + + '@swc/core-linux-arm64-gnu@1.15.40': + optional: true + + '@swc/core-linux-arm64-musl@1.15.40': + optional: true + + '@swc/core-linux-ppc64-gnu@1.15.40': + optional: true + + '@swc/core-linux-s390x-gnu@1.15.40': + optional: true + + '@swc/core-linux-x64-gnu@1.15.40': + optional: true + + '@swc/core-linux-x64-musl@1.15.40': + optional: true + + '@swc/core-win32-arm64-msvc@1.15.40': + optional: true + + '@swc/core-win32-ia32-msvc@1.15.40': + optional: true + + '@swc/core-win32-x64-msvc@1.15.40': + optional: true + + '@swc/core@1.15.40(@swc/helpers@0.5.21)': + dependencies: + '@swc/counter': 0.1.3 + '@swc/types': 0.1.26 + optionalDependencies: + '@swc/core-darwin-arm64': 1.15.40 + '@swc/core-darwin-x64': 1.15.40 + '@swc/core-linux-arm-gnueabihf': 1.15.40 + '@swc/core-linux-arm64-gnu': 1.15.40 + '@swc/core-linux-arm64-musl': 1.15.40 + '@swc/core-linux-ppc64-gnu': 1.15.40 + '@swc/core-linux-s390x-gnu': 1.15.40 + '@swc/core-linux-x64-gnu': 1.15.40 + '@swc/core-linux-x64-musl': 1.15.40 + '@swc/core-win32-arm64-msvc': 1.15.40 + '@swc/core-win32-ia32-msvc': 1.15.40 + '@swc/core-win32-x64-msvc': 1.15.40 + '@swc/helpers': 0.5.21 + '@swc/counter@0.1.3': {} '@swc/helpers@0.5.21': @@ -18717,6 +24450,10 @@ snapshots: '@swc/counter': 0.1.3 tslib: 2.8.1 + '@swc/types@0.1.26': + dependencies: + '@swc/counter': 0.1.3 + '@tanstack/match-sorter-utils@8.19.4': dependencies: remove-accents: 0.5.0 @@ -18868,6 +24605,18 @@ snapshots: lz-string: 1.5.0 pretty-format: 27.5.1 + '@testing-library/jest-dom@5.17.0': + dependencies: + '@adobe/css-tools': 4.4.4 + '@babel/runtime': 7.29.2 + '@types/testing-library__jest-dom': 5.14.9 + aria-query: 5.3.2 + chalk: 3.0.0 + css.escape: 1.5.1 + dom-accessibility-api: 0.5.16 + lodash: 4.18.1 + redent: 3.0.0 + '@testing-library/jest-dom@6.9.1': dependencies: '@adobe/css-tools': 4.4.4 @@ -18877,6 +24626,16 @@ snapshots: picocolors: 1.1.1 redent: 3.0.0 + '@testing-library/react@12.1.5(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': + dependencies: + '@babel/runtime': 7.29.2 + '@testing-library/dom': 8.20.1 + '@types/react-dom': 17.0.26(@types/react@19.2.14) + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + transitivePeerDependencies: + - '@types/react' + '@testing-library/react@16.3.2(@testing-library/dom@10.4.1)(@types/react-dom@19.2.3(@types/react@19.2.14))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)': dependencies: '@babel/runtime': 7.29.2 @@ -19010,6 +24769,8 @@ snapshots: dependencies: '@types/estree': 1.0.9 + '@types/estree@0.0.39': {} + '@types/estree@0.0.51': {} '@types/estree@1.0.9': {} @@ -19084,6 +24845,11 @@ snapshots: dependencies: '@types/istanbul-lib-report': 3.0.3 + '@types/jest@27.5.2': + dependencies: + jest-matcher-utils: 27.5.1 + pretty-format: 27.5.1 + '@types/jest@29.5.14': dependencies: expect: 29.7.0 @@ -19162,6 +24928,10 @@ snapshots: '@types/range-parser@1.2.7': {} + '@types/react-dom@17.0.26(@types/react@19.2.14)': + dependencies: + '@types/react': 19.2.14 + '@types/react-dom@19.2.3(@types/react@19.2.14)': dependencies: '@types/react': 19.2.14 @@ -19174,8 +24944,15 @@ snapshots: dependencies: csstype: 3.2.3 + '@types/resolve@1.20.2': {} + '@types/retry@0.12.0': {} + '@types/rimraf@3.0.2': + dependencies: + '@types/glob': 9.0.0 + '@types/node': 22.19.19 + '@types/semver@7.7.1': {} '@types/send@0.17.6': @@ -19197,6 +24974,11 @@ snapshots: '@types/node': 22.19.19 '@types/send': 0.17.6 + '@types/shelljs@0.8.15': + dependencies: + '@types/glob': 7.2.0 + '@types/node': 22.19.19 + '@types/sockjs@0.3.36': dependencies: '@types/node': 22.19.19 @@ -19207,6 +24989,10 @@ snapshots: '@types/tapable@1.0.12': {} + '@types/testing-library__jest-dom@5.14.9': + dependencies: + '@types/jest': 29.5.14 + '@types/trusted-types@2.0.7': optional: true @@ -19257,6 +25043,44 @@ snapshots: '@types/zxcvbn@4.4.5': {} + '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0)(typescript@4.9.5)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 5.62.0(eslint@7.32.0)(typescript@4.9.5) + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/type-utils': 5.62.0(eslint@7.32.0)(typescript@4.9.5) + '@typescript-eslint/utils': 5.62.0(eslint@7.32.0)(typescript@4.9.5) + debug: 4.4.3(supports-color@8.1.1) + eslint: 7.32.0 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare-lite: 1.4.0 + semver: 7.8.0 + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@eslint-community/regexpp': 4.12.2 + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + debug: 4.4.3(supports-color@8.1.1) + eslint: 8.57.1 + graphemer: 1.4.0 + ignore: 5.3.2 + natural-compare-lite: 1.4.0 + semver: 7.8.0 + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5)': dependencies: '@eslint-community/regexpp': 4.12.2 @@ -19264,7 +25088,7 @@ snapshots: '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/type-utils': 5.62.0(eslint@9.39.4)(typescript@4.9.5) '@typescript-eslint/utils': 5.62.0(eslint@9.39.4)(typescript@4.9.5) - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) eslint: 9.39.4 graphemer: 1.4.0 ignore: 5.3.2 @@ -19283,7 +25107,7 @@ snapshots: '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/type-utils': 5.62.0(eslint@9.39.4)(typescript@5.9.3) '@typescript-eslint/utils': 5.62.0(eslint@9.39.4)(typescript@5.9.3) - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) eslint: 9.39.4 graphemer: 1.4.0 ignore: 5.3.2 @@ -19311,6 +25135,14 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/experimental-utils@5.62.0(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + eslint: 8.57.1 + transitivePeerDependencies: + - supports-color + - typescript + '@typescript-eslint/experimental-utils@5.62.0(eslint@9.39.4)(typescript@4.9.5)': dependencies: '@typescript-eslint/utils': 5.62.0(eslint@9.39.4)(typescript@4.9.5) @@ -19327,12 +25159,36 @@ snapshots: - supports-color - typescript + '@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + debug: 4.4.3(supports-color@8.1.1) + eslint: 7.32.0 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + debug: 4.4.3(supports-color@8.1.1) + eslint: 8.57.1 + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5)': dependencies: '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) eslint: 9.39.4 optionalDependencies: typescript: 4.9.5 @@ -19344,7 +25200,7 @@ snapshots: '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.9.3) - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) eslint: 9.39.4 optionalDependencies: typescript: 5.9.3 @@ -19357,7 +25213,7 @@ snapshots: '@typescript-eslint/types': 8.59.4 '@typescript-eslint/typescript-estree': 8.59.4(typescript@5.9.3) '@typescript-eslint/visitor-keys': 8.59.4 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) eslint: 8.57.1 typescript: 5.9.3 transitivePeerDependencies: @@ -19367,7 +25223,7 @@ snapshots: dependencies: '@typescript-eslint/tsconfig-utils': 8.59.4(typescript@5.9.3) '@typescript-eslint/types': 8.59.4 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -19386,11 +25242,35 @@ snapshots: dependencies: typescript: 5.9.3 + '@typescript-eslint/type-utils@5.62.0(eslint@7.32.0)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + '@typescript-eslint/utils': 5.62.0(eslint@7.32.0)(typescript@4.9.5) + debug: 4.4.3(supports-color@8.1.1) + eslint: 7.32.0 + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + + '@typescript-eslint/type-utils@5.62.0(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + debug: 4.4.3(supports-color@8.1.1) + eslint: 8.57.1 + tsutils: 3.21.0(typescript@4.9.5) + optionalDependencies: + typescript: 4.9.5 + transitivePeerDependencies: + - supports-color + '@typescript-eslint/type-utils@5.62.0(eslint@9.39.4)(typescript@4.9.5)': dependencies: '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) '@typescript-eslint/utils': 5.62.0(eslint@9.39.4)(typescript@4.9.5) - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) eslint: 9.39.4 tsutils: 3.21.0(typescript@4.9.5) optionalDependencies: @@ -19402,7 +25282,7 @@ snapshots: dependencies: '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.9.3) '@typescript-eslint/utils': 5.62.0(eslint@9.39.4)(typescript@5.9.3) - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) eslint: 9.39.4 tsutils: 3.21.0(typescript@5.9.3) optionalDependencies: @@ -19415,7 +25295,7 @@ snapshots: '@typescript-eslint/types': 8.59.4 '@typescript-eslint/typescript-estree': 8.59.4(typescript@5.9.3) '@typescript-eslint/utils': 8.59.4(eslint@8.57.1)(typescript@5.9.3) - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) eslint: 8.57.1 ts-api-utils: 2.5.0(typescript@5.9.3) typescript: 5.9.3 @@ -19430,7 +25310,7 @@ snapshots: dependencies: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 semver: 7.8.0 @@ -19444,7 +25324,7 @@ snapshots: dependencies: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) globby: 11.1.0 is-glob: 4.0.3 semver: 7.8.0 @@ -19460,7 +25340,7 @@ snapshots: '@typescript-eslint/tsconfig-utils': 8.59.4(typescript@5.9.3) '@typescript-eslint/types': 8.59.4 '@typescript-eslint/visitor-keys': 8.59.4 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) minimatch: 10.2.5 semver: 7.8.0 tinyglobby: 0.2.16 @@ -19469,6 +25349,36 @@ snapshots: transitivePeerDependencies: - supports-color + '@typescript-eslint/utils@5.62.0(eslint@7.32.0)(typescript@4.9.5)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@7.32.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.7.1 + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + eslint: 7.32.0 + eslint-scope: 5.1.1 + semver: 7.8.0 + transitivePeerDependencies: + - supports-color + - typescript + + '@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@4.9.5)': + dependencies: + '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) + '@types/json-schema': 7.0.15 + '@types/semver': 7.7.1 + '@typescript-eslint/scope-manager': 5.62.0 + '@typescript-eslint/types': 5.62.0 + '@typescript-eslint/typescript-estree': 5.62.0(typescript@4.9.5) + eslint: 8.57.1 + eslint-scope: 5.1.1 + semver: 7.8.0 + transitivePeerDependencies: + - supports-color + - typescript + '@typescript-eslint/utils@5.62.0(eslint@8.57.1)(typescript@5.9.3)': dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) @@ -19891,20 +25801,37 @@ snapshots: '@webpack-cli/configtest@1.2.0(webpack-cli@4.10.0)(webpack@5.106.2)': dependencies: - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0) webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.106.2) + '@webpack-cli/configtest@2.1.1(webpack-cli@5.1.4)(webpack@5.106.2)': + dependencies: + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.106.2) + '@webpack-cli/info@1.5.0(webpack-cli@4.10.0)': dependencies: envinfo: 7.21.0 webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.106.2) + '@webpack-cli/info@2.0.2(webpack-cli@5.1.4)(webpack@5.106.2)': + dependencies: + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.106.2) + '@webpack-cli/serve@1.7.0(webpack-cli@4.10.0)(webpack-dev-server@4.15.2)': dependencies: webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.106.2) optionalDependencies: webpack-dev-server: 4.15.2(webpack-cli@4.10.0)(webpack@5.106.2) + '@webpack-cli/serve@2.0.5(webpack-cli@5.1.4)(webpack-dev-server@4.15.2)(webpack@5.106.2)': + dependencies: + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.106.2) + optionalDependencies: + webpack-dev-server: 4.15.2(webpack-cli@5.1.4)(webpack@5.106.2) + '@xtuc/ieee754@1.2.0': {} '@xtuc/long@4.2.2': {} @@ -19972,7 +25899,7 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -20048,6 +25975,10 @@ snapshots: ansi-colors@4.1.3: {} + ansi-escapes@2.0.0: {} + + ansi-escapes@3.2.0: {} + ansi-escapes@4.3.2: dependencies: type-fest: 0.21.3 @@ -20058,10 +25989,18 @@ snapshots: ansi-regex@2.1.1: {} + ansi-regex@3.0.1: {} + + ansi-regex@4.1.1: {} + ansi-regex@5.0.1: {} ansi-regex@6.2.2: {} + ansi-sequence-parser@1.1.3: {} + + ansi-styles@2.2.1: {} + ansi-styles@3.2.1: dependencies: color-convert: 1.9.3 @@ -20080,6 +26019,8 @@ snapshots: ansicolors@0.3.2: {} + any-promise@1.3.0: {} + anymatch@2.0.0: dependencies: micromatch: 3.1.10 @@ -20258,6 +26199,8 @@ snapshots: assign-symbols@1.0.0: {} + ast-stringify@0.2.1: {} + ast-types-flow@0.0.8: {} ast-types@0.14.2: @@ -20268,6 +26211,8 @@ snapshots: dependencies: tslib: 2.8.1 + astral-regex@2.0.0: {} + async-each@1.0.6: optional: true @@ -20283,6 +26228,8 @@ snapshots: atomic-sleep@1.0.0: {} + attr-accept@2.2.5: {} + author-regex@1.0.0: {} autoprefixer@9.8.8: @@ -20353,14 +26300,23 @@ snapshots: schema-utils: 2.7.1 webpack: 4.47.0 - babel-loader@8.4.1(@babel/core@7.29.0)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)): + babel-loader@8.4.1(@babel/core@7.29.0)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)): dependencies: '@babel/core': 7.29.0 find-cache-dir: 3.3.2 loader-utils: 2.0.4 make-dir: 3.1.0 schema-utils: 2.7.1 - webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14) + + babel-loader@8.4.1(@babel/core@7.29.0)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)): + dependencies: + '@babel/core': 7.29.0 + find-cache-dir: 3.3.2 + loader-utils: 2.0.4 + make-dir: 3.1.0 + schema-utils: 2.7.1 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14) babel-loader@8.4.1(@babel/core@7.29.0)(webpack@5.106.2): dependencies: @@ -20369,7 +26325,14 @@ snapshots: loader-utils: 2.0.4 make-dir: 3.1.0 schema-utils: 2.7.1 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0) + + babel-loader@9.2.1(@babel/core@7.29.0)(webpack@5.106.2): + dependencies: + '@babel/core': 7.29.0 + find-cache-dir: 4.0.0 + schema-utils: 4.3.3 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@5.1.4) babel-plugin-add-react-displayname@0.0.5: {} @@ -20508,6 +26471,8 @@ snapshots: base58@2.0.1: {} + base64-arraybuffer-es6@0.7.0: {} + base64-js@1.5.1: {} base@0.11.2: @@ -20526,6 +26491,8 @@ snapshots: bech32@1.1.4: {} + bech32@2.0.0: {} + before-after-hook@2.2.3: {} better-opn@2.1.1: @@ -20667,6 +26634,8 @@ snapshots: browser-process-hrtime@1.0.0: {} + browser-stdout@1.3.1: {} + browserify-aes@1.2.0: dependencies: buffer-xor: 1.0.3 @@ -20765,6 +26734,10 @@ snapshots: dependencies: semver: 7.8.0 + bundle-name@4.1.0: + dependencies: + run-applescript: 7.1.0 + busboy@1.6.0: dependencies: streamsearch: 1.1.0 @@ -20946,6 +26919,8 @@ snapshots: case-sensitive-paths-webpack-plugin@2.4.0: {} + case@1.6.3: {} + ccount@1.1.0: {} ccount@2.0.1: {} @@ -20954,12 +26929,25 @@ snapshots: dependencies: '@chain-registry/types': 0.50.356 + chalk@1.1.3: + dependencies: + ansi-styles: 2.2.1 + escape-string-regexp: 1.0.5 + has-ansi: 2.0.0 + strip-ansi: 3.0.1 + supports-color: 2.0.0 + chalk@2.4.2: dependencies: ansi-styles: 3.2.1 escape-string-regexp: 1.0.5 supports-color: 5.5.0 + chalk@3.0.0: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + chalk@4.1.0: dependencies: ansi-styles: 4.3.0 @@ -20986,6 +26974,10 @@ snapshots: character-reference-invalid@2.0.1: {} + chardet@0.4.2: {} + + chardet@0.7.0: {} + chardet@2.1.1: {} chokidar@2.1.8: @@ -21063,10 +27055,22 @@ snapshots: clean-webpack-plugin@4.0.0(webpack@5.106.2): dependencies: del: 4.1.1 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0) cli-boxes@2.2.1: {} + cli-color@2.0.4: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-iterator: 2.0.3 + memoizee: 0.4.17 + timers-ext: 0.1.8 + + cli-cursor@2.1.0: + dependencies: + restore-cursor: 2.0.0 + cli-cursor@3.1.0: dependencies: restore-cursor: 3.1.0 @@ -21081,6 +27085,8 @@ snapshots: optionalDependencies: '@colors/colors': 1.5.0 + cli-width@2.2.1: {} + cli-width@3.0.0: {} client-only@0.0.1: {} @@ -21107,6 +27113,8 @@ snapshots: clone@1.0.4: {} + clone@2.1.2: {} + clsx@1.1.0: {} clsx@1.2.1: {} @@ -21158,6 +27166,8 @@ snapshots: colornames@1.1.1: {} + colors@1.4.0: {} + columnify@1.6.0: dependencies: strip-ansi: 6.0.1 @@ -21167,10 +27177,18 @@ snapshots: dependencies: delayed-stream: 1.0.0 + comlink@4.4.2: {} + comma-separated-tokens@1.0.8: {} comma-separated-tokens@2.0.3: {} + commander@10.0.1: {} + + commander@12.1.0: {} + + commander@14.0.3: {} + commander@2.20.3: {} commander@4.1.1: {} @@ -21181,6 +27199,10 @@ snapshots: commander@8.3.0: {} + commander@9.5.0: {} + + common-path-prefix@3.0.0: {} + commondir@1.0.1: {} compare-func@2.0.0: @@ -21315,6 +27337,16 @@ snapshots: dependencies: toggle-selection: 1.0.6 + copy-webpack-plugin@11.0.0(webpack@5.106.2): + dependencies: + fast-glob: 3.3.3 + glob-parent: 6.0.2 + globby: 13.2.2 + normalize-path: 3.0.0 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@5.1.4) + core-js-compat@3.49.0: dependencies: browserslist: 4.28.2 @@ -21352,6 +27384,16 @@ snapshots: cosmjs-types@0.10.1: {} + cosmjs-types@0.4.1: + dependencies: + long: 4.0.0 + protobufjs: 6.11.6 + + cosmjs-types@0.5.2: + dependencies: + long: 4.0.0 + protobufjs: 6.11.6 + cosmjs-types@0.9.0: {} cp-file@7.0.0: @@ -21397,6 +27439,21 @@ snapshots: safe-buffer: 5.2.1 sha.js: 2.4.12 + create-jest@29.7.0(@types/node@16.18.126)(babel-plugin-macros@3.1.0): + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@16.18.126)(babel-plugin-macros@3.1.0) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + create-jest@29.7.0(@types/node@22.19.19)(babel-plugin-macros@3.1.0): dependencies: '@jest/types': 29.6.3 @@ -21457,6 +27514,10 @@ snapshots: dependencies: postcss: 8.5.14 + css-declaration-sorter@7.4.0(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + css-loader@3.6.0(webpack@4.47.0): dependencies: camelcase: 5.3.1 @@ -21474,7 +27535,7 @@ snapshots: semver: 6.3.1 webpack: 4.47.0 - css-loader@5.2.7(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)): + css-loader@5.2.7(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)): dependencies: icss-utils: 5.1.0(postcss@8.5.14) loader-utils: 2.0.4 @@ -21486,7 +27547,21 @@ snapshots: postcss-value-parser: 4.2.0 schema-utils: 3.3.0 semver: 7.8.0 - webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14) + + css-loader@5.2.7(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)): + dependencies: + icss-utils: 5.1.0(postcss@8.5.14) + loader-utils: 2.0.4 + postcss: 8.5.14 + postcss-modules-extract-imports: 3.1.0(postcss@8.5.14) + postcss-modules-local-by-default: 4.2.0(postcss@8.5.14) + postcss-modules-scope: 3.2.1(postcss@8.5.14) + postcss-modules-values: 4.0.0(postcss@8.5.14) + postcss-value-parser: 4.2.0 + schema-utils: 3.3.0 + semver: 7.8.0 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14) css-loader@6.11.0(webpack@5.106.2): dependencies: @@ -21499,7 +27574,7 @@ snapshots: postcss-value-parser: 4.2.0 semver: 7.8.0 optionalDependencies: - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0) css-minimizer-webpack-plugin@3.4.1(webpack@5.106.2): dependencies: @@ -21509,7 +27584,17 @@ snapshots: schema-utils: 4.3.3 serialize-javascript: 6.0.2 source-map: 0.6.1 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0) + + css-minimizer-webpack-plugin@5.0.1(webpack@5.106.2): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + cssnano: 6.1.2(postcss@8.5.14) + jest-worker: 29.7.0 + postcss: 8.5.14 + schema-utils: 4.3.3 + serialize-javascript: 6.0.2 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@5.1.4) css-select@4.3.0: dependencies: @@ -21591,10 +27676,48 @@ snapshots: postcss-svgo: 5.1.0(postcss@8.5.14) postcss-unique-selectors: 5.1.1(postcss@8.5.14) + cssnano-preset-default@6.1.2(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + css-declaration-sorter: 7.4.0(postcss@8.5.14) + cssnano-utils: 4.0.2(postcss@8.5.14) + postcss: 8.5.14 + postcss-calc: 9.0.1(postcss@8.5.14) + postcss-colormin: 6.1.0(postcss@8.5.14) + postcss-convert-values: 6.1.0(postcss@8.5.14) + postcss-discard-comments: 6.0.2(postcss@8.5.14) + postcss-discard-duplicates: 6.0.3(postcss@8.5.14) + postcss-discard-empty: 6.0.3(postcss@8.5.14) + postcss-discard-overridden: 6.0.2(postcss@8.5.14) + postcss-merge-longhand: 6.0.5(postcss@8.5.14) + postcss-merge-rules: 6.1.1(postcss@8.5.14) + postcss-minify-font-values: 6.1.0(postcss@8.5.14) + postcss-minify-gradients: 6.0.3(postcss@8.5.14) + postcss-minify-params: 6.1.0(postcss@8.5.14) + postcss-minify-selectors: 6.0.4(postcss@8.5.14) + postcss-normalize-charset: 6.0.2(postcss@8.5.14) + postcss-normalize-display-values: 6.0.2(postcss@8.5.14) + postcss-normalize-positions: 6.0.2(postcss@8.5.14) + postcss-normalize-repeat-style: 6.0.2(postcss@8.5.14) + postcss-normalize-string: 6.0.2(postcss@8.5.14) + postcss-normalize-timing-functions: 6.0.2(postcss@8.5.14) + postcss-normalize-unicode: 6.1.0(postcss@8.5.14) + postcss-normalize-url: 6.0.2(postcss@8.5.14) + postcss-normalize-whitespace: 6.0.2(postcss@8.5.14) + postcss-ordered-values: 6.0.2(postcss@8.5.14) + postcss-reduce-initial: 6.1.0(postcss@8.5.14) + postcss-reduce-transforms: 6.0.2(postcss@8.5.14) + postcss-svgo: 6.0.3(postcss@8.5.14) + postcss-unique-selectors: 6.0.4(postcss@8.5.14) + cssnano-utils@3.1.0(postcss@8.5.14): dependencies: postcss: 8.5.14 + cssnano-utils@4.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + cssnano@5.1.15(postcss@8.5.14): dependencies: cssnano-preset-default: 5.2.14(postcss@8.5.14) @@ -21602,6 +27725,12 @@ snapshots: postcss: 8.5.14 yaml: 1.10.3 + cssnano@6.1.2(postcss@8.5.14): + dependencies: + cssnano-preset-default: 6.1.2(postcss@8.5.14) + lilconfig: 3.1.3 + postcss: 8.5.14 + csso@4.2.0: dependencies: css-tree: 1.1.3 @@ -21691,6 +27820,11 @@ snapshots: d3-timer@3.0.1: {} + d@1.0.2: + dependencies: + es5-ext: 0.10.64 + type: 2.7.3 + damerau-levenshtein@1.0.8: {} dargs@7.0.0: {} @@ -21738,13 +27872,23 @@ snapshots: dependencies: ms: 2.0.0 - debug@3.2.7: + debug@3.2.7(supports-color@5.5.0): dependencies: ms: 2.1.3 + optionalDependencies: + supports-color: 5.5.0 - debug@4.4.3: + debug@4.4.3(supports-color@5.5.0): dependencies: ms: 2.1.3 + optionalDependencies: + supports-color: 5.5.0 + + debug@4.4.3(supports-color@8.1.1): + dependencies: + ms: 2.1.3 + optionalDependencies: + supports-color: 8.1.1 decamelize-keys@1.1.1: dependencies: @@ -21753,6 +27897,8 @@ snapshots: decamelize@1.2.0: {} + decamelize@4.0.0: {} + decimal.js-light@2.5.1: {} decimal.js@10.6.0: {} @@ -21794,6 +27940,8 @@ snapshots: deep-object-diff@1.1.9: {} + deepmerge@4.2.2: {} + deepmerge@4.3.1: {} default-browser-id@1.0.4: @@ -21803,6 +27951,13 @@ snapshots: untildify: 2.1.0 optional: true + default-browser-id@5.0.1: {} + + default-browser@5.5.0: + dependencies: + bundle-name: 4.1.0 + default-browser-id: 5.0.1 + default-gateway@6.0.3: dependencies: execa: 5.1.1 @@ -21819,6 +27974,8 @@ snapshots: define-lazy-prop@2.0.0: {} + define-lazy-prop@3.0.0: {} + define-properties@1.2.1: dependencies: define-data-property: 1.1.4 @@ -21883,6 +28040,8 @@ snapshots: detect-indent@5.0.0: {} + detect-libc@1.0.3: {} + detect-libc@2.1.2: {} detect-newline@3.1.0: {} @@ -21896,7 +28055,7 @@ snapshots: detect-port@1.6.1: dependencies: address: 1.2.2 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -21906,8 +28065,14 @@ snapshots: diff-sequences@27.5.1: {} + diff-sequences@28.1.1: {} + diff-sequences@29.6.3: {} + diff@3.5.1: {} + + diff@5.2.2: {} + diffie-hellman@5.0.3: dependencies: bn.js: 4.12.3 @@ -21965,6 +28130,10 @@ snapshots: domelementtype@2.3.0: {} + domexception@1.0.1: + dependencies: + webidl-conversions: 4.0.2 + domexception@2.0.1: dependencies: webidl-conversions: 5.0.0 @@ -22008,15 +28177,26 @@ snapshots: dotenv-expand@10.0.0: {} + dotenv-expand@11.0.7: + dependencies: + dotenv: 16.6.1 + dotenv-expand@5.1.0: {} dotenv-webpack@7.1.1(webpack@5.106.2): dependencies: dotenv-defaults: 2.0.2 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0) + + dotenv-webpack@8.1.1(webpack@5.106.2): + dependencies: + dotenv-defaults: 2.0.2 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@5.1.4) dotenv@16.3.2: {} + dotenv@16.6.1: {} + dotenv@8.6.0: {} dunder-proto@1.0.1: @@ -22246,13 +28426,38 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 + es5-ext@0.10.64: + dependencies: + es6-iterator: 2.0.3 + es6-symbol: 3.1.4 + esniff: 2.0.1 + next-tick: 1.1.0 + es5-shim@4.6.7: {} + es6-iterator@2.0.3: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-symbol: 3.1.4 + es6-shim@0.35.8: {} + es6-symbol@3.1.4: + dependencies: + d: 1.0.2 + ext: 1.7.0 + + es6-weak-map@2.0.3: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-iterator: 2.0.3 + es6-symbol: 3.1.4 + esbuild-register@3.6.0(esbuild@0.25.12): dependencies: - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) esbuild: 0.25.12 transitivePeerDependencies: - supports-color @@ -22304,6 +28509,24 @@ snapshots: optionalDependencies: source-map: 0.6.1 + eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0))(eslint@7.32.0): + dependencies: + confusing-browser-globals: 1.0.11 + eslint: 7.32.0 + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0) + object.assign: 4.1.7 + object.entries: 1.1.9 + semver: 6.3.1 + + eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1): + dependencies: + confusing-browser-globals: 1.0.11 + eslint: 8.57.1 + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) + object.assign: 4.1.7 + object.entries: 1.1.9 + semver: 6.3.1 + eslint-config-airbnb-base@15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint@9.39.4): dependencies: confusing-browser-globals: 1.0.11 @@ -22331,6 +28554,22 @@ snapshots: object.entries: 1.1.9 semver: 6.3.1 + eslint-config-airbnb-typescript@16.2.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0))(eslint@7.32.0): + dependencies: + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0)(typescript@4.9.5) + '@typescript-eslint/parser': 5.62.0(eslint@7.32.0)(typescript@4.9.5) + eslint: 7.32.0 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0))(eslint@7.32.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0) + + eslint-config-airbnb-typescript@16.2.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1): + dependencies: + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + eslint: 8.57.1 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) + eslint-config-airbnb-typescript@16.2.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5))(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint@9.39.4): dependencies: '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5) @@ -22355,6 +28594,39 @@ snapshots: eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1))(eslint@8.57.1) eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint@8.57.1) + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0))(eslint-plugin-jsx-a11y@6.10.2(eslint@7.32.0))(eslint-plugin-react-hooks@5.2.0(eslint@7.32.0))(eslint-plugin-react@7.37.5(eslint@7.32.0))(eslint@7.32.0): + dependencies: + eslint: 7.32.0 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0))(eslint@7.32.0) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0) + eslint-plugin-jsx-a11y: 6.10.2(eslint@7.32.0) + eslint-plugin-react: 7.37.5(eslint@7.32.0) + eslint-plugin-react-hooks: 5.2.0(eslint@7.32.0) + object.assign: 4.1.7 + object.entries: 1.1.9 + + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1))(eslint-plugin-react-hooks@4.6.2(eslint@8.57.1))(eslint-plugin-react@7.37.5(eslint@8.57.1))(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) + eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) + eslint-plugin-react: 7.37.5(eslint@8.57.1) + eslint-plugin-react-hooks: 4.6.2(eslint@8.57.1) + object.assign: 4.1.7 + object.entries: 1.1.9 + + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1))(eslint-plugin-react-hooks@5.2.0(eslint@8.57.1))(eslint-plugin-react@7.37.5(eslint@8.57.1))(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1))(eslint@8.57.1) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) + eslint-plugin-jsx-a11y: 6.10.2(eslint@8.57.1) + eslint-plugin-react: 7.37.5(eslint@8.57.1) + eslint-plugin-react-hooks: 5.2.0(eslint@8.57.1) + object.assign: 4.1.7 + object.entries: 1.1.9 + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4))(eslint-plugin-react-hooks@4.6.2(eslint@9.39.4))(eslint-plugin-react@7.37.5(eslint@9.39.4))(eslint@9.39.4): dependencies: eslint: 9.39.4 @@ -22366,6 +28638,17 @@ snapshots: object.assign: 4.1.7 object.entries: 1.1.9 + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4))(eslint-plugin-react-hooks@5.2.0(eslint@9.39.4))(eslint-plugin-react@7.37.5(eslint@9.39.4))(eslint@9.39.4): + dependencies: + eslint: 9.39.4 + eslint-config-airbnb-base: 15.0.0(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4))(eslint@9.39.4) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4) + eslint-plugin-jsx-a11y: 6.10.2(eslint@9.39.4) + eslint-plugin-react: 7.37.5(eslint@9.39.4) + eslint-plugin-react-hooks: 5.2.0(eslint@9.39.4) + object.assign: 4.1.7 + object.entries: 1.1.9 + eslint-config-airbnb@19.0.4(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4))(eslint-plugin-jsx-a11y@6.10.2(eslint@9.39.4))(eslint-plugin-react-hooks@4.6.2(eslint@9.39.4))(eslint-plugin-react@7.37.5(eslint@9.39.4))(eslint@9.39.4): dependencies: eslint: 9.39.4 @@ -22408,6 +28691,10 @@ snapshots: - eslint-plugin-import-x - supports-color + eslint-config-prettier@8.10.2(eslint@7.32.0): + dependencies: + eslint: 7.32.0 + eslint-config-prettier@8.10.2(eslint@8.57.1): dependencies: eslint: 8.57.1 @@ -22418,12 +28705,21 @@ snapshots: eslint-import-resolver-node@0.3.10: dependencies: - debug: 3.2.7 + debug: 3.2.7(supports-color@5.5.0) is-core-module: 2.16.2 resolve: 2.0.0-next.6 transitivePeerDependencies: - supports-color + eslint-import-resolver-root-import@1.0.4(babel-plugin-root-import@5.1.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)): + dependencies: + babel-plugin-root-import: 5.1.0 + eslint-import-resolver-node: 0.3.10 + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) + json5: 2.2.3 + transitivePeerDependencies: + - supports-color + eslint-import-resolver-root-import@1.0.4(babel-plugin-root-import@5.1.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)): dependencies: babel-plugin-root-import: 5.1.0 @@ -22433,6 +28729,33 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-import-resolver-root-import@1.0.4(babel-plugin-root-import@6.6.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0)): + dependencies: + babel-plugin-root-import: 6.6.0 + eslint-import-resolver-node: 0.3.10 + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0) + json5: 2.2.3 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-root-import@1.0.4(babel-plugin-root-import@6.6.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)): + dependencies: + babel-plugin-root-import: 6.6.0 + eslint-import-resolver-node: 0.3.10 + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1) + json5: 2.2.3 + transitivePeerDependencies: + - supports-color + + eslint-import-resolver-root-import@1.0.4(babel-plugin-root-import@6.6.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)): + dependencies: + babel-plugin-root-import: 6.6.0 + eslint-import-resolver-node: 0.3.10 + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4) + json5: 2.2.3 + transitivePeerDependencies: + - supports-color + eslint-import-resolver-root-import@1.0.4(babel-plugin-root-import@6.6.0)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint@9.39.4)): dependencies: babel-plugin-root-import: 6.6.0 @@ -22454,7 +28777,7 @@ snapshots: eslint-import-resolver-typescript@3.10.1(eslint-plugin-import@2.32.0)(eslint@9.39.4): dependencies: '@nolyfill/is-core-module': 1.0.39 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) eslint: 9.39.4 get-tsconfig: 4.14.0 is-bun-module: 2.0.0 @@ -22466,9 +28789,29 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-module-utils@2.12.1(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint-import-resolver-node@0.3.10)(eslint@7.32.0): + dependencies: + debug: 3.2.7(supports-color@5.5.0) + optionalDependencies: + '@typescript-eslint/parser': 5.62.0(eslint@7.32.0)(typescript@4.9.5) + eslint: 7.32.0 + eslint-import-resolver-node: 0.3.10 + transitivePeerDependencies: + - supports-color + + eslint-module-utils@2.12.1(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.10)(eslint@8.57.1): + dependencies: + debug: 3.2.7(supports-color@5.5.0) + optionalDependencies: + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.10 + transitivePeerDependencies: + - supports-color + eslint-module-utils@2.12.1(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint-import-resolver-node@0.3.10)(eslint@9.39.4): dependencies: - debug: 3.2.7 + debug: 3.2.7(supports-color@5.5.0) optionalDependencies: '@typescript-eslint/parser': 5.62.0(eslint@9.39.4)(typescript@4.9.5) eslint: 9.39.4 @@ -22478,7 +28821,7 @@ snapshots: eslint-module-utils@2.12.1(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint-import-resolver-typescript@3.10.1)(eslint@9.39.4): dependencies: - debug: 3.2.7 + debug: 3.2.7(supports-color@5.5.0) optionalDependencies: '@typescript-eslint/parser': 5.62.0(eslint@9.39.4)(typescript@5.9.3) eslint: 9.39.4 @@ -22489,7 +28832,7 @@ snapshots: eslint-module-utils@2.12.1(@typescript-eslint/parser@8.59.4(eslint@8.57.1)(typescript@5.9.3))(eslint-import-resolver-node@0.3.10)(eslint@8.57.1): dependencies: - debug: 3.2.7 + debug: 3.2.7(supports-color@5.5.0) optionalDependencies: '@typescript-eslint/parser': 8.59.4(eslint@8.57.1)(typescript@5.9.3) eslint: 8.57.1 @@ -22497,6 +28840,64 @@ snapshots: transitivePeerDependencies: - supports-color + eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint@7.32.0): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7(supports-color@5.5.0) + doctrine: 2.1.0 + eslint: 7.32.0 + eslint-import-resolver-node: 0.3.10 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@5.62.0(eslint@7.32.0)(typescript@4.9.5))(eslint-import-resolver-node@0.3.10)(eslint@7.32.0) + hasown: 2.0.3 + is-core-module: 2.16.2 + is-glob: 4.0.3 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 5.62.0(eslint@7.32.0)(typescript@4.9.5) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + + eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1): + dependencies: + '@rtsao/scc': 1.1.0 + array-includes: 3.1.9 + array.prototype.findlastindex: 1.2.6 + array.prototype.flat: 1.3.3 + array.prototype.flatmap: 1.3.3 + debug: 3.2.7(supports-color@5.5.0) + doctrine: 2.1.0 + eslint: 8.57.1 + eslint-import-resolver-node: 0.3.10 + eslint-module-utils: 2.12.1(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint-import-resolver-node@0.3.10)(eslint@8.57.1) + hasown: 2.0.3 + is-core-module: 2.16.2 + is-glob: 4.0.3 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + object.groupby: 1.0.3 + object.values: 1.2.1 + semver: 6.3.1 + string.prototype.trimend: 1.0.9 + tsconfig-paths: 3.15.0 + optionalDependencies: + '@typescript-eslint/parser': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + transitivePeerDependencies: + - eslint-import-resolver-typescript + - eslint-import-resolver-webpack + - supports-color + eslint-plugin-import@2.32.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4): dependencies: '@rtsao/scc': 1.1.0 @@ -22504,7 +28905,7 @@ snapshots: array.prototype.findlastindex: 1.2.6 array.prototype.flat: 1.3.3 array.prototype.flatmap: 1.3.3 - debug: 3.2.7 + debug: 3.2.7(supports-color@5.5.0) doctrine: 2.1.0 eslint: 9.39.4 eslint-import-resolver-node: 0.3.10 @@ -22533,7 +28934,7 @@ snapshots: array.prototype.findlastindex: 1.2.6 array.prototype.flat: 1.3.3 array.prototype.flatmap: 1.3.3 - debug: 3.2.7 + debug: 3.2.7(supports-color@5.5.0) doctrine: 2.1.0 eslint: 9.39.4 eslint-import-resolver-node: 0.3.10 @@ -22562,7 +28963,7 @@ snapshots: array.prototype.findlastindex: 1.2.6 array.prototype.flat: 1.3.3 array.prototype.flatmap: 1.3.3 - debug: 3.2.7 + debug: 3.2.7(supports-color@5.5.0) doctrine: 2.1.0 eslint: 9.39.4 eslint-import-resolver-node: 0.3.10 @@ -22591,7 +28992,7 @@ snapshots: array.prototype.findlastindex: 1.2.6 array.prototype.flat: 1.3.3 array.prototype.flatmap: 1.3.3 - debug: 3.2.7 + debug: 3.2.7(supports-color@5.5.0) doctrine: 2.1.0 eslint: 8.57.1 eslint-import-resolver-node: 0.3.10 @@ -22613,6 +29014,28 @@ snapshots: - eslint-import-resolver-webpack - supports-color + eslint-plugin-jest@26.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@27.5.1)(typescript@4.9.5): + dependencies: + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + eslint: 8.57.1 + optionalDependencies: + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + jest: 27.5.1 + transitivePeerDependencies: + - supports-color + - typescript + + eslint-plugin-jest@26.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(jest@29.7.0(@types/node@16.18.126)(babel-plugin-macros@3.1.0))(typescript@4.9.5): + dependencies: + '@typescript-eslint/utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + eslint: 8.57.1 + optionalDependencies: + '@typescript-eslint/eslint-plugin': 5.62.0(@typescript-eslint/parser@5.62.0(eslint@8.57.1)(typescript@4.9.5))(eslint@8.57.1)(typescript@4.9.5) + jest: 29.7.0(@types/node@16.18.126)(babel-plugin-macros@3.1.0) + transitivePeerDependencies: + - supports-color + - typescript + eslint-plugin-jest@26.9.0(@typescript-eslint/eslint-plugin@5.62.0(@typescript-eslint/parser@5.62.0(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(typescript@4.9.5))(eslint@9.39.4)(jest@27.5.1)(typescript@4.9.5): dependencies: '@typescript-eslint/utils': 5.62.0(eslint@9.39.4)(typescript@4.9.5) @@ -22645,6 +29068,25 @@ snapshots: - supports-color - typescript + eslint-plugin-jsx-a11y@6.10.2(eslint@7.32.0): + dependencies: + aria-query: 5.3.2 + array-includes: 3.1.9 + array.prototype.flatmap: 1.3.3 + ast-types-flow: 0.0.8 + axe-core: 4.11.4 + axobject-query: 4.1.0 + damerau-levenshtein: 1.0.8 + emoji-regex: 9.2.2 + eslint: 7.32.0 + hasown: 2.0.3 + jsx-ast-utils: 3.3.5 + language-tags: 1.0.9 + minimatch: 3.1.5 + object.fromentries: 2.0.8 + safe-regex-test: 1.1.0 + string.prototype.includes: 2.0.1 + eslint-plugin-jsx-a11y@6.10.2(eslint@8.57.1): dependencies: aria-query: 5.3.2 @@ -22683,6 +29125,21 @@ snapshots: safe-regex-test: 1.1.0 string.prototype.includes: 2.0.1 + eslint-plugin-mocha@10.5.0(eslint@7.32.0): + dependencies: + eslint: 7.32.0 + eslint-utils: 3.0.0(eslint@7.32.0) + globals: 13.24.0 + rambda: 7.5.0 + + eslint-plugin-prettier@4.2.5(eslint-config-prettier@8.10.2(eslint@7.32.0))(eslint@7.32.0)(prettier@2.8.8): + dependencies: + eslint: 7.32.0 + prettier: 2.8.8 + prettier-linter-helpers: 1.0.1 + optionalDependencies: + eslint-config-prettier: 8.10.2(eslint@7.32.0) + eslint-plugin-prettier@4.2.5(eslint-config-prettier@8.10.2(eslint@8.57.1))(eslint@8.57.1)(prettier@2.8.8): dependencies: eslint: 8.57.1 @@ -22707,10 +29164,40 @@ snapshots: dependencies: eslint: 9.39.4 + eslint-plugin-react-hooks@5.2.0(eslint@7.32.0): + dependencies: + eslint: 7.32.0 + + eslint-plugin-react-hooks@5.2.0(eslint@8.57.1): + dependencies: + eslint: 8.57.1 + eslint-plugin-react-hooks@5.2.0(eslint@9.39.4): dependencies: eslint: 9.39.4 + eslint-plugin-react@7.37.5(eslint@7.32.0): + dependencies: + array-includes: 3.1.9 + array.prototype.findlast: 1.2.5 + array.prototype.flatmap: 1.3.3 + array.prototype.tosorted: 1.1.4 + doctrine: 2.1.0 + es-iterator-helpers: 1.3.2 + eslint: 7.32.0 + estraverse: 5.3.0 + hasown: 2.0.3 + jsx-ast-utils: 3.3.5 + minimatch: 3.1.5 + object.entries: 1.1.9 + object.fromentries: 2.0.8 + object.values: 1.2.1 + prop-types: 15.8.1 + resolve: 2.0.0-next.6 + semver: 6.3.1 + string.prototype.matchall: 4.0.12 + string.prototype.repeat: 1.0.0 + eslint-plugin-react@7.37.5(eslint@8.57.1): dependencies: array-includes: 3.1.9 @@ -22755,6 +29242,16 @@ snapshots: string.prototype.matchall: 4.0.12 string.prototype.repeat: 1.0.0 + eslint-plugin-storybook@0.5.13(eslint@8.57.1)(typescript@4.9.5): + dependencies: + '@storybook/csf': 0.0.1 + '@typescript-eslint/experimental-utils': 5.62.0(eslint@8.57.1)(typescript@4.9.5) + eslint: 8.57.1 + requireindex: 1.2.0 + transitivePeerDependencies: + - supports-color + - typescript + eslint-plugin-storybook@0.5.13(eslint@9.39.4)(typescript@4.9.5): dependencies: '@storybook/csf': 0.0.1 @@ -22795,12 +29292,70 @@ snapshots: esrecurse: 4.3.0 estraverse: 5.3.0 + eslint-utils@2.1.0: + dependencies: + eslint-visitor-keys: 1.3.0 + + eslint-utils@3.0.0(eslint@7.32.0): + dependencies: + eslint: 7.32.0 + eslint-visitor-keys: 2.1.0 + + eslint-visitor-keys@1.3.0: {} + + eslint-visitor-keys@2.1.0: {} + eslint-visitor-keys@3.4.3: {} eslint-visitor-keys@4.2.1: {} eslint-visitor-keys@5.0.1: {} + eslint@7.32.0: + dependencies: + '@babel/code-frame': 7.12.11 + '@eslint/eslintrc': 0.4.3 + '@humanwhocodes/config-array': 0.5.0 + ajv: 6.15.0 + chalk: 4.1.2 + cross-spawn: 7.0.6 + debug: 4.4.3(supports-color@8.1.1) + doctrine: 3.0.0 + enquirer: 2.3.6 + escape-string-regexp: 4.0.0 + eslint-scope: 5.1.1 + eslint-utils: 2.1.0 + eslint-visitor-keys: 2.1.0 + espree: 7.3.1 + esquery: 1.7.0 + esutils: 2.0.3 + fast-deep-equal: 3.1.3 + file-entry-cache: 6.0.1 + functional-red-black-tree: 1.0.1 + glob-parent: 5.1.2 + globals: 13.24.0 + ignore: 4.0.6 + import-fresh: 3.3.1 + imurmurhash: 0.1.4 + is-glob: 4.0.3 + js-yaml: 3.14.2 + json-stable-stringify-without-jsonify: 1.0.1 + levn: 0.4.1 + lodash.merge: 4.6.2 + minimatch: 3.1.5 + natural-compare: 1.4.0 + optionator: 0.9.4 + progress: 2.0.3 + regexpp: 3.2.0 + semver: 7.8.0 + strip-ansi: 6.0.1 + strip-json-comments: 3.1.1 + table: 6.9.0 + text-table: 0.2.0 + v8-compile-cache: 2.3.0 + transitivePeerDependencies: + - supports-color + eslint@8.57.1: dependencies: '@eslint-community/eslint-utils': 4.9.1(eslint@8.57.1) @@ -22814,7 +29369,7 @@ snapshots: ajv: 6.15.0 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -22861,7 +29416,7 @@ snapshots: ajv: 6.15.0 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) escape-string-regexp: 4.0.0 eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -22883,12 +29438,25 @@ snapshots: transitivePeerDependencies: - supports-color + esniff@2.0.1: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + event-emitter: 0.3.5 + type: 2.7.3 + espree@10.4.0: dependencies: acorn: 8.16.0 acorn-jsx: 5.3.2(acorn@8.16.0) eslint-visitor-keys: 4.2.1 + espree@7.3.1: + dependencies: + acorn: 7.4.1 + acorn-jsx: 5.3.2(acorn@7.4.1) + eslint-visitor-keys: 1.3.0 + espree@9.6.1: dependencies: acorn: 8.16.0 @@ -22919,10 +29487,29 @@ snapshots: estree-util-is-identifier-name@3.0.0: {} + estree-walker@0.6.1: {} + + estree-walker@1.0.1: {} + + estree-walker@2.0.2: {} + esutils@2.0.3: {} etag@1.8.1: {} + ethereum-cryptography@3.2.0: + dependencies: + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.0 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + + event-emitter@0.3.5: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + eventemitter3@4.0.7: {} events@3.3.0: {} @@ -22989,6 +29576,14 @@ snapshots: jest-matcher-utils: 27.5.1 jest-message-util: 27.5.1 + expect@28.1.3: + dependencies: + '@jest/expect-utils': 28.1.3 + jest-get-type: 28.0.2 + jest-matcher-utils: 28.1.3 + jest-message-util: 28.1.3 + jest-util: 28.1.3 + expect@29.7.0: dependencies: '@jest/expect-utils': 29.7.0 @@ -23035,6 +29630,10 @@ snapshots: transitivePeerDependencies: - supports-color + ext@1.7.0: + dependencies: + type: 2.7.3 + extend-shallow@2.0.1: dependencies: is-extendable: 0.1.1 @@ -23046,6 +29645,18 @@ snapshots: extend@3.0.2: {} + external-editor@2.2.0: + dependencies: + chardet: 0.4.2 + iconv-lite: 0.4.24 + tmp: 0.0.33 + + external-editor@3.1.0: + dependencies: + chardet: 0.7.0 + iconv-lite: 0.4.24 + tmp: 0.0.33 + extglob@2.0.4: dependencies: array-unique: 0.3.2 @@ -23059,6 +29670,10 @@ snapshots: transitivePeerDependencies: - supports-color + fake-indexeddb@4.0.2: + dependencies: + realistic-structured-clone: 3.0.0 + fast-deep-equal@3.1.3: {} fast-diff@1.3.0: {} @@ -23115,7 +29730,7 @@ snapshots: find-root: 1.1.0 parse-author: 2.0.0 parse5: 6.0.1 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0) optionalDependencies: html-webpack-plugin: 5.6.7(webpack@5.106.2) transitivePeerDependencies: @@ -23143,6 +29758,10 @@ snapshots: figgy-pudding@3.5.2: {} + figures@2.0.0: + dependencies: + escape-string-regexp: 1.0.5 + figures@3.2.0: dependencies: escape-string-regexp: 1.0.5 @@ -23161,17 +29780,25 @@ snapshots: schema-utils: 3.3.0 webpack: 4.47.0 - file-loader@6.2.0(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)): + file-loader@6.2.0(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14) file-loader@6.2.0(webpack@5.106.2): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0) + + file-selector@0.1.19: + dependencies: + tslib: 2.8.1 + + file-selector@2.1.2: + dependencies: + tslib: 2.8.1 file-system-cache@1.1.0: dependencies: @@ -23207,6 +29834,17 @@ snapshots: transitivePeerDependencies: - supports-color + finalhandler@2.1.1: + dependencies: + debug: 4.4.3(supports-color@8.1.1) + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + find-cache-dir@2.1.0: dependencies: commondir: 1.0.1 @@ -23219,6 +29857,11 @@ snapshots: make-dir: 3.1.0 pkg-dir: 4.2.0 + find-cache-dir@4.0.0: + dependencies: + common-path-prefix: 3.0.0 + pkg-dir: 7.0.0 + find-root@1.1.0: {} find-up@1.1.2: @@ -23245,6 +29888,11 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 + find-up@6.3.0: + dependencies: + locate-path: 7.2.0 + path-exists: 5.0.0 + flat-cache@3.2.0: dependencies: flatted: 3.4.2 @@ -23287,6 +29935,22 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 + fork-ts-checker-webpack-plugin@4.1.6(eslint@8.57.1)(typescript@4.9.5)(webpack@4.47.0): + dependencies: + '@babel/code-frame': 7.29.0 + chalk: 2.4.2 + micromatch: 3.1.10 + minimatch: 3.1.5 + semver: 5.7.2 + tapable: 1.1.3 + typescript: 4.9.5 + webpack: 4.47.0 + worker-rpc: 0.1.1 + optionalDependencies: + eslint: 8.57.1 + transitivePeerDependencies: + - supports-color + fork-ts-checker-webpack-plugin@4.1.6(eslint@9.39.4)(typescript@4.9.5)(webpack@4.47.0): dependencies: '@babel/code-frame': 7.29.0 @@ -23303,6 +29967,46 @@ snapshots: transitivePeerDependencies: - supports-color + fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.1)(typescript@4.9.5)(webpack@4.47.0): + dependencies: + '@babel/code-frame': 7.29.0 + '@types/json-schema': 7.0.15 + chalk: 4.1.2 + chokidar: 3.6.0 + cosmiconfig: 6.0.0 + deepmerge: 4.3.1 + fs-extra: 9.1.0 + glob: 7.2.3 + memfs: 3.5.3 + minimatch: 3.1.5 + schema-utils: 2.7.0 + semver: 7.8.0 + tapable: 1.1.3 + typescript: 4.9.5 + webpack: 4.47.0 + optionalDependencies: + eslint: 8.57.1 + + fork-ts-checker-webpack-plugin@6.5.3(eslint@8.57.1)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)): + dependencies: + '@babel/code-frame': 7.29.0 + '@types/json-schema': 7.0.15 + chalk: 4.1.2 + chokidar: 3.6.0 + cosmiconfig: 6.0.0 + deepmerge: 4.3.1 + fs-extra: 9.1.0 + glob: 7.2.3 + memfs: 3.5.3 + minimatch: 3.1.5 + schema-utils: 2.7.0 + semver: 7.8.0 + tapable: 1.1.3 + typescript: 4.9.5 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14) + optionalDependencies: + eslint: 8.57.1 + fork-ts-checker-webpack-plugin@6.5.3(eslint@9.39.4)(typescript@4.9.5)(webpack@4.47.0): dependencies: '@babel/code-frame': 7.29.0 @@ -23323,7 +30027,7 @@ snapshots: optionalDependencies: eslint: 9.39.4 - fork-ts-checker-webpack-plugin@6.5.3(eslint@9.39.4)(typescript@4.9.5)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)): + fork-ts-checker-webpack-plugin@6.5.3(eslint@9.39.4)(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)): dependencies: '@babel/code-frame': 7.29.0 '@types/json-schema': 7.0.15 @@ -23339,10 +30043,27 @@ snapshots: semver: 7.8.0 tapable: 1.1.3 typescript: 4.9.5 - webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14) optionalDependencies: eslint: 9.39.4 + fork-ts-checker-webpack-plugin@7.3.0(typescript@4.9.5)(webpack@5.106.2): + dependencies: + '@babel/code-frame': 7.29.0 + chalk: 4.1.2 + chokidar: 3.6.0 + cosmiconfig: 7.1.0 + deepmerge: 4.3.1 + fs-extra: 10.1.0 + memfs: 3.5.3 + minimatch: 3.1.5 + node-abort-controller: 3.1.1 + schema-utils: 3.3.0 + semver: 7.8.0 + tapable: 2.3.3 + typescript: 4.9.5 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(webpack-cli@4.10.0) + fork-ts-checker-webpack-plugin@7.3.0(typescript@5.9.3)(webpack@5.106.2): dependencies: '@babel/code-frame': 7.29.0 @@ -23358,7 +30079,24 @@ snapshots: semver: 7.8.0 tapable: 2.3.3 typescript: 5.9.3 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0) + + fork-ts-checker-webpack-plugin@8.0.0(typescript@4.9.5)(webpack@5.106.2): + dependencies: + '@babel/code-frame': 7.29.0 + chalk: 4.1.2 + chokidar: 3.6.0 + cosmiconfig: 7.1.0 + deepmerge: 4.3.1 + fs-extra: 10.1.0 + memfs: 3.5.3 + minimatch: 3.1.5 + node-abort-controller: 3.1.1 + schema-utils: 3.3.0 + semver: 7.8.0 + tapable: 2.3.3 + typescript: 4.9.5 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@5.1.4) form-data@3.0.4: dependencies: @@ -23384,6 +30122,8 @@ snapshots: fresh@0.5.2: {} + fresh@2.0.0: {} + from2@2.3.0: dependencies: inherits: 2.0.4 @@ -23449,8 +30189,12 @@ snapshots: hasown: 2.0.3 is-callable: 1.2.7 + functional-red-black-tree@1.0.1: {} + functions-have-names@1.2.3: {} + fuzzy@0.1.3: {} + gauge@3.0.2: dependencies: aproba: 2.1.0 @@ -23502,6 +30246,8 @@ snapshots: through2: 2.0.5 yargs: 16.2.0 + get-port@4.2.0: {} + get-port@5.1.1: {} get-proto@1.0.1: @@ -23512,6 +30258,8 @@ snapshots: get-stdin@4.0.1: optional: true + get-stdin@8.0.0: {} + get-stream@4.1.0: dependencies: pump: 3.0.4 @@ -23581,6 +30329,11 @@ snapshots: '@types/glob': 9.0.0 glob: 7.2.3 + glob-promise@4.2.2(glob@7.2.3): + dependencies: + '@types/glob': 7.2.0 + glob: 7.2.3 + glob-to-regexp@0.3.0: {} glob-to-regexp@0.4.1: {} @@ -23632,6 +30385,8 @@ snapshots: min-document: 2.19.2 process: 0.11.10 + globals@11.12.0: {} + globals@13.24.0: dependencies: type-fest: 0.20.2 @@ -23652,6 +30407,14 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 + globby@13.2.2: + dependencies: + dir-glob: 3.0.1 + fast-glob: 3.3.3 + ignore: 5.3.2 + merge2: 1.4.1 + slash: 4.0.0 + globby@6.1.0: dependencies: array-union: 1.0.2 @@ -23704,6 +30467,10 @@ snapshots: hard-rejection@2.1.0: {} + has-ansi@2.0.0: + dependencies: + ansi-regex: 2.1.1 + has-bigints@1.1.0: {} has-flag@3.0.0: {} @@ -23940,7 +30707,7 @@ snapshots: util.promisify: 1.0.0 webpack: 4.47.0 - html-webpack-plugin@5.6.7(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)): + html-webpack-plugin@5.6.7(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)): dependencies: '@types/html-minifier-terser': 6.1.0 html-minifier-terser: 6.1.0 @@ -23948,7 +30715,17 @@ snapshots: pretty-error: 4.0.0 tapable: 2.3.3 optionalDependencies: - webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14) + + html-webpack-plugin@5.6.7(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)): + dependencies: + '@types/html-minifier-terser': 6.1.0 + html-minifier-terser: 6.1.0 + lodash: 4.18.1 + pretty-error: 4.0.0 + tapable: 2.3.3 + optionalDependencies: + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14) html-webpack-plugin@5.6.7(webpack@5.106.2): dependencies: @@ -23958,7 +30735,7 @@ snapshots: pretty-error: 4.0.0 tapable: 2.3.3 optionalDependencies: - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0) htmlparser2@6.1.0: dependencies: @@ -23993,7 +30770,7 @@ snapshots: dependencies: '@tootallnate/once': 1.1.2 agent-base: 6.0.2 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -24001,14 +30778,14 @@ snapshots: dependencies: '@tootallnate/once': 2.0.1 agent-base: 6.0.2 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.4 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -24037,14 +30814,14 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.4 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) transitivePeerDependencies: - supports-color @@ -24093,6 +30870,8 @@ snapshots: iferr@0.1.5: {} + ignore-by-default@1.0.1: {} + ignore-walk@5.0.1: dependencies: minimatch: 5.1.9 @@ -24162,6 +30941,49 @@ snapshots: inline-style-parser@0.2.7: {} + inquirer-autocomplete-prompt@0.11.1: + dependencies: + ansi-escapes: 2.0.0 + chalk: 1.1.3 + figures: 2.0.0 + inquirer: 3.1.1 + lodash: 4.18.1 + run-async: 2.4.1 + util: 0.10.4 + + inquirer@3.1.1: + dependencies: + ansi-escapes: 2.0.0 + chalk: 1.1.3 + cli-cursor: 2.1.0 + cli-width: 2.2.1 + external-editor: 2.2.0 + figures: 2.0.0 + lodash: 4.18.1 + mute-stream: 0.0.7 + run-async: 2.4.1 + rx-lite: 4.0.8 + rx-lite-aggregates: 4.0.8 + string-width: 2.1.1 + strip-ansi: 3.0.1 + through: 2.3.8 + + inquirer@6.5.2: + dependencies: + ansi-escapes: 3.2.0 + chalk: 2.4.2 + cli-cursor: 2.1.0 + cli-width: 2.2.1 + external-editor: 3.1.0 + figures: 2.0.0 + lodash: 4.18.1 + mute-stream: 0.0.7 + run-async: 2.4.1 + rxjs: 6.6.7 + string-width: 2.1.1 + strip-ansi: 5.2.0 + through: 2.3.8 + inquirer@8.2.7(@types/node@22.19.19): dependencies: '@inquirer/external-editor': 1.0.3(@types/node@22.19.19) @@ -24182,6 +31004,31 @@ snapshots: transitivePeerDependencies: - '@types/node' + inquirerer@0.1.3: + dependencies: + colors: 1.4.0 + inquirer: 6.5.2 + inquirer-autocomplete-prompt: 0.11.1 + + interchainjs@1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237): + dependencies: + '@interchainjs/cosmos': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + '@interchainjs/cosmos-types': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + '@interchainjs/crypto': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + '@interchainjs/encoding': 1.17.1 + '@interchainjs/ethereum': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + '@interchainjs/math': 1.17.1 + '@interchainjs/pubkey': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + '@interchainjs/types': 1.17.1 + '@interchainjs/utils': 1.17.1(@chain-registry/v2-types@0.53.146)(@chain-registry/v2@1.71.237) + '@noble/hashes': 1.8.0 + decimal.js: 10.6.0 + transitivePeerDependencies: + - '@chain-registry/v2' + - '@chain-registry/v2-types' + - bufferutil + - utf-8-validate + internal-slot@1.1.0: dependencies: es-errors: 1.3.0 @@ -24192,8 +31039,12 @@ snapshots: internmap@2.0.3: {} + interpret@1.4.0: {} + interpret@2.2.0: {} + interpret@3.1.1: {} + ip-address@10.2.0: {} ip@2.0.1: {} @@ -24318,6 +31169,8 @@ snapshots: is-docker@2.2.1: {} + is-docker@3.0.0: {} + is-dom@1.1.0: dependencies: is-object: 1.0.2 @@ -24338,6 +31191,8 @@ snapshots: is-finite@1.1.0: optional: true + is-fullwidth-code-point@2.0.0: {} + is-fullwidth-code-point@3.0.0: {} is-function@1.0.2: {} @@ -24366,12 +31221,20 @@ snapshots: is-in-browser@1.1.3: {} + is-in-ssh@1.0.0: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + is-interactive@1.0.0: {} is-lambda@1.0.1: {} is-map@2.0.3: {} + is-module@1.0.0: {} + is-negative-zero@2.0.3: {} is-number-object@1.1.1: @@ -24417,6 +31280,12 @@ snapshots: is-potential-custom-element-name@1.0.1: {} + is-promise@2.2.2: {} + + is-reference@1.2.1: + dependencies: + '@types/estree': 1.0.9 + is-regex@1.2.1: dependencies: call-bound: 1.0.4 @@ -24491,6 +31360,10 @@ snapshots: dependencies: is-docker: 2.2.1 + is-wsl@3.1.1: + dependencies: + is-inside-container: 1.0.0 + isarray@1.0.0: {} isarray@2.0.5: {} @@ -24555,7 +31428,7 @@ snapshots: istanbul-lib-source-maps@4.0.1: dependencies: - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -24677,6 +31550,25 @@ snapshots: - ts-node - utf-8-validate + jest-cli@29.7.0(@types/node@16.18.126)(babel-plugin-macros@3.1.0): + dependencies: + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@16.18.126)(babel-plugin-macros@3.1.0) + exit: 0.1.2 + import-local: 3.2.0 + jest-config: 29.7.0(@types/node@16.18.126)(babel-plugin-macros@3.1.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jest-cli@29.7.0(@types/node@22.19.19)(babel-plugin-macros@3.1.0): dependencies: '@jest/core': 29.7.0(babel-plugin-macros@3.1.0) @@ -24728,6 +31620,36 @@ snapshots: - supports-color - utf-8-validate + jest-config@29.7.0(@types/node@16.18.126)(babel-plugin-macros@3.1.0): + dependencies: + '@babel/core': 7.29.0 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.29.0) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0(babel-plugin-macros@3.1.0) + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 16.18.126 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + jest-config@29.7.0(@types/node@22.19.19)(babel-plugin-macros@3.1.0): dependencies: '@babel/core': 7.29.0 @@ -24765,6 +31687,13 @@ snapshots: jest-get-type: 27.5.1 pretty-format: 27.5.1 + jest-diff@28.1.3: + dependencies: + chalk: 4.1.2 + diff-sequences: 28.1.1 + jest-get-type: 28.0.2 + pretty-format: 28.1.3 + jest-diff@29.7.0: dependencies: chalk: 4.1.2 @@ -24831,6 +31760,8 @@ snapshots: jest-get-type@27.5.1: {} + jest-get-type@28.0.2: {} + jest-get-type@29.6.3: {} jest-haste-map@26.6.2: @@ -24925,6 +31856,13 @@ snapshots: jest-get-type: 27.5.1 pretty-format: 27.5.1 + jest-matcher-utils@28.1.3: + dependencies: + chalk: 4.1.2 + jest-diff: 28.1.3 + jest-get-type: 28.0.2 + pretty-format: 28.1.3 + jest-matcher-utils@29.7.0: dependencies: chalk: 4.1.2 @@ -24944,6 +31882,18 @@ snapshots: slash: 3.0.0 stack-utils: 2.0.6 + jest-message-util@28.1.3: + dependencies: + '@babel/code-frame': 7.29.0 + '@jest/types': 28.1.3 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + pretty-format: 28.1.3 + slash: 3.0.0 + stack-utils: 2.0.6 + jest-message-util@29.7.0: dependencies: '@babel/code-frame': 7.29.0 @@ -25210,6 +32160,15 @@ snapshots: graceful-fs: 4.2.11 picomatch: 2.3.2 + jest-util@28.1.3: + dependencies: + '@jest/types': 28.1.3 + '@types/node': 22.19.19 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.2 + jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 @@ -25289,6 +32248,18 @@ snapshots: - ts-node - utf-8-validate + jest@29.7.0(@types/node@16.18.126)(babel-plugin-macros@3.1.0): + dependencies: + '@jest/core': 29.7.0(babel-plugin-macros@3.1.0) + '@jest/types': 29.6.3 + import-local: 3.2.0 + jest-cli: 29.7.0(@types/node@16.18.126)(babel-plugin-macros@3.1.0) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jest@29.7.0(@types/node@22.19.19)(babel-plugin-macros@3.1.0): dependencies: '@jest/core': 29.7.0(babel-plugin-macros@3.1.0) @@ -25391,6 +32362,8 @@ snapshots: - '@noble/hashes' - supports-color + jsesc@2.5.2: {} + jsesc@3.1.0: {} json-buffer@3.0.1: {} @@ -25562,12 +32535,12 @@ snapshots: lefthook-windows-arm64: 1.13.6 lefthook-windows-x64: 1.13.6 - lerna@7.4.2(@types/node@22.19.19)(encoding@0.1.13): + lerna@7.4.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(@types/node@22.19.19)(encoding@0.1.13): dependencies: '@lerna/child-process': 7.4.2 - '@lerna/create': 7.4.2(@types/node@22.19.19)(encoding@0.1.13)(typescript@5.9.3) + '@lerna/create': 7.4.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(@types/node@22.19.19)(encoding@0.1.13)(typescript@5.9.3) '@npmcli/run-script': 6.0.2 - '@nx/devkit': 16.10.0(nx@16.10.0) + '@nx/devkit': 16.10.0(nx@16.10.0(@swc/core@1.15.40(@swc/helpers@0.5.21))) '@octokit/plugin-enterprise-rest': 6.0.1 '@octokit/rest': 19.0.11(encoding@0.1.13) byte-size: 8.1.1 @@ -25610,7 +32583,7 @@ snapshots: npm-packlist: 5.1.1 npm-registry-fetch: 14.0.5 npmlog: 6.0.2 - nx: 16.10.0 + nx: 16.10.0(@swc/core@1.15.40(@swc/helpers@0.5.21)) p-map: 4.0.0 p-map-series: 2.1.0 p-pipe: 3.1.0 @@ -25691,12 +32664,78 @@ snapshots: dependencies: immediate: 3.0.6 + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-darwin-arm64@1.32.0: + optional: true + + lightningcss-darwin-x64@1.32.0: + optional: true + + lightningcss-freebsd-x64@1.32.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.32.0: + optional: true + + lightningcss-linux-arm64-gnu@1.32.0: + optional: true + + lightningcss-linux-arm64-musl@1.32.0: + optional: true + + lightningcss-linux-x64-gnu@1.32.0: + optional: true + + lightningcss-linux-x64-musl@1.32.0: + optional: true + + lightningcss-win32-arm64-msvc@1.32.0: + optional: true + + lightningcss-win32-x64-msvc@1.32.0: + optional: true + + lightningcss@1.32.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.32.0 + lightningcss-darwin-arm64: 1.32.0 + lightningcss-darwin-x64: 1.32.0 + lightningcss-freebsd-x64: 1.32.0 + lightningcss-linux-arm-gnueabihf: 1.32.0 + lightningcss-linux-arm64-gnu: 1.32.0 + lightningcss-linux-arm64-musl: 1.32.0 + lightningcss-linux-x64-gnu: 1.32.0 + lightningcss-linux-x64-musl: 1.32.0 + lightningcss-win32-arm64-msvc: 1.32.0 + lightningcss-win32-x64-msvc: 1.32.0 + lilconfig@2.1.0: {} + lilconfig@3.1.3: {} + lines-and-columns@1.2.4: {} lines-and-columns@2.0.4: {} + lmdb@2.8.5: + dependencies: + msgpackr: 1.11.12 + node-addon-api: 6.1.0 + node-gyp-build-optional-packages: 5.1.1 + ordered-binary: 1.6.1 + weak-lru-cache: 1.2.2 + optionalDependencies: + '@lmdb/lmdb-darwin-arm64': 2.8.5 + '@lmdb/lmdb-darwin-x64': 2.8.5 + '@lmdb/lmdb-linux-arm': 2.8.5 + '@lmdb/lmdb-linux-arm64': 2.8.5 + '@lmdb/lmdb-linux-x64': 2.8.5 + '@lmdb/lmdb-win32-x64': 2.8.5 + load-json-file@1.1.0: dependencies: graceful-fs: 4.2.11 @@ -25758,6 +32797,10 @@ snapshots: dependencies: p-locate: 5.0.0 + locate-path@7.2.0: + dependencies: + p-locate: 6.0.0 + lodash-es@4.18.1: {} lodash.debounce@4.0.8: {} @@ -25772,6 +32815,8 @@ snapshots: lodash.trimstart@4.5.1: {} + lodash.truncate@4.4.2: {} + lodash.uniq@4.5.0: {} lodash.words@4.2.0: {} @@ -25819,12 +32864,34 @@ snapshots: lru-cache@7.18.3: {} + lru-queue@0.1.0: + dependencies: + es5-ext: 0.10.64 + lucide-react@0.453.0(react@19.2.6): dependencies: react: 19.2.6 + lunr@2.3.9: {} + lz-string@1.5.0: {} + magic-string@0.25.2: + dependencies: + sourcemap-codec: 1.4.8 + + magic-string@0.25.9: + dependencies: + sourcemap-codec: 1.4.8 + + magic-string@0.27.0: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + make-dir@2.1.0: dependencies: pify: 4.0.1 @@ -25904,6 +32971,8 @@ snapshots: markdown-escapes@1.0.4: {} + marked@4.3.0: {} + material-react-table@3.2.1(010425a9628d654b3c54ea7b922081d1): dependencies: '@emotion/react': 11.14.0(@types/react@19.2.14)(react@19.2.6) @@ -26061,6 +33130,17 @@ snapshots: dependencies: fs-monkey: 1.1.0 + memoizee@0.4.17: + dependencies: + d: 1.0.2 + es5-ext: 0.10.64 + es6-weak-map: 2.0.3 + event-emitter: 0.3.5 + is-promise: 2.2.2 + lru-queue: 0.1.0 + next-tick: 1.1.0 + timers-ext: 0.1.8 + memoizerific@1.11.3: dependencies: map-or-similar: 1.5.0 @@ -26229,7 +33309,7 @@ snapshots: micromark@4.0.2: dependencies: '@types/debug': 4.1.13 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) decode-named-character-reference: 1.3.0 devlop: 1.1.0 micromark-core-commonmark: 2.0.3 @@ -26284,10 +33364,18 @@ snapshots: dependencies: mime-db: 1.52.0 + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + mime@1.6.0: {} mime@2.6.0: {} + mime@3.0.0: {} + + mimic-fn@1.2.0: {} + mimic-fn@2.1.0: {} mimic-fn@3.1.0: {} @@ -26298,11 +33386,17 @@ snapshots: min-indent@1.0.1: {} + mini-css-extract-plugin@2.10.2(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))): + dependencies: + schema-utils: 4.3.3 + tapable: 2.3.3 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21)) + mini-css-extract-plugin@2.10.2(webpack@5.106.2): dependencies: schema-utils: 4.3.3 tapable: 2.3.3 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0) minimalistic-assert@1.0.1: {} @@ -26338,6 +33432,8 @@ snapshots: is-plain-obj: 1.1.0 kind-of: 6.0.3 + minimist@1.2.6: {} + minimist@1.2.8: {} minipass-collect@1.0.2: @@ -26418,10 +33514,37 @@ snapshots: mobx@6.15.3: {} + mocha@10.8.2: + dependencies: + ansi-colors: 4.1.3 + browser-stdout: 1.3.1 + chokidar: 3.6.0 + debug: 4.4.3(supports-color@8.1.1) + diff: 5.2.2 + escape-string-regexp: 4.0.0 + find-up: 5.0.0 + glob: 8.1.0 + he: 1.2.0 + js-yaml: 4.1.1 + log-symbols: 4.1.0 + minimatch: 5.1.9 + ms: 2.1.3 + serialize-javascript: 6.0.2 + strip-json-comments: 3.1.1 + supports-color: 8.1.1 + workerpool: 6.5.1 + yargs: 16.2.0 + yargs-parser: 20.2.9 + yargs-unparser: 2.0.0 + modern-ahocorasick@1.1.0: {} modify-values@1.0.1: {} + moq.ts@7.4.1: + dependencies: + tslib: 2.1.0 + move-concurrently@1.0.1: dependencies: aproba: 1.2.0 @@ -26435,6 +33558,22 @@ snapshots: ms@2.1.3: {} + msgpackr-extract@3.0.4: + dependencies: + node-gyp-build-optional-packages: 5.2.2 + optionalDependencies: + '@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 + optional: true + + msgpackr@1.11.12: + optionalDependencies: + msgpackr-extract: 3.0.4 + multicast-dns@7.2.5: dependencies: dns-packet: 5.6.1 @@ -26448,10 +33587,18 @@ snapshots: arrify: 2.0.1 minimatch: 3.1.5 + mute-stream@0.0.7: {} + mute-stream@0.0.8: {} mute-stream@1.0.0: {} + mz@2.7.0: + dependencies: + any-promise: 1.3.0 + object-assign: 4.1.1 + thenify-all: 1.6.0 + nan@2.27.0: {} nanoclone@0.2.1: {} @@ -26488,6 +33635,10 @@ snapshots: nested-error-stacks@2.1.1: {} + nested-obj@0.2.2: {} + + next-tick@1.1.0: {} + next@14.2.35(babel-plugin-macros@3.1.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): dependencies: '@next/env': 14.2.35 @@ -26522,7 +33673,7 @@ snapshots: nock@13.5.4: dependencies: - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) json-stringify-safe: 5.0.1 propagate: 2.0.1 transitivePeerDependencies: @@ -26532,6 +33683,10 @@ snapshots: node-addon-api@3.2.1: {} + node-addon-api@6.1.0: {} + + node-addon-api@7.1.1: {} + node-dir@0.1.17: dependencies: minimatch: 3.1.5 @@ -26559,6 +33714,15 @@ snapshots: node-forge@1.4.0: {} + node-gyp-build-optional-packages@5.1.1: + dependencies: + detect-libc: 2.1.2 + + node-gyp-build-optional-packages@5.2.2: + dependencies: + detect-libc: 2.1.2 + optional: true + node-gyp-build@4.8.4: {} node-gyp@9.4.1: @@ -26612,6 +33776,32 @@ snapshots: node-releases@2.0.44: {} + nodemon@3.0.1: + dependencies: + chokidar: 3.6.0 + debug: 3.2.7(supports-color@5.5.0) + ignore-by-default: 1.0.1 + minimatch: 3.1.5 + pstree.remy: 1.1.8 + semver: 7.8.0 + simple-update-notifier: 2.0.0 + supports-color: 5.5.0 + touch: 3.1.1 + undefsafe: 2.0.5 + + nodemon@3.1.14: + dependencies: + chokidar: 3.6.0 + debug: 4.4.3(supports-color@5.5.0) + ignore-by-default: 1.0.1 + minimatch: 10.2.5 + pstree.remy: 1.1.8 + semver: 7.8.0 + simple-update-notifier: 2.0.0 + supports-color: 5.5.0 + touch: 3.1.1 + undefsafe: 2.0.5 + nopt@6.0.0: dependencies: abbrev: 1.1.1 @@ -26755,13 +33945,15 @@ snapshots: dependencies: boolbase: 1.0.0 + nullthrows@1.1.1: {} + num2fraction@1.2.2: {} nwsapi@2.2.23: {} - nx@16.10.0: + nx@16.10.0(@swc/core@1.15.40(@swc/helpers@0.5.21)): dependencies: - '@nrwl/tao': 16.10.0 + '@nrwl/tao': 16.10.0(@swc/core@1.15.40(@swc/helpers@0.5.21)) '@parcel/watcher': 2.0.4 '@yarnpkg/lockfile': 1.1.0 '@yarnpkg/parsers': 3.0.0-rc.46 @@ -26808,6 +34000,7 @@ snapshots: '@nx/nx-linux-x64-musl': 16.10.0 '@nx/nx-win32-arm64-msvc': 16.10.0 '@nx/nx-win32-x64-msvc': 16.10.0 + '@swc/core': 1.15.40(@swc/helpers@0.5.21) transitivePeerDependencies: - debug @@ -26904,10 +34097,23 @@ snapshots: dependencies: wrappy: 1.0.2 + onetime@2.0.1: + dependencies: + mimic-fn: 1.2.0 + onetime@5.1.2: dependencies: mimic-fn: 2.1.0 + open@11.0.0: + dependencies: + default-browser: 5.5.0 + define-lazy-prop: 3.0.0 + is-in-ssh: 1.0.0 + is-inside-container: 1.0.0 + powershell-utils: 0.1.0 + wsl-utils: 0.3.1 + open@7.4.2: dependencies: is-docker: 2.2.1 @@ -26946,11 +34152,19 @@ snapshots: strip-ansi: 6.0.1 wcwidth: 1.0.1 + ordered-binary@1.6.1: {} + os-browserify@0.3.0: {} os-homedir@1.0.2: optional: true + os-tmpdir@1.0.2: {} + + ospec@3.1.0: + dependencies: + glob: 7.2.3 + own-keys@1.0.1: dependencies: get-intrinsic: 1.3.0 @@ -26985,6 +34199,10 @@ snapshots: dependencies: yocto-queue: 0.1.0 + p-limit@4.0.0: + dependencies: + yocto-queue: 1.2.2 + p-locate@2.0.0: dependencies: p-limit: 1.3.0 @@ -27001,6 +34219,10 @@ snapshots: dependencies: p-limit: 3.1.0 + p-locate@6.0.0: + dependencies: + p-limit: 4.0.0 + p-map-series@2.1.0: {} p-map@2.1.0: {} @@ -27080,6 +34302,27 @@ snapshots: dot-case: 3.0.4 tslib: 2.8.1 + parcel@2.16.4(@swc/helpers@0.5.21): + dependencies: + '@parcel/config-default': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))(@swc/helpers@0.5.21) + '@parcel/core': 2.16.4(@swc/helpers@0.5.21) + '@parcel/diagnostic': 2.16.4 + '@parcel/events': 2.16.4 + '@parcel/feature-flags': 2.16.4 + '@parcel/fs': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/logger': 2.16.4 + '@parcel/package-manager': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21))(@swc/helpers@0.5.21) + '@parcel/reporter-cli': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/reporter-dev-server': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/reporter-tracer': 2.16.4(@parcel/core@2.16.4(@swc/helpers@0.5.21)) + '@parcel/utils': 2.16.4 + chalk: 4.1.2 + commander: 12.1.0 + get-port: 4.2.0 + transitivePeerDependencies: + - '@swc/helpers' + - napi-wasm + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -27132,6 +34375,8 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 + parse-package-name@1.0.0: {} + parse-path@7.1.0: dependencies: protocols: 2.0.2 @@ -27170,6 +34415,8 @@ snapshots: path-exists@4.0.0: {} + path-exists@5.0.0: {} + path-is-absolute@1.0.1: {} path-is-inside@1.0.2: {} @@ -27268,6 +34515,10 @@ snapshots: dependencies: find-up: 5.0.0 + pkg-dir@7.0.0: + dependencies: + find-up: 6.3.0 + pnp-webpack-plugin@1.6.4(typescript@4.9.5): dependencies: ts-pnp: 1.2.0(typescript@4.9.5) @@ -27288,6 +34539,12 @@ snapshots: postcss-selector-parser: 6.1.2 postcss-value-parser: 4.2.0 + postcss-calc@9.0.1(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-selector-parser: 6.1.2 + postcss-value-parser: 4.2.0 + postcss-colormin@5.3.1(postcss@8.5.14): dependencies: browserslist: 4.28.2 @@ -27296,28 +34553,58 @@ snapshots: postcss: 8.5.14 postcss-value-parser: 4.2.0 + postcss-colormin@6.1.0(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + colord: 2.9.3 + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + postcss-convert-values@5.1.3(postcss@8.5.14): dependencies: browserslist: 4.28.2 postcss: 8.5.14 postcss-value-parser: 4.2.0 + postcss-convert-values@6.1.0(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + postcss-discard-comments@5.1.2(postcss@8.5.14): dependencies: postcss: 8.5.14 + postcss-discard-comments@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-discard-duplicates@5.1.0(postcss@8.5.14): dependencies: postcss: 8.5.14 + postcss-discard-duplicates@6.0.3(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-discard-empty@5.1.1(postcss@8.5.14): dependencies: postcss: 8.5.14 + postcss-discard-empty@6.0.3(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-discard-overridden@5.1.0(postcss@8.5.14): dependencies: postcss: 8.5.14 + postcss-discard-overridden@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-flexbugs-fixes@4.2.1: dependencies: postcss: 7.0.39 @@ -27338,6 +34625,12 @@ snapshots: postcss-value-parser: 4.2.0 stylehacks: 5.1.1(postcss@8.5.14) + postcss-merge-longhand@6.0.5(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + stylehacks: 6.1.1(postcss@8.5.14) + postcss-merge-rules@5.1.4(postcss@8.5.14): dependencies: browserslist: 4.28.2 @@ -27346,11 +34639,24 @@ snapshots: postcss: 8.5.14 postcss-selector-parser: 6.1.2 + postcss-merge-rules@6.1.1(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + cssnano-utils: 4.0.2(postcss@8.5.14) + postcss: 8.5.14 + postcss-selector-parser: 6.1.2 + postcss-minify-font-values@5.1.0(postcss@8.5.14): dependencies: postcss: 8.5.14 postcss-value-parser: 4.2.0 + postcss-minify-font-values@6.1.0(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + postcss-minify-gradients@5.1.1(postcss@8.5.14): dependencies: colord: 2.9.3 @@ -27358,6 +34664,13 @@ snapshots: postcss: 8.5.14 postcss-value-parser: 4.2.0 + postcss-minify-gradients@6.0.3(postcss@8.5.14): + dependencies: + colord: 2.9.3 + cssnano-utils: 4.0.2(postcss@8.5.14) + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + postcss-minify-params@5.1.4(postcss@8.5.14): dependencies: browserslist: 4.28.2 @@ -27365,11 +34678,23 @@ snapshots: postcss: 8.5.14 postcss-value-parser: 4.2.0 + postcss-minify-params@6.1.0(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + cssnano-utils: 4.0.2(postcss@8.5.14) + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + postcss-minify-selectors@5.2.1(postcss@8.5.14): dependencies: postcss: 8.5.14 postcss-selector-parser: 6.1.2 + postcss-minify-selectors@6.0.4(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-selector-parser: 6.1.2 + postcss-modules-extract-imports@2.0.0: dependencies: postcss: 7.0.39 @@ -27416,65 +34741,127 @@ snapshots: dependencies: postcss: 8.5.14 + postcss-normalize-charset@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-normalize-display-values@5.1.0(postcss@8.5.14): dependencies: postcss: 8.5.14 postcss-value-parser: 4.2.0 + postcss-normalize-display-values@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + postcss-normalize-positions@5.1.1(postcss@8.5.14): dependencies: postcss: 8.5.14 postcss-value-parser: 4.2.0 + postcss-normalize-positions@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + postcss-normalize-repeat-style@5.1.1(postcss@8.5.14): dependencies: postcss: 8.5.14 postcss-value-parser: 4.2.0 + postcss-normalize-repeat-style@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + postcss-normalize-string@5.1.0(postcss@8.5.14): dependencies: postcss: 8.5.14 postcss-value-parser: 4.2.0 + postcss-normalize-string@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + postcss-normalize-timing-functions@5.1.0(postcss@8.5.14): dependencies: postcss: 8.5.14 postcss-value-parser: 4.2.0 + postcss-normalize-timing-functions@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + postcss-normalize-unicode@5.1.1(postcss@8.5.14): dependencies: browserslist: 4.28.2 postcss: 8.5.14 postcss-value-parser: 4.2.0 + postcss-normalize-unicode@6.1.0(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + postcss-normalize-url@5.1.0(postcss@8.5.14): dependencies: normalize-url: 6.1.0 postcss: 8.5.14 postcss-value-parser: 4.2.0 + postcss-normalize-url@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + postcss-normalize-whitespace@5.1.1(postcss@8.5.14): dependencies: postcss: 8.5.14 postcss-value-parser: 4.2.0 + postcss-normalize-whitespace@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + postcss-ordered-values@5.1.3(postcss@8.5.14): dependencies: cssnano-utils: 3.1.0(postcss@8.5.14) postcss: 8.5.14 postcss-value-parser: 4.2.0 + postcss-ordered-values@6.0.2(postcss@8.5.14): + dependencies: + cssnano-utils: 4.0.2(postcss@8.5.14) + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + postcss-reduce-initial@5.1.2(postcss@8.5.14): dependencies: browserslist: 4.28.2 caniuse-api: 3.0.0 postcss: 8.5.14 + postcss-reduce-initial@6.1.0(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + caniuse-api: 3.0.0 + postcss: 8.5.14 + postcss-reduce-transforms@5.1.0(postcss@8.5.14): dependencies: postcss: 8.5.14 postcss-value-parser: 4.2.0 + postcss-reduce-transforms@6.0.2(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + postcss-selector-parser@6.1.2: dependencies: cssesc: 3.0.0 @@ -27491,11 +34878,22 @@ snapshots: postcss-value-parser: 4.2.0 svgo: 2.8.2 + postcss-svgo@6.0.3(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-value-parser: 4.2.0 + svgo: 3.3.3 + postcss-unique-selectors@5.1.1(postcss@8.5.14): dependencies: postcss: 8.5.14 postcss-selector-parser: 6.1.2 + postcss-unique-selectors@6.0.4(postcss@8.5.14): + dependencies: + postcss: 8.5.14 + postcss-selector-parser: 6.1.2 + postcss-value-parser@4.2.0: {} postcss@7.0.39: @@ -27515,6 +34913,8 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + powershell-utils@0.1.0: {} + prelude-ls@1.2.1: {} prettier-linter-helpers@1.0.1: @@ -27541,6 +34941,13 @@ snapshots: ansi-styles: 5.2.0 react-is: 17.0.2 + pretty-format@28.1.3: + dependencies: + '@jest/schemas': 28.1.3 + ansi-regex: 5.0.1 + ansi-styles: 5.2.0 + react-is: 18.3.1 + pretty-format@29.7.0: dependencies: '@jest/schemas': 29.6.3 @@ -27557,6 +34964,8 @@ snapshots: process@0.11.10: {} + progress@2.0.3: {} + promise-inflight@1.0.1(bluebird@3.7.2): optionalDependencies: bluebird: 3.7.2 @@ -27655,6 +35064,8 @@ snapshots: dependencies: punycode: 2.3.1 + pstree.remy@1.1.8: {} + public-encrypt@4.0.3: dependencies: bn.js: 4.12.3 @@ -27720,6 +35131,8 @@ snapshots: '@vanilla-extract/css': 1.20.1(babel-plugin-macros@3.1.0) '@vanilla-extract/dynamic': 2.1.5 + rambda@7.5.0: {} + ramda@0.26.1: {} ramda@0.28.0: {} @@ -27786,6 +35199,20 @@ snapshots: react: 19.2.6 scheduler: 0.27.0 + react-dropzone@10.2.2(react@19.2.6): + dependencies: + attr-accept: 2.2.5 + file-selector: 0.1.19 + prop-types: 15.8.1 + react: 19.2.6 + + react-dropzone@14.4.1(react@19.2.6): + dependencies: + attr-accept: 2.2.5 + file-selector: 2.1.2 + prop-types: 15.8.1 + react: 19.2.6 + react-element-to-jsx-string@14.3.4(react-dom@19.2.6(react@19.2.6))(react@19.2.6): dependencies: '@base2/pretty-print-object': 1.0.1 @@ -27848,6 +35275,20 @@ snapshots: react-merge-refs@1.1.0: {} + react-mui-dropzone@4.0.7(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@mui/icons-material@5.18.0(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mui/styles@5.18.0(@types/react@19.2.14)(react@19.2.6))(prop-types@15.8.1)(react-dom@19.2.6(react@19.2.6))(react@19.2.6): + dependencies: + '@babel/runtime': 7.29.2 + '@emotion/react': 11.14.0(@types/react@19.2.14)(react@19.2.6) + '@emotion/styled': 11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@mui/icons-material': 5.18.0(@mui/material@5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@types/react@19.2.14)(react@19.2.6) + '@mui/material': 5.18.0(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react@19.2.6))(@types/react@19.2.14)(react-dom@19.2.6(react@19.2.6))(react@19.2.6) + '@mui/styles': 5.18.0(@types/react@19.2.14)(react@19.2.6) + clsx: 1.2.1 + prop-types: 15.8.1 + react: 19.2.6 + react-dom: 19.2.6(react@19.2.6) + react-dropzone: 10.2.2(react@19.2.6) + react-random-avatars@1.3.1(react@19.2.6): dependencies: react: 19.2.6 @@ -27857,10 +35298,17 @@ snapshots: react-refresh: 0.10.0 typescript: 5.9.3 + react-refresh-typescript@2.0.12(react-refresh@0.16.0)(typescript@4.9.5): + dependencies: + react-refresh: 0.16.0 + typescript: 4.9.5 + react-refresh@0.10.0: {} react-refresh@0.11.0: {} + react-refresh@0.16.0: {} + react-router-dom@6.30.3(react-dom@19.2.6(react@19.2.6))(react@19.2.6): dependencies: '@remix-run/router': 1.23.2 @@ -28003,6 +35451,12 @@ snapshots: real-require@0.1.0: {} + realistic-structured-clone@3.0.0: + dependencies: + domexception: 1.0.1 + typeson: 6.1.0 + typeson-registry: 1.0.0-alpha.39 + recast@0.23.11: dependencies: ast-types: 0.16.1 @@ -28028,10 +35482,18 @@ snapshots: tiny-invariant: 1.3.3 victory-vendor: 36.9.2 + rechoir@0.6.2: + dependencies: + resolve: 1.22.12 + rechoir@0.7.1: dependencies: resolve: 1.22.12 + rechoir@0.8.0: + dependencies: + resolve: 1.22.12 + redent@1.0.0: dependencies: indent-string: 2.1.0 @@ -28066,6 +35528,8 @@ snapshots: regenerator-runtime@0.13.11: {} + regenerator-runtime@0.14.1: {} + regex-not@1.0.2: dependencies: extend-shallow: 3.0.2 @@ -28080,6 +35544,8 @@ snapshots: gopd: 1.2.0 set-function-name: 2.0.2 + regexpp@3.2.0: {} + regexpu-core@6.4.0: dependencies: regenerate: 1.4.2 @@ -28097,6 +35563,21 @@ snapshots: relateurl@0.2.7: {} + reload@3.4.3: + dependencies: + cli-color: 2.0.4 + commander: 14.0.3 + finalhandler: 2.1.1 + minimist: 1.2.8 + nodemon: 3.1.14 + open: 11.0.0 + serve-static: 2.2.1 + ws: 8.19.0 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + remark-external-links@8.0.0: dependencies: extend: 3.0.2 @@ -28235,6 +35716,11 @@ snapshots: path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + restore-cursor@2.0.0: + dependencies: + onetime: 2.0.1 + signal-exit: 3.0.7 + restore-cursor@3.1.0: dependencies: onetime: 5.1.2 @@ -28267,10 +35753,59 @@ snapshots: hash-base: 3.1.2 inherits: 2.0.4 + rlp@3.0.0: {} + robust-predicates@3.0.3: {} + rollup-plugin-base64@1.0.1(rollup@3.30.0): + dependencies: + '@rollup/pluginutils': 3.1.0(rollup@3.30.0) + transitivePeerDependencies: + - rollup + + rollup-plugin-dts@5.3.1(rollup@3.30.0)(typescript@4.9.5): + dependencies: + magic-string: 0.30.21 + rollup: 3.30.0 + typescript: 4.9.5 + optionalDependencies: + '@babel/code-frame': 7.29.0 + + rollup-plugin-inject@3.0.2: + dependencies: + estree-walker: 0.6.1 + magic-string: 0.25.9 + rollup-pluginutils: 2.8.2 + + rollup-plugin-modify@3.0.0: + dependencies: + magic-string: 0.25.2 + ospec: 3.1.0 + + rollup-plugin-node-polyfills@0.2.1: + dependencies: + rollup-plugin-inject: 3.0.2 + + rollup-plugin-polyfill@4.2.0(rollup@3.30.0): + dependencies: + rollup: 3.30.0 + + rollup-plugin-web-worker-loader@1.7.0(rollup@3.30.0): + dependencies: + rollup: 3.30.0 + + rollup-pluginutils@2.8.2: + dependencies: + estree-walker: 0.6.1 + + rollup@3.30.0: + optionalDependencies: + fsevents: 2.3.3 + rsvp@4.8.5: {} + run-applescript@7.1.0: {} + run-async@2.4.1: {} run-parallel@1.2.0: @@ -28281,6 +35816,16 @@ snapshots: dependencies: aproba: 1.2.0 + rx-lite-aggregates@4.0.8: + dependencies: + rx-lite: 4.0.8 + + rx-lite@4.0.8: {} + + rxjs@6.6.7: + dependencies: + tslib: 1.14.1 + rxjs@7.8.2: dependencies: tslib: 2.8.1 @@ -28408,6 +35953,22 @@ snapshots: transitivePeerDependencies: - supports-color + send@1.2.1: + dependencies: + debug: 4.4.3(supports-color@8.1.1) + 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 + transitivePeerDependencies: + - supports-color + serialize-javascript@4.0.0: dependencies: randombytes: 2.1.0 @@ -28449,6 +36010,15 @@ snapshots: transitivePeerDependencies: - supports-color + serve-static@2.2.1: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1 + transitivePeerDependencies: + - supports-color + set-blocking@2.0.0: {} set-function-length@1.2.2: @@ -28534,6 +36104,25 @@ snapshots: shell-quote@1.8.3: {} + shelljs@0.8.5: + dependencies: + glob: 7.2.3 + interpret: 1.4.0 + rechoir: 0.6.2 + + shiki@0.10.1: + dependencies: + jsonc-parser: 3.2.0 + vscode-oniguruma: 1.7.0 + vscode-textmate: 5.2.0 + + shiki@0.14.7: + dependencies: + ansi-sequence-parser: 1.1.3 + jsonc-parser: 3.2.0 + vscode-oniguruma: 1.7.0 + vscode-textmate: 8.0.0 + side-channel-list@1.0.1: dependencies: es-errors: 1.3.0 @@ -28580,6 +36169,10 @@ snapshots: dependencies: is-arrayish: 0.3.4 + simple-update-notifier@2.0.0: + dependencies: + semver: 7.8.0 + sisteransi@1.0.5: {} slash@1.0.0: {} @@ -28588,8 +36181,18 @@ snapshots: slash@3.0.0: {} + slash@4.0.0: {} + + slice-ansi@4.0.0: + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + smart-buffer@4.2.0: {} + smob@0.0.6: {} + snapdragon-node@2.1.1: dependencies: define-property: 1.0.0 @@ -28622,7 +36225,7 @@ snapshots: socks-proxy-agent@7.0.0: dependencies: agent-base: 6.0.2 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) socks: 2.8.9 transitivePeerDependencies: - supports-color @@ -28670,6 +36273,8 @@ snapshots: source-map@0.7.6: {} + sourcemap-codec@1.4.8: {} + space-separated-tokens@1.1.5: {} space-separated-tokens@2.0.2: {} @@ -28690,7 +36295,7 @@ snapshots: spdy-transport@3.0.0: dependencies: - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) detect-node: 2.1.0 hpack.js: 2.1.6 obuf: 1.1.2 @@ -28701,7 +36306,7 @@ snapshots: spdy@4.0.2: dependencies: - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) handle-thing: 2.0.1 http-deceiver: 1.2.7 select-hose: 2.0.0 @@ -28828,6 +36433,11 @@ snapshots: lodash.words: 4.2.0 rgb-hex: 3.0.0 + string-width@2.1.1: + dependencies: + is-fullwidth-code-point: 2.0.0 + strip-ansi: 4.0.0 + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -28922,6 +36532,14 @@ snapshots: dependencies: ansi-regex: 2.1.1 + strip-ansi@4.0.0: + dependencies: + ansi-regex: 3.0.1 + + strip-ansi@5.2.0: + dependencies: + ansi-regex: 4.1.1 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -28966,15 +36584,21 @@ snapshots: schema-utils: 2.7.1 webpack: 4.47.0 - style-loader@2.0.0(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)): + style-loader@2.0.0(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)): dependencies: loader-utils: 2.0.4 schema-utils: 3.3.0 - webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14) + + style-loader@2.0.0(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)): + dependencies: + loader-utils: 2.0.4 + schema-utils: 3.3.0 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14) style-loader@3.3.4(webpack@5.106.2): dependencies: - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0) style-to-js@1.1.21: dependencies: @@ -29001,8 +36625,16 @@ snapshots: postcss: 8.5.14 postcss-selector-parser: 6.1.2 + stylehacks@6.1.1(postcss@8.5.14): + dependencies: + browserslist: 4.28.2 + postcss: 8.5.14 + postcss-selector-parser: 6.1.2 + stylis@4.2.0: {} + supports-color@2.0.0: {} + supports-color@5.5.0: dependencies: has-flag: 3.0.0 @@ -29064,6 +36696,14 @@ snapshots: tabbable@6.4.0: {} + table@6.9.0: + dependencies: + ajv: 8.20.0 + lodash.truncate: 4.4.2 + slice-ansi: 4.0.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + tapable@1.1.3: {} tapable@2.3.3: {} @@ -29107,6 +36747,8 @@ snapshots: temp-dir@1.0.0: {} + term-size@2.2.1: {} + terminal-link@2.1.1: dependencies: ansi-escapes: 4.3.2 @@ -29140,34 +36782,59 @@ snapshots: transitivePeerDependencies: - bluebird - terser-webpack-plugin@5.6.0(esbuild@0.25.12)(postcss@8.5.14)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)): + terser-webpack-plugin@5.6.0(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 terser: 5.47.1 - webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14) optionalDependencies: + '@swc/core': 1.15.40(@swc/helpers@0.5.21) esbuild: 0.25.12 postcss: 8.5.14 - terser-webpack-plugin@5.6.0(postcss@8.5.14)(webpack@5.106.2): + terser-webpack-plugin@5.6.0(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 terser: 5.47.1 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14) optionalDependencies: + '@swc/core': 1.15.40(@swc/helpers@0.5.21) postcss: 8.5.14 - terser-webpack-plugin@5.6.0(webpack@5.106.2): + terser-webpack-plugin@5.6.0(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack@5.106.2): dependencies: '@jridgewell/trace-mapping': 0.3.31 jest-worker: 27.5.1 schema-utils: 4.3.3 terser: 5.47.1 - webpack: 5.106.2(webpack-cli@4.10.0) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0) + optionalDependencies: + '@swc/core': 1.15.40(@swc/helpers@0.5.21) + postcss: 8.5.14 + + terser-webpack-plugin@5.6.0(@swc/core@1.15.40(@swc/helpers@0.5.21))(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + terser: 5.47.1 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21)) + optionalDependencies: + '@swc/core': 1.15.40(@swc/helpers@0.5.21) + + terser-webpack-plugin@5.6.0(@swc/core@1.15.40(@swc/helpers@0.5.21))(webpack@5.106.2): + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + jest-worker: 27.5.1 + schema-utils: 4.3.3 + terser: 5.47.1 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(webpack-cli@4.10.0) + optionalDependencies: + '@swc/core': 1.15.40(@swc/helpers@0.5.21) terser@4.8.1: dependencies: @@ -29193,6 +36860,14 @@ snapshots: text-table@0.2.0: {} + thenify-all@1.6.0: + dependencies: + thenify: 3.3.1 + + thenify@3.3.1: + dependencies: + any-promise: 1.3.0 + thread-loader@3.0.4(webpack@5.106.2): dependencies: json-parse-better-errors: 1.0.2 @@ -29200,7 +36875,15 @@ snapshots: loader-utils: 2.0.4 neo-async: 2.6.2 schema-utils: 3.3.0 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0) + + thread-loader@4.0.4(webpack@5.106.2): + dependencies: + json-parse-better-errors: 1.0.2 + loader-runner: 4.3.2 + neo-async: 2.6.2 + schema-utils: 4.3.3 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@5.1.4) thread-stream@0.15.2: dependencies: @@ -29221,6 +36904,11 @@ snapshots: dependencies: setimmediate: 1.0.5 + timers-ext@0.1.8: + dependencies: + es5-ext: 0.10.64 + next-tick: 1.1.0 + tiny-invariant@1.3.3: {} tiny-secp256k1@1.1.7: @@ -29246,6 +36934,10 @@ snapshots: dependencies: tldts-core: 7.0.30 + tmp@0.0.33: + dependencies: + os-tmpdir: 1.0.2 + tmp@0.2.5: {} tmpl@1.0.5: {} @@ -29258,6 +36950,8 @@ snapshots: safe-buffer: 5.2.1 typed-array-buffer: 1.0.3 + to-fast-properties@2.0.0: {} + to-object-path@0.3.0: dependencies: kind-of: 3.2.2 @@ -29284,6 +36978,8 @@ snapshots: toposort@2.0.2: {} + touch@3.1.1: {} + tough-cookie@4.1.4: dependencies: psl: 1.15.0 @@ -29326,7 +37022,7 @@ snapshots: ts-dedent@2.2.0: {} - ts-jest@27.1.5(@babel/core@7.29.0)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5): + ts-jest@27.1.5(@babel/core@7.29.0)(@types/jest@27.5.2)(babel-jest@27.5.1(@babel/core@7.29.0))(esbuild@0.25.12)(jest@27.5.1)(typescript@4.9.5): dependencies: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 @@ -29340,9 +37036,30 @@ snapshots: yargs-parser: 20.2.9 optionalDependencies: '@babel/core': 7.29.0 + '@types/jest': 27.5.2 babel-jest: 27.5.1(@babel/core@7.29.0) esbuild: 0.25.12 + ts-jest@29.4.9(@babel/core@7.29.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@16.18.126)(babel-plugin-macros@3.1.0))(typescript@4.9.5): + dependencies: + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + handlebars: 4.7.9 + jest: 29.7.0(@types/node@16.18.126)(babel-plugin-macros@3.1.0) + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.8.0 + type-fest: 4.41.0 + typescript: 4.9.5 + yargs-parser: 21.1.1 + optionalDependencies: + '@babel/core': 7.29.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.29.0) + jest-util: 29.7.0 + ts-jest@29.4.9(@babel/core@7.29.0)(@jest/transform@29.7.0)(@jest/types@29.6.3)(babel-jest@29.7.0(@babel/core@7.29.0))(jest-util@29.7.0)(jest@29.7.0(@types/node@22.19.19)(babel-plugin-macros@3.1.0))(typescript@5.9.3): dependencies: bs-logger: 0.2.6 @@ -29363,6 +37080,26 @@ snapshots: babel-jest: 29.7.0(@babel/core@7.29.0) jest-util: 29.7.0 + ts-loader@9.5.7(typescript@4.9.5)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))): + dependencies: + chalk: 4.1.2 + enhanced-resolve: 5.21.3 + micromatch: 4.0.8 + semver: 7.8.0 + source-map: 0.7.6 + typescript: 4.9.5 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21)) + + ts-loader@9.5.7(typescript@4.9.5)(webpack@5.106.2): + dependencies: + chalk: 4.1.2 + enhanced-resolve: 5.21.3 + micromatch: 4.0.8 + semver: 7.8.0 + source-map: 0.7.6 + typescript: 4.9.5 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(webpack-cli@4.10.0) + ts-loader@9.5.7(typescript@5.9.3)(webpack@5.106.2): dependencies: chalk: 4.1.2 @@ -29371,10 +37108,28 @@ snapshots: semver: 7.8.0 source-map: 0.7.6 typescript: 5.9.3 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0) ts-mixer@6.0.4: {} + ts-mocha@10.1.0(mocha@10.8.2): + dependencies: + mocha: 10.8.2 + ts-node: 7.0.1 + optionalDependencies: + tsconfig-paths: 3.15.0 + + ts-node@7.0.1: + dependencies: + arrify: 1.0.1 + buffer-from: 1.1.2 + diff: 3.5.1 + make-error: 1.3.6 + minimist: 1.2.8 + mkdirp: 0.5.6 + source-map-support: 0.5.21 + yn: 2.0.0 + ts-pnp@1.2.0(typescript@4.9.5): optionalDependencies: typescript: 4.9.5 @@ -29385,6 +37140,13 @@ snapshots: enhanced-resolve: 5.21.3 tsconfig-paths: 3.15.0 + tsconfig-paths-webpack-plugin@4.2.0: + dependencies: + chalk: 4.1.2 + enhanced-resolve: 5.21.3 + tapable: 2.3.3 + tsconfig-paths: 4.2.0 + tsconfig-paths@3.15.0: dependencies: '@types/json5': 0.0.29 @@ -29400,6 +37162,8 @@ snapshots: tslib@1.14.1: {} + tslib@2.1.0: {} + tslib@2.8.1: {} tslog@3.3.3: @@ -29421,7 +37185,7 @@ snapshots: tuf-js@1.1.7: dependencies: '@tufjs/models': 1.0.4 - debug: 4.4.3 + debug: 4.4.3(supports-color@8.1.1) make-fetch-happen: 11.1.1 transitivePeerDependencies: - supports-color @@ -29455,6 +37219,8 @@ snapshots: media-typer: 0.3.0 mime-types: 2.1.35 + type@2.7.3: {} + typed-array-buffer@1.0.3: dependencies: call-bound: 1.0.4 @@ -29494,12 +37260,37 @@ snapshots: typedarray@0.0.6: {} + typedoc@0.22.18(typescript@4.9.5): + dependencies: + glob: 8.1.0 + lunr: 2.3.9 + marked: 4.3.0 + minimatch: 5.1.9 + shiki: 0.10.1 + typescript: 4.9.5 + + typedoc@0.24.8(typescript@4.9.5): + dependencies: + lunr: 2.3.9 + marked: 4.3.0 + minimatch: 9.0.9 + shiki: 0.14.7 + typescript: 4.9.5 + typeforce@1.18.0: {} typescript@4.9.5: {} typescript@5.9.3: {} + typeson-registry@1.0.0-alpha.39: + dependencies: + base64-arraybuffer-es6: 0.7.0 + typeson: 6.1.0 + whatwg-url: 8.7.0 + + typeson@6.1.0: {} + ufo@1.6.4: {} uglify-js@3.19.3: @@ -29514,6 +37305,8 @@ snapshots: uncrypto@0.1.3: {} + undefsafe@2.0.5: {} + undici-types@6.21.0: {} undici@7.25.0: {} @@ -29720,14 +37513,14 @@ snapshots: schema-utils: 3.3.0 webpack: 4.47.0 optionalDependencies: - file-loader: 6.2.0(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + file-loader: 6.2.0(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) url-loader@4.1.1(file-loader@6.2.0(webpack@5.106.2))(webpack@5.106.2): dependencies: loader-utils: 2.0.4 mime-types: 2.1.35 schema-utils: 3.3.0 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0) optionalDependencies: file-loader: 6.2.0(webpack@5.106.2) @@ -29865,6 +37658,12 @@ snapshots: void-elements@3.1.0: {} + vscode-oniguruma@1.7.0: {} + + vscode-textmate@5.2.0: {} + + vscode-textmate@8.0.0: {} + w3c-hr-time@1.0.2: dependencies: browser-process-hrtime: 1.0.0 @@ -29911,10 +37710,14 @@ snapshots: dependencies: defaults: 1.0.4 + weak-lru-cache@1.2.2: {} + web-namespaces@1.1.4: {} webidl-conversions@3.0.1: {} + webidl-conversions@4.0.2: {} + webidl-conversions@5.0.0: {} webidl-conversions@6.1.0: {} @@ -29934,11 +37737,30 @@ snapshots: import-local: 3.2.0 interpret: 2.2.0 rechoir: 0.7.1 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0) webpack-merge: 5.10.0 optionalDependencies: webpack-dev-server: 4.15.2(webpack-cli@4.10.0)(webpack@5.106.2) + webpack-cli@5.1.4(webpack-dev-server@4.15.2)(webpack@5.106.2): + dependencies: + '@discoveryjs/json-ext': 0.5.7 + '@webpack-cli/configtest': 2.1.1(webpack-cli@5.1.4)(webpack@5.106.2) + '@webpack-cli/info': 2.0.2(webpack-cli@5.1.4)(webpack@5.106.2) + '@webpack-cli/serve': 2.0.5(webpack-cli@5.1.4)(webpack-dev-server@4.15.2)(webpack@5.106.2) + colorette: 2.0.20 + commander: 10.0.1 + cross-spawn: 7.0.6 + envinfo: 7.21.0 + fastest-levenshtein: 1.0.16 + import-local: 3.2.0 + interpret: 3.1.1 + rechoir: 0.8.0 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@5.1.4) + webpack-merge: 5.10.0 + optionalDependencies: + webpack-dev-server: 4.15.2(webpack-cli@5.1.4)(webpack@5.106.2) + webpack-dev-middleware@3.7.3(webpack@4.47.0): dependencies: memory-fs: 0.4.1 @@ -29948,7 +37770,7 @@ snapshots: webpack: 4.47.0 webpack-log: 2.0.0 - webpack-dev-middleware@4.3.0(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)): + webpack-dev-middleware@4.3.0(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)): dependencies: colorette: 1.4.0 mem: 8.1.1 @@ -29956,16 +37778,36 @@ snapshots: mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 3.3.0 - webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14) - webpack-dev-middleware@5.3.4(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)): + webpack-dev-middleware@4.3.0(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)): + dependencies: + colorette: 1.4.0 + mem: 8.1.1 + memfs: 3.5.3 + mime-types: 2.1.35 + range-parser: 1.2.1 + schema-utils: 3.3.0 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14) + + webpack-dev-middleware@5.3.4(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)): dependencies: colorette: 2.0.20 memfs: 3.5.3 mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.3.3 - webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14) + optional: true + + webpack-dev-middleware@5.3.4(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)): + dependencies: + colorette: 2.0.20 + memfs: 3.5.3 + mime-types: 2.1.35 + range-parser: 1.2.1 + schema-utils: 4.3.3 + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14) optional: true webpack-dev-middleware@5.3.4(webpack@5.106.2): @@ -29975,7 +37817,7 @@ snapshots: mime-types: 2.1.35 range-parser: 1.2.1 schema-utils: 4.3.3 - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0) webpack-dev-server@4.15.2(webpack-cli@4.10.0)(webpack@5.106.2): dependencies: @@ -30010,7 +37852,7 @@ snapshots: webpack-dev-middleware: 5.3.4(webpack@5.106.2) ws: 8.20.1 optionalDependencies: - webpack: 5.106.2(postcss@8.5.14)(webpack-cli@4.10.0) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0) webpack-cli: 4.10.0(webpack-dev-server@4.15.2)(webpack@5.106.2) transitivePeerDependencies: - bufferutil @@ -30018,7 +37860,7 @@ snapshots: - supports-color - utf-8-validate - webpack-dev-server@4.15.2(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)): + webpack-dev-server@4.15.2(webpack-cli@5.1.4)(webpack@5.106.2): dependencies: '@types/bonjour': 3.5.13 '@types/connect-history-api-fallback': 1.5.4 @@ -30048,10 +37890,92 @@ snapshots: serve-index: 1.9.2 sockjs: 0.3.24 spdy: 4.0.2 - webpack-dev-middleware: 5.3.4(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + webpack-dev-middleware: 5.3.4(webpack@5.106.2) ws: 8.20.1 optionalDependencies: - webpack: 5.106.2(esbuild@0.25.12)(postcss@8.5.14) + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@5.1.4) + webpack-cli: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.106.2) + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - utf-8-validate + + webpack-dev-server@4.15.2(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)): + dependencies: + '@types/bonjour': 3.5.13 + '@types/connect-history-api-fallback': 1.5.4 + '@types/express': 4.17.25 + '@types/serve-index': 1.9.4 + '@types/serve-static': 1.15.10 + '@types/sockjs': 0.3.36 + '@types/ws': 8.18.1 + ansi-html-community: 0.0.8 + bonjour-service: 1.3.0 + chokidar: 3.6.0 + colorette: 2.0.20 + compression: 1.8.1 + connect-history-api-fallback: 2.0.0 + default-gateway: 6.0.3 + express: 4.22.2 + graceful-fs: 4.2.11 + html-entities: 2.6.0 + http-proxy-middleware: 2.0.9(@types/express@4.17.25) + ipaddr.js: 2.4.0 + launch-editor: 2.13.2 + open: 8.4.2 + p-retry: 4.6.2 + rimraf: 3.0.2 + schema-utils: 4.3.3 + selfsigned: 2.4.1 + serve-index: 1.9.2 + sockjs: 0.3.24 + spdy: 4.0.2 + webpack-dev-middleware: 5.3.4(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) + ws: 8.20.1 + optionalDependencies: + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14) + transitivePeerDependencies: + - bufferutil + - debug + - supports-color + - utf-8-validate + optional: true + + webpack-dev-server@4.15.2(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)): + dependencies: + '@types/bonjour': 3.5.13 + '@types/connect-history-api-fallback': 1.5.4 + '@types/express': 4.17.25 + '@types/serve-index': 1.9.4 + '@types/serve-static': 1.15.10 + '@types/sockjs': 0.3.36 + '@types/ws': 8.18.1 + ansi-html-community: 0.0.8 + bonjour-service: 1.3.0 + chokidar: 3.6.0 + colorette: 2.0.20 + compression: 1.8.1 + connect-history-api-fallback: 2.0.0 + default-gateway: 6.0.3 + express: 4.22.2 + graceful-fs: 4.2.11 + html-entities: 2.6.0 + http-proxy-middleware: 2.0.9(@types/express@4.17.25) + ipaddr.js: 2.4.0 + launch-editor: 2.13.2 + open: 8.4.2 + p-retry: 4.6.2 + rimraf: 3.0.2 + schema-utils: 4.3.3 + selfsigned: 2.4.1 + serve-index: 1.9.2 + sockjs: 0.3.24 + spdy: 4.0.2 + webpack-dev-middleware: 5.3.4(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + ws: 8.20.1 + optionalDependencies: + webpack: 5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14) transitivePeerDependencies: - bufferutil - debug @@ -30093,7 +38017,7 @@ snapshots: webpack-virtual-modules@0.2.2: dependencies: - debug: 3.2.7 + debug: 3.2.7(supports-color@5.5.0) transitivePeerDependencies: - supports-color @@ -30127,7 +38051,7 @@ snapshots: transitivePeerDependencies: - supports-color - webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14): + webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21)): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.9 @@ -30150,7 +38074,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.3 - terser-webpack-plugin: 5.6.0(esbuild@0.25.12)(postcss@8.5.14)(webpack@5.106.2(esbuild@0.25.12)(postcss@8.5.14)) + terser-webpack-plugin: 5.6.0(@swc/core@1.15.40(@swc/helpers@0.5.21))(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))) watchpack: 2.5.1 webpack-sources: 3.4.1 transitivePeerDependencies: @@ -30167,7 +38091,7 @@ snapshots: - postcss - uglify-js - webpack@5.106.2(postcss@8.5.14)(webpack-cli@4.10.0): + webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.9 @@ -30190,7 +38114,87 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.3 - terser-webpack-plugin: 5.6.0(postcss@8.5.14)(webpack@5.106.2) + terser-webpack-plugin: 5.6.0(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(esbuild@0.25.12)(postcss@8.5.14)) + watchpack: 2.5.1 + webpack-sources: 3.4.1 + transitivePeerDependencies: + - '@minify-html/node' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - esbuild + - html-minifier-terser + - lightningcss + - postcss + - uglify-js + + webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14): + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.9 + '@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.16.0 + acorn-import-phases: 1.0.4(acorn@8.16.0) + browserslist: 4.28.2 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.21.3 + es-module-lexer: 2.1.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + loader-runner: 4.3.2 + mime-db: 1.54.0 + neo-async: 2.6.2 + schema-utils: 4.3.3 + tapable: 2.3.3 + terser-webpack-plugin: 5.6.0(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)) + watchpack: 2.5.1 + webpack-sources: 3.4.1 + transitivePeerDependencies: + - '@minify-html/node' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - esbuild + - html-minifier-terser + - lightningcss + - postcss + - uglify-js + + webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@4.10.0): + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.9 + '@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.16.0 + acorn-import-phases: 1.0.4(acorn@8.16.0) + browserslist: 4.28.2 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.21.3 + es-module-lexer: 2.1.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + loader-runner: 4.3.2 + mime-db: 1.54.0 + neo-async: 2.6.2 + schema-utils: 4.3.3 + tapable: 2.3.3 + terser-webpack-plugin: 5.6.0(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack@5.106.2) watchpack: 2.5.1 webpack-sources: 3.4.1 optionalDependencies: @@ -30209,7 +38213,7 @@ snapshots: - postcss - uglify-js - webpack@5.106.2(webpack-cli@4.10.0): + webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack-cli@5.1.4): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.9 @@ -30232,7 +38236,49 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.3 tapable: 2.3.3 - terser-webpack-plugin: 5.6.0(webpack@5.106.2) + terser-webpack-plugin: 5.6.0(@swc/core@1.15.40(@swc/helpers@0.5.21))(postcss@8.5.14)(webpack@5.106.2) + watchpack: 2.5.1 + webpack-sources: 3.4.1 + optionalDependencies: + webpack-cli: 5.1.4(webpack-dev-server@4.15.2)(webpack@5.106.2) + transitivePeerDependencies: + - '@minify-html/node' + - '@swc/core' + - '@swc/css' + - '@swc/html' + - clean-css + - cssnano + - csso + - esbuild + - html-minifier-terser + - lightningcss + - postcss + - uglify-js + + webpack@5.106.2(@swc/core@1.15.40(@swc/helpers@0.5.21))(webpack-cli@4.10.0): + dependencies: + '@types/eslint-scope': 3.7.7 + '@types/estree': 1.0.9 + '@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.16.0 + acorn-import-phases: 1.0.4(acorn@8.16.0) + browserslist: 4.28.2 + chrome-trace-event: 1.0.4 + enhanced-resolve: 5.21.3 + es-module-lexer: 2.1.0 + eslint-scope: 5.1.1 + events: 3.3.0 + glob-to-regexp: 0.4.1 + graceful-fs: 4.2.11 + loader-runner: 4.3.2 + mime-db: 1.54.0 + neo-async: 2.6.2 + schema-utils: 4.3.3 + tapable: 2.3.3 + terser-webpack-plugin: 5.6.0(@swc/core@1.15.40(@swc/helpers@0.5.21))(webpack@5.106.2) watchpack: 2.5.1 webpack-sources: 3.4.1 optionalDependencies: @@ -30365,6 +38411,8 @@ snapshots: dependencies: microevent.ts: 0.1.1 + workerpool@6.5.1: {} + world-countries@5.1.0: {} wrap-ansi@6.2.0: @@ -30427,8 +38475,15 @@ snapshots: ws@7.5.10: {} + ws@8.19.0: {} + ws@8.20.1: {} + wsl-utils@0.3.1: + dependencies: + is-wsl: 3.1.1 + powershell-utils: 0.1.0 + x-default-browser@0.4.0: optionalDependencies: default-browser-id: 1.0.4 @@ -30469,6 +38524,13 @@ snapshots: yargs-parser@21.1.1: {} + yargs-unparser@2.0.0: + dependencies: + camelcase: 6.3.0 + decamelize: 4.0.0 + flat: 5.0.2 + is-plain-obj: 2.1.0 + yargs@16.2.0: dependencies: cliui: 7.0.4 @@ -30489,8 +38551,12 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 + yn@2.0.0: {} + yocto-queue@0.1.0: {} + yocto-queue@1.2.2: {} + yup@0.32.11: dependencies: '@babel/runtime': 7.29.2 diff --git a/sdk/typescript/scripts/build-prod-sdk.sh b/sdk/typescript/scripts/build-prod-sdk.sh index e34985d8d0..f015118aaf 100755 --- a/sdk/typescript/scripts/build-prod-sdk.sh +++ b/sdk/typescript/scripts/build-prod-sdk.sh @@ -14,8 +14,15 @@ rm -rf dist || true pnpm build:wasm # enable dev mode and then install dev packages +# +# `--no-frozen-lockfile` is required: dev:on injects the four smolmix-family +# packages (plus wasm/smolmix/pkg) as new workspace importers that the committed +# lockfile does not know about. CI sets CI=true, which makes a bare `pnpm install` +# default to frozen and fail with ERR_PNPM_OUTDATED_LOCKFILE. Use the `--no-` +# form, not `--frozen-lockfile false`: pnpm parses the bare `false` as a separate +# argument and ignores it. pnpm dev:on -pnpm install +pnpm install --no-frozen-lockfile # build the Typescript SDK packages pnpm build:ci:sdk diff --git a/sdk/typescript/scripts/publish.sh b/sdk/typescript/scripts/publish.sh index b279c74d3c..30210c4a33 100755 --- a/sdk/typescript/scripts/publish.sh +++ b/sdk/typescript/scripts/publish.sh @@ -24,6 +24,24 @@ set -o pipefail REPO_ROOT="$(git rev-parse --show-toplevel)" cd "$REPO_ROOT" +# `pnpm publish` rewrites each package's `workspace:*` deps (mix-fetch/dns/websocket +# all depend on mix-tunnel) to concrete versions at pack time by re-globbing +# pnpm-workspace.yaml for the sibling packages. They are only in the workspace +# while dev mode is on, and build-prod-sdk.sh turns dev mode off when it finishes, +# so enable it here and restore the clean state on exit. This is a YAML edit only; +# no reinstall is needed because pack-time resolution reads sibling package.json +# versions directly. +# Arm the cleanup before mutating the workspace: dev:off filters unconditionally, +# so it is safe even if dev:on fails mid-write, and this closes the window where a +# crash between the two would leave pnpm-workspace.yaml dirty. +# +# The trap must cd back to the repo root first: a failed `pnpm publish` exits +# (errexit) while still inside a pushd'd package dir, and `dev:off` is a script +# defined only in the root package.json. Running it from a package dir fails with +# "Command dev:off not found" and leaves dev mode on. +trap 'cd "$REPO_ROOT" && pnpm dev:off' EXIT +pnpm dev:on + packages=( "sdk/typescript/packages/mix-tunnel" "sdk/typescript/packages/mix-fetch" @@ -39,12 +57,86 @@ popd () { command popd > /dev/null } -echo "Summary of versions to publish:" +# Resolve the npm dist-tag for one package. +# +# NPM_DIST_TAG=latest|next forces that tag on every package. The default, +# `auto`, derives the tag per package from what is already on npm so that no +# manual promote step has to be remembered: +# +# * version has a prerelease suffix (x.y.z-rc.N) -> next +# prereleases must never become the default install. +# * package is not yet on npm (npm view 404s) -> latest +# a first publish has to set `latest`, or a bare `npm i` finds no version. +# * publishing major == current `latest` major -> latest +# an ordinary patch/minor of the live line. +# * publishing major > current `latest` major -> next +# a breaking major: ship under `next`, leave existing users on `latest`, +# and promote later with `npm dist-tag add @ latest`. +# Once `latest` points at the new major, the next patch resolves to +# `latest` again on its own, with nothing to clean up. +# * publishing major < current `latest` major -> next +# a backport; never silently move `latest` backwards. Pass an explicit +# NPM_DIST_TAG if a dedicated legacy tag is wanted. +resolve_tag() { + local name="$1" version="$2" mode="$3" + if [[ "$mode" != "auto" ]]; then + printf '%s' "$mode" + return + fi + if [[ "$version" == *-* ]]; then + printf 'next' + return + fi + # Find the package's current `latest` version on npm. There are three + # outcomes, each driving the tag decision below: + # - success -> compare majors (same major: latest; higher: next) + # - package not found -> first ever publish; it has to set `latest` + # - any other failure -> registry/network problem; abort rather than guess + # + # The third case is why this is careful. Defaulting to `latest` when the + # lookup merely failed would move `latest` onto this version even for a + # package that already exists, and so could push a breaking major onto every + # current consumer. Only a genuine 404 counts as "new"; anything else aborts. + # + # stderr is sent to a file rather than merged into stdout so the success value + # holds only the version (never an npm warning), while the failure text can + # still be inspected to recognise a 404. + local current err + err="$(mktemp)" + if current="$(npm view "$name" dist-tags.latest 2>"$err")"; then + rm -f "$err" + elif grep -qiE 'E404|404 Not Found' "$err"; then + current="" + rm -f "$err" + else + printf 'npm view failed for %s (not a 404), refusing to guess a dist-tag: %s\n' "$name" "$(cat "$err")" >&2 + rm -f "$err" + return 1 + fi + + if [[ -z "$current" ]]; then + printf 'latest' + elif [[ "${version%%.*}" == "${current%%.*}" ]]; then + printf 'latest' + else + printf 'next' + fi +} + +NPM_DIST_TAG="${NPM_DIST_TAG:-auto}" + +# Resolve every tag up front so the summary shows exactly what each package will +# get. Under DRY_RUN this is the whole point: you see the tag decision before +# anything is uploaded. +declare -a TAGS +echo "Summary of packages to publish (mode: $NPM_DIST_TAG):" echo for item in "${packages[@]}"; do - pushd "$item" - jq -r '. | " " + .version + " " + .name' < package.json - popd + name="$(jq -r '.name' "$item/package.json")" + version="$(jq -r '.version' "$item/package.json")" + tag="$(resolve_tag "$name" "$version" "$NPM_DIST_TAG")" + TAGS+=("$tag") + printf ' %-34s %-8s --tag %s\n' "$name" "$version" "$tag" done echo @@ -54,22 +146,23 @@ echo # string, which produces tarballs that fail to install. # # Flags: -# --access=public scoped packages default to private; smolmix-family is public -# --no-git-checks CI runners can have dirty working trees from the build step -# --tag $NPM_DIST_TAG defaults to `latest`; set to `next` for pre-release shipping -NPM_DIST_TAG="${NPM_DIST_TAG:-latest}" +# --access=public scoped packages default to private; smolmix-family is public +# --no-git-checks CI runners can have dirty working trees from the build step +# --tag per-package, resolved above DRY_RUN_FLAG="" if [[ "${DRY_RUN:-0}" == "1" ]]; then DRY_RUN_FLAG="--dry-run" - echo "DRY_RUN=1 — running pnpm publish in dry-run mode (no tarballs uploaded)" + echo "DRY_RUN=1: running pnpm publish in dry-run mode (no tarballs uploaded)" fi COUNTER=0 -for item in "${packages[@]}"; do +for i in "${!packages[@]}"; do + item="${packages[$i]}" + tag="${TAGS[$i]}" (( COUNTER+=1 )) pushd "$item" - echo "Publishing $item (${COUNTER}/${#packages[@]}) --tag $NPM_DIST_TAG" - pnpm publish --access=public --no-git-checks --tag "$NPM_DIST_TAG" $DRY_RUN_FLAG + echo "Publishing $item (${COUNTER}/${#packages[@]}) --tag $tag" + pnpm publish --access=public --no-git-checks --tag "$tag" $DRY_RUN_FLAG popd echo done diff --git a/sdk/typescript/scripts/release.sh b/sdk/typescript/scripts/release.sh index a40a46efcb..ab05c0a772 100755 --- a/sdk/typescript/scripts/release.sh +++ b/sdk/typescript/scripts/release.sh @@ -9,7 +9,7 @@ make sdk-wasm-build # Build Typescript packages pnpm i -pnpm build:sdk +pnpm sdk:build # Publish to NPM ./sdk/typescript/scripts/publish.sh From 9ff2ec249df56ed2bca08d877d5ba1178e94ffce Mon Sep 17 00:00:00 2001 From: Tommy Verrall Date: Mon, 8 Jun 2026 11:53:56 +0200 Subject: [PATCH 89/94] Show unbonded delegations in wallet delegation list - In `delegate.rs`, add `delegation_node_identity` and `delegation_mixnode_is_unbonding` so missing node details emit `unbonded:{mix_id}` with `mixnode_is_unbonding: true` instead of an empty `node_identity`. - Add `delegationListVisibility.ts` (`shouldHideDelegationFromList`, `filterVisibleDelegations`, `searchDelegations`) and wire `DelegationList.tsx` to the shared helpers. - Update `useSortDelegations.tsx` to pin fully unbonded delegations to the top via `isFullyUnbondedDelegation`. - In `UndelegateModal.tsx`, display `Node unbonded (mix N)` instead of raw `unbonded:{mix_id}` on the confirm screen. - Add jest tests - Add Rust unit test --- .../src/operations/mixnet/delegate.rs | 42 +++++++++++++- .../components/Delegation/DelegationList.tsx | 49 +++++++--------- .../components/Delegation/UndelegateModal.tsx | 7 ++- .../src/context/delegationQuery.test.ts | 54 +++++++++++++++++ nym-wallet/src/hooks/useSortDelegations.tsx | 9 ++- .../src/utils/delegationIdentity.test.ts | 38 ++++++++++++ nym-wallet/src/utils/delegationIdentity.ts | 27 +++++++++ .../src/utils/delegationListVisibility.ts | 48 +++++++++++++++ nym-wallet/src/utils/index.ts | 2 + .../unbondedDelegation.acceptance.test.ts | 58 +++++++++++++++++++ .../src/utils/unbondedDelegation.fixture.ts | 53 +++++++++++++++++ 11 files changed, 354 insertions(+), 33 deletions(-) create mode 100644 nym-wallet/src/context/delegationQuery.test.ts create mode 100644 nym-wallet/src/utils/delegationIdentity.test.ts create mode 100644 nym-wallet/src/utils/delegationIdentity.ts create mode 100644 nym-wallet/src/utils/delegationListVisibility.ts create mode 100644 nym-wallet/src/utils/unbondedDelegation.acceptance.test.ts create mode 100644 nym-wallet/src/utils/unbondedDelegation.fixture.ts diff --git a/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs b/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs index 0e6fa01ee7..9e4cb383f3 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs @@ -418,7 +418,7 @@ pub async fn get_all_mix_delegations( pending_events.len() ); - let mixnode_is_unbonding = node_details.as_ref().map(|m| m.is_unbonding); + let mixnode_is_unbonding = delegation_mixnode_is_unbonding(&node_details); log::trace!( " >>> node with mix_id: {} is unbonding: {:?}", d.mix_id, @@ -428,7 +428,7 @@ pub async fn get_all_mix_delegations( with_everything.push(DelegationWithEverything { owner: d.owner, mix_id: d.mix_id, - node_identity: node_details.map(|m| m.node_identity).unwrap_or_default(), + node_identity: delegation_node_identity(&node_details, d.mix_id), amount: d.amount, block_height: d.height, uses_vesting_contract_tokens, @@ -536,3 +536,41 @@ pub async fn get_delegation_summary( total_rewards, }) } + +pub(crate) fn delegation_node_identity( + node_details: &Option, + mix_id: NodeId, +) -> String { + node_details + .as_ref() + .map(|m| m.node_identity.clone()) + .unwrap_or_else(|| format!("unbonded:{}", mix_id)) +} + +pub(crate) fn delegation_mixnode_is_unbonding( + node_details: &Option, +) -> Option { + node_details.as_ref().map(|m| m.is_unbonding).or_else(|| { + if node_details.is_none() { + Some(true) + } else { + None + } + }) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn unbonded_registry_miss_uses_synthetic_identity() { + const EXAMPLE_MIX_ID: NodeId = 1234; + + assert_eq!( + delegation_node_identity(&None, EXAMPLE_MIX_ID), + "unbonded:1234" + ); + assert_eq!(delegation_mixnode_is_unbonding(&None), Some(true)); + } +} diff --git a/nym-wallet/src/components/Delegation/DelegationList.tsx b/nym-wallet/src/components/Delegation/DelegationList.tsx index 51ad848a49..230811180a 100644 --- a/nym-wallet/src/components/Delegation/DelegationList.tsx +++ b/nym-wallet/src/components/Delegation/DelegationList.tsx @@ -4,6 +4,7 @@ import { AlertTitle, Box, Button, + Chip, Collapse, FormControl, IconButton, @@ -30,7 +31,7 @@ import { useNavigate } from 'react-router-dom'; import { TauriLink as Link } from 'src/components/TauriLinkWrapper'; import { format } from 'date-fns'; import { Undelegate } from 'src/svg-icons'; -import { toPercentIntegerString } from 'src/utils'; +import { toPercentIntegerString, isFullyUnbondedDelegation, formatUnbondedNodeLabel, shouldHideDelegationFromList, searchDelegations } from 'src/utils'; import { InfoTooltip } from '../InfoToolTip'; import { DelegationListItemActions, DelegationsActionsMenu } from './DelegationActions'; import { PendingDelegationCard } from './PendingDelegationCard'; @@ -41,25 +42,7 @@ export type Order = 'asc' | 'desc'; type AdditionalTypes = { profit_margin_percent: number; operating_cost: number }; export type SortingKeys = keyof AdditionalTypes | keyof DelegationWithEverything; -const shouldBeFiltered = (item: any): boolean => { - if (isDelegation(item)) { - if (!item.node_identity || item.node_identity === '-' || item.node_identity === '...') { - return true; - } - if (typeof item.avg_uptime_percent === 'string' && item.avg_uptime_percent === '-') { - return true; - } - } - - if (isPendingDelegation(item)) { - if ((!item.node_identity || item.node_identity === '') && item.event && item.event.kind === 'Undelegate') { - return true; - } - return false; - } - - return false; -}; +const shouldBeFiltered = (item: any): boolean => shouldHideDelegationFromList(item); const SORT_FIELD_OPTIONS: { id: SortingKeys; label: string }[] = [ { id: 'delegated_on_iso_datetime', label: 'Delegated on' }, @@ -132,9 +115,8 @@ export const DelegationList: FCWithChildren<{ const searchNeedle = identityFilter.trim().toLowerCase(); const displayedDelegations = React.useMemo(() => { - if (!searchNeedle) return activeDelegations; - return activeDelegations.filter((d) => d.node_identity.toLowerCase().includes(searchNeedle)); - }, [activeDelegations, searchNeedle]); + return searchDelegations(activeDelegations, identityFilter); + }, [activeDelegations, identityFilter]); const activeCount = activeDelegations.length; @@ -407,7 +389,7 @@ export const DelegationList: FCWithChildren<{ displayedDelegations.map((item) => { const rowKey = `${item.mix_id}-${item.node_identity}`; const isOpen = expandedKey === rowKey; - const nodeIsUnbonded = Boolean(!item.node_identity); + const nodeIsFullyUnbonded = isFullyUnbondedDelegation(item); const satNum = saturationNumeric(item); let satColor: 'text.secondary' | 'error.main' | 'success.main' = 'text.secondary'; if (satNum !== undefined) { @@ -458,9 +440,20 @@ export const DelegationList: FCWithChildren<{ )} - {nodeIsUnbonded ? ( + {nodeIsFullyUnbonded ? ( - - + + } + /> + + {formatUnbondedNodeLabel(item.mix_id)} + + ) : ( - {!item.pending_events.length && !nodeIsUnbonded && ( + {!item.pending_events.length && !nodeIsFullyUnbonded && ( onItemActionClick ? onItemActionClick(item, action) : undefined @@ -496,7 +489,7 @@ export const DelegationList: FCWithChildren<{ disableDelegateMore={item.mixnode_is_unbonding} /> )} - {!item.pending_events.length && nodeIsUnbonded && ( + {!item.pending_events.length && nodeIsFullyUnbonded && ( t.palette.nym.nymWallet.text.main }} size="small"> (onItemActionClick ? onItemActionClick(item, 'undelegate') : undefined)} diff --git a/nym-wallet/src/components/Delegation/UndelegateModal.tsx b/nym-wallet/src/components/Delegation/UndelegateModal.tsx index 1038dbe341..e08f1135c7 100644 --- a/nym-wallet/src/components/Delegation/UndelegateModal.tsx +++ b/nym-wallet/src/components/Delegation/UndelegateModal.tsx @@ -3,6 +3,7 @@ import { Box, SxProps } from '@mui/material'; import { FeeDetails } from '@nymproject/types'; import { useGetFee } from 'src/hooks/useGetFee'; import { simulateUndelegateFromNode, simulateVestingUndelegateFromMixnode } from 'src/requests'; +import { formatDelegationNodeIdentityForDisplay } from 'src/utils'; import { AppContext } from 'src/context'; import { ModalFee } from '../Modals/ModalFee'; import { ModalListItem } from '../Modals/ModalListItem'; @@ -49,7 +50,11 @@ export const UndelegateModal: FCWithChildren<{ backdropProps={backdropProps} > - + diff --git a/nym-wallet/src/context/delegationQuery.test.ts b/nym-wallet/src/context/delegationQuery.test.ts new file mode 100644 index 0000000000..f560b3134a --- /dev/null +++ b/nym-wallet/src/context/delegationQuery.test.ts @@ -0,0 +1,54 @@ +jest.mock('src/utils', () => ({ + decCoinToDisplay: jest.fn((coin: { amount: string; denom: string }) => coin), +})); + +jest.mock('src/requests', () => ({ + getDelegationSummary: jest.fn(), + getAllPendingDelegations: jest.fn(), +})); + +import { fetchDelegationSummaryQuery } from './delegationQuery'; +import { getAllPendingDelegations, getDelegationSummary } from 'src/requests'; + +const mockedGetDelegationSummary = getDelegationSummary as jest.MockedFunction; +const mockedGetAllPendingDelegations = getAllPendingDelegations as jest.MockedFunction< + typeof getAllPendingDelegations +>; + +describe('fetchDelegationSummaryQuery', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('includes unbonded delegations in totals and keeps pending events on new nodes separate', async () => { + mockedGetDelegationSummary.mockResolvedValue({ + delegations: [ + { + mix_id: 42, + node_identity: 'unbonded:42', + amount: { amount: '1000000', denom: 'unym' }, + unclaimed_rewards: { amount: '50000', denom: 'unym' }, + mixnode_is_unbonding: true, + }, + ], + total_delegations: { amount: '1000000', denom: 'unym' }, + total_rewards: { amount: '50000', denom: 'unym' }, + } as unknown as Awaited>); + + mockedGetAllPendingDelegations.mockResolvedValue([ + { + node_identity: 'new-node-identity', + event: { mix_id: 99, kind: 'Delegate', address: 'n1test' }, + }, + ] as Awaited>); + + const result = await fetchDelegationSummaryQuery(); + + expect(result.delegations).toHaveLength(2); + expect(result.delegations[0]).toMatchObject({ mix_id: 42, node_identity: 'unbonded:42' }); + expect(result.pendingDelegations).toHaveLength(1); + expect(result.totalDelegations.amount).toBe('1000000'); + expect(result.totalRewards.amount).toBe('50000'); + expect(result.totalDelegationsAndRewards.amount).toBe('1050000.000000'); + }); +}); diff --git a/nym-wallet/src/hooks/useSortDelegations.tsx b/nym-wallet/src/hooks/useSortDelegations.tsx index b2bdcce787..df7dcf6680 100644 --- a/nym-wallet/src/hooks/useSortDelegations.tsx +++ b/nym-wallet/src/hooks/useSortDelegations.tsx @@ -1,12 +1,17 @@ import { orderBy as _orderBy } from 'lodash'; import { Order, SortingKeys } from 'src/components/Delegation/DelegationList'; import { TDelegations, isDelegation } from 'src/context/delegations'; +import { isFullyUnbondedDelegation } from 'src/utils'; type MappedTypes = 'delegationValue' | 'operatorReward' | 'profitMarginValue' | 'operatorCostValue'; export const useSortDelegations = (delegationItems: TDelegations, order: Order, orderBy: SortingKeys) => { - const unbondedDelegations = delegationItems.filter((delegation) => !delegation.node_identity); - const delegations = delegationItems.filter((delegation) => delegation.node_identity); + const unbondedDelegations = delegationItems.filter( + (delegation) => isDelegation(delegation) && isFullyUnbondedDelegation(delegation), + ); + const delegations = delegationItems.filter( + (delegation) => !(isDelegation(delegation) && isFullyUnbondedDelegation(delegation)), + ); // example of a mapped type in typescript diff --git a/nym-wallet/src/utils/delegationIdentity.test.ts b/nym-wallet/src/utils/delegationIdentity.test.ts new file mode 100644 index 0000000000..c0f38d8ed5 --- /dev/null +++ b/nym-wallet/src/utils/delegationIdentity.test.ts @@ -0,0 +1,38 @@ +import { + UNBONDED_NODE_IDENTITY_PREFIX, + formatUnbondedNodeLabel, + formatDelegationNodeIdentityForDisplay, + isFullyUnbondedDelegation, + isUnbondedNodeIdentity, +} from './delegationIdentity'; + +describe('delegationIdentity', () => { + it('treats empty identity as unbonded', () => { + expect(isUnbondedNodeIdentity('')).toBe(true); + expect(isUnbondedNodeIdentity(undefined)).toBe(true); + expect(isFullyUnbondedDelegation({ node_identity: '', mixnode_is_unbonding: false })).toBe(true); + }); + + it('treats unbonded prefix as fully unbonded', () => { + const identity = `${UNBONDED_NODE_IDENTITY_PREFIX}42`; + expect(isUnbondedNodeIdentity(identity)).toBe(true); + expect(isFullyUnbondedDelegation({ node_identity: identity, mixnode_is_unbonding: false })).toBe(true); + }); + + it('does not treat bonded identity as unbonded', () => { + const identity = '2Abcdefghijklmnopqrstuvwxyz1234567890'; + expect(isUnbondedNodeIdentity(identity)).toBe(false); + expect(isFullyUnbondedDelegation({ node_identity: identity, mixnode_is_unbonding: true })).toBe(false); + }); + + it('formats unbonded node label with mix id', () => { + expect(formatUnbondedNodeLabel(123)).toBe('Node unbonded (mix 123)'); + }); + + it('formats unbonded identity for display using mix id', () => { + expect(formatDelegationNodeIdentityForDisplay('unbonded:42', 42)).toBe('Node unbonded (mix 42)'); + expect(formatDelegationNodeIdentityForDisplay('2Abcdefghijklmnopqrstuvwxyz1234567890', 42)).toBe( + '2Abcdefghijklmnopqrstuvwxyz1234567890', + ); + }); +}); diff --git a/nym-wallet/src/utils/delegationIdentity.ts b/nym-wallet/src/utils/delegationIdentity.ts new file mode 100644 index 0000000000..04cc394be2 --- /dev/null +++ b/nym-wallet/src/utils/delegationIdentity.ts @@ -0,0 +1,27 @@ +import type { DelegationWithEverything } from '@nymproject/types'; + +export const UNBONDED_NODE_IDENTITY_PREFIX = 'unbonded:'; + +export function isUnbondedNodeIdentity(nodeIdentity: string | undefined | null): boolean { + if (!nodeIdentity) { + return true; + } + return nodeIdentity.startsWith(UNBONDED_NODE_IDENTITY_PREFIX); +} + +export function isFullyUnbondedDelegation( + item: Pick, +): boolean { + return isUnbondedNodeIdentity(item.node_identity); +} + +export function formatUnbondedNodeLabel(mixId: number): string { + return `Node unbonded (mix ${mixId})`; +} + +export function formatDelegationNodeIdentityForDisplay(nodeIdentity: string, mixId: number): string { + if (isUnbondedNodeIdentity(nodeIdentity)) { + return formatUnbondedNodeLabel(mixId); + } + return nodeIdentity; +} diff --git a/nym-wallet/src/utils/delegationListVisibility.ts b/nym-wallet/src/utils/delegationListVisibility.ts new file mode 100644 index 0000000000..fae364abc6 --- /dev/null +++ b/nym-wallet/src/utils/delegationListVisibility.ts @@ -0,0 +1,48 @@ +import type { DelegationWithEverything, WrappedDelegationEvent } from '@nymproject/types'; +import { isFullyUnbondedDelegation } from './delegationIdentity'; + +export type DelegationListItem = DelegationWithEverything | WrappedDelegationEvent; + +const isPendingDelegationItem = (delegation: DelegationListItem): delegation is WrappedDelegationEvent => + 'event' in delegation; + +const isDelegationItem = (delegation: DelegationListItem): delegation is DelegationWithEverything => + 'owner' in delegation; + +export function shouldHideDelegationFromList(item: DelegationListItem): boolean { + if (isDelegationItem(item)) { + if (!item.node_identity || item.node_identity === '-' || item.node_identity === '...') { + return true; + } + } + + if (isPendingDelegationItem(item)) { + if ((!item.node_identity || item.node_identity === '') && item.event && item.event.kind === 'Undelegate') { + return true; + } + return false; + } + + return false; +} + +export function filterVisibleDelegations(items: DelegationListItem[]): DelegationListItem[] { + return items.filter((item) => !shouldHideDelegationFromList(item)); +} + +export function searchDelegations( + delegations: DelegationWithEverything[], + searchNeedle: string, +): DelegationWithEverything[] { + const needle = searchNeedle.trim().toLowerCase(); + if (!needle) { + return delegations; + } + return delegations.filter( + (d) => d.node_identity.toLowerCase().includes(needle) || String(d.mix_id).includes(needle), + ); +} + +export function isUndelegateOnlyDelegation(item: DelegationWithEverything): boolean { + return isFullyUnbondedDelegation(item); +} diff --git a/nym-wallet/src/utils/index.ts b/nym-wallet/src/utils/index.ts index b1a2ade95a..9f26adf78d 100644 --- a/nym-wallet/src/utils/index.ts +++ b/nym-wallet/src/utils/index.ts @@ -1,4 +1,6 @@ export * from './common'; +export * from './delegationIdentity'; +export * from './delegationListVisibility'; export * from './fireRequests'; export * from './console'; export { default as fireRequests } from './fireRequests'; diff --git a/nym-wallet/src/utils/unbondedDelegation.acceptance.test.ts b/nym-wallet/src/utils/unbondedDelegation.acceptance.test.ts new file mode 100644 index 0000000000..0157771526 --- /dev/null +++ b/nym-wallet/src/utils/unbondedDelegation.acceptance.test.ts @@ -0,0 +1,58 @@ +import type { DelegationWithEverything } from '@nymproject/types'; +import { formatDelegationNodeIdentityForDisplay } from './delegationIdentity'; +import { + filterVisibleDelegations, + isUndelegateOnlyDelegation, + searchDelegations, + shouldHideDelegationFromList, +} from './delegationListVisibility'; +import { + EXAMPLE_HISTORICAL_NODE_IDENTITY, + EXAMPLE_UNBONDED_MIX_ID, + buildFixedUnbondedWalletDelegation, + buildLegacyHiddenUnbondedWalletDelegation, +} from './unbondedDelegation.fixture'; + +describe('unbonded delegation wallet visibility acceptance', () => { + it('hides the pre-fix wallet row with empty node_identity', () => { + const legacyRow = buildLegacyHiddenUnbondedWalletDelegation(); + + expect(legacyRow.mix_id).toBe(EXAMPLE_UNBONDED_MIX_ID); + expect(legacyRow.node_identity).toBe(''); + expect(shouldHideDelegationFromList(legacyRow)).toBe(true); + expect(filterVisibleDelegations([legacyRow])).toHaveLength(0); + }); + + it('shows the post-fix wallet row for the same on-chain delegation', () => { + const fixedRow = buildFixedUnbondedWalletDelegation(); + + expect(fixedRow.node_identity).toBe(`unbonded:${EXAMPLE_UNBONDED_MIX_ID}`); + expect(fixedRow.mixnode_is_unbonding).toBe(true); + expect(shouldHideDelegationFromList(fixedRow)).toBe(false); + expect(filterVisibleDelegations([fixedRow])).toHaveLength(1); + expect(isUndelegateOnlyDelegation(fixedRow)).toBe(true); + }); + + it('does not hide the row when uptime is missing', () => { + const fixedRow = buildFixedUnbondedWalletDelegation(); + + expect(fixedRow.avg_uptime_percent).toBeNull(); + expect(shouldHideDelegationFromList(fixedRow)).toBe(false); + }); + + it('finds the row by mix_id search when historical identity is unavailable', () => { + const fixedRow = buildFixedUnbondedWalletDelegation(); + const visible = filterVisibleDelegations([fixedRow]) as DelegationWithEverything[]; + + expect(searchDelegations(visible, String(EXAMPLE_UNBONDED_MIX_ID))).toHaveLength(1); + expect(searchDelegations(visible, EXAMPLE_HISTORICAL_NODE_IDENTITY)).toHaveLength(0); + }); + + it('formats undelegate confirmation copy without exposing the synthetic prefix', () => { + const fixedRow = buildFixedUnbondedWalletDelegation(); + + expect(formatDelegationNodeIdentityForDisplay(fixedRow.node_identity, fixedRow.mix_id)).toBe( + `Node unbonded (mix ${EXAMPLE_UNBONDED_MIX_ID})`, + ); + }); +}); diff --git a/nym-wallet/src/utils/unbondedDelegation.fixture.ts b/nym-wallet/src/utils/unbondedDelegation.fixture.ts new file mode 100644 index 0000000000..c03fc344ea --- /dev/null +++ b/nym-wallet/src/utils/unbondedDelegation.fixture.ts @@ -0,0 +1,53 @@ +import type { DelegationWithEverything } from '@nymproject/types'; +import { UNBONDED_NODE_IDENTITY_PREFIX } from './delegationIdentity'; + +/** Synthetic mix_id used in wallet unbonded-delegation tests. */ +export const EXAMPLE_UNBONDED_MIX_ID = 1234; + +/** Example bonded-node identity (registry miss => wallet uses unbonded prefix instead). */ +export const EXAMPLE_HISTORICAL_NODE_IDENTITY = '2ExampleHistoricalNodeIdentityKey00000000000001'; + +export const EXAMPLE_DELEGATOR_ADDRESS = 'n1exampledelegator00000000000000000000000'; + +type UnbondedWalletDelegationOptions = { + mixId?: number; + amount?: string; + blockHeight?: bigint; + owner?: string; +}; + +export function buildFixedUnbondedWalletDelegation( + options: UnbondedWalletDelegationOptions = {}, +): DelegationWithEverything { + const mixId = options.mixId ?? EXAMPLE_UNBONDED_MIX_ID; + + return { + mix_id: mixId, + node_identity: `${UNBONDED_NODE_IDENTITY_PREFIX}${mixId}`, + amount: { amount: options.amount ?? '1000000', denom: 'nym' }, + owner: options.owner ?? EXAMPLE_DELEGATOR_ADDRESS, + block_height: options.blockHeight ?? BigInt(1_000_000), + delegated_on_iso_datetime: null, + unclaimed_rewards: null, + stake_saturation: null, + avg_uptime_percent: null, + accumulated_by_delegates: null, + accumulated_by_operator: null, + cost_params: null, + uses_vesting_contract_tokens: false, + pending_events: [], + mixnode_is_unbonding: true, + errors: null, + }; +} + +/** Pre-fix wallet backend shape when node registry lookup returned none. */ +export function buildLegacyHiddenUnbondedWalletDelegation( + options: UnbondedWalletDelegationOptions = {}, +): DelegationWithEverything { + return { + ...buildFixedUnbondedWalletDelegation(options), + node_identity: '', + mixnode_is_unbonding: null, + }; +} From 959a986e2c7323e2e85752aca6b1d3216eebb812 Mon Sep 17 00:00:00 2001 From: Tommy Verrall Date: Mon, 8 Jun 2026 12:23:00 +0200 Subject: [PATCH 90/94] PR review comments - Add `historical_node_identity` to `DelegationWithEverything` and populate via `lookup_historical_node_identity` in `delegate.rs` so search works after unbond. - `searchDelegations` searches `historical_node_identity` and guards null/empty `node_identity` with optional chaining. - Acceptance tests: historical identity search, bonded-unbonding vs synthetic branch semantics, empty-identity search safety. - Fix linting --- .../types/rust/DelegationWithEverything.ts | 6 ++- common/types/src/delegation.rs | 2 + .../src/operations/mixnet/delegate.rs | 50 ++++++++++++++++--- .../components/Delegation/DelegationList.tsx | 17 +++++-- .../src/context/delegationQuery.test.ts | 10 ++-- nym-wallet/src/context/mocks/delegations.tsx | 2 + .../src/utils/delegationListVisibility.ts | 8 +-- .../unbondedDelegation.acceptance.test.ts | 41 ++++++++++++++- .../src/utils/unbondedDelegation.fixture.ts | 2 + .../types/rust/DelegationWithEverything.ts | 1 + 10 files changed, 116 insertions(+), 23 deletions(-) diff --git a/common/types/bindings/ts-packages/types/src/types/rust/DelegationWithEverything.ts b/common/types/bindings/ts-packages/types/src/types/rust/DelegationWithEverything.ts index ed8a84b8d7..1ba2be7775 100644 --- a/common/types/bindings/ts-packages/types/src/types/rust/DelegationWithEverything.ts +++ b/common/types/bindings/ts-packages/types/src/types/rust/DelegationWithEverything.ts @@ -3,4 +3,8 @@ import type { DecCoin } from "./DecCoin"; import type { DelegationEvent } from "./DelegationEvent"; import type { NodeCostParams } from "./MixNodeCostParams"; -export type DelegationWithEverything = { owner: string, mix_id: number, node_identity: string, amount: DecCoin, accumulated_by_delegates: DecCoin | null, accumulated_by_operator: DecCoin | null, block_height: bigint, delegated_on_iso_datetime: string | null, cost_params: NodeCostParams | null, avg_uptime_percent: number | null, stake_saturation: string | null, uses_vesting_contract_tokens: boolean, unclaimed_rewards: DecCoin | null, errors: string | null, pending_events: Array, mixnode_is_unbonding: boolean | null, }; +export type DelegationWithEverything = { owner: string, mix_id: number, node_identity: string, +/** + * Prior node identity when `node_identity` is synthetic (registry miss after unbond). + */ +historical_node_identity: string | null, amount: DecCoin, accumulated_by_delegates: DecCoin | null, accumulated_by_operator: DecCoin | null, block_height: bigint, delegated_on_iso_datetime: string | null, cost_params: NodeCostParams | null, avg_uptime_percent: number | null, stake_saturation: string | null, uses_vesting_contract_tokens: boolean, unclaimed_rewards: DecCoin | null, errors: string | null, pending_events: Array, mixnode_is_unbonding: boolean | null, }; diff --git a/common/types/src/delegation.rs b/common/types/src/delegation.rs index 3060a02e3a..bfaff3a2d6 100644 --- a/common/types/src/delegation.rs +++ b/common/types/src/delegation.rs @@ -49,6 +49,8 @@ pub struct DelegationWithEverything { pub owner: String, pub mix_id: NodeId, pub node_identity: String, + /// Prior node identity when `node_identity` is synthetic (registry miss after unbond). + pub historical_node_identity: Option, pub amount: DecCoin, pub accumulated_by_delegates: Option, pub accumulated_by_operator: Option, diff --git a/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs b/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs index 9e4cb383f3..81ec42da5c 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs @@ -184,6 +184,39 @@ pub(crate) async fn get_node_information( Ok(None) } +pub(crate) async fn lookup_historical_node_identity( + client: &DirectSigningHttpRpcValidatorClient, + node_id: NodeId, + error_strings: &mut Vec, +) -> Option { + match client.nyxd.get_unbonded_nymnode_information(node_id).await { + Ok(response) => { + if let Some(details) = response.details { + return Some(details.identity_key); + } + } + Err(err) => { + let str_err = format!( + "Failed to get unbonded nymnode information for node_id = {node_id}. Error: {err}", + ); + log::error!(" <<< {str_err}"); + error_strings.push(str_err); + } + } + + match client.nyxd.get_unbonded_mixnode_information(node_id).await { + Ok(response) => response.unbonded_info.map(|info| info.identity_key), + Err(err) => { + let str_err = format!( + "Failed to get unbonded mixnode information for mix_id = {node_id}. Error: {err}", + ); + log::error!(" <<< {str_err}"); + error_strings.push(str_err); + None + } + } +} + // TODO: fix later (yeah...) #[allow(deprecated)] #[tauri::command] @@ -425,10 +458,16 @@ pub async fn get_all_mix_delegations( mixnode_is_unbonding ); + let historical_node_identity = match &node_details { + Some(node) => Some(node.node_identity.clone()), + None => lookup_historical_node_identity(client, d.mix_id, &mut error_strings).await, + }; + with_everything.push(DelegationWithEverything { owner: d.owner, mix_id: d.mix_id, node_identity: delegation_node_identity(&node_details, d.mix_id), + historical_node_identity, amount: d.amount, block_height: d.height, uses_vesting_contract_tokens, @@ -550,13 +589,10 @@ pub(crate) fn delegation_node_identity( pub(crate) fn delegation_mixnode_is_unbonding( node_details: &Option, ) -> Option { - node_details.as_ref().map(|m| m.is_unbonding).or_else(|| { - if node_details.is_none() { - Some(true) - } else { - None - } - }) + match node_details { + Some(node) => Some(node.is_unbonding), + None => Some(true), + } } #[cfg(test)] diff --git a/nym-wallet/src/components/Delegation/DelegationList.tsx b/nym-wallet/src/components/Delegation/DelegationList.tsx index 230811180a..b239a16283 100644 --- a/nym-wallet/src/components/Delegation/DelegationList.tsx +++ b/nym-wallet/src/components/Delegation/DelegationList.tsx @@ -31,7 +31,13 @@ import { useNavigate } from 'react-router-dom'; import { TauriLink as Link } from 'src/components/TauriLinkWrapper'; import { format } from 'date-fns'; import { Undelegate } from 'src/svg-icons'; -import { toPercentIntegerString, isFullyUnbondedDelegation, formatUnbondedNodeLabel, shouldHideDelegationFromList, searchDelegations } from 'src/utils'; +import { + toPercentIntegerString, + isFullyUnbondedDelegation, + formatUnbondedNodeLabel, + shouldHideDelegationFromList, + searchDelegations, +} from 'src/utils'; import { InfoTooltip } from '../InfoToolTip'; import { DelegationListItemActions, DelegationsActionsMenu } from './DelegationActions'; import { PendingDelegationCard } from './PendingDelegationCard'; @@ -42,7 +48,7 @@ export type Order = 'asc' | 'desc'; type AdditionalTypes = { profit_margin_percent: number; operating_cost: number }; export type SortingKeys = keyof AdditionalTypes | keyof DelegationWithEverything; -const shouldBeFiltered = (item: any): boolean => shouldHideDelegationFromList(item); +const shouldBeFiltered = (item: TDelegations[number]): boolean => shouldHideDelegationFromList(item); const SORT_FIELD_OPTIONS: { id: SortingKeys; label: string }[] = [ { id: 'delegated_on_iso_datetime', label: 'Delegated on' }, @@ -114,9 +120,10 @@ export const DelegationList: FCWithChildren<{ const searchNeedle = identityFilter.trim().toLowerCase(); - const displayedDelegations = React.useMemo(() => { - return searchDelegations(activeDelegations, identityFilter); - }, [activeDelegations, identityFilter]); + const displayedDelegations = React.useMemo( + () => searchDelegations(activeDelegations, identityFilter), + [activeDelegations, identityFilter], + ); const activeCount = activeDelegations.length; diff --git a/nym-wallet/src/context/delegationQuery.test.ts b/nym-wallet/src/context/delegationQuery.test.ts index f560b3134a..c06f6a3e3e 100644 --- a/nym-wallet/src/context/delegationQuery.test.ts +++ b/nym-wallet/src/context/delegationQuery.test.ts @@ -1,3 +1,6 @@ +import { getAllPendingDelegations, getDelegationSummary } from 'src/requests'; +import { fetchDelegationSummaryQuery } from './delegationQuery'; + jest.mock('src/utils', () => ({ decCoinToDisplay: jest.fn((coin: { amount: string; denom: string }) => coin), })); @@ -7,13 +10,8 @@ jest.mock('src/requests', () => ({ getAllPendingDelegations: jest.fn(), })); -import { fetchDelegationSummaryQuery } from './delegationQuery'; -import { getAllPendingDelegations, getDelegationSummary } from 'src/requests'; - const mockedGetDelegationSummary = getDelegationSummary as jest.MockedFunction; -const mockedGetAllPendingDelegations = getAllPendingDelegations as jest.MockedFunction< - typeof getAllPendingDelegations ->; +const mockedGetAllPendingDelegations = getAllPendingDelegations as jest.MockedFunction; describe('fetchDelegationSummaryQuery', () => { beforeEach(() => { diff --git a/nym-wallet/src/context/mocks/delegations.tsx b/nym-wallet/src/context/mocks/delegations.tsx index 27c15d3e1d..fe0dcddcf1 100644 --- a/nym-wallet/src/context/mocks/delegations.tsx +++ b/nym-wallet/src/context/mocks/delegations.tsx @@ -37,6 +37,7 @@ let mockDelegations: DelegationWithEverything[] = [ uses_vesting_contract_tokens: false, pending_events: [], mixnode_is_unbonding: false, + historical_node_identity: null, errors: null, }, { @@ -61,6 +62,7 @@ let mockDelegations: DelegationWithEverything[] = [ uses_vesting_contract_tokens: true, pending_events: [], mixnode_is_unbonding: false, + historical_node_identity: null, errors: null, }, ]; diff --git a/nym-wallet/src/utils/delegationListVisibility.ts b/nym-wallet/src/utils/delegationListVisibility.ts index fae364abc6..548f6f0312 100644 --- a/nym-wallet/src/utils/delegationListVisibility.ts +++ b/nym-wallet/src/utils/delegationListVisibility.ts @@ -38,9 +38,11 @@ export function searchDelegations( if (!needle) { return delegations; } - return delegations.filter( - (d) => d.node_identity.toLowerCase().includes(needle) || String(d.mix_id).includes(needle), - ); + return delegations.filter((d) => { + const identity = d.node_identity?.toLowerCase() ?? ''; + const historical = d.historical_node_identity?.toLowerCase() ?? ''; + return identity.includes(needle) || historical.includes(needle) || String(d.mix_id).includes(needle); + }); } export function isUndelegateOnlyDelegation(item: DelegationWithEverything): boolean { diff --git a/nym-wallet/src/utils/unbondedDelegation.acceptance.test.ts b/nym-wallet/src/utils/unbondedDelegation.acceptance.test.ts index 0157771526..c7dd2df2a3 100644 --- a/nym-wallet/src/utils/unbondedDelegation.acceptance.test.ts +++ b/nym-wallet/src/utils/unbondedDelegation.acceptance.test.ts @@ -1,5 +1,5 @@ import type { DelegationWithEverything } from '@nymproject/types'; -import { formatDelegationNodeIdentityForDisplay } from './delegationIdentity'; +import { formatDelegationNodeIdentityForDisplay, isFullyUnbondedDelegation } from './delegationIdentity'; import { filterVisibleDelegations, isUndelegateOnlyDelegation, @@ -48,6 +48,45 @@ describe('unbonded delegation wallet visibility acceptance', () => { expect(searchDelegations(visible, EXAMPLE_HISTORICAL_NODE_IDENTITY)).toHaveLength(0); }); + it('does not throw when search runs on unfiltered rows with empty node_identity', () => { + const legacyRow = buildLegacyHiddenUnbondedWalletDelegation(); + + expect(searchDelegations([legacyRow], String(EXAMPLE_UNBONDED_MIX_ID))).toHaveLength(1); + expect(searchDelegations([legacyRow], 'nonexistent-needle')).toHaveLength(0); + }); + + it('finds the row by historical identity when the backend preserved it', () => { + const fixedRow = buildFixedUnbondedWalletDelegation({ + historicalNodeIdentity: EXAMPLE_HISTORICAL_NODE_IDENTITY, + }); + const visible = filterVisibleDelegations([fixedRow]) as DelegationWithEverything[]; + + expect(searchDelegations(visible, EXAMPLE_HISTORICAL_NODE_IDENTITY)).toHaveLength(1); + expect(searchDelegations(visible, String(EXAMPLE_UNBONDED_MIX_ID))).toHaveLength(1); + }); + + it('keeps bonded-but-unbonding rows linked and not undelegate-only', () => { + const bondedUnbondingRow: DelegationWithEverything = { + ...buildFixedUnbondedWalletDelegation(), + node_identity: EXAMPLE_HISTORICAL_NODE_IDENTITY, + historical_node_identity: EXAMPLE_HISTORICAL_NODE_IDENTITY, + mixnode_is_unbonding: true, + }; + + expect(isFullyUnbondedDelegation(bondedUnbondingRow)).toBe(false); + expect(isUndelegateOnlyDelegation(bondedUnbondingRow)).toBe(false); + expect(searchDelegations([bondedUnbondingRow], EXAMPLE_HISTORICAL_NODE_IDENTITY)).toHaveLength(1); + }); + + it('treats synthetic registry-miss rows as undelegate-only even with historical identity', () => { + const syntheticRow = buildFixedUnbondedWalletDelegation({ + historicalNodeIdentity: EXAMPLE_HISTORICAL_NODE_IDENTITY, + }); + + expect(isFullyUnbondedDelegation(syntheticRow)).toBe(true); + expect(isUndelegateOnlyDelegation(syntheticRow)).toBe(true); + }); + it('formats undelegate confirmation copy without exposing the synthetic prefix', () => { const fixedRow = buildFixedUnbondedWalletDelegation(); diff --git a/nym-wallet/src/utils/unbondedDelegation.fixture.ts b/nym-wallet/src/utils/unbondedDelegation.fixture.ts index c03fc344ea..83fee7cd07 100644 --- a/nym-wallet/src/utils/unbondedDelegation.fixture.ts +++ b/nym-wallet/src/utils/unbondedDelegation.fixture.ts @@ -14,6 +14,7 @@ type UnbondedWalletDelegationOptions = { amount?: string; blockHeight?: bigint; owner?: string; + historicalNodeIdentity?: string | null; }; export function buildFixedUnbondedWalletDelegation( @@ -37,6 +38,7 @@ export function buildFixedUnbondedWalletDelegation( uses_vesting_contract_tokens: false, pending_events: [], mixnode_is_unbonding: true, + historical_node_identity: options.historicalNodeIdentity ?? null, errors: null, }; } diff --git a/ts-packages/types/src/types/rust/DelegationWithEverything.ts b/ts-packages/types/src/types/rust/DelegationWithEverything.ts index a37755f1a7..4adde3e782 100644 --- a/ts-packages/types/src/types/rust/DelegationWithEverything.ts +++ b/ts-packages/types/src/types/rust/DelegationWithEverything.ts @@ -7,6 +7,7 @@ export type DelegationWithEverything = { owner: string; mix_id: number; node_identity: string; + historical_node_identity: string | null; amount: DecCoin; accumulated_by_delegates: DecCoin | null; accumulated_by_operator: DecCoin | null; From c52fc0c9af1874dff55d36684670f78f133f44d2 Mon Sep 17 00:00:00 2001 From: Tommy Verrall Date: Mon, 8 Jun 2026 12:29:19 +0200 Subject: [PATCH 91/94] Last round of fixes - Align `get_pending_delegation_events` with active delegation identity resolution: `get_node_information` + `delegation_node_identity` synthetic fallback on registry miss. - Stop hiding pending delegation rows in `shouldHideDelegationFromList` when bonded-registry identity lookup missed. --- .../src/operations/mixnet/delegate.rs | 26 +++-- .../Delegation/PendingDelegationCard.tsx | 95 +++++++++++-------- .../src/utils/delegationListVisibility.ts | 4 +- .../unbondedDelegation.acceptance.test.ts | 10 ++ .../src/utils/unbondedDelegation.fixture.ts | 18 +++- 5 files changed, 101 insertions(+), 52 deletions(-) diff --git a/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs b/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs index 81ec42da5c..bc36a6a350 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs @@ -48,13 +48,25 @@ pub async fn get_pending_delegation_events( let mut client_specific_events = Vec::new(); for delegation_event in delegation_events { if delegation_event.address_matches(client.nyxd.address().as_ref()) { - let node_identity = client - .nyxd - .get_mixnode_details(delegation_event.mix_id) - .await? - .mixnode_details - .map(|d| d.bond_information.mix_node.identity_key) - .unwrap_or_default(); + let mut error_strings = Vec::new(); + let node_identity = match get_node_information( + client, + delegation_event.mix_id, + &mut error_strings, + ) + .await + { + Ok(node_details) => { + delegation_node_identity(&node_details, delegation_event.mix_id) + } + Err(err) => { + log::error!( + "Failed to resolve node identity for pending event mix_id = {}. Error: {err}", + delegation_event.mix_id + ); + delegation_node_identity(&None, delegation_event.mix_id) + } + }; client_specific_events .push(WrappedDelegationEvent::new(delegation_event, node_identity)); diff --git a/nym-wallet/src/components/Delegation/PendingDelegationCard.tsx b/nym-wallet/src/components/Delegation/PendingDelegationCard.tsx index 6af5f797ec..7c4eac65d7 100644 --- a/nym-wallet/src/components/Delegation/PendingDelegationCard.tsx +++ b/nym-wallet/src/components/Delegation/PendingDelegationCard.tsx @@ -2,45 +2,58 @@ import React from 'react'; import { Box, Chip, Paper, Stack, Tooltip, Typography } from '@mui/material'; import { WrappedDelegationEvent } from '@nymproject/types'; import { TauriLink as Link } from 'src/components/TauriLinkWrapper'; +import { formatDelegationNodeIdentityForDisplay, isUnbondedNodeIdentity } from 'src/utils/delegationIdentity'; -export const PendingDelegationCard = ({ item, explorerUrl }: { item: WrappedDelegationEvent; explorerUrl: string }) => ( - (t.palette.mode === 'dark' ? 'nym.nymWallet.nav.background' : 'nym.nymWallet.background.subtle'), - borderColor: 'divider', - }} - > - - - - {item.event.amount?.amount} {item.event.amount?.denom?.toUpperCase() ?? 'NYM'} - - - - Your delegation of {item.event.amount?.amount} {item.event.amount?.denom} will take effect when the new - epoch starts. There is a new epoch every hour. - - } - arrow - PopperProps={{ - sx: { - '& .MuiTooltip-tooltip': { textAlign: 'left' }, - }, - }} - > - - - - -); +export const PendingDelegationCard = ({ item, explorerUrl }: { item: WrappedDelegationEvent; explorerUrl: string }) => { + const displayIdentity = formatDelegationNodeIdentityForDisplay(item.node_identity, item.event.mix_id); + const nodeIsUnbonded = isUnbondedNodeIdentity(item.node_identity); + + return ( + + t.palette.mode === 'dark' ? 'nym.nymWallet.nav.background' : 'nym.nymWallet.background.subtle', + borderColor: 'divider', + }} + > + + {nodeIsUnbonded ? ( + + {displayIdentity} + + ) : ( + + )} + + {item.event.amount?.amount} {item.event.amount?.denom?.toUpperCase() ?? 'NYM'} + + + + Your delegation of {item.event.amount?.amount} {item.event.amount?.denom} will take effect when the new + epoch starts. There is a new epoch every hour. + + } + arrow + PopperProps={{ + sx: { + '& .MuiTooltip-tooltip': { textAlign: 'left' }, + }, + }} + > + + + + + ); +}; diff --git a/nym-wallet/src/utils/delegationListVisibility.ts b/nym-wallet/src/utils/delegationListVisibility.ts index 548f6f0312..c241507077 100644 --- a/nym-wallet/src/utils/delegationListVisibility.ts +++ b/nym-wallet/src/utils/delegationListVisibility.ts @@ -17,9 +17,7 @@ export function shouldHideDelegationFromList(item: DelegationListItem): boolean } if (isPendingDelegationItem(item)) { - if ((!item.node_identity || item.node_identity === '') && item.event && item.event.kind === 'Undelegate') { - return true; - } + // Pending rows carry mix_id on the event; do not hide when bonded-registry identity lookup missed. return false; } diff --git a/nym-wallet/src/utils/unbondedDelegation.acceptance.test.ts b/nym-wallet/src/utils/unbondedDelegation.acceptance.test.ts index c7dd2df2a3..d85f461974 100644 --- a/nym-wallet/src/utils/unbondedDelegation.acceptance.test.ts +++ b/nym-wallet/src/utils/unbondedDelegation.acceptance.test.ts @@ -11,6 +11,7 @@ import { EXAMPLE_UNBONDED_MIX_ID, buildFixedUnbondedWalletDelegation, buildLegacyHiddenUnbondedWalletDelegation, + buildPendingUndelegateEvent, } from './unbondedDelegation.fixture'; describe('unbonded delegation wallet visibility acceptance', () => { @@ -55,6 +56,15 @@ describe('unbonded delegation wallet visibility acceptance', () => { expect(searchDelegations([legacyRow], 'nonexistent-needle')).toHaveLength(0); }); + it('shows pending undelegate events when node identity lookup missed', () => { + const emptyIdentityPending = buildPendingUndelegateEvent(''); + const syntheticPending = buildPendingUndelegateEvent(`unbonded:${EXAMPLE_UNBONDED_MIX_ID}`); + + expect(shouldHideDelegationFromList(emptyIdentityPending)).toBe(false); + expect(shouldHideDelegationFromList(syntheticPending)).toBe(false); + expect(filterVisibleDelegations([emptyIdentityPending, syntheticPending])).toHaveLength(2); + }); + it('finds the row by historical identity when the backend preserved it', () => { const fixedRow = buildFixedUnbondedWalletDelegation({ historicalNodeIdentity: EXAMPLE_HISTORICAL_NODE_IDENTITY, diff --git a/nym-wallet/src/utils/unbondedDelegation.fixture.ts b/nym-wallet/src/utils/unbondedDelegation.fixture.ts index 83fee7cd07..4b2befb28d 100644 --- a/nym-wallet/src/utils/unbondedDelegation.fixture.ts +++ b/nym-wallet/src/utils/unbondedDelegation.fixture.ts @@ -1,4 +1,4 @@ -import type { DelegationWithEverything } from '@nymproject/types'; +import type { DelegationWithEverything, WrappedDelegationEvent } from '@nymproject/types'; import { UNBONDED_NODE_IDENTITY_PREFIX } from './delegationIdentity'; /** Synthetic mix_id used in wallet unbonded-delegation tests. */ @@ -53,3 +53,19 @@ export function buildLegacyHiddenUnbondedWalletDelegation( mixnode_is_unbonding: null, }; } + +export function buildPendingUndelegateEvent( + nodeIdentity: string, + mixId: number = EXAMPLE_UNBONDED_MIX_ID, +): WrappedDelegationEvent { + return { + node_identity: nodeIdentity, + event: { + kind: 'Undelegate', + mix_id: mixId, + address: EXAMPLE_DELEGATOR_ADDRESS, + amount: { amount: '1000000', denom: 'nym' }, + proxy: null, + }, + }; +} From 2c1b5f59a38c8e31e61a3fa9de7f6baeeeab08c7 Mon Sep 17 00:00:00 2001 From: Tommy Verrall Date: Mon, 8 Jun 2026 12:38:09 +0200 Subject: [PATCH 92/94] Last fixes - Pending Delegate events with registry-miss identity keep explorer navigation; unbonded label limited to pending Undelegate rows (`isPendingUndelegateWithRegistryMiss`, `formatPendingDelegationLinkLabel`). - Tests in `delegationIdentity.test.ts`. --- .../components/Delegation/DelegationList.tsx | 25 +++---------------- .../Delegation/PendingDelegationCard.tsx | 13 +++++++--- .../src/utils/delegationIdentity.test.ts | 19 ++++++++++++++ nym-wallet/src/utils/delegationIdentity.ts | 15 ++++++++++- .../src/utils/unbondedDelegation.fixture.ts | 16 ++++++++++++ 5 files changed, 61 insertions(+), 27 deletions(-) diff --git a/nym-wallet/src/components/Delegation/DelegationList.tsx b/nym-wallet/src/components/Delegation/DelegationList.tsx index b239a16283..c1dbf69856 100644 --- a/nym-wallet/src/components/Delegation/DelegationList.tsx +++ b/nym-wallet/src/components/Delegation/DelegationList.tsx @@ -319,28 +319,9 @@ export const DelegationList: FCWithChildren<{ Pending - {pendingItems.map((item: any, index: number) => { - if ( - item.event && - item.event.kind === 'Delegate' && - (!item.node_identity || item.node_identity === '') - ) { - return ( - - ); - } - - return ( - - ); - })} + {pendingItems.map((item: any, index: number) => ( + + ))} )} diff --git a/nym-wallet/src/components/Delegation/PendingDelegationCard.tsx b/nym-wallet/src/components/Delegation/PendingDelegationCard.tsx index 7c4eac65d7..2c4ac35422 100644 --- a/nym-wallet/src/components/Delegation/PendingDelegationCard.tsx +++ b/nym-wallet/src/components/Delegation/PendingDelegationCard.tsx @@ -2,11 +2,16 @@ import React from 'react'; import { Box, Chip, Paper, Stack, Tooltip, Typography } from '@mui/material'; import { WrappedDelegationEvent } from '@nymproject/types'; import { TauriLink as Link } from 'src/components/TauriLinkWrapper'; -import { formatDelegationNodeIdentityForDisplay, isUnbondedNodeIdentity } from 'src/utils/delegationIdentity'; +import { + formatDelegationNodeIdentityForDisplay, + formatPendingDelegationLinkLabel, + isPendingUndelegateWithRegistryMiss, +} from 'src/utils/delegationIdentity'; export const PendingDelegationCard = ({ item, explorerUrl }: { item: WrappedDelegationEvent; explorerUrl: string }) => { + const pendingUndelegateRegistryMiss = isPendingUndelegateWithRegistryMiss(item); const displayIdentity = formatDelegationNodeIdentityForDisplay(item.node_identity, item.event.mix_id); - const nodeIsUnbonded = isUnbondedNodeIdentity(item.node_identity); + const linkLabel = formatPendingDelegationLinkLabel(item.node_identity, item.event.mix_id); return ( - {nodeIsUnbonded ? ( + {pendingUndelegateRegistryMiss ? ( {displayIdentity} @@ -28,7 +33,7 @@ export const PendingDelegationCard = ({ item, explorerUrl }: { item: WrappedDele diff --git a/nym-wallet/src/utils/delegationIdentity.test.ts b/nym-wallet/src/utils/delegationIdentity.test.ts index c0f38d8ed5..9a83b52791 100644 --- a/nym-wallet/src/utils/delegationIdentity.test.ts +++ b/nym-wallet/src/utils/delegationIdentity.test.ts @@ -2,9 +2,12 @@ import { UNBONDED_NODE_IDENTITY_PREFIX, formatUnbondedNodeLabel, formatDelegationNodeIdentityForDisplay, + formatPendingDelegationLinkLabel, isFullyUnbondedDelegation, + isPendingUndelegateWithRegistryMiss, isUnbondedNodeIdentity, } from './delegationIdentity'; +import { buildPendingDelegateEvent, buildPendingUndelegateEvent } from './unbondedDelegation.fixture'; describe('delegationIdentity', () => { it('treats empty identity as unbonded', () => { @@ -35,4 +38,20 @@ describe('delegationIdentity', () => { '2Abcdefghijklmnopqrstuvwxyz1234567890', ); }); + + it('uses unbonded label only for pending undelegate registry misses', () => { + const pendingDelegate = buildPendingDelegateEvent(`unbonded:${42}`); + const pendingUndelegate = buildPendingUndelegateEvent(`unbonded:${42}`); + + expect(isPendingUndelegateWithRegistryMiss(pendingDelegate)).toBe(false); + expect(isPendingUndelegateWithRegistryMiss(pendingUndelegate)).toBe(true); + }); + + it('formats pending delegate explorer link label by mix id when identity lookup missed', () => { + expect(formatPendingDelegationLinkLabel('', 788)).toBe('Mix 788'); + expect(formatPendingDelegationLinkLabel('unbonded:788', 788)).toBe('Mix 788'); + expect(formatPendingDelegationLinkLabel('2Abcdefghijklmnopqrstuvwxyz1234567890', 788)).toBe( + '2Abcde...567890', + ); + }); }); diff --git a/nym-wallet/src/utils/delegationIdentity.ts b/nym-wallet/src/utils/delegationIdentity.ts index 04cc394be2..7b09466fe1 100644 --- a/nym-wallet/src/utils/delegationIdentity.ts +++ b/nym-wallet/src/utils/delegationIdentity.ts @@ -1,4 +1,4 @@ -import type { DelegationWithEverything } from '@nymproject/types'; +import type { DelegationWithEverything, WrappedDelegationEvent } from '@nymproject/types'; export const UNBONDED_NODE_IDENTITY_PREFIX = 'unbonded:'; @@ -25,3 +25,16 @@ export function formatDelegationNodeIdentityForDisplay(nodeIdentity: string, mix } return nodeIdentity; } + +export function isPendingUndelegateWithRegistryMiss( + item: Pick, +): boolean { + return item.event.kind === 'Undelegate' && isUnbondedNodeIdentity(item.node_identity); +} + +export function formatPendingDelegationLinkLabel(nodeIdentity: string, mixId: number): string { + if (!nodeIdentity || isUnbondedNodeIdentity(nodeIdentity)) { + return `Mix ${mixId}`; + } + return `${nodeIdentity.slice(0, 6)}...${nodeIdentity.slice(-6)}`; +} diff --git a/nym-wallet/src/utils/unbondedDelegation.fixture.ts b/nym-wallet/src/utils/unbondedDelegation.fixture.ts index 4b2befb28d..5cdb9a949b 100644 --- a/nym-wallet/src/utils/unbondedDelegation.fixture.ts +++ b/nym-wallet/src/utils/unbondedDelegation.fixture.ts @@ -69,3 +69,19 @@ export function buildPendingUndelegateEvent( }, }; } + +export function buildPendingDelegateEvent( + nodeIdentity: string, + mixId: number = EXAMPLE_UNBONDED_MIX_ID, +): WrappedDelegationEvent { + return { + node_identity: nodeIdentity, + event: { + kind: 'Delegate', + mix_id: mixId, + address: EXAMPLE_DELEGATOR_ADDRESS, + amount: { amount: '1000000', denom: 'nym' }, + proxy: null, + }, + }; +} From d609d30f3ade5720a28509364f8582381773e452 Mon Sep 17 00:00:00 2001 From: Tommy Verrall Date: Mon, 8 Jun 2026 12:47:01 +0200 Subject: [PATCH 93/94] Formatting fixes --- nym-wallet/src/utils/delegationIdentity.test.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/nym-wallet/src/utils/delegationIdentity.test.ts b/nym-wallet/src/utils/delegationIdentity.test.ts index 9a83b52791..771a91cc56 100644 --- a/nym-wallet/src/utils/delegationIdentity.test.ts +++ b/nym-wallet/src/utils/delegationIdentity.test.ts @@ -50,8 +50,6 @@ describe('delegationIdentity', () => { it('formats pending delegate explorer link label by mix id when identity lookup missed', () => { expect(formatPendingDelegationLinkLabel('', 788)).toBe('Mix 788'); expect(formatPendingDelegationLinkLabel('unbonded:788', 788)).toBe('Mix 788'); - expect(formatPendingDelegationLinkLabel('2Abcdefghijklmnopqrstuvwxyz1234567890', 788)).toBe( - '2Abcde...567890', - ); + expect(formatPendingDelegationLinkLabel('2Abcdefghijklmnopqrstuvwxyz1234567890', 788)).toBe('2Abcde...567890'); }); }); From f7fbf942f9a91ecdac2188a19e242e8c4c13a4af Mon Sep 17 00:00:00 2001 From: Tommy Verrall Date: Mon, 8 Jun 2026 13:20:15 +0200 Subject: [PATCH 94/94] PR comments - Fix addressing concern around unbonding - Amend existing tests to reflect this --- nym-wallet/src-tauri/src/operations/mixnet/delegate.rs | 4 ++-- nym-wallet/src/context/delegationQuery.test.ts | 2 +- nym-wallet/src/utils/unbondedDelegation.acceptance.test.ts | 2 +- nym-wallet/src/utils/unbondedDelegation.fixture.ts | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs b/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs index bc36a6a350..2f129d5569 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/delegate.rs @@ -603,7 +603,7 @@ pub(crate) fn delegation_mixnode_is_unbonding( ) -> Option { match node_details { Some(node) => Some(node.is_unbonding), - None => Some(true), + None => None, } } @@ -619,6 +619,6 @@ mod tests { delegation_node_identity(&None, EXAMPLE_MIX_ID), "unbonded:1234" ); - assert_eq!(delegation_mixnode_is_unbonding(&None), Some(true)); + assert_eq!(delegation_mixnode_is_unbonding(&None), None); } } diff --git a/nym-wallet/src/context/delegationQuery.test.ts b/nym-wallet/src/context/delegationQuery.test.ts index c06f6a3e3e..8893fcbea6 100644 --- a/nym-wallet/src/context/delegationQuery.test.ts +++ b/nym-wallet/src/context/delegationQuery.test.ts @@ -26,7 +26,7 @@ describe('fetchDelegationSummaryQuery', () => { node_identity: 'unbonded:42', amount: { amount: '1000000', denom: 'unym' }, unclaimed_rewards: { amount: '50000', denom: 'unym' }, - mixnode_is_unbonding: true, + mixnode_is_unbonding: null, }, ], total_delegations: { amount: '1000000', denom: 'unym' }, diff --git a/nym-wallet/src/utils/unbondedDelegation.acceptance.test.ts b/nym-wallet/src/utils/unbondedDelegation.acceptance.test.ts index d85f461974..c8ea17615e 100644 --- a/nym-wallet/src/utils/unbondedDelegation.acceptance.test.ts +++ b/nym-wallet/src/utils/unbondedDelegation.acceptance.test.ts @@ -28,7 +28,7 @@ describe('unbonded delegation wallet visibility acceptance', () => { const fixedRow = buildFixedUnbondedWalletDelegation(); expect(fixedRow.node_identity).toBe(`unbonded:${EXAMPLE_UNBONDED_MIX_ID}`); - expect(fixedRow.mixnode_is_unbonding).toBe(true); + expect(fixedRow.mixnode_is_unbonding).toBeNull(); expect(shouldHideDelegationFromList(fixedRow)).toBe(false); expect(filterVisibleDelegations([fixedRow])).toHaveLength(1); expect(isUndelegateOnlyDelegation(fixedRow)).toBe(true); diff --git a/nym-wallet/src/utils/unbondedDelegation.fixture.ts b/nym-wallet/src/utils/unbondedDelegation.fixture.ts index 5cdb9a949b..b158943950 100644 --- a/nym-wallet/src/utils/unbondedDelegation.fixture.ts +++ b/nym-wallet/src/utils/unbondedDelegation.fixture.ts @@ -37,7 +37,7 @@ export function buildFixedUnbondedWalletDelegation( cost_params: null, uses_vesting_contract_tokens: false, pending_events: [], - mixnode_is_unbonding: true, + mixnode_is_unbonding: null, historical_node_identity: options.historicalNodeIdentity ?? null, errors: null, };